Open extratone opened 2 years ago
Netflix Viewing Activity Updated 07212022-191040
07212022-191040
I was able to download the entirety of my Netflix user activity in JSON format ridiculously quickly thanks to a script I found from GitHub User jsejcksn as well and the (brilliant, open source) Userscripts Safari Extension.
I'm assuming there's nothing revealing so I guess I'll publish it lol.
// ==UserScript== // @name Netflix: Download activity // @version 1.0.4 // @description Download your Netflix ratings or viewing activity as a JSON-formatted file // @license MIT // @author Jesse Jackson // @match https://www.netflix.com/moviesyouveseen // @match https://www.netflix.com/MoviesYouveSeen // @match https://www.netflix.com/settings/rated/* // @match https://www.netflix.com/settings/viewed/* // @match https://www.netflix.com/viewingactivity // @namespace https://github.com/jsejcksn // @noframes // @run-at document-idle // ==/UserScript== (() => { 'use strict'; const wait = ms => new Promise(res => setTimeout(res, ms)); const saveData = (obj, fileName) => { const a = document.createElement('a'); document.body.appendChild(a); a.style = 'display: none'; const json = JSON.stringify(obj); const blob = new Blob([json], {type: 'application/json'}); const url = URL.createObjectURL(blob); a.href = url; a.download = fileName; a.click(); a.remove(); URL.revokeObjectURL(url); }; const init = async () => { const halfSecond = 500; const confirmationMessage = activity.type === activity.types.RATINGS ? 'Download ratings activity?' : 'Download viewing activity?'; // eslint-disable-next-line no-alert if (confirm(confirmationMessage)) { const button = document.querySelector('button.btn.btn-blue.btn-small'); while (!button.classList.contains('disabled')) { button.click(); await wait(halfSecond); scrollTo(0, document.body.scrollHeight); } const results = []; const items = document.querySelectorAll('.retableRow'); for (const item of items) { const data = {}; const idStartIndex = 30; data.id = item.querySelector('.col.title > a').href.slice(idStartIndex); data.title = item.querySelector('.col.title > a').textContent; data.date = item.querySelector('.col.date').textContent.split('/').map((val, i) => { const padLength = 2; if (i !== padLength) return val.padStart(padLength, '0'); return `20${val}`; }).sort((a, b) => { const targetLength = 4; if (a.length === targetLength) return -1; else if (b.length === targetLength) return 1; return 0; }).join('-'); if (activity.type === activity.types.RATINGS) { data.rating_stars = null; data.rating_thumbs = null; if (item.querySelector('.col.rating > .starbar')) { const maxStars = 5; let filled = 0; let empty = 0; const stars = item.querySelectorAll('.col.rating > .starbar > .icon-star'); for (const star of stars) { if (star.classList.contains('personal')) filled += 1; if (star.classList.contains('sb-placeholder')) empty += 1; } if (filled) data.rating_stars = filled; else if (empty === maxStars) data.rating_stars = 0; } else if (item.querySelector('.col.rating > .thumbs-component')) { const thumbs = item.querySelector('.col.rating > .thumbs-component'); if (thumbs.classList.contains('rated-up')) data.rating_thumbs = 'up'; if (thumbs.classList.contains('rated-down')) data.rating_thumbs = 'down'; } } results.push(data); } const date = new Date(); const dateFormatted = `${date.toISOString().split('.')[0].split('-').join('').split(':').join('')}Z`; let profileName = 'Unknown'; try { profileName = document.querySelector('img.activeProfile').getAttribute('alt'); } catch {} const data = { profile: profileName, results, timestamp: date.toISOString(), type: activity.type, }; saveData(data, `netflix-activity-${activity.type}-${profileName.toLowerCase()}-${dateFormatted}.json`); } }; const activity = { types: { RATINGS: 'ratings', VIEWS: 'views', }, }; const reRatings = /^\/(?:settings\/rated|moviesyouveseen).*/u; const reViews = /^\/(?:settings\/viewed|viewingactivity).*/u; if (reRatings.test(location.pathname.toLowerCase())) { activity.type = activity.types.RATINGS; } else if (reViews.test(location.pathname.toLowerCase())) { activity.type = activity.types.VIEWS; } else throw new Error(`Activity type couldn't be determined by URL`); init(); const selector = document.querySelector('.pageToggle'); selector.addEventListener('click', async () => { const halfSecond = 500; await wait(halfSecond); if (selector.querySelector('.choice.icon.rating').nodeName === 'SPAN') { activity.type = activity.types.RATINGS; init(); } else if (selector.querySelector('.choice.icon').nodeName === 'SPAN') { activity.type = activity.types.VIEWS; init(); } }); })();
<a href="https://apps.apple.com/us/app/userscripts/id1463298887?itscg=30200&itsct=apps_box_appicon" style="width: 170px; height: 170px; border-radius: 22%; overflow: hidden; display: inline-block; vertical-align: middle;"><img src="https://is2-ssl.mzstatic.com/image/thumb/Purple122/v4/0a/74/d8/0a74d831-62c4-3255-94b8-64e69558b018/AppIcon-1x_U007emarketing-0-7-0-85-220.png/540x540bb.jpg&h=80cbebde5bc2bec0f9384eeeba09e0c0" alt="Userscripts" style="width: 170px; height: 170px; border-radius: 22%; overflow: hidden; display: inline-block; vertical-align: middle;"></a>
https://user-images.githubusercontent.com/43663476/180336423-5e40803c-5f39-4c1a-bd5e-ac1ca06f83cd.MOV
Netflix Viewing Activity Updated
07212022-191040
I was able to download the entirety of my Netflix user activity in JSON format ridiculously quickly thanks to a script I found from GitHub User jsejcksn as well and the (brilliant, open source) Userscripts Safari Extension.
I'm assuming there's nothing revealing so I guess I'll publish it lol.
Script
Userscripts for Safari
Another Embed...