IsThereAnyDeal.com Collection Importer

Adds buttons to various sites to export your game lists to ITAD

// Generated by CoffeeScript 1.7.1

/* IsThereAnyDeal.com Collection Importer
// ==UserScript==
// @name IsThereAnyDeal.com Collection Importer
// @version 0.1b18
// @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
// @license MIT
// @supportURL https://github.com/ssokolow/itad_importer/issues
// @require https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js
//
// @match *://fireflowergames.com/my-account*
// @match *://fireflowergames.com/my-lists/*
// @match *://flyingbundle.com/users/account*
// @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=*
// ==/UserScript==

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-2018 Stephan Sokolow
License: MIT (http://opensource.org/licenses/MIT)

TODO:
- Add a `@downloadURL` for the script
 */
var BUTTON_LABEL, ITAD_12X12, ITAD_14X14_GRAY, attr, gog_prepare_title, humble_make_button, humble_parse, scrapeGames, scrapers;

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=";

this.$ = this.jQuery = jQuery.noConflict(true);

attr = function(node, name) {
  return node.getAttribute(name);
};

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 = $('<span class="label"></span>').html(BUTTON_LABEL);
  a = $('<a class="a" href="#"></span>').html(BUTTON_LABEL).css('padding-left', '9px');
  return button = $('<div class="flexbtn active noicon"></div>').append('<div class="right"></div>').append(label).append(a);
};

humble_parse = function() {
  var x;
  return {
    version: "02",
    data: (function() {
      var _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(),
          copies: [
            {
              type: 'humblestore'
            }
          ]
        });
      }
      return _results;
    })()
  };
};

scrapers = {
  'fireflowergames.com': {
    '^https://fireflowergames\\.com/my-account/?': {
      'source_id': 'fireflower',
      'game_list': function() {
        var results, title, titles, uniques, x;
        results = $('ul.digital-downloads li a');
        titles = [
          (function() {
            var _i, _len, _results;
            _results = [];
            for (_i = 0, _len = results.length; _i < _len; _i++) {
              x = results[_i];
              _results.push($(x).text().split(" – ")[0].trim());
            }
            return _results;
          })()
        ][0];
        uniques = titles.filter(function(title, pos) {
          return titles.indexOf(title) === pos;
        });
        return {
          version: "02",
          data: (function() {
            var _i, _len, _results;
            _results = [];
            for (_i = 0, _len = uniques.length; _i < _len; _i++) {
              title = uniques[_i];
              _results.push({
                title: title,
                copies: [
                  {
                    type: 'fireflower',
                    status: 'redeemed',
                    owned: 1
                  }
                ]
              });
            }
            return _results;
          })()
        };
      },
      'insert_button': function() {
        return $('<a class="button"></a>').html(BUTTON_LABEL).css({
          verticalAlign: '20%',
          marginLeft: '1em'
        }).appendTo($('ul.digital-downloads').prev());
      }
    },
    '^http://fireflowergames\\.com/my-lists/(edit-my|view-a)-list/\\?.+': {
      'source_id': 'fireflower',
      'game_list': function() {
        var results, x;
        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');
        }
        return {
          version: "02",
          data: (function() {
            var _i, _len, _results;
            _results = [];
            for (_i = 0, _len = results.length; _i < _len; _i++) {
              x = results[_i];
              _results.push({
                title: $(x).text().trim()
              });
            }
            return _results;
          })()
        };
      },
      'insert_button': function() {
        return $('<a class="button"></a>').html(BUTTON_LABEL).wrap('<td></td>').appendTo($('table.wl-actions-table tbody:first').find('tr:last'));
      },
      'is_wishlist': true
    }
  },
  'flyingbundle.com': {
    'https?://(www\\.)?flyingbundle\\.com/users/account#?': {
      'source_id': 'flying_bundle',
      'game_list': function() {
        var x;
        return {
          version: "02",
          data: (function() {
            var _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(),
                copies: [
                  {
                    type: 'Flying Bundle',
                    status: 'redeemed',
                    owned: 1,
                    source: {
                      type: "s",
                      id: "other"
                    }
                  }
                ]
              });
            }
            return _results;
          })()
        };
      },
      'insert_button': function() {
        var li;
        li = $("<li></li>").appendTo('.legenda_points ul');
        return $('<a href="#">' + BUTTON_LABEL + ' <img src="' + ITAD_14X14_GRAY + '" /></a>').css('text-transform', 'uppercase').wrap("<li></li>").appendTo(li);
      }
    }
  },
  'www.gog.com': {
    '^https://www\\.gog\\.com/order/status/.+': {
      'source_id': 'gog',
      'game_list': function() {
        var x;
        console.debug("game_list called for GOG order status page");
        return {
          "version": "02",
          "data": (function() {
            var _i, _len, _ref, _results;
            _ref = $('.order + .container .product-row');
            _results = [];
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
              x = _ref[_i];
              _results.push({
                title: gog_prepare_title(x),
                copies: [
                  {
                    type: 'gog',
                    status: 'redeemed',
                    owned: 1
                  }
                ]
              });
            }
            return _results;
          })()
        };
      },
      'insert_button': function() {
        console.debug("insert_button called for GOG order status page");
        $(".order-article__btn-pointer-wrapper .order-article__btn-pointer").css({
          marginTop: -4,
          zIndex: 20
        });
        $('.order-article__dropdown-items').css('z-index', 10);
        return $("<a class='_dropdown__item ng-scope'></a>").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;
        console.debug("game_list called for GOG collection page");
        return {
          "version": "02",
          "data": (function() {
            var _i, _len, _ref, _results;
            _ref = $('.product-row');
            _results = [];
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
              x = _ref[_i];
              _results.push({
                title: gog_prepare_title(x),
                copies: [
                  {
                    type: 'gog',
                    status: 'redeemed',
                    owned: 1
                  }
                ]
              });
            }
            return _results;
          })()
        };
      },
      'insert_button': function() {
        console.debug("insert_button called for GOG collection page");
        return $("<span></span>").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;
        return {
          "version": "02",
          "data": (function() {
            var _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(),
                copies: [
                  {
                    type: 'Groupees.com',
                    status: 'redeemed',
                    owned: 1,
                    source: {
                      type: "s",
                      id: "other"
                    }
                  }
                ]
              });
            }
            return _results;
          })()
        };
      },
      'insert_button': function() {
        return $("<button></button>").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;
        return {
          "version": "02",
          "data": (function() {
            var _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(),
                copies: [
                  {
                    type: 'humblestore',
                    status: 'redeemed',
                    owned: 1
                  }
                ]
              });
            }
            return _results;
          })()
        };
      },
      'insert_button': function() {
        var button, config, found_early, observer;
        config = {
          childList: true,
          subtree: true
        };
        button = $('<button class="download-button"></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);
      }
    }
  }
};

scrapers['www.flyingbundle.com'] = scrapers['flyingbundle.com'];

scrapers['www.groupees.com'] = scrapers['groupees.com'];

scrapeGames = function(scraper_obj) {
  var form, params, url;
  params = {
    file: btoa(unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list())))),
    upload: 'x'
  };
  url = scraper_obj.is_wishlist != null ? 'https://isthereanydeal.com/waitlist/import/' : 'https://isthereanydeal.com/collection/import/';
  form = $("<form id='itad_submitter' method='POST' />").attr('action', url);
  params['returnTo'] = location.href;
  form.css({
    display: 'none'
  });
  $.each(params, function(key, value) {
    return $("<input type='hidden' />").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;
  }
});