]> git.lizzy.rs Git - cheatdb.git/blobdiff - app/models.py
Increase size of release URL
[cheatdb.git] / app / models.py
index 188377c8b9221905bbc2237f1780e1601fd73d10..9a1b803d8e6f71285140b3e0fbd9331353975d63 100644 (file)
@@ -1,5 +1,23 @@
+# 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 <https://www.gnu.org/licenses/>.
+
+
 from flask import Flask, url_for
 from flask_sqlalchemy import SQLAlchemy
+from flask_migrate import Migrate
 from app import app
 from datetime import datetime
 from sqlalchemy.orm import validates
@@ -8,6 +26,7 @@ import enum
 
 # Initialise database
 db = SQLAlchemy(app)
+migrate = Migrate(app, db)
 
 
 class UserRank(enum.Enum):
@@ -48,7 +67,10 @@ class Permission(enum.Enum):
        APPROVE_RELEASE    = "APPROVE_RELEASE"
        APPROVE_NEW        = "APPROVE_NEW"
        CHANGE_RELEASE_URL = "CHANGE_RELEASE_URL"
+       CHANGE_DNAME       = "CHANGE_DNAME"
        CHANGE_RANK        = "CHANGE_RANK"
+       CHANGE_EMAIL       = "CHANGE_EMAIL"
+       EDIT_EDITREQUEST   = "EDIT_EDITREQUEST"
 
        # Only return true if the permission is valid for *all* contexts
        # See Package.checkPerm for package-specific contexts
@@ -87,8 +109,11 @@ class User(db.Model, UserMixin):
        display_name = db.Column(db.String(100), nullable=False, server_default="")
 
        # Content
-       packages = db.relationship("Package", backref="author", lazy="dynamic")
-       requests = db.relationship("EditRequest", backref="author", lazy="dynamic")
+       notifications = db.relationship("Notification", primaryjoin="User.id==Notification.user_id")
+
+       # causednotifs  = db.relationship("Notification", backref="causer", lazy="dynamic")
+       packages      = db.relationship("Package", backref="author", lazy="dynamic")
+       requests      = db.relationship("EditRequest", backref="author", lazy="dynamic")
 
        def __init__(self, username):
                import datetime
@@ -98,6 +123,11 @@ class User(db.Model, UserMixin):
                self.display_name = username
                self.rank = UserRank.NOT_JOINED
 
+       def canAccessTodoList(self):
+               return Permission.APPROVE_NEW.check(self) or \
+                               Permission.APPROVE_RELEASE.check(self) or \
+                               Permission.APPROVE_CHANGES.check(self)
+
        def isClaimed(self):
                return self.rank.atLeast(UserRank.NEW_MEMBER)
 
@@ -113,11 +143,37 @@ class User(db.Model, UserMixin):
                # Members can edit their own packages, and editors can edit any packages
                if perm == Permission.CHANGE_AUTHOR:
                        return user.rank.atLeast(UserRank.EDITOR)
-               elif perm == Permission.CHANGE_RANK:
+               elif perm == Permission.CHANGE_RANK or perm == Permission.CHANGE_DNAME:
                        return user.rank.atLeast(UserRank.MODERATOR)
+               elif perm == Permission.CHANGE_EMAIL:
+                       return user == self or (user.rank.atLeast(UserRank.MODERATOR) and user.rank.atLeast(self.rank))
                else:
                        raise Exception("Permission {} is not related to users".format(perm.name))
 
+class UserEmailVerification(db.Model):
+       id      = db.Column(db.Integer, primary_key=True)
+       user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
+       email   = db.Column(db.String(100))
+       token   = db.Column(db.String(32))
+       user    = db.relationship("User", foreign_keys=[user_id])
+
+class Notification(db.Model):
+       id        = db.Column(db.Integer, primary_key=True)
+       user_id   = db.Column(db.Integer, db.ForeignKey("user.id"))
+       causer_id = db.Column(db.Integer, db.ForeignKey("user.id"))
+       user      = db.relationship("User", foreign_keys=[user_id])
+       causer    = db.relationship("User", foreign_keys=[causer_id])
+
+       title     = db.Column(db.String(100), nullable=False)
+       url       = db.Column(db.String(200), nullable=True)
+
+       def __init__(self, us, cau, titl, ur):
+               self.user   = us
+               self.causer = cau
+               self.title  = titl
+               self.url    = ur
+
+
 class License(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(50), nullable=False, unique=True)
@@ -165,13 +221,23 @@ class PackagePropertyKey(enum.Enum):
 
        def convert(self, value):
                if self == PackagePropertyKey.tags:
-                       return ','.join([t.title for t in value])
+                       return ",".join([t.title for t in value])
                else:
                        return str(value)
 
-tags = db.Table('tags',
-    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'), primary_key=True),
-    db.Column('package_id', db.Integer, db.ForeignKey('package.id'), primary_key=True)
+tags = db.Table("tags",
+    db.Column("tag_id", db.Integer, db.ForeignKey("tag.id"), primary_key=True),
+    db.Column("package_id", db.Integer, db.ForeignKey("package.id"), primary_key=True)
+)
+
+harddeps = db.Table("harddeps",
+       db.Column("package_id",    db.Integer, db.ForeignKey("package.id"), primary_key=True),
+    db.Column("dependency_id", db.Integer, db.ForeignKey("package.id"), primary_key=True)
+)
+
+softdeps = db.Table("softdeps",
+       db.Column("package_id",    db.Integer, db.ForeignKey("package.id"), primary_key=True),
+    db.Column("dependency_id", db.Integer, db.ForeignKey("package.id"), primary_key=True)
 )
 
 class Package(db.Model):
@@ -195,9 +261,20 @@ class Package(db.Model):
        issueTracker = db.Column(db.String(200), nullable=True)
        forums       = db.Column(db.Integer,     nullable=False)
 
+       tags = db.relationship("Tag", secondary=tags, lazy="subquery",
+                       backref=db.backref("packages", lazy=True))
 
-       tags = db.relationship('Tag', secondary=tags, lazy='subquery',
-                       backref=db.backref('packages', lazy=True))
+       harddeps = db.relationship("Package",
+                               secondary=harddeps,
+                               primaryjoin=id==harddeps.c.package_id,
+                               secondaryjoin=id==harddeps.c.dependency_id,
+                               backref="dependents")
+
+       softdeps = db.relationship("Package",
+                               secondary=softdeps,
+                               primaryjoin=id==softdeps.c.package_id,
+                               secondaryjoin=id==softdeps.c.dependency_id,
+                               backref="softdependents")
 
        releases = db.relationship("PackageRelease", backref="package",
                        lazy="dynamic", order_by=db.desc("package_release_releaseDate"))
@@ -218,48 +295,41 @@ class Package(db.Model):
                        "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]
                }
 
        def getDetailsURL(self):
                return url_for("package_page",
-                               type=self.type.toName(),
                                author=self.author.username, name=self.name)
 
        def getEditURL(self):
                return url_for("create_edit_package_page",
-                               type=self.type.toName(),
                                author=self.author.username, name=self.name)
 
        def getApproveURL(self):
                return url_for("approve_package_page",
-                               type=self.type.toName(),
                                author=self.author.username, name=self.name)
 
-
-
        def getNewScreenshotURL(self):
                return url_for("create_screenshot_page",
-                               type=self.type.toName(),
                                author=self.author.username, name=self.name)
 
        def getCreateReleaseURL(self):
                return url_for("create_release_page",
-                               type=self.type.toName(),
                                author=self.author.username, name=self.name)
 
        def getCreateEditRequestURL(self):
-               return url_for("create_editrequest_page",
-                               ptype=self.type.toName(),
+               return url_for("create_edit_editrequest_page",
                                author=self.author.username, name=self.name)
 
        def getDownloadURL(self):
                return url_for("package_download_page",
-                               type=self.type.toName(),
                                author=self.author.username, name=self.name)
 
        def getMainScreenshotURL(self):
-               return self.screenshots[0].url if len(self.screenshots) > 0 else None
+               screenshot = self.screenshots.first()
+               return screenshot.url if screenshot is not None else None
 
        def getDownloadRelease(self):
                for rel in self.releases:
@@ -311,7 +381,7 @@ class Tag(db.Model):
                self.textColor       = textColor
 
                import re
-               regex = re.compile('[^a-z_]')
+               regex = re.compile("[^a-z_]")
                self.name = regex.sub("", self.title.lower().replace(" ", "_"))
 
 class PackageRelease(db.Model):
@@ -320,13 +390,13 @@ class PackageRelease(db.Model):
        package_id   = db.Column(db.Integer, db.ForeignKey("package.id"))
        title        = db.Column(db.String(100), nullable=False)
        releaseDate  = db.Column(db.DateTime,        nullable=False)
-       url          = db.Column(db.String(100), nullable=False)
+       url          = db.Column(db.String(200), nullable=False)
        approved     = db.Column(db.Boolean, nullable=False, default=False)
+       task_id      = db.Column(db.String(37), nullable=True)
 
 
        def getEditURL(self):
                return url_for("edit_release_page",
-                               type=self.package.type.toName(),
                                author=self.package.author.username,
                                name=self.package.name,
                                id=self.id)
@@ -352,6 +422,9 @@ class EditRequest(db.Model):
        title        = db.Column(db.String(100), nullable=False)
        desc         = db.Column(db.String(1000), nullable=True)
 
+       # 0 - open
+       # 1 - merged
+       # 2 - rejected
        status       = db.Column(db.Integer, nullable=False, default=0)
 
        changes = db.relationship("EditRequestChange", backref="request",
@@ -359,21 +432,24 @@ class EditRequest(db.Model):
 
        def getURL(self):
                return url_for("view_editrequest_page",
-                               ptype=self.package.type.toName(),
                                author=self.package.author.username,
                                name=self.package.name,
                                id=self.id)
 
        def getApproveURL(self):
                return url_for("approve_editrequest_page",
-                               ptype=self.package.type.toName(),
                                author=self.package.author.username,
                                name=self.package.name,
                                id=self.id)
 
        def getRejectURL(self):
                return url_for("reject_editrequest_page",
-                               ptype=self.package.type.toName(),
+                               author=self.package.author.username,
+                               name=self.package.name,
+                               id=self.id)
+
+       def getEditURL(self):
+               return url_for("create_edit_editrequest_page",
                                author=self.package.author.username,
                                name=self.package.name,
                                id=self.id)
@@ -383,6 +459,26 @@ class EditRequest(db.Model):
                        change.apply(package)
 
 
+       def checkPerm(self, user, perm):
+               if not user.is_authenticated:
+                       return False
+
+               if type(perm) == str:
+                       perm = Permission[perm]
+               elif type(perm) != Permission:
+                       raise Exception("Unknown permission given to EditRequest.checkPerm()")
+
+               isOwner = user == self.author
+
+               # Members can edit their own packages, and editors can edit any packages
+               if perm == Permission.EDIT_EDITREQUEST:
+                       return isOwner or user.rank.atLeast(UserRank.EDITOR)
+
+               else:
+                       raise Exception("Permission {} is not related to packages".format(perm.name))
+
+
+
 
 class EditRequestChange(db.Model):
        id           = db.Column(db.Integer, primary_key=True)