Beispiel #1
0
 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))
Beispiel #2
0
    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())
Beispiel #3
0
    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())
Beispiel #4
0
    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())
Beispiel #5
0
    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))
Beispiel #6
0
    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))
Beispiel #7
0
 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')
Beispiel #8
0
    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)
Beispiel #9
0
    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)
Beispiel #10
0
    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))
Beispiel #11
0
    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))
Beispiel #12
0
    def _get_path(self, url):
        parts = [self.dest.path] + url.split('/')

        if url.endswith('/'):
            parts.append('index.html')

        return normpath(*parts)
Beispiel #13
0
    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}))))
Beispiel #14
0
 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))
Beispiel #15
0
 def _get_path(self, url):
     parts = [self.dest.path] + url.split('/')
     
     if url.endswith('/'):
         parts.append('index.html')
     
     return normpath(*parts)
Beispiel #16
0
 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)
Beispiel #17
0
    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)))
Beispiel #18
0
 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)
Beispiel #19
0
 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())
Beispiel #20
0
    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)
Beispiel #21
0
    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())
Beispiel #22
0
 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}))
             ))
Beispiel #23
0
 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)
Beispiel #24
0
 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))
Beispiel #25
0
Datei: fs.py Projekt: NaPs/mynt
 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))
Beispiel #26
0
 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))
Beispiel #27
0
 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
Beispiel #28
0
    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
Beispiel #29
0
    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))
Beispiel #30
0
 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
Beispiel #31
0
    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))
Beispiel #32
0
 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
Beispiel #33
0
    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)
Beispiel #34
0
 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')
Beispiel #35
0
    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')
Beispiel #36
0
    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})
Beispiel #37
0
 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})
Beispiel #38
0
    def __init__(self, name, source, configuration):
        super().__init__(name, source, configuration)

        self.path = Directory(normpath(source.path, '_containers', self.name))
Beispiel #39
0
 def __init__(self, name, src, config):
     super(Items, self).__init__(name, src, config)
     
     self.path = Directory(normpath(src.path, '_containers', self.name))
Beispiel #40
0
    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')
Beispiel #41
0
    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')
Beispiel #42
0
    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')
Beispiel #43
0
    def __init__(self, source, site):
        super().__init__('posts', source, self._get_configuration(site))

        self.path = Directory(normpath(source.path, '_posts'))
Beispiel #44
0
    def __init__(self, src, config):
        super(Posts, self).__init__('posts', src, config)

        self.path = Directory(normpath(self.src.path, '_posts'))

        self._update_config()
Beispiel #45
0
 def __init__(self, src, site):
     super(Posts, self).__init__('posts', src, self._get_config(site))
     
     self.path = Directory(normpath(src.path, '_posts'))
Beispiel #46
0
 def __init__(self, src, config):
     super(Posts, self).__init__('posts', src, config)
     
     self.path = Directory(normpath(self.src.path, '_posts'))
     
     self._update_config()