38 """Class for managing all uploaded files.
40 This is a system-wide repository
for user uploaded files that allows
41 easy search
and discovery
while retaining security
and ease of
42 management. Files can be made searchable, requires a direct link to
43 access,
or locked down to the point where a timed access token
is
44 needed to access the file.
46 For efficiency, all uploaded images are converted to the webp format,
47 audio to mp3,
and video to h264 MP4s. If you don
't want this behavior,
48 modify the system/upload handler in system/__init__.py
52 'rid': (
'INTEGER PRIMARY KEY',
'NOT NULL',),
56 'descriptions': (
'TRANSLATION',
"NOT NULL DEFAULT 0",),
57 'modified': (
'DATETIME',
'NOT NULL',),
58 'size': (
'BIGINT',
'NOT NULL',),
59 'hash': (
'TEXT',
'NOT NULL',),
60 'filetype': (
'INT16',
'NOT NULL',),
61 'width': (
'INT16',
'NOT NULL DEFAULT 0',),
62 'height': (
'INT16',
'NOT NULL DEFAULT 0',),
63 'length': (
'INT16',
'NOT NULL DEFAULT 0',),
64 'flags': (
'INT',
'NOT NULL DEFAULT 0',),
65 'accesstokens': (
'DICT',
"NOT NULL DEFAULT ''",),
69 _dbdisplay = [
'filename',
'description',
'modified',
'size']
70 _dbflags = pafera.db.DB_SECURE
99 """Returns the filesystem path for this file.
107 if self.flags & FILE_PRIVATE:
108 return 'private/system/files/' + dirpath +
'.' + self.extension
110 return 'static/system/files/' + dirpath +
'.' + self.extension
114 """Returns the filesystem path for an appropiate thumbnail.
122 return "static/system/icons/document.webp"
123 elif self.
filetype == FILE_SPREADSHEET:
124 return "static/system/icons/spreadsheet.webp"
125 elif self.
filetype == FILE_PRESENTATION:
126 return "static/system/icons/presentation.webp"
128 return "static/system/icons/image.webp"
130 return "static/system/icons/audio.webp"
132 return "static/system/icons/video.webp"
134 return "static/system/icons/archive.webp"
136 return "static/system/icons/program.webp"
138 return "static/system/icons/book.webp"
140 return "static/system/icons/text.webp"
141 elif self.
filetype == FILE_DISK_IMAGE:
142 return "static/system/icons/iso.webp"
144 return "static/system/icons/webpage.webp"
146 return "static/system/icons/unknown.webp"
150 """Returns a URL to display the thumbnail image.
152 if self.flags & FILE_PRIVATE:
153 return '/system/thumbnailer/' +
ToShortCode(self.rid)
159 """Analyzes the file and inserts it into the system registry, or
160 update any changed files.
162 if not self.filename:
163 raise Exception(
'Cannot process empty templateclass.')
166 stats = os.stat(fullpath)
169 modified = stats.st_mtime;
177 extension = os.path.splitext(this.filename)[1]
220 filetype = FILE_DOCUMENT
256 filetype = FILE_AUDIO
282 filetype = FILE_VIDEO
311 filetype = FILE_ARCHIVE
318 filetype = FILE_PROGRAM
326 filetype = FILE_SPREADSHEET
332 filetype = FILE_PRESENTATION
345 filetype = FILE_WEBPAGE
349 filetype = FILE_DELETED
351 filetype = FILE_OTHER
356 extension = extension,
367 """Creates or updates a thumbnail if needed.
369 The default thumbnail size is 256x256, but
if you are working
with
370 high resolution screens, feel free to use 512x512
or higher.
372 You
'll need to install imagemagick, ffmpeg, and ffmpegthumbnailer
373 to use this functionality.
375 if self.flags & FILE_PRIVATE:
380 os.makedirs(os.path.dirname(thumbfile), exist_ok =
True)
382 if os.path.exists(thumbfile):
383 stats = os.stat(thumbfile)
385 if stats.st_mtime > self.
modified.timestamp():
392 if self.
size < (20 * 1024):
393 if self.flags & FILE_PRIVATE:
400 result = subprocess.run([
'identify', fullpath], stdout=subprocess.PIPE).stdout.decode(
'utf-8')
403 matches = re.findall(
'([0-9]+)x([0-9]+)', result, re.MULTILINE)
406 width = matches[0][0],
407 height = matches[0][1],
414 thumbsize +
'x' + thumbsize +
'^',
418 thumbsize +
'x' + thumbsize,
423 result = subprocess.run([
'ffmpeg',
'-i', fullpath], stdout=subprocess.PIPE).stdout.decode(
'utf-8')
425 matches = re.findall(
'Duration: ([0-9]+):([0-9]+):([0-9]+)', result, re.MULTILINE)
429 (int(matches[0][0]) * 3600)
430 + (int(matches[0][1]) * 60)
431 + (int(matches[0][2]))
435 matches = re.findall(
'([0-9]+)x([0-9]+)', result, re.MULTILINE)
438 width = matches[0][0],
439 height = matches[0][1],
442 subprocess.run([
'ffmpegthumbnailer',
'-i',
'fullpath',
'-o', thumbfile,
'-s',
'512',
'-a'])
444 if os.path.exists(thumbfile):
Base class for all database models.
def Set(self, **kwargs)
We use this method instead of direct attribute access in order to keep track of what values have been...
Throws an exception on blank values.
Class for managing all uploaded files.
def Process(self, g)
Analyzes the file and inserts it into the system registry, or update any changed files.
def ThumbnailFile(self)
Returns the filesystem path for an appropiate thumbnail.
def MakeThumbnail(self, thumbsize='256')
Creates or updates a thumbnail if needed.
def FullPath(self)
Returns the filesystem path for this file.
def __init__(self)
Initialize all fields at creation like a good programmer should.
def ThumbnailURL(self)
Returns a URL to display the thumbnail image.
def ToShortCode(val, chars='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_')
Turns a 32-bit value into a six character alphanumeric code.
def CodeDir(code)
Separates a filename into three character segments with the directory separator '/' in between.