-
-
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 3.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 | |
// @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(); | |
waitForKeyElements(".game_link", makeRed); | |
if (document.querySelector('.game_title a') == null || document.querySelector('.game_title a') == undefined) { | |
mode = "list"; | |
} else { | |
mode = "grid"; | |
} | |
$('.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(); | |
// Scrape the game names from the code | |
// GRID MODE | |
if (mode == 'grid') { | |
$('.game_cell').each(function() { | |
console.log("======= Game Package Data ======="); | |
const $cell = $(this); | |
// Itch Game ID | |
gameID = $cell.attr('data-game_id'); | |
console.log("gameID: " + gameID); | |
// Path to thumbnail hosted on Itch | |
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 if (mode == 'list') { | |
$('.game_row').each(function() { | |
console.log("======= Game Package Data ======="); | |
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 hosted on Itch | |
imagePath = $row.find('.lazy_loaded').attr('src'); | |
console.log("imagePath: " + imagePath); | |
// Game URL | |
URL = $row.find('.game_title').attr('href'); | |
console.log("URL: " + URL); | |
// Game Synopsis | |
Synopsis = "Synopsis not available in List Mode libraries"; | |
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 { | |
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); | |
}); | |
})(); |
Jumping right to 2.5.
Changes:
- Game URLs now included in CSV
Jumped to 2.5 because the feature addition required a bit of a significant rewrite to the code.
3.0
Changes:
- Basically gutted and re-worked the code to scrape a whole bunch more data now :D
Former code only grabbed title and URL.
New code grabs:
- Title
- Author
- GameID
- Path to thumbnail on Itch
- Description (not available in list collections, only grid collections)
- Game URL
- Genre
Still some stuff that can be cleaned up, but it's 6am and I need to sleep lol
LOL left my self-deprecating debug code in there... whoops.
Also realized that I forgot to sanitize for quotes in strings. Update coming shortly
Done.
3.2
Changes:
- Fixed data to clean up lines that may have a double-quote
- Got rid of silly debug code
3.3
Untipo over on Itch pointed out that my script wasn't working on the purchases page. Good catch! Thanks.
I've added a new @match line so it will activate on the purchases page.
3.5
Refactored code to make it a bit less stupid in how it hunts for the data. Also exports "Blurb" text now. I think Itch intended for this to be used to write your own thoughts on each item, but you can also use it to add your own metadata to the csv.
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.
Thanks for the suggestion!
2.0: brings 2 "huge" updates.