Skip to content

Instantly share code, notes, and snippets.

@techarch
Last active May 5, 2024 16:09
Show Gist options
  • Save techarch/2d5a26c6bb235c6467dc to your computer and use it in GitHub Desktop.
Save techarch/2d5a26c6bb235c6467dc to your computer and use it in GitHub Desktop.
/* mff.bookmarklet
version 0.0.6
*/
// Lazy initialize our namespace context: mff.bookmarklet
if (typeof(mff) == 'undefined') mff = { };
if (typeof(mff.cookie) == 'undefined') mff.cookie = { };
Base64 = {_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}
mff.cookie.getAllCookies = function() {
var all = {};
var cookies = document.cookie ? document.cookie.split('; ') : [];
for (var i = 0, l = cookies.length; i < l; i++) {
var parts = cookies[i].split('=');
var name = decodeURIComponent(parts.shift());
var cookie = parts.join('=');
all[name] = mff.cookie.parseCookieValue(cookie);
}
return all;
}
mff.cookie.getCookie = function(key) {
var result = key ? undefined : {};
var cookies = document.cookie ? document.cookie.split('; ') : [];
for (var i = 0, l = cookies.length; i < l; i++) {
var parts = cookies[i].split('=');
var name = decodeURIComponent(parts.shift());
var cookie = parts.join('=');
if (key && key === name) {
result = mff.cookie.parseCookieValue(cookie);
break;
}
}
return result;
}
mff.cookie.parseCookieValue = function(s) {
var pluses = /\+/g;
if (s.indexOf('"') === 0) {
// This is a quoted cookie as according to RFC2068, unescape...
s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
}
try {
// Replace server-side written pluses with spaces.
// If we can't decode the cookie, ignore it, it's unusable.
// If we can't parse the cookie, ignore it, it's unusable.
s = decodeURIComponent(s.replace(pluses, ' '));
return s;
} catch(e) {}
}
mff.cookie.setCookie = function(key, value, options) {
options = options || {};
if (typeof options.expires === 'number') {
var days = options.expires, t = options.expires = new Date();
t.setTime(+t + days * 864e+5);
}
return (document.cookie = [
encodeURIComponent(key), '=', encodeURIComponent(value),
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
options.path ? '; path=' + options.path : '',
options.domain ? '; domain=' + options.domain : '',
options.secure ? '; secure' : ''
].join(''));
}
mff.cookie.stringifyCookieValue = function(value) {
return encodeURIComponent(String(value));
}
/* ------------ */
if (typeof(mff.bookmarklet) == 'undefined') mff.bookmarklet = { };
if (typeof(console) != 'undefined' && console) console.info("mff.bookmarklet loading ...");
mff.bookmarklet.createControlPanel = function () {
var panel = $( '<div id="mff-netflix-control-panel">' +
'<header>MyFavFilms</header>' +
'<section>' +
'<div id="mff-initial-setup">' +
'<a id="mff-fetch-all" href="#">Fetch All</a><br/>' +
'<a id="mff-export-all" href="#">Export All</a>' +
'</div><br/>' +
'<div id="mff-ongoing-exports">' +
'<a id="mff-fetch-recent" href="#">Fetch Recent</a><br/>' +
'<a id="mff-export-recent" href="#">Export Recent</a>' +
'</div>' +
'</section>' +
'</div>');
$('body').append(panel);
$('#mff-fetch-all').on('click', mff.bookmarklet.fetchAll);
$('#mff-export-all').on('click', mff.bookmarklet.exportAll);
$('#mff-fetch-recent').on('click', mff.bookmarklet.fetchRecent);
$('#mff-export-recent-all').on('click', mff.bookmarklet.exportRecent);
}
mff.bookmarklet.exportItem = function (li) {
var filmActivity = mff.bookmarklet.extractItem($(li));
if (filmActivity == null)
return null;
console.debug('Manage NetFlix Activity List - exportItem ' + filmActivity.movieId + ' : ' + filmActivity.title);
return filmActivity;
}
mff.bookmarklet.exportItems = function (lis) {
var liCount = lis.length;
console.debug('Manage NetFlix Activity List - exportItems ' + liCount + ' - begin');
var activity = mff.bookmarklet.extractItems(lis);
console.debug('Manage NetFlix Activity List - exportItems ' + liCount + ' - extract done');
mff.bookmarklet.sendExports(activity);
console.debug('Manage NetFlix Activity List - exportItems ' + liCount + ' - end');
return activity;
}
mff.bookmarklet.exportAll = function (event) {
console.debug('Manage NetFlix Activity List - exportAll');
var lis = $('#viewingactivity ul li');
mff.bookmarklet.exportItems(lis);
}
mff.bookmarklet.exportRecent = function (event) {
console.debug('Manage NetFlix Activity List - exportRecent');
}
mff.bookmarklet.extractItem = function (li) {
if (li.length == 0)
return null;
var filmActivity = {};
try {
var anchor = li.find('a');
filmActivity.date = li.find('div.date').text() || '';
filmActivity.movieId = li.attr('data-movieid') || '';
filmActivity.title = anchor.text() || '';
filmActivity.ref = anchor.attr('href') || '';
} catch (ex) {
console.error('mff.bookmarklet.extract failed due to: ' + ex);
return null;
}
return filmActivity;
}
mff.bookmarklet.extractItems = function (lis) {
var liCount = lis.length;
console.debug('Manage NetFlix Activity List - extractItems ' + liCount + ' - begin');
var activity = [];
for (var i = 0; i < liCount; i++) {
var li = lis[i];
var filmActivity = mff.bookmarklet.extractItem($(li));
if (filmActivity != null)
activity.push(filmActivity);
};
console.debug('Manage NetFlix Activity List - extractItems ' + liCount + ' - end');
return activity;
}
mff.bookmarklet.fetchAll = function (event) {
console.debug('Manage NetFlix Activity List - fetchAll');
var filmCount = $('#viewingactivity ul li').length;
$('#mff-netflix-control-panel').data('filmsCount', filmCount);
setTimeout('window.scrollTo(0,0);',10)
setTimeout(mff.bookmarklet.fetchMore(),1000);
}
mff.bookmarklet.fetchRecent = function (event) {
console.debug('Manage NetFlix Activity List - fetchRecent');
}
mff.bookmarklet.fetchMore = function (event) {
console.debug('Manage NetFlix Activity List - fetchMore');
setTimeout("window.scrollBy(0,10 * window.innerHeight);",10);
var footer = $('.footer-mount')[0];
//footer.scrollIntoView();
setTimeout(function() {
var filmCount = $('#viewingactivity ul li').length;
var previousFilmCount = $('#mff-netflix-control-panel').data('filmsCount');
console.debug('Manage NetFlix Activity List - fetchMore: current=' + filmCount + ' old=' + previousFilmCount);
if (filmCount > previousFilmCount) {
$('#mff-netflix-control-panel').data('filmsCount', filmCount);
console.debug('Manage NetFlix Activity List - fetchMore: still need more ...');
mff.bookmarklet.fetchMore();
} else {
console.debug('Manage NetFlix Activity List - fetchMore: all done => ' + filmCount + ' films');
}
}, 1000);
}
mff.bookmarklet.log = function (message, level) {
if (!$.browser.msie) { // $.browser.mozilla || $.browser.webkit
switch (level) {
case "debug":
try { console.debug(message); } catch (ex) { var a = 1; }
break;
case "error":
try { console.error(message); } catch (ex) { var a = 1; }
break;
case "info":
try { console.info(message); } catch (ex) { var a = 1; }
break;
default:
try { console.debug(message); } catch (ex) { var a = 1; }
break;
}
return;
}
if ($.browser.msie || $.browser.webkit) {
try { console.log(message); } catch (ex) { var a = 1; }
}
}
mff.bookmarklet.login = function() {
mff.bookmarklet.log("mff.bookmarklet.login");
var host = 'localhost:3000';
var username = 'pfmonnet';
var password = '1234';
var authorizationToken = username + ':' + password;
var basicAuthorizationToken = Base64.encode(authorizationToken);
var basicAuthorizationHeaderValue = "Basic " + basicAuthorizationToken;
var url = 'http://' + username + '@' + host + '/api/user/' + username + '/login';
$.ajaxSetup({ cache: false });
$.ajax({
// Send
url: url,
type: 'POST',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
crossDomain: true,
headers: {"Authorization": basicAuthorizationHeaderValue},
// Receive
dataType: 'json',
//timeout: 10000,
error: mff.bookmarklet.loginHandleError,
success: mff.bookmarklet.loginHandleSuccess
});
}
mff.bookmarklet.loginHandleSuccess = function(loginResult) {
var account = loginResult.account;
mff.bookmarklet.log('Manage NetFlix Activity List - login success: ' + account);
}
mff.bookmarklet.loginHandleError = function(jqXHR, textStatus, errorThrown) {
var errorMsg = jqXHR.status + ' ' + textStatus + ' '
+ this.url + ' '
+ jqXHR.statusText + ' '
+ jqXHR.responseText;
mff.bookmarklet.log('Manage NetFlix Activity List - login failure: ' + errorMsg, 'error');
}
mff.bookmarklet.sendExports = function(exportedItems) {
mff.bookmarklet.log("mff.bookmarklet.sendExports");
var username = 'pfmonnet';
var password = '1234';
var authorizationToken = username + ':' + password;
var basicAuthorizationToken = Base64.encode(authorizationToken);
var basicAuthorizationHeaderValue = "Basic " + basicAuthorizationToken;
var activity = {username: username, exportedItems: exportedItems};
var activityJSON = ko.mapping.toJSON(activity);
var url = 'http://' + username + '@' + host
+ '/api/user/'
+ username + '/import';
$.ajaxSetup({ cache: false });
$.ajax({
// Send
url: url,
type: 'POST',
contentType: 'application/json',
crossDomain: true,
headers: {"Authorization": basicAuthorizationHeaderValue},
data: activityJSON,
// Receive
dataType: 'json',
//timeout: 10000,
error: mff.bookmarklet.sendExportsHandleError,
success: mff.bookmarklet.sendExportsHandleSuccess
});
}
mff.bookmarklet.sendExportsHandleSuccess = function(changeSet) {
mff.bookmarklet.log("mff.bookmarklet.sendExportsHandleSuccess");
mff.bookmarklet.log("mff.bookmarklet.sendExportsHandleSuccess done");
}
mff.bookmarklet.sendExportsHandleError = function(jqXHR, textStatus, errorThrown) {
mff.bookmarklet.log("mff.bookmarklet.sendExportsHandleError " + jqXHR.status + " " + jqXHR.statusText);
var errorMsg = jqXHR.status + ' ' + textStatus + ' '
+ this.url + ' '
+ jqXHR.statusText + ' '
+ jqXHR.responseText;
}
mff.bookmarklet.wireup = function (jQuery) {
$ = jQuery;
console.debug('Manage NetFlix Activity List - wiring up ...');
mff.bookmarklet.createControlPanel();
console.debug('Manage NetFlix Activity List - wired up!');
}
if (typeof(console) != 'undefined' && console) console.info("Manage NetFlix Activity List - loading ...");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment