def test_process_simple(): wiki = Wiki(Settings()) document = { 'sample': trim(""" Title > Quote = Calvin, /Institutes/ @ Headline Paragraph * Bullets * Bullets """) } _ = wiki.process('user-slug', 'doc-slug', document) __ = html.fromstring(str(_)) assert __.xpath("//article/section") assert __.xpath("//h1/a[contains(., 'Title')]") assert __.xpath("//blockquote[contains(., 'Quote')]") assert __.xpath("//p[@class='caption'] and contains(., 'Calvin')") assert __.xpath("//p[@class='caption']/em[contains(., 'Institutes')]") assert __.xpath("//p[@class='subhead'][contains(., 'Headline')]") assert __.xpath("//p[contains(., 'Paragraph')]") assert __.xpath("count(//ul/li[contains(., 'Bullets')])") == 2
def save(self, pregenerate=True, update_doc_slug=None): """ Stores self.parts; compare with self.old to know how to update the metadata and cache. """ self.require_slugs() self.require_parts() # Old and new doc slugs may differ old_doc_slug = self.doc_slug new_doc_slug = self.doc_slug if update_doc_slug is None: update_doc_slug = all([ # fixtures, templates old_doc_slug not in self.protected_doc_slugs(), ]) if update_doc_slug: if 'index' in self.parts: new_text = self.parts['index'] _, _, title_slug, _ = get_title_data(new_text, 'index') if self.doc_slug != title_slug: new_doc_slug = title_slug with self.data as _: _.userDocument_set(self.user_slug, new_doc_slug, self.parts) if old_doc_slug not in self.protected_doc_slugs(): _.userDocumentLastChanged_set(self.user_slug, old_doc_slug, new_doc_slug) _.userDocumentCache_delete(self.user_slug, old_doc_slug) _.userDocumentMetadata_delete(self.user_slug, old_doc_slug) self.doc_slug = new_doc_slug if pregenerate: wiki = Wiki( Settings({ 'config:host': self.host, # <-- ebooks req. FQDN 'config:user': self.user_slug, 'config:document': self.doc_slug })) html = wiki.process(self.user_slug, self.doc_slug, self.parts) self.data.userDocumentCache_set(self.user_slug, self.doc_slug, html) metadata = wiki.compile_metadata(self.data.time_zone, self.user_slug, self.doc_slug) self.data.userDocumentMetadata_set(self.user_slug, self.doc_slug, metadata) return self.doc_slug
def show_editor(source: str, user_slug: str = '', doc_slug: str = '', part_slug: str = '', is_preview: bool = False, can_be_saved: bool = False): """ Common renderer for /playground and /edit/user_slug/doc_slug/part_slug. """ settings = Settings({ 'config:host': domain_name(bottle.request), 'config:user': user_slug, 'config:document': doc_slug, }) wiki = Wiki(settings) part_slug, title, title_slug, summary = get_title_data(source, part_slug) text = reformat_part(part_slug, source) if part_slug == '': slug = slugify(title) elif part_slug != 'index' and is_index_part(text): slug = 'index' elif part_slug == 'biblio': slug = 'biblio' else: slug = part_slug html = wiki.process(user_slug, doc_slug, { slug: copy(text), }, fragment=False, preview=True) template = views.get_template('editor.html') return template.render(page_title="Editing: {:s}".format(title), config=config, user_slug=user_slug, doc_slug=doc_slug, part_slug=part_slug, preview=html, source=escape(text), is_preview=is_preview, can_be_saved=can_be_saved)
def test_split_author(): wiki = Wiki(Settings()) expect = [['Name']] actual = wiki.split_author(trim(""" Name """)) assert expect == actual expect = [['Name', 'Email', 'Affiliation']] actual = wiki.split_author( trim(""" Name / Email / Affiliation """)) assert expect == actual expect = [['Name', 'Email', 'Affiliation'], ['Name2', 'Email2', 'Affiliation2']] actual = wiki.split_author( trim(""" Name / Email / Affiliation + Name2 / Email2 / Affiliation2 """)) assert expect == actual
def read_document(user_slug, doc_slug): """ Compile the complete html document. """ header_buttons = [ home_button(), edit_button(user_slug, doc_slug, 'index'), ] login = get_login() if not login: header_buttons += [subscribe_button(), rss_button(user_slug)] footer_buttons = [biblio_button(user_slug, doc_slug)] if has_authority_for_user(user_slug): footer_buttons += [upload_button(user_slug, doc_slug)] footer_buttons += [download_button(user_slug, doc_slug)] settings = Settings({ 'config:host': domain_name(bottle.request), 'config:user': user_slug, 'config:document': doc_slug, }) metadata = data.userDocumentMetadata_get(user_slug, doc_slug) html = data.userDocumentCache_get(user_slug, doc_slug) if not html or not metadata: wiki = Wiki(settings) doc_parts = require_document(user_slug, doc_slug) html = wiki.process(user_slug, doc_slug, doc_parts) data.userDocumentCache_set(user_slug, doc_slug, html) metadata = wiki.compile_metadata(config['TIME_ZONE'], user_slug, doc_slug) metadata['url'] = '/read/{:s}/{:s}'.format(user_slug, doc_slug) data.userDocumentMetadata_set(user_slug, doc_slug, metadata) uri = '/read/{:s}/{:s}'.format(user_slug, doc_slug) metadata['url'] = abs_url(bottle.request, uri) author_uri = '/user/{:s}'.format(user_slug) metadata['author_url'] = abs_url(bottle.request, author_uri) metadata['home_url'] = abs_url(bottle.request, '/') image_uri = '/image/card/{:s}/{:s}.jpg'.format(user_slug, doc_slug) metadata['image_url'] = abs_url(bottle.request, image_uri) # @todo: function to split on multi authors as well as emails. title = metadata.get('title', 'Untitled') author = metadata.get('author', 'Anonymous') page_title = "{:s} - {:s}".format(title, author) template = views.get_template('read.html') template.trim_blocks = True template.lstrip_blocks = True page_html = template.render(config=config, page_title=page_title, metadata=metadata, user_slug=user_slug, doc_slug=doc_slug, web_buttons=web_buttons(user_slug, doc_slug), header_buttons=header_buttons, footer_buttons=footer_buttons, content_html=html) return page_html
def user_page(user_slug): """ Show <user_slug>/fixtures/author + user documents. """ header_buttons = [login_or_logout_button()] login = get_login() if login and login['username'] == user_slug: header_buttons += [ new_article_button(user_slug), ] header_buttons += [ edit_button(user_slug, 'fixtures', 'author'), ] if not login: header_buttons += [subscribe_button(), rss_button(user_slug)] footer_buttons = [] if config['ARTICLE_WIKI_CREDIT'] == 'YES': footer_buttons += [source_button()] footer_buttons += [help_button()] if has_authority_for_user(user_slug): footer_buttons += [export_archive_button(user_slug)] slugs = data.userDocumentSet_list(user_slug) changes_list = data.userDocumentLastChanged_list(user_slug) if not has_authority_for_user(user_slug): # Show only those that have been published changes_list, __ = split_published(changes_list) article_slugs = [_ for _ in slugs if _ not in ['fixtures', 'templates']] article_keys = [ data.userDocumentMetadata_key(user_slug, _) for _ in article_slugs ] article_list = sorted(data.get_hashes(article_keys), key=lambda _: _.get('title', '')) published_articles, unpublished_articles = split_published(article_list) if not has_authority_for_user(user_slug): unpublished_articles = [] settings = Settings({ 'config:host': domain_name(bottle.request), 'config:user': user_slug, 'config:document': 'fixtures', }) wiki = Wiki(settings) document = data.userDocument_get(user_slug, 'fixtures') if not document: msg = "User '{:s}' not found." bottle.abort(HTTP_NOT_FOUND, msg.format(user_slug)) if 'author' in document: text = document['author'] else: text = trim(""" Author Page (Author information to be added here...) """) blocks = BlockList(clean_text(text)) page_title, page_summary = blocks.pop_titles() content_html = wiki.process(None, None, {'index': blocks.text()}, fragment=True, preview=True) inline = Inline() return views.get_template('user.html').render( config=config, user=user_slug, page_title="{:s} - {:s}".format(page_title, page_summary), title_html=inline.process(page_title), summary_html=inline.process(page_summary), header_buttons=header_buttons, footer_buttons=footer_buttons, changes_list=changes_list, published_articles=published_articles, unpublished_articles=unpublished_articles, content_html=content_html, pluralize=pluralize # <-- hack function injection )
def write_epub(user_slug, doc_slug, file_path): # Get all the data config = load_env_config() data = Data(config) user = data.user_get(user_slug) # or None if not user: raise RuntimeError("User not found: %s", user_slug) document = data.userDocument_get(user_slug, doc_slug) # or Noen if not document: raise RuntimeError("Document not found: %s" % doc_slug) # ------------------------- # 0. Create book # 1. Create cover # 2. Create title page # 3. Create chapter (which basically is the book) # ... This upgrades to multiple chapters when compiling books. # Pre-processing... settings = Settings({ 'config:user': user_slug, 'config:document': doc_slug, }) wiki = Wiki(settings) xhtml = wiki.process(user_slug, doc_slug, document) metadata = wiki.compile_metadata(config['TIME_ZONE'], user_slug, doc_slug) metadata['url'] = '/read/{:s}/{:s}'.format(user_slug, doc_slug), title = metadata.get('title', 'Untitled') summary = metadata.get('summary', '') author = metadata.get('author', 'Anonymous') date = metadata.get('date', '') # ------------------------- # 0. CREATE BOOK book = epub.EpubBook() # set metadata book.set_identifier(user_slug + '+' + doc_slug) book.set_title(title) book.set_language('en') book.add_author(author) # define CSS style with open('static/epub.css') as f: style = f.read() global_css = epub.EpubItem(uid="style_nav", file_name="style/nav.css", media_type="text/css", content=style) book.add_item(global_css) # ------------------------- # 1. Create Cover tmp_cover_file = "/tmp/%s-%s-cover.png" % (user_slug, doc_slug) image = make_background((1600, 2200), (160, 184, 160)) cover = make_cover(image, [title, summary, author, date], [COLOR_TEXT, COLOR_SHADOW]) cover.save(tmp_cover_file, "JPEG") chapter_file_name = doc_slug + '.xhtml' assert os.path.exists(tmp_cover_file) cover_image = open(tmp_cover_file, 'rb').read() book.set_cover("image.jpg", cover_image) # ------------------------- # 2. Create Title Page date_string = datetime.now().strftime("%Y-%m-%d %H:%M:%S") title_xhtml = """ <html> <body> <div>Generated by <i>Article Wiki</i>:</div> <div>%s</div> <div> </div> <div>Permanent URL:</div> <div>http://chapman.wiki/read/%s/%s</div> </body> </html> """ % (date_string, user_slug, doc_slug) c1 = epub.EpubHtml(title="About this book", file_name="title.xhtml", lang='en') c1.content = title_xhtml c1.add_item(global_css) book.add_item(c1) # ------------------------- # 3. Create Chapter c2 = epub.EpubHtml(title=title, file_name=chapter_file_name, lang='en') c2.content = xhtml c2.add_item(global_css) book.add_item(c2) # Define Table Of Contents book.toc = ( epub.Link(chapter_file_name, title, doc_slug), # (epub.Section(user_slug), (c2)) ) # add default NCX and Nav file book.add_item(epub.EpubNcx()) book.add_item(epub.EpubNav()) # basic spine book.spine = ['nav', c1, c2] # write to the file epub.write_epub(file_path, book, {})