// Generated by CoffeeScript 1.8.0 /* IsThereAnyDeal.com Collection Importer Any patches to this script should be made against the original CoffeeScript source file available (and documented) at: https://github.com/ssokolow/itad_importer Copyright ©2014-2015 Stephan Sokolow License: MIT (http://opensource.org/licenses/MIT) TODO: - Add a `@downloadURL` for the script Note: While we do not use GM_info, we must request it to force the userscript to be isolated from the page so its jQuery doesn't collide with the site's jQuery. // ==UserScript== // @name IsThereAnyDeal.com Collection Importer // @version 0.1b10 // @namespace http://isthereanydeal.com/ // @description Adds buttons to various sites to export your game lists to ITAD // @icon http://s3-eu-west-1.amazonaws.com/itad/images/banners/50x50.gif // @grant GM_info // @require https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js // // @match *://www.dotemu.com/* // @match *://fireflowergames.com/my-lists/* // @match *://www.flyingbundle.com/users/account // @match *://www.gog.com/account* // @match *://www.gog.com/order/status/* // @match *://groupees.com/purchases // @match *://groupees.com/users/* // @match *://www.humblebundle.com/home* // @match *://www.humblebundle.com/downloads?key=* // @match *://www.humblebundle.com/s?key=* // @match *://indiegamestand.com/wallet.php // @match *://indiegamestand.com/wishlist.php // @match *://www.shinyloot.com/m/games* // @match *://www.shinyloot.com/m/wishlist* // @downloadURL none // ==/UserScript== */ var BUTTON_LABEL, ITAD_12X12, ITAD_14X14_GRAY, attr, dotemu_add_button, gog_prepare_title, humble_make_button, humble_parse, scrapeGames, scrapers, shinyloot_insert_button, titlecase_cb, underscore_re, word_re; BUTTON_LABEL = "Export to ITAD"; ITAD_12X12 = "data:image/png;base64,\niVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAMAAABhq6zVAAAAZlBMVEUEbrIEbrIJcbQLcrQefboo\ng70rhb4thr8vh78zicA6jcNCksVLl8hWnctZn8xdoc1ipM9ipc9kptB5stZ6staCt9mHutqJu9ud\nxuGozeSrz+W72OrA2+zJ4O7U5vLX6PPn8fj3+vyC0mvkAAAAAXRSTlMAQObYZgAAAFdJREFUCB0F\nwYkCgUAABcA3CpElRyRH6/9/0kwCQALtZSwNglN9Pt5LR+jqGuelEaYbeBXh04P7KMwDeF6E8l1h\nW1vh8PsO/bWeiGPdl/kzdYjdBkACQP5LygQ7CM8T6wAAAABJRU5ErkJggg=="; ITAD_14X14_GRAY = "data:image/png;base64,\niVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAAdVBMVEUEbrKTlaCTlZ+TlZ+UlqCY\nmaSYmqWcnqednqieoKmfoaugoqulprCvsLivsbiwsrmztLuztby2uL7BwsjDxcrExcvIyc7V1trW\n1trX2Nvn5+rp6evx8vP19fb39/j4+Pn5+fr7+/v7+/z8/Pz8/P39/f3///8J+FboAAAAJHRSTlMA\ny+rw8PHx8fHx8vLy9PT09PT19vf39/n5+fz8/f3+/v7+/v695LIzAAAAcUlEQVQIHQXBhwGCQAAE\nsHui2FHsBeyy/4gmSQGgJKWCeTNFVQJNN9yH2xJB+z3WZuf3kjDuD+B8I6wfIzAbpsLuCrg3QtsD\n9TAXJq8tOHYEl9+W0eHbEPaf06u/PvoWsXmuTNrdegwp1QJAVZICQMkf1qQG7Yh+Z60AAAAASUVO\nRK5CYII="; underscore_re = /_/g; word_re = /\b\w+/g; titlecase_cb = function(s) { return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase(); }; attr = function(node, name) { return node.getAttribute(name); }; dotemu_add_button = function(parent_selector) { return $('').html(BUTTON_LABEL).css({ float: 'right', marginRight: '5px' }).appendTo(parent_selector); }; gog_prepare_title = function(elem) { var dom; dom = $('.product-title', elem).clone(); $('._product-flag', dom).remove(); return dom.text(); }; humble_make_button = function() { var a, button, label; label = $('').html(BUTTON_LABEL); a = $('').html(BUTTON_LABEL).css('padding-left', '9px'); return button = $('
').append('
').append(label).append(a); }; humble_parse = function() { var x, _i, _len, _ref, _results; _ref = $('div.row').has(' .downloads.windows .download, .downloads.linux .download, .downloads.mac .download, .downloads.android .download').find('div.title'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { x = _ref[_i]; _results.push({ title: x.textContent.trim(), sources: ['humblestore'] }); } return _results; }; shinyloot_insert_button = function() { return $('').html(BUTTON_LABEL).css({ background: 'url("/images/filters/sort-background-inactive.png") ' + 'repeat-x scroll 0% 0% transparent', border: '1px solid #666', borderRadius: '2px', boxShadow: '0px 1px 6px #777', color: '#222', fontSize: '12px', fontWeight: 'bold', fontFamily: 'Arial,Helvetica,Sans-serif', float: 'right', padding: '2px 8px', marginRight: '-6px', verticalAlign: 'middle' }).appendTo('#content .header'); }; scrapers = { 'www.dotemu.com': { 'https://www\\.dotemu\\.com/(en|fr|es)/user/?': [ { 'source_id': 'dotemu', 'game_list': function() { var x, _i, _len, _ref, _results; _ref = $('div.my-games div.field-title a'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { x = _ref[_i]; _results.push({ title: attr(x, 'title'), url: x.href, sources: ['dotemu'] }); } return _results; }, 'insert_button': function() { return dotemu_add_button('div.my-games h2.pane-title'); } }, { 'source_id': 'dotemu', 'game_list': function() { var x, _i, _len, _ref, _results; _ref = $('div.user-wishlist .views-field-title-1 a'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { x = _ref[_i]; _results.push({ title: attr(x, 'title'), url: x.href, sources: ['dotemu'] }); } return _results; }, 'insert_button': function() { return dotemu_add_button('.user-wishlist h2.pane-title'); }, 'is_wishlist': true } ] }, 'fireflowergames.com': { '^http://fireflowergames\\.com/my-lists/(edit-my|view-a)-list/\\?.+': { 'source_id': 'fireflower', 'game_list': function() { var results, x, _i, _len, _results; results = $('table.wl-table tbody td.check-column input:checked').parents('tr').find('td.product-name a'); if (!results.length) { results = $('table.wl-table td.product-name a'); } _results = []; for (_i = 0, _len = results.length; _i < _len; _i++) { x = results[_i]; _results.push({ title: $(x).text().trim(), url: x.href, sources: ['fireflower'] }); } return _results; }, 'insert_button': function() { return $('
').html(BUTTON_LABEL).wrap('').appendTo($('table.wl-actions-table tbody:first').find('tr:last')); }, 'is_wishlist': true } }, 'www.flyingbundle.com': { 'https?://www\\.flyingbundle\\.com/users/account': { 'source_id': 'flying_bundle', 'game_list': function() { var x, _i, _len, _ref, _results; _ref = $(".div_btn_download[href^='/users/sources']").parents('li').find(':first'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { x = _ref[_i]; _results.push({ title: $(x).text(), sources: 'flying_bundle' }); } return _results; }, 'insert_button': function() { var li; li = $("
  • ").appendTo('.legenda_points ul'); return $('' + BUTTON_LABEL + ' ').css('text-transform', 'uppercase').wrap("
  • ").appendTo(li); } } }, 'www.gog.com': { '^https://www\\.gog\\.com/order/status/.+': { 'source_id': 'gog', 'game_list': function() { var x, _i, _len, _ref, _results; console.debug("game_list called for GOG order status page"); _ref = $('.order__hero-unit ul.summary-list li'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { x = _ref[_i]; _results.push({ title: $(x).text().trim(), sources: ['gog'] }); } return _results; }, 'insert_button': function() { console.debug("insert_button called for GOG order status page"); return $("").html("On ITAD").prependTo($('.order-message__actions ._dropdown__items').filter(':first')); } }, '^https?://www\\.gog\\.com/account(/games(/(shelf|list))?)?/?(\\?|$)': { 'source_id': 'gog', 'game_list': function() { var x, _i, _len, _ref, _results; console.debug("game_list called for GOG collection page"); _ref = $('.product-row'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { x = _ref[_i]; _results.push({ id: attr(x, 'gog-product'), title: gog_prepare_title(x), sources: ['gog'] }); } return _results; }, 'insert_button': function() { console.debug("insert_button called for GOG collection page"); return $("").css({ float: 'right', cursor: 'pointer', position: 'relative', marginBottom: '-2em', zIndex: 1 }).html(BUTTON_LABEL + " (This Page)").prependTo($('.collection-header').filter(':first')); } } }, 'groupees.com': { 'https?://(www\\.)?groupees\\.com/(purchases|users/\\d+)': { 'source_id': 'other', 'game_list': function() { var x, _i, _len, _ref, _results; _ref = $('.product ul.dropdown-menu').parents('.details').find('h3'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { x = _ref[_i]; _results.push({ title: x.textContent.trim(), sources: ['other'] }); } return _results; }, 'insert_button': function() { return $("").css({ float: 'right' }).addClass('button btn btn-sm btn-primary').html(BUTTON_LABEL + " (Selected Bundle)").insertBefore("input[name='search']"); } } }, 'www.humblebundle.com': { 'https://www\\.humblebundle\\.com/home/library/?': { 'source_id': 'humblestore', 'game_list': function() { var x, _i, _len, _ref, _results; _ref = $('.subproduct-selector h2'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { x = _ref[_i]; _results.push({ title: x.textContent.trim(), sources: ['humblestore'] }); } return _results; }, 'insert_button': function() { var button, config, found_early, observer; config = { childList: true, subtree: true }; button = $('').html(BUTTON_LABEL).css({ display: 'inline', border: '1px solid #CCC', background: '#F1F3F6', padding: '5px 10px 5px 10px', marginLeft: '10px' }); found_early = $(".top-controls"); if (found_early.length > 0) { console.log("Inserting button immediately."); button.appendTo(found_early); } else { console.log("Using MutationObserver for deferred button insertion."); observer = new MutationObserver(function(mutations) { return mutations.forEach(function(mutation) { var found, tnode_cls; tnode_cls = mutation.target.getAttribute("class"); found = $(".top-controls", mutation.target); if (found.length > 0) { observer.disconnect(); return button.appendTo(found); } }); }); observer.observe(document.querySelector('.js-library-holder'), config); } return button; } }, 'https://www\\.humblebundle\\.com/home/?': { 'source_id': 'humblestore', 'game_list': humble_parse, 'insert_button': function() { return humble_make_button().css({ float: 'right', fontSize: '14px', fontWeight: 'normal' }).prependTo('.base-main-wrapper h1'); } }, 'https://www\\.humblebundle\\.com/(download)?s\\?key=.+': { 'source_id': 'humblestore', 'game_list': humble_parse, 'insert_button': function() { var parent; parent = $('.js-gamelist-holder').parents('.whitebox'); parent.find('.staple.s4').remove(); return humble_make_button().css({ position: 'absolute', top: 11, right: 17 }).appendTo(parent); } } }, 'indiegamestand.com': { 'https://indiegamestand\\.com/wallet\\.php': { 'source_id': 'indiegamestand', 'game_list': function() { var x, _i, _len, _ref, _ref1, _ref2, _ref3, _results; _ref = $('#wallet_contents .line-item'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { x = _ref[_i]; _results.push({ url: (_ref1 = $('.game-thumb', x)) != null ? (_ref2 = _ref1.closest('a')) != null ? (_ref3 = _ref2[0]) != null ? _ref3.href : void 0 : void 0 : void 0, title: $('.game-title', x).text().trim(), sources: ['indiegamestand'] }); } return _results; }, 'insert_button': function() { return $('
    ').html(BUTTON_LABEL).wrapInner("
    ").css({ display: 'inline-block', marginLeft: '1em', verticalAlign: 'middle' }).appendTo('#game_wallet h2'); } }, 'https://indiegamestand\\.com/wishlist\\.php': { 'source_id': 'indiegamestand', 'game_list': function() { var x, _i, _len, _ref, _ref1, _ref2, _ref3, _results; _ref = $('#store_browse_game_list .game_list_item'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { x = _ref[_i]; _results.push({ url: (_ref1 = $('.game-thumb', x)) != null ? (_ref2 = _ref1.closest('a')) != null ? (_ref3 = _ref2[0]) != null ? _ref3.href : void 0 : void 0 : void 0, title: $('.game_details h3', x).text().trim(), sources: ['indiegamestand'] }); } return _results; }, 'is_wishlist': true, 'insert_button': function() { var innerDiv; innerDiv = $("
    ").css({ paddingLeft: '10px', background: 'url("images/icon-arrow.png") no-repeat scroll ' + '155px 45% transparent' }); return $('
    ').html(BUTTON_LABEL).wrapInner(innerDiv).css({ display: 'inline-block', verticalAlign: 'middle', float: 'right', width: '170px', height: '21px', background: 'url("images/btn-bg-blue-longer.png") ' + 'no-repeat scroll 0px 0px transparent', lineHeight: '21px', color: '#FFF', whiteSpace: 'nowrap', marginLeft: '1em', marginBottom: '4px', fontSize: '12px', cursor: 'pointer' }).css({ margin: '11px 5px auto auto' }).appendTo('#store_browse_game_list .header'); } } }, 'www.shinyloot.com': { 'https?://www\\.shinyloot\\.com/m/games/?': { 'source_id': 'shinyloot', 'game_list': function() { var x, _i, _len, _ref, _results; _ref = $('#accordion .ui-widget-content'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { x = _ref[_i]; _results.push({ url: $('.right-float a img', x).closest('a')[0].href, title: $(x).prev('h3').text().trim(), sources: ['shinyloot'] }); } return _results; }, 'insert_button': shinyloot_insert_button }, 'https?://www\\.shinyloot\\.com/m/wishlist/?': { 'source_id': 'shinyloot', 'game_list': function() { var x, _i, _len, _ref, _results; _ref = $('.gameItem'); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { x = _ref[_i]; _results.push({ url: $('.gameInfo + a', x)[0].href, title: $('.gameName', x).text().trim() }); } return _results; }, 'insert_button': shinyloot_insert_button, 'is_wishlist': true } } }; scrapeGames = function(scraper_obj) { var form, params, url; params = { json: JSON.stringify(scraper_obj.game_list()), source: scraper_obj.source_id }; url = scraper_obj.is_wishlist != null ? 'https://isthereanydeal.com/outside/user/wait/3rdparty' : 'https://isthereanydeal.com/outside/user/collection/3rdparty'; form = $("
    ").attr('action', url); params['returnTo'] = location.href; form.css({ display: 'none' }); $.each(params, function(key, value) { return $("").attr("name", key).attr("value", value).appendTo(form); }); $(document.body).append(form); return form.submit(); }; $(function() { var e, profile, profile_matched, regex, scraper, _fn, _i, _len, _ref, _results; console.log("Loading ITAD importer..."); if (scrapers[location.host]) { console.log("Matched domain: " + location.host); _ref = scrapers[location.host]; _results = []; for (regex in _ref) { profile = _ref[regex]; try { profile_matched = location.href.match(regex); } catch (_error) { e = _error; console.error("Bad regex: " + regex); } if (profile_matched) { console.log("Matched profile: " + regex); $('.itad_btn, #itad_dlg, .itad_close').remove(); if (!Array.isArray(profile)) { profile = [profile]; } _fn = function(scraper) { console.log("Inserting ITAD button for source ID: " + scraper.source_id); return typeof scraper.insert_button === "function" ? scraper.insert_button().addClass('itad_btn').click(function() { console.log("ITAD button clicked"); return scrapeGames(scraper); }) : void 0; }; for (_i = 0, _len = profile.length; _i < _len; _i++) { scraper = profile[_i]; _fn(scraper); } break; } else { _results.push(void 0); } } return _results; } });