From f9162addf898ab2110ad940591fc1154aa75e83c Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Sat, 18 Apr 2020 21:34:51 -0700 Subject: [PATCH] Add info cache, get phantom coloring working in editor previews --- amanuensis/config/context.py | 6 ++--- amanuensis/config/loader.py | 2 +- amanuensis/lexicon/manage.py | 46 +++++++++++++++++++++++++----------- amanuensis/server/lexicon.py | 11 +++++---- 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/amanuensis/config/context.py b/amanuensis/config/context.py index 608226a..6a85b3a 100644 --- a/amanuensis/config/context.py +++ b/amanuensis/config/context.py @@ -41,16 +41,16 @@ class ConfigDirectoryContext(): raise MissingConfigError(fpath) return json_ro(fpath) - def edit(self, filename): + def edit(self, filename, create=False): """ Loads a JSON file in write mode. """ if not filename.endswith('.json'): filename = f'{filename}.json' fpath = os.path.join(self.path, filename) - if not os.path.isfile(fpath): + if not create and not os.path.isfile(fpath): raise MissingConfigError(fpath) - return json_rw(fpath, new=False) + return json_rw(fpath, new=create) def delete(self, filename): """Deletes a file.""" diff --git a/amanuensis/config/loader.py b/amanuensis/config/loader.py index 8f3f360..4c3f2c2 100644 --- a/amanuensis/config/loader.py +++ b/amanuensis/config/loader.py @@ -111,7 +111,7 @@ class json_rw(open_ex): return self.config def __exit__(self, exc_type, exc_value, traceback): - # Only write the enw value out if there wasn't an exception + # Only write the new value out if there wasn't an exception if not exc_type: self.fd.seek(0) json.dump(self.config, self.fd, allow_nan=False, indent='\t') diff --git a/amanuensis/lexicon/manage.py b/amanuensis/lexicon/manage.py index 8fd9771..2c551a6 100644 --- a/amanuensis/lexicon/manage.py +++ b/amanuensis/lexicon/manage.py @@ -285,11 +285,11 @@ def publish_turn(lexicon, drafts): src_ctx = lexicon.ctx.src for filename in drafts: with draft_ctx.read(filename) as source: - with src_ctx.new(filename) as dest: + with src_ctx.edit(filename, create=True) as dest: dest.update(source) draft_ctx.delete(filename) - # Rebuilding the interlink data begins with loading all articles + # Load all articles in the source directory and rebuild their renderable trees article_model_by_title = {} article_renderable_by_title = {} for filename in src_ctx.ls(): @@ -297,27 +297,45 @@ def publish_turn(lexicon, drafts): article_model_by_title[article.title] = article article_renderable_by_title[article.title] = parse_raw_markdown(article.contents) - # Determine the full list of articles by checking for phantom citations - written_titles = list(article_model_by_title.keys()) - phantom_titles = [] - for article in article_renderable_by_title.values(): - citations = article.render(GetCitations()) - for target in citations: - if target not in written_titles and target not in phantom_titles: - phantom_titles.append(target) + # Get all citations + citations_by_title = {} + for title, article in article_renderable_by_title.items(): + citations_by_title[title] = article.render(GetCitations()) - # Render article HTML and save to cache + # Get the written and phantom lists from the citation map + written_titles = list(citations_by_title.keys()) + phantom_titles = [] + for citations in citations_by_title.values(): + for title in citations: + if title not in written_titles and title not in phantom_titles: + phantom_titles.append(title) + + # Build the citation map and save it to the info cache + # TODO delete obsolete entries? + with lexicon.ctx.edit('info', create=True) as info: + for title in written_titles: + info[title] = { + 'citations': citations_by_title[title], + 'character': article_model_by_title[title].character + } + for title in phantom_titles: + info[title] = { + 'citations': [], + 'character': None, + } + + # Render article HTML and save to article cache rendered_html_by_title = {} for title, article in article_renderable_by_title.items(): html = article.render(HtmlRenderer(written_titles)) filename = filesafe_title(title) - with lexicon.ctx.article.new(filename) as f: + with lexicon.ctx.article.edit(filename, create=True) as f: f['title'] = title f['html'] = html for title in phantom_titles: - html = "" + html = None filename = filesafe_title(title) - with lexicon.ctx.article.new(filename) as f: + with lexicon.ctx.article.edit(filename, create=True) as f: f['title'] = title f['html'] = html diff --git a/amanuensis/server/lexicon.py b/amanuensis/server/lexicon.py index 3680966..d3d70eb 100644 --- a/amanuensis/server/lexicon.py +++ b/amanuensis/server/lexicon.py @@ -70,7 +70,7 @@ def get_bp(): def article(name, title): with g.lexicon.ctx.article.read(title) as a: article = dict(a) - article['html'] = Markup(a['html']) + article['html'] = Markup(a['html'] or "") return render_template('lexicon/article.html', article=article) @bp.route('/rules/', methods=['GET']) @@ -211,7 +211,6 @@ def get_bp(): form=form, article_html=Markup(rendered_html)) - @bp.route('/statistics/', methods=['GET']) @lexicon_param @player_required_if_not_public @@ -319,8 +318,12 @@ def get_bp(): # check if article was previously approved # check extrinsic constraints for blocking errors parsed_draft = parse_raw_markdown(article['contents']) - rendered_html = parsed_draft.render(PreviewHtmlRenderer( - {'Article':'default','Phantom':None})) + with g.lexicon.ctx.read('info') as info: + authorship = { + title: article.character + for title, article in info.items() + } + rendered_html = parsed_draft.render(PreviewHtmlRenderer(authorship)) features = parsed_draft.render(FeatureCounter()) filename = f'{article["character"]}.{article["aid"]}'