Exemplo n.º 1
0
        def chandler(default, toconf):
            print(
                "You can configure comments now.  Type '?' (a question mark, sans quotes) to list available comment systems.  If you do not want any comments, just leave the field blank."
            )
            answer = ask("Comment system", "")
            while answer.strip() == "?":
                print("\n# Available comment systems:")
                print(SAMPLE_CONF["_SUPPORTED_COMMENT_SYSTEMS"])
                print("")
                answer = ask("Comment system", "")

            while answer and answer not in LEGAL_VALUES["COMMENT_SYSTEM"]:
                if answer != "?":
                    print("    ERROR: Nikola does not know this comment system.")
                print("\n# Available comment systems:")
                print(SAMPLE_CONF["_SUPPORTED_COMMENT_SYSTEMS"])
                print("")
                answer = ask("Comment system", "")

            SAMPLE_CONF["COMMENT_SYSTEM"] = answer
            SAMPLE_CONF["COMMENT_SYSTEM_ID"] = ""

            if answer:
                print(
                    "You need to provide the site identifier for your comment system.  Consult the Nikola manual for details on what the value should be.  (you can leave it empty and come back later)"
                )
                answer = ask("Comment system site identifier", "")
                SAMPLE_CONF["COMMENT_SYSTEM_ID"] = answer
Exemplo n.º 2
0
        def chandler(default, toconf):
            print(
                "You can configure comments now.  Type '?' (a question mark, sans quotes) to list available comment systems.  If you do not want any comments, just leave the field blank."
            )
            answer = ask('Comment system', '')
            while answer.strip() == '?':
                print('\n# Available comment systems:')
                print(SAMPLE_CONF['_SUPPORTED_COMMENT_SYSTEMS'])
                print('')
                answer = ask('Comment system', '')

            while answer and answer not in LEGAL_VALUES['COMMENT_SYSTEM']:
                if answer != '?':
                    print(
                        '    ERROR: Nikola does not know this comment system.')
                print('\n# Available comment systems:')
                print(SAMPLE_CONF['_SUPPORTED_COMMENT_SYSTEMS'])
                print('')
                answer = ask('Comment system', '')

            SAMPLE_CONF['COMMENT_SYSTEM'] = answer
            SAMPLE_CONF['COMMENT_SYSTEM_ID'] = ''

            if answer:
                print(
                    "You need to provide the site identifier for your comment system.  Consult the Nikola manual for details on what the value should be.  (you can leave it empty and come back later)"
                )
                answer = ask('Comment system site identifier', '')
                SAMPLE_CONF['COMMENT_SYSTEM_ID'] = answer
Exemplo n.º 3
0
        def lhandler(default, toconf, show_header=True):
            if show_header:
                print("We will now ask you to provide the list of languages you want to use.")
                print(
                    "Please list all the desired languages, comma-separated, using ISO 639-1 codes.  The first language will be used as the default."
                )
                print("Type '?' (a question mark, sans quotes) to list available languages.")
            answer = ask("Language(s) to use", "en")
            while answer.strip() == "?":
                print("\n# Available languages:")
                try:
                    print(SAMPLE_CONF["_SUPPORTED_LANGUAGES"] + "\n")
                except UnicodeEncodeError:
                    # avoid Unicode characters in supported language names
                    print(unidecode.unidecode(SAMPLE_CONF["_SUPPORTED_LANGUAGES"]) + "\n")
                answer = ask("Language(s) to use", "en")

            langs = [i.strip().lower().replace("-", "_") for i in answer.split(",")]
            for partial, full in LEGAL_VALUES["_TRANSLATIONS_WITH_COUNTRY_SPECIFIERS"].items():
                if partial in langs:
                    langs[langs.index(partial)] = full
                    print("NOTICE: Assuming '{0}' instead of '{1}'.".format(full, partial))

            default = langs.pop(0)
            SAMPLE_CONF["DEFAULT_LANG"] = default
            # format_default_translations_config() is intelligent enough to
            # return the current value if there are no additional languages.
            SAMPLE_CONF["TRANSLATIONS"] = format_default_translations_config(langs)

            # Get messages for navigation_links.  In order to do this, we need
            # to generate a throwaway TRANSLATIONS dict.
            tr = {default: ""}
            for l in langs:
                tr[l] = "./" + l
            # Assuming that base contains all the locales, and that base does
            # not inherit from anywhere.
            try:
                messages = load_messages(["base"], tr, default)
                SAMPLE_CONF["NAVIGATION_LINKS"] = format_navigation_links(
                    langs, default, messages, SAMPLE_CONF["STRIP_INDEXES"]
                )
            except nikola.utils.LanguageNotFoundError as e:
                print("    ERROR: the language '{0}' is not supported.".format(e.lang))
                print(
                    "    Are you sure you spelled the name correctly?  Names are case-sensitive and need to be reproduced as-is (complete with the country specifier, if any)."
                )
                print("\nType '?' (a question mark, sans quotes) to list available languages.")
                lhandler(default, toconf, show_header=False)
Exemplo n.º 4
0
        def tzhandler(default, toconf):
            print("\nPlease choose the correct time zone for your blog. Nikola uses the tz database.")
            print("You can find your time zone here:")
            print("https://en.wikipedia.org/wiki/List_of_tz_database_time_zones")
            print("")
            answered = False
            while not answered:
                try:
                    lz = get_localzone()
                except:
                    lz = None
                answer = ask("Time zone", lz if lz else "UTC")
                tz = dateutil.tz.gettz(answer)

                if tz is None:
                    print("    WARNING: Time zone not found.  Searching list of time zones for a match.")
                    zonesfile = tarfile.open(fileobj=dateutil.zoneinfo.getzoneinfofile_stream())
                    zonenames = [zone for zone in zonesfile.getnames() if answer.lower() in zone.lower()]
                    if len(zonenames) == 1:
                        tz = dateutil.tz.gettz(zonenames[0])
                        answer = zonenames[0]
                        print("    Picking '{0}'.".format(answer))
                    elif len(zonenames) > 1:
                        print("    The following time zones match your query:")
                        print("        " + "\n        ".join(zonenames))
                        continue

                if tz is not None:
                    time = datetime.datetime.now(tz).strftime("%H:%M:%S")
                    print("    Current time in {0}: {1}".format(answer, time))
                    answered = ask_yesno("Use this time zone?", True)
                else:
                    print("    ERROR: No matches found.  Please try again.")

            SAMPLE_CONF["TIMEZONE"] = answer
Exemplo n.º 5
0
        def urlhandler(default, toconf):
            answer = ask("Site URL", "https://example.com/")
            try:
                answer = answer.decode("utf-8")
            except (AttributeError, UnicodeDecodeError):
                pass
            if not answer.startswith("http"):
                print("    ERROR: You must specify a protocol (http or https).")
                urlhandler(default, toconf)
                return
            if not answer.endswith("/"):
                print("    The URL does not end in '/' -- adding it.")
                answer += "/"

            dst_url = urlsplit(answer)
            try:
                dst_url.netloc.encode("ascii")
            except (UnicodeEncodeError, UnicodeDecodeError):
                # The IDN contains characters beyond ASCII.  We must convert it
                # to Punycode. (Issue #1644)
                nl = dst_url.netloc.encode("idna")
                answer = urlunsplit((dst_url.scheme, nl, dst_url.path, dst_url.query, dst_url.fragment))
                print("    Converting to Punycode:", answer)

            SAMPLE_CONF["SITE_URL"] = answer
Exemplo n.º 6
0
        def urlhandler(default, toconf):
            answer = ask('Site URL', 'https://example.com/')
            try:
                answer = answer.decode('utf-8')
            except (AttributeError, UnicodeDecodeError):
                pass
            if not answer.startswith(u'http'):
                print(
                    "    ERROR: You must specify a protocol (http or https).")
                urlhandler(default, toconf)
                return
            if not answer.endswith('/'):
                print("    The URL does not end in '/' -- adding it.")
                answer += '/'

            dst_url = urlsplit(answer)
            try:
                dst_url.netloc.encode('ascii')
            except (UnicodeEncodeError, UnicodeDecodeError):
                # The IDN contains characters beyond ASCII.  We must convert it
                # to Punycode. (Issue #1644)
                nl = dst_url.netloc.encode('idna')
                answer = urlunsplit((dst_url.scheme, nl, dst_url.path,
                                     dst_url.query, dst_url.fragment))
                print("    Converting to Punycode:", answer)

            SAMPLE_CONF['SITE_URL'] = answer
Exemplo n.º 7
0
        def tzhandler(default, toconf):
            print("\nPlease choose the correct time zone for your blog. Nikola uses the tz database.")
            print("You can find your time zone here:")
            print("https://en.wikipedia.org/wiki/List_of_tz_database_time_zones")
            print("")
            answered = False
            while not answered:
                try:
                    lz = get_localzone()
                except:
                    lz = None
                answer = ask('Time zone', lz if lz else "UTC")
                tz = dateutil.tz.gettz(answer)

                if tz is None:
                    print("    WARNING: Time zone not found.  Searching list of time zones for a match.")
                    zonesfile = tarfile.open(fileobj=dateutil.zoneinfo.getzoneinfofile_stream())
                    zonenames = [zone for zone in zonesfile.getnames() if answer.lower() in zone.lower()]
                    if len(zonenames) == 1:
                        tz = dateutil.tz.gettz(zonenames[0])
                        answer = zonenames[0]
                        print("    Picking '{0}'.".format(answer))
                    elif len(zonenames) > 1:
                        print("    The following time zones match your query:")
                        print('        ' + '\n        '.join(zonenames))
                        continue

                if tz is not None:
                    time = datetime.datetime.now(tz).strftime('%H:%M:%S')
                    print("    Current time in {0}: {1}".format(answer, time))
                    answered = ask_yesno("Use this time zone?", True)
                else:
                    print("    ERROR: No matches found.  Please try again.")

            SAMPLE_CONF['TIMEZONE'] = answer
Exemplo n.º 8
0
        def tzhandler(default, toconf):
            print("\nPlease choose the correct time zone for your blog. Nikola uses the tz database.")
            print("You can find your time zone here:")
            print("http://en.wikipedia.org/wiki/List_of_tz_database_time_zones")
            print("")
            answered = False
            while not answered:
                try:
                    lz = get_localzone()
                except:
                    lz = None
                answer = ask('Time zone', lz if lz else "UTC")
                tz = dateutil.tz.gettz(answer)

                if tz is None:
                    print("    WARNING: Time zone not found.  Searching most common timezones for a match.")
                    zonesfile = tarfile.TarFile.open(os.path.join(dateutil.zoneinfo.ZONEINFOFILE))
                    zonenames = [zone for zone in zonesfile.getnames() if answer.lower() in zone.lower()]
                    if len(zonenames) == 1:
                        tz = dateutil.tz.gettz(zonenames[0])
                    elif len(zonenames) > 1:
                        print("    Could not pick one timezone. Choose one of the following:")
                        print('        ' + '\n        '.join(zonenames))
                        continue

                if tz is not None:
                    time = datetime.datetime.now(tz).strftime('%H:%M:%S')
                    print("    Current time in {0}: {1}".format(answer, time))
                    answered = ask_yesno("Use this time zone?", True)
                else:
                    print("    ERROR: Time zone not found.  Please try again.  Time zones are case-sensitive.")

            SAMPLE_CONF['TIMEZONE'] = answer
Exemplo n.º 9
0
        def tzhandler(default, toconf):
            print(
                "\nPlease choose the correct time zone for your blog. Nikola uses the tz database."
            )
            print("You can find your time zone here:")
            print(
                "http://en.wikipedia.org/wiki/List_of_tz_database_time_zones")
            print("")
            answered = False
            while not answered:
                try:
                    lz = get_localzone()
                except:
                    lz = None
                answer = ask('Time zone', lz if lz else "UTC")
                tz = dateutil.tz.gettz(answer)
                if tz is not None:
                    time = datetime.datetime.now(tz).strftime('%H:%M:%S')
                    print("    Current time in {0}: {1}".format(answer, time))
                    answered = ask_yesno("Use this time zone?", True)
                else:
                    print(
                        "    ERROR: Time zone not found.  Please try again.  Time zones are case-sensitive."
                    )

            SAMPLE_CONF['TIMEZONE'] = answer
Exemplo n.º 10
0
        def lhandler(default, toconf, show_header=True):
            if show_header:
                print("We will now ask you to provide the list of languages you want to use.")
                print("Please list all the desired languages, comma-separated, using ISO 639-1 codes.  The first language will be used as the default.")
                print("Type '?' (a question mark, sans quotes) to list available languages.")
            answer = ask('Language(s) to use', 'en')
            while answer.strip() == '?':
                print('\n# Available languages:')
                try:
                    print(SAMPLE_CONF['_SUPPORTED_LANGUAGES'] + '\n')
                except UnicodeEncodeError:
                    # avoid Unicode characters in supported language names
                    print(unidecode.unidecode(SAMPLE_CONF['_SUPPORTED_LANGUAGES']) + '\n')
                answer = ask('Language(s) to use', 'en')

            langs = [i.strip().lower().replace('-', '_') for i in answer.split(',')]
            for partial, full in LEGAL_VALUES['_TRANSLATIONS_WITH_COUNTRY_SPECIFIERS'].items():
                if partial in langs:
                    langs[langs.index(partial)] = full
                    print("NOTICE: Assuming '{0}' instead of '{1}'.".format(full, partial))

            default = langs.pop(0)
            SAMPLE_CONF['DEFAULT_LANG'] = default
            # format_default_translations_config() is intelligent enough to
            # return the current value if there are no additional languages.
            SAMPLE_CONF['TRANSLATIONS'] = format_default_translations_config(langs)

            # Get messages for navigation_links.  In order to do this, we need
            # to generate a throwaway TRANSLATIONS dict.
            tr = {default: ''}
            for l in langs:
                tr[l] = './' + l
            # Assuming that base contains all the locales, and that base does
            # not inherit from anywhere.
            try:
                messages = load_messages(['base'], tr, default)
                SAMPLE_CONF['NAVIGATION_LINKS'] = format_navigation_links(langs, default, messages, SAMPLE_CONF['STRIP_INDEXES'])
            except nikola.utils.LanguageNotFoundError as e:
                print("    ERROR: the language '{0}' is not supported.".format(e.lang))
                print("    Are you sure you spelled the name correctly?  Names are case-sensitive and need to be reproduced as-is (complete with the country specifier, if any).")
                print("\nType '?' (a question mark, sans quotes) to list available languages.")
                lhandler(default, toconf, show_header=False)
Exemplo n.º 11
0
        def tzhandler(default, toconf):
            print(
                "\nPlease choose the correct time zone for your blog. Nikola uses the tz database."
            )
            print("You can find your time zone here:")
            print(
                "http://en.wikipedia.org/wiki/List_of_tz_database_time_zones")
            print("")
            answered = False
            while not answered:
                try:
                    lz = get_localzone()
                except:
                    lz = None
                answer = ask('Time zone', lz if lz else "UTC")
                tz = dateutil.tz.gettz(answer)

                if tz is None:
                    print(
                        "    WARNING: Time zone not found.  Searching most common timezones for a match."
                    )
                    zonesfile = tarfile.TarFile.open(
                        os.path.join(dateutil.zoneinfo.ZONEINFOFILE))
                    zonenames = [
                        zone for zone in zonesfile.getnames()
                        if answer.lower() in zone.lower()
                    ]
                    if len(zonenames) == 1:
                        tz = dateutil.tz.gettz(zonenames[0])
                    elif len(zonenames) > 1:
                        print(
                            "    Could not pick one timezone. Choose one of the following:"
                        )
                        print('        ' + '\n        '.join(zonenames))
                        continue

                if tz is not None:
                    time = datetime.datetime.now(tz).strftime('%H:%M:%S')
                    print("    Current time in {0}: {1}".format(answer, time))
                    answered = ask_yesno("Use this time zone?", True)
                else:
                    print(
                        "    ERROR: Time zone not found.  Please try again.  Time zones are case-sensitive."
                    )

            SAMPLE_CONF['TIMEZONE'] = answer
Exemplo n.º 12
0
Arquivo: init.py Projeto: rghv/nikola
        def tzhandler(default, toconf):
            print("\nPlease choose the correct time zone for your blog.  Nikola uses the tz database.")
            print("You can find your time zone here:")
            print("http://en.wikipedia.org/wiki/List_of_tz_database_time_zones")
            print("")
            answered = False
            while not answered:
                answer = ask("Time zone", "UTC")
                tz = dateutil.tz.gettz(answer)
                if tz is not None:
                    time = datetime.datetime.now(tz).strftime("%H:%M:%S")
                    print("    Current time in {0}: {1}".format(answer, time))
                    answered = ask_yesno("Use this time zone?", True)
                else:
                    print("    ERROR: Time zone not found.  Please try again.  Time zones are case-sensitive.")

            SAMPLE_CONF["TIMEZONE"] = answer
Exemplo n.º 13
0
Arquivo: init.py Projeto: rghv/nikola
    def ask_questions(target):
        """Ask some questions about Nikola."""

        def lhandler(default, toconf, show_header=True):
            if show_header:
                print("We will now ask you to provide the list of languages you want to use.")
                print(
                    "Please list all the desired languages, comma-separated, using ISO 639-1 codes.  The first language will be used as the default."
                )
                print("Type '?' (a question mark, sans quotes) to list available languages.")
            answer = ask("Language(s) to use", "en")
            while answer.strip() == "?":
                print("\n# Available languages:")
                print(SAMPLE_CONF["_SUPPORTED_LANGUAGES"] + "\n")
                answer = ask("Language(s) to use", "en")

            langs = [i.strip().lower().replace("-", "_") for i in answer.split(",")]
            for partial, full in LEGAL_VALUES["_TRANSLATIONS_WITH_COUNTRY_SPECIFIERS"].items():
                if partial in langs:
                    langs[langs.index(partial)] = full
                    print("NOTICE: Assuming '{0}' instead of '{1}'.".format(full, partial))

            default = langs.pop(0)
            SAMPLE_CONF["DEFAULT_LANG"] = default
            # format_default_translations_config() is intelligent enough to
            # return the current value if there are no additional languages.
            SAMPLE_CONF["TRANSLATIONS"] = format_default_translations_config(langs)

            # Get messages for navigation_links.  In order to do this, we need
            # to generate a throwaway TRANSLATIONS dict.
            tr = {default: ""}
            for l in langs:
                tr[l] = "./" + l
            # Assuming that base contains all the locales, and that base does
            # not inherit from anywhere.
            try:
                messages = load_messages(["base"], tr, default)
                SAMPLE_CONF["NAVIGATION_LINKS"] = format_navigation_links(langs, default, messages)
            except nikola.utils.LanguageNotFoundError as e:
                print("    ERROR: the language '{0}' is not supported.".format(e.lang))
                print(
                    "    Are you sure you spelled the name correctly?  Names are case-sensitive and need to be reproduced as-is (complete with the country specifier, if any)."
                )
                print("\nType '?' (a question mark, sans quotes) to list available languages.")
                lhandler(default, toconf, show_header=False)

        def tzhandler(default, toconf):
            print("\nPlease choose the correct time zone for your blog.  Nikola uses the tz database.")
            print("You can find your time zone here:")
            print("http://en.wikipedia.org/wiki/List_of_tz_database_time_zones")
            print("")
            answered = False
            while not answered:
                answer = ask("Time zone", "UTC")
                tz = dateutil.tz.gettz(answer)
                if tz is not None:
                    time = datetime.datetime.now(tz).strftime("%H:%M:%S")
                    print("    Current time in {0}: {1}".format(answer, time))
                    answered = ask_yesno("Use this time zone?", True)
                else:
                    print("    ERROR: Time zone not found.  Please try again.  Time zones are case-sensitive.")

            SAMPLE_CONF["TIMEZONE"] = answer

        def chandler(default, toconf):
            print(
                "You can configure comments now.  Type '?' (a question mark, sans quotes) to list available comment systems.  If you do not want any comments, just leave the field blank."
            )
            answer = ask("Comment system", "")
            while answer.strip() == "?":
                print("\n# Available comment systems:")
                print(SAMPLE_CONF["_SUPPORTED_COMMENT_SYSTEMS"])
                print("")
                answer = ask("Comment system", "")

            while answer and answer not in LEGAL_VALUES["COMMENT_SYSTEM"]:
                if answer != "?":
                    print("    ERROR: Nikola does not know this comment system.")
                print("\n# Available comment systems:")
                print(SAMPLE_CONF["_SUPPORTED_COMMENT_SYSTEMS"])
                print("")
                answer = ask("Comment system", "")

            SAMPLE_CONF["COMMENT_SYSTEM"] = answer
            SAMPLE_CONF["COMMENT_SYSTEM_ID"] = ""

            if answer:
                print(
                    "You need to provide the site identifier for your comment system.  Consult the Nikola manual for details on what the value should be.  (you can leave it empty and come back later)"
                )
                answer = ask("Comment system site identifier", "")
                SAMPLE_CONF["COMMENT_SYSTEM_ID"] = answer

        STORAGE = {"target": target}

        questions = [
            ("Questions about the site", None, None, None),
            # query, default, toconf, destination
            ("Destination", None, False, "!target"),
            ("Site title", "My Nikola Site", True, "BLOG_TITLE"),
            ("Site author", "Nikola Tesla", True, "BLOG_AUTHOR"),
            ("Site author’s e-mail", "*****@*****.**", True, "BLOG_EMAIL"),
            ("Site description", "This is a demo site for Nikola.", True, "BLOG_DESCRIPTION"),
            ("Site URL", "http://getnikola.com/", True, "SITE_URL"),
            ("Questions about languages and locales", None, None, None),
            (lhandler, None, True, True),
            (tzhandler, None, True, True),
            ("Questions about comments", None, None, None),
            (chandler, None, True, True),
        ]

        print("Creating Nikola Site")
        print("====================\n")
        print(
            "This is Nikola v{0}.  We will now ask you a few easy questions about your new site.".format(
                nikola.__version__
            )
        )
        print(
            "If you do not want to answer and want to go with the defaults instead, simply restart with the `-q` parameter."
        )

        for query, default, toconf, destination in questions:
            if target and destination == "!target":
                # Skip the destination question if we know it already
                pass
            else:
                if default is toconf is destination is None:
                    print("--- {0} ---".format(query))
                elif destination is True:
                    query(default, toconf)
                else:
                    answer = ask(query, default)
                    if toconf:
                        SAMPLE_CONF[destination] = answer
                    if destination == "!target":
                        while not answer:
                            print("    ERROR: you need to specify a target directory.\n")
                            answer = ask(query, default)
                        STORAGE["target"] = answer

        print("\nThat's it, Nikola is now configured.  Make sure to edit conf.py to your liking.")
        print(
            "If you are looking for themes and addons, check out http://themes.getnikola.com/ and http://plugins.getnikola.com/."
        )
        print("Have fun!")
        return STORAGE
Exemplo n.º 14
0
    def _execute(self, options, args):
        """Create a new post or page."""
        global LOGGER
        compiler_names = [
            p.name for p in self.site.plugin_manager.getPluginsOfCategory(
                "PageCompiler")
        ]

        if len(args) > 1:
            print(self.help())
            return False
        elif args:
            path = args[0]
        else:
            path = None

        # Even though stuff was split into `new_page`, it’s easier to do it
        # here not to duplicate the code.
        is_page = options.get('is_page', False)
        is_post = not is_page
        content_type = 'page' if is_page else 'post'
        title = options['title'] or None
        author = options['author'] or ''
        tags = options['tags']
        onefile = options['onefile']
        twofile = options['twofile']
        import_file = options['import']
        wants_available = options['available-formats']
        date_path_opt = options['date-path']
        date_path_auto = self.site.config[
            'NEW_POST_DATE_PATH'] and content_type == 'post'
        date_path_format = self.site.config['NEW_POST_DATE_PATH_FORMAT'].strip(
            '/')

        if wants_available:
            self.print_compilers()
            return

        if is_page:
            LOGGER = PAGELOGGER
        else:
            LOGGER = POSTLOGGER

        if twofile:
            onefile = False
        if not onefile and not twofile:
            onefile = self.site.config.get('ONE_FILE_POSTS', True)

        content_format = options['content_format']
        content_subformat = None

        if "@" in content_format:
            content_format, content_subformat = content_format.split("@")

        if not content_format and path and not os.path.isdir(path):
            # content_format not specified. If path was given, use
            # it to guess (Issue #2798)
            extension = os.path.splitext(path)[-1]
            for compiler, extensions in self.site.config['COMPILERS'].items():
                if extension in extensions:
                    content_format = compiler
            if not content_format:
                LOGGER.error(
                    "Unknown {0} extension {1}, maybe you need to install a plugin or enable an existing one?"
                    .format(content_type, extension))
                return

        elif not content_format and import_file:
            # content_format not specified. If import_file was given, use
            # it to guess (Issue #2798)
            extension = os.path.splitext(import_file)[-1]
            for compiler, extensions in self.site.config['COMPILERS'].items():
                if extension in extensions:
                    content_format = compiler
            if not content_format:
                LOGGER.error(
                    "Unknown {0} extension {1}, maybe you need to install a plugin or enable an existing one?"
                    .format(content_type, extension))
                return

        elif not content_format:  # Issue #400
            content_format = get_default_compiler(
                is_post, self.site.config['COMPILERS'],
                self.site.config['post_pages'])

        elif content_format not in compiler_names:
            LOGGER.error(
                "Unknown {0} format {1}, maybe you need to install a plugin or enable an existing one?"
                .format(content_type, content_format))
            self.print_compilers()
            return

        compiler_plugin = self.site.plugin_manager.getPluginByName(
            content_format, "PageCompiler").plugin_object

        # Guess where we should put this
        entry = self.filter_post_pages(content_format, is_post)

        if entry is False:
            return 1

        if import_file:
            print("Importing Existing {xx}".format(xx=content_type.title()))
            print("-----------------------\n")
        else:
            print("Creating New {xx}".format(xx=content_type.title()))
            print("-----------------\n")
        if title is not None:
            print("Title:", title)
        else:
            while not title:
                title = utils.ask('Title')

        if isinstance(title, utils.bytes_str):
            try:
                title = title.decode(sys.stdin.encoding)
            except (AttributeError, TypeError):  # for tests
                title = title.decode('utf-8')

        title = title.strip()
        if not path:
            slug = utils.slugify(title, lang=self.site.default_lang)
        else:
            if isinstance(path, utils.bytes_str):
                try:
                    path = path.decode(sys.stdin.encoding)
                except (AttributeError, TypeError):  # for tests
                    path = path.decode('utf-8')
            if os.path.isdir(path):
                # If the user provides a directory, add the file name generated from title (Issue #2651)
                slug = utils.slugify(title, lang=self.site.default_lang)
                pattern = os.path.basename(entry[0])
                suffix = pattern[1:]
                path = os.path.join(path, slug + suffix)
            else:
                slug = utils.slugify(os.path.splitext(
                    os.path.basename(path))[0],
                                     lang=self.site.default_lang)

        if isinstance(author, utils.bytes_str):
            try:
                author = author.decode(sys.stdin.encoding)
            except (AttributeError, TypeError):  # for tests
                author = author.decode('utf-8')

        # Calculate the date to use for the content
        # SCHEDULE_ALL is post-only (Issue #2921)
        schedule = options['schedule'] or (self.site.config['SCHEDULE_ALL']
                                           and is_post)
        rule = self.site.config['SCHEDULE_RULE']
        self.site.scan_posts()
        timeline = self.site.timeline
        last_date = None if not timeline else timeline[0].date
        date, dateobj = get_date(schedule, rule, last_date, self.site.tzinfo,
                                 self.site.config['FORCE_ISO8601'])
        data = {
            'title': title,
            'slug': slug,
            'date': date,
            'tags': tags,
            'link': '',
            'description': '',
            'type': 'text',
        }

        if not path:
            pattern = os.path.basename(entry[0])
            suffix = pattern[1:]
            output_path = os.path.dirname(entry[0])
            if date_path_auto or date_path_opt:
                output_path += os.sep + dateobj.strftime(date_path_format)

            txt_path = os.path.join(output_path, slug + suffix)
            meta_path = os.path.join(output_path, slug + ".meta")
        else:
            if date_path_opt:
                LOGGER.warning("A path has been specified, ignoring -d")
            txt_path = os.path.join(self.site.original_cwd, path)
            meta_path = os.path.splitext(txt_path)[0] + ".meta"

        if (not onefile and os.path.isfile(meta_path)) or \
                os.path.isfile(txt_path):

            # Emit an event when a post exists
            event = dict(path=txt_path)
            if not onefile:  # write metadata file
                event['meta_path'] = meta_path
            signal('existing_' + content_type).send(self, **event)

            LOGGER.error("The title already exists!")
            LOGGER.info("Existing {0}'s text is at: {1}".format(
                content_type, txt_path))
            if not onefile:
                LOGGER.info("Existing {0}'s metadata is at: {1}".format(
                    content_type, meta_path))
            return 8

        d_name = os.path.dirname(txt_path)
        utils.makedirs(d_name)
        metadata = {}
        if author:
            metadata['author'] = author
        metadata.update(self.site.config['ADDITIONAL_METADATA'])
        data.update(metadata)

        # ipynb plugin needs the Jupyter kernel info. We get the kernel name
        # from the content_subformat and pass it to the compiler in the metadata
        if content_format == "ipynb" and content_subformat is not None:
            metadata["jupyter_kernel"] = content_subformat

        # Override onefile if not really supported.
        if not compiler_plugin.supports_onefile and onefile:
            onefile = False
            LOGGER.warning('This compiler does not support one-file posts.')

        if onefile and import_file:
            with io.open(import_file, 'r', encoding='utf-8') as fh:
                content = fh.read()
        elif not import_file:
            if is_page:
                content = self.site.MESSAGES[
                    self.site.default_lang]["Write your page here."]
            else:
                content = self.site.MESSAGES[
                    self.site.default_lang]["Write your post here."]

        if (not onefile) and import_file:
            # Two-file posts are copied  on import (Issue #2380)
            shutil.copy(import_file, txt_path)
        else:
            compiler_plugin.create_post(txt_path,
                                        content=content,
                                        onefile=onefile,
                                        title=title,
                                        slug=slug,
                                        date=date,
                                        tags=tags,
                                        is_page=is_page,
                                        **metadata)

        event = dict(path=txt_path)

        if not onefile:  # write metadata file
            with io.open(meta_path, "w+", encoding="utf8") as fd:
                fd.write(
                    utils.write_metadata(data,
                                         comment_wrap=False,
                                         site=self.site))
            LOGGER.info("Your {0}'s metadata is at: {1}".format(
                content_type, meta_path))
            event['meta_path'] = meta_path
        LOGGER.info("Your {0}'s text is at: {1}".format(
            content_type, txt_path))

        signal('new_' + content_type).send(self, **event)

        if options['edit']:
            editor = os.getenv('EDITOR', '').split()
            to_run = editor + [txt_path]
            if not onefile:
                to_run.append(meta_path)
            if editor:
                subprocess.call(to_run)
            else:
                LOGGER.error(
                    'The $EDITOR environment variable is not set, cannot edit the post with \'-e\'.  Please edit the post manually.'
                )
Exemplo n.º 15
0
    def _execute(self, options, args):
        """Create a new post or page."""
        global LOGGER
        compiler_names = [p.name for p in
                          self.site.plugin_manager.getPluginsOfCategory(
                              "PageCompiler")]

        if len(args) > 1:
            print(self.help())
            return False
        elif args:
            path = args[0]
        else:
            path = None

        # Even though stuff was split into `new_page`, it’s easier to do it
        # here not to duplicate the code.
        is_page = options.get('is_page', False)
        is_post = not is_page
        content_type = 'page' if is_page else 'post'
        title = options['title'] or None
        author = options['author'] or ''
        tags = options['tags']
        onefile = options['onefile']
        twofile = options['twofile']
        import_file = options['import']
        wants_available = options['available-formats']
        date_path_opt = options['date-path']
        date_path_auto = self.site.config['NEW_POST_DATE_PATH']
        date_path_format = self.site.config['NEW_POST_DATE_PATH_FORMAT'].strip('/')

        if wants_available:
            self.print_compilers()
            return

        if is_page:
            LOGGER = PAGELOGGER
        else:
            LOGGER = POSTLOGGER

        if twofile:
            onefile = False
        if not onefile and not twofile:
            onefile = self.site.config.get('ONE_FILE_POSTS', True)

        content_format = options['content_format']
        content_subformat = None

        if "@" in content_format:
            content_format, content_subformat = content_format.split("@")

        if not content_format:  # Issue #400
            content_format = get_default_compiler(
                is_post,
                self.site.config['COMPILERS'],
                self.site.config['post_pages'])

        if content_format not in compiler_names:
            LOGGER.error("Unknown {0} format {1}, maybe you need to install a plugin or enable an existing one?".format(content_type, content_format))
            self.print_compilers()
            return
        compiler_plugin = self.site.plugin_manager.getPluginByName(
            content_format, "PageCompiler").plugin_object

        # Guess where we should put this
        entry = self.filter_post_pages(content_format, is_post)

        if entry is False:
            return 1

        if import_file:
            print("Importing Existing {xx}".format(xx=content_type.title()))
            print("-----------------------\n")
        else:
            print("Creating New {xx}".format(xx=content_type.title()))
            print("-----------------\n")
        if title is not None:
            print("Title:", title)
        else:
            while not title:
                title = utils.ask('Title')

        if isinstance(title, utils.bytes_str):
            try:
                title = title.decode(sys.stdin.encoding)
            except (AttributeError, TypeError):  # for tests
                title = title.decode('utf-8')

        title = title.strip()
        if not path:
            slug = utils.slugify(title, lang=self.site.default_lang)
        else:
            if isinstance(path, utils.bytes_str):
                try:
                    path = path.decode(sys.stdin.encoding)
                except (AttributeError, TypeError):  # for tests
                    path = path.decode('utf-8')
            slug = utils.slugify(os.path.splitext(os.path.basename(path))[0], lang=self.site.default_lang)

        if isinstance(author, utils.bytes_str):
                try:
                    author = author.decode(sys.stdin.encoding)
                except (AttributeError, TypeError):  # for tests
                    author = author.decode('utf-8')

        # Calculate the date to use for the content
        schedule = options['schedule'] or self.site.config['SCHEDULE_ALL']
        rule = self.site.config['SCHEDULE_RULE']
        self.site.scan_posts()
        timeline = self.site.timeline
        last_date = None if not timeline else timeline[0].date
        date, dateobj = get_date(schedule, rule, last_date, self.site.tzinfo, self.site.config['FORCE_ISO8601'])
        data = {
            'title': title,
            'slug': slug,
            'date': date,
            'tags': tags,
            'link': '',
            'description': '',
            'type': 'text',
        }

        if not path:
            pattern = os.path.basename(entry[0])
            suffix = pattern[1:]
            output_path = os.path.dirname(entry[0])
            if date_path_auto or date_path_opt:
                output_path += os.sep + dateobj.strftime(date_path_format)

            txt_path = os.path.join(output_path, slug + suffix)
            meta_path = os.path.join(output_path, slug + ".meta")
        else:
            if date_path_opt:
                LOGGER.warn("A path has been specified, ignoring -d")
            txt_path = os.path.join(self.site.original_cwd, path)
            meta_path = os.path.splitext(txt_path)[0] + ".meta"

        if (not onefile and os.path.isfile(meta_path)) or \
                os.path.isfile(txt_path):

            # Emit an event when a post exists
            event = dict(path=txt_path)
            if not onefile:  # write metadata file
                event['meta_path'] = meta_path
            signal('existing_' + content_type).send(self, **event)

            LOGGER.error("The title already exists!")
            LOGGER.info("Existing {0}'s text is at: {1}".format(content_type, txt_path))
            if not onefile:
                LOGGER.info("Existing {0}'s metadata is at: {1}".format(content_type, meta_path))
            return 8

        d_name = os.path.dirname(txt_path)
        utils.makedirs(d_name)
        metadata = {}
        if author:
            metadata['author'] = author
        metadata.update(self.site.config['ADDITIONAL_METADATA'])
        data.update(metadata)

        # ipynb plugin needs the ipython kernel info. We get the kernel name
        # from the content_subformat and pass it to the compiler in the metadata
        if content_format == "ipynb" and content_subformat is not None:
            metadata["ipython_kernel"] = content_subformat

        # Override onefile if not really supported.
        if not compiler_plugin.supports_onefile and onefile:
            onefile = False
            LOGGER.warn('This compiler does not support one-file posts.')

        if onefile and import_file:
            with io.open(import_file, 'r', encoding='utf-8') as fh:
                content = fh.read()
        elif not import_file:
            if is_page:
                content = self.site.MESSAGES[self.site.default_lang]["Write your page here."]
            else:
                content = self.site.MESSAGES[self.site.default_lang]["Write your post here."]

        if (not onefile) and import_file:
            # Two-file posts are copied  on import (Issue #2380)
            shutil.copy(import_file, txt_path)
        else:
            compiler_plugin.create_post(
                txt_path, content=content, onefile=onefile, title=title,
                slug=slug, date=date, tags=tags, is_page=is_page, **metadata)

        event = dict(path=txt_path)

        if not onefile:  # write metadata file
            with io.open(meta_path, "w+", encoding="utf8") as fd:
                fd.write(utils.write_metadata(data))
            LOGGER.info("Your {0}'s metadata is at: {1}".format(content_type, meta_path))
            event['meta_path'] = meta_path
        LOGGER.info("Your {0}'s text is at: {1}".format(content_type, txt_path))

        signal('new_' + content_type).send(self, **event)

        if options['edit']:
            editor = os.getenv('EDITOR', '').split()
            to_run = editor + [txt_path]
            if not onefile:
                to_run.append(meta_path)
            if editor:
                subprocess.call(to_run)
            else:
                LOGGER.error('$EDITOR not set, cannot edit the post.  Please do it manually.')
Exemplo n.º 16
0
    def _execute(self, options, args):
        """Create a new post or page."""
        global LOGGER
        compiler_names = [p.name for p in self.site.plugin_manager.getPluginsOfCategory("PageCompiler")]

        if len(args) > 1:
            print(self.help())
            return False
        elif args:
            path = args[0]
        else:
            path = None

        # Even though stuff was split into `new_page`, it’s easier to do it
        # here not to duplicate the code.
        is_page = options.get("is_page", False)
        is_post = not is_page
        content_type = "page" if is_page else "post"
        title = options["title"] or None
        author = options["author"] or ""
        tags = options["tags"]
        onefile = options["onefile"]
        twofile = options["twofile"]
        import_file = options["import"]
        wants_available = options["available-formats"]

        if wants_available:
            self.print_compilers()
            return

        if is_page:
            LOGGER = PAGELOGGER
        else:
            LOGGER = POSTLOGGER

        if twofile:
            onefile = False
        if not onefile and not twofile:
            onefile = self.site.config.get("ONE_FILE_POSTS", True)

        content_format = options["content_format"]
        content_subformat = None

        if "@" in content_format:
            content_format, content_subformat = content_format.split("@")

        if not content_format:  # Issue #400
            content_format = get_default_compiler(
                is_post, self.site.config["COMPILERS"], self.site.config["post_pages"]
            )

        if content_format not in compiler_names:
            LOGGER.error(
                "Unknown {0} format {1}, maybe you need to install a plugin?".format(content_type, content_format)
            )
            self.print_compilers()
            return
        compiler_plugin = self.site.plugin_manager.getPluginByName(content_format, "PageCompiler").plugin_object

        # Guess where we should put this
        entry = self.filter_post_pages(content_format, is_post)

        if entry is False:
            return 1

        if import_file:
            print("Importing Existing {xx}".format(xx=content_type.title()))
            print("-----------------------\n")
        else:
            print("Creating New {xx}".format(xx=content_type.title()))
            print("-----------------\n")
        if title is not None:
            print("Title:", title)
        else:
            while not title:
                title = utils.ask("Title")

        if isinstance(title, utils.bytes_str):
            try:
                title = title.decode(sys.stdin.encoding)
            except (AttributeError, TypeError):  # for tests
                title = title.decode("utf-8")

        title = title.strip()
        if not path:
            slug = utils.slugify(title)
        else:
            if isinstance(path, utils.bytes_str):
                try:
                    path = path.decode(sys.stdin.encoding)
                except (AttributeError, TypeError):  # for tests
                    path = path.decode("utf-8")
            slug = utils.slugify(os.path.splitext(os.path.basename(path))[0])

        if isinstance(author, utils.bytes_str):
            try:
                author = author.decode(sys.stdin.encoding)
            except (AttributeError, TypeError):  # for tests
                author = author.decode("utf-8")

        # Calculate the date to use for the content
        schedule = options["schedule"] or self.site.config["SCHEDULE_ALL"]
        rule = self.site.config["SCHEDULE_RULE"]
        self.site.scan_posts()
        timeline = self.site.timeline
        last_date = None if not timeline else timeline[0].date
        date = get_date(schedule, rule, last_date, self.site.tzinfo, self.site.config["FORCE_ISO8601"])
        data = {"title": title, "slug": slug, "date": date, "tags": tags, "link": "", "description": "", "type": "text"}
        output_path = os.path.dirname(entry[0])
        meta_path = os.path.join(output_path, slug + ".meta")
        pattern = os.path.basename(entry[0])
        suffix = pattern[1:]
        if not path:
            txt_path = os.path.join(output_path, slug + suffix)
        else:
            txt_path = os.path.join(self.site.original_cwd, path)

        if (not onefile and os.path.isfile(meta_path)) or os.path.isfile(txt_path):

            # Emit an event when a post exists
            event = dict(path=txt_path)
            if not onefile:  # write metadata file
                event["meta_path"] = meta_path
            signal("existing_" + content_type).send(self, **event)

            LOGGER.error("The title already exists!")
            return 8

        d_name = os.path.dirname(txt_path)
        utils.makedirs(d_name)
        metadata = {}
        if author:
            metadata["author"] = author
        metadata.update(self.site.config["ADDITIONAL_METADATA"])
        data.update(metadata)

        # ipynb plugin needs the ipython kernel info. We get the kernel name
        # from the content_subformat and pass it to the compiler in the metadata
        if content_format == "ipynb" and content_subformat is not None:
            metadata["ipython_kernel"] = content_subformat

        # Override onefile if not really supported.
        if not compiler_plugin.supports_onefile and onefile:
            onefile = False
            LOGGER.warn("This compiler does not support one-file posts.")

        if import_file:
            with io.open(import_file, "r", encoding="utf-8") as fh:
                content = fh.read()
        else:
            if is_page:
                content = self.site.MESSAGES[self.site.default_lang]["Write your page here."]
            else:
                content = self.site.MESSAGES[self.site.default_lang]["Write your post here."]
        compiler_plugin.create_post(
            txt_path,
            content=content,
            onefile=onefile,
            title=title,
            slug=slug,
            date=date,
            tags=tags,
            is_page=is_page,
            **metadata
        )

        event = dict(path=txt_path)

        if not onefile:  # write metadata file
            with io.open(meta_path, "w+", encoding="utf8") as fd:
                fd.write(utils.write_metadata(data))
            LOGGER.info("Your {0}'s metadata is at: {1}".format(content_type, meta_path))
            event["meta_path"] = meta_path
        LOGGER.info("Your {0}'s text is at: {1}".format(content_type, txt_path))

        signal("new_" + content_type).send(self, **event)

        if options["edit"]:
            editor = os.getenv("EDITOR", "").split()
            to_run = editor + [txt_path]
            if not onefile:
                to_run.append(meta_path)
            if editor:
                subprocess.call(to_run)
            else:
                LOGGER.error("$EDITOR not set, cannot edit the post.  Please do it manually.")
Exemplo n.º 17
0
    def _execute(self, options, args):
        """Create a new post or page."""
        global LOGGER
        compiler_names = [p.name for p in
                          self.site.plugin_manager.getPluginsOfCategory(
                              "PageCompiler")]

        if len(args) > 1:
            print(self.help())
            return False
        elif args:
            path = args[0]
        else:
            path = None

        # Even though stuff was split into `new_page`, it’s easier to do it
        # here not to duplicate the code.
        is_page = options.get('is_page', False)
        is_post = not is_page
        content_type = 'page' if is_page else 'post'
        title = options['title'] or None
        author = options['author'] or ''
        tags = options['tags']
        onefile = options['onefile']
        twofile = options['twofile']
        import_file = options['import']

        if is_page:
            LOGGER = PAGELOGGER
        else:
            LOGGER = POSTLOGGER

        if twofile:
            onefile = False
        if not onefile and not twofile:
            onefile = self.site.config.get('ONE_FILE_POSTS', True)

        content_format = options['content_format']

        if not content_format:  # Issue #400
            content_format = get_default_compiler(
                is_post,
                self.site.config['COMPILERS'],
                self.site.config['post_pages'])

        if content_format not in compiler_names:
            LOGGER.error("Unknown {0} format {1}".format(content_type, content_format))
            return
        compiler_plugin = self.site.plugin_manager.getPluginByName(
            content_format, "PageCompiler").plugin_object

        # Guess where we should put this
        entry = filter_post_pages(content_format, is_post,
                                  self.site.config['COMPILERS'],
                                  self.site.config['post_pages'])

        if import_file:
            print("Importing Existing {xx}".format(xx=content_type.title()))
            print("-----------------------\n")
        else:
            print("Creating New {xx}".format(xx=content_type.title()))
            print("-----------------\n")
        if title is not None:
            print("Title:", title)
        else:
            while not title:
                title = utils.ask('Title')

        if isinstance(title, utils.bytes_str):
            try:
                title = title.decode(sys.stdin.encoding)
            except (AttributeError, TypeError):  # for tests
                title = title.decode('utf-8')

        title = title.strip()
        if not path:
            slug = utils.slugify(title)
        else:
            if isinstance(path, utils.bytes_str):
                try:
                    path = path.decode(sys.stdin.encoding)
                except (AttributeError, TypeError):  # for tests
                    path = path.decode('utf-8')
            slug = utils.slugify(os.path.splitext(os.path.basename(path))[0])

        if isinstance(author, utils.bytes_str):
                try:
                    author = author.decode(sys.stdin.encoding)
                except (AttributeError, TypeError):  # for tests
                    author = author.decode('utf-8')

        # Calculate the date to use for the content
        schedule = options['schedule'] or self.site.config['SCHEDULE_ALL']
        rule = self.site.config['SCHEDULE_RULE']
        self.site.scan_posts()
        timeline = self.site.timeline
        last_date = None if not timeline else timeline[0].date
        date = get_date(schedule, rule, last_date, self.site.tzinfo, self.site.config['FORCE_ISO8601'])
        data = {
            'title': title,
            'slug': slug,
            'date': date,
            'tags': tags,
            'link': '',
            'description': '',
            'type': 'text',
        }
        output_path = os.path.dirname(entry[0])
        meta_path = os.path.join(output_path, slug + ".meta")
        pattern = os.path.basename(entry[0])
        suffix = pattern[1:]
        if not path:
            txt_path = os.path.join(output_path, slug + suffix)
        else:
            txt_path = path

        if (not onefile and os.path.isfile(meta_path)) or \
                os.path.isfile(txt_path):
            LOGGER.error("The title already exists!")
            exit(8)

        d_name = os.path.dirname(txt_path)
        utils.makedirs(d_name)
        metadata = {}
        if author:
            metadata['author'] = author
        metadata.update(self.site.config['ADDITIONAL_METADATA'])
        data.update(metadata)

        # Override onefile if not really supported.
        if not compiler_plugin.supports_onefile and onefile:
            onefile = False
            LOGGER.warn('This compiler does not support one-file posts.')

        if import_file:
            with io.open(import_file, 'r', encoding='utf-8') as fh:
                content = fh.read()
        else:
            # ipynb's create_post depends on this exact string, take care
            # if you're changing it
            content = "Write your {0} here.".format('page' if is_page else 'post')
        compiler_plugin.create_post(
            txt_path, content=content, onefile=onefile, title=title,
            slug=slug, date=date, tags=tags, is_page=is_page, **metadata)

        event = dict(path=txt_path)

        if not onefile:  # write metadata file
            with io.open(meta_path, "w+", encoding="utf8") as fd:
                fd.write(utils.write_metadata(data))
            LOGGER.info("Your {0}'s metadata is at: {1}".format(content_type, meta_path))
            event['meta_path'] = meta_path
        LOGGER.info("Your {0}'s text is at: {1}".format(content_type, txt_path))

        signal('new_' + content_type).send(self, **event)

        if options['edit']:
            editor = os.getenv('EDITOR', '').split()
            to_run = editor + [txt_path]
            if not onefile:
                to_run.append(meta_path)
            if editor:
                subprocess.call(to_run)
            else:
                LOGGER.error('$EDITOR not set, cannot edit the post.  Please do it manually.')
Exemplo n.º 18
0
    def ask_questions(target):
        """Ask some questions about Nikola."""
        def lhandler(default, toconf, show_header=True):
            if show_header:
                print("We will now ask you to provide the list of languages you want to use.")
                print("Please list all the desired languages, comma-separated, using ISO 639-1 codes.  The first language will be used as the default.")
                print("Type '?' (a question mark, sans quotes) to list available languages.")
            answer = ask('Language(s) to use', 'en')
            while answer.strip() == '?':
                print('\n# Available languages:')
                try:
                    print(SAMPLE_CONF['_SUPPORTED_LANGUAGES'] + '\n')
                except UnicodeEncodeError:
                    # avoid Unicode characters in supported language names
                    print(unidecode.unidecode(SAMPLE_CONF['_SUPPORTED_LANGUAGES']) + '\n')
                answer = ask('Language(s) to use', 'en')

            langs = [i.strip().lower().replace('-', '_') for i in answer.split(',')]
            for partial, full in LEGAL_VALUES['_TRANSLATIONS_WITH_COUNTRY_SPECIFIERS'].items():
                if partial in langs:
                    langs[langs.index(partial)] = full
                    print("NOTICE: Assuming '{0}' instead of '{1}'.".format(full, partial))

            default = langs.pop(0)
            SAMPLE_CONF['DEFAULT_LANG'] = default
            # format_default_translations_config() is intelligent enough to
            # return the current value if there are no additional languages.
            SAMPLE_CONF['TRANSLATIONS'] = format_default_translations_config(langs)

            # Get messages for navigation_links.  In order to do this, we need
            # to generate a throwaway TRANSLATIONS dict.
            tr = {default: ''}
            for l in langs:
                tr[l] = './' + l
            # Assuming that base contains all the locales, and that base does
            # not inherit from anywhere.
            try:
                messages = load_messages(['base'], tr, default)
                SAMPLE_CONF['NAVIGATION_LINKS'] = format_navigation_links(langs, default, messages)
            except nikola.utils.LanguageNotFoundError as e:
                print("    ERROR: the language '{0}' is not supported.".format(e.lang))
                print("    Are you sure you spelled the name correctly?  Names are case-sensitive and need to be reproduced as-is (complete with the country specifier, if any).")
                print("\nType '?' (a question mark, sans quotes) to list available languages.")
                lhandler(default, toconf, show_header=False)

        def tzhandler(default, toconf):
            print("\nPlease choose the correct time zone for your blog. Nikola uses the tz database.")
            print("You can find your time zone here:")
            print("http://en.wikipedia.org/wiki/List_of_tz_database_time_zones")
            print("")
            answered = False
            while not answered:
                try:
                    lz = get_localzone()
                except:
                    lz = None
                answer = ask('Time zone', lz if lz else "UTC")
                tz = dateutil.tz.gettz(answer)

                if tz is None:
                    print("    WARNING: Time zone not found.  Searching list of time zones for a match.")
                    zonesfile = tarfile.open(fileobj=dateutil.zoneinfo.getzoneinfofile_stream())
                    zonenames = [zone for zone in zonesfile.getnames() if answer.lower() in zone.lower()]
                    if len(zonenames) == 1:
                        tz = dateutil.tz.gettz(zonenames[0])
                        answer = zonenames[0]
                        print("    Picking '{0}'.".format(answer))
                    elif len(zonenames) > 1:
                        print("    The following time zones match your query:")
                        print('        ' + '\n        '.join(zonenames))
                        continue

                if tz is not None:
                    time = datetime.datetime.now(tz).strftime('%H:%M:%S')
                    print("    Current time in {0}: {1}".format(answer, time))
                    answered = ask_yesno("Use this time zone?", True)
                else:
                    print("    ERROR: No matches found.  Please try again.")

            SAMPLE_CONF['TIMEZONE'] = answer

        def chandler(default, toconf):
            print("You can configure comments now.  Type '?' (a question mark, sans quotes) to list available comment systems.  If you do not want any comments, just leave the field blank.")
            answer = ask('Comment system', '')
            while answer.strip() == '?':
                print('\n# Available comment systems:')
                print(SAMPLE_CONF['_SUPPORTED_COMMENT_SYSTEMS'])
                print('')
                answer = ask('Comment system', '')

            while answer and answer not in LEGAL_VALUES['COMMENT_SYSTEM']:
                if answer != '?':
                    print('    ERROR: Nikola does not know this comment system.')
                print('\n# Available comment systems:')
                print(SAMPLE_CONF['_SUPPORTED_COMMENT_SYSTEMS'])
                print('')
                answer = ask('Comment system', '')

            SAMPLE_CONF['COMMENT_SYSTEM'] = answer
            SAMPLE_CONF['COMMENT_SYSTEM_ID'] = ''

            if answer:
                print("You need to provide the site identifier for your comment system.  Consult the Nikola manual for details on what the value should be.  (you can leave it empty and come back later)")
                answer = ask('Comment system site identifier', '')
                SAMPLE_CONF['COMMENT_SYSTEM_ID'] = answer

        STORAGE = {'target': target}

        questions = [
            ('Questions about the site', None, None, None),
            # query, default, toconf, destination
            ('Destination', None, False, '!target'),
            ('Site title', 'My Nikola Site', True, 'BLOG_TITLE'),
            ('Site author', 'Nikola Tesla', True, 'BLOG_AUTHOR'),
            ('Site author\'s e-mail', '*****@*****.**', True, 'BLOG_EMAIL'),
            ('Site description', 'This is a demo site for Nikola.', True, 'BLOG_DESCRIPTION'),
            ('Site URL', 'http://getnikola.com/', True, 'SITE_URL'),
            ('Questions about languages and locales', None, None, None),
            (lhandler, None, True, True),
            (tzhandler, None, True, True),
            ('Questions about comments', None, None, None),
            (chandler, None, True, True),
        ]

        print("Creating Nikola Site")
        print("====================\n")
        print("This is Nikola v{0}.  We will now ask you a few easy questions about your new site.".format(nikola.__version__))
        print("If you do not want to answer and want to go with the defaults instead, simply restart with the `-q` parameter.")

        for query, default, toconf, destination in questions:
            if target and destination == '!target':
                # Skip the destination question if we know it already
                pass
            else:
                if default is toconf is destination is None:
                    print('--- {0} ---'.format(query))
                elif destination is True:
                    query(default, toconf)
                else:
                    answer = ask(query, default)
                    try:
                        answer = answer.decode('utf-8')
                    except (AttributeError, UnicodeDecodeError):
                        pass
                    if toconf:
                        SAMPLE_CONF[destination] = answer
                    if destination == '!target':
                        while not answer:
                            print('    ERROR: you need to specify a target directory.\n')
                            answer = ask(query, default)
                        STORAGE['target'] = answer

        print("\nThat's it, Nikola is now configured.  Make sure to edit conf.py to your liking.")
        print("If you are looking for themes and addons, check out http://themes.getnikola.com/ and http://plugins.getnikola.com/.")
        print("Have fun!")
        return STORAGE
Exemplo n.º 19
0
    def ask_questions(target, demo=False):
        """Ask some questions about Nikola."""
        def urlhandler(default, toconf):
            answer = ask('Site URL', 'https://example.com/')
            try:
                answer = answer.decode('utf-8')
            except (AttributeError, UnicodeDecodeError):
                pass
            if not answer.startswith(u'http'):
                print(
                    "    ERROR: You must specify a protocol (http or https).")
                urlhandler(default, toconf)
                return
            if not answer.endswith('/'):
                print("    The URL does not end in '/' -- adding it.")
                answer += '/'

            dst_url = urlsplit(answer)
            try:
                dst_url.netloc.encode('ascii')
            except (UnicodeEncodeError, UnicodeDecodeError):
                # The IDN contains characters beyond ASCII.  We must convert it
                # to Punycode. (Issue #1644)
                nl = dst_url.netloc.encode('idna')
                answer = urlunsplit((dst_url.scheme, nl, dst_url.path,
                                     dst_url.query, dst_url.fragment))
                print("    Converting to Punycode:", answer)

            SAMPLE_CONF['SITE_URL'] = answer

        def prettyhandler(default, toconf):
            SAMPLE_CONF['PRETTY_URLS'] = ask_yesno(
                'Enable pretty URLs (/page/ instead of /page.html) that don\'t need web server configuration?',
                default=True)
            SAMPLE_CONF['STRIP_INDEXES'] = SAMPLE_CONF['PRETTY_URLS']

        def lhandler(default, toconf, show_header=True):
            if show_header:
                print(
                    "We will now ask you to provide the list of languages you want to use."
                )
                print(
                    "Please list all the desired languages, comma-separated, using ISO 639-1 codes.  The first language will be used as the default."
                )
                print(
                    "Type '?' (a question mark, sans quotes) to list available languages."
                )
            answer = ask('Language(s) to use', 'en')
            while answer.strip() == '?':
                print('\n# Available languages:')
                try:
                    print(SAMPLE_CONF['_SUPPORTED_LANGUAGES'] + '\n')
                except UnicodeEncodeError:
                    # avoid Unicode characters in supported language names
                    print(
                        unidecode.unidecode(
                            SAMPLE_CONF['_SUPPORTED_LANGUAGES']) + '\n')
                answer = ask('Language(s) to use', 'en')

            langs = [
                i.strip().lower().replace('-', '_') for i in answer.split(',')
            ]
            for partial, full in LEGAL_VALUES[
                    '_TRANSLATIONS_WITH_COUNTRY_SPECIFIERS'].items():
                if partial in langs:
                    langs[langs.index(partial)] = full
                    print("NOTICE: Assuming '{0}' instead of '{1}'.".format(
                        full, partial))

            default = langs.pop(0)
            SAMPLE_CONF['DEFAULT_LANG'] = default
            # format_default_translations_config() is intelligent enough to
            # return the current value if there are no additional languages.
            SAMPLE_CONF['TRANSLATIONS'] = format_default_translations_config(
                langs)

            # Get messages for navigation_links.  In order to do this, we need
            # to generate a throwaway TRANSLATIONS dict.
            tr = {default: ''}
            for l in langs:
                tr[l] = './' + l
            # Assuming that base contains all the locales, and that base does
            # not inherit from anywhere.
            try:
                messages = load_messages(['base'],
                                         tr,
                                         default,
                                         themes_dirs=['themes'])
                SAMPLE_CONF['NAVIGATION_LINKS'] = format_navigation_links(
                    langs, default, messages, SAMPLE_CONF['STRIP_INDEXES'])
            except nikola.utils.LanguageNotFoundError as e:
                print("    ERROR: the language '{0}' is not supported.".format(
                    e.lang))
                print(
                    "    Are you sure you spelled the name correctly?  Names are case-sensitive and need to be reproduced as-is (complete with the country specifier, if any)."
                )
                print(
                    "\nType '?' (a question mark, sans quotes) to list available languages."
                )
                lhandler(default, toconf, show_header=False)

        def tzhandler(default, toconf):
            print(
                "\nPlease choose the correct time zone for your blog. Nikola uses the tz database."
            )
            print("You can find your time zone here:")
            print(
                "https://en.wikipedia.org/wiki/List_of_tz_database_time_zones")
            print("")
            answered = False
            while not answered:
                try:
                    lz = get_localzone()
                except:
                    lz = None
                answer = ask('Time zone', lz if lz else "UTC")
                tz = dateutil.tz.gettz(answer)

                if tz is None:
                    print(
                        "    WARNING: Time zone not found.  Searching list of time zones for a match."
                    )
                    zonesfile = tarfile.open(
                        fileobj=dateutil.zoneinfo.getzoneinfofile_stream())
                    zonenames = [
                        zone for zone in zonesfile.getnames()
                        if answer.lower() in zone.lower()
                    ]
                    if len(zonenames) == 1:
                        tz = dateutil.tz.gettz(zonenames[0])
                        answer = zonenames[0]
                        print("    Picking '{0}'.".format(answer))
                    elif len(zonenames) > 1:
                        print("    The following time zones match your query:")
                        print('        ' + '\n        '.join(zonenames))
                        continue

                if tz is not None:
                    time = datetime.datetime.now(tz).strftime('%H:%M:%S')
                    print("    Current time in {0}: {1}".format(answer, time))
                    answered = ask_yesno("Use this time zone?", True)
                else:
                    print("    ERROR: No matches found.  Please try again.")

            SAMPLE_CONF['TIMEZONE'] = answer

        def chandler(default, toconf):
            print(
                "You can configure comments now.  Type '?' (a question mark, sans quotes) to list available comment systems.  If you do not want any comments, just leave the field blank."
            )
            answer = ask('Comment system', '')
            while answer.strip() == '?':
                print('\n# Available comment systems:')
                print(SAMPLE_CONF['_SUPPORTED_COMMENT_SYSTEMS'])
                print('')
                answer = ask('Comment system', '')

            while answer and answer not in LEGAL_VALUES['COMMENT_SYSTEM']:
                if answer != '?':
                    print(
                        '    ERROR: Nikola does not know this comment system.')
                print('\n# Available comment systems:')
                print(SAMPLE_CONF['_SUPPORTED_COMMENT_SYSTEMS'])
                print('')
                answer = ask('Comment system', '')

            SAMPLE_CONF['COMMENT_SYSTEM'] = answer
            SAMPLE_CONF['COMMENT_SYSTEM_ID'] = ''

            if answer:
                print(
                    "You need to provide the site identifier for your comment system.  Consult the Nikola manual for details on what the value should be.  (you can leave it empty and come back later)"
                )
                answer = ask('Comment system site identifier', '')
                SAMPLE_CONF['COMMENT_SYSTEM_ID'] = answer

        STORAGE = {'target': target}

        questions = [
            ('Questions about the site', None, None, None),
            # query, default, toconf, destination
            ('Destination', None, False, '!target'),
            ('Site title', 'My Nikola Site', True, 'BLOG_TITLE'),
            ('Site author', 'Nikola Tesla', True, 'BLOG_AUTHOR'),
            ('Site author\'s e-mail', '*****@*****.**', True,
             'BLOG_EMAIL'),
            ('Site description', 'This is a demo site for Nikola.', True,
             'BLOG_DESCRIPTION'),
            (urlhandler, None, True, True),
            (prettyhandler, None, True, True),
            ('Questions about languages and locales', None, None, None),
            (lhandler, None, True, True),
            (tzhandler, None, True, True),
            ('Questions about comments', None, None, None),
            (chandler, None, True, True),
        ]

        print("Creating Nikola Site")
        print("====================\n")
        print(
            "This is Nikola v{0}.  We will now ask you a few easy questions about your new site."
            .format(nikola.__version__))
        print(
            "If you do not want to answer and want to go with the defaults instead, simply restart with the `-q` parameter."
        )

        for query, default, toconf, destination in questions:
            if target and destination == '!target' and test_destination(
                    target, demo):
                # Skip the destination question if we know it already
                pass
            else:
                if default is toconf is destination is None:
                    print('--- {0} ---'.format(query))
                elif destination is True:
                    query(default, toconf)
                else:
                    answer = ask(query, default)
                    try:
                        answer = answer.decode('utf-8')
                    except (AttributeError, UnicodeDecodeError):
                        pass
                    if toconf:
                        SAMPLE_CONF[destination] = answer
                    if destination == '!target':
                        while not answer or not test_destination(answer, demo):
                            if not answer:
                                print(
                                    '    ERROR: you need to specify a target directory.\n'
                                )
                            answer = ask(query, default)
                        STORAGE['target'] = answer

        print(
            "\nThat's it, Nikola is now configured.  Make sure to edit conf.py to your liking."
        )
        print(
            "If you are looking for themes and addons, check out https://themes.getnikola.com/ and https://plugins.getnikola.com/."
        )
        print("Have fun!")
        return STORAGE
Exemplo n.º 20
0
    def _execute(self, options, args):
        """Create a new post or page."""
        global LOGGER
        compiler_names = [
            p.name for p in self.site.plugin_manager.getPluginsOfCategory(
                "PageCompiler")
        ]

        if len(args) > 1:
            print(self.help())
            return False
        elif args:
            path = args[0]
        else:
            path = None

        # Even though stuff was split into `new_page`, it’s easier to do it
        # here not to duplicate the code.
        is_page = options.get('is_page', False)
        is_post = not is_page
        content_type = 'page' if is_page else 'post'
        title = options['title'] or None
        author = options['author'] or ''
        tags = options['tags']
        onefile = options['onefile']
        twofile = options['twofile']
        import_file = options['import']

        if is_page:
            LOGGER = PAGELOGGER
        else:
            LOGGER = POSTLOGGER

        if twofile:
            onefile = False
        if not onefile and not twofile:
            onefile = self.site.config.get('ONE_FILE_POSTS', True)

        content_format = options['content_format']

        if not content_format:  # Issue #400
            content_format = get_default_compiler(
                is_post, self.site.config['COMPILERS'],
                self.site.config['post_pages'])

        if content_format not in compiler_names:
            LOGGER.error("Unknown {0} format {1}".format(
                content_type, content_format))
            return
        compiler_plugin = self.site.plugin_manager.getPluginByName(
            content_format, "PageCompiler").plugin_object

        # Guess where we should put this
        entry = filter_post_pages(content_format, is_post,
                                  self.site.config['COMPILERS'],
                                  self.site.config['post_pages'])

        if import_file:
            print("Importing Existing {xx}".format(xx=content_type.title()))
            print("-----------------------\n")
        else:
            print("Creating New {xx}".format(xx=content_type.title()))
            print("-----------------\n")
        if title is not None:
            print("Title:", title)
        else:
            while not title:
                title = utils.ask('Title')

        if isinstance(title, utils.bytes_str):
            try:
                title = title.decode(sys.stdin.encoding)
            except (AttributeError, TypeError):  # for tests
                title = title.decode('utf-8')

        title = title.strip()
        if not path:
            slug = utils.slugify(title)
        else:
            if isinstance(path, utils.bytes_str):
                try:
                    path = path.decode(sys.stdin.encoding)
                except (AttributeError, TypeError):  # for tests
                    path = path.decode('utf-8')
            slug = utils.slugify(os.path.splitext(os.path.basename(path))[0])

        if isinstance(author, utils.bytes_str):
            try:
                author = author.decode(sys.stdin.encoding)
            except (AttributeError, TypeError):  # for tests
                author = author.decode('utf-8')

        # Calculate the date to use for the content
        schedule = options['schedule'] or self.site.config['SCHEDULE_ALL']
        rule = self.site.config['SCHEDULE_RULE']
        self.site.scan_posts()
        timeline = self.site.timeline
        last_date = None if not timeline else timeline[0].date
        date = get_date(schedule, rule, last_date, self.site.tzinfo,
                        self.site.config['FORCE_ISO8601'])
        data = {
            'title': title,
            'slug': slug,
            'date': date,
            'tags': tags,
            'link': '',
            'description': '',
            'type': 'text',
        }
        output_path = os.path.dirname(entry[0])
        meta_path = os.path.join(output_path, slug + ".meta")
        pattern = os.path.basename(entry[0])
        suffix = pattern[1:]
        if not path:
            txt_path = os.path.join(output_path, slug + suffix)
        else:
            txt_path = path

        if (not onefile and os.path.isfile(meta_path)) or \
                os.path.isfile(txt_path):
            LOGGER.error("The title already exists!")
            exit(8)

        d_name = os.path.dirname(txt_path)
        utils.makedirs(d_name)
        metadata = {}
        if author:
            metadata['author'] = author
        metadata.update(self.site.config['ADDITIONAL_METADATA'])
        data.update(metadata)

        # Override onefile if not really supported.
        if not compiler_plugin.supports_onefile and onefile:
            onefile = False
            LOGGER.warn('This compiler does not support one-file posts.')

        if import_file:
            with io.open(import_file, 'r', encoding='utf-8') as fh:
                content = fh.read()
        else:
            # ipynb's create_post depends on this exact string, take care
            # if you're changing it
            content = "Write your {0} here.".format(
                'page' if is_page else 'post')
        compiler_plugin.create_post(txt_path,
                                    content=content,
                                    onefile=onefile,
                                    title=title,
                                    slug=slug,
                                    date=date,
                                    tags=tags,
                                    is_page=is_page,
                                    **metadata)

        event = dict(path=txt_path)

        if not onefile:  # write metadata file
            with io.open(meta_path, "w+", encoding="utf8") as fd:
                fd.write(utils.write_metadata(data))
            LOGGER.info("Your {0}'s metadata is at: {1}".format(
                content_type, meta_path))
            event['meta_path'] = meta_path
        LOGGER.info("Your {0}'s text is at: {1}".format(
            content_type, txt_path))

        signal('new_' + content_type).send(self, **event)

        if options['edit']:
            editor = os.getenv('EDITOR', '').split()
            to_run = editor + [txt_path]
            if not onefile:
                to_run.append(meta_path)
            if editor:
                subprocess.call(to_run)
            else:
                LOGGER.error(
                    '$EDITOR not set, cannot edit the post.  Please do it manually.'
                )
Exemplo n.º 21
0
    def ask_questions(target):
        """Ask some questions about Nikola."""

        def urlhandler(default, toconf):
            answer = ask("Site URL", "https://example.com/")
            try:
                answer = answer.decode("utf-8")
            except (AttributeError, UnicodeDecodeError):
                pass
            if not answer.startswith("http"):
                print("    ERROR: You must specify a protocol (http or https).")
                urlhandler(default, toconf)
                return
            if not answer.endswith("/"):
                print("    The URL does not end in '/' -- adding it.")
                answer += "/"

            dst_url = urlsplit(answer)
            try:
                dst_url.netloc.encode("ascii")
            except (UnicodeEncodeError, UnicodeDecodeError):
                # The IDN contains characters beyond ASCII.  We must convert it
                # to Punycode. (Issue #1644)
                nl = dst_url.netloc.encode("idna")
                answer = urlunsplit((dst_url.scheme, nl, dst_url.path, dst_url.query, dst_url.fragment))
                print("    Converting to Punycode:", answer)

            SAMPLE_CONF["SITE_URL"] = answer

        def prettyhandler(default, toconf):
            SAMPLE_CONF["PRETTY_URLS"] = ask_yesno(
                "Enable pretty URLs (/page/ instead of /page.html) that don't need web server configuration?",
                default=True,
            )
            SAMPLE_CONF["STRIP_INDEXES"] = SAMPLE_CONF["PRETTY_URLS"]

        def lhandler(default, toconf, show_header=True):
            if show_header:
                print("We will now ask you to provide the list of languages you want to use.")
                print(
                    "Please list all the desired languages, comma-separated, using ISO 639-1 codes.  The first language will be used as the default."
                )
                print("Type '?' (a question mark, sans quotes) to list available languages.")
            answer = ask("Language(s) to use", "en")
            while answer.strip() == "?":
                print("\n# Available languages:")
                try:
                    print(SAMPLE_CONF["_SUPPORTED_LANGUAGES"] + "\n")
                except UnicodeEncodeError:
                    # avoid Unicode characters in supported language names
                    print(unidecode.unidecode(SAMPLE_CONF["_SUPPORTED_LANGUAGES"]) + "\n")
                answer = ask("Language(s) to use", "en")

            langs = [i.strip().lower().replace("-", "_") for i in answer.split(",")]
            for partial, full in LEGAL_VALUES["_TRANSLATIONS_WITH_COUNTRY_SPECIFIERS"].items():
                if partial in langs:
                    langs[langs.index(partial)] = full
                    print("NOTICE: Assuming '{0}' instead of '{1}'.".format(full, partial))

            default = langs.pop(0)
            SAMPLE_CONF["DEFAULT_LANG"] = default
            # format_default_translations_config() is intelligent enough to
            # return the current value if there are no additional languages.
            SAMPLE_CONF["TRANSLATIONS"] = format_default_translations_config(langs)

            # Get messages for navigation_links.  In order to do this, we need
            # to generate a throwaway TRANSLATIONS dict.
            tr = {default: ""}
            for l in langs:
                tr[l] = "./" + l
            # Assuming that base contains all the locales, and that base does
            # not inherit from anywhere.
            try:
                messages = load_messages(["base"], tr, default)
                SAMPLE_CONF["NAVIGATION_LINKS"] = format_navigation_links(
                    langs, default, messages, SAMPLE_CONF["STRIP_INDEXES"]
                )
            except nikola.utils.LanguageNotFoundError as e:
                print("    ERROR: the language '{0}' is not supported.".format(e.lang))
                print(
                    "    Are you sure you spelled the name correctly?  Names are case-sensitive and need to be reproduced as-is (complete with the country specifier, if any)."
                )
                print("\nType '?' (a question mark, sans quotes) to list available languages.")
                lhandler(default, toconf, show_header=False)

        def tzhandler(default, toconf):
            print("\nPlease choose the correct time zone for your blog. Nikola uses the tz database.")
            print("You can find your time zone here:")
            print("https://en.wikipedia.org/wiki/List_of_tz_database_time_zones")
            print("")
            answered = False
            while not answered:
                try:
                    lz = get_localzone()
                except:
                    lz = None
                answer = ask("Time zone", lz if lz else "UTC")
                tz = dateutil.tz.gettz(answer)

                if tz is None:
                    print("    WARNING: Time zone not found.  Searching list of time zones for a match.")
                    zonesfile = tarfile.open(fileobj=dateutil.zoneinfo.getzoneinfofile_stream())
                    zonenames = [zone for zone in zonesfile.getnames() if answer.lower() in zone.lower()]
                    if len(zonenames) == 1:
                        tz = dateutil.tz.gettz(zonenames[0])
                        answer = zonenames[0]
                        print("    Picking '{0}'.".format(answer))
                    elif len(zonenames) > 1:
                        print("    The following time zones match your query:")
                        print("        " + "\n        ".join(zonenames))
                        continue

                if tz is not None:
                    time = datetime.datetime.now(tz).strftime("%H:%M:%S")
                    print("    Current time in {0}: {1}".format(answer, time))
                    answered = ask_yesno("Use this time zone?", True)
                else:
                    print("    ERROR: No matches found.  Please try again.")

            SAMPLE_CONF["TIMEZONE"] = answer

        def chandler(default, toconf):
            print(
                "You can configure comments now.  Type '?' (a question mark, sans quotes) to list available comment systems.  If you do not want any comments, just leave the field blank."
            )
            answer = ask("Comment system", "")
            while answer.strip() == "?":
                print("\n# Available comment systems:")
                print(SAMPLE_CONF["_SUPPORTED_COMMENT_SYSTEMS"])
                print("")
                answer = ask("Comment system", "")

            while answer and answer not in LEGAL_VALUES["COMMENT_SYSTEM"]:
                if answer != "?":
                    print("    ERROR: Nikola does not know this comment system.")
                print("\n# Available comment systems:")
                print(SAMPLE_CONF["_SUPPORTED_COMMENT_SYSTEMS"])
                print("")
                answer = ask("Comment system", "")

            SAMPLE_CONF["COMMENT_SYSTEM"] = answer
            SAMPLE_CONF["COMMENT_SYSTEM_ID"] = ""

            if answer:
                print(
                    "You need to provide the site identifier for your comment system.  Consult the Nikola manual for details on what the value should be.  (you can leave it empty and come back later)"
                )
                answer = ask("Comment system site identifier", "")
                SAMPLE_CONF["COMMENT_SYSTEM_ID"] = answer

        STORAGE = {"target": target}

        questions = [
            ("Questions about the site", None, None, None),
            # query, default, toconf, destination
            ("Destination", None, False, "!target"),
            ("Site title", "My Nikola Site", True, "BLOG_TITLE"),
            ("Site author", "Nikola Tesla", True, "BLOG_AUTHOR"),
            ("Site author's e-mail", "*****@*****.**", True, "BLOG_EMAIL"),
            ("Site description", "This is a demo site for Nikola.", True, "BLOG_DESCRIPTION"),
            (urlhandler, None, True, True),
            (prettyhandler, None, True, True),
            ("Questions about languages and locales", None, None, None),
            (lhandler, None, True, True),
            (tzhandler, None, True, True),
            ("Questions about comments", None, None, None),
            (chandler, None, True, True),
        ]

        print("Creating Nikola Site")
        print("====================\n")
        print(
            "This is Nikola v{0}.  We will now ask you a few easy questions about your new site.".format(
                nikola.__version__
            )
        )
        print(
            "If you do not want to answer and want to go with the defaults instead, simply restart with the `-q` parameter."
        )

        for query, default, toconf, destination in questions:
            if target and destination == "!target":
                # Skip the destination question if we know it already
                pass
            else:
                if default is toconf is destination is None:
                    print("--- {0} ---".format(query))
                elif destination is True:
                    query(default, toconf)
                else:
                    answer = ask(query, default)
                    try:
                        answer = answer.decode("utf-8")
                    except (AttributeError, UnicodeDecodeError):
                        pass
                    if toconf:
                        SAMPLE_CONF[destination] = answer
                    if destination == "!target":
                        while not answer:
                            print("    ERROR: you need to specify a target directory.\n")
                            answer = ask(query, default)
                        STORAGE["target"] = answer

        print("\nThat's it, Nikola is now configured.  Make sure to edit conf.py to your liking.")
        print(
            "If you are looking for themes and addons, check out https://themes.getnikola.com/ and https://plugins.getnikola.com/."
        )
        print("Have fun!")
        return STORAGE
Exemplo n.º 22
0
    def ask_questions(target):
        """Ask some questions about Nikola."""
        def lhandler(default, toconf, show_header=True):
            if show_header:
                print("We will now ask you to provide the list of languages you want to use.")
                print("Please list all the desired languages, comma-separated, using ISO 639-1 codes.  The first language will be used as the default.")
                print("Type '?' (a question mark, sans quotes) to list available languages.")
            answer = ask('Language(s) to use', 'en')
            while answer.strip() == '?':
                print('\n# Available languages:')
                print(SAMPLE_CONF['_SUPPORTED_LANGUAGES'] + '\n')
                answer = ask('Language(s) to use', 'en')

            langs = [i.strip().lower().replace('-', '_') for i in answer.split(',')]
            for partial, full in LEGAL_VALUES['_TRANSLATIONS_WITH_COUNTRY_SPECIFIERS'].items():
                if partial in langs:
                    langs[langs.index(partial)] = full
                    print("NOTICE: Assuming '{0}' instead of '{1}'.".format(full, partial))

            default = langs.pop(0)
            SAMPLE_CONF['DEFAULT_LANG'] = default
            # format_default_translations_config() is intelligent enough to
            # return the current value if there are no additional languages.
            SAMPLE_CONF['TRANSLATIONS'] = format_default_translations_config(langs)

            # Get messages for navigation_links.  In order to do this, we need
            # to generate a throwaway TRANSLATIONS dict.
            tr = {default: ''}
            for l in langs:
                tr[l] = './' + l
            # Assuming that base contains all the locales, and that base does
            # not inherit from anywhere.
            try:
                messages = load_messages(['base'], tr, default)
                SAMPLE_CONF['NAVIGATION_LINKS'] = format_navigation_links(langs, default, messages)
            except nikola.utils.LanguageNotFoundError as e:
                print("    ERROR: the language '{0}' is not supported.".format(e.lang))
                print("    Are you sure you spelled the name correctly?  Names are case-sensitive and need to be reproduced as-is (complete with the country specifier, if any).")
                print("\nType '?' (a question mark, sans quotes) to list available languages.")
                lhandler(default, toconf, show_header=False)

        def tzhandler(default, toconf):
            print("\nPlease choose the correct time zone for your blog.  Nikola uses the tz database.")
            print("You can find your time zone here:")
            print("http://en.wikipedia.org/wiki/List_of_tz_database_time_zones")
            print("")
            answered = False
            while not answered:
                answer = ask('Time zone', 'UTC')
                tz = dateutil.tz.gettz(answer)
                if tz is not None:
                    time = datetime.datetime.now(tz).strftime('%H:%M:%S')
                    print("    Current time in {0}: {1}".format(answer, time))
                    answered = ask_yesno("Use this time zone?", True)
                else:
                    print("    ERROR: Time zone not found.  Please try again.  Time zones are case-sensitive.")

            SAMPLE_CONF['TIMEZONE'] = answer

        def chandler(default, toconf):
            print("You can configure comments now.  Type '?' (a question mark, sans quotes) to list available comment systems.  If you do not want any comments, just leave the field blank.")
            answer = ask('Comment system', '')
            while answer.strip() == '?':
                print('\n# Available comment systems:')
                print(SAMPLE_CONF['_SUPPORTED_COMMENT_SYSTEMS'])
                print('')
                answer = ask('Comment system', '')

            while answer and answer not in LEGAL_VALUES['COMMENT_SYSTEM']:
                if answer != '?':
                    print('    ERROR: Nikola does not know this comment system.')
                print('\n# Available comment systems:')
                print(SAMPLE_CONF['_SUPPORTED_COMMENT_SYSTEMS'])
                print('')
                answer = ask('Comment system', '')

            SAMPLE_CONF['COMMENT_SYSTEM'] = answer
            SAMPLE_CONF['COMMENT_SYSTEM_ID'] = ''

            if answer:
                print("You need to provide the site identifier for your comment system.  Consult the Nikola manual for details on what the value should be.  (you can leave it empty and come back later)")
                answer = ask('Comment system site identifier', '')
                SAMPLE_CONF['COMMENT_SYSTEM_ID'] = answer

        STORAGE = {'target': target}

        questions = [
            ('Questions about the site', None, None, None),
            # query, default, toconf, destination
            ('Destination', None, False, '!target'),
            ('Site title', 'My Nikola Site', True, 'BLOG_TITLE'),
            ('Site author', 'Nikola Tesla', True, 'BLOG_AUTHOR'),
            ('Site author’s e-mail', '*****@*****.**', True, 'BLOG_EMAIL'),
            ('Site description', 'This is a demo site for Nikola.', True, 'BLOG_DESCRIPTION'),
            ('Site URL', 'http://getnikola.com/', True, 'SITE_URL'),
            ('Questions about languages and locales', None, None, None),
            (lhandler, None, True, True),
            (tzhandler, None, True, True),
            ('Questions about comments', None, None, None),
            (chandler, None, True, True),
        ]

        print("Creating Nikola Site")
        print("====================\n")
        print("This is Nikola v{0}.  We will now ask you a few easy questions about your new site.".format(nikola.__version__))
        print("If you do not want to answer and want to go with the defaults instead, simply restart with the `-q` parameter.")

        for query, default, toconf, destination in questions:
            if target and destination == '!target':
                # Skip the destination question if we know it already
                pass
            else:
                if default is toconf is destination is None:
                    print('--- {0} ---'.format(query))
                elif destination is True:
                    query(default, toconf)
                else:
                    answer = ask(query, default)
                    if toconf:
                        SAMPLE_CONF[destination] = answer
                    if destination == '!target':
                        while not answer:
                            print('    ERROR: you need to specify a target directory.\n')
                            answer = ask(query, default)
                        STORAGE['target'] = answer

        print("\nThat's it, Nikola is now configured.  Make sure to edit conf.py to your liking.")
        print("If you are looking for themes and addons, check out http://themes.getnikola.com/ and http://plugins.getnikola.com/.")
        print("Have fun!")
        return STORAGE