Skip to content

Instantly share code, notes, and snippets.

@Xernium
Created January 5, 2021 15:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xernium/91d67367dbcfef4b18fbe91b74324e06 to your computer and use it in GitHub Desktop.
Save Xernium/91d67367dbcfef4b18fbe91b74324e06 to your computer and use it in GitHub Desktop.
Small python3 script for downloading the latest versions of Papermc projects using the v2 API
#!/usr/bin/env python3
#
# paperv2-downloader.py
# Python script to download the latest versions of various paper projects with one command
#
# examples:
# paperv2-downloader.py paper /path/to/server.jar
# paperv2-downloader.py waterfall proxyserver.jar --overwrite
#
# Licensed under: The Unlicense
#
# Project originally by FivePB <admin@fivepb.me>
#
# This is free and unencumbered software released into the public domain.
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
# For more information, please refer to <https://unlicense.org>
import requests
import json
import argparse, sys, os
import hashlib
__version__ = '1.1'
USER_AGENT = 'paper-v2-api-downloader-pyscript/%s' % __version__
def getProjectVersions(project):
url = 'https://papermc.io/api/v2/projects/%s' % project
r = requests.get(url, headers={'User-Agent': USER_AGENT})
tmp1 = json.loads((r.text))
return tmp1['versions']
def getProjectVersionBuilds(project, version):
url = 'https://papermc.io/api/v2/projects/%s/versions/%s' % (project, version)
r = requests.get(url, headers={'User-Agent': USER_AGENT})
tmp1 = json.loads((r.text))
return tmp1['builds']
def getProjectVersionBuildApplication(project, version, build):
url = 'https://papermc.io/api/v2/projects/%s/versions/%s/builds/%s' % (project, version, build)
r = requests.get(url, headers={'User-Agent': USER_AGENT})
tmp1 = json.loads((r.text))
return tmp1['downloads']['application']
def download(project, version, build, filename):
url = 'https://papermc.io/api/v2/projects/%s/versions/%s/builds/%s/downloads/%s' % (project, version, build, filename)
r = requests.get(url, headers={'User-Agent': USER_AGENT})
return r.content
def parse_args():
parser = argparse.ArgumentParser(description='Paper-V2-API project downloader')
parser.add_argument('project', help='Project name for ex: Waterfall or Paper')
parser.add_argument('file', help='Path (and name) to save the download to')
parser.add_argument('--overwrite', help='overwrite any existing file', action='store_true')
parser.add_argument('--skip-file-check', help='skip sha256 checksum test', action='store_true')
return parser.parse_args()
def writeFile(path, data):
f = open(path, 'wb')
f.write(data)
f.close()
def main(passedArgs = None):
if passedArgs:
args = passedArgs
else:
args = parse_args()
versions = None
try:
versions = getProjectVersions(args.project)
except Exception as e:
print('An error occured: %s\nIf it\'s a KeyError the project most likely doesn\'t exist or the Paper API servers are down or the API has changed. Anything else is most likely a Network issue on your side' % e.__class__.__name__ )
return 1
version = versions[-1]
buildinfo = getProjectVersionBuilds(args.project, version)
build = buildinfo[-1]
app = getProjectVersionBuildApplication(args.project, version, build)
appname = app['name']
checksum = app['sha256']
file = args.file
if os.path.isdir(file):
file = os.path.join(file, appname)
if os.path.isfile(file) and not args.overwrite:
print('Error, file %s already exists but you didn\'t specify --overwrite. Quitting!' )
return 2
data = download(args.project, version, build, appname)
if not args.skip_file_check:
calculatedHash = hashlib.sha256(data).hexdigest();
if calculatedHash != checksum:
print('Warning! Couldn\'t verify the downloaded file; the checksum failed. Expected %s but got %s that means there is something very wrong here. If you would like to proceed anyway you can re-run the command with --skip-file-check (NOT RECOMMENDED).' % (checksum, calculatedHash))
return 3
writeFile(file, data)
if __name__ == '__main__':
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment