186 lines
5.8 KiB
Python
186 lines
5.8 KiB
Python
#!/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.name>
|
|
## 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()
|
|
|