def php_format_to_strftime_format(fmt): replacements = { 'd': '%d', 'D': '%a', 'j': '%d', 'l': '%A', 'w': '%w', 'z': '%j', 'W': '%W', 'F': '%B', 'm': '%m', 'M': '%b', 'n': '%m', 'y': '%Y', 'Y': '%y', 'g': '%I', 'G': '%H', 'h': '%I', 'H': '%H', 'i': '%M', 's': '%S', 'e': '%Z', 'O': '%z', 'c': '%Y-%m-%dT%H:%M:%SZ' } return multi_replace(fmt, replacements)
def php_format_to_strftime_format(fmt): replacements = { "d": "%d", "D": "%a", "j": "%d", "l": "%A", "w": "%w", "z": "%j", "W": "%W", "F": "%B", "m": "%m", "M": "%b", "n": "%m", "y": "%Y", "Y": "%y", "g": "%I", "G": "%H", "h": "%I", "H": "%H", "i": "%M", "s": "%S", "e": "%Z", "O": "%z", "c": "%Y-%m-%dT%H:%M:%SZ", } return multi_replace(fmt, replacements)
def buildPageFactory(self, path): if not path.startswith(self.fs_endpoint_path): raise Exception("Page path '%s' isn't inside '%s'." % ( path, self.fs_endpoint_path)) rel_path = path[len(self.fs_endpoint_path):].lstrip('\\/') pat = self.PATH_FORMAT % { 'year': 'YEAR', 'month': 'MONTH', 'day': 'DAY', 'slug': 'SLUG', 'ext': 'EXT'} pat = re.escape(pat) pat = multi_replace(pat, { 'YEAR': '(\d{4})', 'MONTH': '(\d{2})', 'DAY': '(\d{2})', 'SLUG': '(.*)', 'EXT': '(.*)'}) m = re.match(pat, rel_path) if m is None: raise Exception("'%s' isn't a proper %s page path." % ( rel_path, self.SOURCE_NAME)) return self._makeFactory( rel_path, m.group(4), int(m.group(1)), int(m.group(2)), int(m.group(3)))
def php_format_to_strftime_format(fmt): replacements = { 'd': '%d', 'D': '%a', 'j': '%d', 'l': '%A', 'w': '%w', 'z': '%j', 'W': '%W', 'F': '%B', 'm': '%m', 'M': '%b', 'n': '%m', 'y': '%Y', 'Y': '%y', 'g': '%I', 'G': '%H', 'h': '%I', 'H': '%H', 'i': '%M', 's': '%S', 'e': '%Z', 'O': '%z', 'c': '%Y-%m-%dT%H:%M:%SZ'} return multi_replace(fmt, replacements)
def _cacheAssets(self): if self._cache_map is not None: return source = self._page.source content_item = self._page.content_item try: assets = source.getRelatedContents(content_item, REL_ASSETS) except NotImplementedError: assets = None self._cache_map = {} self._cache_list = [] if assets is None: return app = source.app root_dir = app.root_dir asset_url_format = app.config.get('site/asset_url_format') if not asset_url_format: raise Exception("No asset URL format was specified.") page_uri = self._page.getUri() pretty_urls = app.config.get('site/pretty_urls') if not pretty_urls: page_uri, _ = os.path.splitext(page_uri) uri_build_tokens = { '%path%': None, '%filename%': None, '%page_uri%': page_uri } for a in assets: name = a.metadata['name'] if name in self._cache_map: raise UnsupportedAssetsError( "An asset with name '%s' already exists for item '%s'. " "Do you have multiple assets with colliding names?" % (name, content_item.spec)) # TODO: this assumes a file-system source! uri_build_tokens['%path%'] = \ os.path.relpath(a.spec, root_dir).replace('\\', '/') uri_build_tokens['%filename%'] = a.metadata.get('filename') uri = multi_replace(asset_url_format, uri_build_tokens) self._cache_map[name] = _AssetInfo(a, uri) self._cache_list.append(uri) stack = app.env.render_ctx_stack cur_ctx = stack.current_ctx if cur_ctx is not None: cur_ctx.render_info['used_assets'] = True
def build_base_url(app, uri, rel_assets_path): base_url_format = app.env.base_asset_url_format rel_assets_path = rel_assets_path.replace('\\', '/') # Remove any extension since we'll be copying assets into the 1st # sub-page's folder. pretty = app.config.get('site/pretty_urls') if not pretty: uri, _ = os.path.splitext(uri) base_url = multi_replace(base_url_format, { '%path%': rel_assets_path, '%uri%': uri }) return base_url.rstrip('/') + '/'
def run(self, ctx): if not hasattr(ctx.args, 'source'): raise Exception("No source specified. " "Please run `chef prepare -h` for usage.") app = ctx.app source = ctx.args.source metadata = source.buildMetadata(ctx.args) factory = source.findPageFactory(metadata, MODE_CREATING) path = factory.path name, ext = os.path.splitext(path) if ext == '.*': path = '%s.%s' % ( name, app.config.get('site/default_auto_format')) if os.path.exists(path): raise Exception("'%s' already exists." % path) tpl_name = ctx.args.template extensions = self.getExtensions(app) ext = next( filter( lambda e: tpl_name in e.getTemplateNames(ctx.app), extensions), None) if ext is None: raise Exception("No such page template: %s" % tpl_name) tpl_text = ext.getTemplate(ctx.app, tpl_name) if tpl_text is None: raise Exception("Error loading template: %s" % tpl_name) title = (metadata.get('slug') or metadata.get('path') or 'Untitled page') title = make_title(title) tokens = { '%title%': title, '%time.today%': time.strftime('%Y/%m/%d'), '%time.now%': time.strftime('%H:%M:%S')} tpl_text = multi_replace(tpl_text, tokens) logger.info("Creating page: %s" % os.path.relpath(path, app.root_dir)) if not os.path.exists(os.path.dirname(path)): os.makedirs(os.path.dirname(path), 0o755) with open(path, 'w') as f: f.write(tpl_text)
def build_base_url(app, uri, rel_assets_path): base_url_format = app.env.base_asset_url_format rel_assets_path = rel_assets_path.replace('\\', '/') # Remove any extension since we'll be copying assets into the 1st # sub-page's folder. pretty = app.config.get('site/pretty_urls') if not pretty: uri, _ = os.path.splitext(uri) base_url = multi_replace( base_url_format, { '%path%': rel_assets_path, '%uri%': uri}) return base_url.rstrip('/') + '/'
def run(self, ctx): if not hasattr(ctx.args, 'source'): raise Exception("No source specified. " "Please run `chef prepare -h` for usage.") app = ctx.app source = ctx.args.source metadata = source.buildMetadata(ctx.args) factory = source.findPageFactory(metadata, MODE_CREATING) path = factory.path name, ext = os.path.splitext(path) if ext == '.*': path = '%s.%s' % (name, app.config.get('site/default_auto_format')) if os.path.exists(path): raise Exception("'%s' already exists." % path) tpl_name = ctx.args.template extensions = self.getExtensions(app) ext = next( filter(lambda e: tpl_name in e.getTemplateNames(ctx.app), extensions), None) if ext is None: raise Exception("No such page template: %s" % tpl_name) tpl_text = ext.getTemplate(ctx.app, tpl_name) if tpl_text is None: raise Exception("Error loading template: %s" % tpl_name) title = (metadata.get('slug') or metadata.get('path') or 'Untitled page') title = make_title(title) tokens = { '%title%': title, '%time.today%': time.strftime('%Y/%m/%d'), '%time.now%': time.strftime('%H:%M:%S') } tpl_text = multi_replace(tpl_text, tokens) logger.info("Creating page: %s" % os.path.relpath(path, app.root_dir)) if not os.path.exists(os.path.dirname(path)): os.makedirs(os.path.dirname(path), 0o755) with open(path, 'w') as f: f.write(tpl_text)
def convertConfig(self, app, src_path): logger.debug(" Converting configuration file.") with open(src_path, 'r', encoding='utf8') as fp: config = yaml.load(fp) if 'site' not in config: config['site'] = {} config['site']['related_posts'] = [] config['site']['posts_fs'] = 'flat' config['site']['templates_dirs'] = ['includes', 'layouts'] config['site']['tag_url'] = 'tags/%tag%' if 'permalink' in config: permalink = config['permalink'] if permalink == 'date': permalink = '/:categories/:year/:month/:day/:title.html' elif permalink == 'pretty': permalink = '/:categories/:year/:month/:day/:title/' elif permalink == 'none': permalink = '/:categories/:title.html' # TODO: handle `:categories` token. post_url = multi_replace( permalink, {':year': '%year%', ':month': '%month%', ':day': '%day%', ':title': '%slug%', ':categories': ''}) post_url = post_url.replace('//', '/').strip('/') config['site']['post_url'] = post_url if 'exclude' in config: if 'baker' not in config: config['baker'] = {} config['baker']['ignore'] = list(map( lambda i: '^/_%s/' % re.escape(i))) if 'jinja' not in config: config['jinja'] = {} config['jinja']['auto_escape'] = False if 'markdown' in config: if not isinstance(config['markdown'], dict): logger.warning("Discarding markdown setting: %s" % config['markdown']) del config['markdown'] with open(os.path.join(app.root_dir, 'config.yml'), 'w') as fp: yaml.dump(config, stream=fp)
def _maybeActivate(self, pipeline): if self._state != self.STATE_UNKNOWN: return config = self.app.config.get('compass') if config is None or not config.get('enable'): logger.debug("Compass processing is disabled (set " "`compass/enable` to `true` to enable it).") self._state = self.STATE_INACTIVE return logger.debug("Activating Compass processing for SCSS/SASS files.") self._state = self.STATE_ACTIVE bin_path = config.get('bin', 'compass') config_path = config.get('config_path', 'config.rb') config_path = os.path.join(self.app.root_dir, config_path) if not os.path.exists(config_path): raise Exception("Can't find Compass configuration file: %s" % config_path) self._args = '%s compile --config "%s"' % (bin_path, config_path) frameworks = config.get('frameworks', []) if not isinstance(frameworks, list): frameworks = frameworks.split(',') for f in frameworks: self._args += ' --load %s' % f custom_args = config.get('options') if custom_args: self._args += ' ' + custom_args out_dir = pipeline.out_dir tmp_dir = os.path.join(pipeline.tmp_dir, 'compass') self._args = multi_replace( self._args, {'%out_dir%': out_dir, '%tmp_dir%': tmp_dir}) self._runInSite = False self._runInTheme = False
def _maybeActivate(self, pipeline): if self._state != self.STATE_UNKNOWN: return config = self.app.config.get('compass') if config is None or not config.get('enable'): logger.debug("Compass processing is disabled (set " "`compass/enable` to `true` to enable it).") self._state = self.STATE_INACTIVE return logger.debug("Activating Compass processing for SCSS/SASS files.") self._state = self.STATE_ACTIVE bin_path = config.get('bin', 'compass') config_path = config.get('config_path', 'config.rb') config_path = os.path.join(self.app.root_dir, config_path) if not os.path.exists(config_path): raise Exception("Can't find Compass configuration file: %s" % config_path) self._args = '%s compile --config "%s"' % (bin_path, config_path) frameworks = config.get('frameworks', []) if not isinstance(frameworks, list): frameworks = frameworks.split(',') for f in frameworks: self._args += ' --load %s' % f custom_args = config.get('options') if custom_args: self._args += ' ' + custom_args out_dir = pipeline.out_dir tmp_dir = os.path.join(pipeline.tmp_dir, 'compass') self._args = multi_replace(self._args, { '%out_dir%': out_dir, '%tmp_dir%': tmp_dir }) self._runInSite = False self._runInTheme = False
def _setup_app_environment(app, env): from piecrust.uriutil import multi_replace tokens = { '%root_dir%': app.root_dir} for k, v in env.items(): varname = k append = False if k.lower() == 'path': append = True v = os.pathsep + v elif k.endswith('+'): varname = k[:-1] append = True v = multi_replace(v, tokens) if append: logger.debug("Env: $%s += %s" % (varname, v)) os.environ[varname] += v else: logger.debug("Env: $%s = %s" % (varname, v)) os.environ[varname] = v
def _doRun(self, ctx): import time from piecrust.uriutil import multi_replace from piecrust.sources.fs import FSContentSourceBase if not hasattr(ctx.args, 'source'): raise Exception("No source specified. " "Please run `chef prepare -h` for usage.") app = ctx.app tpl_name = ctx.args.template extensions = self.getExtensions(app) ext = next( filter( lambda e: tpl_name in e.getTemplateNames(app), extensions), None) if ext is None: raise Exception("No such page template: %s" % tpl_name) tpl_text = ext.getTemplate(app, tpl_name) if tpl_text is None: raise Exception("Error loading template: %s" % tpl_name) source = ctx.args.source content_item = source.createContent(vars(ctx.args)) if content_item is None: raise Exception("Can't create item.") config_tokens = { '%title%': "Untitled Content", '%time.today%': time.strftime('%Y/%m/%d'), '%time.now%': time.strftime('%H:%M:%S') } config = content_item.metadata.get('config') if config: for k, v in config.items(): config_tokens['%%%s%%' % k] = v tpl_text = multi_replace(tpl_text, config_tokens) logger.info("Creating content: %s" % content_item.spec) mode = 'w' if ctx.args.force else 'x' with source.openItem(content_item, mode) as f: f.write(tpl_text) # If this was a file-system content item, see if we need to auto-open # an editor on it. editor = ctx.app.config.get('prepare/editor') editor_type = ctx.app.config.get('prepare/editor_type', 'exe') if editor and isinstance(source, FSContentSourceBase): import shlex shell = False args = '%s "%s"' % (editor, content_item.spec) if '%path%' in editor: args = editor.replace('%path%', content_item.spec) if editor_type.lower() == 'shell': shell = True else: args = shlex.split(args) import subprocess logger.info("Running: %s" % args) subprocess.Popen(args, shell=shell)
def resolvePath(self, path): path = multi_replace(path, {'%theme_dir%': self.theme_dir}) return os.path.join(self.root_dir, path)