def build_artifact(self, artifact): ctx = get_ctx() feed_source = self.source page = feed_source.parent feed = AtomFeed( title=page.record_label + u' — Pallets Project', feed_url=url_to(feed_source, external=True), url=url_to('/blog', external=True), id=get_id(ctx.env.project.id) ) for item in page.children.order_by( '-pub_date', '-pub_order', 'title' ).limit(10): item_author = item['author'] feed.add( item['title'], text_type(item['body']), xml_base=url_to(item, external=True), url=url_to(item, external=True), content_type='html', id=get_id(u'%s/%s' % ( ctx.env.project.id, item['_path'].encode('utf-8'))), author=item_author, updated=datetime(*item['pub_date'].timetuple()[:3])) with artifact.open('wb') as f: f.write(feed.to_string().encode('utf-8'))
def generate_feed(artifact): feed = AtomFeed( title=title or 'Feed', subtitle=unicode(subtitle or ''), subtitle_type=hasattr(subtitle, '__html__') and 'html' or 'text', feed_url=feed_url, url=embed_url, id=get_id(ctx.env.project.id + 'lektor') ) for item in items: feed.add( get_item_title(item, item_title_field), get_item_body(item, item_body_field), xml_base=url_to(item, external=True), url=url_to(item, external=True), content_type='html', id=get_id(u'%slektor/%s' % ( ctx.env.project.id, item['_path'].encode('utf-8'), )), author=get_item_author(item, item_author_field), updated=get_item_updated(item, item_date_field)) with artifact.open('wb') as f: f.write(feed.to_string().encode('utf-8') + '\n')
def build_artifact(self, artifact): ctx = get_ctx() feed_source = self.source blog = feed_source.parent summary = get(blog, feed_source.blog_summary_field) or '' subtitle_type = ('html' if hasattr(summary, '__html__') else 'text') blog_author = unicode(get(blog, feed_source.blog_author_field) or '') generator = ('Lektor Atom Plugin', 'https://github.com/ajdavis/lektor-atom', pkg_resources.get_distribution('lektor-atom').version) project_id = ctx.env.load_config().base_url if not project_id: project_id = ctx.env.project.id feed = AtomFeed( title=feed_source.feed_name, subtitle=unicode(summary), subtitle_type=subtitle_type, author=blog_author, feed_url=url_to(feed_source, external=True), url=url_to(blog, external=True), id=get_id(project_id), generator=generator) if feed_source.items: # "feed_source.items" is a string like "site.query('/blog')". expr = Expression(ctx.env, feed_source.items) items = expr.evaluate(ctx.pad) else: items = blog.children if feed_source.item_model: items = items.filter(F._model == feed_source.item_model) order_by = '-' + feed_source.item_date_field items = items.order_by(order_by).limit(int(feed_source.limit)) for item in items: item_author_field = feed_source.item_author_field item_author = get(item, item_author_field) or blog_author feed.add( get_item_title(item, feed_source.item_title_field), get_item_body(item, feed_source.item_body_field), xml_base=url_to(item, external=True), url=url_to(item, external=True), content_type='html', id=get_id(u'%s/%s' % ( project_id, item['_path'].encode('utf-8'))), author=item_author, updated=get_item_updated(item, feed_source.item_date_field)) with artifact.open('wb') as f: f.write(feed.to_string().encode('utf-8'))
def __init__(self, project, load_plugins=True): self.project = project self.root_path = os.path.abspath(project.tree) self.jinja_env = CustomJinjaEnvironment( autoescape=self.select_jinja_autoescape, extensions=["jinja2.ext.autoescape", "jinja2.ext.with_"], loader=jinja2.FileSystemLoader(os.path.join(self.root_path, "templates")), ) from lektor.db import F self.jinja_env.filters.update( tojson=tojson_filter, latformat=lambda x, secs=True: format_lat_long(lat=x, secs=secs), longformat=lambda x, secs=True: format_lat_long(long=x, secs=secs), latlongformat=lambda x, secs=True: format_lat_long(secs=secs, *x), # By default filters need to be side-effect free. This is not # the case for this one, so we need to make it as a dummy # context filter so that jinja2 will not inline it. url=jinja2.contextfilter(lambda ctx, *a, **kw: url_to(*a, **kw)), asseturl=jinja2.contextfilter(lambda ctx, *a, **kw: get_asset_url(*a, **kw)), markdown=jinja2.contextfilter(lambda ctx, *a, **kw: Markdown(*a, **kw)), ) self.jinja_env.globals.update( F=F, url_to=url_to, site=site_proxy, config=config_proxy, bag=lookup_from_bag, get_random_id=lambda: uuid.uuid4().hex, ) self.jinja_env.filters.update( datetimeformat=_pass_locale(dates.format_datetime), dateformat=_pass_locale(dates.format_date), timeformat=_pass_locale(dates.format_time), ) from lektor.types import builtin_types self.types = builtin_types.copy() from lektor.publisher import builtin_publishers self.publishers = builtin_publishers.copy() # The plugins that are loaded for this environment. This is # modified by the plugin controller and registry methods on the # environment. self.plugin_controller = PluginController(self) self.plugins = {} self.plugin_ids_by_class = {} self.build_programs = [] self.special_file_assets = {} self.special_file_suffixes = {} self.custom_url_resolvers = [] self.custom_generators = [] if load_plugins: self.load_plugins()
def __init__(self, project): self.project = project self.root_path = os.path.abspath(project.tree) self.jinja_env = CustomJinjaEnvironment( autoescape=self.select_jinja_autoescape, extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_'], loader=jinja2.FileSystemLoader( os.path.join(self.root_path, 'templates')) ) from lektor.db import F self.jinja_env.filters.update( tojson=tojson_filter, # By default filters need to be side-effect free. This is not # the case for this one, so we need to make it as a dummy # context filter so that jinja2 will not inline it. url=jinja2.contextfilter( lambda ctx, *a, **kw: url_to(*a, **kw)), asseturl=jinja2.contextfilter( lambda ctx, *a, **kw: url_to(get_asset_url(*a, **kw))), ) self.jinja_env.globals.update( F=F, url_to=url_to, site=site_proxy, config=config_proxy, bag=lookup_from_bag, get_random_id=lambda: uuid.uuid4().hex, ) from lektor.types import builtin_types self.types = builtin_types.copy() # The plugins that are loaded for this environment. This is # modified by the plugin controller and registry methods on the # environment. self.plugin_controller = PluginController(self) self.plugins = {} self.build_programs = [] self.special_file_assets = {} self.special_file_suffixes = {}
def build_artifact(self, artifact): ctx = get_ctx() source = self.source appcast = AppCast( title=source.cast_name, link=url_to(source, external=True), ) try: expr = Expression(ctx.env, source.items) except AttributeError: items = source.parent.children else: items = expr.evaluate(ctx.pad) if source.item_model: items = items.filter(F._model == source.item_model) items = items.order_by('-build_number') for item in items: with ctx.changed_base_url(item.url_path): description = six.text_type(markupsafe.escape(item['note'])) try: offset = int(source.timezone) except ValueError: tzinfo = pytz.timezone(source.timezone) else: tzinfo = pytz.FixedOffset(offset) pub_date = item['pub_datetime'].replace(tzinfo=tzinfo) try: build_number = str(item['build_number']) if '.' in build_number: build_number = build_number.rstrip('0').rstrip('.') appcast.add( title='Version {}'.format(item['version']), description=description, pub_date=pub_date, url=item['download_url'], build=build_number, version=item['version'], length=item['length'], dsasign=item['dsa_signature'], minsysver=item['min_sysver'], ) except Exception as e: msg = '{}: {}'.format(item.id, e) click.echo(click.style('E', fg='red') + ' ' + msg) with artifact.open('wb') as f: f.write(appcast.to_string().encode('utf-8'))
def __init__(self, project, load_plugins=True): self.project = project self.root_path = os.path.abspath(project.tree) self.theme_paths = [os.path.join(self.root_path, 'themes', theme) for theme in self.project.themes] if not self.theme_paths: # load the directories in the themes directory as the themes try: for fname in os.listdir(os.path.join(self.root_path, 'themes')): f = os.path.join(self.root_path, 'themes', fname) if os.path.isdir(f): self.theme_paths.append(f) except OSError: pass template_paths = [os.path.join(path, 'templates') for path in [self.root_path] + self.theme_paths] self.jinja_env = CustomJinjaEnvironment( autoescape=self.select_jinja_autoescape, extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_'], loader=jinja2.FileSystemLoader( template_paths) ) from lektor.db import F, get_alts self.jinja_env.filters.update( tojson=tojson_filter, latformat=lambda x, secs=True: format_lat_long(lat=x, secs=secs), longformat=lambda x, secs=True: format_lat_long(long=x, secs=secs), latlongformat=lambda x, secs=True: format_lat_long(secs=secs, *x), # By default filters need to be side-effect free. This is not # the case for this one, so we need to make it as a dummy # context filter so that jinja2 will not inline it. url=jinja2.contextfilter( lambda ctx, *a, **kw: url_to(*a, **kw)), asseturl=jinja2.contextfilter( lambda ctx, *a, **kw: get_asset_url(*a, **kw)), markdown=jinja2.contextfilter( lambda ctx, *a, **kw: Markdown(*a, **kw)), ) self.jinja_env.globals.update( F=F, url_to=url_to, site=site_proxy, config=config_proxy, bag=lookup_from_bag, get_alts=get_alts, get_random_id=lambda: uuid.uuid4().hex, ) self.jinja_env.filters.update( datetimeformat=_pass_locale(dates.format_datetime), dateformat=_pass_locale(dates.format_date), timeformat=_pass_locale(dates.format_time), ) from lektor.types import builtin_types self.types = builtin_types.copy() from lektor.publisher import builtin_publishers self.publishers = builtin_publishers.copy() # The plugins that are loaded for this environment. This is # modified by the plugin controller and registry methods on the # environment. self.plugin_controller = PluginController(self) self.plugins = {} self.plugin_ids_by_class = {} self.build_programs = [] self.special_file_assets = {} self.special_file_suffixes = {} self.custom_url_resolvers = [] self.custom_generators = [] self.virtual_sources = {} if load_plugins: self.load_plugins() from lektor.db import siblings_resolver self.virtualpathresolver('siblings')(siblings_resolver)
def create_atom_feed(filename='atom.xml', title=None, subtitle=None, link=None, items=None, item_title_field='title', item_body_field='body', item_author_field='author', item_date_field='pub_date'): ctx = get_ctx() if ctx is None: raise RuntimeError('A context is required') source = ctx.source if source is None: raise RuntimeError('Can only generate feeds out of sources.') if items is None: raise RuntimeError('An item expression is required') artifact_name = posixpath.join(source.url_path, filename) config_hash = get_structure_hash({ 'filename': filename, 'title': title, 'subtitle': subtitle, 'link': link, 'items': items, 'item_title_field': item_title_field, 'item_body_field': item_body_field, 'item_author_field': item_author_field, 'item_date_field': item_date_field, }) # Iterating over the items will resolve dependencies. As we are very # interested in those, we need to capture tem, dependencies = set() with ctx.gather_dependencies(dependencies.add): items = list(items) here = posixpath.join(source.url_path, filename) feed_url = url_to(here, external=True) embed_url = url_to(source, external=True) @ctx.sub_artifact(artifact_name, source_obj=ctx.source, sources=list(dependencies), config_hash=config_hash) def generate_feed(artifact): feed = AtomFeed( title=title or 'Feed', subtitle=unicode(subtitle or ''), subtitle_type=hasattr(subtitle, '__html__') and 'html' or 'text', feed_url=feed_url, url=embed_url, id=get_id(ctx.env.project.id + 'lektor') ) for item in items: feed.add( get_item_title(item, item_title_field), get_item_body(item, item_body_field), xml_base=url_to(item, external=True), url=url_to(item, external=True), content_type='html', id=get_id(u'%slektor/%s' % ( ctx.env.project.id, item['_path'].encode('utf-8'), )), author=get_item_author(item, item_author_field), updated=get_item_updated(item, item_date_field)) with artifact.open('wb') as f: f.write(feed.to_string().encode('utf-8') + '\n') return artifact_name
def __init__(self, project, load_plugins=True): self.project = project self.root_path = os.path.abspath(project.tree) self.jinja_env = CustomJinjaEnvironment( autoescape=self.select_jinja_autoescape, extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_'], loader=jinja2.FileSystemLoader( os.path.join(self.root_path, 'templates'))) from lektor.db import F self.jinja_env.filters.update( tojson=tojson_filter, latformat=lambda x, secs=True: format_lat_long(lat=x, secs=secs), longformat=lambda x, secs=True: format_lat_long(long=x, secs=secs), latlongformat=lambda x, secs=True: format_lat_long(secs=secs, *x), # By default filters need to be side-effect free. This is not # the case for this one, so we need to make it as a dummy # context filter so that jinja2 will not inline it. url=jinja2.contextfilter(lambda ctx, *a, **kw: url_to(*a, **kw)), asseturl=jinja2.contextfilter( lambda ctx, *a, **kw: get_asset_url(*a, **kw)), markdown=jinja2.contextfilter( lambda ctx, *a, **kw: Markdown(*a, **kw)), ) self.jinja_env.globals.update( F=F, url_to=url_to, site=site_proxy, config=config_proxy, bag=lookup_from_bag, get_random_id=lambda: uuid.uuid4().hex, ) self.jinja_env.filters.update( datetimeformat=_pass_locale(dates.format_datetime), dateformat=_pass_locale(dates.format_date), timeformat=_pass_locale(dates.format_time), ) from lektor.types import builtin_types self.types = builtin_types.copy() from lektor.publisher import builtin_publishers self.publishers = builtin_publishers.copy() # The plugins that are loaded for this environment. This is # modified by the plugin controller and registry methods on the # environment. self.plugin_controller = PluginController(self) self.plugins = {} self.plugin_ids_by_class = {} self.build_programs = [] self.special_file_assets = {} self.special_file_suffixes = {} self.custom_url_resolvers = [] self.custom_generators = [] self.virtual_sources = {} if load_plugins: self.load_plugins() from lektor.db import siblings_resolver self.virtualpathresolver('siblings')(siblings_resolver)
def __init__(self, project, load_plugins=True, extra_flags=None): self.project = project self.root_path = os.path.abspath(project.tree) self.theme_paths = [ os.path.join(self.root_path, "themes", theme) for theme in self.project.themes ] if not self.theme_paths: # load the directories in the themes directory as the themes try: for fname in os.listdir(os.path.join(self.root_path, "themes")): f = os.path.join(self.root_path, "themes", fname) if os.path.isdir(f): self.theme_paths.append(f) except OSError: pass template_paths = [ os.path.join(path, "templates") for path in [self.root_path] + self.theme_paths ] self.jinja_env = CustomJinjaEnvironment( autoescape=self.select_jinja_autoescape, extensions=[ "jinja2.ext.autoescape", "jinja2.ext.with_", "jinja2.ext.do" ], loader=jinja2.FileSystemLoader(template_paths), ) from lektor.db import F, get_alts self.jinja_env.filters.update( tojson=tojson_filter, latformat=lambda x, secs=True: format_lat_long(lat=x, secs=secs), longformat=lambda x, secs=True: format_lat_long(long=x, secs=secs), latlongformat=lambda x, secs=True: format_lat_long(secs=secs, *x), # By default filters need to be side-effect free. This is not # the case for this one, so we need to make it as a dummy # context filter so that jinja2 will not inline it. url=jinja2.contextfilter(lambda ctx, *a, **kw: url_to(*a, **kw)), asseturl=jinja2.contextfilter( lambda ctx, *a, **kw: get_asset_url(*a, **kw)), markdown=jinja2.contextfilter( lambda ctx, *a, **kw: Markdown(*a, **kw)), ) self.jinja_env.globals.update( F=F, url_to=url_to, site=site_proxy, config=config_proxy, bag=lookup_from_bag, get_alts=get_alts, get_random_id=lambda: uuid.uuid4().hex, ) self.jinja_env.filters.update( datetimeformat=_pass_locale(dates.format_datetime), dateformat=_pass_locale(dates.format_date), timeformat=_pass_locale(dates.format_time), ) from lektor.types import builtin_types self.types = builtin_types.copy() from lektor.publisher import builtin_publishers self.publishers = builtin_publishers.copy() # The plugins that are loaded for this environment. This is # modified by the plugin controller and registry methods on the # environment. self.plugin_controller = PluginController(self, extra_flags) self.plugins = {} self.plugin_ids_by_class = {} self.build_programs = [] self.special_file_assets = {} self.special_file_suffixes = {} self.custom_url_resolvers = [] self.custom_generators = [] self.virtual_sources = {} if load_plugins: self.load_plugins() from lektor.db import siblings_resolver self.virtualpathresolver("siblings")(siblings_resolver)
def build_artifact(self, artifact): ctx = get_ctx() feed_source = self.source blog = feed_source.parent summary = get(blog, feed_source.blog_summary_field) or '' if hasattr(summary, '__html__'): subtitle_type = 'html' summary = text_type(summary.__html__()) else: subtitle_type = 'text' blog_author = text_type(get(blog, feed_source.blog_author_field) or '') generator = ('Lektor Atom Plugin', 'https://github.com/ajdavis/lektor-atom', pkg_resources.get_distribution('lektor-atom').version) feed = AtomFeed(title=feed_source.feed_name, subtitle=summary, subtitle_type=subtitle_type, author=blog_author, feed_url=url_to(feed_source, external=True), url=url_to(blog, external=True), id=get_id(ctx.env.project.id), generator=generator) if feed_source.items: # "feed_source.items" is a string like "site.query('/blog')". expr = Expression(ctx.env, feed_source.items) items = expr.evaluate(ctx.pad) else: items = blog.children if feed_source.item_model: items = items.filter(F._model == feed_source.item_model) order_by = '-' + feed_source.item_date_field items = items.order_by(order_by).limit(int(feed_source.limit)) for item in items: try: item_author_field = feed_source.item_author_field item_author = get(item, item_author_field) or blog_author feed.add( get_item_title(item, feed_source.item_title_field), get_item_body(item, feed_source.item_body_field), xml_base=url_to(item, external=True), url=url_to(item, external=True), content_type='html', id=get_id( u'%s/%s' % (ctx.env.project.id, item['_path'].encode('utf-8'))), author=item_author, updated=get_item_updated(item, feed_source.item_date_field)) except Exception as exc: msg = '%s: %s' % (item.id, exc) click.echo(click.style('E', fg='red') + ' ' + msg) with artifact.open('wb') as f: f.write(feed.to_string().encode('utf-8'))