]> git.lizzy.rs Git - cheatdb.git/blob - app/models.py
4ea8d3ca40c1c30e94df08143b58ca7655eca93b
[cheatdb.git] / app / models.py
1 from flask import Flask, url_for
2 from flask_sqlalchemy import SQLAlchemy
3 from app import app
4 from datetime import datetime
5 from sqlalchemy.orm import validates
6 from flask_user import login_required, UserManager, UserMixin, SQLAlchemyAdapter
7 import enum
8
9 # Initialise database
10 db = SQLAlchemy(app)
11
12 def title_to_url(title):
13         return title.lower().replace(" ", "_")
14
15 def url_to_title(url):
16         return url.replace("_", " ")
17
18 class UserRank(enum.Enum):
19         NEW_MEMBER = 0
20         MEMBER     = 1
21         EDITOR     = 2
22         ADMIN      = 3
23
24         def atLeast(self, min):
25                 return self.value >= min.value
26
27 class User(db.Model, UserMixin):
28         id = db.Column(db.Integer, primary_key=True)
29
30         # User authentication information
31         username = db.Column(db.String(50), nullable=False, unique=True)
32         password = db.Column(db.String(255), nullable=False, server_default='')
33         reset_password_token = db.Column(db.String(100), nullable=False, server_default='')
34
35         rank = db.Column(db.Enum(UserRank))
36
37         # Account linking
38         github_username = db.Column(db.String(50), nullable=True, unique=True)
39         forums_username = db.Column(db.String(50), nullable=True, unique=True)
40
41         # User email information
42         email = db.Column(db.String(255), nullable=True, unique=True)
43         confirmed_at = db.Column(db.DateTime())
44
45         # User information
46         active = db.Column('is_active', db.Boolean, nullable=False, server_default='0')
47         display_name = db.Column(db.String(100), nullable=False, server_default='')
48
49         # Content
50         packages = db.relationship('Package', backref='author', lazy='dynamic')
51
52         def __init__(self, username):
53                 import datetime
54
55                 self.username = username
56                 self.confirmed_at = datetime.datetime.now() - datetime.timedelta(days=6000)
57                 self.display_name = username
58                 self.rank = UserRank.MEMBER
59
60         def isClaimed(self):
61                 return self.password is not None and self.password != ""
62
63 class Permission(enum.Enum):
64         EDIT_PACKAGE   = "EDIT_PACKAGE"
65         APPROVE        = "APPROVE"
66         DELETE_PACKAGE = "DELETE_PACKAGE"
67         CHANGE_AUTHOR  = "CHANGE_AUTHOR"
68
69 class PackageType(enum.Enum):
70         MOD  = "Mod"
71         GAME = "Game"
72         TXP  = "Texture Pack"
73
74         @staticmethod
75         def fromName(name):
76                 if name == "mod":
77                         return PackageType.MOD
78                 elif name == "game":
79                         return PackageType.GAME
80                 elif name == "texturepacks":
81                         return PackageType.TXP
82                 else:
83                         return None
84
85         @classmethod
86         def choices(cls):
87                 return [(choice, choice.value) for choice in cls]
88
89         @classmethod
90         def coerce(cls, item):
91                 """item will be both type(enum) AND type(unicode).
92                 """
93                 if item == 'PackageType.MOD' or item == PackageType.MOD:
94                         return PackageType.MOD
95                 elif item == 'PackageType.GAME' or item == PackageType.GAME:
96                         return PackageType.GAME
97                 elif item == 'PackageType.TXP' or item == PackageType.TXP:
98                         return PackageType.TXP
99                 else:
100                         print("Can't coerce", item, type(item))
101
102 class Package(db.Model):
103         id           = db.Column(db.Integer, primary_key=True)
104
105         # Basic details
106         author_id    = db.Column(db.Integer, db.ForeignKey('user.id'))
107         name         = db.Column(db.String(100), nullable=False)
108         title        = db.Column(db.String(100), nullable=False)
109         shortDesc    = db.Column(db.Text, nullable=True)
110         desc         = db.Column(db.Text, nullable=True)
111         type         = db.Column(db.Enum(PackageType))
112
113         # Downloads
114         repo         = db.Column(db.String(200), nullable=True)
115         website      = db.Column(db.String(200), nullable=True)
116         issueTracker = db.Column(db.String(200), nullable=True)
117         forums       = db.Column(db.String(200), nullable=False)
118
119         def getDetailsURL(self):
120                 return url_for("package_page",
121                                 type=self.type.value.lower(),
122                                 author=self.author.username, name=self.name)
123
124         def getEditURL(self):
125                 return url_for("edit_package_page",
126                                 type=self.type.value.lower(),
127                                 author=self.author.username, name=self.name)
128
129         def checkPerm(self, user, perm):
130                 if type(perm) == str:
131                         perm = Permission[perm]
132
133                 isOwner = user == self.author
134                 if perm == Permission.EDIT_PACKAGE or perm == Permission.APPROVE:
135                         return user.rank.atLeast(UserRank.MEMBER if isOwner else UserRank.EDITOR)
136                 elif perm == Permission.DELETE_PACKAGE or perm == Permission.CHANGE_AUTHOR:
137                         return user.rank.atLeast(UserRank.EDITOR)
138                 else:
139                         return False
140
141 # Setup Flask-User
142 db_adapter = SQLAlchemyAdapter(db, User)        # Register the User model
143 user_manager = UserManager(db_adapter, app)     # Initialize Flask-User