def send_update_notification(mod, version, user): followers = [u.email for u in mod.followers] changelog = version.changelog if changelog: changelog = '\n'.join([' ' + l for l in changelog.split('\n')]) targets = list() for follower in followers: targets.append(follower) if len(targets) == 0: return with open("emails/mod-updated") as f: message = html.parser.HTMLParser().unescape( pystache.render( f.read(), { 'mod': mod, 'user': user, 'site-name': _cfg('site-name'), 'domain': _cfg("domain"), 'latest': version, 'url': '/mod/' + str(mod.id) + '/' + secure_filename(mod.name)[:64], 'changelog': changelog })) subject = user.username + " has just updated " + mod.name + "!" send_mail.delay(_cfg('support-mail'), targets, subject, message)
def send_update_notification(mod): followers = [u.email for u in mod.followers] changelog = mod.versions[-1].changelog if changelog: changelog = '\n'.join([' ' + l for l in changelog.split('\n')]) for follower in followers: smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port")) smtp.login(_cfg("smtp-user"), _cfg("smtp-password")) with open("emails/mod-updated") as f: message = MIMEText( pystache.render( f.read(), { 'mod': mod, 'domain': _cfg("domain"), 'latest': mod.versions[-1], 'url': '/mod/' + str(mod.id) + '/' + secure_filename(mod.name)[:64], 'changelog': changelog })) message[ 'Subject'] = mod.user.username + " has just updated " + mod.name + "!" message['From'] = "*****@*****.**" message['To'] = follower smtp.sendmail("*****@*****.**", [follower], message.as_string()) smtp.quit()
def is_oauth_provider_configured(provider): if provider == 'github': return bool(_cfg('gh-oauth-id')) and bool(_cfg('gh-oauth-secret')) if provider == 'google': return (bool(_cfg('google-oauth-id')) and bool(_cfg('google-oauth-secret'))) return False
def send_autoupdate_notification(mod): if _cfg("smtp-host") == "": return followers = [u.email for u in mod.followers] changelog = mod.default_version().changelog if changelog: changelog = '\n'.join([' ' + l for l in changelog.split('\n')]) targets = list() for follower in followers: targets.append(follower) if len(targets) == 0: return with open("emails/mod-autoupdated") as f: message = MIMEText(html.parser.HTMLParser().unescape(pystache.render(f.read(), { 'mod': mod, 'domain': _cfg("domain"), 'latest': mod.default_version(), 'url': '/mod/' + str(mod.id) + '/' + secure_filename(mod.name)[:64], 'changelog': changelog }))) message['X-MC-PreserveRecipients'] = "false" message['Subject'] = mod.name + " is compatible with RimWorld " + mod.versions[0].ksp_version + "!" message['From'] = "*****@*****.**" message['To'] = ";".join(targets) sendEmail(message,targets)
def update_mod_background(mod_id): if current_user == None: return { 'error': True, 'reason': 'You are not logged in.' }, 401 mod = Mod.query.filter(Mod.id == mod_id).first() if not mod: return { 'error': True, 'reason': 'Mod not found.' }, 404 editable = False if current_user: if current_user.admin: editable = True if current_user.id == mod.user_id: editable = True if any([u.accepted and u.user == current_user for u in mod.shared_authors]): editable = True if not editable: return { 'error': True, 'reason': 'Not enought rights.' }, 401 f = request.files['image'] filetype = os.path.splitext(os.path.basename(f.filename))[1] if not filetype in ['.png', '.jpg']: return { 'error': True, 'reason': 'This file type is not acceptable.' }, 400 filename = secure_filename(mod.name) + '-' + str(time.time()) + filetype base_path = os.path.join(secure_filename(mod.user.username) + '_' + str(mod.user.id), secure_filename(mod.name)) full_path = os.path.join(_cfg('storage'), base_path) if not os.path.exists(full_path): os.makedirs(full_path) path = os.path.join(full_path, filename) try: os.remove(os.path.join(_cfg('storage'), mod.background)) except: pass # who cares f.save(path) mod.background = os.path.join(base_path, filename) return { 'path': '/content/' + mod.background }
def browse_updated(): mods = Mod.query.filter(Mod.published, ModVersion.query.filter(ModVersion.mod_id == Mod.id).count() > 1).order_by( desc(Mod.updated) ) total_pages = math.ceil(mods.count() / 30) page = request.args.get("page") if page: page = int(page) if page < 1: page = 1 if page > total_pages: page = total_pages else: page = 1 mods = mods.offset(30 * (page - 1)).limit(30) return render_template( "browse-list.html", mods=mods, page=page, total_pages=total_pages, url="/browse/updated", name="Recently Updated Mods", rss="/browse/updated.rss", site_name=_cfg("site-name"), support_mail=_cfg("support-mail"), )
def send_autoupdate_notification(mod): followers = [u.email for u in mod.followers] changelog = mod.default_version().changelog if changelog: changelog = '\n'.join([' ' + l for l in changelog.split('\n')]) targets = list() for follower in followers: targets.append(follower) if len(targets) == 0: return with open("emails/mod-autoupdated") as f: message = html.parser.HTMLParser().unescape(pystache.render(f.read(), { 'mod': mod, 'domain': _cfg("domain"), 'latest': mod.default_version(), 'url': '/mod/' + str(mod.id) + '/' + secure_filename(mod.name)[:64], 'changelog': changelog })) # We (or rather just me) probably want that this is not dependent on KSP, since I know some people # who run forks of KerbalStuff for non-KSP purposes. # TODO(Thomas): Consider in putting the game name into a config. subject = mod.name + " is compatible with KSP " + mod.versions[0].ksp_version + "!" send_mail.delay(_cfg('support-mail'), targets, subject, message)
def browse_new_rss(): mods = Mod.query.filter(Mod.published).order_by(desc(Mod.created)) mods = mods.limit(30) return Response(render_template("rss.xml", mods=mods, title="New mods on Kerbal Stuff",\ description="The newest mods on Kerbal Stuff", \ url="/browse/new", site_name=_cfg('site-name'), support_mail=_cfg('support-mail')), mimetype="text/xml")
def send_mail(sender, recipients, subject, message, important=False): if _cfg("smtp-host") == "": return smtp = smtplib.SMTP(host=_cfg("smtp-host"), port=_cfgi("smtp-port")) if _cfgb("smtp-tls"): smtp.starttls() if _cfg("smtp-user") != "": smtp.login(_cfg("smtp-user"), _cfg("smtp-password")) message = MIMEText(message) if important: message['X-MC-Important'] = "true" message['X-MC-PreserveRecipients'] = "false" message['Subject'] = subject message['From'] = sender if len(recipients) > 1: message['Precedence'] = 'bulk' for group in chunks(recipients, 100): if len(group) > 1: message['To'] = "undisclosed-recipients:;" else: message['To'] = ";".join(group) print("Sending email from {} to {} recipients".format( sender, len(group))) smtp.sendmail(sender, group, message.as_string()) smtp.quit()
def index(): featured = Featured.query.order_by(desc(Featured.created)).limit(6)[:6] top = search_mods("", 1, 3)[0] new = Mod.query.filter(Mod.published).order_by(desc( Mod.created)).limit(3)[:3] recent = Mod.query.filter(Mod.published).order_by(desc( Mod.updated)).limit(3)[:3] user_count = User.query.count() mod_count = Mod.query.count() yours = list() if current_user: yours = sorted(current_user.following, key=lambda m: m.updated, reverse=True)[:3] return render_template("index.html",\ featured=featured,\ new=new,\ top=top,\ recent=recent,\ user_count=user_count,\ mod_count=mod_count, yours=yours, site_name=_cfg('site-name'), support_mail=_cfg('support-mail'), source_code=_cfg('source-code'))
def send_autoupdate_notification(mod): followers = [u.email for u in mod.followers] changelog = mod.default_version().changelog if changelog: changelog = "\n".join([" " + l for l in changelog.split("\n")]) targets = list() for follower in followers: targets.append(follower) if len(targets) == 0: return with open("emails/mod-autoupdated") as f: message = html.parser.HTMLParser().unescape( pystache.render( f.read(), { "mod": mod, "domain": _cfg("domain"), "site-name": _cfg("site-name"), "latest": mod.default_version(), "url": "/mod/" + str(mod.id) + "/" + secure_filename(mod.name)[:64], "changelog": changelog, }, ) ) # We (or rather just me) probably want that this is not dependent on KSP, since I know some people # who run forks of KerbalStuff for non-KSP purposes. # TODO(Thomas): Consider in putting the game name into a config. subject = mod.name + " is compatible with Game " + mod.versions[0].gameversion.friendly_version + "!" send_mail.delay(_cfg("support-mail"), targets, subject, message)
def browse_updated_rss(): mods = Mod.query.filter(Mod.published).order_by(desc(Mod.updated)) mods = mods.limit(30) return Response(render_template("rss.xml", mods=mods, title="Recently updated on Kerbal Stuff",\ description="Mods on Kerbal Stuff updated recently", \ url="/browse/updated", site_name=_cfg('site-name'), support_mail=_cfg('support-mail')), mimetype="text/xml")
def send_update_notification(mod, version, user): followers = [u.email for u in mod.followers] changelog = version.changelog if changelog: changelog = "\n".join([" " + l for l in changelog.split("\n")]) targets = list() for follower in followers: targets.append(follower) if len(targets) == 0: return with open("emails/mod-updated") as f: message = html.parser.HTMLParser().unescape( pystache.render( f.read(), { "mod": mod, "user": user, "site-name": _cfg("site-name"), "domain": _cfg("domain"), "latest": version, "url": "/mod/" + str(mod.id) + "/" + secure_filename(mod.name)[:64], "changelog": changelog, }, ) ) subject = user.username + " has just updated " + mod.name + "!" send_mail.delay(_cfg("support-mail"), targets, subject, message)
def update_mod_background(mod_id): if current_user == None: return {"error": True, "reason": "You are not logged in."}, 401 mod = Mod.query.filter(Mod.id == mod_id).first() if not mod: return {"error": True, "reason": "Mod not found."}, 404 editable = False if current_user: if current_user.admin: editable = True if current_user.id == mod.user_id: editable = True if any([u.accepted and u.user == current_user for u in mod.shared_authors]): editable = True if not editable: return {"error": True, "reason": "Not enought rights."}, 401 f = request.files["image"] filetype = os.path.splitext(os.path.basename(f.filename))[1] if not filetype in [".png", ".jpg"]: return {"error": True, "reason": "This file type is not acceptable."}, 400 filename = secure_filename(mod.name) + "-" + str(time.time()) + filetype base_path = os.path.join(secure_filename(mod.user.username) + "_" + str(mod.user.id), secure_filename(mod.name)) full_path = os.path.join(_cfg("storage"), base_path) if not os.path.exists(full_path): os.makedirs(full_path) path = os.path.join(full_path, filename) try: os.remove(os.path.join(_cfg("storage"), mod.background)) except: pass # who cares f.save(path) mod.background = os.path.join(base_path, filename) return {"path": "/content/" + mod.background}
def send_update_notification_sync(mod, version, user): followers = [u.email for u in mod.followers] changelog = version.changelog if changelog: changelog = '\n'.join([' ' + l for l in changelog.split('\n')]) targets = list() for follower in followers: targets.append(follower) if len(targets) == 0: return smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port")) smtp.starttls() smtp.login(_cfg("smtp-user"), _cfg("smtp-password")) with open("emails/mod-updated") as f: message = MIMEText(html.parser.HTMLParser().unescape(pystache.render(f.read(), { 'mod': mod, 'user': user, 'domain': _cfg("domain"), 'latest': version, 'url': '/mod/' + str(mod.id) + '/' + secure_filename(mod.name)[:64], 'changelog': changelog }))) message['X-MC-PreserveRecipients'] = "false" message['Subject'] = user + " has just updated " + mod.name + "!" message['From'] = "*****@*****.**" message['To'] = ";".join(targets) smtp.sendmail("*****@*****.**", targets, message.as_string()) smtp.quit()
def sendEmail(message,emailto): smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port")) smtp.starttls() smtp.ehlo() smtp.login(_cfg("smtp-user"), _cfg("smtp-password")) smtp.sendmail("*****@*****.**", [ emailto ], message.as_string()) smtp.quit()
def download(mod_id, mod_name, version): mod = Mod.query.filter(Mod.id == mod_id).first() if not mod: abort(404) if not mod.published and (not current_user or current_user.id != mod.user_id): abort(401) version = ModVersion.query.filter(ModVersion.mod_id == mod_id, \ ModVersion.friendly_version == version).first() if not version: abort(404) download = DownloadEvent.query\ .filter(DownloadEvent.mod_id == mod.id and DownloadEvent.version_id == version.id)\ .order_by(desc(DownloadEvent.created))\ .first() if not os.path.isfile(os.path.join(_cfg('storage'), version.download_path)): abort(404) # Events are aggregated hourly if not download or ((datetime.now() - download.created).seconds / 60 / 60) >= 1: download = DownloadEvent() download.mod = mod download.version = version download.downloads = 1 mod.downloads.append(download) db.add(download) else: download.downloads += 1 mod.download_count += 1 return send_file(os.path.join(_cfg('storage'), version.download_path), as_attachment = True)
def hook_publish(): print("Hook recieved") allow = False for ip in _cfg("hook_ips").split(","): parts = ip.split("/") range = 32 if len(parts) != 1: range = int(parts[1]) addr = networkMask(parts[0], range) if addressInNetwork(dottedQuadToNum(request.remote_addr), addr): allow = True if not allow: print("Hook ignored - not whitelisted IP") abort(403) print("Hook permitted") # Pull and restart site event = json.loads(request.data.decode("utf-8")) if not _cfg("hook_repository") == "%s/%s" % (event["repository"]["owner"]["name"], event["repository"]["name"]): return "ignored" if any("[noupdate]" in c["message"] for c in event["commits"]): return "ignored" if "refs/heads/" + _cfg("hook_branch") == event["ref"]: print("Updating on hook") subprocess.call(["git", "pull", "origin", "master"]) subprocess.call(_cfg("restart_command").split()) return "thanks" return "ignored"
def send_autoupdate_notification(mod): followers = [u.email for u in mod.followers] changelog = mod.default_version().changelog if changelog: changelog = '\n'.join([' ' + l for l in changelog.split('\n')]) targets = list() for follower in followers: targets.append(follower) if len(targets) == 0: return with open("emails/mod-autoupdated") as f: message = html.parser.HTMLParser().unescape( pystache.render( f.read(), { 'mod': mod, 'domain': _cfg("domain"), 'latest': mod.default_version(), 'url': '/mod/' + str(mod.id) + '/' + secure_filename(mod.name)[:64], 'changelog': changelog })) # We (or rather just me) probably want that this is not dependent on KSP, since I know some people # who run forks of KerbalStuff for non-KSP purposes. # TODO(Thomas): Consider in putting the game name into a config. subject = mod.name + " is compatible with KSP " + mod.versions[ 0].ksp_version + "!" send_mail.delay(_cfg('support-mail'), targets, subject, message)
def singlegame_browse_updated(gameshort): if not gameshort: gameshort = "kerbal-space-program" ga = Game.query.filter(Game.short == gameshort).first() session["game"] = ga.id session["gamename"] = ga.name session["gameshort"] = ga.short session["gameid"] = ga.id mods = Mod.query.filter( Mod.published, Mod.game_id == ga.id, ModVersion.query.filter(ModVersion.mod_id == Mod.id).count() > 1 ).order_by(desc(Mod.updated)) total_pages = math.ceil(mods.count() / 30) page = request.args.get("page") if page: page = int(page) if page < 1: page = 1 if page > total_pages: page = total_pages else: page = 1 mods = mods.offset(30 * (page - 1)).limit(30) return render_template( "browse-list.html", mods=mods, page=page, total_pages=total_pages, ga=ga, url="/browse/updated", name="Recently Updated Mods", rss="/browse/updated.rss", site_name=_cfg("site-name"), support_mail=_cfg("support-mail"), )
def hook_publish(): print("Hook recieved") allow = False for ip in _cfg("hook_ips").split(","): parts = ip.split("/") range = 32 if len(parts) != 1: range = int(parts[1]) addr = networkMask(parts[0], range) if addressInNetwork(dottedQuadToNum(request.remote_addr), addr): allow = True if not allow: print("Hook ignored - not whitelisted IP") abort(403) print("Hook permitted") # Pull and restart site event = json.loads(request.data.decode("utf-8")) if not _cfg("hook_repository") == "%s/%s" % ( event["repository"]["owner"]["name"], event["repository"]["name"]): return "ignored" if any("[noupdate]" in c["message"] for c in event["commits"]): return "ignored" if "refs/heads/" + _cfg("hook_branch") == event["ref"]: print("Updating on hook") subprocess.call(["git", "pull", "origin", "master"]) subprocess.call(_cfg("restart_command").split()) return "thanks" return "ignored"
def send_autoupdate_notification(mod): if _cfg("smtp-host") == "": return followers = [u.email for u in mod.followers] changelog = mod.versions[-1].changelog if changelog: changelog = '\n'.join([' ' + l for l in changelog.split('\n')]) for follower in followers: smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port")) smtp.login(_cfg("smtp-user"), _cfg("smtp-password")) with open("emails/mod-autoupdated") as f: message = MIMEText(pystache.render(f.read(), { 'mod': mod, 'domain': _cfg("domain"), 'latest': mod.versions[-1], 'url': '/mod/' + str(mod.id) + '/' + secure_filename(mod.name)[:64], 'changelog': changelog })) message['Subject'] = mod.name + " is compatible with KSP " + mod.versions[0].ksp_version + "!" message['From'] = "*****@*****.**" message['To'] = follower smtp.sendmail("*****@*****.**", [ follower ], message.as_string()) smtp.quit()
def singlegame_browse_featured_rss(gameshort): if not gameshort: gameshort = "kerbal-space-program" ga = Game.query.filter(Game.short == gameshort).first() session["game"] = ga.id session["gamename"] = ga.name session["gameshort"] = ga.short session["gameid"] = ga.id mods = Featured.query.outerjoin(Mod).filter(Mod.game_id == ga.id).order_by(desc(Featured.created)) mods = mods.limit(30) # Fix dates for f in mods: f.mod.created = f.created mods = [dumb_object(f.mod) for f in mods] db.rollback() return Response( render_template( "rss.xml", mods=mods, title="Featured mods on " + _cfg("site-name"), ga=ga, description="Featured mods on " + _cfg("site-name"), url="/browse/featured", ), mimetype="text/xml", )
def browse_updated_rss(): mods = Mod.query.filter(Mod.published).order_by(desc(Mod.updated)) mods = mods.limit(30) return Response(render_template("rss.xml", mods=mods, title="Recently updated on " + _cfg('site-name'),\ description="Mods on " + _cfg('site-name') + " updated recently", \ url="/browse/updated", site_name=_cfg('site-name'), support_mail=_cfg('support-mail')), mimetype="text/xml")
def singlegame_browse_all(gameshort): if not gameshort: gameshort = "kerbal-space-program" ga = Game.query.filter(Game.short == gameshort).first() session["game"] = ga.id session["gamename"] = ga.name session["gameshort"] = ga.short session["gameid"] = ga.id page = request.args.get("page") if page: page = int(page) else: page = 1 mods, total_pages = search_mods(ga, "", page, 30) return render_template( "browse-list.html", mods=mods, page=page, total_pages=total_pages, ga=ga, url="/browse/all", name="All Mods", site_name=_cfg("site-name"), support_mail=_cfg("support-mail"), )
def send_autoupdate_notification(mod): if _cfg("smtp-host") == "": return followers = [u.email for u in mod.followers] changelog = mod.default_version().changelog if changelog: changelog = '\n'.join([' ' + l for l in changelog.split('\n')]) targets = list() for follower in followers: targets.append(follower) if len(targets) == 0: return smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port")) smtp.login(_cfg("smtp-user"), _cfg("smtp-password")) with open("emails/mod-autoupdated") as f: message = MIMEText(html.parser.HTMLParser().unescape(pystache.render(f.read(), { 'mod': mod, 'domain': _cfg("domain"), 'latest': mod.default_version(), 'url': '/mod/' + str(mod.id) + '/' + secure_filename(mod.name)[:64], 'changelog': changelog }))) message['X-MC-PreserveRecipients'] = "false" message['Subject'] = mod.name + " is compatible with KSP " + mod.versions[0].ksp_version + "!" message['From'] = "*****@*****.**" message['To'] = ";".join(targets) smtp.sendmail("*****@*****.**", targets, message.as_string()) smtp.quit()
def browse_new_rss(): mods = Mod.query.filter(Mod.published).order_by(desc(Mod.created)) mods = mods.limit(30) return Response(render_template("rss.xml", mods=mods, title="New mods on " + _cfg('site-name'),\ description="The newest mods on " + _cfg('site-name'), \ url="/browse/new", site_name=_cfg('site-name'), support_mail=_cfg('support-mail')), mimetype="text/xml")
def update_user_background(username): if current_user == None: return {'error': True, 'reason': 'You are not logged in.'}, 401 user = User.query.filter(User.username == username).first() if not current_user.admin and current_user.username != user.username: return { 'error': True, 'reason': 'You are not authorized to edit this user\'s background' }, 403 f = request.files['image'] filetype = os.path.splitext(os.path.basename(f.filename))[1] if not filetype in ['.png', '.jpg']: return { 'error': True, 'reason': 'This file type is not acceptable.' }, 400 filename = secure_filename(user.username) + filetype base_path = os.path.join( secure_filename(user.username) + '-' + str(time.time()) + '_' + str(user.id)) full_path = os.path.join(_cfg('storage'), base_path) if not os.path.exists(full_path): os.makedirs(full_path) path = os.path.join(full_path, filename) try: os.remove(os.path.join(_cfg('storage'), user.backgroundMedia)) except: pass # who cares f.save(path) user.backgroundMedia = os.path.join(base_path, filename) return {'path': '/content/' + user.backgroundMedia}
def send_reset(user): with open("emails/password-reset") as f: message = html.parser.HTMLParser().unescape(\ pystache.render(f.read(), { 'user': user, 'site-name': _cfg('site-name'), "domain": _cfg("domain"), 'confirmation': user.passwordReset })) send_mail.delay(_cfg('support-mail'), [user.email], "Reset your password on " + _cfg('site-name'), message, important=True)
def send_confirmation(user, followMod=None): with open("emails/confirm-account") as f: if followMod != None: message = pystache.render(f.read(), { 'user': user, "domain": _cfg("domain"),\ 'confirmation': user.confirmation + "?f=" + followMod }) else: message = html.parser.HTMLParser().unescape(\ pystache.render(f.read(), { 'user': user, "domain": _cfg("domain"), 'confirmation': user.confirmation })) send_mail.delay("*****@*****.**", [ user.email ], "Welcome to Kerbal Stuff!", message, important=True)
def send_confirmation(user, followMod=None): with open("emails/confirm-account") as f: if followMod != None: message = pystache.render(f.read(), { 'user': user, 'site-name': _cfg('site-name'), "domain": _cfg("domain"),\ 'confirmation': user.confirmation + "?f=" + followMod }) else: message = html.parser.HTMLParser().unescape(\ pystache.render(f.read(), { 'user': user, 'site-name': _cfg('site-name'), "domain": _cfg("domain"), 'confirmation': user.confirmation })) send_mail.delay(_cfg('support-mail'), [ user.email ], "Welcome to " + _cfg('site-name') + "!", message, important=True)
def send_confirmation(user, followMod=None): with open("emails/confirm-account") as f: if followMod != None: message = pystache.render(f.read(), { 'user': user, "domain": _cfg("domain"),\ 'confirmation': user.confirmation + "?f=" + followMod }) else: message = html.parser.HTMLParser().unescape(\ pystache.render(f.read(), { 'user': user, "domain": _cfg("domain"), 'confirmation': user.confirmation })) send_mail.delay(_cfg('support-mail'), [ user.email ], "Welcome to " + _cfg('site-name') + "!", message, important=True)
def send_confirmation(user): smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port")) smtp.login(_cfg("smtp-user"), _cfg("smtp-password")) with open("emails/confirm-account") as f: message = MIMEText(pystache.render(f.read(), { 'user': user, "domain": _cfg("domain"), 'confirmation': user.confirmation })) message['Subject'] = "Welcome to Kerbal Stuff!" message['From'] = "*****@*****.**" message['To'] = user.email smtp.sendmail("*****@*****.**", [ user.email ], message.as_string()) smtp.quit()
def send_grant_notice(mod, user): with open("emails/grant-notice") as f: message = html.parser.HTMLParser().unescape(\ pystache.render(f.read(), { 'user': user, 'site-name': _cfg('site-name'), "domain": _cfg("domain"),\ 'mod': mod, 'url': url_for('mods.mod', id=mod.id, mod_name=mod.name) })) send_mail.delay(_cfg('support-mail'), [user.email], "You've been asked to co-author a mod on " + _cfg('site-name'), message, important=True)
def connect_with_oauth(): provider = request.form.get('provider') if not is_oauth_provider_configured(provider): return 'This install is not configured for login with %s' % provider oauth = get_oauth_provider(provider) callback = "{}://{}{}".format(_cfg("protocol"), _cfg("domain"), url_for('.connect_with_oauth_authorized_' + provider)) return oauth.authorize(callback=callback)
def edit_list(list_id, list_name): mod_list = ModList.query.filter(ModList.id == list_id).first() if not mod_list: abort(404) editable = False if current_user: if current_user.admin: editable = True if current_user.id == mod_list.user_id: editable = True if not editable: abort(401) if request.method == 'GET': return render_template( "edit_list.html", **{ 'mod_list': mod_list, 'mod_ids': [m.mod.id for m in mod_list.mods], "site_name": _cfg('site-name'), "support_mail": _cfg('support-mail') }) else: description = request.form.get('description') background = request.form.get('background') bgOffsetY = request.form.get('bg-offset-y') mods = json.loads(request.form.get('mods')) mod_list.description = description if background and background != '': mod_list.background = background try: mod_list.bgOffsetY = int(bgOffsetY) except: pass # Remove mods removed_mods = [m for m in mod_list.mods if not m.mod_id in mods] for mod in removed_mods: mod_list.mods.remove(mod) # Add mods added_mods = [ m for m in mods if not m in [mod.mod.id for mod in mod_list.mods] ] for m in added_mods: mod = Mod.query.filter(Mod.id == m).first() mli = ModListItem() mli.mod_id = mod.id mli.mod_list = mod_list mod_list.mods.append(mli) db.add(mli) db.commit() for mod in mod_list.mods: mod.sort_index = mods.index(mod.mod.id) return redirect( url_for("lists.view_list", list_id=mod_list.id, list_name=mod_list.name))
def browse(): featured = Featured.query.order_by(desc(Featured.created)).limit(6)[:6] top = search_mods("", 1, 6)[:6][0] new = Mod.query.filter(Mod.published).order_by(desc( Mod.created)).limit(6)[:6] return render_template("browse.html", featured=featured, top=top, new=new, site_name=_cfg('site-name'), support_mail=_cfg('support-mail'))
def register(): if not _cfgb('registration'): return redirect("/") if request.method == 'POST': # Validate kwargs = dict() followMod = request.form.get('follow-mod') email = request.form.get('email') username = request.form.get('username') password = request.form.get('password') confirmPassword = request.form.get('repeatPassword') error = check_email_for_registration(email) if error: kwargs['emailError'] = error error = check_username_for_registration(username) if error: kwargs['usernameError'] = error if not password: kwargs['passwordError'] = 'Password is required.' else: if password != confirmPassword: kwargs['repeatPasswordError'] = 'Passwords do not match.' if len(password) < 5: kwargs['passwordError'] = 'Your password must be greater than 5 characters.' if len(password) > 256: kwargs['passwordError'] = 'We admire your dedication to security, but please use a shorter password.' if not kwargs == dict(): # Fill in config values kwargs['site_name'] = _cfg('site-name') kwargs['support_mail'] = _cfg('support-mail') if email is not None: kwargs['email'] = email if username is not None: kwargs['username'] = username kwargs['registration'] = registration = _cfgb('registration') print("test") return render_template("register.html", **kwargs) # All valid, let's make them an account user = User(username, email, password) user.confirmation = binascii.b2a_hex(os.urandom(20)).decode("utf-8") db.add(user) db.commit() # We do this manually so that we're sure everything's hunky dory before the email leaves if followMod: send_confirmation(user, followMod) else: send_confirmation(user) return redirect("/account-pending") else: return render_template("register.html", **{ "site_name": _cfg('site-name'), "support_mail": _cfg('support-mail'), "registration": _cfgb('registration') })
def send_to_ckan(mod): if not _cfg("netkan_repo_path"): return if not mod.ckan: return json_blob = { 'spec_version': 'v1.4', 'identifier': re.sub(r'\W+', '', mod.name), '$kref': '#/ckan/spacedock/' + str(mod.id), 'license': mod.license, 'x_via': 'Automated ' + _cfg('site-name') + ' CKAN submission' } wd = _cfg("netkan_repo_path") path = os.path.join(wd, 'NetKAN', json_blob['identifier'] + '.netkan') if os.path.exists(path): # If the file is already there, then chances are this mod has already been indexed return with open(path, 'w') as f: f.write(json.dumps(json_blob, indent=4)) subprocess.call(['git', 'fetch', 'upstream'], cwd=wd) subprocess.call([ 'git', 'checkout', '-b', 'add-' + json_blob['identifier'], 'upstream/master' ], cwd=wd) subprocess.call(['git', 'add', '-A'], cwd=wd) subprocess.call(['git', 'commit', '-m', 'Add {0} from '.format(mod.name) + _cfg('site-name') + '\n\nThis is an automated commit on behalf of {1}'\ .format(mod.name, mod.user.username), '--author={0} <{1}>'.format(mod.user.username, mod.user.email)], cwd=wd) subprocess.call( ['git', 'push', '-u', 'origin', 'add-' + json_blob['identifier']], cwd=wd) g = Github(_cfg('github_user'), _cfg('github_pass')) r = g.get_repo("KSP-CKAN/NetKAN") r.create_pull(title="Add {0} from ".format(mod.name) + _cfg('site-name'), base=r.default_branch, head=_cfg('github_user') + ":add-" + json_blob['identifier'], body=\ """\ This pull request was automatically generated by """ + _cfg('site-name') + """ on behalf of {0}, to add [{1}]({4}{2}) to CKAN. Mod details: name = {2} author = {0} abstract = {6} license = {7} Homepage = {8} description = {5} Please direct questions about this pull request to [{0}]({4}{3}). """.format(mod.user.username, mod.name,\ url_for('mods.mod', mod_name=mod.name, id=mod.id),\ url_for("profile.view_profile", username=mod.user.username),\ _cfg("protocol") + "://" + _cfg("domain"),\ mod.description, mod.short_description,\ mod.license, mod.external_link))
def send_reset(user): smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port")) smtp.login(_cfg("smtp-user"), _cfg("smtp-password")) with open("emails/password-reset") as f: message = MIMEText(pystache.render(f.read(), { 'user': user, "domain": _cfg("domain"), 'confirmation': user.passwordReset })) message['X-MC-Important'] = "true" message['Subject'] = "Reset your password on Kerbal Stuff" message['From'] = "*****@*****.**" message['To'] = user.email smtp.sendmail("*****@*****.**", [ user.email ], message.as_string()) smtp.quit()
def connect_with_oauth(): provider = request.form.get('provider') if not is_oauth_provider_configured(provider): return 'This install is not configured for login with %s' % provider oauth = get_oauth_provider(provider) callback = "{}://{}{}".format( _cfg("protocol"), _cfg("domain"), url_for('.connect_with_oauth_authorized_' + provider)) return oauth.authorize(callback=callback)
def browse_featured_rss(): mods = Featured.query.order_by(desc(Featured.created)) mods = mods.limit(30) # Fix dates for f in mods: f.mod.created = f.created mods = [dumb_object(f.mod) for f in mods] db.rollback() return Response(render_template("rss.xml", mods=mods, title="Featured mods on Kerbal Stuff",\ description="Featured mods on Kerbal Stuff", \ url="/browse/featured", site_name=_cfg('site-name'), support_mail=_cfg('support-mail')), mimetype="text/xml")
def background_thumb(self): if (_cfg('thumbnail_size') == ''): return self.background thumbnailSizesStr = _cfg('thumbnail_size').split('x') thumbnailSize = (int(thumbnailSizesStr[0]), int(thumbnailSizesStr[1])) split = os.path.split(self.background) thumbPath = os.path.join(split[0], 'thumb_' + split[1]) fullThumbPath = os.path.join(os.path.join(_cfg('storage'), thumbPath.replace('/content/', ''))) fullImagePath = os.path.join(_cfg('storage'), self.background.replace('/content/', '')) if not os.path.exists(fullThumbPath): thumbnail.create(fullImagePath, fullThumbPath, thumbnailSize) return thumbPath
def browse_featured_rss(): mods = Featured.query.order_by(desc(Featured.created)) mods = mods.limit(30) # Fix dates for f in mods: f.mod.created = f.created mods = [dumb_object(f.mod) for f in mods] db.rollback() return Response(render_template("rss.xml", mods=mods, title="Featured mods on " + _cfg('site-name'),\ description="Featured mods on " + _cfg('site-name'), \ url="/browse/featured", site_name=_cfg('site-name'), support_mail=_cfg('support-mail')), mimetype="text/xml")
def send_reset(user): if _cfg("smtp-host") == "": return with open("emails/password-reset") as f: message = MIMEText(html.parser.HTMLParser().unescape(\ pystache.render(f.read(), { 'user': user, "domain": _cfg("domain"), 'confirmation': user.passwordReset }))) message['X-MC-Important'] = "true" message['X-MC-PreserveRecipients'] = "false" message['Subject'] = "Reset your password on Planet RimWorld Mods" message['From'] = "*****@*****.**" message['To'] = user.email sendEmail(message,user.email)
def backend(): users = User.query.count() new_users = User.query.order_by(desc(User.created)).limit(24) mods = Mod.query.count() versions = GameVersion.query.order_by(desc(GameVersion.id)).all() return render_template("admin.html", users=users, mods=mods, new_users=new_users, versions=versions, site_name=_cfg('site-name'), support_mail=_cfg('support-mail'))
def send_bulk_email(users, subject, body): if _cfg("smtp-host") == "": return for u in users: smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port")) smtp.login(_cfg("smtp-user"), _cfg("smtp-password")) message = MIMEText(body) message['Subject'] = subject message['From'] = "*****@*****.**" message['To'] = u smtp.sendmail("*****@*****.**", [ u ], message.as_string()) smtp.quit()
def browse_new_rss(): mods = Mod.query.filter(Mod.published).order_by(desc(Mod.created)) mods = mods.limit(30) return Response( render_template( "rss.xml", mods=mods, title="New mods on " + _cfg("site-name"), description="The newest mods on " + _cfg("site-name"), url="/browse/new", ), mimetype="text/xml", )
def send_grant_notice(mod, user): if _cfg("smtp-host") == "": return with open("emails/grant-notice") as f: message = MIMEText(html.parser.HTMLParser().unescape(\ pystache.render(f.read(), { 'user': user, "domain": _cfg("domain"),\ 'mod': mod, 'url': url_for('mods.mod', id=mod.id, mod_name=mod.name) }))) message['X-MC-Important'] = "true" message['X-MC-PreserveRecipients'] = "false" message['Subject'] = "You've been asked to co-author a mod on Planet RimWorld Mods" message['From'] = "*****@*****.**" message['To'] = user.email sendEmail(message,user.email)
def singlegame_browse_new_rss(gameshort): if not gameshort: gameshort = 'kerbal-space-program' ga = Game.query.filter(Game.short == gameshort).first() session['game'] = ga.id session['gamename'] = ga.name session['gameshort'] = ga.short session['gameid'] = ga.id mods = Mod.query.filter(Mod.published, Mod.game_id == ga.id).order_by(desc(Mod.created)) mods = mods.limit(30) return Response(render_template("rss.xml", mods=mods, title="New mods on " + _cfg('site-name'),ga = ga,\ description="The newest mods on " + _cfg('site-name'), \ url="/browse/new"), mimetype="text/xml")
def inject(): ads = True first_visit = True if 'ad-opt-out' in request.cookies: ads = False if g.do_not_track: ads = False if not _cfg("project_wonderful_id"): ads = False if request.cookies.get('first_visit') != None: first_visit = False return { 'mobile': g.mobile, 'ua_platform': request.user_agent.platform, 'analytics_id': _cfg("google_analytics_id"), 'analytics_domain': _cfg("google_analytics_domain"), 'disqus_id': _cfg("disqus_id"), 'dnt': g.do_not_track, 'ads': ads, 'ad_id': _cfg("project_wonderful_id"), 'root': _cfg("protocol") + "://" + _cfg("domain"), 'domain': _cfg("domain"), 'user': current_user, 'len': len, 'any': any, 'following_mod': following_mod, 'following_user': following_user, 'admin': is_admin(), 'wrap_mod': wrap_mod, 'dumb_object': dumb_object, 'first_visit': first_visit, 'request': request, 'locale': locale, 'url_for': url_for }
def inject(): ads = True if 'ad-opt-out' in request.cookies: ads = False if g.do_not_track: ads = False if not _cfg("project_wonderful_id"): ads = False return { 'mobile': g.mobile, 'ua_platform': request.user_agent.platform, 'analytics_id': _cfg("google_analytics_id"), 'analytics_domain': _cfg("google_analytics_domain"), 'disqus_id': _cfg("disqus_id"), 'dnt': g.do_not_track, 'ads': ads, 'ad_id': _cfg("project_wonderful_id"), 'root': _cfg("protocol") + "://" + _cfg("domain"), 'domain': _cfg("domain"), 'user': get_user(), 'len': len, 'any': any, 'following_mod': following_mod, 'following_user': following_user, 'bgindex': random.choice(range(0, 11)), 'admin': is_admin(), 'wrap_mod': wrap_mod, 'dumb_object': dumb_object }
def send_bulk_email(users, subject, body): if _cfg("smtp-host") == "": return targets = list() for u in users: targets.append(u) smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port")) smtp.login(_cfg("smtp-user"), _cfg("smtp-password")) message = MIMEText(body) message['X-MC-PreserveRecipients'] = "false" message['Subject'] = subject message['From'] = "*****@*****.**" message['To'] = ";".join(targets) smtp.sendmail("*****@*****.**", targets, message.as_string()) smtp.quit()
def forgot_password(): if request.method == 'GET': return render_template("forgot.html", **{ "site_name": _cfg('site-name'), "support_mail": _cfg('support-mail') }) else: email = request.form.get('email') if not email: return render_template("forgot.html", **{ "bad_email": True, "site_name": _cfg('site-name'), "support_mail": _cfg('support-mail') }) user = User.query.filter(User.email == email).first() if not user: return render_template("forgot.html", **{ "bad_email": True, "email": email, "site_name": _cfg('site-name'), "support_mail": _cfg('support-mail') }) user.passwordReset = binascii.b2a_hex(os.urandom(20)).decode("utf-8") user.passwordResetExpiry = datetime.now() + timedelta(days=1) db.commit() send_reset(user) return render_template("forgot.html", **{ "success": True, "site_name": _cfg('site-name'), "support_mail": _cfg('support-mail') })
def send_reset(user): if _cfg("smtp-host") == "": return smtp = smtplib.SMTP(_cfg("smtp-host"), _cfgi("smtp-port")) smtp.login(_cfg("smtp-user"), _cfg("smtp-password")) with open("emails/password-reset") as f: message = MIMEText(html.parser.HTMLParser().unescape(\ pystache.render(f.read(), { 'user': user, "domain": _cfg("domain"), 'confirmation': user.passwordReset }))) message['X-MC-Important'] = "true" message['X-MC-PreserveRecipients'] = "false" message['Subject'] = "Reset your password on Kerbal Stuff" message['From'] = "*****@*****.**" message['To'] = user.email smtp.sendmail("*****@*****.**", [ user.email ], message.as_string()) smtp.quit()