-
-
Save abraxas86/ad72ba46b6cdd86dc63058bba0c629c2 to your computer and use it in GitHub Desktop.
| // ==UserScript== | |
| // @name Itch Collection CSV Exporter | |
| // @namespace https://github.com/abraxas86/tampermonkey-scripts/blob/main/itch.io/ | |
| // @version 4.5 | |
| // @description Scroll down to the bottom of your collection, click the button, get CSV of your collection! | |
| // @author Abraxas86 | |
| // @match https://itch.io/c/* | |
| // @match https://itch.io/my-purchases | |
| // @match https://itch.io/b/* | |
| // @match https://itch.io/bundle/* | |
| // @match https://itch.io/s/* | |
| // @require https://gist.github.com/raw/2625891/waitForKeyElements.js | |
| // @require https://raw.githubusercontent.com/eligrey/FileSaver.js/master/src/FileSaver.js | |
| // @grant none | |
| // @icon https://itch.io//static/images/itchio-square-144.png | |
| // ==/UserScript== | |
| /* globals jQuery, $, waitForKeyElements, saveAs */ | |
| (function() { | |
| 'use strict'; | |
| const games = []; | |
| let mode = "null"; | |
| let gameID = ""; | |
| let imagePath = ""; | |
| let Title = ""; | |
| let Synopsis = ""; | |
| let Author = ""; | |
| let Genre = ""; | |
| let URL = ""; | |
| let Blurb = ""; | |
| let output = "gameid,genre,title,author,synopsis,imagepath,url,blurb\n"; | |
| let filename = $('.grid_header > h2:nth-child(1)').text(); | |
| if(!filename) { | |
| filename = $('.stat_header_widget .text_container h2 .object_title').text(); | |
| } | |
| waitForKeyElements(".game_link", makeRed); | |
| if (document.querySelector('[class*=bundle_download_page]')) { | |
| mode = "bundle"; | |
| } else if (document.querySelector('[class*=game_list]')) { | |
| mode = "list"; | |
| } else if (document.querySelector('[id^=game_grid]') || document.querySelector('[class*=bundle]')) { | |
| mode = "grid"; | |
| } else { | |
| mode = "Error"; | |
| } | |
| //alert(mode); | |
| $('.footer').prepend('<span class="csvButton">Export to CSV</span> <input type="text" id="fileName" class="csvText" value=""> <span class="extension">.csv</span><p></p>'); | |
| $('#fileName').attr("value", filename); | |
| $('.csvButton').css({'color':'white','background-color':'grey','border-radius':'10px','padding':'15px','cursor':'pointer'}); | |
| $('.extension').css({'font-size':'14pt'}); | |
| $('.csvText').css({'padding':'5px','border':'none','border-radius':'10px','font-size':'13pt','background-color':'#555555','color':'#BCBCBC','text-align':'right'}); | |
| function makeRed() { | |
| $('.game_link').css("color", "red"); | |
| } | |
| $('.csvButton').click(function() { | |
| // These elements will mess up our data for the CSV. | |
| $('.price_value').remove(); | |
| $('.gif_label').remove(); | |
| console.log("======= Game Package Data ======="); | |
| // GRID MODE | |
| if (mode == 'grid') { | |
| $('.game_cell').each(function() { | |
| const cell = $(this); | |
| // Itch Game ID | |
| gameID = cell.attr('data-game_id'); | |
| console.log("gameID: " + gameID); | |
| // Path to thumbnail | |
| imagePath = cell.find('.lazy_loaded').attr('src'); | |
| console.log("imagePath: " + imagePath); | |
| // Game Title Note Note: .title is for bundle compatibility | |
| Title = cell.find('.game_title, .title').text().replace(/"/g, '""'); | |
| console.log("Title: " + Title); | |
| // Game URL Note: .title is for bundle compatibility | |
| URL = cell.find('.game_title a, .title').attr('href'); | |
| console.log("URL: " + URL); | |
| // Game Synopsis Note: .short_text is for bundle compatibility | |
| Synopsis = cell.find('.game_text, .short_text').text().replace(/"/g, '""'); | |
| console.log("Synopsis: " + Synopsis); | |
| // Game Author | |
| Author = cell.find('.game_author, .user_link').text().replace(/"/g, '""'); | |
| console.log("Author: " + Author); | |
| // Game Genre | |
| Genre = cell.find('.game_genre').text().replace(/"/g, '""'); | |
| console.log("Genre: " + Genre); | |
| // Game Blurb (user-created comment about library item) | |
| Blurb = cell.find('.blurb_drop').text().trim().replace(/"/g, '""'); | |
| console.log("Blurb: " + Blurb); | |
| // Build Array to push to CSV File, sanitizing data to prevent commas in scraped data from screwing things up | |
| games.push(`"${gameID}","${Genre}","${Title}","${Author}","${Synopsis}","${imagePath}","${URL}","${Blurb}"`); | |
| }); | |
| } else if (mode == 'list') { | |
| $('.game_row').each(function() { | |
| const row = $(this); | |
| // Game Title | |
| Title = row.find('.conversion_link_widget .game_title').text().replace(/"/g, '""'); | |
| console.log("Title: " + Title); | |
| // Itch Game ID | |
| gameID = row.find('.game_cell').attr('data-game_id'); | |
| console.log("gameID: " + gameID); | |
| // Path to thumbnail | |
| imagePath = row.find('.game_thumb').attr('src'); | |
| console.log("imagePath: " + imagePath); | |
| // Game URL | |
| URL = row.find('.game_title').attr('href'); | |
| console.log("URL: " + URL); | |
| // Game Synopsis (not avaiable in list mode) | |
| Synopsis = ""; | |
| console.log("Synopsis: " + Synopsis); | |
| // Game Author | |
| Author = row.find('.author_link').text().replace(/"/g, '""'); | |
| console.log("Author: " + Author); | |
| // Game Genre | |
| Genre = row.find('.game_genre').text().replace(/"/g, '""'); | |
| console.log("Genre: " + Genre); | |
| // Game Blurb | |
| Blurb = row.find('.blurb_drop').text().trim().replace(/"/g, '""'); | |
| console.log("Blurb: " + Blurb); | |
| // Build Array to push to CSV File, sanitizing data to prevent commas in scraped data from screwing things up | |
| games.push(`"${gameID}","${Genre}","${Title}","${Author}","${Synopsis}","${imagePath}","${URL}","${Blurb}"`); | |
| }); | |
| } else if (mode == 'bundle') { | |
| $('.game_row').each(function() { | |
| const row = $(this); | |
| // Path to thumbnail | |
| imagePath = row.find('.game_thumb').attr('data-background_image'); | |
| console.log("imagePath: " + imagePath); | |
| // Game URL | |
| URL = row.find('.game_title a').attr('href'); | |
| console.log("URL: " + URL); | |
| // Game Title | |
| Title = row.find('.game_title a').text().replace(/"/g, '""'); | |
| console.log("Title: " + Title); | |
| // Game Synopsis | |
| Synopsis = row.find('.game_short_text').text().trim().replace(/"/g, '""'); | |
| console.log("Synopsis: " + Synopsis); | |
| // Game Author | |
| Author = row.find('.game_author a').text().replace(/"/g, '""'); | |
| console.log("Author: " + Author); | |
| // GameID (not available in bundle lists) | |
| gameID = ""; | |
| console.log("gameID: " + gameID); | |
| // Game Blurb (not available in bundle lists) | |
| Blurb = ""; | |
| console.log("Blurb: " + Blurb); | |
| // Build Array to push to CSV File | |
| games.push(`"${gameID}","${Genre}","${Title}","${Author}","${Synopsis}","${imagePath}","${URL}","${Blurb}"`); | |
| }); | |
| } else if (mode == 'bundlegrid') { | |
| $('.game_cell').each(function() { | |
| const cell = $(this); | |
| // Itch Game ID | |
| gameID = cell.attr('data-game_id'); | |
| console.log("gameID: " + gameID); | |
| // Path to thumbnail | |
| imagePath = cell.find('.lazy_loaded').attr('src'); | |
| console.log("imagePath: " + imagePath); | |
| // Game Title | |
| Title = cell.find('.game_title').text().replace(/"/g, '""'); | |
| console.log("Title: " + Title); | |
| // Game URL | |
| URL = cell.find('.game_title a').attr('href'); | |
| console.log("URL: " + URL); | |
| // Game Synopsis | |
| Synopsis = cell.find('.game_text').text().replace(/"/g, '""'); | |
| console.log("Synopsis: " + Synopsis); | |
| // Game Author | |
| Author = cell.find('.game_author').text().replace(/"/g, '""'); | |
| console.log("Author: " + Author); | |
| // Game Genre | |
| Genre = cell.find('.game_genre').text().replace(/"/g, '""'); | |
| console.log("Genre: " + Genre); | |
| // Game Blurb (user-created comment about library item) | |
| Blurb = cell.find('.blurb_drop').text().trim().replace(/"/g, '""'); | |
| console.log("Blurb: " + Blurb); | |
| // Build Array to push to CSV File, sanitizing data to prevent commas in scraped data from screwing things up | |
| games.push(`"${gameID}","${Genre}","${Title}","${Author}","${Synopsis}","${imagePath}","${URL}","${Blurb}"`); | |
| }); | |
| } else { | |
| alert("Error: Unable to correctly identify code."); | |
| } | |
| // Format array for CSV output, sanitizing for titles with commas, | |
| // and adding a newline at the end of each title | |
| for (let i = 0; i < games.length; i++) { | |
| output += games[i] + "\n"; | |
| } | |
| filename = document.getElementById("fileName").value; | |
| if (filename === "") { | |
| filename = "collection"; | |
| } | |
| filename = filename + ".csv"; | |
| const blob = new Blob([output], { | |
| type: "text/plain;charset=utf-8" | |
| }); | |
| saveAs(blob, filename); | |
| }); | |
| })(); |
4.5
Getting duplicate titles with grid view.
e.g.
Brütal LegendBrütal Legend
Changing to the following seemed to fix it:
// Game Title Note Note: .title is for bundle compatibility
Title = cell.find('.game_link, .title').text().replace(/"/g, '""');
console.log("Title: " + Title);
4.5
IntuitiveThinker on Itch had asked if there was a way to differentiate different types of content (games, books, physical games, soundtracks, etc). I couldn't find any way to do this, so I was thinking that adding it to the Blurb is probably the best way to manage it. If Itch ever expands to allow this type of info to be added, I will update the script to reflect the change.
hey i figured out a way to do this, at least in grid mode while on a bundle page (https://itch.io/b/*)
Category = cell.find('.cell_tags a').attr('href');
if(Category == undefined){
Category = "games";
} else {
Category = Category.replace(/\//g, "");
}
a bit ugly but it works
4.5
IntuitiveThinker on Itch had asked if there was a way to differentiate different types of content (games, books, physical games, soundtracks, etc). I couldn't find any way to do this, so I was thinking that adding it to the Blurb is probably the best way to manage it. If Itch ever expands to allow this type of info to be added, I will update the script to reflect the change.
hey i figured out a way to do this, at least in grid mode while on a bundle page (
https://itch.io/b/*)Category = cell.find('.cell_tags a').attr('href'); if(Category == undefined){ Category = "games"; } else { Category = Category.replace(/\//g, ""); }a bit ugly but it works
if(Category === undefined){ may be safer but I'm not a JS expert.
4.5
Forgot to remove a line of debug code. The functionality it self was also broken and I didn't catch it. It's good now I hope. It passed the tests I threw at it, at least.