Netflix VIP PANEL v7.1
⚠️ ÖNEMLİ BİLGİ:
Bu sayfadaki kodlar yalnızca kopyalama amaçlıdır; sitede otomatik çalıştırılmaz.
Kodu kullanmak için Tampermonkey kurup yeni script olarak eklemeniz gerekir.
Otomasyonun sürekli, agresif veya dengesiz kullanımı platform limitlerine takılmanıza neden olabilir; hesabınız geçici olarak kilitlenebilir, kısıtlanabilir, askıya alınabilir veya kalıcı olarak kapatılabilir.
Tüm işlemleri kendi sorumluluğunuzda, düşük hızda ve dikkatli şekilde kullanın.
1. Tampermonkey Kurulumu
Tarayıcınıza Tampermonkey uzantısını yükleyin. Ardından uzantı ayarlarından Geliştirici Modunu açın ve gerekiyorsa Dosya URL'lerine erişim iznini etkinleştirin.
2. Scripti Ekleme
Netflix için aşağıdaki kodu 📋 KOPYALA ile alın, Tampermonkey'de yeni script açıp yapıştırın ve kaydedin.
3. Nasıl Kullanılır?
Netflix sitesine giriş yapın, sayfayı yenileyin ve panel butonlarını kullanın.
Netflix viewing activity sayfasında script panelini açın, isterseniz CSV yükleyin veya sayfayı taratın.
// ==UserScript==
// @name CODUM.TR NETFLİX ANALİZATÖR VIP
// @namespace http://tampermonkey.net/
// @version 7.1
// @description CODUM.TR - Netflix VIP İzleme Analiz Paneli
// @author CODUM.TR
// @match https://www.netflix.com/viewingactivity*
// @match https://www.netflix.com/*/viewingactivity*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// ==/UserScript==
(function() {
'use strict';
class CodumNetflixAnalyzer {
constructor() {
if (document.getElementById('codum-vip-panel')) return;
this.shows = new Map();
this.movies = [];
this.totalEpisodes = 0;
this.isAnalyzing = false;
this.watchedEpisodes = new Set();
this.watchedMovies = new Set();
this.dataSource = 'none';
this.init();
}
init() {
this.createPanel();
this.loadData();
this.setupEvents();
setTimeout(() => {
if (this.dataSource !== 'csv') {
this.scrapePage();
}
}, 1500);
}
createPanel() {
const panel = document.createElement('div');
panel.id = 'codum-vip-panel';
panel.innerHTML = `
<style>
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700;800;900&family=Inter:wght@300;400;500;600;700&display=swap');
#codum-vip-panel * {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#codum-vip-panel {
position: fixed;
top: 80px;
right: 24px;
z-index: 999999;
width: 360px;
max-height: 85vh;
overflow-y: auto;
background: #0a0a0f;
border-radius: 20px;
padding: 24px;
border: 2px solid #ff0040;
box-shadow:
0 0 30px rgba(255, 0, 64, 0.2),
0 0 60px rgba(255, 0, 64, 0.08),
inset 0 0 30px rgba(255, 0, 64, 0.03);
color: #fff;
font-family: 'Inter', sans-serif;
transition: all 0.3s ease;
}
#codum-vip-panel::-webkit-scrollbar {
width: 4px;
}
#codum-vip-panel::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.02);
}
#codum-vip-panel::-webkit-scrollbar-thumb {
background: #ff0040;
border-radius: 10px;
}
/* ===== HEADER ===== */
.neon-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 16px;
border-bottom: 1px solid rgba(255, 0, 64, 0.15);
}
.neon-header .brand {
display: flex;
align-items: center;
}
.neon-header .brand .info h3 {
font-family: 'Orbitron', monospace;
font-size: 16px;
font-weight: 800;
background: linear-gradient(90deg, #ff0040, #ff6b9d, #ff0040);
background-size: 200% auto;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: neonText 3s linear infinite;
letter-spacing: 0.5px;
}
@keyframes neonText {
0% { background-position: 0% center; }
100% { background-position: 200% center; }
}
.neon-header .brand .info .badge-container {
display: flex;
align-items: center;
gap: 6px;
margin-top: 4px;
}
.neon-header .brand .info .badge {
font-size: 9px;
font-weight: 700;
padding: 2px 8px;
border-radius: 20px;
font-family: 'Orbitron', monospace;
letter-spacing: 0.5px;
text-transform: uppercase;
}
.neon-header .brand .info .badge.csv {
background: rgba(0, 255, 255, 0.1);
border: 1px solid rgba(0, 255, 255, 0.2);
color: #00ffff;
}
.neon-header .brand .info .badge.page {
background: rgba(255, 0, 64, 0.1);
border: 1px solid rgba(255, 0, 64, 0.2);
color: #ff0040;
}
.neon-header .brand .info .badge.vip {
background: linear-gradient(135deg, #ffd700, #ffaa00);
color: #000;
font-weight: 900;
}
.neon-header .close-btn {
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.05);
color: rgba(255, 255, 255, 0.3);
width: 32px;
height: 32px;
border-radius: 10px;
cursor: pointer;
font-size: 16px;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
}
.neon-header .close-btn:hover {
background: rgba(255, 0, 64, 0.1);
border-color: #ff0040;
color: #ff0040;
}
/* ===== DROP ZONE ===== */
.neon-drop {
border: 2px dashed rgba(255, 0, 64, 0.2);
border-radius: 14px;
padding: 18px 16px;
text-align: center;
margin-bottom: 18px;
cursor: pointer;
transition: all 0.3s ease;
background: rgba(255, 0, 64, 0.02);
}
.neon-drop:hover {
border-color: rgba(255, 0, 64, 0.5);
background: rgba(255, 0, 64, 0.05);
}
.neon-drop.dragover {
border-color: #ff0040;
background: rgba(255, 0, 64, 0.08);
transform: scale(1.01);
}
.neon-drop .icon {
font-size: 26px;
display: block;
margin-bottom: 4px;
}
.neon-drop .main-text {
font-size: 12px;
font-weight: 500;
color: rgba(255, 255, 255, 0.7);
}
.neon-drop .main-text strong {
color: #ff0040;
}
.neon-drop .sub-text {
font-size: 10px;
color: rgba(255, 255, 255, 0.25);
margin-top: 4px;
}
#file-input { display: none; }
.file-info {
display: none;
font-size: 11px;
color: rgba(255, 255, 255, 0.4);
text-align: center;
padding: 6px 0 12px 0;
border-bottom: 1px solid rgba(255, 0, 64, 0.08);
margin-bottom: 16px;
}
.file-info.show { display: block; }
.file-info .name { color: #00ffff; font-weight: 600; }
/* ===== STATS ===== */
.neon-stats {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 8px;
margin-bottom: 16px;
}
.neon-stat {
background: rgba(255, 255, 255, 0.02);
border-radius: 12px;
padding: 12px 8px;
text-align: center;
border: 1px solid rgba(255, 255, 255, 0.04);
transition: all 0.3s;
}
.neon-stat:hover {
transform: translateY(-2px);
border-color: rgba(255, 0, 64, 0.3);
}
.neon-stat .number {
font-family: 'Orbitron', monospace;
font-size: 22px;
font-weight: 800;
letter-spacing: 1px;
}
.neon-stat .number.red { color: #ff0040; }
.neon-stat .number.cyan { color: #00ffff; }
.neon-stat .number.pink { color: #ff6b9d; }
.neon-stat .label {
font-size: 8px;
text-transform: uppercase;
color: rgba(255, 255, 255, 0.3);
font-weight: 600;
margin-top: 4px;
font-family: 'Orbitron', monospace;
}
/* ===== TOP LIST ===== */
.neon-top {
background: rgba(255, 255, 255, 0.01);
border-radius: 12px;
padding: 12px 14px;
margin-bottom: 14px;
border: 1px solid rgba(255, 0, 64, 0.08);
max-height: 150px;
overflow-y: auto;
}
.neon-top::-webkit-scrollbar { width: 3px; }
.neon-top::-webkit-scrollbar-thumb { background: #ff0040; border-radius: 10px; }
.neon-top .top-header {
display: flex;
justify-content: space-between;
font-size: 9px;
color: rgba(255, 255, 255, 0.25);
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
padding-bottom: 6px;
border-bottom: 1px solid rgba(255, 0, 64, 0.08);
margin-bottom: 6px;
font-family: 'Orbitron', monospace;
}
.neon-top .top-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 5px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.02);
}
.neon-top .top-item .rank {
font-size: 10px;
color: rgba(255, 255, 255, 0.2);
font-weight: 700;
width: 24px;
font-family: 'Orbitron', monospace;
}
.neon-top .top-item .name {
flex: 1;
font-size: 11px;
color: rgba(255, 255, 255, 0.8);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0 8px;
}
.neon-top .top-item .count {
font-size: 10px;
font-weight: 700;
color: #ff0040;
background: rgba(255, 0, 64, 0.08);
padding: 1px 8px;
border-radius: 20px;
font-family: 'Orbitron', monospace;
}
.neon-top .empty-state {
color: rgba(255, 255, 255, 0.15);
font-size: 11px;
text-align: center;
padding: 16px 0;
font-family: 'Orbitron', monospace;
}
/* ===== PROGRESS ===== */
.neon-progress {
margin: 12px 0 8px 0;
display: none;
}
.neon-progress.active { display: block; }
.neon-progress .bar {
height: 3px;
background: rgba(255, 255, 255, 0.05);
border-radius: 10px;
overflow: hidden;
}
.neon-progress .bar .fill {
height: 100%;
background: linear-gradient(90deg, #ff0040, #00ffff);
width: 0%;
transition: width 0.3s;
}
.neon-progress .text {
font-size: 9px;
color: rgba(255, 255, 255, 0.3);
text-align: center;
margin-top: 4px;
font-family: 'Orbitron', monospace;
}
/* ===== BUTTONS ===== */
.neon-actions {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
.neon-actions .full { grid-column: 1 / -1; }
.neon-btn {
padding: 10px 14px;
border: none;
border-radius: 10px;
font-size: 10px;
font-weight: 700;
cursor: pointer;
transition: all 0.3s;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
font-family: 'Orbitron', monospace;
text-transform: uppercase;
}
.neon-btn-primary {
background: linear-gradient(135deg, #ff0040, #cc0033);
color: #fff;
box-shadow: 0 4px 15px rgba(255, 0, 64, 0.25);
}
.neon-btn-primary:hover:not(:disabled) {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(255, 0, 64, 0.4);
}
.neon-btn-primary:disabled { opacity: 0.3; cursor: not-allowed; }
.neon-btn-secondary {
background: rgba(255, 255, 255, 0.03);
color: rgba(255, 255, 255, 0.6);
border: 1px solid rgba(255, 255, 255, 0.08);
}
.neon-btn-secondary:hover:not(:disabled) {
background: rgba(255, 255, 255, 0.08);
color: #fff;
}
.neon-btn-danger {
background: rgba(255, 0, 64, 0.05);
color: rgba(255, 0, 64, 0.6);
border: 1px solid rgba(255, 0, 64, 0.15);
}
.neon-btn-danger:hover:not(:disabled) {
background: rgba(255, 0, 64, 0.15);
color: #ff0040;
}
/* ===== STATUS ===== */
.neon-status {
margin-top: 14px;
padding: 8px 12px;
border-radius: 8px;
font-size: 10px;
text-align: center;
background: rgba(255, 255, 255, 0.02);
color: rgba(255, 255, 255, 0.3);
border: 1px solid rgba(255, 255, 255, 0.04);
font-family: 'Orbitron', monospace;
}
.neon-status.success { background: rgba(0, 255, 200, 0.05); color: #00ffc8; border-color: rgba(0, 255, 200, 0.1); }
.neon-status.info { background: rgba(0, 255, 255, 0.05); color: #00ffff; border-color: rgba(0, 255, 200, 0.1); }
.neon-status.warning { background: rgba(255, 107, 157, 0.05); color: #ff6b9d; border-color: rgba(255, 107, 157, 0.1); }
/* ===== MINI TOGGLE ===== */
.neon-toggle {
position: fixed;
bottom: 24px;
right: 24px;
z-index: 999998;
width: 50px;
height: 50px;
border-radius: 14px;
background: #0a0a0f;
border: 2px solid #ff0040;
color: #ff0040;
font-size: 14px;
font-weight: 900;
font-family: 'Orbitron', monospace;
cursor: pointer;
box-shadow: 0 0 20px rgba(255, 0, 64, 0.2);
display: none;
align-items: center;
justify-content: center;
}
.neon-toggle:hover { transform: scale(1.05); }
</style>
<!-- PANEL -->
<div class="neon-header">
<div class="brand">
<div class="info">
<h3>CODUM.TR</h3>
<div class="badge-container">
<span class="badge vip">VIP</span>
<span class="badge page" id="source-badge">⚡ SAYFA</span>
</div>
</div>
</div>
<button class="close-btn" id="panel-close">✕</button>
</div>
<!-- DROP ZONE -->
<div class="neon-drop" id="drop-zone">
<span class="icon">📂</span>
<div class="main-text">
<strong>CSV</strong> dosyasını sürükle veya tıkla
</div>
<div class="sub-text">Netflix CSV geçmiş dosyasını yükle</div>
</div>
<input type="file" id="file-input" accept=".csv">
<div class="file-info" id="file-info">
📄 <span class="name" id="file-name">dosya.csv</span> aktarıldı
</div>
<!-- STATS -->
<div class="neon-stats">
<div class="neon-stat">
<div class="number red" id="stat-shows">0</div>
<div class="label">Diziler</div>
</div>
<div class="neon-stat">
<div class="number cyan" id="stat-episodes">0</div>
<div class="label">Bölümler</div>
</div>
<div class="neon-stat">
<div class="number pink" id="stat-movies">0</div>
<div class="label">Filmler</div>
</div>
</div>
<!-- TOP LIST -->
<div class="neon-top">
<div class="top-header">
<span>🏆 EN ÇOK İZLENENLER</span>
<span>✦</span>
</div>
<div id="top-list">
<div class="empty-state">VERİ YOK</div>
</div>
</div>
<!-- PROGRESS -->
<div class="neon-progress" id="progress-wrap">
<div class="bar">
<div class="fill" id="progress-fill"></div>
</div>
<div class="text" id="progress-text">TARANIYOR...</div>
</div>
<!-- ACTIONS -->
<div class="neon-actions">
<button class="neon-btn neon-btn-primary full" id="btn-scan">⟳ SAYFAYI TARA</button>
<button class="neon-btn neon-btn-secondary" id="btn-export">⤓ DIŞA AKTAR</button>
<button class="neon-btn neon-btn-danger" id="btn-reset">✕ TEMİZLE</button>
</div>
<!-- STATUS -->
<div class="neon-status" id="status">
⚡ CODUM.TR Hazır
</div>
<!-- MINI TOGGLE -->
<button class="neon-toggle" id="mini-toggle">CODUM</button>
`;
document.body.appendChild(panel);
}
// ========== EVENT LİSTENER ==========
setupEvents() {
const dropZone = document.getElementById('drop-zone');
const fileInput = document.getElementById('file-input');
dropZone.addEventListener('click', () => fileInput.click());
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('dragover');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('dragover');
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('dragover');
if (e.dataTransfer.files.length > 0) {
this.handleFile(e.dataTransfer.files[0]);
}
});
fileInput.addEventListener('change', (e) => {
if (e.target.files.length > 0) {
this.handleFile(e.target.files[0]);
}
});
document.getElementById('btn-scan').addEventListener('click', () => this.fullScan());
document.getElementById('btn-export').addEventListener('click', () => this.exportData());
document.getElementById('btn-reset').addEventListener('click', () => this.resetData());
document.getElementById('panel-close').addEventListener('click', () => this.togglePanel());
document.getElementById('mini-toggle').addEventListener('click', () => this.togglePanel());
}
togglePanel() {
const panel = document.getElementById('codum-vip-panel');
const toggle = document.getElementById('mini-toggle');
if (panel.style.display === 'none') {
panel.style.display = 'block';
toggle.style.display = 'none';
} else {
panel.style.display = 'none';
toggle.style.display = 'flex';
}
}
// ========== CSV İŞLEME ==========
handleFile(file) {
if (!file.name.endsWith('.csv')) {
this.setStatus('Lütfen geçerli CSV dosyası yükleyin', 'warning');
return;
}
this.shows.clear();
this.movies = [];
this.totalEpisodes = 0;
this.watchedEpisodes.clear();
this.watchedMovies.clear();
this.setStatus(`${file.name} işleniyor...`, 'info');
document.getElementById('file-name').textContent = file.name;
document.getElementById('file-info').classList.add('show');
const badge = document.getElementById('source-badge');
badge.textContent = '📁 CSV';
badge.className = 'badge csv';
this.dataSource = 'csv';
const reader = new FileReader();
reader.onload = (e) => {
try {
this.parseCSV(e.target.result);
this.setStatus(`✅ ${file.name} başarıyla yüklendi!`, 'success');
} catch (err) {
this.setStatus('CSV okunamadı: ' + err.message, 'warning');
}
};
reader.readAsText(file, 'UTF-8');
}
parseCSV(content) {
const lines = content.split('\n').filter(line => line.trim());
let startIndex = 0;
for (let i = 0; i < Math.min(lines.length, 5); i++) {
if (lines[i].toLowerCase().includes('title')) {
startIndex = i + 1;
break;
}
}
for (let i = startIndex; i < lines.length; i++) {
const line = lines[i];
const parts = line.split(',');
let title = parts[0]?.trim();
if (title && title.startsWith('"')) title = title.substring(1);
if (title && title.endsWith('"')) title = title.substring(0, title.length - 1);
title = title?.replace(/^"|"$/g, '').trim();
if (!title || title.length < 2) continue;
const uniqueId = title;
if (title.includes(':')) {
const showName = title.split(':')[0].trim();
if (showName) {
if (!this.shows.has(showName)) {
this.shows.set(showName, { episodes: 0 });
}
if (!this.watchedEpisodes.has(uniqueId)) {
const show = this.shows.get(showName);
show.episodes = (show.episodes || 0) + 1;
this.totalEpisodes++;
this.watchedEpisodes.add(uniqueId);
}
}
} else {
if (!this.watchedMovies.has(uniqueId)) {
if (!this.movies.includes(title)) {
this.movies.push(title);
}
this.watchedMovies.add(uniqueId);
}
}
}
this.saveData();
this.updateUI();
}
// ========== SAYFA TARAMA ==========
scrapePage() {
if (this.dataSource === 'csv') return;
const rows = document.querySelectorAll('.retableRow .title a, [data-uia="item-title"]');
if (!rows || rows.length === 0) return;
let newShows = 0;
let newEpisodes = 0;
rows.forEach(el => {
const title = el.innerText?.trim();
if (!title) return;
const uniqueId = title;
if (title.includes(':')) {
const showName = title.split(':')[0].trim();
if (showName) {
if (!this.shows.has(showName)) {
this.shows.set(showName, { episodes: 0 });
newShows++;
}
if (!this.watchedEpisodes.has(uniqueId)) {
const show = this.shows.get(showName);
show.episodes = (show.episodes || 0) + 1;
this.totalEpisodes++;
this.watchedEpisodes.add(uniqueId);
newEpisodes++;
}
}
} else {
if (!this.watchedMovies.has(uniqueId)) {
if (!this.movies.includes(title)) {
this.movies.push(title);
}
this.watchedMovies.add(uniqueId);
}
}
});
if (newShows > 0 || newEpisodes > 0) {
this.saveData();
this.updateUI();
this.setStatus(`✅ ${newShows} yeni dizi, ${newEpisodes} yeni bölüm eklendi`, 'success');
}
}
// ========== TAM TARAMA ==========
fullScan() {
if (this.isAnalyzing) return;
if (this.dataSource === 'csv') {
this.setStatus('⚠️ CSV modundasınız, sayfa taranamaz!', 'warning');
return;
}
this.isAnalyzing = true;
const btn = document.getElementById('btn-scan');
const progressWrap = document.getElementById('progress-wrap');
const progressFill = document.getElementById('progress-fill');
const progressText = document.getElementById('progress-text');
btn.disabled = true;
btn.textContent = '⟳ TARANIYOR...';
progressWrap.classList.add('active');
let lastHeight = 0;
let scrollCount = 0;
let previousTotal = this.totalEpisodes;
const timer = setInterval(() => {
window.scrollTo(0, document.body.scrollHeight);
this.scrapePage();
scrollCount++;
const currentHeight = document.body.scrollHeight;
const progress = Math.min((scrollCount / 30) * 100, 95);
progressFill.style.width = progress + '%';
progressText.textContent = `TARANIYOR... %${Math.round(progress)}`;
if (currentHeight === lastHeight || scrollCount >= 80) {
clearInterval(timer);
progressFill.style.width = '100%';
progressText.textContent = '✓ TAMAMLANDI';
setTimeout(() => {
progressWrap.classList.remove('active');
btn.disabled = false;
btn.textContent = '⟳ SAYFAYI TARA';
this.isAnalyzing = false;
const totalNew = this.totalEpisodes - previousTotal;
if (totalNew > 0) {
this.setStatus(`✅ Tarama bitti! ${totalNew} yeni bölüm eklendi`, 'success');
} else {
this.setStatus('⚡ Veriler zaten güncel', 'info');
}
}, 600);
}
lastHeight = currentHeight;
}, 500);
}
// ========== VERİ YÖNETİMİ ==========
saveData() {
try {
const data = {
shows: Object.fromEntries(this.shows),
movies: this.movies,
totalEpisodes: this.totalEpisodes,
watchedEpisodes: Array.from(this.watchedEpisodes),
watchedMovies: Array.from(this.watchedMovies),
dataSource: this.dataSource
};
GM_setValue('codum_netflix_data', JSON.stringify(data));
} catch (e) {}
}
loadData() {
try {
const saved = GM_getValue('codum_netflix_data');
if (saved) {
const data = JSON.parse(saved);
this.shows = new Map(Object.entries(data.shows || {}));
this.movies = data.movies || [];
this.totalEpisodes = data.totalEpisodes || 0;
this.watchedEpisodes = new Set(data.watchedEpisodes || []);
this.watchedMovies = new Set(data.watchedMovies || []);
this.dataSource = data.dataSource || 'page';
const badge = document.getElementById('source-badge');
if (this.dataSource === 'csv') {
badge.textContent = '📁 CSV';
badge.className = 'badge csv';
} else {
badge.textContent = '⚡ SAYFA';
badge.className = 'badge page';
}
this.updateUI();
return true;
}
} catch (e) {}
return false;
}
// ========== UI GÜNCELLE ==========
updateUI() {
document.getElementById('stat-shows').textContent = this.shows.size || 0;
document.getElementById('stat-episodes').textContent = this.totalEpisodes || 0;
document.getElementById('stat-movies').textContent = this.movies.length || 0;
const sorted = Array.from(this.shows.entries())
.sort((a, b) => (b[1]?.episodes || 0) - (a[1]?.episodes || 0))
.slice(0, 6);
const container = document.getElementById('top-list');
if (sorted.length === 0) {
container.innerHTML = '<div class="empty-state">VERİ YOK</div>';
} else {
container.innerHTML = sorted.map(([name, data], index) => `
<div class="top-item">
<span class="rank">#${index + 1}</span>
<span class="name">${this.escapeHtml(name)}</span>
<span class="count">${data?.episodes || 0}</span>
</div>
`).join('');
}
}
// ========== DIŞA AKTAR ==========
exportData() {
if (this.shows.size === 0 && this.movies.length === 0) {
this.setStatus('Dışa aktarılacak veri yok', 'warning');
return;
}
const data = {
site: "codum.tr",
shows: Object.fromEntries(this.shows),
movies: this.movies,
totalEpisodes: this.totalEpisodes,
totalShows: this.shows.size,
totalMovies: this.movies.length,
dataSource: this.dataSource,
exportDate: new Date().toISOString()
};
const json = JSON.stringify(data, null, 2);
const blob = new Blob([json], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `codum_netflix_analiz_${new Date().toISOString().slice(0,10)}.json`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
this.setStatus('✅ Veriler JSON olarak aktarıldı!', 'success');
}
// ========== SIFIRLA ==========
resetData() {
if (!confirm('⚡ Tüm CODUM.TR verileri silinecektir. Onaylıyor musunuz?')) return;
this.shows.clear();
this.movies = [];
this.totalEpisodes = 0;
this.watchedEpisodes.clear();
this.watchedMovies.clear();
this.dataSource = 'none';
GM_deleteValue('codum_netflix_data');
document.getElementById('file-info').classList.remove('show');
const badge = document.getElementById('source-badge');
badge.textContent = '⚡ SAYFA';
badge.className = 'badge page';
this.updateUI();
this.setStatus('🗑️ Veriler temizlendi', '');
}
// ========== YARDIMCI ==========
setStatus(text, type = '') {
const el = document.getElementById('status');
const emoji = text.match(/^[^\s]+/)?.[0] || '⚡';
const cleanText = text.replace(/^[^\s]+\s/, '');
el.innerHTML = `${emoji} ${cleanText || text}`;
el.className = 'neon-status' + (type ? ' ' + type : '');
}
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
}
// ========== BAŞLAT ==========
window.addEventListener('load', () => {
setTimeout(() => new CodumNetflixAnalyzer(), 1200);
});
})();