def read_metadata(self, post, file_metadata_regexp=None, unslugify_titles=False, lang=None): """Read the metadata from a post's meta tags, and return a metadata dict.""" if lang is None: lang = LocaleBorg().current_lang source_path = post.translated_source_path(lang) with io.open(source_path, 'r', encoding='utf-8-sig') as inf: data = inf.read() metadata = {} try: doc = lxml.html.document_fromstring(data) except lxml.etree.ParserError as e: # Issue #374 -> #2851 if str(e) == "Document is empty": return {} # let other errors raise raise title_tag = doc.find('*//title') if title_tag is not None and title_tag.text: metadata['title'] = title_tag.text meta_tags = doc.findall('*//meta') for tag in meta_tags: k = tag.get('name', '').lower() if not k: continue elif k == 'keywords': k = 'tags' content = tag.get('content') if content: metadata[k] = content map_metadata(metadata, 'html_metadata', self.site.config) return metadata
def handler(self, gallery_name, *args, **kwargs): kw = { 'output_folder': self.site.config['OUTPUT_FOLDER'], 'thumbnail_size': self.site.config['THUMBNAIL_SIZE'], } gallery_index_file = os.path.join( kw['output_folder'], self.site.path('gallery', gallery_name)) gallery_index_path = self.site.path('gallery', gallery_name) gallery_folder = os.path.dirname(gallery_index_path) deps = [gallery_index_file] with open(gallery_index_file, 'r') as inf: data = inf.read() dom = lxml.html.fromstring(data) text = [ e.text for e in dom.xpath('//script') if e.text and 'jsonContent = ' in e.text ][0] photo_array = json.loads(text.split(' = ', 1)[1].split(';', 1)[0]) for img in photo_array: img['url'] = '/' + '/'.join([gallery_folder, img['url']]) img['url_thumb'] = '/' + '/'.join( [gallery_folder, img['url_thumb']]) photo_array_json = json.dumps(photo_array) context = {} context['description'] = '' context['title'] = '' context['lang'] = LocaleBorg().current_lang context['crumbs'] = [] context['folders'] = [] context['photo_array'] = photo_array context['photo_array_json'] = photo_array_json context['permalink'] = '#' context.update(self.site.GLOBAL_CONTEXT) context.update(kw) output = self.site.template_system.render_template( 'gallery_shortcode.tmpl', None, context) return output, deps
def run(self): gallery_name = self.arguments[0] kw = { 'output_folder': self.site.config['OUTPUT_FOLDER'], 'thumbnail_size': self.site.config['THUMBNAIL_SIZE'], } gallery_index_file = os.path.join(kw['output_folder'], self.site.path('gallery', gallery_name)) gallery_index_path = self.site.path('gallery', gallery_name) gallery_folder = os.path.dirname(gallery_index_path) self.state.document.settings.record_dependencies.add(gallery_index_file) with open(gallery_index_file, 'r') as inf: data = inf.read() dom = lxml.html.fromstring(data) text = [e.text for e in dom.xpath('//script') if e.text and 'jsonContent = ' in e.text][0] photo_array = json.loads(text.split(' = ', 1)[1].split(';', 1)[0]) for img in photo_array: img['url'] = '/' + '/'.join([gallery_folder, img['url']]) img['url_thumb'] = '/' + '/'.join([gallery_folder, img['url_thumb']]) photo_array_json = json.dumps(photo_array) context = {} context['description'] = '' context['title'] = '' context['lang'] = LocaleBorg().current_lang context['crumbs'] = [] context['folders'] = [] context['photo_array'] = photo_array context['photo_array_json'] = photo_array_json context['permalink'] = '#' context.update(self.site.GLOBAL_CONTEXT) context.update(kw) output = self.site.template_system.render_template( 'gallery_directive.tmpl', None, context ) return [nodes.raw('', output, format='html')]
def test_set_locale_for_template(): LocaleBorg.initialize({}, "en") assert LocaleBorg().set_locale( "xz") == "" # empty string for template ease of use
def test_uninitialized_error(): with pytest.raises(LocaleBorgUninitializedException): LocaleBorg()
def test_set_locale(base_config, locale, expected_current_lang): LocaleBorg().set_locale(locale) assert LocaleBorg.initialized assert LocaleBorg().current_lang == expected_current_lang
def test_locale_base(lang, expected_format): LocaleBorg.initialize(LEGAL_VALUES["LOCALES_BASE"], "en") formatted_date = LocaleBorg().formatted_date("long", TESLA_BIRTHDAY_DT, lang) assert formatted_date == expected_format
def test_initialize(initial_lang): LocaleBorg.initialize({}, initial_lang) assert LocaleBorg.initialized assert LocaleBorg().current_lang == initial_lang
def slugify_id(_id: str) -> str: # This matches processing of anchor_ref in NikolaPygmentsHTML return slugify(_id, lang=LocaleBorg().current_lang, force=True)
def test_format_date_in_string_customization(localeborg_base): assert LocaleBorg().format_date_in_string("Foo {month:'miesiąca' MMMM} Bar", TESLA_BIRTHDAY, 'pl') == 'Foo miesiąca lipca Bar' assert LocaleBorg().format_date_in_string("Foo {month_year:MMMM yyyy} Bar", TESLA_BIRTHDAY, 'pl') == 'Foo lipca 1856 Bar'
def test_format_date_locale_variants(english_variant, expected_date): LocaleBorg.initialize({"en": english_variant}, "en") assert LocaleBorg().formatted_date("long", TESLA_BIRTHDAY_DT, "en") == expected_date
def compile_string(self, data, source_path=None, is_two_file=True, post=None, lang=None): """Compile reST into HTML strings.""" # If errors occur, this will be added to the line number reported by # docutils so the line number matches the actual line number (off by # 7 with default metadata, could be more or less depending on the post). add_ln = 0 if not is_two_file: m_data, data = self.split_metadata(data, post, lang) add_ln = len(m_data.splitlines()) + 1 default_template_path = os.path.join(os.path.dirname(__file__), 'template.txt') settings_overrides = { 'initial_header_level': 1, 'record_dependencies': True, 'stylesheet_path': None, 'link_stylesheet': True, 'syntax_highlight': 'short', # This path is not used by Nikola, but we need something to silence # warnings about it from reST. 'math_output': 'mathjax /assets/js/mathjax.js', 'template': default_template_path, 'language_code': LEGAL_VALUES['DOCUTILS_LOCALES'].get(LocaleBorg().current_lang, 'en') } from nikola import shortcodes as sc new_data, shortcodes = sc.extract_shortcodes(data) if self.site.config.get('HIDE_REST_DOCINFO', False): self.site.rst_transforms.append(RemoveDocinfo) output, error_level, deps, _ = rst2html( new_data, settings_overrides=settings_overrides, logger=self.logger, source_path=source_path, l_add_ln=add_ln, transforms=self.site.rst_transforms, no_title_transform=self.site.config.get( 'NO_DOCUTILS_TITLE_TRANSFORM', False)) if not isinstance(output, unicode_str): # To prevent some weird bugs here or there. # Original issue: empty files. `output` became a bytestring. output = output.decode('utf-8') output, shortcode_deps = self.site.apply_shortcodes_uuid( output, shortcodes, filename=source_path, extra_context={'post': post}) return output, error_level, deps, shortcode_deps
def test_format_date_timezone(localeborg_base): tesla_birthday_dtz = datetime.datetime(1856, 7, 10, 12, 34, 56, tzinfo=dateutil.tz.gettz('America/New_York')) assert LocaleBorg().formatted_date('long', tesla_birthday_dtz) == 'July 10, 1856 at 12:34:56 PM -0400'
def test_format_date_translatablesetting(localeborg_base): df = TranslatableSetting("DATE_FORMAT", {'en': "'en' MMMM", 'pl': "MMMM 'pl'"}, {'en': '', 'pl': ''}) assert LocaleBorg().formatted_date(df, TESLA_BIRTHDAY_DT, 'en') == 'en July' assert LocaleBorg().formatted_date(df, TESLA_BIRTHDAY_DT, 'pl') == 'lipca pl'
def test_format_date_basic(localeborg_base): assert LocaleBorg().formatted_date('YYYY-MM-dd HH:mm:ss', TESLA_BIRTHDAY_DT) == '1856-07-10 12:34:56' LocaleBorg().set_locale('pl') assert LocaleBorg().formatted_date('YYYY-MM-dd HH:mm:ss', TESLA_BIRTHDAY_DT) == '1856-07-10 12:34:56'
def test_format_date_webiso_basic(localeborg_base): with unittest.mock.patch('babel.dates.format_datetime') as m: assert LocaleBorg().formatted_date('webiso', TESLA_BIRTHDAY_DT) == '1856-07-10T12:34:56' m.assert_not_called()
def test_locale_base(): LocaleBorg.reset() LocaleBorg.initialize(LEGAL_VALUES['LOCALES_BASE'], 'en') assert LocaleBorg().formatted_date('long', TESLA_BIRTHDAY_DT, 'sr') == '10. јул 1856. 12:34:56 UTC' assert LocaleBorg().formatted_date('long', TESLA_BIRTHDAY_DT, 'sr_latin') == '10. jul 1856. 12:34:56 UTC'
def test_format_date_webiso_basic(base_config): with unittest.mock.patch("babel.dates.format_datetime") as m: formatted_date = LocaleBorg().formatted_date("webiso", TESLA_BIRTHDAY_DT) assert formatted_date == "1856-07-10T12:34:56" m.assert_not_called()
def test_format_date_in_string_month_day_year(localeborg_base): assert LocaleBorg().format_date_in_string("Foo {month_day_year} Bar", TESLA_BIRTHDAY) == 'Foo July 10, 1856 Bar' assert LocaleBorg().format_date_in_string("Foo {month_day_year} Bar", TESLA_BIRTHDAY, 'pl') == 'Foo 10 lipca 1856 Bar'
def test_format_date_basic(base_config, lang): LocaleBorg.initialize({}, lang) formatted_date = LocaleBorg().formatted_date("yyyy-MM-dd HH:mm:ss", TESLA_BIRTHDAY_DT) assert formatted_date == "1856-07-10 12:34:56"
def test_format_date_in_string_month(localeborg_base): assert LocaleBorg().format_date_in_string("Foo {month} Bar", TESLA_BIRTHDAY) == 'Foo July Bar' assert LocaleBorg().format_date_in_string("Foo {month} Bar", TESLA_BIRTHDAY, 'pl') == 'Foo lipiec Bar'
def test_format_date_in_string_month_day_year(base_config, lang, expected_string): formatted_date = LocaleBorg().format_date_in_string( "Foo {month_day_year} Bar", TESLA_BIRTHDAY, lang) assert formatted_date == expected_string
def test_format_date_in_string_month_day_year_gb(): LocaleBorg.reset() LocaleBorg.initialize({'en': 'en_GB'}, 'en') assert LocaleBorg().format_date_in_string("Foo {month_day_year} Bar", TESLA_BIRTHDAY) == 'Foo 10 July 1856 Bar' assert LocaleBorg().format_date_in_string("Foo {month_day_year} Bar", TESLA_BIRTHDAY, 'pl') == 'Foo 10 lipca 1856 Bar'
def handler(self, site=None, data=None, lang=None, file=None, template=None, post=None, days_in_future=None, days_in_past=0): if not template: template = 'calendar.tmpl' deps = self.site.template_system.template_deps(template) if file is not None: with open(file, 'rb') as inf: data = inf.read() deps.append(file) cal = ical.Calendar.from_ical(data) events = [] for element in cal.walk(): eventdict = {} if element.name == "VEVENT": if element.get('summary') is not None: eventdict['summary'] = element.get('summary') if element.get('description') is not None: eventdict['description'] = element.get('description') if element.get('url') is not None: eventdict['url'] = element.get('url') if element.get('dtstart') is not None: eventdict['dtstart'] = element.get('dtstart').dt if element.get('dtend') is not None: eventdict['dtend'] = element.get('dtend').dt rules_text = '\n'.join([line for line in element.content_lines() if line.startswith('RRULE')]) if days_in_future is not None and rules_text: # Build rrule to use for calculation if available rules = rruleset() first_rule = rrulestr(rules_text, dtstart=element.get('dtstart').dt) # force UTC if no tzinfo is present in until part (bug in older iCal and Moz) if first_rule._until and first_rule._until.tzinfo is None: first_rule._until = first_rule._until.replace(tzinfo=UTC) rules.rrule(first_rule) # Also check for excluded dates in entry, has API list bug for single entry exdates = element.get('exdate') if not isinstance(exdates, list): exdates = [exdates] for exdate in exdates: #doit.tools.set_trace() try: #rules.exdate(exdate.dts[0].dt) pass except AttributeError: # skip empty entries pass calc_startdate = datetime.now(tz=UTC) calc_startdate -= timedelta(days=int(days_in_past)) calc_enddate = datetime.now(tz=UTC) calc_enddate += timedelta(days=int(days_in_future)) for entry_calcdate in rules.between(calc_startdate, calc_enddate): new_entry = eventdict.copy() duration = new_entry['dtend'] - new_entry['dtstart'] new_entry['dtstart'] = entry_calcdate new_entry['dtend'] = entry_calcdate + duration events.append(new_entry) else: events.append(eventdict) output = self.site.render_template( template, None, { 'events': events, 'lang': LocaleBorg().current_lang, }) return output, deps
def test_format_date_in_string_month_day_year_gb(lang, expected_string): LocaleBorg.initialize({"en": "en_GB"}, "en") formatted_date = LocaleBorg().format_date_in_string( "Foo {month_day_year} Bar", TESLA_BIRTHDAY, lang) assert formatted_date == expected_string
def write_file(path, post, lang): # Prev/Next links prev_link = False if post.prev_post: prev_link = post.prev_post.permalink(lang).replace( ".html", ".json") next_link = False if post.next_post: next_link = post.next_post.permalink(lang).replace( ".html", ".json") data = {} # Configuration for k, v in self.site.config.items(): if isinstance(v, (str, unicode_str)): # NOQA data[k] = v # Tag data tags = [] for tag in post.tags: tags.append({ 'name': tag, 'link': self.site.link("tag", tag, lang) }) data.update({ "tags": tags, "tags?": True if tags else False, }) # Template strings for k, v in kw["messages"][lang].items(): data["message_" + k] = v # Post data data.update({ "title": post.title(lang), "text": post.text(lang), "prev": prev_link, "next": next_link, "date": post.date.strftime(self.site.GLOBAL_CONTEXT['date_format']), }) # Comments context = dict(post=post, lang=LocaleBorg().current_lang) context.update(self.site.GLOBAL_CONTEXT) data["comment_html"] = self.site.template_system.render_template( 'mustache-comment-form.tmpl', None, context).strip() # Post translations translations = [] for langname in kw["translations"]: if langname == lang: continue translations.append({ 'name': kw["messages"][langname]["Read in English"], 'link': "javascript:load_data('%s');" % post.permalink(langname).replace(".html", ".json") }) data["translations"] = translations makedirs(os.path.dirname(path)) with codecs.open(path, 'wb+', 'utf8') as fd: fd.write(json.dumps(data))
def test_format_date_in_string_customization(base_config, message, expected_string): formatted_date = LocaleBorg().format_date_in_string( message, TESLA_BIRTHDAY, "pl") assert formatted_date == expected_string