Help for newbie getting a script to run

132 views
Skip to first unread message

John Giguere

unread,
May 18, 2013, 2:51:08 PM5/18/13
to greasemon...@googlegroups.com
I'm trying to update the script that was originally on the link below. The script (also included below) will grab your netflix ratings, but I'm getting some errors and am new at this. Would appreciate if someone can help out a newbie as I'm getting this error:

Exception: GM_registerMenuCommand is not defined
@Scratchpad/7:20
Exception: GM_registerMenuCommand is not defined@Scratchpad/8:20

I also have the Firefox error console up and the first line which should print out "Hello World" is not even happening???

/*
Exception: GM_registerMenuCommand is not defined
@Scratchpad/8:20
*/
Exception: GM_registerMenuCommand is not defined
@Scratchpad/7:20

http://web.arantius.com/getflix-revamped

----------------------------------------------------------------------------------------------------------------------
// ==UserScript==
// @name           GetFlix Grabber2
// @namespace      file:///C:
// @description    Grab all the data about your NetFlix ratings
// @grant          GM_registerMenuCommand
// @grant          GM_xmlhttpRequest
// @include        http://www.netflix.com/*
// @include        http://dvd.netflix.com/*
// ==/UserScript==

console.log("Hello World");
console.error("Hello World");

////////////////////////////////////////////////////////////////////////////////

var myBaseUrl='file:///C:/Netflix/';

////////////////////////////////////////////////////////////////////////////////

GM_registerMenuCommand('Start GetFlix', startGetFlix);
GM_registerMenuCommand('Stop GetFlix', stopGetFlix);

var button1=document.createElement('button');
button1.setAttribute('style', 'margin: 0.5em 1em; vertical-align: middle;');
button1.appendChild(document.createTextNode('Start'));
button1.addEventListener('click', startGetFlix, true);

var button2=document.createElement('button');
button2.setAttribute('style', 'margin: 0.5em 1em; vertical-align: middle;');
button2.appendChild(document.createTextNode('Stop'));
button2.addEventListener('click', stopGetFlix, true);

var menu=document.createElement('div');
menu.setAttribute('style', 'text-align: center; border: 10px solid #B9090B;');
menu.appendChild(document.createTextNode('GetFlix:'));
menu.appendChild(button1);
menu.appendChild(button2);
document.body.appendChild(menu);

////////////////////////////////////////////////////////////////////////////////

function startGetFlix() {
    // init a single-task queue
    actionQueue=[ ['getRatingsPage', 1] ];
    // and start the queue running!
    runQueue();
}

function stopGetFlix() {
    // stop the queue runner
    clearTimeout(actionTimer);
    actionTimer=null;
    // and empty out the queue
    actionQueue=[];
}

////////////////////////////////////////////////////////////////////////////////

var niceness=50;
var nicefact=0.33;
function getNice() {
    var min=niceness-(niceness*nicefact);
    var max=niceness+(niceness*nicefact);
   
    // Peek at first action to slow down remote fetches.
    var fac=1;
    if (actionQueue && actionQueue[0]) {
        if ('get'==actionQueue[0][0].substr(0, 3)) fac=75;
    }

    return ( (Math.random()*(max-min)*fac) + min );
}

////////////////////////////////////////////////////////////////////////////////

var actionTimer=null;
var actionQueue=[];
function runQueue() {
    actionTimer=setTimeout(runQueue, getNice());

    var action=actionQueue.shift();
    if (!action) return;

    console.log(
        'Queue length: '+actionQueue.length+'.  Running action '+action[0]+'.'
    );

    switch (action[0]) {
    case 'getRatingsPage':
        getRatingsPage(action[1]);
        break;
    case 'parseRatings':
        parseRatingsPage(action[1], action[2]);
        break;
    case 'saveRating':
        saveRating(action[1]);
        break;
    case 'checkMovieDetail':
        checkMovieDetail(action[1]);
        break;
    case 'getMovieDetails':
        getMovieDetails(action[1]);
        break;
    case 'parseMovieDetails':
        parseMovieDetails(action[1], action[2]);
        break;
    case 'saveMovieDetails':
        saveMovieDetails(action[1]);
        break;
    }
}

////////////////////////////////////////////////////////////////////////////////

function getRatingsPage(pagenum) {
    var url='http://dvd.netflix.com/MoviesYouveSeen?'+
        'pageNum='+parseInt(pagenum, 10);
    console.info('Fetch:', url);
    GM_xmlhttpRequest({
        'method':'GET',
        'url':url,
        'onload':function(xhr) {
            actionQueue.push(['parseRatings', pagenum, xhr.responseText]);
        }
    });
}

function getMovieDetails(id) {
    var url='http://dvd.netflix.com/Movie/'+id;
    console.info('Fetch:', url);
    GM_xmlhttpRequest({
        'method':'GET',
        'url':url,
        'onload':function(xhr) {
            actionQueue.push(['parseMovieDetails', id, xhr.responseText]);
        }
    });
}

////////////////////////////////////////////////////////////////////////////////

function parseRatingsPage(num, text) {
    var ratings=text.split('addlk');
    ratings.shift(); // get rid of the HTML before the first one

    for (var i=0, rating=null; rating=ratings[i]; i++) {
        try {
            var detail={
                'id':rating.match(/\/([0-9]+)\?trkid/)[1],
                'title':rating.match(/"list-title"><a.*?>(.*?)</)[1],
                'year':rating.match(/"list-titleyear"> \(([0-9]+)\)/)[1],
                'mpaa':rating.match(/"list-mpaa">(.+?)</)[1],
                'genre':rating.match(/"list-genre">(.+?)</)[1],
                'rating':rating.match(/stars_[0-9]_([0-9]+)\.gif/)[1]/10
            };

            actionQueue.push(['saveRating', detail]);
        } catch (e) {
            console.debug('Couldn\'t parse ratings item '+i+' because:');
            console.error(e);
            console.log(rating);
            stopGetFlix();
        }
    }

    if (text.match(/paginationLink-next/)) {
        actionQueue.push(['getRatingsPage', num+1]);
    }
}

function parseMovieDetails(id, text) {
    var detail={
        'id':id
    };

    try {
        detail.globalRating=text.match(/ratings:.*?"value">([.0-9]+)</)[1];

        //var director=text.match(/id="director".*?<a.*id=([0-9]+).*?>(.*?)</);
        var director=text.match(/id="director".*?<a.*href=".*?([0-9]+)".*?>(.*?)</);
        if (director && director[1] && director[2]) {
            detail.directorID=director[1];
            detail.directorName=director[2];
        } else {
            console.debug('No director for movie '+id);
        }
    } catch (e) {
        console.debug('Couldn\'t parse a director detail for movie '+id+' because:');
        console.error(e);
        stopGetFlix();
    }

    try {
        var actors=text.replace(/\n|\r/g, '')
            .match(/id="cast".*?div class="section"/);
        if (actors && actors[0]) {
            actors=actors[0].split('<a');
            actors.shift(); // remove the stuff before the first actor

            for (var i=0, actor=null; actor=actors[i]; i++) {
                var m=actor.match(/href=".*?([0-9]+)">(.*?)</);
                detail['actorID['+i+']']=m[1];
                detail['actorName['+i+']']=m[2];
            }
        } else {
            console.debug('No actors for movie '+id);
        }
    } catch (e) {
        console.debug('Couldn\'t parse an actor detail for movie '+id+' because:');
        console.error(e);
        console.log(actor);
        stopGetFlix();
    }

    actionQueue.push(['saveMovieDetails', detail]);
}

////////////////////////////////////////////////////////////////////////////////

function saveRating(detail) {
    var url=myBaseUrl+'backend.php?do=rating';
    var data='';
    for (key in detail) {
        data+=key+'='+escape(detail[key])+'&';
    }
    data=data.replace(/&$/, '');

    GM_xmlhttpRequest({
        'method':'POST',
        'url':url,
        'headers':{'Content-type':'application/x-www-form-urlencoded'},
        'data':data
    });

    actionQueue.push(['checkMovieDetail', detail.id]);
}

function checkMovieDetail(id) {
    var url=myBaseUrl+'backend.php?do=check';
    var data='id='+id;

    GM_xmlhttpRequest({
        'method':'POST',
        'url':url,
        'headers':{'Content-type':'application/x-www-form-urlencoded'},
        'data':data,
        'onload':function(xhr) {
            var data=xhr.responseText.split('|');
            if (0==data[1]) {
                actionQueue.push(['getMovieDetails', data[0]]);
            }
        }
    });
}

function saveMovieDetails(detail) {
    var url=myBaseUrl+'backend.php?do=detail';
    var data='';
    for (key in detail) {
        data+=key+'='+escape(detail[key])+'&';
    }
    data=data.replace(/&$/, '');

    GM_xmlhttpRequest({
        'method':'POST',
        'url':url,
        'headers':{'Content-type':'application/x-www-form-urlencoded'},
        'data':data
    });
}

///////////////////////////////////////////////

Zulkarnain K.

unread,
May 19, 2013, 4:12:18 AM5/19/13
to Greasemonkey Users
On Sun, May 19, 2013 at 1:51 AM, John Giguere <jgig...@gmail.com> wrote:
> I'm trying to update the script that was originally on the link below. The
> script (also included below) will grab your netflix ratings, but I'm getting
> some errors and am new at this. Would appreciate if someone can help out a
> newbie as I'm getting this error:
>
> Exception: GM_registerMenuCommand is not defined
> @Scratchpad/7:20
>
> Exception: GM_registerMenuCommand is not defined@Scratchpad/8:20
>
> I also have the Firefox error console up and the first line which should
> print out "Hello World" is not even happening???
>
>
> /*
> Exception: GM_registerMenuCommand is not defined
> @Scratchpad/8:20
> */
>
> Exception: GM_registerMenuCommand is not defined
> @Scratchpad/7:20
>
>

You can edit userscript with Scratchpad but you can't execute it from
Scratchpad.
To run the userscript, go to the web site specified in @include rule.

--
Zulkarnain K.
https://mozillians.org/u/zoolcar9
https://userscripts.org/users/12

John Giguere

unread,
May 20, 2013, 11:53:03 AM5/20/13
to greasemon...@googlegroups.com
I've got the basic script running now and it's going out to get the first page of my ratings.

I'm logged into my Netflix account and can see my ratings, but if I run the script when it gets the page Netflix is giving it the Netflix login page (even though I'm logged in). I looked at the page source before running the script and it is my ratings page, then if I look at page source after the script requests the page it is actually showing me the login page (just like what it's giving the script) even though my ratings are still showing in the browser. Plus if I disable the script and refresh the page my ratings are still there, it didn't ask me to relogin and now the page source is correct again.

Quite tricky to say the least on Netflix's part, so I'm looking for someone that can tell me what the heck Netflix is doing and if there is a way around it.

John Giguere

unread,
May 20, 2013, 1:42:22 PM5/20/13
to greasemon...@googlegroups.com
Actually I thought about it a bit more and I figure that when my browser makes a request to Netflix (and logs in) it gets some kind of session id, but when the script trys to change to the ratings page Netflix sees its a different session id and it sends the login page to the script. Makes sense, so I think there would be 2 ways to go.

1. If there is a way to get the Firefox browser session ID, and then edit the javascript ID that gets send with it's page requests, so it is effectively spoofing the browser's ID. I'm guessing due to all the security holes that something like this could create that it's not possible, but if anyone knows for sure let me know.

2. The 2nd approach would be to create a new function in the script that actually logs into your Netflix account. This assumes that Netflix would allow this, or maybe they have no choice. Seems like the better option, so if anyone knows this will work let me know.
Reply all
Reply to author
Forward
0 new messages