bep40 commited on
Commit
6db3bcc
·
verified ·
1 Parent(s): e8f1d9e

Delete static/shorts_fresh_fetch.js with huggingface_hub

Browse files
Files changed (1) hide show
  1. static/shorts_fresh_fetch.js +0 -214
static/shorts_fresh_fetch.js DELETED
@@ -1,214 +0,0 @@
1
- /**
2
- * VNEWS Fresh Shorts Fetcher
3
- * Fetches latest shorts directly from YouTube via proxy
4
- * Runs in browser to bypass server SSL blocks
5
- */
6
- (function() {
7
- 'use strict';
8
-
9
- const PROXY_URL = 'https://api.allorigins.win/raw?url=';
10
- const CHANNELS = [
11
- { handle: 'baodantri7941', name: 'Dân trí' },
12
- { handle: 'baosuckhoedoisongboyte', name: 'SKĐS' },
13
- { handle: 'vtvnambo', name: 'VTV Nam Bộ' }
14
- ];
15
-
16
- function showToast(msg) {
17
- let t = document.getElementById('short-progress-toast');
18
- if (!t) {
19
- t = document.createElement('div');
20
- t.id = 'short-progress-toast';
21
- document.body.appendChild(t);
22
- }
23
- t.textContent = msg;
24
- t.style.display = 'block';
25
- setTimeout(() => { t.style.display = 'none'; }, 3000);
26
- }
27
-
28
- async function fetchPage(url) {
29
- const proxyUrl = PROXY_URL + encodeURIComponent(url);
30
- const resp = await fetch(proxyUrl);
31
- if (!resp.ok) throw new Error('Proxy error: ' + resp.status);
32
- return await resp.text();
33
- }
34
-
35
- function extractShortsFromHTML(html, handle) {
36
- const shorts = [];
37
- const seen = new Set();
38
-
39
- // Method 1: Parse ytInitialData JSON
40
- const match = html.match(/var ytInitialData = ({.+?});<\/script>/s);
41
- if (match) {
42
- try {
43
- const data = JSON.parse(match[1]);
44
- function walk(obj, depth) {
45
- if (depth > 12 || shorts.length >= 30) return;
46
- if (obj && typeof obj === 'object') {
47
- if (obj.videoRenderer) {
48
- const vr = obj.videoRenderer;
49
- const vid = vr.videoId;
50
- if (vid && !seen.has(vid)) {
51
- seen.add(vid);
52
- const titleRuns = (vr.title && vr.title.runs) || [];
53
- const title = titleRuns.map(r => r.text).join('') || 'YouTube Short';
54
- shorts.push({
55
- id: vid,
56
- title: title.substring(0, 120),
57
- img: 'https://i.ytimg.com/vi/' + vid + '/hqdefault.jpg',
58
- link: 'https://www.youtube.com/shorts/' + vid,
59
- channel: handle,
60
- source: 'yt'
61
- });
62
- }
63
- }
64
- for (const key in obj) {
65
- if (Array.isArray(obj[key])) {
66
- obj[key].forEach(item => walk(item, depth + 1));
67
- } else if (typeof obj[key] === 'object') {
68
- walk(obj[key], depth + 1);
69
- }
70
- }
71
- }
72
- }
73
- walk(data, 0);
74
- } catch(e) {}
75
- }
76
-
77
- // Method 2: Regex fallback
78
- if (shorts.length === 0) {
79
- const vidRegex = /"videoId":"([A-Za-z0-9_-]{11})"/g;
80
- let m;
81
- while ((m = vidRegex.exec(html)) !== null) {
82
- const vid = m[1];
83
- if (!seen.has(vid)) {
84
- seen.add(vid);
85
- const context = html.substring(Math.max(0, m.index - 600), m.index + 100);
86
- let title = 'YouTube Short';
87
- const tm = context.match(/"title":\{"runs":\[\{"text":"([^"]+)"/
88
- ) || context.match(/"title":"([^"]+)"/);
89
- if (tm) title = tm[1].replace(/\\n/g, ' ').replace(/\\"/g, '"');
90
- shorts.push({
91
- id: vid,
92
- title: title.substring(0, 120),
93
- img: 'https://i.ytimg.com/vi/' + vid + '/hqdefault.jpg',
94
- link: 'https://www.youtube.com/shorts/' + vid,
95
- channel: handle,
96
- source: 'yt'
97
- });
98
- if (shorts.length >= 30) break;
99
- }
100
- }
101
- }
102
-
103
- // Method 3: /shorts/ URL pattern
104
- if (shorts.length === 0) {
105
- const shortsRegex = /\/shorts\/([A-Za-z0-9_-]{11})/g;
106
- let m;
107
- while ((m = shortsRegex.exec(html)) !== null) {
108
- const vid = m[1];
109
- if (!seen.has(vid)) {
110
- seen.add(vid);
111
- shorts.push({
112
- id: vid,
113
- title: 'YouTube Short from @' + handle,
114
- img: 'https://i.ytimg.com/vi/' + vid + '/hqdefault.jpg',
115
- link: 'https://www.youtube.com/shorts/' + vid,
116
- channel: handle,
117
- source: 'yt'
118
- });
119
- if (shorts.length >= 30) break;
120
- }
121
- }
122
- }
123
-
124
- return shorts;
125
- }
126
-
127
- async function fetchFreshShorts(handle) {
128
- const url = 'https://www.youtube.com/@' + handle + '/shorts';
129
- const html = await fetchPage(url);
130
- return extractShortsFromHTML(html, handle);
131
- }
132
-
133
- // Main function: fetch all channels
134
- window.fetchAllFreshShorts = async function() {
135
- const allShorts = [];
136
- for (const ch of CHANNELS) {
137
- try {
138
- const shorts = await fetchFreshShorts(ch.handle);
139
- allShorts.push(...shorts);
140
- await new Promise(r => setTimeout(r, 1500));
141
- } catch(e) {
142
- console.warn('Failed to fetch @' + ch.handle + ':', e.message);
143
- }
144
- }
145
- const seen = new Set();
146
- return allShorts.filter(s => {
147
- if (seen.has(s.id)) return false;
148
- seen.add(s.id);
149
- return true;
150
- });
151
- };
152
-
153
- // Refresh and update _shortsData
154
- window.refreshShortsData = async function() {
155
- try {
156
- showToast('🔄 Đang cập nhật shorts mới...');
157
- const fresh = await window.fetchAllFreshShorts();
158
- if (fresh.length > 0) {
159
- const existing = window._shortsData || [];
160
- const existingIds = new Set(existing.map(s => s.id));
161
- const newShorts = fresh.filter(s => !existingIds.has(s.id));
162
- window._shortsData = [...newShorts, ...existing].slice(0, 60);
163
- localStorage.setItem('vnews_shorts_cache', JSON.stringify({
164
- timestamp: Date.now(),
165
- shorts: window._shortsData
166
- }));
167
- showToast('✓ Đã cập nhật ' + newShorts.length + ' shorts mới!');
168
- // Re-render if on home
169
- if (typeof _renderShortsIn === 'function') {
170
- const afterEl = document.getElementById('home-after-wc');
171
- if (afterEl) _renderShortsIn(afterEl);
172
- }
173
- return window._shortsData;
174
- } else {
175
- showToast('⚠️ Không lấy được shorts mới, dùng cache cũ');
176
- return window._shortsData || [];
177
- }
178
- } catch(e) {
179
- console.error('Refresh shorts error:', e);
180
- showToast('⚠️ Lỗi cập nhật shorts, dùng cache cũ');
181
- return window._shortsData || [];
182
- }
183
- };
184
-
185
- // Load from localStorage cache on startup
186
- function loadLocalCache() {
187
- try {
188
- const cached = localStorage.getItem('vnews_shorts_cache');
189
- if (cached) {
190
- const data = JSON.parse(cached);
191
- if (Date.now() - data.timestamp < 7200000 && data.shorts && data.shorts.length > 0) {
192
- console.log('[Shorts] Loaded ' + data.shorts.length + ' from localStorage cache');
193
- return data.shorts;
194
- }
195
- }
196
- } catch(e) {}
197
- return null;
198
- }
199
-
200
- // Override _shortsData with local cache
201
- const localShorts = loadLocalCache();
202
- if (localShorts) {
203
- window._shortsData = localShorts;
204
- }
205
-
206
- // Auto-refresh on page load
207
- setTimeout(() => {
208
- if (typeof window.refreshShortsData === 'function') {
209
- window.refreshShortsData().catch(() => {});
210
- }
211
- }, 5000);
212
-
213
- console.log('[Shorts] Fresh fetcher loaded');
214
- })();