#!/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 # . ## Version:...... 0.1.0 ## Maintainer:... Niels Serup ## 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 = ''' \n''' _videotemplate = '''

{description}

Year: {year}

Download: {downloads}

''' # 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'] += "{linkname} WebM".format( dir=_settings['videos_dir'], sid=sid, name=kwds['name'], linkname=linkname) kwds['downloads'] += "{linkname} Theora".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 = ''' {{title}} '''.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()