Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python3
- from json import load
- from hashlib import sha1
- from os import mkdir, listdir
- from argparse import ArgumentParser
- from shutil import copyfile, rmtree
- from os.path import join, isfile, isdir
- import requests
- BLOCK_SIZE = 65535
- MOD_DIR = "mods"
- API_VERSION = 2
- MODS_URL = "https://mods.factorio.com"
- AUTH_URL = "https://auth.factorio.com"
- USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
- TOKEN_FILE = "token.txt"
- def download_file(url: str, filename: str) -> None:
- r = session.get(url, stream=True, params={"username": username, "token": token})
- with open(filename, 'wb') as f:
- for chunk in r.iter_content(chunk_size=2048):
- if chunk:
- f.write(chunk)
- def hash_file(filename: str) -> str:
- hasher = sha1()
- with open(filename, "rb") as f:
- buff = f.read(BLOCK_SIZE)
- while len(buff) > 0:
- hasher.update(buff)
- buff = f.read(BLOCK_SIZE)
- return hasher.hexdigest()
- if __name__ == "__main__":
- # setup arguments
- parser = ArgumentParser(description="A script to download Factorio mods according to a mod list")
- parser.add_argument("-i", "--in-file", type=str, default="mod-list.json", help="The mod list file to read from")
- parser.add_argument("-u", "--username", type=str, help="The username you use to log into mods.factorio.com")
- parser.add_argument("-p", "--password", type=str, help="The password you use to log into mods.factorio.com")
- # parse arguments
- args = parser.parse_args()
- # make sure the mod list file exists
- assert isfile(args.in_file), "The specified mod list file doesn't exist"
- # clear the mod directory if anything exists in it
- if len(listdir(MOD_DIR)) > 0:
- print("Clearing mod directory...")
- rmtree(MOD_DIR)
- # create the mod directory if it doesn't exist
- if not isdir(MOD_DIR):
- print("Creating mod directory...")
- mkdir(MOD_DIR)
- # create a requests session
- session = requests.session()
- # make sure our session makes requests with a valid user agent
- session.headers.update({"User-Agent": USER_AGENT})
- # log in and generate the token file
- token = None
- if not isfile(TOKEN_FILE):
- # set the username global
- username = args.username
- # send the login request
- response = session.post(AUTH_URL + "/api-login", data={"username": username, "password": args.password, "require_game_ownership": "True"}, params={"api_version": API_VERSION})
- # parse the JSON and grab the token
- response_json = response.json()
- # make sure the login was successful
- assert "token" in response_json, "Invalid credentials"
- # set the token global
- token = response_json["token"]
- # dump the token
- with open(TOKEN_FILE, "w") as f:
- f.write("%s:%s" % (username, token))
- else: # load the cookies from a cookie jar
- # load the cookies from a file
- with open(TOKEN_FILE, "r") as f:
- (username, token) = f.read().split(":", 1)
- # grab the mod list from the mod-list.json file
- client_mod_list = load(open(args.in_file, "r"))
- # iterate through each mod in the list
- for mod in client_mod_list["mods"]:
- # make sure the mod isn't base and that it's enabled
- if mod["name"] != "base" and mod["enabled"]:
- # grab the info for the mod
- mod_info = session.get(MODS_URL + "/api/mods/" + mod["name"]).json()
- # get the latest release from the mod info
- latest_release = mod_info["releases"][-1] # last element is the newest
- # the name of the mod's zip file
- mod_file_name = latest_release["file_name"]
- # the SHA-1 hash of the file
- mod_hash = latest_release["sha1"]
- # the URL to download the mod from
- mod_download_url = MODS_URL + latest_release["download_url"]
- # create the mod file path
- mod_download_path = join(MOD_DIR, mod_file_name)
- # print status
- print("Downloading %s to \"%s\"..." % (mod["name"], mod_download_path))
- # download the mod
- download_file(mod_download_url, mod_download_path)
- # verify the mod's hash
- assert mod_hash == hash_file(mod_download_path), "Invalid hash on %s" % (mod["name"])
- # copy the mod-list.json into the new mods folder
- copyfile(args.in_file, join(MOD_DIR, args.in_file))
Advertisement
Add Comment
Please, Sign In to add comment