Example #1
0
    def generate(self, conf, env, data, **kwargs):

        if self.pagination is None:
            self.items_per_page = 2**32
            self.pagination = self.path

        ipp = self.items_per_page
        tt = env.engine.fromfile(env, self.template)

        route = expand(self.path, kwargs)
        entrylist = data['entrylist']
        paginator = paginate(entrylist, ipp, route, conf.default_orphans)

        for (next, curr, prev), entrylist, modified in paginator:

            next = None if next is None \
                else link(u'Next', expand(self.path, kwargs)) if next == 1 \
                    else link(u'Next', expand(self.pagination, union({'num': next}, kwargs)))

            curr = link(curr, expand(self.path, kwargs)) if curr == 1 \
                else link(curr, expand(self.pagination, union({'num': curr}, kwargs)))

            prev = None if prev is None \
               else link(u'Previous', expand(self.pagination, union({'num': prev}, kwargs)))

            path = joinurl(conf['output_dir'], curr.href)

            if isfile(path) and not (modified or tt.modified or env.modified or conf.modified):
                event.skip(self.__class__.__name__.lower(), path)
                continue

            html = self.render(conf, env, union(locals(), kwargs))
            yield html, path
Example #2
0
    def generate(self, conf, env, request):
        for lang in env.langs:
            for entry in self._get_page_list(request, lang):
                path = ''
                route = strip_default_lang(expand(self.path, entry), self.conf)

                if entry.hasproperty('permalink'):
                    path = joinurl(self.conf['output_dir'], entry.permalink)
                elif lang == self.conf.lang_code:
                    path = joinurl(self.conf['output_dir'], route, '/')
                else:
                    path = joinurl(self.conf['output_dir'], expand(self.path, entry))

                if path.endswith('/'):
                    path = joinurl(path, 'index.html')

                request['env']['path'] = '/'
                request['env']['lang'] = lang
                request['env']['active_route'] = route

                tt = env.engine.fromfile(self.template)
                html = tt.render(conf=conf, entry=entry, env=union(env,
                    type=self.__class__.__name__.lower(), route=route))

                yield html, path
Example #3
0
    def generate(self, request):

        entrylist = sorted((e for e in request['entrylist'] if not e.draft),
                        key=lambda k: k.date, reverse=True)

        tt = self.env.tt.fromfile(self.template)
        path = joinurl(self.conf['output_dir'], self.path, 'index.html')

        hv = md5(*entrylist, attr=lambda o: o.md5)
        rv = memoize('articles-hash')

        if rv == hv:
            has_changed = False
        else:
            # save new value for next run
            memoize('articles-hash', hv)
            has_changed = True

        if exists(path) and not has_changed and not tt.has_changed:
            event.skip(path)
            raise StopIteration

        articles = {}
        for entry in entrylist:
            articles.setdefault((entry.year, entry.month), []).append(entry)

        html = tt.render(conf=self.conf, articles=articles,
                         env=union(self.env, num_entries=len(entrylist)))

        yield html, path
Example #4
0
    def generate(self, request):
        """Creates nicely paged listing of your posts.  First page is the
        index.hml used to have this nice url: http://yourblog.com/ with a recent
        list of your (e.g. summarized) Posts. Other pages are enumerated to /page/n+1
        """

        ipp = self.items_per_page
        tt = self.env.jinja2.get_template('main.html')

        entrylist = [entry for entry in request['entrylist'] if not entry.draft]
        paginator = paginate(entrylist, ipp, orphans=self.conf['default_orphans'])

        for (next, curr, prev), entries, has_changed in paginator:
            # curr = current page, next = newer pages, prev = older pages

            if next is not None:
                next = self.path.rstrip('/') if next == 1 \
                           else expand(self.pagination, {'num': next})

            curr = self.path if curr == 1 else expand(self.pagination, {'num': curr})
            prev = None if prev is None else expand(self.pagination, {'num': prev})
            path = joinurl(self.conf['output_dir'], curr, 'index.html')

            if exists(path) and not has_changed and not tt.has_changed:
                event.skip(path)
                continue

            html = tt.render(conf=self.conf, env=union(self.env, entrylist=entries,
                                  type='index', prev=prev, curr=curr, next=next,
                                  items_per_page=ipp, num_entries=len(entrylist)))

            yield html, path
Example #5
0
    def transform(self, content, entry, *args):
        options = helpers.union(Introduction.defaults,
                                self.conf.fetch('intro_'))

        try:
            options.update(entry.intro)
        except AttributeError:
            pass

        try:
            maxparagraphs = int(options.get('maxparagraphs') or args[0])
        except (IndexError, ValueError) as ex:
            if isinstance(ex, ValueError):
                log.warn('Introduction: invalid maxparagraphs argument %r',
                         options.get('maxparagraphs') or args[0])
            maxparagraphs = 1

        try:
            return ''.join(
                Introducer(content, maxparagraphs,
                           self.env.path + entry.permalink, options).result)
        except:
            log.exception('could not extract intro from ' + entry.filename)
            return content
        return content
Example #6
0
    def generate(self, conf, env, data):

        ipp = self.items_per_page
        tt = env.engine.fromfile(self.template)

        entrylist = data['entrylist']
        paginator = paginate(entrylist, ipp, self.path, conf.default_orphans)
        route = self.path

        for (next, curr, prev), entries, modified in paginator:
            # curr = current page, next = newer pages, prev = older pages

            next = None if next is None \
                else link(u'« Next', self.path.rstrip('/')) if next == 1 \
                    else link(u'« Next', expand(self.pagination, {'num': next}))

            curr = link(curr, self.path) if curr == 1 \
                else link(expand(self.pagination, {'num': curr}))

            prev = None if prev is None \
               else link(u'Previous »', expand(self.pagination, {'num': prev}))

            path = joinurl(conf['output_dir'], curr.href, 'index.html')

            if isfile(path) and not (modified or tt.modified or env.modified or conf.modified):
                event.skip(path)
                continue

            html = tt.render(conf=conf, env=union(env, entrylist=entries,
                                  type='index', prev=prev, curr=curr, next=next,
                                  items_per_page=ipp, num_entries=len(entrylist), route=route))
            yield html, path
Example #7
0
    def generate(self, request):
        entrylist = filter(lambda e: not e.draft, request['entrylist'])
        entrylist = list(entrylist)[0:self.num_entries]
        tt = self.env.engine.fromfile('%s.xml' % self.type)

        path = joinurl(self.conf['output_dir'], self.path)
        if not path.endswith(('.xml', '.html')):
            path = joinurl(path, 'index.html')

        # detect removed entries
        hv = md5(*entrylist, attr=lambda e: e.permalink)
        if memoize(path) != hv:
            memoize(path, hv)
            has_changed = True
        else:
            has_changed = False

        if (exists(path) and not filter(lambda e: e.has_changed, entrylist) and
            not has_changed and not tt.has_changed):
            event.skip(path)
            raise StopIteration

        updated = entrylist[0].date if entrylist else datetime.utcnow()
        html = tt.render(conf=self.conf, env=union(self.env, route=self.path,
                         updated=updated, entrylist=entrylist))

        yield html, path
Example #8
0
    def generate(self, request):

        tt = self.env.jinja2.get_template('main.html')

        entrylist = request['entrylist']
        pathes = dict()

        for entry in entrylist:
            if entry.permalink != expand(self.path, entry):
                p = joinurl(self.conf['output_dir'], entry.permalink)
            else:
                p = joinurl(self.conf['output_dir'], expand(self.path, entry))

            if p.endswith('/'):
                p = joinurl(p, 'index.html')

            if p in pathes:
                raise AcrylamidException("title collision %r in %r" % (entry.permalink,
                                                                       entry.filename))
            pathes[p] = entry

        for path, entry in pathes.iteritems():
            if exists(path) and not entry.has_changed and not tt.has_changed:
                event.skip(path)
                continue

            html = tt.render(env=union(self.env, entrylist=[entry], type='entry'),
                             conf=self.conf, entry=entry)

            yield html, path
Example #9
0
    def generate(self, request):

        entrylist = sorted((e for e in request['entrylist'] if not e.draft),
                           key=lambda k: k.date,
                           reverse=True)

        tt = self.env.engine.fromfile(self.template)
        path = joinurl(self.conf['output_dir'], self.path, 'index.html')

        hv = md5(*entrylist, attr=lambda o: o.md5)
        rv = memoize('articles-hash')

        if rv == hv:
            has_changed = False
        else:
            # save new value for next run
            memoize('articles-hash', hv)
            has_changed = True

        if exists(path) and not has_changed and not tt.has_changed:
            event.skip(path)
            raise StopIteration

        articles = {}
        for entry in entrylist:
            articles.setdefault((entry.year, entry.imonth), []).append(entry)

        route = self.path
        html = tt.render(conf=self.conf,
                         articles=articles,
                         env=union(self.env,
                                   num_entries=len(entrylist),
                                   route=route))

        yield html, path
Example #10
0
    def generate(self, request):

        ipp = self.items_per_page
        tt = self.env.engine.fromfile(self.template)

        entrylist = [entry for entry in request['entrylist'] if not entry.draft]
        paginator = paginate(entrylist, ipp, orphans=self.conf['default_orphans'])
        route = self.path

        for (next, curr, prev), entries, has_changed in paginator:
            # curr = current page, next = newer pages, prev = older pages

            next = None if next is None \
                else link(u'« Next', self.path.rstrip('/')) if next == 1 \
                    else link(u'« Next', expand(self.pagination, {'num': next}))

            curr = link(curr, self.path) if curr == 1 \
                else link(expand(self.pagination, {'num': curr}))

            prev = None if prev is None \
               else link(u'Previous »', expand(self.pagination, {'num': prev}))

            path = joinurl(self.conf['output_dir'], curr.href, 'index.html')

            if exists(path) and not has_changed and not tt.has_changed:
                event.skip(path)
                continue

            html = tt.render(conf=self.conf, env=union(self.env, entrylist=entries,
                                  type='index', prev=prev, curr=curr, next=next,
                                  items_per_page=ipp, num_entries=len(entrylist), route=route))

            yield html, path
Example #11
0
    def generate(self, request):
        """Creates paged listing by tag."""

        ipp = self.items_per_page
        tt = self.env.engine.fromfile(self.template)

        for tag in self.tags:

            entrylist = [entry for entry in self.tags[tag]]
            paginator = paginate(entrylist, ipp, salt=tag, orphans=self.conf["default_orphans"])
            route = expand(self.path, {"name": tag}).rstrip("/")

            for (next, curr, prev), entries, has_changed in paginator:

                # e.g.: curr = /page/3, next = /page/2, prev = /page/4

                next = (
                    None
                    if next is None
                    else link(u"« Next", expand(self.path, {"name": tag}).rstrip("/"))
                    if next == 1
                    else link(u"« Next", expand(self.pagination, {"name": tag, "num": next}))
                )

                curr = (
                    link(curr, expand(self.path, {"name": tag}))
                    if curr == 1
                    else link(expand(self.pagination, {"num": curr, "name": tag}))
                )

                prev = (
                    None if prev is None else link(u"Previous »", expand(self.pagination, {"name": tag, "num": prev}))
                )

                path = joinurl(self.conf["output_dir"], curr, "index.html")

                if exists(path) and not has_changed and not tt.has_changed:
                    event.skip(path)
                    continue

                html = tt.render(
                    conf=self.conf,
                    env=union(
                        self.env,
                        entrylist=entries,
                        type="tag",
                        prev=prev,
                        curr=curr,
                        next=next,
                        tag=tag,
                        items_per_page=ipp,
                        num_entries=len(entrylist),
                        route=route,
                    ),
                )

                yield html, path
Example #12
0
    def generate(self, conf, env, data):

        tt = env.engine.fromfile(env, self.template)
        keyfunc = lambda k: ()

        if '/:year' in self.path:
            keyfunc = lambda k: (k.year, )
        if '/:month' in self.path:
            keyfunc = lambda k: (k.year, k.imonth)
        if '/:day' in self.path:
            keyfunc = lambda k: (k.year, k.imonth, k.iday)

        for next, curr, prev in neighborhood(
                groupby(data['entrylist'], keyfunc)):

            salt, group = '-'.join(str(i) for i in curr[0]), list(curr[1])
            modified = memoize('archive-' + salt, hash(*group)) or any(
                e.modified for e in group)

            if prev:
                prev = link(u'/'.join('%02i' % i for i in prev[0]),
                            expand(self.path, prev[1][0]))
            if next:
                next = link(u'/'.join('%02i' % i for i in next[0]),
                            expand(self.path, next[1][0]))

            route = expand(self.path, group[0])
            path = joinurl(conf['output_dir'], route)

            # an object storing year, zero-padded month and day as attributes (may be None)
            key = type(
                'Archive', (object, ),
                dict(
                    zip(('year', 'month', 'day'),
                        map(lambda x: '%02i' % x if x else None,
                            keyfunc(group[0])))))()

            if isfile(path) and not (modified or tt.modified or env.modified
                                     or conf.modified):
                event.skip('archive', path)
                continue

            html = tt.render(conf=conf,
                             env=union(env,
                                       entrylist=group,
                                       type='archive',
                                       prev=prev,
                                       curr=link(route),
                                       next=next,
                                       num_entries=len(group),
                                       route=route,
                                       archive=key))

            yield html, path
Example #13
0
    def generate(self, request):
        """Creates paged listing by tag."""

        ipp = self.items_per_page
        tt = self.env.engine.fromfile(self.template)

        entrylist = [
            entry for entry in request['entrylist'] if not entry.draft
        ]

        for tag in self.tags:

            entrylist = [entry for entry in self.tags[tag]]
            paginator = paginate(entrylist,
                                 ipp,
                                 salt=tag,
                                 orphans=self.conf['default_orphans'])
            route = expand(self.path, {'name': tag}).rstrip('/')

            for (next, curr, prev), entries, has_changed in paginator:

                # e.g.: curr = /page/3, next = /page/2, prev = /page/4

                next = None if next is None \
                else link(u'« Next', expand(self.path, {'name': tag}).rstrip('/')) if next == 1 \
                    else link(u'« Next', expand(self.pagination, {'name': tag, 'num': next}))

                curr = link(curr, expand(self.path, {'name': tag})) if curr == 1 \
                    else link(expand(self.pagination, {'num': curr, 'name': tag}))

                prev = None if prev is None \
                    else link(u'Previous »', expand(self.pagination, {'name': tag, 'num': prev}))

                path = joinurl(self.conf['output_dir'], curr, 'index.html')

                if exists(path) and not has_changed and not tt.has_changed:
                    event.skip(path)
                    continue

                html = tt.render(conf=self.conf,
                                 env=union(self.env,
                                           entrylist=entries,
                                           type='tag',
                                           prev=prev,
                                           curr=curr,
                                           next=next,
                                           tag=tag,
                                           items_per_page=ipp,
                                           num_entries=len(entrylist),
                                           route=route))

                yield html, path
Example #14
0
    def generate(self, conf, env, data):
        for lang in env.langs:
            ipp = self.items_per_page
            tt = env.engine.fromfile(self.template)

            entrylist = []
            for entry in data['entrylist']:
                try:
                    e = entry_for_lang(data, lang, entry)
                    entrylist.append(e)
                except TranslationNotFound:
                    pass#entrylist.append(entry)

            paginator = paginate(entrylist, ipp, self.path, conf.default_orphans)
            route = '/blog/'

            for (next, curr, prev), entries, modified in paginator:
                # curr = current page, next = newer pages, prev = older pages

                if next is None:
                    pass
                elif next == 1:
                    next = link(u'« Next', expand(self.path.rstrip('/'), {'lang':lang}))
                else:
                    next = link(u'« Next', expand(self.pagination, {'num': next,'lang': lang}))

                if next:
                    next.href = strip_default_lang(next.href, self.conf)

                curr = link(curr, self.path) if curr == 1 \
                    else link(expand(self.pagination, {'num': curr,'lang': lang}))
                curr.href = strip_default_lang(curr.href, self.conf)

                prev = None if prev is None \
                   else link(u'Previous »', expand(self.pagination, {'num': prev,'lang': lang}))
                if prev:
                    prev.href = strip_default_lang(prev.href, self.conf)

                path = joinurl(conf['output_dir'], expand(curr.href, {'lang': lang}), 'index.html')
                path = strip_default_lang(path, self.conf)
                env['lang'] = lang
                env['active_route'] = route

                if isfile(path) and not (modified or tt.modified or env.modified or conf.modified):
                    event.skip(path)
                    continue

                html = tt.render(conf=conf, env=union(env, entrylist=entries,
                                      type='index', prev=prev, curr=curr, next=next,
                                      items_per_page=ipp, num_entries=len(entrylist), route=route))
                yield html, path
Example #15
0
    def generate(self, conf, env, data):

        pathes, entrylist = set(), data[self.type]
        unmodified = not env.modified and not conf.modified

        for i, entry in enumerate(entrylist):

            if entry.hasproperty('permalink'):
                path = joinurl(conf['output_dir'], entry.permalink)
            else:
                path = joinurl(conf['output_dir'], expand(self.path, entry))

            if isfile(path) and path in pathes:
                try:
                    os.remove(path)
                finally:
                    other = [e.filename for e in entrylist
                        if e is not entry and e.permalink == entry.permalink][0]
                    log.error("title collision %s caused by %s and %s",
                              entry.permalink, entry.filename, other)
                    raise SystemExit

            pathes.add(path)
            next, prev = self.next(entrylist, i), self.prev(entrylist, i)

            # per-entry template
            tt = env.engine.fromfile(env, entry.props.get('layout', self.template))

            if all([isfile(path), unmodified, not tt.modified, not entry.modified,
            not modified(*references(entry))]):
                event.skip(self.name, path)
            else:
                html = tt.render(conf=conf, entry=entry, env=union(env,
                                 entrylist=[entry], type=self.__class__.__name__.lower(),
                                 prev=prev, next=next, route=expand(self.path, entry)))
                yield html, path

            # check if any resources need to be moved
            if entry.hasproperty('copy'):
                for res_src in entry.resources:
                    res_dest = join(dirname(path), basename(res_src))
                    # Note, presence of res_src check in FileReader.getresources
                    if isfile(res_dest) and getmtime(res_dest) > getmtime(res_src):
                        event.skip(self.name, res_dest)
                        continue
                    try:
                        fp = io.open(res_src, 'rb')
                        # use mkfile rather than yield so different ns can be specified (and filtered by sitemap)
                        mkfile(fp, res_dest, ns='resource', force=env.options.force, dryrun=env.options.dryrun)
                    except IOError as e:
                        log.warn("Failed to copy resource '%s' whilst processing '%s' (%s)" % (res_src, entry.filename, e.strerror))
Example #16
0
    def generate(self, conf, env, data):
        for lang in env.langs:
            entrylist = []
            for entry in data[self.type]:
                try:
                    e = entry_for_lang(data, lang, entry)
                    entrylist.append(e)
                except TranslationNotFound:
                    entrylist.append(entry)

            unmodified = not env.modified and not conf.modified

            for i, entry in enumerate(entrylist):
                route = strip_default_lang(expand(self.path, entry), self.conf)
                if entry.hasproperty('permalink'):
                    path = joinurl(conf['output_dir'], entry.permalink)
                elif lang == self.conf.lang_code:
                    path = joinurl(self.conf['output_dir'], route, '/')
                    entry.permalink = route
                else:
                    path = joinurl(self.conf['output_dir'],
                                   expand(self.path, entry))
                    entry.permalink = route

                if path.endswith('/'):
                    path = joinurl(path, 'index.html')

                next, prev = self.next(entrylist, i), self.prev(entrylist, i)
                env['lang'] = lang
                env['active_route'] = route

                # per-entry template
                tt = env.engine.fromfile(entry.props.get('layout', self.template))

                if all([isfile(path), unmodified, not tt.modified, not entry.modified,
                        not modified(*references(entry))]):
                    event.skip(self.name, path)
                    continue

                html = tt.render(conf=conf, entry=entry, env=union(env,
                                                                   entrylist=[entry],
                                                                   type=self.__class__.__name__.lower(),
                                                                   prev=prev, next=next,
                                                                   route=expand(
                                                                       self.path,
                                                                       entry)))

                yield html, path
Example #17
0
    def generate(self, conf, env, data):
        entrylist = data['entrylist']
        entrylist = list(entrylist)[0:self.num_entries]
        tt = env.engine.fromfile('%s.xml' % self.type)

        path = joinurl(conf['output_dir'], self.route)
        modified = any(entry.modified for entry in entrylist)

        if isfile(path) and not (conf.modified or env.modified or tt.modified or modified):
            event.skip(self.name, path)
            raise StopIteration

        updated = entrylist[0].date if entrylist else datetime.utcnow()
        html = tt.render(conf=conf, env=union(env, route=self.route,
                         updated=updated, entrylist=entrylist))
        yield html, path
Example #18
0
    def generate(self, request):

        tt = self.env.engine.fromfile(self.template)
        pathes = set()

        nondrafts, drafts = [], []
        for entry in request[self.type]:
            if not entry.draft:
                nondrafts.append(entry)
            else:
                drafts.append(entry)

        for isdraft, entrylist in enumerate([nondrafts, drafts]):
            has_changed = self.has_changed(entrylist, 'draft' if isdraft else 'entry')

            for i, entry in enumerate(entrylist):

                if entry.hasproperty('permalink'):
                    path = joinurl(self.conf['output_dir'], entry.permalink)
                else:
                    path = joinurl(self.conf['output_dir'], expand(self.path, entry))

                if path.endswith('/'):
                    path = joinurl(path, 'index.html')

                if isfile(path) and path in pathes:
                    try:
                        os.remove(path)
                    finally:
                        f = lambda e: e is not entry and e.permalink == entry.permalink
                        raise AcrylamidException("title collision %r in %r with %r." %
                            (entry.permalink, entry.filename, filter(f, entrylist)[0].filename))

                pathes.add(path)
                next = self.next(entrylist, i) if not isdraft else None
                prev = self.prev(entrylist, i) if not isdraft else None

                if isfile(path) and not any([has_changed, entry.has_changed, tt.has_changed]):
                    event.skip(path)
                    continue

                route = expand(self.path, entry)
                html = tt.render(conf=self.conf, entry=entry, env=union(self.env,
                                 entrylist=[entry], type=self.__class__.__name__.lower(),
                                 prev=prev, next=next, route=route))

                yield html, path
Example #19
0
    def generate(self, request):

        tt = self.env.tt.fromfile(self.template)

        entrylist = request['entrylist']
        pathes = dict()

        for entry in entrylist:
            if entry.permalink != expand(self.path, entry):
                p = joinurl(self.conf['output_dir'], entry.permalink)
            else:
                p = joinurl(self.conf['output_dir'], expand(self.path, entry))

            if p.endswith('/'):
                p = joinurl(p, 'index.html')

            if p in pathes:
                raise AcrylamidException("title collision %r in %r" % (entry.permalink,
                                                                       entry.filename))
            pathes[p] = entry

        has_changed = False
        hv = md5(*entrylist, attr=lambda e: e.permalink)

        if memoize('entry-permalinks') != hv:
            memoize('entry-permalinks', hv)
            has_changed = True

        pathes = sorted(pathes.iteritems(), key=lambda k: k[1].date, reverse=True)
        for i, (path, entry) in enumerate(pathes):

            next = None if i == 0 else link(entrylist[i-1].title,
                                            entrylist[i-1].permalink.rstrip('/'),
                                            entrylist[i-1])
            prev = None if i == len(pathes) - 1 else link(entrylist[i+1].title,
                                                          entrylist[i+1].permalink.rstrip('/'),
                                                          entrylist[i+1])

            if exists(path) and not any([has_changed, entry.has_changed, tt.has_changed]):
                event.skip(path)
                continue

            html = tt.render(conf=self.conf, entry=entry, env=union(self.env,
                             entrylist=[entry], type='entry', prev=prev, next=next))

            yield html, path
Example #20
0
    def generate(self, conf, env, data):

        entrylist = data['entrylist']

        tt = env.engine.fromfile(env, self.template)
        path = joinurl(conf['output_dir'], self.path, 'index.html')

        if exists(path) and not (conf.modified or env.modified or tt.modified):
            event.skip('article', path)
            raise StopIteration

        articles = {}
        for entry in entrylist:
            articles.setdefault((entry.year, entry.imonth), []).append(entry)

        html = tt.render(conf=conf, articles=articles, env=union(env,
                         num_entries=len(entrylist), route=self.path))
        yield html, path
Example #21
0
    def generate(self, request):

        ipp = self.items_per_page
        tt = self.env.engine.fromfile(self.template)

        entrylist = [
            entry for entry in request['entrylist'] if not entry.draft
        ]
        paginator = paginate(entrylist,
                             ipp,
                             orphans=self.conf['default_orphans'])
        route = self.path

        for (next, curr, prev), entries, has_changed in paginator:
            # curr = current page, next = newer pages, prev = older pages

            next = None if next is None \
                else link(u'« Next', self.path.rstrip('/')) if next == 1 \
                    else link(u'« Next', expand(self.pagination, {'num': next}))

            curr = link(curr, self.path) if curr == 1 \
                else link(expand(self.pagination, {'num': curr}))

            prev = None if prev is None \
               else link(u'Previous »', expand(self.pagination, {'num': prev}))

            path = joinurl(self.conf['output_dir'], curr.href, 'index.html')

            if exists(path) and not has_changed and not tt.has_changed:
                event.skip(path)
                continue

            html = tt.render(conf=self.conf,
                             env=union(self.env,
                                       entrylist=entries,
                                       type='index',
                                       prev=prev,
                                       curr=curr,
                                       next=next,
                                       items_per_page=ipp,
                                       num_entries=len(entrylist),
                                       route=route))

            yield html, path
Example #22
0
    def generate(self, request):
        entrylist = filter(lambda e: not e.draft, request['entrylist'])
        entrylist = list(entrylist)[0:self.num_entries]
        tt = self.env.engine.fromfile('%s.xml' % self.type)

        path = joinurl(self.conf['output_dir'], self.path)
        if not path.endswith(('.xml', '.html')):
            path = joinurl(path, 'index.html')

        if exists(path) and not filter(lambda e: e.has_changed, entrylist):
            if not tt.has_changed:
                event.skip(path)
                raise StopIteration

        updated = entrylist[0].date if entrylist else datetime.now()
        html = tt.render(conf=self.conf, env=union(self.env, path=self.path,
                         updated=updated, entrylist=entrylist))

        yield html, path
Example #23
0
    def generate(self, request):
        entrylist = filter(lambda e: not e.draft, request['entrylist'])
        entrylist = list(entrylist)[0:self.num_entries]
        tt = self.env.engine.fromfile('%s.xml' % self.type)

        path = joinurl(self.conf['output_dir'], self.path)
        if not path.endswith(('.xml', '.html')):
            path = joinurl(path, 'index.html')

        if exists(path) and not filter(lambda e: e.has_changed, entrylist):
            if not tt.has_changed:
                event.skip(path)
                raise StopIteration

        updated = entrylist[0].date if entrylist else datetime.utcnow()
        html = tt.render(conf=self.conf, env=union(self.env, route=self.path,
                         updated=updated, entrylist=entrylist))

        yield html, path
Example #24
0
    def generate(self, request):

        tt = self.env.engine.fromfile(self.template)

        entrylist = request[self.type]
        pathes = set()

        has_changed = self.has_changed(entrylist)

        for i, entry in enumerate(entrylist):

            if entry.hasproperty('permalink'):
                path = joinurl(self.conf['output_dir'], entry.permalink)
            else:
                path = joinurl(self.conf['output_dir'], expand(self.path, entry))

            if path.endswith('/'):
                path = joinurl(path, 'index.html')

            if isfile(path) and path in pathes:
                try:
                    os.remove(path)
                finally:
                    f = lambda e: e is not entry and e.permalink == entry.permalink
                    raise AcrylamidException("title collision %r in %r with %r." %
                        (entry.permalink, entry.filename, filter(f, entrylist)[0].filename))

            next, prev = self.next(entrylist, i), self.prev(entrylist, i)

            # detect collisions
            pathes.add(path)

            if isfile(path) and not any([has_changed, entry.has_changed, tt.has_changed]):
                event.skip(path)
                continue

            route = expand(self.path, entry)
            html = tt.render(conf=self.conf, entry=entry, env=union(self.env,
                             entrylist=[entry], type=self.__class__.__name__.lower(),
                             prev=prev, next=next, route=route))

            yield html, path
Example #25
0
    def transform(self, content, entry, *args):
        options = helpers.union(Summarize.defaults, self.conf.fetch("summarize_"))

        try:
            options.update(entry.summarize)
        except AttributeError:
            pass

        try:
            maxwords = int(options.get("maxwords") or args[0])
        except (IndexError, ValueError) as ex:
            if isinstance(ex, ValueError):
                log.warn("Summarize: invalid maxwords argument %r", options.get("maxwords") or args[0])
            maxwords = 100

        try:
            return "".join(Summarizer(content, maxwords, self.env.path + entry.permalink, options).result)
        except HTMLParseError:
            log.exception("could not summarize " + entry.filename)
            return content
Example #26
0
    def generate(self, request):

        entrylist = filter(lambda e: not e.draft, request['entrylist'])[:self.num_entries]
        tt = self.env.jinja2.get_template('%s.xml' % self.__class__.__name__.lower())

        path = joinurl(self.conf['output_dir'], self.path)
        if not filter(lambda e: path.endswith(e), ['.xml', '.html']):
            path = joinurl(path, 'index.html')


        if exists(path) and not filter(lambda e: e.has_changed, entrylist):
            if not tt.has_changed:
                event.skip(path)
                raise StopIteration

        updated=entrylist[0].date if entrylist else datetime.now()
        html = tt.render(conf=self.conf, env=union(self.env,
                         updated=updated, entrylist=entrylist))

        yield html, path
Example #27
0
    def generate(self, request):

        tt = self.env.engine.fromfile(self.template)

        entrylist = request[self.type]
        pathes = set()

        has_changed = self.has_changed(entrylist)

        for i, entry in enumerate(entrylist):

            if entry.hasproperty('permalink'):
                path = joinurl(self.conf['output_dir'], entry.permalink)
            else:
                path = joinurl(self.conf['output_dir'], expand(self.path, entry))

            if path.endswith('/'):
                path = joinurl(path, 'index.html')

            if isfile(path) and path in pathes:
                try:
                    os.remove(path)
                finally:
                    f = lambda e: e is not entry and e.permalink == entry.permalink
                    raise AcrylamidException("title collision %r in %r with %r." %
                        (entry.permalink, entry.filename, filter(f, entrylist)[0].filename))

            next, prev = self.next(entrylist, i), self.prev(entrylist, i)

            # detect collisions
            pathes.add(path)

            if isfile(path) and not any([has_changed, entry.has_changed, tt.has_changed]):
                event.skip(path)
                continue

            html = tt.render(conf=self.conf, entry=entry, env=union(self.env,
                             entrylist=[entry], type=self.__class__.__name__.lower(),
                             prev=prev, next=next))

            yield html, path
Example #28
0
    def generate(self, request):
        """Creates paged listing by tag."""

        ipp = self.items_per_page
        tt = self.env.jinja2.get_template('main.html')

        entrylist = [entry for entry in request['entrylist'] if not entry.draft]

        for tag in self.tags:

            entrylist = [entry for entry in self.tags[tag]]
            paginator = paginate(entrylist, ipp, salt=tag, orphans=self.conf['default_orphans'])

            for (next, curr, prev), entries, has_changed in paginator:

                # e.g.: curr = /page/3, next = /page/2, prev = /page/4

                if next == 1:
                    next = expand(self.path, {'name': tag}).rstrip('/')
                elif next > 1:
                    next = expand(self.pagination, {'name': tag, 'num': next})

                if curr == 1:
                    curr = expand(self.path, {'name': tag})
                elif curr > 1:
                    curr = expand(self.pagination, {'num': curr, 'name': tag})

                if prev is not None:
                    prev = expand(self.pagination, {'name': tag, 'num': prev})

                path = joinurl(self.conf['output_dir'], curr, 'index.html')

                if exists(path) and not has_changed and not tt.has_changed:
                    event.skip(path)
                    continue

                html = tt.render(conf=self.conf, env=union(self.env, entrylist=entries,
                                type='tag', prev=prev, curr=curr, next=next,
                                items_per_page=ipp, num_entries=len(entrylist)))

                yield html, path
Example #29
0
    def generate(self, conf, env, data):

        entrylist = data['entrylist']

        tt = env.engine.fromfile(env, self.template)
        path = joinurl(conf['output_dir'], self.path, 'index.html')

        if exists(path) and not (conf.modified or env.modified or tt.modified):
            event.skip('article', path)
            raise StopIteration

        articles = {}
        for entry in entrylist:
            articles.setdefault((entry.year, entry.imonth), []).append(entry)

        html = tt.render(conf=conf,
                         articles=articles,
                         env=union(env,
                                   num_entries=len(entrylist),
                                   route=self.path))
        yield html, path
Example #30
0
    def generate(self, request):
        """Creates paged listing by tag."""

        ipp = self.items_per_page
        tt = self.env.engine.fromfile(self.template)

        entrylist = [entry for entry in request['entrylist'] if not entry.draft]

        for tag in self.tags:

            entrylist = [entry for entry in self.tags[tag]]
            paginator = paginate(entrylist, ipp, salt=tag, orphans=self.conf['default_orphans'])
            route = expand(self.path, {'name': tag}).rstrip('/')

            for (next, curr, prev), entries, has_changed in paginator:

                # e.g.: curr = /page/3, next = /page/2, prev = /page/4

                next = None if next is None \
                else link(u'« Next', expand(self.path, {'name': tag}).rstrip('/')) if next == 1 \
                    else link(u'« Next', expand(self.pagination, {'name': tag, 'num': next}))

                curr = link(curr, expand(self.path, {'name': tag})) if curr == 1 \
                    else link(expand(self.pagination, {'num': curr, 'name': tag}))

                prev = None if prev is None \
                    else link(u'Previous »', expand(self.pagination, {'name': tag, 'num': prev}))

                path = joinurl(self.conf['output_dir'], curr, 'index.html')

                if exists(path) and not has_changed and not tt.has_changed:
                    event.skip(path)
                    continue

                html = tt.render(conf=self.conf, env=union(self.env, entrylist=entries,
                                type='tag', prev=prev, curr=curr, next=next, tag=tag,
                                items_per_page=ipp, num_entries=len(entrylist), route=route))

                yield html, path
Example #31
0
    def transform(self, content, entry, *args):
        options = helpers.union(Summarize.defaults, self.conf.fetch('summarize_'))

        try:
            options.update(entry.summarize)
        except AttributeError:
            pass

        try:
            maxwords = int(options.get('maxwords') or args[0])
        except (IndexError, ValueError) as ex:
            if isinstance(ex, ValueError):
                log.warn('Summarize: invalid maxwords argument %r',
                         options.get('maxwords') or args[0])
            maxwords = 100

        try:
            return ''.join(Summarizer(
                content, maxwords, self.env.path+entry.permalink, options).result)
        except HTMLParseError as e:
            log.warn('%s: %s in %s' % (e.__class__.__name__, e.msg, entry.filename))
            return content
Example #32
0
    def generate(self, conf, env, data):

        tt = env.engine.fromfile(env, self.template)
        keyfunc = lambda k: ( )

        if '/:year' in self.path:
            keyfunc = lambda k: (k.year, )
        if '/:month' in self.path:
            keyfunc = lambda k: (k.year, k.imonth)
        if '/:day' in self.path:
            keyfunc = lambda k: (k.year, k.imonth, k.iday)

        for next, curr, prev in neighborhood(groupby(data['entrylist'], keyfunc)):

            salt, group = '-'.join(str(i) for i in curr[0]), list(curr[1])
            modified = memoize('archive-' + salt, hash(*group)) or any(e.modified for e in group)

            if prev:
                prev = link(u'/'.join('%02i' % i for i in prev[0]), expand(self.path, prev[1][0]))
            if next:
                next = link(u'/'.join('%02i' % i for i in next[0]), expand(self.path, next[1][0]))

            route = expand(self.path, group[0])
            path = joinurl(conf['output_dir'], route)

            # an object storing year, zero-padded month and day as attributes (may be None)
            key = type('Archive', (object, ), dict(zip(('year', 'month', 'day'),
                map(lambda x: '%02i' % x if x else None, keyfunc(group[0]))
            )))()

            if isfile(path) and not (modified or tt.modified or env.modified or conf.modified):
                event.skip('archive', path)
                continue

            html = tt.render(conf=conf, env=union(env, entrylist=group,
                type='archive', prev=prev, curr=link(route), next=next,
                num_entries=len(group), route=route, archive=key))

            yield html, path
Example #33
0
    def transform(self, content, entry, *args):
        options = helpers.union(Introduction.defaults, self.conf.fetch('intro_'))

        try:
            options.update(entry.intro)
        except AttributeError:
            pass

        try:
            maxparagraphs = int(options.get('maxparagraphs') or args[0])
        except (IndexError, ValueError) as ex:
            if isinstance(ex, ValueError):
                log.warn('Introduction: invalid maxparagraphs argument %r',
                         options.get('maxparagraphs') or args[0])
            maxparagraphs = 1

        try:
            return ''.join(Introducer(
                content, maxparagraphs, self.env.path+entry.permalink, options).result)
        except HTMLParseError as e:
            log.exception('could not extract intro from ' + entry.filename)
            return content
        return content
Example #34
0
    def generate(self, conf, env, data):
        """Creates paged listing by tag."""

        ipp = self.items_per_page
        tt = env.engine.fromfile(self.template)

        for tag in self.tags:

            route = expand(self.path, {'name': tag}).rstrip('/')
            entrylist = [entry for entry in self.tags[tag]]
            paginator = paginate(entrylist, ipp, route, conf['default_orphans'])

            for (next, curr, prev), entries, modified in paginator:

                # e.g.: curr = /page/3, next = /page/2, prev = /page/4

                next = None if next is None \
                else link(u'Next', expand(self.path, {'name': tag}).rstrip('/')) if next == 1 \
                    else link(u'Next', expand(self.pagination, {'name': tag, 'num': next}))

                curr = link(curr, expand(self.path, {'name': tag})) if curr == 1 \
                    else link(expand(self.pagination, {'num': curr, 'name': tag}))

                prev = None if prev is None \
                    else link(u'Previous', expand(self.pagination, {'name': tag, 'num': prev}))

                path = joinurl(conf['output_dir'], curr)

                if isfile(path) and not (modified or tt.modified or env.modified or conf.modified):
                    event.skip('tag', path)
                    continue

                html = tt.render(conf=conf, env=union(env, entrylist=entries,
                                type='tag', prev=prev, curr=curr, next=next, tag=tag,
                                items_per_page=ipp, num_entries=len(entrylist), route=route))

                yield html, path
Example #35
0
    def generate(self, conf, env, data):

        tt = env.engine.fromfile(self.template)
        pathes, entrylist = set(), data[self.type]
        unmodified = not tt.modified and not env.modified and not conf.modified

        for i, entry in enumerate(entrylist):

            if entry.hasproperty('permalink'):
                path = joinurl(conf['output_dir'], entry.permalink)
            else:
                path = joinurl(conf['output_dir'], expand(self.path, entry))

            if path.endswith('/'):
                path = joinurl(path, 'index.html')

            if isfile(path) and path in pathes:
                try:
                    os.remove(path)
                finally:
                    f = lambda e: e is not entry and e.permalink == entry.permalink
                    raise AcrylamidException("title collision %r in %r with %r." %
                        (entry.permalink, entry.filename, filter(f, entrylist)[0].filename))

            pathes.add(path)
            next, prev = self.next(entrylist, i), self.prev(entrylist, i)

            if isfile(path) and unmodified and not (entry.modified or modified(*references(entry))):
                event.skip(path)
                continue

            route = expand(self.path, entry)
            html = tt.render(conf=conf, entry=entry, env=union(env,
                             entrylist=[entry], type=self.__class__.__name__.lower(),
                             prev=prev, next=next, route=route))

            yield html, path
Example #36
0
    def transform(self, content, entry, *args):
        options = helpers.union(Summarize.defaults,
                                self.conf.fetch('summarize_'))

        try:
            options.update(entry.summarize)
        except AttributeError:
            pass

        try:
            maxwords = int(options.get('maxwords') or args[0])
        except (IndexError, ValueError) as ex:
            if isinstance(ex, ValueError):
                log.warn('Summarize: invalid maxwords argument %r',
                         options.get('maxwords') or args[0])
            maxwords = 100

        try:
            return ''.join(
                Summarizer(content, maxwords, self.env.path + entry.permalink,
                           options).result)
        except:
            log.exception('could not summarize ' + entry.filename)
            return content
Example #37
0
    def generate(self, conf, env, data):

        pathes, entrylist = set(), data[self.type]
        unmodified = not env.modified and not conf.modified

        for i, entry in enumerate(entrylist):

            if entry.hasproperty('permalink'):
                path = joinurl(conf['output_dir'], entry.permalink)
            else:
                path = joinurl(conf['output_dir'], expand(self.path, entry))

            if isfile(path) and path in pathes:
                try:
                    os.remove(path)
                finally:
                    other = [
                        e.filename for e in entrylist
                        if e is not entry and e.permalink == entry.permalink
                    ][0]
                    log.error("title collision %s caused by %s and %s",
                              entry.permalink, entry.filename, other)
                    raise SystemExit

            pathes.add(path)
            next, prev = self.next(entrylist, i), self.prev(entrylist, i)

            # per-entry template
            tt = env.engine.fromfile(env,
                                     entry.props.get('layout', self.template))

            if all([
                    isfile(path), unmodified, not tt.modified,
                    not entry.modified, not modified(*references(entry))
            ]):
                event.skip(self.name, path)
            else:
                html = tt.render(conf=conf,
                                 entry=entry,
                                 env=union(
                                     env,
                                     entrylist=[entry],
                                     type=self.__class__.__name__.lower(),
                                     prev=prev,
                                     next=next,
                                     route=expand(self.path, entry)))
                yield html, path

            # check if any resources need to be moved
            if entry.hasproperty('copy'):
                for res_src in entry.resources:
                    res_dest = join(dirname(path), basename(res_src))
                    # Note, presence of res_src check in FileReader.getresources
                    if isfile(res_dest
                              ) and getmtime(res_dest) > getmtime(res_src):
                        event.skip(self.name, res_dest)
                        continue
                    try:
                        fp = io.open(res_src, 'rb')
                        # use mkfile rather than yield so different ns can be specified (and filtered by sitemap)
                        mkfile(fp,
                               res_dest,
                               ns='resource',
                               force=env.options.force,
                               dryrun=env.options.dryrun)
                    except IOError as e:
                        log.warn(
                            "Failed to copy resource '%s' whilst processing '%s' (%s)"
                            % (res_src, entry.filename, e.strerror))