celery_tasks.py
Python script, ASCII text executable
1import common 2import time 3import os 4import config 5import email_send 6import shutil 7from celery import shared_task 8from app import db 9from smtplib import SMTP 10from celery.utils.log import get_task_logger 11 12 13@shared_task(ignore_result=False) 14def send_notification(user_notification_id): 15from models import UserNotification 16user_notification = db.session.get(UserNotification, user_notification_id) 17user = user_notification.user 18notification = user_notification.notification 19 20if user.email: 21with (SMTP(config.MAIL_SERVER) as mail): 22if notification.data.get("type") == "welcome": 23message = email_send.make_multipart_message( 24f"Welcome, {user.username}", 25config.NOTIFICATION_EMAIL, 26user.email, 27"welcome", 28username=user.username) 29 30mail.sendmail(config.NOTIFICATION_EMAIL, user.email, message) 31 32return 0 # notification sent successfully 33 34 35@shared_task(ignore_result=False) 36def merge_heads(head_route, head_branch, base_route, base_branch, simulate=True): 37from models import Repo 38server_repo_location = os.path.join(config.REPOS_PATH, base_route.lstrip("/")) 39if not os.path.isdir(server_repo_location): 40raise FileNotFoundError(f"Repo {server_repo_location} not found, cannot merge.") 41 42if base_route == head_route: 43common.git_command(server_repo_location, b"", "checkout", f"{base_branch}") 44if simulate: 45out, err, merge_exit = common.git_command(server_repo_location, b"", "merge", "--no-commit", "--no-ff", f"heads/{head_branch}", 46return_err=True, return_exit=True) 47 48# Undo the merge. 49common.git_command(server_repo_location, b"", "merge", "--abort") 50else: 51out, err, merge_exit = common.git_command(server_repo_location, b"", "merge", f"heads/{head_branch}", 52return_err=True, return_exit=True) 53 54return "merge_simulator" if simulate else "merge", out, err, head_route, head_branch, base_route, base_branch, merge_exit 55 56# Otherwise, we need to fetch the head repo. 57remote_url = os.path.join(config.BASE_DOMAIN, "git", base_route.lstrip("/")) 58 59out, err = b"", b"" 60part_out, part_err = common.git_command(server_repo_location, b"", "remote", "add", "NEW", remote_url, return_err=True) 61out += part_out 62err += part_err 63part_out, part_err = common.git_command(server_repo_location, b"", "remote", "update", return_err=True) 64out += part_out 65err += part_err 66part_out, part_err = common.git_command(server_repo_location, b"", "checkout", f"{base_branch}", return_err=True) 67out += part_out 68err += part_err 69if simulate: 70part_out, part_err, merge_exit = common.git_command(server_repo_location, b"", "merge", "--allow-unrelated-histories", 71"--no-commit", "--no-ff", f"NEW/{head_branch}", return_err=True, return_exit=True) 72else: 73part_out, part_err, merge_exit = common.git_command(server_repo_location, b"", "merge", "--allow-unrelated-histories", 74f"NEW/{head_branch}", return_err=True, return_exit=True) 75 76diff, diff_exit = common.git_command(server_repo_location, b"", "diff", "--check", return_exit=True) 77 78out += part_out 79err += part_err 80part_out, part_err = common.git_command(server_repo_location, b"", "remote", "rm", "NEW", return_err=True) 81out += part_out 82err += part_err 83if simulate: 84# Undo the merge. 85common.git_command(server_repo_location, b"", "merge", "--abort") 86 87return "merge_simulator" if simulate else "merge", out, err, head_route, head_branch, base_route, base_branch, merge_exit 88 89 90@shared_task(ignore_result=False) 91def copy_site(route): 92from models import Repo 93repo = db.session.get(Repo, route) 94server_repo_location = os.path.join(config.REPOS_PATH, route.lstrip("/")) 95if repo.has_site == 2: 96subdomain = repo.owner.username 97else: 98subdomain = repo.name + "." + repo.owner.username 99site_location = os.path.join(config.SITE_PATH, subdomain) 100# Get the branch to be used for the site; if it somehow doesn't exist, use the default branch. 101branch = repo.site_branch or repo.default_branch 102# Make a shallow clone of the repo; this prevents getting the full git database when it's not needed. 103if os.path.isdir(site_location): 104# Delete the old site. 105shutil.rmtree(site_location) 106 107common.git_command(config.SITE_PATH, b"", "clone", "--depth=1", f"--branch={branch}", os.path.join(os.getcwd(), server_repo_location), subdomain) 108 109 110@shared_task(ignore_result=False) 111def delete_site(route): 112from models import Repo 113repo = db.session.get(Repo, route) 114if repo.has_site == 2: 115subdomain = repo.owner.username 116else: 117subdomain = repo.name + "." + repo.owner.username 118site_location = os.path.join(config.SITE_PATH, subdomain) 119if os.path.isdir(site_location): 120shutil.rmtree(site_location) 121