Exemplo n.º 1
0
    def _execute(self, options, args):
        """Apply mincss the generated site."""
        output_folder = self.site.config["OUTPUT_FOLDER"]
        if Processor is None:
            LOGGER.warn("To use the mincss command," ' you have to install the "mincss" package.')
            return

        p = Processor(preserve_remote_urls=False)
        urls = []
        css_files = {}
        for root, dirs, files in os.walk(output_folder):
            for f in files:
                url = os.path.join(root, f)
                if url.endswith(".css"):
                    fname = os.path.basename(url)
                    if fname in css_files:
                        LOGGER.error("You have two CSS files with the same name and that confuses me.")
                        sys.exit(1)
                    css_files[fname] = url
                if not f.endswith(".html"):
                    continue
                urls.append(url)
        p.process(*urls)
        for inline in p.links:
            fname = os.path.basename(inline.href)
            with open(css_files[fname], "wb+") as outf:
                outf.write(inline.after)
Exemplo n.º 2
0
    def handleMatch(self, m):
        gist_id = m.group("gist_id")
        gist_file = m.group("filename")

        gist_elem = etree.Element("div")
        gist_elem.set("class", "gist")
        script_elem = etree.SubElement(gist_elem, "script")

        if requests:
            noscript_elem = etree.SubElement(gist_elem, "noscript")

            try:
                if gist_file:
                    script_elem.set("src", GIST_FILE_JS_URL.format(gist_id, gist_file))
                    raw_gist = self.get_raw_gist_with_filename(gist_id, gist_file)

                else:
                    script_elem.set("src", GIST_JS_URL.format(gist_id))
                    raw_gist = self.get_raw_gist(gist_id)

                # Insert source as <pre/> within <noscript>
                pre_elem = etree.SubElement(noscript_elem, "pre")
                pre_elem.text = AtomicString(raw_gist)

            except GistFetchException as e:
                LOGGER.warn(e.message)
                warning_comment = etree.Comment(" WARNING: {0} ".format(e.message))
                noscript_elem.append(warning_comment)

        else:
            LOGGER.warn('"requests" package not installed.  ' "Please install to add inline gist source.")

        return gist_elem
Exemplo n.º 3
0
    def site_context(self, site, client_templates):
        from nikola.utils import TranslatableSetting, LOGGER, Functionary
        result = {}
        translated_settings = {}
        for l in site.config['TRANSLATIONS']:
            translated_settings[l] = {}
        for k, v in site.GLOBAL_CONTEXT.items():
            if k in ['template_hooks', 'get_post_data', 'timezone']:
                continue
            if callable(v):
                if isinstance(v, TranslatableSetting):
                    for l in site.config['TRANSLATIONS']:
                        translated_settings[l][k] = v.values[l]
                    continue
                elif isinstance(v, Functionary):
                    # just a callable dict
                    pass
                else:
                    LOGGER.warn('Found unserializable callable in GLOBAL_CONTEXT: %r, %s' % (k, type(v)))
                    continue

            result[k] = v
        result['translated_settings'] = translated_settings
        # TODO: LEGAL_VALUES isn't exported by nikola.py!
        # result['lang'] in LEGAL_VALUES['RTL_LANGUAGES']
        result['is_rtl'] = False
        result['default_lang'] = site.default_lang
        result['BASE_URL'] = site.config['BASE_URL']
        result['client_templates'] = client_templates
        return result
Exemplo n.º 4
0
def emoji_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    text = text.lower()
    LOGGER.warn('The role :emoji:`{0}` is deprecated. Use |{0}| instead'.format(text))
    node = nodes.image(
        uri='https://cdnjs.cloudflare.com/ajax/libs/emojify.js/1.1.0/images/basic/{0}.png'.format(text),
        alt=text,
        classes=['emoji'],
    )
    return [node], []
Exemplo n.º 5
0
def emoji_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    text = text.lower()
    LOGGER.warn('The role :emoji:`{0}` is deprecated. Use |{0}| instead'.format(text))
    node = nodes.image(
        uri='http://www.tortue.me/emoji/{0}.png'.format(text),
        alt=text,
        classes=['emoji'],
    )
    return [node], []
Exemplo n.º 6
0
def emoji_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    text = text.lower()
    LOGGER.warn(
        'The role :emoji:`{0}` is deprecated. Use |{0}| instead'.format(text))
    node = nodes.image(
        uri='http://www.tortue.me/emoji/{0}.png'.format(text),
        alt=text,
        classes=['emoji'],
    )
    return [node], []
Exemplo n.º 7
0
def doc_shortcode(*args, **kwargs):
    """Implement the doc shortcode."""
    text = kwargs['data']
    success, twin_slugs, title, permalink, slug = _doc_link(text, text, LOGGER)
    if success:
        if twin_slugs:
            LOGGER.warn(
                'More than one post with the same slug. Using "{0}" for doc shortcode'.format(permalink))
        return '<a href="{0}">{1}</a>'.format(permalink, title)
    else:
        LOGGER.error(
            '"{0}" slug doesn\'t exist.'.format(slug))
        return '<span class="error text-error" style="color: red;">Invalid link: {0}</span>'.format(text)
Exemplo n.º 8
0
Arquivo: doc.py Projeto: rowhit/nikola
def doc_shortcode(*args, **kwargs):
    """Implement the doc shortcode."""
    text = kwargs['data']
    success, twin_slugs, title, permalink, slug = _doc_link(text, text, LOGGER)
    if success:
        if twin_slugs:
            LOGGER.warn(
                'More than one post with the same slug. Using "{0}" for doc shortcode'.format(permalink))
        return '<a href="{0}">{1}</a>'.format(permalink, title)
    else:
        LOGGER.error(
            '"{0}" slug doesn\'t exist.'.format(slug))
        return '<span class="error text-error" style="color: red;">Invalid link: {0}</span>'.format(text)
Exemplo n.º 9
0
 def analyze(self, task, find_sources=False):
     rv = False
     self.whitelist = [re.compile(x) for x in self.site.config['LINK_CHECK_WHITELIST']]
     try:
         filename = task.split(":")[-1]
         d = lxml.html.fromstring(open(filename).read())
         for l in d.iterlinks():
             target = l[0].attrib[l[1]]
             if target == "#":
                 continue
             parsed = urlparse(target)
             if parsed.scheme or target.startswith('//'):
                 continue
             if parsed.fragment:
                 target = target.split('#')[0]
             target_filename = os.path.abspath(
                 os.path.join(os.path.dirname(filename), unquote(target)))
             if any(re.match(x, target_filename) for x in self.whitelist):
                 continue
             elif target_filename not in self.existing_targets:
                 if os.path.exists(target_filename):
                     self.existing_targets.add(target_filename)
                 else:
                     rv = True
                     LOGGER.warn("Broken link in {0}: ".format(filename), target)
                     if find_sources:
                         LOGGER.warn("Possible sources:")
                         LOGGER.warn(os.popen('nikola list --deps ' + task, 'r').read())
                         LOGGER.warn("===============================\n")
     except Exception as exc:
         LOGGER.error("Error with:", filename, exc)
     return rv
Exemplo n.º 10
0
def doc_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    """Handle the doc role."""
    success, twin_slugs, title, permalink, slug = _doc_link(rawtext, text, options, content)
    if success:
        if twin_slugs:
            inliner.reporter.warning(
                'More than one post with the same slug. Using "{0}"'.format(permalink))
            LOGGER.warn(
                'More than one post with the same slug. Using "{0}" for doc role'.format(permalink))
        node = make_link_node(rawtext, title, permalink, options)
        return [node], []
    else:
        msg = inliner.reporter.error(
            '"{0}" slug doesn\'t exist.'.format(slug),
            line=lineno)
        prb = inliner.problematic(rawtext, rawtext, msg)
        return [prb], [msg]
Exemplo n.º 11
0
Arquivo: doc.py Projeto: rowhit/nikola
def doc_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
    """Handle the doc role."""
    success, twin_slugs, title, permalink, slug = _doc_link(rawtext, text, options, content)
    if success:
        if twin_slugs:
            inliner.reporter.warning(
                'More than one post with the same slug. Using "{0}"'.format(permalink))
            LOGGER.warn(
                'More than one post with the same slug. Using "{0}" for doc role'.format(permalink))
        node = make_link_node(rawtext, title, permalink, options)
        return [node], []
    else:
        msg = inliner.reporter.error(
            '"{0}" slug doesn\'t exist.'.format(slug),
            line=lineno)
        prb = inliner.problematic(rawtext, rawtext, msg)
        return [prb], [msg]
Exemplo n.º 12
0
    def _execute(self, command, args):
        # Get last succesful deploy date
        timestamp_path = os.path.join(self.site.config['CACHE_FOLDER'], 'lastdeploy')
        if self.site.config['COMMENT_SYSTEM_ID'] == 'nikolademo':
            LOGGER.warn("\nWARNING WARNING WARNING WARNING\n"
                        "You are deploying using the nikolademo Disqus account.\n"
                        "That means you will not be able to moderate the comments in your own site.\n"
                        "And is probably not what you want to do.\n"
                        "Think about it for 5 seconds, I'll wait :-)\n\n")
            time.sleep(5)

        deploy_drafts = self.site.config.get('DEPLOY_DRAFTS', True)
        deploy_future = self.site.config.get('DEPLOY_FUTURE', False)
        if not (deploy_drafts and deploy_future):
            # Remove drafts and future posts
            out_dir = self.site.config['OUTPUT_FOLDER']
            self.site.scan_posts()
            for post in self.site.timeline:
                if (not deploy_drafts and post.is_draft) or \
                   (not deploy_future and post.publish_later):
                    remove_file(os.path.join(out_dir, post.destination_path()))
                    remove_file(os.path.join(out_dir, post.source_path))

        for command in self.site.config['DEPLOY_COMMANDS']:
            try:
                with open(timestamp_path, 'rb') as inf:
                    last_deploy = literal_eval(inf.read().strip())
            except Exception:
                last_deploy = datetime(1970, 1, 1)  # NOQA

            LOGGER.notice("==>", command)
            ret = subprocess.check_call(command, shell=True)
            if ret != 0:  # failed deployment
                raise Exception("Failed deployment")
        LOGGER.notice("Successful deployment")
        new_deploy = datetime.now()
        # Store timestamp of successful deployment
        with codecs.open(timestamp_path, 'wb+', 'utf8') as outf:
            outf.write(repr(new_deploy))
Exemplo n.º 13
0
 def scan_files(self):
     failure = False
     LOGGER.notice("Checking Files:")
     LOGGER.notice("===============\n")
     only_on_output, only_on_input = self.real_scan_files()
     if only_on_output:
         only_on_output.sort()
         LOGGER.warn("Files from unknown origins:")
         for f in only_on_output:
             LOGGER.warn(f)
         failure = True
     if only_on_input:
         only_on_input.sort()
         LOGGER.warn("Files not generated:")
         for f in only_on_input:
             LOGGER.warn(f)
     if not failure:
         LOGGER.notice("All files checked.")
     return failure
Exemplo n.º 14
0
    def set_site(self, site):
        """
        Map navstories config to nav_config[*] as TranslatableSettings
        """

        # Read NAVSTORIES_SUBMENU_INDENTION and store in self.navstories_submenu_indention
        if 'NAVSTORIES_SUBMENU_INDENTION' in site.config:
            self.navstories_submenu_indention = site.config[
                'NAVSTORIES_SUBMENU_INDENTION']

        nav_config = {}
        for i in self.conf_vars:
            # Read config variables in a try...except in case a variable is missing
            try:
                nav_config[i] = utils.TranslatableSetting(
                    i, site.config[i], site.config['TRANSLATIONS'])
            except KeyError:
                # Initialize to "empty" in case config variable i is missing
                nav_config[i] = utils.TranslatableSetting(
                    i, self.conf_defaults[i](), site.config['TRANSLATIONS'])

        site.scan_posts()
        # NAVIGATION_LINKS is a TranslatableSetting, values is an actual dict
        for lang in site.config['NAVIGATION_LINKS'].values:
            # navstories config for lang
            nav_conf_lang = {}
            for i in self.conf_vars:
                nav_conf_lang[i] = nav_config[i](lang)

            # Which paths are navstories active for current lang? - Must start and end with /
            paths = tuple(('/' + s.strip('/') + '/')
                          for s in nav_conf_lang['NAVSTORIES_PATHS'])

            # Unsorted (raw) new entries, deleted as mapped to new
            new_raw = {}
            # Sorted entries as a list of top-level menu entries, later
            new = []
            # Map site pages to new_raw structure
            for p in site.pages:
                # Generate navpath (menu) based on permalink without language prefix
                # If TRANSLATION[DEFAULT_LANG] = '', then "permalink_nolang = p.permalink()" is ok
                permalink_nolang = re.sub(
                    r'^/' + nav_conf_lang['TRANSLATIONS'].lstrip('./') + '/?',
                    '/', p.permalink(lang))
                s_candidates = [
                    s for s in paths if permalink_nolang.startswith(s)
                ]
                if not s_candidates:
                    continue
                # get longest path
                s = max(s_candidates, key=len)
                # Strip off the longest path in paths
                navpath = permalink_nolang[len(s):].strip('/').split('/')
                if len(navpath) == 0:
                    # Should not happen that navpath is empty, but to prevent errors, and inform via a warning
                    LOGGER.warn(
                        "Page with permalink: '%s', title: '%s', not added to menu by navstories."
                        % (p.permalink(lang), p.title(lang)))
                    continue
                if lang in p.translated_to and not p.meta('hidefromnav'):
                    # Add entry
                    if not navpath[0] in new_raw:
                        new_raw[navpath[0]] = []
                    new_raw[navpath[0]].append(
                        self.NavNode(navpath, p.permalink(lang),
                                     p.title(lang)))

            # Map from new_raw to new, sorting by NAVSTORIES_MAPPING
            for map_key, map_txt in nav_conf_lang['NAVSTORIES_MAPPING']:
                # Loop over all new_raw entries, checking if it matches map_key; if match: add it and delete from new_raw
                if map_key in new_raw:
                    new.append([map_txt, new_raw[map_key]])
                    del (new_raw[map_key])
            # Add remaing new_raw entries which didn't match any map_key
            new.extend([[None, new_raw[_]] for _ in sorted(new_raw)])

            # Map to tuple
            new_entries = self.map_to_menu(new)
            old_entries = site.config['NAVIGATION_LINKS'](lang)
            # Update NAVIGATION_LINKS with navstories dynamically generated entries and NAVIGATION_LINKS_POST_NAVSTORIES entries
            site.config['NAVIGATION_LINKS'].values[
                lang] = old_entries + new_entries + nav_conf_lang[
                    'NAVIGATION_LINKS_POST_NAVSTORIES']
        super(NavStories, self).set_site(site)
Exemplo n.º 15
0
    def set_site(self, site):
        """
        Map navstories config to nav_config[*] as TranslatableSettings
        """

        # Read NAVSTORIES_SUBMENU_INDENTION and store in self.navstories_submenu_indention
        if 'NAVSTORIES_SUBMENU_INDENTION' in site.config:
            self.navstories_submenu_indention = site.config['NAVSTORIES_SUBMENU_INDENTION']

        nav_config = {}
        for i in self.conf_vars:
            # Read config variables in a try...except in case a variable is missing
            try:
                nav_config[i] = utils.TranslatableSetting(i, site.config[i], site.config['TRANSLATIONS'])
            except KeyError:
                # Initialize to "empty" in case config variable i is missing
                nav_config[i] = utils.TranslatableSetting(i, self.conf_defaults[i](), site.config['TRANSLATIONS'])

        site.scan_posts()
        # NAVIGATION_LINKS is a TranslatableSetting, values is an actual dict
        for lang in site.config['NAVIGATION_LINKS'].values:
            # navstories config for lang
            nav_conf_lang = {}
            for i in self.conf_vars:
                nav_conf_lang[i] = nav_config[i](lang)

            # Which paths are navstories active for current lang? - Must start and end with /
            paths = tuple(('/' + s.strip('/') + '/') for s in nav_conf_lang['NAVSTORIES_PATHS'])

            # Unsorted (raw) new entries, deleted as mapped to new
            new_raw = {}
            # Sorted entries as a list of top-level menu entries, later
            new = []
            # Map site pages to new_raw structure
            for p in site.pages:
                # Generate navpath (menu) based on permalink without language prefix
                # If TRANSLATION[DEFAULT_LANG] = '', then "permalink_nolang = p.permalink()" is ok
                permalink_nolang = re.sub(r'^/' + nav_conf_lang['TRANSLATIONS'].lstrip('./') + '/?', '/', p.permalink(lang))
                s_candidates = [s for s in paths if permalink_nolang.startswith(s)]
                if not s_candidates:
                    continue
                # get longest path
                s = max(s_candidates, key=len)
                # Strip off the longest path in paths
                navpath = permalink_nolang[len(s):].strip('/').split('/')
                if len(navpath) == 0:
                    # Should not happen that navpath is empty, but to prevent errors, and inform via a warning
                    LOGGER.warn("Page with permalink: '%s', title: '%s', not added to menu by navstories." % (p.permalink(lang), p.title(lang)))
                    continue
                if lang in p.translated_to and not p.meta('hidefromnav'):
                    # Add entry
                    if not navpath[0] in new_raw:
                        new_raw[navpath[0]] = []
                    new_raw[navpath[0]].append(self.NavNode(navpath, p.permalink(lang), p.title(lang)))

            # Map from new_raw to new, sorting by NAVSTORIES_MAPPING
            for map_key, map_txt in nav_conf_lang['NAVSTORIES_MAPPING']:
                # Loop over all new_raw entries, checking if it matches map_key; if match: add it and delete from new_raw
                if map_key in new_raw:
                    new.append([map_txt, new_raw[map_key]])
                    del(new_raw[map_key])
            # Add remaing new_raw entries which didn't match any map_key
            new.extend([[None, new_raw[_]] for _ in sorted(new_raw)])

            # Map to tuple
            new_entries = self.map_to_menu(new)
            old_entries = site.config['NAVIGATION_LINKS'](lang)
            # Update NAVIGATION_LINKS with navstories dynamically generated entries and NAVIGATION_LINKS_POST_NAVSTORIES entries
            site.config['NAVIGATION_LINKS'].values[lang] = old_entries + new_entries + nav_conf_lang['NAVIGATION_LINKS_POST_NAVSTORIES']
        super(NavStories, self).set_site(site)