mirror of
https://github.com/DragoonAethis/itch-dl.git
synced 2024-12-21 02:21:52 +01:00
Add support for downloading bundles
This commit is contained in:
parent
49ad7a719c
commit
9e006543c2
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Bulk download games from [itch.io](https://itch.io/).
|
Bulk download games from [itch.io](https://itch.io/).
|
||||||
|
|
||||||
- Can download game jams, browse pages (popular, newest, browse by tag...) and individual games.
|
- Can download game jams, browse pages (popular, newest, browse by tag...), bundles and individual games.
|
||||||
- Requires Python 3.8+, grab it from PyPI: `pip install itch-dl`
|
- Requires Python 3.8+, grab it from PyPI: `pip install itch-dl`
|
||||||
- For development, use [Poetry](https://python-poetry.org/).
|
- For development, use [Poetry](https://python-poetry.org/).
|
||||||
|
|
||||||
@ -19,9 +19,9 @@ More arguments are available - check them out with `itch-dl --help`.
|
|||||||
|
|
||||||
The downloader is able to grab more or less everything you can download via the itch app.
|
The downloader is able to grab more or less everything you can download via the itch app.
|
||||||
|
|
||||||
The input URL can be any "Browse" page (top, popular, newest, filtered by tags, etc) or any
|
The input URL can be any "Browse" page (top, popular, newest, filtered by tags, etc), any
|
||||||
game jam. The input can also be a path to a itch.io JSON file with game jam entries, or just
|
game jam or any bundle. The input can also be a path to a itch.io JSON file with game jam
|
||||||
a list of itch.io game URLs (not browse/jam pages!) to download.
|
entries, or just a list of itch.io game URLs (not browse pages!) to download.
|
||||||
|
|
||||||
**It's expected that the downloader output will not be complete** - logs are stupidly verbose
|
**It's expected that the downloader output will not be complete** - logs are stupidly verbose
|
||||||
and it prints a report on failed downloads and external URLs (links to files that are not on
|
and it prints a report on failed downloads and external URLs (links to files that are not on
|
||||||
|
@ -15,7 +15,7 @@ logging.getLogger().setLevel(logging.INFO)
|
|||||||
def parse_args() -> argparse.Namespace:
|
def parse_args() -> argparse.Namespace:
|
||||||
parser = argparse.ArgumentParser(description="Bulk download stuff from Itch.io.")
|
parser = argparse.ArgumentParser(description="Bulk download stuff from Itch.io.")
|
||||||
parser.add_argument("url_or_path",
|
parser.add_argument("url_or_path",
|
||||||
help="itch.io URL or path to a game jam entries.json file")
|
help="itch.io URL or path to either a game jam entries.json file or bundle games.json file")
|
||||||
parser.add_argument("--api-key", metavar="key", default=None,
|
parser.add_argument("--api-key", metavar="key", default=None,
|
||||||
help="itch.io API key - https://itch.io/user/settings/api-keys")
|
help="itch.io API key - https://itch.io/user/settings/api-keys")
|
||||||
parser.add_argument("--profile", metavar="profile", default=None,
|
parser.add_argument("--profile", metavar="profile", default=None,
|
||||||
|
@ -83,6 +83,21 @@ def get_jobs_for_browse_url(url: str, client: ItchApiClient) -> List[str]:
|
|||||||
return list(found_urls)
|
return list(found_urls)
|
||||||
|
|
||||||
|
|
||||||
|
def get_jobs_for_bundle_json(bundle_json: dict) -> List[str]:
|
||||||
|
if 'games' not in bundle_json:
|
||||||
|
raise Exception("Provided JSON is not a valid itch.io bundle JSON.")
|
||||||
|
|
||||||
|
return [g['url'] for g in bundle_json['games']]
|
||||||
|
|
||||||
|
|
||||||
|
def get_bundle_json(bundle_id: str, client: ItchApiClient) -> dict:
|
||||||
|
r = client.get(f"{ITCH_URL}/bundle/{bundle_id}/games.json")
|
||||||
|
if not r.ok:
|
||||||
|
raise ItchDownloadError(f"Could not download game list: {r.status_code} {r.reason}")
|
||||||
|
|
||||||
|
return r.json()
|
||||||
|
|
||||||
|
|
||||||
def get_jobs_for_itch_url(url: str, client: ItchApiClient) -> List[str]:
|
def get_jobs_for_itch_url(url: str, client: ItchApiClient) -> List[str]:
|
||||||
if url.startswith("http://"):
|
if url.startswith("http://"):
|
||||||
logging.info("HTTP link provided, upgrading to HTTPS")
|
logging.info("HTTP link provided, upgrading to HTTPS")
|
||||||
@ -116,7 +131,8 @@ def get_jobs_for_itch_url(url: str, client: ItchApiClient) -> List[str]:
|
|||||||
return get_jobs_for_browse_url(clean_browse_url, client)
|
return get_jobs_for_browse_url(clean_browse_url, client)
|
||||||
|
|
||||||
elif site in ("b", "bundle"): # Bundles
|
elif site in ("b", "bundle"): # Bundles
|
||||||
raise NotImplementedError("itch-dl cannot download bundles yet.")
|
bundle_json = get_bundle_json(url_path_parts[1], client)
|
||||||
|
return get_jobs_for_bundle_json(bundle_json)
|
||||||
|
|
||||||
elif site in ("j", "jobs"): # Jobs...
|
elif site in ("j", "jobs"): # Jobs...
|
||||||
raise ValueError("itch-dl cannot download a job.")
|
raise ValueError("itch-dl cannot download a job.")
|
||||||
@ -149,7 +165,7 @@ def get_jobs_for_itch_url(url: str, client: ItchApiClient) -> List[str]:
|
|||||||
|
|
||||||
|
|
||||||
def get_jobs_for_path(path: str) -> List[str]:
|
def get_jobs_for_path(path: str) -> List[str]:
|
||||||
try: # Game Jam Entries JSON?
|
try: # Game Jam Entries JSON or Bundle Games JSON?
|
||||||
with open(path, "rb") as f:
|
with open(path, "rb") as f:
|
||||||
json_data = json.load(f)
|
json_data = json.load(f)
|
||||||
|
|
||||||
@ -159,6 +175,10 @@ def get_jobs_for_path(path: str) -> List[str]:
|
|||||||
if 'jam_games' in json_data:
|
if 'jam_games' in json_data:
|
||||||
logging.info("Parsing provided file as a Game Jam Entries JSON...")
|
logging.info("Parsing provided file as a Game Jam Entries JSON...")
|
||||||
return get_jobs_for_game_jam_json(json_data)
|
return get_jobs_for_game_jam_json(json_data)
|
||||||
|
|
||||||
|
if 'games' in json_data:
|
||||||
|
logging.info("Parsing provided file as Bundle Games JSON...")
|
||||||
|
return get_jobs_for_bundle_json(json_data)
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
pass # Not a valid JSON, okay...
|
pass # Not a valid JSON, okay...
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user