def upload_file(file, fileType, fileTypeDesc): if not file or file is None or file.filename == "": raise LogicError(400, "Expected file") assert os.path.isdir(app.config["UPLOAD_DIR"]), "UPLOAD_DIR must exist" isImage = False if fileType == "image": allowedExtensions = ["jpg", "jpeg", "png"] isImage = True elif fileType == "zip": allowedExtensions = ["zip"] else: raise Exception("Invalid fileType") ext = get_extension(file.filename) if ext is None or not ext in allowedExtensions: raise LogicError(400, "Please upload " + fileTypeDesc) if isImage and not isAllowedImage(file.stream.read()): raise LogicError(400, "Uploaded image isn't actually an image") file.stream.seek(0) filename = randomString(10) + "." + ext filepath = os.path.join(app.config["UPLOAD_DIR"], filename) file.save(filepath) return "/uploads/" + filename, filepath
def importRepoScreenshot(id): package = Package.query.get(id) if package is None: raise Exception("Unexpected none package") # Get URL Maker url = urlparse(package.repo) urlmaker = None if url.netloc == "github.com": urlmaker = GithubURLMaker(url) else: raise TaskError("Unsupported repo") if not urlmaker.isValid(): raise TaskError("Error! Url maker not valid") try: filename = randomString(10) + ".png" imagePath = os.path.join("app/public/uploads", filename) print(imagePath) urllib.request.urlretrieve(urlmaker.getScreenshotURL(), imagePath) ss = PackageScreenshot() ss.package = package ss.title = "screenshot.png" ss.url = "/uploads/" + filename db.session.add(ss) db.session.commit() return "/uploads/" + filename except HTTPError: print("screenshot.png does not exist") return None
def makeVCSRelease(id, branch): release = PackageRelease.query.get(id) if release is None: raise TaskError("No such release!") elif release.package is None: raise TaskError("No package attached to release") urlmaker = None url = urlparse(release.package.repo) if url.netloc == "github.com": return makeVCSReleaseFromGithub(id, branch, release, url) else: gitDir, repo = cloneRepo(release.package.repo, ref=branch, recursive=True) try: filename = randomString(10) + ".zip" destPath = os.path.join("app/public/uploads", filename) with open(destPath, "wb") as fp: repo.archive(fp, format="zip") release.url = "/uploads/" + filename release.task_id = None release.commit_hash = repo.head.object.hexsha release.approve(release.package.author) print(release.url) db.session.commit() return release.url finally: shutil.rmtree(gitDir)
def makeVCSRelease(self, id, branch): release = PackageRelease.query.get(id) if release is None: raise TaskError("No such release!") elif release.package is None: raise TaskError("No package attached to release") with clone_repo(release.package.repo, ref=branch, recursive=True) as repo: postReleaseCheckUpdate(self, release, repo.working_tree_dir) filename = randomString(10) + ".zip" destPath = os.path.join(app.config["UPLOAD_DIR"], filename) assert(not os.path.isfile(destPath)) archiver = GitArchiver(prefix=release.package.name, force_sub=True, main_repo_abspath=repo.working_tree_dir) archiver.create(destPath) assert(os.path.isfile(destPath)) release.url = "/uploads/" + filename release.task_id = None release.commit_hash = repo.head.object.hexsha release.approve(release.package.author) db.session.commit() return release.url
def importRepoScreenshot(id): package = Package.query.get(id) if package is None or package.state == PackageState.DELETED: raise Exception("Unexpected none package") try: with clone_repo(package.repo) as repo: for ext in ["png", "jpg", "jpeg"]: sourcePath = repo.working_tree_dir + "/screenshot." + ext if os.path.isfile(sourcePath): filename = randomString(10) + "." + ext destPath = os.path.join(app.config["UPLOAD_DIR"], filename) shutil.copyfile(sourcePath, destPath) ss = PackageScreenshot() ss.approved = True ss.package = package ss.title = "screenshot.png" ss.url = "/uploads/" + filename db.session.add(ss) db.session.commit() return "/uploads/" + filename except TaskError as e: # ignore download errors print(e) pass print("screenshot.png does not exist") return None
def makeVCSRelease(self, id, branch): release = PackageRelease.query.get(id) if release is None: raise TaskError("No such release!") elif release.package is None: raise TaskError("No package attached to release") gitDir, repo = cloneRepo(release.package.repo, ref=branch, recursive=True) postReleaseCheckUpdate(self, release, gitDir) try: filename = randomString(10) + ".zip" destPath = os.path.join(app.config["UPLOAD_DIR"], filename) assert (not os.path.isfile(destPath)) archiver = GitArchiver(force_sub=True, main_repo_abspath=gitDir) archiver.create(destPath) assert (os.path.isfile(destPath)) release.url = "/uploads/" + filename release.task_id = None release.commit_hash = repo.head.object.hexsha release.approve(release.package.author) db.session.commit() updateMetaFromRelease.delay(release.id, destPath) return release.url finally: shutil.rmtree(gitDir)
def handle_set_password(form): one = form.password.data two = form.password2.data if one != two: flash("Passwords do not much", "danger") return addAuditLog(AuditSeverity.USER, current_user, "Changed their password", url_for("users.profile", username=current_user.username)) current_user.password = make_flask_login_password(form.password.data) if hasattr(form, "email"): newEmail = nonEmptyOrNone(form.email.data) if newEmail and newEmail != current_user.email: if EmailSubscription.query.filter_by(email=form.email.data, blacklisted=True).count() > 0: flash( "That email address has been unsubscribed/blacklisted, and cannot be used", "danger") return token = randomString(32) ver = UserEmailVerification() ver.user = current_user ver.token = token ver.email = newEmail db.session.add(ver) db.session.commit() flash("Your password has been changed successfully.", "success") return redirect(url_for("homepage.home"))
def forgot_password(): form = ForgotPasswordForm(request.form) if form.validate_on_submit(): email = form.email.data user = User.query.filter_by(email=email).first() if user: token = randomString(32) addAuditLog(AuditSeverity.USER, user, "(Anonymous) requested a password reset", url_for("users.profile", username=user.username), None) ver = UserEmailVerification() ver.user = user ver.token = token ver.email = email ver.is_password_reset = True db.session.add(ver) db.session.commit() send_verify_email.delay(form.email.data, token) else: send_anon_email.delay(email, "Unable to find account", """ <p> We were unable to perform the password reset as we could not find an account associated with this email. </p> <p> If you weren't expecting to receive this email, then you can safely ignore it. </p> """) flash("Check your email address to continue the reset", "success") return redirect(url_for("homepage.home")) return render_template("users/forgot_password.html", form=form)
def handle_register(form): user_by_name = User.query.filter( or_(User.username == form.username.data, User.username == form.display_name.data, User.display_name == form.display_name.data, User.forums_username == form.username.data, User.github_username == form.username.data)).first() if user_by_name: if user_by_name.rank == UserRank.NOT_JOINED and user_by_name.forums_username: flash( "An account already exists for that username but hasn't been claimed yet.", "danger") return redirect( url_for("users.claim_forums", username=user_by_name.forums_username)) else: flash( "That username/display name is already in use, please choose another.", "danger") return user_by_email = User.query.filter_by(email=form.email.data).first() if user_by_email: send_anon_email.delay( form.email.data, "Email already in use", "We were unable to create the account as the email is already in use by {}. Try a different email address." .format(user_by_email.display_name)) flash("Check your email address to verify your account", "success") return redirect(url_for("homepage.home")) elif EmailSubscription.query.filter_by(email=form.email.data, blacklisted=True).count() > 0: flash( "That email address has been unsubscribed/blacklisted, and cannot be used", "danger") return user = User(form.username.data, False, form.email.data, make_flask_login_password(form.password.data)) user.notification_preferences = UserNotificationPreferences(user) if form.display_name.data: user.display_name = form.display_name.data db.session.add(user) addAuditLog(AuditSeverity.USER, user, "Registered with email, display name=" + user.display_name, url_for("users.profile", username=user.username)) token = randomString(32) ver = UserEmailVerification() ver.user = user ver.token = token ver.email = form.email.data db.session.add(ver) db.session.commit() send_verify_email.delay(form.email.data, token) flash("Check your email address to verify your account", "success") return redirect(url_for("homepage.home"))
def reset_token(username, id): user = User.query.filter_by(username=username).first() if user is None: abort(404) if not user.checkPerm(current_user, Permission.CREATE_TOKEN): abort(403) is_new = id is None token = APIToken.query.get(id) if token is None: abort(404) elif token.owner != user: abort(403) token.access_token = randomString(32) db.session.commit() # save # Store token so it can be shown in the edit page session["token_" + str(token.id)] = token.access_token return redirect( url_for("api.create_edit_token", username=username, id=token.id))
def set_password_page(): if current_user.password is not None: return redirect(url_for("user.change_password")) form = SetPasswordForm(request.form) if current_user.email == None: form.email.validators = [InputRequired(), Email()] if request.method == "POST" and form.validate(): one = form.password.data two = form.password2.data if one == two: # Hash password hashed_password = user_manager.hash_password(form.password.data) # Change password user_manager.update_password(current_user, hashed_password) # Send 'password_changed' email if user_manager.enable_email and user_manager.send_password_changed_email and current_user.email: emails.send_password_changed_email(current_user) # Send password_changed signal signals.user_changed_password.send( current_app._get_current_object(), user=current_user) # Prepare one-time system message flash('Your password has been changed successfully.', 'success') newEmail = form["email"].data if newEmail != current_user.email and newEmail.strip() != "": token = randomString(32) ver = UserEmailVerification() ver.user = current_user ver.token = token ver.email = newEmail db.session.add(ver) db.session.commit() task = sendVerifyEmail.delay(newEmail, token) return redirect( url_for("check_task", id=task.id, r=url_for("user_profile_page", username=current_user.username))) else: return redirect( url_for("user_profile_page", username=current_user.username)) else: flash("Passwords do not match", "error") return render_template("users/set_password.html", form=form, optional=request.args.get("optional"))
def get_email_subscription(email): assert type(email) == str ret = EmailSubscription.query.filter_by(email=email).first() if not ret: ret = EmailSubscription(email) ret.token = randomString(32) db.session.add(ret) db.session.commit() return ret
def getOrCreateImage(self, image, dir_path): ext = getImageType(image) if ext is not None: filename = randomString(10) + "." + ext path = os.path.join(dir_path, filename) with open(path, "wb") as f: f.write(image) return "/static/uploads/" + filename return None
def create_edit_token(username, id=None): user = User.query.filter_by(username=username).first() if user is None: abort(404) if not user.checkPerm(current_user, Permission.CREATE_TOKEN): abort(403) is_new = id is None token = None access_token = None if not is_new: token = APIToken.query.get(id) if token is None: abort(404) elif token.owner != user: abort(403) access_token = session.pop("token_" + str(token.id), None) form = CreateAPIToken(formdata=request.form, obj=token) form.package.query_factory = lambda: Package.query.filter_by(author=user ).all() if form.validate_on_submit(): if is_new: token = APIToken() token.owner = user token.access_token = randomString(32) form.populate_obj(token) db.session.add(token) db.session.commit() # save if is_new: # Store token so it can be shown in the edit page session["token_" + str(token.id)] = token.access_token return redirect( url_for("api.create_edit_token", username=username, id=token.id)) return render_template("api/create_edit_token.html", user=user, form=form, token=token, access_token=access_token)
def unsubscribe_verify(): form = UnsubscribeForm(request.form) if form.validate_on_submit(): email = form.email.data sub = EmailSubscription.query.filter_by(email=email).first() if not sub: sub = EmailSubscription(email) db.session.add(sub) sub.token = randomString(32) db.session.commit() send_unsubscribe_verify.delay(form.email.data) flash("Check your email address to continue the unsubscribe", "success") return redirect(url_for("homepage.home")) return render_template("users/unsubscribe.html", form=form)
def registerReq(): req = request.get_json() username = None if 'username' in req: username = req['username'] if username is not None: userData = getUserByUsername(username, True) if userData is None: pendingHash = randomString() success = sendEmailWithLink(username, pendingHash) if success: setNewPendingUser(username, pendingHash) return 'success' else: return make_response('Something wrong!', 403) return make_response('User already exists!', 403)
def handle_email_notifications(user, prefs: UserNotificationPreferences, is_new, form): for notificationType in NotificationType: field_email = getattr(form, "pref_" + notificationType.toName()).data field_digest = getattr(form, "pref_" + notificationType.toName() + "_digest").data or field_email prefs.set_can_email(notificationType, field_email) prefs.set_can_digest(notificationType, field_digest) if is_new: db.session.add(prefs) if user.checkPerm(current_user, Permission.CHANGE_EMAIL): newEmail = form.email.data if newEmail and newEmail != user.email and newEmail.strip() != "": if EmailSubscription.query.filter_by(email=form.email.data, blacklisted=True).count() > 0: flash( "That email address has been unsubscribed/blacklisted, and cannot be used", "danger") return token = randomString(32) severity = AuditSeverity.NORMAL if current_user == user else AuditSeverity.MODERATION msg = "Changed email of {}".format(user.display_name) addAuditLog(severity, current_user, msg, url_for("users.profile", username=user.username)) ver = UserEmailVerification() ver.user = user ver.token = token ver.email = newEmail db.session.add(ver) db.session.commit() flash("Check your email to confirm it", "success") send_verify_email.delay(newEmail, token) return redirect( url_for("users.email_notifications", username=user.username)) db.session.commit() return redirect( url_for("users.email_notifications", username=user.username))
def setup_webhook(): pid = request.args.get("pid") if pid is None: abort(404) package = Package.query.get(pid) if package is None: abort(404) if not package.checkPerm(current_user, Permission.APPROVE_RELEASE): flash("Only trusted members can use webhooks", "danger") return redirect(package.getDetailsURL()) gh_user, gh_repo = package.getGitHubFullName() if gh_user is None or gh_repo is None: flash("Unable to get Github full name from repo address", "danger") return redirect(package.getDetailsURL()) if current_user.github_access_token is None: return github.authorize("write:repo_hook", redirect_uri=abs_url_for( "github.callback_webhook", pid=pid)) form = SetupWebhookForm(formdata=request.form) if form.validate_on_submit(): token = APIToken() token.name = "GitHub Webhook for " + package.title token.owner = current_user token.access_token = randomString(32) token.package = package event = form.event.data if event != "push" and event != "create": abort(500) if handleMakeWebhook(gh_user, gh_repo, package, current_user.github_access_token, event, token): flash("Successfully created webhook", "success") return redirect(package.getDetailsURL()) else: return redirect(url_for("github.setup_webhook", pid=package.id)) return render_template("github/setup_webhook.html", form=form, package=package)
def upload_image(): upload_id = randomString(8) upload_page = "/user_input/" + upload_id if request.method == "POST": if request.files: image = request.files['image'] filename = image.filename if image.filename == " ": print("image must have a filename") return redirect("/input") if not allowed_filename(filename): print("Image extenstion not allowed") return redirect("/input") else: file_name = "user_input_image" image.save(app.config["IMAGE_UPLOADS"] + file_name) return redirect(upload_page) return redirect("/input")
def makeVCSRelease(id, branch): release = PackageRelease.query.get(id) if release is None: raise TaskError("No such release!") elif release.package is None: raise TaskError("No package attached to release") gitDir, repo = cloneRepo(release.package.repo, ref=branch, recursive=True) tree = None try: tree = build_tree(gitDir, expected_type=ContentType[release.package.type.name], \ author=release.package.author.username, name=release.package.name) except MinetestCheckError as err: raise TaskError(str(err)) try: filename = randomString(10) + ".zip" destPath = os.path.join(app.config["UPLOAD_DIR"], filename) assert (not os.path.isfile(destPath)) archiver = GitArchiver(force_sub=True, main_repo_abspath=gitDir) archiver.create(destPath) assert (os.path.isfile(destPath)) release.url = "/uploads/" + filename release.task_id = None release.commit_hash = repo.head.object.hexsha if tree.meta.get("min_minetest_version"): release.min_rel = MinetestRelease.get( tree.meta["min_minetest_version"], None) if tree.meta.get("max_minetest_version"): release.max_rel = MinetestRelease.get( tree.meta["max_minetest_version"], None) release.approve(release.package.author) db.session.commit() return release.url finally: shutil.rmtree(gitDir)
def getShotUrlByLongUrl(longUrl): database = r"ShortUrlDb" # create a database connection conn = create_connection(database) with conn: row = select_link_by_LongUrl(conn, longUrl) if row != None: return row[2] else: # generate new shortUrl and insert to the Db shortUrl ='' while shortUrl=='': tempShortUrl = randomString() if(check_if_ShortUrl_exist(conn, tempShortUrl) == False): shortUrl = tempShortUrl #insert to the db insert_ShortUrl_to_db(conn,longUrl,shortUrl) return shortUrl
def clone_repo(urlstr, ref=None, recursive=False): gitDir = os.path.join(tempfile.gettempdir(), randomString(10)) err = None try: gitUrl = generateGitURL(urlstr) print("Cloning from " + gitUrl) if ref is None: repo = git.Repo.clone_from(gitUrl, gitDir, progress=None, env=None, depth=1, recursive=recursive, kill_after_timeout=15) else: assert ref != "" repo = git.Repo.init(gitDir) origin = repo.create_remote("origin", url=gitUrl) assert origin.exists() origin.fetch() repo.git.checkout(ref) if recursive: for submodule in repo.submodules: submodule.update(init=True) yield repo shutil.rmtree(gitDir) return except GitCommandError as e: # This is needed to stop the backtrace being weird err = e.stderr except gitdb.exc.BadName as e: err = "Unable to find the reference " + (ref or "?") + "\n" + e.stderr raise TaskError(err.replace("stderr: ", "") \ .replace("Cloning into '" + gitDir + "'...", "") \ .strip())
def cloneRepo(urlstr, ref=None, recursive=False): gitDir = tempfile.gettempdir() + "/" + randomString(10) err = None try: gitUrl = generateGitURL(urlstr) print("Cloning from " + gitUrl) repo = git.Repo.clone_from(gitUrl, gitDir, \ progress=None, env=None, depth=1, recursive=recursive, kill_after_timeout=15) if ref is not None: repo.create_head("myhead", ref).checkout() return gitDir, repo except GitCommandError as e: # This is needed to stop the backtrace being weird err = e.stderr raise TaskError(err.replace("stderr: ", "") \ .replace("Cloning into '" + gitDir + "'...", "") \ .strip())
def invite(): form = InviteForm(request.form) if request.method == "GET": form.invite.data = randomString(32) if form.validate_on_submit(): username = form.username.data if User.query.filter_by(username=username).first() is None: user = User() user.username = username user.invite = form.invite.data print(form.invite.data) assert (len(form.invite.data) == 32) db.session.add(user) db.session.commit() flash("Created username and for " + username, "success") return redirect(url_for('admin')) else: flash("User " + username + " already exists", "danger") return render_template("admin/invite.html", form=form)
def importForeignDownloads(self, id): release = PackageRelease.query.get(id) if release is None: raise TaskError("No such release!") elif release.package is None: raise TaskError("No package attached to release") elif not release.url.startswith("http"): return try: ext = getExtension(release.url) filename = randomString(10) + "." + ext filepath = os.path.join(app.config["UPLOAD_DIR"], filename) urllib.request.urlretrieve(release.url, filepath) release.url = "/uploads/" + filename db.session.commit() except urllib.error.URLError: db.session.rollback() release.task_id = self.request.id release.approved = False db.session.commit()
def importRepoScreenshot(id): package = Package.query.get(id) if package is None or package.soft_deleted: raise Exception("Unexpected none package") # Get URL Maker try: gitDir, _ = cloneRepo(package.repo) except TaskError as e: # ignore download errors print(e) return None # Find and import screenshot try: for ext in ["png", "jpg", "jpeg"]: sourcePath = gitDir + "/screenshot." + ext if os.path.isfile(sourcePath): filename = randomString(10) + "." + ext destPath = os.path.join("app/public/uploads", filename) shutil.copyfile(sourcePath, destPath) ss = PackageScreenshot() ss.approved = True ss.package = package ss.title = "screenshot.png" ss.url = "/uploads/" + filename db.session.add(ss) db.session.commit() return "/uploads/" + filename finally: shutil.rmtree(gitDir) print("screenshot.png does not exist") return None
def get_temp_dir(): temp = os.path.join(tempfile.gettempdir(), randomString(10)) yield temp shutil.rmtree(temp)
def user_profile_page(username): user = User.query.filter_by(username=username).first() if not user: abort(404) form = None if user.checkPerm(current_user, Permission.CHANGE_DNAME) or \ user.checkPerm(current_user, Permission.CHANGE_EMAIL) or \ user.checkPerm(current_user, Permission.CHANGE_RANK): # Initialize form form = UserProfileForm(formdata=request.form, obj=user) # Process valid POST if request.method == "POST" and form.validate(): # Copy form fields to user_profile fields if user.checkPerm(current_user, Permission.CHANGE_DNAME): user.display_name = form["display_name"].data user.website_url = form["website_url"].data user.donate_url = form["donate_url"].data if user.checkPerm(current_user, Permission.CHANGE_RANK): newRank = form["rank"].data if current_user.rank.atLeast(newRank): user.rank = form["rank"].data else: flash( "Can't promote a user to a rank higher than yourself!", "error") if user.checkPerm(current_user, Permission.CHANGE_EMAIL): newEmail = form["email"].data if newEmail != user.email and newEmail.strip() != "": token = randomString(32) ver = UserEmailVerification() ver.user = user ver.token = token ver.email = newEmail db.session.add(ver) db.session.commit() task = sendVerifyEmail.delay(newEmail, token) return redirect( url_for("check_task", id=task.id, r=url_for("user_profile_page", username=username))) # Save user_profile db.session.commit() # Redirect to home page return redirect(url_for("user_profile_page", username=username)) packages = user.packages.filter_by(soft_deleted=False) if not current_user.is_authenticated or ( user != current_user and not current_user.canAccessTodoList()): packages = packages.filter_by(approved=True) packages = packages.order_by(db.asc(Package.title)) topics_to_add = None if current_user == user or user.checkPerm(current_user, Permission.CHANGE_AUTHOR): topics_to_add = ForumTopic.query \ .filter_by(author_id=user.id) \ .filter(~ db.exists().where(Package.forums==ForumTopic.topic_id)) \ .order_by(db.asc(ForumTopic.name), db.asc(ForumTopic.title)) \ .all() # Process GET or invalid POST return render_template("users/user_profile_page.html", user=user, form=form, packages=packages, topics_to_add=topics_to_add)
def user_claim_page(): username = request.args.get("username") if username is None: username = "" else: method = request.args.get("method") user = User.query.filter_by(forums_username=username).first() if user and user.rank.atLeast(UserRank.NEW_MEMBER): flash("User has already been claimed", "error") return redirect(url_for("user_claim_page")) elif user is None and method == "github": flash("Unable to get Github username for user", "error") return redirect(url_for("user_claim_page")) elif user is None: flash("Unable to find that user", "error") return redirect(url_for("user_claim_page")) if user is not None and method == "github": return redirect(url_for("github_signin_page")) token = None if "forum_token" in session: token = session["forum_token"] else: token = randomString(32) session["forum_token"] = token if request.method == "POST": ctype = request.form.get("claim_type") username = request.form.get("username") if username is None or len(username.strip()) < 2: flash("Invalid username", "error") elif ctype == "github": task = checkForumAccount.delay(username) return redirect( url_for("check_task", id=task.id, r=url_for("user_claim_page", username=username, method="github"))) elif ctype == "forum": user = User.query.filter_by(forums_username=username).first() if user is not None and user.rank.atLeast(UserRank.NEW_MEMBER): flash("That user has already been claimed!", "error") return redirect(url_for("user_claim_page")) # Get signature sig = None try: profile = getProfile("https://forum.minetest.net", username) sig = profile.signature except IOError: flash("Unable to get forum signature - does the user exist?", "error") return redirect(url_for("user_claim_page", username=username)) # Look for key if token in sig: if user is None: user = User(username) user.forums_username = username db.session.add(user) db.session.commit() if loginUser(user): return redirect(url_for("set_password_page")) else: flash("Unable to login as user", "error") return redirect( url_for("user_claim_page", username=username)) else: flash("Could not find the key in your signature!", "error") return redirect(url_for("user_claim_page", username=username)) else: flash("Unknown claim type", "error") return render_template("users/claim.html", username=username, key=token)
class Config: NAME = os.getenv("NAME", "Flask App") SERVER_NAME = os.getenv("SERVER_NAME", "") ROOT_KEY = os.getenv("ROOT_KEY", randomKey(12)) SECRET_KEY = os.getenv("SECRET_KEY", randomString(25)) STRIPE = { "publishable_key": os.getenv("STRIPE_PUBLISHABLE_KEY"), "secret_key": os.getenv("STRIPE_SECRET_KEY"), } MAIL = { "url": "https://api.eu.mailgun.net/v3/", "domain": os.getenv("MAIL_DOMAIN"), "key": os.getenv("MAIL_KEY"), "from": os.getenv("MAIL_FROM_ADDRESS"), "reply-to": os.getenv("MAIL_REPLY_ADDRESS"), } CSP = { "default-src": [ "'self'", "'unsafe-inline'", "fonts.googleapis.com", "fonts.gstatic.com", "api.mapbox.com", ], "img-src": ["*", "data:", "blob:"], "script-src": [ "'self'", "'unsafe-inline'", "cdnjs.cloudflare.com", "js.stripe.com", "api.mapbox.com", ], "frame-src": [ "js.stripe.com", ], "worker-src": ["blob:"], "child-src": ["blob:"], "connect-src": [ "'self'", "*.tiles.mapbox.com", "api.mapbox.com", "events.mapbox.com", ], } COMPRESS_MIMETYPES = [ "text/html", "text/css", "text/xml", "application/json", "application/javascript", ] COMPRESS_LEVEL = 6 COMPRESS_MIN_SIZE = 500 SEND_FILE_MAX_AGE_DEFAULT = 31536000 MAX_CONTENT_LENGTH = 50 * 1024 * 1024 UPLOAD_FOLDER = "app/uploads" UPLOAD_EXTENSIONS = { "bmp", "gif", "jpg", "jpeg", "png", "webp", "avi", "mov", "mp4", "webm", } SQLALCHEMY_TRACK_MODIFICATIONS = False MAP = { "mapbox_key": os.getenv("MAPBOX_KEY", ""), "default_lat": os.getenv("MAP_DEFAULT_LAT", 0), "default_lon": os.getenv("MAP_DEFAULT_LON", 0), }