+ self.releaseDate = datetime.datetime.now()
+
+
+class PackageReview(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+ package_id = db.Column(db.Integer, db.ForeignKey("package.id"))
+ thread_id = db.Column(db.Integer, db.ForeignKey("thread.id"), nullable=False)
+ recommend = db.Column(db.Boolean, nullable=False, default=True)
+
+
+class PackageScreenshot(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+ package_id = db.Column(db.Integer, db.ForeignKey("package.id"))
+ title = db.Column(db.String(100), nullable=False)
+ url = db.Column(db.String(100), nullable=False)
+ approved = db.Column(db.Boolean, nullable=False, default=False)
+
+
+ def getEditURL(self):
+ return url_for("edit_screenshot_page",
+ author=self.package.author.username,
+ name=self.package.name,
+ id=self.id)
+
+ def getThumbnailURL(self, level=2):
+ return self.url.replace("/uploads/", ("/thumbnails/{:d}/").format(level))
+
+
+
+class EditRequest(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+
+ package_id = db.Column(db.Integer, db.ForeignKey("package.id"))
+ author_id = db.Column(db.Integer, db.ForeignKey("user.id"))
+
+ 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",
+ lazy="dynamic")
+
+ def getURL(self):
+ return url_for("view_editrequest_page",
+ author=self.package.author.username,
+ name=self.package.name,
+ id=self.id)
+
+ def getApproveURL(self):
+ return url_for("approve_editrequest_page",
+ author=self.package.author.username,
+ name=self.package.name,
+ id=self.id)
+
+ def getRejectURL(self):
+ return url_for("reject_editrequest_page",
+ 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)
+
+ def applyAll(self, package):
+ for change in self.changes:
+ 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)
+
+ request_id = db.Column(db.Integer, db.ForeignKey("edit_request.id"))
+ key = db.Column(db.Enum(PackagePropertyKey), nullable=False)
+
+ # TODO: make diff instead
+ oldValue = db.Column(db.Text, nullable=True)
+ newValue = db.Column(db.Text, nullable=True)
+
+ def apply(self, package):
+ if self.key == PackagePropertyKey.tags:
+ package.tags.clear()
+ for tagTitle in self.newValue.split(","):
+ tag = Tag.query.filter_by(title=tagTitle.strip()).first()
+ package.tags.append(tag)
+
+ else:
+ setattr(package, self.key.name, self.newValue)
+
+
+watchers = db.Table("watchers",
+ db.Column("user_id", db.Integer, db.ForeignKey("user.id"), primary_key=True),
+ db.Column("thread_id", db.Integer, db.ForeignKey("thread.id"), primary_key=True)
+)
+
+class Thread(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+
+ package_id = db.Column(db.Integer, db.ForeignKey("package.id"), nullable=True)
+ package = db.relationship("Package", foreign_keys=[package_id])
+
+ author_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
+ title = db.Column(db.String(100), nullable=False)
+ private = db.Column(db.Boolean, server_default="0")
+
+ created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
+
+ replies = db.relationship("ThreadReply", backref="thread", lazy="dynamic")
+
+ watchers = db.relationship("User", secondary=watchers, lazy="subquery", \
+ backref=db.backref("watching", lazy=True))
+
+
+ def getSubscribeURL(self):
+ return url_for("thread_subscribe_page",
+ id=self.id)
+
+ def getUnsubscribeURL(self):
+ return url_for("thread_unsubscribe_page",
+ id=self.id)
+
+ def checkPerm(self, user, perm):
+ if not user.is_authenticated:
+ return not self.private
+
+ if type(perm) == str:
+ perm = Permission[perm]
+ elif type(perm) != Permission:
+ raise Exception("Unknown permission given to Thread.checkPerm()")
+
+ isOwner = user == self.author or (self.package is not None and self.package.author == user)
+
+ if perm == Permission.SEE_THREAD:
+ return not self.private or isOwner or user.rank.atLeast(UserRank.EDITOR)
+
+ else:
+ raise Exception("Permission {} is not related to threads".format(perm.name))
+
+class ThreadReply(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+ thread_id = db.Column(db.Integer, db.ForeignKey("thread.id"), nullable=False)
+ comment = db.Column(db.String(500), nullable=False)
+ author_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
+ created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
+
+
+REPO_BLACKLIST = [".zip", "mediafire.com", "dropbox.com", "weebly.com", \
+ "minetest.net", "dropboxusercontent.com", "4shared.com", \
+ "digitalaudioconcepts.com", "hg.intevation.org", "www.wtfpl.net", \
+ "imageshack.com", "imgur.com"]
+
+class ForumTopic(db.Model):
+ topic_id = db.Column(db.Integer, primary_key=True, autoincrement=False)
+ author_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
+ author = db.relationship("User")
+
+ wip = db.Column(db.Boolean, server_default="0")
+ discarded = db.Column(db.Boolean, server_default="0")
+
+ 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)
+
+ posts = db.Column(db.Integer, nullable=False)
+ views = db.Column(db.Integer, nullable=False)
+
+ created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
+
+ def getRepoURL(self):
+ if self.link is None:
+ return None
+
+ for item in REPO_BLACKLIST:
+ if item in self.link:
+ return None
+
+ return self.link.replace("repo.or.cz/w/", "repo.or.cz/")
+
+ def getAsDictionary(self):
+ return {
+ "author": self.author.username,
+ "name": self.name,
+ "type": self.type.toName(),
+ "title": self.title,
+ "id": self.topic_id,
+ "link": self.link,
+ "posts": self.posts,
+ "views": self.views,
+ "is_wip": self.wip,
+ "discarded": self.discarded,
+ "created_at": self.created_at.isoformat(),
+ }
+
+ 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 ForumTopic.checkPerm()")
+
+ if perm == Permission.TOPIC_DISCARD:
+ return self.author == user or user.rank.atLeast(UserRank.EDITOR)
+
+ else:
+ raise Exception("Permission {} is not related to topics".format(perm.name))
+