aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorduvallj <jediguy9@gmail.com>2019-02-02 13:32:01 -0500
committerduvallj <jediguy9@gmail.com>2019-02-02 13:32:01 -0500
commitce4cb0b5cd157c77396344958b403c41a4f0f8b3 (patch)
tree24834ded27cd08fbff997cb67e3f330043102609
parent39f07d92af6f363175f3c09ccbd73b4093b4f172 (diff)
downloadmodpackman-ce4cb0b5cd157c77396344958b403c41a4f0f8b3.tar.gz
modpackman-ce4cb0b5cd157c77396344958b403c41a4f0f8b3.zip
Update update.py (better argument parsing, documentation)
-rw-r--r--mods.txt (renamed from latest-urls.txt)0
-rw-r--r--readme.md11
-rw-r--r--requirements.txt3
-rwxr-xr-xupdate.py179
4 files changed, 124 insertions, 69 deletions
diff --git a/latest-urls.txt b/mods.txt
index a844b6e..a844b6e 100644
--- a/latest-urls.txt
+++ b/mods.txt
diff --git a/readme.md b/readme.md
index dc53e31..0438f1e 100644
--- a/readme.md
+++ b/readme.md
@@ -5,12 +5,15 @@ Script to update modpacks automatically
#### To Use
-Simply put the location of your `mods` folder in `pack-location.txt` and run `python update.py install`
+First, install [Python 3](https://www.python.org/downloads/) and [Git](https://git-scm.com/downloads) and add them to your `$PATH`.
+Then, run `pip install -r requirements.txt` to install all the Python module requirements.
-Requires the `requests` module.
+Simply put the location of your `mods` folder in `pack-location.txt` and run `python update.py install`
#### Maintenance:
-To check `downloads.txt` modlist for updates against `latest-urls.txt` modlist, run `python update.py check_updates`
+To check `downloads.txt` modlist for updates against `mods.txt` modlist, run `python update.py check_updates`.
+
+To automatically populate `downloads.txt` with the most recent versions of mods listed in `mods.txt` run `python update.py apply_updates`.
-To automatically populate `downloads.txt` with the most recent versions of mods listed in `latest-urls.txt` run `python update.py apply_updates`
+Finally, to actually install your mods from the list in `downloads.txt`, run `python update.py install`
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..5f37ed8
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,3 @@
+requests
+colorama
+termcolor \ No newline at end of file
diff --git a/update.py b/update.py
index 373a839..a04df5c 100755
--- a/update.py
+++ b/update.py
@@ -1,97 +1,146 @@
#!/usr/bin/env python3
-import hashlib
-import requests
+
+import argparse
+import textwrap
import os
-import shutil
import sys
+import hashlib
+import shutil
+
+import requests
+import colorama
+from termcolor import colored
-# Initalize from config
-INSTALL_DIR = ""
-with open("pack-location.txt", "r") as f:
- INSTALL_DIR = f.read().strip()
+parser = argparse.ArgumentParser(
+ description="A Simple Git-Based Modpack Manager",
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ epilog='''\
+Available commands:
+ install : Downloads mods listed in downloads.txt and populates the mods folder specified in pack-location.txt
+ apply_updates : Using the latest downloads in latest-urls.txt, repopulates downloads.txt to reflect the most recent mod versions
+ check_updates : Compares downloads.txt and latest-urls.txt to see if any mods can be updated
+''')
+parser.add_argument('command',
+ nargs='?',
+ default='install',
+ help="The action to perform (default: install)")
+parser.add_argument('filename',
+ nargs='?',
+ default="mods.txt",
+ help="Optional filename to specify latest mods (default: mods.txt)")
+parser.add_argument('--url-file',
+ type=str,
+ default="downloads.txt",
+ help="Optional custom URL file to download mods from (default: downloads.txt)")
+parser.add_argument('--pack-location',
+ type=str,
+ help="Optional custom modpack folder location (default: read from pack-location.txt)")
+
+def read_file(fil):
+ strings = []
+ with open(fil) as f:
+ for line in f:
+ string = line.strip().split()
+ if len(line) > 1 and line[0] != '#':
+ # run strip on each element
+ string = tuple(map(lambda x: x.strip(), string))
+ strings.append(string)
+ return strings
# Apply updates to the actual mod pack
-def install():
- print("Updating pack...")
+def install(args):
+ print(colored("Updating pack...", 'green', attrs=['bold']))
# (fname, checksum, url)
- mods = read_file("downloads.txt")
+ mods = read_file(args.url_file)
names = [mod[0] for mod in mods]
+
for mod in mods:
- if mod[0] in os.listdir(INSTALL_DIR) and hashlib.sha1(open(os.path.join(INSTALL_DIR, mod[0]), 'rb').read()).hexdigest() == mod[1]:
- print("Skipping " + mod[0] + ", already up to date")
+ mod_path = os.path.join(args.pack_location, mod[0])
+ if os.path.exists(mod_path) and os.path.isfile(mod_path) and \
+ hashlib.sha1(open(mod_path, 'rb').read()).hexdigest() == mod[1]:
+ print("Skipping {mod[0]}, already up to date".format(mod=mod))
else:
- print(f'Installing {mod[0]} from {mod[2]}...')
+ print(colored('Installing {mod[0]} from {mod[2]}...'.format(mod=mod), attrs=['bold']))
download_obj = requests.get(mod[2], stream=True)
- with open(os.path.join(INSTALL_DIR, mod[0]), "wb") as write_file:
+ with open(mod_path, "wb") as write_file:
shutil.copyfileobj(download_obj.raw, write_file)
print("Done!")
- print("\nRemoving old versions...")
- for jar in os.listdir(INSTALL_DIR):
+ print()
+ print(colored("Removing old mods...", 'green', attrs=['bold']))
+
+ for jar in os.listdir(args.pack_location):
if jar not in names and os.path.splitext(jar)[1] == ".jar":
- os.remove(os.path.join(INSTALL_DIR, jar))
- print(f"Removing '{jar}'")
+ os.remove(os.path.join(args.pack_location, jar))
+ print(colored("Removing '{jar}'".format(jar=jar), attrs=['bold']))
- print("\nFinished installing mods!")
+ print()
+ print(colored("Finished installing mods!", 'green', attrs=['bold']))
# Using the latest urls, update downloads.txt to match the urls and have the correct sha1
-def apply_updates():
- print("Populating downloads.txt...")
- mods = read_file("latest-urls.txt")
- print("Getting new versions of all mods...")
- with open('downloads.txt', 'w') as f:
+def apply_updates(args):
+ print(colored("Populating URL File...", 'green', attrs=['bold']))
+ mods = read_file(args.filename)
+ print(colored("Getting new versions of all mods...", attrs=['bold']))
+ with open(args.url_file, 'w') as f:
f.write('# Format: <jarname> <hex digested sha1> <direct download url>\n')
for mod in mods:
- print(f"Fetching {mod[0]}...")
+ print("Fetching {mod[0]}...".format(mod=mod))
resp = requests.get(mod[1])
- hsh = hashlib.sha1(resp.content)
- f.write(f'{mod[0]} {hsh.hexdigest()} {resp.url}\n')
- print("\nDone!\nUpdates applied to downloads.txt")
- print("[!] No mods were installed. To update your mods folder, run 'update.py install'")
+ hsh = hashlib.sha1(resp.content).hexdigest()
+ f.write('{mod[0]} {hsh} {resp.url}\n'.format(mod=mod, hsh=hsh, resp=resp))
+ print()
+ print("Done!")
+ print(colored("Updates applied to downloads.txt", 'green', attrs=['bold']))
+ print(colored("[!] No mods were installed. To update your mods folder, run 'update.py install'", 'white', 'on_red', attrs=['bold', 'underline']))
# Find if any updates are available
-def check_updates():
- print("check_updates: Checking for updates to mods...")
- latest = read_file("latest-urls.txt")
- old = read_file("downloads.txt")
+def check_updates(args):
+ print(colored("Checking for updates to mods...", 'green', attrs=['bold']))
+ latest = read_file(args.filename)
+ old = read_file(args.url_file)
old_urls = [mod[2] for mod in old]
- print("Checking updates...\nThe following mods have updates available:\n")
+ print(colored("Checking updates...", attrs=['bold']))
for mod in latest:
- print(f"Checking for updates to {mod[0]}..." + " " * 35,end="\r")
+ print('\033[2K',end="") # ANSI code to clear line
+ print("Checking for updates to {mod[0]}...".format(mod=mod),end="\r")
resp = requests.get(mod[1])
if not resp.url in old_urls:
- print(f" -> Found update for {mod[0]}: {resp.url.split('/')[-1]}")
- print("Finished checking for updates!" + " " * 35)
-
-def read_file(fil):
- strings = []
- with open(fil) as f:
- for line in f:
- string = line.strip().split()
- if len(line) > 1 and line[0] != '#':
- # run strip on each element
- string = tuple(map(lambda x: x.strip(), string))
- strings.append(string)
- return strings
+ print(colored(" -> Found update for {mod[0]}: {resp.url.split('/')[-1]}".format(mod=mod, resp=resp), attrs=['bold']))
+
+ print('\033[2K' + colored("Finished checking for updates!", attrs=['bold']))
+COMMAND_MAP = {
+ 'install': install,
+ 'apply_updates': apply_updates,
+ 'check_updates': check_updates,
+}
-if len(sys.argv) < 2:
- #install by default
- install()
-elif sys.argv[1] == 'install':
- install()
-elif sys.argv[1] == 'apply_updates':
- apply_updates()
-elif sys.argv[1] == 'check_updates':
- check_updates()
-elif 'h' in sys.argv[1]:
- print(f"Usage: {sys.argv[0]} <install|apply_updates|check_updates>")
- print(" install\tdownloads mods listed in downloads.txt and populates the mods folder specified in pack-location.txt")
- print(" apply_updates\tusing the latest downloads in latest-urls.txt, repopulates downloads.txt to reflect the most recent mod versions")
- print(" check_updates\tcompares downloads.txt and latest-urls.txt to see if any mods can be updated")
-else:
- print(f"Usage: {sys.argv[0]} <install|apply_updates|check_updates>")
- sys.exit(-1)
+if __name__ == "__main__":
+ colorama.init()
+ args = parser.parse_args()
+
+ if not args.pack_location:
+ # initialize from config
+ with open("pack-location.txt", "r") as f:
+ args.pack_location = f.read().strip()
+
+ if not os.path.exists(args.pack_location):
+ print(colored("Error: mod folder \"" + args.pack_location + "\" does not exist.", 'red', attrs=['bold']))
+ parser.print_help()
+ sys.exit(1)
+ elif not os.path.isdir(args.pack_location):
+ print(colored("Error: mod folder \"" + args.pack_location + "\" is not actually a folder.", 'red', attrs=['bold']))
+ parser.print_help()
+ sys.exit(1)
+
+ if not (args.command in COMMAND_MAP):
+ print(colored("Error: command \"" + args.command + "\" does not exist", 'red', attrs=['bold']))
+ parser.print_help()
+ sys.exit(1)
+
+ # run the command
+ COMMAND_MAP[args.command](args)