136 lines
3.9 KiB
Python
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")
|