mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
Initial pass of removing Python 2 support
This commit removes Six as a dependency for Pelican, replacing the relevant aliases with the proper Python 3 imports. It also removes references to Python 2 logic that did not require Six.
This commit is contained in:
parent
ae73d06301
commit
1e0e541b57
43 changed files with 126 additions and 459 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -11,7 +11,6 @@ tags
|
||||||
.tox
|
.tox
|
||||||
.coverage
|
.coverage
|
||||||
htmlcov
|
htmlcov
|
||||||
six-*.egg/
|
|
||||||
*.orig
|
*.orig
|
||||||
venv
|
venv
|
||||||
samples/output
|
samples/output
|
||||||
|
|
|
||||||
1
THANKS
1
THANKS
|
|
@ -92,6 +92,7 @@ Joshua Adelman
|
||||||
Julian Berman
|
Julian Berman
|
||||||
Justin Mayer
|
Justin Mayer
|
||||||
Kevin Deldycke
|
Kevin Deldycke
|
||||||
|
Kevin Yap
|
||||||
Kyle Fuller
|
Kyle Fuller
|
||||||
Laureline Guerin
|
Laureline Guerin
|
||||||
Leonard Huang
|
Leonard Huang
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
try:
|
try:
|
||||||
import collections.abc as collections
|
import collections.abc as collections
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import collections
|
import collections
|
||||||
import locale
|
|
||||||
import logging
|
import logging
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import os
|
import os
|
||||||
|
|
@ -15,8 +13,6 @@ import sys
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
# pelican.log has to be the first pelican module to be loaded
|
# pelican.log has to be the first pelican module to be loaded
|
||||||
# because logging.setLoggerClass has to be called before logging.getLogger
|
# because logging.setLoggerClass has to be called before logging.getLogger
|
||||||
from pelican.log import init as init_logging
|
from pelican.log import init as init_logging
|
||||||
|
|
@ -76,11 +72,10 @@ class Pelican(object):
|
||||||
sys.path.insert(0, pluginpath)
|
sys.path.insert(0, pluginpath)
|
||||||
for plugin in self.settings['PLUGINS']:
|
for plugin in self.settings['PLUGINS']:
|
||||||
# if it's a string, then import it
|
# if it's a string, then import it
|
||||||
if isinstance(plugin, six.string_types):
|
if isinstance(plugin, str):
|
||||||
logger.debug("Loading plugin `%s`", plugin)
|
logger.debug("Loading plugin `%s`", plugin)
|
||||||
try:
|
try:
|
||||||
plugin = __import__(plugin, globals(), locals(),
|
plugin = __import__(plugin, globals(), locals(), 'module')
|
||||||
str('module'))
|
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
logger.error(
|
logger.error(
|
||||||
"Cannot load plugin `%s`\n%s", plugin, e)
|
"Cannot load plugin `%s`\n%s", plugin, e)
|
||||||
|
|
@ -375,15 +370,6 @@ def get_config(args):
|
||||||
config['BIND'] = args.bind
|
config['BIND'] = args.bind
|
||||||
config['DEBUG'] = args.verbosity == logging.DEBUG
|
config['DEBUG'] = args.verbosity == logging.DEBUG
|
||||||
|
|
||||||
# argparse returns bytes in Py2. There is no definite answer as to which
|
|
||||||
# encoding argparse (or sys.argv) uses.
|
|
||||||
# "Best" option seems to be locale.getpreferredencoding()
|
|
||||||
# http://mail.python.org/pipermail/python-list/2006-October/405766.html
|
|
||||||
if not six.PY3:
|
|
||||||
enc = locale.getpreferredencoding()
|
|
||||||
for key in config:
|
|
||||||
if key in ('PATH', 'OUTPUT_PATH', 'THEME'):
|
|
||||||
config[key] = config[key].decode(enc)
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -397,7 +383,7 @@ def get_instance(args):
|
||||||
settings = read_settings(config_file, override=get_config(args))
|
settings = read_settings(config_file, override=get_config(args))
|
||||||
|
|
||||||
cls = settings['PELICAN_CLASS']
|
cls = settings['PELICAN_CLASS']
|
||||||
if isinstance(cls, six.string_types):
|
if isinstance(cls, str):
|
||||||
module, cls_name = cls.rsplit('.', 1)
|
module, cls_name = cls.rsplit('.', 1)
|
||||||
module = __import__(module)
|
module = __import__(module)
|
||||||
cls = getattr(module, cls_name)
|
cls = getattr(module, cls_name)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
"""
|
"""
|
||||||
python -m pelican module entry point to run via python -m
|
python -m pelican module entry point to run via python -m
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
|
||||||
|
|
||||||
from . import main
|
from . import main
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import pickle
|
||||||
from six.moves import cPickle as pickle
|
|
||||||
|
|
||||||
from pelican.utils import mkdir_p
|
from pelican.utils import mkdir_p
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,20 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
import datetime
|
||||||
import locale
|
import locale
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
from urllib.parse import urljoin, urlparse, urlunparse
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
import six
|
|
||||||
from six.moves.urllib.parse import urljoin, urlparse, urlunparse
|
|
||||||
|
|
||||||
from pelican import signals
|
from pelican import signals
|
||||||
from pelican.settings import DEFAULT_CONFIG
|
from pelican.settings import DEFAULT_CONFIG
|
||||||
from pelican.utils import (SafeDatetime, deprecated_attribute, memoized,
|
from pelican.utils import (deprecated_attribute, memoized, path_to_url,
|
||||||
path_to_url, posixize_path,
|
posixize_path, sanitised_join, set_date_tzinfo,
|
||||||
python_2_unicode_compatible, sanitised_join,
|
slugify, truncate_html_words)
|
||||||
set_date_tzinfo, slugify, strftime,
|
|
||||||
truncate_html_words)
|
|
||||||
|
|
||||||
# Import these so that they're avalaible when you import from pelican.contents.
|
# Import these so that they're avalaible when you import from pelican.contents.
|
||||||
from pelican.urlwrappers import (Author, Category, Tag, URLWrapper) # NOQA
|
from pelican.urlwrappers import (Author, Category, Tag, URLWrapper) # NOQA
|
||||||
|
|
@ -27,7 +22,6 @@ from pelican.urlwrappers import (Author, Category, Tag, URLWrapper) # NOQA
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Content(object):
|
class Content(object):
|
||||||
"""Represents a content.
|
"""Represents a content.
|
||||||
|
|
||||||
|
|
@ -121,9 +115,6 @@ class Content(object):
|
||||||
|
|
||||||
if isinstance(self.date_format, tuple):
|
if isinstance(self.date_format, tuple):
|
||||||
locale_string = self.date_format[0]
|
locale_string = self.date_format[0]
|
||||||
if sys.version_info < (3, ) and isinstance(locale_string,
|
|
||||||
six.text_type):
|
|
||||||
locale_string = locale_string.encode('ascii')
|
|
||||||
locale.setlocale(locale.LC_ALL, locale_string)
|
locale.setlocale(locale.LC_ALL, locale_string)
|
||||||
self.date_format = self.date_format[1]
|
self.date_format = self.date_format[1]
|
||||||
|
|
||||||
|
|
@ -133,11 +124,11 @@ class Content(object):
|
||||||
|
|
||||||
if hasattr(self, 'date'):
|
if hasattr(self, 'date'):
|
||||||
self.date = set_date_tzinfo(self.date, timezone)
|
self.date = set_date_tzinfo(self.date, timezone)
|
||||||
self.locale_date = strftime(self.date, self.date_format)
|
self.locale_date = self.date.strftime(self.date_format)
|
||||||
|
|
||||||
if hasattr(self, 'modified'):
|
if hasattr(self, 'modified'):
|
||||||
self.modified = set_date_tzinfo(self.modified, timezone)
|
self.modified = set_date_tzinfo(self.modified, timezone)
|
||||||
self.locale_modified = strftime(self.modified, self.date_format)
|
self.locale_modified = self.modified.strftime(self.date_format)
|
||||||
|
|
||||||
# manage status
|
# manage status
|
||||||
if not hasattr(self, 'status'):
|
if not hasattr(self, 'status'):
|
||||||
|
|
@ -213,7 +204,7 @@ class Content(object):
|
||||||
'path': path_to_url(path),
|
'path': path_to_url(path),
|
||||||
'slug': getattr(self, 'slug', ''),
|
'slug': getattr(self, 'slug', ''),
|
||||||
'lang': getattr(self, 'lang', 'en'),
|
'lang': getattr(self, 'lang', 'en'),
|
||||||
'date': getattr(self, 'date', SafeDatetime.now()),
|
'date': getattr(self, 'date', datetime.datetime.now()),
|
||||||
'author': self.author.slug if hasattr(self, 'author') else '',
|
'author': self.author.slug if hasattr(self, 'author') else '',
|
||||||
'category': self.category.slug if hasattr(self, 'category') else ''
|
'category': self.category.slug if hasattr(self, 'category') else ''
|
||||||
})
|
})
|
||||||
|
|
@ -512,22 +503,21 @@ class Article(Content):
|
||||||
# handle WITH_FUTURE_DATES (designate article to draft based on date)
|
# handle WITH_FUTURE_DATES (designate article to draft based on date)
|
||||||
if not self.settings['WITH_FUTURE_DATES'] and hasattr(self, 'date'):
|
if not self.settings['WITH_FUTURE_DATES'] and hasattr(self, 'date'):
|
||||||
if self.date.tzinfo is None:
|
if self.date.tzinfo is None:
|
||||||
now = SafeDatetime.now()
|
now = datetime.datetime.now()
|
||||||
else:
|
else:
|
||||||
now = SafeDatetime.utcnow().replace(tzinfo=pytz.utc)
|
now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
|
||||||
if self.date > now:
|
if self.date > now:
|
||||||
self.status = 'draft'
|
self.status = 'draft'
|
||||||
|
|
||||||
# if we are a draft and there is no date provided, set max datetime
|
# if we are a draft and there is no date provided, set max datetime
|
||||||
if not hasattr(self, 'date') and self.status == 'draft':
|
if not hasattr(self, 'date') and self.status == 'draft':
|
||||||
self.date = SafeDatetime.max
|
self.date = datetime.datetime.max
|
||||||
|
|
||||||
def _expand_settings(self, key):
|
def _expand_settings(self, key):
|
||||||
klass = 'draft' if self.status == 'draft' else 'article'
|
klass = 'draft' if self.status == 'draft' else 'article'
|
||||||
return super(Article, self)._expand_settings(key, klass)
|
return super(Article, self)._expand_settings(key, klass)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Static(Content):
|
class Static(Content):
|
||||||
mandatory_properties = ('title',)
|
mandatory_properties = ('title',)
|
||||||
default_status = 'published'
|
default_status = 'published'
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import calendar
|
import calendar
|
||||||
import errno
|
import errno
|
||||||
|
|
@ -15,15 +14,12 @@ from operator import attrgetter
|
||||||
from jinja2 import (BaseLoader, ChoiceLoader, Environment, FileSystemLoader,
|
from jinja2 import (BaseLoader, ChoiceLoader, Environment, FileSystemLoader,
|
||||||
PrefixLoader, TemplateNotFound)
|
PrefixLoader, TemplateNotFound)
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from pelican import signals
|
from pelican import signals
|
||||||
from pelican.cache import FileStampDataCacher
|
from pelican.cache import FileStampDataCacher
|
||||||
from pelican.contents import Article, Page, Static
|
from pelican.contents import Article, Page, Static
|
||||||
from pelican.readers import Readers
|
from pelican.readers import Readers
|
||||||
from pelican.utils import (DateFormatter, copy, mkdir_p, order_content,
|
from pelican.utils import (DateFormatter, copy, mkdir_p, order_content,
|
||||||
posixize_path, process_translations,
|
posixize_path, process_translations)
|
||||||
python_2_unicode_compatible)
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
@ -33,7 +29,6 @@ class PelicanTemplateNotFound(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class Generator(object):
|
class Generator(object):
|
||||||
"""Baseclass generator"""
|
"""Baseclass generator"""
|
||||||
|
|
||||||
|
|
@ -138,7 +133,7 @@ class Generator(object):
|
||||||
extensions are allowed)
|
extensions are allowed)
|
||||||
"""
|
"""
|
||||||
# backward compatibility for older generators
|
# backward compatibility for older generators
|
||||||
if isinstance(paths, six.string_types):
|
if isinstance(paths, str):
|
||||||
paths = [paths]
|
paths = [paths]
|
||||||
|
|
||||||
# group the exclude dir names by parent path, for use with os.walk()
|
# group the exclude dir names by parent path, for use with os.walk()
|
||||||
|
|
@ -513,8 +508,6 @@ class ArticlesGenerator(CachingGenerator):
|
||||||
context["period"] = (_period,)
|
context["period"] = (_period,)
|
||||||
else:
|
else:
|
||||||
month_name = calendar.month_name[_period[1]]
|
month_name = calendar.month_name[_period[1]]
|
||||||
if not six.PY3:
|
|
||||||
month_name = month_name.decode('utf-8')
|
|
||||||
if key == period_date_key['month']:
|
if key == period_date_key['month']:
|
||||||
context["period"] = (_period[0],
|
context["period"] = (_period[0],
|
||||||
month_name)
|
month_name)
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,9 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import locale
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
try:
|
|
||||||
from collections.abc import Mapping
|
|
||||||
except ImportError:
|
|
||||||
from collections import Mapping
|
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'init'
|
'init'
|
||||||
|
|
@ -29,20 +21,17 @@ class BaseFormatter(logging.Formatter):
|
||||||
# format multiline messages 'nicely' to make it clear they are together
|
# format multiline messages 'nicely' to make it clear they are together
|
||||||
record.msg = record.msg.replace('\n', '\n | ')
|
record.msg = record.msg.replace('\n', '\n | ')
|
||||||
record.args = tuple(arg.replace('\n', '\n | ') if
|
record.args = tuple(arg.replace('\n', '\n | ') if
|
||||||
isinstance(arg, six.string_types) else
|
isinstance(arg, str) else
|
||||||
arg for arg in record.args)
|
arg for arg in record.args)
|
||||||
return super(BaseFormatter, self).format(record)
|
return super(BaseFormatter, self).format(record)
|
||||||
|
|
||||||
def formatException(self, ei):
|
def formatException(self, ei):
|
||||||
''' prefix traceback info for better representation '''
|
''' prefix traceback info for better representation '''
|
||||||
# .formatException returns a bytestring in py2 and unicode in py3
|
|
||||||
# since .format will handle unicode conversion,
|
|
||||||
# str() calls are used to normalize formatting string
|
|
||||||
s = super(BaseFormatter, self).formatException(ei)
|
s = super(BaseFormatter, self).formatException(ei)
|
||||||
# fancy format traceback
|
# fancy format traceback
|
||||||
s = str('\n').join(str(' | ') + line for line in s.splitlines())
|
s = '\n'.join(' | ' + line for line in s.splitlines())
|
||||||
# separate the traceback from the preceding lines
|
# separate the traceback from the preceding lines
|
||||||
s = str(' |___\n{}').format(s)
|
s = ' |___\n{}'.format(s)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def _get_levelname(self, name):
|
def _get_levelname(self, name):
|
||||||
|
|
@ -140,41 +129,7 @@ class LimitFilter(logging.Filter):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class SafeLogger(logging.Logger):
|
class LimitLogger(logging.Logger):
|
||||||
"""
|
|
||||||
Base Logger which properly encodes Exceptions in Py2
|
|
||||||
"""
|
|
||||||
_exc_encoding = locale.getpreferredencoding()
|
|
||||||
|
|
||||||
def _log(self, level, msg, args, exc_info=None, extra=None):
|
|
||||||
# if the only argument is a Mapping, Logger uses that for formatting
|
|
||||||
# format values for that case
|
|
||||||
if args and len(args) == 1 and isinstance(args[0], Mapping):
|
|
||||||
args = ({k: self._decode_arg(v) for k, v in args[0].items()},)
|
|
||||||
# otherwise, format each arg
|
|
||||||
else:
|
|
||||||
args = tuple(self._decode_arg(arg) for arg in args)
|
|
||||||
super(SafeLogger, self)._log(
|
|
||||||
level, msg, args, exc_info=exc_info, extra=extra)
|
|
||||||
|
|
||||||
def _decode_arg(self, arg):
|
|
||||||
'''
|
|
||||||
properly decode an arg for Py2 if it's Exception
|
|
||||||
|
|
||||||
|
|
||||||
localized systems have errors in native language if locale is set
|
|
||||||
so convert the message to unicode with the correct encoding
|
|
||||||
'''
|
|
||||||
if isinstance(arg, Exception):
|
|
||||||
text = str('%s: %s') % (arg.__class__.__name__, arg)
|
|
||||||
if six.PY2:
|
|
||||||
text = text.decode(self._exc_encoding)
|
|
||||||
return text
|
|
||||||
else:
|
|
||||||
return arg
|
|
||||||
|
|
||||||
|
|
||||||
class LimitLogger(SafeLogger):
|
|
||||||
"""
|
"""
|
||||||
A logger which adds LimitFilter automatically
|
A logger which adds LimitFilter automatically
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -7,8 +6,6 @@ import os
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from math import ceil
|
from math import ceil
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
PaginationRule = namedtuple(
|
PaginationRule = namedtuple(
|
||||||
'PaginationRule',
|
'PaginationRule',
|
||||||
|
|
@ -131,7 +128,7 @@ class Page(object):
|
||||||
|
|
||||||
prop_value = getattr(rule, key)
|
prop_value = getattr(rule, key)
|
||||||
|
|
||||||
if not isinstance(prop_value, six.string_types):
|
if not isinstance(prop_value, str):
|
||||||
logger.warning('%s is set to %s', key, prop_value)
|
logger.warning('%s is set to %s', key, prop_value)
|
||||||
return prop_value
|
return prop_value
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
from html.parser import HTMLParser
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
import docutils
|
import docutils
|
||||||
import docutils.core
|
import docutils.core
|
||||||
|
|
@ -12,16 +14,11 @@ import docutils.io
|
||||||
from docutils.parsers.rst.languages import get_language as get_docutils_lang
|
from docutils.parsers.rst.languages import get_language as get_docutils_lang
|
||||||
from docutils.writers.html4css1 import HTMLTranslator, Writer
|
from docutils.writers.html4css1 import HTMLTranslator, Writer
|
||||||
|
|
||||||
import six
|
|
||||||
from six import StringIO
|
|
||||||
from six.moves.html_parser import HTMLParser
|
|
||||||
|
|
||||||
from pelican import rstdirectives # NOQA
|
from pelican import rstdirectives # NOQA
|
||||||
from pelican import signals
|
from pelican import signals
|
||||||
from pelican.cache import FileStampDataCacher
|
from pelican.cache import FileStampDataCacher
|
||||||
from pelican.contents import Author, Category, Page, Tag
|
from pelican.contents import Author, Category, Page, Tag
|
||||||
from pelican.utils import SafeDatetime, escape_html, get_date, pelican_open, \
|
from pelican.utils import escape_html, get_date, pelican_open, posixize_path
|
||||||
posixize_path
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from markdown import Markdown
|
from markdown import Markdown
|
||||||
|
|
@ -79,7 +76,7 @@ def ensure_metadata_list(text):
|
||||||
Regardless, all list items undergo .strip() before returning, and
|
Regardless, all list items undergo .strip() before returning, and
|
||||||
empty items are discarded.
|
empty items are discarded.
|
||||||
"""
|
"""
|
||||||
if isinstance(text, six.text_type):
|
if isinstance(text, str):
|
||||||
if ';' in text:
|
if ';' in text:
|
||||||
text = text.split(';')
|
text = text.split(';')
|
||||||
else:
|
else:
|
||||||
|
|
@ -212,8 +209,7 @@ class RstReader(BaseReader):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
if six.PY3:
|
kwargs['mode'] = kwargs.get('mode', 'r').replace('U', '')
|
||||||
kwargs['mode'] = kwargs.get('mode', 'r').replace('U', '')
|
|
||||||
docutils.io.FileInput.__init__(self, *args, **kwargs)
|
docutils.io.FileInput.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
@ -685,10 +681,10 @@ def default_metadata(settings=None, process=None):
|
||||||
metadata['category'] = value
|
metadata['category'] = value
|
||||||
if settings.get('DEFAULT_DATE', None) and \
|
if settings.get('DEFAULT_DATE', None) and \
|
||||||
settings['DEFAULT_DATE'] != 'fs':
|
settings['DEFAULT_DATE'] != 'fs':
|
||||||
if isinstance(settings['DEFAULT_DATE'], six.string_types):
|
if isinstance(settings['DEFAULT_DATE'], str):
|
||||||
metadata['date'] = get_date(settings['DEFAULT_DATE'])
|
metadata['date'] = get_date(settings['DEFAULT_DATE'])
|
||||||
else:
|
else:
|
||||||
metadata['date'] = SafeDatetime(*settings['DEFAULT_DATE'])
|
metadata['date'] = datetime.datetime(*settings['DEFAULT_DATE'])
|
||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -696,7 +692,7 @@ def path_metadata(full_path, source_path, settings=None):
|
||||||
metadata = {}
|
metadata = {}
|
||||||
if settings:
|
if settings:
|
||||||
if settings.get('DEFAULT_DATE', None) == 'fs':
|
if settings.get('DEFAULT_DATE', None) == 'fs':
|
||||||
metadata['date'] = SafeDatetime.fromtimestamp(
|
metadata['date'] = datetime.datetime.fromtimestamp(
|
||||||
os.stat(full_path).st_mtime)
|
os.stat(full_path).st_mtime)
|
||||||
|
|
||||||
# Apply EXTRA_PATH_METADATA for the source path and the paths of any
|
# Apply EXTRA_PATH_METADATA for the source path and the paths of any
|
||||||
|
|
@ -731,7 +727,7 @@ def parse_path_metadata(source_path, settings=None, process=None):
|
||||||
... process=reader.process_metadata)
|
... process=reader.process_metadata)
|
||||||
>>> pprint.pprint(metadata) # doctest: +ELLIPSIS
|
>>> pprint.pprint(metadata) # doctest: +ELLIPSIS
|
||||||
{'category': <pelican.urlwrappers.Category object at ...>,
|
{'category': <pelican.urlwrappers.Category object at ...>,
|
||||||
'date': SafeDatetime(2013, 1, 1, 0, 0),
|
'date': datetime.datetime(2013, 1, 1, 0, 0),
|
||||||
'slug': 'my-slug'}
|
'slug': 'my-slug'}
|
||||||
"""
|
"""
|
||||||
metadata = {}
|
metadata = {}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
@ -10,8 +9,6 @@ from pygments import highlight
|
||||||
from pygments.formatters import HtmlFormatter
|
from pygments.formatters import HtmlFormatter
|
||||||
from pygments.lexers import TextLexer, get_lexer_by_name
|
from pygments.lexers import TextLexer, get_lexer_by_name
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
import pelican.settings as pys
|
import pelican.settings as pys
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -49,7 +46,7 @@ class Pygments(Directive):
|
||||||
|
|
||||||
# Fetch the defaults
|
# Fetch the defaults
|
||||||
if pys.PYGMENTS_RST_OPTIONS is not None:
|
if pys.PYGMENTS_RST_OPTIONS is not None:
|
||||||
for k, v in six.iteritems(pys.PYGMENTS_RST_OPTIONS):
|
for k, v in pys.PYGMENTS_RST_OPTIONS.items():
|
||||||
# Locally set options overrides the defaults
|
# Locally set options overrides the defaults
|
||||||
if k not in self.options:
|
if k not in self.options:
|
||||||
self.options[k] = v
|
self.options[k] = v
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -7,16 +6,14 @@ import os
|
||||||
import posixpath
|
import posixpath
|
||||||
import ssl
|
import ssl
|
||||||
import sys
|
import sys
|
||||||
|
import urllib
|
||||||
|
from http import server
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from magic import from_file as magic_from_file
|
from magic import from_file as magic_from_file
|
||||||
except ImportError:
|
except ImportError:
|
||||||
magic_from_file = None
|
magic_from_file = None
|
||||||
|
|
||||||
from six.moves import BaseHTTPServer
|
|
||||||
from six.moves import SimpleHTTPServer as srvmod
|
|
||||||
from six.moves import urllib
|
|
||||||
|
|
||||||
from pelican.log import init as init_logging
|
from pelican.log import init as init_logging
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -44,7 +41,7 @@ def parse_arguments():
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
class ComplexHTTPRequestHandler(srvmod.SimpleHTTPRequestHandler):
|
class ComplexHTTPRequestHandler(server.SimpleHTTPRequestHandler):
|
||||||
SUFFIXES = ['.html', '/index.html', '/', '']
|
SUFFIXES = ['.html', '/index.html', '/', '']
|
||||||
|
|
||||||
def translate_path(self, path):
|
def translate_path(self, path):
|
||||||
|
|
@ -76,7 +73,7 @@ class ComplexHTTPRequestHandler(srvmod.SimpleHTTPRequestHandler):
|
||||||
if not self.path:
|
if not self.path:
|
||||||
return
|
return
|
||||||
|
|
||||||
srvmod.SimpleHTTPRequestHandler.do_GET(self)
|
server.SimpleHTTPRequestHandler.do_GET(self)
|
||||||
|
|
||||||
def get_path_that_exists(self, original_path):
|
def get_path_that_exists(self, original_path):
|
||||||
# Try to strip trailing slash
|
# Try to strip trailing slash
|
||||||
|
|
@ -96,7 +93,7 @@ class ComplexHTTPRequestHandler(srvmod.SimpleHTTPRequestHandler):
|
||||||
def guess_type(self, path):
|
def guess_type(self, path):
|
||||||
"""Guess at the mime type for the specified file.
|
"""Guess at the mime type for the specified file.
|
||||||
"""
|
"""
|
||||||
mimetype = srvmod.SimpleHTTPRequestHandler.guess_type(self, path)
|
mimetype = server.SimpleHTTPRequestHandler.guess_type(self, path)
|
||||||
|
|
||||||
# If the default guess is too generic, try the python-magic library
|
# If the default guess is too generic, try the python-magic library
|
||||||
if mimetype == 'application/octet-stream' and magic_from_file:
|
if mimetype == 'application/octet-stream' and magic_from_file:
|
||||||
|
|
@ -105,9 +102,9 @@ class ComplexHTTPRequestHandler(srvmod.SimpleHTTPRequestHandler):
|
||||||
return mimetype
|
return mimetype
|
||||||
|
|
||||||
|
|
||||||
class RootedHTTPServer(BaseHTTPServer.HTTPServer):
|
class RootedHTTPServer(server.HTTPServer):
|
||||||
def __init__(self, base_path, *args, **kwargs):
|
def __init__(self, base_path, *args, **kwargs):
|
||||||
BaseHTTPServer.HTTPServer.__init__(self, *args, **kwargs)
|
server.HTTPServer.__init__(self, *args, **kwargs)
|
||||||
self.RequestHandlerClass.base_path = base_path
|
self.RequestHandlerClass.base_path = base_path
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import inspect
|
import inspect
|
||||||
|
|
@ -10,8 +9,6 @@ import re
|
||||||
from os.path import isabs
|
from os.path import isabs
|
||||||
from posixpath import join as posix_join
|
from posixpath import join as posix_join
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from pelican.log import LimitFilter
|
from pelican.log import LimitFilter
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -278,7 +275,7 @@ def handle_deprecated_settings(settings):
|
||||||
del settings['PLUGIN_PATH']
|
del settings['PLUGIN_PATH']
|
||||||
|
|
||||||
# PLUGIN_PATHS: str -> [str]
|
# PLUGIN_PATHS: str -> [str]
|
||||||
if isinstance(settings.get('PLUGIN_PATHS'), six.string_types):
|
if isinstance(settings.get('PLUGIN_PATHS'), str):
|
||||||
logger.warning("Defining PLUGIN_PATHS setting as string "
|
logger.warning("Defining PLUGIN_PATHS setting as string "
|
||||||
"has been deprecated (should be a list)")
|
"has been deprecated (should be a list)")
|
||||||
settings['PLUGIN_PATHS'] = [settings['PLUGIN_PATHS']]
|
settings['PLUGIN_PATHS'] = [settings['PLUGIN_PATHS']]
|
||||||
|
|
@ -547,13 +544,13 @@ def configure_settings(settings):
|
||||||
|
|
||||||
# standardize strings to lists
|
# standardize strings to lists
|
||||||
for key in ['LOCALE']:
|
for key in ['LOCALE']:
|
||||||
if key in settings and isinstance(settings[key], six.string_types):
|
if key in settings and isinstance(settings[key], str):
|
||||||
settings[key] = [settings[key]]
|
settings[key] = [settings[key]]
|
||||||
|
|
||||||
# check settings that must be a particular type
|
# check settings that must be a particular type
|
||||||
for key, types in [
|
for key, types in [
|
||||||
('OUTPUT_SOURCES_EXTENSION', six.string_types),
|
('OUTPUT_SOURCES_EXTENSION', str),
|
||||||
('FILENAME_METADATA', six.string_types),
|
('FILENAME_METADATA', str),
|
||||||
]:
|
]:
|
||||||
if key in settings and not isinstance(settings[key], types):
|
if key in settings and not isinstance(settings[key], types):
|
||||||
value = settings.pop(key)
|
value = settings.pop(key)
|
||||||
|
|
@ -647,7 +644,7 @@ def configure_settings(settings):
|
||||||
'PAGE_PATHS',
|
'PAGE_PATHS',
|
||||||
)
|
)
|
||||||
for PATH_KEY in filter(lambda k: k in settings, path_keys):
|
for PATH_KEY in filter(lambda k: k in settings, path_keys):
|
||||||
if isinstance(settings[PATH_KEY], six.string_types):
|
if isinstance(settings[PATH_KEY], str):
|
||||||
logger.warning("Detected misconfiguration with %s setting "
|
logger.warning("Detected misconfiguration with %s setting "
|
||||||
"(must be a list), falling back to the default",
|
"(must be a list), falling back to the default",
|
||||||
PATH_KEY)
|
PATH_KEY)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
from blinker import signal
|
from blinker import signal
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
AUTHOR = 'Alexis Métaireau'
|
AUTHOR = 'Alexis Métaireau'
|
||||||
SITENAME = "Alexis' log"
|
SITENAME = "Alexis' log"
|
||||||
SITEURL = 'http://blog.notmyidea.org'
|
SITEURL = 'http://blog.notmyidea.org'
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import locale
|
import locale
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -10,12 +9,11 @@ import sys
|
||||||
import unittest
|
import unittest
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
from io import StringIO
|
||||||
from logging.handlers import BufferingHandler
|
from logging.handlers import BufferingHandler
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
|
|
||||||
from six import StringIO
|
|
||||||
|
|
||||||
from pelican.contents import Article
|
from pelican.contents import Article
|
||||||
from pelican.readers import default_metadata
|
from pelican.readers import default_metadata
|
||||||
from pelican.settings import DEFAULT_CONFIG
|
from pelican.settings import DEFAULT_CONFIG
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import absolute_import, unicode_literals
|
|
||||||
|
|
||||||
|
import datetime
|
||||||
import locale
|
import locale
|
||||||
import logging
|
import logging
|
||||||
import os.path
|
import os.path
|
||||||
|
|
@ -9,15 +9,12 @@ from sys import platform
|
||||||
|
|
||||||
from jinja2.utils import generate_lorem_ipsum
|
from jinja2.utils import generate_lorem_ipsum
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from pelican.contents import Article, Author, Category, Page, Static
|
from pelican.contents import Article, Author, Category, Page, Static
|
||||||
from pelican.settings import DEFAULT_CONFIG
|
from pelican.settings import DEFAULT_CONFIG
|
||||||
from pelican.signals import content_object_init
|
from pelican.signals import content_object_init
|
||||||
from pelican.tests.support import (LoggedTestCase, get_context, get_settings,
|
from pelican.tests.support import (LoggedTestCase, get_context, get_settings,
|
||||||
unittest)
|
unittest)
|
||||||
from pelican.utils import (SafeDatetime, path_to_url, posixize_path,
|
from pelican.utils import (path_to_url, posixize_path, truncate_html_words)
|
||||||
truncate_html_words)
|
|
||||||
|
|
||||||
|
|
||||||
# generate one paragraph, enclosed with <p>
|
# generate one paragraph, enclosed with <p>
|
||||||
|
|
@ -185,7 +182,7 @@ class TestPage(LoggedTestCase):
|
||||||
|
|
||||||
def test_datetime(self):
|
def test_datetime(self):
|
||||||
# If DATETIME is set to a tuple, it should be used to override LOCALE
|
# If DATETIME is set to a tuple, it should be used to override LOCALE
|
||||||
dt = SafeDatetime(2015, 9, 13)
|
dt = datetime.datetime(2015, 9, 13)
|
||||||
|
|
||||||
page_kwargs = self._copy_page_kwargs()
|
page_kwargs = self._copy_page_kwargs()
|
||||||
|
|
||||||
|
|
@ -286,9 +283,7 @@ class TestPage(LoggedTestCase):
|
||||||
'<a href="http://notmyidea.org/category/category.html">link</a>'))
|
'<a href="http://notmyidea.org/category/category.html">link</a>'))
|
||||||
|
|
||||||
def test_intrasite_link(self):
|
def test_intrasite_link(self):
|
||||||
# type does not take unicode in PY2 and bytes in PY3, which in
|
cls_name = '_DummyArticle'
|
||||||
# combination with unicode literals leads to following insane line:
|
|
||||||
cls_name = '_DummyArticle' if six.PY3 else b'_DummyArticle'
|
|
||||||
article = type(cls_name, (object,), {'url': 'article.html'})
|
article = type(cls_name, (object,), {'url': 'article.html'})
|
||||||
|
|
||||||
args = self.page_kwargs.copy()
|
args = self.page_kwargs.copy()
|
||||||
|
|
@ -370,9 +365,7 @@ class TestPage(LoggedTestCase):
|
||||||
self.assertEqual(p.custom, linked)
|
self.assertEqual(p.custom, linked)
|
||||||
|
|
||||||
def test_intrasite_link_more(self):
|
def test_intrasite_link_more(self):
|
||||||
# type does not take unicode in PY2 and bytes in PY3, which in
|
cls_name = '_DummyAsset'
|
||||||
# combination with unicode literals leads to following insane line:
|
|
||||||
cls_name = '_DummyAsset' if six.PY3 else b'_DummyAsset'
|
|
||||||
|
|
||||||
args = self.page_kwargs.copy()
|
args = self.page_kwargs.copy()
|
||||||
args['settings'] = get_settings()
|
args['settings'] = get_settings()
|
||||||
|
|
@ -487,9 +480,7 @@ class TestPage(LoggedTestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_intrasite_link_markdown_spaces(self):
|
def test_intrasite_link_markdown_spaces(self):
|
||||||
# Markdown introduces %20 instead of spaces, this tests that
|
cls_name = '_DummyArticle'
|
||||||
# we support markdown doing this.
|
|
||||||
cls_name = '_DummyArticle' if six.PY3 else b'_DummyArticle'
|
|
||||||
article = type(cls_name, (object,), {'url': 'article-spaces.html'})
|
article = type(cls_name, (object,), {'url': 'article-spaces.html'})
|
||||||
|
|
||||||
args = self.page_kwargs.copy()
|
args = self.page_kwargs.copy()
|
||||||
|
|
@ -512,7 +503,7 @@ class TestPage(LoggedTestCase):
|
||||||
def test_intrasite_link_source_and_generated(self):
|
def test_intrasite_link_source_and_generated(self):
|
||||||
"""Test linking both to the source and the generated article
|
"""Test linking both to the source and the generated article
|
||||||
"""
|
"""
|
||||||
cls_name = '_DummyAsset' if six.PY3 else b'_DummyAsset'
|
cls_name = '_DummyAsset'
|
||||||
|
|
||||||
args = self.page_kwargs.copy()
|
args = self.page_kwargs.copy()
|
||||||
args['settings'] = get_settings()
|
args['settings'] = get_settings()
|
||||||
|
|
@ -538,7 +529,7 @@ class TestPage(LoggedTestCase):
|
||||||
def test_intrasite_link_to_static_content_with_filename(self):
|
def test_intrasite_link_to_static_content_with_filename(self):
|
||||||
"""Test linking to a static resource with deprecated {filename}
|
"""Test linking to a static resource with deprecated {filename}
|
||||||
"""
|
"""
|
||||||
cls_name = '_DummyAsset' if six.PY3 else b'_DummyAsset'
|
cls_name = '_DummyAsset'
|
||||||
|
|
||||||
args = self.page_kwargs.copy()
|
args = self.page_kwargs.copy()
|
||||||
args['settings'] = get_settings()
|
args['settings'] = get_settings()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import locale
|
import locale
|
||||||
import os
|
import os
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import locale
|
import locale
|
||||||
import os
|
import os
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import absolute_import, unicode_literals
|
|
||||||
|
|
||||||
import locale
|
import locale
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import collections.abc as collections
|
import collections.abc as collections
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from pelican import readers
|
from pelican import readers
|
||||||
from pelican.tests.support import get_settings, unittest
|
from pelican.tests.support import get_settings, unittest
|
||||||
from pelican.utils import SafeDatetime
|
from pelican.utils import SafeDatetime
|
||||||
|
|
@ -64,8 +61,7 @@ class TestAssertDictHasSubset(ReaderTest):
|
||||||
self.assertDictHasSubset(self.dictionary, self.dictionary)
|
self.assertDictHasSubset(self.dictionary, self.dictionary)
|
||||||
|
|
||||||
def test_fail_not_set(self):
|
def test_fail_not_set(self):
|
||||||
six.assertRaisesRegex(
|
self.assertRaisesRegex(
|
||||||
self,
|
|
||||||
AssertionError,
|
AssertionError,
|
||||||
r'Expected.*key-c.*to have value.*val-c.*but was not in Dict',
|
r'Expected.*key-c.*to have value.*val-c.*but was not in Dict',
|
||||||
self.assertDictHasSubset,
|
self.assertDictHasSubset,
|
||||||
|
|
@ -73,8 +69,7 @@ class TestAssertDictHasSubset(ReaderTest):
|
||||||
{'key-c': 'val-c'})
|
{'key-c': 'val-c'})
|
||||||
|
|
||||||
def test_fail_wrong_val(self):
|
def test_fail_wrong_val(self):
|
||||||
six.assertRaisesRegex(
|
self.assertRaisesRegex(
|
||||||
self,
|
|
||||||
AssertionError,
|
AssertionError,
|
||||||
r'Expected .*key-a.* to have value .*val-b.* but was .*val-a.*',
|
r'Expected .*key-a.* to have value .*val-b.* but was .*val-a.*',
|
||||||
self.assertDictHasSubset,
|
self.assertDictHasSubset,
|
||||||
|
|
@ -445,7 +440,7 @@ class RstReaderTest(ReaderTest):
|
||||||
def test_parse_error(self):
|
def test_parse_error(self):
|
||||||
# Verify that it raises an Exception, not nothing and not SystemExit or
|
# Verify that it raises an Exception, not nothing and not SystemExit or
|
||||||
# some such
|
# some such
|
||||||
with six.assertRaisesRegex(self, Exception, "underline too short"):
|
with self.assertRaisesRegex(Exception, "underline too short"):
|
||||||
self.read_file(path='../parse_error/parse_error.rst')
|
self.read_file(path='../parse_error/parse_error.rst')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
from pelican.tests.support import unittest
|
from pelican.tests.support import unittest
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import os
|
import os
|
||||||
|
from io import BytesIO
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
|
|
||||||
from six import BytesIO
|
|
||||||
|
|
||||||
from pelican.server import ComplexHTTPRequestHandler
|
from pelican.server import ComplexHTTPRequestHandler
|
||||||
from pelican.tests.support import unittest
|
from pelican.tests.support import unittest
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import locale
|
import locale
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from pelican.tests.support import unittest
|
from pelican.tests.support import unittest
|
||||||
from pelican.urlwrappers import Author, Category, Tag, URLWrapper
|
from pelican.urlwrappers import Author, Category, Tag, URLWrapper
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import absolute_import, print_function, unicode_literals
|
|
||||||
|
|
||||||
import locale
|
import locale
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -11,8 +10,6 @@ from tempfile import mkdtemp
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from pelican import utils
|
from pelican import utils
|
||||||
from pelican.generators import TemplatePagesGenerator
|
from pelican.generators import TemplatePagesGenerator
|
||||||
from pelican.settings import read_settings
|
from pelican.settings import read_settings
|
||||||
|
|
@ -720,8 +717,7 @@ class TestSanitisedJoin(unittest.TestCase):
|
||||||
@unittest.skipIf(platform == 'win32',
|
@unittest.skipIf(platform == 'win32',
|
||||||
"Different filesystem root on Windows")
|
"Different filesystem root on Windows")
|
||||||
def test_detect_parent_breakout(self):
|
def test_detect_parent_breakout(self):
|
||||||
with six.assertRaisesRegex(
|
with self.assertRaisesRegex(
|
||||||
self,
|
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
"Attempted to break out of output directory to /foo/test"):
|
"Attempted to break out of output directory to /foo/test"):
|
||||||
utils.sanitised_join(
|
utils.sanitised_join(
|
||||||
|
|
@ -732,8 +728,7 @@ class TestSanitisedJoin(unittest.TestCase):
|
||||||
@unittest.skipIf(platform == 'win32',
|
@unittest.skipIf(platform == 'win32',
|
||||||
"Different filesystem root on Windows")
|
"Different filesystem root on Windows")
|
||||||
def test_detect_root_breakout(self):
|
def test_detect_root_breakout(self):
|
||||||
with six.assertRaisesRegex(
|
with self.assertRaisesRegex(
|
||||||
self,
|
|
||||||
RuntimeError,
|
RuntimeError,
|
||||||
"Attempted to break out of output directory to /test"):
|
"Attempted to break out of output directory to /test"):
|
||||||
utils.sanitised_join(
|
utils.sanitised_join(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -11,10 +10,9 @@ import sys
|
||||||
import time
|
import time
|
||||||
from codecs import open
|
from codecs import open
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from urllib.error import URLError
|
||||||
from six.moves.urllib.error import URLError
|
from urllib.parse import quote, urlparse, urlsplit, urlunsplit
|
||||||
from six.moves.urllib.parse import quote, urlparse, urlsplit, urlunsplit
|
from urllib.request import urlretrieve
|
||||||
from six.moves.urllib.request import urlretrieve
|
|
||||||
|
|
||||||
# because logging.setLoggerClass has to be called before logging.getLogger
|
# because logging.setLoggerClass has to be called before logging.getLogger
|
||||||
from pelican.log import init
|
from pelican.log import init
|
||||||
|
|
@ -24,7 +22,7 @@ from pelican.utils import SafeDatetime, slugify
|
||||||
try:
|
try:
|
||||||
from html import unescape # py3.5+
|
from html import unescape # py3.5+
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from six.moves.html_parser import HTMLParser
|
from html.parser import HTMLParser
|
||||||
unescape = HTMLParser().unescape
|
unescape = HTMLParser().unescape
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
@ -396,19 +394,8 @@ def posterous2fields(api_token, email, password):
|
||||||
"""Imports posterous posts"""
|
"""Imports posterous posts"""
|
||||||
import base64
|
import base64
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
try:
|
import json
|
||||||
# py3k import
|
import urllib.request as urllib_request
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
# py2 import
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
try:
|
|
||||||
# py3k import
|
|
||||||
import urllib.request as urllib_request
|
|
||||||
except ImportError:
|
|
||||||
# py2 import
|
|
||||||
import urllib2 as urllib_request
|
|
||||||
|
|
||||||
def get_posterous_posts(api_token, email, password, page=1):
|
def get_posterous_posts(api_token, email, password, page=1):
|
||||||
base64string = base64.encodestring(
|
base64string = base64.encodestring(
|
||||||
|
|
@ -451,19 +438,8 @@ def posterous2fields(api_token, email, password):
|
||||||
|
|
||||||
def tumblr2fields(api_key, blogname):
|
def tumblr2fields(api_key, blogname):
|
||||||
""" Imports Tumblr posts (API v2)"""
|
""" Imports Tumblr posts (API v2)"""
|
||||||
try:
|
import json
|
||||||
# py3k import
|
import urllib.request as urllib_request
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
# py2 import
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
try:
|
|
||||||
# py3k import
|
|
||||||
import urllib.request as urllib_request
|
|
||||||
except ImportError:
|
|
||||||
# py2 import
|
|
||||||
import urllib2 as urllib_request
|
|
||||||
|
|
||||||
def get_tumblr_posts(api_key, blogname, offset=0):
|
def get_tumblr_posts(api_key, blogname, offset=0):
|
||||||
url = ("http://api.tumblr.com/v2/blog/%s.tumblr.com/"
|
url = ("http://api.tumblr.com/v2/blog/%s.tumblr.com/"
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import codecs
|
import codecs
|
||||||
import locale
|
import locale
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
|
|
||||||
from jinja2 import Environment, FileSystemLoader
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
|
||||||
|
|
@ -23,8 +21,6 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
_DEFAULT_TIMEZONE = 'Europe/Paris'
|
_DEFAULT_TIMEZONE = 'Europe/Paris'
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from pelican import __version__
|
from pelican import __version__
|
||||||
|
|
||||||
locale.setlocale(locale.LC_ALL, '')
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
|
|
@ -77,41 +73,24 @@ CONF = {
|
||||||
# url for list of valid timezones
|
# url for list of valid timezones
|
||||||
_TZ_URL = 'http://en.wikipedia.org/wiki/List_of_tz_database_time_zones'
|
_TZ_URL = 'http://en.wikipedia.org/wiki/List_of_tz_database_time_zones'
|
||||||
|
|
||||||
_input_compat = six.moves.input
|
|
||||||
str_compat = six.text_type
|
|
||||||
|
|
||||||
|
|
||||||
# Create a 'marked' default path, to determine if someone has supplied
|
# Create a 'marked' default path, to determine if someone has supplied
|
||||||
# a path on the command-line.
|
# a path on the command-line.
|
||||||
class _DEFAULT_PATH_TYPE(str_compat):
|
class _DEFAULT_PATH_TYPE(str):
|
||||||
is_default_path = True
|
is_default_path = True
|
||||||
|
|
||||||
|
|
||||||
_DEFAULT_PATH = _DEFAULT_PATH_TYPE(os.curdir)
|
_DEFAULT_PATH = _DEFAULT_PATH_TYPE(os.curdir)
|
||||||
|
|
||||||
|
|
||||||
def decoding_strings(f):
|
def ask(question, answer=str, default=None, length=None):
|
||||||
def wrapper(*args, **kwargs):
|
if answer == str:
|
||||||
out = f(*args, **kwargs)
|
|
||||||
if isinstance(out, six.string_types) and not six.PY3:
|
|
||||||
# todo: make encoding configurable?
|
|
||||||
if six.PY3:
|
|
||||||
return out
|
|
||||||
else:
|
|
||||||
return out.decode(sys.stdin.encoding)
|
|
||||||
return out
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
@decoding_strings
|
|
||||||
def ask(question, answer=str_compat, default=None, length=None):
|
|
||||||
if answer == str_compat:
|
|
||||||
r = ''
|
r = ''
|
||||||
while True:
|
while True:
|
||||||
if default:
|
if default:
|
||||||
r = _input_compat('> {0} [{1}] '.format(question, default))
|
r = input('> {0} [{1}] '.format(question, default))
|
||||||
else:
|
else:
|
||||||
r = _input_compat('> {0} '.format(question, default))
|
r = input('> {0} '.format(question, default))
|
||||||
|
|
||||||
r = r.strip()
|
r = r.strip()
|
||||||
|
|
||||||
|
|
@ -133,11 +112,11 @@ def ask(question, answer=str_compat, default=None, length=None):
|
||||||
r = None
|
r = None
|
||||||
while True:
|
while True:
|
||||||
if default is True:
|
if default is True:
|
||||||
r = _input_compat('> {0} (Y/n) '.format(question))
|
r = input('> {0} (Y/n) '.format(question))
|
||||||
elif default is False:
|
elif default is False:
|
||||||
r = _input_compat('> {0} (y/N) '.format(question))
|
r = input('> {0} (y/N) '.format(question))
|
||||||
else:
|
else:
|
||||||
r = _input_compat('> {0} (y/n) '.format(question))
|
r = input('> {0} (y/n) '.format(question))
|
||||||
|
|
||||||
r = r.strip().lower()
|
r = r.strip().lower()
|
||||||
|
|
||||||
|
|
@ -157,9 +136,9 @@ def ask(question, answer=str_compat, default=None, length=None):
|
||||||
r = None
|
r = None
|
||||||
while True:
|
while True:
|
||||||
if default:
|
if default:
|
||||||
r = _input_compat('> {0} [{1}] '.format(question, default))
|
r = input('> {0} [{1}] '.format(question, default))
|
||||||
else:
|
else:
|
||||||
r = _input_compat('> {0} '.format(question))
|
r = input('> {0} '.format(question))
|
||||||
|
|
||||||
r = r.strip()
|
r = r.strip()
|
||||||
|
|
||||||
|
|
@ -175,14 +154,14 @@ def ask(question, answer=str_compat, default=None, length=None):
|
||||||
return r
|
return r
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
'Argument `answer` must be str_compat, bool, or integer')
|
'Argument `answer` must be str, bool, or integer')
|
||||||
|
|
||||||
|
|
||||||
def ask_timezone(question, default, tzurl):
|
def ask_timezone(question, default, tzurl):
|
||||||
"""Prompt for time zone and validate input"""
|
"""Prompt for time zone and validate input"""
|
||||||
lower_tz = [tz.lower() for tz in pytz.all_timezones]
|
lower_tz = [tz.lower() for tz in pytz.all_timezones]
|
||||||
while True:
|
while True:
|
||||||
r = ask(question, str_compat, default)
|
r = ask(question, str, default)
|
||||||
r = r.strip().replace(' ', '_').lower()
|
r = r.strip().replace(' ', '_').lower()
|
||||||
if r in lower_tz:
|
if r in lower_tz:
|
||||||
r = pytz.all_timezones[lower_tz.index(r)]
|
r = pytz.all_timezones[lower_tz.index(r)]
|
||||||
|
|
@ -227,20 +206,20 @@ needed by Pelican.
|
||||||
else:
|
else:
|
||||||
CONF['basedir'] = os.path.abspath(os.path.expanduser(
|
CONF['basedir'] = os.path.abspath(os.path.expanduser(
|
||||||
ask('Where do you want to create your new web site?',
|
ask('Where do you want to create your new web site?',
|
||||||
answer=str_compat, default=args.path)))
|
answer=str, default=args.path)))
|
||||||
|
|
||||||
CONF['sitename'] = ask('What will be the title of this web site?',
|
CONF['sitename'] = ask('What will be the title of this web site?',
|
||||||
answer=str_compat, default=args.title)
|
answer=str, default=args.title)
|
||||||
CONF['author'] = ask('Who will be the author of this web site?',
|
CONF['author'] = ask('Who will be the author of this web site?',
|
||||||
answer=str_compat, default=args.author)
|
answer=str, default=args.author)
|
||||||
CONF['lang'] = ask('What will be the default language of this web site?',
|
CONF['lang'] = ask('What will be the default language of this web site?',
|
||||||
str_compat, args.lang or CONF['lang'], 2)
|
str, args.lang or CONF['lang'], 2)
|
||||||
|
|
||||||
if ask('Do you want to specify a URL prefix? e.g., https://example.com ',
|
if ask('Do you want to specify a URL prefix? e.g., https://example.com ',
|
||||||
answer=bool, default=True):
|
answer=bool, default=True):
|
||||||
CONF['siteurl'] = ask('What is your URL prefix? (see '
|
CONF['siteurl'] = ask('What is your URL prefix? (see '
|
||||||
'above example; no trailing slash)',
|
'above example; no trailing slash)',
|
||||||
str_compat, CONF['siteurl'])
|
str, CONF['siteurl'])
|
||||||
|
|
||||||
CONF['with_pagination'] = ask('Do you want to enable article pagination?',
|
CONF['with_pagination'] = ask('Do you want to enable article pagination?',
|
||||||
bool, bool(CONF['default_pagination']))
|
bool, bool(CONF['default_pagination']))
|
||||||
|
|
@ -263,49 +242,49 @@ needed by Pelican.
|
||||||
answer=bool, default=False):
|
answer=bool, default=False):
|
||||||
CONF['ftp'] = True,
|
CONF['ftp'] = True,
|
||||||
CONF['ftp_host'] = ask('What is the hostname of your FTP server?',
|
CONF['ftp_host'] = ask('What is the hostname of your FTP server?',
|
||||||
str_compat, CONF['ftp_host'])
|
str, CONF['ftp_host'])
|
||||||
CONF['ftp_user'] = ask('What is your username on that server?',
|
CONF['ftp_user'] = ask('What is your username on that server?',
|
||||||
str_compat, CONF['ftp_user'])
|
str, CONF['ftp_user'])
|
||||||
CONF['ftp_target_dir'] = ask('Where do you want to put your '
|
CONF['ftp_target_dir'] = ask('Where do you want to put your '
|
||||||
'web site on that server?',
|
'web site on that server?',
|
||||||
str_compat, CONF['ftp_target_dir'])
|
str, CONF['ftp_target_dir'])
|
||||||
if ask('Do you want to upload your website using SSH?',
|
if ask('Do you want to upload your website using SSH?',
|
||||||
answer=bool, default=False):
|
answer=bool, default=False):
|
||||||
CONF['ssh'] = True,
|
CONF['ssh'] = True,
|
||||||
CONF['ssh_host'] = ask('What is the hostname of your SSH server?',
|
CONF['ssh_host'] = ask('What is the hostname of your SSH server?',
|
||||||
str_compat, CONF['ssh_host'])
|
str, CONF['ssh_host'])
|
||||||
CONF['ssh_port'] = ask('What is the port of your SSH server?',
|
CONF['ssh_port'] = ask('What is the port of your SSH server?',
|
||||||
int, CONF['ssh_port'])
|
int, CONF['ssh_port'])
|
||||||
CONF['ssh_user'] = ask('What is your username on that server?',
|
CONF['ssh_user'] = ask('What is your username on that server?',
|
||||||
str_compat, CONF['ssh_user'])
|
str, CONF['ssh_user'])
|
||||||
CONF['ssh_target_dir'] = ask('Where do you want to put your '
|
CONF['ssh_target_dir'] = ask('Where do you want to put your '
|
||||||
'web site on that server?',
|
'web site on that server?',
|
||||||
str_compat, CONF['ssh_target_dir'])
|
str, CONF['ssh_target_dir'])
|
||||||
|
|
||||||
if ask('Do you want to upload your website using Dropbox?',
|
if ask('Do you want to upload your website using Dropbox?',
|
||||||
answer=bool, default=False):
|
answer=bool, default=False):
|
||||||
CONF['dropbox'] = True,
|
CONF['dropbox'] = True,
|
||||||
CONF['dropbox_dir'] = ask('Where is your Dropbox directory?',
|
CONF['dropbox_dir'] = ask('Where is your Dropbox directory?',
|
||||||
str_compat, CONF['dropbox_dir'])
|
str, CONF['dropbox_dir'])
|
||||||
|
|
||||||
if ask('Do you want to upload your website using S3?',
|
if ask('Do you want to upload your website using S3?',
|
||||||
answer=bool, default=False):
|
answer=bool, default=False):
|
||||||
CONF['s3'] = True,
|
CONF['s3'] = True,
|
||||||
CONF['s3_bucket'] = ask('What is the name of your S3 bucket?',
|
CONF['s3_bucket'] = ask('What is the name of your S3 bucket?',
|
||||||
str_compat, CONF['s3_bucket'])
|
str, CONF['s3_bucket'])
|
||||||
|
|
||||||
if ask('Do you want to upload your website using '
|
if ask('Do you want to upload your website using '
|
||||||
'Rackspace Cloud Files?', answer=bool, default=False):
|
'Rackspace Cloud Files?', answer=bool, default=False):
|
||||||
CONF['cloudfiles'] = True,
|
CONF['cloudfiles'] = True,
|
||||||
CONF['cloudfiles_username'] = ask('What is your Rackspace '
|
CONF['cloudfiles_username'] = ask('What is your Rackspace '
|
||||||
'Cloud username?', str_compat,
|
'Cloud username?', str,
|
||||||
CONF['cloudfiles_username'])
|
CONF['cloudfiles_username'])
|
||||||
CONF['cloudfiles_api_key'] = ask('What is your Rackspace '
|
CONF['cloudfiles_api_key'] = ask('What is your Rackspace '
|
||||||
'Cloud API key?', str_compat,
|
'Cloud API key?', str,
|
||||||
CONF['cloudfiles_api_key'])
|
CONF['cloudfiles_api_key'])
|
||||||
CONF['cloudfiles_container'] = ask('What is the name of your '
|
CONF['cloudfiles_container'] = ask('What is the name of your '
|
||||||
'Cloud Files container?',
|
'Cloud Files container?',
|
||||||
str_compat,
|
str,
|
||||||
CONF['cloudfiles_container'])
|
CONF['cloudfiles_container'])
|
||||||
|
|
||||||
if ask('Do you want to upload your website using GitHub Pages?',
|
if ask('Do you want to upload your website using GitHub Pages?',
|
||||||
|
|
@ -363,9 +342,7 @@ needed by Pelican.
|
||||||
try:
|
try:
|
||||||
with codecs.open(os.path.join(CONF['basedir'], 'Makefile'),
|
with codecs.open(os.path.join(CONF['basedir'], 'Makefile'),
|
||||||
'w', 'utf-8') as fd:
|
'w', 'utf-8') as fd:
|
||||||
py_v = 'python'
|
py_v = 'python3'
|
||||||
if six.PY3:
|
|
||||||
py_v = 'python3'
|
|
||||||
_template = _jinja_env.get_template('Makefile.jinja2')
|
_template = _jinja_env.get_template('Makefile.jinja2')
|
||||||
fd.write(_template.render(py_v=py_v, **CONF))
|
fd.write(_template.render(py_v=py_v, **CONF))
|
||||||
fd.close()
|
fd.close()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*- #
|
# -*- coding: utf-8 -*- #
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
AUTHOR = {{author}}
|
AUTHOR = {{author}}
|
||||||
SITENAME = {{sitename}}
|
SITENAME = {{sitename}}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*- #
|
# -*- coding: utf-8 -*- #
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
# This file is only used if you use `make publish` or
|
# This file is only used if you use `make publish` or
|
||||||
# explicitly specify it as your config file.
|
# explicitly specify it as your config file.
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,14 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import six
|
from pelican.utils import slugify
|
||||||
|
|
||||||
from pelican.utils import python_2_unicode_compatible, slugify
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
@functools.total_ordering
|
@functools.total_ordering
|
||||||
class URLWrapper(object):
|
class URLWrapper(object):
|
||||||
def __init__(self, name, settings):
|
def __init__(self, name, settings):
|
||||||
|
|
@ -66,26 +62,26 @@ class URLWrapper(object):
|
||||||
|
|
||||||
def _normalize_key(self, key):
|
def _normalize_key(self, key):
|
||||||
subs = self.settings.get('SLUG_REGEX_SUBSTITUTIONS', [])
|
subs = self.settings.get('SLUG_REGEX_SUBSTITUTIONS', [])
|
||||||
return six.text_type(slugify(key, regex_subs=subs))
|
return str(slugify(key, regex_subs=subs))
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if isinstance(other, self.__class__):
|
if isinstance(other, self.__class__):
|
||||||
return self.slug == other.slug
|
return self.slug == other.slug
|
||||||
if isinstance(other, six.text_type):
|
if isinstance(other, str):
|
||||||
return self.slug == self._normalize_key(other)
|
return self.slug == self._normalize_key(other)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
if isinstance(other, self.__class__):
|
if isinstance(other, self.__class__):
|
||||||
return self.slug != other.slug
|
return self.slug != other.slug
|
||||||
if isinstance(other, six.text_type):
|
if isinstance(other, str):
|
||||||
return self.slug != self._normalize_key(other)
|
return self.slug != self._normalize_key(other)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
if isinstance(other, self.__class__):
|
if isinstance(other, self.__class__):
|
||||||
return self.slug < other.slug
|
return self.slug < other.slug
|
||||||
if isinstance(other, six.text_type):
|
if isinstance(other, str):
|
||||||
return self.slug < self._normalize_key(other)
|
return self.slug < self._normalize_key(other)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
@ -105,7 +101,7 @@ class URLWrapper(object):
|
||||||
"""
|
"""
|
||||||
setting = "%s_%s" % (self.__class__.__name__.upper(), key)
|
setting = "%s_%s" % (self.__class__.__name__.upper(), key)
|
||||||
value = self.settings[setting]
|
value = self.settings[setting]
|
||||||
if not isinstance(value, six.string_types):
|
if not isinstance(value, str):
|
||||||
logger.warning('%s is set to %s', setting, value)
|
logger.warning('%s is set to %s', setting, value)
|
||||||
return value
|
return value
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals
|
|
||||||
|
|
||||||
import codecs
|
import codecs
|
||||||
import datetime
|
import datetime
|
||||||
|
|
@ -12,12 +11,15 @@ import re
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
import urllib
|
||||||
try:
|
try:
|
||||||
from collections.abc import Hashable
|
from collections.abc import Hashable
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from collections import Hashable
|
from collections import Hashable
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
from html import entities
|
||||||
|
from html.parser import HTMLParser
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
|
||||||
|
|
@ -27,10 +29,6 @@ from jinja2 import Markup
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
import six
|
|
||||||
from six.moves import html_entities
|
|
||||||
from six.moves.html_parser import HTMLParser
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from html import escape
|
from html import escape
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|
@ -98,10 +96,6 @@ def strftime(date, date_format):
|
||||||
else:
|
else:
|
||||||
formatted = date.strftime(candidate)
|
formatted = date.strftime(candidate)
|
||||||
|
|
||||||
# convert Py2 result to unicode
|
|
||||||
if not six.PY3 and enc is not None:
|
|
||||||
formatted = formatted.decode(enc)
|
|
||||||
|
|
||||||
# strip zeros if '-' prefix is used
|
# strip zeros if '-' prefix is used
|
||||||
if conversion:
|
if conversion:
|
||||||
formatted = conversion(formatted)
|
formatted = conversion(formatted)
|
||||||
|
|
@ -150,22 +144,6 @@ class DateFormatter(object):
|
||||||
return formatted
|
return formatted
|
||||||
|
|
||||||
|
|
||||||
def python_2_unicode_compatible(klass):
|
|
||||||
"""
|
|
||||||
A decorator that defines __unicode__ and __str__ methods under Python 2.
|
|
||||||
Under Python 3 it does nothing.
|
|
||||||
|
|
||||||
To support Python 2 and 3 with a single code base, define a __str__ method
|
|
||||||
returning text and apply this decorator to the class.
|
|
||||||
|
|
||||||
From django.utils.encoding.
|
|
||||||
"""
|
|
||||||
if not six.PY3:
|
|
||||||
klass.__unicode__ = klass.__str__
|
|
||||||
klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
|
|
||||||
return klass
|
|
||||||
|
|
||||||
|
|
||||||
class memoized(object):
|
class memoized(object):
|
||||||
"""Function decorator to cache return values.
|
"""Function decorator to cache return values.
|
||||||
|
|
||||||
|
|
@ -214,15 +192,15 @@ def deprecated_attribute(old, new, since=None, remove=None, doc=None):
|
||||||
content of the dummy method is ignored.
|
content of the dummy method is ignored.
|
||||||
"""
|
"""
|
||||||
def _warn():
|
def _warn():
|
||||||
version = '.'.join(six.text_type(x) for x in since)
|
version = '.'.join(str(x) for x in since)
|
||||||
message = ['{} has been deprecated since {}'.format(old, version)]
|
message = ['{} has been deprecated since {}'.format(old, version)]
|
||||||
if remove:
|
if remove:
|
||||||
version = '.'.join(six.text_type(x) for x in remove)
|
version = '.'.join(str(x) for x in remove)
|
||||||
message.append(
|
message.append(
|
||||||
' and will be removed by version {}'.format(version))
|
' and will be removed by version {}'.format(version))
|
||||||
message.append('. Use {} instead.'.format(new))
|
message.append('. Use {} instead.'.format(new))
|
||||||
logger.warning(''.join(message))
|
logger.warning(''.join(message))
|
||||||
logger.debug(''.join(six.text_type(x) for x
|
logger.debug(''.join(str(x) for x
|
||||||
in traceback.format_stack()))
|
in traceback.format_stack()))
|
||||||
|
|
||||||
def fget(self):
|
def fget(self):
|
||||||
|
|
@ -279,10 +257,8 @@ def slugify(value, regex_subs=()):
|
||||||
# value must be unicode per se
|
# value must be unicode per se
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from unidecode import unidecode
|
from unidecode import unidecode
|
||||||
# unidecode returns str in Py2 and 3, so in Py2 we have to make
|
|
||||||
# it unicode again
|
|
||||||
value = unidecode(value)
|
value = unidecode(value)
|
||||||
if isinstance(value, six.binary_type):
|
if isinstance(value, bytes):
|
||||||
value = value.decode('ascii')
|
value = value.decode('ascii')
|
||||||
# still unicode
|
# still unicode
|
||||||
value = unicodedata.normalize('NFKD', value)
|
value = unicodedata.normalize('NFKD', value)
|
||||||
|
|
@ -584,8 +560,8 @@ class _HTMLWordTruncator(HTMLParser):
|
||||||
`name` is the entity ref without ampersand and semicolon (e.g. `mdash`)
|
`name` is the entity ref without ampersand and semicolon (e.g. `mdash`)
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
codepoint = html_entities.name2codepoint[name]
|
codepoint = entities.name2codepoint[name]
|
||||||
char = six.unichr(codepoint)
|
char = chr(codepoint)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
char = ''
|
char = ''
|
||||||
self._handle_ref(name, char)
|
self._handle_ref(name, char)
|
||||||
|
|
@ -602,7 +578,7 @@ class _HTMLWordTruncator(HTMLParser):
|
||||||
codepoint = int(name[1:], 16)
|
codepoint = int(name[1:], 16)
|
||||||
else:
|
else:
|
||||||
codepoint = int(name)
|
codepoint = int(name)
|
||||||
char = six.unichr(codepoint)
|
char = chr(codepoint)
|
||||||
except (ValueError, OverflowError):
|
except (ValueError, OverflowError):
|
||||||
char = ''
|
char = ''
|
||||||
self._handle_ref('#' + name, char)
|
self._handle_ref('#' + name, char)
|
||||||
|
|
@ -663,7 +639,7 @@ def process_translations(content_list, translation_id=None):
|
||||||
if not translation_id:
|
if not translation_id:
|
||||||
return content_list, []
|
return content_list, []
|
||||||
|
|
||||||
if isinstance(translation_id, six.string_types):
|
if isinstance(translation_id, str):
|
||||||
translation_id = {translation_id}
|
translation_id = {translation_id}
|
||||||
|
|
||||||
index = []
|
index = []
|
||||||
|
|
@ -753,7 +729,7 @@ def order_content(content_list, order_by='slug'):
|
||||||
content_list.sort(key=order_by)
|
content_list.sort(key=order_by)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.error('Error sorting with function %s', order_by)
|
logger.error('Error sorting with function %s', order_by)
|
||||||
elif isinstance(order_by, six.string_types):
|
elif isinstance(order_by, str):
|
||||||
if order_by.startswith('reversed-'):
|
if order_by.startswith('reversed-'):
|
||||||
order_reversed = True
|
order_reversed = True
|
||||||
order_by = order_by.replace('reversed-', '', 1)
|
order_by = order_by.replace('reversed-', '', 1)
|
||||||
|
|
@ -901,8 +877,7 @@ def is_selected_for_writing(settings, path):
|
||||||
|
|
||||||
def path_to_file_url(path):
|
def path_to_file_url(path):
|
||||||
'''Convert file-system path to file:// URL'''
|
'''Convert file-system path to file:// URL'''
|
||||||
return six.moves.urllib_parse.urljoin(
|
return urllib.parse.urljoin("file://", urllib.request.pathname2url(path))
|
||||||
"file://", six.moves.urllib.request.pathname2url(path))
|
|
||||||
|
|
||||||
|
|
||||||
def maybe_pluralize(count, singular, plural):
|
def maybe_pluralize(count, singular, plural):
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,18 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import print_function, unicode_literals, with_statement
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
from feedgenerator import Atom1Feed, Rss201rev2Feed, get_tag_uri
|
from feedgenerator import Atom1Feed, Rss201rev2Feed, get_tag_uri
|
||||||
|
|
||||||
from jinja2 import Markup
|
from jinja2 import Markup
|
||||||
|
|
||||||
import six
|
|
||||||
from six.moves.urllib.parse import urljoin
|
|
||||||
|
|
||||||
from pelican import signals
|
from pelican import signals
|
||||||
from pelican.paginator import Paginator
|
from pelican.paginator import Paginator
|
||||||
from pelican.utils import (get_relative_path, is_selected_for_writing,
|
from pelican.utils import (get_relative_path, is_selected_for_writing,
|
||||||
path_to_url, sanitised_join, set_date_tzinfo)
|
path_to_url, sanitised_join, set_date_tzinfo)
|
||||||
|
|
||||||
if not six.PY3:
|
|
||||||
from codecs import open
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -165,8 +159,7 @@ class Writer(object):
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
encoding = 'utf-8' if six.PY3 else None
|
with self._open_w(complete_path, 'utf-8', override_output) as fp:
|
||||||
with self._open_w(complete_path, encoding, override_output) as fp:
|
|
||||||
feed.write(fp, 'utf-8')
|
feed.write(fp, 'utf-8')
|
||||||
logger.info('Writing %s', complete_path)
|
logger.info('Writing %s', complete_path)
|
||||||
|
|
||||||
|
|
|
||||||
120
poetry.lock
generated
120
poetry.lock
generated
|
|
@ -17,15 +17,6 @@ version = "2.7.0"
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pytz = ">=2015.7"
|
pytz = ">=2015.7"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "backports.functools_lru_cache"
|
|
||||||
marker = "python_version < \"3\""
|
|
||||||
name = "backports.functools-lru-cache"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.6"
|
|
||||||
version = "1.5"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Screen-scraping library"
|
description = "Screen-scraping library"
|
||||||
|
|
@ -54,24 +45,6 @@ optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Updated configparser from Python 3.7 for Python 2.6+."
|
|
||||||
marker = "python_version < \"3.2\""
|
|
||||||
name = "configparser"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.6"
|
|
||||||
version = "3.7.4"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Backports and enhancements for the contextlib module"
|
|
||||||
marker = "python_version < \"3\""
|
|
||||||
name = "contextlib2"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "0.5.5"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "Docutils -- Python Documentation Utilities"
|
description = "Docutils -- Python Documentation Utilities"
|
||||||
|
|
@ -88,20 +61,6 @@ optional = false
|
||||||
python-versions = ">=2.7"
|
python-versions = ">=2.7"
|
||||||
version = "0.3"
|
version = "0.3"
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
[package.dependencies.configparser]
|
|
||||||
python = ">=2.7,<2.8"
|
|
||||||
version = ">=3.5"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Python 3.4 Enum backported to 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4"
|
|
||||||
marker = "python_version < \"3.4\""
|
|
||||||
name = "enum34"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "1.1.6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "Standalone version of django.utils.feedgenerator"
|
description = "Standalone version of django.utils.feedgenerator"
|
||||||
|
|
@ -136,22 +95,6 @@ mccabe = ">=0.6.0,<0.7.0"
|
||||||
pycodestyle = ">=2.5.0,<2.6.0"
|
pycodestyle = ">=2.5.0,<2.6.0"
|
||||||
pyflakes = ">=2.1.0,<2.2.0"
|
pyflakes = ">=2.1.0,<2.2.0"
|
||||||
|
|
||||||
[package.dependencies.configparser]
|
|
||||||
python = "<3.2"
|
|
||||||
version = "*"
|
|
||||||
|
|
||||||
[package.dependencies.enum34]
|
|
||||||
python = "<3.4"
|
|
||||||
version = "*"
|
|
||||||
|
|
||||||
[package.dependencies.functools32]
|
|
||||||
python = "<3.2"
|
|
||||||
version = "*"
|
|
||||||
|
|
||||||
[package.dependencies.typing]
|
|
||||||
python = "<3.5"
|
|
||||||
version = "*"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Flake8 and pylama plugin that checks the ordering of import statements."
|
description = "Flake8 and pylama plugin that checks the ordering of import statements."
|
||||||
|
|
@ -164,28 +107,6 @@ version = "0.18.1"
|
||||||
pycodestyle = "*"
|
pycodestyle = "*"
|
||||||
setuptools = "*"
|
setuptools = "*"
|
||||||
|
|
||||||
[package.dependencies.enum34]
|
|
||||||
python = "<2.8"
|
|
||||||
version = "*"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Python function signatures from PEP362 for Python 2.6, 2.7 and 3.2+"
|
|
||||||
marker = "python_version < \"3.3\""
|
|
||||||
name = "funcsigs"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "1.0.2"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Backport of the functools module from Python 3.2.3 for use on 2.7 and PyPy."
|
|
||||||
marker = "python_version < \"3.2\""
|
|
||||||
name = "functools32"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "3.2.3-2"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Getting image size from png/jpeg/jpeg2000/gif file"
|
description = "Getting image size from png/jpeg/jpeg2000/gif file"
|
||||||
|
|
@ -205,14 +126,6 @@ version = "0.18"
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
zipp = ">=0.5"
|
zipp = ">=0.5"
|
||||||
|
|
||||||
[package.dependencies.configparser]
|
|
||||||
python = "<3"
|
|
||||||
version = ">=3.5"
|
|
||||||
|
|
||||||
[package.dependencies.contextlib2]
|
|
||||||
python = "<3"
|
|
||||||
version = "*"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "A small but fast and easy to use stand-alone template engine written in pure python."
|
description = "A small but fast and easy to use stand-alone template engine written in pure python."
|
||||||
|
|
@ -270,10 +183,6 @@ version = "3.0.5"
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
six = "*"
|
six = "*"
|
||||||
|
|
||||||
[package.dependencies.funcsigs]
|
|
||||||
python = "<3.3"
|
|
||||||
version = ">=1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Core utilities for Python packages"
|
description = "Core utilities for Python packages"
|
||||||
|
|
@ -362,7 +271,7 @@ description = "Python 2 and 3 compatibility utilities"
|
||||||
name = "six"
|
name = "six"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
|
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
|
||||||
version = "1.12.0"
|
version = "1.13.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
|
|
@ -388,11 +297,6 @@ optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "1.9.2"
|
version = "1.9.2"
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
[package.dependencies."backports.functools-lru-cache"]
|
|
||||||
python = "<3"
|
|
||||||
version = "*"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Python documentation generator"
|
description = "Python documentation generator"
|
||||||
|
|
@ -449,15 +353,6 @@ six = ">=1.0.0,<2"
|
||||||
toml = ">=0.9.4"
|
toml = ">=0.9.4"
|
||||||
virtualenv = ">=14.0.0"
|
virtualenv = ">=14.0.0"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "Type Hints for Python"
|
|
||||||
marker = "python_version < \"3.5\""
|
|
||||||
name = "typing"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "3.7.4"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Filters to enhance web typography, including support for Django & Jinja templates"
|
description = "Filters to enhance web typography, including support for Django & Jinja templates"
|
||||||
|
|
@ -497,27 +392,21 @@ version = "0.5.1"
|
||||||
markdown = ["markdown"]
|
markdown = ["markdown"]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
content-hash = "d22ff0db3331186ab2f809313de1f9efef1f9c708cc354eaa1638a5111404612"
|
content-hash = "0163177d87dca0955d111319de9481cf2ed0ef014e63a3740ffaf32a1cf07212"
|
||||||
python-versions = "~2.7 || ^3.5"
|
python-versions = "^3.5"
|
||||||
|
|
||||||
[metadata.hashes]
|
[metadata.hashes]
|
||||||
alabaster = ["446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359", "a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"]
|
alabaster = ["446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359", "a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"]
|
||||||
babel = ["af92e6106cb7c55286b25b38ad7695f8b4efb36a90ba483d7f7a6628c46158ab", "e86135ae101e31e2c8ec20a4e0c5220f4eed12487d5cf3f78be7e98d3a57fc28"]
|
babel = ["af92e6106cb7c55286b25b38ad7695f8b4efb36a90ba483d7f7a6628c46158ab", "e86135ae101e31e2c8ec20a4e0c5220f4eed12487d5cf3f78be7e98d3a57fc28"]
|
||||||
"backports.functools-lru-cache" = ["9d98697f088eb1b0fa451391f91afb5e3ebde16bbdb272819fd091151fda4f1a", "f0b0e4eba956de51238e17573b7087e852dfe9854afd2e9c873f73fc0ca0a6dd"]
|
|
||||||
beautifulsoup4 = ["034740f6cb549b4e932ae1ab975581e6103ac8f942200a0e9759065984391858", "945065979fb8529dd2f37dbb58f00b661bdbcbebf954f93b32fdf5263ef35348", "ba6d5c59906a85ac23dadfe5c88deaf3e179ef565f4898671253e50a78680718"]
|
beautifulsoup4 = ["034740f6cb549b4e932ae1ab975581e6103ac8f942200a0e9759065984391858", "945065979fb8529dd2f37dbb58f00b661bdbcbebf954f93b32fdf5263ef35348", "ba6d5c59906a85ac23dadfe5c88deaf3e179ef565f4898671253e50a78680718"]
|
||||||
blinker = ["471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6"]
|
blinker = ["471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6"]
|
||||||
colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"]
|
colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"]
|
||||||
configparser = ["8be81d89d6e7b4c0d4e44bcc525845f6da25821de80cb5e06e7e0238a2899e32", "da60d0014fd8c55eb48c1c5354352e363e2d30bbf7057e5e171a468390184c75"]
|
|
||||||
contextlib2 = ["509f9419ee91cdd00ba34443217d5ca51f5a364a404e1dce9e8979cea969ca48", "f5260a6e679d2ff42ec91ec5252f4eeffdcf21053db9113bd0a8e4d953769c00"]
|
|
||||||
docutils = ["02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6", "51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274", "7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"]
|
docutils = ["02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6", "51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274", "7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"]
|
||||||
entrypoints = ["589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", "c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"]
|
entrypoints = ["589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", "c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"]
|
||||||
enum34 = ["2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850", "644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a", "6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79", "8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"]
|
|
||||||
feedgenerator = ["5ae05daa9cfa47fa406ee4744d0b7fa1c8a05a7a47ee0ad328ddf55327cfb106"]
|
feedgenerator = ["5ae05daa9cfa47fa406ee4744d0b7fa1c8a05a7a47ee0ad328ddf55327cfb106"]
|
||||||
filelock = ["18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", "929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"]
|
filelock = ["18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", "929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"]
|
||||||
flake8 = ["859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661", "a796a115208f5c03b18f332f7c11729812c8c3ded6c46319c59b53efd3819da8"]
|
flake8 = ["859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661", "a796a115208f5c03b18f332f7c11729812c8c3ded6c46319c59b53efd3819da8"]
|
||||||
flake8-import-order = ["90a80e46886259b9c396b578d75c749801a41ee969a235e163cfe1be7afd2543", "a28dc39545ea4606c1ac3c24e9d05c849c6e5444a50fb7e9cdd430fc94de6e92"]
|
flake8-import-order = ["90a80e46886259b9c396b578d75c749801a41ee969a235e163cfe1be7afd2543", "a28dc39545ea4606c1ac3c24e9d05c849c6e5444a50fb7e9cdd430fc94de6e92"]
|
||||||
funcsigs = ["330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca", "a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50"]
|
|
||||||
functools32 = ["89d824aa6c358c421a234d7f9ee0bd75933a67c29588ce50aaa3acdf4d403fa0", "f6253dfbe0538ad2e387bd8fdfd9293c925d63553f5813c4e587745416501e6d"]
|
|
||||||
imagesize = ["3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8", "f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"]
|
imagesize = ["3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8", "f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"]
|
||||||
importlib-metadata = ["6dfd58dfe281e8d240937776065dd3624ad5469c835248219bd16cf2e12dbeb7", "cb6ee23b46173539939964df59d3d72c3e0c1b5d54b84f1d8a7e912fe43612db"]
|
importlib-metadata = ["6dfd58dfe281e8d240937776065dd3624ad5469c835248219bd16cf2e12dbeb7", "cb6ee23b46173539939964df59d3d72c3e0c1b5d54b84f1d8a7e912fe43612db"]
|
||||||
jinja2 = ["065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", "14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b"]
|
jinja2 = ["065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", "14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b"]
|
||||||
|
|
@ -535,7 +424,7 @@ pygments = ["71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127",
|
||||||
pyparsing = ["1873c03321fc118f4e9746baf201ff990ceb915f433f23b395f5580d1840cb2a", "9b6323ef4ab914af344ba97510e966d64ba91055d6b9afa6b30799340e89cc03"]
|
pyparsing = ["1873c03321fc118f4e9746baf201ff990ceb915f433f23b395f5580d1840cb2a", "9b6323ef4ab914af344ba97510e966d64ba91055d6b9afa6b30799340e89cc03"]
|
||||||
python-dateutil = ["7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", "c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"]
|
python-dateutil = ["7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", "c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"]
|
||||||
pytz = ["303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda", "d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141"]
|
pytz = ["303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda", "d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141"]
|
||||||
six = ["3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"]
|
six = ["1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", "30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"]
|
||||||
smartypants = ["8db97f7cbdf08d15b158a86037cd9e116b4cf37703d24e0419a0d64ca5808f0d"]
|
smartypants = ["8db97f7cbdf08d15b158a86037cd9e116b4cf37703d24e0419a0d64ca5808f0d"]
|
||||||
snowballstemmer = ["9f3b9ffe0809d174f7047e121431acf99c89a7040f0ca84f94ba53a498e6d0c9"]
|
snowballstemmer = ["9f3b9ffe0809d174f7047e121431acf99c89a7040f0ca84f94ba53a498e6d0c9"]
|
||||||
soupsieve = ["72b5f1aea9101cf720a36bb2327ede866fd6f1a07b1e87c92a1cc18113cbc946", "e4e9c053d59795e440163733a7fec6c5972210e1790c507e4c7b051d6c5259de"]
|
soupsieve = ["72b5f1aea9101cf720a36bb2327ede866fd6f1a07b1e87c92a1cc18113cbc946", "e4e9c053d59795e440163733a7fec6c5972210e1790c507e4c7b051d6c5259de"]
|
||||||
|
|
@ -543,7 +432,6 @@ sphinx = ["82cd2728c906be96e307b81352d3fd9fb731869234c6b835cc25e9a3dfb4b7e4", "b
|
||||||
sphinx-rtd-theme = ["00cf895504a7895ee433807c62094cf1e95f065843bf3acd17037c3e9a2becd4", "728607e34d60456d736cc7991fd236afb828b21b82f956c5ea75f94c8414040a"]
|
sphinx-rtd-theme = ["00cf895504a7895ee433807c62094cf1e95f065843bf3acd17037c3e9a2becd4", "728607e34d60456d736cc7991fd236afb828b21b82f956c5ea75f94c8414040a"]
|
||||||
toml = ["229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", "235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e", "f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"]
|
toml = ["229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", "235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e", "f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"]
|
||||||
tox = ["dab0b0160dd187b654fc33d690ee1d7bf328bd5b8dc6ef3bb3cc468969c659ba", "ee35ffce74933a6c6ac10c9a0182e41763140a5a5070e21b114feca56eaccdcd"]
|
tox = ["dab0b0160dd187b654fc33d690ee1d7bf328bd5b8dc6ef3bb3cc468969c659ba", "ee35ffce74933a6c6ac10c9a0182e41763140a5a5070e21b114feca56eaccdcd"]
|
||||||
typing = ["38566c558a0a94d6531012c8e917b1b8518a41e418f7f15f00e129cc80162ad3", "53765ec4f83a2b720214727e319607879fec4acde22c4fbb54fa2604e79e44ce", "84698954b4e6719e912ef9a42a2431407fe3755590831699debda6fba92aac55"]
|
|
||||||
typogrify = ["8be4668cda434163ce229d87ca273a11922cb1614cb359970b7dc96eed13cb38"]
|
typogrify = ["8be4668cda434163ce229d87ca273a11922cb1614cb359970b7dc96eed13cb38"]
|
||||||
unidecode = ["1d7a042116536098d05d599ef2b8616759f02985c85b4fef50c78a5aaf10822a", "2b6aab710c2a1647e928e36d69c21e76b453cd455f4e2621000e54b2a9b8cce8"]
|
unidecode = ["1d7a042116536098d05d599ef2b8616759f02985c85b4fef50c78a5aaf10822a", "2b6aab710c2a1647e928e36d69c21e76b453cd455f4e2621000e54b2a9b8cce8"]
|
||||||
virtualenv = ["b7335cddd9260a3dd214b73a2521ffc09647bde3e9457fcca31dc3be3999d04a", "d28ca64c0f3f125f59cabf13e0a150e1c68e5eea60983cc4395d88c584495783"]
|
virtualenv = ["b7335cddd9260a3dd214b73a2521ffc09647bde3e9457fcca31dc3be3999d04a", "d28ca64c0f3f125f59cabf13e0a150e1c68e5eea60983cc4395d88c584495783"]
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ unidecode = "^1.1"
|
||||||
python-dateutil = "^2.8"
|
python-dateutil = "^2.8"
|
||||||
docutils = "^0.14"
|
docutils = "^0.14"
|
||||||
markdown = {version = "~3.1.1", optional = true}
|
markdown = {version = "~3.1.1", optional = true}
|
||||||
six = "^1.4"
|
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
BeautifulSoup4 = "^4.7"
|
BeautifulSoup4 = "^4.7"
|
||||||
|
|
|
||||||
1
samples/pelican.conf.py
vendored
1
samples/pelican.conf.py
vendored
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
AUTHOR = 'Alexis Métaireau'
|
AUTHOR = 'Alexis Métaireau'
|
||||||
SITENAME = "Alexis' log"
|
SITENAME = "Alexis' log"
|
||||||
|
|
|
||||||
1
samples/pelican.conf_FR.py
vendored
1
samples/pelican.conf_FR.py
vendored
|
|
@ -1,5 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
AUTHOR = 'Alexis Métaireau'
|
AUTHOR = 'Alexis Métaireau'
|
||||||
SITENAME = "Alexis' log"
|
SITENAME = "Alexis' log"
|
||||||
|
|
|
||||||
9
setup.py
9
setup.py
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import sys
|
|
||||||
from io import open
|
from io import open
|
||||||
from os import walk
|
from os import walk
|
||||||
from os.path import join, relpath
|
from os.path import join, relpath
|
||||||
|
|
@ -10,8 +10,7 @@ from setuptools import setup
|
||||||
version = "4.2.0"
|
version = "4.2.0"
|
||||||
|
|
||||||
requires = ['feedgenerator >= 1.9', 'jinja2 >= 2.7', 'pygments', 'docutils',
|
requires = ['feedgenerator >= 1.9', 'jinja2 >= 2.7', 'pygments', 'docutils',
|
||||||
'pytz >= 0a', 'blinker', 'unidecode', 'six >= 1.4',
|
'pytz >= 0a', 'blinker', 'unidecode', 'python-dateutil']
|
||||||
'python-dateutil']
|
|
||||||
|
|
||||||
entry_points = {
|
entry_points = {
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
|
|
@ -25,9 +24,7 @@ entry_points = {
|
||||||
README = open('README.rst', encoding='utf-8').read()
|
README = open('README.rst', encoding='utf-8').read()
|
||||||
CHANGELOG = open('docs/changelog.rst', encoding='utf-8').read()
|
CHANGELOG = open('docs/changelog.rst', encoding='utf-8').read()
|
||||||
|
|
||||||
description = u'\n'.join([README, CHANGELOG])
|
description = '\n'.join([README, CHANGELOG])
|
||||||
if sys.version_info.major < 3:
|
|
||||||
description = description.encode('utf-8')
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='pelican',
|
name='pelican',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue