diff options
Diffstat (limited to 'gallery_dl/formatter.py')
| -rw-r--r-- | gallery_dl/formatter.py | 86 |
1 files changed, 55 insertions, 31 deletions
diff --git a/gallery_dl/formatter.py b/gallery_dl/formatter.py index 5246f66..0787464 100644 --- a/gallery_dl/formatter.py +++ b/gallery_dl/formatter.py @@ -13,9 +13,8 @@ import sys import time import string import _string -import datetime import operator -from . import text, util +from . import text, util, dt NONE = util.NONE @@ -68,8 +67,8 @@ class StringFormatter(): - "g": calls text.slugify() - "j": calls json.dumps - "t": calls str.strip - - "T": calls util.datetime_to_timestamp_string() - - "d": calls text.parse_timestamp + - "T": calls dt.to_ts_string() + - "d": calls dt.parse_ts() - "s": calls str() - "S": calls util.to_string() - "U": calls urllib.parse.unescape @@ -331,10 +330,10 @@ def _slice(indices): ) -def _bytesgetter(slice, encoding=sys.getfilesystemencoding()): +def _bytesgetter(slice): def apply_slice_bytes(obj): - return obj.encode(encoding)[slice].decode(encoding, "ignore") + return obj.encode(_ENCODING)[slice].decode(_ENCODING, "ignore") return apply_slice_bytes @@ -414,15 +413,27 @@ def _parse_conversion(format_spec, default): def _parse_maxlen(format_spec, default): maxlen, replacement, format_spec = format_spec.split(_SEPARATOR, 2) - maxlen = text.parse_int(maxlen[1:]) fmt = _build_format_func(format_spec, default) - def mlen(obj): - obj = fmt(obj) - return obj if len(obj) <= maxlen else replacement + if maxlen[1] == "b": + maxlen = text.parse_int(maxlen[2:]) + + def mlen(obj): + obj = fmt(obj) + return obj if len(obj.encode(_ENCODING)) <= maxlen else replacement + else: + maxlen = text.parse_int(maxlen[1:]) + + def mlen(obj): + obj = fmt(obj) + return obj if len(obj) <= maxlen else replacement return mlen +def _parse_identity(format_spec, default): + return util.identity + + def _parse_join(format_spec, default): separator, _, format_spec = format_spec.partition(_SEPARATOR) join = separator[1:].join @@ -471,9 +482,9 @@ def _parse_datetime(format_spec, default): dt_format = dt_format[1:] fmt = _build_format_func(format_spec, default) - def dt(obj): - return fmt(text.parse_datetime(obj, dt_format)) - return dt + def dt_parse(obj): + return fmt(dt.parse(obj, dt_format)) + return dt_parse def _parse_offset(format_spec, default): @@ -482,15 +493,15 @@ def _parse_offset(format_spec, default): fmt = _build_format_func(format_spec, default) if not offset or offset == "local": - def off(dt): - local = time.localtime(util.datetime_to_timestamp(dt)) - return fmt(dt + datetime.timedelta(0, local.tm_gmtoff)) + def off(dt_utc): + local = time.localtime(dt.to_ts(dt_utc)) + return fmt(dt_utc + dt.timedelta(0, local.tm_gmtoff)) else: hours, _, minutes = offset.partition(":") offset = 3600 * int(hours) if minutes: offset += 60 * (int(minutes) if offset > 0 else -int(minutes)) - offset = datetime.timedelta(0, offset) + offset = dt.timedelta(0, offset) def off(obj): return fmt(obj + offset) @@ -502,25 +513,36 @@ def _parse_sort(format_spec, default): fmt = _build_format_func(format_spec, default) if "d" in args or "r" in args: - def sort_desc(obj): + def sort(obj): return fmt(sorted(obj, reverse=True)) - return sort_desc else: - def sort_asc(obj): + def sort(obj): return fmt(sorted(obj)) - return sort_asc + return sort def _parse_limit(format_spec, default): limit, hint, format_spec = format_spec.split(_SEPARATOR, 2) - limit = int(limit[1:]) - limit_hint = limit - len(hint) fmt = _build_format_func(format_spec, default) - def apply_limit(obj): - if len(obj) > limit: - obj = obj[:limit_hint] + hint - return fmt(obj) + if limit[1] == "b": + hint = hint.encode(_ENCODING) + limit = int(limit[2:]) + limit_hint = limit - len(hint) + + def apply_limit(obj): + objb = obj.encode(_ENCODING) + if len(objb) > limit: + obj = (objb[:limit_hint] + hint).decode(_ENCODING, "ignore") + return fmt(obj) + else: + limit = int(limit[1:]) + limit_hint = limit - len(hint) + + def apply_limit(obj): + if len(obj) > limit: + obj = obj[:limit_hint] + hint + return fmt(obj) return apply_limit @@ -541,6 +563,7 @@ class Literal(): _literal = Literal() _CACHE = {} +_ENCODING = sys.getfilesystemencoding() _SEPARATOR = "/" _FORMATTERS = { "E" : ExpressionFormatter, @@ -557,7 +580,7 @@ _FORMATTERS = { _GLOBALS = { "_env": lambda: os.environ, "_lit": lambda: _literal, - "_now": datetime.datetime.now, + "_now": dt.datetime.now, "_nul": lambda: util.NONE, } _CONVERSIONS = { @@ -569,9 +592,9 @@ _CONVERSIONS = { "t": str.strip, "n": len, "L": util.code_to_language, - "T": util.datetime_to_timestamp_string, - "d": text.parse_timestamp, - "D": util.to_datetime, + "T": dt.to_ts_string, + "d": dt.parse_ts, + "D": dt.convert, "U": text.unescape, "H": lambda s: text.unescape(text.remove_html(s)), "g": text.slugify, @@ -590,6 +613,7 @@ _FORMAT_SPECIFIERS = { "A": _parse_arithmetic, "C": _parse_conversion, "D": _parse_datetime, + "I": _parse_identity, "J": _parse_join, "L": _parse_maxlen, "M": _parse_map, |
