diff --git a/sigal/__init__.py b/sigal/__init__.py index 5d683b3..e669d2c 100644 --- a/sigal/__init__.py +++ b/sigal/__init__.py @@ -20,20 +20,18 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -from __future__ import absolute_import, print_function - import click import importlib -import io import locale import logging import os +import socketserver import sys import time from click import argument, option +from http import server -from .compat import server, socketserver, string_types from .gallery import Gallery from .log import init_logging from .pkgmeta import __version__ @@ -68,7 +66,7 @@ def init(path): from pkg_resources import resource_string conf = resource_string(__name__, 'templates/sigal.conf.py') - with io.open(path, 'w', encoding='utf-8') as f: + with open(path, 'w', encoding='utf-8') as f: f.write(conf.decode('utf8')) print("Sample config file created: {}".format(path)) @@ -173,7 +171,7 @@ def init_plugins(settings): for plugin in settings['plugins']: try: - if isinstance(plugin, string_types): + if isinstance(plugin, str): mod = importlib.import_module(plugin) mod.register(settings) else: diff --git a/sigal/compat.py b/sigal/compat.py index 268b777..49f2e83 100644 --- a/sigal/compat.py +++ b/sigal/compat.py @@ -35,26 +35,3 @@ if not PY2: from urllib.parse import quote as url_quote import socketserver import pickle -else: # pragma: no cover - text_type = unicode # NOQA - string_types = (str, unicode) # NOQA - unichr = unichr - - def strxfrm(s): - return locale.strxfrm(s.encode('utf-8')) - - from urllib import quote as url_quote # NOQA - import SimpleHTTPServer as server # NOQA - import SocketServer as socketserver # NOQA - - try: - import cPickle as pickle - except: - import pickle - - -class UnicodeMixin(object): - if not PY2: - __str__ = lambda x: x.__unicode__() - else: # pragma: no cover - __str__ = lambda x: unicode(x).encode('utf-8') diff --git a/sigal/gallery.py b/sigal/gallery.py index bb233bf..fffa37a 100644 --- a/sigal/gallery.py +++ b/sigal/gallery.py @@ -25,12 +25,12 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -from __future__ import absolute_import, print_function - import fnmatch +import locale import logging import multiprocessing import os +import pickle import random import sys import zipfile @@ -40,9 +40,9 @@ from collections import defaultdict from datetime import datetime from itertools import cycle from os.path import isfile, join, splitext +from urllib.parse import quote as url_quote from . import image, video, signals -from .compat import PY2, UnicodeMixin, strxfrm, url_quote, text_type, pickle from .image import (process_image, get_exif_tags, get_exif_data, get_size, get_iptc_data) from .settings import get_thumb @@ -53,7 +53,7 @@ from .video import process_video from .writer import Writer -class Media(UnicodeMixin): +class Media: """Base Class for media files. Attributes: @@ -89,7 +89,7 @@ class Media(UnicodeMixin): def __repr__(self): return "<%s>(%r)" % (self.__class__.__name__, str(self)) - def __unicode__(self): + def __str__(self): return join(self.path, self.filename) @property @@ -222,7 +222,7 @@ class Video(Media): self.mime = get_mime(ext) -class Album(UnicodeMixin): +class Album: """Gather all informations on an album. Attributes: @@ -289,7 +289,7 @@ class Album(UnicodeMixin): return "<%s>(path=%r, title=%r)" % (self.__class__.__name__, self.path, self.title) - def __unicode__(self): + def __str__(self): return (u"{} : ".format(self.path) + ', '.join("{} {}s".format(count, _type) for _type, count in self.medias_count.items())) @@ -341,13 +341,13 @@ class Album(UnicodeMixin): root_path = self.path if self.path != '.' else '' if albums_sort_attr.startswith("meta."): meta_key = albums_sort_attr.split(".", 1)[1] - key = lambda s: strxfrm( + key = lambda s: locale.strxfrm( self.gallery.albums[join(root_path, s)].meta.get(meta_key, [''])[0]) else: - key = lambda s: strxfrm(getattr( + key = lambda s: locale.strxfrm(getattr( self.gallery.albums[join(root_path, s)], albums_sort_attr)) else: - key = strxfrm + key = locale.strxfrm self.subdirs.sort(key=key, reverse=self.settings['albums_sort_reverse']) @@ -360,9 +360,9 @@ class Album(UnicodeMixin): key = lambda s: s.date or datetime.now() elif medias_sort_attr.startswith('meta.'): meta_key = medias_sort_attr.split(".", 1)[1] - key = lambda s: strxfrm(s.meta.get(meta_key, [''])[0]) + key = lambda s: locale.strxfrm(s.meta.get(meta_key, [''])[0]) else: - key = lambda s: strxfrm(getattr(s, medias_sort_attr)) + key = lambda s: locale.strxfrm(getattr(s, medias_sort_attr)) self.medias.sort(key=key, reverse=self.settings['medias_sort_reverse']) @@ -646,10 +646,7 @@ class Gallery(object): # 63 is the total length of progressbar, label, percentage, etc available_length = get_terminal_size()[0] - 64 if x and available_length > 10: - text = text_type(x.name)[:available_length] - if PY2: - text = text.encode('utf-8') - return text + return x.name[:available_length] else: return "" diff --git a/sigal/image.py b/sigal/image.py index da0ac63..8d5da82 100644 --- a/sigal/image.py +++ b/sigal/image.py @@ -48,7 +48,7 @@ from PIL import IptcImagePlugin from pilkit.processors import Transpose from pilkit.utils import save_image -from . import compat, signals, utils +from . import signals, utils from .settings import get_thumb, Status @@ -332,8 +332,7 @@ def get_exif_tags(data, datetime_format='%c'): try: simple['dateobj'] = datetime.strptime(date, '%Y:%m:%d %H:%M:%S') - dt = simple['dateobj'].strftime(datetime_format) - simple['datetime'] = dt.decode('utf8') if compat.PY2 else dt + simple['datetime'] = simple['dateobj'].strftime(datetime_format) except (ValueError, TypeError) as e: logger.info(u'Could not parse DateTimeOriginal: %s', e) diff --git a/sigal/plugins/feeds.py b/sigal/plugins/feeds.py index 6c08e72..3a35731 100644 --- a/sigal/plugins/feeds.py +++ b/sigal/plugins/feeds.py @@ -18,14 +18,13 @@ Example:: """ -import codecs import logging import os from datetime import datetime from feedgenerator import Atom1Feed, Rss201rev2Feed from jinja2 import Markup -from sigal import signals, compat +from sigal import signals logger = logging.getLogger(__name__) @@ -72,8 +71,7 @@ def generate_feed(gallery, medias, feed_type=None, feed_url='', nb_items=0): output_file = os.path.join(root_album.dst_path, feed_url.split('/')[-1]) logger.info('Generate %s feeds: %s', feed_type.upper(), output_file) - encoding = 'utf-8' if not compat.PY2 else None - with codecs.open(output_file, 'w', encoding) as f: + with open(output_file, 'w', encoding='utf8') as f: feed.write(f, 'utf-8') diff --git a/sigal/plugins/media_page.py b/sigal/plugins/media_page.py index 3d36269..1d7c632 100644 --- a/sigal/plugins/media_page.py +++ b/sigal/plugins/media_page.py @@ -31,7 +31,6 @@ previous/next :class:`~sigal.gallery.Media` objects. """ -import codecs import os from sigal import signals @@ -65,7 +64,7 @@ class PageWriter(Writer): output_file = "%s.html" % file_path - with codecs.open(output_file, 'w', 'utf-8') as f: + with open(output_file, 'w', encoding='utf-8') as f: f.write(page) diff --git a/sigal/plugins/nomedia.py b/sigal/plugins/nomedia.py index d23cd33..099bc8d 100644 --- a/sigal/plugins/nomedia.py +++ b/sigal/plugins/nomedia.py @@ -48,7 +48,6 @@ them for good. """ -import io import logging import os from sigal import signals @@ -107,7 +106,7 @@ def filter_nomedia(album, settings=None): album.medias = [] else: - with io.open(nomediapath, "r") as nomediaFile: + with open(nomediapath, "r") as nomediaFile: logger.info("Found a .nomedia file in %s, ignoring its " "entries", album.name) ignored = nomediaFile.read().split("\n") diff --git a/sigal/settings.py b/sigal/settings.py index 76e8518..18262b9 100644 --- a/sigal/settings.py +++ b/sigal/settings.py @@ -22,14 +22,11 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -import locale import logging import os from os.path import abspath, isabs, join, normpath from pprint import pformat -from .compat import PY2, text_type - _DEFAULT_CONFIG = { 'albums_sort_attr': 'name', @@ -146,19 +143,13 @@ def read_settings(filename=None): 'templates')): paths.append('theme') - enc = locale.getpreferredencoding() if PY2 else None - for p in paths: - # paths must to be unicode strings so that os.walk will return - # unicode dirnames and filenames - if PY2 and isinstance(settings[p], str): - settings[p] = settings[p].decode(enc) path = settings[p] if path and not isabs(path): settings[p] = abspath(normpath(join(settings_path, path))) logger.debug("Rewrite %s : %s -> %s", p, path, settings[p]) - if settings['title'] and not isinstance(settings['title'], text_type): + if settings['title'] and not isinstance(settings['title'], str): settings['title'] = settings['title'].decode('utf8') for key in ('img_size', 'thumb_size', 'video_size'): diff --git a/sigal/utils.py b/sigal/utils.py index 4feee53..7ac80d9 100644 --- a/sigal/utils.py +++ b/sigal/utils.py @@ -20,15 +20,12 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -import codecs import os import shutil from markdown import Markdown from markupsafe import Markup from subprocess import Popen, PIPE -from . import compat - VIDEO_MIMES = {'.mp4': 'video/mp4', '.webm': 'video/webm', '.ogv': 'video/ogg'} @@ -75,7 +72,7 @@ def read_markdown(filename): # Use utf-8-sig codec to remove BOM if it is present. This is only possible # this way prior to feeding the text to the markdown parser (which would # also default to pure utf-8) - with codecs.open(filename, 'r', 'utf-8-sig') as f: + with open(filename, 'r', encoding='utf-8-sig') as f: text = f.read() md = Markdown(extensions=['markdown.extensions.meta', @@ -102,10 +99,8 @@ def call_subprocess(cmd): """Wrapper to call ``subprocess.Popen`` and return stdout & stderr.""" p = Popen(cmd, stdout=PIPE, stderr=PIPE) stdout, stderr = p.communicate() - - if not compat.PY2: - stderr = stderr.decode('utf8') - stdout = stdout.decode('utf8') + stderr = stderr.decode('utf8') + stdout = stdout.decode('utf8') return p.returncode, stdout, stderr diff --git a/sigal/video.py b/sigal/video.py index c3aa392..e615ee1 100644 --- a/sigal/video.py +++ b/sigal/video.py @@ -21,8 +21,6 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -from __future__ import with_statement - import logging import os import re diff --git a/sigal/writer.py b/sigal/writer.py index 0c9b746..f638870 100644 --- a/sigal/writer.py +++ b/sigal/writer.py @@ -21,9 +21,6 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -from __future__ import absolute_import - -import codecs import jinja2 import logging import imp @@ -121,5 +118,5 @@ class Writer(object): page = self.template.render(**self.generate_context(album)) output_file = os.path.join(album.dst_path, album.output_file) - with codecs.open(output_file, 'w', 'utf-8') as f: + with open(output_file, 'w', encoding='utf-8') as f: f.write(page) diff --git a/tests/test_cli.py b/tests/test_cli.py index 9a4499d..089c0bd 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -import io import logging import os from click.testing import CliRunner @@ -52,7 +51,7 @@ def test_build(tmpdir, disconnect_signals): '-n', 1, '--debug']) assert result.exit_code == 1 - with io.open(config_file) as f: + with open(config_file) as f: text = f.read() text += """ @@ -71,7 +70,7 @@ rss_feed = {'feed_url': 'http://example.org/feed.rss', 'nb_items': 10} atom_feed = {'feed_url': 'http://example.org/feed.atom', 'nb_items': 10} """ - with io.open(config_file, 'w') as f: + with open(config_file, 'w') as f: f.write(text) result = runner.invoke(build, ['pictures', 'build', diff --git a/tests/test_video.py b/tests/test_video.py index 02efcf0..2f5a6f1 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -1,7 +1,5 @@ # -*- coding:utf-8 -*- -from __future__ import division - import os import pytest