Skip to content
Snippets Groups Projects
Verified Commit 61a76160 authored by Jake's avatar Jake
Browse files

more native datatypes and factories

parent c6fda5f1
No related branches found
No related tags found
No related merge requests found
...@@ -27,8 +27,10 @@ def main(): ...@@ -27,8 +27,10 @@ def main():
print(config) print(config)
factories = {} factories = {}
factories['page'] = datatypes.PageFactory() factories['page'] = datatypes.PageFactory(config, factories)
factories['author'] = datatypes.AuthorFactory() factories['author'] = datatypes.AuthorFactory(config, factories)
factories['tag'] = datatypes.TagFactory(config, factories)
factories['link'] = datatypes.LinkFactory(config, factories)
mdreader = reader.MarkdownReader(config, factories) mdreader = reader.MarkdownReader(config, factories)
pages = [] pages = []
...@@ -48,7 +50,7 @@ def main(): ...@@ -48,7 +50,7 @@ def main():
context = {} context = {}
gen = generator.Generator(config, context) gen = generator.Generator(config, context, factories)
gen.generate_context(pages, static_files) gen.generate_context(pages, static_files)
wrt = writer.Writer(config, context, OUTPUT_DIR, THEME_DIR) wrt = writer.Writer(config, context, OUTPUT_DIR, THEME_DIR)
......
...@@ -2,105 +2,126 @@ import datetime ...@@ -2,105 +2,126 @@ import datetime
from dateutil import parser as dtparser from dateutil import parser as dtparser
class PageFactory: class PageFactory:
def __init__(self): def __init__(self, config, factories):
self.config = config
self.factories = factories
self.store = {} self.store = {}
for lang in self.config['lang']['supported']:
self.store[lang] = {}
def has(self, slug, lang):
return (slug in self.store[lang])
def get(self, slug, lang): def get(self, slug, lang):
if slug not in self.store: if not self.has(slug, lang):
self.store[slug] = {} self.store[lang][slug] = Page(slug, lang, self.config, self.factories)
if lang not in self.store[slug]: return self.store[lang][slug];
self.store[slug][lang] = Page(slug, lang)
return self.store[slug][lang];
class Page: class Page:
def __init__(self, slug, lang): def __init__(self, slug, lang, config, factories):
self.slug = slug self.slug = slug
self.lang = lang self.lang = lang
self._config = config
self._factories = factories
self.initialized = False self.initialized = False
def init(self, filename, subpath, raw, metadata, content, title, category, date_created, date_modified, authors, last_modification_author, status, config, factories): def init(self, filename, subpath, raw, metadata, content, title, category, date_created, date_modified, authors, last_modification_author, status):
self.initialized = True self.initialized = True
self.filename = filename self.filename = filename
self.subpath = subpath self.subpath = subpath
self.raw = raw self.raw = raw
self.metadata = metadata self._metadata = metadata
self.content = content self.content = content
self.title = title self.title = title
self.category = category self.category = self._factories['tag'].get(category, self.lang)
self.date_created = Date(date_created, config) self.date_created = Date(date_created, self._config)
self.date_modified = Date(date_modified, config) self.date_modified = Date(date_modified, self._config)
self.status = status self.status = status
#self.config = config
# authors # authors
self.authors = [] self.authors = []
for local_part, domain, name in authors: for local_part, domain, name in authors:
self.authors.append(factories['author'].get(local_part + '@' + domain, name)) self.authors.append(self._factories['author'].get(local_part + '@' + domain, name))
if last_modification_author: if last_modification_author:
self.last_modification_author = factories['author'].get(last_modification_author[0] + '@' + last_modification_author[1], last_modification_author[2]) self.last_modification_author = self._factories['author'].get(last_modification_author[0] + '@' + last_modification_author[1], last_modification_author[2])
else: else:
self.last_modification_author = None self.last_modification_author = None
#print(authors) #print(authors)
#print(last_modification_author) #print(last_modification_author)
# category
self.category.reg_page(self, True)
# url
#self.url = self.lang + '/' + self.category.name + '/' + self.slug + ".html"
self.link = self._factories['link'].get_by_type("slug", self.slug, self.lang)
# tags
self.tags = []
if 'tags' in metadata:
tags = self.tags_str_to_list(metadata['tags'])
for t in tags:
if (t != category):
self.tags.append(t)
self.tags.append(self.category) # the category is also a default tag
# template def get_metadata(self):
if 'template' in metadata: deflang = self._config['lang']['default']
self.template = metadata['template'] if self.lang == deflang:
else: return self._metadata
self.template = config['theme']['default_template'] defpage = self._factories['page'].get(self.slug, deflang)
res = defpage.metadata.copy()
res.update(self._metadata)
return res
metadata = property(get_metadata, None, None)
# url def get_tags(self):
self.url = self.lang + '/' + self.category + '/' + self.slug + ".html" res = []
if 'tags' in self.metadata:
# relevance rawtags = self.tags_str_to_list(self.metadata['tags'])
self.relevance = {} for t in rawtags:
self.relevance['is_relevant'] = False if (t != self.category.name):
self.relevance['was_relevant'] = False tag = factories['tag'].get(t, self.lang)
self.relevance['will_be_relevant'] = False tag.reg_page(self)
if 'relevant' in metadata: res.append(tag)
lrel = metadata['relevant'] res.append(self.category) # the category is also a default tag
return res
tags = property(get_tags, None, None)
def get_relevance(self):
res = {}
res['is_relevant'] = False
res['was_relevant'] = False
res['will_be_relevant'] = False
if 'relevant' in self.metadata:
lrel = self.metadata['relevant']
if not isinstance(lrel, dict): if not isinstance(lrel, dict):
prio = lrel prio = lrel
lrel = {} lrel = {}
lrel['prio'] = prio lrel['prio'] = prio
if 'prio' in lrel: if 'prio' in lrel:
self.relevance['prio']= lrel['prio'] res['prio']= lrel['prio']
else: else:
self.relevance['prio']= 0 res['prio']= 0
start = Date("min", config) start = Date("min", self._config)
if 'start' in lrel: if 'start' in lrel:
start = Date(lrel['start'], config) start = Date(lrel['start'], self._config)
self.relevance['start'] = start res['start'] = start
end = Date("max", config) end = Date("max", self._config)
if 'end' in lrel: if 'end' in lrel:
end = Date(lrel['end'], config) end = Date(lrel['end'], self._config)
self.relevance['end'] = end res['end'] = end
build_date = Date("now", config) build_date = Date("now", self._config)
if (build_date > end): if (build_date > end):
self.relevance['was_relevant'] = True res['was_relevant'] = True
elif (build_date < start): elif (build_date < start):
self.relevance['will_be_relevant'] = True res['will_be_relevant'] = True
else: else:
self.relevance['is_relevant'] = True res['is_relevant'] = True
return res
relevance = property(get_relevance, None, None)
def get_template(self):
if 'template' in self.metadata:
return self.metadata['template']
else:
return self._config['theme']['default_template']
template = property(get_template, None, None)
def tags_str_to_list(self, s): def tags_str_to_list(self, s):
...@@ -123,6 +144,66 @@ class Page: ...@@ -123,6 +144,66 @@ class Page:
raise Exception("Page not initialized.") raise Exception("Page not initialized.")
return self.date_modified < other.date_modified return self.date_modified < other.date_modified
class TagFactory:
def __init__(self, config, factories):
self.config = config
self.factories = factories
self.store = {}
for lang in self.config['lang']['supported']:
self.store[lang] = {}
def get(self, name, lang):
if not isinstance(name, str):
raise Exception("name is not a string", name, type(name))
if name not in self.store[lang]:
self.store[lang][name] = Tag(name, lang, self.factories)
return self.store[lang][name];
def all(self):
return self.store
class Tag:
def __init__(self, name, lang, factories):
self.name = name
self.lang = lang
self.pages = set()
self.is_category = False
self._link = None
self._factories = factories
def get_link(self):
if not self._link:
self._link = self._factories['link'].get_by_type("tag", self.name, self.lang)
return self._link
link = property(get_link, None, None)
def get_page(self):
if self._factories['page'].has('tag-' + self.name, self.lang):
return self._factories['page'].get('tag-' + self.name, self.lang)
else:
return None
page = property(get_page, None, None)
def get_color(self):
if 'color' in self.page.metadata:
return self.page.metadata['color']
else:
return self.config['default_tag_color']
color = property(get_color, None, None)
def get_title(self):
if self.page:
return self.page.title
else:
return self.name
title = property(get_title, None, None)
def reg_page(self, page, is_category = False):
if page == None:
return
if page.lang != self.lang:
raise Exception("Page has different lang than Tag.", page.lang, tag.lang)
self.pages.add(page)
if is_category:
self.is_category = is_category
class Date: class Date:
...@@ -148,17 +229,20 @@ class Date: ...@@ -148,17 +229,20 @@ class Date:
return self.dt.timestamp() < other.dt.timestamp() return self.dt.timestamp() < other.dt.timestamp()
class AuthorFactory: class AuthorFactory:
def __init__(self): def __init__(self, config, factories):
self.config = config
self.factories = factories
self.store = {} self.store = {}
def get(self, email, name = None): def get(self, email, name = None):
if email not in self.store: if email not in self.store:
self.store[email] = Author(email, name) self.store[email] = Author(email)
return self.store[email]; author = self.store[email]
author.reg_name(name)
return author;
class Author: class Author:
def __init__(self, email, name = None): def __init__(self, email):
self.email = email self.email = email
self.names = set() self.names = set()
self.reg_name(name)
split = email.split('@') split = email.split('@')
# TODO proper email validation # TODO proper email validation
...@@ -172,4 +256,124 @@ class Author: ...@@ -172,4 +256,124 @@ class Author:
if name == None: if name == None:
return return
self.names.add(name) self.names.add(name)
class LinkFactory:
def __init__(self, config, factories):
self.config = config
self.factories = factories
self.store = {}
def get_by_raw(self, rawurl, deflang):
if rawurl not in self.store:
self.store[rawurl] = Link(rawurl, self.factories, deflang)
return self.store[rawurl];
def get_by_type(self, reftype, refid, reflang):
rawurl = reftype + ':' + refid + ':' + reflang
return self.get_by_raw(rawurl=rawurl, deflang=reflang)
class Link:
def __init__(self, rawurl, factories, deflang):
self.raw = rawurl
self.is_external = False
urlasplit = rawurl.split('#')
self.anchor = None
if len(urlasplit) == 2:
self.anchor = urlasplit[1]
urlwoa = urlasplit[0] # url without anchor
if len(urlwoa) == 0:
# rawurl: '#some-section'
self.url = ""
self.type = "local"
else:
components = urlwoa.split(':')
if len(components) == 1:
# rawurl: 'lageplan.uni-goettingen.de'
self.url = "https://" + urlwoa
self.is_external = True
else:
reftype = components[0]
refid = components[1]
reflang = deflang
if len(components) > 2:
reflang = components[2]
if reftype == "slug":
# rawurl: 'slug:some-page:de'
self.page = factories['page'].get(refid, reflang)
# TODO handle link/alias pages
self.path = '/'.join([self.page.lang, self.page.category.name, self.page.slug + '.html'])
self.url = self.path
self.type = reftype
elif reftype == "tag":
# rawurl: 'tag:some-tag:de'
self.tag = factories['tag'].get(refid, reflang)
self.path = '/'.join([self.tag.lang, 'tag', self.tag.name + '.html'])
self.url = self.path
self.type = reftype
else:
# rawurl: 'https://example.com'
self.url = urlwoa
self.is_external = True
self.urlwithanchor = self.url
if self.anchor:
self.urlwithanchor = self.url + "#" + self.anchor
import datatypes import datatypes
class Generator: class Generator:
def __init__(self, config, context): def __init__(self, config, context, factories):
self.config = config self.config = config
self.context = context self.context = context
self.factories = factories
def generate_context(self, pages, static_files): def generate_context(self, pages, static_files):
# static_files # static_files
...@@ -41,26 +42,17 @@ class Generator: ...@@ -41,26 +42,17 @@ class Generator:
# TODO draft pages # TODO draft pages
# TODO authors # TODO authors
# categories
categories = {}
for page in published_pages:
if page.lang not in categories:
categories[page.lang] = {}
if page.category not in categories[page.lang]:
categories[page.lang][page.category] = []
categories[page.lang][page.category].append(page)
self.context['categories'] = categories
# tags # tags
tags = {} self.context['tags'] = self.factories['tag'].all()
for page in published_pages:
for tag in page.tags: # categories
if page.lang not in tags: self.context['categories'] = {}
tags[page.lang] = {} for lang in self.config['lang']['supported']:
if tag not in tags[page.lang]: self.context['categories'][lang] = {}
tags[page.lang][tag] = [] for tag in self.context['tags'][lang].values():
tags[page.lang][tag].append(page) if tag.is_category:
self.context['tags'] = tags self.context['categories'][lang][tag.name] = tag
# build_date # build_date
self.context['build_date'] = datatypes.Date("now", self.config) self.context['build_date'] = datatypes.Date("now", self.config)
...@@ -96,11 +88,11 @@ class Generator: ...@@ -96,11 +88,11 @@ class Generator:
for lang in self.config['lang']['supported']: for lang in self.config['lang']['supported']:
# all pages # all pages
for page in self.context['pages'][lang].values(): for page in self.context['pages'][lang].values():
writer.write_template(page.template, page.url, lang, {'page': page}) writer.write_template(page.template, page.link.path, lang, {'page': page})
# all tags # all tags
for tag, tagpages in self.context['tags'][lang].items(): for tag in self.context['tags'][lang].values():
writer.write_template('tag.html', lang + '/tag/' + tag + '.html', lang, {'tag': tag, 'tagpages': tagpages}) writer.write_template('tag.html', tag.link.path, lang, {'tag': tag})
# homepages for languages # homepages for languages
self.generate_homepage(writer, lang, lang + "/index.html") self.generate_homepage(writer, lang, lang + "/index.html")
......
...@@ -125,9 +125,7 @@ class MarkdownReader: ...@@ -125,9 +125,7 @@ class MarkdownReader:
date_modified, date_modified,
authors, authors,
last_modification_author, last_modification_author,
status, status)
self.config,
self.factories)
return p return p
def extract_author(self, raw): def extract_author(self, raw):
......
...@@ -43,6 +43,12 @@ class Writer: ...@@ -43,6 +43,12 @@ class Writer:
context["path"] = path context["path"] = path
context["siteurl"] = siteurl context["siteurl"] = siteurl
context.update(extra_context) context.update(extra_context)
print("template: ", template)
print("path: ", path)
print("lang: ", lang)
print("context: ", context)
print("context keys: ", context.keys())
print("tags:", type(context['tags']), context['tags'])
out = tmpl.render(context) out = tmpl.render(context)
# write file # write file
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment