You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.6 KiB
Python

1 year ago
from sqlalchemy import create_engine
from sqlalchemy.sql import select, update, insert
from sqlalchemy.sql.expression import literal
from .schema import metadata, articles
from markdown import markdown
import re
import os
import sys
db_file = os.path.join(sys.argv[1], 'lazy_wiki.sqlite3')
regex = re.compile(r'^\W+|^\W*\w+\W*')
# instantiate an engine for connecting to a database
engine = create_engine('sqlite:///{}'.format(db_file))
# create tables if they don't exist
metadata.create_all(engine)
# connect to the database
dbc = engine.connect()
def select_longest_keyword_string_starts_with(string):
'''
Fetch the longest keyword that the given string starts with.
'''
query = select([articles]) \
.where(literal(string).ilike(articles.c.title + '%'))
# may be bottleneck
results = [dict(u) for u in dbc.execute(query).fetchall()]
if not results:
return None
return max(results, key = lambda keyword : len(keyword['title']))
def select_article(keyword):
'''
Fetch an article associated with the given keyword.
'''
query = select([articles]) \
.where(articles.c.title == literal(keyword))
try:
return dict(dbc.execute(query).fetchone())
except:
return None
def select_formatted_article(keyword):
'''
Fetch an article associated with the given keyword,
add hyperlinks to it, and format it to HTML.
'''
# get article content
article = select_article(keyword)
raw = article['content']
# add hyperlinks to the content
formatted = ''
# until the raw content is empty
while raw:
# if the remaining raw content starts with a keyword
word = select_longest_keyword_string_starts_with(raw)
if word:
# use original capitalization for hyperlink text
original = raw[:len(word['title'])]
# create a Markdown hyperlink
word = '[{}](/view/{})'.format(original, word['title'])
# cut off the start of the raw content
raw = raw[len(original):]
else:
# cut a word off the start of the raw content
word = regex.search(raw).group()
raw = raw[len(word):]
# add the hyperlink or word to the formatted content
formatted += word
article['content'] = markdown(formatted)
return article
def insert_article(**kwargs):
query = insert(articles).values(**kwargs)
dbc.execute(query)
def update_article(title, **kwargs):
query = update(articles) \
.where(articles.c.title == literal(title)) \
.values(**kwargs)
dbc.execute(query)