Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions scripts/fetch-rt.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ const TV_DATA_DIR = path.join(__dirname, '../lib/data/tv');
const TRACKED_SHOWS_FILE = path.join(TV_DATA_DIR, 'tracked-shows.json');
const OUTPUT_FILE = path.join(TV_DATA_DIR, 'rotten-tomatoes.json');

async function fetchWithTimeout(url, timeoutMs = 15000) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(url, { signal: controller.signal });
clearTimeout(id);
return response;
} catch (err) {
clearTimeout(id);
throw err;
}
}

async function main() {
console.log('Starting Rotten Tomatoes schedule pre-cache fetcher...');
try {
Expand Down Expand Up @@ -93,6 +106,37 @@ async function main() {
console.warn('Could not read TV data directory for extra show files:', dirErr.message);
}

// 5. Discover US TV show names dynamically from TVMaze schedule (next 7 days)
console.log('Discovering TV shows from TVMaze US schedule...');
try {
for (let i = 0; i <= 7; i++) {
const d = new Date();
d.setDate(d.getDate() + i);
const dateStr = d.toISOString().slice(0, 10);
Comment on lines +113 to +115

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Timezone misalignment skips the current local day during schedule discovery.

Both scripts mix local date mutation (getDate(), setDate()) with UTC string formatting (toISOString()). If the script runs in a timezone where the local date lags behind UTC (e.g., US evenings), toISOString() evaluates to the next calendar day. This mismatch causes the discovery loop to completely skip the current local day's schedule.

  • scripts/fetch-rt.js#L113-L115: Format local year, month, and day to ensure the query date strictly matches the local date iteration.
  • scripts/google-verify.js#L212-L214: Apply the exact same local date formatting fix to ensure consistent date boundaries here.
🛠️ Proposed fix for both files
-        const d = new Date();
-        d.setDate(d.getDate() + i);
-        const dateStr = d.toISOString().slice(0, 10);
+        const d = new Date();
+        d.setDate(d.getDate() + i);
+        const dateStr = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const d = new Date();
d.setDate(d.getDate() + i);
const dateStr = d.toISOString().slice(0, 10);
const d = new Date();
d.setDate(d.getDate() + i);
const dateStr = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
📍 Affects 2 files
  • scripts/fetch-rt.js#L113-L115 (this comment)
  • scripts/google-verify.js#L212-L214
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/fetch-rt.js` around lines 113 - 115, Replace the UTC-based date
formatting after local date mutation in scripts/fetch-rt.js lines 113-115 and
scripts/google-verify.js lines 212-214 with local year, month, and day
formatting, preserving the existing date iteration so each query matches the
intended local calendar date.

const scheduleUrl = `https://api.tvmaze.com/schedule?country=US&date=${dateStr}`;
try {
const response = await fetchWithTimeout(scheduleUrl);
if (response.ok) {
const scheduleData = await response.json();
if (Array.isArray(scheduleData)) {
for (const item of scheduleData) {
const name = item.show?.name;
if (typeof name === 'string' && name.trim()) {
showSet.add(name.trim());
}
}
}
} else {
console.warn(` Failed to fetch US schedule for ${dateStr}: ${response.status}`);
}
} catch (fetchErr) {
console.warn(` Error fetching US schedule for ${dateStr}:`, fetchErr.message);
}
}
} catch (scheduleErr) {
console.warn('Could not discover shows from TVMaze US schedule:', scheduleErr.message);
}

const showsToFetch = Array.from(showSet);
console.log(`Discovered ${showsToFetch.length} unique TV shows to process:`, showsToFetch);

Expand All @@ -105,10 +149,10 @@ async function main() {
let seasonsToFetch = new Set([1]); // default to season 1
try {
const tvmazeUrl = `https://api.tvmaze.com/singlesearch/shows?q=${encodeURIComponent(query)}`;
const response = await fetch(tvmazeUrl);
const response = await fetchWithTimeout(tvmazeUrl);
if (response.ok) {
const show = await response.json();
const episodesResponse = await fetch(`https://api.tvmaze.com/shows/${show.id}/episodes?specials=0`);
const episodesResponse = await fetchWithTimeout(`https://api.tvmaze.com/shows/${show.id}/episodes?specials=0`);
if (episodesResponse.ok) {
const episodes = await episodesResponse.json();
episodes.forEach(ep => {
Expand Down
48 changes: 46 additions & 2 deletions scripts/google-verify.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ const TRACKED_SHOWS_FILE = path.join(TV_DATA_DIR, 'tracked-shows.json');
const RT_DATA_FILE = path.join(TV_DATA_DIR, 'rotten-tomatoes.json');
const OUTPUT_FILE = path.join(TV_DATA_DIR, 'google-verified.json');

async function fetchWithTimeout(url, timeoutMs = 15000) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(url, { signal: controller.signal });
clearTimeout(id);
return response;
} catch (err) {
clearTimeout(id);
throw err;
}
}

function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
Expand Down Expand Up @@ -192,6 +205,37 @@ async function main() {
console.warn('Could not read TV data directory for extra show files:', dirErr.message);
}

// 5. Discover US TV show names dynamically from TVMaze schedule (next 7 days)
console.log('Discovering TV shows from TVMaze US schedule...');
try {
for (let i = 0; i <= 7; i++) {
const d = new Date();
d.setDate(d.getDate() + i);
const dateStr = d.toISOString().slice(0, 10);
const scheduleUrl = `https://api.tvmaze.com/schedule?country=US&date=${dateStr}`;
try {
const response = await fetchWithTimeout(scheduleUrl);
if (response.ok) {
const scheduleData = await response.json();
if (Array.isArray(scheduleData)) {
for (const item of scheduleData) {
const name = item.show?.name;
if (typeof name === 'string' && name.trim()) {
showSet.add(name.trim());
}
}
}
} else {
console.warn(` Failed to fetch US schedule for ${dateStr}: ${response.status}`);
}
} catch (fetchErr) {
console.warn(` Error fetching US schedule for ${dateStr}:`, fetchErr.message);
}
}
} catch (scheduleErr) {
console.warn('Could not discover shows from TVMaze US schedule:', scheduleErr.message);
}

const showsToFetch = Array.from(showSet);
console.log(`Discovered ${showsToFetch.length} unique TV shows to process on MakeICS:`);
showsToFetch.forEach(s => console.log(` - Fetching Google verification for: "${s}"`));
Expand Down Expand Up @@ -239,10 +283,10 @@ async function main() {
let tvmazeEps = [];
try {
const tvmazeUrl = `https://api.tvmaze.com/singlesearch/shows?q=${encodeURIComponent(query)}`;
const response = await fetch(tvmazeUrl);
const response = await fetchWithTimeout(tvmazeUrl);
if (response.ok) {
tvmazeShow = await response.json();
const epResponse = await fetch(`https://api.tvmaze.com/shows/${tvmazeShow.id}/episodes?specials=0`);
const epResponse = await fetchWithTimeout(`https://api.tvmaze.com/shows/${tvmazeShow.id}/episodes?specials=0`);
if (epResponse.ok) {
tvmazeEps = await epResponse.json();
}
Expand Down
29 changes: 29 additions & 0 deletions test/googleVerify.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,32 @@ test('formatDateVariants returns proper objects with year markers', () => {
// June 1 should match "June 1, 2026"
assert.equal(matchVariant('release date is june 1, 2026', { text: 'june 1', hasYear: false }), true);
});

test('TVMaze schedule discovery parses show names correctly', () => {
const mockSchedule = [
{
show: { name: 'Show A' }
},
{
show: { name: 'Show B' }
},
{
show: null
}
];

const showSet = new Set();
const scheduleData = mockSchedule;
if (Array.isArray(scheduleData)) {
for (const item of scheduleData) {
const name = item.show?.name;
if (typeof name === 'string' && name.trim()) {
showSet.add(name.trim());
}
}
}

assert.equal(showSet.size, 2);
assert.ok(showSet.has('Show A'));
assert.ok(showSet.has('Show B'));
});
Loading