7

I would like to ask if it is possible to build Chrome or Greasemonkey script witch could open all popups in queue. So far i have 2 seperate scripts for this, but that is not working well since popups have anti-spam feature that don't allow too much of them at the same time.

What i would like to do is to process array of popup links in queue fashion and only open next when previous is closed. I have no expirience when it goes down to queues and any kind of event binding.

So resources i got:

1) Array of links already prepared

var URL_Array = [];

$('form[name="form_gallery"] .img img').each(function(i,e){
    // Format URL array here
    if($(this).closest('.object').children('.phs_voted_count').length == 0){
        var string = e.src;
        var nowBrake = string.substring(string.length-7,7);
        var splited = nowBrake.split('/');
        var urlStr = '/window/friend/gallery_view/'+splited[3]+'/'+splited[4]+'.html';
        URL_Array[i] = urlStr;
    }
});

2) Script that votes on image in popup

    /*######################################################*/  
    var voteBy            = '#vte_mark_12';            // Prefered vote icon
    var voteDefault       = '#vte_mark_5';             // Default vote icon
    var voteFormLoc       = 'image_voting';            // Image voting popups form
    var buyExtraVote      = 'image_voting_buy';        // If run out of votes buy more
    var captchaLoc        = 'input[name="captcha"]';   // Captcha input field
    var captchaTxt        = 'Enter captcha text!';     // Captcha alert text
    var simpatyFormId     = '#sym_send';               // Simpaty window form

    var startScript          = true; 
    var formProcessedAlready = false; // Used to check if image already was voted
    /*######################################################*/  

$(function(){
    if(startScript){
        if($(captchaLoc).length > 0){
            alert(captchaTxt);
            $(captchaLoc).focus().css('border', '2px solid red');
            return false;
        }else{
            if($('#50').length > 0){
                $('#50').attr('checked', true);
                $('form').attr('id', buyExtraVote);
                $('#'+buyExtraVote).submit();
            }else{
                $('form').attr('id', voteFormLoc);
                if($(voteBy).length > 0){
                    $(voteBy).attr('checked', true);
                    setTimeout("$('#"+voteFormLoc+"').submit()", 2000);
                }else if($(voteDefault).length > 0){
                    $(voteDefault).attr('checked', true);
                    setTimeout("$('#"+voteFormLoc+"').submit()", 2000);
                }else{
                    // If we have simpaty box autocast submit
                    if($(simpatyFormId).length > 0){
                        if($(captchaLoc).length > 0){
                            alert(captchaTxt);
                            $(captchaLoc).focus().css('border', '2px solid red');
                            return false;
                        }else{
                            $(simpatyFormId).submit();
                            formProcessedAlready = true;
                        }
                    }else{
                        formProcessedAlready = true;
                    }
                }
            }
        }

        if(formProcessedAlready){
            self.close();
        }
    }
});

As far as i can understand it should go like this:
1) Get all unvoted urls and form array (done)
2) Queue all popups to open
3) Start first popup
4) Voting done and popup closes (done)
5) Start second popup
6) When array finished switch to next page (done)

What you think?

arma
  • 4,084
  • 10
  • 48
  • 63
  • 1
    I better done it one popup, so any antivirus program willn't block it. Start first popup -> Voting done and popup refreshes with new form -> ... – Arthur Halma Apr 26 '11 at 12:15
  • I'm up for any solution one or new each time. I'll be only person who will be using this so i don't worry about any blocking. – arma Apr 26 '11 at 21:29

2 Answers2

2

You could do something like:

var links = get_your_links();
function process_one() {
    if(links.length > 0) {
        show_popup(links.pop(), process_one);
    }
}
function show_popup(link, callback) {
   var popup = window.open(link, "mywindow", "width=100,height=100");
   $(popup).bind("beforeunload", function() { 
     process_one();
     return true;
   })

}

I hope it helps...

iwiznia
  • 1,669
  • 14
  • 21
  • everything looks good and i got it working for first popup, but other popups don't process. That probably because `$(window).bind` as it binds current window that is not popup but main page. i need to hit refresh for other to be processed. How do you bind it like `$(popup).bind` ? – arma Apr 26 '11 at 22:13
  • Still executes just the first time page loads. Looks like it's loosing popup and can't catch any events from it. I have `// @match` for both mainpage and popup address in script. – arma Apr 27 '11 at 22:20
  • mmmm, so the beforeunload is not firing? Can you debug it usign firebug? – iwiznia Apr 28 '11 at 09:36
  • Just get a variable saying if process_one() has already been done and add the event on onunload too and in the function, check if the variable is true or not and if it is, just don't do anything. – xavierm02 Apr 28 '11 at 17:58
  • @iwiznia i use chrome dev toolbar and i get nothing in console. If i would go to FireFox i would need to adapt code to greasemonkey. – arma Apr 28 '11 at 21:20
2
  • What are the exact URL's of the main page(s) and also of the popups?
  • What version of jQuery are you using, and how are you including it?

The exact URLs are important because the script needs to handle both the main pages and the popups and operate differently on each.

Their are 2 main ways to handle this. Either:

  1. Use include directives to make sure that the script runs on both the main page and the popup, but switches its behavior depending on the page type. This will have two different instances of the script running simultaneously, which is not a problem.

  2. Use include and possibly exclude directives to ensure that the script only runs on the main page. Then have the popup-opening code manipulate the form.


Here's how to do approach 1:

(1) Suppose the main pages were like:
    somewhere.com/main/*
    and the popup pages were like:
    somewhere.com/window/friend/gallery_view/*
    Make sure the script's include-directives fire on both sets of pages.

(2) Ensure that jQuery is available on both kinds of pages. jQuery 1.5.1 is recommended. jQuery 1.3.2 probably won't work for the following code.

(3) Then code like the following should work:

var URL_Array   = [];
var PopupQueue  = $({});    //-- jQuery on an empty object - a perfect queue holder

//--- Is this a popup window or the main page?

if ( /\/window\/friend\/gallery_view\//i.test (window.location.href) )
{
    //--- This is a popup page

    /*######################################################*/  
    var voteBy            = '#vte_mark_12';            // Prefered vote icon
    var voteDefault       = '#vte_mark_5';             // Default vote icon
    var voteFormLoc       = 'image_voting';            // Image voting popups form
    var buyExtraVote      = 'image_voting_buy';        // If run out of votes buy more
    var captchaLoc        = 'input[name="captcha"]';   // Captcha input field
    var captchaTxt        = 'Enter captcha text!';     // Captcha alert text
    var simpatyFormId     = '#sym_send';               // Simpaty window form

    var startScript          = true; 
    var formProcessedAlready = false; // Used to check if image already was voted
    /*######################################################*/  

    $(function(){
        if(startScript){
            if($(captchaLoc).length > 0){
                alert(captchaTxt);
                $(captchaLoc).focus().css('border', '2px solid red');
                return false;
            }else{
                if($('#50').length > 0){
                    $('#50').attr('checked', true);
                    $('form').attr('id', buyExtraVote);
                    $('#'+buyExtraVote).submit();
                }else{
                    $('form').attr('id', voteFormLoc);
                    if($(voteBy).length > 0){
                        $(voteBy).attr('checked', true);
                        setTimeout("$('#"+voteFormLoc+"').submit()", 2000);
                    }else if($(voteDefault).length > 0){
                        $(voteDefault).attr('checked', true);
                        setTimeout("$('#"+voteFormLoc+"').submit()", 2000);
                    }else{
                        // If we have simpaty box autocast submit
                        if($(simpatyFormId).length > 0){
                            if($(captchaLoc).length > 0){
                                alert(captchaTxt);
                                $(captchaLoc).focus().css('border', '2px solid red');
                                return false;
                            }else{
                                $(simpatyFormId).submit();
                                formProcessedAlready = true;
                            }
                        }else{
                            formProcessedAlready = true;
                        }
                    }
                }
            }

            if(formProcessedAlready){
                self.close();
            }
        }
    });
}
else
{   //--- This is a main page

    $('form[name="form_gallery"] .img img').each(function(i,e){
        // Format URL array here
        if($(this).closest('.object').children('.phs_voted_count').length == 0){
            var string = e.src;
            var nowBrake = string.substring(string.length-7,7);
            var splited = nowBrake.split('/');
            var urlStr = '/window/friend/gallery_view/'+splited[3]+'/'+splited[4]+'.html';
            URL_Array[i] = urlStr;
        }
    });

    //--- Load up the queue.
    $.each (URL_Array, function (PopupNum, PopupURL) {

        PopupQueue.queue ('Popups', function (NextQ_Item) {

            OpenPopupFromQueue (NextQ_Item, PopupNum+1, PopupURL);
        } );
    } );

    //--- Launch the Popups, one at a time.
    PopupQueue.dequeue ('Popups');
}


function OpenPopupFromQueue (NextQ_Item, PopupNum, PopupURL)
{
    var PopupWin    = window.open (PopupURL, "_blank");
    if (!PopupWin)
    {
        console.log ('Bad URL ' + PopupURL)
        setTimeout (function() { NextQ_Item (); }, 2003);
        return;
    }

    /*--- Only after the popup has loaded can we do any processing.
    */
    PopupWin.addEventListener (
        "load",
        function () {
            /*--- Setup the listener for when the popup has closed.
                We fire the next popup from the queue, there.
            */
            PopupWin.addEventListener (
                "unload",
                function () {
                    PopupClosed (NextQ_Item);
                },
                false
            );

            /*--- We could process the popup here, but it's better to let another instance of this
                script do it, instead.
            */
        },
        false
    );
}


function PopupClosed (NextQ_Item)
{
    //--- Launch the next popup from the queue.
    NextQ_Item ();
}
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • Ah, Brock hello. Yes your script was looking good but in chrome i simply get `Uncaught TypeError: Cannot call method 'addEventListener' of undefined`. And i use 1.5.2 version now and i have it pasted in my script. Main pages url: `http://friends.example.com/friend/28r6afk4bf/gallery/3044094.html` and i match it with `http://friends.example.com/friend/*/gallery/*`and popup is: `http://friends.example.com/window/friend/gallery_view/28r6afk4bf/a4w01kb3i0bg.html` also i match that with `http://friends.boomtime.lv/window/friend/*` – arma May 02 '11 at 12:31
  • Ok, I tweaked the code. It shouldn't error out on bad URLs now. The script was looking good but then errored? Does that mean it worked in Firefox? Or, it worked for a few popups and then errored?   My tests work, I can't debug further without knowing the real target page. – Brock Adams May 02 '11 at 12:54
  • Now it does 1 popup and spits into console `Bad URL /window/friend/gallery_view/28r6afk4bf/cxa4w065bnz1bg.html`. What you mean by target page? – arma May 02 '11 at 13:50
  • By target page, I mean one of the exact pages, on a real server, that the script runs on. ... ... That error means that `/window/friend/gallery_view/28r6afk4bf/cxa4w065bnz1bg.html` is not a valid page. This could be happening because the main page (AKA the target page) is on one domain but the popup page needs to be on another. Carefully examine that `URL_Array` that is generated. You may need to explicitly add the correct `http://friends.example.com/` (or whatever) to each URL string. – Brock Adams May 02 '11 at 15:29
  • Bad URL `http://friends.boomtime.lv/window/friend/gallery_view/cbh5bxbybf/cxd3582a3ukbn.html` here is the full popup url. Still 1 pops and then stops with bad url. Maybe it's not possible to do this with javascript userscripts? domains are the same. – arma May 02 '11 at 16:15
  • It is possible; I've tested it from FF GM anyway (and there's no obvious reason why Chrome should be different in this case). Anyway, I've tweaked the code to continue after a failure. ... ... You say "Still 1 pops and then stops with bad url". Does 1 popup open, then close, and then the bad url? is the bad url the same as the open popup? ... ... Finally, look at the URL in your last comment. It **appears** to end in ".html", but if you look at the actual code, it's ".-html". Was that just a paste error? – Brock Adams May 02 '11 at 17:46
  • 1) When popup opens - it does perform all required actions (putting vote on desired field and submits it after 2000ms and at the same time throws that BadUrl console record. 2) The `-.html` must be paste error or something because i don't have that nowhere in my code. 3) Your last updated code opens all popups at once (20 of them) and processes them as desired, but gets me anti-spam ban since too fast voting. – arma May 02 '11 at 21:11
  • Something about the site or your actual setup is busting the functionality of `window.open()`. It's not setting the return value. My local test site works fine. ... ... Anyway, I've added a 2-second delay, on failure, to the modified code above. If the "anti-spam ban" still kicks in, increase the delay. For stealth reasons, I recommend using a prime number and a minimum of 1 second. – Brock Adams May 02 '11 at 23:06
  • Well i guess thats closest i can get to automation of this. Not fail-proof, but will do. Will just add page switching and it will be ok. Thanks for all your effort. – arma May 02 '11 at 23:12
  • Well I'm glad it finally worked for you. We were approaching the limit of the debugging I could do without access to the pages you're using. – Brock Adams May 02 '11 at 23:54
  • Yeah, i understand thats no cake for you. I managed to remove cookie that watches for captcha timers and with timeout on 3003ms i can leave this now automated :) – arma May 03 '11 at 00:04