def _generate(self): logger.debug('>> Initializing\n.. src: {0}\n.. dest: {1}'.format(self.src.path, self.dest.path)) self._update_config() for opt in ('base_url',): if opt in self.opts: self.config[opt] = self.opts[opt] self.renderer.register({'site': self.config}) self._render() logger.info('>> Generating') assets_src = Directory(normpath(self.src.path, '_assets')) assets_dest = Directory(normpath(self.dest.path, *self.config['assets_url'].split('/'))) if self.dest.exists: if self.opts['force']: self.dest.empty() else: self.dest.rm() else: self.dest.mk() for page in self.pages: page.mk() if assets_src.exists: for asset in assets_src: asset.cp(asset.path.replace(assets_src.path, assets_dest.path)) logger.info('Completed in {0:.3f}s'.format(time() - self._start))
def init(self): Timer.start() self.src = Directory(self._get_theme(self.opts['theme'])) self.dest = Directory(self.opts['dest']) if not self.src.exists: raise OptionException('Theme not found.') elif self.dest.exists and not self.opts['force']: raise OptionException( 'Destination already exists.', 'the -f flag must be passed to force initialization by deleting the destination' ) logger.info('>> Initializing') if self.opts['bare']: self.dest.rm() for d in ('_assets/css', '_assets/images', '_assets/js', '_templates', '_posts'): Directory(normpath(self.dest.path, d)).mk() File(normpath(self.dest.path, 'config.yml')).mk() else: self.src.cp(self.dest.path, False) logger.info('Completed in %.3fs', Timer.stop())
def initialize(self): Timer.start() self.source = Directory(self._get_theme(self.options['theme'])) self.destination = Directory(self.options['destination']) if not self.source.exists: raise OptionException('Theme not found') elif self.destination.exists and not self.options['delete']: raise OptionException( 'Destination already exists', 'to force initialization, use the following flag', ' `-d` to DELETE the destination') logger.info('>> Initializing') if self.options['bare']: self.destination.rm() directories = ('_assets/css', '_assets/images', '_assets/js', '_templates', '_posts') for d in directories: Directory(normpath(self.destination.path, d)).mk() File(normpath(self.destination.path, 'mynt.yml')).mk() else: self.source.cp(self.destination.path, False) logger.info('Completed in %.3fs', Timer.stop())
def init(self): Timer.start() self.src = Directory(self._get_theme(self.opts['theme'])) self.dest = Directory(self.opts['dest']) if not self.src.exists: raise OptionException('Theme not found.') elif self.dest.exists and not self.opts['force']: raise OptionException('Destination already exists.', 'the -f flag must be passed to force initialization by deleting the destination') logger.info('>> Initializing') if self.opts['bare']: self.dest.rm() for d in ('_assets/css', '_assets/images', '_assets/js', '_templates', '_posts'): Directory(normpath(self.dest.path, d)).mk() File(normpath(self.dest.path, 'config.yml')).mk() else: self.src.cp(self.dest.path, False) logger.info('Completed in %.3fs', Timer.stop())
def init(self): self.src = Directory(self._get_theme(self.opts['theme'])) self.dest = Directory(self.opts['dest']) if not self.src.exists: raise OptionException('Theme not found.') elif self.dest.exists and not self.opts['force']: raise OptionException( 'Destination already exists.', 'the -f option must be used to force initialization by deleting the destination' ) logger.info('>> Initializing') if self.opts['bare']: for d in [ '_assets/css', '_assets/images', '_assets/js', '_templates', '_posts' ]: Directory(normpath(self.dest.path, d)).mk() File(normpath(self.dest.path, 'config.yml')).mk() else: self.src.cp(self.dest.path) logger.info('Completed in {0:.3f}s'.format(time() - self._start))
def setup(self): self.config.update(self.options) self.config['loader'] = _PrefixLoader( OrderedDict([(op.sep, FileSystemLoader(self.path)), ('', FileSystemLoader(normpath(self.path, '_templates')))]), None) self.environment = Environment(**self.config) self.environment.filters['absolutize'] = self._absolutize self.environment.filters['date'] = self._date self.environment.filters['items'] = self._items self.environment.filters['values'] = self._values self.environment.globals.update(self.globals) self.environment.globals['get_asset'] = self._get_asset self.environment.globals['get_url'] = self._get_url if 'extensions' in self.config and 'jinja2.ext.i18n' in self.config[ 'extensions']: try: langs = [ locale.getlocale(locale.LC_MESSAGES)[0].decode('utf-8') ] except AttributeError: langs = None self.environment.install_gettext_translations( gettext.translation(gettext.textdomain(), normpath(self.path, '_locales'), langs, fallback=True))
def _update_config(self): self.config = deepcopy(self.defaults) logger.debug('>> Searching for config') for ext in ('.yml', '.yaml'): f = File(normpath(self.src.path, 'config' + ext)) if f.exists: logger.debug('.. found: %s', f.path) try: self.config.update(Config(f.content)) except ConfigException as e: raise ConfigException(e.message, 'src: {0}'.format(f.path)) self.config['locale'] = self.opts.get('locale', self.config['locale']) self.config['assets_url'] = absurl(self.config['assets_url'], '') self.config['base_url'] = absurl(self.opts.get('base_url', self.config['base_url']), '') for setting in ('archives_url', 'posts_url', 'tags_url'): self.config[setting] = absurl(self.config[setting]) for setting in ('archives_url', 'assets_url', 'base_url', 'posts_url', 'tags_url'): if re.search(r'(?:^\.{2}/|/\.{2}$|/\.{2}/)', self.config[setting]): raise ConfigException('Invalid config setting.', 'setting: {0}'.format(setting), 'path traversal is not allowed') for pattern in self.config['include']: if op.commonprefix((self.src.path, normpath(self.src.path, pattern))) != self.src.path: raise ConfigException('Invalid include path.', 'path: {0}'.format(pattern), 'path traversal is not allowed') break else: logger.debug('.. no config file found')
def _generate(self): self._initialize() self._parse() self._render() logger.info('>> Generating') assets_src = Directory(normpath(self.src.path, '_assets')) assets_dest = Directory(normpath(self.dest.path, *self.config['assets_url'].split('/'))) figures_src = Directory(normpath(self.src.path, '_figures')) figures_dest = Directory(normpath(self.dest.path, *self.config['figures_url'].split('/'))) if self.dest.exists: if self.opts['force']: self.dest.empty() else: self.dest.rm() else: self.dest.mk() for page in self.pages: page.mk() assets_src.cp(assets_dest.path) figures_src.cp(figures_dest.path) for pattern in self.config['include']: for path in iglob(normpath(self.src.path, pattern)): dest = path.replace(self.src.path, self.dest.path) if op.isdir(path): Directory(path).cp(dest, False) elif op.isfile(path): File(path).cp(dest)
def _generate(self): self._initialize() self._parse() self._render() logger.info('>> Generating') assets_src = Directory(normpath(self.src.path, '_assets')) assets_dest = Directory( normpath(self.dest.path, *self.config['assets_url'].split('/'))) if self.dest.exists: if self.opts['force']: self.dest.empty() else: self.dest.rm() else: self.dest.mk() for page in self.pages: page.mk() assets_src.cp(assets_dest.path) for pattern in self.config['include']: for path in iglob(normpath(self.src.path, pattern)): dest = path.replace(self.src.path, self.dest.path) if op.isdir(path): Directory(path).cp(dest, False) elif op.isfile(path): File(path).cp(dest)
def generate(self): self._render() logger.info('>> Generating') assets_src = Directory(normpath(self.src.path, '_assets')) assets_dest = Directory( normpath(self.dest.path, *self.config['assets_url'].split('/'))) if self.dest.exists: if not self.opts['force']: raise OptionException( 'Destination already exists.', 'the -f option must be used to force generation by deleting the destination' ) self.dest.rm() self.dest.mk() for page in self.pages: page.mk() if assets_src.exists: for asset in assets_src: asset.cp(asset.path.replace(assets_src.path, assets_dest.path)) logger.info('Completed in {0:.3f}s'.format(time() - self._start))
def _generate(self): logger.debug('>> Initializing\n.. src: {0}\n.. dest: {1}'.format(self.src.path, self.dest.path)) self._update_config() for opt in ('base_url',): if opt in self.opts: self.config[opt] = self.opts[opt] self.renderer.register({'site': self.config}) self._render() logger.info('>> Generating') assets_src = Directory(normpath(self.src.path, '_assets')) assets_dest = Directory(normpath(self.dest.path, *self.config['assets_url'].split('/'))) if self.dest.exists: if self.opts['force']: self.dest.empty() else: self.dest.rm() else: self.dest.mk() for page in self.pages: page.mk() if assets_src.exists: for asset in assets_src: asset.cp(asset.path.replace(assets_src.path, assets_dest.path)) # cbr - v0.8 - 2013-01-25 robots_src = File(normpath(self.src.path, 'robots.txt' )) favicon_src = File(normpath(self.src.path, 'favicon.ico' )) if robots_src.exists: logger.debug('.. found: {0}'.format(robots_src.path)) robots_src_dest = robots_src.path.replace(robots_src.path, self.dest.path) robots_src.cp(robots_src_dest + '/robots.txt') else: logger.debug('.. no robots file found: {0}'.format(robots_src.path)) # cbr - v0.8 - 2013-01-25 if favicon_src.exists: logger.debug('.. found: {0}'.format(favicon_src.path)) favicon_file_dest = favicon_src.path.replace(favicon_src.path, self.dest.path) favicon_src.cp(favicon_file_dest + '/favicon.ico') else: logger.debug('.. no favicon found at: {0}'.format(favicon_src.path)) logger.info('Completed in {0:.3f}s'.format(time() - self._start))
def _get_path(self, url): parts = [self.dest.path] + url.split('/') if url.endswith('/'): parts.append('index.html') return normpath(*parts)
def _render(self): self._process() logger.info('>> Rendering') self.renderer.register({ 'archives': self.archives, 'posts': self.posts, 'tags': self.tags }) logger.debug('.. posts') for post in self.posts: try: self.pages.append( Page( self._get_path(post['url']), self._pygmentize( self.renderer.render(post['layout'], {'post': post})))) except RendererException as e: raise RendererException( e.message, '{0} in post \'{1}\''.format(post['layout'], post['title'])) logger.debug('.. pages') for f in self.src: if f.extension not in ('.html', '.htm', '.xml'): continue template = f.path.replace(self.src.path, '') self.pages.append( Page(normpath(self.dest.path, template), self._pygmentize(self.renderer.render(template)))) if self.config['tag_layout'] and self.tags: logger.debug('.. tags') for name, data in self.tags: self.pages.append( Page( self._get_path(data['url']), self._pygmentize( self.renderer.render(self.config['tag_layout'], {'tag': data})))) if self.config['archive_layout'] and self.archives: logger.debug('.. archives') for year, data in self.archives: self.pages.append( Page( self._get_path(data['url']), self._pygmentize( self.renderer.render(self.config['archive_layout'], {'archive': data}))))
def setup(self): self.config.update(self.options) self.config['loader'] = _PrefixLoader(OrderedDict([ (op.sep, FileSystemLoader(self.path)), ('', FileSystemLoader(normpath(self.path, '_templates'))) ]), None) self.environment = Environment(**self.config) self.environment.filters['absolutize'] = self._absolutize self.environment.filters['date'] = self._date self.environment.filters['items'] = self._items self.environment.filters['values'] = self._values self.environment.globals.update(self.globals) self.environment.globals['get_asset'] = self._get_asset self.environment.globals['get_url'] = self._get_url if 'extensions' in self.config and 'jinja2.ext.i18n' in self.config['extensions']: try: langs = [locale.getlocale(locale.LC_MESSAGES)[0].decode('utf-8')] except AttributeError: langs = None self.environment.install_gettext_translations(gettext.translation(gettext.textdomain(), normpath(self.path, '_locales'), langs, fallback = True))
def _parse(self): logger.info('>> Parsing') path = Directory(normpath(self.src.path, '_posts')) logger.debug('.. src: %s', path) for f in path: post = Post(f) content = self.parser.parse(self.renderer.from_string(post.bodymatter, post.frontmatter)) excerpt = re.search(r'\A.*?(?:<p>(.+?)</p>)?', content, re.M | re.S).group(1) try: data = { 'content': content, 'date': post.date.strftime(self.config['date_format']).decode('utf-8'), 'excerpt': excerpt, 'tags': [], 'timestamp': timegm(post.date.utctimetuple()), 'url': self._get_post_url(post.date, post.slug) } except PageException: raise PageException('Invalid post slug.', 'src: {0}'.format(post.path)) data.update(post.frontmatter) data['tags'].sort(key = unicode.lower) self.posts.append(data) for tag in data['tags']: if tag not in self.tags: self.tags[tag] = [] self.tags[tag].append(data)
def _update_config(self): self.config = deepcopy(self.defaults) logger.debug('>> Searching for config') for ext in ('.yml', '.yaml'): f = File(normpath(self.src.path, 'config' + ext)) if f.exists: logger.debug('.. found: {0}'.format(f.path)) try: self.config.update(Config(f.content)) except ConfigException as e: raise ConfigException(e.message, 'src: {0}'.format(f.path)) break else: logger.debug('.. no config file found') # suport for the time_locale if self.config['time_locale']: # ascii-encoding is fallback for: http://bugs.python.org/issue3067 time_locale = self.config['time_locale'].encode('ascii') logger.debug('.. chaning time locale to ' + time_locale) try: locale.setlocale(locale.LC_TIME, (time_locale, b'utf-8')) except ValueError: logger.error('Wrong time locale format: {0} ({1})'.format(time_locale, type(time_locale)))
def _parse(self): logger.info('>> Parsing') path = Directory(normpath(self.src.path, '_posts')) logger.debug('.. src: {0}'.format(path)) for f in path: post = Post(f) content = self.parser.parse(self.renderer.from_string(post.bodymatter, post.frontmatter)) excerpt = re.search(r'\A.*?(<p>.+?</p>)?', content, re.M | re.S).group(1) data = { 'content': content, 'date': post.date.strftime(self.config['date_format']).decode('utf-8'), 'excerpt': excerpt, 'tags': [], 'timestamp': timegm(post.date.utctimetuple()), 'url': self._get_post_url(post.date, post.slug) } data.update(post.frontmatter) data['tags'].sort(key = unicode.lower) self.posts.append(data) for tag in data['tags']: if tag not in self.tags: self.tags[tag] = [] self.tags[tag].append(data)
def __init__(self, name, src, config): self._pages = None self.name = name self.src = src self.path = Directory(normpath(self.src.path, '_containers', self.name)) self.config = config self.data = Data([], OrderedDict(), OrderedDict())
def _generate(self): logger.debug('>> Initializing\n.. src: %s\n.. dest: %s', self.src.path, self.dest.path) self._update_config() if self.config['locale']: try: locale.setlocale(locale.LC_ALL, (self.config['locale'], 'utf-8')) except locale.Error: raise ConfigException( 'Locale not available.', 'run `locale -a` to see available locales') self.writer.register({'site': self.config}) self._render() logger.info('>> Generating') assets_src = Directory(normpath(self.src.path, '_assets')) assets_dest = Directory( normpath(self.dest.path, *self.config['assets_url'].split('/'))) if self.dest.exists: if self.opts['force']: self.dest.empty() else: self.dest.rm() else: self.dest.mk() for page in self.pages: page.mk() assets_src.cp(assets_dest.path) for pattern in self.config['include']: for path in iglob(normpath(self.src.path, pattern)): dest = path.replace(self.src.path, self.dest.path) if op.isdir(path): Directory(path).cp(dest, False) elif op.isfile(path): File(path).cp(dest)
def _render(self): self._process() logger.info('>> Rendering') self.renderer.register({ 'archives': self.archives, 'posts': self.posts, 'tags': self.tags }) logger.debug('.. posts') for post in self.posts: try: self.pages.append(Page( self._get_path(post['url']), self._pygmentize(self.renderer.render(post['layout'], {'post': post})) )) except RendererException as e: raise RendererException(e.message, '{0} in post \'{1}\''.format(post['layout'], post['title'])) logger.debug('.. pages') for f in self.src: if f.extension not in ('.html', '.htm', '.xml'): continue template = f.path.replace(self.src.path, '') self.pages.append(Page( normpath(self.dest.path, template), self._pygmentize(self.renderer.render(template)) )) if self.config['tag_layout'] and self.tags: logger.debug('.. tags') for name, data in self.tags: self.pages.append(Page( self._get_path(data['url']), self._pygmentize(self.renderer.render(self.config['tag_layout'], {'tag': data})) )) self.pages.append(Page( self._get_path(data['url']).replace('index.html', self.config['tag_feed_layout']), self._pygmentize(self.renderer.render(self.config['tag_feed_layout'], {'tag': data})) )) if self.config['archive_layout'] and self.archives: logger.debug('.. archives') for year, data in self.archives: self.pages.append(Page( self._get_path(data['url']), self._pygmentize(self.renderer.render(self.config['archive_layout'], {'archive': data})) ))
def _generate(self): logger.debug('>> Initializing\n.. src: %s\n.. dest: %s', self.src.path, self.dest.path) self._update_config() if self.config['locale']: try: locale.setlocale(locale.LC_ALL, (self.config['locale'], 'utf-8')) except locale.Error: raise ConfigException('Locale not available.', 'run `locale -a` to see available locales') self.renderer.register({'site': self.config}) self._render() logger.info('>> Generating') assets_src = Directory(normpath(self.src.path, '_assets')) assets_dest = Directory(normpath(self.dest.path, *self.config['assets_url'].split('/'))) if self.dest.exists: if self.opts['force']: self.dest.empty() else: self.dest.rm() else: self.dest.mk() for page in self.pages: page.mk() assets_src.cp(assets_dest.path) for pattern in self.config['include']: for path in iglob(normpath(self.src.path, pattern)): dest = path.replace(self.src.path, self.dest.path) if op.isdir(path): Directory(path).cp(dest, False) elif op.isfile(path): File(path).cp(dest) logger.info('Completed in %.3fs', time() - self._start)
def __iter__(self): for root, dirs, files in walk(self.path): for d in dirs[:]: if d.startswith(('.', '_')): dirs.remove(d) for f in files: if f.startswith(('.', '_')): continue yield File(normpath(root, f))
def init(self): self.src = Directory(self._get_theme(self.opts['theme'])) self.dest = Directory(self.opts['dest']) if not self.src.exists: raise OptionException('Theme not found.') elif self.dest.exists and not self.opts['force']: raise OptionException('Destination already exists.', 'the -f option must be used to force initialization by deleting the destination') logger.info('>> Initializing') if self.opts['bare']: for d in ['_assets/css', '_assets/images', '_assets/js', '_templates', '_posts']: Directory(normpath(self.dest.path, d)).mk() File(normpath(self.dest.path, 'config.yml')).mk() else: self.src.cp(self.dest.path) logger.info('Completed in {0:.3f}s'.format(time() - self._start))
def _get_path(self, url): parts = [self.dest.path] + url.split('/') if url.endswith('/'): parts.append('index.html') path = normpath(*parts) if op.commonprefix((self.dest.path, path)) != self.dest.path: raise ConfigException('Invalid URL.', 'url: {0}'.format(url), 'path traversal is not allowed') return path
def _generate(self): logger.debug('>> Initializing\n.. src: {0}\n.. dest: {1}'.format( self.src.path, self.dest.path)) self._update_config() for opt in ('base_url', ): if opt in self.opts: self.config[opt] = self.opts[opt] self.renderer.register({'site': self.config}) self._render() logger.info('>> Generating') assets_src = Directory(normpath(self.src.path, '_assets')) assets_dest = Directory( normpath(self.dest.path, *self.config['assets_url'].split('/'))) if self.dest.exists: if self.opts['force']: self.dest.empty() else: self.dest.rm() else: self.dest.mk() for page in self.pages: page.mk() if assets_src.exists: for asset in assets_src: asset.cp(asset.path.replace(assets_src.path, assets_dest.path)) logger.info('Completed in {0:.3f}s'.format(time() - self._start))
def setup(self): self.config.update(self.options) self.config['loader'] = _PrefixLoader(OrderedDict([ (pathsep, FileSystemLoader(self.path)), ('', FileSystemLoader(normpath(self.path, '_templates'))) ]), None) self.environment = Environment(**self.config) self.environment.filters['date'] = self._date self.environment.filters['needed'] = self._needed self.environment.globals.update(self.globals) self.environment.globals['get_asset'] = self._get_asset self.environment.globals['get_url'] = self._get_url
def generate(self): self._render() logger.info('>> Generating') assets_src = Directory(normpath(self.src.path, '_assets')) assets_dest = Directory(normpath(self.dest.path, *self.config['assets_url'].split('/'))) if self.dest.exists: if not self.opts['force']: raise OptionException('Destination already exists.', 'the -f option must be used to force generation by deleting the destination') self.dest.rm() self.dest.mk() for page in self.pages: page.mk() if assets_src.exists: for asset in assets_src: asset.cp(asset.path.replace(assets_src.path, assets_dest.path)) logger.info('Completed in {0:.3f}s'.format(time() - self._start))
def setup(self): self.config.update(self.options) self.config['loader'] = _PrefixLoader(OrderedDict([ ('/', FileSystemLoader(self.path)), ('', FileSystemLoader(normpath(self.path, '_templates'))) ]), None) self.environment = Environment(**self.config) self.environment.filters['date'] = self._date self.environment.filters['needed'] = self._needed self.environment.globals.update(self.globals) self.environment.globals['get_asset'] = self._get_asset self.environment.globals['get_url'] = self._get_url
def _parse(self): logger.info('>> Parsing') path = Directory(normpath(self.src.path, '_posts')) logger.debug('.. src: {0}'.format(path)) for f in path: post = Post(f) postdate = post.date.strftime(self.config['date_format']).decode('utf-8') logger.debug('.. .. postdate: {0}'.format(postdate)) content = self.parser.parse(self.renderer.from_string(post.bodymatter, post.frontmatter)) excerpt = re.search(r'\A.*?(?:<p>(.+?)</p>)?', content, re.M | re.S).group(1) if self.config['check_more']: # check for the more tag if set, then check the posts for it # because if set in config, use it for the posts # do nothing if not found logger.debug('.. checking the <!--more--> tag') more_excerpt = re.search(r'(\A.*?)(?:<!--more-->).*', content, re.M | re.S) if more_excerpt != None: excerpt = more_excerpt.group(1) data = { 'content': content, 'date': post.date.strftime(self.config['date_format']).decode('utf-8'), 'excerpt': excerpt, 'tags': [], 'timestamp': timegm(post.date.utctimetuple()), 'url': self._get_post_url(post.date, post.slug) } data.update(post.frontmatter) data['tags'].sort(key = unicode.lower) self.posts.append(data) for tag in data['tags']: if tag not in self.tags: self.tags[tag] = [] self.tags[tag].append(data)
def _update_config(self): self.config = deepcopy(self.defaults) logger.debug('>> Searching for config') for ext in ('.yml', '.yaml'): f = File(normpath(self.src.path, 'config' + ext)) if f.exists: logger.debug('.. found: {0}'.format(f.path)) try: self.config.update(Config(f.content)) except ConfigException as e: raise ConfigException(e.message, 'src: {0}'.format(f.path)) break else: logger.debug('.. no config file found')
def __init__(self, args=None): self._start = time() self.opts = self._get_opts(args) self.src = Directory(self.opts['src']) self.dest = Directory(self.opts['dest']) logger.setLevel(getattr(logging, self.opts['level'], logging.INFO)) logger.debug('>> Initializing\n.. src: {0}\n.. dest: {1}'.format( self.src, self.dest)) if self.src == self.dest: raise OptionException('Source and destination must differ.') elif self.src.path in ('/', '//') or self.dest.path in ('/', '//'): raise OptionException('Root is not a valid source or destination.') logger.debug('>> Searching for config') for ext in ('.yml', '.yaml'): f = File(normpath(self.src.path, 'config' + ext)) if f.exists: logger.debug('.. found: {0}'.format(f.path)) try: self.config.update(Config(f.content)) except ConfigException as e: raise ConfigException(e.message, 'src: {0}'.format(f.path)) break else: logger.debug('.. no config file found') for opt in ('base_url', ): if opt in self.opts: self.config[opt] = self.opts[opt] self.renderer.register({'site': self.config})
def __init__(self, args = None): self._start = time() self.opts = self._get_opts(args) self.src = Directory(self.opts['src']) self.dest = Directory(self.opts['dest']) logger.setLevel(getattr(logging, self.opts['level'], logging.INFO)) logger.debug('>> Initializing\n.. src: {0}\n.. dest: {1}'.format(self.src, self.dest)) if self.src == self.dest: raise OptionException('Source and destination must differ.') elif self.src.path in ('/', '//') or self.dest.path in ('/', '//'): raise OptionException('Root is not a valid source or destination.') logger.debug('>> Searching for config') for ext in ('.yml', '.yaml'): f = File(normpath(self.src.path, 'config' + ext)) if f.exists: logger.debug('.. found: {0}'.format(f.path)) try: self.config.update(Config(f.content)) except ConfigException as e: raise ConfigException(e.message, 'src: {0}'.format(f.path)) break else: logger.debug('.. no config file found') for opt in ('base_url',): if opt in self.opts: self.config[opt] = self.opts[opt] self.renderer.register({'site': self.config})
def __init__(self, name, source, configuration): super().__init__(name, source, configuration) self.path = Directory(normpath(source.path, '_containers', self.name))
def __init__(self, name, src, config): super(Items, self).__init__(name, src, config) self.path = Directory(normpath(src.path, '_containers', self.name))
def _update_config(self): self.config = deepcopy(self.defaults) logger.debug('>> Searching for config') for ext in ('.yml', '.yaml'): f = File(normpath(self.src.path, 'config' + ext)) if f.exists: logger.debug('.. found: %s', f.path) try: self.config.update(Config(f.content)) except ConfigException as e: raise ConfigException(e.message, 'src: {0}'.format(f.path)) self.config['locale'] = self.opts.get('locale', self.config['locale']) self.config['assets_url'] = Url.join(self.config['assets_url'], '') self.config['base_url'] = Url.join( self.opts.get('base_url', self.config['base_url']), '') for setting in ('archives_url', 'posts_url', 'tags_url'): self.config[setting] = Url.join(self.config[setting]) for setting in ('archives_url', 'assets_url', 'base_url', 'posts_url', 'tags_url'): if re.search(r'(?:^\.{2}/|/\.{2}$|/\.{2}/)', self.config[setting]): raise ConfigException('Invalid config setting.', 'setting: {0}'.format(setting), 'path traversal is not allowed') containers_src = normpath(self.src.path, '_containers') for name, config in self.config['containers'].iteritems(): if op.commonprefix( (containers_src, normpath(containers_src, name))) != containers_src: raise ConfigException( 'Invalid config setting.', 'setting: containers:{0}'.format(name), 'container name contains illegal characters') try: url = Url.join(config['url']) except KeyError: raise ConfigException( 'Invalid config setting.', 'setting: containers:{0}'.format(name), 'url must be set for all containers') if re.search(r'(?:^\.{2}/|/\.{2}$|/\.{2}/)', url): raise ConfigException( 'Invalid config setting.', 'setting: containers:{0}:url'.format(name), 'path traversal is not allowed') config.update( (k, v) for k, v in self.container_defaults.iteritems() if k not in config) config['url'] = url for pattern in self.config['include']: if op.commonprefix( (self.src.path, normpath(self.src.path, pattern))) != self.src.path: raise ConfigException('Invalid include path.', 'path: {0}'.format(pattern), 'path traversal is not allowed') break else: logger.debug('.. no config file found')
def _update_configuration(self): self.configuration = deepcopy(self.defaults) logger.info('>> Searching for configuration file') for configuration in product(('mynt', 'config'), ('.yml', '.yaml')): configuration = ''.join(configuration) configuration = File(normpath(self.source.path, configuration)) if not configuration.exists: continue logger.debug('.. found: %s', configuration.path) if configuration.name == 'config': logger.warn('@@ Deprecated configuration file found') logger.warn('.. rename config.yml to mynt.yml') break else: logger.debug('.. no configuration file found') return try: self.configuration.update(Configuration(configuration.content)) except ConfigurationException as error: raise ConfigurationException( error.message, 'source: {0}'.format(configuration.path)) domain = self.configuration['domain'] if domain and not domain.startswith(('https://', 'http://', '//')): logger.warn('@@ Configuration setting `domain` missing protocol') logger.warn('.. defaulting to `https`') self.configuration['domain'] = 'https://{0}'.format(domain) self.configuration['base_url'] = self.options.get('base_url') self.configuration['locale'] = self.options.get('locale') options = ('archives_url', 'assets_url', 'base_url', 'posts_url', 'tags_url') for option in options: url = URL.join(self.configuration[option], '') if re.search(r'(?:^\.{2}/|/\.{2}$|/\.{2}/)', url): raise ConfigurationException( 'Invalid configuration option', 'option: {0}'.format(self.configuration[option]), 'path traversal is not allowed') containers_source = normpath(self.source.path, '_containers') for name, options in self.configuration['containers'].items(): prefix = op.commonprefix( (containers_source, normpath(containers_source, name))) if prefix != containers_source: raise ConfigurationException( 'Invalid configuration option', 'setting: containers:{0}'.format(name), 'container name contains illegal characters') try: url = URL.join(options['url']) except KeyError: raise ConfigurationException( 'Invalid configuration option', 'setting: containers:{0}'.format(name), 'url must be set for all containers') if re.search(r'(?:^\.{2}/|/\.{2}$|/\.{2}/)', url): raise ConfigurationException( 'Invalid configuration option', 'setting: containers:{0}:url'.format(name), 'path traversal is not allowed') for name, value in self.container_defaults.items(): if name not in options: options[name] = value options['url'] = url for pattern in self.configuration['include']: prefix = op.commonprefix( (self.source.path, normpath(self.source.path, pattern))) if prefix != self.source.path: raise ConfigurationException('Invalid include path', 'path: {0}'.format(pattern), 'path traversal is not allowed')
def _update_config(self): self.config = deepcopy(self.defaults) logger.debug('>> Searching for config') for ext in ('.yml', '.yaml'): f = File(normpath(self.src.path, 'config' + ext)) if f.exists: logger.debug('.. found: %s', f.path) try: self.config.update(Config(f.content)) except ConfigException as e: raise ConfigException(e.message, 'src: {0}'.format(f.path)) self.config['locale'] = self.opts.get('locale', self.config['locale']) self.config['assets_url'] = Url.join(self.config['assets_url'], '') self.config['base_url'] = Url.join(self.opts.get('base_url', self.config['base_url']), '') for setting in ('archives_url', 'posts_url', 'tags_url'): self.config[setting] = Url.join(self.config[setting]) for setting in ('archives_url', 'assets_url', 'base_url', 'posts_url', 'tags_url'): if re.search(r'(?:^\.{2}/|/\.{2}$|/\.{2}/)', self.config[setting]): raise ConfigException('Invalid config setting.', 'setting: {0}'.format(setting), 'path traversal is not allowed') containers_src = normpath(self.src.path, '_containers') for name, config in self.config['containers'].iteritems(): if op.commonprefix((containers_src, normpath(containers_src, name))) != containers_src: raise ConfigException('Invalid config setting.', 'setting: containers:{0}'.format(name), 'container name contains illegal characters') try: url = Url.join(config['url']) except KeyError: raise ConfigException('Invalid config setting.', 'setting: containers:{0}'.format(name), 'url must be set for all containers') if re.search(r'(?:^\.{2}/|/\.{2}$|/\.{2}/)', url): raise ConfigException('Invalid config setting.', 'setting: containers:{0}:url'.format(name), 'path traversal is not allowed') config.update((k, v) for k, v in self.container_defaults.iteritems() if k not in config) config['url'] = url for pattern in self.config['include']: if op.commonprefix((self.src.path, normpath(self.src.path, pattern))) != self.src.path: raise ConfigException('Invalid include path.', 'path: {0}'.format(pattern), 'path traversal is not allowed') break else: logger.debug('.. no config file found')
def __init__(self, source, site): super().__init__('posts', source, self._get_configuration(site)) self.path = Directory(normpath(source.path, '_posts'))
def __init__(self, src, config): super(Posts, self).__init__('posts', src, config) self.path = Directory(normpath(self.src.path, '_posts')) self._update_config()
def __init__(self, src, site): super(Posts, self).__init__('posts', src, self._get_config(site)) self.path = Directory(normpath(src.path, '_posts'))