summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authormorpheus65535 <[email protected]>2021-12-13 20:05:13 -0500
committermorpheus65535 <[email protected]>2021-12-13 20:05:13 -0500
commitf38d03ce86723f46edcd50ef7fa78133ee6e337e (patch)
treef0080265e9045bb63e3c67cba5aa0c90fab6ee30
parent8f58b8b6c70d4b05c1824dfbf72348288993e2c4 (diff)
parent3cc0d4bac4bcd643bf87a76fab9216052e05961d (diff)
downloadbazarr-1.0.2-beta.7.tar.gz
bazarr-1.0.2-beta.7.zip
Merge remote-tracking branch 'origin/development' into developmentv1.0.2-beta.7
-rw-r--r--README.md1
-rw-r--r--bazarr/config.py3
-rw-r--r--bazarr/get_providers.py7
-rw-r--r--frontend/package-lock.json851
-rw-r--r--frontend/package.json1
-rw-r--r--frontend/src/Settings/Providers/list.ts11
-rwxr-xr-xlibs/fese/__init__.py401
-rw-r--r--libs/subliminal/subtitle.py2
-rw-r--r--libs/subliminal_patch/core.py19
-rw-r--r--libs/subliminal_patch/providers/embeddedsubtitles.py162
-rw-r--r--tests/subliminal_patch/data/file_1.mkvbin0 -> 646450 bytes
-rw-r--r--tests/subliminal_patch/data/file_2.mkvbin0 -> 1248441 bytes
-rw-r--r--tests/subliminal_patch/test_embeddedsubtitles.py115
13 files changed, 717 insertions, 856 deletions
diff --git a/README.md b/README.md
index 109804d85..b1a1c24bd 100644
--- a/README.md
+++ b/README.md
@@ -46,6 +46,7 @@ If you need something that is not already part of Bazarr, feel free to create a
* Assrt
* BetaSeries
* BSplayer
+* Embedded Subtitles
* GreekSubtitles
* Hosszupuska
* LegendasDivx
diff --git a/bazarr/config.py b/bazarr/config.py
index 78af8b39c..c27931344 100644
--- a/bazarr/config.py
+++ b/bazarr/config.py
@@ -190,6 +190,9 @@ defaults = {
'approved_only': 'False',
'multithreading': 'True'
},
+ 'embeddedsubtitles': {
+ 'include_ass': 'True',
+ },
'subsync': {
'use_subsync': 'False',
'use_subsync_threshold': 'False',
diff --git a/bazarr/get_providers.py b/bazarr/get_providers.py
index bf230931e..9e1d652f6 100644
--- a/bazarr/get_providers.py
+++ b/bazarr/get_providers.py
@@ -13,6 +13,7 @@ import ast
from get_args import args
from config import settings, get_array_from
from event_handler import event_stream
+from utils import get_binary
from subliminal_patch.exceptions import TooManyRequests, APIThrottled, ParseResponseError, IPAddressBlocked
from subliminal.providers.opensubtitles import DownloadLimitReached
from subliminal.exceptions import DownloadLimitExceeded, ServiceUnavailable
@@ -198,6 +199,12 @@ def get_providers_auth():
'email': settings.ktuvit.email,
'hashed_password': settings.ktuvit.hashed_password,
},
+ 'embeddedsubtitles': {
+ 'include_ass': settings.embeddedsubtitles.getboolean('include_ass'),
+ 'cache_dir': os.path.join(args.config_dir, "cache"),
+ 'ffprobe_path': get_binary("ffprobe"),
+ 'ffmpeg_path': get_binary("ffmpeg"),
+ }
}
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 1f062865a..45fe602f6 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -20,7 +20,6 @@
"bootstrap": "^4",
"lodash": "^4",
"moment": "^2.29.1",
- "package.json": "^2.0.1",
"rc-slider": "^9.7",
"react": "^17",
"react-bootstrap": "^1",
@@ -4220,14 +4219,6 @@
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
"integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q=="
},
- "node_modules/abs": {
- "version": "1.3.14",
- "resolved": "https://registry.npmjs.org/abs/-/abs-1.3.14.tgz",
- "integrity": "sha512-PrS26IzwKLWwuURpiKl8wRmJ2KdR/azaVrLEBWG/TALwT20Y7qjtYp1qcMLHA4206hBHY5phv3w4pjf9NPv4Vw==",
- "dependencies": {
- "ul": "^5.0.0"
- }
- },
"node_modules/accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@@ -5891,14 +5882,6 @@
"node": "6.* || 8.* || >= 10.*"
}
},
- "node_modules/capture-stack-trace": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
- "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/case-sensitive-paths-webpack-plugin": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz",
@@ -6580,17 +6563,6 @@
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
},
- "node_modules/create-error-class": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
- "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
- "dependencies": {
- "capture-stack-trace": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/create-hash": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
@@ -7216,14 +7188,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
- "engines": {
- "node": ">=4.0.0"
- }
- },
"node_modules/deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -7357,14 +7321,6 @@
"which": "bin/which"
}
},
- "node_modules/deffy": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/deffy/-/deffy-2.2.4.tgz",
- "integrity": "sha512-pLc9lsbsWjr6RxmJ2OLyvm+9l4j1yK69h+TML/gUit/t3vTijpkNGh8LioaJYTGO7F25m6HZndADcUOo2PsiUg==",
- "dependencies": {
- "typpy": "^2.0.0"
- }
- },
"node_modules/define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -7739,14 +7695,6 @@
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg=="
},
- "node_modules/duplexer2": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
- "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
- "dependencies": {
- "readable-stream": "^2.0.2"
- }
- },
"node_modules/duplexify": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
@@ -7948,14 +7896,6 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
- "node_modules/err": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/err/-/err-1.1.1.tgz",
- "integrity": "sha1-65KOLhGjFmSPeCgz0PlyWLpDwvg=",
- "dependencies": {
- "typpy": "^2.2.0"
- }
- },
"node_modules/errno": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
@@ -9098,15 +9038,6 @@
"safe-buffer": "^5.1.1"
}
},
- "node_modules/exec-limiter": {
- "version": "3.2.13",
- "resolved": "https://registry.npmjs.org/exec-limiter/-/exec-limiter-3.2.13.tgz",
- "integrity": "sha512-86Ri699bwiHZVBzTzNj8gspqAhCPchg70zPVWIh3qzUOA1pUMcb272Em3LPk8AE0mS95B9yMJhtqF8vFJAn0dA==",
- "dependencies": {
- "limit-it": "^3.0.0",
- "typpy": "^2.1.0"
- }
- },
"node_modules/exec-sh": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz",
@@ -9960,14 +9891,6 @@
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
- "node_modules/function.name": {
- "version": "1.0.13",
- "resolved": "https://registry.npmjs.org/function.name/-/function.name-1.0.13.tgz",
- "integrity": "sha512-mVrqdoy5npWZyoXl4DxCeuVF6delDcQjVS9aPdvLYlBxtMTZDR2B5GVEQEoM1jJyspCqg3C0v4ABkLE7tp9xFA==",
- "dependencies": {
- "noop6": "^1.0.1"
- }
- },
"node_modules/functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
@@ -10037,47 +9960,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/git-package-json": {
- "version": "1.4.10",
- "resolved": "https://registry.npmjs.org/git-package-json/-/git-package-json-1.4.10.tgz",
- "integrity": "sha512-DRAcvbzd2SxGK7w8OgYfvKqhFliT5keX0lmSmVdgScgf1kkl5tbbo7Pam6uYoCa1liOiipKxQZG8quCtGWl/fA==",
- "dependencies": {
- "deffy": "^2.2.1",
- "err": "^1.1.1",
- "gry": "^5.0.0",
- "normalize-package-data": "^2.3.5",
- "oargv": "^3.4.1",
- "one-by-one": "^3.1.0",
- "r-json": "^1.2.1",
- "r-package-json": "^1.0.0",
- "tmp": "0.0.28"
- }
- },
- "node_modules/git-source": {
- "version": "1.1.10",
- "resolved": "https://registry.npmjs.org/git-source/-/git-source-1.1.10.tgz",
- "integrity": "sha512-XZZ7ZgnLL35oLgM/xjnLYgtlKlxJG0FohC1kWDvGkU7s1VKGXK0pFF/g1itQEwQ3D+uTQzBnzPi8XbqOv7Wc1Q==",
- "dependencies": {
- "git-url-parse": "^5.0.1"
- }
- },
- "node_modules/git-up": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/git-up/-/git-up-1.2.1.tgz",
- "integrity": "sha1-JkSAoAax2EJhrB/gmjpRacV+oZ0=",
- "dependencies": {
- "is-ssh": "^1.0.0",
- "parse-url": "^1.0.0"
- }
- },
- "node_modules/git-url-parse": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-5.0.1.tgz",
- "integrity": "sha1-/j15xnRq4FBIz6UIyB553du6OEM=",
- "dependencies": {
- "git-up": "^1.0.0"
- }
- },
"node_modules/glob": {
"version": "7.1.7",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
@@ -10170,51 +10052,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/got": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/got/-/got-5.6.0.tgz",
- "integrity": "sha1-ux1+4WO3gIK7yOuDbz85UATqb78=",
- "dependencies": {
- "create-error-class": "^3.0.1",
- "duplexer2": "^0.1.4",
- "is-plain-obj": "^1.0.0",
- "is-redirect": "^1.0.0",
- "is-retry-allowed": "^1.0.0",
- "is-stream": "^1.0.0",
- "lowercase-keys": "^1.0.0",
- "node-status-codes": "^1.0.0",
- "object-assign": "^4.0.1",
- "parse-json": "^2.1.0",
- "pinkie-promise": "^2.0.0",
- "read-all-stream": "^3.0.0",
- "readable-stream": "^2.0.5",
- "timed-out": "^2.0.0",
- "unzip-response": "^1.0.0",
- "url-parse-lax": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/got/node_modules/is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/got/node_modules/parse-json": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
- "dependencies": {
- "error-ex": "^1.2.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/graceful-fs": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
@@ -10226,17 +10063,6 @@
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
"optional": true
},
- "node_modules/gry": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/gry/-/gry-5.0.8.tgz",
- "integrity": "sha512-meq9ZjYVpLzZh3ojhTg7IMad9grGsx6rUUKHLqPnhLXzJkRQvEL2U3tQpS5/WentYTtHtxkT3Ew/mb10D6F6/g==",
- "dependencies": {
- "abs": "^1.2.1",
- "exec-limiter": "^3.0.0",
- "one-by-one": "^3.0.0",
- "ul": "^5.0.0"
- }
- },
"node_modules/gzip-size": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz",
@@ -11454,14 +11280,6 @@
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
},
- "node_modules/is-redirect": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
- "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
@@ -11490,14 +11308,6 @@
"resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
"integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg=="
},
- "node_modules/is-retry-allowed": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
- "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/is-root": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz",
@@ -11506,14 +11316,6 @@
"node": ">=6"
}
},
- "node_modules/is-ssh": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.3.tgz",
- "integrity": "sha512-NKzJmQzJfEEma3w5cJNcUMxoXfDjz0Zj0eyCalHn2E6VOwlzjZo0yuO2fcBSf8zhFuVCL/82/r5gRcoi6aEPVQ==",
- "dependencies": {
- "protocols": "^1.1.0"
- }
- },
"node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -11714,11 +11516,6 @@
"node": ">=8"
}
},
- "node_modules/iterate-object": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/iterate-object/-/iterate-object-1.3.4.tgz",
- "integrity": "sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw=="
- },
"node_modules/jest": {
"version": "26.6.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-26.6.0.tgz",
@@ -13433,14 +13230,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/limit-it": {
- "version": "3.2.10",
- "resolved": "https://registry.npmjs.org/limit-it/-/limit-it-3.2.10.tgz",
- "integrity": "sha512-T0NK99pHnkimldr1WUqvbGV1oWDku/xC9J/OqzJFsV1jeOS6Bwl8W7vkeQIBqwiON9dTALws+rX/XPMQqWerDQ==",
- "dependencies": {
- "typpy": "^2.0.0"
- }
- },
"node_modules/lines-and-columns": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
@@ -13602,14 +13391,6 @@
"tslib": "^2.0.3"
}
},
- "node_modules/lowercase-keys": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
- "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -14255,19 +14036,6 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
"integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg=="
},
- "node_modules/node-status-codes": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz",
- "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/noop6": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/noop6/-/noop6-1.0.9.tgz",
- "integrity": "sha512-DB3Hwyd89dPr5HqEPg3YHjzvwh/mCqizC1zZ8vyofqc+TQRyPDnT4wgXXbLGF4z9YAzwwTLi8pNLhGqcbSjgkA=="
- },
"node_modules/normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@@ -14349,23 +14117,6 @@
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
"integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ=="
},
- "node_modules/oargv": {
- "version": "3.4.10",
- "resolved": "https://registry.npmjs.org/oargv/-/oargv-3.4.10.tgz",
- "integrity": "sha512-SXaMANv9sr7S/dP0vj0+Ybipa47UE1ntTWQ2rpPRhC6Bsvfl+Jg03Xif7jfL0sWKOYWK8oPjcZ5eJ82t8AP/8g==",
- "dependencies": {
- "iterate-object": "^1.1.0",
- "ul": "^5.0.0"
- }
- },
- "node_modules/obj-def": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/obj-def/-/obj-def-1.0.9.tgz",
- "integrity": "sha512-bQ4ya3VYD6FAA1+s6mEhaURRHSmw4+sKaXE6UyXZ1XDYc5D+c7look25dFdydmLd18epUegh398gdDkMUZI9xg==",
- "dependencies": {
- "deffy": "^2.2.2"
- }
- },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -14616,15 +14367,6 @@
"wrappy": "1"
}
},
- "node_modules/one-by-one": {
- "version": "3.2.8",
- "resolved": "https://registry.npmjs.org/one-by-one/-/one-by-one-3.2.8.tgz",
- "integrity": "sha512-HR/pSzZdm46Xqj58K+Bu64kMbSTw8/u77AwWvV+rprO/OsuR++pPlkUJn+SmwqBGRgHKwSKQ974V3uls7crIeQ==",
- "dependencies": {
- "obj-def": "^1.0.0",
- "sliced": "^1.0.1"
- }
- },
"node_modules/onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -14714,14 +14456,6 @@
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc="
},
- "node_modules/os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/p-each-series": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz",
@@ -14788,47 +14522,6 @@
"node": ">=6"
}
},
- "node_modules/package-json": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz",
- "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=",
- "dependencies": {
- "got": "^5.0.0",
- "registry-auth-token": "^3.0.1",
- "registry-url": "^3.0.3",
- "semver": "^5.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/package-json-path": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/package-json-path/-/package-json-path-1.0.9.tgz",
- "integrity": "sha512-uNu7f6Ef7tQHZRnkyVnCtzdSYVN9uBtge/sG7wzcUaawFWkPYUq67iXxRGrQSg/q0tzxIB8jSyIYUKjG2Jn//A==",
- "dependencies": {
- "abs": "^1.2.1"
- }
- },
- "node_modules/package-json/node_modules/semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/package.json": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/package.json/-/package.json-2.0.1.tgz",
- "integrity": "sha1-+IYFnSpJ7QduZIg2ldc7K0bSHW0=",
- "deprecated": "Use pkg.json instead.",
- "dependencies": {
- "git-package-json": "^1.4.0",
- "git-source": "^1.1.0",
- "package-json": "^2.3.1"
- }
- },
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -14893,15 +14586,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/parse-url": {
- "version": "1.3.11",
- "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-1.3.11.tgz",
- "integrity": "sha1-V8FUKKuKiSsfQ4aWRccR0OFEtVQ=",
- "dependencies": {
- "is-ssh": "^1.3.0",
- "protocols": "^1.4.0"
- }
- },
"node_modules/parse5": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
@@ -16542,9 +16226,9 @@
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
"node_modules/pretty-quick": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.1.tgz",
- "integrity": "sha512-ZYLGiMoV2jcaas3vTJrLvKAYsxDoXQBUn8OSTxkl67Fyov9lyXivJTl0+2WVh+y6EovGcw7Lm5ThYpH+Sh3XxQ==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.2.tgz",
+ "integrity": "sha512-T+fpTJrDjTzewql4p3lKrRA7z3MrNyjBK1MKeaBm5PpKwATgVm885TpY7TgY8KFt5Q1Qn3QDseRQcyX9AKTKkA==",
"dev": true,
"dependencies": {
"chalk": "^3.0.0",
@@ -16697,11 +16381,6 @@
"react": ">=0.14.0"
}
},
- "node_modules/protocols": {
- "version": "1.4.8",
- "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz",
- "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg=="
- },
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -16848,20 +16527,6 @@
}
]
},
- "node_modules/r-json": {
- "version": "1.2.10",
- "resolved": "https://registry.npmjs.org/r-json/-/r-json-1.2.10.tgz",
- "integrity": "sha512-hu9vyLjSlHXT62NAS7DjI9WazDlvjN0lgp3n431dCVnirVcLkZIpzSwA3orhZEKzdDD2jqNYI+w0yG0aFf4kpA=="
- },
- "node_modules/r-package-json": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/r-package-json/-/r-package-json-1.0.9.tgz",
- "integrity": "sha512-G4Vpf1KImWmmPFGdtWQTU0L9zk0SjqEC4qs/jE7AQ+Ylmr5kizMzGeC4wnHp5+ijPqNN+2ZPpvyjVNdN1CDVcg==",
- "dependencies": {
- "package-json-path": "^1.0.0",
- "r-json": "^1.2.1"
- }
- },
"node_modules/raf": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
@@ -16917,20 +16582,6 @@
"node": ">= 0.8"
}
},
- "node_modules/rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "dependencies": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "bin": {
- "rc": "cli.js"
- }
- },
"node_modules/rc-align": {
"version": "4.0.9",
"resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.9.tgz",
@@ -17026,14 +16677,6 @@
"react-dom": ">=16.9.0"
}
},
- "node_modules/rc/node_modules/strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/react": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
@@ -17737,18 +17380,6 @@
"react-dom": ">=16.6.0"
}
},
- "node_modules/read-all-stream": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz",
- "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=",
- "dependencies": {
- "pinkie-promise": "^2.0.0",
- "readable-stream": "^2.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -18055,26 +17686,6 @@
"node": ">=4"
}
},
- "node_modules/registry-auth-token": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
- "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
- "dependencies": {
- "rc": "^1.1.6",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/registry-url": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
- "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
- "dependencies": {
- "rc": "^1.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/regjsgen": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
@@ -19099,11 +18710,6 @@
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
}
},
- "node_modules/sliced": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
- "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
- },
"node_modules/snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -20514,14 +20120,6 @@
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
},
- "node_modules/timed-out": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz",
- "integrity": "sha1-84sK6B03R9YoAB9B2vxlKs5nHAo=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/timers-browserify": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
@@ -20548,17 +20146,6 @@
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
},
- "node_modules/tmp": {
- "version": "0.0.28",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz",
- "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=",
- "dependencies": {
- "os-tmpdir": "~1.0.1"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
"node_modules/tmpl": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
@@ -20802,23 +20389,6 @@
"node": ">=4.2.0"
}
},
- "node_modules/typpy": {
- "version": "2.3.13",
- "resolved": "https://registry.npmjs.org/typpy/-/typpy-2.3.13.tgz",
- "integrity": "sha512-vOxIcQz9sxHi+rT09SJ5aDgVgrPppQjwnnayTrMye1ODaU8gIZTDM19t9TxmEElbMihx2Nq/0/b/MtyKfayRqA==",
- "dependencies": {
- "function.name": "^1.0.3"
- }
- },
- "node_modules/ul": {
- "version": "5.2.15",
- "resolved": "https://registry.npmjs.org/ul/-/ul-5.2.15.tgz",
- "integrity": "sha512-svLEUy8xSCip5IWnsRa0UOg+2zP0Wsj4qlbjTmX6GJSmvKMHADBuHOm1dpNkWqWPIGuVSqzUkV3Cris5JrlTRQ==",
- "dependencies": {
- "deffy": "^2.2.2",
- "typpy": "^2.3.4"
- }
- },
"node_modules/unbox-primitive": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
@@ -21012,14 +20582,6 @@
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
- "node_modules/unzip-response": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz",
- "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=",
- "engines": {
- "node": ">=0.10"
- }
- },
"node_modules/upath": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
@@ -21104,17 +20666,6 @@
"requires-port": "^1.0.0"
}
},
- "node_modules/url-parse-lax": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
- "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
- "dependencies": {
- "prepend-http": "^1.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/url/node_modules/punycode": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
@@ -25871,14 +25422,6 @@
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
"integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q=="
},
- "abs": {
- "version": "1.3.14",
- "resolved": "https://registry.npmjs.org/abs/-/abs-1.3.14.tgz",
- "integrity": "sha512-PrS26IzwKLWwuURpiKl8wRmJ2KdR/azaVrLEBWG/TALwT20Y7qjtYp1qcMLHA4206hBHY5phv3w4pjf9NPv4Vw==",
- "requires": {
- "ul": "^5.0.0"
- }
- },
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@@ -27187,11 +26730,6 @@
"rsvp": "^4.8.4"
}
},
- "capture-stack-trace": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
- "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw=="
- },
"case-sensitive-paths-webpack-plugin": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz",
@@ -27741,14 +27279,6 @@
}
}
},
- "create-error-class": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
- "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
- "requires": {
- "capture-stack-trace": "^1.0.0"
- }
- },
"create-hash": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
@@ -28256,11 +27786,6 @@
"regexp.prototype.flags": "^1.2.0"
}
},
- "deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
- },
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
@@ -28360,14 +27885,6 @@
}
}
},
- "deffy": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/deffy/-/deffy-2.2.4.tgz",
- "integrity": "sha512-pLc9lsbsWjr6RxmJ2OLyvm+9l4j1yK69h+TML/gUit/t3vTijpkNGh8LioaJYTGO7F25m6HZndADcUOo2PsiUg==",
- "requires": {
- "typpy": "^2.0.0"
- }
- },
"define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -28663,14 +28180,6 @@
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg=="
},
- "duplexer2": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
- "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
- "requires": {
- "readable-stream": "^2.0.2"
- }
- },
"duplexify": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
@@ -28825,14 +28334,6 @@
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="
},
- "err": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/err/-/err-1.1.1.tgz",
- "integrity": "sha1-65KOLhGjFmSPeCgz0PlyWLpDwvg=",
- "requires": {
- "typpy": "^2.2.0"
- }
- },
"errno": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
@@ -29637,15 +29138,6 @@
"safe-buffer": "^5.1.1"
}
},
- "exec-limiter": {
- "version": "3.2.13",
- "resolved": "https://registry.npmjs.org/exec-limiter/-/exec-limiter-3.2.13.tgz",
- "integrity": "sha512-86Ri699bwiHZVBzTzNj8gspqAhCPchg70zPVWIh3qzUOA1pUMcb272Em3LPk8AE0mS95B9yMJhtqF8vFJAn0dA==",
- "requires": {
- "limit-it": "^3.0.0",
- "typpy": "^2.1.0"
- }
- },
"exec-sh": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz",
@@ -30314,14 +29806,6 @@
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
- "function.name": {
- "version": "1.0.13",
- "resolved": "https://registry.npmjs.org/function.name/-/function.name-1.0.13.tgz",
- "integrity": "sha512-mVrqdoy5npWZyoXl4DxCeuVF6delDcQjVS9aPdvLYlBxtMTZDR2B5GVEQEoM1jJyspCqg3C0v4ABkLE7tp9xFA==",
- "requires": {
- "noop6": "^1.0.1"
- }
- },
"functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
@@ -30370,47 +29854,6 @@
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
},
- "git-package-json": {
- "version": "1.4.10",
- "resolved": "https://registry.npmjs.org/git-package-json/-/git-package-json-1.4.10.tgz",
- "integrity": "sha512-DRAcvbzd2SxGK7w8OgYfvKqhFliT5keX0lmSmVdgScgf1kkl5tbbo7Pam6uYoCa1liOiipKxQZG8quCtGWl/fA==",
- "requires": {
- "deffy": "^2.2.1",
- "err": "^1.1.1",
- "gry": "^5.0.0",
- "normalize-package-data": "^2.3.5",
- "oargv": "^3.4.1",
- "one-by-one": "^3.1.0",
- "r-json": "^1.2.1",
- "r-package-json": "^1.0.0",
- "tmp": "0.0.28"
- }
- },
- "git-source": {
- "version": "1.1.10",
- "resolved": "https://registry.npmjs.org/git-source/-/git-source-1.1.10.tgz",
- "integrity": "sha512-XZZ7ZgnLL35oLgM/xjnLYgtlKlxJG0FohC1kWDvGkU7s1VKGXK0pFF/g1itQEwQ3D+uTQzBnzPi8XbqOv7Wc1Q==",
- "requires": {
- "git-url-parse": "^5.0.1"
- }
- },
- "git-up": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/git-up/-/git-up-1.2.1.tgz",
- "integrity": "sha1-JkSAoAax2EJhrB/gmjpRacV+oZ0=",
- "requires": {
- "is-ssh": "^1.0.0",
- "parse-url": "^1.0.0"
- }
- },
- "git-url-parse": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-5.0.1.tgz",
- "integrity": "sha1-/j15xnRq4FBIz6UIyB553du6OEM=",
- "requires": {
- "git-up": "^1.0.0"
- }
- },
"glob": {
"version": "7.1.7",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
@@ -30478,44 +29921,6 @@
"slash": "^3.0.0"
}
},
- "got": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/got/-/got-5.6.0.tgz",
- "integrity": "sha1-ux1+4WO3gIK7yOuDbz85UATqb78=",
- "requires": {
- "create-error-class": "^3.0.1",
- "duplexer2": "^0.1.4",
- "is-plain-obj": "^1.0.0",
- "is-redirect": "^1.0.0",
- "is-retry-allowed": "^1.0.0",
- "is-stream": "^1.0.0",
- "lowercase-keys": "^1.0.0",
- "node-status-codes": "^1.0.0",
- "object-assign": "^4.0.1",
- "parse-json": "^2.1.0",
- "pinkie-promise": "^2.0.0",
- "read-all-stream": "^3.0.0",
- "readable-stream": "^2.0.5",
- "timed-out": "^2.0.0",
- "unzip-response": "^1.0.0",
- "url-parse-lax": "^1.0.0"
- },
- "dependencies": {
- "is-stream": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
- },
- "parse-json": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
- "requires": {
- "error-ex": "^1.2.0"
- }
- }
- }
- },
"graceful-fs": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
@@ -30527,17 +29932,6 @@
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
"optional": true
},
- "gry": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/gry/-/gry-5.0.8.tgz",
- "integrity": "sha512-meq9ZjYVpLzZh3ojhTg7IMad9grGsx6rUUKHLqPnhLXzJkRQvEL2U3tQpS5/WentYTtHtxkT3Ew/mb10D6F6/g==",
- "requires": {
- "abs": "^1.2.1",
- "exec-limiter": "^3.0.0",
- "one-by-one": "^3.0.0",
- "ul": "^5.0.0"
- }
- },
"gzip-size": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz",
@@ -31426,11 +30820,6 @@
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
},
- "is-redirect": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
- "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ="
- },
"is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
@@ -31450,24 +30839,11 @@
"resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
"integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg=="
},
- "is-retry-allowed": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
- "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg=="
- },
"is-root": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz",
"integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg=="
},
- "is-ssh": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.3.tgz",
- "integrity": "sha512-NKzJmQzJfEEma3w5cJNcUMxoXfDjz0Zj0eyCalHn2E6VOwlzjZo0yuO2fcBSf8zhFuVCL/82/r5gRcoi6aEPVQ==",
- "requires": {
- "protocols": "^1.1.0"
- }
- },
"is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -31609,11 +30985,6 @@
"istanbul-lib-report": "^3.0.0"
}
},
- "iterate-object": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/iterate-object/-/iterate-object-1.3.4.tgz",
- "integrity": "sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw=="
- },
"jest": {
"version": "26.6.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-26.6.0.tgz",
@@ -32911,14 +32282,6 @@
"type-check": "~0.4.0"
}
},
- "limit-it": {
- "version": "3.2.10",
- "resolved": "https://registry.npmjs.org/limit-it/-/limit-it-3.2.10.tgz",
- "integrity": "sha512-T0NK99pHnkimldr1WUqvbGV1oWDku/xC9J/OqzJFsV1jeOS6Bwl8W7vkeQIBqwiON9dTALws+rX/XPMQqWerDQ==",
- "requires": {
- "typpy": "^2.0.0"
- }
- },
"lines-and-columns": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
@@ -33054,11 +32417,6 @@
"tslib": "^2.0.3"
}
},
- "lowercase-keys": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
- "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
- },
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -33586,16 +32944,6 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
"integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg=="
},
- "node-status-codes": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz",
- "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8="
- },
- "noop6": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/noop6/-/noop6-1.0.9.tgz",
- "integrity": "sha512-DB3Hwyd89dPr5HqEPg3YHjzvwh/mCqizC1zZ8vyofqc+TQRyPDnT4wgXXbLGF4z9YAzwwTLi8pNLhGqcbSjgkA=="
- },
"normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@@ -33661,23 +33009,6 @@
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
"integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ=="
},
- "oargv": {
- "version": "3.4.10",
- "resolved": "https://registry.npmjs.org/oargv/-/oargv-3.4.10.tgz",
- "integrity": "sha512-SXaMANv9sr7S/dP0vj0+Ybipa47UE1ntTWQ2rpPRhC6Bsvfl+Jg03Xif7jfL0sWKOYWK8oPjcZ5eJ82t8AP/8g==",
- "requires": {
- "iterate-object": "^1.1.0",
- "ul": "^5.0.0"
- }
- },
- "obj-def": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/obj-def/-/obj-def-1.0.9.tgz",
- "integrity": "sha512-bQ4ya3VYD6FAA1+s6mEhaURRHSmw4+sKaXE6UyXZ1XDYc5D+c7look25dFdydmLd18epUegh398gdDkMUZI9xg==",
- "requires": {
- "deffy": "^2.2.2"
- }
- },
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -33857,15 +33188,6 @@
"wrappy": "1"
}
},
- "one-by-one": {
- "version": "3.2.8",
- "resolved": "https://registry.npmjs.org/one-by-one/-/one-by-one-3.2.8.tgz",
- "integrity": "sha512-HR/pSzZdm46Xqj58K+Bu64kMbSTw8/u77AwWvV+rprO/OsuR++pPlkUJn+SmwqBGRgHKwSKQ974V3uls7crIeQ==",
- "requires": {
- "obj-def": "^1.0.0",
- "sliced": "^1.0.1"
- }
- },
"onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -33933,11 +33255,6 @@
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc="
},
- "os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
- },
"p-each-series": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz",
@@ -33977,42 +33294,6 @@
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
},
- "package-json": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz",
- "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=",
- "requires": {
- "got": "^5.0.0",
- "registry-auth-token": "^3.0.1",
- "registry-url": "^3.0.3",
- "semver": "^5.1.0"
- },
- "dependencies": {
- "semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
- }
- }
- },
- "package-json-path": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/package-json-path/-/package-json-path-1.0.9.tgz",
- "integrity": "sha512-uNu7f6Ef7tQHZRnkyVnCtzdSYVN9uBtge/sG7wzcUaawFWkPYUq67iXxRGrQSg/q0tzxIB8jSyIYUKjG2Jn//A==",
- "requires": {
- "abs": "^1.2.1"
- }
- },
- "package.json": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/package.json/-/package.json-2.0.1.tgz",
- "integrity": "sha1-+IYFnSpJ7QduZIg2ldc7K0bSHW0=",
- "requires": {
- "git-package-json": "^1.4.0",
- "git-source": "^1.1.0",
- "package-json": "^2.3.1"
- }
- },
"pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -34068,15 +33349,6 @@
"lines-and-columns": "^1.1.6"
}
},
- "parse-url": {
- "version": "1.3.11",
- "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-1.3.11.tgz",
- "integrity": "sha1-V8FUKKuKiSsfQ4aWRccR0OFEtVQ=",
- "requires": {
- "is-ssh": "^1.3.0",
- "protocols": "^1.4.0"
- }
- },
"parse5": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
@@ -35399,9 +34671,9 @@
}
},
"pretty-quick": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.1.tgz",
- "integrity": "sha512-ZYLGiMoV2jcaas3vTJrLvKAYsxDoXQBUn8OSTxkl67Fyov9lyXivJTl0+2WVh+y6EovGcw7Lm5ThYpH+Sh3XxQ==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.2.tgz",
+ "integrity": "sha512-T+fpTJrDjTzewql4p3lKrRA7z3MrNyjBK1MKeaBm5PpKwATgVm885TpY7TgY8KFt5Q1Qn3QDseRQcyX9AKTKkA==",
"dev": true,
"requires": {
"chalk": "^3.0.0",
@@ -35517,11 +34789,6 @@
"warning": "^4.0.0"
}
},
- "protocols": {
- "version": "1.4.8",
- "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz",
- "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg=="
- },
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -35635,20 +34902,6 @@
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
},
- "r-json": {
- "version": "1.2.10",
- "resolved": "https://registry.npmjs.org/r-json/-/r-json-1.2.10.tgz",
- "integrity": "sha512-hu9vyLjSlHXT62NAS7DjI9WazDlvjN0lgp3n431dCVnirVcLkZIpzSwA3orhZEKzdDD2jqNYI+w0yG0aFf4kpA=="
- },
- "r-package-json": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/r-package-json/-/r-package-json-1.0.9.tgz",
- "integrity": "sha512-G4Vpf1KImWmmPFGdtWQTU0L9zk0SjqEC4qs/jE7AQ+Ylmr5kizMzGeC4wnHp5+ijPqNN+2ZPpvyjVNdN1CDVcg==",
- "requires": {
- "package-json-path": "^1.0.0",
- "r-json": "^1.2.1"
- }
- },
"raf": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
@@ -35697,24 +34950,6 @@
}
}
},
- "rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "requires": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "dependencies": {
- "strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
- }
- }
- },
"rc-align": {
"version": "4.0.9",
"resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.9.tgz",
@@ -36320,15 +35555,6 @@
"prop-types": "^15.6.2"
}
},
- "read-all-stream": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz",
- "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=",
- "requires": {
- "pinkie-promise": "^2.0.0",
- "readable-stream": "^2.0.0"
- }
- },
"read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -36584,23 +35810,6 @@
"unicode-match-property-value-ecmascript": "^1.2.0"
}
},
- "registry-auth-token": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
- "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
- "requires": {
- "rc": "^1.1.6",
- "safe-buffer": "^5.0.1"
- }
- },
- "registry-url": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
- "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
- "requires": {
- "rc": "^1.0.1"
- }
- },
"regjsgen": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
@@ -37398,11 +36607,6 @@
"is-fullwidth-code-point": "^3.0.0"
}
},
- "sliced": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
- "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
- },
"snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -38515,11 +37719,6 @@
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
},
- "timed-out": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz",
- "integrity": "sha1-84sK6B03R9YoAB9B2vxlKs5nHAo="
- },
"timers-browserify": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
@@ -38543,14 +37742,6 @@
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
},
- "tmp": {
- "version": "0.0.28",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz",
- "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=",
- "requires": {
- "os-tmpdir": "~1.0.1"
- }
- },
"tmpl": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
@@ -38736,23 +37927,6 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz",
"integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA=="
},
- "typpy": {
- "version": "2.3.13",
- "resolved": "https://registry.npmjs.org/typpy/-/typpy-2.3.13.tgz",
- "integrity": "sha512-vOxIcQz9sxHi+rT09SJ5aDgVgrPppQjwnnayTrMye1ODaU8gIZTDM19t9TxmEElbMihx2Nq/0/b/MtyKfayRqA==",
- "requires": {
- "function.name": "^1.0.3"
- }
- },
- "ul": {
- "version": "5.2.15",
- "resolved": "https://registry.npmjs.org/ul/-/ul-5.2.15.tgz",
- "integrity": "sha512-svLEUy8xSCip5IWnsRa0UOg+2zP0Wsj4qlbjTmX6GJSmvKMHADBuHOm1dpNkWqWPIGuVSqzUkV3Cris5JrlTRQ==",
- "requires": {
- "deffy": "^2.2.2",
- "typpy": "^2.3.4"
- }
- },
"unbox-primitive": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
@@ -38907,11 +38081,6 @@
}
}
},
- "unzip-response": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz",
- "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4="
- },
"upath": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
@@ -38982,14 +38151,6 @@
"requires-port": "^1.0.0"
}
},
- "url-parse-lax": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
- "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
- "requires": {
- "prepend-http": "^1.0.1"
- }
- },
"use": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 0ebd83d4a..4ec88d834 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -25,7 +25,6 @@
"bootstrap": "^4",
"lodash": "^4",
"moment": "^2.29.1",
- "package.json": "^2.0.1",
"rc-slider": "^9.7",
"react": "^17",
"react-bootstrap": "^1",
diff --git a/frontend/src/Settings/Providers/list.ts b/frontend/src/Settings/Providers/list.ts
index dc076eb1c..c5defab07 100644
--- a/frontend/src/Settings/Providers/list.ts
+++ b/frontend/src/Settings/Providers/list.ts
@@ -47,6 +47,17 @@ export const ProviderList: Readonly<ProviderInfo[]> = [
name: "BSplayer",
},
{
+ key: "embeddedsubtitles",
+ name: "Embedded Subtitles",
+ description: "Embedded Subtitles from your Media Files",
+ defaultKey: {
+ include_ass: true,
+ },
+ keyNameOverride: {
+ include_ass: "Convert embedded ASS to SRT",
+ },
+ },
+ {
key: "greeksubs",
name: "GreekSubs",
description: "Greek Subtitles Provider",
diff --git a/libs/fese/__init__.py b/libs/fese/__init__.py
new file mode 100755
index 000000000..b1024b8ff
--- /dev/null
+++ b/libs/fese/__init__.py
@@ -0,0 +1,401 @@
+# -*- coding: utf-8 -*-
+# License: GPL
+
+from __future__ import annotations
+
+import json
+import logging
+import os
+import re
+import subprocess
+from typing import List, Optional
+
+from babelfish import Language
+from babelfish.exceptions import LanguageError
+import pysubs2
+
+__version__ = "0.1.0"
+
+logger = logging.getLogger(__name__)
+
+# Paths to executables
+FFPROBE_PATH = os.environ.get("FFPROBE_PATH", "ffprobe")
+FFMPEG_PATH = os.environ.get("FFMPEG_PATH", "ffmpeg")
+
+FFMPEG_STATS = True
+FF_LOG_LEVEL = "quiet"
+
+
+class FeseError(Exception):
+ pass
+
+
+class ExtractionError(FeseError):
+ pass
+
+
+class InvalidFile(FeseError):
+ pass
+
+
+class InvalidStream(FeseError):
+ pass
+
+
+class InvalidSource(FeseError):
+ pass
+
+
+class ConversionError(FeseError):
+ pass
+
+
+class LanguageNotFound(FeseError):
+ pass
+
+
+# Extensions
+
+SRT = "srt"
+ASS = "ass"
+
+
+class FFprobeSubtitleDisposition:
+ def __init__(self, data: dict):
+ self.default = False
+ self.generic = False
+ self.dub = False
+ self.original = False
+ self.comment = False
+ self.lyrics = False
+ self.karaoke = False
+ self.forced = False
+ self.hearing_impaired = False
+ self.visual_impaired = False
+ self.clean_effects = False
+ self.attached_pic = False
+ self.timed_thumbnails = False
+ self._content_type = None
+
+ for key, val in data.items():
+ if hasattr(self, key):
+ setattr(self, key, bool(val))
+
+ def update_from_tags(self, tags):
+ tag_title = tags.get("title")
+ if tag_title is None:
+ logger.debug("Title not found. Marking as generic")
+ self.generic = True
+ return None
+
+ l_tag_title = tag_title.lower()
+
+ for key, val in _content_types.items():
+ if val.search(l_tag_title) is not None:
+ logger.debug("Found %s: %s", key, l_tag_title)
+ self._content_type = key
+ setattr(self, key, True)
+ return None
+
+ logger.debug("Generic disposition title found: %s", l_tag_title)
+ self.generic = True
+ return None
+
+ @property
+ def suffix(self):
+ if self._content_type is not None:
+ return f"-{self._content_type}"
+
+ return ""
+
+ def __str__(self):
+ return self.suffix.lstrip("-").upper() or "GENERIC"
+
+
+class FFprobeSubtitleStream:
+ """Base class for FFprobe (FFmpeg) extractable subtitle streams."""
+
+ def __init__(self, stream: dict):
+ """
+ :raises: LanguageNotFound
+ """
+ self.index = int(stream.get("index", 0))
+ self.codec_name = stream.get("codec_name", "Unknown")
+ self.extension = _subtitle_extensions.get(self.codec_name, self.codec_name)
+ self.r_frame_rate = stream.get("r_frame_rate")
+ self.avg_frame_rate = stream.get("avg_frame_rate")
+ self.time_base = stream.get("time_base")
+ self.tags = stream.get("tags", {})
+ self.duration = float(stream.get("duration", 0))
+ self.start_time = float(stream.get("start_time", 0))
+ self.duration_ts = int(stream.get("duration_ts", 0))
+ self.start_pts = int(stream.get("start_pts", 0))
+
+ self.disposition = FFprobeSubtitleDisposition(stream.get("disposition", {}))
+
+ if self.tags:
+ self.disposition.update_from_tags(self.tags)
+
+ self.language: Language = self._language()
+
+ @property
+ def suffix(self):
+ lang = self.language.alpha2
+ if self.language.country is not None:
+ lang = f"{lang}-{self.language.country}"
+
+ return f"{lang}{self.disposition.suffix}.{self.extension}"
+
+ def _language(self) -> Language:
+ og_lang = self.tags.get("language")
+
+ if og_lang is not None:
+ if og_lang in _extra_languages:
+ extra = _extra_languages[og_lang]
+ title = self.tags.get("title", "n/a").lower()
+ if any(possible in title for possible in extra["matches"]):
+ logger.debug("Found extra language %s", extra["language_args"])
+ return Language(*extra["language_args"])
+
+ try:
+ return Language.fromalpha3b(og_lang)
+ except LanguageError as error:
+ logger.debug("Error with '%s' language: %s", og_lang, error)
+
+ raise LanguageNotFound(f"Couldn't detect language for stream: {self.tags}")
+
+ def __repr__(self) -> str:
+ return f"<{self.codec_name.upper()}: {self.language}@{self.disposition}>"
+
+
+# Helpers
+
+
+class FFprobeVideoContainer:
+ def __init__(self, path: str):
+ self.path = path
+
+ @property
+ def extension(self):
+ return os.path.splitext(self.path)[-1].lstrip(".")
+
+ def get_subtitles(self, timeout: int = 600) -> List[FFprobeSubtitleStream]:
+ """Factory function to create subtitle instances from FFprobe.
+
+ :param timeout: subprocess timeout in seconds (default: 600)
+ :raises: InvalidSource"""
+
+ ff_command = [
+ FFPROBE_PATH,
+ "-v",
+ FF_LOG_LEVEL,
+ "-print_format",
+ "json",
+ "-show_format",
+ "-show_streams",
+ self.path,
+ ]
+ try:
+ result = subprocess.run(
+ ff_command, stdout=subprocess.PIPE, check=True, timeout=timeout
+ )
+ streams = json.loads(result.stdout)["streams"]
+ except _ffprobe_exceptions as error:
+ raise InvalidSource(
+ f"{error} trying to get information from {self.path}"
+ ) from error # We want to see the traceback
+
+ subs = []
+ for stream in streams:
+ if stream.get("codec_type", "n/a") != "subtitle":
+ continue
+ try:
+ subs.append(FFprobeSubtitleStream(stream))
+ except LanguageNotFound:
+ pass
+
+ if not subs:
+ logger.debug("Source doesn't have any subtitle valid streams")
+ return []
+
+ logger.debug("Found subtitle streams: %s", subs)
+ return subs
+
+ def extract_subtitles(
+ self,
+ subtitles: List[FFprobeSubtitleStream],
+ custom_dir=None,
+ overwrite=True,
+ timeout=600,
+ ):
+ """Extracts a list of subtitles. Returns a dictionary of the extracted
+ filenames by index.
+
+ :param subtitles: a list of FFprobeSubtitle instances
+ :param custom_dir: a custom directory to save the subtitles. Defaults to
+ same directory as the media file
+ :param overwrite: overwrite files with the same name (default: True)
+ :param timeout: subprocess timeout in seconds (default: 600)
+ :raises: ExtractionError, OSError
+ """
+ extract_command = [FFMPEG_PATH, "-v", FF_LOG_LEVEL]
+ if FFMPEG_STATS:
+ extract_command.append("-stats")
+ extract_command.extend(["-y", "-i", self.path])
+
+ if custom_dir is not None:
+ # May raise OSError
+ os.makedirs(custom_dir, exist_ok=True)
+
+ items = {}
+ collected_paths = set()
+
+ for subtitle in subtitles:
+ sub_path = f"{os.path.splitext(self.path)[0]}.{subtitle.suffix}"
+ if custom_dir is not None:
+ sub_path = os.path.join(custom_dir, os.path.basename(sub_path))
+
+ if sub_path in collected_paths:
+ sub_path = (
+ f"{sub_path.rstrip(f'.{subtitle.suffix}')}"
+ f"-{len(collected_paths)}.{subtitle.suffix}"
+ )
+
+ if not overwrite and os.path.isfile(sub_path):
+ logger.debug("Ignoring path (OVERWRITE TRUE): %s", sub_path)
+ continue
+
+ extract_command.extend(
+ ["-map", f"0:{subtitle.index}", "-c", "copy", sub_path]
+ )
+ logger.debug("Appending subtitle path: %s", sub_path)
+
+ collected_paths.add(sub_path)
+
+ items[subtitle.index] = sub_path
+
+ if not items:
+ logger.debug("No subtitles to extract")
+ return {}
+
+ logger.debug("Extracting subtitle with command %s", " ".join(extract_command))
+
+ try:
+ subprocess.run(extract_command, timeout=timeout, check=True)
+ except (subprocess.SubprocessError, FileNotFoundError) as error:
+ raise ExtractionError(f"Error calling ffmpeg: {error}") from error
+
+ for path in items.values():
+ if not os.path.isfile(path):
+ logger.debug("%s was not extracted", path)
+
+ return items
+
+ def __repr__(self) -> str:
+ return f"<FFprobeVideoContainer {self.extension}: {self.path}>"
+
+
+def check_integrity(
+ subtitle: FFprobeSubtitleStream, path: str, sec_offset_threshold=900
+):
+ """A relative check for the integriy of a file. This can be used to find a failed
+ ffmpeg extraction where the final file might not be complete or might be corrupted.
+ Currently, only ASS and Subrip are supported.
+
+ :param subtitle: FFprobeSubtitle instance
+ :param path: the path of the subtitle file (ass or srt)
+ :param sec_offset_threshold: the maximum seconds offset to determine if the file is complete
+ :raises: InvalidFile
+ """
+ if subtitle.extension not in (ASS, SRT):
+ raise InvalidFile(f"Extension not supported: {subtitle.extension}")
+
+ try:
+ sub = pysubs2.load(path)
+ except (pysubs2.Pysubs2Error, UnicodeError, OSError, FileNotFoundError) as error:
+ raise InvalidFile(error) from error
+ else:
+ off = abs(int(sub[-1].end) - subtitle.duration_ts)
+ if off > abs(sec_offset_threshold) * 1000:
+ raise InvalidFile(
+ f"The last subtitle timestamp ({sub[-1].end/1000} sec) is {off/1000} sec ahead"
+ f" from the subtitle stream total duration ({subtitle.duration} sec)"
+ )
+
+ logger.debug("Integrity check passed (%d sec offset)", off / 1000)
+
+
+def to_srt(
+ source: str, output: Optional[str] = None, remove_source: bool = False
+) -> str:
+ """Convert a subtitle to SubRip. Currently, only ASS is supported. SubRip
+ files will be silently ignored.
+
+ raises: ConversionError, OSError"""
+ if source.endswith(".srt"):
+ return source
+
+ split_path = os.path.splitext(source)
+
+ if split_path[-1] not in (".ass"):
+ raise ConversionError(
+ f"No converter found for extension: {split_path[-1]}"
+ ) from None
+
+ output = output or f"{split_path[0]}.srt"
+
+ try:
+ parsed = pysubs2.load(source)
+ parsed.save(output)
+ except (pysubs2.Pysubs2Error, UnicodeError) as error:
+ raise ConversionError(f"Exception converting {output}: {error}") from error
+
+ logger.debug("Converted: %s", output)
+
+ if remove_source and source != output:
+ try:
+ os.remove(source)
+ except OSError as error:
+ logger.debug("Can't remove source: %s (%s)", source, error)
+
+ return output
+
+
+_subtitle_extensions = {"subrip": "srt", "ass": "ass"}
+
+
+_content_types = {
+ "hearing_impaired": re.compile(r"sdh|hearing impaired"),
+ "forced": re.compile(r"forced"),
+ "comment": re.compile(r"comment"),
+ "visual_impaired": re.compile(r"signs|visual impair"),
+ "karaoke": re.compile(r"karaoke|songs"),
+}
+
+
+_ffprobe_exceptions = (
+ subprocess.SubprocessError,
+ json.JSONDecodeError,
+ FileNotFoundError,
+ KeyError,
+)
+
+_extra_languages = {
+ "spa": {
+ "matches": (
+ "es-la",
+ "spa-la",
+ "spl",
+ "mx",
+ "latin",
+ "mexic",
+ "argent",
+ "latam",
+ ),
+ "language_args": ("spa", "MX"),
+ },
+ "por": {
+ "matches": ("pt-br", "pob", "pb", "brazilian", "brasil", "brazil"),
+ "language_args": ("por", "BR"),
+ },
+}
diff --git a/libs/subliminal/subtitle.py b/libs/subliminal/subtitle.py
index 792df1a1c..2f30f43da 100644
--- a/libs/subliminal/subtitle.py
+++ b/libs/subliminal/subtitle.py
@@ -50,6 +50,8 @@ class Subtitle(object):
#: Encoding to decode with when accessing :attr:`text`
self.encoding = None
+ self.release_info = None
+
# validate the encoding
if encoding:
try:
diff --git a/libs/subliminal_patch/core.py b/libs/subliminal_patch/core.py
index aa82db1f9..f4605b1eb 100644
--- a/libs/subliminal_patch/core.py
+++ b/libs/subliminal_patch/core.py
@@ -187,16 +187,15 @@ class SZProviderPool(ProviderPool):
if (str(provider), str(s.id)) in self.blacklist:
logger.info("Skipping blacklisted subtitle: %s", s)
continue
- if hasattr(s, 'release_info'):
- if s.release_info is not None:
- if any([x for x in self.ban_list["must_not_contain"]
- if re.search(x, s.release_info, flags=re.IGNORECASE) is not None]):
- logger.info("Skipping subtitle because release name contains prohibited string: %s", s)
- continue
- if any([x for x in self.ban_list["must_contain"]
- if re.search(x, s.release_info, flags=re.IGNORECASE) is None]):
- logger.info("Skipping subtitle because release name does not contains required string: %s", s)
- continue
+ if s.release_info is not None:
+ if any([x for x in self.ban_list["must_not_contain"]
+ if re.search(x, s.release_info, flags=re.IGNORECASE) is not None]):
+ logger.info("Skipping subtitle because release name contains prohibited string: %s", s)
+ continue
+ if any([x for x in self.ban_list["must_contain"]
+ if re.search(x, s.release_info, flags=re.IGNORECASE) is None]):
+ logger.info("Skipping subtitle because release name does not contains required string: %s", s)
+ continue
if s.id in seen:
continue
s.plex_media_fps = float(video.fps) if video.fps else None
diff --git a/libs/subliminal_patch/providers/embeddedsubtitles.py b/libs/subliminal_patch/providers/embeddedsubtitles.py
new file mode 100644
index 000000000..bf89340c5
--- /dev/null
+++ b/libs/subliminal_patch/providers/embeddedsubtitles.py
@@ -0,0 +1,162 @@
+# -*- coding: utf-8 -*-
+
+import logging
+import os
+import shutil
+import tempfile
+
+from babelfish import language_converters
+import fese
+from fese import check_integrity
+from fese import FFprobeSubtitleStream
+from fese import FFprobeVideoContainer
+from fese import to_srt
+from subliminal.subtitle import fix_line_ending
+from subliminal_patch.core import Episode
+from subliminal_patch.core import Movie
+from subliminal_patch.providers import Provider
+from subliminal_patch.subtitle import Subtitle
+from subzero.language import Language
+
+logger = logging.getLogger(__name__)
+
+# Replace Babelfish's Language with Subzero's Language
+fese.Language = Language
+
+
+class EmbeddedSubtitle(Subtitle):
+ provider_name = "embeddedsubtitles"
+ hash_verifiable = False
+
+ def __init__(self, stream, container, matches):
+ super().__init__(stream.language, stream.disposition.hearing_impaired)
+ self.stream: FFprobeSubtitleStream = stream
+ self.container: FFprobeVideoContainer = container
+ self._matches: set = matches
+ self.page_link = self.container.path
+ self.release_info = os.path.basename(self.page_link)
+
+ def get_matches(self, video):
+ if self.hearing_impaired:
+ self._matches.add("hearing_impaired")
+
+ self._matches.add("hash")
+ return self._matches
+
+ @property
+ def id(self):
+ return f"{self.container.path}_{self.stream.index}"
+
+
+class EmbeddedSubtitlesProvider(Provider):
+ provider_name = "embeddedsubtitles"
+
+ languages = {Language("por", "BR"), Language("spa", "MX")} | {
+ Language.fromalpha2(l) for l in language_converters["alpha2"].codes
+ }
+ languages.update(set(Language.rebuild(lang, hi=True) for lang in languages))
+
+ # TODO: add forced support
+ # languages.update(set(Language.rebuild(lang, forced=True) for lang in languages))
+
+ video_types = (Episode, Movie)
+ subtitle_class = EmbeddedSubtitle
+
+ def __init__(
+ self, include_ass=True, cache_dir=None, ffprobe_path=None, ffmpeg_path=None
+ ):
+ self._include_ass = include_ass
+ self._cache_dir = os.path.join(
+ cache_dir or tempfile.gettempdir(), self.__class__.__name__.lower()
+ )
+ self._cached_paths = {}
+
+ fese.FFPROBE_PATH = ffprobe_path or fese.FFPROBE_PATH
+ fese.FFMPEG_PATH = ffmpeg_path or fese.FFMPEG_PATH
+
+ if logger.getEffectiveLevel() == logging.DEBUG:
+ fese.FF_LOG_LEVEL = "warning"
+ else:
+ # Default is True
+ fese.FFMPEG_STATS = False
+
+ def initialize(self):
+ os.makedirs(self._cache_dir, exist_ok=True)
+
+ def terminate(self):
+ # Remove leftovers
+ shutil.rmtree(self._cache_dir, ignore_errors=True)
+
+ def query(self, path: str, languages):
+ video = FFprobeVideoContainer(path)
+
+ try:
+ streams = video.get_subtitles()
+ except fese.InvalidSource as error:
+ logger.error("Error trying to get subtitles for %s: %s", video, error)
+ streams = []
+
+ if not streams:
+ logger.debug("No subtitles found for container: %s", video)
+
+ subtitles = []
+
+ for stream in streams:
+ # Only subrip and ass are currently supported
+ if stream.codec_name not in ("subrip", "ass"):
+ logger.debug("Ignoring codec: %s", stream)
+ continue
+
+ if not self._include_ass and stream.codec_name == "ass":
+ logger.debug("Ignoring ASS subtitle: %s", stream)
+ continue
+
+ if stream.language not in languages:
+ continue
+
+ disposition = stream.disposition
+ if disposition.generic or disposition.hearing_impaired:
+ logger.debug("Appending subtitle: %s", stream)
+ subtitles.append(EmbeddedSubtitle(stream, video, {"hash"}))
+ else:
+ logger.debug("Ignoring unwanted subtitle: %s", stream)
+
+ return subtitles
+
+ def list_subtitles(self, video, languages):
+ return self.query(video.name, languages)
+
+ def download_subtitle(self, subtitle):
+ path = self._get_subtitle_path(subtitle)
+ with open(path, "rb") as sub:
+ content = sub.read()
+ subtitle.content = fix_line_ending(content)
+
+ def _get_subtitle_path(self, subtitle: EmbeddedSubtitle):
+ container = subtitle.container
+
+ # Check if the container is not already in the instance
+ if container.path not in self._cached_paths:
+ # Extract all subittle streams to avoid reading the entire
+ # container over and over
+ streams = filter(_check_allowed_extensions, container.get_subtitles())
+ extracted = container.extract_subtitles(list(streams), self._cache_dir)
+ # Add the extracted paths to the containter path key
+ self._cached_paths[container.path] = extracted
+
+ cached_path = self._cached_paths[container.path]
+ # Get the subtitle file by index
+ subtitle_path = cached_path[subtitle.stream.index]
+
+ check_integrity(subtitle.stream, subtitle_path)
+
+ # Convert to SRT if the subtitle is ASS
+ new_subtitle_path = to_srt(subtitle_path, remove_source=True)
+ if new_subtitle_path != subtitle_path:
+ cached_path[subtitle.stream.index] = new_subtitle_path
+
+ return new_subtitle_path
+
+
+def _check_allowed_extensions(subtitle: FFprobeSubtitleStream):
+ return subtitle.extension in ("ass", "srt")
diff --git a/tests/subliminal_patch/data/file_1.mkv b/tests/subliminal_patch/data/file_1.mkv
new file mode 100644
index 000000000..61112e0c2
--- /dev/null
+++ b/tests/subliminal_patch/data/file_1.mkv
Binary files differ
diff --git a/tests/subliminal_patch/data/file_2.mkv b/tests/subliminal_patch/data/file_2.mkv
new file mode 100644
index 000000000..eefabffe9
--- /dev/null
+++ b/tests/subliminal_patch/data/file_2.mkv
Binary files differ
diff --git a/tests/subliminal_patch/test_embeddedsubtitles.py b/tests/subliminal_patch/test_embeddedsubtitles.py
new file mode 100644
index 000000000..59ffaf0f2
--- /dev/null
+++ b/tests/subliminal_patch/test_embeddedsubtitles.py
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*-
+import os
+
+import fese
+import pytest
+from subliminal_patch.core import Episode, Movie
+from subliminal_patch.providers.embeddedsubtitles import EmbeddedSubtitlesProvider
+from subzero.language import Language
+
+_DATA = os.path.join(os.path.abspath(os.path.dirname(__file__)), "data")
+
+
+fese.Language = Language
+
+
+def video_single_language():
+ # Has only ASS streams in english
+ return Episode(
+ os.path.join(_DATA, "file_1.mkv"),
+ "Serial Experiments Lain",
+ 1,
+ 1,
+ source="Web",
+ )
+
+
+def video_multiple_languages():
+ # Has SubRip streams in multiple languages
+ return Movie(
+ os.path.join(_DATA, "file_2.mkv"),
+ "I'm No Longer Here",
+ year=2019,
+ source="Web",
+ )
+
+
+def video_inexistent(tmpdir):
+ return Movie(
+ os.path.join(tmpdir, "inexistent_video.mkv"),
+ "Dummy",
+ year=2021,
+ source="Web",
+ )
+
+
+def test_inexistent_video(video_inexistent):
+ with EmbeddedSubtitlesProvider() as provider:
+ subtitles = provider.list_subtitles(video_inexistent, {})
+ assert len(subtitles) == 0
+
+
+def test_list_subtitles_single_language(video_single_language):
+ with EmbeddedSubtitlesProvider() as provider:
+ subs = provider.list_subtitles(
+ video_single_language, {Language.fromalpha2("en")}
+ )
+
+ for sub in subs:
+ assert sub.language == Language.fromalpha2("en")
+
+
+def test_list_subtitles_multiple_languages(video_multiple_languages):
+ with EmbeddedSubtitlesProvider() as provider:
+ languages = {Language.fromalpha2(code) for code in ("en", "it", "fr", "es")} | {
+ Language("por", "BR")
+ }
+
+ subs = provider.list_subtitles(video_multiple_languages, languages)
+ for expected in languages:
+ assert any(sub.language == expected for sub in subs)
+
+
+def test_list_subtitles_wo_ass(video_single_language):
+ with EmbeddedSubtitlesProvider(include_ass=False) as provider:
+ subs = provider.list_subtitles(
+ video_single_language, {Language.fromalpha2("en")}
+ )
+ assert not subs
+
+
+def test_download_subtitle_multiple(video_multiple_languages):
+ with EmbeddedSubtitlesProvider() as provider:
+ languages = {Language.fromalpha2(code) for code in ("en", "it", "fr")} | {
+ Language("por", "BR")
+ }
+
+ subs = provider.list_subtitles(video_multiple_languages, languages)
+ for sub in subs:
+ provider.download_subtitle(sub)
+ assert sub.content is not None
+
+
+def test_download_subtitle_single(video_single_language):
+ with EmbeddedSubtitlesProvider() as provider:
+ subtitle = provider.list_subtitles(
+ video_single_language, {Language.fromalpha2("en")}
+ )[0]
+ provider.download_subtitle(subtitle)
+ assert subtitle.content is not None
+
+
+def test_download_invalid_subtitle(video_single_language):
+ with EmbeddedSubtitlesProvider() as provider:
+ subtitle = provider.list_subtitles(
+ video_single_language, {Language.fromalpha2("en")}
+ )[0]
+
+ provider._cached_paths[subtitle.container.path] = {
+ subtitle.stream.index: "dummy.srt"
+ }
+ with pytest.raises(fese.InvalidFile):
+ provider.download_subtitle(subtitle)