feat: 50 channels, daily 3AM cron sync, countdown timer, remove manual button
This commit is contained in:
+1
-1
@@ -51,7 +51,7 @@ async def fetch_subscriptions():
|
||||
# Step 2: For each channel, get latest videos
|
||||
new_count = 0
|
||||
async with aiosqlite.connect(DB_PATH) as db:
|
||||
for cid in channel_ids[:20]:
|
||||
for cid in channel_ids[:50]:
|
||||
try:
|
||||
req = youtube.search().list(
|
||||
part="snippet",
|
||||
|
||||
+6
-7
@@ -7,14 +7,13 @@ services:
|
||||
dockerfile: Dockerfile
|
||||
container_name: t-youtube
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
ports:
|
||||
- "8001:8000"
|
||||
environment:
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY:-sk-Kq5JbgmnEEkdzTqNAQ6bV6nztQ0ngeHTHF9Vg8nUglQvrOlx}
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
- ANTHROPIC_BASE_URL=https://www.bytecatcode.org
|
||||
- HTTP_PROXY=http://100.70.115.1:8118
|
||||
- HTTPS_PROXY=http://100.70.115.1:8118
|
||||
- NO_PROXY=localhost,127.0.0.1,100.0.0.0/8,192.168.0.0/16
|
||||
- DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}
|
||||
- DEEPSEEK_BASE_URL=https://api.deepseek.com
|
||||
- DEEPSEEK_MODEL=deepseek-chat
|
||||
- DB_DIR=/app/data
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
- ./config:/app/config
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
let isSyncing = $state(false);
|
||||
let syncMessage = $state('');
|
||||
let pendingCount = $state(0);
|
||||
let nextSync = $state(localStorage.getItem('t-yt-next-sync') || '');
|
||||
let theme = $state(localStorage.getItem('theme') || 'dark');
|
||||
let summaryPanel = $state(null);
|
||||
let notes = $state(JSON.parse(localStorage.getItem('t-yt-notes') || '{}'));
|
||||
@@ -92,10 +93,25 @@
|
||||
document.documentElement.className = theme;
|
||||
loadVideos();
|
||||
loadPendingCount();
|
||||
updateSyncTimer();
|
||||
window.addEventListener('keydown', handleKeydown);
|
||||
return () => window.removeEventListener('keydown', handleKeydown);
|
||||
});
|
||||
|
||||
function updateSyncTimer() {
|
||||
const el = document.getElementById('sync-timer');
|
||||
if (!el) return;
|
||||
const now = new Date();
|
||||
const next = new Date(now);
|
||||
next.setHours(3, 0, 0, 0); // 3 AM daily
|
||||
if (now > next) next.setDate(next.getDate() + 1);
|
||||
const diff = next - now;
|
||||
const h = Math.floor(diff / 3600000);
|
||||
const m = Math.floor((diff % 3600000) / 60000);
|
||||
el.textContent = `Next sync in ${h}h ${m}m`;
|
||||
setTimeout(updateSyncTimer, 60000);
|
||||
}
|
||||
|
||||
async function loadPendingCount() {
|
||||
try {
|
||||
const res = await fetch('/api/videos?status=pending&limit=1');
|
||||
@@ -191,16 +207,12 @@
|
||||
<span class="text-[10px] px-2 py-0.5 rounded font-semibold uppercase tracking-widest" style="background:var(--bg-tertiary);color:var(--text-muted)">text feed</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-3">
|
||||
<button onclick={syncSubscriptions} disabled={isSyncing}
|
||||
class="px-3 py-1.5 text-xs font-bold rounded-lg transition"
|
||||
style="background:var(--accent);color:white">
|
||||
{isSyncing ? 'Syncing...' : 'Sync'}
|
||||
</button>
|
||||
<button onclick={toggleTheme}
|
||||
class="text-sm px-2 py-1 rounded transition" style="color:var(--text-muted)"
|
||||
title="Toggle theme">
|
||||
{theme === 'dark' ? '☀' : '☾'}
|
||||
</button>
|
||||
<span class="text-[10px]" style="color:var(--text-muted)" id="sync-timer"></span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user