aboutsummaryrefslogtreecommitdiffstats
path: root/gallery_dl/formatter.py
diff options
context:
space:
mode:
Diffstat (limited to 'gallery_dl/formatter.py')
-rw-r--r--gallery_dl/formatter.py86
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,