diff --git a/app/blueprints/admin/actions.py b/app/blueprints/admin/actions.py index 68762b9..8c62a18 100644 --- a/app/blueprints/admin/actions.py +++ b/app/blueprints/admin/actions.py @@ -26,8 +26,8 @@ from sqlalchemy import or_, and_ from app.logic.game_support import GameSupportResolver from app.models import PackageRelease, db, Package, PackageState, PackageScreenshot, MetaPackage, User, \ - NotificationType, PackageUpdateConfig, License, UserRank, PackageType, PackageGameSupport -from app.tasks.forumtasks import importTopicList, checkAllForumAccounts + NotificationType, PackageUpdateConfig, License, UserRank, PackageGameSupport +# from app.tasks.forumtasks import importTopicList, checkAllForumAccounts from app.tasks.importtasks import importRepoScreenshot, checkZipRelease, check_for_updates from app.tasks.appstreamtasks import importFromFlathub from app.utils import addNotification, get_system_user @@ -90,20 +90,20 @@ def reimport_packages(): return redirect(url_for("todo.view_editor")) -@action("Import forum topic list") -def import_topic_list(): - task = importTopicList.delay() - return redirect(url_for("tasks.check", id=task.id, r=url_for("admin.admin_page"))) +# @action("Import forum topic list") +# def import_topic_list(): +# task = importTopicList.delay() +# return redirect(url_for("tasks.check", id=task.id, r=url_for("admin.admin_page"))) @action("Import appstream from flathub") def import_from_flathub(): task = importFromFlathub.delay() return redirect(url_for("tasks.check", id=task.id, r=url_for("todo.topics"))) -@action("Check all forum accounts") -def check_all_forum_accounts(): - task = checkAllForumAccounts.delay() - return redirect(url_for("tasks.check", id=task.id, r=url_for("admin.admin_page"))) +# @action("Check all forum accounts") +# def check_all_forum_accounts(): +# task = checkAllForumAccounts.delay() +# return redirect(url_for("tasks.check", id=task.id, r=url_for("admin.admin_page"))) @action("Import screenshots") @@ -297,13 +297,12 @@ def delete_inactive_users(): @action("Send Video URL notification") def remind_video_url(): users = User.query.filter(User.maintained_packages.any( - and_(Package.video_url.is_(None), Package.type==PackageType.GAME, Package.state==PackageState.APPROVED))) + and_(Package.video_url.is_(None), Package.state==PackageState.APPROVED))) system_user = get_system_user() for user in users: packages = db.session.query(Package.title).filter( or_(Package.author==user, Package.maintainers.any(User.id==user.id)), Package.video_url.is_(None), - Package.type == PackageType.GAME, Package.state == PackageState.APPROVED) \ .all() diff --git a/app/blueprints/api/endpoints.py b/app/blueprints/api/endpoints.py index 428b3b3..b2d45ae 100644 --- a/app/blueprints/api/endpoints.py +++ b/app/blueprints/api/endpoints.py @@ -25,10 +25,10 @@ from sqlalchemy.sql.expression import func from app import csrf from app.markdown import render_markdown -from app.models import Tag, PackageState, PackageType, Package, db, PackageRelease, Permission, ForumTopic, \ +from app.models import Tag, PackageState, Package, db, PackageRelease, Permission, ForumTopic, \ APIToken, PackageScreenshot, License, ContentWarning, User, PackageReview, Thread from app.querybuilder import QueryBuilder -from app.utils import is_package_page, get_int_or_abort, url_set_query, abs_url, isYes +from app.utils import is_package_page, get_int_or_abort, url_set_query, abs_url, isYes, get_toplevel_tags from . import bp from .auth import is_api_authd from .support import error, api_create_vcs_release, api_create_zip_release, api_create_screenshot, \ @@ -89,9 +89,6 @@ def resolve_package_deps(out, package, only_hard, depth=1): ret = [] out[id] = ret - if package.type != PackageType.TOOL: - return - for dep in package.dependencies: if only_hard and dep.optional: continue @@ -106,7 +103,7 @@ def resolve_package_deps(out, package, only_hard, depth=1): fulfilled_by = [ pkg.getId() for pkg in dep.meta_package.packages] if depth == 1 and not dep.optional: - most_likely = next((pkg for pkg in dep.meta_package.packages if pkg.type == PackageType.TOOL), None) + most_likely = next((pkg for pkg in dep.meta_package.packages), None) if most_likely: resolve_package_deps(out, most_likely, only_hard, depth + 1) @@ -470,9 +467,11 @@ def homepage(): featured = query.filter(Package.tags.any(name="featured")).order_by( func.random()).limit(6).all() new = query.order_by(db.desc(Package.approved_at)).limit(4).all() - pop_mod = query.filter_by(type=PackageType.TOOL).order_by(db.desc(Package.score)).limit(8).all() - pop_gam = query.filter_by(type=PackageType.GAME).order_by(db.desc(Package.score)).limit(8).all() - pop_txp = query.filter_by(type=PackageType.ASSETPACK).order_by(db.desc(Package.score)).limit(8).all() + toplevel_tags = get_toplevel_tags() + popular = {} + # new = join(query.order_by(db.desc(Package.approved_at))).limit(4).all() + for toplevel_tag in toplevel_tags: + popular[toplevel_tag.name] = query.filter(Package.tags.any(name=toplevel_tag.name)).order_by(db.desc(Package.score)).limit(8).all() high_reviewed = query.order_by(db.desc(Package.score - Package.score_downloads)) \ .filter(Package.reviews.any()).limit(4).all() @@ -487,16 +486,15 @@ def homepage(): def mapPackages(packages: List[Package]): return [pkg.getAsDictionaryShort(current_app.config["BASE_URL"]) for pkg in packages] - + popular = { k:mapPackages(v) for (k, v) in popular.items() } return jsonify({ "count": count, "downloads": downloads, "featured": mapPackages(featured), "new": mapPackages(new), "updated": mapPackages(updated), - "pop_mod": mapPackages(pop_mod), - "pop_txp": mapPackages(pop_txp), - "pop_game": mapPackages(pop_gam), + "popular": popular, + "toplevel": [ x.getAsDictionary() for x in toplevel_tags ], "high_reviewed": mapPackages(high_reviewed) }) @@ -505,7 +503,7 @@ def homepage(): @cors_allowed def welcome_v1(): featured = Package.query \ - .filter(Package.type == PackageType.GAME, Package.state == PackageState.APPROVED, + .filter(Package.state == PackageState.APPROVED, Package.tags.any(name="featured")) \ .order_by(func.random()) \ .limit(5).all() @@ -520,23 +518,6 @@ def welcome_v1(): "featured": map_packages(featured), }) - -# @bp.route("/api/minetest_versions/") -# @cors_allowed -# def versions(): -# protocol_version = request.args.get("protocol_version") -# engine_version = request.args.get("engine_version") -# if protocol_version or engine_version: -# rel = MinetestRelease.get(engine_version, get_int_or_abort(protocol_version)) -# if rel is None: -# error(404, "No releases found") - -# return jsonify(rel.getAsDictionary()) - -# return jsonify([rel.getAsDictionary() \ -# for rel in MinetestRelease.query.all() if rel.getActual() is not None]) - - @bp.route("/api/dependencies/") @cors_allowed def all_deps(): @@ -545,7 +526,7 @@ def all_deps(): def format_pkg(pkg: Package): return { - "type": pkg.type.toName(), + # "type": pkg.type.toName(), "author": pkg.author.username, "name": pkg.name, "provides": [x.name for x in pkg.provides], diff --git a/app/blueprints/homepage/__init__.py b/app/blueprints/homepage/__init__.py index 8a7d9a7..519aca4 100644 --- a/app/blueprints/homepage/__init__.py +++ b/app/blueprints/homepage/__init__.py @@ -3,6 +3,7 @@ from flask import Blueprint, render_template, redirect bp = Blueprint("homepage", __name__) from app.models import * +from app.utils import get_toplevel_tags from sqlalchemy.orm import joinedload from sqlalchemy.sql.expression import func @@ -18,11 +19,12 @@ def home(): count = query.count() featured = query.filter(Package.tags.any(name="featured")).order_by(func.random()).limit(6).all() - + toplevel_tags = get_toplevel_tags() #Tag.query.filter_by(is_toplevel=True).all() + popular = {} new = join(query.order_by(db.desc(Package.approved_at))).limit(4).all() - pop_mod = join(query.filter_by(type=PackageType.TOOL).order_by(db.desc(Package.score))).limit(8).all() - pop_gam = join(query.filter_by(type=PackageType.GAME).order_by(db.desc(Package.score))).limit(8).all() - pop_txp = join(query.filter_by(type=PackageType.ASSETPACK).order_by(db.desc(Package.score))).limit(8).all() + for toplevel_tag in toplevel_tags: + popular[toplevel_tag.name] = join(query.filter(Package.tags.any(name=toplevel_tag.name)).order_by(db.desc(Package.score))).limit(8).all() + high_reviewed = join(query.order_by(db.desc(Package.score - Package.score_downloads))) \ .filter(Package.reviews.any()).limit(4).all() @@ -41,4 +43,4 @@ def home(): .select_from(Tag).outerjoin(Tags).group_by(Tag.id).order_by(db.asc(Tag.title)).all() return render_template("index.html", count=count, downloads=downloads, tags=tags, featured=featured, - new=new, updated=updated, pop_mod=pop_mod, pop_txp=pop_txp, pop_gam=pop_gam, high_reviewed=high_reviewed, reviews=reviews) + new=new, updated=updated, popular=popular, toplevel=toplevel_tags, high_reviewed=high_reviewed, reviews=reviews) diff --git a/app/blueprints/packages/game_hub.py b/app/blueprints/packages/game_hub.py index 2388e7a..a724ed5 100644 --- a/app/blueprints/packages/game_hub.py +++ b/app/blueprints/packages/game_hub.py @@ -18,16 +18,13 @@ from flask import render_template, abort from sqlalchemy.orm import joinedload from . import bp -from app.utils import is_package_page -from ...models import Package, PackageType, PackageState, db, PackageRelease +from app.utils import is_package_page, get_toplevel_tags +from ...models import Package, PackageState, db, PackageRelease @bp.route("/packages///hub/") @is_package_page def game_hub(package: Package): - if package.type != PackageType.GAME: - abort(404) - def join(query): return query.options( joinedload(Package.license), @@ -37,9 +34,11 @@ def game_hub(package: Package): count = query.count() new = join(query.order_by(db.desc(Package.approved_at))).limit(4).all() - pop_mod = join(query.filter_by(type=PackageType.TOOL).order_by(db.desc(Package.score))).limit(8).all() - pop_gam = join(query.filter_by(type=PackageType.GAME).order_by(db.desc(Package.score))).limit(8).all() - pop_txp = join(query.filter_by(type=PackageType.ASSETPACK).order_by(db.desc(Package.score))).limit(8).all() + toplevel_tags = get_toplevel_tags() #Tag.query.filter_by(is_toplevel=True).order_by(db.desc(Tag.id)).all() + popular = {} + new = join(query.order_by(db.desc(Package.approved_at))).limit(4).all() + for toplevel_tag in toplevel_tags: + popular[toplevel_tag.name] = join(query.filter(Package.tags.any(name=toplevel_tag.name)).order_by(db.desc(Package.score))).limit(8).all() high_reviewed = join(query.order_by(db.desc(Package.score - Package.score_downloads))) \ .filter(Package.reviews.any()).limit(4).all() @@ -50,5 +49,5 @@ def game_hub(package: Package): updated = updated[:4] return render_template("packages/game_hub.html", package=package, count=count, - new=new, updated=updated, pop_mod=pop_mod, pop_txp=pop_txp, pop_gam=pop_gam, + new=new, updated=updated, popular=popular, toplevel=toplevel_tags, high_reviewed=high_reviewed) diff --git a/app/blueprints/packages/packages.py b/app/blueprints/packages/packages.py index 89d1efe..016522d 100644 --- a/app/blueprints/packages/packages.py +++ b/app/blueprints/packages/packages.py @@ -99,10 +99,12 @@ def list_all(): selected_tags = set(qb.tags) + toplevel_tags = get_toplevel_tags() #Tag.query.filter_by(is_toplevel=True).all() + return render_template("packages/list.html", query_hint=title, packages=query.items, pagination=query, query=search, tags=tags, selected_tags=selected_tags, type=type_name, - authors=authors, packages_count=query.total, topics=topics) + authors=authors, packages_count=query.total, topics=topics, toplevel=toplevel_tags) def getReleases(package): @@ -120,7 +122,7 @@ def view(package): package.checkPerm(current_user, Permission.APPROVE_NEW)) conflicting_modnames = None - if show_similar and package.type != PackageType.ASSETPACK: + if show_similar: conflicting_modnames = db.session.query(MetaPackage.name) \ .filter(MetaPackage.id.in_([ mp.id for mp in package.provides ])) \ .filter(MetaPackage.packages.any(Package.id != package.id)) \ @@ -136,14 +138,12 @@ def view(package): conflicting_modnames = set([x[0] for x in conflicting_modnames]) packages_uses = None - if package.type == PackageType.TOOL: - packages_uses = Package.query.filter( - Package.type == PackageType.TOOL, - Package.id != package.id, - Package.state == PackageState.APPROVED, - Package.dependencies.any( - Dependency.meta_package_id.in_([p.id for p in package.provides]))) \ - .order_by(db.desc(Package.score)).limit(6).all() + packages_uses = Package.query.filter( + Package.id != package.id, + Package.state == PackageState.APPROVED, + Package.dependencies.any( + Dependency.meta_package_id.in_([p.id for p in package.provides]))) \ + .order_by(db.desc(Package.score)).limit(6).all() releases = getReleases(package) @@ -178,11 +178,13 @@ def view(package): has_review = current_user.is_authenticated and PackageReview.query.filter_by(package=package, author=current_user).count() > 0 + toplevel_tags = get_toplevel_tags() #Tag.query.filter_by(is_toplevel=True).all() + return render_template("packages/view.html", package=package, releases=releases, packages_uses=packages_uses, conflicting_modnames=conflicting_modnames, review_thread=review_thread, topic_error=topic_error, topic_error_lvl=topic_error_lvl, - threads=threads.all(), has_review=has_review) + threads=threads.all(), has_review=has_review, toplevel=toplevel_tags) @bp.route("/packages///shields//") @@ -226,7 +228,14 @@ def makeLabel(obj): class PackageForm(FlaskForm): - type = SelectField(lazy_gettext("Type"), [InputRequired()], choices=PackageType.choices(), coerce=PackageType.coerce, default=PackageType.GAME) + try: + toplevel_tags = [ x.title for x in Tag.query.filter_by(is_toplevel=True).all() ] + type = SelectField(lazy_gettext("Type"), [InputRequired()], choices=toplevel_tags, default=toplevel_tags[0]) + except: + toplevel_tags = [] + # type = SelectField(lazy_gettext("Type"), [InputRequired()], choices=toplevel_tags, default=toplevel_tags[0]) + + # type = SelectField(lazy_gettext("Type"), [InputRequired()], choices=PackageType.choices(), coerce=PackageType.coerce, default=PackageType.GAME) title = StringField(lazy_gettext("Title (Human-readable)"), [InputRequired(), Length(1, 100)]) name = StringField(lazy_gettext("Name (Technical)"), [InputRequired(), Length(1, 100), Regexp("^[a-zA-Z0-9_\-\.]+$", 0, lazy_gettext("Lower case letters (a-z), digits (0-9), and underscores (_), dashes and periods only"))]) short_desc = StringField(lazy_gettext("Short Description (Plaintext)"), [InputRequired(), Length(1,200)]) @@ -293,9 +302,6 @@ def create_edit(author=None, name=None): form.tags.data = package.tags form.content_warnings.data = package.content_warnings - if request.method == "POST" and form.type.data == PackageType.ASSETPACK: - form.license.data = form.media_license.data - if form.validate_on_submit(): wasNew = False if not package: @@ -353,7 +359,7 @@ def create_edit(author=None, name=None): form=form, author=author, enable_wizard=enableWizard, packages=package_query.all(), mpackages=MetaPackage.query.order_by(db.asc(MetaPackage.name)).all(), - tabs=get_package_tabs(current_user, package), current_tab="edit") + tabs=get_package_tabs(current_user, package), current_tab="edit", toplevel=get_toplevel_tags()) @bp.route("/packages///state/", methods=["POST"]) @@ -408,7 +414,7 @@ def move_to_state(package): def remove(package): if request.method == "GET": return render_template("packages/remove.html", package=package, - tabs=get_package_tabs(current_user, package), current_tab="remove") + tabs=get_package_tabs(current_user, package), current_tab="remove", toplevel=get_toplevel_tags()) reason = request.form.get("reason") or "?" @@ -501,7 +507,7 @@ def edit_maintainers(package): users = User.query.filter(User.rank >= UserRank.NEW_MEMBER).order_by(db.asc(User.username)).all() return render_template("packages/edit_maintainers.html", package=package, form=form, - users=users, tabs=get_package_tabs(current_user, package), current_tab="maintainers") + users=users, tabs=get_package_tabs(current_user, package), current_tab="maintainers", toplevel=get_toplevel_tags()) @bp.route("/packages///remove-self-maintainer/", methods=["POST"]) @@ -540,7 +546,7 @@ def audit(package): pagination = query.paginate(page, num, True) return render_template("packages/audit.html", log=pagination.items, pagination=pagination, - package=package, tabs=get_package_tabs(current_user, package), current_tab="audit") + package=package, tabs=get_package_tabs(current_user, package), current_tab="audit", toplevel=get_toplevel_tags()) class PackageAliasForm(FlaskForm): @@ -554,7 +560,7 @@ class PackageAliasForm(FlaskForm): @rank_required(UserRank.EDITOR) @is_package_page def alias_list(package: Package): - return render_template("packages/alias_list.html", package=package) + return render_template("packages/alias_list.html", package=package, toplevel=get_toplevel_tags()) @bp.route("/packages///aliases/new/", methods=["GET", "POST"]) @@ -580,7 +586,7 @@ def alias_create_edit(package: Package, alias_id: int = None): return redirect(package.getURL("packages.alias_list")) - return render_template("packages/alias_create_edit.html", package=package, form=form) + return render_template("packages/alias_create_edit.html", package=package, form=form, toplevel=get_toplevel_tags()) @bp.route("/packages///share/") @@ -588,7 +594,7 @@ def alias_create_edit(package: Package, alias_id: int = None): @is_package_page def share(package): return render_template("packages/share.html", package=package, - tabs=get_package_tabs(current_user, package), current_tab="share") + tabs=get_package_tabs(current_user, package), current_tab="share", toplevel=get_toplevel_tags()) @bp.route("/packages///similar/") @@ -610,4 +616,4 @@ def similar(package): # .all() return render_template("packages/similar.html", package=package, - packages_modnames=packages_modnames, similar_topics=[]) + packages_modnames=packages_modnames, similar_topics=[], toplevel=get_toplevel_tags()) diff --git a/app/blueprints/packages/releases.py b/app/blueprints/packages/releases.py index 7732a86..2503e54 100644 --- a/app/blueprints/packages/releases.py +++ b/app/blueprints/packages/releases.py @@ -35,7 +35,7 @@ from . import bp, get_package_tabs def list_releases(package): return render_template("packages/releases_list.html", package=package, - tabs=get_package_tabs(current_user, package), current_tab="releases") + tabs=get_package_tabs(current_user, package), current_tab="releases", toplevel=get_toplevel_tags()) # def get_mt_releases(is_max): @@ -92,7 +92,7 @@ def create_release(package): except LogicError as e: flash(e.message, "danger") - return render_template("packages/release_new.html", package=package, form=form) + return render_template("packages/release_new.html", package=package, form=form, toplevel=get_toplevel_tags()) @bp.route("/packages///releases//download/") @@ -163,7 +163,7 @@ def edit_release(package, id): db.session.commit() return redirect(package.getURL("packages.list_releases")) - return render_template("packages/release_edit.html", package=package, release=release, form=form) + return render_template("packages/release_edit.html", package=package, release=release, form=form, toplevel=get_toplevel_tags()) @@ -203,7 +203,7 @@ def bulk_change_release(package): return redirect(package.getURL("packages.list_releases")) - return render_template("packages/release_bulk_change.html", package=package, form=form) + return render_template("packages/release_bulk_change.html", package=package, form=form, toplevel=get_toplevel_tags()) @bp.route("/packages///releases//delete/", methods=["POST"]) @@ -301,7 +301,7 @@ def update_config(package): return redirect(package.getURL("packages.list_releases")) - return render_template("packages/update_config.html", package=package, form=form) + return render_template("packages/update_config.html", package=package, form=form, toplevel=get_toplevel_tags()) @bp.route("/packages///setup-releases/") @@ -314,7 +314,7 @@ def setup_releases(package): if package.update_config: return redirect(package.getURL("packages.update_config")) - return render_template("packages/release_wizard.html", package=package) + return render_template("packages/release_wizard.html", package=package, toplevel=get_toplevel_tags()) @bp.route("/user/update-configs/") @@ -343,4 +343,4 @@ def bulk_update_config(username=None): Package.update_config.has()) \ .order_by(db.asc(Package.title)).all() - return render_template("packages/bulk_update_conf.html", user=user, confs=confs, form=form) + return render_template("packages/bulk_update_conf.html", user=user, confs=confs, form=form, toplevel=get_toplevel_tags()) diff --git a/app/blueprints/packages/reviews.py b/app/blueprints/packages/reviews.py index a5b194c..5968b52 100644 --- a/app/blueprints/packages/reviews.py +++ b/app/blueprints/packages/reviews.py @@ -26,7 +26,7 @@ from wtforms import * from wtforms.validators import * from app.models import db, PackageReview, Thread, ThreadReply, NotificationType, PackageReviewVote, Package, UserRank, \ Permission, AuditSeverity -from app.utils import is_package_page, addNotification, get_int_or_abort, isYes, is_safe_url, rank_required, addAuditLog +from app.utils import is_package_page, addNotification, get_int_or_abort, isYes, is_safe_url, rank_required, addAuditLog, get_toplevel_tags from app.tasks.webhooktasks import post_discord_webhook @@ -36,7 +36,7 @@ def list_reviews(): num = min(40, get_int_or_abort(request.args.get("n"), 100)) pagination = PackageReview.query.order_by(db.desc(PackageReview.created_at)).paginate(page, num, True) - return render_template("packages/reviews_list.html", pagination=pagination, reviews=pagination.items) + return render_template("packages/reviews_list.html", pagination=pagination, reviews=pagination.items, toplevel=get_toplevel_tags()) class ReviewForm(FlaskForm): @@ -123,7 +123,7 @@ def review(package): return redirect(package.getURL("packages.view")) return render_template("packages/review_create_edit.html", - form=form, package=package, review=review) + form=form, package=package, review=review, toplevel=get_toplevel_tags()) @bp.route("/packages///reviews//delete/", methods=["POST"]) @@ -237,4 +237,4 @@ def review_votes(package): user_biases_info.sort(key=lambda x: -abs(x.balance)) return render_template("packages/review_votes.html", form=form, package=package, reviews=package.reviews, - user_biases=user_biases_info) + user_biases=user_biases_info, toplevel=get_toplevel_tags()) diff --git a/app/blueprints/packages/screenshots.py b/app/blueprints/packages/screenshots.py index b6a2cc8..eb08ca3 100644 --- a/app/blueprints/packages/screenshots.py +++ b/app/blueprints/packages/screenshots.py @@ -73,7 +73,7 @@ def screenshots(package): db.session.commit() return render_template("packages/screenshots.html", package=package, form=form, - tabs=get_package_tabs(current_user, package), current_tab="screenshots") + tabs=get_package_tabs(current_user, package), current_tab="screenshots", toplevel=get_toplevel_tags()) @bp.route("/packages///screenshots/new/", methods=["GET", "POST"]) @@ -92,7 +92,7 @@ def create_screenshot(package): except LogicError as e: flash(e.message, "danger") - return render_template("packages/screenshot_new.html", package=package, form=form) + return render_template("packages/screenshot_new.html", package=package, form=form, toplevel=get_toplevel_tags()) @bp.route("/packages///screenshots//edit/", methods=["GET", "POST"]) @@ -124,7 +124,7 @@ def edit_screenshot(package, id): db.session.commit() return redirect(package.getURL("packages.screenshots")) - return render_template("packages/screenshot_edit.html", package=package, screenshot=screenshot, form=form) + return render_template("packages/screenshot_edit.html", package=package, screenshot=screenshot, form=form, toplevel=get_toplevel_tags()) @bp.route("/packages///screenshots//delete/", methods=["POST"]) diff --git a/app/blueprints/users/account.py b/app/blueprints/users/account.py index 274340c..10a7bc4 100644 --- a/app/blueprints/users/account.py +++ b/app/blueprints/users/account.py @@ -15,7 +15,9 @@ # along with this program. If not, see . - +import base64 +import string +import random from flask import * from flask_babel import gettext, lazy_gettext, get_locale from flask_login import current_user, login_required, logout_user, login_user @@ -23,6 +25,7 @@ from flask_wtf import FlaskForm from sqlalchemy import or_ from wtforms import * from wtforms.validators import * +from captcha.image import ImageCaptcha from app.models import * from app.tasks.emails import send_verify_email, send_anon_email, send_unsubscribe_verify, send_user_email @@ -105,13 +108,13 @@ class RegisterForm(FlaskForm): Regexp("^[a-zA-Z0-9._-]+$", message=lazy_gettext("Only a-zA-Z0-9._ allowed"))]) email = StringField(lazy_gettext("Email"), [InputRequired(), Email()]) password = PasswordField(lazy_gettext("Password"), [InputRequired(), Length(6, 100)]) - question = StringField(lazy_gettext("What is the result of the above calculation?"), [InputRequired()]) + question = StringField(lazy_gettext("Type the characters from the image above."), [InputRequired()]) agree = BooleanField(lazy_gettext("I agree"), [DataRequired()]) submit = SubmitField(lazy_gettext("Register")) def handle_register(form): - if form.question.data.strip().lower() != "19": + if form.question.data.strip().lower() != session["captcha-solution"]: flash(gettext("Incorrect captcha answer"), "danger") return @@ -181,7 +184,13 @@ def register(): if ret: return ret - return render_template("users/register.html", form=form, + image = ImageCaptcha() + characters = string.ascii_letters + string.digits + solution = ''.join(random.choice(characters) for i in range(4)) + data = image.generate(solution) + session["captcha-solution"] = solution + b64data = "data:image/png;base64," + base64.b64encode(data.read()).decode("utf-8") + return render_template("users/register.html", form=form, captcha=b64data, suggested_password=genphrase(entropy=52, wordset="bip39")) diff --git a/app/blueprints/users/profile.py b/app/blueprints/users/profile.py index c81bcd2..045c4ba 100644 --- a/app/blueprints/users/profile.py +++ b/app/blueprints/users/profile.py @@ -151,24 +151,17 @@ def get_user_medals(user: User) -> Tuple[List[Medal], List[Medal]]: .filter(text("rank <= 30")) \ .all() - user_package_ranks = next( - (x for x in user_package_ranks if x[0] == PackageType.TOOL or x[2] <= 10), - None) + user_package_ranks = next((x for x in user_package_ranks if x[2] <= 10), None) if user_package_ranks: top_rank = user_package_ranks[2] - top_type = PackageType.coerce(user_package_ranks[0]) + # top_type = PackageType.coerce(user_package_ranks[0]) if top_rank == 1: - title = gettext(u"Top %(type)s", type=top_type.text.lower()) + title = gettext(u"Top projects", type=top_type.text.lower()) else: - title = gettext(u"Top %(group)d %(type)s", group=top_rank, type=top_type.text.lower()) - if top_type == PackageType.TOOL: - icon = "fa-box" - elif top_type == PackageType.GAME: - icon = "fa-gamepad" - else: - icon = "fa-paint-brush" + title = gettext(u"Top %(group)d projects", group=top_rank, type=top_type.text.lower()) + icon = "fa-paint-brush" - description = gettext(u"%(display_name)s has a %(type)s placed at #%(place)d.", + description = gettext(u"%(display_name)s has a projects placed at #%(place)d.", display_name=user.display_name, type=top_type.text.lower(), place=top_rank) unlocked.append( Medal.make_unlocked(place_to_color(top_rank), icon, title, description)) diff --git a/app/default_data.py b/app/default_data.py index 9d5cd80..5025ff0 100644 --- a/app/default_data.py +++ b/app/default_data.py @@ -36,11 +36,11 @@ def populate(session): featured.is_protected = True # These tags replace "package types" - game_tag = Tag("Game") + game_tag = Tag("Games") game_tag.is_toplevel = True - tool_tag = Tag("Tool") + tool_tag = Tag("Tools") tool_tag.is_toplevel = True - mod_tag = Tag("Mod") + mod_tag = Tag("Mods") mod_tag.is_toplevel = True session.add(featured) session.add(game_tag) @@ -110,7 +110,7 @@ def populate_test_data(session): tool.title = "Alpha Test" tool.license = licenses["MIT"] tool.media_license = licenses["MIT"] - tool.type = PackageType.TOOL + # tool.type = PackageType.TOOL tool.author = admin_user tool.tags.append(tags["mapgen"]) tool.tags.append(tags["environment"]) @@ -134,7 +134,7 @@ def populate_test_data(session): mod1.title = "Awards" mod1.license = licenses["LGPLv2.1"] mod1.media_license = licenses["MIT"] - mod1.type = PackageType.TOOL + # mod1.type = PackageType.TOOL mod1.author = admin_user mod1.tags.append(tags["player_effects"]) mod1.repo = "https://github.com/libregaming/awards" @@ -170,7 +170,7 @@ awards.register_achievement("award_mesefind",{ mod2.name = "mesecons" mod2.title = "Mesecons" mod2.tags.append(tags["tools"]) - mod2.type = PackageType.TOOL + # mod2.type = PackageType.TOOL mod2.license = licenses["LGPLv3"] mod2.media_license = licenses["MIT"] mod2.author = jeija @@ -260,7 +260,7 @@ No warranty is provided, express or implied, for any part of the project. tool.title = "Handholds" tool.license = licenses["MIT"] tool.media_license = licenses["MIT"] - tool.type = PackageType.TOOL + # tool.type = PackageType.TOOL tool.author = ez tool.tags.append(tags["player_effects"]) tool.repo = "https://github.com/ezhh/handholds" @@ -284,7 +284,7 @@ No warranty is provided, express or implied, for any part of the project. tool.title = "Other Worlds" tool.license = licenses["MIT"] tool.media_license = licenses["MIT"] - tool.type = PackageType.TOOL + # tool.type = PackageType.TOOL tool.author = ez tool.tags.append(tags["mapgen"]) tool.tags.append(tags["environment"]) @@ -301,7 +301,7 @@ No warranty is provided, express or implied, for any part of the project. tool.title = "Food" tool.license = licenses["LGPLv2.1"] tool.media_license = licenses["MIT"] - tool.type = PackageType.TOOL + # tool.type = PackageType.TOOL tool.author = admin_user tool.tags.append(tags["player_effects"]) tool.repo = "https://github.com/libregaming/food/" @@ -317,7 +317,7 @@ No warranty is provided, express or implied, for any part of the project. tool.title = "Sweet Foods" tool.license = licenses["CC0"] tool.media_license = licenses["MIT"] - tool.type = PackageType.TOOL + # tool.type = PackageType.TOOL tool.author = admin_user tool.tags.append(tags["player_effects"]) tool.repo = "https://github.com/libregaming/food_sweet/" @@ -332,7 +332,7 @@ No warranty is provided, express or implied, for any part of the project. game1.state = PackageState.APPROVED game1.name = "capturetheflag" game1.title = "Capture The Flag" - game1.type = PackageType.GAME + # game1.type = PackageType.GAME game1.license = licenses["LGPLv2.1"] game1.media_license = licenses["MIT"] game1.author = admin_user @@ -397,7 +397,7 @@ Uses the CTF PvP Engine. tool.title = "PixelBOX Reloaded" tool.license = licenses["CC0"] tool.media_license = licenses["MIT"] - tool.type = PackageType.ASSETPACK + # tool.type = PackageType.ASSETPACK tool.author = admin_user tool.forums = 14132 tool.short_desc = "This is an update of the original PixelBOX texture pack by the brillant artist Gambit" @@ -413,16 +413,16 @@ Uses the CTF PvP Engine. session.commit() - metas = {} - for package in Package.query.filter_by(type=PackageType.TOOL).all(): - meta = None - try: - meta = metas[package.name] - except KeyError: - meta = MetaPackage(package.name) - session.add(meta) - metas[package.name] = meta - package.provides.append(meta) + # metas = {} + # for package in Package.query.filter_by(type=PackageType.TOOL).all(): + # meta = None + # try: + # meta = metas[package.name] + # except KeyError: + # meta = MetaPackage(package.name) + # session.add(meta) + # metas[package.name] = meta + # package.provides.append(meta) - dep = Dependency(food_sweet, meta=metas["food"]) - session.add(dep) + # dep = Dependency(food_sweet, meta=metas["food"]) + # session.add(dep) diff --git a/app/flatpages/help/api.md b/app/flatpages/help/api.md index cab3943..08b69e1 100644 --- a/app/flatpages/help/api.md +++ b/app/flatpages/help/api.md @@ -390,9 +390,8 @@ Supported query parameters: * `downloads`: get number of downloads * `new`: new packages * `updated`: recently updated packages - * `pop_mod`: popular mods - * `pop_txp`: popular textures - * `pop_game`: popular games + * `popular`: popular packages + * `toplevel`: toplevel nav tags * `high_reviewed`: highest reviewed * GET `/api/welcome/v1/` ([View](/api/welcome/v1/)) - in-menu welcome dialog. Experimental (may change without warning) * `featured`: featured games diff --git a/app/flatpages/help/faq.md b/app/flatpages/help/faq.md index 6713647..5754a8d 100644 --- a/app/flatpages/help/faq.md +++ b/app/flatpages/help/faq.md @@ -13,7 +13,7 @@ If you don't, then you can just sign up using an email address and password. GitHub can only be used to login, not to register. -Register +Register ### My verification email never arrived diff --git a/app/logic/game_support.py b/app/logic/game_support.py index 76824d7..7e71ace 100644 --- a/app/logic/game_support.py +++ b/app/logic/game_support.py @@ -20,7 +20,7 @@ import sys from typing import List, Dict, Optional, Iterator, Iterable from app.logic.LogicError import LogicError -from app.models import Package, MetaPackage, PackageType, PackageState, PackageGameSupport, db +from app.models import Package, MetaPackage, PackageState, PackageGameSupport, db """ get_game_support(package): @@ -128,39 +128,36 @@ class GameSupportResolver: history = history.copy() history.append(key) - if package.type == PackageType.GAME: - return PackageSet([package]) + # if package.type == PackageType.GAME: + return PackageSet([package]) - if key in self.resolved_packages: - return self.resolved_packages.get(key) + # if key in self.resolved_packages: + # return self.resolved_packages.get(key) - if key in self.checked_packages: - print(f"Error, cycle found: {','.join(history)}", file=sys.stderr) - return PackageSet() + # if key in self.checked_packages: + # print(f"Error, cycle found: {','.join(history)}", file=sys.stderr) + # return PackageSet() - self.checked_packages.add(key) + # self.checked_packages.add(key) - if package.type != PackageType.TOOL: - raise LogicError(500, "Got non-tool") + # retval = PackageSet() - retval = PackageSet() + # for dep in package.dependencies.filter_by(optional=False).all(): + # ret = self.resolve_for_meta_package(dep.meta_package, history) + # if len(ret) == 0: + # continue + # elif len(retval) == 0: + # retval.update(ret) + # else: + # retval.intersection_update(ret) + # if len(retval) == 0: + # raise LogicError(500, f"Detected game support contradiction, {key} may not be compatible with any games") - for dep in package.dependencies.filter_by(optional=False).all(): - ret = self.resolve_for_meta_package(dep.meta_package, history) - if len(ret) == 0: - continue - elif len(retval) == 0: - retval.update(ret) - else: - retval.intersection_update(ret) - if len(retval) == 0: - raise LogicError(500, f"Detected game support contradiction, {key} may not be compatible with any games") - - self.resolved_packages[key] = retval - return retval + # self.resolved_packages[key] = retval + # return retval def update_all(self) -> None: - for package in Package.query.filter(Package.type == PackageType.TOOL, Package.state != PackageState.DELETED).all(): + for package in Package.query.filter(Package.state != PackageState.DELETED).all(): retval = self.resolve(package, []) for game in retval: support = PackageGameSupport(package, game) diff --git a/app/logic/packages.py b/app/logic/packages.py index d8343df..8c88683 100644 --- a/app/logic/packages.py +++ b/app/logic/packages.py @@ -20,7 +20,7 @@ import validators from flask_babel import lazy_gettext from app.logic.LogicError import LogicError -from app.models import User, Package, PackageType, MetaPackage, Tag, ContentWarning, db, Permission, AuditSeverity, \ +from app.models import User, Package, MetaPackage, Tag, ContentWarning, db, Permission, AuditSeverity, \ License, UserRank, PackageDevState from app.utils import addAuditLog from app.utils.url import clean_youtube_url @@ -118,8 +118,8 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool, validate(data) - if "type" in data: - data["type"] = PackageType.coerce(data["type"]) + # if "type" in data: + # data["type"] = PackageType.coerce(data["type"]) if "dev_state" in data: data["dev_state"] = PackageDevState.coerce(data["dev_state"]) @@ -140,12 +140,12 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool, if key in data: setattr(package, key, data[key]) - if package.type == PackageType.ASSETPACK: - package.license = package.media_license + # if package.type == PackageType.ASSETPACK: + # package.license = package.media_license - if was_new and package.type == PackageType.TOOL: - m = MetaPackage.GetOrCreate(package.name, {}) - package.provides.append(m) + # if was_new and package.type == PackageType.TOOL: + # m = MetaPackage.GetOrCreate(package.name, {}) + # package.provides.append(m) if "tags" in data: old_tags = list(package.tags) diff --git a/app/models/__init__.py b/app/models/__init__.py index 8b9cfab..ea8e2a2 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -120,7 +120,7 @@ class ForumTopic(db.Model): wip = db.Column(db.Boolean, default=False, nullable=False) discarded = db.Column(db.Boolean, default=False, nullable=False) - type = db.Column(db.Enum(PackageType), nullable=False) + # type = db.Column(db.Enum(PackageType), nullable=False) title = db.Column(db.String(200), nullable=False) name = db.Column(db.String(30), nullable=True) link = db.Column(db.String(200), nullable=True) diff --git a/app/models/packages.py b/app/models/packages.py index 85a8308..c2ffe59 100644 --- a/app/models/packages.py +++ b/app/models/packages.py @@ -48,49 +48,49 @@ class License(db.Model): return self.name -class PackageType(enum.Enum): - GAME = "Game" - TOOL = "Tool" - ASSETPACK = "Asset Pack" +# class PackageType(enum.Enum): +# GAME = "Game" +# TOOL = "Tool" +# ASSETPACK = "Asset Pack" - def toName(self): - return self.name.lower() +# def toName(self): +# return self.name.lower() - def __str__(self): - return self.name +# def __str__(self): +# return self.name - @property - def text(self): - if self == PackageType.TOOL: - return lazy_gettext("Tool") - elif self == PackageType.GAME: - return lazy_gettext("Game") - elif self == PackageType.ASSETPACK: - return lazy_gettext("Asset Pack") +# @property +# def text(self): +# if self == PackageType.TOOL: +# return lazy_gettext("Tool") +# elif self == PackageType.GAME: +# return lazy_gettext("Game") +# elif self == PackageType.ASSETPACK: +# return lazy_gettext("Asset Pack") - @property - def plural(self): - if self == PackageType.TOOL: - return lazy_gettext("Tools") - elif self == PackageType.GAME: - return lazy_gettext("Games") - elif self == PackageType.ASSETPACK: - return lazy_gettext("Asset Packs") +# @property +# def plural(self): +# if self == PackageType.TOOL: +# return lazy_gettext("Tools") +# elif self == PackageType.GAME: +# return lazy_gettext("Games") +# elif self == PackageType.ASSETPACK: +# return lazy_gettext("Asset Packs") - @classmethod - def get(cls, name): - try: - return PackageType[name.upper()] - except KeyError: - return None +# @classmethod +# def get(cls, name): +# try: +# return PackageType[name.upper()] +# except KeyError: +# return None - @classmethod - def choices(cls): - return [(choice, choice.text) for choice in cls] +# @classmethod +# def choices(cls): +# return [(choice, choice.text) for choice in cls] - @classmethod - def coerce(cls, item): - return item if type(item) == PackageType else PackageType[item.upper()] +# @classmethod +# def coerce(cls, item): +# return item if type(item) == PackageType else PackageType[item.upper()] class PackageDevState(enum.Enum): @@ -218,7 +218,7 @@ class PackagePropertyKey(enum.Enum): title = "Title" short_desc = "Short Description" desc = "Description" - type = "Type" + # type = "Type" license = "License" media_license = "Media License" tags = "Tags" @@ -378,7 +378,7 @@ class Package(db.Model): desc = db.Column(db.UnicodeText, nullable=True) build_desc = db.Column(db.UnicodeText, nullable=True) install_desc = db.Column(db.UnicodeText, nullable=True) - type = db.Column(db.Enum(PackageType), nullable=False) + # type = db.Column(db.Enum(PackageType), nullable=False) created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow) approved_at = db.Column(db.DateTime, nullable=True, default=None) @@ -534,7 +534,7 @@ class Package(db.Model): "title": self.title, "author": self.author.username, "short_description": short_desc, - "type": self.type.toName(), + # "type": self.type.toName(), "release": release_id, "thumbnail": (base_url + tnurl) if tnurl is not None else None, "aliases": [ alias.getAsDictionary() for alias in self.aliases ], @@ -559,7 +559,7 @@ class Package(db.Model): "title": self.title, "short_description": self.short_desc, "long_description": self.desc, - "type": self.type.toName(), + # "type": self.type.toName(), "created_at": self.created_at.isoformat(), "license": self.license.name, @@ -771,7 +771,7 @@ class MetaPackage(db.Model): dependencies = db.relationship("Dependency", back_populates="meta_package", lazy="dynamic") packages = db.relationship("Package", lazy="dynamic", back_populates="provides", secondary=PackageProvides) - mp_name_valid = db.CheckConstraint("name ~* '^[a-z0-9_]+$'") + mp_name_valid = db.CheckConstraint("name ~* '^[a-zA-Z0-9_\-\.]+$'") def __init__(self, name=None): self.name = name @@ -872,48 +872,6 @@ class Tag(db.Model): } -# class MinetestRelease(db.Model): -# id = db.Column(db.Integer, primary_key=True) -# name = db.Column(db.String(100), unique=True, nullable=False) -# protocol = db.Column(db.Integer, nullable=False, default=0) - -# def __init__(self, name=None, protocol=0): -# self.name = name -# self.protocol = protocol - -# def getActual(self): -# return None if self.name == "None" else self - -# def getAsDictionary(self): -# return { -# "name": self.name, -# "protocol_version": self.protocol, -# "is_dev": "-dev" in self.name, -# } - -# @classmethod -# def get(cls, version, protocol_num): -# if version: -# parts = version.strip().split(".") -# if len(parts) >= 2: -# major_minor = parts[0] + "." + parts[1] -# query = MinetestRelease.query.filter(MinetestRelease.name.like("{}%".format(major_minor))) -# if protocol_num: -# query = query.filter_by(protocol=protocol_num) - -# release = query.one_or_none() -# if release: -# return release - -# if protocol_num: -# # Find the closest matching release -# return MinetestRelease.query.order_by(db.desc(MinetestRelease.protocol), -# db.desc(MinetestRelease.id)) \ -# .filter(MinetestRelease.protocol <= protocol_num).first() - -# return None - - class PackageRelease(db.Model): id = db.Column(db.Integer, primary_key=True) @@ -929,11 +887,6 @@ class PackageRelease(db.Model): downloads = db.Column(db.Integer, nullable=False, default=0) channel = db.Column(db.String(200), nullable=False, default="") - # min_rel_id = db.Column(db.Integer, db.ForeignKey("minetest_release.id"), nullable=True, server_default=None) - # min_rel = db.relationship("MinetestRelease", foreign_keys=[min_rel_id]) - - # max_rel_id = db.Column(db.Integer, db.ForeignKey("minetest_release.id"), nullable=True, server_default=None) - # max_rel = db.relationship("MinetestRelease", foreign_keys=[max_rel_id]) # If the release is approved, then the task_id must be null and the url must be present CK_approval_valid = db.CheckConstraint("not approved OR (task_id IS NULL AND (url = '') IS NOT FALSE)") @@ -951,8 +904,6 @@ class PackageRelease(db.Model): "commit": self.commit_hash, "downloads": self.downloads, "channel": self.channel, - # "min_minetest_version": self.min_rel and self.min_rel.getAsDictionary(), - # "max_minetest_version": self.max_rel and self.max_rel.getAsDictionary(), } def getLongAsDictionary(self): @@ -963,8 +914,6 @@ class PackageRelease(db.Model): "release_date": self.releaseDate.isoformat(), "commit": self.commit_hash, "downloads": self.downloads, - # "min_minetest_version": self.min_rel and self.min_rel.getAsDictionary(), - # "max_minetest_version": self.max_rel and self.max_rel.getAsDictionary(), "channel": self.channel, "package": self.package.getAsDictionaryKey() } diff --git a/app/public/static/lg-logo.png b/app/public/static/lg-logo.png new file mode 100644 index 0000000..b46d8a5 Binary files /dev/null and b/app/public/static/lg-logo.png differ diff --git a/app/querybuilder.py b/app/querybuilder.py index 1022aca..c6a6468 100644 --- a/app/querybuilder.py +++ b/app/querybuilder.py @@ -3,7 +3,7 @@ from sqlalchemy import or_ from sqlalchemy.orm import subqueryload from sqlalchemy.sql.expression import func -from .models import db, PackageType, Package, ForumTopic, License, PackageRelease, User, Tag, \ +from .models import db, Package, ForumTopic, License, PackageRelease, User, Tag, \ ContentWarning, PackageState, PackageDevState from .utils import isYes, get_int_or_abort @@ -17,11 +17,11 @@ class QueryBuilder: title = "Packages" # Get request types - types = args.getlist("type") - types = [PackageType.get(tname) for tname in types] - types = [type for type in types if type is not None] - if len(types) > 0: - title = ", ".join([str(type.plural) for type in types]) + # types = args.getlist("type") + # types = [PackageType.get(tname) for tname in types] + # types = [type for type in types if type is not None] + # if len(types) > 0: + # title = ", ".join([str(type.plural) for type in types]) # Get tags types tags = args.getlist("tag") @@ -32,7 +32,7 @@ class QueryBuilder: self.hide_flags = set(args.getlist("hide")) self.title = title - self.types = types + # self.types = types self.tags = tags self.random = "random" in args @@ -126,8 +126,8 @@ class QueryBuilder: return query def filterPackageQuery(self, query): - if len(self.types) > 0: - query = query.filter(Package.type.in_(self.types)) + # if len(self.types) > 0: + # query = query.filter(Package.type.in_(self.types)) if self.author: author = User.query.filter_by(username=self.author).first() @@ -233,8 +233,8 @@ class QueryBuilder: query = query.filter(or_(ForumTopic.title.ilike('%' + self.search + '%'), ForumTopic.name == self.search.lower())) - if len(self.types) > 0: - query = query.filter(ForumTopic.type.in_(self.types)) + # if len(self.types) > 0: + # query = query.filter(ForumTopic.type.in_(self.types)) if self.limit: query = query.limit(self.limit) diff --git a/app/tasks/appstreamtasks.py b/app/tasks/appstreamtasks.py index e8dedc3..ebe6602 100644 --- a/app/tasks/appstreamtasks.py +++ b/app/tasks/appstreamtasks.py @@ -21,6 +21,16 @@ from app.utils import make_flask_login_password from app.utils.image import get_image_size from app.utils import randomString +map_categories = { + "tools": [ "development", "gtk", "qt" ], + "mods": [ "mod", "mods", "extension", "addon" ], + "games": [ "games", "game" ] +} + +exclude_hashtags = [ + "game" +] + #Workaround to get the urls because app.get_urls() doesn't work :| def get_urls(app): kinds = [AppStreamGlib.UrlKind(kind) for kind in range(11)] @@ -80,23 +90,39 @@ def importFromFlathub(): game1.state = PackageState.APPROVED game1.name = app.get_id() game1.title = app.get_name() - if "Development" in app.get_categories(): - game1.type = PackageType.TOOL - else: - game1.type = PackageType.GAME + hashtags = [] license = "Uknown" if app.get_project_license() is None else app.get_project_license().split("AND")[0].split("and")[0] if license not in licenses: row = License(license) licenses[row.name] = row session.add(row) session.commit() - for category in app.get_categories(): - if category.lower() not in tags: - row = Tag(category.lower()) - tags[row.name] = row - print("adding tag: ", row.name) - session.add(row) - game1.tags.append(tags[category.lower()]) + has_toplevel = False + categories = list(set([ x.lower() for x in app.get_categories() ])) + added = [] + # how do we get the type attribute from here? + # if app.get_type() == "addon": + # game1.tags.append(tags["mods"]) + # added.append("mods") + # has_toplevel = True + for category in categories: + if category in tags and category not in added: + if category in map_categories: + has_toplevel = True + game1.tags.append(tags[category]) + added.append(category) + elif category not in exclude_hashtags: + hashtags.append(category) + if not has_toplevel: + for map_category in map_categories: + if category in map_categories[map_category] and map_category not in added: + game1.tags.append(tags[map_category]) + added.append(map_category) + has_toplevel = True + break + if not has_toplevel and "games" not in added: + game1.tags.append(tags["games"]) + added.append("games") # this short list seems like a reasonable set of initial "featured" games if app.get_id() in alwaysAccept: @@ -110,12 +136,16 @@ def importFromFlathub(): for url,t in urls: if t == "bugtracker": game1.issueTracker = url - elif t == "homepage": + if "git" in url and "issues" in url: + game1.repo = url.replace("/issues", "") + elif t == "homepage" and not game1.repo: game1.repo = url + if t == "homepage" and "git" not in url: + game1.website = url game1.forums = 12835 game1.short_desc = "" or app.get_comment() - game1.desc = app.get_description() + game1.desc = app.get_description() + "\n " + ",".join([ "#" + x for x in hashtags ]) game1.install_desc = "Make sure to follow the [setup guide](https://flatpak.org/setup/) before installing. \n" game1.install_desc += f"\n```\nflatpak install flathub {app.get_id()}\n```\n" game1.install_desc += "Run: \n" diff --git a/app/tasks/forumtasks.py b/app/tasks/forumtasks.py index 4a5c322..132ce4c 100644 --- a/app/tasks/forumtasks.py +++ b/app/tasks/forumtasks.py @@ -117,76 +117,76 @@ def getLinksFromModSearch(): return links -@celery.task() -def importTopicList(): - links_by_id = getLinksFromModSearch() +# @celery.task() +# def importTopicList(): +# links_by_id = getLinksFromModSearch() - info_by_id = {} - getTopicsFromForum(11, out=info_by_id, extra={ 'type': PackageType.TOOL, 'wip': False }) - getTopicsFromForum(9, out=info_by_id, extra={ 'type': PackageType.TOOL, 'wip': True }) - getTopicsFromForum(15, out=info_by_id, extra={ 'type': PackageType.GAME, 'wip': False }) - getTopicsFromForum(50, out=info_by_id, extra={ 'type': PackageType.GAME, 'wip': True }) +# info_by_id = {} +# getTopicsFromForum(11, out=info_by_id, extra={ 'type': PackageType.TOOL, 'wip': False }) +# getTopicsFromForum(9, out=info_by_id, extra={ 'type': PackageType.TOOL, 'wip': True }) +# getTopicsFromForum(15, out=info_by_id, extra={ 'type': PackageType.GAME, 'wip': False }) +# getTopicsFromForum(50, out=info_by_id, extra={ 'type': PackageType.GAME, 'wip': True }) - # Caches - username_to_user = {} - topics_by_id = {} - for topic in ForumTopic.query.all(): - topics_by_id[topic.topic_id] = topic +# # Caches +# username_to_user = {} +# topics_by_id = {} +# for topic in ForumTopic.query.all(): +# topics_by_id[topic.topic_id] = topic - def get_or_create_user(username): - user = username_to_user.get(username) - if user: - return user +# def get_or_create_user(username): +# user = username_to_user.get(username) +# if user: +# return user - if not is_username_valid(username): - return None +# if not is_username_valid(username): +# return None - user = User.query.filter_by(forums_username=username).first() - if user is None: - user = User.query.filter_by(username=username).first() - if user: - return None +# user = User.query.filter_by(forums_username=username).first() +# if user is None: +# user = User.query.filter_by(username=username).first() +# if user: +# return None - user = User(username) - user.forums_username = username - db.session.add(user) +# user = User(username) +# user.forums_username = username +# db.session.add(user) - username_to_user[username] = user - return user +# username_to_user[username] = user +# return user - # Create or update - for info in info_by_id.values(): - id = int(info["id"]) +# # Create or update +# for info in info_by_id.values(): +# id = int(info["id"]) - # Get author - username = info["author"] - user = get_or_create_user(username) - if user is None: - print("Error! Unable to create user {}".format(username), file=sys.stderr) - continue +# # Get author +# username = info["author"] +# user = get_or_create_user(username) +# if user is None: +# print("Error! Unable to create user {}".format(username), file=sys.stderr) +# continue - # Get / add row - topic = topics_by_id.get(id) - if topic is None: - topic = ForumTopic() - db.session.add(topic) +# # Get / add row +# topic = topics_by_id.get(id) +# if topic is None: +# topic = ForumTopic() +# db.session.add(topic) - # Parse title - title, name = parseTitle(info["title"]) +# # Parse title +# title, name = parseTitle(info["title"]) - # Get link - link = links_by_id.get(id) +# # Get link +# link = links_by_id.get(id) - # Fill row - topic.topic_id = int(id) - topic.author = user - topic.type = info["type"] - topic.title = title - topic.name = name - topic.link = link - topic.wip = info["wip"] - topic.posts = int(info["posts"]) - topic.views = int(info["views"]) - topic.created_at = info["date"] +# # Fill row +# topic.topic_id = int(id) +# topic.author = user +# topic.type = info["type"] +# topic.title = title +# topic.name = name +# topic.link = link +# topic.wip = info["wip"] +# topic.posts = int(info["posts"]) +# topic.views = int(info["views"]) +# topic.created_at = info["date"] - db.session.commit() +# db.session.commit() diff --git a/app/tasks/importtasks.py b/app/tasks/importtasks.py index 0b2187a..2ae0fe1 100644 --- a/app/tasks/importtasks.py +++ b/app/tasks/importtasks.py @@ -75,8 +75,7 @@ def getMeta(urlstr, author): def postReleaseCheckUpdate(self, release: PackageRelease, path): try: - tree = build_tree(path, expected_type=ContentType[release.package.type.name], - author=release.package.author.username, name=release.package.name) + tree = build_tree(path, author=release.package.author.username, name=release.package.name) cache = {} @@ -109,9 +108,9 @@ def postReleaseCheckUpdate(self, release: PackageRelease, path): db.session.add(Dependency(package, meta=meta, optional=True)) # Update game supports - if package.type == PackageType.TOOL: - resolver = GameSupportResolver() - resolver.update(package) + # if package.type == PackageType.TOOL: + # resolver = GameSupportResolver() + # resolver.update(package) # # Update min/max # if tree.meta.get("min_minetest_version"): diff --git a/app/templates/base.html b/app/templates/base.html index 3be58ec..2eb3a16 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -6,32 +6,29 @@ {% block title %}title{% endblock %} - {{ config.USER_APP_NAME }} - + - - - + {% block headextra %}{% endblock %}