CH Plaintext HIT Export

Export HIT information in multi-line plain text format.

Versione datata 03/06/2015. Vedi la nuova versione l'ultima versione.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name          CH Plaintext HIT Export
// @description   Export HIT information in multi-line plain text format.
// @version       1.6c
// @include       https://www.mturk.com/mturk/findhits*
// @include       https://www.mturk.com/mturk/viewhits*
// @include       https://www.mturk.com/mturk/sorthits*
// @include       https://www.mturk.com/mturk/searchbar*selectedSearchType=hitgroups*
// @include       https://www.mturk.com/mturk/viewsearchbar*selectedSearchType=hitgroups*
// @include       https://www.mturk.com/mturk/sortsearchbar*HITGroup*
// @include       https://www.mturk.com/mturk/preview*
// @grant         GM_setClipboard
// @author        Cristo + clickhappier
// @namespace     mturkgrind
// ==/UserScript==


// based on 'IRC Export (reformatted output mod)': https://greasyfork.org/en/scripts/6254-irc-export-reformatted-output-mod


var caps = document.getElementsByClassName('capsulelink');
for (var c = 0; c < caps.length/2; c++){
    button = document.createElement('button');
    button.setAttribute("place",c);
    button.textContent = 'TXT';
    button.style.height = '14px';
    button.style.width = '30px';
    button.style.fontSize = '8px';
    button.style.border = '1px solid';
    button.style.padding = '0px';
    button.style.backgroundColor = 'transparent';
    button.title = 'Click to save Hit information to your clipboard';
    button.addEventListener("click", display, false);
    document.getElementById('capsule'+c+'-0').parentNode.appendChild(button);
}

function getTO(f){
    var toComp = [];
    var toUrl = 'https://mturk-api.istrack.in/multi-attrs.php?ids='+f;
    var toUrl2 = 'https://turkopticon.ucsd.edu/api/multi-attrs.php?ids='+f;
    requestTO = new XMLHttpRequest();
    try{   // first try Miku's TO mirror server (istrack.in)
        requestTO.onreadystatechange = function () {
            if ((requestTO.readyState ===4) && (requestTO.status ===200)) {
                if (requestTO.responseText.split(':').length > 2) {
                    var toInfo = requestTO.responseText.split('{')[3].split('}')[0].split(',');
                    for (var t = 0; t < 4; t++) {
                        var arrTo = toInfo[t].split(':');
                        toComp.push(arrTo[1].substring(1,4));
                    }
                } 
                else { toComp = ['-','-','-','-']; }
            }
        };
        requestTO.open('GET', toUrl, false);
        requestTO.send(null);
        return toComp;
    }
    catch(err){   // if mirror unavailable, try main TO server
        try{
            requestTO.onreadystatechange = function () {
                if ((requestTO.readyState ===4) && (requestTO.status ===200)) {
                    if (requestTO.responseText.split(':').length > 2) {
                        var toInfo = requestTO.responseText.split('{')[3].split('}')[0].split(',');
                        for (var t = 0; t < 4; t++) {
                            var arrTo = toInfo[t].split(':');
                            toComp.push(arrTo[1].substring(1,4));
                        }
                    } 
                    else { toComp = ['-','-','-','-']; }
                }
            };
            requestTO.open('GET', toUrl2, false);
            requestTO.send(null);
            return toComp;
        }
        catch(err){   // if both unavailable, return 'na's
            toComp = ['na','na','na','na'];
            return toComp;
        }
    }
}

// output display box
var txtexportdiv = document.createElement('div');
var txtexporttextarea = document.createElement('textarea');
txtexportdiv.style.position = 'fixed';
txtexportdiv.style.width = '500px';
txtexportdiv.style.height = '255px';
txtexportdiv.style.left = '50%';
txtexportdiv.style.right = '50%';
txtexportdiv.style.margin = '-250px 0px 0px -250px';
txtexportdiv.style.top = '300px';
txtexportdiv.style.padding = '5px';
txtexportdiv.style.border = '2px';
txtexportdiv.style.backgroundColor = 'black';
txtexportdiv.style.color = 'white';
txtexportdiv.style.zIndex = '100';
txtexportdiv.setAttribute('id','txtexport_div');
txtexportdiv.style.display = 'none';
txtexporttextarea.style.padding = '2px';
txtexporttextarea.style.width = '500px';
txtexporttextarea.style.height = '230px';
txtexporttextarea.title = 'Plaintext Export Output';
txtexporttextarea.setAttribute('id','txtexport_text');
txtexportdiv.textContent = 'Plaintext Export: Press Ctrl+C to (re-)copy to clipboard. Click textarea to close.';
txtexportdiv.style.fontSize = '12px';
txtexportdiv.appendChild(txtexporttextarea);
document.body.insertBefore(txtexportdiv, document.body.firstChild);
txtexporttextarea.addEventListener("click", function(){ txtexportdiv.style.display = 'none'; }, false);


function display(e){
    var theButton = e.target;
    theButton.style.backgroundColor = '#CC0000';
    
    var capHand = document.getElementById('capsule'+theButton.getAttribute("place")+'-0');
    var tBodies = capHand.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
    
    var capReq = tBodies.getElementsByClassName('requesterIdentity')[0].textContent;
    var capReqId = tBodies.getElementsByClassName('requesterIdentity')[0].parentNode.href.split('requesterId=')[1];
    // if on certain types of searches when logged out, more infernal Amazon-meddling may add a useless &state= value to the end of the requester link
    if ( capReqId.indexOf('&state=') > -1 )
    {
        capReqId = capReqId.split('&state')[1];
    }
    
    var capTitle = capHand.textContent.trim();
    capTitle = capTitle.replace(/<(\w+)[^>]*>.*<\/\1>/gi, "").trim();  // addition to strip html tags and their contents, appearing inside the title link (re 10-20-2014 appearance of "<span class="tags"></span>")

    var capGId = 'unavailable';  // handle logged-out export requests for HITs with no preview/notqualified links
    // if hit has a preview or notqualified link
    if ( capHand.parentNode.parentNode.getElementsByClassName('capsulelink')[1].firstChild.nextSibling.href !== '' )  
    {
        // if this is a preview link
        if ( capHand.parentNode.parentNode.getElementsByClassName('capsulelink')[1].firstChild.nextSibling.href.indexOf('preview') > -1 )
        {
            capGId = capHand.parentNode.parentNode.getElementsByClassName('capsulelink')[1].firstChild.nextSibling.href.split('=')[1];
        }
        // if this is a notqualified link
        else if ( capHand.parentNode.parentNode.getElementsByClassName('capsulelink')[1].firstChild.nextSibling.href.indexOf('notqualified') > -1 )
        {
            capGId = capHand.parentNode.parentNode.getElementsByClassName('capsulelink')[1].firstChild.nextSibling.href.split('=')[1];
            // Amazon messed up the notqualified links, now looking like https://www.mturk.com/mturk/notqualified?hitGroupId=3ID43DSF4IQ1X8LO308D15ZSD5J5GX&hitId=3ID43DSF4IQ1X8LO308D15ZSD5J5GX ; this and the above split happening on = instead of a specific value address that
            capGId = capGId.replace("&hitId", "").replace("&hitGroupId", "");  // added a removal of hitGroupId too since Amazon flipped the order of these on 6/2/15
        }
        // if this is a requestqualification link we shouldn't be on, but are anyway because of stuff Amazon screwed with on 6/2/15
        else if ( capHand.parentNode.parentNode.getElementsByClassName('capsulelink')[1].firstChild.nextSibling.href.indexOf('requestqualification') > -1 )
        {
            // go to the next link, the "(why?)" notqualified link instead
            capGId = capHand.parentNode.parentNode.getElementsByClassName('capsulelink')[1].firstChild.nextSibling.nextElementSibling.href.split('=')[1];
            // Amazon messed up the notqualified links, now looking like https://www.mturk.com/mturk/notqualified?hitGroupId=3ID43DSF4IQ1X8LO308D15ZSD5J5GX&hitId=3ID43DSF4IQ1X8LO308D15ZSD5J5GX ; this and the above split happening on = instead of a specific value address that
            capGId = capGId.replace("&hitId", "").replace("&hitGroupId", "");  // added a removal of hitGroupId too since Amazon flipped the order of these on 6/2/15
        }
    }
    
    var capRew = tBodies.getElementsByClassName('reward')[0].textContent;

    var capTime = tBodies.getElementsByClassName('capsule_field_text')[2].textContent;

    var capAvailable = tBodies.getElementsByClassName('capsule_field_text')[4].textContent;

    var qualList = document.getElementById('capsule'+theButton.getAttribute("place")+'target').getElementsByTagName('tbody')[2];
    if ( document.location.href.indexOf('?last_hits_previewed') > -1 ) { qualList = document.getElementById('capsule'+theButton.getAttribute("place")+'target').getElementsByTagName('tbody')[1]; }
    var qualColl = qualList.getElementsByTagName('td');
    var qualStart = 3;
    if ( document.getElementById('lnkWorkerSignin') ) { qualStart = 1; }  // handle logged-out export requests - difference in qual table coding
    if ( document.location.href.indexOf('?last_hits_previewed') > -1 ) { qualStart = 2; }
    var masterStat = '';
    for ( var m = qualStart; m < qualColl.length; m++ ) {
        if ( qualColl[m].textContent.indexOf('Masters') > -1 ) {
            masterStat = 'MASTERS ';
        }
    }
    
    var capUrl = 'https://www.mturk.com/mturk/preview?groupId='+capGId;
    var capReqUrl = 'https://www.mturk.com/mturk/searchbar?selectedSearchType=hitgroups&requesterId='+capReqId;
    var hitLinkUnav = '';
    if ( capGId == 'unavailable' ) { capUrl = capReqUrl; hitLinkUnav = " (preview link unavailable)"; }  // handle logged-out export requests for HITs with no preview/notqualified links
    var toLink = 'http://turkopticon.ucsd.edu/'+capReqId;
    var capToStats = getTO(capReqId);


    // additions for plaintext export:
    
    function DST() {    // check if daylight savings time should be adjusted for, from http://www.mresoftware.com/simpleDST.htm
        var today = new Date();
        var yr = today.getFullYear();
        var dst_start = new Date("March 14, "+yr+" 02:00:00"); // 2nd Sunday in March can't occur after the 14th 
        var dst_end = new Date("November 07, "+yr+" 02:00:00"); // 1st Sunday in November can't occur after the 7th
        var day = dst_start.getDay(); // day of week of 14th
        dst_start.setDate(14-day); // Calculate 2nd Sunday in March of this year
        day = dst_end.getDay(); // day of the week of 7th
        dst_end.setDate(7-day); // Calculate first Sunday in November of this year
        if (today >= dst_start && today < dst_end) { //does today fall inside of DST period?
            return true; //if so then return true
        }
        return false; //if not then return false
    }

    var currentDate = new Date();
    var utc = currentDate.getTime() + (currentDate.getTimezoneOffset() * 60000);   // http://www.techrepublic.com/article/convert-the-local-time-to-another-time-zone-with-this-javascript/
    var offset = '';
    if ( DST() == true ) { offset = "-7"; } else { offset = "-8"; }   // adjust Pacific Time's UTC offset for daylight savings time - http://stackoverflow.com/questions/8207655/how-to-get-time-of-specific-timezone-using-javascript/8207708#8207708
    var amazonDate = new Date(utc + (3600000*offset));
    var month = amazonDate.getMonth() + 1;
    var day = amazonDate.getDate();
    var year = amazonDate.getFullYear();
    var hours = amazonDate.getHours();
    if (hours < 10) { hours = '0' + hours; }   // http://stackoverflow.com/questions/6838197/get-local-date-string-and-time-string/6838658#6838658
    var minutes = amazonDate.getMinutes();
    if (minutes < 10) { minutes = '0' + minutes; }
    var dateStr = month + "/" + day + "/" + year + " " + hours + ":" + minutes + " PT";
    
    var capDesc = '"' + tBodies.getElementsByClassName('capsule_field_text')[5].textContent.trim().replace(/(\t)+/g,' ').replace(/(\n)+/g,' ').replace(/(\r)+/g,' ').replace(/(  )+/g,' ').replace(/(\s)+/g,' ') + '"';
    if (capDesc == '""') { capDesc = "none"; }

    var capKeywords = "";
    if ( document.location.href.indexOf('?last_hits_previewed') > -1 ) { capKeywords = "unavailable (exported from Last HITs Previewed)"; }
    else { capKeywords = '"' + tBodies.getElementsByClassName('capsule_field_text')[6].textContent.trim().replace(/(\t)+/g,' ').replace(/(\n)+/g,' ').replace(/(\r)+/g,' ').replace(/(  )+/g,' ').replace(/(\s)+/g,' ') + '"'; }
    if (capKeywords == '""' || capKeywords == '') { capKeywords = "none"; }

    var qualStr = "";
    for ( var q = qualStart; q < qualColl.length; q++ ) {
        if ( ( (qualColl[q].textContent.indexOf('is') > -1) || (qualColl[q].textContent.indexOf('has') > -1) ) && (qualColl[q].textContent.indexOf('You meet this') < 0) && (qualColl[q].textContent.indexOf('Contact the Requester') < 0) ) {
            if (qualStr != "") { qualStr += '   '; }
            qualStr += qualColl[q].textContent.trim().replace(/(\t)+/g,' ').replace(/(\n)+/g,' ').replace(/(\r)+/g,' ').replace(/(  )+/g,' ').replace(/(\s)+/g,' ') + '  \r\n';
        }
    }
    if (qualStr == "") { qualStr = "none  \r\n"; }


    var exString = dateStr + '  \r\n'
                 + masterStat + 'HIT: ' + capTitle + '   - ' + capUrl + hitLinkUnav + '  \r\n'
                 + 'Requester: ' + capReq + '   - ' + capReqUrl + '  \r\n'
                 + 'TO Ratings: ' + 'Pay='+capToStats[1] + ' Fair='+capToStats[2] + ' Comm='+capToStats[0] + ' Speed='+capToStats[3] + '   - ' + toLink + '  \r\n'
                 + 'Time Allotted: ' + capTime + '  \r\n'
                 + 'Reward: ' + capRew + '  \r\n'
                 + 'HITs Available: ' + capAvailable + '  \r\n'
                 + 'Description: ' + capDesc + '  \r\n'
                 + 'Keywords: ' + capKeywords + '  \r\n'
                 + 'Qualifications: ' + qualStr + '  \r\n' ;
    if (GM_setClipboard) { GM_setClipboard(exString); }
    window.setTimeout(function(){ theButton.style.backgroundColor = 'transparent'; }, 500);
    txtexporttextarea.textContent = exString;
    txtexportdiv.style.display = 'block';
    txtexporttextarea.select();
}