First commit.
This commit is contained in:
185
subsites/films/films.wsgi
Normal file
185
subsites/films/films.wsgi
Normal file
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# films.wsgi: a WSGI script for showing films
|
||||
# Copyright (C) 2011 Niels Serup
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public
|
||||
# License along with this program. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
## Version:...... 0.1.0
|
||||
## Maintainer:... Niels Serup <ns@metanohi.org>
|
||||
## Website:...... http://films.metanohi.name/about/
|
||||
|
||||
import sys
|
||||
import os
|
||||
import bottle
|
||||
from bottle import route, abort, error, request, redirect
|
||||
import configparser
|
||||
import locale
|
||||
_preferred_encoding = 'utf-8' #locale.getpreferredencoding() # fail
|
||||
|
||||
_absfile = os.path.abspath(__file__)
|
||||
_filedir = os.path.dirname(_absfile)
|
||||
_configfile_name = 'films.config'
|
||||
|
||||
# Get settings
|
||||
_settings = {'previews_dir': '/previews', 'videos_dir': '/videos'} # Defaults
|
||||
|
||||
_cfg = configparser.SafeConfigParser(_settings)
|
||||
_cfg.add_section('films')
|
||||
try:
|
||||
_cfg.read(os.path.join(_filedir, _configfile_name))
|
||||
except configparser.Error as e:
|
||||
print('Python error: ' + repr(e), file=sys.stderr)
|
||||
except TypeError:
|
||||
pass
|
||||
_settings = {name: value for name, value in _cfg.items('films')}
|
||||
|
||||
# Get templates
|
||||
def _readfile(locpath):
|
||||
with open(os.path.join(_filedir, locpath), 'rb') as f:
|
||||
return f.read().decode(_preferred_encoding)
|
||||
|
||||
_template, _about, _frontpage = (_readfile(x + '.html') for x in
|
||||
('template', 'about', 'frontpage'))
|
||||
|
||||
# Create more templates
|
||||
_videosource = ''' <source src='{url}' type='{mime}' />\n'''
|
||||
_videotemplate = '''
|
||||
<video width='640' height='{height}' autoplay='autoplay'
|
||||
controls='controls', style='width: 640px; height: {height}px;'>
|
||||
{sources}
|
||||
<applet code='com.fluendo.player.Cortado.class'
|
||||
archive='http://theora.org/cortado.jar'
|
||||
width='640' height='{height}'>
|
||||
<param name='url' value='{url}' />
|
||||
</applet>
|
||||
</video>
|
||||
|
||||
<div id='description' style='height: {height}px'>
|
||||
<p>{description}</p>
|
||||
<p><span>Year:</span> {year}</p>
|
||||
</div>
|
||||
|
||||
<div id='dl'>
|
||||
<p><span>Download:</span> {downloads}</p>
|
||||
</div>
|
||||
'''
|
||||
|
||||
# Extract info
|
||||
def _parse_filminfo(locpath):
|
||||
with open(os.path.join(_filedir, locpath), 'U') as f:
|
||||
sfilms = (line.split('\n', 7) for line in f.read().split('\n' * 3))
|
||||
films, films_html = [], {}
|
||||
i = 1
|
||||
for x in sfilms:
|
||||
kwds = {
|
||||
'name': x[0],
|
||||
'title': x[1],
|
||||
'year': int(x[2]),
|
||||
'16:9': x[3] == 'true',
|
||||
'sizes': x[4],
|
||||
'webm': x[5] == 'true',
|
||||
'description': x[7]
|
||||
}
|
||||
|
||||
if kwds['16:9']:
|
||||
kwds['height'] = 360
|
||||
sizes = (
|
||||
'640x360',
|
||||
'1024x576',
|
||||
'1280x720',
|
||||
'1920x1080'
|
||||
)
|
||||
else:
|
||||
kwds['height'] = 480
|
||||
sizes = (
|
||||
'640x480',
|
||||
'768x576',
|
||||
'960x720',
|
||||
'1440x1080'
|
||||
)
|
||||
kwds['downloads'] = ''
|
||||
linknames = {
|
||||
'': (sizes[0], '640w'),
|
||||
'b': (sizes[1], '576p'),
|
||||
'c': (sizes[2], '720p'),
|
||||
'd': (sizes[3], '1080p'),
|
||||
'e': ('Behind', 'behind')
|
||||
}
|
||||
for x in filter(lambda x: x in kwds['sizes'], linknames.keys()):
|
||||
linkname, sid = linknames[x]
|
||||
if kwds['webm']:
|
||||
kwds['downloads'] += "<a href='{dir}/{name}-{sid}.webm'>{linkname} WebM</a>".format(
|
||||
dir=_settings['videos_dir'], sid=sid, name=kwds['name'], linkname=linkname)
|
||||
kwds['downloads'] += "<a href='{dir}/{name}-{sid}.ogv'>{linkname} Theora</a>".format(
|
||||
dir=_settings['videos_dir'], sid=sid, name=kwds['name'], linkname=linkname)
|
||||
|
||||
addr = _settings['videos_dir']
|
||||
srcs = ''
|
||||
kwds['url'] = '{}/{}-{}.ogv'.format(
|
||||
addr, kwds['name'], linknames[''][1])
|
||||
if kwds['webm']:
|
||||
srcs += _videosource.format(url='{}/{}-{}.webm'.format(
|
||||
addr, kwds['name'], linknames[''][1]), mime='video/webm')
|
||||
srcs += _videosource.format(url=kwds['url'], mime='video/ogg')
|
||||
kwds['sources'] = srcs
|
||||
kwds['content'] = _videotemplate.format(**kwds)
|
||||
kwds['leftclass'] = " class='left'" if i % 2 else ''
|
||||
i += 1
|
||||
|
||||
films.append(kwds)
|
||||
films_html[kwds['name']] = _template.format(**kwds)
|
||||
return films, films_html
|
||||
|
||||
_films, _films_html = _parse_filminfo('filminfo')
|
||||
_settings['numberoffilms'] = len(_films)
|
||||
|
||||
# Improve templates
|
||||
_frontpage_boxlink = '''
|
||||
<a href='/{{name}}' style='background-image: url({previews_dir}/{{name}}.jpg);'{{leftclass}}>
|
||||
<span>{{title}}</span>
|
||||
</a>
|
||||
'''.format(**_settings)
|
||||
|
||||
_settings['filmboxes'] = ''.join(_frontpage_boxlink.format(**kwds)
|
||||
for kwds in _films)
|
||||
|
||||
_frontpage = _frontpage.format(**_settings)
|
||||
|
||||
_settings['content'], _settings['title'] = _frontpage, 'Start'
|
||||
_frontpage = _template.format(**_settings)
|
||||
_settings['content'], _settings['title'] = _about, 'About'
|
||||
_about = _template.format(**_settings)
|
||||
del _settings['content']
|
||||
del _settings['title']
|
||||
|
||||
@route('/')
|
||||
def frontpage():
|
||||
if request.query_string:
|
||||
# compatibility reasons, can be removed
|
||||
redirect('/' + request.query_string)
|
||||
return _frontpage
|
||||
|
||||
@route('/about')
|
||||
@route('/!about') # compatibility reasons, can be removed
|
||||
def about():
|
||||
return _about
|
||||
|
||||
@route('/:name')
|
||||
def film(name):
|
||||
return _films_html[name]
|
||||
|
||||
application = bottle.default_app()
|
||||
|
||||
Reference in New Issue
Block a user