Files
2022-10-27 03:08:27 +02:00

136 lines
3.9 KiB
Python

# Imports
import os
import json
import logging
import sys
import threading
import time
import zipfile
import git
from flask import Flask, request
# Config vars
runPath = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(runPath, ".."))
import conf
# Logging
logging.basicConfig(level=logging.INFO, format='%(levelname)-7s:%(message)s')
logging.getLogger("Webhook")
# Vars
app = Flask(__name__)
repo = git.Repo(conf.ese_location)
# Helper functions
# Threaded hooks
def update_self():
time.sleep(0.5) # sleep to let the server reply
git.Repo(runPath).remote().pull()
logging.info("Pulled the update. Webhook should restart soon")
def update_ese():
# Update local git
if not pull_repo():
logging.error("Could not pull update the ESE repo")
return "ERROR" # Blocking issue
# Write songlist to repo
if not make_song_list():
logging.error("Could not write songlist")
# Not a blocking issue, so we can continue
# zip up the repo into chunks
if not package():
logging.error("Could not finish updating zip files")
# Not blocking
# Actions
def pull_repo():
try:
logging.debug("Pulling ESE repo")
repo.remote().pull()
logging.info("Local ESE repo updated")
return True
except Exception as e:
print(e)
return False
def get_folder_struct():
root = repo.working_dir
rel = len(root)+1
dirs = sorted([x[0][rel:] for x in os.walk(root) if not x[0][rel:].startswith('.git') and x[0] != root])
return dirs
def make_song_list():
root = repo.working_dir
rel = len(root)+1
data = ""
for path in get_folder_struct():
level = path.count(os.sep)
if level == 0:
data+=f"\n[{path}]"
else:
indent = ' ' * 4 * (level)
data += f"\n{indent}-{os.path.basename(path)}"
try:
logging.info("Writing songlist to repo")
open(os.path.join(root, "songlist.txt"), "w").write(data.strip())
return True
except Exception as e:
print(e)
return False
def make_zip(dirs, location):
logging.info(f"writing {location}")
with zipfile.ZipFile(location, 'w') as chunk:
for dir in dirs:
dir = os.path.join(repo.working_dir, dir)
for file in [os.path.join(dir, f) for f in os.listdir(dir) if os.path.isfile(os.path.join(dir, f))]:
arcname = file.replace(repo.working_dir, "")
chunk.write(file, arcname)
def package():
folder = get_folder_struct()
# Split per genre
groups = {group: [dir for dir in folder if dir.startswith(group) and dir != group] for group in folder if group.count(os.sep) == 0}
# Split in chunks
size = conf.songs_per_zip
groups = {key: [val[i:i+size] for i in range(0, len(val), size)] for key, val in groups.items()}
# zip the individual chunks
for group, dirs in groups.items():
for i, chunk in enumerate(dirs):
outfile = os.path.join(conf.zip_location, f"{group}-{i+1}.zip")
make_zip(chunk, outfile)
# Web routes
@app.route(conf.webhook_ese,methods=['POST'])
def webhook_ese():
data = json.loads(request.data)
authors = [a.get('author', {}).get('name') for a in data.get('commits', [])]
authors = " & ".join(set([a for a in authors if a]))
pusher = data.get('pusher', {}).get('login', '[UNKNOWN]')
logging.info(f"Push made by {pusher}. Edits made by {authors}")
threading.Thread(target = update_ese).start()
return "OK"
@app.route(conf.webhook_self, methods=['POST'])
def webhook_update():
logging.info("Webhook repo was updated. Pulling updates")
threading.Thread(target = update_self).start()
return "OK"
if __name__ == '__main__':
logging.info("Webhook (re)started")
app.run(host=conf.host, port=conf.port, debug=True)
logging.info("Webhook stopped")