-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdb.py
More file actions
136 lines (109 loc) · 5.47 KB
/
Copy pathdb.py
File metadata and controls
136 lines (109 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#! /usr/bin/env python
import datetime
from peewee import *
from flask_security import Security, PeeweeUserDatastore, UserMixin, RoleMixin, login_required
from app import app
class UnknownField(object):
pass
# Create database instance with foreign key constraints enabled
db = SqliteDatabase(app.config['DATABASE']['name'], pragmas={'foreign_keys': 1})
class BaseModel(Model):
class Meta:
database = db
class Photo(BaseModel):
datetaken = DateTimeField(null=True)
filetype = TextField(null=False)
privacy = IntegerField(null=True)
sha1 = TextField(null=False,unique=True)
uploaded_by_id = IntegerField(null=True) # Foreign key to User.id (set by migration)
ts = DateTimeField(default=lambda: datetime.datetime.now())
class Comment(BaseModel):
comment = TextField(null=False)
photo = IntegerField(null=False)
ts = DateTimeField(default=lambda: datetime.datetime.now())
class Gallery(BaseModel):
description = TextField(null=True)
title = TextField(null=False,unique=True)
ts = DateTimeField(default=lambda: datetime.datetime.now())
class Photoset(BaseModel):
description = TextField(null=True)
title = TextField(null=False,unique=True)
ts = DateTimeField(default=lambda: datetime.datetime.now())
class Tag(BaseModel):
name = TextField(null=False,unique=True)
ts = DateTimeField(default=lambda: datetime.datetime.now())
class PhotoPhotoset(BaseModel):
photo = ForeignKeyField(Photo, null=False, on_delete='CASCADE')
photoset = ForeignKeyField(Photoset, null=False, on_delete='CASCADE')
ts = DateTimeField(default=lambda: datetime.datetime.now())
class PhotosetGallery(BaseModel):
gallery = ForeignKeyField(Gallery,null=False)
photoset = ForeignKeyField(Photoset,null=False)
ts = DateTimeField(default=lambda: datetime.datetime.now())
class PhotoTag(BaseModel):
photo = ForeignKeyField(Photo, null=False, on_delete='CASCADE')
tag = ForeignKeyField(Tag, null=False)
ts = DateTimeField(default=lambda: datetime.datetime.now())
class ImportMeta(BaseModel):
sha1 = TextField(null=False,unique=True)
photo = ForeignKeyField(Photo, backref='import_meta', on_delete='CASCADE')
importpath = TextField(null=True)
importsource = TextField(null=True)
filedate = DateTimeField(null=True)
s3 = IntegerField(null=True)
ts = DateTimeField(default=lambda: datetime.datetime.now())
class ShareToken(BaseModel):
token = CharField(unique=True, null=False)
share_type = CharField(default='photo') # 'photo' or 'photoset'
photo = ForeignKeyField(Photo, backref='share_tokens', on_delete='CASCADE', null=True)
photoset = ForeignKeyField(Photoset, backref='share_tokens', on_delete='CASCADE', null=True)
comment = TextField(null=True)
allow_download = BooleanField(default=False)
max_views = IntegerField(null=True) # NULL = unlimited
created_by_id = IntegerField(null=True) # Foreign key to User.id
created_at = DateTimeField(default=lambda: datetime.datetime.now())
expires_at = DateTimeField(null=True)
views = IntegerField(default=0)
class Role(BaseModel, RoleMixin):
name = CharField(unique=True)
description = TextField(null=True)
def get_permissions(self):
"""Stub for Flask-Principal compatibility (we don't use permissions)"""
return []
class User(BaseModel, UserMixin):
email = TextField(unique=True)
password = TextField(null=False)
active = BooleanField(default=True)
confirmed_at = DateTimeField(null=True)
fs_uniquifier = TextField(unique=True, null=True) # Required by Flask-Security-Too 5.x
permission_level = CharField(null=True) # 'private', 'family', 'friends', 'public'
ts = DateTimeField(default=lambda: datetime.datetime.now())
@property
def roles(self):
"""Return actual Role objects (Flask-Security compatibility)
Override the Peewee backref to return Role objects instead of UserRoles objects"""
return [ur.role for ur in UserRoles.select().where(UserRoles.user == self)]
def has_role(self, role_name):
"""Override to check role by name (Flask-Security compatibility)"""
for role in self.roles:
if role.name == role_name:
return True
return False
class UserRoles(BaseModel):
user = ForeignKeyField(User, related_name='user_roles_set')
role = ForeignKeyField(Role, related_name='role_users_set')
name = property(lambda self: self.role.name)
description = property(lambda self: self.role.description)
class PowChallenge(BaseModel):
"""Proof-of-Work challenges - active puzzles awaiting solution"""
challenge = CharField(unique=True, index=True) # Random hex string
created_at = DateTimeField(default=lambda: datetime.datetime.now())
expires_at = DateTimeField(index=True) # Typically 5 minutes from creation
class PowToken(BaseModel):
"""Proof-of-Work tokens - verified solutions with request/time limits"""
token = CharField(unique=True, index=True) # Random token for cookie
ip_address = CharField(null=True) # Track IP for binding
created_at = DateTimeField(default=lambda: datetime.datetime.now())
expires_at = DateTimeField(index=True) # Time-based expiry
request_count = IntegerField(default=0) # Count photo views (limit: 50)
last_request_at = DateTimeField(null=True) # Last usage timestamp