diff --git a/itchiodl/downloader/__main__.py b/itchiodl/downloader/__main__.py index aada99d..70e2223 100644 --- a/itchiodl/downloader/__main__.py +++ b/itchiodl/downloader/__main__.py @@ -1,5 +1,6 @@ import argparse from getpass import getpass +import re import itchiodl @@ -25,6 +26,18 @@ def main(): help="Number of concurrent downloads, defaults to 4", ) + parser.add_argument( + "--download-publisher", + type=str, + help="Download all games from a specific publisher", + ) + + parser.add_argument( + "--download-game", + type=str, + help="Download a specific game, should be in the format publisher.itch.io/game", + ) + args = parser.parse_args() l = "" @@ -37,7 +50,15 @@ def main(): l = args.api_key lib = itchiodl.Library(l, args.jobs) - lib.load_games() + + if args.download_publisher: + lib.load_games(args.download_publisher) + elif args.download_game: + matches = re.match(r"https://(.+)\.itch\.io/(.+)", args.download_game) + lib.load_game(matches.group(1), matches.group(2)) + else: + lib.load_owned_games() + lib.download_library(args.platform) diff --git a/itchiodl/game.py b/itchiodl/game.py index 314932d..c080354 100644 --- a/itchiodl/game.py +++ b/itchiodl/game.py @@ -18,9 +18,12 @@ class Game: self.name = self.data["title"] self.publisher = self.data["user"]["username"] self.link = self.data["url"] - - self.id = data["id"] - self.game_id = data["game_id"] + if "game_id" in self.data: + self.id = self.data["id"] + self.game_id = self.data["game_id"] + else: + self.id = False + self.game_id = self.data["id"] matches = re.match(r"https://(.+)\.itch\.io/(.+)", self.link) self.game_slug = matches.group(2) @@ -32,10 +35,16 @@ class Game: def load_downloads(self, token): """Load all downloads for this game""" self.downloads = [] - r = requests.get( - f"https://api.itch.io/games/{self.game_id}/uploads?download_key_id={self.id}", - headers={"Authorization": token}, - ) + if self.id: + r = requests.get( + f"https://api.itch.io/games/{self.game_id}/uploads?download_key_id={self.id}", + headers={"Authorization": token}, + ) + else: + r = requests.get( + f"https://api.itch.io/games/{self.game_id}/uploads", + headers={"Authorization": token}, + ) j = r.json() for d in j["uploads"]: self.downloads.append(d) @@ -129,10 +138,16 @@ class Game: j = r.json() # Download - url = ( - f"https://api.itch.io/uploads/{d['id']}/" - + f"download?api_key={token}&download_key_id={self.id}&uuid={j['uuid']}" - ) + if self.id: + url = ( + f"https://api.itch.io/uploads/{d['id']}/" + + f"download?api_key={token}&download_key_id={self.id}&uuid={j['uuid']}" + ) + else: + url = ( + f"https://api.itch.io/uploads/{d['id']}/" + + f"download?api_key={token}&uuid={j['uuid']}" + ) # response_code = urllib.request.urlopen(url).getcode() try: itchiodl.utils.download(url, path, self.name, file) diff --git a/itchiodl/library.py b/itchiodl/library.py index 6503c37..4c6bc44 100644 --- a/itchiodl/library.py +++ b/itchiodl/library.py @@ -3,6 +3,7 @@ from concurrent.futures import ThreadPoolExecutor import functools import threading import requests +from bs4 import BeautifulSoup from itchiodl.game import Game @@ -29,7 +30,7 @@ class Library: return len(j["owned_keys"]) - def load_games(self): + def load_owned_games(self): """Load all games in the library via the API""" page = 1 while True: @@ -38,9 +39,36 @@ class Library: break page += 1 + def load_game(self, publisher, title): + """Load a game by publisher and title""" + rsp = requests.get( + f"https://{publisher}.itch.io/{title}/data.json", + headers={"Authorization": self.login}, + ) + j = json.loads(rsp.text) + game_id = j["id"] + gsp = requests.get( + f"https://api.itch.io/games/{game_id}", + headers={"Authorization": self.login}, + ) + k = json.loads(gsp.text) + self.games.append(Game(k)) + + def load_games(self, publisher): + """Load all games by publisher""" + rsp = requests.get(f"https://{publisher}.itch.io") + soup = BeautifulSoup(rsp.text, "html.parser") + for link in soup.select("a.game_link"): + game_id = link.get("data-label").split(":")[1] + gsp = requests.get( + f"https://api.itch.io/games/{game_id}", + headers={"Authorization": self.login}, + ) + k = json.loads(gsp.text) + self.games.append(Game(k)) + def download_library(self, platform=None): """Download all games in the library""" - with ThreadPoolExecutor(max_workers=self.jobs) as executor: i = [0] l = len(self.games) diff --git a/pyproject.toml b/pyproject.toml index 7b9fb74..606aeac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "itchiodl" -version = "2.0.0" +version = "2.1.0" description = "Python Scripts for downloading / archiving your itchio library" authors = ["Peter Taylor "] license = "MIT"