Example #1
0
    def set_main_language(self):
        main = self.main_language
        languages = self.get_languages()
        if self.languages and \
           (not self.main_language \
            or self.main_language not in languages):
            main = languages[0]
            logger.warning("main_language not correctly defined, "
                           "taking «{}» as main language".format(main))

        self.main_language = main
Example #2
0
    def add_to_menu(self, menu_name, menu_object, parent=None):
        if menu_name not in self.menus:
            self.menus[menu_name] = {}

        menu_id = menu_object.id
        if menu_id in self.menus[menu_name]:
            logger.warning(
                'Duplicated menu element found for id «{}»'.format(menu_id))

        self.menus[menu_name][menu_id] = {
            'object': menu_object,
            'parent_id': parent
        }
Example #3
0
    def get_routing_content(self):
        content = []
        if os.path.isfile(config.routing_path):
            with open(config.routing_path) as routing_file:
                try:
                    content = json.load(routing_file)
                except Exception as e:
                    logger.warning(
                        'Routing file could not be parsed: {}'.format(
                            e.message))

        if not isinstance(content, list):
            logger.warning('Routing file wrong format: {}'.format(e.message))
            content = []
        return content
Example #4
0
 def get_translations(self, language):
     locale_dir = config.locales_path
     if language == constants.DEFAULT_LANG:
         translations = gettext.NullTranslations()
     else:
         langs = [language]
         try:
             translations = gettext.translation(constants.GETTEXT_DOMAIN,
                                                locale_dir, langs)
         except (IOError, OSError):
             logger.warning(
                 ("Cannot find translations for language '{}'."
                  " Installing NullTranslations.").format(language))
             translations = gettext.NullTranslations()
     return translations
Example #5
0
    def build_routed_contents(self):
        routing_content = self.get_routing_content()

        for content in routing_content:
            try:
                routed_page = self.handle_routed_content(content)
            except Exception as e:
                logger.warning(
                    'Routed config with data {} could not be handle. Error: {}'
                    .format(json.dumps(content), str(e)))
            else:
                if routed_page:
                    language = routed_page.language
                    if routed_page.to_publish():
                        self.contents[language].append(routed_page)
                    elif routed_page.is_expired():
                        self.expired_contents[language].append(routed_page)
Example #6
0
    def load_config(self, config_file_path):
        self.config_path = config_file_path

        self.base_path = os.path.dirname(os.path.abspath(self.config_path))

        # Default
        self.content_path = os.path.join(self.base_path, constants.DEFAULT_CONTENT_PATH)
        self.public_path = os.path.join(self.base_path, constants.DEFAULT_PUBLIC_PATH)
        self.static_path = os.path.join(self.base_path, constants.DEFAULT_STATIC_PATH)
        self.templates_path = os.path.join(self.base_path, constants.DEFAULT_TEMPLATES_PATH)
        self.locales_path = os.path.join(self.base_path, constants.DEFAULT_LOCALES_PATH)
        self.routing_path = os.path.join(self.base_path, constants.DEFAULT_ROUTING_FILE_PATH)

        path_options = ['public_path', 'content_path', 'static_path', 'custom_filters']
        with open(self.config_path, 'r') as config_file:
            parsed_config = yaml.load(config_file)

            if not parsed_config:
                logger.warning('Config file completely empty')
                parsed_config = []

            for param in parsed_config:
                value = parsed_config[param]
                if param in path_options:
                    value = value if os.path.isdir(value) else os.path.join(self.base_path, value)
                setattr(self, param, value)

        if not os.path.isdir(self.content_path):
            logger.error('Invalid path for content. Folder not found')
            sys.exit(1)

        if self.custom_filters and not os.path.isfile(self.custom_filters):
            logger.error('Specified filters file not found.')
            self.custom_filters = None
            return

        # TODO: make patterns configurables
        self.ignore_files_regex = [re.compile(i) for i in constants.IGNORE_FILES_PATTERN]

        self._format_languages()
        self.set_main_language()

        self.check_taxonomies_format()

        current_file_path = os.path.abspath(os.path.dirname(__file__))
        self.files_path = os.path.join(current_file_path, 'files/')
Example #7
0
    def get_from_config(self):
        menus = config.get_menus(self.language)
        for menu_name, items in menus.items():

            for item in items:
                id = item.get('id', None)
                title = item.get('title', None)
                weight = item.get('weight', 0)
                url = item.get('url', None)
                parent = item.get('parent', None)

                if title and id and url:
                    menu_object = Menu(self.generator,
                                       id=id,
                                       title=title,
                                       weight=weight,
                                       url=url)

                    self.add_to_menu(menu_name, menu_object, parent)
                else:
                    logger.warning(
                        'Malformed menu item: id, title and url are mandatory')
Example #8
0
    def render(self, content, output_path, context, meta_tag, js_includes):
        template = self.get_content_template(content)
        if template:
            try:
                content = template.render(**context)
                content = content.replace('</head>',
                                          "{}\n\n</head>".format(meta_tag))

                js_includes = '\n'.join(js_includes)
                content = content.replace('</body>',
                                          "{}\n\n</body>".format(js_includes))

                with open(output_path, 'w') as output_file:
                    output_file.write(content)
            except Exception as error:
                template_path = '/' + template.filename.replace(
                    config.base_path, '').lstrip('/')
                logger.error('Rendering template {} for content {}: {}'.format(
                    template_path, content, str(error)))
        else:
            logger.warning(
                'No template found for content - {}'.format(content))
Example #9
0
    def compile(self):
        for language in config.get_languages():
            locale_path = os.path.join(config.locales_path, language,
                                       'LC_MESSAGES')
            po_file_path = os.path.join(locale_path, self.po_filename)
            mo_file_path = os.path.join(locale_path, self.mo_filename)

            if has_bom(po_file_path):
                logger.error("The {} file has a BOM (Byte Order Mark). "
                             "Sitic only supports .po files encoded in "
                             "UTF-8 and without any BOM.".format(po_file_path))

            if not os.path.exists(po_file_path):
                logger.warning(
                    "Not .po file found for language «{}»."
                    "Run «makemessages» to generate it.".format(language))
                continue

            msgmt_args = ['msgfmt'] + self.msgfmt_options + [
                '-o', mo_file_path, po_file_path
            ]
            output, errors, status = call_subprocess(msgmt_args)

            if status != constants.STATUS_OK and errors:
                logger.error(
                    "errors happened while running msgmerge\n{}".format(
                        errors))
                sys.exit(1)
            elif errors:
                logger.error(errors)

            logger.info(
                'Messages successfully compiled for language «{}»'.format(
                    language))

        logger.warning(
            'Please, keep in mind that «msgfmt» won\'t generate any «.mo» file if no translation modified'
        )
Example #10
0
    def check_taxonomies_format(self):

        taxonomies_to_check = {}

        if self.taxonomies is not None:
            taxonomies_to_check['global'] = self.taxonomies

        # Any language defined
        if self.main_language is not None:
            for language in self.get_languages():
                config = self.get_language_config(language)
                taxonomies = config.get('taxonomies', None)
                if taxonomies is not None:
                    taxonomies_to_check[language] = taxonomies

        self.taxonomies = {}
        for config_key in taxonomies_to_check:
            taxonomies = taxonomies_to_check[config_key]

            if not isinstance(taxonomies, dict):
                logger.warning('«{}» config, taxonomies must be a dictionary(key: value)'.format(config_key))
                continue

            for taxonomy_key in taxonomies:
                taxonomy_value = taxonomies[taxonomy_key]

                if not isinstance(taxonomy_value, str) or not isinstance(taxonomy_key, str):
                    logger.warning('«{}» config, taxonomies key and value must be strings'.format(config_key))
                    continue

                if config_key == 'global':
                    self.taxonomies[taxonomy_key] = taxonomy_value
                else:
                    self.taxonomies_by_lang[lang][taxonomy_key] = taxonomy_value

        if not self.taxonomies:
            self.taxonomies = constants.DEFAULT_TAXONOMIES
Example #11
0
    def get_from_page(self, page):
        menus = page.menus()

        if not menus:
            return

        menus_items = menus.items() if isinstance(menus,
                                                  dict) else enumerate(menus)
        for index, menu_data in menus_items:
            data = self.get_data(index, menu_data)

            if self.lazy_menu and self.lazy_menu == data['name']:
                logger.warning(
                    'Menu «{}» declared as lazy menu, skipping for page id «{}»'
                    .format(self.lazy_menu, page.id))
                continue

            if not data:
                continue

            menu_object = self.get_object_from_page(page, data)

            self.add_to_menu(data['name'], menu_object,
                             data.get('parent', None))
Example #12
0
    def handle_routed_content(self, content):

        languages = config.get_languages()

        if not isinstance(content, dict):
            logger.warning(
                'Every element in the routing file must be a dictionary')
            return

        mandatory_fields = [('title', str), ('section', str), ('url', str)]

        for field, field_type in mandatory_fields:
            value = content.get(field, None)
            if not value:
                logger.warning(
                    'Every routed page must have a «{}» attribute'.format(
                        field))
                return
            if not isinstance(value, field_type):
                logger.warning('«{}» attribute must be type «{}»'.format(
                    field, field_type))
                return

        language = config.main_language
        if 'language' in content:
            language = content['language'] if content[
                'language'] in languages else language
            del content['language']

        section_name = None
        if 'section' in content:
            section_name = content.get('section')
            del content['section']

        routed_page = RoutedPage(content, language)

        if routed_page.to_publish():
            section = self._get_section(section_name, language)
            section.add_page(routed_page)

            self.update_taxonomies(routed_page)

        return routed_page