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
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 }
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
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
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)
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/')
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')
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))
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' )
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
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))
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