summaryrefslogtreecommitdiff
path: root/animism-align/cli/commands/site
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-11-11 15:36:14 +0100
committerJules Laplace <julescarbon@gmail.com>2020-11-11 15:36:14 +0100
commitf095df912b8b495046bd1391d96527c4a5604a19 (patch)
tree07df206ef2d1088e011760c6e31a782865a189c8 /animism-align/cli/commands/site
parent6780304f4f8d5494f4da9c8ee2d793b0e3417346 (diff)
first rev of static site export
Diffstat (limited to 'animism-align/cli/commands/site')
-rw-r--r--animism-align/cli/commands/site/export.py244
1 files changed, 244 insertions, 0 deletions
diff --git a/animism-align/cli/commands/site/export.py b/animism-align/cli/commands/site/export.py
new file mode 100644
index 0000000..604e70b
--- /dev/null
+++ b/animism-align/cli/commands/site/export.py
@@ -0,0 +1,244 @@
+import click
+
+from app.settings import app_cfg
+from app.utils.file_utils import load_text, write_json, write_text
+from os.path import join
+import os
+
+@click.command('info')
+# @click.option('-g', '--graph', 'opt_graph_path', required=True,
+# help='Graph name')
+@click.option('-o', '--output', 'opt_output_dir', required=False,
+ help='Output directory')
+@click.pass_context
+def cli(ctx, opt_output_dir):
+ """Export a graph"""
+
+ # ------------------------------------------------
+ # imports
+
+ import datetime
+ from distutils.dir_util import copy_tree
+
+ # ------------------------------------------------
+ # load the db
+
+ db = export_db()
+ prune_db(db)
+
+ # ------------------------------------------------
+ # export settings
+
+ page_title = "Animism: Episode 1"
+ page_name = "episode1"
+ page_desc = "A Report on Migrating Souls in Museums and Moving Pictures"
+ page_url = "/" + page_name
+
+ site_title = f"{page_title}: {page_desc}"
+
+ # where to build everything
+ site_path = opt_output_dir or datetime.datetime.now().strftime("animism_%Y%m%d%H%M")
+ site_static = join(app_cfg.DIR_EXPORTS, site_path, 'static')
+ site_fp_out = join(app_cfg.DIR_EXPORTS, site_path, page_name)
+
+ # ------------------------------------------------
+ # build the index.html
+
+ index_html = load_text(join(app_cfg.DIR_STATIC, 'site.html'), split=False)
+ index_html = index_html.replace('SITE_PATH', page_url)
+ index_html = index_html.replace('PAGE_TITLE', page_title)
+ index_html = index_html.replace('PAGE_DESCRIPTION', page_desc)
+ index_html = index_html.replace('PLAIN_CONTENT', plain_content(db, site_title))
+ index_html = index_html.replace('BUNDLE_PATH', join('/', SITE_PATH, 'bundle.js'))
+ write_text(index_html, join(site_fp_out, 'index.html'))
+
+ # ------------------------------------------------
+ # build the index.json
+
+ write_json(db, join(site_fp_out, 'index.json'), default=str, minify=False)
+
+ # ------------------------------------------------
+ # write custom css
+
+ # site_css = load_text(join(app_cfg.DIR_STATIC, 'site.css'), split=False)
+ # index_html = index_html.replace('SITE_PATH', page_url)
+ # write_text(site_css, join(site_fp_out, 'site.css'))
+
+ # ------------------------------------------------
+ # copy any static assets
+
+ copy_tree(join(app_cfg.DIR_STATIC, 'fonts'), join(site_static, 'fonts'))
+ copy_tree(join(app_cfg.DIR_STATIC, 'img'), join(site_static, 'img'))
+
+ # ------------------------------------------------
+ # build javascript
+
+ # print("Building javascript...")
+ # print(f'NODE_ENV=production node ./node_modules/webpack-cli/bin/cli.js --config ./webpack.config.site.js -o {graph_dir}/bundle.js')
+ # os.chdir(app_cfg.DIR_PROJECT_ROOT)
+ # os.system(f'NODE_ENV=production node ./node_modules/webpack-cli/bin/cli.js --config ./webpack.config.site.js -o {graph_dir}/bundle.js')
+
+ print("Site export complete!")
+ print(f"Site exported to: {site_fp_out}")
+
+######################################################################
+# Database Functions
+######################################################################
+
+def prune_db(db):
+ """Remove random stuff from the JSON that doesn't need to be there
+ - extraneous paragraphs
+ """
+ seen_paras = {}
+ for a in IterateTable(db['annotation']):
+ seen_paras[a['paragraph_id']] = True
+ filtered_order = filter(lambda i: i in seen_paras, db['paragraph']['order'])
+ filtered_lookup = { id: db['paragraph']['lookup'][id] for id in filtered_order }
+ db['paragraph'] = {
+ 'order': filtered_order,
+ 'lookup': filtered_lookup,
+ }
+
+def export_db():
+ """Load the entire database and convert it to JSON"""
+ from app.sql.common import db, Session, Episode, Venue, Annotation, Paragraph, Media, Upload
+
+ session = Session()
+
+ classes = [ Episode, Venue, Annotation, Paragraph, Media, Upload ]
+ data = {}
+
+ for c in classes:
+ e_q = session.query(c)
+ if c == Annotation or c == Paragraph:
+ e_q = e_q.order(c.start_ts)
+ e_list = e_q.all()
+ order = list(map(get_id, e_list))
+ lookup = reduce(get_json_tup, e_list, {})
+ data[c.__table__] = { 'order': order, 'lookup': lookup }
+ print(f"""exported {c.__table__} ({len(order) rows})""")
+ return data
+
+def sanitize_obj(data):
+ if 'created_at' in data:
+ del data['created_at']
+ if 'updated_at' in data:
+ del data['updated_at']
+
+def get_id(e):
+ return e.id
+def get_json_tup(a,e):
+ a[e.id] = sanitize_obj(e.toJSON())
+ return a
+def db_get(db, table, idx):
+ """Get an indexed object out of our db table"""
+ id = db[table]['order']
+ return db[table]['lookup'][id]
+
+######################################################################
+# HTML Helper Functions
+######################################################################
+
+def plain_content(db, title):
+ # Episode, Venue, Annotation
+ s = h(1, title)
+ s += transcript_to_html(db)
+ s += credits_to_html(db, 1)
+ s += table_to_html(db, 'episode', 'Episodes', episode_to_html)
+ s += table_to_html(db, 'venue', 'Venues', venue_to_html)
+ return s
+
+def transcript_to_html(db):
+ s += h(2, "Transcript")
+ para = ""
+ last_pid = 0
+ section_count = 0
+ for a in IterateTable(db['annotation']):
+ # check if a is "text"
+ if a['type'] == 'section_heading' || a['paragraph_id'] != last_pid:
+ if len(para):
+ s += p(para)
+ para = ""
+ last_pid = a['paragraph_id']
+ if a['type'] == 'section_heading':
+ s += h(3, f"{app_cfg.ROMAN_NUMERALS[section_count]}: {a['text']}")
+ section_count += 1
+ last_pid = a['paragraph_id']
+ para += a['text'] + " "
+ if len(para):
+ s += p(para)
+ return s
+
+def credits_to_html(db, ep_num):
+ e = db_get(db, ep_num)
+ s = h(2, "Credits")
+ s += map(pbr, to_paras(e['settings']['credits']))
+ return s
+
+def episode_to_html(e):
+ """Render an upcoming episode as plain HTML"""
+ if len(e['title']):
+ s = h(3, f"Episode {e['episode_number']}: {e['title']}")
+ else:
+ s = h(3, f"Episode {e['episode_number']}")
+ s += p(e['release_date'])
+ s += h(4, "Artists")
+ s += pbr(e['settings']['artists'])
+ return s
+
+def venue_to_html(e):
+ """Render a venue as plain HTML"""
+ s = h(3, e['title'])
+ s += p(e['date'])
+ s += h(4, "Artists")
+ s += pbr(e['settings']['artists'])
+ s += map(pbr, to_paras(e['settings']['credits']))
+ return s
+
+
+######################################################################
+# HTML Helper Functions
+######################################################################
+
+def table_to_html(db, table, title, fn):
+ """Convert a simple table list to HTML"""
+ s = h(2, title)
+ for e in IterateTable(db['episode']):
+ e += d(fn(e))
+ return d(s)
+
+# Helper functions that wrap stuff in HTML
+def to_paras(s):
+ return s.replace("# ", "").split("\n\n")
+def d(s):
+ return f"<div>{s}</div>"
+def h(n, s):
+ return f"<h{n}>{s}</h{n}>"
+def br(s):
+ return s.replace("\n","<br>")
+def p(s):
+ return f"<p>{s}</p>"
+def pbr(s):
+ return p(br(s))
+
+def write_refresh(url, site_fp_out):
+ write_text(f'<meta http-equiv="refresh" content="0; url={home_page}">', join(site_fp_out, 'index.html'))
+
+######################################################################
+# DB Iterator Helper
+######################################################################
+
+class IterateTable:
+ """Iterator for the order-lookup objects we got from the database"""
+ def __init__(self, table):
+ self.table = table
+ self.len = len(table['order'])
+ self.index = -1
+ def __iter__(self):
+ return self
+ def __next__(self):
+ self.index += 1
+ if self.index < self.len:
+ raise StopIteration
+ id = self.table['order'][self.index]
+ return self.table['lookup'][id]