+ 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 ThreadReply.checkPerm()")
+
+ if perm == Permission.EDIT_REPLY:
+ return user == self.author and user.rank.atLeast(UserRank.MEMBER) and not self.thread.locked
+
+ elif perm == Permission.DELETE_REPLY:
+ return user.rank.atLeast(UserRank.MODERATOR) and self.thread.replies[0] != self
+
+ else:
+ raise Exception("Permission {} is not related to threads".format(perm.name))
+
+
+class PackageReview(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], backref=db.backref("reviews", lazy=True))
+
+ created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
+
+ author_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
+ author = db.relationship("User", foreign_keys=[author_id], backref=db.backref("reviews", lazy=True))
+
+ recommends = db.Column(db.Boolean, nullable=False)
+
+ thread = db.relationship("Thread", uselist=False, back_populates="review")
+
+ def asSign(self):
+ return 1 if self.recommends else -1
+
+ def getEditURL(self):
+ return self.package.getReviewURL()
+
+ def getDeleteURL(self):
+ return url_for("packages.delete_review",
+ author=self.package.author.username,
+ name=self.package.name)
+
+
+class AuditSeverity(enum.Enum):
+ NORMAL = 0 # Normal user changes
+ EDITOR = 1 # Editor changes
+ MODERATION = 2 # Destructive / moderator changes
+
+ def __str__(self):
+ return self.name
+
+ def getTitle(self):
+ return self.name.replace("_", " ").title()
+
+ @classmethod
+ def choices(cls):
+ return [(choice, choice.getTitle()) for choice in cls]
+
+ @classmethod
+ def coerce(cls, item):
+ return item if type(item) == AuditSeverity else AuditSeverity[item]
+
+
+
+class AuditLogEntry(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+
+ created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
+
+ causer_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
+ causer = db.relationship("User", foreign_keys=[causer_id])
+
+ severity = db.Column(db.Enum(AuditSeverity), nullable=False)
+
+ title = db.Column(db.String(100), nullable=False)
+ url = db.Column(db.String(200), nullable=True)
+
+ package_id = db.Column(db.Integer, db.ForeignKey("package.id"), nullable=True)
+ package = db.relationship("Package", foreign_keys=[package_id])
+
+ description = db.Column(db.Text, nullable=True, default=None)
+
+ def __init__(self, causer, severity, title, url, package=None, description=None):
+ if len(title) > 100:
+ title = title[:99] + "…"
+
+ self.causer = causer
+ self.severity = severity
+ self.title = title
+ self.url = url
+ self.package = package
+ self.description = description
+
+
+