From 7a968cbdf10463726361a55aaa6298434a06f89b Mon Sep 17 00:00:00 2001 From: Reuben Peterkin Date: Sat, 18 Aug 2018 22:43:58 +1000 Subject: [PATCH 1/8] add itch --- itad_importer.user.coffee | 39 ++ itad_importer.user.js | 861 ++++++++++++++++++++------------------ 2 files changed, 493 insertions(+), 407 deletions(-) diff --git a/itad_importer.user.coffee b/itad_importer.user.coffee index 1d5b176..afb980e 100644 --- a/itad_importer.user.coffee +++ b/itad_importer.user.coffee @@ -15,6 +15,7 @@ // @match *://www.flyingbundle.com/users/account* // @match *://www.gog.com/account* // @match *://www.gog.com/order/status/* +// @match *://itch.io/my-purchases* // @match *://groupees.com/purchases* // @match *://groupees.com/users/* // @match *://www.humblebundle.com/home* @@ -238,6 +239,42 @@ scrapers = .html(BUTTON_LABEL + " (This Page)") .prependTo($('.collection-header').filter(':first')) + 'itch.io': + '^https?://itch\\.io/my-purchases': + 'source_id': 'itchio' + 'game_list': -> + console.debug("game_list called for itch.io collection page") + { +# old_date = 0 +# new_date = "" + "version": "02", + "data": { + # id: attr(x, 'gog-account-product') + #.attr('title').trim() + title: $('.title.game_link',x).first().text().trim() + copies: [{ + added: new Date($('span',$('.date_header',x)).first().attr('title')).getTime()/1000 + type: 'itchio', + status: 'redeemed', + owned: 1, + }] + } for x in $('.game_cell') + } + + 'insert_button': -> + console.debug("insert_button called for GOG collection page") + $("") + .css + float: 'right' + cursor: 'pointer' + # TODO: Replace the following hacks with whatever GOG uses + position: 'relative' + marginBottom: '-2em' + zIndex: 1 + .html(BUTTON_LABEL + " (This Page)") + .appendTo($('.header_tabs').filter(':first')) + + 'groupees.com': # TODO: Support the new UI beta @@ -345,6 +382,7 @@ scrapers['www.groupees.com'] = scrapers['groupees.com'] # Callback for the button scrapeGames = (scraper_obj) -> params = { +# file: unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list()))) file: btoa(unescape(encodeURIComponent(JSON.stringify( scraper_obj.game_list())))), upload: 'x' @@ -353,6 +391,7 @@ scrapeGames = (scraper_obj) -> url = if scraper_obj.is_wishlist? 'https://isthereanydeal.com/waitlist/import/' else +# 'https://httpbin.org/post' 'https://isthereanydeal.com/collection/import/' # **TODO:** Figure out why attempting to use an iframe for non-HTTPS sites diff --git a/itad_importer.user.js b/itad_importer.user.js index a89fa89..e719b65 100644 --- a/itad_importer.user.js +++ b/itad_importer.user.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.7.1 +// Generated by CoffeeScript 1.12.8 /* IsThereAnyDeal.com Collection Importer // ==UserScript== @@ -17,6 +17,7 @@ // @match *://www.flyingbundle.com/users/account* // @match *://www.gog.com/account* // @match *://www.gog.com/order/status/* +// @match *://itch.io/my-purchases* // @match *://groupees.com/purchases* // @match *://groupees.com/users/* // @match *://www.humblebundle.com/home* @@ -35,445 +36,491 @@ 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"; +(function() { + var BUTTON_LABEL, ITAD_12X12, ITAD_14X14_GRAY, attr, gog_prepare_title, humble_make_button, humble_parse, scrapeGames, scrapers; -ITAD_12X12 = "data:image/png;base64,\niVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAMAAABhq6zVAAAAZlBMVEUEbrIEbrIJcbQLcrQefboo\ng70rhb4thr8vh78zicA6jcNCksVLl8hWnctZn8xdoc1ipM9ipc9kptB5stZ6staCt9mHutqJu9ud\nxuGozeSrz+W72OrA2+zJ4O7U5vLX6PPn8fj3+vyC0mvkAAAAAXRSTlMAQObYZgAAAFdJREFUCB0F\nwYkCgUAABcA3CpElRyRH6/9/0kwCQALtZSwNglN9Pt5LR+jqGuelEaYbeBXh04P7KMwDeF6E8l1h\nW1vh8PsO/bWeiGPdl/kzdYjdBkACQP5LygQ7CM8T6wAAAABJRU5ErkJggg=="; + BUTTON_LABEL = "Export to ITAD"; -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="; + ITAD_12X12 = "data:image/png;base64,\niVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAMAAABhq6zVAAAAZlBMVEUEbrIEbrIJcbQLcrQefboo\ng70rhb4thr8vh78zicA6jcNCksVLl8hWnctZn8xdoc1ipM9ipc9kptB5stZ6staCt9mHutqJu9ud\nxuGozeSrz+W72OrA2+zJ4O7U5vLX6PPn8fj3+vyC0mvkAAAAAXRSTlMAQObYZgAAAFdJREFUCB0F\nwYkCgUAABcA3CpElRyRH6/9/0kwCQALtZSwNglN9Pt5LR+jqGuelEaYbeBXh04P7KMwDeF6E8l1h\nW1vh8PsO/bWeiGPdl/kzdYjdBkACQP5LygQ7CM8T6wAAAABJRU5ErkJggg=="; -this.$ = this.jQuery = jQuery.noConflict(true); + 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="; -attr = function(node, name) { - return node.getAttribute(name); -}; + this.$ = this.jQuery = jQuery.noConflict(true); -gog_prepare_title = function(elem) { - var dom; - dom = $('.product-title', elem).clone(); - $('._product-flag', dom).remove(); - return dom.text(); -}; + attr = function(node, name) { + return node.getAttribute(name); + }; -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); -}; + gog_prepare_title = function(elem) { + var dom; + dom = $('.product-title', elem).clone(); + $('._product-flag', dom).remove(); + return dom.text(); + }; -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; - })() + 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); }; -}; -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 $('
').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'); + humble_parse = function() { + var x; + return { + version: "02", + data: (function() { + var i, len, ref, results1; + ref = $('div.row').has(' .downloads.windows .download, .downloads.linux .download, .downloads.mac .download, .downloads.android .download').find('div.title'); + results1 = []; + for (i = 0, len = ref.length; i < len; i++) { + x = ref[i]; + results1.push({ + title: x.textContent.trim(), + copies: [ + { + type: 'humblestore' + } + ] + }); } - 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 $('').html(BUTTON_LABEL).wrap('').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 results1; + })() + }; + }; + + 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, results1; + results1 = []; + for (i = 0, len = results.length; i < len; i++) { + x = results[i]; + results1.push($(x).text().split(" – ")[0].trim()); + } + return results1; + })() + ][0]; + uniques = titles.filter(function(title, pos) { + return titles.indexOf(title) === pos; + }); + return { + version: "02", + data: (function() { + var i, len, results1; + results1 = []; + for (i = 0, len = uniques.length; i < len; i++) { + title = uniques[i]; + results1.push({ + title: title, + copies: [ + { + type: 'fireflower', + status: 'redeemed', + owned: 1 } - } - ] - }); - } - 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; - 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; - })() - }; + ] + }); + } + return results1; + })() + }; + }, + 'insert_button': function() { + return $('').html(BUTTON_LABEL).css({ + verticalAlign: '20%', + marginLeft: '1em' + }).appendTo($('ul.digital-downloads').prev()); + } }, - '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 $("").html("On ITAD").prependTo($('.order-message__actions ._dropdown__items').filter(':first')); + '^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, results1; + results1 = []; + for (i = 0, len = results.length; i < len; i++) { + x = results[i]; + results1.push({ + title: $(x).text().trim() + }); + } + return results1; + })() + }; + }, + 'insert_button': function() { + return $('').html(BUTTON_LABEL).wrap('').appendTo($('table.wl-actions-table tbody:first').find('tr:last')); + }, + 'is_wishlist': true } }, - '^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 $("").css({ - float: 'right', - cursor: 'pointer', - position: 'relative', - marginBottom: '-2em', - zIndex: 1 - }).html(BUTTON_LABEL + " (This Page)").prependTo($('.collection-header').filter(':first')); + '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, results1; + ref = $(".div_btn_download[href^='/users/sources']").parents('li').find(':first'); + results1 = []; + for (i = 0, len = ref.length; i < len; i++) { + x = ref[i]; + results1.push({ + title: $(x).text(), + copies: [ + { + type: 'Flying Bundle', + status: 'redeemed', + owned: 1, + source: { + type: "s", + id: "other" + } + } + ] + }); + } + return results1; + })() + }; + }, + 'insert_button': function() { + var li; + li = $("
  • ").appendTo('.legenda_points ul'); + return $('' + BUTTON_LABEL + ' ').css('text-transform', 'uppercase').wrap("
  • ").appendTo(li); + } } - } - }, - '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" + }, + '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, results1; + ref = $('.order + .container .product-row'); + results1 = []; + for (i = 0, len = ref.length; i < len; i++) { + x = ref[i]; + results1.push({ + title: gog_prepare_title(x), + copies: [ + { + type: 'gog', + status: 'redeemed', + owned: 1 } - } - ] - }); - } - return _results; - })() - }; + ] + }); + } + return results1; + })() + }; + }, + '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 $("").html("On ITAD").prependTo($('.order-message__actions ._dropdown__items').filter(':first')); + } }, - 'insert_button': function() { - return $("").css({ - float: 'right' - }).addClass('button btn btn-sm btn-primary').html(BUTTON_LABEL + " (Selected Bundle)").insertBefore("input[name='search']"); + '^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, results1; + ref = $('.product-row'); + results1 = []; + for (i = 0, len = ref.length; i < len; i++) { + x = ref[i]; + results1.push({ + title: gog_prepare_title(x), + copies: [ + { + type: 'gog', + status: 'redeemed', + owned: 1 + } + ] + }); + } + return results1; + })() + }; + }, + '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')); + } } - } - }, - '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 = $('').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); + }, + 'itch.io': { + '^https?://itch\\.io/my-purchases': { + 'source_id': 'itchio', + 'game_list': function() { + var date, x; + console.debug("game_list called for itch.io collection page"); + return { + "version": "02", + "data": (function() { + var i, len, ref, results1; + ref = $('.game_cell'); + results1 = []; + for (i = 0, len = ref.length; i < len; i++) { + x = ref[i]; + results1.push({ + title: $('.title.game_link', x).first().text().trim(), + copies: [ + { + added: date = new Date($('span', $('.date_header', x)).first().attr('title')).getTime() / 1000, + type: 'itchio', + status: 'redeemed', + owned: 1 + } + ] + }); } - }); - }); - observer.observe(document.querySelector('.js-library-holder'), config); + return results1; + })() + }; + }, + '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)").appendTo($('.header_tabs').filter(':first')); } - 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'); + '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, results1; + ref = $('.product ul.dropdown-menu').parents('.details').find('h3'); + results1 = []; + for (i = 0, len = ref.length; i < len; i++) { + x = ref[i]; + results1.push({ + title: x.textContent.trim(), + copies: [ + { + type: 'Groupees.com', + status: 'redeemed', + owned: 1, + source: { + type: "s", + id: "other" + } + } + ] + }); + } + return results1; + })() + }; + }, + 'insert_button': function() { + return $("").css({ + float: 'right' + }).addClass('button btn btn-sm btn-primary').html(BUTTON_LABEL + " (Selected Bundle)").insertBefore("input[name='search']"); + } } }, - '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); + '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, results1; + ref = $('.subproduct-selector h2'); + results1 = []; + for (i = 0, len = ref.length; i < len; i++) { + x = ref[i]; + results1.push({ + title: x.textContent.trim(), + copies: [ + { + type: 'humblestore', + status: 'redeemed', + owned: 1 + } + ] + }); + } + return results1; + })() + }; + }, + '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); + } } } - } -}; + }; -scrapers['www.flyingbundle.com'] = scrapers['flyingbundle.com']; + scrapers['www.flyingbundle.com'] = scrapers['flyingbundle.com']; -scrapers['www.groupees.com'] = scrapers['groupees.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' + 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 = $("
    ").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(); }; - url = scraper_obj.is_wishlist != null ? 'https://isthereanydeal.com/waitlist/import/' : 'https://isthereanydeal.com/collection/import/'; - 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]; + $(function() { + var e, fn, i, len, profile, profile_matched, ref, regex, results1, scraper; + console.log("Loading ITAD importer..."); + if (scrapers[location.host]) { + console.log("Matched domain: " + location.host); + ref = scrapers[location.host]; + results1 = []; + for (regex in ref) { + profile = ref[regex]; + try { + profile_matched = location.href.match(regex); + } catch (error) { + e = error; + console.error("Bad regex: " + regex); } - _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); + 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 { + results1.push(void 0); } - break; - } else { - _results.push(void 0); } + return results1; } - return _results; - } -}); + }); + +}).call(this); From bf866016d8814e02c4e83d6fd831f38c86b02ee4 Mon Sep 17 00:00:00 2001 From: Reuben Peterkin Date: Mon, 27 Aug 2018 20:29:08 +1000 Subject: [PATCH 2/8] match itch.io game host --- itad_importer.user.coffee | 60 +++++++++++++++++++++++++++++++++------ itad_importer.user.js | 59 ++++++++++++++++++++++++++++++++++---- 2 files changed, 106 insertions(+), 13 deletions(-) diff --git a/itad_importer.user.coffee b/itad_importer.user.coffee index afb980e..be0ecb4 100644 --- a/itad_importer.user.coffee +++ b/itad_importer.user.coffee @@ -16,6 +16,7 @@ // @match *://www.gog.com/account* // @match *://www.gog.com/order/status/* // @match *://itch.io/my-purchases* +// @match *://*.itch.io/* // @match *://groupees.com/purchases* // @match *://groupees.com/users/* // @match *://www.humblebundle.com/home* @@ -240,19 +241,23 @@ scrapers = .prependTo($('.collection-header').filter(':first')) 'itch.io': - '^https?://itch\\.io/my-purchases': + '^https?://itch\\.io/my-purchadses': 'source_id': 'itchio' 'game_list': -> + old_date=0 + new_date=null console.debug("game_list called for itch.io collection page") { -# old_date = 0 -# new_date = "" +# new_date=0 "version": "02", "data": { # id: attr(x, 'gog-account-product') #.attr('title').trim() title: $('.title.game_link',x).first().text().trim() copies: [{ + new_date: new Date($('span',$('.date_header',x)).first().attr('title')).getTime()/1000 +#if (new_date == null) +# new_date=o added: new Date($('span',$('.date_header',x)).first().attr('title')).getTime()/1000 type: 'itchio', status: 'redeemed', @@ -273,6 +278,42 @@ scrapers = zIndex: 1 .html(BUTTON_LABEL + " (This Page)") .appendTo($('.header_tabs').filter(':first')) + + '^https?://.+\\.itch\\.io/.+/download/.+': +# '^https?://itch\\.io/my-purchases': + 'source_id': 'itchio' + 'game_list': -> + console.debug("game_list called for itch.io download page") + { + "version": "02", + "data": { + # id: attr(x, 'gog-account-product') + #.attr('title').trim() + title: $('.object_title',x).first().text().trim() + copies: [{ + added: new Date($('abbr').first().attr('title')).getTime()/1000 +#if (new_date == null) +# new_date=o +# added: new Date($('span',$('.date_header',x)).first().attr('title')).getTime()/1000 + type: 'itchio', + status: 'redeemed', + owned: 1, + }] + } for x in $('.inner_column') + } + + 'insert_button': -> + console.debug("insert_button called for GOG collection page") + $("") + .css + float: 'right' + cursor: 'pointer' + # TODO: Replace the following hacks with whatever GOG uses + position: 'relative' + marginBottom: '-2em' + zIndex: 1 + .html(BUTTON_LABEL + " (This Page)") + .appendTo($('.header_tabs').filter(':first')) 'groupees.com': @@ -382,17 +423,16 @@ scrapers['www.groupees.com'] = scrapers['groupees.com'] # Callback for the button scrapeGames = (scraper_obj) -> params = { -# file: unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list()))) - file: btoa(unescape(encodeURIComponent(JSON.stringify( - scraper_obj.game_list())))), + file: unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list()))) +# file: btoa(unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list())))), upload: 'x' } url = if scraper_obj.is_wishlist? 'https://isthereanydeal.com/waitlist/import/' else -# 'https://httpbin.org/post' - 'https://isthereanydeal.com/collection/import/' + 'https://httpbin.org/post' +# 'https://isthereanydeal.com/collection/import/' # **TODO:** Figure out why attempting to use an iframe for non-HTTPS sites # navigates the top-level window. @@ -417,6 +457,10 @@ $ -> # It seems we don't need an explicit `if location.host of scrapers` # before the `for` loop console.log("Loading ITAD importer...") + console.log(location.host) + console.log(location.host.match(/\.itch\.io/)) + if location.host.match(/\.itch\.io/) + scrapers[location.host] = scrapers['itch.io'] if scrapers[location.host] console.log("Matched domain: " + location.host) for regex, profile of scrapers[location.host] diff --git a/itad_importer.user.js b/itad_importer.user.js index e719b65..d0ef336 100644 --- a/itad_importer.user.js +++ b/itad_importer.user.js @@ -18,6 +18,7 @@ // @match *://www.gog.com/account* // @match *://www.gog.com/order/status/* // @match *://itch.io/my-purchases* +// @match *://*.itch.io/* // @match *://groupees.com/purchases* // @match *://groupees.com/users/* // @match *://www.humblebundle.com/home* @@ -288,10 +289,12 @@ TODO: } }, 'itch.io': { - '^https?://itch\\.io/my-purchases': { + '^https?://itch\\.io/my-purchadses': { 'source_id': 'itchio', 'game_list': function() { - var date, x; + var new_date, old_date, x; + old_date = 0; + new_date = null; console.debug("game_list called for itch.io collection page"); return { "version": "02", @@ -305,7 +308,48 @@ TODO: title: $('.title.game_link', x).first().text().trim(), copies: [ { - added: date = new Date($('span', $('.date_header', x)).first().attr('title')).getTime() / 1000, + new_date: new Date($('span', $('.date_header', x)).first().attr('title')).getTime() / 1000, + added: new Date($('span', $('.date_header', x)).first().attr('title')).getTime() / 1000, + type: 'itchio', + status: 'redeemed', + owned: 1 + } + ] + }); + } + return results1; + })() + }; + }, + '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)").appendTo($('.header_tabs').filter(':first')); + } + }, + '^https?://.+\\.itch\\.io/.+/download/.+': { + 'source_id': 'itchio', + 'game_list': function() { + var x; + console.debug("game_list called for itch.io download page"); + return { + "version": "02", + "data": (function() { + var i, len, ref, results1; + ref = $('.inner_column'); + results1 = []; + for (i = 0, len = ref.length; i < len; i++) { + x = ref[i]; + results1.push({ + title: $('.object_title', x).first().text().trim(), + copies: [ + { + added: new Date($('abbr').first().attr('title')).getTime() / 1000, type: 'itchio', status: 'redeemed', owned: 1 @@ -466,10 +510,10 @@ TODO: scrapeGames = function(scraper_obj) { var form, params, url; params = { - file: btoa(unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list())))), + file: 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/'; + url = scraper_obj.is_wishlist != null ? 'https://isthereanydeal.com/waitlist/import/' : 'https://httpbin.org/post'; form = $("").attr('action', url); params['returnTo'] = location.href; form.css({ @@ -485,6 +529,11 @@ TODO: $(function() { var e, fn, i, len, profile, profile_matched, ref, regex, results1, scraper; console.log("Loading ITAD importer..."); + console.log(location.host); + console.log(location.host.match(/\.itch\.io/)); + if (location.host.match(/\.itch\.io/)) { + scrapers[location.host] = scrapers['itch.io']; + } if (scrapers[location.host]) { console.log("Matched domain: " + location.host); ref = scrapers[location.host]; From a627386c299a06830eca09be69e3cc9d0f7b22d6 Mon Sep 17 00:00:00 2001 From: Reuben Peterkin Date: Tue, 28 Aug 2018 10:27:18 +1000 Subject: [PATCH 3/8] this now works --- itad_importer.user.coffee | 16 ++++++++-------- itad_importer.user.js | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/itad_importer.user.coffee b/itad_importer.user.coffee index be0ecb4..a8ffba1 100644 --- a/itad_importer.user.coffee +++ b/itad_importer.user.coffee @@ -241,7 +241,7 @@ scrapers = .prependTo($('.collection-header').filter(':first')) 'itch.io': - '^https?://itch\\.io/my-purchadses': + '^https?://itch\\.io/my-purchases': 'source_id': 'itchio' 'game_list': -> old_date=0 @@ -291,7 +291,7 @@ scrapers = #.attr('title').trim() title: $('.object_title',x).first().text().trim() copies: [{ - added: new Date($('abbr').first().attr('title')).getTime()/1000 + added: new Date($('abbr',x).attr('title').replace('@','')).getTime()/1000 #if (new_date == null) # new_date=o # added: new Date($('span',$('.date_header',x)).first().attr('title')).getTime()/1000 @@ -303,7 +303,7 @@ scrapers = } 'insert_button': -> - console.debug("insert_button called for GOG collection page") + console.debug("insert_button called for itch.io download page") $("") .css float: 'right' @@ -313,7 +313,7 @@ scrapers = marginBottom: '-2em' zIndex: 1 .html(BUTTON_LABEL + " (This Page)") - .appendTo($('.header_tabs').filter(':first')) + .appendTo($('.header_nav_tabs').filter(':first')) 'groupees.com': @@ -423,16 +423,16 @@ scrapers['www.groupees.com'] = scrapers['groupees.com'] # Callback for the button scrapeGames = (scraper_obj) -> params = { - file: unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list()))) -# file: btoa(unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list())))), +# file: unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list()))) + file: btoa(unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list())))), upload: 'x' } url = if scraper_obj.is_wishlist? 'https://isthereanydeal.com/waitlist/import/' else - 'https://httpbin.org/post' -# 'https://isthereanydeal.com/collection/import/' +# 'https://httpbin.org/post' + 'https://isthereanydeal.com/collection/import/' # **TODO:** Figure out why attempting to use an iframe for non-HTTPS sites # navigates the top-level window. diff --git a/itad_importer.user.js b/itad_importer.user.js index d0ef336..11f4114 100644 --- a/itad_importer.user.js +++ b/itad_importer.user.js @@ -289,7 +289,7 @@ TODO: } }, 'itch.io': { - '^https?://itch\\.io/my-purchadses': { + '^https?://itch\\.io/my-purchases': { 'source_id': 'itchio', 'game_list': function() { var new_date, old_date, x; @@ -349,7 +349,7 @@ TODO: title: $('.object_title', x).first().text().trim(), copies: [ { - added: new Date($('abbr').first().attr('title')).getTime() / 1000, + added: new Date($('abbr', x).attr('title').replace('@', '')).getTime() / 1000, type: 'itchio', status: 'redeemed', owned: 1 @@ -362,14 +362,14 @@ TODO: }; }, 'insert_button': function() { - console.debug("insert_button called for GOG collection page"); + console.debug("insert_button called for itch.io download page"); return $("").css({ float: 'right', cursor: 'pointer', position: 'relative', marginBottom: '-2em', zIndex: 1 - }).html(BUTTON_LABEL + " (This Page)").appendTo($('.header_tabs').filter(':first')); + }).html(BUTTON_LABEL + " (This Page)").appendTo($('.header_nav_tabs').filter(':first')); } } }, @@ -510,10 +510,10 @@ TODO: scrapeGames = function(scraper_obj) { var form, params, url; params = { - file: unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list()))), + file: btoa(unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list())))), upload: 'x' }; - url = scraper_obj.is_wishlist != null ? 'https://isthereanydeal.com/waitlist/import/' : 'https://httpbin.org/post'; + url = scraper_obj.is_wishlist != null ? 'https://isthereanydeal.com/waitlist/import/' : 'https://isthereanydeal.com/collection/import/'; form = $("").attr('action', url); params['returnTo'] = location.href; form.css({ From 0bb4ee89bb92d8f73313ab6fce7569062f0e7f07 Mon Sep 17 00:00:00 2001 From: Reuben Peterkin Date: Fri, 1 Mar 2019 14:15:29 +1000 Subject: [PATCH 4/8] use product name not title --- itad_importer.user.coffee | 6 +++--- itad_importer.user.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/itad_importer.user.coffee b/itad_importer.user.coffee index a8ffba1..6c1a1ae 100644 --- a/itad_importer.user.coffee +++ b/itad_importer.user.coffee @@ -91,7 +91,7 @@ humble_parse = -> { .downloads.linux .download, .downloads.mac .download, .downloads.android .download' - ).find('div.title')} + ).find('div.product-name')} # Scrapers are looked up first by domain (lightweight) and then by # a regex check on the URL (accurate). @@ -423,8 +423,8 @@ scrapers['www.groupees.com'] = scrapers['groupees.com'] # Callback for the button scrapeGames = (scraper_obj) -> params = { -# file: unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list()))) - file: btoa(unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list())))), + file: unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list()))) +# file: btoa(unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list())))), upload: 'x' } diff --git a/itad_importer.user.js b/itad_importer.user.js index 11f4114..fa1f8f1 100644 --- a/itad_importer.user.js +++ b/itad_importer.user.js @@ -73,7 +73,7 @@ TODO: version: "02", data: (function() { var i, len, ref, results1; - ref = $('div.row').has(' .downloads.windows .download, .downloads.linux .download, .downloads.mac .download, .downloads.android .download').find('div.title'); + ref = $('div.row').has(' .downloads.windows .download, .downloads.linux .download, .downloads.mac .download, .downloads.android .download').find('div.product-name'); results1 = []; for (i = 0, len = ref.length; i < len; i++) { x = ref[i]; @@ -510,7 +510,7 @@ TODO: scrapeGames = function(scraper_obj) { var form, params, url; params = { - file: btoa(unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list())))), + file: 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/'; From 5bc1f0a83954e66eccc4baae6f056393f1a63f51 Mon Sep 17 00:00:00 2001 From: Reuben Peterkin Date: Fri, 1 Mar 2019 15:34:50 +1000 Subject: [PATCH 5/8] Make sure time is imported as GMT/UTC --- itad_importer.user.coffee | 12 ++++++++---- itad_importer.user.js | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/itad_importer.user.coffee b/itad_importer.user.coffee index 6c1a1ae..9518031 100644 --- a/itad_importer.user.coffee +++ b/itad_importer.user.coffee @@ -67,6 +67,9 @@ gog_prepare_title = (elem) -> $('._product-flag', dom).remove() dom.text() +itch_plain = (elem) -> + elem.toLowerCase(); + humble_make_button = -> # Humble Library uses very weird button markup label = $('').html(BUTTON_LABEL) @@ -289,9 +292,10 @@ scrapers = "data": { # id: attr(x, 'gog-account-product') #.attr('title').trim() - title: $('.object_title',x).first().text().trim() + title: $('.object_title',x).first().text().replace(" "," ").trim() +# plain: itch_plain($('.object_title',x).first().text().trim()) copies: [{ - added: new Date($('abbr',x).attr('title').replace('@','')).getTime()/1000 + added: new Date($('abbr',x).attr('title').replace('@','') + " UTC").getTime()/1000 #if (new_date == null) # new_date=o # added: new Date($('span',$('.date_header',x)).first().attr('title')).getTime()/1000 @@ -423,8 +427,8 @@ scrapers['www.groupees.com'] = scrapers['groupees.com'] # Callback for the button scrapeGames = (scraper_obj) -> params = { - file: unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list()))) -# file: btoa(unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list())))), +# file: unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list()))) + file: btoa(unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list())))), upload: 'x' } diff --git a/itad_importer.user.js b/itad_importer.user.js index fa1f8f1..6f5c6cd 100644 --- a/itad_importer.user.js +++ b/itad_importer.user.js @@ -39,7 +39,7 @@ TODO: */ (function() { - var BUTTON_LABEL, ITAD_12X12, ITAD_14X14_GRAY, attr, gog_prepare_title, humble_make_button, humble_parse, scrapeGames, scrapers; + var BUTTON_LABEL, ITAD_12X12, ITAD_14X14_GRAY, attr, gog_prepare_title, humble_make_button, humble_parse, itch_plain, scrapeGames, scrapers; BUTTON_LABEL = "Export to ITAD"; @@ -60,6 +60,10 @@ TODO: return dom.text(); }; + itch_plain = function(elem) { + return elem.toLowerCase(); + }; + humble_make_button = function() { var a, button, label; label = $('').html(BUTTON_LABEL); @@ -346,10 +350,10 @@ TODO: for (i = 0, len = ref.length; i < len; i++) { x = ref[i]; results1.push({ - title: $('.object_title', x).first().text().trim(), + title: $('.object_title', x).first().text().replace(" ", " ").trim(), copies: [ { - added: new Date($('abbr', x).attr('title').replace('@', '')).getTime() / 1000, + added: new Date($('abbr', x).attr('title').replace('@', '') + " UTC").getTime() / 1000, type: 'itchio', status: 'redeemed', owned: 1 @@ -510,7 +514,7 @@ TODO: scrapeGames = function(scraper_obj) { var form, params, url; params = { - file: unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list()))), + 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/'; From e74eb9966d704787bb18baef27481acaf93f707c Mon Sep 17 00:00:00 2001 From: Reuben Peterkin Date: Wed, 3 Apr 2019 11:55:38 +1000 Subject: [PATCH 6/8] filter by first inner_column --- itad_importer.user.coffee | 2 +- itad_importer.user.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/itad_importer.user.coffee b/itad_importer.user.coffee index 9518031..513916d 100644 --- a/itad_importer.user.coffee +++ b/itad_importer.user.coffee @@ -303,7 +303,7 @@ scrapers = status: 'redeemed', owned: 1, }] - } for x in $('.inner_column') + } for x in $('.inner_column').filter(':first') } 'insert_button': -> diff --git a/itad_importer.user.js b/itad_importer.user.js index 6f5c6cd..8d25c26 100644 --- a/itad_importer.user.js +++ b/itad_importer.user.js @@ -345,7 +345,7 @@ TODO: "version": "02", "data": (function() { var i, len, ref, results1; - ref = $('.inner_column'); + ref = $('.inner_column').filter(':first'); results1 = []; for (i = 0, len = ref.length; i < len; i++) { x = ref[i]; From 3c0976779d20f9015d9a2d03862d69bc1296226d Mon Sep 17 00:00:00 2001 From: Reuben Peterkin Date: Wed, 3 Apr 2019 12:08:36 +1000 Subject: [PATCH 7/8] remove debugging/testing minor logging fix whitespace --- itad_importer.user.coffee | 11 ++++------- itad_importer.user.js | 6 ++---- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/itad_importer.user.coffee b/itad_importer.user.coffee index 513916d..85b7b13 100644 --- a/itad_importer.user.coffee +++ b/itad_importer.user.coffee @@ -94,7 +94,7 @@ humble_parse = -> { .downloads.linux .download, .downloads.mac .download, .downloads.android .download' - ).find('div.product-name')} + ).find('div.title')} # Scrapers are looked up first by domain (lightweight) and then by # a regex check on the URL (accurate). @@ -270,7 +270,7 @@ scrapers = } 'insert_button': -> - console.debug("insert_button called for GOG collection page") + console.debug("insert_button called for itch.io collection page") $("") .css float: 'right' @@ -427,15 +427,14 @@ scrapers['www.groupees.com'] = scrapers['groupees.com'] # Callback for the button scrapeGames = (scraper_obj) -> params = { -# file: unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list()))) - file: btoa(unescape(encodeURIComponent(JSON.stringify(scraper_obj.game_list())))), + file: btoa(unescape(encodeURIComponent(JSON.stringify( + scraper_obj.game_list())))), upload: 'x' } url = if scraper_obj.is_wishlist? 'https://isthereanydeal.com/waitlist/import/' else -# 'https://httpbin.org/post' 'https://isthereanydeal.com/collection/import/' # **TODO:** Figure out why attempting to use an iframe for non-HTTPS sites @@ -461,8 +460,6 @@ $ -> # It seems we don't need an explicit `if location.host of scrapers` # before the `for` loop console.log("Loading ITAD importer...") - console.log(location.host) - console.log(location.host.match(/\.itch\.io/)) if location.host.match(/\.itch\.io/) scrapers[location.host] = scrapers['itch.io'] if scrapers[location.host] diff --git a/itad_importer.user.js b/itad_importer.user.js index 8d25c26..3e8faa8 100644 --- a/itad_importer.user.js +++ b/itad_importer.user.js @@ -77,7 +77,7 @@ TODO: version: "02", data: (function() { var i, len, ref, results1; - ref = $('div.row').has(' .downloads.windows .download, .downloads.linux .download, .downloads.mac .download, .downloads.android .download').find('div.product-name'); + ref = $('div.row').has(' .downloads.windows .download, .downloads.linux .download, .downloads.mac .download, .downloads.android .download').find('div.title'); results1 = []; for (i = 0, len = ref.length; i < len; i++) { x = ref[i]; @@ -326,7 +326,7 @@ TODO: }; }, 'insert_button': function() { - console.debug("insert_button called for GOG collection page"); + console.debug("insert_button called for itch.io collection page"); return $("").css({ float: 'right', cursor: 'pointer', @@ -533,8 +533,6 @@ TODO: $(function() { var e, fn, i, len, profile, profile_matched, ref, regex, results1, scraper; console.log("Loading ITAD importer..."); - console.log(location.host); - console.log(location.host.match(/\.itch\.io/)); if (location.host.match(/\.itch\.io/)) { scrapers[location.host] = scrapers['itch.io']; } From ac0315b97d6c26cd52943a494afa2c6ff429cfe8 Mon Sep 17 00:00:00 2001 From: Reuben Date: Wed, 23 Oct 2019 21:09:32 +1000 Subject: [PATCH 8/8] remove broken collection page method --- itad_importer.user.coffee | 102 +++++++++++++++++++++++--------------- itad_importer.user.js | 72 ++++++++++----------------- 2 files changed, 90 insertions(+), 84 deletions(-) diff --git a/itad_importer.user.coffee b/itad_importer.user.coffee index 85b7b13..f98394a 100644 --- a/itad_importer.user.coffee +++ b/itad_importer.user.coffee @@ -62,6 +62,21 @@ this.$ = this.jQuery = jQuery.noConflict(true) # Less overhead than instantiating a new jQuery object attr = (node, name) -> node.getAttribute(name) +#from http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter + +romanise_numbers = (elem) -> + elem = elem.replace(/1/g,"i") + elem = elem.replace(/2/g,"ii") + elem = elem.replace(/3/g,"iii") + elem = elem.replace(/4/g,"iv") + elem = elem.replace(/5/g,"v") + elem = elem.replace(/6/g,"vi") + elem = elem.replace(/7/g,"vii") + elem = elem.replace(/8/g,"viii") + elem = elem.replace(/9/g,"ix") + elem = elem.replace(/9/g,"ix") + + gog_prepare_title = (elem) -> dom = $('.product-title', elem).clone() $('._product-flag', dom).remove() @@ -70,6 +85,15 @@ gog_prepare_title = (elem) -> itch_plain = (elem) -> elem.toLowerCase(); +title_plain = (elem) -> + plain = elem; + plain = plain.toLowerCase() + plain = plain.replace(/\bthe\b/g,"") + plain = plain.replace(/ & /g," and ") + plain = plain.replace(" ","") + plain = plain.replace(/[\s\.\!@"#$%^&'*\(\)\-:_+=;,\?]/g,"") + return romanise_numbers(plain); + humble_make_button = -> # Humble Library uses very weird button markup label = $('').html(BUTTON_LABEL) @@ -244,43 +268,43 @@ scrapers = .prependTo($('.collection-header').filter(':first')) 'itch.io': - '^https?://itch\\.io/my-purchases': - 'source_id': 'itchio' - 'game_list': -> - old_date=0 - new_date=null - console.debug("game_list called for itch.io collection page") - { -# new_date=0 - "version": "02", - "data": { - # id: attr(x, 'gog-account-product') - #.attr('title').trim() - title: $('.title.game_link',x).first().text().trim() - copies: [{ - new_date: new Date($('span',$('.date_header',x)).first().attr('title')).getTime()/1000 -#if (new_date == null) -# new_date=o - added: new Date($('span',$('.date_header',x)).first().attr('title')).getTime()/1000 - type: 'itchio', - status: 'redeemed', - owned: 1, - }] - } for x in $('.game_cell') - } - - 'insert_button': -> - console.debug("insert_button called for itch.io collection page") - $("") - .css - float: 'right' - cursor: 'pointer' - # TODO: Replace the following hacks with whatever GOG uses - position: 'relative' - marginBottom: '-2em' - zIndex: 1 - .html(BUTTON_LABEL + " (This Page)") - .appendTo($('.header_tabs').filter(':first')) +# '^https?://itch\\.io/my-purchases': +# 'source_id': 'itchio' +# 'game_list': -> +# old_date=0 +# new_date=null +# console.debug("game_list called for itch.io collection page") +# { +# # new_date=0 +# "version": "02", +# "data": { +# # id: attr(x, 'gog-account-product') +# #.attr('title').trim() +# title: $('.title.game_link',x).first().text().trim() +# copies: [{ +# new_date: new Date($('span',$('.date_header',x)).first().attr('title')).getTime()/1000 +# #if (new_date == null) +# # new_date=o +# added: new Date($('span',$('.date_header',x)).first().attr('title')).getTime()/1000 +# type: 'itchio', +# status: 'redeemed', +# owned: 1, +# }] +# } for x in $('.game_cell') +# } +# +# 'insert_button': -> +# console.debug("insert_button called for itch.io collection page") +# $("") +# .css +# float: 'right' +# cursor: 'pointer' +# # TODO: Replace the following hacks with whatever GOG uses +# position: 'relative' +# marginBottom: '-2em' +# zIndex: 1 +# .html(BUTTON_LABEL + " (This Page)") +# .appendTo($('.header_tabs').filter(':first')) '^https?://.+\\.itch\\.io/.+/download/.+': # '^https?://itch\\.io/my-purchases': @@ -293,9 +317,9 @@ scrapers = # id: attr(x, 'gog-account-product') #.attr('title').trim() title: $('.object_title',x).first().text().replace(" "," ").trim() -# plain: itch_plain($('.object_title',x).first().text().trim()) + plain: title_plain($('.object_title',x).first().text().trim()) copies: [{ - added: new Date($('abbr',x).attr('title').replace('@','') + " UTC").getTime()/1000 + added: new Date($('p > abbr',x).attr('title').replace('@','') + " UTC").getTime()/1000 #if (new_date == null) # new_date=o # added: new Date($('span',$('.date_header',x)).first().attr('title')).getTime()/1000 diff --git a/itad_importer.user.js b/itad_importer.user.js index 3e8faa8..af100ec 100644 --- a/itad_importer.user.js +++ b/itad_importer.user.js @@ -39,7 +39,7 @@ TODO: */ (function() { - var BUTTON_LABEL, ITAD_12X12, ITAD_14X14_GRAY, attr, gog_prepare_title, humble_make_button, humble_parse, itch_plain, scrapeGames, scrapers; + var BUTTON_LABEL, ITAD_12X12, ITAD_14X14_GRAY, attr, gog_prepare_title, humble_make_button, humble_parse, itch_plain, romanise_numbers, scrapeGames, scrapers, title_plain; BUTTON_LABEL = "Export to ITAD"; @@ -53,6 +53,19 @@ TODO: return node.getAttribute(name); }; + romanise_numbers = function(elem) { + elem = elem.replace(/1/g, "i"); + elem = elem.replace(/2/g, "ii"); + elem = elem.replace(/3/g, "iii"); + elem = elem.replace(/4/g, "iv"); + elem = elem.replace(/5/g, "v"); + elem = elem.replace(/6/g, "vi"); + elem = elem.replace(/7/g, "vii"); + elem = elem.replace(/8/g, "viii"); + elem = elem.replace(/9/g, "ix"); + return elem = elem.replace(/9/g, "ix"); + }; + gog_prepare_title = function(elem) { var dom; dom = $('.product-title', elem).clone(); @@ -64,6 +77,17 @@ TODO: return elem.toLowerCase(); }; + title_plain = function(elem) { + var plain; + plain = elem; + plain = plain.toLowerCase(); + plain = plain.replace(/\bthe\b/g, ""); + plain = plain.replace(/ & /g, " and "); + plain = plain.replace(" ", ""); + plain = plain.replace(/[\s\.\!@"#$%^&'*\(\)\-:_+=;,\?]/g, ""); + return romanise_numbers(plain); + }; + humble_make_button = function() { var a, button, label; label = $('').html(BUTTON_LABEL); @@ -293,49 +317,6 @@ TODO: } }, 'itch.io': { - '^https?://itch\\.io/my-purchases': { - 'source_id': 'itchio', - 'game_list': function() { - var new_date, old_date, x; - old_date = 0; - new_date = null; - console.debug("game_list called for itch.io collection page"); - return { - "version": "02", - "data": (function() { - var i, len, ref, results1; - ref = $('.game_cell'); - results1 = []; - for (i = 0, len = ref.length; i < len; i++) { - x = ref[i]; - results1.push({ - title: $('.title.game_link', x).first().text().trim(), - copies: [ - { - new_date: new Date($('span', $('.date_header', x)).first().attr('title')).getTime() / 1000, - added: new Date($('span', $('.date_header', x)).first().attr('title')).getTime() / 1000, - type: 'itchio', - status: 'redeemed', - owned: 1 - } - ] - }); - } - return results1; - })() - }; - }, - 'insert_button': function() { - console.debug("insert_button called for itch.io collection page"); - return $("").css({ - float: 'right', - cursor: 'pointer', - position: 'relative', - marginBottom: '-2em', - zIndex: 1 - }).html(BUTTON_LABEL + " (This Page)").appendTo($('.header_tabs').filter(':first')); - } - }, '^https?://.+\\.itch\\.io/.+/download/.+': { 'source_id': 'itchio', 'game_list': function() { @@ -351,9 +332,10 @@ TODO: x = ref[i]; results1.push({ title: $('.object_title', x).first().text().replace(" ", " ").trim(), + plain: title_plain($('.object_title', x).first().text().trim()), copies: [ { - added: new Date($('abbr', x).attr('title').replace('@', '') + " UTC").getTime() / 1000, + added: new Date($('p > abbr', x).attr('title').replace('@', '') + " UTC").getTime() / 1000, type: 'itchio', status: 'redeemed', owned: 1