diff --git a/app/models.py b/app/models.py index a293ab6..5332dbd 100644 --- a/app/models.py +++ b/app/models.py @@ -376,7 +376,7 @@ class Package(db.Model): for e in PackagePropertyKey: setattr(self, e.name, getattr(package, e.name)) - def getAsDictionary(self, base_url): + def getAsDictionaryShort(self, base_url): tnurl = self.getThumbnailURL() return { "name": self.name, @@ -384,14 +384,37 @@ class Package(db.Model): "author": self.author.display_name, "shortDesc": self.shortDesc, "type": self.type.toName(), - "license": self.license.name, - "repo": self.repo, - "url": base_url + self.getDownloadURL(), "release": self.getDownloadRelease().id if self.getDownloadRelease() is not None else None, - "screenshots": [base_url + ss.url for ss in self.screenshots], "thumbnail": (base_url + tnurl) if tnurl is not None else None } + def getAsDictionary(self, base_url): + tnurl = self.getThumbnailURL() + return { + "author": self.author.display_name, + "name": self.name, + "title": self.title, + "shortDesc": self.shortDesc, + "desc": self.desc, + "type": self.type.toName(), + "createdAt": self.created_at, + + "license": self.license.name, + "mediaLicense": self.media_license.name, + + "repo": self.repo, + "website": self.website, + "issueTracker": self.issueTracker, + "forums": self.forums, + + "provides": [x.name for x in self.provides], + "thumbnail": (base_url + tnurl) if tnurl is not None else None, + "screenshots": [base_url + ss.url for ss in self.screenshots], + + "url": base_url + self.getDownloadURL(), + "release": self.getDownloadRelease().id if self.getDownloadRelease() is not None else None + } + def getThumbnailURL(self): screenshot = self.screenshots.filter_by(approved=True).first() return screenshot.getThumbnailURL() if screenshot is not None else None diff --git a/app/views/__init__.py b/app/views/__init__.py index 5257675..2001a90 100644 --- a/app/views/__init__.py +++ b/app/views/__init__.py @@ -51,7 +51,8 @@ def home_page(): packages = query.order_by(db.desc(Package.created_at)).limit(15).all() return render_template("index.html", packages=packages, count=count) -from . import users, githublogin, packages, sass, tasks, admin, notifications, tagseditor, meta, thumbnails, threads +from . import users, githublogin, packages, meta, threads, api +from . import sass, tasks, admin, notifications, tagseditor, thumbnails @menu.register_menu(app, ".help", "Help", order=19, endpoint_arguments_constructor=lambda: { 'path': 'help' }) @app.route('//') diff --git a/app/views/api.py b/app/views/api.py new file mode 100644 index 0000000..c4112b5 --- /dev/null +++ b/app/views/api.py @@ -0,0 +1,35 @@ +# Content DB +# Copyright (C) 2018 rubenwardy +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +from flask import * +from flask_user import * +from app import app +from app.models import * +from app.utils import is_package_page +from .packages import build_packages_query + +@app.route("/api/packages/") +def api_packages_page(): + query = build_packages_query() + pkgs = [package.getAsDictionaryShort(app.config["BASE_URL"]) \ + for package in query.all() if package.getDownloadRelease() is not None] + return jsonify(pkgs) + +@app.route("/api/packages///") +@is_package_page +def api_package_page(package): + return jsonify(package.getAsDictionary(app.config["BASE_URL"])) diff --git a/app/views/packages/__init__.py b/app/views/packages/__init__.py index 0c22a70..0b802af 100644 --- a/app/views/packages/__init__.py +++ b/app/views/packages/__init__.py @@ -30,14 +30,7 @@ from wtforms import * from wtforms.validators import * from wtforms.ext.sqlalchemy.fields import QuerySelectField, QuerySelectMultipleField -# TODO: the following could be made into one route, except I"m not sure how -# to do the menu - -@menu.register_menu(app, ".mods", "Mods", order=11, endpoint_arguments_constructor=lambda: { 'type': 'mod' }) -@menu.register_menu(app, ".games", "Games", order=12, endpoint_arguments_constructor=lambda: { 'type': 'game' }) -@menu.register_menu(app, ".txp", "Texture Packs", order=13, endpoint_arguments_constructor=lambda: { 'type': 'txp' }) -@app.route("/packages/") -def packages_page(): +def build_packages_query(): type_name = request.args.get("type") type = None if type_name is not None: @@ -54,24 +47,30 @@ def packages_page(): if search is not None and search.strip() != "": query = query.filter(Package.title.ilike('%' + search + '%')) + return query + +@menu.register_menu(app, ".mods", "Mods", order=11, endpoint_arguments_constructor=lambda: { 'type': 'mod' }) +@menu.register_menu(app, ".games", "Games", order=12, endpoint_arguments_constructor=lambda: { 'type': 'game' }) +@menu.register_menu(app, ".txp", "Texture Packs", order=13, endpoint_arguments_constructor=lambda: { 'type': 'txp' }) +@app.route("/packages/") +def packages_page(): if shouldReturnJson(): - pkgs = [package.getAsDictionary(app.config["BASE_URL"]) \ - for package in query.all() if package.getDownloadRelease() is not None] - return jsonify(pkgs) - else: - page = int(request.args.get("page") or 1) - num = min(42, int(request.args.get("n") or 100)) - query = query.paginate(page, num, True) + return redirect(url_for("api_packages_page")) - next_url = url_for("packages_page", type=type_name, q=search, page=query.next_num) \ - if query.has_next else None - prev_url = url_for("packages_page", type=type_name, q=search, page=query.prev_num) \ - if query.has_prev else None + query = build_packages_query() + page = int(request.args.get("page") or 1) + num = min(42, int(request.args.get("n") or 100)) + query = query.paginate(page, num, True) - tags = Tag.query.all() - return render_template("packages/list.html", title=title, packages=query.items, \ - query=search, tags=tags, type=type_name, \ - next_url=next_url, prev_url=prev_url, page=page, page_max=query.pages, packages_count=query.total) + next_url = url_for("packages_page", type=type_name, q=search, page=query.next_num) \ + if query.has_next else None + prev_url = url_for("packages_page", type=type_name, q=search, page=query.prev_num) \ + if query.has_prev else None + + tags = Tag.query.all() + return render_template("packages/list.html", title=title, packages=query.items, \ + query=search, tags=tags, type=type_name, \ + next_url=next_url, prev_url=prev_url, page=page, page_max=query.pages, packages_count=query.total) def getReleases(package): @@ -84,41 +83,38 @@ def getReleases(package): @app.route("/packages///") @is_package_page def package_page(package): - if shouldReturnJson(): - return jsonify(package.getAsDictionary(app.config["BASE_URL"])) - else: - clearNotifications(package.getDetailsURL()) + clearNotifications(package.getDetailsURL()) - alternatives = None - if package.type == PackageType.MOD: - alternatives = Package.query \ - .filter_by(name=package.name, type=PackageType.MOD, soft_deleted=False) \ - .filter(Package.id != package.id) \ - .order_by(db.asc(Package.title)) \ - .all() + alternatives = None + if package.type == PackageType.MOD: + alternatives = Package.query \ + .filter_by(name=package.name, type=PackageType.MOD, soft_deleted=False) \ + .filter(Package.id != package.id) \ + .order_by(db.asc(Package.title)) \ + .all() - show_similar_topics = current_user == package.author or \ - package.checkPerm(current_user, Permission.APPROVE_NEW) + show_similar_topics = current_user == package.author or \ + package.checkPerm(current_user, Permission.APPROVE_NEW) - similar_topics = None if not show_similar_topics else \ - KrockForumTopic.query \ - .filter_by(name=package.name) \ - .filter(KrockForumTopic.topic_id != package.forums) \ - .filter(~ db.exists().where(Package.forums==KrockForumTopic.topic_id)) \ - .order_by(db.asc(KrockForumTopic.name), db.asc(KrockForumTopic.title)) \ - .all() + similar_topics = None if not show_similar_topics else \ + KrockForumTopic.query \ + .filter_by(name=package.name) \ + .filter(KrockForumTopic.topic_id != package.forums) \ + .filter(~ db.exists().where(Package.forums==KrockForumTopic.topic_id)) \ + .order_by(db.asc(KrockForumTopic.name), db.asc(KrockForumTopic.title)) \ + .all() - releases = getReleases(package) - requests = [r for r in package.requests if r.status == 0] + releases = getReleases(package) + requests = [r for r in package.requests if r.status == 0] - review_thread = Thread.query.filter_by(package_id=package.id, private=True).first() - if review_thread is not None and not review_thread.checkPerm(current_user, Permission.SEE_THREAD): - review_thread = None + review_thread = Thread.query.filter_by(package_id=package.id, private=True).first() + if review_thread is not None and not review_thread.checkPerm(current_user, Permission.SEE_THREAD): + review_thread = None - return render_template("packages/view.html", \ - package=package, releases=releases, requests=requests, \ - alternatives=alternatives, similar_topics=similar_topics, \ - review_thread=review_thread) + return render_template("packages/view.html", \ + package=package, releases=releases, requests=requests, \ + alternatives=alternatives, similar_topics=similar_topics, \ + review_thread=review_thread) @app.route("/packages///download/")