From 9ab322751a732d8cbc1ddf4f2ecf5022d7242baa Mon Sep 17 00:00:00 2001 From: Marijn Besseling Date: Sun, 7 Sep 2025 20:56:09 +0200 Subject: WIP migration --- Blog/Components/Pages/Letterflixd.razor.js | 99 ++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 Blog/Components/Pages/Letterflixd.razor.js (limited to 'Blog/Components/Pages/Letterflixd.razor.js') diff --git a/Blog/Components/Pages/Letterflixd.razor.js b/Blog/Components/Pages/Letterflixd.razor.js new file mode 100644 index 0000000..a3903e2 --- /dev/null +++ b/Blog/Components/Pages/Letterflixd.razor.js @@ -0,0 +1,99 @@ +import { getById, resetLog, writeError, writeInfo, writeDebug, a, span, div, addClass } from "/common.module.js" + +let netflix_file_input = undefined; + +export function onLoad() { + + const form = getById("form"); + netflix_file_input = getById("netflix-file"); + + form.addEventListener("submit", submitForm); +} + + +/** @param {SubmitEvent} event */ +function submitForm(event) { + event.preventDefault(); + event.stopPropagation(); + + resetLog(); + const files = netflix_file_input.files; + if (files.length !== 1) { + writeError("First select your viewing history file."); + return; + } + + const netflix_file = files[0]; + + writeInfo("Checking metadata..."); + + if (!netflix_file.type.match('text/csv')) { + let detected_filetype = ""; + if (netflix_file.type) { + detected_filetype = ", detected filetype: " + netflix_file.type; + } + writeError("Select a CSV file" + detected_filetype); + return; + } + + handleFile(netflix_file); +} + +/** @param {File} file */ +function handleFile(file) { + writeInfo("Reading file..."); + file.text() + .then(convertText); +} + +const viewingHistoryPattern = /"(.*)","(\d{1,2})\/(\d{1,2})\/(\d+)"/; + +/** @param {string} data */ +function convertText(data) { + writeInfo("Checking header..."); + const [header, ...lines] = data.split(/\r?\n|\r|\n/g); + if (header !== "Title,Date") { + writeError("Invalid Netflix viewing history file, expected header \"Title,Date\""); + return; + } + writeInfo("History count: " + lines.length); + let letterboxd_output = "Title,WatchedDate,Rewatch\n"; + let watched_movies = new Set(); + + for (let line of lines) { + if (!line) continue; + if (line.includes(": Season") + || line.includes(": Limited Series:") + || line.includes(": Part") + || line.includes(": Chapter ") + || line.includes(": Volume ") + || line.includes(": Series ") + || line.includes(": Book ")) { + writeDebug("Skipping show episode: " + line); + continue; + } + if (line.startsWith(": ")) { + writeDebug("Skipping empty title entry") + } + const [_, title, day, month, year] = viewingHistoryPattern.exec(line); + if (title && day && month && year) { + const rewatch = watched_movies.has(title); + letterboxd_output += `"${title}",${year}-${month}-${day},${rewatch}\n` + if (rewatch) { + writeDebug("Rewatch of: " + title); + } + watched_movies.add(title); + } + else { + writeError("could not parse line: " + line); + } + } + + let letterboxd_import = new Blob([letterboxd_output], { type: 'text/csv' }); + + const filename = "netflix-letterboxd-import.csv" + let download_button = a(window.URL.createObjectURL(letterboxd_import), filename) + let download_text = span("Download import file ==> ") + download_button.download = filename; + log.appendChild(div(addClass(download_text, "info"), download_button)); +} \ No newline at end of file -- cgit v1.2.3