This repository has been archived by the owner on Dec 8, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
models.py
163 lines (129 loc) · 4.44 KB
/
models.py
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# Python Utils
import uuid
import os
# Flask
from flask import current_app
# SQLAlchemy
from app import db, Base
# POSS Utils
from .utils import is_valid_url
from .utils import format_object_title
# POSS Exceptions
from .exceptions import InvalidLinkException
from .exceptions import ObjectIsNotDeletedException
from .exceptions import UnknownObjectTypeException
# Settings
oid_MIN_LENGTH = 5
oid_MAX_LENGTH = 32
oid_DEFAULT_LENGTH = 20
oid_ALLOWED_CHARS = 'a-zA-Z0-9-_'
# def oid_validate(key):
# key = re.sub('[^%s]' % oid_ALLOWED_CHARS, '', key)
# key = key[0:oid_DEFAULT_LENGTH]
#
# if len(key) <= oid_MIN_LENGTH:
# return False
# else:
# return True
def oid_generate():
while True:
oid = str(uuid.uuid4()).replace('-', '')[0:oid_DEFAULT_LENGTH]
if not Object.query.filter(Object.oid == oid).first():
return oid
def fid_generate():
while True:
p1_length = 10
rnd = str(uuid.uuid4()).replace('-', '')
p1 = rnd[:p1_length]
p2 = rnd[p1_length:]
p1 = '1/%s' % '/'.join([p1[i:i+2] for i in range(0, len(p1), 2)])
fid = '%s/%s' % (p1, p2)
if not Object.query.filter(Object.fid == fid).first():
return fid
class Object(Base):
__tablename__ = 'object'
# Users
owner = db.Column(db.Integer, db.ForeignKey('user.id',
ondelete='CASCADE',
onupdate='CASCADE'))
# Object type and oid
type = db.Column(db.Enum('file', 'link'), nullable=False)
size = db.Column(db.Integer, nullable=True)
# Location
oid = db.Column(db.String(64), nullable=False, unique=True)
fid = db.Column(db.String(39), nullable=True, unique=True)
title = db.Column(db.String(64), nullable=True)
link = db.Column(db.Text, nullable=True)
# Lifecycle
deleted = db.Column(db.Boolean, nullable=False, default=False)
deleted_reason = db.Column(db.Enum('user', 'admin', 'autodelete', 'system'), nullable=True)
autodelete_type = db.Column(db.Enum('on_view', 'by_viewer', 'at_time'), nullable=True)
autodelete_param = db.Column(db.Integer, nullable=True)
# Views
viewcount = db.Column(db.Integer, nullable=False, default=0)
views = db.relationship('View')
last_viewed = db.Column(db.DateTime, nullable=True)
def __init__(self, owner, type, link, randomize_filename=False):
self.oid = oid_generate()
self.type = type
self.owner = owner
self.set_link(link)
if self.type == 'file':
self.fid = fid_generate()
if randomize_filename:
self.randomize_filename()
elif self.type == 'link':
pass
else:
raise UnknownObjectTypeException
def set_title(self, title):
if title:
self.title = format_object_title(title)
else:
self.title = None
def set_link(self, link):
if self.type == 'link':
if not is_valid_url(link):
raise InvalidLinkException
else:
self.link = link
elif self.type == 'file':
if len(link) > 0:
self.link = link
else:
raise InvalidLinkException
else:
self.link = link
def randomize_filename(self):
self.link = '%s%s' % (self.oid, os.path.splitext(self.link)[1])
def filepath(self):
return os.path.join(current_app.config['DATA_DIR'], self.fid)
def delete(self, reason):
if self.type == 'file':
if os.path.isfile(self.filepath()):
os.remove(self.filepath())
self.deleted = True
self.deleted_reason = reason
self.size = None
self.link = None
def undelete(self):
self.deleted = False
self.deleted_reason = None
def convert_to_link(self):
if not self.deleted:
raise ObjectIsNotDeletedException
elif not self.type == 'file':
raise UnknownObjectTypeException
else:
self.fid = None
self.type = 'link'
def convert_to_file(self):
if not self.deleted:
raise ObjectIsNotDeletedException
elif not self.type == 'link':
raise UnknownObjectTypeException
else:
self.fid = fid_generate()
self.type = 'file'
def __repr__(self):
return '<Object %r>' % (self.oid)