Skip to content

Instantly share code, notes, and snippets.

@FichteFoll
Last active January 30, 2024 01:43
Show Gist options
  • Save FichteFoll/ae6818210b68f297c6d2a21f5d14b201 to your computer and use it in GitHub Desktop.
Save FichteFoll/ae6818210b68f297c6d2a21f5d14b201 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# This is a very crude attempt at a Genshin Impact mora history exporter
# that was done as a last ditch effort
# to preserve history for the [TCBS](https://gensheets.co.uk/teyvat-central-banking-systems/) project.
# Because of problems with Google,
# the import stopped working for some people
# and this script attempts to at least maintain an archive of exports
# that *could* be merged into your TCBS sheet in the future.
#
# Required environment variables:
#
# - LTOKEN: ltoken_v2 cookie
# - LTUID: ltuid_v2 cookie
# - LTMID: ltmid_v2 cookie
# - UID_: your account's in-game UID
#
# See also https://github.com/thesadru/genshin.py
# for another already existing and more sophisticated implementation in Python
# and available as a library.
# I may or may not use it as a dependency in the future.
#
# Known issues:
# - Better not run the script on the first of a month
# because the "current year" and month detection is naive and fragile.
import json
import os
import sys
from datetime import date
from pathlib import Path
import requests
url = 'https://sg-hk4e-api.hoyolab.com/event/ysledgeros/month_detail'
headers = {
'Cookie': f"ltoken_v2={os.environ['LTOKEN']}; ltuid_v2={os.environ['LTUID']}; ltmid_v2={os.environ['LTMID']}",
}
BASE_PATH = Path("data")
# See https://github.com/Yippy/primorina/blob/main/src/genshinApi.ts for supported values
# for region, lang (and also the base domain).
BASE_PARAMS = {
# 'month': '0', # '0' means current
'region': 'os_euro',
'uid': os.environ['UID_'],
'lang': 'en-us',
# 'current_page': '1',
'type': '2',
# 'type': '1', # this one is for primogems
}
def main() -> int:
response = requests.get(url, headers=headers, params=BASE_PARAMS)
print(f"{headers=}")
data = response.json()
if not data.get('data'):
print("Failed to retrieve data.")
print(f"{data=}")
return 1
print(f"{data=}")
months = data['data']['optional_month']
print(f"{months=}")
current_year = date.today().year
for m in months:
y = current_year
if m > months[-1]:
y -= 1
if ret := fetch_month(m, y):
return ret
return 0
def fetch_month(month: int, year: int) -> int:
acc = None
current_page = 1
while True:
print(f"{month=} {current_page=}")
params = {**BASE_PARAMS, 'current_page': str(current_page), 'month': str(month)}
response = requests.get(url, headers=headers, params=params)
data = response.json()
if not data['data']['list']:
print("page was empty")
break
if not acc:
acc = data
else:
acc['data']['list'].extend(data['data']['list'])
current_page += 1
if not acc:
print(f"no data for {month=}")
print(f"writing data for {year:04}-{month:02}")
BASE_PATH.mkdir(parents=True, exist_ok=True)
with open(f"data/{year:04}-{month:02}.json", 'w') as fp:
json.dump(acc, fp, indent=2)
return 0
if __name__ == '__main__':
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment