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)