Separation of site from code
Working on separating the Lunatics site data from the LunaGen source code, and replacing it with test code only.
This commit is contained in:
parent
b836bef771
commit
158718a650
BIN
LunaGen/lunagen_profile.txt
Normal file
BIN
LunaGen/lunagen_profile.txt
Normal file
Binary file not shown.
0
LunaGen/profile_stats.txt
Normal file
0
LunaGen/profile_stats.txt
Normal file
479
LunaGen/src/lunagen_backup.py
Executable file
479
LunaGen/src/lunagen_backup.py
Executable file
@ -0,0 +1,479 @@
|
||||
#!/usr/bin/python3
|
||||
# encoding: utf-8
|
||||
'''
|
||||
lunagen -- "Lunatics!" Project Release Site Generator
|
||||
|
||||
LunaGen generates a small static HTML website based on YAML
|
||||
data documents containing the key release information. This
|
||||
generates an index.html file containing the episode lists
|
||||
for all series, individual release pages for each episode,
|
||||
and additional pages for character list and story background.
|
||||
|
||||
This is meant to be a fan-focused site.
|
||||
|
||||
It also contains affiliate link, sponsor, advertising, and
|
||||
other fundraising elements.
|
||||
|
||||
@author: Terry Hancock
|
||||
|
||||
@copyright: 2019 Anansi Spaceworks.
|
||||
|
||||
@license: GNU General Public License, version 2.0 or later. (Python code)
|
||||
Creative Commons Attribution-ShareAlike, version 3.0 or later. (Website Templates).
|
||||
|
||||
@contact: digitante@gmail.com
|
||||
'''
|
||||
|
||||
import sys
|
||||
import os
|
||||
#from shutil import copytree, rmtree
|
||||
from distutils.dir_util import remove_tree, copy_tree
|
||||
from optparse import OptionParser
|
||||
import random
|
||||
from collections import OrderedDict
|
||||
|
||||
import yaml
|
||||
import jinja2
|
||||
|
||||
import lunagen
|
||||
|
||||
lunagen.demo()
|
||||
|
||||
class Config(object):
|
||||
"""
|
||||
Installation configuration variables.
|
||||
|
||||
TODO: Probably change this to load from a YAML file in the future.
|
||||
"""
|
||||
__all__ = []
|
||||
__version__ = 0.1
|
||||
__date__ = '2019-09-19'
|
||||
__updated__ = '2019-09-19'
|
||||
|
||||
DEBUG = True
|
||||
TESTRUN = False
|
||||
PROFILE = False
|
||||
THEMES = '../themes'
|
||||
|
||||
class LunaGen(jinja2.Environment):
|
||||
"""
|
||||
Generator for a LunaGen site, based on contents of srcdir:
|
||||
|
||||
<srcdir>/data - YAML files (handwritten content)
|
||||
<srcdir>/templates - Jinja2 site templates
|
||||
<srcdir>/skeleton - unchanging parts of the site (copied)
|
||||
|
||||
The new site is created in <tgtdir>.
|
||||
"""
|
||||
def __init__(self, srcdir, tgtdir=None, verbosity=0):
|
||||
self.srcdir = os.path.abspath(srcdir)
|
||||
if not tgtdir:
|
||||
self.tgtdir = os.path.join(self.srcdir, 'site')
|
||||
else:
|
||||
self.tgtdir = os.path.abspath(tgtdir)
|
||||
self.datadir = os.path.join(self.srcdir, 'data')
|
||||
self.templates = os.path.join(self.srcdir, 'templates')
|
||||
self.skeleton = os.path.join(self.srcdir, 'skeleton')
|
||||
|
||||
self.verbose = verbosity
|
||||
|
||||
if self.verbose:
|
||||
print("Source directory: %s" % self.srcdir)
|
||||
print("Target directory: %s" % self.tgtdir)
|
||||
print("YAML content should be in: %s" % self.datadir)
|
||||
print("Jinja2 templates should be in: %s" % self.templates)
|
||||
print("Skeleton website should be in: %s" % self.skeleton)
|
||||
|
||||
|
||||
#TODO: Could make sure these directories exist
|
||||
|
||||
# Load up the data from YAML files:
|
||||
self._load_sitedata()
|
||||
self._load_theme()
|
||||
self._load_affiliates()
|
||||
self._load_softwarelist()
|
||||
self._load_products()
|
||||
self._load_serieslist()
|
||||
|
||||
super().__init__(
|
||||
loader=jinja2.ChoiceLoader([
|
||||
jinja2.FileSystemLoader(os.path.join(self.datadir, 'templates')),
|
||||
jinja2.FileSystemLoader(self.theme['path']),
|
||||
jinja2.FileSystemLoader(self.templates)]),
|
||||
autoescape=jinja2.select_autoescape(['html','xml']))
|
||||
|
||||
@staticmethod
|
||||
def _paginate(seq, pagesize):
|
||||
"""
|
||||
Given a sequence of objects, break it into a book of
|
||||
pages, each containing no more than pagesize objects:
|
||||
|
||||
>>> test = [1,'2','three', 4, 5, 'six', 'seven', 8, 9, True, False, None, 0]
|
||||
>>> LunaGen._paginate(test, 4)
|
||||
[[1, '2', 'three', 4], [5, 'six', 'seven', 8], [9, True, False, None], [0]]
|
||||
>>>
|
||||
"""
|
||||
book = []
|
||||
page = []
|
||||
for i,ob in enumerate(seq):
|
||||
if i%pagesize==0:
|
||||
if i>0: book.append(page)
|
||||
page = []
|
||||
page.append(ob)
|
||||
if len(page)>0:
|
||||
book.append(page)
|
||||
return book
|
||||
|
||||
@staticmethod
|
||||
def _paginate_sponsors(series, episode):
|
||||
"""
|
||||
Regroup sponsors into pages which:
|
||||
- Contain only one kind of sponsor
|
||||
- Contain no more than the 'page' limit number of sponsors per page
|
||||
- Are tagged with the sponsortype so we can find the right tempate for them:
|
||||
|
||||
>>> series = {'sponsortypes':
|
||||
... {'A':{'page':1,'limit':1},
|
||||
... 'B':{'page':3, 'limit':10},
|
||||
... 'C':{'page':4, 'limit':20}}}
|
||||
...
|
||||
>>> episode = {'sponsors':
|
||||
... {'A':list(range(2)),
|
||||
... 'B':list(range(7)),
|
||||
... 'C':list(range(22))}}
|
||||
...
|
||||
>>> LunaGen._paginate_sponsors(series, episode)
|
||||
[('A', [0]), ('B', [0, 1, 2]), ('B', [3, 4, 5]), ('B', [6]), ('C', [0, 1, 2, 3]), ('C', [4, 5, 6, 7]), ('C', [8, 9, 10, 11]), ('C', [12, 13, 14, 15]), ('C', [16, 17, 18, 19])]
|
||||
>>>
|
||||
"""
|
||||
paged_sponsors = []
|
||||
for spkey, sponsortype in series['sponsortypes'].items():
|
||||
if spkey not in episode['sponsors']:
|
||||
episode['sponsors'][spkey] = []
|
||||
#if 'excludes' in sponsortype:
|
||||
# for excluded in sponsortype['excludes']:
|
||||
# if excluded in episode['sponsors'] and episode['sponsors'][excluded]:
|
||||
# print("WARNING: excluded sponsortype %s will be ignored, because of existing %s." %
|
||||
# (excluded, spkey))
|
||||
if 'page'in sponsortype:
|
||||
paged = LunaGen._paginate(
|
||||
episode['sponsors'][spkey][:sponsortype['limit']],
|
||||
sponsortype['page'])
|
||||
tags = [spkey] * len(paged)
|
||||
paged_sponsors.extend(zip(tags, paged))
|
||||
return paged_sponsors
|
||||
|
||||
@staticmethod
|
||||
def _fix_series(series):
|
||||
"""
|
||||
Modify series data to correct certain datatypes that are not
|
||||
natively supported by YAML (like OrderedDict):
|
||||
>>> series = {'credits':{
|
||||
... 'a':{'labels':'ordered'},
|
||||
... 'b':{'labels':[['A','-A-'],['B','-B-']]}}}
|
||||
...
|
||||
>>> LunaGen._fix_series(series)
|
||||
>>> series['credits']['b']['labels']
|
||||
OrderedDict([('A', '-A-'), ('B', '-B-')])
|
||||
>>>
|
||||
"""
|
||||
for key, credit in series['credits'].items():
|
||||
if type(credit['labels']) != type(''):
|
||||
credit['labels']=OrderedDict(credit['labels'])
|
||||
|
||||
def _collect_stylesheets(self, *extras):
|
||||
"""
|
||||
Collect a list of unique stylesheets from various stylesheet
|
||||
requirements from theme, site, and data from extra pages.
|
||||
"""
|
||||
stylesheets = []
|
||||
stylesheets.extend(self.theme['stylesheets'])
|
||||
stylesheets.extend(self.sitedata['stylesheets'])
|
||||
for extra in extras:
|
||||
if 'stylesheets' in extra:
|
||||
stylesheets.extend(extra['stylesheets'])
|
||||
stylesheets = [s for i,s in enumerate(stylesheets) if s not in stylesheets[:i]]
|
||||
return stylesheets
|
||||
|
||||
def _load_sitedata(self):
|
||||
if self.verbose: print("Loading global site data.")
|
||||
with open(os.path.join(self.datadir, 'site.yaml'), 'rt') as sitedatafile:
|
||||
self.sitedata = yaml.load(sitedatafile)
|
||||
|
||||
def _load_theme(self):
|
||||
if self.verbose: print("Loading theme data.")
|
||||
self.theme = { 'stylesheets':[] } # Default values
|
||||
themedir = os.path.join(Config.THEMES, self.sitedata['theme'])
|
||||
if not os.path.exists(themedir):
|
||||
raise FileNotFoundError("Theme directory %s not found!" % themedir)
|
||||
with open(os.path.join(themedir, 'theme.yaml'), 'rt') as themedatafile:
|
||||
self.theme.update(yaml.load(themedatafile))
|
||||
self.theme['path'] = themedir
|
||||
|
||||
def _load_affiliates(self):
|
||||
if self.verbose: print("Loading affiliates data.")
|
||||
try:
|
||||
with open(os.path.join(self.datadir, 'affiliates.yaml')) as aff_file:
|
||||
affiliates = yaml.load(aff_file)
|
||||
stylesheets = self.sitedata['stylesheets']
|
||||
self.sitedata.update(affiliates)
|
||||
self.sitedata['stylesheets'] = self._collect_stylesheets(affiliates)
|
||||
self.sitedata['affiliates'] = random.sample(
|
||||
affiliates['affiliates'], min( int(affiliates['affiliates_at_once']),
|
||||
len(affiliates['affiliates'])))
|
||||
except FileNotFoundError:
|
||||
print("No affiliates.yaml file, so affiliates list is empty.")
|
||||
self.sitedata['affiliates'] = []
|
||||
|
||||
|
||||
def _load_softwarelist(self):
|
||||
if self.verbose: print("Loading software data.")
|
||||
try:
|
||||
with open(os.path.join(self.datadir, 'software.yaml')) as sw_file:
|
||||
softwarelist = yaml.load(sw_file)
|
||||
stylesheets = self.sitedata['stylesheets']
|
||||
self.sitedata.update(softwarelist)
|
||||
self.sitedata['stylesheets'] = self._collect_stylesheets(softwarelist)
|
||||
except FileNotFoundError:
|
||||
print("No software.yaml file, so software list is empty.")
|
||||
self.sitedata['softwarelist'] = []
|
||||
|
||||
def _load_products(self):
|
||||
if self.verbose: print("Loading store products data.")
|
||||
try:
|
||||
with open(os.path.join(self.datadir, 'products.yaml')) as prod_file:
|
||||
products = yaml.load(prod_file)
|
||||
stylesheets = self.sitedata['stylesheets']
|
||||
self.sitedata.update(products)
|
||||
self.sitedata['stylesheets'] = self._collect_stylesheets(products)
|
||||
except FileNotFoundError:
|
||||
print("No products.yaml file, so software list is empty.")
|
||||
self.sitedata['products'] = []
|
||||
|
||||
def _load_serieslist(self):
|
||||
if self.verbose: print("Loading series data")
|
||||
try:
|
||||
with open(os.path.join(self.datadir, 'episodes', 'series.yaml'),'rt') as seriesfile:
|
||||
self.serieslist = yaml.load(seriesfile)['serieslist']
|
||||
for series in self.serieslist:
|
||||
self._fix_series(series)
|
||||
episodes = []
|
||||
seriesdir = os.path.join(self.datadir, 'episodes', series['directory'])
|
||||
episode_filenames = [f for f in os.listdir(seriesdir) if f.endswith('.yaml')]
|
||||
for episode_filename in episode_filenames:
|
||||
if self.verbose: print("Loading episode from %s" % episode_filename)
|
||||
with open(os.path.join(seriesdir, episode_filename), 'rt') as episode_file:
|
||||
episodes.append(yaml.load(episode_file))
|
||||
# Sort by episode number specified in the files:
|
||||
try:
|
||||
episodes.sort(key=lambda a: int(a['episode']))
|
||||
except KeyError:
|
||||
print("Some episode YAML files may not have an 'episode' number entry?")
|
||||
series['episodes'] = episodes
|
||||
except FileNotFoundError:
|
||||
print("No series.yaml file, so no series loaded.")
|
||||
self.sitedata['serieslist'] = []
|
||||
|
||||
|
||||
def _copy_skeleton(self):
|
||||
if os.path.exists(self.tgtdir):
|
||||
remove_tree(self.tgtdir, verbose=self.verbose)
|
||||
if self.verbose: print("Copying the theme base.")
|
||||
copy_tree(os.path.join(self.theme['path'], 'base'), self.tgtdir, verbose=self.verbose)
|
||||
if self.verbose: print("Copying the skeleton site.")
|
||||
copy_tree(self.skeleton, self.tgtdir, verbose=self.verbose)
|
||||
|
||||
|
||||
def _gen_simple_page(self, pagename, stylesheets=()):
|
||||
"""
|
||||
Generates a simple page with 1:1:1 Jinja2+YAML+CSS.
|
||||
|
||||
The YAML and CSS pages are optional. If no file exists
|
||||
for them, they will be ignored and the page generated
|
||||
with only the template and global data and/or style.
|
||||
"""
|
||||
if self.verbose: print("Creating '%s' page" % pagename)
|
||||
jinja2_name = pagename + '.j2'
|
||||
yaml_path = os.path.join(self.datadir, pagename+'.yaml')
|
||||
css_path = os.path.join(self.tgtdir, pagename+'.css')
|
||||
# Assumes skeleton already copied
|
||||
data = {} # Defaults can be set here
|
||||
data.update(self.sitedata) # Global data
|
||||
if os.path.exists(yaml_path):
|
||||
with open(yaml_path, 'rt') as yaml_file:
|
||||
data.update(yaml.load(yaml_file)) # Page data
|
||||
data['stylesheets'] = self._collect_stylesheets(data)
|
||||
# Add CSS if not already present:
|
||||
if os.path.exists(css_path) and pagename not in data['stylesheets']:
|
||||
data['stylesheets'].append(pagename)
|
||||
if self.verbose: print("Generating '%s.html' from template." % pagename)
|
||||
html = self.get_template(jinja2_name).render(data)
|
||||
with open(os.path.join(self.tgtdir, pagename+'.html'), 'wt') as page:
|
||||
page.write(html)
|
||||
|
||||
def _gen_index(self):
|
||||
"""
|
||||
Generate an index page, if the skeleton doesn't already have one.
|
||||
"""
|
||||
if not os.path.exists(os.path.join(self.tgtdir, 'index.html')):
|
||||
if self.verbose: print("Generating the Index page.")
|
||||
data = {}
|
||||
data.update(self.sitedata)
|
||||
data['next'] = next # Adds iterator capability
|
||||
data['stylesheets'] = self._collect_stylesheets(self.sitedata['stylesheets'])
|
||||
if 'episode_as_index' in self.sitedata and self.sitedata['episode_as_index']:
|
||||
data['serieslist'] = self.serieslist
|
||||
data['banners'] = iter(['affiliates_banner.j2',
|
||||
'store_banner.j2',
|
||||
'sponsoropps_banner.j2'])
|
||||
data['stylesheets'].extend(self._collect_stylesheets(
|
||||
self.sitedata['episode_list_page']))
|
||||
html = self.get_template('index.j2').render(data)
|
||||
with open(os.path.join(self.tgtdir, 'index.html'), 'wt') as page:
|
||||
page.write(html)
|
||||
else:
|
||||
if self.verbose: print("Found 'index.html', so not generated.")
|
||||
|
||||
def _gen_episode_list_page(self):
|
||||
"""
|
||||
Generate a page linking to all of the individual episodes,
|
||||
grouped into "series" (or "seasons").
|
||||
|
||||
#Currently hard-coded to be saved as 'index.html' for the site.
|
||||
"""
|
||||
if self.verbose: print("Generating the Index (Episode List) page.")
|
||||
if 'render_as' in self.sitedata['episode_list_page']:
|
||||
render_as = self.sitedata['episode_list_page']['render_as']
|
||||
else:
|
||||
render_as = 'index.html'
|
||||
data = {}
|
||||
data.update(self.sitedata)
|
||||
data['serieslist'] = self.serieslist
|
||||
data['banners'] = iter(['affiliates_banner.j2', 'store_banner.j2', 'sponsoropps_banner.j2'])
|
||||
data['stylesheets'] = self._collect_stylesheets(self.sitedata['episode_list_page'])
|
||||
data['next'] = next # Adds iterator capability
|
||||
html = self.get_template('episode_list.j2').render(data)
|
||||
with open(os.path.join(self.tgtdir, render_as), 'wt') as page:
|
||||
page.write(html)
|
||||
|
||||
def _gen_episode_pages(self):
|
||||
"""
|
||||
Generate a page for each episode in each series.
|
||||
"""
|
||||
if self.verbose: print("Generating episode pages...")
|
||||
|
||||
if 'stylesheets' in self.sitedata['episode_pages']:
|
||||
stylesheets = self.sitedata['episode_pages']['stylesheets']
|
||||
else:
|
||||
stylesheets = []
|
||||
|
||||
for series in self.serieslist:
|
||||
for episode in series['episodes']:
|
||||
paged_sponsors = self._paginate_sponsors(series, episode)
|
||||
episode['paged_sponsors'] = iter(paged_sponsors)
|
||||
data = {}
|
||||
data.update(self.sitedata)
|
||||
data['series'] = series
|
||||
data['episode'] = episode
|
||||
data['stylesheets'] = self._collect_stylesheets(self.sitedata['episode_pages'],episode)
|
||||
data['next'] = next
|
||||
data['banners'] = ['affiliates_banner.j2']
|
||||
html = self.get_template('episode_page.j2').render(data)
|
||||
filename = episode['series'] +'E' + ('%2.2d' % int(episode['episode'])) + '.html'
|
||||
os.makedirs(os.path.join(self.tgtdir, series['directory']), exist_ok=True)
|
||||
with open(os.path.join(self.tgtdir, series['directory'], filename), 'wt') as page:
|
||||
page.write(html)
|
||||
|
||||
def gensite(self):
|
||||
"""
|
||||
Generate the site, using the data we've accumulated.
|
||||
"""
|
||||
self._copy_skeleton()
|
||||
for page in self.sitedata['simple_pages']:
|
||||
self._gen_simple_page(page)
|
||||
if self.sitedata['serieslist']:
|
||||
self._gen_episode_list_page()
|
||||
self._gen_episode_pages()
|
||||
else:
|
||||
print("Not generating series & episode pages: serieslist empty.")
|
||||
self._gen_index()
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
'''Command line options.'''
|
||||
|
||||
program_name = os.path.basename(sys.argv[0])
|
||||
program_version = "v0.1"
|
||||
program_build_date = "%s" % Config.__updated__
|
||||
|
||||
program_version_string = '%%prog %s (%s)' % (program_version, program_build_date)
|
||||
program_longdesc = '''\
|
||||
LunaGen is a static HTML website generator designed for releasing
|
||||
a series of episodes (technically: a series of series of episodes).
|
||||
|
||||
Data is authored using the YAML structured data language, which allows
|
||||
for episode metadata and descriptions to be written in a human-friendly
|
||||
format, which is then formatted into HTML using Jinja2 templates.
|
||||
|
||||
Once generated, the site is static and can simply be uploaded to a
|
||||
standard web server with minimal or no configuration (like a static web host).
|
||||
|
||||
It was originally created to generate the release pages for
|
||||
Anansi Spaceworks' "Lunatics!" series.
|
||||
|
||||
For details, please see the 'examples' and 'doc' directories.
|
||||
'''
|
||||
program_license = "Copyright 2019 Terry Hancock (Anansi Spaceworks) \
|
||||
Licensed under the GNU General Public License, version 2.0\n"
|
||||
|
||||
if argv is None:
|
||||
argv = sys.argv[1:]
|
||||
#try:
|
||||
# setup option parser
|
||||
parser = OptionParser(version=program_version_string, epilog=program_longdesc, description=program_license)
|
||||
parser.add_option("-i", "--in", dest="src", help="set input path [default: %default]", metavar="FILE")
|
||||
parser.add_option("-o", "--out", dest="tgt", help="set output path [default: %default]", metavar="FILE")
|
||||
parser.add_option("-v", "--verbose", dest="verbose", action="count", help="set verbosity level [default: %default]")
|
||||
|
||||
# set defaults
|
||||
parser.set_defaults(tgt="./site", src=".")
|
||||
|
||||
# process options
|
||||
(opts, args) = parser.parse_args(argv)
|
||||
|
||||
if opts.verbose > 0:
|
||||
print("verbosity level = %d" % opts.verbose)
|
||||
if opts.src:
|
||||
print("src = %s" % opts.src)
|
||||
if opts.tgt:
|
||||
print("tgt = %s" % opts.tgt)
|
||||
|
||||
lunagen = LunaGen(opts.src, opts.tgt, opts.verbose)
|
||||
lunagen.gensite()
|
||||
|
||||
# except Exception as e:
|
||||
# indent = len(program_name) * " "
|
||||
# sys.stderr.write(program_name + ": " + repr(e) + "\n")
|
||||
# sys.stderr.write(indent + " for help use --help")
|
||||
# return 2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if Config.DEBUG:
|
||||
#sys.argv.append("-h")
|
||||
sys.argv.append("-v")
|
||||
if Config.TESTRUN:
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
if Config.PROFILE:
|
||||
import cProfile
|
||||
import pstats
|
||||
profile_filename = 'lunagen_profile.txt'
|
||||
cProfile.run('main()', profile_filename)
|
||||
statsfile = open("profile_stats.txt", "wb")
|
||||
p = pstats.Stats(profile_filename, stream=statsfile)
|
||||
stats = p.strip_dirs().sort_stats('cumulative')
|
||||
stats.print_stats()
|
||||
statsfile.close()
|
||||
sys.exit(0)
|
||||
sys.exit(main())
|
55
LunaGen/testdata/series/data/affiliates-old.yaml
vendored
55
LunaGen/testdata/series/data/affiliates-old.yaml
vendored
@ -1,55 +0,0 @@
|
||||
# Affiliates Ad data
|
||||
# This is a MOCK-UP, not real affiliates.
|
||||
# (Because I don't have any yet)
|
||||
---
|
||||
stylesheets:
|
||||
- affiliates
|
||||
# It's awkward to have too many affiliate links at one time, so
|
||||
# the script will choose a number of them at random on each refresh
|
||||
# we need to tell it how many we want:
|
||||
affiliates_at_once: 7
|
||||
|
||||
affiliates:
|
||||
- name: 123posters
|
||||
url: http://www.123posters.com/
|
||||
img: 123posters.png
|
||||
|
||||
- name: Amazon
|
||||
url: http://amazon.com
|
||||
img: amazon.png
|
||||
|
||||
- name: Barnes & Noble
|
||||
url: https://www.barnesandnoble.com/
|
||||
img: barnes_noble.png
|
||||
|
||||
- name: Better World Books
|
||||
url: https://www.betterworldbooks.com/
|
||||
img: betterworldbooks.png
|
||||
|
||||
- name: Crayola
|
||||
url: https://www.crayola.com/
|
||||
img: crayola.png
|
||||
|
||||
- name: Humble Bundle
|
||||
url: https://www.humblebundle.com/
|
||||
img: humble.png
|
||||
|
||||
- name: Kiwi Crate
|
||||
url: https://www.kiwico.com/
|
||||
img: kiwicrate.png
|
||||
|
||||
- name: Linux Foundation Training Programs
|
||||
url: https://www.linuxfoundation.org/
|
||||
img: linux_foundation.png
|
||||
|
||||
- name: Lonely Planet
|
||||
url: https://www.lonelyplanet.com/
|
||||
img: lonelyplanet.png
|
||||
|
||||
- name: Red Hat
|
||||
url: https://www.redhat.com/en
|
||||
img: redhat.png
|
||||
|
||||
- name: Lenovo
|
||||
url: https://www.lenovo.com/us/en/pc
|
||||
img: lenovo.png
|
147
LunaGen/testdata/series/data/affiliates.yaml
vendored
147
LunaGen/testdata/series/data/affiliates.yaml
vendored
@ -1,147 +0,0 @@
|
||||
# Affiliates Ad data
|
||||
# This is a MOCK-UP, using popular Free Culture / Open Source projects
|
||||
# We do not have any actual affiliation with these sites
|
||||
#
|
||||
---
|
||||
stylesheets:
|
||||
- affiliates
|
||||
# It's awkward to have too many affiliate links at one time, so
|
||||
# the script will choose a number of them at random on each refresh
|
||||
# we need to tell it how many we want:
|
||||
affiliates_at_once: 7
|
||||
|
||||
affiliates_message: >
|
||||
We benefit when you support these projects and services!
|
||||
|
||||
affiliates:
|
||||
- name: Ardour
|
||||
url: https://ardour.org
|
||||
img: ardour.png
|
||||
type: Software We Use
|
||||
|
||||
- name: Audacity
|
||||
url: https://audacityteam.org
|
||||
img: audacity.png
|
||||
type: Software We Use
|
||||
|
||||
- name: Blender
|
||||
url: https://blender.org
|
||||
img: blender.png
|
||||
type: Software We Use
|
||||
|
||||
- name: Blender Cloud
|
||||
url: https://cloud.blender.org
|
||||
img: blender_cloud.png
|
||||
type: Open Movie Platform
|
||||
|
||||
- name: BlendSwap
|
||||
url: https://blendswap.com
|
||||
img: blendswap.png
|
||||
type: Shared Asset Archive
|
||||
|
||||
- name: Creative Commons
|
||||
url: https://www.creativecommons.org
|
||||
img: creativecommons.png
|
||||
type: Free Culture Advocacy Group
|
||||
|
||||
- name: Debian
|
||||
url: https://debian.org
|
||||
img: debian.png
|
||||
type: Software We Use
|
||||
|
||||
- name: Ethic Cinema
|
||||
url: http://ethiccinema.org
|
||||
img: ethiccinema.png
|
||||
type: Free Culture Advocacy Group
|
||||
|
||||
- name: Free Software Foundation
|
||||
url: https://www.fsf.org
|
||||
img: freesoftwarefoundation.png
|
||||
type: Free Software Advocacy Group
|
||||
|
||||
- name: Free Sound
|
||||
url: https://freesound.org
|
||||
img: freesound.png
|
||||
type: Shared Asset Archive
|
||||
|
||||
- name: GIMP
|
||||
url: https://gimp.org
|
||||
img: gimp.png
|
||||
type: Software We Use
|
||||
|
||||
- name: Inkscape
|
||||
url: https://inkscape.org
|
||||
img: inkscape.png
|
||||
type: Software We Use
|
||||
|
||||
- name: Internet Archive
|
||||
url: https://archive.org
|
||||
img: internet_archive.png
|
||||
type: Shared Asset Archive
|
||||
|
||||
- name: Jamendo
|
||||
url: https://jamendo.com
|
||||
img: jamendo.png
|
||||
type: Shared Asset Archive
|
||||
|
||||
- name: Kdenlive
|
||||
url: https://kdenlive.org
|
||||
img: kdenlive.png
|
||||
type: Software We Use
|
||||
|
||||
- name: Krita
|
||||
url: https://krita.org
|
||||
img: krita.png
|
||||
type: Software We Use
|
||||
|
||||
- name: Mastodon
|
||||
url: http://mastodon.social
|
||||
img: mastodon.png
|
||||
type: Social Media Platform We Use
|
||||
|
||||
- name: Morevna Project
|
||||
url: https://morevnaproject.org
|
||||
img: morevnaproject.png
|
||||
type: Free Culture Project
|
||||
|
||||
- name: MusOpen
|
||||
url: https://musopen.org
|
||||
img: musopen.png
|
||||
type: Shared Asset Archive
|
||||
|
||||
- name: Olive Video Editor
|
||||
url: https://olivevideoeditor.org
|
||||
img: olivevideoeditor.png
|
||||
type: Software We Use
|
||||
|
||||
- name: Public Domain Files
|
||||
url: http://www.publicdomainfiles.com
|
||||
img: publicdomainfiles.png
|
||||
type: Shared Asset Archive
|
||||
|
||||
- name: Public Knowledge
|
||||
url: https://publicknowledge.org
|
||||
img: publicknowledge.png
|
||||
type: Free Culture Advocacy Group
|
||||
|
||||
- name: Question Copyright
|
||||
url: https://questioncopyright.org
|
||||
img: questioncopyright.png
|
||||
type: Free Culture Advocacy Group
|
||||
|
||||
- name: Software Freedom Conservancy
|
||||
url: https://sfconservancy.org
|
||||
img: sfconservancy.png
|
||||
type: Free Software Advocacy Group
|
||||
|
||||
- name: Ubuntu Studio
|
||||
url: https://ubuntustudio.org
|
||||
img: ubuntu_studio.png
|
||||
type: Software We Use
|
||||
|
||||
- name: Urchn
|
||||
url: https://urchn.org
|
||||
img: urchn.png
|
||||
type: Free Culture Studio
|
||||
|
||||
|
227
LunaGen/testdata/series/data/characters.yaml
vendored
227
LunaGen/testdata/series/data/characters.yaml
vendored
@ -1,227 +0,0 @@
|
||||
# Data for the character list page
|
||||
---
|
||||
stylesheets:
|
||||
- bkg_moon_iridium
|
||||
|
||||
characters:
|
||||
- name: Hiromi
|
||||
fullname: Hiromi Aoki Lerner
|
||||
img: hiromi_render_portrait.png
|
||||
born: 2001
|
||||
first_episode: 1
|
||||
|
||||
|
||||
|
||||
desc: >
|
||||
Hiromi Lerner was a medical student and a concert
|
||||
pianist when she first learned about the International
|
||||
Space Foundation's project to put a colony on the Moon.
|
||||
|
||||
She's had a life-long interest in space (stemming partly
|
||||
from her father, who owns a small aerospace business in
|
||||
Torrance, California), but her main motivation is to
|
||||
humanize the project and establish a comfortable home
|
||||
on the Moon. She idolizes her husband Rob Lerner, but
|
||||
also recognizes that he often has his head in the clouds,
|
||||
and is not always the most stable man. She does a lot to
|
||||
keep him grounded.
|
||||
|
||||
She's a traditionalist when it comes to home, decor,
|
||||
and fashion, and has an active artistic interest in
|
||||
integrating Japanese traditionalist aesthetics with
|
||||
her technological lifestyle. She also sometimes sees
|
||||
herself in terms of American western pioneers, who she
|
||||
feels a lot of connection with as a pioneer on a new
|
||||
frontier.
|
||||
|
||||
relations:
|
||||
husband: Rob Lerner
|
||||
daughter: Georgiana Lerner
|
||||
father: David Aoki
|
||||
mother: Ryoko Takamura
|
||||
|
||||
- name: Rob
|
||||
fullname: John Robert Lerner
|
||||
img: rob_render_portrait.png
|
||||
born: 1993
|
||||
first_episode: 2
|
||||
|
||||
desc: >
|
||||
Rob Lerner is a dreamer who has always been fascinated
|
||||
with the idea of living on another world. He grew up
|
||||
reading (and watching) science fiction, and chose
|
||||
mechanical engineering as a major in college. He's originally
|
||||
from Texas, although he's lived in many parts of the US
|
||||
Southwest during his life.
|
||||
|
||||
He tends to be focused on big picture ideas, although he
|
||||
can also become bogged down in technical details and tends
|
||||
to see problems through his engineering lens, which sometimes
|
||||
leads him to struggle with more organic problems. His personality
|
||||
is somewhat mercurial, prone to manic obsessions and depression
|
||||
when things don't work out as he hopes.
|
||||
|
||||
He has a great enthusiasm for humanity in the abstract, but
|
||||
often finds real individual humans hard to get along with. He
|
||||
doesn't quite understand what he did to deserve the loyalty
|
||||
and affection of Hiromi, but he's determined to keep doing it.
|
||||
|
||||
He founded the International Space Foundation which sponsors
|
||||
the colony, and his place there is largely connected to that
|
||||
status. He's seen as a kind of spiritual leader to the rest,
|
||||
but isn't necessarily formally in charge.
|
||||
|
||||
relations:
|
||||
wife: Hiromi Lerner
|
||||
daughter: Georgiana Lerner
|
||||
|
||||
- name: Anya
|
||||
fullname: Anna Anatolyeva Titova / Anna Titova-Farmer (US)
|
||||
img: anya_render_portrait.png
|
||||
born: 2005
|
||||
first_episode: 3
|
||||
|
||||
desc: >
|
||||
Anya Titova (also known as Anya Farmer or Anya Titova-Farmer,
|
||||
but she uses her well-known maiden name professionally) is
|
||||
the youngest child and only daughter of the billionaire co-owner of
|
||||
a major space company (RK Cosmos), Anatoly Titov (his brother
|
||||
Konstantin is also a major shareholder, as well being largely
|
||||
in charge of research and development), and granddaughter of
|
||||
Igor Titov who founded the company.
|
||||
|
||||
Unlike her older brothers, Sergei and Gregor, she was not
|
||||
pressured to work as a cosmonaut, although she has had
|
||||
extensive pilot training as a kind of family expectation.
|
||||
|
||||
She's lived a very privileged life, and was very much a rich
|
||||
party girl in her youth. She liked fast cars and flashy
|
||||
technology, but has increasingly wanted to make an identity
|
||||
for herself. In her early twenties, she established her own
|
||||
satellite company, and has used the profits to press her
|
||||
new interest in space development.
|
||||
|
||||
She met Josh Farmer at a conference on space agriculture
|
||||
sponsored by Rob Lerner's ISF, and there was immediate
|
||||
chemistry her and Josh, which led to them getting married
|
||||
and having a child not long after. But Anya never really
|
||||
slowed down in her career, simply turning her efforts
|
||||
more and more directly towards the ISF project.
|
||||
|
||||
Her family regards her interest in this project amusingly
|
||||
"domestic", and tease her about it, but this will not stop
|
||||
her. The more menial aspects of frontier life are a hard
|
||||
challenge for her to adapt to, but she's managing.
|
||||
|
||||
She and Rob became co-conspirators on founding the project,
|
||||
and she largely brought in the money and the corporate
|
||||
connections to make it happen -- partly on the condition that
|
||||
she and her family are in on this first colony.
|
||||
|
||||
relations:
|
||||
husband: Josh Farmer
|
||||
son: Tim Farmer
|
||||
father: Anatoly Titov
|
||||
brothers:
|
||||
- Sergei Titov
|
||||
- Gregor Titov
|
||||
grandfather: Igor Titov
|
||||
|
||||
- name: Josh
|
||||
fullname: Joshua Randall Farmer
|
||||
img: josh_render_portrait.png
|
||||
born: 2004
|
||||
first_episode: 2
|
||||
|
||||
desc: >
|
||||
Josh Farmer is amused at his appropriate name, as he
|
||||
is indeed from a family of Farmers in the US Midwest. He
|
||||
has a lot of Middle-American attitudes and values, but
|
||||
he is the one who went to college. In fact, he has a
|
||||
doctorate in agricultural science, though he doesn't
|
||||
really like to be called "Doctor Farmer".
|
||||
|
||||
His specialty is space agriculture, and he knows just
|
||||
about everything that anyone knows about how to grow
|
||||
crops in space, and he's got a pretty fair knowledge of
|
||||
animal husbandry as well, largely from his youth, growing
|
||||
up on a farm.
|
||||
|
||||
He and his wife Anya seem like complete opposites, but
|
||||
in fact, they share a lot of basic values, and so their
|
||||
relationship is more complementary than oppositional. But
|
||||
it's no question that Josh's quiet stoic outlook on life
|
||||
makes an intense contrast with Anya's firebrand personality
|
||||
and outspokenness.
|
||||
|
||||
Rob Lerner recruited Josh early on in the Lunar Independent
|
||||
Biospherics Research Experiment (LIBRE) -- the Earthly
|
||||
prototype the ISF colony is based on, early on, and he
|
||||
has been instrumental to the planning and operation of the
|
||||
project.
|
||||
|
||||
relations:
|
||||
wife: Anya Titova
|
||||
son: Tim Farmer
|
||||
|
||||
- name: Tim
|
||||
fullname: Igor Timothy Farmer
|
||||
img: tim_render_portrait.png
|
||||
born: 2026
|
||||
first_episode: 2
|
||||
|
||||
desc: >
|
||||
Tim does not like his first name, Igor, which Anya gave
|
||||
him in honor of his great-grandfather, and prefers to
|
||||
stick with Tim. His mother still calls him "Igor", though.
|
||||
|
||||
He did not exactly choose to be a Lunar colonist, though
|
||||
his chosen form of rebellion (promoting Mars colonization)
|
||||
betrays a bit of his pride in his family and situation. It's
|
||||
also true that he was old enough to have stayed with one
|
||||
of his uncles' families had he really not wanted to go.
|
||||
|
||||
He is very much aware of the social deprivation of being
|
||||
"literally the only teenager on the entire planet", and
|
||||
he spends a lot of his time online, interacting with his
|
||||
friends in VR communities on the "Great Global Grid" which
|
||||
he jokes is now th "Great Galactic Grid". He has a large
|
||||
following online, including a lot of teenage girls, who
|
||||
he has a not-entirely-ethical attitude towards, much to
|
||||
his mother's frustration, and a somewhat unhealthy connection
|
||||
to a piece of anime-inspired "virtual girlfriend" software,
|
||||
known as "Momo Aiai".
|
||||
|
||||
He spends a lot of time hanging out with Georgiana, who is
|
||||
a little like a sister, given how close their living
|
||||
arrangements are, but they're too far apart in age to have
|
||||
really common interests.
|
||||
|
||||
relations:
|
||||
father: Josh Farmer
|
||||
mother: Anya Titova
|
||||
|
||||
- name: Georgiana
|
||||
fullname: Georgiana Lerner
|
||||
img: georgiana_render_portrait.png
|
||||
born: 2033
|
||||
first_episode: 1
|
||||
|
||||
desc:
|
||||
Georgiana is a very quiet, introspective girl, who likes to
|
||||
play with her bunny doll and secretly misses Earth, though
|
||||
she's also excited about the prospect of living on the Moon,
|
||||
and doesn't want to disappoint her parents.
|
||||
|
||||
She's still at a young enough age for magical thinking, and
|
||||
sometimes invents her own "mythology" to explain how her
|
||||
world works, ranging from insightful to woefully incorrect,
|
||||
as with most children her age.
|
||||
|
||||
She's eager to learn new skills and adapts pretty quickly to
|
||||
life in the colony.
|
||||
|
||||
relations:
|
||||
mother: Hiromi Lerner
|
||||
father: Rob Lerner
|
||||
|
35
LunaGen/testdata/series/data/products.yaml
vendored
35
LunaGen/testdata/series/data/products.yaml
vendored
@ -1,35 +0,0 @@
|
||||
# Gumroad Store product links
|
||||
---
|
||||
stylesheets:
|
||||
- products
|
||||
|
||||
products:
|
||||
- name: Books
|
||||
desc: Artbooks, writers guide, and more.
|
||||
url: http://gumroad.com/anansispace
|
||||
img: store_books.png
|
||||
|
||||
- name: Hard Media
|
||||
desc: Video on DVD or flash media. Soundtrack on CD or vinyl.
|
||||
url: http://gumroad.com/anansispace
|
||||
img: store_hardmedia.png
|
||||
|
||||
- name: Posters
|
||||
desc: Decorate your wall with posters and banners.
|
||||
url: http://gumroad.com/anansispace
|
||||
img: store_posters.png
|
||||
|
||||
- name: Subscriptions
|
||||
desc: Subscribe to keep up to date, or become a patron for one episode.
|
||||
url: http://gumroad.com/anansispace
|
||||
img: store_subscriptions.png
|
||||
|
||||
- name: Novelties
|
||||
desc: Collectible novelties and toys.
|
||||
url: http://gumroad.com/anansispace
|
||||
img: store_novelties.png
|
||||
|
||||
- name: Digital Perks
|
||||
desc: Wallpapers, digital design, 3D printing, custom products.
|
||||
url: http://gumroad.com/anansispace
|
||||
img: store_digitalperks.png
|
20
LunaGen/testdata/series/data/site.yaml
vendored
20
LunaGen/testdata/series/data/site.yaml
vendored
@ -1,36 +1,22 @@
|
||||
# Global data for the site
|
||||
# ALL templates will have access to these
|
||||
---
|
||||
sitename: lunatics
|
||||
sitetitle: Lunatics!
|
||||
sitename: series_test
|
||||
sitetitle: Series Test
|
||||
imgdir: images
|
||||
theme: lunatics
|
||||
|
||||
stylesheets:
|
||||
- products
|
||||
- affiliates
|
||||
theme: default
|
||||
|
||||
episode_list_page:
|
||||
render_as: index.html
|
||||
stylesheets:
|
||||
- main
|
||||
- credits
|
||||
- affiliates
|
||||
- series
|
||||
- products
|
||||
- bkg_moon_iridium
|
||||
|
||||
episode_pages:
|
||||
stylesheets:
|
||||
- main
|
||||
- credits
|
||||
- affiliates
|
||||
- products
|
||||
- episode
|
||||
- sponsors
|
||||
|
||||
simple_pages:
|
||||
- characters
|
||||
- universe
|
||||
- sponsorship
|
||||
|
139
LunaGen/testdata/series/data/software.yaml
vendored
139
LunaGen/testdata/series/data/software.yaml
vendored
@ -1,139 +0,0 @@
|
||||
# Software list
|
||||
---
|
||||
softwarelist:
|
||||
- name: Aegisub
|
||||
desc: Subtitle editor
|
||||
url: http://www.aegisub.org/
|
||||
img: aegisub.png
|
||||
|
||||
- name: Ansible
|
||||
desc: Provisioning automation system
|
||||
url: https://www.ansible.com/
|
||||
img: ansible.png
|
||||
|
||||
- name: Ardour
|
||||
desc: Digital audio workstation
|
||||
url: http://ardour.org/
|
||||
img: ardour.png
|
||||
|
||||
- name: Audacity
|
||||
desc: Audio recorder and editor
|
||||
url: http://web.audacityteam.org/
|
||||
img: audacity.png
|
||||
|
||||
- name: Brasero
|
||||
desc: Optical disk burning utility
|
||||
url: https://wiki.gnome.org/Apps/Brasero
|
||||
img: brasero.png
|
||||
|
||||
- name: DVDStyler
|
||||
desc: DVD mastering tool
|
||||
url: https://www.dvdstyler.org/en/
|
||||
img: dvdstyler.png
|
||||
|
||||
- name: GIMP
|
||||
desc: Image Manipulation Package
|
||||
url: http://www.gimp.org/
|
||||
img: gimp.png
|
||||
|
||||
- name: Inkscape
|
||||
desc: 2D vector graphic editing application
|
||||
url: http://www.inkscape.org/
|
||||
img: inkscape.png
|
||||
|
||||
- name: Kdenlive
|
||||
desc: Non-linear video editor
|
||||
url: http://kdenlive.org/
|
||||
img: kdenlive.png
|
||||
|
||||
- name: Krita
|
||||
desc: Digital painting application
|
||||
url: http://www.krita.org/
|
||||
img: krita.png
|
||||
|
||||
- name: LibreOffice
|
||||
desc: Office Suite
|
||||
url: https://www.libreoffice.org
|
||||
img: libreoffice.png
|
||||
|
||||
- name: MediaWiki
|
||||
desc: Collaborative document editing platform
|
||||
url: http://mediawiki.org/
|
||||
img: mediawiki.png
|
||||
|
||||
- name: Mumble
|
||||
desc: VOIP teleconferencing package
|
||||
url: https://wiki.mumble.info/
|
||||
img: mumble.png
|
||||
|
||||
- name: MyPaint
|
||||
desc: Digital painting application
|
||||
url: http://mypaint.org/about/
|
||||
img: mypaint.png
|
||||
|
||||
- name: OBS Studio
|
||||
desc: Screencasting package
|
||||
url: https://obsproject.com/
|
||||
img: obs.png
|
||||
|
||||
- name: Papagayo-NG
|
||||
desc: Lipsinc animation editor
|
||||
url: https://morevnaproject.org/papagayo-ng/
|
||||
img: papagayo-ng.png
|
||||
|
||||
- name: RapidSVN
|
||||
desc: Subversion (version control) client
|
||||
url: https://rapidsvn.org/
|
||||
img: rapidsvn.png
|
||||
|
||||
- name: RenderChan
|
||||
desc: Render management system
|
||||
url: https://morevnaproject.org/renderchan
|
||||
img: renderchan.png
|
||||
|
||||
- name: Resource Space
|
||||
desc: Digital asset management system
|
||||
url: https://www.resourcespace.com/
|
||||
img: resourcespace.png
|
||||
|
||||
- name: Subversion
|
||||
desc: Version control system
|
||||
url: https://subversion.apache.org/
|
||||
img: subversion.png
|
||||
|
||||
- name: Synfig
|
||||
desc: 2D animation package
|
||||
url: http://synfig.org/
|
||||
img: synfig.png
|
||||
|
||||
- name: TACTIC
|
||||
desc: Digital asset and project management system
|
||||
url: https://southpawtech.com/tactic-open-source/
|
||||
img: tactic.png
|
||||
|
||||
- name: Trac
|
||||
desc: Version control web interface (for Subversion)
|
||||
url: https://trac.edgewall.org/
|
||||
img: trac.png
|
||||
|
||||
- name: Ubuntu Studio
|
||||
desc: Multimedia distribution of GNU/Linux
|
||||
url: https://ubuntustudio.org/
|
||||
img: ubuntustudio.png
|
||||
|
||||
- name: VLC
|
||||
desc: Media player
|
||||
url: https://www.videolan.org/index.html
|
||||
img: vlc.png
|
||||
|
||||
- name: Vokoscreen
|
||||
desc: Screencasting software
|
||||
url: http://linuxecke.volkoh.de/vokoscreen/vokoscreen.html
|
||||
img: vokoscreen.png
|
||||
|
||||
- name: Wordpress
|
||||
desc: Content management system
|
||||
url: https://wordpress.org/
|
||||
img: wordpress.png
|
||||
|
||||
|
140
LunaGen/testdata/series/data/sponsorship.yaml
vendored
140
LunaGen/testdata/series/data/sponsorship.yaml
vendored
@ -1,140 +0,0 @@
|
||||
---
|
||||
stylesheets:
|
||||
- sponsorship
|
||||
|
||||
individual:
|
||||
- name: Donation
|
||||
amount: "Any"
|
||||
gumroad_url: "https://gumroad.com/anansispace#ZCNlG"
|
||||
patreon_url: "https://www.patreon.com/lunatics"
|
||||
embed_template: paypal_donate_button
|
||||
img: donations.png
|
||||
description: >
|
||||
If you just want to help us out, we can take simple donations of any amount
|
||||
via our Gumroad store (once only), Patreon Memberships (multiple tiers
|
||||
per-episode), or by making a one-time donation via PayPal.
|
||||
|
||||
|
||||
- name: Patron
|
||||
amount: "$20.00"
|
||||
gumroad_url: "https://gumroad.com/anansispace#sumVF"
|
||||
patreon_url: "https://www.patreon.com/lunatics"
|
||||
img: patron_sponsor.png
|
||||
description: >
|
||||
Patron sponsors' names are listed at the end of the credits. You
|
||||
may use a pseudonym, collective name, or business name if you like,
|
||||
as long as there's no offensive language or messages included.
|
||||
|
||||
This is included with Patreon memberships of $20 per episode or more,
|
||||
or can be acquired for one episode via our Gumroad account.
|
||||
|
||||
- name: Silver Sponsorship
|
||||
amount: "$50.00"
|
||||
gumroad_url: "https://gumroad.com/anansispace#sumVF"
|
||||
patreon_url: "https://www.patreon.com/lunatics"
|
||||
img: silver_sponsor.png
|
||||
description: >
|
||||
Silver sponsors get their names in a prominent listing after the
|
||||
Gold sponsors.
|
||||
|
||||
- name: Gold Sponsorship
|
||||
amount: "$100.00"
|
||||
gumroad_url: "https://gumroad.com/anansispace#sumVF"
|
||||
patreon_url: "https://www.patreon.com/lunatics"
|
||||
img: gold_sponsor.png
|
||||
description: >
|
||||
Gold sponsors get their names in a prominent listing, after commercial
|
||||
sponsorships, but before all other individual sponsorships. They will
|
||||
also be listed in the credits on the download page, but they will not
|
||||
be linked. You may use a company or collective name or a pseudonym rather
|
||||
than your legal name, if you like. Please no foul language, slogans, or
|
||||
political messages here, though.
|
||||
|
||||
- name: Film Freedom Monthly Subscription
|
||||
amount: "$3+"
|
||||
patreon_url: "https://www.patreon.com/filmfreedom"
|
||||
img: filmfreedom_subscription.png
|
||||
description: >
|
||||
If you are mainly interested in our technical, development, and documentation
|
||||
work, and like the predictability of a monthly subscription, please consider
|
||||
supporting our <a href="http://filmfreedom.org">Film Freedom</a> project on
|
||||
Patreon. We're starting a podcast to share our experiences with free culture
|
||||
and free licenses software for production work, as well as sharing video and
|
||||
written tutorials, research, and hints.
|
||||
|
||||
commercial:
|
||||
- name: Commercial Sponsorship
|
||||
amount: "$300.00"
|
||||
gumroad_url: "https://gumroad.com/anansispace#chuEA"
|
||||
email_address: sales@anansispaceworks.com
|
||||
img: commercial_sponsor.png
|
||||
description: >
|
||||
Commercial sponsors get a space for a large monochrome logotype graphic
|
||||
in the credits. They will appear in clustered groups alongside the credits,
|
||||
rendered in the same color as the credits, and listed after the
|
||||
"Commercial Logo" sponsorships (but before any of the individual sponsorships).
|
||||
|
||||
These logos will also be included in the credits list on the episode download
|
||||
page on our website, and you may provide a URL to link the logo to from the
|
||||
web page.
|
||||
|
||||
|
||||
- name: Logo Commercial Sponsorship
|
||||
amount: "$1000.00"
|
||||
gumroad_url: "https://gumroad.com/anansispace#chuEA"
|
||||
email_address: sales@anansispaceworks.com
|
||||
img: logo_sponsor.png
|
||||
description: >
|
||||
Logo sponsors will get a square space beside or ahead of the end credits in the
|
||||
episode, and a prominently-placed logo in the download page for the episode on our
|
||||
website. You may provide a URL to link to from the logo for the website.
|
||||
|
||||
The logo art will appear at 480x480 px at our nominal 1920x1080 production frame,
|
||||
although scaling to online video sites may make it appear smaller, so you should
|
||||
plan accordingly (use a bold design and large enough font).
|
||||
|
||||
Your logo will typically appear alongside other logo sponsors in the credits. We
|
||||
limit the number of possible logo spots to a maximum of 12.
|
||||
|
||||
|
||||
corporate:
|
||||
- name: Anorthosite Principal Episode Sponsorship
|
||||
amount: "$25,000"
|
||||
email_address: mailto:sales@anansispaceworks.com
|
||||
img: anorthosite_sponsor.png
|
||||
description: >
|
||||
We estimate that it costs a minimum of $25,000 to produce an episode of "Lunatics!",
|
||||
which of course, is very inexpensive by TV animation standards, but is enabled by our
|
||||
low overhead, free-software pipeline, and virtual studio approach.
|
||||
|
||||
For this amount, we offer the maximum sponsorship exposure, with an animated logo
|
||||
flown right at the beginning, prior even to our own "Anansi Spaceworks" production
|
||||
logo. There will only be one such sponsor accepted for an episode, so the placement
|
||||
is exclusive.
|
||||
|
||||
If you do not have a prepared logo, we can "fly" a simple logo for you, based
|
||||
on a simple graphic trademark or corporate logo from you.
|
||||
|
||||
You will also get a prominent placement ahead of credits on our episode download
|
||||
page, which can be linked to your company's website.
|
||||
|
||||
|
||||
- name: Breccia Associate Episode Sponsorship
|
||||
amount: "$10,000"
|
||||
email_address: mailto:sales@anansispaceworks.com
|
||||
img: breccia_sponsor.png
|
||||
description: >
|
||||
If a full episode sponsorship is a little too high, we also have an "Associate"
|
||||
sponsorship for half the price, with only a slightly less prominent placement, after
|
||||
our initial production logo, but still before the episode starts.
|
||||
|
||||
Obviously, this one is not exclusive, though we won't take more than three associate
|
||||
sponsorships for an episode, or one with a full-episode sponsorship.
|
||||
|
||||
As with the episode sponsorship, you can provide us with a logo animation, or we
|
||||
can do a simple animation for you, based on your logo art.
|
||||
|
||||
You will also get a prominent placement ahead of the credits on our episode download
|
||||
page, which can be linked to your company's website.
|
||||
|
||||
|
282
LunaGen/testdata/series/episodes/S1/S1E01.yaml
vendored
282
LunaGen/testdata/series/episodes/S1/S1E01.yaml
vendored
@ -1,28 +1,25 @@
|
||||
# Episode release data
|
||||
# See also series.yaml for documentation of options
|
||||
---
|
||||
series: S1
|
||||
series: LunaGen Intro
|
||||
episode: 1
|
||||
mode: production
|
||||
title: "Prolog: 'No Children in Space'"
|
||||
poster: s1e01-prolog-600sq.png
|
||||
status: Finishing and Rendering Sequences. Coming Soon!
|
||||
title: "Yaml Tutorial | Learn YAML in 18 mins"
|
||||
poster: s1e01-yaml_tut_yt-nana-600sq.png
|
||||
status: YAML Intro From YouTube
|
||||
stylesheets:
|
||||
- bkg_earth_limb
|
||||
|
||||
description: >
|
||||
In the first episode of this hard-science-fiction fairytale, seven-year-old
|
||||
Georgiana Lerner becomes the first child in space, while her mother grapples
|
||||
with press questions about the ethics of raising children in space. Both fly
|
||||
into orbit aboard a Soyuz launch vehicle from the same launchpad as Yuri
|
||||
Gagarin took 79 years earlier, on the first leg of their journey to the Moon
|
||||
to join the first true extra-terrestrial settlement.
|
||||
In lieu of a custom tutorial for LunaGen, this is a tutorial on YouTube
|
||||
for YAML syntax, presented by "TechWorld with Nana" I'm also testing
|
||||
embedding a video from YouTube.
|
||||
|
||||
videos:
|
||||
- id: preview
|
||||
name: Preview
|
||||
url: https://player.vimeo.com/video/350535112
|
||||
btn: s1e01-preview-btn.png
|
||||
- id: tutorial
|
||||
name: Tutorial
|
||||
url: https://www.youtube.com/watch?v=1uFVr15xDGg
|
||||
btn: s1e01-yaml_tut_yt-nana-60btn.png
|
||||
|
||||
product:
|
||||
img: om_dvd.png
|
||||
@ -43,261 +40,22 @@ product:
|
||||
|
||||
|
||||
sponsors:
|
||||
full_sponsor:
|
||||
- name: Film Freedom Foundation
|
||||
url: http://www.filmfreedom.org
|
||||
img: film_freedom_foundation.png
|
||||
full_sponsor: []
|
||||
|
||||
logo_sponsors:
|
||||
- name: New Worlds Institute
|
||||
url: https://earthlightfoundation.org/newworlds/
|
||||
img: newworlds-600px.png
|
||||
|
||||
- name: Indian Pirate Party
|
||||
url: http://pirates.org.in
|
||||
img: indian_pirates-600px.png
|
||||
|
||||
- name: The Luna Project
|
||||
url: http://www.lunarcc.org
|
||||
img: luna_project-600px.png
|
||||
|
||||
logo_sponsors: []
|
||||
|
||||
corp_sponsors: []
|
||||
|
||||
gold_sponsors: []
|
||||
|
||||
silver_sponsors:
|
||||
- Chris Kuhn
|
||||
silver_sponsors: []
|
||||
|
||||
patron_sponsors:
|
||||
- Tobias Platen
|
||||
- Shiva Wolfe
|
||||
- Filip Krška
|
||||
- Morevna Project
|
||||
- Nigel Waite
|
||||
- Chris Kuhn
|
||||
patron_sponsors: []
|
||||
|
||||
backer_sponsors:
|
||||
- Martin Ansdell-Smith
|
||||
- Jim Bedford
|
||||
- Mauro Bieg
|
||||
- Ryan Cartwright
|
||||
- John Colagioia
|
||||
- Tom Curl
|
||||
- Konstantin Dmitriev
|
||||
- Jonathan Fluck
|
||||
- Joe Futrelle
|
||||
- Thomas Gideon
|
||||
- Gal Goldschmidt
|
||||
- Franz Gustav
|
||||
- Janet Hancock
|
||||
- Simon Harris
|
||||
- Ian
|
||||
- Javier
|
||||
- Norman Jolley
|
||||
- David Jordan
|
||||
- Emmanouel Kapernaros
|
||||
- Kathryn N Kapust
|
||||
- Tom Kiesel
|
||||
- Mike Linksvayer
|
||||
- Raffaele Manzo
|
||||
- David Maulik
|
||||
- Donna & John Myers
|
||||
- John Myers
|
||||
- Stephen Ormsby
|
||||
- Derek Pearcy
|
||||
- Vibha Pingle
|
||||
- Mike Riley
|
||||
- Gregor B. Rosenauer
|
||||
- Timo Rossi
|
||||
- Karen Sandler
|
||||
- Hugo Simões
|
||||
- Elizabeth Small
|
||||
- Barry Solow
|
||||
- Junius Stone
|
||||
- Julie Tribble
|
||||
- John Tyler
|
||||
- Hal Tynan
|
||||
- Stuart Ward
|
||||
- Robert Wicks
|
||||
- Shiva Wolfe
|
||||
- Joseph Yu
|
||||
- mm2001
|
||||
backer_sponsors: []
|
||||
|
||||
credits:
|
||||
main_credits:
|
||||
-
|
||||
- Screenplay
|
||||
- Rosalyn Hunter
|
||||
-
|
||||
- Produced & Directed
|
||||
- Terry Hancock
|
||||
-
|
||||
- Character Design
|
||||
- Daniel Fu
|
||||
main_credits: []
|
||||
|
||||
cast_credits:
|
||||
-
|
||||
- Narrator
|
||||
- Melodee M. Spevack
|
||||
-
|
||||
- Hiromi Lerner
|
||||
- Karrie Shirou
|
||||
-
|
||||
- Georgiana Lerner
|
||||
- Ariel Hancock
|
||||
-
|
||||
- Boy on Train
|
||||
- Shamil Aminov
|
||||
-
|
||||
- Mother on Train
|
||||
- Nadezhda Dmitrieva
|
||||
-
|
||||
- 'Reporter #1 (USA)'
|
||||
- Terry Hancock
|
||||
-
|
||||
- 'Reporter #2 (Canada)'
|
||||
- Jami Cullen
|
||||
|