diff options
author | panni <[email protected]> | 2018-10-31 17:08:29 +0100 |
---|---|---|
committer | panni <[email protected]> | 2018-10-31 17:08:29 +0100 |
commit | 8f584143f8afc46a75a83dab5243739772e3562b (patch) | |
tree | c7dae21e993880af8bee71ad7b5a63f2977db577 /libs/libfilebot | |
parent | 4beaeaa99e84bbe1ed87d0466a55a22ba25c8437 (diff) | |
download | bazarr-8f584143f8afc46a75a83dab5243739772e3562b.tar.gz bazarr-8f584143f8afc46a75a83dab5243739772e3562b.zip |
update deps
Diffstat (limited to 'libs/libfilebot')
-rw-r--r-- | libs/libfilebot/LICENSE | 21 | ||||
-rw-r--r-- | libs/libfilebot/README.md | 17 | ||||
-rw-r--r-- | libs/libfilebot/__init__.py | 5 | ||||
-rw-r--r-- | libs/libfilebot/lib.py | 38 | ||||
-rw-r--r-- | libs/libfilebot/main.py | 135 |
5 files changed, 216 insertions, 0 deletions
diff --git a/libs/libfilebot/LICENSE b/libs/libfilebot/LICENSE new file mode 100644 index 000000000..8864d4a39 --- /dev/null +++ b/libs/libfilebot/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libs/libfilebot/README.md b/libs/libfilebot/README.md new file mode 100644 index 000000000..3356c5a17 --- /dev/null +++ b/libs/libfilebot/README.md @@ -0,0 +1,17 @@ +# libfilebot + +Returns the `net.filebot.filename` property of a file without binary python package dependencies. +It instead uses system-provided binaries while *trying* to avoid calling the filebot-jvm-monstrosity. + +*This is a quick-hack-excerpt from [Sub-Zero.bundle](https://github.com/pannal/Sub-Zero.bundle), so don't expect constant maintenance or code-quality.* + +#### Currently supports: + +* `xattr` command on darwin/osx +* NTFS advanced data streams via python pyADS +* `getfattr`, `attr` and `filebot` commands for every other OS + + +#### Dependencies + +* [pyADS](https://github.com/RobinDavid/pyADS) for Windows
\ No newline at end of file diff --git a/libs/libfilebot/__init__.py b/libs/libfilebot/__init__.py new file mode 100644 index 000000000..c734afaef --- /dev/null +++ b/libs/libfilebot/__init__.py @@ -0,0 +1,5 @@ +# coding=utf-8 + +from main import get_filebot_attrs + +__all__ = ["get_filebot_attrs"] diff --git a/libs/libfilebot/lib.py b/libs/libfilebot/lib.py new file mode 100644 index 000000000..ac7e469b0 --- /dev/null +++ b/libs/libfilebot/lib.py @@ -0,0 +1,38 @@ +# coding=utf-8 + +import os +import sys + + +def find_executable(executable, path=None): + """Find if 'executable' can be run. Looks for it in 'path' + (string that lists directories separated by 'os.pathsep'; + defaults to os.environ['PATH']). Checks for all executable + extensions. Returns full path or None if no command is found. + """ + if path is None: + path = os.environ['PATH'] + paths = path.split(os.pathsep) + extlist = [''] + if os.name == 'os2': + (base, ext) = os.path.splitext(executable) + # executable files on OS/2 can have an arbitrary extension, but + # .exe is automatically appended if no dot is present in the name + if not ext: + executable = executable + ".exe" + elif sys.platform == 'win32': + pathext = os.environ['PATHEXT'].lower().split(os.pathsep) + (base, ext) = os.path.splitext(executable) + if ext.lower() not in pathext: + extlist = pathext + for ext in extlist: + execname = executable + ext + if os.path.isfile(execname): + return execname + else: + for p in paths: + f = os.path.join(p, execname) + if os.path.isfile(f): + return f + else: + return None
\ No newline at end of file diff --git a/libs/libfilebot/main.py b/libs/libfilebot/main.py new file mode 100644 index 000000000..9a4e685eb --- /dev/null +++ b/libs/libfilebot/main.py @@ -0,0 +1,135 @@ +# coding=utf-8 + +import subprocess +import sys +import traceback +import logging +import re +import binascii +import types +import os + +from pipes import quote +from lib import find_executable + +mswindows = False +if sys.platform == "win32": + mswindows = True + from pyads import ADS + +logger = logging.getLogger(__name__) + + +def quote_args(seq): + return ' '.join(quote(arg) for arg in seq) + + +def win32_xattr(fn): + handler = ADS(fn) + try: + return handler.get_stream_content("net.filebot.filename") + except IOError: + pass + + +def default_xattr(fn): + if not default_xattr_bin: + raise Exception("Neither getfattr, attr nor filebot were found") + + if "getfattr" in default_xattr_bin: + return ["getfattr", "-n", "user.net.filebot.filename", fn] + + elif "attr" in default_xattr_bin: + return ["attr", "-g", "net.filebot.filename", fn] + + return ["filebot", "-script", "fn:xattr", fn] + + +XATTR_MAP = { + "default": ( + default_xattr, + lambda result: re.search('(?um)(net\.filebot\.filename(?=="|: )[=:" ]+|Attribute.+:\s)([^"\n\r\0]+)', + result).group(2) + ), + # "darwin": ( + # lambda fn: ["xattr", "-p", "net.filebot.filename", fn], + # lambda result: binascii.unhexlify(result.strip().replace(' ', '').replace('\r\n', '').replace('\r', '') + # .replace('\n', '')).strip("\x00") + # ), + "darwin": ( + lambda fn: ["filebot", "-script", "fn:xattr", fn], + lambda result: re.search('(?um)(net\.filebot\.filename(?=="|: )[=:" ]+|Attribute.+:\s)([^"\n\r\0]+)', + result).group(2) + ), + "win32": ( + lambda fn: fn, + win32_xattr, + ) +} + +if sys.platform not in XATTR_MAP: + default_xattr_bin = find_executable("getfattr") or find_executable("attr") or find_executable("filebot") \ + or "filebot" + + +def get_filebot_attrs(fn): + """ + Currently only supports the filebot filename attrs + :param fn: filename + :return: + """ + + if sys.platform in XATTR_MAP: + logger.debug("Using native xattr calls for %s", sys.platform) + else: + logger.debug("Using %s for %s", default_xattr_bin, sys.platform) + + args_func, match_func = XATTR_MAP.get(sys.platform, XATTR_MAP["default"]) + + args = args_func(fn) + if isinstance(args, types.ListType): + try: + env = dict(os.environ) + if not mswindows: + env_path = {"PATH": os.pathsep.join( + [ + "/usr/local/bin", + "/usr/bin", + "/usr/local/sbin", + "/usr/sbin", + os.environ.get("PATH", "") + ] + ) + } + env = dict(os.environ, **env_path) + + env.pop("LD_LIBRARY_PATH", None) + + proc = subprocess.Popen(quote_args(args), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, + env=env) + output, errors = proc.communicate() + + if proc.returncode == 1: + logger.info(u"%s: Couldn't get filebot original filename, args: %r, output: %r, error: %r", fn, args, + output, errors) + return + + output = output.decode() + + except: + logger.error(u"%s: Unexpected error while getting filebot original filename: %s", fn, + traceback.format_exc()) + return + else: + output = args + + try: + orig_fn = match_func(output) + return orig_fn.strip() + except: + logger.info(u"%s: Couldn't get filebot original filename" % fn) + logger.debug(u"%s: Result: %r" % (fn, output)) + + +if __name__ == "__main__": + print get_filebot_attrs(sys.argv[1]) |