Пример #1
0
def expand(url, obj, re=re.compile(r':(\w+)')):
    """Substitutes/expands URL parameters beginning with a colon.

    :param url: a URL with zero or more :key words
    :param obj: a dictionary where we get key from

    >>> expand('/:year/:slug/', {'year': 2012, 'slug': 'awesome title'})
    '/2011/awesome-title/'
    """
    if isinstance(obj, dict):
        return re.sub(lambda m: str(obj.get(m.group(1), m.group(1))), url)
    else:
        return re.sub(lambda m: str(getattr(obj, m.group(1), m.group(1))), url)
Пример #2
0
def distinguish(value):
    """Convert :param value: to None, Int, Float, Bool, a List or String.
    """
    if not isinstance(value, string_types):
        return value

    if not isinstance(value, string_types):
        value = str(value)

    if value in ['None', 'none', '~', 'null']:
        return None
    elif re.match(r'^-?\d+$', value):
        return int(value)
    elif re.match(r'^-?\d+.\d+$', value):
        return float(value)
    elif value in ['True', 'true', 'on']:
        return True
    elif value in ['False', 'false', 'off']:
        return False
    elif len(value) >= 2 and value[0] == '[' and value[-1] == ']':
        tokenizer = shlex.shlex((value[1:-1]).encode('utf-8'), posix=True)
        tokenizer.whitespace = ','.encode('utf-8')
        tokenizer.whitespace_split = True
        tokens = [unsafe(val.decode('utf-8').strip()) for val in list(tokenizer)]
        return [val for val in tokens if val]
    else:
        return unsafe(value)
Пример #3
0
def distinguish(value):
    """Convert :param value: to None, Int, Float, Bool, a List or String.
    """
    if not isinstance(value, string_types):
        return value

    if not isinstance(value, string_types):
        value = str(value)

    if value in ['None', 'none', '~', 'null']:
        return None
    elif re.match(r'^-?\d+$', value):
        return int(value)
    elif re.match(r'^-?\d+.\d+$', value):
        return float(value)
    elif value in ['True', 'true', 'on']:
        return True
    elif value in ['False', 'false', 'off']:
        return False
    elif len(value) >= 2 and value[0] == '[' and value[-1] == ']':
        tokenizer = shlex.shlex((value[1:-1]).encode('utf-8'), posix=True)
        tokenizer.whitespace = ','.encode('utf-8')
        tokenizer.whitespace_split = True
        tokens = [
            unsafe(val.decode('utf-8').strip()) for val in list(tokenizer)
        ]
        return [val for val in tokens if val]
    else:
        return unsafe(value)
Пример #4
0
    def init(self, conf, env, num_entries=25):
        super(RssPerTag, self).init(conf, env)

        self.num_entries = num_entries
        env.engine.register(
            'rfc822', lambda dt: str(format_date_time(total_seconds(dt - epoch))))
        self.type = 'rss'
Пример #5
0
 def run(self):
     while True:
         func, args, kargs = self.tasks.get()
         try:
             func(*args, **kargs)
         except Exception as e:
             log.exception('%s: %s' % (e.__class__.__name__, str(e)))
         self.tasks.task_done()
Пример #6
0
 def run(self):
     while True:
         func, args, kargs = self.tasks.get()
         try:
             func(*args, **kargs)
         except Exception as e:
             log.exception('%s: %s' % (e.__class__.__name__, str(e)))
         self.tasks.task_done()
Пример #7
0
    def __init__(self, chars, patterns, exceptions=''):
        self.chars = str('[.' + chars + ']')
        self.tree = {}
        for pattern in patterns.split():
            self._insert_pattern(pattern)

        self.exceptions = {}
        for ex in exceptions.split():
            # Convert the hyphenated pattern into a point array for use later.
            self.exceptions[ex.replace('-', '')] = [0] + [int(h == '-') for h in re.split(r"[a-z]", ex)]
Пример #8
0
    def __init__(self, chars, patterns, exceptions=''):
        self.chars = str('[.' + chars + ']')
        self.tree = {}
        for pattern in patterns.split():
            self._insert_pattern(pattern)

        self.exceptions = {}
        for ex in exceptions.split():
            # Convert the hyphenated pattern into a point array for use later.
            self.exceptions[ex.replace(
                '-',
                '')] = [0] + [int(h == '-') for h in re.split(r"[a-z]", ex)]
Пример #9
0
def joinurl(*args):
    """Joins multiple urls pieces to one single URL without loosing the root
    (first element). If the URL ends with a slash, Acrylamid automatically
    appends ``index.html``.

    >>> joinurl('/hello/', '/world/')
    '/hello/world/index.html'
    """
    rv = [str(mem) for mem in args]
    if rv[-1].endswith('/'):
        rv.append('index.html')
    return normpath('/'.join(rv))
Пример #10
0
def yamlstyle(fileobj):
    """Open and read content and return metadata and the position where the
    actual content begins.

    If ``pyyaml`` is available we use this parser but we provide a dumb
    fallback parser that can handle simple assigments in YAML.

    :param fileobj: fileobj, utf-8 encoded
    """

    head = []
    i = 0

    while True:
        line = fileobj.readline()
        i += 1
        if i == 1 and not line.startswith('---'):
            raise AcrylamidException("no meta information in %r found" %
                                     fileobj.name)
        elif i > 1 and not line.startswith('---'):
            head.append(line)
        elif i > 1 and line.startswith('---') or not line:
            break

    if yaml:
        try:
            return i, yaml.load(''.join(head))
        except yaml.YAMLError as e:
            raise AcrylamidException('YAMLError: %s' % str(e))
    else:
        props = {}
        for j, line in enumerate(head):
            if line[0] == '#' or not line.strip():
                continue
            try:
                key, value = [x.strip() for x in line.split(':', 1)]
            except ValueError:
                raise AcrylamidException('%s:%i ValueError: %s\n%s' % (
                    fileobj.name, j, line.strip('\n'),
                    ("Either your YAML is malformed or our naïve parser is to dumb \n"
                     "to read it. Revalidate your YAML or install PyYAML parser with \n"
                     "> easy_install -U pyyaml")))
            props[key] = distinguish(value)

    if 'title' not in props:
        raise AcrylamidException('No title given in %r' % fileobj.name)

    return i, props
Пример #11
0
    def __init__(self, obj, style=None, color=None):

        if isinstance(obj, ANSIString):
            if style is None:
                style = obj.style
            if color is None:
                color = obj.color
            obj = obj.obj
        elif not isinstance(obj, string_types):
            obj = str(obj)

        self.obj = obj
        if style:
            self.style = style
        if color:
            self.color = color
Пример #12
0
    def __init__(self, obj, style=None, color=None):

        if isinstance(obj, ANSIString):
            if style is None:
                style = obj.style
            if color is None:
                color = obj.color
            obj = obj.obj
        elif not isinstance(obj, string_types):
            obj = str(obj)

        self.obj = obj
        if style:
            self.style = style
        if color:
            self.color = color
Пример #13
0
def yamlstyle(fileobj):
    """Open and read content and return metadata and the position where the
    actual content begins.

    If ``pyyaml`` is available we use this parser but we provide a dumb
    fallback parser that can handle simple assigments in YAML.

    :param fileobj: fileobj, utf-8 encoded
    """

    head = []
    i = 0

    while True:
        line = fileobj.readline(); i += 1
        if i == 1 and not line.startswith('---'):
            raise AcrylamidException("no meta information in %r found" % fileobj.name)
        elif i > 1 and not line.startswith('---'):
            head.append(line)
        elif i > 1 and line.startswith('---') or not line:
            break

    if yaml:
        try:
            return i, yaml.load(''.join(head))
        except yaml.YAMLError as e:
            raise AcrylamidException('YAMLError: %s' % str(e))
    else:
        props = {}
        for j, line in enumerate(head):
            if line[0] == '#' or not line.strip():
                continue
            try:
                key, value = [x.strip() for x in line.split(':', 1)]
            except ValueError:
                raise AcrylamidException('%s:%i ValueError: %s\n%s' %
                    (fileobj.name, j, line.strip('\n'),
                    ("Either your YAML is malformed or our naïve parser is to dumb \n"
                     "to read it. Revalidate your YAML or install PyYAML parser with \n"
                     "> easy_install -U pyyaml")))
            props[key] = distinguish(value)

    if 'title' not in props:
        raise AcrylamidException('No title given in %r' % fileobj.name)

    return i, props
Пример #14
0
    def __init__(self, path, conf):

        self.filename = path
        self.tzinfo = conf.get('tzinfo', None)
        self.defaultcopywildcard = conf.get('copy_wildcard', '_[0-9]*.*')

        with io.open(path, 'r', encoding='utf-8', errors='replace') as fp:

            peak = lchop(fp.read(512), BOM_UTF8)
            fp.seek(0)

            if peak.startswith('---\n'):
                i, meta = yamlstyle(fp)
            elif isrest(peak):
                i, meta = reststyle(fp)
            elif peak.startswith('% '):
                i, meta = pandocstyle(fp)
            else:
                i, meta = markdownstyle(fp)

        meta['title'] = str(meta['title'])  # YAML can convert 42 to an int
        meta['category'] = lchop(dirname(path) + '/',
                                 conf['content_dir']).split('/')

        jekyll = r'(?:(.+?)/)?(\d{4}-\d{2}-\d{2})-(.+)'
        m = re.match('^' + conf['content_dir'] + jekyll + '$',
                     splitext(path)[0])

        if m:
            meta.setdefault('date', m.group(2))
            meta.setdefault('slug', m.group(3))

            if m.group(1) is not None:
                meta['category'] = m.group(1).split('/')

        self.offset = i
        Reader.__init__(self, conf, meta)

        path, ext = os.path.splitext(path)
        self.path = lchop(path, conf['content_dir'])
        self.extension = ext[1:]
Пример #15
0
    def __init__(self, path, conf):

        self.filename = path
        self.tzinfo = conf.get('tzinfo', None)
        self.defaultcopywildcard = conf.get('copy_wildcard', '_[0-9]*.*')

        with io.open(path, 'r', encoding='utf-8', errors='replace') as fp:

            peak = lchop(fp.read(512), BOM_UTF8)
            fp.seek(0)

            if peak.startswith('---\n'):
                i, meta = yamlstyle(fp)
            elif isrest(peak):
                i, meta = reststyle(fp)
            elif peak.startswith('% '):
                i, meta = pandocstyle(fp)
            else:
                i, meta = markdownstyle(fp)

        meta['title'] = str(meta['title'])  # YAML can convert 42 to an int
        meta['category'] = lchop(dirname(path) + '/', conf['content_dir']).split('/')

        jekyll = r'(?:(.+?)/)?(\d{4}-\d{2}-\d{2})-(.+)'
        m = re.match('^' + conf['content_dir'] + jekyll + '$', splitext(path)[0])

        if m:
            meta.setdefault('date', m.group(2))
            meta.setdefault('slug', m.group(3))

            if m.group(1) is not None:
                meta['category'] = m.group(1).split('/')

        self.offset = i
        Reader.__init__(self, conf, meta)

        path, ext = os.path.splitext(path)
        self.path = lchop(path, conf['content_dir'])
        self.extension = ext[1:]
Пример #16
0
def distinguish(value):
    """Convert :param value: to None, Int, Bool, a List or String.
    """
    if not isinstance(value, string_types):
        return value

    if not isinstance(value, string_types):
        value = str(value)

    if value == '':
        return None
    elif value.isdigit():
        return int(value)
    elif value.lower() in ['true', 'false']:
        return True if value.capitalize() == 'True' else False
    elif value[0] == '[' and value[-1] == ']':
        tokenizer = shlex.shlex(value[1:-1], posix=True)
        value = list(takewhile(
            lambda token: token != tokenizer.eof,
            (tokenizer.get_token() for _ in repeat(None))))
        return [unsafe(val) for val in value if val != ',']
    else:
        return unsafe(value)
Пример #17
0
 def __add__(self, other):
     return str.__add__(str(self), other)
Пример #18
0
 def encode(self, encoding):
     return str(self).encode(encoding)
Пример #19
0
def initialize(conf, env):
    """Initializes Jinja2 environment, prepares locale and configure
    some minor things. Filter and View are inited with conf and env,
    a data dict is returned.
    """
    # initialize cache, optional to cache_dir
    cache.init(conf.get('cache_dir'))

    env['version'] = type('Version', (str, ), dict(zip(
        ['major', 'minor'], LooseVersion(dist.version).version[:2])))(dist.version)

    # crawl through CHANGES.md and stop on breaking changes
    if history.breaks(env, cache.emptyrun):
        cache.shutdown()
        print("Detected version upgrade that might break your configuration. Run")
        print("Acrylamid a second time to get rid of this message and premature exit.")
        raise SystemExit

    # set up templating environment
    env.engine = import_object(conf['engine'])()

    env.engine.init(conf['theme'], cache.cache_dir)
    env.engine.register('safeslug', helpers.safeslug)
    env.engine.register('tagify', lambda x: x)

    # try language set in LANG, if set correctly use it
    try:
        locale.setlocale(locale.LC_ALL, str(conf.get('lang', '')))
    except (locale.Error, TypeError):
        # try if LANG is an alias
        try:
            locale.setlocale(locale.LC_ALL, locale.locale_alias[str(conf.get('lang', '')).lower()])
        except (locale.Error, KeyError):
            # LANG is not an alias, so we use system's default
            try:
                locale.setlocale(locale.LC_ALL, '')
            except locale.Error:
                pass  # hope this makes Travis happy
            log.info('notice  your OS does not support %s, fallback to %s', conf.get('lang', ''),
                     locale.getlocale()[0])
    if locale.getlocale()[0] is not None:
        conf['lang'] = locale.getlocale()[0][:2]
    else:
        # getlocale() is (None, None) aka 'C'
        conf['lang'] = 'en'

    if 'www_root' not in conf:
        log.warn('no `www_root` specified, using localhost:8000')
        conf['www_root'] = 'http://localhost:8000/'

    # figure out timezone and set offset, more verbose for 2.6 compatibility
    td = (datetime.now() - datetime.utcnow())
    offset = round(total_seconds(td) / 3600.0)
    conf['tzinfo'] = readers.Timezone(offset)

    # determine http(s), host and path
    env['protocol'], env['netloc'], env['path'], x, y = urlsplit(conf['www_root'])

    # take off the trailing slash for www_root and path
    conf['www_root'] = conf['www_root'].rstrip('/')
    env['path'] = env['path'].rstrip('/')

    if env['path']:
        conf['output_dir'] = conf['output_dir'] + env['path']

    lazy.enable()
    filters.initialize(conf["filters_dir"][:], conf, env)
    lazy.disable()  # this has weird side effects with jinja2, so disabled after filters

    views.initialize(conf["views_dir"][:], conf, env)
    env.views = views.Views(view for view in views.get_views())

    entryfmt, pagefmt = '/:year/:slug/', '/:slug/'
    for view in views.get_views():
        if view.name == 'entry':
            entryfmt = view.path
        if view.name == 'page':
            pagefmt = view.path

    conf.setdefault('entry_permalink', entryfmt)
    conf.setdefault('page_permalink', pagefmt)

    # register webassets to theme engine, make webassets available as env.webassets
    assets.initialize(conf, env)

    return {'conf': conf, 'env': env}
Пример #20
0
 def __add__(self, other):
     return str(self) + other
Пример #21
0
 def __add__(self, other):
     return str.__add__(str(self), other)
Пример #22
0
 def encode(self, encoding):
     return str(self).encode(encoding)
Пример #23
0
 def __radd__(self, other):
     return other + str(other)
Пример #24
0
def initialize(conf, env):
    """Initializes Jinja2 environment, prepares locale and configure
    some minor things. Filter and View are inited with conf and env,
    a data dict is returned.
    """
    # initialize cache, optional to cache_dir
    cache.init(conf.get('cache_dir'))

    env['version'] = type(
        'Version', (str, ),
        dict(zip(['major', 'minor'],
                 LooseVersion(dist.version).version[:2])))(dist.version)

    # crawl through CHANGES.md and stop on breaking changes
    if history.breaks(env, cache.emptyrun):
        cache.shutdown()
        print(
            "Detected version upgrade that might break your configuration. Run"
        )
        print(
            "Acrylamid a second time to get rid of this message and premature exit."
        )
        raise SystemExit

    # set up templating environment
    env.engine = import_object(conf['engine'])(conf['theme'], cache.cache_dir)
    env.engine.register('safeslug', helpers.safeslug)
    env.engine.register('tagify', lambda x: x)

    # try language set in LANG, if set correctly use it
    try:
        locale.setlocale(locale.LC_ALL, str(conf.get('lang', '')))
    except (locale.Error, TypeError):
        # try if LANG is an alias
        try:
            locale.setlocale(
                locale.LC_ALL, locale.locale_alias[str(conf.get('lang',
                                                                '')).lower()])
        except (locale.Error, KeyError):
            # LANG is not an alias, so we use system's default
            try:
                locale.setlocale(locale.LC_ALL, '')
            except locale.Error:
                pass  # hope this makes Travis happy
            log.info('notice  your OS does not support %s, fallback to %s',
                     conf.get('lang', ''),
                     locale.getlocale()[0])
    if locale.getlocale()[0] is not None:
        conf['lang'] = locale.getlocale()[0][:2]
    else:
        # getlocale() is (None, None) aka 'C'
        conf['lang'] = 'en'

    if 'www_root' not in conf:
        log.warn('no `www_root` specified, using localhost:8000')
        conf['www_root'] = 'http://localhost:8000/'

    # figure out timezone and set offset, more verbose for 2.6 compatibility
    td = (datetime.now() - datetime.utcnow())
    offset = round(total_seconds(td) / 3600.0)
    conf['tzinfo'] = readers.Timezone(offset)

    # determine http(s), host and path
    env['protocol'], env['netloc'], env['path'], x, y = urlsplit(
        conf['www_root'])

    # take off the trailing slash for www_root and path
    conf['www_root'] = conf['www_root'].rstrip('/')
    env['path'] = env['path'].rstrip('/')

    if env['path']:
        conf['output_dir'] = conf['output_dir'] + env['path']

    lazy.enable()
    filters.initialize(conf["filters_dir"][:], conf, env)
    lazy.disable(
    )  # this has weird side effects with jinja2, so disabled after filters

    views.initialize(conf["views_dir"][:], conf, env)
    env.views = views.Views(view for view in views.get_views())

    entryfmt, pagefmt = '/:year/:slug/', '/:slug/'
    for view in views.get_views():
        if view.name == 'entry':
            entryfmt = view.path
        if view.name == 'page':
            pagefmt = view.path

    conf.setdefault('entry_permalink', entryfmt)
    conf.setdefault('page_permalink', pagefmt)

    # register webassets to theme engine, make webassets available as env.webassets
    assets.initialize(conf, env)

    return {'conf': conf, 'env': env}