diff --git a/app/blueprints/api/tokens.py b/app/blueprints/api/tokens.py index 28df7b6d..62976109 100644 --- a/app/blueprints/api/tokens.py +++ b/app/blueprints/api/tokens.py @@ -20,10 +20,10 @@ from flask_babel import lazy_gettext from flask_login import login_required, current_user from flask_wtf import FlaskForm from wtforms import * -from wtforms_sqlalchemy.fields import QuerySelectField from wtforms.validators import * +from wtforms_sqlalchemy.fields import QuerySelectField -from app.models import db, User, APIToken, Package, Permission +from app.models import db, User, APIToken, Permission from app.utils import randomString from . import bp from ..users.settings import get_setting_tabs @@ -137,8 +137,6 @@ def delete_token(username, id): if not user.check_perm(current_user, Permission.CREATE_TOKEN): abort(403) - is_new = id is None - token = APIToken.query.get(id) if token is None: abort(404) diff --git a/app/blueprints/github/__init__.py b/app/blueprints/github/__init__.py index 4f657eba..ef52d9de 100644 --- a/app/blueprints/github/__init__.py +++ b/app/blueprints/github/__init__.py @@ -38,10 +38,10 @@ def view_permissions(): current_app.config["GITHUB_CLIENT_ID"] return redirect(url) + @bp.route("/github/callback/") @github.authorized_handler def callback(oauth_token): - next_url = request.args.get("next") if oauth_token is None: flash(gettext("Authorization failed [err=gh-oauth-login-failed]"), "danger") return redirect(url_for("users.login")) diff --git a/app/blueprints/packages/packages.py b/app/blueprints/packages/packages.py index 9aeb676d..e2c2911e 100644 --- a/app/blueprints/packages/packages.py +++ b/app/blueprints/packages/packages.py @@ -13,29 +13,29 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -import typing + from urllib.parse import quote as urlescape -from flask import render_template, make_response from celery import uuid -from flask_wtf import FlaskForm +from flask import render_template, make_response from flask_login import login_required +from flask_wtf import FlaskForm from jinja2.utils import markupsafe from sqlalchemy import func from sqlalchemy.orm import joinedload, subqueryload from wtforms import * -from wtforms_sqlalchemy.fields import QuerySelectField, QuerySelectMultipleField from wtforms.validators import * +from wtforms_sqlalchemy.fields import QuerySelectField, QuerySelectMultipleField -from app.querybuilder import QueryBuilder -from app.rediscache import has_key, set_key -from app.tasks.importtasks import importRepoScreenshot, checkZipRelease -from app.utils import * -from . import bp, get_package_tabs from app.logic.LogicError import LogicError from app.logic.packages import do_edit_package from app.models.packages import PackageProvides +from app.querybuilder import QueryBuilder +from app.rediscache import has_key, set_key +from app.tasks.importtasks import importRepoScreenshot, checkZipRelease from app.tasks.webhooktasks import post_discord_webhook +from app.utils import * +from . import bp, get_package_tabs from ...logic.game_support import GameSupportResolver @@ -253,7 +253,7 @@ class PackageForm(FlaskForm): submit = SubmitField(lazy_gettext("Save")) - def validate_name(form, field): + def validate_name(self, field): if field.data == "_game": raise ValidationError(lazy_gettext("_game is not an allowed name")) diff --git a/app/blueprints/threads/__init__.py b/app/blueprints/threads/__init__.py index 6ca13b53..502e860a 100644 --- a/app/blueprints/threads/__init__.py +++ b/app/blueprints/threads/__init__.py @@ -101,7 +101,6 @@ def set_lock(id): if thread.locked is None: abort(400) - msg = None if thread.locked: msg = "Locked thread '{}'".format(thread.title) flash(gettext("Locked thread"), "success") diff --git a/app/blueprints/users/account.py b/app/blueprints/users/account.py index b58bbd27..566347ac 100644 --- a/app/blueprints/users/account.py +++ b/app/blueprints/users/account.py @@ -17,7 +17,7 @@ from flask import * -from flask_babel import gettext, lazy_gettext, get_locale +from flask_babel import gettext, get_locale from flask_login import current_user, login_required, logout_user, login_user from flask_wtf import FlaskForm from sqlalchemy import or_ @@ -28,8 +28,6 @@ from app.models import * from app.tasks.emails import send_verify_email, send_anon_email, send_unsubscribe_verify, send_user_email from app.utils import randomString, make_flask_login_password, is_safe_url, check_password_hash, addAuditLog, \ nonEmptyOrNone, post_login, is_username_valid -from passlib.pwd import genphrase - from . import bp diff --git a/app/blueprints/users/claim.py b/app/blueprints/users/claim.py index da20cb8f..6949a282 100644 --- a/app/blueprints/users/claim.py +++ b/app/blueprints/users/claim.py @@ -73,7 +73,6 @@ def claim_forums(): return redirect(url_for("users.claim_forums")) # Get signature - sig = None try: profile = getProfile("https://forum.minetest.net", username) sig = profile.signature if profile else None diff --git a/app/blueprints/users/settings.py b/app/blueprints/users/settings.py index b22f8608..aec179eb 100644 --- a/app/blueprints/users/settings.py +++ b/app/blueprints/users/settings.py @@ -1,5 +1,5 @@ from flask import * -from flask_babel import gettext, lazy_gettext, get_locale +from flask_babel import gettext, get_locale from flask_login import current_user, login_required, logout_user from flask_wtf import FlaskForm from sqlalchemy import or_ @@ -7,8 +7,8 @@ from wtforms import * from wtforms.validators import * from app.models import * -from app.utils import nonEmptyOrNone, addAuditLog, randomString, rank_required, has_blocked_domains from app.tasks.emails import send_verify_email +from app.utils import nonEmptyOrNone, addAuditLog, randomString, rank_required, has_blocked_domains from . import bp diff --git a/app/default_data.py b/app/default_data.py index 7db893e0..c5f12abe 100644 --- a/app/default_data.py +++ b/app/default_data.py @@ -52,7 +52,6 @@ def populate_test_data(session): tags = { x.name : x for x in Tag.query.all() } admin_user = User.query.filter_by(rank=UserRank.ADMIN).first() v4 = MinetestRelease.query.filter_by(protocol=32).first() - v50 = MinetestRelease.query.filter_by(protocol=37).first() v51 = MinetestRelease.query.filter_by(protocol=38).first() ez = User("Shara") @@ -381,7 +380,6 @@ Uses the CTF PvP Engine. metas = {} for package in Package.query.filter_by(type=PackageType.MOD).all(): - meta = None try: meta = metas[package.name] except KeyError: diff --git a/app/logic/graphs.py b/app/logic/graphs.py index 3d44b87b..d5bcacba 100644 --- a/app/logic/graphs.py +++ b/app/logic/graphs.py @@ -134,7 +134,7 @@ def get_package_overview_for_user(user: Optional[User], start_date: datetime.dat return result -def get_all_package_stats(start_date: Optional[datetime.date], end_date: Optional[datetime.date]): +def get_all_package_stats(start_date: Optional[datetime.date] = None, end_date: Optional[datetime.date] = None): now_date = datetime.datetime.utcnow().date() if end_date is None or end_date > now_date: end_date = now_date diff --git a/app/logic/packages.py b/app/logic/packages.py index 30928418..6e245048 100644 --- a/app/logic/packages.py +++ b/app/logic/packages.py @@ -16,8 +16,10 @@ import json import re +import typing + import validators -from flask_babel import lazy_gettext +from flask_babel import lazy_gettext, LazyString from app.logic.LogicError import LogicError from app.models import User, Package, PackageType, MetaPackage, Tag, ContentWarning, db, Permission, AuditSeverity, \ @@ -26,7 +28,7 @@ from app.utils import addAuditLog, has_blocked_domains, diff_dictionaries, descr from app.utils.url import clean_youtube_url -def check(cond: bool, msg: str): +def check(cond: bool, msg: typing.Union[str, LazyString]): if not cond: raise LogicError(400, msg) diff --git a/app/logic/screenshots.py b/app/logic/screenshots.py index 8560055e..869255c6 100644 --- a/app/logic/screenshots.py +++ b/app/logic/screenshots.py @@ -64,9 +64,9 @@ def do_order_screenshots(_user: User, package: Package, order: [any]): try: lookup[int(ss_id)].order = counter counter += 1 - except KeyError as e: + except KeyError: raise LogicError(400, "Unable to find screenshot with id={}".format(ss_id)) - except (ValueError, TypeError) as e: + except (ValueError, TypeError): raise LogicError(400, "Invalid id, not a number: {}".format(json.dumps(ss_id))) db.session.commit() @@ -75,7 +75,7 @@ def do_order_screenshots(_user: User, package: Package, order: [any]): def do_set_cover_image(_user: User, package: Package, cover_image): try: cover_image = int(cover_image) - except (ValueError, TypeError) as e: + except (ValueError, TypeError): raise LogicError(400, "Invalid id, not a number: {}".format(json.dumps(cover_image))) for screenshot in package.screenshots.all(): diff --git a/app/models/packages.py b/app/models/packages.py index 213f83c9..b6bfc686 100644 --- a/app/models/packages.py +++ b/app/models/packages.py @@ -214,30 +214,6 @@ PACKAGE_STATE_FLOW = { } -class PackagePropertyKey(enum.Enum): - name = "Name" - title = "Title" - short_desc = "Short Description" - desc = "Description" - type = "Type" - license = "License" - media_license = "Media License" - tags = "Tags" - provides = "Provides" - repo = "Repository" - website = "Website" - issueTracker = "Issue Tracker" - forums = "Forum Topic ID" - - def convert(self, value): - if self == PackagePropertyKey.tags: - return ",".join([t.title for t in value]) - elif self == PackagePropertyKey.provides: - return ",".join([t.name for t in value]) - else: - return str(value) - - PackageProvides = db.Table("provides", db.Column("package_id", db.Integer, db.ForeignKey("package.id"), primary_key=True), db.Column("metapackage_id", db.Integer, db.ForeignKey("meta_package.id"), primary_key=True) @@ -491,9 +467,6 @@ class Package(db.Model): self.maintainers.append(self.author) - for e in PackagePropertyKey: - setattr(self, e.name, getattr(package, e.name)) - @classmethod def get_by_key(cls, key): parts = key.split("/") diff --git a/app/querybuilder.py b/app/querybuilder.py index 5658ce62..59d5bc15 100644 --- a/app/querybuilder.py +++ b/app/querybuilder.py @@ -40,7 +40,6 @@ class QueryBuilder: self.random or self.lucky or self.author or self.version or self.game) def __init__(self, args): - title = "Packages" # Get request types types = args.getlist("type") diff --git a/app/tasks/__init__.py b/app/tasks/__init__.py index c80fd349..5e419430 100644 --- a/app/tasks/__init__.py +++ b/app/tasks/__init__.py @@ -28,9 +28,13 @@ class TaskError(Exception): def __str__(self): return repr("TaskError: " + self.value) + class FlaskCelery(Celery): + app: flask.app + def __init__(self, *args, **kwargs): super(FlaskCelery, self).__init__(*args, **kwargs) + self.app = None self.patch_task() if 'app' in kwargs: @@ -56,6 +60,7 @@ class FlaskCelery(Celery): self.app = app self.config_from_object(app.config) + def make_celery(app): celery = FlaskCelery(app.import_name, backend=app.config['CELERY_RESULT_BACKEND'], broker=app.config['CELERY_BROKER_URL']) @@ -63,8 +68,10 @@ def make_celery(app): celery.init_app(app) return celery + celery = make_celery(app) + CELERYBEAT_SCHEDULE = { 'topic_list_import': { 'task': 'app.tasks.forumtasks.importTopicList', @@ -97,6 +104,7 @@ CELERYBEAT_SCHEDULE = { } celery.conf.beat_schedule = CELERYBEAT_SCHEDULE + from . import importtasks, forumtasks, emails, pkgtasks, usertasks diff --git a/app/tasks/emails.py b/app/tasks/emails.py index 7972b847..ca146e2e 100644 --- a/app/tasks/emails.py +++ b/app/tasks/emails.py @@ -14,10 +14,11 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import typing from typing import Dict from flask import render_template, escape -from flask_babel import force_locale, gettext, lazy_gettext +from flask_babel import force_locale, gettext, lazy_gettext, LazyString from flask_mail import Message from app import mail from app.models import Notification, db, EmailSubscription, User @@ -90,7 +91,8 @@ def send_unsubscribe_verify(email, locale): @celery.task(rate_limit="25/m") -def send_email_with_reason(email: str, locale: str, subject: str, text: str, html: str, reason: str, conn: any): +def send_email_with_reason(email: str, locale: str, subject: str, text: str, html: str, + reason: typing.Union[str, LazyString], conn: any): sub = get_email_subscription(email) if sub.blacklisted: return diff --git a/app/template_filters.py b/app/template_filters.py index 28ad4275..c1b13065 100644 --- a/app/template_filters.py +++ b/app/template_filters.py @@ -1,16 +1,15 @@ -import jinja2.nodes +from datetime import datetime as dt +from urllib.parse import urlparse + +from flask_babel import format_timedelta, gettext +from flask_login import current_user from markupsafe import Markup from . import app, utils +from .markdown import get_headings from .models import Permission, Package, PackageState, PackageRelease from .utils import abs_url_for, url_set_query, url_set_anchor, url_current from .utils.minetest_hypertext import normalize_whitespace as do_normalize_whitespace -from .markdown import get_headings - -from flask_login import current_user -from flask_babel import format_timedelta, gettext -from urllib.parse import urlparse -from datetime import datetime as dt @app.context_processor diff --git a/app/utils/flask.py b/app/utils/flask.py index 0a4a4bd9..2651ecd8 100644 --- a/app/utils/flask.py +++ b/app/utils/flask.py @@ -14,9 +14,9 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import typing from urllib.parse import urljoin, urlparse, urlunparse -import typing import user_agents from flask import request, abort from flask_babel import LazyString diff --git a/app/utils/git.py b/app/utils/git.py index e1363245..9475ce85 100644 --- a/app/utils/git.py +++ b/app/utils/git.py @@ -47,7 +47,6 @@ def get_temp_dir(): def clone_repo(urlstr, ref=None, recursive=False): gitDir = os.path.join(tempfile.gettempdir(), randomString(10)) - err = None try: gitUrl = generate_git_url(urlstr) print("Cloning from " + gitUrl) diff --git a/app/utils/models.py b/app/utils/models.py index d7d54647..c93654f0 100644 --- a/app/utils/models.py +++ b/app/utils/models.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . - +import typing from functools import wraps from typing import List @@ -87,7 +87,8 @@ def addNotification(target, causer: User, type: NotificationType, title: str, ur db.session.add(notif) -def addAuditLog(severity: AuditSeverity, causer: User, title: str, url: str, package : Package =None, description : str =None): +def addAuditLog(severity: AuditSeverity, causer: User, title: str, url: typing.Optional[str], + package: Package = None, description: str = None): entry = AuditLogEntry(causer, severity, title, url, package, description) db.session.add(entry)