Compare commits
250 Commits
2.5.3.2414
...
2.5.7.2663
| Author | SHA1 | Date | |
|---|---|---|---|
| 6d444ebe99 | |||
| 237eafed35 | |||
| fbc5069fb8 | |||
| d23c44589e | |||
| 42cc500b05 | |||
| 81760192dc | |||
| 2cb077423d | |||
| de8aaaa5e5 | |||
| b9ebd4e1d6 | |||
| 8fdf1e841c | |||
| 9df92d0262 | |||
| a07d5aa440 | |||
| 54bd222605 | |||
| 6487258136 | |||
| d1935a4439 | |||
| 026c30642e | |||
| 036d036a61 | |||
| 2092d44627 | |||
| c6e7e64ba3 | |||
| a8f5ad6435 | |||
| afa0c3a1b0 | |||
| b3132d57b2 | |||
| 0a2a6b558f | |||
| adb9926928 | |||
| 3ce25007b5 | |||
| 5690ada2a7 | |||
| 76481186e9 | |||
| 8d2d2341c8 | |||
| 4e20d282f7 | |||
| edc3ce1ba4 | |||
| b9249ff09a | |||
| c3b2ffa97d | |||
| 4e3b8ee3c2 | |||
| a749ed4837 | |||
| 67ba6be6e2 | |||
| 7a47e6617d | |||
| 4a4c6e7df2 | |||
| 5661528862 | |||
| 696e9d6b64 | |||
| c0aa465827 | |||
| a6120ae27a | |||
| ba8a165aa5 | |||
| 833d7072ed | |||
| 9829137001 | |||
| c686214f56 | |||
| 2252d7ea6a | |||
| e7fbfca2d7 | |||
| 9ca959a20a | |||
| bd8e26ecab | |||
| 451b34dceb | |||
| 02761db660 | |||
| 42b7e9fa62 | |||
| edf6c25e17 | |||
| e91aac65cc | |||
| 01d5a18af8 | |||
| 70c1142f8d | |||
| 8b6b162073 | |||
| 5199fbe0cb | |||
| 924de62dff | |||
| 4cba7d8684 | |||
| f3f9ab1360 | |||
| 682d1d85ce | |||
| a1cc9a2049 | |||
| a7f7b3e572 | |||
| 7c32a7c2c8 | |||
| e842579f25 | |||
| bdd9134a0e | |||
| a01552e88c | |||
| 824957ae85 | |||
| af335d5565 | |||
| 2f9eb51868 | |||
| aebbc17643 | |||
| 84e78e1e20 | |||
| 89bb747ee3 | |||
| 62e37dbd09 | |||
| edef9cb936 | |||
| 3ae02c3050 | |||
| a4016616a1 | |||
| b4855611c4 | |||
| 1b44f6d220 | |||
| b0f0af087b | |||
| 1344f7255d | |||
| 39fe3b0fd6 | |||
| 0ba676b5e7 | |||
| 4d6897c138 | |||
| c7c6ba09e9 | |||
| c06baa67f1 | |||
| cdb7946c00 | |||
| bdb5da8df0 | |||
| e961c8d3aa | |||
| 3eb1a9eef8 | |||
| 67aead8fcc | |||
| fd764d0576 | |||
| dad55d7922 | |||
| fb32772512 | |||
| 918ce65acd | |||
| 9f03b9ee71 | |||
| 2235de1a2d | |||
| 8804c89f04 | |||
| 2e8805015c | |||
| f435ca2961 | |||
| 71c3761b20 | |||
| e4c441043a | |||
| 8a655a5d6e | |||
| 777c21ce87 | |||
| e22ff09691 | |||
| d0f685e87c | |||
| 8f71c417a9 | |||
| b62977c494 | |||
| 8d11136c1c | |||
| 4a7ea43095 | |||
| 8fe4bd2751 | |||
| 38bb819a24 | |||
| dbe75ad18d | |||
| 760441b45a | |||
| 56645b601b | |||
| 885e4bc99f | |||
| b04e5510fd | |||
| 806000725b | |||
| 71270641d3 | |||
| bf4f2bec91 | |||
| dafad3a7a3 | |||
| 182a1cc3fb | |||
| 4b7664aaa6 | |||
| 2050aef1e5 | |||
| 390af30bf6 | |||
| 698f48b1fd | |||
| 2e5cc61ac6 | |||
| 8d97fb7633 | |||
| 8a41c393bb | |||
| 6ae38359d7 | |||
| 7ddd1e3497 | |||
| 20a0993aa8 | |||
| 57d58056de | |||
| 06c6fa4d01 | |||
| 41f884e129 | |||
| 77a74c8839 | |||
| c198788017 | |||
| 4cbfa21b52 | |||
| f3754de394 | |||
| d47ad013cd | |||
| 8c4372d0d3 | |||
| 1c7b9145c8 | |||
| c477f53ee6 | |||
| f99f03dc33 | |||
| 2ddd786819 | |||
| 6e604f98e3 | |||
| 729404d05f | |||
| de50dfdb7c | |||
| 7bda522f0a | |||
| 6c39fb0649 | |||
| a7342ac77e | |||
| 5d45b8bbdd | |||
| aa0ff38ed7 | |||
| d55aa3b569 | |||
| d86a99fb32 | |||
| c687152724 | |||
| 65ec539875 | |||
| 6dba0792d2 | |||
| df78cecb31 | |||
| 3d8687f69d | |||
| 92196897a9 | |||
| 4206edfb13 | |||
| c08e63ab80 | |||
| 03646b4f87 | |||
| d9fa860b0c | |||
| 93d8494ddc | |||
| bd982958fa | |||
| e280b62f5c | |||
| 2bb050de40 | |||
| f3ed3bf0bf | |||
| 79457536f2 | |||
| 048f930da1 | |||
| 6aa8108fce | |||
| c234f75d7e | |||
| 064b634f77 | |||
| 8d83184cd1 | |||
| 7a5112bee5 | |||
| 0c549c6bda | |||
| c48e704502 | |||
| bec66895d9 | |||
| c9f1e8a8bb | |||
| ac209e7ee2 | |||
| 525256e15c | |||
| 3b8c965f4b | |||
| 8f8da8e6ea | |||
| ac9b81abea | |||
| 1c39c55423 | |||
| ca11273b37 | |||
| b532a60c3d | |||
| 941662e9f2 | |||
| 4d1e4c3ebe | |||
| f66fd9bcae | |||
| f5c5ecd1b9 | |||
| f9b7855d19 | |||
| 418a8af99a | |||
| ce3b4661de | |||
| 4b811f38b0 | |||
| bba2823065 | |||
| 5547e9658d | |||
| e14cbb19f5 | |||
| 0613a001c5 | |||
| 2970ba69f8 | |||
| 2c6b811d4d | |||
| d5a3caf961 | |||
| 7e64778546 | |||
| 1afd0d7c28 | |||
| 3027a3c3e8 | |||
| 3d7df100ff | |||
| 4de5030196 | |||
| e3bfe368db | |||
| e45fe0aaa0 | |||
| 807d758bfa | |||
| 7c5164b9a5 | |||
| 1e15fb8e43 | |||
| ae996b4b9a | |||
| 3259a7eec9 | |||
| 39a5aa1d63 | |||
| dbe378ad82 | |||
| a316c11974 | |||
| 2fd05c2464 | |||
| 8adabb946e | |||
| 3f251b9c0e | |||
| aadd60c3ad | |||
| 99cc994865 | |||
| da0355ca88 | |||
| aaa7c0934a | |||
| 03c70f4dfa | |||
| 0704609fa5 | |||
| d26569b26f | |||
| 007e93e526 | |||
| 8feec0284d | |||
| eaa79fb3bd | |||
| 3af5102e93 | |||
| d936460d83 | |||
| f51649c59f | |||
| be1e33b555 | |||
| 059645dec7 | |||
| 6439becd7d | |||
| 917fbc1ea2 | |||
| c97fee90b7 | |||
| 35d04946b4 | |||
| d0d71d626e | |||
| 5a1b39c67e | |||
| a8cbd37697 | |||
| b2bac94009 | |||
| d88b7e2a17 | |||
| 68bf35d83d | |||
| a78e6587ac | |||
| 21f715a321 |
@@ -1,4 +1,101 @@
|
||||
|
||||
2.5.4.2541
|
||||
|
||||
- core: try retrieving advanced_settings.json from the path given, which may be a file path or a directory
|
||||
- menu: ignore options: fix plugin not responding, fix unicode strings; resolve #509
|
||||
- providers: addic7ed: fix usage/adapt to new show search method
|
||||
- providers: opensubtitles: properly handle responses again, re-enable automatic throttling based on those (broken since XMLRPC handler rewrite)
|
||||
|
||||
|
||||
2.5.4.2527
|
||||
|
||||
- core: bugfixes
|
||||
- core: get_item: don't fail on socket timeout; fixes #498
|
||||
- core: fix scandir encoding errors; #453 #461 #441
|
||||
- core: clamp menu history to 25 items
|
||||
- add UnRAR for aarch64 (untested), arm (armv5tel, untested), linux/i386, MacOSX/i386; fixes #311
|
||||
- add 3rd party licenses
|
||||
- menu: new debounce/history mechanism; fixes the back button usage
|
||||
- config: add custom path option for advanced_settings.json
|
||||
- providers: opensubtitles: re-add support for throttling based on HTTP response codes, which got ditched due to new connection interface
|
||||
- providers: legendastv: disable if unrar wasn't found
|
||||
- providers: addic7ed: reduce show cache to 1 week
|
||||
- advanced settings: sonarr/radarr: make ssl verification optional
|
||||
- advanced settings: opensubtitles: add configurable connection timeout
|
||||
- refiners: drone: use certifi for HTTPS connections
|
||||
- tasks: SearchAllRecentlyAddedMissing: fix ZeroDivisionError in edgecases; fixes #496
|
||||
|
||||
|
||||
2.5.3.2452
|
||||
|
||||
- core: update certifi to 2018.01.18
|
||||
- core: metadata storage: only allow one subtitle per language
|
||||
- core: metadata storage: only parse latest metadata subtitle in localmedia
|
||||
- core: metadata storage: kill existing metadata subtitles explicitly upon storing a new one
|
||||
- core: metadata storage: fix selecting current subtitle from menu
|
||||
- providers: opensubtitles: use new requests based transport by default, finally fixes ResponseNotReady properly
|
||||
- providers: opensubtitles: mask token in logs
|
||||
- providers: don't check for hash validity if it isn't verifiable (fixes napiprojekt, #478)
|
||||
- submod: common: extend non_word_only matching
|
||||
- submod: common: reduce multi spaces to one
|
||||
- submod: OCR: fix III'll=I'll
|
||||
- advanced settings: add option to use HTTP instead of HTTPS for OpenSubtitles
|
||||
|
||||
|
||||
2.5.3.2422
|
||||
|
||||
- core: don't fail on embedded subtitle streams without language code set, fixes #473
|
||||
- providers: catch ResponseNotReady in list_subtitles_provider as well (partly fixes OpenSubtitles)
|
||||
- providers: don't use retry logic in case of ResponseNotReady
|
||||
- providers: addic7ed: use new search endpoint
|
||||
|
||||
|
||||
2.5.3.2414
|
||||
|
||||
- core: expand user agent list
|
||||
- core: update subliminal to 4ad5d31
|
||||
- core: treat 23.976, 23.98, 24.0 fps as equal
|
||||
- core: correctly skip blacklist entries when iterating through currently known subs
|
||||
- core: fix unpacking of packs without asked-for-release-group
|
||||
- core: fix embedded subtitle language detection; add debug log
|
||||
- core: treat embedded subtitle containing "forced" in its title as forced
|
||||
- core: improve embedded subtitles detection
|
||||
- core: store extracted embedded forced subtitles with the "forced" suffix (e.g.: video.en.forced.srt)
|
||||
- core: don't bother trying to extract embedded subtitle if transcoder wasn't found
|
||||
- core: fix automatic extraction of unknown embedded subtitle streams
|
||||
- core: skip immediately searching for new subtitle after successfully extracting embedded
|
||||
- core: extract embedded ASS: don't transcode to SRT using ffmpeg (Plex Transcoder), do the transcoding later using pysubs2; fixes offset issues
|
||||
- core: extract embedded: let ffmpeg auto convert mov_text/tx3g to srt
|
||||
- core: fix transcoder detection; add fallback #460
|
||||
- core: remove LD_LIBRARY_PATH from environment before calling notification executable
|
||||
- core: auto extract embedded subtitles in a separate thread
|
||||
- core: reduce encoding change log spam
|
||||
- core: only allow one automatic extraction at a time; add optional advanced settings "auto_extract_multithread"
|
||||
- core: add minimum score a subtitle has to have when considered by the find better subtitles task, when the current subtitle is an extracted embedded one; add advanced_settings entries
|
||||
- core/config: automatic extraction: add config setting to indicate whether there should be an immediate search for available subtitles after extraction or not (default: off)
|
||||
- core/menu/submod: add reverse_rtl modification for Hebrew; fixes #409
|
||||
- core: scoring: assume title match on tvdb_id match
|
||||
- tasks: search all recently added missing: fix attribute access on missing stored subtitle info
|
||||
- providers: add hosszupuska (hungarian, thanks morpheus133 for the basic implementation)
|
||||
- providers: add argenteam (spanish, thanks mmiraglia for the basic implementation)
|
||||
- providers: addic7ed: use random user agent by default (enforce for existing configs)
|
||||
- providers: enable subscene by default
|
||||
- providers: opensubtitles: add fallback for dict based query response in contrast to list/array based
|
||||
- advanced settings: make text-based-subtitle-formats configurable
|
||||
- menu: submod: inverse-reverse subtitle timing time-choices for better accessibility
|
||||
- submod: reduce log spam in case of debug logs enabled
|
||||
- submod: style tags could result in no output at all
|
||||
- submod: fix empty content if only non-line-mods were used, no line-mods; fixes #449
|
||||
- submod: HI: correctly handle style tags when checking for brackets
|
||||
- submod: HI: don't remove anything that's surrounded by quotes
|
||||
- submod: HI: double or triple dash is em dash
|
||||
- submod: HI: HI_before_colon_noncaps, don't assume single quotes are sentence enders
|
||||
- submod: common: don't uppercase after abbreviations
|
||||
- submod: common: don't break phone numbers (more than one spaced number pair found)
|
||||
- submod: common: also count lines only consisting of dots as removable
|
||||
- submod: common: replace more than 3 consecutive dots with 3 dots
|
||||
- submod: OCR: "H i." = "Hi."
|
||||
|
||||
|
||||
2.5.0.2287
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@ def Start():
|
||||
intent = get_intent()
|
||||
intent.cleanup()
|
||||
|
||||
#Locale.DefaultLocale = "de"
|
||||
|
||||
# clear expired menu history items
|
||||
now = datetime.datetime.now()
|
||||
if "menu_history" in Dict:
|
||||
|
||||
@@ -20,86 +20,98 @@ from support.lib import Plex
|
||||
from support.storage import reset_storage, log_storage, get_subtitle_storage
|
||||
from support.scheduler import scheduler
|
||||
from support.items import set_mods_for_part, get_item_kind_from_rating_key
|
||||
from support.i18n import _
|
||||
|
||||
|
||||
@route(PREFIX + '/advanced')
|
||||
def AdvancedMenu(randomize=None, header=None, message=None):
|
||||
oc = SubFolderObjectContainer(header=header or "Internal stuff, pay attention!", message=message, no_cache=True,
|
||||
no_history=True,
|
||||
replace_parent=False, title2="Advanced")
|
||||
oc = SubFolderObjectContainer(
|
||||
header=header or _("Internal stuff, pay attention!"),
|
||||
message=message,
|
||||
no_cache=True,
|
||||
no_history=True,
|
||||
replace_parent=False,
|
||||
title2=_("Advanced"))
|
||||
|
||||
if config.lock_advanced_menu and not config.pin_correct:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(PinMenu, randomize=timestamp(), success_go_to="advanced"),
|
||||
title=pad_title("Enter PIN"),
|
||||
summary="The owner has restricted the access to this menu. Please enter the correct pin",
|
||||
key=Callback(
|
||||
PinMenu,
|
||||
randomize=timestamp(),
|
||||
success_go_to=_("advanced")),
|
||||
title=pad_title(_("Enter PIN")),
|
||||
summary=_("The owner has restricted the access to this menu. Please enter the correct pin"),
|
||||
))
|
||||
return oc
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(TriggerRestart, randomize=timestamp()),
|
||||
title=pad_title("Restart the plugin"),
|
||||
title=pad_title(_("Restart the plugin")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(GetLogsLink),
|
||||
title="Get my logs (copy the appearing link and open it in your browser, please)",
|
||||
summary="Copy the appearing link and open it in your browser, please",
|
||||
title=_("Get my logs (copy the appearing link and open it in your browser, please)"),
|
||||
summary=_("Copy the appearing link and open it in your browser, please"),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(TriggerBetterSubtitles, randomize=timestamp()),
|
||||
title=pad_title("Trigger find better subtitles"),
|
||||
title=pad_title(_("Trigger find better subtitles")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SkipFindBetterSubtitles, randomize=timestamp()),
|
||||
title=pad_title("Skip next find better subtitles (sets last run to now)"),
|
||||
title=pad_title(_("Skip next find better subtitles (sets last run to now)")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(TriggerStorageMaintenance, randomize=timestamp()),
|
||||
title=pad_title("Trigger subtitle storage maintenance"),
|
||||
title=pad_title(_("Trigger subtitle storage maintenance")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(TriggerStorageMigration, randomize=timestamp()),
|
||||
title=pad_title("Trigger subtitle storage migration (expensive)"),
|
||||
title=pad_title(_("Trigger subtitle storage migration (expensive)")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(TriggerCacheMaintenance, randomize=timestamp()),
|
||||
title=pad_title("Trigger cache maintenance (refiners, providers and packs/archives)"),
|
||||
title=pad_title(_("Trigger cache maintenance (refiners, providers and packs/archives)")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ApplyDefaultMods, randomize=timestamp()),
|
||||
title=pad_title("Apply configured default subtitle mods to all (active) stored subtitles"),
|
||||
title=pad_title(_("Apply configured default subtitle mods to all (active) stored subtitles")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ReApplyMods, randomize=timestamp()),
|
||||
title=pad_title("Re-Apply mods of all stored subtitles"),
|
||||
title=pad_title(_("Re-Apply mods of all stored subtitles")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(LogStorage, key="tasks", randomize=timestamp()),
|
||||
title=pad_title("Log the plugin's scheduled tasks state storage"),
|
||||
title=pad_title(_("Log the plugin's scheduled tasks state storage")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(LogStorage, key="ignore", randomize=timestamp()),
|
||||
title=pad_title("Log the plugin's internal ignorelist storage"),
|
||||
title=pad_title(_("Log the plugin's internal ignorelist storage")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(LogStorage, key=None, randomize=timestamp()),
|
||||
title=pad_title("Log the plugin's complete state storage"),
|
||||
title=pad_title(_("Log the plugin's complete state storage")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ResetStorage, key="tasks", randomize=timestamp()),
|
||||
title=pad_title("Reset the plugin's scheduled tasks state storage"),
|
||||
title=pad_title(_("Reset the plugin's scheduled tasks state storage")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ResetStorage, key="ignore", randomize=timestamp()),
|
||||
title=pad_title("Reset the plugin's internal ignorelist storage"),
|
||||
title=pad_title(_("Reset the plugin's internal ignorelist storage")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ResetStorage, key="menu_history", randomize=timestamp()),
|
||||
title=pad_title("Reset the plugin's menu history storage"),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(InvalidateCache, randomize=timestamp()),
|
||||
title=pad_title("Invalidate Sub-Zero metadata caches (subliminal)"),
|
||||
title=pad_title(_("Invalidate Sub-Zero metadata caches (subliminal)")),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ResetProviderThrottle, randomize=timestamp()),
|
||||
title=pad_title("Reset provider throttle states"),
|
||||
title=pad_title(_("Reset provider throttle states")),
|
||||
))
|
||||
return oc
|
||||
|
||||
@@ -111,15 +123,20 @@ def DispatchRestart():
|
||||
@route(PREFIX + '/advanced/restart/trigger')
|
||||
@debounce
|
||||
def TriggerRestart(randomize=None):
|
||||
set_refresh_menu_state("Restarting the plugin")
|
||||
set_refresh_menu_state(_("Restarting the plugin"))
|
||||
DispatchRestart()
|
||||
return fatality(header="Restart triggered, please wait about 5 seconds", force_title=" ", only_refresh=True,
|
||||
replace_parent=True,
|
||||
no_history=True, randomize=timestamp())
|
||||
return fatality(
|
||||
header=_("Restart triggered, please wait about 5 seconds"),
|
||||
force_title=" ",
|
||||
only_refresh=True,
|
||||
replace_parent=True,
|
||||
no_history=True,
|
||||
randomize=timestamp())
|
||||
|
||||
|
||||
@route(PREFIX + '/advanced/restart/execute')
|
||||
def Restart():
|
||||
@debounce
|
||||
def Restart(randomize=None):
|
||||
Plex[":/plugins"].restart(PLUGIN_IDENTIFIER)
|
||||
|
||||
|
||||
@@ -127,10 +144,17 @@ def Restart():
|
||||
@debounce
|
||||
def ResetStorage(key, randomize=None, sure=False):
|
||||
if not sure:
|
||||
oc = SubFolderObjectContainer(no_history=True, title1="Reset subtitle storage", title2="Are you sure?")
|
||||
oc = SubFolderObjectContainer(
|
||||
no_history=True,
|
||||
title1=_("Reset subtitle storage"),
|
||||
title2=_("Are you sure?"))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ResetStorage, key=key, sure=True, randomize=timestamp()),
|
||||
title=pad_title("Are you really sure?"),
|
||||
key=Callback(
|
||||
ResetStorage,
|
||||
key=key,
|
||||
sure=True,
|
||||
randomize=timestamp()),
|
||||
title=pad_title(_("Are you really sure?")),
|
||||
|
||||
))
|
||||
return oc
|
||||
@@ -144,8 +168,8 @@ def ResetStorage(key, randomize=None, sure=False):
|
||||
|
||||
return AdvancedMenu(
|
||||
randomize=timestamp(),
|
||||
header='Success',
|
||||
message='Information Storage (%s) reset' % key
|
||||
header=_("Success"),
|
||||
message=_("Information Storage (%s) reset", key)
|
||||
)
|
||||
|
||||
|
||||
@@ -154,8 +178,8 @@ def LogStorage(key, randomize=None):
|
||||
log_storage(key)
|
||||
return AdvancedMenu(
|
||||
randomize=timestamp(),
|
||||
header='Success',
|
||||
message='Information Storage (%s) logged' % key
|
||||
header=_("Success"),
|
||||
message=_("Information Storage (%s) logged", key)
|
||||
)
|
||||
|
||||
|
||||
@@ -165,12 +189,11 @@ def TriggerBetterSubtitles(randomize=None):
|
||||
scheduler.dispatch_task("FindBetterSubtitles")
|
||||
return AdvancedMenu(
|
||||
randomize=timestamp(),
|
||||
header='Success',
|
||||
message='FindBetterSubtitles triggered'
|
||||
header=_("Success"),
|
||||
message=_("FindBetterSubtitles triggered")
|
||||
)
|
||||
|
||||
|
||||
|
||||
@route(PREFIX + '/skipbetter')
|
||||
@debounce
|
||||
def SkipFindBetterSubtitles(randomize=None):
|
||||
@@ -179,8 +202,8 @@ def SkipFindBetterSubtitles(randomize=None):
|
||||
|
||||
return AdvancedMenu(
|
||||
randomize=timestamp(),
|
||||
header='Success',
|
||||
message='FindBetterSubtitles skipped'
|
||||
header=_("Success"),
|
||||
message=_("FindBetterSubtitles skipped")
|
||||
)
|
||||
|
||||
|
||||
@@ -190,8 +213,8 @@ def TriggerStorageMaintenance(randomize=None):
|
||||
scheduler.dispatch_task("SubtitleStorageMaintenance")
|
||||
return AdvancedMenu(
|
||||
randomize=timestamp(),
|
||||
header='Success',
|
||||
message='SubtitleStorageMaintenance triggered'
|
||||
header=_("Success"),
|
||||
message=_("SubtitleStorageMaintenance triggered")
|
||||
)
|
||||
|
||||
|
||||
@@ -201,8 +224,8 @@ def TriggerStorageMigration(randomize=None):
|
||||
scheduler.dispatch_task("MigrateSubtitleStorage")
|
||||
return AdvancedMenu(
|
||||
randomize=timestamp(),
|
||||
header='Success',
|
||||
message='MigrateSubtitleStorage triggered'
|
||||
header=_("Success"),
|
||||
message=_("MigrateSubtitleStorage triggered")
|
||||
)
|
||||
|
||||
|
||||
@@ -212,8 +235,8 @@ def TriggerCacheMaintenance(randomize=None):
|
||||
scheduler.dispatch_task("CacheMaintenance")
|
||||
return AdvancedMenu(
|
||||
randomize=timestamp(),
|
||||
header='Success',
|
||||
message='TriggerCacheMaintenance triggered'
|
||||
header=_("Success"),
|
||||
message=_("TriggerCacheMaintenance triggered")
|
||||
)
|
||||
|
||||
|
||||
@@ -265,8 +288,8 @@ def ApplyDefaultMods(randomize=None):
|
||||
Thread.CreateTimer(1.0, apply_default_mods)
|
||||
return AdvancedMenu(
|
||||
randomize=timestamp(),
|
||||
header='Success',
|
||||
message='This may take some time ...'
|
||||
header=_("Success"),
|
||||
message=_("This may take some time ...")
|
||||
)
|
||||
|
||||
|
||||
@@ -276,17 +299,20 @@ def ReApplyMods(randomize=None):
|
||||
Thread.CreateTimer(1.0, apply_default_mods, reapply_current=True)
|
||||
return AdvancedMenu(
|
||||
randomize=timestamp(),
|
||||
header='Success',
|
||||
message='This may take some time ...'
|
||||
header=_("Success"),
|
||||
message=_("This may take some time ...")
|
||||
)
|
||||
|
||||
|
||||
@route(PREFIX + '/get_logs_link')
|
||||
def GetLogsLink():
|
||||
if not config.plex_token:
|
||||
oc = ObjectContainer(title2="Download Logs", no_cache=True, no_history=True,
|
||||
header="Sorry, feature unavailable",
|
||||
message="Universal Plex token not available")
|
||||
oc = ObjectContainer(
|
||||
title2=_("Download Logs"),
|
||||
no_cache=True,
|
||||
no_history=True,
|
||||
header=_("Sorry, feature unavailable"),
|
||||
message=_("Universal Plex token not available"))
|
||||
return oc
|
||||
|
||||
# try getting the link base via the request in context, first, otherwise use the public ip
|
||||
@@ -311,9 +337,12 @@ def GetLogsLink():
|
||||
Log.Debug("Using ip-based fallback link_base")
|
||||
|
||||
logs_link = "%s%s?X-Plex-Token=%s" % (link_base, PREFIX + '/logs', config.plex_token)
|
||||
oc = ObjectContainer(title2=logs_link, no_cache=True, no_history=True,
|
||||
header="Copy this link and open this in your browser, please",
|
||||
message=logs_link)
|
||||
oc = ObjectContainer(
|
||||
title2=logs_link,
|
||||
no_cache=True,
|
||||
no_history=True,
|
||||
header=_("Copy this link and open this in your browser, please"),
|
||||
message=logs_link)
|
||||
return oc
|
||||
|
||||
|
||||
@@ -343,32 +372,45 @@ def InvalidateCache(randomize=None):
|
||||
region.invalidate()
|
||||
return AdvancedMenu(
|
||||
randomize=timestamp(),
|
||||
header='Success',
|
||||
message='Cache invalidated'
|
||||
header=_("Success"),
|
||||
message=_("Cache invalidated")
|
||||
)
|
||||
|
||||
|
||||
@route(PREFIX + '/pin')
|
||||
def PinMenu(pin="", randomize=None, success_go_to="channel"):
|
||||
oc = ObjectContainer(title2="Enter PIN number %s" % (len(pin) + 1), no_cache=True, no_history=True,
|
||||
skip_pin_lock=True)
|
||||
oc = ObjectContainer(
|
||||
title2=_("Enter PIN number ") + str(len(pin) + 1),
|
||||
no_cache=True,
|
||||
no_history=True,
|
||||
skip_pin_lock=True)
|
||||
|
||||
if pin == config.pin:
|
||||
Dict["pin_correct_time"] = datetime.datetime.now()
|
||||
config.locked = False
|
||||
if success_go_to == "channel":
|
||||
return fatality(force_title="PIN correct", header="PIN correct", no_history=True)
|
||||
return fatality(
|
||||
force_title=_("PIN correct"),
|
||||
header=_("PIN correct"),
|
||||
no_history=True)
|
||||
elif success_go_to == "advanced":
|
||||
return AdvancedMenu(randomize=timestamp())
|
||||
|
||||
for i in range(10):
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(PinMenu, randomize=timestamp(), pin=pin + str(i), success_go_to=success_go_to),
|
||||
key=Callback(
|
||||
PinMenu,
|
||||
randomize=timestamp(),
|
||||
pin=pin + str(i),
|
||||
success_go_to=success_go_to),
|
||||
title=pad_title(str(i)),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(PinMenu, randomize=timestamp(), success_go_to=success_go_to),
|
||||
title=pad_title("Reset"),
|
||||
key=Callback(
|
||||
PinMenu,
|
||||
randomize=timestamp(),
|
||||
success_go_to=success_go_to),
|
||||
title=pad_title(_("Reset")),
|
||||
))
|
||||
return oc
|
||||
|
||||
@@ -377,7 +419,7 @@ def PinMenu(pin="", randomize=None, success_go_to="channel"):
|
||||
def ClearPin(randomize=None):
|
||||
Dict["pin_correct_time"] = None
|
||||
config.locked = True
|
||||
return fatality(force_title="Menu locked", header=" ", no_history=True)
|
||||
return fatality(force_title=_("Menu locked"), header=" ", no_history=True)
|
||||
|
||||
|
||||
@route(PREFIX + '/reset_throttle')
|
||||
@@ -386,6 +428,6 @@ def ResetProviderThrottle(randomize=None):
|
||||
Dict.Save()
|
||||
return AdvancedMenu(
|
||||
randomize=timestamp(),
|
||||
header='Success',
|
||||
message='Provider throttles reset'
|
||||
)
|
||||
header=_("Success"),
|
||||
message=_("Provider throttles reset")
|
||||
)
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# coding=utf-8
|
||||
|
||||
import datetime
|
||||
import operator
|
||||
|
||||
from support.config import config
|
||||
from support.helpers import timestamp
|
||||
|
||||
|
||||
def enable_channel_wrapper(func):
|
||||
@@ -25,3 +29,157 @@ def enable_channel_wrapper(func):
|
||||
return (func if (config.enable_channel or enforce_route) else noop)(*args, **kwargs)
|
||||
|
||||
return wrap
|
||||
|
||||
|
||||
ROUTE_REGISTRY = {}
|
||||
|
||||
|
||||
def get_func_name(args):
|
||||
return list(args).pop(0).__name__
|
||||
|
||||
|
||||
def get_lookup_key(f, args, kwargs):
|
||||
return tuple([f.__name__, tuple(args), tuple([(key, value) for key, value in kwargs.iteritems()])])
|
||||
|
||||
|
||||
def should_debounce(f, key, kw):
|
||||
return getattr(f, "debounce", False) and "randomize" in kw and key in Dict["menu_history"]
|
||||
|
||||
|
||||
def register_route_function(f):
|
||||
fn = f.__name__
|
||||
if fn != "ValidatePrefs" and fn not in ROUTE_REGISTRY:
|
||||
ROUTE_REGISTRY[fn] = f
|
||||
return f
|
||||
|
||||
|
||||
def main_menu_fallback():
|
||||
key = get_lookup_key(ROUTE_REGISTRY["fatality"], [], {})
|
||||
Dict["last_menu_item"] = key
|
||||
add_to_menu_history(key)
|
||||
|
||||
return ROUTE_REGISTRY["fatality"](randomize=timestamp())
|
||||
|
||||
|
||||
def add_to_menu_history(key):
|
||||
# add function to menu history
|
||||
mh = Dict["menu_history"]
|
||||
if key in mh:
|
||||
del mh[key]
|
||||
|
||||
mh[key] = datetime.datetime.now() + datetime.timedelta(hours=6)
|
||||
|
||||
# limit to 25 items
|
||||
Dict["menu_history"] = dict(sorted(sorted(mh.items(), key=operator.itemgetter(1),
|
||||
reverse=True)[:25]))
|
||||
|
||||
try:
|
||||
Dict.Save()
|
||||
except TypeError:
|
||||
Log.Error("Can't save menu history for: %r", key)
|
||||
del Dict["menu_history"][key]
|
||||
|
||||
|
||||
def route_wrapper(*args, **kwargs):
|
||||
def wrap(f):
|
||||
already_wrapped = getattr(f, "orig_f", False)
|
||||
|
||||
register_route_function(f)
|
||||
|
||||
def inner(*a, **kw):
|
||||
if "menu_history" not in Dict:
|
||||
Dict["menu_history"] = {}
|
||||
|
||||
if "last_menu_item" not in Dict:
|
||||
Dict["last_menu_item"] = None
|
||||
|
||||
key = get_lookup_key(f, list(a), kw)
|
||||
|
||||
ret_f = f
|
||||
ret_a = a
|
||||
ret_kw = kw
|
||||
# mh = Dict["menu_history"]
|
||||
# mh_keys = [k for k, v in sorted(mh.items(), key=operator.itemgetter(1))]
|
||||
#
|
||||
# fallback_needed = False
|
||||
# fallback_found = False
|
||||
|
||||
if should_debounce(ret_f, key, kw):
|
||||
# special case for TriggerRestart
|
||||
if ret_f.__name__ in ("TriggerRestart", "Restart"):
|
||||
Log.Debug("Don't trigger a re-restart, falling back to main menu")
|
||||
else:
|
||||
Log.Debug("not triggering %s twice with %s, %s, returning to main menu" %
|
||||
(f.__name__, a, kw))
|
||||
|
||||
return main_menu_fallback()
|
||||
#
|
||||
# fallback_needed = True
|
||||
#
|
||||
# # try to find a suitable fallback route in case we've encountered an already visited
|
||||
# # debounced route
|
||||
# fallbacks = []
|
||||
# current_last_visit = mh[key]
|
||||
# last_menu_item = Dict["last_menu_item"]
|
||||
# direction_backwards = True
|
||||
#
|
||||
# if last_menu_item and last_menu_item in mh and key in mh:
|
||||
# last_mi_pos = mh_keys.index(last_menu_item)
|
||||
# current_mi_pos = mh_keys.index(key)
|
||||
# if current_mi_pos > -1 and last_mi_pos > -1:
|
||||
# print "SHEKEL", current_mi_pos, last_mi_pos, current_mi_pos < last_mi_pos
|
||||
|
||||
# only consider items in menu history that have an older timestamp than the current
|
||||
# for key_, last_visit in sorted(mh.items(), key=operator.itemgetter(1),
|
||||
# reverse=True):
|
||||
# if last_visit < current_last_visit:
|
||||
# fallbacks.append(key_)
|
||||
#
|
||||
# for key_ in fallbacks:
|
||||
# # old data structure
|
||||
# if not len(key_) == 3 or not (isinstance(key_[1], tuple) and isinstance(key_[2], tuple)):
|
||||
# continue
|
||||
#
|
||||
# old_f, old_a, old_kw = key_
|
||||
# if old_f == "ValidatePrefs":
|
||||
# continue
|
||||
#
|
||||
# possible_fallback = ROUTE_REGISTRY[old_f]
|
||||
#
|
||||
# # non-debounced function found
|
||||
# if not getattr(possible_fallback, "debounce", False):
|
||||
# ret_kw = dict(old_kw)
|
||||
# ret_a = old_a
|
||||
# if "randomize" in ret_kw:
|
||||
# ret_kw["randomize"] = timestamp()
|
||||
#
|
||||
# ret_f = possible_fallback
|
||||
# key = get_lookup_key(ret_f, list(ret_a), ret_kw)
|
||||
# fallback_found = True
|
||||
#
|
||||
# Log.Debug("not triggering %s twice with %s, %s, returning to %s, %s, %s" %
|
||||
# (f.__name__, a, kw, ret_f.__name__, ret_a, ret_kw))
|
||||
#
|
||||
# break
|
||||
#
|
||||
# if not fallback_found:
|
||||
# Log.Debug("No fallback found in menu history for %s, falling back to main menu", f)
|
||||
# return main_menu_fallback()
|
||||
|
||||
# if not fallback_needed:
|
||||
# add_to_menu_history(key)
|
||||
# if ret_f.__name__ != "ValidatePrefs":
|
||||
# Dict["last_menu_item"] = key
|
||||
#
|
||||
add_to_menu_history(key)
|
||||
Dict["last_menu_item"] = key
|
||||
return ret_f(*ret_a, **ret_kw)
|
||||
|
||||
# @route may be used multiple times
|
||||
if not already_wrapped:
|
||||
inner.orig_f = f
|
||||
|
||||
return enable_channel_wrapper(route(*args, **kwargs))(inner)
|
||||
return enable_channel_wrapper(route(*args, **kwargs))(f)
|
||||
|
||||
return wrap
|
||||
|
||||
@@ -16,12 +16,12 @@ from support.plex_media import get_plex_metadata, get_part, get_embedded_subtitl
|
||||
from support.scanning import scan_videos
|
||||
from support.scheduler import scheduler
|
||||
from support.storage import get_subtitle_storage
|
||||
from support.i18n import _
|
||||
|
||||
|
||||
# fixme: needs kwargs cleanup
|
||||
|
||||
@route(PREFIX + '/item/{rating_key}/actions')
|
||||
@debounce
|
||||
def ItemDetailsMenu(rating_key, title=None, base_title=None, item_title=None, randomize=None, header=None,
|
||||
message=None):
|
||||
"""
|
||||
@@ -41,14 +41,23 @@ def ItemDetailsMenu(rating_key, title=None, base_title=None, item_title=None, ra
|
||||
|
||||
timeout = 30
|
||||
|
||||
oc = SubFolderObjectContainer(title2=title, replace_parent=True, header=header, message=message)
|
||||
oc = SubFolderObjectContainer(
|
||||
title2=title,
|
||||
replace_parent=True,
|
||||
header=header,
|
||||
message=message)
|
||||
|
||||
if not item:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ItemDetailsMenu, rating_key=rating_key, title=title, base_title=base_title,
|
||||
item_title=item_title, randomize=timestamp()),
|
||||
title=u"Item not found: %s!" % item_title,
|
||||
summary="Plex didn't return any information about the item, please refresh it and come back later",
|
||||
key=Callback(
|
||||
ItemDetailsMenu,
|
||||
rating_key=rating_key,
|
||||
title=title,
|
||||
base_title=base_title,
|
||||
item_title=item_title,
|
||||
randomize=timestamp()),
|
||||
title=_(u"Item not found: %s!", item_title),
|
||||
summary=_("Plex didn't return any information about the item, please refresh it and come back later"),
|
||||
thumb=default_thumb
|
||||
))
|
||||
return oc
|
||||
@@ -60,26 +69,37 @@ def ItemDetailsMenu(rating_key, title=None, base_title=None, item_title=None, ra
|
||||
season = get_item(item.season.rating_key)
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(MetadataMenu, rating_key=season.rating_key, title=season.title, base_title=show.title,
|
||||
previous_item_type="show", previous_rating_key=show.rating_key,
|
||||
display_items=True, randomize=timestamp()),
|
||||
title=u"< Back to %s" % season.title,
|
||||
summary="Back to %s > %s" % (show.title, season.title),
|
||||
key=Callback(
|
||||
MetadataMenu,
|
||||
rating_key=season.rating_key,
|
||||
title=season.title,
|
||||
base_title=show.title,
|
||||
previous_item_type="show",
|
||||
previous_rating_key=show.rating_key,
|
||||
display_items=True,
|
||||
randomize=timestamp()),
|
||||
title=_(u"< Back to %s", season.title),
|
||||
summary=_("Back to %s > %s", show.title, season.title),
|
||||
thumb=season.thumb or default_thumb
|
||||
))
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(RefreshItem, rating_key=rating_key, item_title=item_title, randomize=timestamp(),
|
||||
timeout=timeout * 1000),
|
||||
title=u"Refresh: %s" % item_title,
|
||||
summary="Refreshes the %s, possibly searching for missing and picking up new subtitles on disk" % current_kind,
|
||||
key=Callback(
|
||||
RefreshItem,
|
||||
rating_key=rating_key,
|
||||
item_title=item_title,
|
||||
randomize=timestamp(),
|
||||
timeout=timeout * 1000),
|
||||
title=_(u"Refresh: %s", item_title),
|
||||
summary=_("Refreshes %(the_movie_series_season_episode)s, possibly searching for missing and picking up "
|
||||
"new subtitles on disk", the_movie_series_season_episode=_(u"the %s" % current_kind)),
|
||||
thumb=item.thumb or default_thumb
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(RefreshItem, rating_key=rating_key, item_title=item_title, force=True, randomize=timestamp(),
|
||||
timeout=timeout * 1000),
|
||||
title=u"Force-find subtitles: %s" % item_title,
|
||||
summary="Issues a forced refresh, ignoring known subtitles and searching for new ones",
|
||||
title=_(u"Force-find subtitles: %(item_title)s", item_title=item_title),
|
||||
summary=_("Issues a forced refresh, ignoring known subtitles and searching for new ones"),
|
||||
thumb=item.thumb or default_thumb
|
||||
))
|
||||
|
||||
@@ -99,11 +119,11 @@ def ItemDetailsMenu(rating_key, title=None, base_title=None, item_title=None, ra
|
||||
part_id = str(part.id)
|
||||
part_index += 1
|
||||
|
||||
part_index_addon = ""
|
||||
part_summary_addon = ""
|
||||
part_index_addon = u""
|
||||
part_summary_addon = u""
|
||||
if has_multiple_parts:
|
||||
part_index_addon = u"File %s: " % part_index
|
||||
part_summary_addon = "%s " % filename
|
||||
part_index_addon = _(u"File %(file_part_index)s: ", file_part_index=part_index)
|
||||
part_summary_addon = u"%s " % filename
|
||||
|
||||
# iterate through all configured languages
|
||||
for lang in config.lang_list:
|
||||
@@ -112,17 +132,22 @@ def ItemDetailsMenu(rating_key, title=None, base_title=None, item_title=None, ra
|
||||
current_sub_id = None
|
||||
current_sub_provider_name = None
|
||||
|
||||
summary = u"%sNo current subtitle in storage" % part_summary_addon
|
||||
summary = _(u"%(part_summary)sNo current subtitle in storage", part_summary=part_summary_addon)
|
||||
current_score = None
|
||||
if current_sub:
|
||||
current_sub_id = current_sub.id
|
||||
current_sub_provider_name = current_sub.provider_name
|
||||
current_score = current_sub.score
|
||||
|
||||
summary = u"%sCurrent subtitle: %s (added: %s, %s), Language: %s, Score: %i, Storage: %s" % \
|
||||
(part_summary_addon, current_sub.provider_name, df(current_sub.date_added),
|
||||
current_sub.mode_verbose, display_language(lang), current_sub.score,
|
||||
current_sub.storage_type)
|
||||
summary = _(u"%(part_summary)sCurrent subtitle: %(provider_name)s (added: %(date_added)s, "
|
||||
u"%(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s",
|
||||
part_summary=part_summary_addon,
|
||||
provider_name=current_sub.provider_name,
|
||||
date_added=df(current_sub.date_added),
|
||||
mode=current_sub.mode_verbose,
|
||||
language=display_language(lang),
|
||||
score=current_sub.score,
|
||||
storage_type=current_sub.storage_type)
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleOptionsMenu, rating_key=rating_key, part_id=part_id, title=title,
|
||||
@@ -131,7 +156,8 @@ def ItemDetailsMenu(rating_key, title=None, base_title=None, item_title=None, ra
|
||||
item_type=plex_item.type, filename=filename, current_data=summary,
|
||||
randomize=timestamp(), current_provider=current_sub_provider_name,
|
||||
current_score=current_score),
|
||||
title=u"%sManage %s subtitle" % (part_index_addon, display_language(lang)),
|
||||
title=_(u"%(part_summary)sManage %(language)s subtitle", part_summary=part_index_addon,
|
||||
language=display_language(lang)),
|
||||
summary=summary
|
||||
))
|
||||
else:
|
||||
@@ -142,7 +168,8 @@ def ItemDetailsMenu(rating_key, title=None, base_title=None, item_title=None, ra
|
||||
item_type=plex_item.type, filename=filename, current_data=summary,
|
||||
randomize=timestamp(), current_provider=current_sub_provider_name,
|
||||
current_score=current_score),
|
||||
title=u"%sList %s subtitles" % (part_index_addon, display_language(lang)),
|
||||
title=_(u"%(part_summary)sList %(language)s subtitles", part_summary=part_index_addon,
|
||||
language=display_language(lang)),
|
||||
summary=summary
|
||||
))
|
||||
|
||||
@@ -167,9 +194,10 @@ def ItemDetailsMenu(rating_key, title=None, base_title=None, item_title=None, ra
|
||||
key=Callback(ListEmbeddedSubsForItemMenu, rating_key=rating_key, part_id=part_id, title=title,
|
||||
item_type=plex_item.type, item_title=item_title, base_title=base_title,
|
||||
randomize=timestamp()),
|
||||
title=u"%sEmbedded subtitles (%s)" % (part_index_addon, ", ".join(display_language(l) for l in
|
||||
set(embedded_langs))),
|
||||
summary=u"Extract and activate embedded subtitle streams"
|
||||
title=_(u"%(part_summary)sEmbedded subtitles (%(languages)s)",
|
||||
part_summary=part_index_addon,
|
||||
languages=", ".join(display_language(l) for l in set(embedded_langs))),
|
||||
summary=_(u"Extract and activate embedded subtitle streams")
|
||||
))
|
||||
|
||||
ignore_title = item_title
|
||||
@@ -188,7 +216,7 @@ def SubtitleOptionsMenu(**kwargs):
|
||||
rating_key = kwargs["rating_key"]
|
||||
part_id = kwargs["part_id"]
|
||||
language = kwargs["language"]
|
||||
current_data = kwargs["current_data"]
|
||||
current_data = unicode(kwargs["current_data"])
|
||||
|
||||
current_sub, stored_subs, storage = get_current_sub(rating_key, part_id, language)
|
||||
subs_count = stored_subs.count(part_id, language)
|
||||
@@ -197,33 +225,35 @@ def SubtitleOptionsMenu(**kwargs):
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ItemDetailsMenu, rating_key=kwargs["rating_key"], item_title=kwargs["item_title"],
|
||||
title=kwargs["title"], randomize=timestamp()),
|
||||
title=u"< Back to %s" % kwargs["title"],
|
||||
summary=kwargs["current_data"],
|
||||
title=_(u"< Back to %s", kwargs["title"]),
|
||||
summary=current_data,
|
||||
thumb=default_thumb
|
||||
))
|
||||
if subs_count:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ListStoredSubsForItemMenu, randomize=timestamp(), **kwargs),
|
||||
title=u"Select active %s subtitle" % kwargs["language_name"],
|
||||
summary=u"%d subtitles in storage" % subs_count
|
||||
title=_(u"Select active %(language)s subtitle", language=kwargs["language_name"]),
|
||||
summary=_(u"%(count)d subtitles in storage", count=subs_count)
|
||||
))
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ListAvailableSubsForItemMenu, randomize=timestamp(), **kwargs),
|
||||
title=u"List available %s subtitles" % kwargs["language_name"],
|
||||
summary=kwargs["current_data"]
|
||||
title=_(u"List available %(language)s subtitles", language=kwargs["language_name"]),
|
||||
summary=current_data
|
||||
))
|
||||
if current_sub:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleModificationsMenu, randomize=timestamp(), **kwargs),
|
||||
title=u"Modify current %s subtitle" % kwargs["language_name"],
|
||||
summary=u"Currently applied mods: %s" % (", ".join(current_sub.mods) if current_sub.mods else "none")
|
||||
title=_(u"Modify current %(language)s subtitle", language=kwargs["language_name"]),
|
||||
summary=_(u"Currently applied mods: %(mod_list)s",
|
||||
mod_list=(", ".join(current_sub.mods) if current_sub.mods else "none"))
|
||||
))
|
||||
|
||||
if current_sub.provider_name != "embedded":
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(BlacklistSubtitleMenu, randomize=timestamp(), **kwargs),
|
||||
title=u"Blacklist current %s subtitle and search for a new one" % kwargs["language_name"],
|
||||
title=_(u"Blacklist current %(language)s subtitle and search for a new one",
|
||||
language=kwargs["language_name"]),
|
||||
summary=current_data
|
||||
))
|
||||
|
||||
@@ -231,8 +261,8 @@ def SubtitleOptionsMenu(**kwargs):
|
||||
if current_bl:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ManageBlacklistMenu, randomize=timestamp(), **kwargs),
|
||||
title=u"Manage blacklist (%s contained)" % len(current_bl),
|
||||
summary=u"Inspect currently blacklisted subtitles"
|
||||
title=_(u"Manage blacklist (%(amount)s contained)", amount=len(current_bl)),
|
||||
summary=_(u"Inspect currently blacklisted subtitles")
|
||||
))
|
||||
|
||||
storage.destroy()
|
||||
@@ -254,10 +284,13 @@ def ListStoredSubsForItemMenu(**kwargs):
|
||||
key=lambda x: x[1].date_added, reverse=True):
|
||||
is_current = key == all_subs["current"]
|
||||
|
||||
summary = u"added: %s, %s, Language: %s, Score: %i, Storage: %s" % \
|
||||
(df(subtitle.date_added),
|
||||
subtitle.mode_verbose, display_language(language), subtitle.score,
|
||||
subtitle.storage_type)
|
||||
summary = _(u"added: %(date_added)s, %(mode)s, Language: %(language)s, Score: %(score)i, Storage: "
|
||||
u"%(storage_type)s",
|
||||
date_added=df(subtitle.date_added),
|
||||
mode=subtitle.mode_verbose,
|
||||
language=display_language(language),
|
||||
score=subtitle.score,
|
||||
storage_type=subtitle.storage_type)
|
||||
|
||||
sub_name = subtitle.provider_name
|
||||
if sub_name == "embedded":
|
||||
@@ -265,8 +298,10 @@ def ListStoredSubsForItemMenu(**kwargs):
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SelectStoredSubForItemMenu, randomize=timestamp(), sub_key="__".join(key), **kwargs),
|
||||
title=u"%s%s, Score: %s" % ("Current: " if is_current else "Stored: ", sub_name,
|
||||
subtitle.score),
|
||||
title=_(u"%(current_state)s%(subtitle_name)s, Score: %(score)s",
|
||||
current_state=_("Current: ") if is_current else _("Stored: "),
|
||||
subtitle_name=sub_name,
|
||||
score=subtitle.score),
|
||||
summary=summary
|
||||
))
|
||||
|
||||
@@ -298,8 +333,8 @@ def SelectStoredSubForItemMenu(**kwargs):
|
||||
|
||||
kwargs.pop("randomize")
|
||||
|
||||
kwargs["header"] = 'Success'
|
||||
kwargs["message"] = 'Subtitle saved to disk'
|
||||
kwargs["header"] = _("Success")
|
||||
kwargs["message"] = _("Subtitle saved to disk")
|
||||
|
||||
return SubtitleOptionsMenu(randomize=timestamp(), **kwargs)
|
||||
|
||||
@@ -388,6 +423,7 @@ def ManageBlacklistMenu(**kwargs):
|
||||
part_id = kwargs["part_id"]
|
||||
language = kwargs["language"]
|
||||
remove_sub_key = kwargs.pop("remove_sub_key", None)
|
||||
current_data = unicode(kwargs["current_data"])
|
||||
|
||||
current_sub, stored_subs, storage = get_current_sub(rating_key, part_id, language)
|
||||
current_bl, subs = stored_subs.get_blacklist(part_id, language)
|
||||
@@ -403,8 +439,8 @@ def ManageBlacklistMenu(**kwargs):
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ItemDetailsMenu, rating_key=kwargs["rating_key"], item_title=kwargs["item_title"],
|
||||
title=kwargs["title"], randomize=timestamp()),
|
||||
title=u"< Back to %s" % kwargs["title"],
|
||||
summary=kwargs["current_data"],
|
||||
title=_(u"< Back to %s", kwargs["title"]),
|
||||
summary=current_data,
|
||||
thumb=default_thumb
|
||||
))
|
||||
|
||||
@@ -414,15 +450,19 @@ def ManageBlacklistMenu(**kwargs):
|
||||
|
||||
for sub_key, data in sorted(current_bl.iteritems(), key=sorter, reverse=True):
|
||||
provider_name, subtitle_id = sub_key
|
||||
title = u"%s, %s (added: %s, %s), Language: " \
|
||||
u"%s, Score: %i, Storage: %s" % (provider_name, subtitle_id, df(data["date_added"]),
|
||||
current_sub.get_mode_verbose(data["mode"]),
|
||||
display_language(Language.fromietf(language)), data["score"],
|
||||
data["storage_type"])
|
||||
title = _(u"%(provider_name)s, %(subtitle_id)s (added: %(date_added)s, %(mode)s), Language: %(language)s, "
|
||||
u"Score: %(score)i, Storage: %(storage_type)s",
|
||||
provider_name=provider_name,
|
||||
subtitle_id=subtitle_id,
|
||||
date_added=df(data["date_added"]),
|
||||
mode=current_sub.get_mode_verbose(data["mode"]),
|
||||
language=display_language(Language.fromietf(language)),
|
||||
score=data["score"],
|
||||
storage_type=data["storage_type"])
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ManageBlacklistMenu, remove_sub_key="__".join(sub_key), randomize=timestamp(), **kwargs),
|
||||
title=title,
|
||||
summary=u"Remove subtitle from blacklist"
|
||||
summary=_(u"Remove subtitle from blacklist")
|
||||
))
|
||||
|
||||
storage.destroy()
|
||||
@@ -431,7 +471,6 @@ def ManageBlacklistMenu(**kwargs):
|
||||
|
||||
|
||||
@route(PREFIX + '/item/search/{rating_key}/{part_id}', force=bool)
|
||||
@debounce
|
||||
def ListAvailableSubsForItemMenu(rating_key=None, part_id=None, title=None, item_title=None, filename=None,
|
||||
item_type="episode", language=None, language_name=None, force=False, current_id=None,
|
||||
current_data=None,
|
||||
@@ -441,6 +480,8 @@ def ListAvailableSubsForItemMenu(rating_key=None, part_id=None, title=None, item
|
||||
running = scheduler.is_task_running("AvailableSubsForItem")
|
||||
search_results = get_item_task_data("AvailableSubsForItem", rating_key, language)
|
||||
|
||||
current_data = unicode(current_data) if current_data else None
|
||||
|
||||
if (search_results is None or force) and not running:
|
||||
scheduler.dispatch_task("AvailableSubsForItem", rating_key=rating_key, item_type=item_type, part_id=part_id,
|
||||
language=language)
|
||||
@@ -449,7 +490,7 @@ def ListAvailableSubsForItemMenu(rating_key=None, part_id=None, title=None, item
|
||||
oc = SubFolderObjectContainer(title2=unicode(title), replace_parent=True)
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ItemDetailsMenu, rating_key=rating_key, item_title=item_title, title=title, randomize=timestamp()),
|
||||
title=u"< Back to %s" % title,
|
||||
title=_(u"< Back to %s", title),
|
||||
summary=current_data,
|
||||
thumb=default_thumb
|
||||
))
|
||||
@@ -467,20 +508,24 @@ def ListAvailableSubsForItemMenu(rating_key=None, part_id=None, title=None, item
|
||||
|
||||
video_display_data = [video.format] if video.format else []
|
||||
if video.release_group:
|
||||
video_display_data.append(u"by %s" % video.release_group)
|
||||
video_display_data.append(unicode(_(u"by %(release_group)s", release_group=video.release_group)))
|
||||
video_display_data = " ".join(video_display_data)
|
||||
else:
|
||||
video_display_data = metadata["filename"]
|
||||
|
||||
current_display = (u"Current: %s (%s) " % (current_provider, current_score) if current_provider else "")
|
||||
current_display = (_(u"Current: %(provider_name)s (%(score)s) ",
|
||||
provider_name=current_provider,
|
||||
score=current_score if current_provider else ""))
|
||||
if not running:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ListAvailableSubsForItemMenu, rating_key=rating_key, item_title=item_title, language=language,
|
||||
filename=filename, part_id=part_id, title=title, current_id=current_id, force=True,
|
||||
current_provider=current_provider, current_score=current_score,
|
||||
current_data=current_data, item_type=item_type, randomize=timestamp()),
|
||||
title=u"Search for %s subs (%s)" % (get_language(language).name, video_display_data),
|
||||
summary=u"%sFilename: %s" % (current_display, filename),
|
||||
title=_(u"Search for %(language)s subs (%(video_data)s)",
|
||||
language=get_language(language).name,
|
||||
video_data=video_display_data),
|
||||
summary=_(u"%(current_info)sFilename: %(filename)s", current_info=current_display, filename=filename),
|
||||
thumb=default_thumb
|
||||
))
|
||||
|
||||
@@ -491,8 +536,8 @@ def ListAvailableSubsForItemMenu(rating_key=None, part_id=None, title=None, item
|
||||
part_id=part_id, title=title, current_id=current_id, item_type=item_type,
|
||||
current_provider=current_provider, current_score=current_score,
|
||||
randomize=timestamp()),
|
||||
title=u"No subtitles found",
|
||||
summary=u"%sFilename: %s" % (current_display, filename),
|
||||
title=_(u"No subtitles found"),
|
||||
summary=_(u"%(current_info)sFilename: %(filename)s", current_info=current_display, filename=filename),
|
||||
thumb=default_thumb
|
||||
))
|
||||
else:
|
||||
@@ -502,9 +547,10 @@ def ListAvailableSubsForItemMenu(rating_key=None, part_id=None, title=None, item
|
||||
part_id=part_id, title=title, current_id=current_id, item_type=item_type,
|
||||
current_provider=current_provider, current_score=current_score,
|
||||
randomize=timestamp()),
|
||||
title=u"Searching for %s subs (%s), refresh here ..." % (display_language(get_language(language)),
|
||||
video_display_data),
|
||||
summary=u"%sFilename: %s" % (current_display, filename),
|
||||
title=_(u"Searching for %(language)s subs (%(video_data)s), refresh here ...",
|
||||
language=display_language(get_language(language)),
|
||||
video_data=video_display_data),
|
||||
summary=_(u"%(current_info)sFilename: %(filename)s", current_info=current_display, filename=filename),
|
||||
thumb=default_thumb
|
||||
))
|
||||
|
||||
@@ -526,16 +572,25 @@ def ListAvailableSubsForItemMenu(rating_key=None, part_id=None, title=None, item
|
||||
wrong_fps_addon = ""
|
||||
if subtitle.wrong_fps:
|
||||
if plex_part:
|
||||
wrong_fps_addon = " (wrong FPS, sub: %s, media: %s)" % (subtitle.fps, plex_part.fps)
|
||||
wrong_fps_addon = _(" (wrong FPS, sub: %(subtitle_fps)s, media: %(media_fps)s)",
|
||||
subtitle_fps=subtitle.fps,
|
||||
media_fps=plex_part.fps)
|
||||
else:
|
||||
wrong_fps_addon = " (wrong FPS, sub: %s, media: unknown, low impact mode)" % subtitle.fps
|
||||
wrong_fps_addon = _(" (wrong FPS, sub: %(subtitle_fps)s, media: unknown, low impact mode)",
|
||||
subtitle_fps=subtitle.fps)
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(TriggerDownloadSubtitle, rating_key=rating_key, randomize=timestamp(), item_title=item_title,
|
||||
subtitle_id=str(subtitle.id), language=language),
|
||||
title=u"%s%s: %s, score: %s%s" % (bl_addon, "Available" if current_id != subtitle.id else "Current",
|
||||
subtitle.provider_name, subtitle.score, wrong_fps_addon),
|
||||
summary=u"Release: %s, Matches: %s" % (subtitle.release_info, ", ".join(subtitle.matches)),
|
||||
title=_(u"%(blacklisted_state)s%(current_state)s: %(provider_name)s, score: %(score)s%(wrong_fps_state)s",
|
||||
blacklisted_state=bl_addon,
|
||||
current_state=_("Available") if current_id != subtitle.id else _("Current"),
|
||||
provider_name=subtitle.provider_name,
|
||||
score=subtitle.score,
|
||||
wrong_fps_state=wrong_fps_addon),
|
||||
summary=_(u"Release: %(release_info)s, Matches: %(matches)s",
|
||||
release_info=subtitle.release_info,
|
||||
matches=", ".join(subtitle.matches)),
|
||||
thumb=default_thumb
|
||||
))
|
||||
|
||||
@@ -549,7 +604,7 @@ def ListAvailableSubsForItemMenu(rating_key=None, part_id=None, title=None, item
|
||||
def TriggerDownloadSubtitle(rating_key=None, subtitle_id=None, item_title=None, language=None, randomize=None):
|
||||
from interface.main import fatality
|
||||
|
||||
set_refresh_menu_state("Downloading subtitle for %s" % item_title or rating_key)
|
||||
set_refresh_menu_state(_("Downloading subtitle for %(title_or_id)s", title_or_id=item_title or rating_key))
|
||||
search_results = get_item_task_data("AvailableSubsForItem", rating_key, language)
|
||||
|
||||
download_subtitle = None
|
||||
@@ -580,7 +635,7 @@ def ListEmbeddedSubsForItemMenu(**kwargs):
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ItemDetailsMenu, rating_key=kwargs["rating_key"], item_title=kwargs["item_title"],
|
||||
base_title=kwargs["base_title"], title=kwargs["item_title"], randomize=timestamp()),
|
||||
title=u"< Back to %s" % kwargs["title"],
|
||||
title=_("< Back to %s", kwargs["title"]),
|
||||
thumb=default_thumb
|
||||
))
|
||||
|
||||
@@ -598,19 +653,24 @@ def ListEmbeddedSubsForItemMenu(**kwargs):
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(TriggerExtractEmbeddedSubForItemMenu, randomize=timestamp(),
|
||||
stream_index=str(stream.index), language=language, with_mods=True, **kwargs),
|
||||
title=u"Extract stream %s, "
|
||||
u"%s%s%s%s with default mods" % (stream.index, display_language(language),
|
||||
" (unknown)" if is_unknown else "",
|
||||
" (forced)" if is_forced else "",
|
||||
" (\"%s\")" % stream.title if stream.title else ""),
|
||||
title=_(u"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s"
|
||||
u"%(stream_title)s with default mods",
|
||||
stream_index=stream.index,
|
||||
language=display_language(language),
|
||||
unknown_state=_(" (unknown)") if is_unknown else "",
|
||||
forced_state=_(" (forced)") if is_forced else "",
|
||||
stream_title=" (\"%s\")" % stream.title if stream.title else ""),
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(TriggerExtractEmbeddedSubForItemMenu, randomize=timestamp(),
|
||||
stream_index=str(stream.index), language=language, **kwargs),
|
||||
title=u"Extract stream %s, %s%s%s%s" % (stream.index, display_language(language),
|
||||
" (unknown)" if is_unknown else "",
|
||||
" (forced)" if is_forced else "",
|
||||
" (\"%s\")" % stream.title if stream.title else ""),
|
||||
title=_(u"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s"
|
||||
u"%(stream_title)s",
|
||||
stream_index=stream.index,
|
||||
language=display_language(language),
|
||||
unknown_state=_(" (unknown)") if is_unknown else "",
|
||||
forced_state=_(" (forced)") if is_forced else "",
|
||||
stream_title=" (\"%s\")" % stream.title if stream.title else ""),
|
||||
))
|
||||
return oc
|
||||
|
||||
@@ -623,7 +683,8 @@ def TriggerExtractEmbeddedSubForItemMenu(**kwargs):
|
||||
stream_index = kwargs.get("stream_index")
|
||||
|
||||
Thread.Create(extract_embedded_sub, **kwargs)
|
||||
header = u"Extracting of embedded subtitle %s of part %s:%s triggered" % (stream_index, rating_key, part_id)
|
||||
header = _(u"Extracting of embedded subtitle %s of part %s:%s triggered",
|
||||
stream_index, rating_key, part_id)
|
||||
|
||||
kwargs.pop("randomize")
|
||||
kwargs.pop("item_type")
|
||||
|
||||
@@ -8,6 +8,7 @@ from support.ignore import ignore_list
|
||||
from support.items import get_item_thumb, get_on_deck_items, get_all_items, get_items_info, get_item, get_item_title
|
||||
from menu_helpers import main_icon, debounce, SubFolderObjectContainer, default_thumb, dig_tree, add_ignore_options, \
|
||||
ObjectContainer, route, handler
|
||||
from support.i18n import _
|
||||
from item_details import ItemDetailsMenu
|
||||
|
||||
|
||||
@@ -35,8 +36,8 @@ def fatality(randomize=None, force_title=None, header=None, message=None, only_r
|
||||
if config.lock_menu and not config.pin_correct:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(PinMenu, randomize=timestamp()),
|
||||
title=pad_title("Enter PIN"),
|
||||
summary="The owner has restricted the access to this menu. Please enter the correct pin",
|
||||
title=pad_title(_("Enter PIN")),
|
||||
summary=_("The owner has restricted the access to this menu. Please enter the correct pin"),
|
||||
))
|
||||
return oc
|
||||
|
||||
@@ -44,23 +45,25 @@ def fatality(randomize=None, force_title=None, header=None, message=None, only_r
|
||||
if not isinstance(config.missing_permissions, list):
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(fatality, randomize=timestamp()),
|
||||
title=pad_title("Insufficient permissions"),
|
||||
title=pad_title(_("Insufficient permissions")),
|
||||
summary=config.missing_permissions,
|
||||
))
|
||||
else:
|
||||
for title, path in config.missing_permissions:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(fatality, randomize=timestamp()),
|
||||
title=pad_title("Insufficient permissions"),
|
||||
summary="Insufficient permissions on library %s, folder: %s" % (title, path),
|
||||
title=pad_title(_("Insufficient permissions")),
|
||||
summary=_("Insufficient permissions on library %(title)s, folder: %(path)s",
|
||||
title=title,
|
||||
path=path),
|
||||
))
|
||||
return oc
|
||||
|
||||
if not config.enabled_sections:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(fatality, randomize=timestamp()),
|
||||
title=pad_title("I'm not enabled!"),
|
||||
summary="Please enable me for some of your libraries in your server settings; currently I do nothing",
|
||||
title=pad_title(_("I'm not enabled!")),
|
||||
summary=_("Please enable me for some of your libraries in your server settings; currently I do nothing"),
|
||||
))
|
||||
return oc
|
||||
|
||||
@@ -68,46 +71,42 @@ def fatality(randomize=None, force_title=None, header=None, message=None, only_r
|
||||
if Dict["current_refresh_state"]:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(fatality, force_title=" ", randomize=timestamp()),
|
||||
title=pad_title("Working ... refresh here"),
|
||||
summary="Current state: %s; Last state: %s" % (
|
||||
(Dict["current_refresh_state"] or "Idle") if "current_refresh_state" in Dict else "Idle",
|
||||
(Dict["last_refresh_state"] or "None") if "last_refresh_state" in Dict else "None"
|
||||
title=pad_title(_("Working ... refresh here")),
|
||||
summary=_("Current state: %s; Last state: %s",
|
||||
(Dict["current_refresh_state"] or _("Idle")) if "current_refresh_state" in Dict else _("Idle"),
|
||||
(Dict["last_refresh_state"] or _("None")) if "last_refresh_state" in Dict else _("None")
|
||||
)
|
||||
))
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(OnDeckMenu),
|
||||
title="On-deck items",
|
||||
summary="Shows the current on deck items and allows you to individually (force-) refresh their metadata/"
|
||||
"subtitles.",
|
||||
title=_("On-deck items"),
|
||||
summary=_("Shows the current on deck items and allows you to individually (force-) refresh their metadata/subtitles."),
|
||||
thumb=R("icon-ondeck.jpg")
|
||||
))
|
||||
if "last_played_items" in Dict and Dict["last_played_items"]:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(RecentlyPlayedMenu),
|
||||
title=pad_title("Recently played items"),
|
||||
summary="Shows the %i recently played items and allows you to individually (force-) refresh their "
|
||||
"metadata/subtitles." % config.store_recently_played_amount,
|
||||
title=pad_title(_("Recently played items")),
|
||||
summary=_("Shows the %s recently played items and allows you to individually (force-) refresh their metadata/subtitles.", config.store_recently_played_amount),
|
||||
thumb=R("icon-played.jpg")
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(RecentlyAddedMenu),
|
||||
title="Recently-added items",
|
||||
summary="Shows the recently added items per section.",
|
||||
title=_("Recently-added items"),
|
||||
summary=_("Shows the recently added items per section."),
|
||||
thumb=R("icon-added.jpg")
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(RecentMissingSubtitlesMenu, randomize=timestamp()),
|
||||
title="Show recently added items with missing subtitles",
|
||||
summary="Lists items with missing subtitles. Click on \"Find recent items with missing subs\" "
|
||||
"to update list",
|
||||
title=_("Show recently added items with missing subtitles"),
|
||||
summary=_("Lists items with missing subtitles. Click on Find recent items with missing subs to update list"),
|
||||
thumb=R("icon-missing.jpg")
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SectionsMenu),
|
||||
title="Browse all items",
|
||||
summary="Go through your whole library and manage your ignore list. You can also "
|
||||
"(force-) refresh the metadata/subtitles of individual items.",
|
||||
title=_("Browse all items"),
|
||||
summary=_("Go through your whole library and manage your ignore list. You can also (force-) refresh the metadata/subtitles of individual items."),
|
||||
thumb=R("icon-browse.jpg")
|
||||
))
|
||||
|
||||
@@ -115,43 +114,46 @@ def fatality(randomize=None, force_title=None, header=None, message=None, only_r
|
||||
task = scheduler.task(task_name)
|
||||
|
||||
if task.ready_for_display:
|
||||
task_state = "Running: %s/%s (%s%%)" % (task.items_done, task.items_searching, task.percentage)
|
||||
task_state = _("Running: %(items_done)s/%(items_searching)s (%(percentage)s%%)",
|
||||
items_done=task.items_done,
|
||||
items_searching=task.items_searching,
|
||||
percentage=task.percentage)
|
||||
else:
|
||||
lr = scheduler.last_run(task_name)
|
||||
nr = scheduler.next_run(task_name)
|
||||
task_state = "Last run: %s; Next scheduled run: %s; Last runtime: %s" % (
|
||||
task_state = _("Last run: %s; Next scheduled run: %s; Last runtime: %s",
|
||||
df(scheduler.last_run(task_name)) if lr else "never",
|
||||
df(scheduler.next_run(task_name)) if nr else "never",
|
||||
str(task.last_run_time).split(".")[0])
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(RefreshMissing, randomize=timestamp()),
|
||||
title="Search for missing subtitles (in recently-added items, max-age: %s)" % Prefs[
|
||||
"scheduler.item_is_recent_age"],
|
||||
summary="Automatically run periodically by the scheduler, if configured. %s" % task_state,
|
||||
title=_("Search for missing subtitles (in recently-added items, max-age: %s)", Prefs[
|
||||
"scheduler.item_is_recent_age"]),
|
||||
summary=_("Automatically run periodically by the scheduler, if configured. %s", task_state),
|
||||
thumb=R("icon-search.jpg")
|
||||
))
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(IgnoreListMenu),
|
||||
title="Display ignore list (%d)" % len(ignore_list),
|
||||
summary="Show the current ignore list (mainly used for the automatic tasks)",
|
||||
title=_("Display ignore list (%(ignored_count)d)", ignored_count=len(ignore_list)),
|
||||
summary=_("Show the current ignore list (mainly used for the automatic tasks)"),
|
||||
thumb=R("icon-ignore.jpg")
|
||||
))
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(HistoryMenu),
|
||||
title="History",
|
||||
summary="Show the last %i downloaded subtitles" % int(Prefs["history_size"]),
|
||||
title=_("History"),
|
||||
summary=_("Show the last %i downloaded subtitles", int(Prefs["history_size"])),
|
||||
thumb=R("icon-history.jpg")
|
||||
))
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(fatality, force_title=" ", randomize=timestamp()),
|
||||
title=pad_title("Refresh"),
|
||||
summary="Current state: %s; Last state: %s" % (
|
||||
(Dict["current_refresh_state"] or "Idle") if "current_refresh_state" in Dict else "Idle",
|
||||
(Dict["last_refresh_state"] or "None") if "last_refresh_state" in Dict else "None"
|
||||
title=pad_title(_("Refresh")),
|
||||
summary=_("Current state: %s; Last state: %s",
|
||||
(Dict["current_refresh_state"] or _("Idle")) if "current_refresh_state" in Dict else _("Idle"),
|
||||
(Dict["last_refresh_state"] or _("None")) if "last_refresh_state" in Dict else _("None")
|
||||
),
|
||||
thumb=R("icon-refresh.jpg")
|
||||
))
|
||||
@@ -160,8 +162,8 @@ def fatality(randomize=None, force_title=None, header=None, message=None, only_r
|
||||
if config.pin:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(ClearPin, randomize=timestamp()),
|
||||
title=pad_title("Re-lock menu(s)"),
|
||||
summary="Enabled the PIN again for menu(s)"
|
||||
title=pad_title(_("Re-lock menu(s)")),
|
||||
summary=_("Enabled the PIN again for menu(s)")
|
||||
))
|
||||
|
||||
if not only_refresh:
|
||||
@@ -169,19 +171,22 @@ def fatality(randomize=None, force_title=None, header=None, message=None, only_r
|
||||
summary_data = []
|
||||
for provider, data in Dict["provider_throttle"].iteritems():
|
||||
reason, until, desc = data
|
||||
summary_data.append("%s until %s (%s)" % (provider, until.strftime("%y/%m/%d %H:%M"), reason))
|
||||
summary_data.append(unicode(_("%(throttled_provider)s until %(until_date)s (%(reason)s)",
|
||||
throttled_provider=provider,
|
||||
until_date=until.strftime("%y/%m/%d %H:%M"),
|
||||
reason=reason)))
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(fatality, force_title=" ", randomize=timestamp()),
|
||||
title=pad_title("Throttled providers: %s" % ", ".join(Dict["provider_throttle"].keys())),
|
||||
title=pad_title(_("Throttled providers: %s", ", ".join(Dict["provider_throttle"].keys()))),
|
||||
summary=", ".join(summary_data),
|
||||
thumb=R("icon-throttled.jpg")
|
||||
))
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(AdvancedMenu),
|
||||
title=pad_title("Advanced functions"),
|
||||
summary="Use at your own risk",
|
||||
title=pad_title(_("Advanced functions")),
|
||||
summary=_("Use at your own risk"),
|
||||
thumb=R("icon-advanced.jpg")
|
||||
))
|
||||
|
||||
@@ -195,12 +200,12 @@ def OnDeckMenu(message=None):
|
||||
:param message:
|
||||
:return:
|
||||
"""
|
||||
return mergedItemsMenu(title="Items On Deck", base_title="Items On Deck", itemGetter=get_on_deck_items)
|
||||
return mergedItemsMenu(title=_("Items On Deck"), base_title=_("Items On Deck"), itemGetter=get_on_deck_items)
|
||||
|
||||
|
||||
@route(PREFIX + '/recently_played')
|
||||
def RecentlyPlayedMenu():
|
||||
base_title = "Recently Played"
|
||||
base_title = _("Recently Played")
|
||||
oc = SubFolderObjectContainer(title2=base_title, replace_parent=True)
|
||||
|
||||
for item in [get_item(rating_key) for rating_key in Dict["last_played_items"]]:
|
||||
@@ -228,13 +233,13 @@ def RecentlyAddedMenu(message=None):
|
||||
:param message:
|
||||
:return:
|
||||
"""
|
||||
return SectionsMenu(base_title="Recently added", section_items_key="recently_added", ignore_options=False)
|
||||
return SectionsMenu(base_title=_("Recently added"), section_items_key="recently_added", ignore_options=False)
|
||||
|
||||
|
||||
@route(PREFIX + '/recent', force=bool)
|
||||
@debounce
|
||||
def RecentMissingSubtitlesMenu(force=False, randomize=None):
|
||||
title = "Items with missing subtitles"
|
||||
title = _("Items with missing subtitles")
|
||||
oc = SubFolderObjectContainer(title2=title, no_cache=True, no_history=True)
|
||||
|
||||
running = scheduler.is_task_running("MissingSubtitles")
|
||||
@@ -248,13 +253,13 @@ def RecentMissingSubtitlesMenu(force=False, randomize=None):
|
||||
if not running:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(RecentMissingSubtitlesMenu, force=True, randomize=timestamp()),
|
||||
title=u"Find recent items with missing subtitles",
|
||||
title=_(u"Find recent items with missing subtitles"),
|
||||
thumb=default_thumb
|
||||
))
|
||||
else:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(RecentMissingSubtitlesMenu, force=False, randomize=timestamp()),
|
||||
title=u"Updating, refresh here ...",
|
||||
title=_(u"Updating, refresh here ..."),
|
||||
thumb=default_thumb
|
||||
))
|
||||
|
||||
@@ -264,7 +269,7 @@ def RecentMissingSubtitlesMenu(force=False, randomize=None):
|
||||
key=Callback(ItemDetailsMenu, title=title + " > " + item_title, item_title=item_title,
|
||||
rating_key=item_id),
|
||||
title=item_title,
|
||||
summary="Missing: %s" % ", ".join(display_language(l) for l in missing_languages),
|
||||
summary=_("Missing: %s", ", ".join(display_language(l) for l in missing_languages)),
|
||||
thumb=get_item_thumb(item) or default_thumb
|
||||
))
|
||||
|
||||
@@ -322,18 +327,25 @@ def IgnoreMenu(kind, rating_key, title=None, sure=False, todo="not_set"):
|
||||
"""
|
||||
is_ignored = rating_key in ignore_list[kind]
|
||||
if not sure:
|
||||
oc = SubFolderObjectContainer(no_history=True, replace_parent=True, title1="%s %s %s %s the ignore list" % (
|
||||
"Add" if not is_ignored else "Remove", ignore_list.verbose(kind), title,
|
||||
"to" if not is_ignored else "from"), title2="Are you sure?")
|
||||
t = u"Add %(kind)s %(title)s to the ignore list"
|
||||
if is_ignored:
|
||||
t = u"Remove %(kind)s %(title)s from the ignore list"
|
||||
oc = SubFolderObjectContainer(no_history=True, replace_parent=True,
|
||||
title1=_(t,
|
||||
kind=ignore_list.verbose(kind),
|
||||
title=title
|
||||
),
|
||||
title2=_("Are you sure?"))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(IgnoreMenu, kind=kind, rating_key=rating_key, title=title, sure=True,
|
||||
todo="add" if not is_ignored else "remove"),
|
||||
title=pad_title("Are you sure?"),
|
||||
title=pad_title(_("Are you sure?")),
|
||||
))
|
||||
return oc
|
||||
|
||||
rel = ignore_list[kind]
|
||||
dont_change = False
|
||||
state = None
|
||||
if todo == "remove":
|
||||
if not is_ignored:
|
||||
dont_change = True
|
||||
@@ -342,7 +354,6 @@ def IgnoreMenu(kind, rating_key, title=None, sure=False, todo="not_set"):
|
||||
Log.Info("Removed %s (%s) from the ignore list", title, rating_key)
|
||||
ignore_list.remove_title(kind, rating_key)
|
||||
ignore_list.save()
|
||||
state = "removed from"
|
||||
elif todo == "add":
|
||||
if is_ignored:
|
||||
dont_change = True
|
||||
@@ -351,25 +362,29 @@ def IgnoreMenu(kind, rating_key, title=None, sure=False, todo="not_set"):
|
||||
Log.Info("Added %s (%s) to the ignore list", title, rating_key)
|
||||
ignore_list.add_title(kind, rating_key, title)
|
||||
ignore_list.save()
|
||||
state = "added to"
|
||||
else:
|
||||
dont_change = True
|
||||
|
||||
if dont_change:
|
||||
return fatality(force_title=" ", header="Didn't change the ignore list", no_history=True)
|
||||
return fatality(force_title=" ", header=_("Didn't change the ignore list"), no_history=True)
|
||||
|
||||
return fatality(force_title=" ", header="%s %s the ignore list" % (title, state), no_history=True)
|
||||
t = "%(title)s added to the ignore list"
|
||||
if todo == "remove":
|
||||
t = "%(title)s removed from the ignore list"
|
||||
return fatality(force_title=" ", header=_(t,
|
||||
title=title,),
|
||||
no_history=True)
|
||||
|
||||
|
||||
@route(PREFIX + '/sections')
|
||||
def SectionsMenu(base_title="Sections", section_items_key="all", ignore_options=True):
|
||||
def SectionsMenu(base_title=_("Sections"), section_items_key="all", ignore_options=True):
|
||||
"""
|
||||
displays the menu for all sections
|
||||
:return:
|
||||
"""
|
||||
items = get_all_items("sections")
|
||||
|
||||
return dig_tree(SubFolderObjectContainer(title2="Sections", no_cache=True, no_history=True), items, None,
|
||||
return dig_tree(SubFolderObjectContainer(title2=_("Sections"), no_cache=True, no_history=True), items, None,
|
||||
menu_determination_callback=determine_section_display, pass_kwargs={"base_title": base_title,
|
||||
"section_items_key": section_items_key,
|
||||
"ignore_options": ignore_options},
|
||||
@@ -430,7 +445,7 @@ def SectionFirstLetterMenu(rating_key, title=None, base_title=None, section_titl
|
||||
add_ignore_options(oc, "sections", title=section_title, rating_key=rating_key, callback_menu=IgnoreMenu)
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SectionMenu, title="All", base_title=title, rating_key=rating_key, ignore_options=False),
|
||||
key=Callback(SectionMenu, title=_("All"), base_title=title, rating_key=rating_key, ignore_options=False),
|
||||
title="All"
|
||||
)
|
||||
)
|
||||
|
||||
@@ -24,6 +24,7 @@ from support.helpers import timestamp, df, display_language
|
||||
from support.ignore import ignore_list
|
||||
from support.items import get_all_items, get_items_info, get_item_kind_from_rating_key, get_item, MI_KEY, get_item_title
|
||||
from support.storage import get_subtitle_storage
|
||||
from support.i18n import _
|
||||
|
||||
# init GUI
|
||||
ObjectContainer.art = R(ART)
|
||||
@@ -89,7 +90,7 @@ def MetadataMenu(rating_key, title=None, base_title=None, display_items=False, p
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(MetadataMenu, rating_key=show.rating_key, title=show.title, base_title=show.section.title,
|
||||
previous_item_type="section", display_items=True, randomize=timestamp()),
|
||||
title=u"< Back to %s" % show.title,
|
||||
title=_(u"< Back to %s", show.title),
|
||||
thumb=show.thumb or default_thumb
|
||||
))
|
||||
elif current_kind == "series":
|
||||
@@ -117,9 +118,9 @@ def MetadataMenu(rating_key, title=None, base_title=None, display_items=False, p
|
||||
title=title,
|
||||
previous_item_type=previous_item_type, with_mods=True,
|
||||
previous_rating_key=previous_rating_key, randomize=timestamp()),
|
||||
title=u"Extract missing %s embedded subtitles" % display_language(lang),
|
||||
summary="Extracts the not yet extracted embedded subtitles of all episodes for the current season "
|
||||
"with all configured default modifications"
|
||||
title=_(u"Extract missing %(language)s embedded subtitles", language=display_language(lang)),
|
||||
summary=_("Extracts the not yet extracted embedded subtitles of all episodes for the current "
|
||||
"season with all configured default modifications")
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SeasonExtractEmbedded, rating_key=rating_key, language=lang,
|
||||
@@ -127,24 +128,25 @@ def MetadataMenu(rating_key, title=None, base_title=None, display_items=False, p
|
||||
title=title, force=True,
|
||||
previous_item_type=previous_item_type, with_mods=True,
|
||||
previous_rating_key=previous_rating_key, randomize=timestamp()),
|
||||
title=u"Extract and activate %s embedded subtitles" % display_language(lang),
|
||||
summary="Extracts embedded subtitles of all episodes for the current season "
|
||||
"with all configured default modifications"
|
||||
title=_(u"Extract and activate %(language)s embedded subtitles", language=display_language(lang)),
|
||||
summary=_("Extracts embedded subtitles of all episodes for the current season "
|
||||
"with all configured default modifications")
|
||||
))
|
||||
|
||||
# add refresh
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(RefreshItem, rating_key=rating_key, item_title=title, refresh_kind=current_kind,
|
||||
previous_rating_key=previous_rating_key, timeout=timeout * 1000, randomize=timestamp()),
|
||||
title=u"Refresh: %s" % item_title,
|
||||
summary="Refreshes the %s, possibly searching for missing and picking up new subtitles on disk" % current_kind
|
||||
title=_(u"Refresh: %s", item_title),
|
||||
summary=_("Refreshes %(the_movie_series_season_episode)s, possibly searching for missing and picking up "
|
||||
"new subtitles on disk", the_movie_series_season_episode=_(u"the %s" % current_kind))
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(RefreshItem, rating_key=rating_key, item_title=title, force=True,
|
||||
refresh_kind=current_kind, previous_rating_key=previous_rating_key, timeout=timeout * 1000,
|
||||
randomize=timestamp()),
|
||||
title=u"Auto-Find subtitles: %s" % item_title,
|
||||
summary="Issues a forced refresh, ignoring known subtitles and searching for new ones"
|
||||
title=_(u"Auto-Find subtitles: %s", item_title),
|
||||
summary=_("Issues a forced refresh, ignoring known subtitles and searching for new ones")
|
||||
))
|
||||
else:
|
||||
return ItemDetailsMenu(rating_key=rating_key, title=title, item_title=item_title)
|
||||
@@ -164,8 +166,8 @@ def SeasonExtractEmbedded(**kwargs):
|
||||
Thread.Create(season_extract_embedded, **{"rating_key": rating_key, "requested_language": requested_language,
|
||||
"with_mods": with_mods, "force": force})
|
||||
|
||||
kwargs["header"] = 'Success'
|
||||
kwargs["message"] = u"Extracting of embedded subtitles for %s triggered" % title
|
||||
kwargs["header"] = _("Success")
|
||||
kwargs["message"] = _(u"Extracting of embedded subtitles for %s triggered", title)
|
||||
|
||||
kwargs.pop("randomize")
|
||||
return MetadataMenu(randomize=timestamp(), title=item_title, **kwargs)
|
||||
@@ -231,7 +233,7 @@ def IgnoreListMenu():
|
||||
def HistoryMenu():
|
||||
from support.history import get_history
|
||||
history = get_history()
|
||||
oc = SubFolderObjectContainer(title2="History", replace_parent=True)
|
||||
oc = SubFolderObjectContainer(title2=_("History"), replace_parent=True)
|
||||
|
||||
for item in history.items:
|
||||
possible_language = item.language
|
||||
@@ -241,7 +243,7 @@ def HistoryMenu():
|
||||
key=Callback(ItemDetailsMenu, title=item.title, item_title=item.item_title,
|
||||
rating_key=item.rating_key),
|
||||
title=u"%s (%s)" % (item.item_title, item.mode_verbose),
|
||||
summary=u"%s in %s (%s, score: %s), %s" % (language_display, item.section_title,
|
||||
summary=_(u"%s in %s (%s, score: %s), %s", language_display, item.section_title,
|
||||
item.provider_name, item.score, df(item.time))
|
||||
))
|
||||
|
||||
@@ -290,20 +292,20 @@ def ValidatePrefs():
|
||||
update_dict = True
|
||||
|
||||
elif Dict["channel_enabled"] != config.enable_channel:
|
||||
Log.Debug("Channel features %s, restarting plugin", "enabled" if config.enable_channel else "disabled")
|
||||
Log.Debug("Interface features %s, restarting plugin", "enabled" if config.enable_channel else "disabled")
|
||||
update_dict = True
|
||||
restart = True
|
||||
|
||||
if "plugin_pin_mode" not in Dict:
|
||||
if "plugin_pin_mode2" not in Dict:
|
||||
update_dict = True
|
||||
|
||||
elif Dict["plugin_pin_mode"] != Prefs["plugin_pin_mode"]:
|
||||
elif Dict["plugin_pin_mode2"] != Prefs["plugin_pin_mode2"]:
|
||||
update_dict = True
|
||||
restart = True
|
||||
|
||||
if update_dict:
|
||||
Dict["channel_enabled"] = config.enable_channel
|
||||
Dict["plugin_pin_mode"] = Prefs["plugin_pin_mode"]
|
||||
Dict["plugin_pin_mode2"] = Prefs["plugin_pin_mode2"]
|
||||
Dict.Save()
|
||||
|
||||
if restart:
|
||||
@@ -323,7 +325,7 @@ def ValidatePrefs():
|
||||
"version", "app_support_path", "data_path", "data_items_path", "enable_agent",
|
||||
"enable_channel", "permissions_ok", "missing_permissions", "fs_encoding",
|
||||
"subtitle_destination_folder", "new_style_cache", "dbm_supported", "lang_list", "providers",
|
||||
"plex_transcoder", "refiner_settings"]:
|
||||
"plex_transcoder", "refiner_settings", "unrar", "adv_cfg_path"]:
|
||||
|
||||
value = getattr(config, attr)
|
||||
if isinstance(value, dict):
|
||||
|
||||
@@ -4,9 +4,11 @@ import types
|
||||
import datetime
|
||||
import subprocess
|
||||
import os
|
||||
import operator
|
||||
|
||||
from func import enable_channel_wrapper
|
||||
from func import enable_channel_wrapper, route_wrapper, register_route_function
|
||||
from subzero.language import Language
|
||||
from support.i18n import is_localized_string, _
|
||||
from support.items import get_kind, get_item_thumb, get_item, get_item_kind_from_item, refresh_item
|
||||
from support.helpers import get_video_display_title, pad_title, display_language, quote_args, is_stream_forced
|
||||
from support.ignore import ignore_list
|
||||
@@ -24,7 +26,7 @@ default_thumb = R(ICON_SUB)
|
||||
main_icon = ICON if not config.is_development else "icon-dev.jpg"
|
||||
|
||||
# noinspection PyUnboundLocalVariable
|
||||
route = enable_channel_wrapper(route)
|
||||
route = route_wrapper
|
||||
# noinspection PyUnboundLocalVariable
|
||||
handler = enable_channel_wrapper(handler)
|
||||
|
||||
@@ -48,10 +50,15 @@ def add_ignore_options(oc, kind, callback_menu=None, title=None, rating_key=None
|
||||
|
||||
in_list = rating_key in ignore_list[use_kind]
|
||||
|
||||
t = u"Ignore %(kind)s \"%(title)s\""
|
||||
if in_list:
|
||||
t = u"Un-ignore %(kind)s \"%(title)s\""
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(callback_menu, kind=use_kind, rating_key=rating_key, title=title),
|
||||
title=u"%s %s \"%s\"" % (
|
||||
"Un-Ignore" if in_list else "Ignore", ignore_list.verbose(kind) if add_kind else "", unicode(title))
|
||||
key=Callback(callback_menu, kind=use_kind, sure=False, todo="not_set", rating_key=rating_key, title=title),
|
||||
title=_(t,
|
||||
kind=ignore_list.verbose(kind) if add_kind else "",
|
||||
title=unicode(title))
|
||||
)
|
||||
)
|
||||
|
||||
@@ -91,8 +98,8 @@ def set_refresh_menu_state(state_or_media, media_type="movies"):
|
||||
Dict["current_refresh_state"] = None
|
||||
return
|
||||
|
||||
if isinstance(state_or_media, types.StringTypes):
|
||||
Dict["current_refresh_state"] = state_or_media
|
||||
if isinstance(state_or_media, types.StringTypes) or is_localized_string(state_or_media):
|
||||
Dict["current_refresh_state"] = unicode(state_or_media)
|
||||
return
|
||||
|
||||
media = state_or_media
|
||||
@@ -103,14 +110,19 @@ def set_refresh_menu_state(state_or_media, media_type="movies"):
|
||||
for episode in media.seasons[season].episodes:
|
||||
ep = media.seasons[season].episodes[episode]
|
||||
media_id = ep.id
|
||||
title = get_video_display_title("show", ep.title, parent_title=media.title, season=int(season), episode=int(episode))
|
||||
title = get_video_display_title(_("show"), ep.title, parent_title=media.title, season=int(season), episode=int(episode))
|
||||
else:
|
||||
title = get_video_display_title("movie", media.title)
|
||||
title = get_video_display_title(_("movie"), media.title)
|
||||
|
||||
intent = get_intent()
|
||||
force_refresh = intent.get("force", media_id)
|
||||
|
||||
Dict["current_refresh_state"] = u"%sRefreshing %s" % ("Force-" if force_refresh else "", unicode(title))
|
||||
t = u"Refreshing %(title)s"
|
||||
if force_refresh:
|
||||
t = u"Force-refreshing %(title)s"
|
||||
|
||||
Dict["current_refresh_state"] = unicode(_(t,
|
||||
title=unicode(title)))
|
||||
|
||||
|
||||
def get_item_task_data(task_name, rating_key, language):
|
||||
@@ -125,30 +137,10 @@ def debounce(func):
|
||||
:param func:
|
||||
:return:
|
||||
"""
|
||||
def get_lookup_key(args, kwargs):
|
||||
func_name = list(args).pop(0).__name__
|
||||
return tuple([func_name] + [(key, value) for key, value in kwargs.iteritems()])
|
||||
|
||||
def wrap(*args, **kwargs):
|
||||
if "randomize" in kwargs:
|
||||
if "menu_history" not in Dict:
|
||||
Dict["menu_history"] = {}
|
||||
func.debounce = True
|
||||
|
||||
key = get_lookup_key([func] + list(args), kwargs)
|
||||
if key in Dict["menu_history"]:
|
||||
Log.Debug("not triggering %s twice with %s, %s" % (func, args, kwargs))
|
||||
return ObjectContainer()
|
||||
else:
|
||||
Dict["menu_history"][key] = datetime.datetime.now() + datetime.timedelta(hours=6)
|
||||
try:
|
||||
Dict.Save()
|
||||
except TypeError:
|
||||
Log.Error("Can't save menu history for: %r", key)
|
||||
del Dict["menu_history"][key]
|
||||
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return wrap
|
||||
return func
|
||||
|
||||
|
||||
def extract_embedded_sub(**kwargs):
|
||||
@@ -178,7 +170,9 @@ def extract_embedded_sub(**kwargs):
|
||||
is_forced = is_stream_forced(stream)
|
||||
bn = os.path.basename(part.file)
|
||||
|
||||
set_refresh_menu_state(u"Extracting subtitle %s of %s" % (stream_index, bn))
|
||||
set_refresh_menu_state(_(u"Extracting subtitle %(stream_index)s of %(filename)s",
|
||||
stream_index=stream_index,
|
||||
filename=bn))
|
||||
Log.Info(u"Extracting stream %s (%s) of %s", stream_index, display_language(language), bn)
|
||||
|
||||
out_codec = stream.codec if stream.codec != "mov_text" else "srt"
|
||||
@@ -244,10 +238,10 @@ class SubFolderObjectContainer(ObjectContainer):
|
||||
from support.helpers import pad_title, timestamp
|
||||
self.add(DirectoryObject(
|
||||
key=Callback(fatality, force_title=" ", randomize=timestamp()),
|
||||
title=pad_title("<< Back to home"),
|
||||
summary="Current state: %s; Last state: %s" % (
|
||||
(Dict["current_refresh_state"] or "Idle") if "current_refresh_state" in Dict else "Idle",
|
||||
(Dict["last_refresh_state"] or "None") if "last_refresh_state" in Dict else "None"
|
||||
title=pad_title(_("<< Back to home")),
|
||||
summary=_("Current state: %s; Last state: %s",
|
||||
(Dict["current_refresh_state"] or _("Idle")) if "current_refresh_state" in Dict else _("Idle"),
|
||||
(Dict["last_refresh_state"] or _("None")) if "last_refresh_state" in Dict else _("None")
|
||||
)
|
||||
))
|
||||
|
||||
@@ -265,4 +259,4 @@ class ZipObject(ObjectClass):
|
||||
self.SetHeader("Content-Disposition",
|
||||
'attachment; filename="' + datetime.datetime.now().strftime("Logs_%y%m%d_%H-%M-%S.zip")
|
||||
+ '"')
|
||||
return self.zipdata
|
||||
return self.zipdata
|
||||
|
||||
@@ -4,6 +4,7 @@ from subzero.constants import PREFIX
|
||||
from menu_helpers import debounce, set_refresh_menu_state, route
|
||||
from support.items import refresh_item
|
||||
from support.helpers import timestamp
|
||||
from support.i18n import _
|
||||
|
||||
|
||||
@route(PREFIX + '/item/refresh/{rating_key}/force', force=True)
|
||||
@@ -15,9 +16,17 @@ def RefreshItem(rating_key=None, came_from="/recent", item_title=None, force=Fal
|
||||
from interface.main import fatality
|
||||
header = " "
|
||||
if trigger:
|
||||
set_refresh_menu_state(u"Triggering %sRefresh for %s" % ("Force-" if force else "", item_title))
|
||||
t = u"Triggering refresh for %(title)s"
|
||||
if force:
|
||||
u"Triggering forced refresh for %(title)s"
|
||||
set_refresh_menu_state(_(t,
|
||||
title=item_title))
|
||||
Thread.Create(refresh_item, rating_key=rating_key, force=force, refresh_kind=refresh_kind,
|
||||
parent_rating_key=previous_rating_key, timeout=int(timeout))
|
||||
|
||||
header = u"%s of item %s triggered" % ("Refresh" if not force else "Forced-refresh", rating_key)
|
||||
t = u"Refresh of item %(item_id)s triggered"
|
||||
if force:
|
||||
t = u"Forced refresh of item %(item_id)s triggered"
|
||||
header = _(t,
|
||||
item_id=rating_key)
|
||||
return fatality(randomize=timestamp(), header=header, replace_parent=True)
|
||||
|
||||
@@ -12,10 +12,10 @@ from support.plex_media import get_plex_metadata
|
||||
from support.scanning import scan_videos
|
||||
from support.helpers import timestamp, pad_title
|
||||
from support.items import get_current_sub, set_mods_for_part
|
||||
from support.i18n import _
|
||||
|
||||
|
||||
@route(PREFIX + '/item/sub_mods/{rating_key}/{part_id}', force=bool)
|
||||
@debounce
|
||||
def SubtitleModificationsMenu(**kwargs):
|
||||
rating_key = kwargs["rating_key"]
|
||||
part_id = kwargs["part_id"]
|
||||
@@ -31,8 +31,8 @@ def SubtitleModificationsMenu(**kwargs):
|
||||
from interface.item_details import SubtitleOptionsMenu
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleOptionsMenu, randomize=timestamp(), **kwargs),
|
||||
title=u"< Back to subtitle options for: %s" % kwargs["title"],
|
||||
summary=kwargs["current_data"],
|
||||
title=_(u"< Back to subtitle options for: %s", kwargs["title"]),
|
||||
summary=unicode(kwargs["current_data"]),
|
||||
thumb=default_thumb
|
||||
))
|
||||
|
||||
@@ -48,48 +48,48 @@ def SubtitleModificationsMenu(**kwargs):
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleSetMods, mods=identifier, mode="add", randomize=timestamp(), **kwargs),
|
||||
title=pad_title(mod.description), summary=mod.long_description or ""
|
||||
title=pad_title(_(mod.description)), summary=_(mod.long_description) or ""
|
||||
))
|
||||
|
||||
fps_mod = SubtitleModifications.get_mod_class("change_FPS")
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleFPSModMenu, randomize=timestamp(), **kwargs),
|
||||
title=pad_title(fps_mod.description), summary=fps_mod.long_description or ""
|
||||
title=pad_title(_(fps_mod.description)), summary=_(fps_mod.long_description) or ""
|
||||
))
|
||||
|
||||
shift_mod = SubtitleModifications.get_mod_class("shift_offset")
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleShiftModUnitMenu, randomize=timestamp(), **kwargs),
|
||||
title=pad_title(shift_mod.description), summary=shift_mod.long_description or ""
|
||||
title=pad_title(_(shift_mod.description)), summary=_(shift_mod.long_description) or ""
|
||||
))
|
||||
|
||||
color_mod = SubtitleModifications.get_mod_class("color")
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleColorModMenu, randomize=timestamp(), **kwargs),
|
||||
title=pad_title(color_mod.description), summary=color_mod.long_description or ""
|
||||
title=pad_title(_(color_mod.description)), summary=_(color_mod.long_description) or ""
|
||||
))
|
||||
|
||||
if current_mods:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleSetMods, mods=None, mode="remove_last", randomize=timestamp(), **kwargs),
|
||||
title=pad_title("Remove last applied mod (%s)" % current_mods[-1]),
|
||||
summary=u"Currently applied mods: %s" % (", ".join(current_mods) if current_mods else "none")
|
||||
title=pad_title(_("Remove last applied mod (%s)", current_mods[-1])),
|
||||
summary=_(u"Currently applied mods: %(mod_list)s", mod_list=", ".join(current_mods) if current_mods else _("none"))
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleListMods, randomize=timestamp(), **kwargs),
|
||||
title=pad_title("Manage applied mods"),
|
||||
summary=u"Currently applied mods: %s" % (", ".join(current_mods))
|
||||
title=pad_title(_("Manage applied mods")),
|
||||
summary=_(u"Currently applied mods: %(mod_list)s", mod_list=", ".join(current_mods))
|
||||
))
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleReapplyMods, randomize=timestamp(), **kwargs),
|
||||
title=pad_title("Reapply applied mods"),
|
||||
summary=u"Currently applied mods: %s" % (", ".join(current_mods) if current_mods else "none")
|
||||
title=pad_title(_("Reapply applied mods")),
|
||||
summary=_(u"Currently applied mods: %(mod_list)s", mod_list=", ".join(current_mods) if current_mods else _("none"))
|
||||
))
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleSetMods, mods=None, mode="clear", randomize=timestamp(), **kwargs),
|
||||
title=pad_title("Restore original version"),
|
||||
summary=u"Currently applied mods: %s" % (", ".join(current_mods) if current_mods else "none")
|
||||
title=pad_title(_("Restore original version")),
|
||||
summary=_(u"Currently applied mods: %(mod_list)s", mod_list=", ".join(current_mods) if current_mods else _("none"))
|
||||
))
|
||||
|
||||
storage.destroy()
|
||||
@@ -109,7 +109,7 @@ def SubtitleFPSModMenu(**kwargs):
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleModificationsMenu, randomize=timestamp(), **kwargs),
|
||||
title="< Back to subtitle modification menu"
|
||||
title=_("< Back to subtitle modification menu")
|
||||
))
|
||||
|
||||
metadata = get_plex_metadata(rating_key, part_id, item_type)
|
||||
@@ -123,14 +123,17 @@ def SubtitleFPSModMenu(**kwargs):
|
||||
continue
|
||||
|
||||
if float(fps) > float(target_fps):
|
||||
indicator = "subs constantly getting faster"
|
||||
indicator = _("subs constantly getting faster")
|
||||
else:
|
||||
indicator = "subs constantly getting slower"
|
||||
indicator = _("subs constantly getting slower")
|
||||
|
||||
mod_ident = SubtitleModifications.get_mod_signature("change_FPS", **{"from": fps, "to": target_fps})
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleSetMods, mods=mod_ident, mode="add", randomize=timestamp(), **kwargs),
|
||||
title="%s fps -> %s fps (%s)" % (fps, target_fps, indicator)
|
||||
title=_("%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)",
|
||||
from_fps=fps,
|
||||
to_fps=target_fps,
|
||||
slower_or_faster_indicator=indicator)
|
||||
))
|
||||
|
||||
return oc
|
||||
@@ -148,13 +151,13 @@ def SubtitleShiftModUnitMenu(**kwargs):
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleModificationsMenu, randomize=timestamp(), **kwargs),
|
||||
title="< Back to subtitle modifications"
|
||||
title=_("< Back to subtitle modifications")
|
||||
))
|
||||
|
||||
for unit, title in POSSIBLE_UNITS:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleShiftModMenu, unit=unit, randomize=timestamp(), **kwargs),
|
||||
title="Adjust by %s" % title
|
||||
title=_("Adjust by %(time_and_unit)s", time_and_unit=title)
|
||||
))
|
||||
|
||||
return oc
|
||||
@@ -171,7 +174,7 @@ def SubtitleShiftModMenu(unit=None, **kwargs):
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleShiftModUnitMenu, randomize=timestamp(), **kwargs),
|
||||
title="< Back to unit selection"
|
||||
title=_("< Back to unit selection")
|
||||
))
|
||||
|
||||
rng = []
|
||||
@@ -205,7 +208,7 @@ def SubtitleColorModMenu(**kwargs):
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleModificationsMenu, randomize=timestamp(), **kwargs),
|
||||
title="< Back to subtitle modification menu"
|
||||
title=_("< Back to subtitle modification menu")
|
||||
))
|
||||
|
||||
for color, code in color_mod.colors.iteritems():
|
||||
@@ -267,13 +270,13 @@ def SubtitleListMods(**kwargs):
|
||||
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleModificationsMenu, randomize=timestamp(), **kwargs),
|
||||
title="< Back to subtitle modifications"
|
||||
title=_("< Back to subtitle modifications")
|
||||
))
|
||||
|
||||
for identifier in current_sub.mods:
|
||||
oc.add(DirectoryObject(
|
||||
key=Callback(SubtitleSetMods, mods=identifier, mode="remove", randomize=timestamp(), **kwargs),
|
||||
title="Remove: %s" % identifier
|
||||
title=_("Remove: %(mod_name)s", mod_name=identifier)
|
||||
))
|
||||
|
||||
storage.destroy()
|
||||
|
||||
@@ -13,6 +13,12 @@ import lib
|
||||
|
||||
sys.modules["support.lib"] = lib
|
||||
|
||||
import i18n
|
||||
|
||||
sys.modules["support.i18n"] = i18n
|
||||
|
||||
helpers._ = i18n._
|
||||
|
||||
import plex_media
|
||||
sys.modules["support.plex_media"] = plex_media
|
||||
|
||||
|
||||
+107
-25
@@ -12,7 +12,7 @@ import subliminal
|
||||
import subliminal_patch
|
||||
import subzero.constants
|
||||
import lib
|
||||
from subliminal.exceptions import ServiceUnavailable, DownloadLimitExceeded
|
||||
from subliminal.exceptions import ServiceUnavailable, DownloadLimitExceeded, AuthenticationError
|
||||
|
||||
from subliminal_patch.core import is_windows_special_path
|
||||
from whichdb import whichdb
|
||||
@@ -69,7 +69,8 @@ PROVIDER_THROTTLE_MAP = {
|
||||
DownloadLimitExceeded: (datetime.timedelta(hours=6), "6 hours"),
|
||||
},
|
||||
"addic7ed": {
|
||||
DownloadLimitExceeded: (datetime.timedelta(hours=24), "24 hours"),
|
||||
DownloadLimitExceeded: (datetime.timedelta(hours=3), "3 hours"),
|
||||
TooManyRequests: (datetime.timedelta(minutes=5), "5 minutes"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +94,7 @@ class Config(object):
|
||||
new_style_cache = False
|
||||
pack_cache_dir = None
|
||||
advanced = None
|
||||
debug_i18n = False
|
||||
|
||||
enable_channel = True
|
||||
enable_agent = True
|
||||
@@ -135,6 +137,8 @@ class Config(object):
|
||||
only_one = False
|
||||
embedded_auto_extract = False
|
||||
ietf_as_alpha3 = False
|
||||
unrar = None
|
||||
adv_cfg_path = None
|
||||
|
||||
store_recently_played_amount = 40
|
||||
|
||||
@@ -165,6 +169,7 @@ class Config(object):
|
||||
self.new_style_cache = cast_bool(Prefs['new_style_cache'])
|
||||
self.pack_cache_dir = self.get_pack_cache_dir()
|
||||
self.advanced = self.get_advanced_config()
|
||||
self.debug_i18n = self.advanced.debug_i18n
|
||||
|
||||
os.environ["SZ_USER_AGENT"] = self.get_user_agent()
|
||||
|
||||
@@ -206,16 +211,44 @@ class Config(object):
|
||||
self.initialized = True
|
||||
|
||||
def init_libraries(self):
|
||||
try_executables = []
|
||||
custom_unrar = os.environ.get("SZ_UNRAR_TOOL")
|
||||
if custom_unrar:
|
||||
if os.path.isfile(custom_unrar):
|
||||
try_executables.append(custom_unrar)
|
||||
|
||||
unrar_exe = None
|
||||
if Core.runtime.os == "Windows":
|
||||
unrar_exe = os.path.abspath(os.path.join(self.libraries_root, "Windows", "i386", "UnRAR", "UnRAR.exe"))
|
||||
if os.path.isfile(unrar_exe):
|
||||
rarfile.UNRAR_TOOL = unrar_exe
|
||||
Log.Info("Using UnRAR from: %s", unrar_exe)
|
||||
|
||||
custom_unrar = os.environ.get("SZ_UNRAR_TOOL")
|
||||
if custom_unrar and os.path.isfile(custom_unrar):
|
||||
rarfile.UNRAR_TOOL = custom_unrar
|
||||
Log.Info("Using UnRAR from: %s", custom_unrar)
|
||||
elif Core.runtime.os == "MacOSX":
|
||||
unrar_exe = os.path.abspath(os.path.join(self.libraries_root, "MacOSX", "i386", "UnRAR", "unrar"))
|
||||
|
||||
elif Core.runtime.os == "Linux":
|
||||
unrar_exe = os.path.abspath(os.path.join(self.libraries_root, "Linux", Core.runtime.cpu, "UnRAR", "unrar"))
|
||||
|
||||
if unrar_exe and os.path.isfile(unrar_exe):
|
||||
try_executables.append(unrar_exe)
|
||||
|
||||
try_executables.append("unrar")
|
||||
|
||||
for exe in try_executables:
|
||||
rarfile.UNRAR_TOOL = exe
|
||||
rarfile.ORIG_UNRAR_TOOL = exe
|
||||
try:
|
||||
rarfile.custom_check([rarfile.UNRAR_TOOL], True)
|
||||
except:
|
||||
Log.Debug("custom check failed for: %s", exe)
|
||||
continue
|
||||
|
||||
rarfile.OPEN_ARGS = rarfile.ORIG_OPEN_ARGS
|
||||
rarfile.EXTRACT_ARGS = rarfile.ORIG_EXTRACT_ARGS
|
||||
rarfile.TEST_ARGS = rarfile.ORIG_TEST_ARGS
|
||||
Log.Info("Using UnRAR from: %s", exe)
|
||||
self.unrar = exe
|
||||
return
|
||||
|
||||
Log.Warn("UnRAR not found")
|
||||
|
||||
def init_cache(self):
|
||||
if self.new_style_cache:
|
||||
@@ -284,11 +317,23 @@ class Config(object):
|
||||
return pack_cache_dir
|
||||
|
||||
def get_advanced_config(self):
|
||||
path = os.path.join(config.data_path, "advanced_settings.json")
|
||||
if os.path.isfile(path):
|
||||
data = FileIO.read(path, "r")
|
||||
paths = []
|
||||
if Prefs['path_to_advanced_settings']:
|
||||
paths = [
|
||||
Prefs['path_to_advanced_settings'],
|
||||
os.path.join(Prefs['path_to_advanced_settings'], "advanced_settings.json")
|
||||
]
|
||||
|
||||
return Dicked(**jstyleson.loads(data))
|
||||
paths.append(os.path.join(config.data_path, "advanced_settings.json"))
|
||||
|
||||
for path in paths:
|
||||
if os.path.isfile(path):
|
||||
data = FileIO.read(path, "r")
|
||||
|
||||
d = Dicked(**jstyleson.loads(data))
|
||||
self.adv_cfg_path = path
|
||||
Log.Info(u"Using advanced settings from: %s", path)
|
||||
return d
|
||||
|
||||
return Dicked()
|
||||
|
||||
@@ -331,16 +376,16 @@ class Config(object):
|
||||
if not self.providers:
|
||||
self.enable_agent = False
|
||||
self.enable_channel = False
|
||||
Log.Warn("No providers enabled, disabling agent and channel!")
|
||||
Log.Warn("No providers enabled, disabling agent and interface!")
|
||||
return
|
||||
|
||||
if Prefs["plugin_mode"] == "only agent":
|
||||
if Prefs["plugin_mode2"] == "only agent":
|
||||
self.enable_channel = False
|
||||
elif Prefs["plugin_mode"] == "only channel":
|
||||
elif Prefs["plugin_mode2"] == "only interface":
|
||||
self.enable_agent = False
|
||||
|
||||
def set_plugin_lock(self):
|
||||
if Prefs["plugin_pin_mode"] in ("channel menu", "advanced menu"):
|
||||
if Prefs["plugin_pin_mode2"] in ("interface", "advanced menu"):
|
||||
# check pin
|
||||
pin = Prefs["plugin_pin"]
|
||||
if not pin or not len(pin):
|
||||
@@ -353,8 +398,8 @@ class Config(object):
|
||||
except ValueError:
|
||||
Log.Warn("PIN has to be an integer (0-9)")
|
||||
self.pin = pin
|
||||
self.lock_advanced_menu = Prefs["plugin_pin_mode"] == "advanced menu"
|
||||
self.lock_menu = Prefs["plugin_pin_mode"] == "channel menu"
|
||||
self.lock_advanced_menu = Prefs["plugin_pin_mode2"] == "advanced menu"
|
||||
self.lock_menu = Prefs["plugin_pin_mode2"] == "interface"
|
||||
|
||||
try:
|
||||
self.pin_valid_minutes = int(Prefs["plugin_pin_valid_for"].strip())
|
||||
@@ -460,12 +505,30 @@ class Config(object):
|
||||
if not fn:
|
||||
return
|
||||
|
||||
splitted_fn = fn.split()
|
||||
exe_fn = splitted_fn[0]
|
||||
arguments = [arg.strip() for arg in splitted_fn[1:]]
|
||||
got_args = "%(" in fn
|
||||
if got_args:
|
||||
first_arg_pos = fn.index("%(")
|
||||
exe_fn = fn[:first_arg_pos].strip()
|
||||
arguments = [arg.strip() for arg in fn[first_arg_pos:].split()]
|
||||
else:
|
||||
exe_fn = fn
|
||||
arguments = []
|
||||
|
||||
if os.path.isfile(exe_fn) and os.access(exe_fn, os.X_OK):
|
||||
return exe_fn, arguments
|
||||
|
||||
# try finding the executable itself, the path might contain spaces and there might have been other arguments
|
||||
fn_split = exe_fn.split(u" ")
|
||||
tmp_exe_fn = fn_split[0]
|
||||
|
||||
for offset in range(1, len(fn_split)+1):
|
||||
if os.path.isfile(tmp_exe_fn) and os.access(tmp_exe_fn, os.X_OK):
|
||||
exe_fn = tmp_exe_fn.strip()
|
||||
arguments = [arg.strip() for arg in fn_split[offset:]] + arguments
|
||||
return exe_fn, arguments
|
||||
|
||||
tmp_exe_fn = u" ".join(fn_split[:offset+1])
|
||||
|
||||
Log.Error("Notify executable not existing or not executable: %s" % exe_fn)
|
||||
|
||||
def refresh_enabled_sections(self):
|
||||
@@ -579,10 +642,12 @@ class Config(object):
|
||||
'legendastv': cast_bool(Prefs['provider.legendastv.enabled']),
|
||||
'napiprojekt': cast_bool(Prefs['provider.napiprojekt.enabled']),
|
||||
'hosszupuska': cast_bool(Prefs['provider.hosszupuska.enabled']),
|
||||
'supersubtitles': cast_bool(Prefs['provider.supersubtitles.enabled']),
|
||||
'shooter': False,
|
||||
'subscene': cast_bool(Prefs['provider.subscene.enabled']),
|
||||
'argenteam': cast_bool(Prefs['provider.argenteam.enabled']),
|
||||
'subscenter': False,
|
||||
'assrt': cast_bool(Prefs['provider.assrt.enabled']),
|
||||
}
|
||||
|
||||
providers_by_prefs = copy.deepcopy(providers)
|
||||
@@ -599,8 +664,14 @@ class Config(object):
|
||||
providers["napiprojekt"] = False
|
||||
providers["shooter"] = False
|
||||
providers["hosszupuska"] = False
|
||||
providers["supersubtitles"] = False
|
||||
providers["titlovi"] = False
|
||||
providers["argenteam"] = False
|
||||
providers["assrt"] = False
|
||||
|
||||
if not self.unrar and providers["legendastv"]:
|
||||
providers["legendastv"] = False
|
||||
Log.Info("Disabling LegendasTV, because UnRAR wasn't found")
|
||||
|
||||
# advanced settings
|
||||
if media_type and self.advanced.providers:
|
||||
@@ -636,6 +707,8 @@ class Config(object):
|
||||
providers = property(get_providers)
|
||||
|
||||
def get_provider_settings(self):
|
||||
os_use_https = self.advanced.providers.opensubtitles.use_https \
|
||||
if self.advanced.providers.opensubtitles.use_https != None else True
|
||||
provider_settings = {'addic7ed': {'username': Prefs['provider.addic7ed.username'],
|
||||
'password': Prefs['provider.addic7ed.password'],
|
||||
'use_random_agents': cast_bool(Prefs['provider.addic7ed.use_random_agents1']),
|
||||
@@ -644,14 +717,17 @@ class Config(object):
|
||||
'password': Prefs['provider.opensubtitles.password'],
|
||||
'use_tag_search': self.exact_filenames,
|
||||
'only_foreign': self.forced_only,
|
||||
'is_vip': cast_bool(Prefs['provider.opensubtitles.is_vip'])
|
||||
'is_vip': cast_bool(Prefs['provider.opensubtitles.is_vip']),
|
||||
'use_ssl': os_use_https,
|
||||
'timeout': self.advanced.providers.opensubtitles.timeout or 15
|
||||
},
|
||||
'podnapisi': {
|
||||
'only_foreign': self.forced_only,
|
||||
},
|
||||
'legendastv': {'username': Prefs['provider.legendastv.username'],
|
||||
'password': Prefs['provider.legendastv.password'],
|
||||
}
|
||||
},
|
||||
'assrt': {'token': Prefs['provider.assrt.token'], }
|
||||
}
|
||||
|
||||
return provider_settings
|
||||
@@ -829,8 +905,11 @@ class Config(object):
|
||||
if Prefs["drone_api.sonarr.url"] and Prefs["drone_api.sonarr.api_key"]:
|
||||
self.refiner_settings["sonarr"] = {
|
||||
"base_url": Prefs["drone_api.sonarr.url"],
|
||||
"api_key": Prefs["drone_api.sonarr.api_key"]
|
||||
"api_key": Prefs["drone_api.sonarr.api_key"],
|
||||
}
|
||||
if self.advanced.refiners.sonarr:
|
||||
self.refiner_settings["sonarr"].update(self.advanced.refiners.sonarr)
|
||||
|
||||
self.exact_filenames = True
|
||||
|
||||
if Prefs["drone_api.radarr.url"] and Prefs["drone_api.radarr.api_key"]:
|
||||
@@ -838,6 +917,9 @@ class Config(object):
|
||||
"base_url": Prefs["drone_api.radarr.url"],
|
||||
"api_key": Prefs["drone_api.radarr.api_key"]
|
||||
}
|
||||
if self.advanced.refiners.radarr:
|
||||
self.refiner_settings["radarr"].update(self.advanced.refiners.radarr)
|
||||
|
||||
self.exact_filenames = True
|
||||
|
||||
@property
|
||||
|
||||
@@ -292,7 +292,6 @@ def notify_executable(exe_info, videos, subtitles, storage):
|
||||
prepared_arguments = [arg % prepared_data for arg in arguments]
|
||||
|
||||
Log.Debug(u"Calling %s with arguments: %s" % (exe, prepared_arguments))
|
||||
env = dict(os.environ)
|
||||
if not mswindows:
|
||||
env_path = {"PATH": os.pathsep.join(
|
||||
[
|
||||
@@ -303,16 +302,30 @@ def notify_executable(exe_info, videos, subtitles, storage):
|
||||
)
|
||||
}
|
||||
env = dict(os.environ, **env_path)
|
||||
env.pop("LD_LIBRARY_PATH", None)
|
||||
else:
|
||||
env = dict(os.environ)
|
||||
|
||||
env.pop("LD_LIBRARY_PATH", None)
|
||||
# clean out any Plex-PYTHONPATH that may bleed through the spawned process
|
||||
if "PYTHONPATH" in env and "plex" in env["PYTHONPATH"].lower():
|
||||
del env["PYTHONPATH"]
|
||||
|
||||
try:
|
||||
output = subprocess.check_output(quote_args([exe] + prepared_arguments),
|
||||
stderr=subprocess.STDOUT, shell=True, env=env)
|
||||
except subprocess.CalledProcessError:
|
||||
Log.Error(u"Calling %s failed: %s" % (exe, traceback.format_exc()))
|
||||
proc = subprocess.Popen(quote_args([exe] + prepared_arguments), stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, shell=True, env=env, cwd=os.path.dirname(exe))
|
||||
output, errors = proc.communicate()
|
||||
|
||||
if proc.returncode == 1:
|
||||
Log.Error(u"Calling %s with args %s failed: output:\n%s, error:\n%s", exe, prepared_arguments,
|
||||
output, errors)
|
||||
return
|
||||
|
||||
output = output.decode()
|
||||
|
||||
except:
|
||||
Log.Error(u"Calling %s failed: %s", exe, traceback.format_exc())
|
||||
else:
|
||||
Log.Debug(u"Process output: %s" % output)
|
||||
Log.Debug(u"Process output: %s", output)
|
||||
|
||||
|
||||
def track_usage(category=None, action=None, label=None, value=None):
|
||||
@@ -370,13 +383,7 @@ def get_language(lang_short):
|
||||
|
||||
|
||||
def display_language(l):
|
||||
addons = []
|
||||
if l.country:
|
||||
addons.append(l.country.alpha2)
|
||||
if l.script:
|
||||
addons.append(l.script.code)
|
||||
|
||||
return l.name if not addons else "%s (%s)" % (l.name, ", ".join(addons))
|
||||
return _(str(l).lower())
|
||||
|
||||
|
||||
def is_stream_forced(stream):
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
# coding=utf-8
|
||||
|
||||
import inspect
|
||||
|
||||
from support.config import config
|
||||
|
||||
|
||||
core = getattr(Data, "_core")
|
||||
|
||||
|
||||
# get original localization module in order to access its base classes later on
|
||||
def get_localization_module():
|
||||
cls = getattr(core.localization, "__class__")
|
||||
return inspect.getmodule(cls)
|
||||
|
||||
|
||||
plex_i18n_module = get_localization_module()
|
||||
|
||||
|
||||
def old_style_placeholders_count(s):
|
||||
# fixme: incomplete, use regex
|
||||
return sum(s.count(c) for c in ["%s", "%d", "%r", "%f", "%i"])
|
||||
|
||||
|
||||
def check_old_style_placeholders(k, args):
|
||||
# replace escaped %'s?
|
||||
k = k.__str__().replace("%%", "")
|
||||
|
||||
if "%(" in k:
|
||||
Log.Error(u"%r defines named placeholders for formatting" % k)
|
||||
return "NEEDS NAMED ARGUMENTS"
|
||||
|
||||
placeholders_found = old_style_placeholders_count(k)
|
||||
if placeholders_found and not args:
|
||||
Log.Error(u"%r requires a arguments for formatting" % k)
|
||||
return "NEEDS FORMAT ARGUMENTS"
|
||||
|
||||
elif not placeholders_found and args:
|
||||
Log.Error(u"%r doesn't define placeholders for formatting" % k)
|
||||
return "HAS NO FORMAT ARGUMENTS"
|
||||
|
||||
elif placeholders_found and placeholders_found != len(args):
|
||||
Log.Error(u"%r wrong amount of arguments supplied for formatting" % k)
|
||||
return "WRONG FORMAT ARGUMENT COUNT"
|
||||
|
||||
|
||||
class SmartLocalStringFormatter(plex_i18n_module.LocalStringFormatter):
|
||||
"""
|
||||
this allows the use of dictionaries for string formatting, also does some sanity checking on the keys and values
|
||||
"""
|
||||
def __init__(self, string1, string2, locale=None):
|
||||
if isinstance(string2, tuple):
|
||||
# dictionary passed
|
||||
if len(string2) == 1 and hasattr(string2[0], "iteritems"):
|
||||
string2 = string2[0]
|
||||
if config.debug_i18n:
|
||||
if "%(" not in string1.__str__().replace("%%", ""):
|
||||
Log.Error(u"%r: dictionary for non-named format string supplied" % string1.__str__())
|
||||
string1 = "%s"
|
||||
string2 = "NO NAMED ARGUMENTS"
|
||||
|
||||
# arguments
|
||||
elif len(string2) >= 1 and config.debug_i18n:
|
||||
msg = check_old_style_placeholders(string1, string2)
|
||||
if msg:
|
||||
string1 = "%s"
|
||||
string2 = msg
|
||||
|
||||
setattr(self, "_string1", string1)
|
||||
setattr(self, "_string2", string2)
|
||||
setattr(self, "_locale", locale)
|
||||
|
||||
|
||||
def local_string_with_optional_format(key, *args, **kwargs):
|
||||
if kwargs:
|
||||
args = (kwargs,)
|
||||
else:
|
||||
args = tuple(args)
|
||||
|
||||
if args:
|
||||
# fixme: may not be the best idea as this evaluates the string early
|
||||
try:
|
||||
return unicode(SmartLocalStringFormatter(plex_i18n_module.LocalString(core, key, Locale.CurrentLocale), args))
|
||||
except TypeError:
|
||||
Log.Exception("Broken translation!")
|
||||
return unicode(SmartLocalStringFormatter(plex_i18n_module.LocalString(core, key, "en"), args))
|
||||
|
||||
# check string instances for arguments
|
||||
if config.debug_i18n:
|
||||
msg = check_old_style_placeholders(key, args)
|
||||
if msg:
|
||||
return msg
|
||||
|
||||
try:
|
||||
return unicode(plex_i18n_module.LocalString(core, key, Locale.CurrentLocale))
|
||||
|
||||
except TypeError:
|
||||
Log.Exception("Broken translation!")
|
||||
return unicode(plex_i18n_module.LocalString(core, key, "en"))
|
||||
|
||||
|
||||
_ = local_string_with_optional_format
|
||||
|
||||
|
||||
def is_localized_string(s):
|
||||
return hasattr(s, "localize")
|
||||
@@ -16,6 +16,7 @@ from lib import Plex, get_intent
|
||||
from config import config, IGNORE_FN
|
||||
from subliminal_patch.subtitle import ModifiedSubtitle
|
||||
from subzero.modification import registry as mod_registry, SubtitleModifications
|
||||
from socket import timeout
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -30,7 +31,11 @@ def get_item(key):
|
||||
except ValueError:
|
||||
return
|
||||
|
||||
item_container = Plex["library"].metadata(item_id)
|
||||
try:
|
||||
item_container = Plex["library"].metadata(item_id)
|
||||
except timeout:
|
||||
Log.Debug("PMS API timed out when querying information about item %d", item_id)
|
||||
return
|
||||
|
||||
try:
|
||||
return list(item_container)[0]
|
||||
@@ -348,16 +353,30 @@ def get_current_sub(rating_key, part_id, language, plex_item=None):
|
||||
|
||||
def save_stored_sub(stored_subtitle, rating_key, part_id, language, item_type, plex_item=None, storage=None,
|
||||
stored_subs=None):
|
||||
"""
|
||||
in order for this to work, if the calling supplies stored_subs and storage, it has to trigger its saving and
|
||||
destruction explicitly
|
||||
:param stored_subtitle:
|
||||
:param rating_key:
|
||||
:param part_id:
|
||||
:param language:
|
||||
:param item_type:
|
||||
:param plex_item:
|
||||
:param storage:
|
||||
:param stored_subs:
|
||||
:return:
|
||||
"""
|
||||
from support.plex_media import get_plex_metadata
|
||||
from support.scanning import scan_videos
|
||||
from support.storage import save_subtitles, get_subtitle_storage
|
||||
|
||||
plex_item = plex_item or get_item(rating_key)
|
||||
storage = storage or get_subtitle_storage()
|
||||
|
||||
cleanup = not storage
|
||||
|
||||
stored_subs = stored_subs or storage.load(plex_item.rating_key)
|
||||
stored_subs_was_provided = True
|
||||
if not stored_subs or not storage:
|
||||
storage = get_subtitle_storage()
|
||||
stored_subs = storage.load(plex_item.rating_key)
|
||||
stored_subs_was_provided = False
|
||||
|
||||
if not all([plex_item, stored_subs]):
|
||||
return
|
||||
@@ -396,9 +415,9 @@ def save_stored_sub(stored_subtitle, rating_key, part_id, language, item_type, p
|
||||
|
||||
if subtitle.storage_path:
|
||||
stored_subtitle.last_mod = datetime.datetime.fromtimestamp(os.path.getmtime(subtitle.storage_path))
|
||||
storage.save(stored_subs)
|
||||
|
||||
if cleanup:
|
||||
if not stored_subs_was_provided:
|
||||
storage.save(stored_subs)
|
||||
storage.destroy()
|
||||
|
||||
|
||||
@@ -436,9 +455,9 @@ def set_mods_for_part(rating_key, part_id, language, item_type, mods, mode="add"
|
||||
current_sub.mods.pop()
|
||||
else:
|
||||
raise NotImplementedError("Wrong mode given")
|
||||
storage.save(stored_subs)
|
||||
|
||||
save_stored_sub(current_sub, rating_key, part_id, language, item_type, plex_item=plex_item, storage=storage,
|
||||
stored_subs=stored_subs)
|
||||
|
||||
storage.save(stored_subs)
|
||||
storage.destroy()
|
||||
|
||||
@@ -144,7 +144,9 @@ def save_subtitles_to_metadata(videos, subtitles, is_forced=False):
|
||||
else:
|
||||
mp = mediaPart
|
||||
pm = Proxy.Media(content, ext="srt", forced="1" if is_forced else None)
|
||||
mp.subtitles[Locale.Language.Match(subtitle.language.alpha2)][subtitle.id] = pm
|
||||
lang = Locale.Language.Match(subtitle.language.alpha2)
|
||||
mp.subtitles[lang].validate_keys({})
|
||||
mp.subtitles[lang]["subzero"] = pm
|
||||
return True
|
||||
|
||||
|
||||
@@ -205,7 +207,7 @@ def save_subtitles(scanned_video_part_map, downloaded_subtitles, mode="a", bare_
|
||||
if not bare_save and save_successful and config.notify_executable:
|
||||
notify_executable(config.notify_executable, scanned_video_part_map, downloaded_subtitles, storage)
|
||||
|
||||
if not bare_save and (save_successful or not set_current):
|
||||
if not bare_save and save_successful or not set_current:
|
||||
store_subtitle_info(scanned_video_part_map, downloaded_subtitles, storage, mode=mode, set_current=set_current)
|
||||
|
||||
return save_successful
|
||||
|
||||
@@ -196,7 +196,7 @@ def get_subtitles_from_metadata(part):
|
||||
if p_type == "Media":
|
||||
# metadata subtitle
|
||||
Log.Debug(u"Found metadata subtitle: %s, %s" % (language, repr(proxy)))
|
||||
subs[language].append(key)
|
||||
subs[language] = [key]
|
||||
return subs
|
||||
|
||||
|
||||
|
||||
@@ -20,11 +20,9 @@ from support.items import get_recent_items, get_item, is_ignored, get_item_title
|
||||
from support.helpers import track_usage, get_title_for_video_metadata, cast_bool, PartUnknownException
|
||||
from support.plex_media import get_plex_metadata
|
||||
from support.scanning import scan_videos
|
||||
from support.i18n import _
|
||||
from download import download_best_subtitles, pre_download_hook, post_download_hook, language_hook
|
||||
|
||||
PROVIDER_SLACK = 30
|
||||
DL_PROVIDER_SLACK = 30
|
||||
|
||||
|
||||
class Task(object):
|
||||
name = None
|
||||
@@ -34,6 +32,9 @@ class Task(object):
|
||||
time_start = None
|
||||
data = None
|
||||
|
||||
PROVIDER_SLACK = 30
|
||||
DL_PROVIDER_SLACK = 30
|
||||
|
||||
stored_attributes = ("last_run", "last_run_time", "running")
|
||||
default_data = {"last_run": None, "last_run_time": None, "running": False, "data": {}}
|
||||
|
||||
@@ -158,9 +159,14 @@ class SubtitleListingMixin(object):
|
||||
continue
|
||||
|
||||
# skip wrong season/episodes
|
||||
if item_type == "episode" and not {"series", "season", "episode"}.issubset(matches):
|
||||
Log.Debug(u"%s: Skipping %s, because it doesn't match our series/episode", self.name, s)
|
||||
continue
|
||||
if item_type == "episode":
|
||||
can_verify_series = True
|
||||
if not s.hash_verifiable and "hash" in matches:
|
||||
can_verify_series = False
|
||||
|
||||
if can_verify_series and not {"series", "season", "episode"}.issubset(matches):
|
||||
Log.Debug(u"%s: Skipping %s, because it doesn't match our series/episode", self.name, s)
|
||||
continue
|
||||
|
||||
unsorted_subtitles.append(
|
||||
(s, compute_score(matches, s, video, hearing_impaired=use_hearing_impaired), matches))
|
||||
@@ -237,7 +243,9 @@ class DownloadSubtitleMixin(object):
|
||||
if not scheduler.is_task_running("MissingSubtitles"):
|
||||
scheduler.clear_task_data("MissingSubtitles")
|
||||
else:
|
||||
set_refresh_menu_state(u"%s: Subtitle download failed (%s)" % (self.name, rating_key))
|
||||
set_refresh_menu_state(_(u"%(class_name)s: Subtitle download failed (%(item_id)s)",
|
||||
class_name=self.name,
|
||||
item_id=rating_key))
|
||||
return download_successful
|
||||
|
||||
|
||||
@@ -379,7 +387,7 @@ class SearchAllRecentlyAddedMissing(Task):
|
||||
|
||||
def skip_item():
|
||||
self.items_searching = self.items_searching - 1
|
||||
self.percentage = int(self.items_done * 100 / self.items_searching)
|
||||
self.percentage = int(self.items_done * 100 / self.items_searching) if self.items_searching > 0 else 100
|
||||
|
||||
# search for subtitles in viable items
|
||||
try:
|
||||
@@ -477,8 +485,8 @@ class SearchAllRecentlyAddedMissing(Task):
|
||||
except:
|
||||
Log.Error(u"%s: DEBUG HIT: %s", self.name, traceback.format_exc())
|
||||
|
||||
Log.Debug(u"%s: Waiting %s seconds before continuing", self.name, PROVIDER_SLACK)
|
||||
Thread.Sleep(PROVIDER_SLACK)
|
||||
Log.Debug(u"%s: Waiting %s seconds before continuing", self.name, self.PROVIDER_SLACK)
|
||||
Thread.Sleep(self.PROVIDER_SLACK)
|
||||
|
||||
download_count += downloads_per_video
|
||||
|
||||
@@ -486,18 +494,18 @@ class SearchAllRecentlyAddedMissing(Task):
|
||||
videos_with_downloads += 1
|
||||
|
||||
self.items_done = self.items_done + 1
|
||||
self.percentage = int(self.items_done * 100 / self.items_searching)
|
||||
self.percentage = int(self.items_done * 100 / self.items_searching) if self.items_searching > 0 else 100
|
||||
|
||||
stored_subs = None
|
||||
|
||||
if downloads_per_video:
|
||||
Log.Debug(u"%s: Subtitles have been downloaded, "
|
||||
u"waiting %s seconds before continuing", self.name, DL_PROVIDER_SLACK)
|
||||
Thread.Sleep(DL_PROVIDER_SLACK)
|
||||
u"waiting %s seconds before continuing", self.name, self.DL_PROVIDER_SLACK)
|
||||
Thread.Sleep(self.DL_PROVIDER_SLACK)
|
||||
else:
|
||||
if hit_providers:
|
||||
Log.Debug(u"%s: Waiting %s seconds before continuing", self.name, PROVIDER_SLACK)
|
||||
Thread.Sleep(PROVIDER_SLACK)
|
||||
Log.Debug(u"%s: Waiting %s seconds before continuing", self.name, self.PROVIDER_SLACK)
|
||||
Thread.Sleep(self.PROVIDER_SLACK)
|
||||
finally:
|
||||
subtitle_storage.destroy()
|
||||
history.destroy()
|
||||
@@ -575,7 +583,7 @@ class LegacySearchAllRecentlyAddedMissing(Task):
|
||||
while 1:
|
||||
if item_id in self.items_done:
|
||||
items_done_count += 1
|
||||
self.percentage = int(items_done_count * 100 / missing_count)
|
||||
self.percentage = int(items_done_count * 100 / missing_count) if missing_count > 0 else 100
|
||||
Log.Debug(u"Task: %s, item %s done (%s%%, %s/%s)", self.name, item_id, self.percentage,
|
||||
items_done_count, missing_count)
|
||||
break
|
||||
@@ -758,8 +766,8 @@ class FindBetterSubtitles(DownloadSubtitleMixin, SubtitleListingMixin, Task):
|
||||
Log.Debug(u"%s: Couldn't download/save subtitle. "
|
||||
u"Continuing to the next one", self.name)
|
||||
Log.Debug(u"%s: Waiting %s seconds before continuing",
|
||||
self.name, DL_PROVIDER_SLACK)
|
||||
Thread.Sleep(DL_PROVIDER_SLACK)
|
||||
self.name, self.DL_PROVIDER_SLACK)
|
||||
Thread.Sleep(self.DL_PROVIDER_SLACK)
|
||||
better_visited += 1
|
||||
|
||||
if better_tried_download and not better_downloaded:
|
||||
@@ -770,19 +778,19 @@ class FindBetterSubtitles(DownloadSubtitleMixin, SubtitleListingMixin, Task):
|
||||
Log.Debug(u"%s: Better subtitle downloaded for %s", self.name, video_id)
|
||||
|
||||
if better_tried_download or better_downloaded:
|
||||
Log.Debug(u"%s: Waiting %s seconds before continuing", self.name, DL_PROVIDER_SLACK)
|
||||
Thread.Sleep(DL_PROVIDER_SLACK)
|
||||
Log.Debug(u"%s: Waiting %s seconds before continuing", self.name, self.DL_PROVIDER_SLACK)
|
||||
Thread.Sleep(self.DL_PROVIDER_SLACK)
|
||||
|
||||
elif better_visited:
|
||||
Log.Debug(u"%s: Waiting %s seconds before continuing", self.name, PROVIDER_SLACK)
|
||||
Thread.Sleep(PROVIDER_SLACK)
|
||||
Log.Debug(u"%s: Waiting %s seconds before continuing", self.name, self.PROVIDER_SLACK)
|
||||
Thread.Sleep(self.PROVIDER_SLACK)
|
||||
|
||||
subs = None
|
||||
|
||||
elif hit_providers:
|
||||
# hit the providers but didn't try downloading? wait.
|
||||
Log.Debug(u"%s: Waiting %s seconds before continuing", self.name, PROVIDER_SLACK)
|
||||
Thread.Sleep(PROVIDER_SLACK)
|
||||
Log.Debug(u"%s: Waiting %s seconds before continuing", self.name, self.PROVIDER_SLACK)
|
||||
Thread.Sleep(self.PROVIDER_SLACK)
|
||||
|
||||
if ditch_parts:
|
||||
for part_id in ditch_parts:
|
||||
|
||||
@@ -50,7 +50,9 @@
|
||||
"tr",
|
||||
"uk",
|
||||
"vi",
|
||||
"hr"
|
||||
"hr",
|
||||
"zh-hans",
|
||||
"zh-hant"
|
||||
],
|
||||
"default": "en"
|
||||
},
|
||||
@@ -106,7 +108,9 @@
|
||||
"tr",
|
||||
"uk",
|
||||
"vi",
|
||||
"hr"
|
||||
"hr",
|
||||
"zh-hans",
|
||||
"zh-hant"
|
||||
],
|
||||
"default": "None"
|
||||
},
|
||||
@@ -162,7 +166,9 @@
|
||||
"tr",
|
||||
"uk",
|
||||
"vi",
|
||||
"hr"
|
||||
"hr",
|
||||
"zh-hans",
|
||||
"zh-hant"
|
||||
],
|
||||
"default": "None"
|
||||
},
|
||||
@@ -380,6 +386,12 @@
|
||||
"type": "bool",
|
||||
"default": "true"
|
||||
},
|
||||
{
|
||||
"id": "provider.supersubtitles.enabled",
|
||||
"label": "Provider: Enable feliratok.info (Hungarian)",
|
||||
"type": "bool",
|
||||
"default": "false"
|
||||
},
|
||||
{
|
||||
"id": "provider.hosszupuska.enabled",
|
||||
"label": "Provider: Enable hosszupuskasub.com (Hungarian)",
|
||||
@@ -392,6 +404,18 @@
|
||||
"type": "bool",
|
||||
"default": "false"
|
||||
},
|
||||
{
|
||||
"id": "provider.assrt.enabled",
|
||||
"label": "Provider: Enable assrt.net (Chinese)",
|
||||
"type": "bool",
|
||||
"default": "false"
|
||||
},
|
||||
{
|
||||
"id": "provider.assrt.token",
|
||||
"label": "Assrt API Token",
|
||||
"type": "text",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"id": "providers.multithreading",
|
||||
"label": "Search enabled providers simultaneously (multithreading)",
|
||||
@@ -709,15 +733,15 @@
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"id": "plugin_mode",
|
||||
"id": "plugin_mode2",
|
||||
"label": "Sub-Zero mode",
|
||||
"type": "enum",
|
||||
"values": [
|
||||
"agent + channel",
|
||||
"agent + interface",
|
||||
"only agent",
|
||||
"only channel"
|
||||
"only interface"
|
||||
],
|
||||
"default": "agent + channel"
|
||||
"default": "agent + interface"
|
||||
},
|
||||
{
|
||||
"id": "plugin_pin",
|
||||
@@ -734,12 +758,12 @@
|
||||
"default": "10"
|
||||
},
|
||||
{
|
||||
"id": "plugin_pin_mode",
|
||||
"id": "plugin_pin_mode2",
|
||||
"label": "Use PIN to restrict access to (needs plugin or PMS restart)",
|
||||
"type": "enum",
|
||||
"values": [
|
||||
"disabled",
|
||||
"channel menu",
|
||||
"interface",
|
||||
"advanced menu"
|
||||
],
|
||||
"default": "disabled"
|
||||
@@ -780,6 +804,12 @@
|
||||
"type": "text",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"id": "path_to_advanced_settings",
|
||||
"label": "Custom path to advanced_settings.json",
|
||||
"type": "text",
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"id": "log_level",
|
||||
"label": "How verbose should the logging be?",
|
||||
|
||||
+5
-3
@@ -9,11 +9,11 @@
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.5.3</string>
|
||||
<string>2.5.4</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2.5.3.2414</string>
|
||||
<string>2.5.7.2663</string>
|
||||
<key>PlexFrameworkVersion</key>
|
||||
<string>2</string>
|
||||
<key>PlexPluginClass</key>
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
<h1>Sub-Zero for Plex</h1><i>Subtitles done right</i>
|
||||
|
||||
Version 2.5.3.2414
|
||||
Version 2.5.7.2663
|
||||
|
||||
Originally based on @bramwalet's awesome <a href="https://github.com/bramwalet/Subliminal.bundle">Subliminal.bundle</a>
|
||||
|
||||
@@ -44,6 +44,8 @@ Score info: <a href="http://v.ht/szscores">http://v.ht/szscores&
|
||||
Plex thread: <a href="https://forums.plex.tv/discussion/186575">https://forums.plex.tv/discussion/186575</a>
|
||||
Github: <a href="https://github.com/pannal/Sub-Zero.bundle">https://github.com/pannal/Sub-Zero</a>
|
||||
|
||||
3rd party licenses: <a href="https://github.com/pannal/Sub-Zero.bundle/tree/master/Licenses">https://github.com/pannal/Sub-Zero.bundle/tree/master/Licenses</a>
|
||||
|
||||
panni, 2018
|
||||
</div>
|
||||
</string>
|
||||
|
||||
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -1,3 +1,3 @@
|
||||
from .core import where, old_where
|
||||
|
||||
__version__ = "2017.11.05"
|
||||
__version__ = "2018.01.18"
|
||||
|
||||
@@ -573,78 +573,6 @@ Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
|
||||
ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
|
||||
# Subject: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
|
||||
# Label: "Camerfirma Chambers of Commerce Root"
|
||||
# Serial: 0
|
||||
# MD5 Fingerprint: b0:01:ee:14:d9:af:29:18:94:76:8e:f1:69:33:2a:84
|
||||
# SHA1 Fingerprint: 6e:3a:55:a4:19:0c:19:5c:93:84:3c:c0:db:72:2e:31:30:61:f0:b1
|
||||
# SHA256 Fingerprint: 0c:25:8a:12:a5:67:4a:ef:25:f2:8b:a7:dc:fa:ec:ee:a3:48:e5:41:e6:f5:cc:4e:e6:3b:71:b3:61:60:6a:c3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn
|
||||
MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
|
||||
ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg
|
||||
b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa
|
||||
MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB
|
||||
ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw
|
||||
IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B
|
||||
AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb
|
||||
unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d
|
||||
BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq
|
||||
7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3
|
||||
0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX
|
||||
roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG
|
||||
A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j
|
||||
aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p
|
||||
26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA
|
||||
BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud
|
||||
EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN
|
||||
BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
|
||||
aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB
|
||||
AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd
|
||||
p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi
|
||||
1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc
|
||||
XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0
|
||||
eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu
|
||||
tGWaIZDgqtCYvDi1czyL+Nw=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
|
||||
# Subject: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
|
||||
# Label: "Camerfirma Global Chambersign Root"
|
||||
# Serial: 0
|
||||
# MD5 Fingerprint: c5:e6:7b:bf:06:d0:4f:43:ed:c4:7a:65:8a:fb:6b:19
|
||||
# SHA1 Fingerprint: 33:9b:6b:14:50:24:9b:55:7a:01:87:72:84:d9:e0:2f:c3:d2:d8:e9
|
||||
# SHA256 Fingerprint: ef:3c:b4:17:fc:8e:bf:6f:97:87:6c:9e:4e:ce:39:de:1e:a5:fe:64:91:41:d1:02:8b:7d:11:c0:b2:29:8c:ed
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn
|
||||
MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
|
||||
ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo
|
||||
YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9
|
||||
MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy
|
||||
NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G
|
||||
A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA
|
||||
A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0
|
||||
Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s
|
||||
QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV
|
||||
eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795
|
||||
B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh
|
||||
z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T
|
||||
AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i
|
||||
ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w
|
||||
TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH
|
||||
MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD
|
||||
VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE
|
||||
VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
|
||||
bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B
|
||||
AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM
|
||||
bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi
|
||||
ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG
|
||||
VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c
|
||||
ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/
|
||||
AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
|
||||
# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
|
||||
# Label: "XRamp Global CA Root"
|
||||
@@ -931,38 +859,6 @@ JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
|
||||
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES
|
||||
# Subject: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES
|
||||
# Label: "DST ACES CA X6"
|
||||
# Serial: 17771143917277623872238992636097467865
|
||||
# MD5 Fingerprint: 21:d8:4c:82:2b:99:09:33:a2:eb:14:24:8d:8e:5f:e8
|
||||
# SHA1 Fingerprint: 40:54:da:6f:1c:3f:40:74:ac:ed:0f:ec:cd:db:79:d1:53:fb:90:1d
|
||||
# SHA256 Fingerprint: 76:7c:95:5a:76:41:2c:89:af:68:8e:90:a1:c7:0f:55:6c:fd:6b:60:25:db:ea:10:41:6d:7e:b6:83:1f:8c:40
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb
|
||||
MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx
|
||||
ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w
|
||||
MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD
|
||||
VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx
|
||||
FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||
MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu
|
||||
ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7
|
||||
gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH
|
||||
fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a
|
||||
ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT
|
||||
ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF
|
||||
MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk
|
||||
c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto
|
||||
dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt
|
||||
aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI
|
||||
hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk
|
||||
QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/
|
||||
h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
|
||||
nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR
|
||||
rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2
|
||||
9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG
|
||||
# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG
|
||||
# Label: "SwissSign Gold CA - G2"
|
||||
@@ -1291,35 +1187,6 @@ fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
|
||||
GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1
|
||||
# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1
|
||||
# Label: "Security Communication EV RootCA1"
|
||||
# Serial: 0
|
||||
# MD5 Fingerprint: 22:2d:a6:01:ea:7c:0a:f7:f0:6c:56:43:3f:77:76:d3
|
||||
# SHA1 Fingerprint: fe:b8:c4:32:dc:f9:76:9a:ce:ae:3d:d8:90:8f:fd:28:86:65:64:7d
|
||||
# SHA256 Fingerprint: a2:2d:ba:68:1e:97:37:6e:2d:39:7d:72:8a:ae:3a:9b:62:96:b9:fd:ba:60:bc:2e:11:f6:47:f2:c6:75:fb:37
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl
|
||||
MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh
|
||||
U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz
|
||||
MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N
|
||||
IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11
|
||||
bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
||||
ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE
|
||||
RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO
|
||||
zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5
|
||||
bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF
|
||||
MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1
|
||||
VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC
|
||||
OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
|
||||
CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW
|
||||
tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ
|
||||
q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb
|
||||
EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+
|
||||
Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O
|
||||
VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
|
||||
# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
|
||||
# Label: "OISTE WISeKey Global Root GA CA"
|
||||
@@ -2673,45 +2540,6 @@ xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
|
||||
KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=CA Disig Root R1 O=Disig a.s.
|
||||
# Subject: CN=CA Disig Root R1 O=Disig a.s.
|
||||
# Label: "CA Disig Root R1"
|
||||
# Serial: 14052245610670616104
|
||||
# MD5 Fingerprint: be:ec:11:93:9a:f5:69:21:bc:d7:c1:c0:67:89:cc:2a
|
||||
# SHA1 Fingerprint: 8e:1c:74:f8:a6:20:b9:e5:8a:f4:61:fa:ec:2b:47:56:51:1a:52:c6
|
||||
# SHA256 Fingerprint: f9:6f:23:f4:c3:e7:9c:07:7a:46:98:8d:5a:f5:90:06:76:a0:f0:39:cb:64:5d:d1:75:49:b2:16:c8:24:40:ce
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV
|
||||
BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
|
||||
MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy
|
||||
MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
|
||||
EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw
|
||||
ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk
|
||||
D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o
|
||||
OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A
|
||||
fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe
|
||||
IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n
|
||||
oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK
|
||||
/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj
|
||||
rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD
|
||||
3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE
|
||||
7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC
|
||||
yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd
|
||||
qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
|
||||
DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI
|
||||
hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR
|
||||
xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA
|
||||
SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo
|
||||
HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB
|
||||
emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC
|
||||
AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb
|
||||
7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x
|
||||
DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk
|
||||
F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF
|
||||
a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT
|
||||
Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=CA Disig Root R2 O=Disig a.s.
|
||||
# Subject: CN=CA Disig Root R2 O=Disig a.s.
|
||||
# Label: "CA Disig Root R2"
|
||||
|
||||
@@ -26,12 +26,12 @@ def where():
|
||||
|
||||
def old_where():
|
||||
warnings.warn(
|
||||
"The weak security bundle is being deprecated. It will be removed in "
|
||||
"2018.",
|
||||
"The weak security bundle has been removed. certifi.old_where() is now an alias "
|
||||
"of certifi.where(). Please update your code to use certifi.where() instead. "
|
||||
"certifi.old_where() will be removed in 2018.",
|
||||
DeprecatedBundleWarning
|
||||
)
|
||||
f = os.path.dirname(__file__)
|
||||
return os.path.join(f, 'weak.pem')
|
||||
return where()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(where())
|
||||
|
||||
@@ -7,11 +7,14 @@ 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__)
|
||||
@@ -48,18 +51,25 @@ XATTR_MAP = {
|
||||
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.replace(' ', '').replace('\n', '')).strip("\x00")
|
||||
},
|
||||
"win32": {
|
||||
# "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")
|
||||
default_xattr_bin = find_executable("getfattr") or find_executable("attr") or find_executable("filebot") \
|
||||
or "filebot"
|
||||
|
||||
|
||||
def get_filebot_attrs(fn):
|
||||
@@ -79,12 +89,35 @@ def get_filebot_attrs(fn):
|
||||
args = args_func(fn)
|
||||
if isinstance(args, types.ListType):
|
||||
try:
|
||||
output = subprocess.check_output(quote_args(args), stderr=subprocess.PIPE, shell=True)
|
||||
except subprocess.CalledProcessError, e:
|
||||
if e.returncode == 1:
|
||||
logger.info(u"%s: Couldn't get filebot original filename", fn)
|
||||
else:
|
||||
logger.error(u"%s: Unexpected error while getting filebot original filename: %s", fn,
|
||||
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:
|
||||
@@ -95,6 +128,7 @@ def get_filebot_attrs(fn):
|
||||
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__":
|
||||
|
||||
@@ -4,9 +4,12 @@ python -c "import logging; logging.basicConfig(level=logging.DEBUG); logging.get
|
||||
# addic7ed download_best
|
||||
python -c "import logging; logging.basicConfig(level=logging.DEBUG); logging.getLogger('rebulk').setLevel(logging.WARNING); import os; os.environ['U1pfT01EQl9LRVk'] = '789CF30DAC2C8B0AF433F5C9AD34290A712DF30D7135F12D0FB3E502006FDE081E'; import subliminal_patch, subliminal; from subliminal_patch.core import SZProviderPool, download_best_subtitles; from subliminal_patch.score import compute_score; from babelfish import Language; subliminal.region.configure('dogpile.cache.memory'); from subzero.video import parse_video; video = parse_video('FILE_NAME', hints={'type': 'episode'}, dry_run=True); download_best_subtitles([video], pool_class=SZProviderPool, compute_score=compute_score, providers=['addic7ed'], provider_configs={'addic7ed': {'use_random_agents': True}}, languages={Language('fra')} )"
|
||||
|
||||
# opensubtitles
|
||||
# opensubtitles:list
|
||||
python -c "import logging; logging.basicConfig(level=logging.DEBUG); logging.getLogger('rebulk').setLevel(logging.WARNING); import subliminal_patch, subliminal; subliminal.region.configure('dogpile.cache.memory'); from subliminal_patch.core import SZProviderPool; from babelfish import Language; from subzero.video import parse_video; SZProviderPool(providers=['opensubtitles'], )['opensubtitles'].list_subtitles(parse_video('FULL_PATH', {}, {'type': 'episode'}), languages=[Language('eng')])"
|
||||
|
||||
# opensubtitles:download
|
||||
python -c "import logging; logging.basicConfig(level=logging.DEBUG); logging.getLogger('rebulk').setLevel(logging.WARNING); import subliminal_patch, subliminal; subliminal.region.configure('dogpile.cache.memory'); from subliminal_patch.core import SZProviderPool, download_best_subtitles; from subliminal_patch.score import compute_score; from babelfish import Language; from subzero.video import parse_video; video = parse_video('FILE_NAME', hints={'type': 'movie'}, dry_run=True); download_best_subtitles([video], pool_class=SZProviderPool, compute_score=compute_score, providers=['opensubtitles'], languages={Language('srp')} )"
|
||||
|
||||
# podnapisi
|
||||
python -c "import logging; logging.basicConfig(level=logging.DEBUG); import subliminal_patch, subliminal; subliminal.region.configure('dogpile.cache.memory'); from subliminal_patch.core import SZProviderPool; from babelfish import Language; SZProviderPool(providers=['podnapisi'], )['podnapisi'].query([Language('eng')], 'Game of Thrones', season=2, episode=1)"
|
||||
|
||||
|
||||
@@ -170,6 +170,9 @@ else: # pragma: no cover
|
||||
unicode = str
|
||||
_byte_code = int # noqa
|
||||
|
||||
# don't break 2.6 completely
|
||||
if sys.hexversion < 0x2070000:
|
||||
memoryview = lambda x: x # noqa
|
||||
|
||||
__version__ = '3.0'
|
||||
|
||||
@@ -215,6 +218,12 @@ ALT_EXTRACT_ARGS = ('-x', '-f')
|
||||
ALT_TEST_ARGS = ('-t', '-f')
|
||||
ALT_CHECK_ARGS = ('--help',)
|
||||
|
||||
#ALT_TOOL = 'unar'
|
||||
#ALT_OPEN_ARGS = ('-o', '-')
|
||||
#ALT_EXTRACT_ARGS = ()
|
||||
#ALT_TEST_ARGS = ('-test',) # does not work
|
||||
#ALT_CHECK_ARGS = ('-v',)
|
||||
|
||||
#: whether to speed up decompression by using tmp archive
|
||||
USE_EXTRACT_HACK = 1
|
||||
|
||||
@@ -2525,6 +2534,53 @@ class Blake2SP(object):
|
||||
"""Hexadecimal digest."""
|
||||
return tohex(self.digest())
|
||||
|
||||
|
||||
class Rar3Sha1(object):
|
||||
"""Bug-compat for SHA1
|
||||
"""
|
||||
digest_size = 20
|
||||
block_size = 64
|
||||
|
||||
_BLK_BE = struct.Struct(b'>16L')
|
||||
_BLK_LE = struct.Struct(b'<16L')
|
||||
|
||||
__slots__ = ('_nbytes', '_md', '_rarbug')
|
||||
|
||||
def __init__(self, data=b'', rarbug=False):
|
||||
self._md = sha1()
|
||||
self._nbytes = 0
|
||||
self._rarbug = rarbug
|
||||
self.update(data)
|
||||
|
||||
def update(self, data):
|
||||
"""Process more data."""
|
||||
self._md.update(data)
|
||||
bufpos = self._nbytes & 63
|
||||
self._nbytes += len(data)
|
||||
|
||||
if self._rarbug and len(data) > 64:
|
||||
dpos = self.block_size - bufpos
|
||||
while dpos + self.block_size <= len(data):
|
||||
self._corrupt(data, dpos)
|
||||
dpos += self.block_size
|
||||
|
||||
def digest(self):
|
||||
"""Return final state."""
|
||||
return self._md.digest()
|
||||
|
||||
def hexdigest(self):
|
||||
"""Return final state as hex string."""
|
||||
return self._md.hexdigest()
|
||||
|
||||
def _corrupt(self, data, dpos):
|
||||
"""Corruption from SHA1 core."""
|
||||
ws = list(self._BLK_BE.unpack_from(data, dpos))
|
||||
for t in range(16, 80):
|
||||
tmp = ws[(t - 3) & 15] ^ ws[(t - 8) & 15] ^ ws[(t - 14) & 15] ^ ws[(t - 16) & 15]
|
||||
ws[t & 15] = ((tmp << 1) | (tmp >> (32 - 1))) & 0xFFFFFFFF
|
||||
self._BLK_LE.pack_into(data, dpos, *ws)
|
||||
|
||||
|
||||
##
|
||||
## Utility functions
|
||||
##
|
||||
@@ -2686,13 +2742,14 @@ def rar3_s2k(psw, salt):
|
||||
"""
|
||||
if not isinstance(psw, unicode):
|
||||
psw = psw.decode('utf8')
|
||||
seed = psw.encode('utf-16le') + salt
|
||||
seed = bytearray(psw.encode('utf-16le') + salt)
|
||||
h = Rar3Sha1(rarbug=True)
|
||||
iv = EMPTY
|
||||
h = sha1()
|
||||
for i in range(16):
|
||||
for j in range(0x4000):
|
||||
cnt = S_LONG.pack(i * 0x4000 + j)
|
||||
h.update(seed + cnt[:3])
|
||||
h.update(seed)
|
||||
h.update(cnt[:3])
|
||||
if j == 0:
|
||||
iv += h.digest()[19:20]
|
||||
key_be = h.digest()[:16]
|
||||
@@ -2814,6 +2871,8 @@ def custom_popen(cmd):
|
||||
except OSError as ex:
|
||||
if ex.errno == errno.ENOENT:
|
||||
raise RarCannotExec("Unrar not installed? (rarfile.UNRAR_TOOL=%r)" % UNRAR_TOOL)
|
||||
if ex.errno == errno.EACCES or ex.errno == errno.EPERM:
|
||||
raise RarCannotExec("Cannot execute unrar (rarfile.UNRAR_TOOL=%r)" % UNRAR_TOOL)
|
||||
raise
|
||||
return p
|
||||
|
||||
@@ -2945,7 +3004,9 @@ def _check_unrar_tool():
|
||||
TEST_ARGS = ALT_TEST_ARGS
|
||||
except RarCannotExec:
|
||||
# no usable tool, only uncompressed archives work
|
||||
pass
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
try:
|
||||
_check_unrar_tool()
|
||||
|
||||
@@ -556,7 +556,13 @@ elif sys.platform.startswith(('linux', 'darwin', 'sunos5')) or 'bsd' in sys.plat
|
||||
name = entry.d_name
|
||||
if name not in (b'.', b'..'):
|
||||
if not is_bytes:
|
||||
name = name.decode(file_system_encoding)
|
||||
try:
|
||||
name = name.decode(file_system_encoding)
|
||||
except UnicodeDecodeError:
|
||||
try:
|
||||
name = name.decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
yield PosixDirEntry(path, name, entry.d_type, entry.d_ino)
|
||||
finally:
|
||||
if closedir(dir_p):
|
||||
@@ -667,5 +673,8 @@ else:
|
||||
|
||||
def walk(top, topdown=True, onerror=None, followlinks=False):
|
||||
if isinstance(top, bytes):
|
||||
top = top.decode(file_system_encoding)
|
||||
try:
|
||||
top = top.decode(file_system_encoding)
|
||||
except UnicodeDecodeError:
|
||||
top = top.decode("utf-8")
|
||||
return _walk(top, topdown, onerror, followlinks)
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from babelfish import LanguageReverseConverter
|
||||
from subliminal.exceptions import ConfigurationError
|
||||
|
||||
class AssrtConverter(LanguageReverseConverter):
|
||||
def __init__(self):
|
||||
self.from_assrt = { u'简体': ('zho', None, 'Hans'), u'繁体': ('zho', None, 'Hant'),
|
||||
u'簡體': ('zho', None, 'Hans'), u'繁體': ('zho', None, 'Hant'),
|
||||
u'英文': ('eng',),
|
||||
u'chs': ('zho', None, 'Hans'), u'cht': ('zho', None, 'Hant'),
|
||||
u'chn': ('zho', None, 'Hans'), u'twn': ('zho', None, 'Hant')}
|
||||
self.to_assrt = { ('zho', None, 'Hans'): u'chs', ('zho', None, 'Hant'): u'cht', ('eng',) : u'eng' }
|
||||
self.codes = set(self.from_assrt.keys())
|
||||
|
||||
def convert(self, alpha3, country=None, script=None):
|
||||
if (alpha3, country, script) in self.to_assrt:
|
||||
return self.to_assrt[(alpha3, country, script)]
|
||||
|
||||
raise ConfigurationError('Unsupported language for assrt: %s, %s, %s' % (alpha3, country, script))
|
||||
|
||||
def reverse(self, assrt):
|
||||
if assrt in self.from_assrt:
|
||||
return self.from_assrt[assrt]
|
||||
|
||||
raise ConfigurationError('Unsupported language code for assrt: %s' % assrt)
|
||||
@@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from babelfish import LanguageReverseConverter, language_converters
|
||||
|
||||
|
||||
class SuperSubtitlesConverter(LanguageReverseConverter):
|
||||
def __init__(self):
|
||||
self.alpha2_converter = language_converters['alpha2']
|
||||
self.from_supersubtitles = {'hu': ('hun', ), 'en': ('eng',)}
|
||||
self.to_supersubtitles = {v: k for k, v in self.from_supersubtitles.items()}
|
||||
self.codes = self.alpha2_converter.codes | set(self.from_supersubtitles.keys())
|
||||
|
||||
def convert(self, alpha3, country=None, script=None):
|
||||
if (alpha3, country) in self.to_supersubtitles:
|
||||
return self.to_supersubtitles[(alpha3, country)]
|
||||
if (alpha3,) in self.to_supersubtitles:
|
||||
return self.to_supersubtitles[(alpha3,)]
|
||||
|
||||
return self.alpha2_converter.convert(alpha3, country, script)
|
||||
|
||||
def reverse(self, supersubtitles):
|
||||
if supersubtitles in self.from_supersubtitles:
|
||||
return self.from_supersubtitles[supersubtitles]
|
||||
|
||||
return self.alpha2_converter.reverse(supersubtitles)
|
||||
@@ -31,7 +31,7 @@ from subliminal.core import guessit, ProviderPool, io, is_windows_special_path,
|
||||
from subliminal_patch.exceptions import TooManyRequests
|
||||
|
||||
from subzero.language import Language
|
||||
from subzero.lib.io import scandir
|
||||
from scandir import scandir
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -156,8 +156,19 @@ class SZProviderPool(ProviderPool):
|
||||
|
||||
# list subtitles
|
||||
logger.info('Listing subtitles with provider %r and languages %r', provider, provider_languages)
|
||||
results = []
|
||||
try:
|
||||
results = self[provider].list_subtitles(video, provider_languages)
|
||||
try:
|
||||
results = self[provider].list_subtitles(video, provider_languages)
|
||||
except ResponseNotReady:
|
||||
logger.error('Provider %r response error, reinitializing', provider)
|
||||
try:
|
||||
self[provider].terminate()
|
||||
self[provider].initialize()
|
||||
results = self[provider].list_subtitles(video, provider_languages)
|
||||
except:
|
||||
logger.error('Provider %r reinitialization error: %s', provider, traceback.format_exc())
|
||||
|
||||
seen = []
|
||||
out = []
|
||||
for s in results:
|
||||
@@ -264,10 +275,12 @@ class SZProviderPool(ProviderPool):
|
||||
self[subtitle.provider_name].terminate()
|
||||
self[subtitle.provider_name].initialize()
|
||||
except:
|
||||
logger.error('Provider %r reinitialization error', subtitle.provider_name)
|
||||
logger.error('Provider %r reinitialization error: %s', subtitle.provider_name,
|
||||
traceback.format_exc())
|
||||
|
||||
except rarfile.BadRarFile:
|
||||
logger.error('Malformed RAR file from provider %r, skipping subtitle.', subtitle.provider_name)
|
||||
logger.debug("RAR Traceback: %s", traceback.format_exc())
|
||||
return False
|
||||
|
||||
except (TooManyRequests, DownloadLimitExceeded, ServiceUnavailable), e:
|
||||
@@ -374,10 +387,15 @@ class SZProviderPool(ProviderPool):
|
||||
score, hearing_impaired)
|
||||
continue
|
||||
|
||||
if is_episode and not {"series", "season", "episode"}.issubset(orig_matches):
|
||||
logger.debug("%r: Skipping subtitle with score %d, because it doesn't match our series/episode",
|
||||
subtitle, score)
|
||||
continue
|
||||
if is_episode:
|
||||
can_verify_series = True
|
||||
if not subtitle.hash_verifiable and "hash" in matches:
|
||||
can_verify_series = False
|
||||
|
||||
if can_verify_series and not {"series", "season", "episode"}.issubset(orig_matches):
|
||||
logger.debug("%r: Skipping subtitle with score %d, because it doesn't match our series/episode",
|
||||
subtitle, score)
|
||||
continue
|
||||
|
||||
# download
|
||||
logger.debug("%r: Trying to download subtitle with matches %s, score: %s; release(s): %s", subtitle, matches,
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
# coding=utf-8
|
||||
from xmlrpclib import SafeTransport, ProtocolError, Fault, Transport
|
||||
|
||||
import certifi
|
||||
import ssl
|
||||
import os
|
||||
import socket
|
||||
import logging
|
||||
import requests
|
||||
import xmlrpclib
|
||||
|
||||
from xmlrpclib import SafeTransport, Transport
|
||||
from requests import Session, exceptions
|
||||
from retry.api import retry_call
|
||||
|
||||
@@ -21,11 +22,17 @@ except AttributeError:
|
||||
default_ssl_context = None
|
||||
|
||||
|
||||
class RetryingSession(Session):
|
||||
class CertifiSession(Session):
|
||||
def __init__(self):
|
||||
super(CertifiSession, self).__init__()
|
||||
self.verify = pem_file
|
||||
|
||||
|
||||
class RetryingSession(CertifiSession):
|
||||
proxied_functions = ("get", "post")
|
||||
|
||||
def __init__(self):
|
||||
super(RetryingSession, self).__init__()
|
||||
super(CertifiSession, self).__init__()
|
||||
self.verify = pem_file
|
||||
|
||||
proxy = os.environ.get('SZ_HTTP_PROXY')
|
||||
@@ -40,7 +47,7 @@ class RetryingSession(Session):
|
||||
# fixme: may be a little loud
|
||||
logger.debug("Using proxy %s for: %s", self.proxies["http"], args[0])
|
||||
|
||||
return retry_call(getattr(super(RetryingSession, self), method), fargs=args, fkwargs=kwargs, tries=3, delay=5,
|
||||
return retry_call(getattr(super(CertifiSession, self), method), fargs=args, fkwargs=kwargs, tries=3, delay=5,
|
||||
exceptions=(exceptions.ConnectionError,
|
||||
exceptions.ProxyError,
|
||||
exceptions.SSLError,
|
||||
@@ -60,55 +67,56 @@ class RetryingSession(Session):
|
||||
return self.retry_method("post", *args, **kwargs)
|
||||
|
||||
|
||||
class TimeoutTransport(Transport):
|
||||
"""Timeout support for ``xmlrpc.client.SafeTransport``."""
|
||||
def __init__(self, timeout, *args, **kwargs):
|
||||
Transport.__init__(self, *args, **kwargs)
|
||||
self.timeout = timeout
|
||||
|
||||
def make_connection(self, host):
|
||||
c = Transport.make_connection(self, host)
|
||||
c.timeout = self.timeout
|
||||
|
||||
return c
|
||||
|
||||
|
||||
class SubZeroTransport(SafeTransport):
|
||||
class SubZeroRequestsTransport(xmlrpclib.SafeTransport):
|
||||
"""
|
||||
Timeout and proxy support for ``xmlrpc.client.(Safe)Transport``
|
||||
Drop in Transport for xmlrpclib that uses Requests instead of httplib
|
||||
|
||||
Based on: https://gist.github.com/chrisguitarguy/2354951#gistcomment-2388906
|
||||
|
||||
"""
|
||||
def __init__(self, timeout, url, *args, **kwargs):
|
||||
SafeTransport.__init__(self, *args, **kwargs)
|
||||
# change our user agent to reflect Requests
|
||||
user_agent = "Python XMLRPC with Requests (python-requests.org)"
|
||||
proxies = None
|
||||
|
||||
def __init__(self, use_https=True, verify=None, user_agent=None, timeout=10, *args, **kwargs):
|
||||
self.verify = pem_file if verify is None else verify
|
||||
self.use_https = use_https
|
||||
self.user_agent = user_agent if user_agent is not None else self.user_agent
|
||||
self.timeout = timeout
|
||||
self.host = None
|
||||
self.proxy = None
|
||||
self.scheme = url.split('://', 1)[0]
|
||||
self.https = url.startswith('https')
|
||||
self.proxy = os.environ.get('SZ_HTTP_PROXY')
|
||||
proxy = os.environ.get('SZ_HTTP_PROXY')
|
||||
if proxy:
|
||||
self.proxies = {
|
||||
"http": proxy,
|
||||
"https": proxy
|
||||
}
|
||||
|
||||
if self.https:
|
||||
self.context = default_ssl_context
|
||||
xmlrpclib.SafeTransport.__init__(self, *args, **kwargs)
|
||||
|
||||
if self.proxy:
|
||||
logger.debug("Using proxy %s for: %s", self.proxy, url)
|
||||
self.https = self.proxy.startswith('https')
|
||||
|
||||
if self.timeout:
|
||||
self.timeout = self.timeout * 3
|
||||
|
||||
def make_connection(self, host):
|
||||
self.host = host
|
||||
if self.proxy:
|
||||
host = self.proxy.split('://', 1)[-1]
|
||||
if self.https:
|
||||
c = SafeTransport.make_connection(self, host)
|
||||
def request(self, host, handler, request_body, verbose=0):
|
||||
"""
|
||||
Make an xmlrpc request.
|
||||
"""
|
||||
headers = {'User-Agent': self.user_agent}
|
||||
url = self._build_url(host, handler)
|
||||
try:
|
||||
resp = requests.post(url, data=request_body, headers=headers,
|
||||
stream=True, timeout=self.timeout, proxies=self.proxies,
|
||||
verify=self.verify)
|
||||
except ValueError:
|
||||
raise
|
||||
except Exception:
|
||||
raise # something went wrong
|
||||
else:
|
||||
c = Transport.make_connection(self, host)
|
||||
resp.raise_for_status()
|
||||
|
||||
c.timeout = self.timeout
|
||||
self.verbose = verbose
|
||||
return self.parse_response(resp.raw)
|
||||
|
||||
return c
|
||||
|
||||
def send_request(self, connection, handler, request_body):
|
||||
handler = '%s://%s%s' % (self.scheme, self.host, handler)
|
||||
Transport.send_request(self, connection, handler, request_body)
|
||||
def _build_url(self, host, handler):
|
||||
"""
|
||||
Build a url for our request based on the host, handler and use_http
|
||||
property
|
||||
"""
|
||||
scheme = 'https' if self.use_https else 'http'
|
||||
handler = handler[1:] if handler and handler[0] == "/" else handler
|
||||
return '%s://%s/%s' % (scheme, host, handler)
|
||||
|
||||
@@ -20,6 +20,10 @@ class PatchedOpenSubtitlesConverter(OpenSubtitlesConverter):
|
||||
self.to_opensubtitles.update({
|
||||
('srp', None, "Latn"): 'scc',
|
||||
('srp', None, "Cyrl"): 'scc',
|
||||
('chi', None, 'Hant'): 'zht'
|
||||
})
|
||||
self.from_opensubtitles.update({
|
||||
'zht': ('zho', None, 'Hant')
|
||||
})
|
||||
|
||||
def convert(self, alpha3, country=None, script=None):
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
# coding=utf-8
|
||||
import logging
|
||||
import re
|
||||
|
||||
import datetime
|
||||
import subliminal
|
||||
import time
|
||||
from random import randint
|
||||
from dogpile.cache.api import NO_VALUE
|
||||
from requests import Session
|
||||
|
||||
from subliminal.exceptions import ServiceUnavailable, DownloadLimitExceeded
|
||||
from subliminal.exceptions import ServiceUnavailable, DownloadLimitExceeded, AuthenticationError
|
||||
from subliminal.providers.addic7ed import Addic7edProvider as _Addic7edProvider, \
|
||||
Addic7edSubtitle as _Addic7edSubtitle, ParserBeautifulSoup, show_cells_re
|
||||
from subliminal.cache import SHOW_EXPIRATION_TIME, region
|
||||
from subliminal.cache import region
|
||||
from subliminal.subtitle import fix_line_ending
|
||||
from subliminal_patch.utils import sanitize
|
||||
from subliminal_patch.exceptions import TooManyRequests
|
||||
@@ -20,6 +23,8 @@ logger = logging.getLogger(__name__)
|
||||
#: Series header parsing regex
|
||||
series_year_re = re.compile(r'^(?P<series>[ \w\'.:(),*&!?-]+?)(?: \((?P<year>\d{4})\))?$')
|
||||
|
||||
SHOW_EXPIRATION_TIME = datetime.timedelta(weeks=1).total_seconds()
|
||||
|
||||
|
||||
class Addic7edSubtitle(_Addic7edSubtitle):
|
||||
hearing_impaired_verifiable = True
|
||||
@@ -67,14 +72,46 @@ class Addic7edProvider(_Addic7edProvider):
|
||||
self.USE_ADDICTED_RANDOM_AGENTS = use_random_agents
|
||||
|
||||
def initialize(self):
|
||||
# patch: add optional user agent randomization
|
||||
super(Addic7edProvider, self).initialize()
|
||||
self.session = Session()
|
||||
self.session.headers['User-Agent'] = 'Subliminal/%s' % subliminal.__short_version__
|
||||
|
||||
if self.USE_ADDICTED_RANDOM_AGENTS:
|
||||
from .utils import FIRST_THOUSAND_OR_SO_USER_AGENTS as AGENT_LIST
|
||||
logger.debug("addic7ed: using random user agents")
|
||||
logger.debug("Addic7ed: using random user agents")
|
||||
self.session.headers['User-Agent'] = AGENT_LIST[randint(0, len(AGENT_LIST) - 1)]
|
||||
self.session.headers['Referer'] = self.server_url
|
||||
|
||||
# login
|
||||
if self.username and self.password:
|
||||
ccks = region.get("addic7ed_cookies", expiration_time=86400)
|
||||
do_login = False
|
||||
if ccks != NO_VALUE:
|
||||
self.session.cookies.update(ccks)
|
||||
r = self.session.get(self.server_url + 'panel.php', allow_redirects=False, timeout=10)
|
||||
if r.status_code == 302:
|
||||
logger.info('Addic7ed: Login expired')
|
||||
do_login = True
|
||||
else:
|
||||
logger.info('Addic7ed: Reusing old login')
|
||||
self.logged_in = True
|
||||
|
||||
if do_login:
|
||||
logger.info('Addic7ed: Logging in')
|
||||
data = {'username': self.username, 'password': self.password, 'Submit': 'Log in'}
|
||||
r = self.session.post(self.server_url + 'dologin.php', data, allow_redirects=False, timeout=10)
|
||||
|
||||
if "relax, slow down" in r.content:
|
||||
raise TooManyRequests(self.username)
|
||||
|
||||
if r.status_code != 302:
|
||||
raise AuthenticationError(self.username)
|
||||
|
||||
region.set("addic7ed_cookies", r.cookies)
|
||||
|
||||
logger.debug('Addic7ed: Logged in')
|
||||
self.logged_in = True
|
||||
|
||||
|
||||
@region.cache_on_arguments(expiration_time=SHOW_EXPIRATION_TIME)
|
||||
def _get_show_ids(self):
|
||||
"""Get the ``dict`` of show ids per series by querying the `shows.php` page.
|
||||
@@ -140,10 +177,26 @@ class Addic7edProvider(_Addic7edProvider):
|
||||
|
||||
# make the search
|
||||
logger.info('Searching show ids with %r', params)
|
||||
r = self.session.get(self.server_url + 'search.php', params=params, timeout=10)
|
||||
r.raise_for_status()
|
||||
|
||||
# currently addic7ed searches via srch.php from the front page, then a re-search is needed which calls
|
||||
# search.php
|
||||
for endpoint in ("srch.php", "search.php",):
|
||||
headers = None
|
||||
if endpoint == "search.php":
|
||||
headers = {
|
||||
"referer": self.server_url + "srch.php"
|
||||
}
|
||||
r = self.session.get(self.server_url + endpoint, params=params, timeout=10, headers=headers)
|
||||
r.raise_for_status()
|
||||
|
||||
if r.content and "Sorry, your search" not in r.content:
|
||||
break
|
||||
|
||||
time.sleep(4)
|
||||
|
||||
if r.status_code == 304:
|
||||
raise TooManyRequests()
|
||||
|
||||
soup = ParserBeautifulSoup(r.content, ['lxml', 'html.parser'])
|
||||
|
||||
suggestion = None
|
||||
@@ -172,7 +225,15 @@ class Addic7edProvider(_Addic7edProvider):
|
||||
|
||||
# get the page of the season of the show
|
||||
logger.info('Getting the page of show id %d, season %d', show_id, season)
|
||||
r = self.session.get(self.server_url + 'show/%d' % show_id, params={'season': season}, timeout=10)
|
||||
r = self.session.get(self.server_url + 'ajax_loadShow.php',
|
||||
params={'show': show_id, 'season': season},
|
||||
timeout=10,
|
||||
headers={
|
||||
"referer": "%sshow/%s" % (self.server_url, show_id),
|
||||
"X-Requested-With": "XMLHttpRequest"
|
||||
}
|
||||
)
|
||||
|
||||
r.raise_for_status()
|
||||
|
||||
if r.status_code == 304:
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
||||
from babelfish import language_converters
|
||||
from guessit import guessit
|
||||
from requests import Session
|
||||
|
||||
from subliminal import Movie, Episode, ProviderError, __short_version__
|
||||
from subliminal.exceptions import AuthenticationError, ConfigurationError, DownloadLimitExceeded, ProviderError
|
||||
from subliminal_patch.subtitle import Subtitle, guess_matches
|
||||
from subliminal.subtitle import fix_line_ending
|
||||
from subliminal_patch.providers import Provider
|
||||
from subzero.language import Language
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
language_converters.register('assrt = subliminal_patch.converters.assrt:AssrtConverter')
|
||||
|
||||
server_url = 'https://api.assrt.net/v1'
|
||||
supported_languages = language_converters['assrt'].to_assrt.keys()
|
||||
|
||||
|
||||
class AssrtSubtitle(Subtitle):
|
||||
"""Assrt Sbutitle."""
|
||||
provider_name = 'assrt'
|
||||
guessit_options = {
|
||||
'allowed_languages': [ l[0] for l in supported_languages ],
|
||||
'allowed_countries': [ l[1] for l in supported_languages if len(l) > 1 ],
|
||||
'enforce_list': True
|
||||
}
|
||||
|
||||
def __init__(self, language, subtitle_id, video_name, session, token):
|
||||
super(AssrtSubtitle, self).__init__(language)
|
||||
self.session = session
|
||||
self.token = token
|
||||
self.subtitle_id = subtitle_id
|
||||
self.video_name = video_name
|
||||
self.url = None
|
||||
self._detail = None
|
||||
|
||||
def _get_detail(self):
|
||||
if self._detail:
|
||||
return self._detail
|
||||
params = {'token': self.token, 'id': self.id}
|
||||
r = self.session.get(server_url + '/sub/detail', params=params, timeout=10)
|
||||
r.raise_for_status()
|
||||
|
||||
result = r.json()
|
||||
sub = result['sub']['subs'][0]
|
||||
files = sub['filelist']
|
||||
|
||||
# first pass: guessit
|
||||
for f in files:
|
||||
logger.info('File %r', f)
|
||||
guess = guessit(f['f'], self.guessit_options)
|
||||
logger.info('GuessIt %r', guess)
|
||||
langs = set()
|
||||
if 'language' in guess:
|
||||
langs.update(guess['language'])
|
||||
if 'subtitle_language' in guess:
|
||||
langs.update(guess['subtitle_language'])
|
||||
if self.language in langs:
|
||||
self._defail = f
|
||||
return f
|
||||
|
||||
# second pass: keyword matching
|
||||
codes = language_converters['assrt'].codes
|
||||
for f in files:
|
||||
langs = set([ Language.fromassrt(k) for k in codes if k in f['f'] ])
|
||||
logger.info('%s: %r', f['f'], langs)
|
||||
if self.language in langs:
|
||||
self._defail = f
|
||||
return f
|
||||
|
||||
# fallback: pick up first file if nothing matches
|
||||
return files[0]
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
return self.subtitle_id
|
||||
|
||||
@property
|
||||
def download_link(self):
|
||||
detail = self._get_detail()
|
||||
return detail['url']
|
||||
|
||||
def get_matches(self, video):
|
||||
matches = guess_matches(video, guessit(self.video_name))
|
||||
return matches
|
||||
|
||||
|
||||
class AssrtProvider(Provider):
|
||||
"""Assrt Provider."""
|
||||
languages = {Language(*l) for l in supported_languages}
|
||||
|
||||
def __init__(self, token=None):
|
||||
if not token:
|
||||
raise ConfigurationError('Token must be specified')
|
||||
self.token = token
|
||||
|
||||
def initialize(self):
|
||||
self.session = Session()
|
||||
self.session.headers = {'User-Agent': os.environ.get("SZ_USER_AGENT", "Sub-Zero/2")}
|
||||
|
||||
def terminate(self):
|
||||
self.session.close()
|
||||
|
||||
def query(self, languages, video):
|
||||
# query the server
|
||||
keywords = []
|
||||
if isinstance(video, Movie):
|
||||
if video.title:
|
||||
keywords.append(video.title)
|
||||
if video.year:
|
||||
keywords.append(str(video.year))
|
||||
elif isinstance(video, Episode):
|
||||
if video.series:
|
||||
keywords.append(video.series)
|
||||
if video.season and video.episode:
|
||||
keywords.append('S%02dE%02d' % (video.season, video.episode))
|
||||
elif video.episode:
|
||||
keywords.append('E%02d' % video.episode)
|
||||
query = ' '.join(keywords)
|
||||
|
||||
params = {'token': self.token, 'q': query, 'is_file': 1}
|
||||
logger.debug('Searching subtitles %r', params)
|
||||
res = self.session.get(server_url + '/sub/search', params=params, timeout=10)
|
||||
res.raise_for_status()
|
||||
result = res.json()
|
||||
|
||||
if result['status'] != 0:
|
||||
logger.error('status error: %r', r)
|
||||
return []
|
||||
|
||||
if not result['sub']['subs']:
|
||||
logger.debug('No subtitle found')
|
||||
|
||||
# parse the subtitles
|
||||
pattern = re.compile(ur'lang(?P<code>\w+)')
|
||||
subtitles = []
|
||||
for sub in result['sub']['subs']:
|
||||
if 'lang' not in sub:
|
||||
continue
|
||||
for key in sub['lang']['langlist'].keys():
|
||||
match = pattern.match(key)
|
||||
try:
|
||||
language = Language.fromassrt(match.group('code'))
|
||||
if language in languages:
|
||||
subtitles.append(AssrtSubtitle(language, sub['id'], sub['videoname'], self.session, self.token))
|
||||
except:
|
||||
pass
|
||||
|
||||
return subtitles
|
||||
|
||||
def list_subtitles(self, video, languages):
|
||||
return self.query(languages, video)
|
||||
|
||||
def download_subtitle(self, subtitle):
|
||||
logger.info('Downloading subtitle %r', subtitle)
|
||||
r = self.session.get(subtitle.download_link, timeout=10)
|
||||
r.raise_for_status()
|
||||
|
||||
subtitle.content = fix_line_ending(r.content)
|
||||
@@ -1,5 +1,7 @@
|
||||
# coding=utf-8
|
||||
import logging
|
||||
import rarfile
|
||||
from subliminal.exceptions import ConfigurationError
|
||||
|
||||
from subliminal.providers.legendastv import LegendasTVSubtitle as _LegendasTVSubtitle, \
|
||||
LegendasTVProvider as _LegendasTVProvider, Episode, Movie, guess_matches, guessit, sanitize
|
||||
@@ -60,6 +62,22 @@ class LegendasTVSubtitle(_LegendasTVSubtitle):
|
||||
class LegendasTVProvider(_LegendasTVProvider):
|
||||
subtitle_class = LegendasTVSubtitle
|
||||
|
||||
def __init__(self, username=None, password=None):
|
||||
|
||||
# Provider needs UNRAR installed. If not available raise ConfigurationError
|
||||
try:
|
||||
rarfile.custom_check([rarfile.UNRAR_TOOL], True)
|
||||
except rarfile.RarExecError:
|
||||
raise ConfigurationError('UNRAR tool not available')
|
||||
|
||||
if any((username, password)) and not all((username, password)):
|
||||
raise ConfigurationError('Username and password must be specified')
|
||||
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.logged_in = False
|
||||
self.session = None
|
||||
|
||||
def download_subtitle(self, subtitle):
|
||||
super(LegendasTVProvider, self).download_subtitle(subtitle)
|
||||
subtitle.archive.content = None
|
||||
|
||||
@@ -5,6 +5,7 @@ import time
|
||||
import logging
|
||||
import traceback
|
||||
import types
|
||||
from httplib import ResponseNotReady
|
||||
|
||||
from guessit import guessit
|
||||
from subliminal import ProviderError
|
||||
@@ -42,7 +43,7 @@ class ProviderRetryMixin(object):
|
||||
while i <= amount:
|
||||
try:
|
||||
return f()
|
||||
except (Unauthorized, ServiceUnavailable, TooManyRequests, DownloadLimitExceeded):
|
||||
except (Unauthorized, ServiceUnavailable, TooManyRequests, DownloadLimitExceeded, ResponseNotReady):
|
||||
raise
|
||||
except exc:
|
||||
formatted_exc = traceback.format_exc()
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
# coding=utf-8
|
||||
|
||||
import base64
|
||||
import logging
|
||||
import os
|
||||
import traceback
|
||||
import zlib
|
||||
|
||||
import requests
|
||||
|
||||
from babelfish import language_converters
|
||||
from dogpile.cache.api import NO_VALUE
|
||||
@@ -10,7 +14,8 @@ from subliminal.providers.opensubtitles import OpenSubtitlesProvider as _OpenSub
|
||||
OpenSubtitlesSubtitle as _OpenSubtitlesSubtitle, Episode, ServerProxy, Unauthorized, NoSession, \
|
||||
DownloadLimitReached, InvalidImdbid, UnknownUserAgent, DisabledUserAgent, OpenSubtitlesError
|
||||
from mixins import ProviderRetryMixin
|
||||
from subliminal_patch.http import SubZeroTransport
|
||||
from subliminal.subtitle import fix_line_ending
|
||||
from subliminal_patch.http import SubZeroRequestsTransport
|
||||
from subliminal.cache import region
|
||||
from subliminal_patch.score import framerate_equal
|
||||
from subzero.language import Language
|
||||
@@ -74,15 +79,17 @@ class OpenSubtitlesProvider(ProviderRetryMixin, _OpenSubtitlesProvider):
|
||||
hearing_impaired_verifiable = True
|
||||
skip_wrong_fps = True
|
||||
is_vip = False
|
||||
use_ssl = True
|
||||
timeout = 15
|
||||
|
||||
default_url = "https://api.opensubtitles.org/xml-rpc"
|
||||
vip_url = "https://vip-api.opensubtitles.org/xml-rpc"
|
||||
default_url = "//api.opensubtitles.org/xml-rpc"
|
||||
vip_url = "//vip-api.opensubtitles.org/xml-rpc"
|
||||
|
||||
languages = {Language.fromopensubtitles(l) for l in language_converters['szopensubtitles'].codes}# | {
|
||||
#Language.fromietf("sr-latn"), Language.fromietf("sr-cyrl")}
|
||||
|
||||
def __init__(self, username=None, password=None, use_tag_search=False, only_foreign=False, skip_wrong_fps=True,
|
||||
is_vip=False):
|
||||
is_vip=False, use_ssl=True, timeout=15):
|
||||
if any((username, password)) and not all((username, password)):
|
||||
raise ConfigurationError('Username and password must be specified')
|
||||
|
||||
@@ -93,6 +100,16 @@ class OpenSubtitlesProvider(ProviderRetryMixin, _OpenSubtitlesProvider):
|
||||
self.skip_wrong_fps = skip_wrong_fps
|
||||
self.token = None
|
||||
self.is_vip = is_vip
|
||||
self.use_ssl = use_ssl
|
||||
self.timeout = timeout
|
||||
|
||||
logger.debug("Using timeout: %d", timeout)
|
||||
|
||||
if use_ssl:
|
||||
logger.debug("Using HTTPS connection")
|
||||
|
||||
self.default_url = ("https:" if use_ssl else "http:") + self.default_url
|
||||
self.vip_url = ("https:" if use_ssl else "http:") + self.vip_url
|
||||
|
||||
if use_tag_search:
|
||||
logger.info("Using tag/exact filename search")
|
||||
@@ -100,8 +117,9 @@ class OpenSubtitlesProvider(ProviderRetryMixin, _OpenSubtitlesProvider):
|
||||
if only_foreign:
|
||||
logger.info("Only searching for foreign/forced subtitles")
|
||||
|
||||
def get_server_proxy(self, url, timeout=10):
|
||||
return ServerProxy(url, SubZeroTransport(timeout, url))
|
||||
def get_server_proxy(self, url, timeout=None):
|
||||
return ServerProxy(url, SubZeroRequestsTransport(use_https=self.use_ssl, timeout=timeout or self.timeout,
|
||||
user_agent=os.environ.get("SZ_USER_AGENT", "Sub-Zero/2")))
|
||||
|
||||
def log_in(self, server_url=None):
|
||||
if server_url:
|
||||
@@ -111,13 +129,13 @@ class OpenSubtitlesProvider(ProviderRetryMixin, _OpenSubtitlesProvider):
|
||||
|
||||
response = self.retry(
|
||||
lambda: checked(
|
||||
self.server.LogIn(self.username, self.password, 'eng',
|
||||
os.environ.get("SZ_USER_AGENT", "Sub-Zero/2"))
|
||||
lambda: self.server.LogIn(self.username, self.password, 'eng',
|
||||
os.environ.get("SZ_USER_AGENT", "Sub-Zero/2"))
|
||||
)
|
||||
)
|
||||
|
||||
self.token = response['token']
|
||||
logger.debug('Logged in with token %r', self.token)
|
||||
logger.debug('Logged in with token %r', self.token[:10]+"X"*(len(self.token)-10))
|
||||
|
||||
region.set("os_token", self.token)
|
||||
|
||||
@@ -143,9 +161,10 @@ class OpenSubtitlesProvider(ProviderRetryMixin, _OpenSubtitlesProvider):
|
||||
token = region.get("os_token", expiration_time=3600)
|
||||
if token is not NO_VALUE:
|
||||
try:
|
||||
checked(self.server.NoOperation(token))
|
||||
logger.debug('Trying previous token')
|
||||
checked(lambda: self.server.NoOperation(token))
|
||||
self.token = token
|
||||
logger.info("Using previous login token: %s", self.token)
|
||||
logger.debug("Using previous login token: %s", self.token)
|
||||
return
|
||||
except:
|
||||
pass
|
||||
@@ -163,12 +182,18 @@ class OpenSubtitlesProvider(ProviderRetryMixin, _OpenSubtitlesProvider):
|
||||
logger.error("Login failed, please check your credentials")
|
||||
|
||||
def terminate(self):
|
||||
try:
|
||||
if self.server:
|
||||
self.server.close()
|
||||
except:
|
||||
pass
|
||||
if self.token:
|
||||
try:
|
||||
checked(lambda: self.server.LogOut(self.token))
|
||||
except:
|
||||
logger.error("Logout failed: %s", traceback.format_exc())
|
||||
|
||||
try:
|
||||
self.server.close()
|
||||
except:
|
||||
logger.error("Logout failed (server close): %s", traceback.format_exc())
|
||||
|
||||
self.server = None
|
||||
self.token = None
|
||||
|
||||
def list_subtitles(self, video, languages):
|
||||
@@ -227,7 +252,7 @@ class OpenSubtitlesProvider(ProviderRetryMixin, _OpenSubtitlesProvider):
|
||||
# query the server
|
||||
logger.info('Searching subtitles %r', criteria)
|
||||
response = self.use_token_or_login(
|
||||
lambda: self.retry(lambda: checked(self.server.SearchSubtitles(self.token, criteria)))
|
||||
lambda: self.retry(lambda: checked(lambda: self.server.SearchSubtitles(self.token, criteria)))
|
||||
)
|
||||
|
||||
subtitles = []
|
||||
@@ -240,12 +265,10 @@ class OpenSubtitlesProvider(ProviderRetryMixin, _OpenSubtitlesProvider):
|
||||
# loop over subtitle items
|
||||
for subtitle_item in response['data']:
|
||||
_subtitle_item = subtitle_item
|
||||
if not isinstance(_subtitle_item, dict):
|
||||
_subtitle_item = response["data"][subtitle_item]
|
||||
|
||||
if not isinstance(_subtitle_item, dict):
|
||||
logger.error("Malformed data returned from API")
|
||||
continue
|
||||
# in case OS messes their API results up again, check whether we've got a dict or a string as subtitle_item
|
||||
if hasattr(_subtitle_item, "startswith"):
|
||||
_subtitle_item = response["data"][subtitle_item]
|
||||
|
||||
# read the item
|
||||
language = Language.fromopensubtitles(_subtitle_item['SubLanguageID'])
|
||||
@@ -287,18 +310,31 @@ class OpenSubtitlesProvider(ProviderRetryMixin, _OpenSubtitlesProvider):
|
||||
return subtitles
|
||||
|
||||
def download_subtitle(self, subtitle):
|
||||
return self.use_token_or_login(lambda: super(OpenSubtitlesProvider, self).download_subtitle(subtitle))
|
||||
logger.info('Downloading subtitle %r', subtitle)
|
||||
response = self.use_token_or_login(
|
||||
lambda: checked(
|
||||
lambda: self.server.DownloadSubtitles(self.token, [str(subtitle.subtitle_id)])
|
||||
)
|
||||
)
|
||||
subtitle.content = fix_line_ending(zlib.decompress(base64.b64decode(response['data'][0]['data']), 47))
|
||||
|
||||
|
||||
def checked(response):
|
||||
"""Check a response status before returning it.
|
||||
def checked(fn):
|
||||
"""Run :fn: and check the response status before returning it.
|
||||
|
||||
:param response: a response from a XMLRPC call to OpenSubtitles.
|
||||
:param fn: the function to make an XMLRPC call to OpenSubtitles.
|
||||
:return: the response.
|
||||
:raise: :class:`OpenSubtitlesError`
|
||||
|
||||
"""
|
||||
status_code = int(response['status'][:3])
|
||||
response = None
|
||||
try:
|
||||
response = fn()
|
||||
except requests.RequestException as e:
|
||||
status_code = e.response.status_code
|
||||
else:
|
||||
status_code = int(response['status'][:3])
|
||||
|
||||
if status_code == 401:
|
||||
raise Unauthorized
|
||||
if status_code == 406:
|
||||
@@ -318,4 +354,4 @@ def checked(response):
|
||||
if status_code != 200:
|
||||
raise OpenSubtitlesError(response['status'])
|
||||
|
||||
return response
|
||||
return response
|
||||
|
||||
@@ -0,0 +1,390 @@
|
||||
# coding=utf-8
|
||||
import io
|
||||
import six
|
||||
import os
|
||||
from pkg_resources import require
|
||||
import logging
|
||||
import re
|
||||
import os
|
||||
import time
|
||||
|
||||
from babelfish import Language, language_converters
|
||||
from requests import Session
|
||||
|
||||
from subliminal.subtitle import fix_line_ending
|
||||
from subliminal_patch.providers import Provider
|
||||
from subliminal_patch.providers.mixins import ProviderSubtitleArchiveMixin
|
||||
from subliminal.providers import ParserBeautifulSoup
|
||||
from subliminal_patch.exceptions import ProviderError
|
||||
from subliminal.score import get_equivalent_release_groups
|
||||
from subliminal_patch.subtitle import Subtitle, guess_matches
|
||||
from subliminal.utils import sanitize, sanitize_release_group
|
||||
from subliminal.video import Episode, Movie
|
||||
from zipfile import ZipFile, is_zipfile
|
||||
from rarfile import RarFile, is_rarfile
|
||||
from subliminal_patch.utils import sanitize, fix_inconsistent_naming as _fix_inconsistent_naming
|
||||
from guessit import guessit
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
language_converters.register('supersubtitles = subliminal_patch.converters.supersubtitles:SuperSubtitlesConverter')
|
||||
|
||||
|
||||
class SuperSubtitlesSubtitle(Subtitle):
|
||||
"""SuperSubtitles Subtitle."""
|
||||
provider_name = 'supersubtitles'
|
||||
|
||||
def __str__(self):
|
||||
subtit = "Subtitle id: " + str(self.subtitle_id) \
|
||||
+ " Series: " + self.series \
|
||||
+ " Season: " + str(self.season) \
|
||||
+ " Episode: " + str(self.episode) \
|
||||
+ " Version: " + str(self.version) \
|
||||
+ " Releases: " + str(self.releases) \
|
||||
+ " DownloadLink: " + str(self.page_link) \
|
||||
+ " Matches: " + str(self.matches)
|
||||
if self.year:
|
||||
subtit = subtit + " Year: " + str(self.year)
|
||||
return subtit.encode('utf-8')
|
||||
|
||||
def __init__(self, language, page_link, subtitle_id, series, season, episode, version,
|
||||
releases, year, imdb_id, asked_for_episode=None, asked_for_release_group=None):
|
||||
super(SuperSubtitlesSubtitle, self).__init__(language, page_link=page_link)
|
||||
self.subtitle_id = subtitle_id
|
||||
self.series = series
|
||||
self.season = season
|
||||
self.episode = episode
|
||||
self.version = version
|
||||
self.releases = releases
|
||||
self.year = year
|
||||
if year:
|
||||
self.year = int(year)
|
||||
|
||||
self.release_info = u", ".join(releases)
|
||||
self.page_link = page_link
|
||||
self.asked_for_release_group = asked_for_release_group
|
||||
self.asked_for_episode = asked_for_episode
|
||||
self.imdb_id = imdb_id
|
||||
self.is_pack = True
|
||||
|
||||
def numeric_id(self):
|
||||
return self.subtitle_id
|
||||
|
||||
def __repr__(self):
|
||||
ep_addon = (" S%02dE%02d" % (self.season, self.episode)) if self.episode else ""
|
||||
return '<%s %r [%s]>' % (
|
||||
self.__class__.__name__, u"%s%s%s [%s]" % (self.series, " (%s)" % self.year if self.year else "", ep_addon,
|
||||
self.release_info), self.language)
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
return str(self.subtitle_id)
|
||||
|
||||
def get_matches(self, video):
|
||||
matches = set()
|
||||
|
||||
# episode
|
||||
if isinstance(video, Episode):
|
||||
# series
|
||||
if video.series and sanitize(self.series) == sanitize(video.series):
|
||||
matches.add('series')
|
||||
# season
|
||||
if video.season and self.season == video.season:
|
||||
matches.add('season')
|
||||
# episode
|
||||
if video.episode and self.episode == video.episode:
|
||||
matches.add('episode')
|
||||
# imdb_id
|
||||
if video.series_imdb_id and self.imdb_id and str(self.imdb_id) == str(video.series_imdb_id):
|
||||
matches.add('series_imdb_id')
|
||||
matches.add('series')
|
||||
matches.add('year')
|
||||
# year
|
||||
if ('series' in matches and video.original_series and self.year is None or
|
||||
video.year and video.year == self.year):
|
||||
matches.add('year')
|
||||
# movie
|
||||
elif isinstance(video, Movie):
|
||||
# title
|
||||
if video.title and (sanitize(self.series) in (
|
||||
sanitize(name) for name in [video.title] + video.alternative_titles)):
|
||||
matches.add('title')
|
||||
# imdb_id
|
||||
if video.imdb_id and self.imdb_id == video.imdb_id:
|
||||
matches.add('imdb_id')
|
||||
matches.add('title')
|
||||
matches.add('year')
|
||||
# year
|
||||
if video.year and self.year == video.year:
|
||||
matches.add('year')
|
||||
|
||||
# release_group
|
||||
if (video.release_group and self.version and
|
||||
any(r in sanitize_release_group(self.version)
|
||||
for r in get_equivalent_release_groups(sanitize_release_group(video.release_group)))):
|
||||
matches.add('release_group')
|
||||
# resolution
|
||||
if video.resolution and self.version and video.resolution in self.version.lower():
|
||||
matches.add('resolution')
|
||||
# format
|
||||
if video.format and self.version and video.format.lower() in self.version.lower():
|
||||
matches.add('format')
|
||||
# other properties
|
||||
# matches |= guess_matches(video, guessit(self.release_info.encode("utf-8")))
|
||||
|
||||
self.matches = matches
|
||||
return matches
|
||||
|
||||
|
||||
class SuperSubtitlesProvider(Provider, ProviderSubtitleArchiveMixin):
|
||||
"""SuperSubtitles Provider."""
|
||||
languages = {Language('hun', 'HU')} | {Language(l) for l in [
|
||||
'hun', 'eng'
|
||||
]}
|
||||
video_types = (Episode, Movie)
|
||||
# https://www.feliratok.info/?search=&soriSorszam=&nyelv=&sorozatnev=The+Flash+%282014%29&sid=3212&complexsearch=true&knyelv=0&evad=4&epizod1=1&cimke=0&minoseg=0&rlsr=0&tab=all
|
||||
server_url = 'https://www.feliratok.info/'
|
||||
subtitle_class = SuperSubtitlesSubtitle
|
||||
hearing_impaired_verifiable = False
|
||||
multi_result_throttle = 2 # seconds
|
||||
|
||||
def initialize(self):
|
||||
self.session = Session()
|
||||
self.session.headers = {'User-Agent': os.environ.get("SZ_USER_AGENT", "Sub-Zero/2")}
|
||||
|
||||
def terminate(self):
|
||||
self.session.close()
|
||||
|
||||
def get_language(self, text):
|
||||
if text == 'Magyar':
|
||||
return Language.fromsupersubtitles('hu')
|
||||
if text == 'Angol':
|
||||
return Language.fromsupersubtitles('en')
|
||||
return None
|
||||
|
||||
def find_imdb_id(self, sub_id):
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
url = self.server_url + "index.php?tipus=adatlap&azon=a_" + sub_id
|
||||
# url = https://www.feliratok.info/index.php?tipus=adatlap&azon=a_1518600916
|
||||
logger.info('Get IMDB id from URL %s', url)
|
||||
r = self.session.get(url, timeout=10).content
|
||||
|
||||
soup = ParserBeautifulSoup(r, ['lxml'])
|
||||
links = soup.find_all("a")
|
||||
|
||||
for value in links:
|
||||
if "imdb.com" in str(value):
|
||||
# <a alt="iMDB" href="http://www.imdb.com/title/tt2357547/" target="_blank"><img alt="iMDB" src="img/adatlap/imdb.png"/></a>
|
||||
imdb_id = re.findall(r'(?<=www\.imdb\.com/title/).*(?=/")', str(value))[0]
|
||||
return imdb_id
|
||||
|
||||
return None
|
||||
|
||||
def find_id(self, series, year, original_title):
|
||||
"""
|
||||
We need to find the id of the series at the following url:
|
||||
https://www.feliratok.info/index.php?term=SERIESNAME&nyelv=0&action=autoname
|
||||
Where SERIESNAME is a searchable string.
|
||||
The result will be something like this:
|
||||
[{"name":"DC\u2019s Legends of Tomorrow (2016)","ID":"3725"},{"name":"Miles from Tomorrowland (2015)","ID":"3789"}
|
||||
,{"name":"No Tomorrow (2016)","ID":"4179"}]
|
||||
|
||||
"""
|
||||
|
||||
# Search for exact name
|
||||
url = self.server_url + "index.php?term=" + series + "&nyelv=0&action=autoname"
|
||||
# url = self.server_url + "index.php?term=" + "fla"+ "&nyelv=0&action=autoname"
|
||||
logger.info('Get series id from URL %s', url)
|
||||
r = self.session.get(url, timeout=10)
|
||||
|
||||
# r is something like this:
|
||||
# [{"name":"DC\u2019s Legends of Tomorrow (2016)","ID":"3725"},{"name":"Miles from Tomorrowland (2015)","ID":"3789"}
|
||||
# ,{"name":"No Tomorrow (2016)","ID":"4179"}]
|
||||
|
||||
results = r.json()
|
||||
|
||||
# check all of the results:
|
||||
for result in results:
|
||||
try:
|
||||
# "name":"Miles from Tomorrowland (2015)","ID":"3789"
|
||||
result_year = re.findall(r"(?<=\()\d\d\d\d(?=\))", result['name'])[0]
|
||||
except IndexError:
|
||||
result_year = ""
|
||||
|
||||
try:
|
||||
# "name":"Miles from Tomorrowland (2015)","ID":"3789"
|
||||
result_title = re.findall(r".*(?=\(\d\d\d\d\))", result['name'])[0]
|
||||
result_id = result['ID']
|
||||
except IndexError:
|
||||
continue
|
||||
|
||||
result_title = result_title.strip().replace("�", "").replace(" ", ".")
|
||||
|
||||
guessable = result_title.strip() + ".s01e01." + result_year
|
||||
guess = guessit(guessable, {'type': "episode"})
|
||||
|
||||
if sanitize(original_title) == sanitize(guess['title']) and year and guess['year'] and year == guess['year']:
|
||||
# Return the founded id
|
||||
return result_id
|
||||
|
||||
return None
|
||||
|
||||
def query(self, series, video=None):
|
||||
year = video.year
|
||||
subtitle = None
|
||||
if isinstance(video, Episode):
|
||||
series = video.series
|
||||
season = video.season
|
||||
episode = video.episode
|
||||
#seriesa = series.replace(' ', '+')
|
||||
|
||||
# Get ID of series with original name
|
||||
series_id = self.find_id(series, year, series)
|
||||
if not series_id:
|
||||
# If not founded try without ' char
|
||||
modified_series = series.replace(' ', '+').replace('\'', '')
|
||||
series_id = self.find_id(modified_series, year, series)
|
||||
if not series_id and modified_series:
|
||||
# If still not founded try with the longest word is series title
|
||||
modified_series = modified_series.split('+')
|
||||
modified_series = max(modified_series, key=len)
|
||||
series_id = self.find_id(modified_series, year, series)
|
||||
|
||||
if not series_id:
|
||||
return None
|
||||
|
||||
# https://www.feliratok.info/index.php?search=&soriSorszam=&nyelv=&sorozatnev=&sid=2075&complexsearch=true&knyelv=0&evad=6&epizod1=16&cimke=0&minoseg=0&rlsr=0&tab=all
|
||||
url = self.server_url + "index.php?search=&soriSorszam=&nyelv=&sorozatnev=&sid=" + \
|
||||
str(series_id) + "&complexsearch=true&knyelv=0&evad=" + str(season) + "&epizod1=" + str(
|
||||
episode) + "&cimke=0&minoseg=0&rlsr=0&tab=all"
|
||||
subtitle = self.process_subs(series, video, url)
|
||||
|
||||
if not subtitle:
|
||||
# No Subtitle found. Maybe already archived to season pack
|
||||
url = self.server_url + "index.php?search=&soriSorszam=&nyelv=&sorozatnev=&sid=" + \
|
||||
str(series_id) + "&complexsearch=true&knyelv=0&evad=" + str(
|
||||
season) + "&epizod1=&evadpakk=on&cimke=0&minoseg=0&rlsr=0&tab=all"
|
||||
subtitle = self.process_subs(series, video, url)
|
||||
|
||||
if isinstance(video, Movie):
|
||||
title = series.replace(" ", "+")
|
||||
|
||||
# https://www.feliratok.info/index.php?search=The+Hitman%27s+BodyGuard&soriSorszam=&nyelv=&tab=film
|
||||
url = self.server_url + "index.php?search=" + title + "&soriSorszam=&nyelv=&tab=film"
|
||||
subtitle = self.process_subs(series, video, url)
|
||||
|
||||
return subtitle
|
||||
|
||||
def process_subs(self, series, video, url):
|
||||
|
||||
subtitles = []
|
||||
|
||||
logger.info('URL for subtitles %s', url)
|
||||
r = self.session.get(url, timeout=10).content
|
||||
|
||||
soup = ParserBeautifulSoup(r, ['lxml'])
|
||||
tables = soup.find_all("table")
|
||||
tables = tables[0].find_all("tr")
|
||||
i = 0
|
||||
series_imdb_id = None
|
||||
for table in tables:
|
||||
if "vilagit" in str(table) and i > 1:
|
||||
try:
|
||||
sub_hun_name = table.findAll("div", {"class": "magyar"})[0]
|
||||
if isinstance(video, Episode):
|
||||
if "vad)" not in str(sub_hun_name):
|
||||
# <div class="magyar">A pletykaf�szek (3. �vad)</div>
|
||||
sub_hun_name = re.findall(r'(?<=<div class="magyar">).*(?= -)', str(sub_hun_name))[0]
|
||||
else:
|
||||
# <div class="magyar">A holnap legend�i - 3x11</div>
|
||||
sub_hun_name = re.findall(r'(?<=<div class="magyar">).*(?= \()', str(sub_hun_name))[0]
|
||||
if isinstance(video, Movie):
|
||||
sub_hun_name = re.findall(r'(?<=<div class="magyar">).*(?=</div)', str(sub_hun_name))[0]
|
||||
except IndexError:
|
||||
sub_hun_name = ""
|
||||
|
||||
asked_for_episode = None
|
||||
sub_season = None
|
||||
sub_episode = None
|
||||
sub_english = table.findAll("div", {"class": "eredeti"})
|
||||
if isinstance(video, Episode):
|
||||
asked_for_episode = video.episode
|
||||
if "Season" not in str(sub_english):
|
||||
# [<div class="eredeti">Gossip Girl (Season 3) (DVDRip-REWARD)</div>]
|
||||
sub_english_name = re.findall(r'(?<=<div class="eredeti">).*?(?= -)', str(sub_english))[0]
|
||||
sub_season = int((re.findall(r"(?<=- ).*?(?= - )", str(sub_english))[0].split('x')[0]).strip())
|
||||
sub_episode = int((re.findall(r"(?<=- ).*?(?= - )", str(sub_english))[0].split('x')[1]).strip())
|
||||
|
||||
else:
|
||||
# [<div class="eredeti">DC's Legends of Tomorrow - 3x11 - Here I Go Again (HDTV-AFG, HDTV-RMX, 720p-SVA, 720p-PSA </div>]
|
||||
sub_english_name = \
|
||||
re.findall(r'(?<=<div class="eredeti">).*?(?=\(Season)', str(sub_english))[0]
|
||||
sub_season = int(re.findall(r"(?<=Season )\d+(?=\))", str(sub_english))[0])
|
||||
sub_episode = int(video.episode)
|
||||
if isinstance(video, Movie):
|
||||
sub_english_name = re.findall(r'(?<=<div class="eredeti">).*?(?=\()', str(sub_english))[0]
|
||||
|
||||
sub_version = (str(sub_english).split('(')[len(str(sub_english).split('(')) - 1]).split(')')[0]
|
||||
# <small>Angol</small>
|
||||
lang = table.findAll("small")[0]
|
||||
sub_language = self.get_language(re.findall(r"(?<=<small>).*(?=</small>)", str(lang))[0])
|
||||
|
||||
# <a href="/index.php?action=letolt&fnev=DCs Legends of Tomorrow - 03x11 - Here I Go Again.SVA.English.C.orig.Addic7ed.com.srt&felirat=1519162191">
|
||||
link = str(table.findAll("a")[len(table.findAll("a")) - 1]).replace("amp;", "")
|
||||
sub_downloadlink = self.server_url + re.findall(r'(?<=href="/).*(?=">)', link)[0]
|
||||
|
||||
sub_id = re.findall(r"(?<=felirat\=).*(?=\"\>)", link)[0]
|
||||
sub_year = video.year
|
||||
sub_releases = [s.strip() for s in sub_version.split(',')]
|
||||
|
||||
# For episodes we open the series page so all subtitles imdb_id must be the same. no need to check all
|
||||
if isinstance(video, Episode) and series_imdb_id is not None:
|
||||
sub_imdb_id = series_imdb_id
|
||||
else:
|
||||
sub_imdb_id = self.find_imdb_id(sub_id)
|
||||
series_imdb_id = sub_imdb_id
|
||||
|
||||
subtitle = SuperSubtitlesSubtitle(sub_language, sub_downloadlink, sub_id, sub_english_name.strip(), sub_season,
|
||||
sub_episode, sub_version, sub_releases, sub_year, sub_imdb_id,
|
||||
asked_for_episode, asked_for_release_group=video.release_group )
|
||||
subtitles.append(subtitle)
|
||||
i = i + 1
|
||||
return subtitles
|
||||
|
||||
def list_subtitles(self, video, languages):
|
||||
if isinstance(video, Episode):
|
||||
titles = [video.series] + video.alternative_series
|
||||
elif isinstance(video, Movie):
|
||||
titles = [video.title] + video.alternative_titles
|
||||
|
||||
for title in titles:
|
||||
subs = self.query(title, video=video)
|
||||
if subs:
|
||||
return subs
|
||||
|
||||
time.sleep(self.multi_result_throttle)
|
||||
return []
|
||||
|
||||
def download_subtitle(self, subtitle):
|
||||
|
||||
# download as a zip
|
||||
logger.info('Downloading subtitle %r', subtitle.subtitle_id)
|
||||
r = self.session.get(subtitle.page_link, timeout=10)
|
||||
r.raise_for_status()
|
||||
|
||||
if ".rar" in subtitle.page_link:
|
||||
logger.debug('Archive identified as rar')
|
||||
archive_stream = io.BytesIO(r.content)
|
||||
archive = RarFile(archive_stream)
|
||||
subtitle.content = self.get_subtitle_from_archive(subtitle, archive)
|
||||
elif ".zip" in subtitle.page_link:
|
||||
logger.debug('Archive identified as zip')
|
||||
archive_stream = io.BytesIO(r.content)
|
||||
archive = ZipFile(archive_stream)
|
||||
subtitle.content = self.get_subtitle_from_archive(subtitle, archive)
|
||||
else:
|
||||
subtitle.content = fix_line_ending(r.content)
|
||||
@@ -4,12 +4,12 @@ import logging
|
||||
import types
|
||||
import os
|
||||
import datetime
|
||||
import requests
|
||||
|
||||
from guessit import guessit
|
||||
from requests.compat import urljoin, quote
|
||||
from subliminal import Episode, Movie, region
|
||||
from subliminal_patch.core import remove_crap_from_fn
|
||||
from subliminal_patch.http import CertifiSession
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -18,11 +18,15 @@ class DroneAPIClient(object):
|
||||
api_url = None
|
||||
_fill_attrs = None
|
||||
|
||||
def __init__(self, version=1, session=None, headers=None, timeout=10, base_url=None, api_key=None):
|
||||
def __init__(self, version=1, session=None, headers=None, timeout=10, base_url=None, api_key=None,
|
||||
ssl_no_verify=False):
|
||||
headers = dict(headers or {}, **{"X-Api-Key": api_key})
|
||||
|
||||
#: Session for the requests
|
||||
self.session = session or requests.Session()
|
||||
self.session = session or CertifiSession()
|
||||
if ssl_no_verify:
|
||||
self.session.verify = False
|
||||
|
||||
self.session.timeout = timeout
|
||||
self.session.headers.update(headers or {})
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
# coding=utf-8
|
||||
|
||||
import logging
|
||||
from libfilebot import get_filebot_attrs
|
||||
from common import update_video
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def refine(video, **kwargs):
|
||||
"""
|
||||
@@ -11,7 +14,12 @@ def refine(video, **kwargs):
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
orig_fn = get_filebot_attrs(video.name)
|
||||
try:
|
||||
orig_fn = get_filebot_attrs(video.name)
|
||||
|
||||
if orig_fn:
|
||||
update_video(video, orig_fn)
|
||||
if orig_fn:
|
||||
update_video(video, orig_fn)
|
||||
else:
|
||||
logger.info(u"%s: Filebot didn't return an original filename", video.name)
|
||||
except:
|
||||
logger.exception(u"%s: Something went wrong when retrieving filebot attributes:", video.name)
|
||||
|
||||
@@ -53,7 +53,7 @@ def refine(video, **kwargs):
|
||||
"""
|
||||
# only deal with Episode videos
|
||||
if not isinstance(video, Episode):
|
||||
logger.error('Cannot refine episodes')
|
||||
logger.error('Can only refine episodes')
|
||||
return
|
||||
|
||||
# exit if the information is complete
|
||||
|
||||
@@ -45,4 +45,7 @@ class SZFileBackend(CacheBackend):
|
||||
|
||||
def clear(self):
|
||||
self._cache.clear()
|
||||
if not hasattr(self._cache, "_buffer") or self._cache._sync:
|
||||
self._cache._sync = False
|
||||
self._cache._buffer = {}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
OS_PLEX_USERAGENT = 'plexapp.com v9.0'
|
||||
|
||||
DEPENDENCY_MODULE_NAMES = ['subliminal', 'subliminal_patch', 'enzyme', 'guessit', 'subzero']
|
||||
DEPENDENCY_MODULE_NAMES = ['subliminal', 'subliminal_patch', 'enzyme', 'guessit', 'subzero', 'libfilebot']
|
||||
PERSONAL_MEDIA_IDENTIFIER = "com.plexapp.agents.none"
|
||||
PLUGIN_IDENTIFIER_SHORT = "subzero"
|
||||
PLUGIN_IDENTIFIER = "com.plexapp.agents.%s" % PLUGIN_IDENTIFIER_SHORT
|
||||
|
||||
@@ -7,10 +7,13 @@ from babelfish import Language as Language_
|
||||
repl_map = {
|
||||
"dk": "da",
|
||||
"nld": "nl",
|
||||
"english": "en",
|
||||
}
|
||||
|
||||
|
||||
def language_from_stream(l):
|
||||
if not l:
|
||||
raise LanguageError()
|
||||
for method in ("fromietf", "fromalpha3t", "fromalpha3b"):
|
||||
try:
|
||||
return getattr(Language, method)(l)
|
||||
@@ -22,8 +25,9 @@ def language_from_stream(l):
|
||||
class Language(Language_):
|
||||
@classmethod
|
||||
def fromietf(cls, ietf):
|
||||
if ietf in repl_map:
|
||||
ietf = repl_map[ietf]
|
||||
ietf_lower = ietf.lower()
|
||||
if ietf_lower in repl_map:
|
||||
ietf = repl_map[ietf_lower]
|
||||
|
||||
return Language_.fromietf(ietf)
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
import dict, geezip, httpfake, io, json, rar, which
|
||||
@@ -123,6 +123,9 @@ class Dicked(object):
|
||||
return self._entries <= d
|
||||
|
||||
def __eq__(self, d):
|
||||
if d is None and not self._entries:
|
||||
return True
|
||||
|
||||
return self._entries == d
|
||||
|
||||
def __ne__(self, d):
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# coding=utf-8
|
||||
|
||||
import logging
|
||||
import rarfile
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RarFile(rarfile.RarFile):
|
||||
def read(self, fname, psw=None):
|
||||
"""
|
||||
read specific content of rarfile without parsing
|
||||
:param fname:
|
||||
:param psw:
|
||||
:return:
|
||||
"""
|
||||
cmd = [rarfile.UNRAR_TOOL] + list(rarfile.ORIG_OPEN_ARGS)
|
||||
|
||||
with rarfile.XTempFile(self._rarfile) as rf:
|
||||
log.debug(u"RAR CMD: %s", cmd + [rf, fname])
|
||||
p = rarfile.custom_popen(cmd + [rf, fname])
|
||||
output = p.communicate()[0]
|
||||
rarfile.check_returncode(p, output)
|
||||
|
||||
return output
|
||||
File diff suppressed because one or more lines are too long
@@ -39,6 +39,7 @@ SZ_FIX_DATA = {
|
||||
},
|
||||
"WholeWords": {
|
||||
u"I'11": u"I'll",
|
||||
u"III'll": u"I'll",
|
||||
u"Tun": u"Run",
|
||||
u"pan'": u"part",
|
||||
u"al'": u"at",
|
||||
|
||||
@@ -39,9 +39,7 @@ class Color(SubtitleModification):
|
||||
|
||||
colors = COLOR_MAP
|
||||
|
||||
long_description = """\
|
||||
Adds the requested color to every line of the subtitle. Support depends on player.
|
||||
"""
|
||||
long_description = "Adds the requested color to every line of the subtitle. Support depends on player."
|
||||
|
||||
def modify(self, content, debug=False, parent=None, **kwargs):
|
||||
color = self.colors.get(kwargs.get("name"))
|
||||
|
||||
@@ -15,16 +15,17 @@ class CommonFixes(SubtitleTextModification):
|
||||
exclusive = True
|
||||
order = 40
|
||||
|
||||
long_description = """\
|
||||
Fix common and whitespace/punctuation issues in subtitles
|
||||
"""
|
||||
long_description = "Fix common and whitespace/punctuation issues in subtitles"
|
||||
|
||||
processors = [
|
||||
# -- = em dash
|
||||
NReProcessor(re.compile(r'(?u)(\w|\b|\s|^)(-\s?-{1,2})'), ur"\1—", name="CM_multidash"),
|
||||
|
||||
# line = _/-/\s
|
||||
NReProcessor(re.compile(r'(?u)(^[-_\s.]*[-_\s.]+[-_\s.]*$)'), "", name="CM_non_word_only"),
|
||||
NReProcessor(re.compile(r'(?u)(^\W*[-_.]+\W*$)'), "", name="CM_non_word_only"),
|
||||
|
||||
# multi space
|
||||
NReProcessor(re.compile(r'(?u)(\s{2,})'), " ", name="CM_multi_space"),
|
||||
|
||||
# fix music symbols
|
||||
NReProcessor(re.compile(ur'(?u)(^[*#¶\s]*[*#¶]+[*#¶\s]*$)'), u"♪", name="CM_music_symbols"),
|
||||
@@ -102,9 +103,7 @@ class RemoveTags(SubtitleModification):
|
||||
exclusive = True
|
||||
modifies_whole_file = True
|
||||
|
||||
long_description = """\
|
||||
Removes all possible style tags from the subtitle, such as font, bold, color etc.
|
||||
"""
|
||||
long_description = "Removes all possible style tags from the subtitle, such as font, bold, color etc."
|
||||
|
||||
def modify(self, content, debug=False, parent=None, **kwargs):
|
||||
for entry in parent.f:
|
||||
@@ -119,10 +118,8 @@ class ReverseRTL(SubtitleModification):
|
||||
order = 50
|
||||
languages = [Language("heb")]
|
||||
|
||||
long_description = """\
|
||||
Some playback devices don't properly handle right-to-left markers for punctuation. Physically swap punctuation.
|
||||
Applicable to languages: hebrew
|
||||
"""
|
||||
long_description = "Some playback devices don't properly handle right-to-left markers for punctuation. " \
|
||||
"Physically swap punctuation. Applicable to languages: hebrew"
|
||||
|
||||
processors = [
|
||||
# new? (?u)(^([\s.!?]*)(.+?)(\s*)(-?\s*)$); \5\4\3\2
|
||||
|
||||
@@ -15,9 +15,7 @@ class ChangeFPS(SubtitleModification):
|
||||
advanced = True
|
||||
modifies_whole_file = True
|
||||
|
||||
long_description = """\
|
||||
Re-syncs the subtitle to the framerate of the current media file.
|
||||
"""
|
||||
long_description = "Re-syncs the subtitle to the framerate of the current media file."
|
||||
|
||||
def modify(self, content, debug=False, parent=None, **kwargs):
|
||||
fps_from = kwargs.get("from")
|
||||
|
||||
@@ -22,9 +22,7 @@ class HearingImpaired(SubtitleTextModification):
|
||||
exclusive = True
|
||||
order = 20
|
||||
|
||||
long_description = """\
|
||||
Removes tags, text and characters from subtitles that are meant for hearing impaired people
|
||||
"""
|
||||
long_description = "Removes tags, text and characters from subtitles that are meant for hearing impaired people"
|
||||
|
||||
processors = [
|
||||
# full bracket entry, single or multiline; starting with brackets and ending with brackets
|
||||
@@ -50,17 +48,18 @@ class HearingImpaired(SubtitleTextModification):
|
||||
|
||||
# uppercase text before colon (at least 3 uppercase chars); at start or after a sentence,
|
||||
# possibly with a dash in front; ignore anything ending with a quote
|
||||
NReProcessor(re.compile(ur'(?u)(?:(?<=^)|(?<=[.\-!?\"\']))([\s-]*(?=[A-ZÀ-Ž]\s*[A-ZÀ-Ž]\s*[A-ZÀ-Ž])'
|
||||
ur'[A-ZÀ-Ž-_0-9\s\"\']+:(?![\"\'’ʼ❜‘‛”“‟„])\s*)(?![0-9])'), "",
|
||||
NReProcessor(re.compile(ur'(?u)(?:(?<=^)|(?<=[.\-!?\"\']))([\s-]*(?=[A-ZÀ-Ž&+]\s*[A-ZÀ-Ž&+]\s*[A-ZÀ-Ž&+])'
|
||||
ur'[A-ZÀ-Ž-_0-9\s\"\'&+]+:(?![\"\'’ʼ❜‘‛”“‟„])\s*)(?![0-9])'), "",
|
||||
name="HI_before_colon_caps"),
|
||||
|
||||
# any text before colon (at least 3 chars); at start or after a sentence,
|
||||
# possibly with a dash in front; try not breaking actual sentences with a colon at the end by not matching if
|
||||
# more than one space is inside the text; ignore anything ending with a quote
|
||||
NReProcessor(re.compile(ur'(?u)(?:(?<=^)|(?<=[.\-!?\"]))([\s-]*(?=[A-zÀ-ž]\s*[A-zÀ-ž]\s*[A-zÀ-ž])'
|
||||
ur'[A-zÀ-ž-_0-9\s\"\']+:(?![\"’ʼ❜‘‛”“‟„])\s*)(?![0-9])'),
|
||||
lambda match: match.group(1) if (match.group(1).count(" ") > 1
|
||||
or match.group(1).count("-") > 1) else "",
|
||||
# a space is inside the text; ignore anything ending with a quote
|
||||
NReProcessor(re.compile(ur'(?u)(?:(?<=^)|(?<=[.\-!?\"]))([\s-]*((?=[A-zÀ-ž&+]\s*[A-zÀ-ž&+]\s*[A-zÀ-ž&+])'
|
||||
ur'[A-zÀ-ž-_0-9\s\"\'&+]+:)(?![\"’ʼ❜‘‛”“‟„])\s*)(?![0-9])'),
|
||||
lambda match:
|
||||
match.group(1) if (match.group(2).count(" ") > 0 or match.group(1).count("-") > 0)
|
||||
else "" if not match.group(1).startswith(" ") else " ",
|
||||
name="HI_before_colon_noncaps"),
|
||||
|
||||
# text in brackets at start, after optional dash, before colon or at end of line
|
||||
@@ -69,7 +68,7 @@ class HearingImpaired(SubtitleTextModification):
|
||||
# name="HI_brackets_special"),
|
||||
|
||||
# all caps line (at least 4 consecutive uppercase chars)
|
||||
NReProcessor(re.compile(ur'(?u)(^(?=.*[A-ZÀ-Ž]{4,})[A-ZÀ-Ž-_\s]+$)'), "", name="HI_all_caps"),
|
||||
NReProcessor(re.compile(ur'(?u)(^(?=.*[A-ZÀ-Ž&+]{4,})[A-ZÀ-Ž-_\s&+]+$)'), "", name="HI_all_caps"),
|
||||
|
||||
# dash in front
|
||||
# NReProcessor(re.compile(r'(?u)^\s*-\s*'), "", name="HI_starting_dash"),
|
||||
|
||||
@@ -19,9 +19,7 @@ class FixOCR(SubtitleTextModification):
|
||||
order = 10
|
||||
data_dict = None
|
||||
|
||||
long_description = """\
|
||||
Fix issues that happen when a subtitle gets converted from bitmap to text through OCR
|
||||
"""
|
||||
long_description = "Fix issues that happen when a subtitle gets converted from bitmap to text through OCR"
|
||||
|
||||
def __init__(self, parent):
|
||||
super(FixOCR, self).__init__(parent)
|
||||
|
||||
@@ -16,9 +16,7 @@ class ShiftOffset(SubtitleModification):
|
||||
args_mergeable = True
|
||||
modifies_whole_file = True
|
||||
|
||||
long_description = """\
|
||||
Adds or substracts a certain amount of time from the whole subtitle to match your media
|
||||
"""
|
||||
long_description = "Adds or substracts a certain amount of time from the whole subtitle to match your media"
|
||||
|
||||
@classmethod
|
||||
def merge_args(cls, args1, args2):
|
||||
|
||||
@@ -12,7 +12,7 @@ import sys
|
||||
|
||||
from json_tricks.nonp import loads
|
||||
from subzero.lib.json import dumps
|
||||
from subzero.lib.io import scandir
|
||||
from scandir import scandir
|
||||
from constants import mode_map
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -115,6 +115,7 @@ def refine_video(video, no_refining=False, refiner_settings=None):
|
||||
video.year = year
|
||||
|
||||
refine(video, **refine_kwargs)
|
||||
logger.info(u"Using filename: %s", video.original_name)
|
||||
|
||||
if hints["type"] == "movie" and not video.imdb_id:
|
||||
if plex_title:
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
(WHOOSHING)
|
||||
This is a phone number: 123 4325 123
|
||||
H i. But not MATCH hindrance.
|
||||
Ja, det är väl det. Tack och lov
|
||||
att HD:s beslut var så solklart.
|
||||
But this should. Peter: Yello!
|
||||
|
||||
2
|
||||
00:00:10,759 --> 00:00:12,678
|
||||
|
||||
@@ -0,0 +1,400 @@
|
||||
{
|
||||
"sq": "Albansk",
|
||||
"ar": "Arabisk",
|
||||
"be": "Hviderussisk",
|
||||
"bs": "Bosnisk",
|
||||
"bg": "Bulgarisk",
|
||||
"ca": "Catalansk",
|
||||
"zh": "Kinesisk",
|
||||
"hr": "Kroatisk",
|
||||
"cs": "Tjekkisk",
|
||||
"da": "Dansk",
|
||||
"nl": "Hollansk",
|
||||
"en": "Engelsk",
|
||||
"et": "Estisk",
|
||||
"fa": "Persisk",
|
||||
"fi": "Finsk",
|
||||
"fr": "Fransk",
|
||||
"de": "Tysk",
|
||||
"el": "Græsk",
|
||||
"he": "Hebrarisk",
|
||||
"hi": "Hindi",
|
||||
"hu": "Ungarsk",
|
||||
"is": "Islansk",
|
||||
"id": "Indonesisk",
|
||||
"it": "Italiensk",
|
||||
"ja": "Japansk",
|
||||
"ko": "Koreansk",
|
||||
"lv": "Lettisk",
|
||||
"lt": "Litauisk",
|
||||
"mk": "Makedonsk",
|
||||
"ms": "Malajsisk",
|
||||
"no": "Norsk",
|
||||
"pl": "Polsk",
|
||||
"pt": "Portugisisk",
|
||||
"pt-br": "Portugisisk (Brasiliansk)",
|
||||
"ro": "Romansk",
|
||||
"ru": "Russisk",
|
||||
"sr": "Serbisk",
|
||||
"sr-cyrl": "Serbisk (Cyrillic)",
|
||||
"sr-latn": "Serbisk (Latin)",
|
||||
"sk": "Slovakisk",
|
||||
"sl": "Slovensk",
|
||||
"es": "Spansk",
|
||||
"sv": "Svensk",
|
||||
"th": "Thaisk",
|
||||
"tr": "Tyrkisk",
|
||||
"uk": "Ukrainsk",
|
||||
"vi": "Vietnamesisk",
|
||||
"Internal stuff, pay attention!": "Interne ting, vær opmærksom!",
|
||||
"Advanced": "Avanceret",
|
||||
"advanced": "avanceret",
|
||||
"Enter PIN": "Indtast Pin",
|
||||
"The owner has restricted the access to this menu. Please enter the correct pin": "Ejeren har begrænset adgangen til denne menu. Venligst indtast den rigtige PIN kode",
|
||||
"Restart the plugin": "Genstart Plugin",
|
||||
"Get my logs (copy the appearing link and open it in your browser, please)": "Hent mine logs (kopier det viste link og åben det i din browser)",
|
||||
"Copy the appearing link and open it in your browser, please": "Kopier det viste link og åben det i din browser",
|
||||
"Trigger find better subtitles": "Trigger find bedre undertekster",
|
||||
"Skip next find better subtitles (sets last run to now)": "Spring næste Find bedre undertekster over (sæt sidste kørsel til nu)",
|
||||
"Trigger subtitle storage maintenance": "Start undertekst lager vedligehold",
|
||||
"Trigger subtitle storage migration (expensive)": "Start migration af undertekst lagre (dyrt?)",
|
||||
"Trigger cache maintenance (refiners, providers and packs/archives)": "Start cache vedligehold (for refiners, udbydere og pakker/arkiver)",
|
||||
"Apply configured default subtitle mods to all (active) stored subtitles": "Brug de standard konfigurede undertekst-mods til alle (aktive) gemte undertekster",
|
||||
"Re-Apply mods of all stored subtitles": "Genindsæt alle mods for alle gemte undertekster",
|
||||
"Log the plugin's scheduled tasks state storage": "Log plugins planlagte aktivitets lagerstatus",
|
||||
"Log the plugin's internal ignorelist storage": "Log plugins interne ignoreliste lager",
|
||||
"Log the plugin's complete state storage": "Log plugins komplette lager status",
|
||||
"Reset the plugin's scheduled tasks state storage": "Nulstil plugins planlagte aktivitets lagerstatus",
|
||||
"Reset the plugin's internal ignorelist storage": "Nulstil plugins internet ignoreliste lager",
|
||||
"Invalidate Sub-Zero metadata caches (subliminal)": "Afkræft Sub-Zero metadata cache (subliminale)",
|
||||
"Reset provider throttle states": "Nulstil udbyders throttle status",
|
||||
"Restarting the plugin": "Genstarter plugin",
|
||||
"Restart triggered, please wait about 5 seconds": "Genstart aktiveret, vent venligst ca. 5 sekunder",
|
||||
"Reset subtitle storage": "Nulstil undertekst lager",
|
||||
"Are you sure?": "Er du sikker?",
|
||||
"Are you really sure?": "Er du helt sikker?",
|
||||
"Success": "Succes",
|
||||
"FindBetterSubtitles triggered": "FindBedreUndertekster startet",
|
||||
"FindBetterSubtitles skipped": "FindBedreUndertekster sprunget over",
|
||||
"SubtitleStorageMaintenance triggered": "Undertekst lager vedligehold startet",
|
||||
"MigrateSubtitleStorage triggered": "Migration af undertekst lager startet",
|
||||
"TriggerCacheMaintenance triggered": "Udløseren for Cache vedligehold startet",
|
||||
"This may take some time ...": "Dette kan tage et stykke tid ...",
|
||||
"Download Logs": "Download logs",
|
||||
"Sorry, feature unavailable": "Beklager, men ikke tilgængelig",
|
||||
"Universal Plex token not available": "Universal Plex token er ikke tilgængelig",
|
||||
"Copy this link and open this in your browser, please": "Kopier venligst dette link, og åben i en browser",
|
||||
"Cache invalidated": "Cache ugyldig",
|
||||
"Enter PIN number ": "Indtast PIN nummer ",
|
||||
"PIN correct": "PIN korrekt",
|
||||
"Reset": "Nulstil",
|
||||
"Menu locked": "Menu låst",
|
||||
"Provider throttles reset": "Udbyders throttle nulstilles",
|
||||
"Information Storage (%s) reset": "Informationslager (%s) nulstilles",
|
||||
"Information Storage (%s) logged": "Informationslager (%s) logget",
|
||||
"Plex didn't return any information about the item, please refresh it and come back later": "Plex retunerede ingen information vedr. mediet. Venligst opdater det i Plex, og forsøg igen",
|
||||
"Item not found: %s!": "Media ikke fundet: %s!",
|
||||
"< Back to %s": "< Tilbage til %s",
|
||||
"Back to %s > %s": "Tilbage til %s > %s",
|
||||
"Refresh: %s": "Opdater: %s",
|
||||
"Issues a forced refresh, ignoring known subtitles and searching for new ones": "Start en tvungen opdatering, ignorer kendte undertekster, og søg for nye",
|
||||
"Extract and activate embedded subtitle streams": "Extrakt og aktiver undertekster fra selve mediet",
|
||||
"Inspect currently blacklisted subtitles": "Undersøg nuværende undertekster i karantæne",
|
||||
"Subtitle saved to disk": "Undertekster gemt på disk",
|
||||
"Remove subtitle from blacklist": "Fjern undertekst fra karantæne",
|
||||
"No subtitles found": "Ingen undertekster fundet",
|
||||
" (unknown)": " (Ukendt)",
|
||||
" (forced)": " (Tvunget)",
|
||||
"Extracting of embedded subtitle %s of part %s:%s triggered": "Udpakker indlejrede undertekster %s som del af %s:%s startet",
|
||||
"Insufficient permissions": "Utilstrækkelig rettigheder",
|
||||
"I'm not enabled!": "Jeg er ikke aktiveret!",
|
||||
"Please enable me for some of your libraries in your server settings; currently I do nothing": "Venligst aktiver mig til nogle af dine biblioteker i dine server indstillinger; lige nu gør jeg ingenting",
|
||||
"Working ... refresh here": "Arbejder ... Opdater her",
|
||||
"Current state: %s; Last state: %s": "Nuværende status: %s; Sidste status: %s",
|
||||
"On-deck items": "Skrivebords medier",
|
||||
"Shows the %s recently played items and allows you to individually (force-) refresh their metadata/subtitles.": "Viser de %s sidste afspillede titler og giver dig mulighed for individuelt (gennem tvinge) at opdatere deres metadata/undertekster. ",
|
||||
"Recently-added items": "Nylig tilføjet media",
|
||||
"Recently played items": "Nylig afspillet media",
|
||||
"Shows the recently added items per section.": "Vis seneste tilføjede media pr. sektion",
|
||||
"Show recently added items with missing subtitles": "Vis seneste tilføjede hvor undertekster mangler",
|
||||
"Browse all items": "Gennemse alle media",
|
||||
"Go through your whole library and manage your ignore list. You can also (force-) refresh the metadata/subtitles of individual items.": "Gå igennem hele dit bibliotek og håndter din ignorer-liste. Du kan også (gennemtvinge) en opdatering af metadata/undertekster og de enkelte elementer.",
|
||||
"Last run: %s; Next scheduled run: %s; Last runtime: %s": "Sidste gennemgang: %s; Næste planlagte gennemgang: %s; Sidste gennemløbs tid: %s",
|
||||
"Search for missing subtitles (in recently-added items, max-age: %s)": "Søg efter manglende undertekster (blandt de sidste tilføjede titler, maksimal alder: %s)",
|
||||
"Automatically run periodically by the scheduler, if configured. %s": "Automatisk periodisk gennemløb af jobplanlæggeren, såfremt konfigureret. %s.",
|
||||
"Show the current ignore list (mainly used for the automatic tasks)": "Hvis den nuværende ignorer liste (hovedsageligt brugt for de automatiske opgaver)",
|
||||
"History": "Historie",
|
||||
"Show the last %i downloaded subtitles": "Vis de sidste %i hentede undertekster",
|
||||
"Refresh": "Opdater",
|
||||
"Re-lock menu(s)": "Gen aflås meny(er)",
|
||||
"Enabled the PIN again for menu(s)": "Aktiver PIN igen for meny(er)",
|
||||
"Throttled providers: %s": "Throttled udbydere: %s",
|
||||
"Advanced functions": "Avancerede funktioner",
|
||||
"Use at your own risk": "Brug for egen risiko",
|
||||
"Items On Deck": "Elementer på skrivebord",
|
||||
"Recently Played": "Nyeligt afspillede",
|
||||
"Items with missing subtitles": "Titler som mangler undertekster",
|
||||
"Find recent items with missing subtitles": "Find seneste medias hvor undertekster mangler",
|
||||
"Updating, refresh here ...": "Opdaterer, klik her for ny status ...",
|
||||
"Missing: %s": "Mangler: %s",
|
||||
"Didn't change the ignore list": "Ændre ikke ignorer-listen",
|
||||
"Sections": "Sektioner",
|
||||
"All": "Alle",
|
||||
"show": "vis",
|
||||
"movie": "film",
|
||||
"<< Back to home": "<< Tilbage til hoved menu",
|
||||
"Auto-Find subtitles: %s": "Auto-Find undertekster: %s",
|
||||
"Extracting of embedded subtitles for %s triggered": "Udpakning af indlejrede undertekster for %s fundne",
|
||||
"< Back to subtitle options for: %s": "< Tilbage til undertekst muligheder for: %s",
|
||||
"Remove last applied mod (%s)": "Fjern sidste aktive",
|
||||
"none": "ingen",
|
||||
"Manage applied mods": "Håndter de gældende mods",
|
||||
"Reapply applied mods": "Genaktiver de pågældende mods",
|
||||
"Restore original version": "Gendan orginal version",
|
||||
"< Back to subtitle modification menu": "< Tilbage til undertekst modifikations meny",
|
||||
"subs constantly getting faster": "Undertekster bliver konstant hurtigere",
|
||||
"subs constantly getting slower": "Undertekster bliver konstant langsommere",
|
||||
"< Back to subtitle modifications": "< Tilbage til undertekst ændringer",
|
||||
"< Back to unit selection": "< Tilbage til enheds valg ",
|
||||
"Subtitle Language (1)": "Undertekst sprog (1)",
|
||||
"Subtitle Language (2)": "Undertekst sprog (2)",
|
||||
"Subtitle Language (3)": "Undertekst sprog (3)",
|
||||
"Additional Subtitle Languages (use ISO-639-1 codes; comma-separated)": "Flere Undertekst sprog (brug ISO-639-1 koder; kommasepareret)",
|
||||
"Only download foreign/forced subtitles": "Download kun fremmede/gennemtvungne undertekster",
|
||||
"Display languages with country attribute as ISO 639-1 (e.g. pt-BR = pt)": "Vis sprog med lande attributer som i ISO639-1 (f.eks. pt-BR = pt)",
|
||||
"Treat languages with country attribute as ISO 639-1 (e.g. don't download pt-BR if pt subtitle exists)": "Behandel sprog med lande attributer som i ISO 639-1 (f.eks hent ikke pt-BR hvis pt undertekster findes)",
|
||||
"Restrict to one language (skips adding \".lang.\" to the subtitle filename; only uses \"Subtitle Language (1)\")": "Indskrænk til et sprog (tilføj ikke \".lang\" til underteksters filnavn; brug kun \"Undertekst sprog (1)\")",
|
||||
"Embedded subtitles: Treat \"Undefined\" (und) as language 1": "Indlejrede undertekster: Behandel \"Udefineret\" som sprog 1",
|
||||
"I rename my files using": "Jeg omdøber mine filer med",
|
||||
"Retrieve original filename from .file_info/file_info index files (see wiki)": "Genskab det originale filnavn fra .file_info/file_info indeks filer (se wiki)",
|
||||
"Sonarr URL (add URL base if configured)": "Sonarr URL (tilføj URL databse hvis konfigureret)",
|
||||
"Sonarr API key": "Sonarr API key",
|
||||
"Radarr URL (add URL base if configured, min. version: 0.2.0.897)": "Radarr URL (tilføj URL database hvos konfigireret, min. version: 0.2.0.897)",
|
||||
"Radarr API key": "Radarr API key",
|
||||
"Provider: Enable OpenSubtitles": "Provider: Aktiver OpenSubtitles",
|
||||
"Opensubtitles Username": "Opensubtitles Brugernavn",
|
||||
"Opensubtitles Password": "Opensubtitles Kodeord",
|
||||
"OpenSubtitles VIP? (ad-free subs, 1000 subs/day, no-cache VIP server: http://v.ht/osvip)": "OpenSubtitles VIP? (reklamefri undertekster, 1000 undertekster/dag, no-cache VIP server: http://v.ht/osvip)",
|
||||
"Provider: Enable Podnapisi.NET": "Provider: Aktiver Podnapisi.NET",
|
||||
"Provider: Enable Titlovi.com": "Provider: Aktiver Titlovi.com",
|
||||
"Provider: Enable Addic7ed": "Provider: Aktiver Addic7ed",
|
||||
"Addic7ed Username": "Addic7ed Brugernavn",
|
||||
"Addic7ed Password": "Addic7ed Kodeord",
|
||||
"Addic7ed: boost score (if requirements met)": "Addic7ed: boost score (hvis betingelser er opfyldt)",
|
||||
"Addic7ed: Use random user agents": "Addic7ed: Brug tilfældig bruger agent",
|
||||
"Provider: Enable Legendas TV (mostly pt-BR; UNRAR NEEDED)": "Provider: Aktiver Legendas TV (for det meste pt-BR; UNRAR skal være tilgængelig)",
|
||||
"Legendas TV Username": "Legendas TV Brugernavn",
|
||||
"Legendas TV Password": "Legendas TV Kodeord",
|
||||
"Provider: Enable TVsubtitles.net": "Provider: Aktiver TVsubtitles.net",
|
||||
"Provider: Enable NapiProjekt.pl (Polish)": "Provider: Aktiver NapiProjekt.pl (Polsk)",
|
||||
"Provider: Enable SubScene (TV shows)": "Provider: Aktiver SubScene (TV shows)",
|
||||
"Provider: Enable hosszupuskasub.com (Hungarian)": "Provider: Aktiver hosszupuskasub.com (Ungaren)",
|
||||
"Provider: Enable aRGENTeaM (Spanish)": "Provider: Aktiver aRGENTeaM (Spansk)",
|
||||
"Search enabled providers simultaneously (multithreading)": "Søg flere providers samtidigt (multithreading)",
|
||||
"Automatically extract and use embedded subtitles upon media addition (with configured default mods)": "Udpak automatisk og brug indlejrede undertekster når nyt indlægges (med konfigurerede default mods)",
|
||||
"After automatic extraction of embedded subtitles, also immediately search for available subtitles?": "Efter automatisk udpakning af indlejrede undertekster skal der straks søges efter tilgængelige undertekster?",
|
||||
"Don't search for subtitles of a language if there are embedded subtitles inside the media file (MKV/MP4)?": "Søg ikke efter undertekster for et sprog når der er indlejrede undertekster i et medies fil (MKV/MP4)?",
|
||||
"Don't search for subtitles of a language if they already exist on the filesystem (metadata/filesystem)?": "Søg ikke efter undertekster for et sprog hvis det allerede eksisterer i filsystemet (metadata/filsystem)?",
|
||||
"How strict should these subtitles existing on the filesystem be detected?": "Hvor eksakt skal undertekster på fil systemet blive fundet?",
|
||||
"Include non-text subtitle formats (anything else than .srt/.ssa/.ass/.vtt; embedded or external) in the above?": "Inkluder ikke-tekst undertekst formater (alt andet end .srt/.ssa/.ass/.vtt; indlejret eller eksternt) i det ovenstående?",
|
||||
"Minimum score for TV (min: 240, def/sane: 337, min-ideal: 352; see http://v.ht/szscores)": "Minimum score for TV (min: 240, def/sane: 337, min-ideal: 352; læs http://v.ht/szscores)",
|
||||
"Minimum score for movies (min: 60, def/sane: 69, min-ideal: 82; see http://v.ht/szscores)": "Minimum score for film(min: 60, def/sane: 69, min-ideal: 82; læs http://v.ht/szscores)",
|
||||
"Download hearing impaired subtitles.": "Hent undertekster for hørehæmmet",
|
||||
"Remove Hearing Impaired tags from downloaded subtitles": "Fjern hørehæmmet dele fra undertekst",
|
||||
"Remove style tags from downloaded subtitles (bold, italic, underline, colors, ...)": "Fjern formatering fra hentede undertekster (fremhævet, kursiv, understreget, farver ...)",
|
||||
"Fix common issues in subtitles": "Fix std. fejl med undertekster",
|
||||
"Fix common OCR errors in downloaded subtitles": "Fix almindelige OCR fejl i downloadede undertekster",
|
||||
"Reverse punctuation in RTL languages (heb)": "Genindkald tegnsætning i RTL sprog (hebræisk)",
|
||||
"Change colors of subtitles to": "Slå farve på undertekster til",
|
||||
"Store subtitles next to media files (instead of metadata)": "Gem undertekster sammen med medie filer (Istedet for internt i Plex)",
|
||||
"Subtitle formats to save (non-SRT only works if the previous option is enabled)": "Undertekster formater der gemmes (non-SRT virker kun såfremt forrige option er aktiveret)",
|
||||
"Subtitle Folder (\"current folder\" is the folder the current media file lives in)": "Undertekst bibliotek (\"Nuværede bibliotek\" er det bibliotek som det aktive medies fil lever i)",
|
||||
"Custom Subtitle folder (overrides \"Subtitle Folder\"; computes to real paths)": "Brugertilpas Undertekst bibliotek (overskriver \"Undertekst bibliotek\"; udregner den rette sti)",
|
||||
"Fall back to metadata storage if filesystem storage failed": "Fald tilbage til metadata lager såfremt filsystem lager fejlede",
|
||||
"Set subtitle file permissions to (integer, e.g.: 0775)": "Sæt undertekst fils egenskaber til (integer, f.eks: 0775)",
|
||||
"Automatically delete leftover/unused (externally saved) subtitles": "Slet automatisk overskuds/ubrugte (eksternt gemte) undertekster",
|
||||
"On media playback: search for missing subtitles (refresh item)": "Ved mediets playback: søg efter manglende undertekster (genindlæs dem)",
|
||||
"Scheduler: Periodically search for recent items with missing subtitles": "Jobplanlægger: Periodisk søgning efter titler med manglende undertekster",
|
||||
"Scheduler: Item age to be considered recent": "Jobplanlægger: En titles alder anses som fornylig",
|
||||
"Scheduler: Recent items to consider per library": "Jobplanlægger: Fornylige titler at blive undersøgt per bibliotek",
|
||||
"Scheduler: Periodically search for better subtitles": "Jobplanlægger:Periodisk søgning efter bedre undertekster",
|
||||
"Scheduler: Days to search for better subtitles (max: 30 days)": "Jobplanlægger: Dage til søgning efter bedre undertekster (max: 30 dage)",
|
||||
"Scheduler: Don't search for better subtitles if the item's air date is older than": "Jobplanlægger: Søg ikke efter bedre undertekster såfremt titlens dato er ældre end",
|
||||
"Scheduler: Overwrite manually selected subtitles when better found": "Jobplanlægger: Overskriv manuelt valgte undertekster når bedre er fundet",
|
||||
"Scheduler: Overwrite subtitles with non-default subtitle modifications when better found": "Jobplanlægger: Overskriv undertekster når ikke-default undertekster ændringer såfremt bedre er fundet",
|
||||
"History: amount of items to store historical data for": "Historie: antallet af titler som der skal gemmes historiske data for",
|
||||
"How many download tries per subtitle (on timeout or error)": "Hvormange downloads forsøg per titel (på timeout eller fejl)",
|
||||
"Ignore folders (with \"subzero.ignore/.subzero.ignore/.nosz\" files in them)": "Ignorer biblioteker (med \"subzero.ignore/.subzero.ignore/.nosz\" filer i dem)",
|
||||
"Ignore anything in the following paths (comma-separated)": "Ignorer alting i det følgende bibliotek (kommesepareret)",
|
||||
"Sub-Zero mode": "Sub-Zero mode",
|
||||
"Access PIN (any amount of numbers, 0-9)": "PIN (tilfældig antal af nummere , 0-9)",
|
||||
"Access PIN valid for minutes": "Pin er gyldig i minutter",
|
||||
"Use PIN to restrict access to (needs plugin or PMS restart)": "Brug PIN til at hindre adgang til (kræver plugin eller PMS genstart)",
|
||||
"Call this executable upon successful subtitle download (see Wiki for details)": "Kald denne eksekverebare såfremt undertekst download (se i WIKI for detaljer)",
|
||||
"Check for correct folder permissions of every library on plugin start": "Undersøg for de korrekte biblioteks tilladelser på hvert bibliotek når plugin stater op",
|
||||
"Use new style caching (for subliminal)": "Brug ny stil cacing (til sublimiral)",
|
||||
"Low impact mode (for remote filesystems)": "Lille indvirkrning tilstand (for remote filsystemer)",
|
||||
"Timeout for API requests sent to the PMS": "Timeout for kommunikation med Plex server",
|
||||
"HTTP proxy to use for providers (supports credentials)": "HTTP proxy til brug for udbydere (understøtter legitimation)",
|
||||
"How verbose should the logging be?": "Hvor ordrig/omfattende skal logning være?",
|
||||
"How many log backups to keep?": "Hvormange log backups skal gemmes?",
|
||||
"Log subtitle modification (debug)": "Log til modifikation af undertekster (debug)",
|
||||
"Log to console (for development/debugging)": "Log til console (for udvikling/fejlfinding)",
|
||||
"Collect anonymous usage statistics": "Indsaml anonymt brugs statistik",
|
||||
"Sonarr/Radarr (fill api info below)": "Sonarr/Radarr (indsæt api information nedenfor)",
|
||||
"Filebot": "Filebot",
|
||||
"Sonarr/Radarr/Filebot": "Sonarr/Radarr/Filebot",
|
||||
"Symlink to original file": "Symlink til original fil",
|
||||
"I keep the original filenames": "Jeg beholder de orginale fil navne",
|
||||
"none of the above": "Ingen af ovenstående",
|
||||
"exact: media filename match": "eksakt: mediets filnavn stemmer",
|
||||
"loose: filename contains media filename": "løs: filnavn indeholder mediets filnavn",
|
||||
"any": "alle",
|
||||
"prefer": "foretræk",
|
||||
"don't prefer": "foretræk ikke",
|
||||
"force HI": "brug kun hørehæmmet",
|
||||
"force non-HI": "brug ikke hørehæmmet",
|
||||
"don't change": "skift ikke",
|
||||
"white": "hvid",
|
||||
"light-grey": "lysegrå",
|
||||
"red": "rød",
|
||||
"green": "grøn",
|
||||
"yellow": "gul",
|
||||
"blue": "blå",
|
||||
"magenta": "magenta",
|
||||
"cyan": "cyan",
|
||||
"black": "sort",
|
||||
"dark-red": "mørkerød",
|
||||
"dark-green": "mørkegrøn",
|
||||
"dark-yellow": "mørkegul",
|
||||
"dark-blue": "mørkeblå",
|
||||
"dark-magenta": "mørkemagenta",
|
||||
"dark-cyan": "mørkecyan",
|
||||
"dark-grey": "mørkegrå",
|
||||
"current folder": "nuværende folder",
|
||||
"never": "aldrig",
|
||||
"current media item": "nuværende titel",
|
||||
"next episode (series)": "næste episode (serier)",
|
||||
"hybrid: current item or next episode": "hybrid: nuværende titel eller næste afsnit",
|
||||
"hybrid-plus: current item and next episode": "hybrid-plus: nuværende titel eller næste afsnit",
|
||||
"every 6 hours": "hver 6 time",
|
||||
"every 12 hours": "hver 12 time",
|
||||
"every 24 hours": "hver 24 time",
|
||||
"1 days": "hver dag",
|
||||
"2 days": "hver 2 dag",
|
||||
"3 days": "hver 3 dag",
|
||||
"4 days": "hver 4 dag",
|
||||
"1 weeks": "hver uge",
|
||||
"2 weeks": "hver 2 uge",
|
||||
"3 weeks": "hver 3 uge",
|
||||
"4 weeks": "hver 4 uge",
|
||||
"5 weeks": "hver 5 uge",
|
||||
"6 weeks": "hver 6 uge",
|
||||
"12 weeks": "hver 12 uge",
|
||||
"don't limit": "ingen begrænsning",
|
||||
"1 year": "1 år",
|
||||
"2 years": "2 år",
|
||||
"3 years": "3 år",
|
||||
"4 years": "4 år",
|
||||
"5 years": "5 år",
|
||||
"6 years": "6 år",
|
||||
"7 years": "7 år",
|
||||
"8 years": "8 år",
|
||||
"9 years": "9 år",
|
||||
"10 years": "10 år",
|
||||
"only agent": "kun agent",
|
||||
"disabled": "ikke aktiv",
|
||||
"advanced menu": "advanceret menu",
|
||||
"CRITICAL": "KRITISK",
|
||||
"ERROR": "FEJL",
|
||||
"WARNING": "ADVARSEL",
|
||||
"INFO": "INFO",
|
||||
"DEBUG": "DEBUG",
|
||||
"Force-find subtitles: %(item_title)s": "Gennentving-find undertekster: %s (titler)",
|
||||
"File %(file_part_index)s: ": "Fil %(file_part_index)s:␣",
|
||||
"%(part_summary)sNo current subtitle in storage": "%(part_summary)s Ingen undertekster for nuværende gemt",
|
||||
"%(part_summary)sCurrent subtitle: %(provider_name)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "%(part_summary)sNuværende undertekst: %(provider_name)s (tilføjet: %(date_added)s, %(mode)s), Sprog: %(language)s, Score: %(score)i, Lager: %(storage_type)s",
|
||||
"%(part_summary)sManage %(language)s subtitle": "%(part_summary)sAdministrer %(language)s undertekster",
|
||||
"%(part_summary)sList %(language)s subtitles": "%(part_summary)sVis %(language)s undertekster",
|
||||
"%(part_summary)sEmbedded subtitles (%(languages)s)": "%(part_summary)sIndlejrede undertekster (%(language)s)",
|
||||
"Select active %(language)s subtitle": "Vælg aktive %(language)s undertekster",
|
||||
"%(count)d subtitles in storage": "%(count)d undertekster gemt",
|
||||
"List available %(language)s subtitles": "Vis tilgængelige %(language)s undertekster",
|
||||
"Modify current %(language)s subtitle": "Modificer nuværende %(language)s undertekst",
|
||||
"Currently applied mods: %(mod_list)s": "Nuværende gældende mods: %(mod_list)s",
|
||||
"Blacklist current %(language)s subtitle and search for a new one": "Blacklist nuværende %(language)s undertekst og søg efter en ny",
|
||||
"Manage blacklist (%(amount)s contained)": "Administrer blacklist (%(amount)s indeholdt)",
|
||||
"%(current_state)s%(subtitle_name)s, Score: %(score)s": "%(current_state)s%(subtitle_name)s, Score: %(score)s",
|
||||
"Current: ": "Nuværende: ",
|
||||
"Stored: ": "Gemt: ",
|
||||
"by %(release_group)s": "af %(release_group)s",
|
||||
"Current: %(provider_name)s (%(score)s) ": "Nuværende: %(provider_name)s (%(score)s)␣",
|
||||
"Search for %(language)s subs (%(video_data)s)": "Søg efter %(language)s undertekster (%(video_data)s)",
|
||||
"%(current_info)sFilename: %(filename)s": "%(current_info)sFilenavn: %(filename)s",
|
||||
"Searching for %(language)s subs (%(video_data)s), refresh here ...": "Søger efter %(language)s undertekster (%(video_data)s), opdater her...",
|
||||
" (wrong FPS, sub: %(subtitle_fps)s, media: %(media_fps)s)": " ␣(forkert FPS, undertekst: %(subtitle_fps)s, medie: %(media_fps)s)",
|
||||
" (wrong FPS, sub: %(subtitle_fps)s, media: unknown, low impact mode)": "␣(forkert FPS, undertekst: %(subtitle_fps)s, medie: ukendt, lav betydnings modus)",
|
||||
"%(blacklisted_state)s%(current_state)s: %(provider_name)s, score: %(score)s%(wrong_fps_state)s": "%(blacklisted_state)s%(current_state)s: %(provider_name)s, score: %(score)s%(wrong_fps_state)s",
|
||||
"Release: %(release_info)s, Matches: %(matches)s": "Udgivelse: %(release_info)s, Stemmer: %(matches)s",
|
||||
"Downloading subtitle for %(title_or_id)s": "Henter undertekster for %(title_or_id)s",
|
||||
"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s with default mods": "Udpak stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s med gældende mods",
|
||||
"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s": "Udpak stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s",
|
||||
"%(provider_name)s, %(subtitle_id)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "%(provider_name)s, %(subtitle_id)s (added: %(date_added)s, %(mode)s), Sprog: %(language)s, Score: %(score)i, Lager: %(storage_type)s",
|
||||
"Insufficient permissions on library %(title)s, folder: %(path)s": "Utilstrækkelig tilladelser for bibliotek %(title)s, Sti: %(path)s",
|
||||
"Running: %(items_done)s/%(items_searching)s (%(percentage)s%%)": "Kører: %(items_done)s/%(items_searching)s (%(percentage)s%%)",
|
||||
"Display ignore list (%(ignored_count)d)": "Vis ignorer listen (%(ignored_count)d)",
|
||||
"%(throttled_provider)s until %(until_date)s (%(reason)s)": "%(throttled_provider)s indtil %(until_date)s (%(reason)s)",
|
||||
"Extracting subtitle %(stream_index)s of %(filename)s": "Udpakker undertekst %(stream_index)s af %(filename)s",
|
||||
"Extract missing %(language)s embedded subtitles": "Udpakker manglende %(language)s indlejrede undertekster",
|
||||
"Extract and activate %(language)s embedded subtitles": "Udpak og aktiver %(language)s indlejrede undertekster",
|
||||
"None": "Ingen",
|
||||
"Idle": "Venter",
|
||||
"%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)": "%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)",
|
||||
"Adjust by %(time_and_unit)s": "Justeret med %(time_and_unit)s",
|
||||
"added: %(date_added)s, %(mode)s, Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "tilføjet: %(date_added)s, %(mode)s, Sprog: %(language)s, Score: %(score)i, Lager: %(storage_type)s",
|
||||
"Remove: %(mod_name)s": "Fjern: %(mod_name)s",
|
||||
"%(class_name)s: Subtitle download failed (%(item_id)s)": "%(class_name)s: Undertekst download fejlede (%(item_id)s)",
|
||||
"agent + interface": "agent + interface",
|
||||
"only interface": "kun interface",
|
||||
"interface": "interface",
|
||||
"Shows the current on deck items and allows you to individually (force-) refresh their metadata/subtitles.": "Vis nuværende desktop titler og du kan individuelt (gennemtvinge) en opdatering af metadata/undertekster.",
|
||||
"Lists items with missing subtitles. Click on \"Find recent items with missing subs\" to update list": "Vis titler med manglende undertekster. Klik på \"Find seneste titler med manglende undertekster\" for at opdatere listen",
|
||||
"Add %(kind)s %(title)s to the ignore list": "Tilføj %(kind)s %(title)s til ignorer listen",
|
||||
"Remove %(kind)s %(title)s from the ignore list": "Fjern %(kind)s %(title)s fra ignorer listen",
|
||||
"%(title)s added to the ignore list": "%(title)s tilføjet til ignorer listen",
|
||||
"%(title)s removed from the ignore list": "%(title)s fjernet fra ignorer listen",
|
||||
"Triggering refresh for %(title)s": "Aktiver genindlæsning for %(title)s",
|
||||
"Triggering forced refresh for %(title)s": "Aktiver gennemtvunget opdatering for %(title)s",
|
||||
"Refresh of item %(item_id)s triggered": "Opdatering af %(item_id)s titler er aktiveret",
|
||||
"Forced refresh of item %(item_id)s triggered": "Gennemtvunget opdatering af %(item_id)s titler er aktiveret",
|
||||
"Ignore %(kind)s \"%(title)s\"": "Ignorer %(kind)s \"%(title)s\"",
|
||||
"Un-ignore %(kind)s \"%(title)s\"": "Ikke-ignorer %(kind)s \"%(title)s\"",
|
||||
"Refreshing %(title)s": "Genindlæser %(title)s",
|
||||
"Force-refreshing %(title)s": "Gennentvunget-opdatering %(title)s",
|
||||
"Extracts the not yet extracted embedded subtitles of all episodes for the current season with all configured default modifications": "Udpakker de endnu ikke udpakkede indlejrede undertekster fra alle afsnit for nuværende sæson ved brug af de konfigurede default indstillede rettelser \n",
|
||||
"Extracts embedded subtitles of all episodes for the current season with all configured default modifications": "Udpakker indlejrede undertekster fra alle afsnit for nuværende sæson ved brug af de konfigurede default indstillede rettelser",
|
||||
"Refreshes %(the_movie_series_season_episode)s, possibly searching for missing and picking up new subtitles on disk": "Genindlæser %(the_movie_series_season_episode)s, sandsynligvis søges der efter manglende undertekster ellers anvendes nye fra disken",
|
||||
"the movie": "filmen",
|
||||
"the series": "serien",
|
||||
"the episode": "episoden",
|
||||
"the season": "sæsonen",
|
||||
"Change the color of the subtitle": "Skift farve på underteksten",
|
||||
"Adds the requested color to every line of the subtitle. Support depends on player.": "Tilføjer den valgte farve til hver linje i underteksten. Support afhænger af afspiller.",
|
||||
"Basic common fixes": "Basale fælles rettelser",
|
||||
"Fix common and whitespace/punctuation issues in subtitles": "Ret fælles og whitespace/tegnsætnings problemer i undertekster",
|
||||
"Remove all style tags": "Fjern alle style tags",
|
||||
"Removes all possible style tags from the subtitle, such as font, bold, color etc.": "Fjern alle mulige style tags fra underteksten såsom font, fed, farve osv.",
|
||||
"Reverse punctuation in RTL languages": "Omvend tegnsætning i RTL sprog",
|
||||
"Some playback devices don't properly handle right-to-left markers for punctuation. Physically swap punctuation. Applicable to languages: hebrew": "Nogle afspille håndterer ikke højre-til-venstre tegnsætning korrekt. Fysisk ændring af tegnsætning. Gældende for sprog som: hebræisk",
|
||||
"Change the FPS of the subtitle": "Ændre FPS for undertekst",
|
||||
"Re-syncs the subtitle to the framerate of the current media file.": "Gensynkroniser underteksten med frameraten på den nuværende medie fil.",
|
||||
"Remove Hearing Impaired tags": "Fjern Høresvækkede tags",
|
||||
"Removes tags, text and characters from subtitles that are meant for hearing impaired people": "Fjern tags, tekst og tegn fra underteksten som er tiltænkt høresvækkede mennesker",
|
||||
"Fix common OCR issues": "Ret fælles OCR problemer",
|
||||
"Fix issues that happen when a subtitle gets converted from bitmap to text through OCR": "Ret problemer når en undertekst bliver oversat fra bitmap eller gennem OCR",
|
||||
"Change the timing of the subtitle": "Ændre timingen på underteksten",
|
||||
"Adds or substracts a certain amount of time from the whole subtitle to match your media": "Tilføj eller fjern en vis tid fra underteksten så den matcher din medie",
|
||||
"Available": "Tilgængelig",
|
||||
"Current": "Nuværende",
|
||||
"Custom path to advanced_settings.json": "Bruger defineret sti til advanced_settings.json"
|
||||
}
|
||||
@@ -0,0 +1,402 @@
|
||||
{
|
||||
"sq": "Albanisch",
|
||||
"ar": "Arabisch",
|
||||
"be": "Weißrussisch",
|
||||
"bs": "Bosnisch",
|
||||
"bg": "Bulgarisch",
|
||||
"ca": "Katalanisch",
|
||||
"zh": "Chinesisch",
|
||||
"hr": "Kroatisch",
|
||||
"cs": "Tschechisch",
|
||||
"da": "Dänisch",
|
||||
"nl": "Holländisch",
|
||||
"en": "Englisch",
|
||||
"et": "Estnisch",
|
||||
"fa": "Persisch",
|
||||
"fi": "Finnisch",
|
||||
"fr": "Französisch",
|
||||
"de": "Deutsch",
|
||||
"el": "Griechisch",
|
||||
"he": "Hebräisch",
|
||||
"hi": "Hindi",
|
||||
"hu": "Ungarisch",
|
||||
"is": "Isländisch",
|
||||
"id": "Indonesisch",
|
||||
"it": "Italienisch",
|
||||
"ja": "Japanisch",
|
||||
"ko": "Koreanisch",
|
||||
"lv": "Lettisch",
|
||||
"lt": "Litauisch",
|
||||
"mk": "Mazedonisch",
|
||||
"ms": "Malaiisch",
|
||||
"no": "Norwegisch",
|
||||
"pl": "Polnisch",
|
||||
"pt": "Portugiesisch",
|
||||
"pt-br": "Portigiesisch (Brasilien)",
|
||||
"ro": "Rumänisch",
|
||||
"ru": "Russisch",
|
||||
"sr": "Serbisch",
|
||||
"sr-cyrl": "Serbisch (Kyrillisch)",
|
||||
"sr-latn": "Serbisch (Lateinisch)",
|
||||
"sk": "Slowakisch",
|
||||
"sl": "Slowenisch",
|
||||
"es": "Spanisch",
|
||||
"sv": "Schwedisch",
|
||||
"th": "Thailändisch",
|
||||
"tr": "Türkisch",
|
||||
"uk": "Ukrainisch",
|
||||
"vi": "Vietnamesisch",
|
||||
"Internal stuff, pay attention!": "Internes, bitte aufpassen!",
|
||||
"Advanced": "Erweitert",
|
||||
"advanced": "erweitert",
|
||||
"Enter PIN": "PIN eingeben",
|
||||
"The owner has restricted the access to this menu. Please enter the correct pin": "Der Inhaber hat den Zugriff zu diesem Menü eingeschränkt, bitte die korrekte PIN eingeben",
|
||||
"Restart the plugin": "Plugin neustarten",
|
||||
"Get my logs (copy the appearing link and open it in your browser, please)": "Hole meine Logs (bitte den erscheinenden Link kopieren und im Browser öffnen)",
|
||||
"Copy the appearing link and open it in your browser, please": "Bitte den erscheinenden Link kopieren und im Browser öffnen",
|
||||
"Trigger find better subtitles": "Bessere Untertitel finden anstoßen",
|
||||
"Skip next find better subtitles (sets last run to now)": "Das nächste Bessere-Untertitel-Finden überspringen (setzt den letzten Laufzeitpunkt auf jetzt)",
|
||||
"Trigger subtitle storage maintenance": "Unterstitelspeicher-Wartung anstoßen",
|
||||
"Trigger subtitle storage migration (expensive)": "Untertitelspeicher-Migration anstoßen (teuer)",
|
||||
"Trigger cache maintenance (refiners, providers and packs/archives)": "Cache-Wartung anstoßen (Refiner, Anbieter, Pakete/Archive)",
|
||||
"Apply configured default subtitle mods to all (active) stored subtitles": "Alle Standard-Untertitel-Mods auf alle (aktiven) gespeicherten Untertitel anwenden",
|
||||
"Re-Apply mods of all stored subtitles": "Alle Mods aller gespeicherten Untertitel abermals anwenden",
|
||||
"Log the plugin's scheduled tasks state storage": "Den Geplante-Aufgaben-Status-Speicher protokollieren",
|
||||
"Log the plugin's internal ignorelist storage": "Den internen Ignore-Listen-Speicher protokollieren",
|
||||
"Log the plugin's complete state storage": "Den kompletten internen State-Speicher protokollieren",
|
||||
"Reset the plugin's scheduled tasks state storage": "Den Geplante-Aufgaben-Status-Speicher zurücksetzen",
|
||||
"Reset the plugin's internal ignorelist storage": "Den internen Ignore-Listen-Speicher zurücksetzen",
|
||||
"Invalidate Sub-Zero metadata caches (subliminal)": "Die Sub-Zero Metadaten-Caches invalidieren (subliminal)",
|
||||
"Reset provider throttle states": "Den Anbieter-Drosselungsstatus zurücksetzen",
|
||||
"Restarting the plugin": "Starte das Plugin neu",
|
||||
"Restart triggered, please wait about 5 seconds": "Neustart angestoßen, bitte circa 5 Sekunden warten",
|
||||
"Reset subtitle storage": "Untertitelspeicher zurücksetzen",
|
||||
"Are you sure?": "Sicher?",
|
||||
"Are you really sure?": "Wirklich sicher?",
|
||||
"Success": "Erfolg",
|
||||
"FindBetterSubtitles triggered": "FindBetterSubtitles angestoßen",
|
||||
"FindBetterSubtitles skipped": "FindBetterSubtitles übersprungen",
|
||||
"SubtitleStorageMaintenance triggered": "SubtitleStorageMaintenance angestoßen",
|
||||
"MigrateSubtitleStorage triggered": "MigrateSubtitleStorage angestoßen",
|
||||
"TriggerCacheMaintenance triggered": "TriggerCacheMaintenance angestoßen",
|
||||
"This may take some time ...": "Dies könnte ein wenig dauern ...",
|
||||
"Download Logs": "Logs herunterladen",
|
||||
"Sorry, feature unavailable": "Entschuldigung, Funktion nicht verfügbar",
|
||||
"Universal Plex token not available": "Universeller Plex-Token nicht verfügbar",
|
||||
"Copy this link and open this in your browser, please": "Bitte diesen Link kopieren und im Browser öffnen",
|
||||
"Cache invalidated": "Cache invalidiert",
|
||||
"Enter PIN number ": "PIN eingeben",
|
||||
"PIN correct": "PIN ist korrekt",
|
||||
"Reset": "Zurücksetzen",
|
||||
"Menu locked": "Menü gesperrt",
|
||||
"Provider throttles reset": "Anbieter-Drosselung zurückgesetzt",
|
||||
"Information Storage (%s) reset": "Informationsspeicher (%s) zurückgesetzt",
|
||||
"Information Storage (%s) logged": "Informationsspeicher (%s) protokolliert",
|
||||
"Plex didn't return any information about the item, please refresh it and come back later": "Plex hat leider keine Informationen über dieses Element, bitte dieses aktualisieren und noch mal probieren",
|
||||
"Item not found: %s!": "Element nicht gefunden: %s!",
|
||||
"< Back to %s": "< Zurück zu %s",
|
||||
"Back to %s > %s": "Zurück zu %s > %s",
|
||||
"Refresh: %s": "Aktualisieren: %s",
|
||||
"Issues a forced refresh, ignoring known subtitles and searching for new ones": "Startet eine erzwungene Aktualisierung; ignoriert dabei bereits bekannte Untertitel und sucht nach neuen",
|
||||
"Extract and activate embedded subtitle streams": "Eingebettete Untertitel extrahieren und aktivieren",
|
||||
"Inspect currently blacklisted subtitles": "Untertitel-Sperrliste ansehen",
|
||||
"Subtitle saved to disk": "Untertitel gespeichert",
|
||||
"Remove subtitle from blacklist": "Untertitel von der Sperrliste entfernen",
|
||||
"No subtitles found": "Keine Untertitel gefunden",
|
||||
" (unknown)": " (unbekannt)",
|
||||
" (forced)": " (erzwungen)",
|
||||
"Extracting of embedded subtitle %s of part %s:%s triggered": "Extraktion des eingebetteten Untertitels %s des Teils %s:%s angestoßen",
|
||||
"Insufficient permissions": "Unzureichende Berechtigungen",
|
||||
"I'm not enabled!": "Ich bin nicht aktiv!",
|
||||
"Please enable me for some of your libraries in your server settings; currently I do nothing": "Bitte für wenigstens eine Medienbibliothek aktivieren, aktuell tue ich nichts",
|
||||
"Working ... refresh here": "In Arbeit ... hier aktualisieren",
|
||||
"Current state: %s; Last state: %s": "Aktueller Status: %s; Letzter Status: %s",
|
||||
"On-deck items": "Aktuelle Medien",
|
||||
"Shows the %s recently played items and allows you to individually (force-) refresh their metadata/subtitles.": "Zeigt die letzten %s abgespielten Medien und ermöglicht die (erzwungene) Aktualisierung derer Metadaten/Untertitel",
|
||||
"Recently-added items": "Zuletzt hinzugefügte Medien",
|
||||
"Recently played items": "Zuletzt abgespielte Medien",
|
||||
"Shows the recently added items per section.": "Zeigt die zuletzt hinzugefügten Medien pro Bereich",
|
||||
"Show recently added items with missing subtitles": "Zeigt zuletzt hinzugefügte Medien mit fehlenden Untertiteln",
|
||||
"Browse all items": "Alle Medien durchsuchen",
|
||||
"Go through your whole library and manage your ignore list. You can also (force-) refresh the metadata/subtitles of individual items.": "Die gesamten Medienbibliothek durchsuchen und die Ignore-Listen verwalten. Hier können ebenfalls die Metadaten/Untertitel einzelner Medien (erzwungen) aktualisiert werden",
|
||||
"Last run: %s; Next scheduled run: %s; Last runtime: %s": "Letzter Durchlauf: %s; Nächster geplanter Durchlauf: %s; Letzte Laufzeit: %s",
|
||||
"Search for missing subtitles (in recently-added items, max-age: %s)": "Nach fehlenden Untertiteln suchen (für zuletzt hinzugefügte Medien, maximales Alter: %s)",
|
||||
"Automatically run periodically by the scheduler, if configured. %s": "Automatisch regelmäßig vom Scheduler ausgeführt, wenn konfiguriert. %s",
|
||||
"Show the current ignore list (mainly used for the automatic tasks)": "Zeige die aktuelle Ignore-Liste (hauptsächlich für Hintergrundaufgaben genutzt)",
|
||||
"History": "Verlauf",
|
||||
"Show the last %i downloaded subtitles": "Zeige die letzten %i heruntergeladenen Untertitel",
|
||||
"Refresh": "Aktualisieren",
|
||||
"Re-lock menu(s)": "Menüs wieder sperren",
|
||||
"Enabled the PIN again for menu(s)": "PIN für Menüs wieder aktiviert",
|
||||
"Throttled providers: %s": "Gedrosselte Anbieter: %s",
|
||||
"Advanced functions": "Erweiterte Funktionen",
|
||||
"Use at your own risk": "Benutzung auf eigene Gefahr",
|
||||
"Items On Deck": "Aktuelle Medien",
|
||||
"Recently Played": "Zuletzt abgespielt",
|
||||
"Items with missing subtitles": "Medien mit fehlenden Untertiteln",
|
||||
"Find recent items with missing subtitles": "Finde zuletzt hinzugefügte Medien mit fehlenden Untertiteln",
|
||||
"Updating, refresh here ...": "Update, hier aktualisieren ...",
|
||||
"Missing: %s": "Fehlt: %s",
|
||||
"Didn't change the ignore list": "Ignore-Liste wurde nicht verändert",
|
||||
"Sections": "Bereiche",
|
||||
"All": "Alle",
|
||||
"show": "Serie",
|
||||
"movie": "Film",
|
||||
"<< Back to home": "<< Zurück zum Anfang",
|
||||
"Auto-Find subtitles: %s": "Untertitel automatisch finden: %s",
|
||||
"Extracting of embedded subtitles for %s triggered": "Extraktion eingebetteter Untertitel für %s angestoßen",
|
||||
"< Back to subtitle options for: %s": "< Zurück zu den Untertiteloptionen für: %s",
|
||||
"Remove last applied mod (%s)": "Die zuletzt angewandte Modifikation entfernen (%s)",
|
||||
"none": "keine",
|
||||
"Manage applied mods": "Angewandte Modifikationen verwalten",
|
||||
"Reapply applied mods": "Angewandte Modifikationen erneut anwenden",
|
||||
"Restore original version": "Originalversion wiederherstellen",
|
||||
"< Back to subtitle modification menu": "< Zurück zum Untertitel-Modifikations-Menü",
|
||||
"subs constantly getting faster": "Untertitel werden konstant schneller",
|
||||
"subs constantly getting slower": "Untertitel werden konstant langsamer",
|
||||
"< Back to subtitle modifications": "< Zurück zu den Untertitel-Modifikationen",
|
||||
"< Back to unit selection": "< Zurück zur Einheiten-Auswahl",
|
||||
"Subtitle Language (1)": "Untertitel-Sprache (1)",
|
||||
"Subtitle Language (2)": "Untertitel-Sprache (2)",
|
||||
"Subtitle Language (3)": "Untertitel-Sprache (3)",
|
||||
"Additional Subtitle Languages (use ISO-639-1 codes; comma-separated)": "Weitere Untertitel-Sprachen (ISO-639-1 Kodierung benutzen, kommagetrennt)",
|
||||
"Only download foreign/forced subtitles": "Nur erzwungende/fremdsprachige Untertitel herunterladen",
|
||||
"Display languages with country attribute as ISO 639-1 (e.g. pt-BR = pt)": "Sprachen mit Landesattribut als ISO 639-1 anzeigen (z. B. pt-BR = pt)",
|
||||
"Treat languages with country attribute as ISO 639-1 (e.g. don't download pt-BR if pt subtitle exists)": "Sprachen mit Landesattribut als ISO 639-1 behandeln (pt-BR nicht herunterladen, wenn ein pt Untertitel existiert)",
|
||||
"Restrict to one language (skips adding \".lang.\" to the subtitle filename; only uses \"Subtitle Language (1)\")": "Auf eine Sprache beschränken (fügt dem Dateinamen kein \".lang.\"-Suffix hinzu; benutzt nur \"Untertitel Sprache (1)\")",
|
||||
"Embedded subtitles: Treat \"Undefined\" (und) as language 1": "Eingebettete Untertitel: behandle Unbekannte Sprache als Sprache 1",
|
||||
"I rename my files using": "Ich benenne meine Dateien um, mit:",
|
||||
"Retrieve original filename from .file_info/file_info index files (see wiki)": "Originale Dateinamen von .file_info/file_info Indexdateien beziehen (siehe Wiki)",
|
||||
"Sonarr URL (add URL base if configured)": "Sonarr URL (URL-Basis hinzufügen, wenn konfiguriert)",
|
||||
"Sonarr API key": "Sonarr API-Schlüssel",
|
||||
"Radarr URL (add URL base if configured, min. version: 0.2.0.897)": "Radarr URL (URL-Basis hinzufügen, wenn konfiguriert; minimale Version: 0.2.0.897)",
|
||||
"Radarr API key": "Radarr API-Schlüssel",
|
||||
"Provider: Enable OpenSubtitles": "Anbieter: OpenSubtitles aktivieren",
|
||||
"Opensubtitles Username": "OpenSubtitles Benutzername",
|
||||
"Opensubtitles Password": "OpenSubtitles Passwort",
|
||||
"OpenSubtitles VIP? (ad-free subs, 1000 subs/day, no-cache VIP server: http://v.ht/osvip)": "OpenSubtitles VIP? (werbefreie Untertitel, 1000 Untertitel/Tag, no-cache VIP-Server: http://v.ht/osvip)",
|
||||
"Provider: Enable Podnapisi.NET": "Anbieter: Podnapisi.NET aktivieren",
|
||||
"Provider: Enable Titlovi.com": "Anbieter: Titlovi.com aktivieren",
|
||||
"Provider: Enable Addic7ed": "Anbieter: Addic7ed aktivieren",
|
||||
"Addic7ed Username": "Addic7ed Benutzername",
|
||||
"Addic7ed Password": "Addic7ed Passwort",
|
||||
"Addic7ed: boost score (if requirements met)": "Addic7ed: Punktzahl anheben (wenn Voraussetzungen erfüllt)",
|
||||
"Addic7ed: Use random user agents": "Addic7ed: Zufällige User-Agents benutzen",
|
||||
"Provider: Enable Legendas TV (mostly pt-BR; UNRAR NEEDED)": "Anbieter: Legendas TV aktivieren (meist pt-BR; UNRAR erforderlich!)",
|
||||
"Legendas TV Username": "Legendas TV Benutzername",
|
||||
"Legendas TV Password": "Legendas TV Passwort",
|
||||
"Provider: Enable TVsubtitles.net": "Anbieter: TVsubtitles.net aktivieren",
|
||||
"Provider: Enable NapiProjekt.pl (Polish)": "Anbieter: NapiProjekt.pl aktivieren (polnisch)",
|
||||
"Provider: Enable SubScene (TV shows)": "Anbieter: SubScene aktivieren (Serien)",
|
||||
"Provider: Enable hosszupuskasub.com (Hungarian)": "Anbieter: Hosszupuskasub.com aktivieren (ungarisch)",
|
||||
"Provider: Enable aRGENTeaM (Spanish)": "Anbieter: aRGENTeaM aktivieren (spanisch)",
|
||||
"Search enabled providers simultaneously (multithreading)": "Durchsuche aktive Anbieter gleichzeitig (Multithreading)",
|
||||
"Automatically extract and use embedded subtitles upon media addition (with configured default mods)": "Extrahiere und aktiviere eingebettete Untertitel automatisch nach dem Hinzufügen der Medien (mit den konfigurierten Standard-Mods)",
|
||||
"After automatic extraction of embedded subtitles, also immediately search for available subtitles?": "Soll nach der automatischen Extraktion eingebetteter Untertitel zusätzlich auch sofort nach verfügbaren gesucht werden?",
|
||||
"Don't search for subtitles of a language if there are embedded subtitles inside the media file (MKV/MP4)?": "Nicht nach Untertiteln einer Sprache suchen, wenn bereits einer als eingebetteter Untertitel in der Mediendatei existiert (MKV/MP4)?",
|
||||
"Don't search for subtitles of a language if they already exist on the filesystem (metadata/filesystem)?": "Nicht nach Untertiteln einer Sprache suchen, wenn bereits einer im Dateisystem existiert (Metadaten/Dateisystem)?",
|
||||
"How strict should these subtitles existing on the filesystem be detected?": "Wie genau soll die Erkennung existierender Untertitel auf dem Dateisystem sein?",
|
||||
"Include non-text subtitle formats (anything else than .srt/.ssa/.ass/.vtt; embedded or external) in the above?": "Dabei nicht-textbasierte Untertitelformate einbeziehen? (Alles außer .srt/.ssa/.ass/.vtt; eingebettet oder extern)",
|
||||
"Minimum score for TV (min: 240, def/sane: 337, min-ideal: 352; see http://v.ht/szscores)": "Minimale Punktzahl für Serien (min: 240, sinnvoll: 337, min-ideal: 352; see http://v.ht/szscores)",
|
||||
"Minimum score for movies (min: 60, def/sane: 69, min-ideal: 82; see http://v.ht/szscores)": "Minimale Punktzahl für Filme (min: 60, def/sane: 69, sinnvoll: 82; see http://v.ht/szscores)",
|
||||
"Download hearing impaired subtitles.": "Untertitel für Hörgeschädigte herunterladen.",
|
||||
"Remove Hearing Impaired tags from downloaded subtitles": "Inhalte für Hörgeschädigte von heruntergeladenen Untertiteln entfernen",
|
||||
"Remove style tags from downloaded subtitles (bold, italic, underline, colors, ...)": "Textformatierungen von heruntergeladenen Untertiteln entfernen (fett, kursiv, unterstrichen, Farben, ...)",
|
||||
"Fix common issues in subtitles": "Häufige Probleme in Untertiteln beheben",
|
||||
"Fix common OCR errors in downloaded subtitles": "Häufige Texterkennungsfehler in Untertiteln beheben",
|
||||
"Reverse punctuation in RTL languages (heb)": "Zeichensetzung in linksläufigen Schriften umkehren (heb)",
|
||||
"Change colors of subtitles to": "Farbe der Untertitel ändern zu",
|
||||
"Store subtitles next to media files (instead of metadata)": "Speichere Untertitel neben den Medien (anstatt im Metadatenspeicher)",
|
||||
"Subtitle formats to save (non-SRT only works if the previous option is enabled)": "Zu speichernde Untertitelformate (Nicht-SRT funktioniert nur, wenn die vorherige Option aktiv ist)",
|
||||
"Subtitle Folder (\"current folder\" is the folder the current media file lives in)": "Untertitel-Ordner (\"aktueller Ordner\" ist der, in dem die Mediendatei liegt)",
|
||||
"Custom Subtitle folder (overrides \"Subtitle Folder\"; computes to real paths)": "Benutzerdefinierter Untertitelordner (überschreibt \"Untertitel-Ordner\"; wird zu echten Pfaden aufgelöst)",
|
||||
"Fall back to metadata storage if filesystem storage failed": "Im Notfall im Metadatenspeicher speichern, wenn nicht auf dem Dateisystem gespeichert werden konnte",
|
||||
"Set subtitle file permissions to (integer, e.g.: 0775)": "Untertitel-Berechtigungen setzen auf (Ganzzahl, z. B.: 0775)",
|
||||
"Automatically delete leftover/unused (externally saved) subtitles": "Automatisch übrig gebliebene/ungenutzte (extern gespeicherter) Untertitel löschen",
|
||||
"On media playback: search for missing subtitles (refresh item)": "Beim Abspielen von Median nach fehlenden Untertiteln suchen (Element aktualisieren)",
|
||||
"Scheduler: Periodically search for recent items with missing subtitles": "Hintergrundaufgaben: Regelmäßig nach aktuellen Medien mit fehlenden Untertiteln suchen",
|
||||
"Scheduler: Item age to be considered recent": "Hintergrundaufgaben: Medien-Alter um als \"aktuell\" zu gelten",
|
||||
"Scheduler: Recent items to consider per library": "Hintergrundaufgaben: Anzahl an zu berücksichtigenden Medien pro Bibliothek",
|
||||
"Scheduler: Periodically search for better subtitles": "Hintergrundaufgaben: Regelmäßig nach besseren Untertiteln suchen",
|
||||
"Scheduler: Days to search for better subtitles (max: 30 days)": "Hintergrundaufgaben: Wie viele Tage soll nach besseren Untertiteln gesucht werden (max: 30 Tage)",
|
||||
"Scheduler: Don't search for better subtitles if the item's air date is older than": "Hintergrundaufgaben: Nicht nach besseren Untertiteln suchen, wenn der Ausstrahlungszeitpunkt älter ist als",
|
||||
"Scheduler: Overwrite manually selected subtitles when better found": "Hintergrundaufgaben: Manuell ausgewählte Untertitel überschreiben, wenn bessere gefunden wurden",
|
||||
"Scheduler: Overwrite subtitles with non-default subtitle modifications when better found": "Hintergrundaufgaben: Untertitel mit Nicht-Standard-Modifikationen überschreiben, wenn bessere gefunden wurden",
|
||||
"History: amount of items to store historical data for": "Verlauf: Anzahl der Elemente",
|
||||
"How many download tries per subtitle (on timeout or error)": "Wie oft soll der Download pro Untertitel versucht werden (bei Fehlern)",
|
||||
"Ignore folders (with \"subzero.ignore/.subzero.ignore/.nosz\" files in them)": "Ignoriere Ordner mit \"subzero.ignore/.subzero.ignore/.nosz\"-Dateien",
|
||||
"Ignore anything in the following paths (comma-separated)": "Ignoriere folgende Pfade",
|
||||
"Sub-Zero mode": "Sub-Zero Modus",
|
||||
"Access PIN (any amount of numbers, 0-9)": "Zugriffs-PIN (beliebige Anzahl Zahlen, 0-9)",
|
||||
"Access PIN valid for minutes": "Zugriffs-PIN gültig für Minuten",
|
||||
"Use PIN to restrict access to (needs plugin or PMS restart)": "Benutze PIN um den Zugriff einzuschränken für (benötigt Plugin- oder PMS-Neustart)",
|
||||
"Call this executable upon successful subtitle download (see Wiki for details)": "Diese ausführbare Datei nach erfolgreichem Untertitel-Download aufrufen (siehe Wiki für Details)",
|
||||
"Check for correct folder permissions of every library on plugin start": "Korrekte Ordnerberechtigungen bei jedem Plugin-Start überprüfen",
|
||||
"Use new style caching (for subliminal)": "Modernes Caching benutzen (für subliminal)",
|
||||
"Low impact mode (for remote filesystems)": "Belastungsarmer Modus (für rechnerferne Dateisysteme)",
|
||||
"Timeout for API requests sent to the PMS": "Timeout für Plex-API-Anfragen",
|
||||
"HTTP proxy to use for providers (supports credentials)": "Benutze HTTP-Proxy für Untertitel-Anbieter (unterstützt Anmeldeinformationen)",
|
||||
"How verbose should the logging be?": "Wie ausführlich soll die Protokollierung sein?",
|
||||
"How many log backups to keep?": "Wie viele Protokoll-Sicherungen sollen behalten werden?",
|
||||
"Log subtitle modification (debug)": "Untertitelmodifikationen protokollieren (debug)",
|
||||
"Log to console (for development/debugging)": "Protokollausgabe in der Konsole (für Entwicklung/Debugging)",
|
||||
"Collect anonymous usage statistics": "Anonyme Nutzungsstatistiken sammeln",
|
||||
"Sonarr/Radarr (fill api info below)": "Sonarr/Radarr (API info unten ergänzen)",
|
||||
"Filebot": "Filebot",
|
||||
"Sonarr/Radarr/Filebot": "Sonarr/Radarr/Filebot",
|
||||
"Symlink to original file": "Symbolischer Link zur Originaldatei",
|
||||
"I keep the original filenames": "Ich behalte die originalen Dateinamen",
|
||||
"none of the above": "keine dieser Optionen",
|
||||
"exact: media filename match": "Exakt: Dateiname stimmt überein",
|
||||
"loose: filename contains media filename": "Locker: Untertiteldateiname enthält Mediendateiname",
|
||||
"any": "alle",
|
||||
"prefer": "bevorzugen",
|
||||
"don't prefer": "nicht bevorzugen",
|
||||
"force HI": "HI erzwingen",
|
||||
"force non-HI": "Non-HI erzwingen",
|
||||
"don't change": "nicht ändern",
|
||||
"white": "weiß",
|
||||
"light-grey": "hellgrau",
|
||||
"red": "rot",
|
||||
"green": "grün",
|
||||
"yellow": "gelb",
|
||||
"blue": "blau",
|
||||
"magenta": "Magentarot",
|
||||
"cyan": "türkis",
|
||||
"black": "schwarz",
|
||||
"dark-red": "dunkelrot",
|
||||
"dark-green": "dunkelgrün",
|
||||
"dark-yellow": "ocker",
|
||||
"dark-blue": "dunkelblau",
|
||||
"dark-magenta": "dunkles Magentarot",
|
||||
"dark-cyan": "dunkles Türkis",
|
||||
"dark-grey": "dunkelgrau",
|
||||
"current folder": "aktueller Ordner",
|
||||
"never": "nie",
|
||||
"current media item": "aktuelle Mediendatei",
|
||||
"next episode (series)": "nächste Episode (Serien)",
|
||||
"hybrid: current item or next episode": "hybrid: aktuelle Mediendatei oder nächste Episode",
|
||||
"hybrid-plus: current item and next episode": "hybrid-plus: aktuelle Mediendatei und nächste Episode",
|
||||
"every 6 hours": "alle 6 Stunden",
|
||||
"every 12 hours": "alle 12 Stunden",
|
||||
"every 24 hours": "alle 24 Stunden",
|
||||
"1 days": "1 Tag",
|
||||
"2 days": "2 Tage",
|
||||
"3 days": "3 Tage",
|
||||
"4 days": "4 Tage",
|
||||
"1 weeks": "1 Woche",
|
||||
"2 weeks": "2 Wochen",
|
||||
"3 weeks": "3 Wochen",
|
||||
"4 weeks": "4 Wochen",
|
||||
"5 weeks": "5 Wochen",
|
||||
"6 weeks": "6 Wochen",
|
||||
"12 weeks": "12 Wochen",
|
||||
"don't limit": "keine Limitierung",
|
||||
"1 year": "1 Jahr",
|
||||
"2 years": "2 Jahre",
|
||||
"3 years": "3 Jahre",
|
||||
"4 years": "4 Jahre",
|
||||
"5 years": "5 Jahre",
|
||||
"6 years": "6 Jahre",
|
||||
"7 years": "7 Jahre",
|
||||
"8 years": "8 Jahre",
|
||||
"9 years": "9 Jahre",
|
||||
"10 years": "10 Jahre",
|
||||
"only agent": "nur Metadaten-Agent",
|
||||
"disabled": "deaktiviert",
|
||||
"advanced menu": "erweitertes Menü",
|
||||
"CRITICAL": "CRITICAL",
|
||||
"ERROR": "ERROR",
|
||||
"WARNING": "WARNING",
|
||||
"INFO": "INFO",
|
||||
"DEBUG": "DEBUG",
|
||||
"Force-find subtitles: %(item_title)s": "Erzwinge Suche nach Untertiteln: %(item_title)s",
|
||||
"File %(file_part_index)s: ": "Datei %(file_part_index)s: ",
|
||||
"%(part_summary)sNo current subtitle in storage": "%(part_summary)sKein aktueller Untertitel im Speicher",
|
||||
"%(part_summary)sCurrent subtitle: %(provider_name)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "%(part_summary)sAktueller Untertitel: %(provider_name)s (hinzugefügt: %(date_added)s, %(mode)s), Sprache: %(language)s, Punktzahl: %(score)i, Speicher: %(storage_type)s",
|
||||
"%(part_summary)sManage %(language)s subtitle": "%(part_summary)s%(language)s: Untertitel verwalten",
|
||||
"%(part_summary)sList %(language)s subtitles": "%(part_summary)s%(language)s: Untertitel auflisten",
|
||||
"%(part_summary)sEmbedded subtitles (%(languages)s)": "%(part_summary)sEingebettete Untertitel (%(languages)s)",
|
||||
"Select active %(language)s subtitle": "%(language)s: Aktiven Untertitel auswählen",
|
||||
"%(count)d subtitles in storage": "%(count)d Untertitel im Speicher",
|
||||
"List available %(language)s subtitles": "%(language)s: Verfügbare Untertitel auflisten",
|
||||
"Modify current %(language)s subtitle": "%(language)s: Aktiven Untertitel modifizieren",
|
||||
"Currently applied mods: %(mod_list)s": "Aktuell angewandte Modifikationen: %(mod_list)s",
|
||||
"Blacklist current %(language)s subtitle and search for a new one": "%(language)s: Aktuellen Untertitel zur Sperrliste hinzufügen und nach einem neuen suchen",
|
||||
"Manage blacklist (%(amount)s contained)": "Sperrliste verwalten (enthält %(amount)s)",
|
||||
"%(current_state)s%(subtitle_name)s, Score: %(score)s": "%(current_state)s%(subtitle_name)s, Punktzahl: %(score)s",
|
||||
"Current: ": "Aktuell: ",
|
||||
"Stored: ": "Gespeichert: ",
|
||||
"by %(release_group)s": "von %(release_group)s",
|
||||
"Current: %(provider_name)s (%(score)s) ": "Aktuell: %(provider_name)s (%(score)s) ",
|
||||
"Search for %(language)s subs (%(video_data)s)": "%(language)s: Nach Untertiteln suchen (%(video_data)s)",
|
||||
"%(current_info)sFilename: %(filename)s": "%(current_info)sDateiname: %(filename)s",
|
||||
"Searching for %(language)s subs (%(video_data)s), refresh here ...": "%(language)s: Suche nach Untertiteln (%(video_data)s), hier aktualisieren ...",
|
||||
" (wrong FPS, sub: %(subtitle_fps)s, media: %(media_fps)s)": " (falsche FPS, Untertitel: %(subtitle_fps)s, Video: %(media_fps)s)",
|
||||
" (wrong FPS, sub: %(subtitle_fps)s, media: unknown, low impact mode)": " (falsche FPS, Untertitel: %(subtitle_fps)s, Video: Unbekannt, belastungsarmer Modus aktiv)",
|
||||
"%(blacklisted_state)s%(current_state)s: %(provider_name)s, score: %(score)s%(wrong_fps_state)s": "%(blacklisted_state)s%(current_state)s: %(provider_name)s, Punktzahl: %(score)s%(wrong_fps_state)s",
|
||||
"Release: %(release_info)s, Matches: %(matches)s": "Release: %(release_info)s, Übereinstimmungen: %(matches)s",
|
||||
"Downloading subtitle for %(title_or_id)s": "Lade Untertitel für %(title_or_id)s herunter",
|
||||
"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s with default mods": "Stream mit Standard-Mods extrahieren: %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s",
|
||||
"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s": "Stream extrahieren: %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s",
|
||||
"%(provider_name)s, %(subtitle_id)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "%(provider_name)s, %(subtitle_id)s (hinzugefügt: %(date_added)s, %(mode)s), Sprache: %(language)s, Punktzahl: %(score)i, Speicher: %(storage_type)s",
|
||||
"Insufficient permissions on library %(title)s, folder: %(path)s": "Ungenügende Berechtigungen der Bibliothek %(title)s, Ordner: %(path)s",
|
||||
"Running: %(items_done)s/%(items_searching)s (%(percentage)s%%)": "Läuft: %(items_done)s/%(items_searching)s (%(percentage)s%%)",
|
||||
"Display ignore list (%(ignored_count)d)": "Ignore-Liste anzeigen (%(ignored_count)d)",
|
||||
"%(throttled_provider)s until %(until_date)s (%(reason)s)": "%(throttled_provider)s bis %(until_date)s (%(reason)s)",
|
||||
"Extracting subtitle %(stream_index)s of %(filename)s": "Extrahiere Untertitel %(stream_index)s von %(filename)s",
|
||||
"Extract missing %(language)s embedded subtitles": "%(language)s: Extrahiere fehlende, eingebettete Untertitel",
|
||||
"Extract and activate %(language)s embedded subtitles": "%(language)s: Extrahiere und aktiviere eingebettete Untertitel",
|
||||
"None": "Nichts",
|
||||
"Idle": "Inaktiv",
|
||||
"%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)": "%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)",
|
||||
"Adjust by %(time_and_unit)s": "Verschieben um %(time_and_unit)s",
|
||||
"added: %(date_added)s, %(mode)s, Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "hinzugefügt: %(date_added)s, %(mode)s, Sprache: %(language)s, Punktzahl: %(score)i, Speicher: %(storage_type)s",
|
||||
"Remove: %(mod_name)s": "%(mod_name)s entfernen",
|
||||
"%(class_name)s: Subtitle download failed (%(item_id)s)": "%(class_name)s: Herunterladen von Untertitel fehlgeschlagen (%(item_id)s)",
|
||||
"agent + interface": "Metadatenagent + Benutzeroberfläche",
|
||||
"only interface": "nur Benutzeroberfläche",
|
||||
"interface": "Benutzeroberfläche",
|
||||
"Shows the current on deck items and allows you to individually (force-) refresh their metadata/subtitles.": "Zeigt die aktuellen Medien und ermöglicht die (erzwungene) Aktualisierung derer Metadaten/Untertitel",
|
||||
"Lists items with missing subtitles. Click on \"Find recent items with missing subs\" to update list": "Zeigt Medien mit fehlenden Untertiteln. Auf \"Finde zuletzt hinzugefügte Medien mit fehlenden Untertiteln\" klicken, um die Liste zu aktualisieren",
|
||||
"Add %(kind)s %(title)s to the ignore list": "Füge %(kind)s %(title)s zur Ignore-Liste hinzu",
|
||||
"Remove %(kind)s %(title)s from the ignore list": "Entferne %(kind)s %(title)s von der Ignore-Liste",
|
||||
"%(title)s added to the ignore list": "%(title)s zur Ignore-Liste hinzugefügt",
|
||||
"%(title)s removed from the ignore list": "%(title)s von der Ignore-Liste entfernt",
|
||||
"Triggering refresh for %(title)s": "Stoße Aktualisierung an, für: %(title)s",
|
||||
"Triggering forced refresh for %(title)s": "Stoße erzwungene Aktualisieren an, für %(title)s",
|
||||
"Refresh of item %(item_id)s triggered": "Aktualisierung von %(item_id)s angestoßen",
|
||||
"Forced refresh of item %(item_id)s triggered": "Erzwungene Aktualisierung von %(item_id)s angestoßen",
|
||||
"Ignore %(kind)s \"%(title)s\"": "%(kind)s \"%(title)s\" ignorieren",
|
||||
"Un-ignore %(kind)s \"%(title)s\"": "%(kind)s \"%(title)s\" nicht mehr ignorieren",
|
||||
"Refreshing %(title)s": "Aktualisiere %(title)s",
|
||||
"Force-refreshing %(title)s": "Erzwinge Aktualisierung von %(title)s",
|
||||
"Extracts the not yet extracted embedded subtitles of all episodes for the current season with all configured default modifications": "Extrahiert die noch nicht extrahierten, eingebetteten Untertitel aller Episoden der aktuellen Staffel, mit allen konfigurierten Standard-Modifikationen",
|
||||
"Extracts embedded subtitles of all episodes for the current season with all configured default modifications": "Extrahiert eingebettete Untertitel aller Episoden der aktuellen Staffel, mit allen konfigurierten Standard-Modifikationen",
|
||||
"Refreshes %(the_movie_series_season_episode)s, possibly searching for missing and picking up new subtitles on disk": "Aktualisiert %(the_movie_series_season_episode)s, möglicherweise mit einer Suche nach fehlenden Untertiteln, sowie Auffinden von Untertiteln im Dateisystem",
|
||||
"the movie": "den Film",
|
||||
"the series": "die Serie",
|
||||
"the episode": "die Episode",
|
||||
"the season": "die Staffel",
|
||||
"Change the color of the subtitle": "Untertitel-Farben ändern",
|
||||
"Adds the requested color to every line of the subtitle. Support depends on player.": "Fügt die gewählte Farbe zu jeder Untertitelzeile hinzu. Wird nicht von jedem Abspielgerät unterstützt",
|
||||
"Basic common fixes": "Behebe häufige Probleme in Untertiteln",
|
||||
"Fix common and whitespace/punctuation issues in subtitles": "Behebe häufige und Leerraum/Zeichensetzungs-Probleme in Untertiteln",
|
||||
"Remove all style tags": "Entferne alle Textformatierungen",
|
||||
"Removes all possible style tags from the subtitle, such as font, bold, color etc.": "Entfernt alle möglichen Textformatierungen von Untertiteln, wie z. B. Schriftart, Fettschrift, Farben etc.",
|
||||
"Reverse punctuation in RTL languages": "Zeichensetzung in linksläufigen Schriften umkehren",
|
||||
"Some playback devices don't properly handle right-to-left markers for punctuation. Physically swap punctuation. Applicable to languages: hebrew": "Einige Abspielgeräte verarbeiten nötige Marker für linksläufige Schriften nicht korrekt. Invertiere die Zeichensetzung, um dies zu beheben. Anwendbar auf: hebräisch",
|
||||
"Change the FPS of the subtitle": "Ändern der Bildwiederholrate des Untertitels",
|
||||
"Re-syncs the subtitle to the framerate of the current media file.": "Synchronisiert den Untertitel zur Bildwiederholrate der Mediendatei.",
|
||||
"Remove Hearing Impaired tags": "Inhalte für Hörgeschädigte von heruntergeladenen Untertiteln entfernen",
|
||||
"Removes tags, text and characters from subtitles that are meant for hearing impaired people": "Entfernt Markierungen, Text und Zeichen von Untertiteln, die Inhalte für Hörgeschädigte enthalten",
|
||||
"Fix common OCR issues": "Häufige Texterkennungsfehler in Untertiteln beheben",
|
||||
"Fix issues that happen when a subtitle gets converted from bitmap to text through OCR": "Behebt Fehler, die auftreten, wenn ein Untertitel vom Bitmap-Format zu Text konvertiert werden (OCR).",
|
||||
"Change the timing of the subtitle": "Die zeitliche Abstimmung des Untertitels ändern",
|
||||
"Adds or substracts a certain amount of time from the whole subtitle to match your media": "Verschiebt den Untertitel um eine bestimmte Zeiteinheit",
|
||||
"Available": "Verfügbar",
|
||||
"Current": "Aktuell",
|
||||
"Custom path to advanced_settings.json": "Spezifischer Pfad zu advanced_settings.json",
|
||||
"zh-hant": "Chinesisch (traditionell)",
|
||||
"zh-hans": "Chinesisch (vereinfacht)"
|
||||
}
|
||||
Executable → Regular
+354
-1
@@ -6,6 +6,8 @@
|
||||
"bg":"Bulgarian",
|
||||
"ca":"Catalan",
|
||||
"zh":"Chinese",
|
||||
"zh-hant":"Chinese (Traditional)",
|
||||
"zh-hans":"Chinese (Simplified)",
|
||||
"hr":"Croatian",
|
||||
"cs":"Czech",
|
||||
"da":"Danish",
|
||||
@@ -45,5 +47,356 @@
|
||||
"th":"Thai",
|
||||
"tr":"Turkish",
|
||||
"uk":"Ukranian",
|
||||
"vi":"Vietnamese"
|
||||
"vi":"Vietnamese",
|
||||
"Internal stuff, pay attention!":"Internal stuff, pay attention!",
|
||||
"Advanced":"Advanced",
|
||||
"advanced":"advanced",
|
||||
"Enter PIN":"Enter PIN",
|
||||
"The owner has restricted the access to this menu. Please enter the correct pin":"The owner has restricted the access to this menu. Please enter the correct pin",
|
||||
"Restart the plugin":"Restart the plugin",
|
||||
"Get my logs (copy the appearing link and open it in your browser, please)":"Get my logs (copy the appearing link and open it in your browser, please)",
|
||||
"Copy the appearing link and open it in your browser, please":"Copy the appearing link and open it in your browser, please",
|
||||
"Trigger find better subtitles":"Trigger find better subtitles",
|
||||
"Skip next find better subtitles (sets last run to now)":"Skip next find better subtitles (sets last run to now)",
|
||||
"Trigger subtitle storage maintenance":"Trigger subtitle storage maintenance",
|
||||
"Trigger subtitle storage migration (expensive)":"Trigger subtitle storage migration (expensive)",
|
||||
"Trigger cache maintenance (refiners, providers and packs/archives)":"Trigger cache maintenance (refiners, providers and packs/archives)",
|
||||
"Apply configured default subtitle mods to all (active) stored subtitles":"Apply configured default subtitle mods to all (active) stored subtitles",
|
||||
"Re-Apply mods of all stored subtitles":"Re-Apply mods of all stored subtitles",
|
||||
"Log the plugin's scheduled tasks state storage":"Log the plugin's scheduled tasks state storage",
|
||||
"Log the plugin's internal ignorelist storage":"Log the plugin's internal ignorelist storage",
|
||||
"Log the plugin's complete state storage":"Log the plugin's complete state storage",
|
||||
"Reset the plugin's scheduled tasks state storage":"Reset the plugin's scheduled tasks state storage",
|
||||
"Reset the plugin's internal ignorelist storage":"Reset the plugin's internal ignorelist storage",
|
||||
"Invalidate Sub-Zero metadata caches (subliminal)":"Invalidate Sub-Zero metadata caches (subliminal)",
|
||||
"Reset provider throttle states":"Reset provider throttle states",
|
||||
"Restarting the plugin":"Restarting the plugin",
|
||||
"Restart triggered, please wait about 5 seconds":"Restart triggered, please wait about 5 seconds",
|
||||
"Reset subtitle storage":"Reset subtitle storage",
|
||||
"Are you sure?":"Are you sure?",
|
||||
"Are you really sure?":"Are you really sure?",
|
||||
"Success":"Success",
|
||||
"Information Storage (%s) reset":"Information Storage (%s) reset",
|
||||
"Information Storage (%s) logged":"Information Storage (%s) logged",
|
||||
"FindBetterSubtitles triggered":"FindBetterSubtitles triggered",
|
||||
"FindBetterSubtitles skipped":"FindBetterSubtitles skipped",
|
||||
"SubtitleStorageMaintenance triggered":"SubtitleStorageMaintenance triggered",
|
||||
"MigrateSubtitleStorage triggered":"MigrateSubtitleStorage triggered",
|
||||
"TriggerCacheMaintenance triggered":"TriggerCacheMaintenance triggered",
|
||||
"This may take some time ...":"This may take some time ...",
|
||||
"Download Logs":"Download Logs",
|
||||
"Sorry, feature unavailable":"Sorry, feature unavailable",
|
||||
"Universal Plex token not available":"Universal Plex token not available",
|
||||
"Copy this link and open this in your browser, please":"Copy this link and open this in your browser, please",
|
||||
"Cache invalidated":"Cache invalidated",
|
||||
"Enter PIN number ":"Enter PIN number ",
|
||||
"PIN correct":"PIN correct",
|
||||
"Reset":"Reset",
|
||||
"Menu locked":"Menu locked",
|
||||
"Provider throttles reset":"Provider throttles reset",
|
||||
"Plex didn't return any information about the item, please refresh it and come back later":"Plex didn't return any information about the item, please refresh it and come back later",
|
||||
"Item not found: %s!":"Item not found: %s!",
|
||||
"< Back to %s":"< Back to %s",
|
||||
"Back to %s > %s":"Back to %s > %s",
|
||||
"Refresh: %s":"Refresh: %s",
|
||||
"Refreshes %(the_movie_series_season_episode)s, possibly searching for missing and picking up new subtitles on disk":"Refreshes %(the_movie_series_season_episode)s, possibly searching for missing and picking up new subtitles on disk",
|
||||
"the movie":"the movie",
|
||||
"the series":"the series",
|
||||
"the episode":"the episode",
|
||||
"the season":"the season",
|
||||
"Force-find subtitles: %(item_title)s":"Force-find subtitles: %(item_title)s",
|
||||
"Issues a forced refresh, ignoring known subtitles and searching for new ones":"Issues a forced refresh, ignoring known subtitles and searching for new ones",
|
||||
"File %(file_part_index)s: ":"File %(file_part_index)s: ",
|
||||
"%(part_summary)sNo current subtitle in storage":"%(part_summary)sNo current subtitle in storage",
|
||||
"%(part_summary)sCurrent subtitle: %(provider_name)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s":"%(part_summary)sCurrent subtitle: %(provider_name)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s",
|
||||
"%(part_summary)sManage %(language)s subtitle":"%(part_summary)sManage %(language)s subtitle",
|
||||
"%(part_summary)sList %(language)s subtitles":"%(part_summary)sList %(language)s subtitles",
|
||||
"%(part_summary)sEmbedded subtitles (%(languages)s)":"%(part_summary)sEmbedded subtitles (%(languages)s)",
|
||||
"Extract and activate embedded subtitle streams":"Extract and activate embedded subtitle streams",
|
||||
"Select active %(language)s subtitle":"Select active %(language)s subtitle",
|
||||
"%(count)d subtitles in storage":"%(count)d subtitles in storage",
|
||||
"List available %(language)s subtitles":"List available %(language)s subtitles",
|
||||
"Modify current %(language)s subtitle":"Modify current %(language)s subtitle",
|
||||
"Currently applied mods: %(mod_list)s":"Currently applied mods: %(mod_list)s",
|
||||
"Blacklist current %(language)s subtitle and search for a new one":"Blacklist current %(language)s subtitle and search for a new one",
|
||||
"Manage blacklist (%(amount)s contained)":"Manage blacklist (%(amount)s contained)",
|
||||
"Inspect currently blacklisted subtitles":"Inspect currently blacklisted subtitles",
|
||||
"%(current_state)s%(subtitle_name)s, Score: %(score)s":"%(current_state)s%(subtitle_name)s, Score: %(score)s",
|
||||
"Current: ":"Current: ",
|
||||
"Stored: ":"Stored: ",
|
||||
"Subtitle saved to disk":"Subtitle saved to disk",
|
||||
"Remove subtitle from blacklist":"Remove subtitle from blacklist",
|
||||
"by %(release_group)s":"by %(release_group)s",
|
||||
"Current: %(provider_name)s (%(score)s) ":"Current: %(provider_name)s (%(score)s) ",
|
||||
"Search for %(language)s subs (%(video_data)s)":"Search for %(language)s subs (%(video_data)s)",
|
||||
"%(current_info)sFilename: %(filename)s":"%(current_info)sFilename: %(filename)s",
|
||||
"No subtitles found":"No subtitles found",
|
||||
"Searching for %(language)s subs (%(video_data)s), refresh here ...":"Searching for %(language)s subs (%(video_data)s), refresh here ...",
|
||||
" (wrong FPS, sub: %(subtitle_fps)s, media: %(media_fps)s)":" (wrong FPS, sub: %(subtitle_fps)s, media: %(media_fps)s)",
|
||||
" (wrong FPS, sub: %(subtitle_fps)s, media: unknown, low impact mode)":" (wrong FPS, sub: %(subtitle_fps)s, media: unknown, low impact mode)",
|
||||
"%(blacklisted_state)s%(current_state)s: %(provider_name)s, score: %(score)s%(wrong_fps_state)s":"%(blacklisted_state)s%(current_state)s: %(provider_name)s, score: %(score)s%(wrong_fps_state)s",
|
||||
"Release: %(release_info)s, Matches: %(matches)s":"Release: %(release_info)s, Matches: %(matches)s",
|
||||
"Downloading subtitle for %(title_or_id)s":"Downloading subtitle for %(title_or_id)s",
|
||||
"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s with default mods":"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s with default mods",
|
||||
" (unknown)":" (unknown)",
|
||||
" (forced)":" (forced)",
|
||||
"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s":"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s",
|
||||
"Extracting of embedded subtitle %s of part %s:%s triggered":"Extracting of embedded subtitle %s of part %s:%s triggered",
|
||||
"%(provider_name)s, %(subtitle_id)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s":"%(provider_name)s, %(subtitle_id)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s",
|
||||
"Insufficient permissions":"Insufficient permissions",
|
||||
"Insufficient permissions on library %(title)s, folder: %(path)s":"Insufficient permissions on library %(title)s, folder: %(path)s",
|
||||
"I'm not enabled!":"I'm not enabled!",
|
||||
"Please enable me for some of your libraries in your server settings; currently I do nothing":"Please enable me for some of your libraries in your server settings; currently I do nothing",
|
||||
"Working ... refresh here":"Working ... refresh here",
|
||||
"Current state: %s; Last state: %s":"Current state: %s; Last state: %s",
|
||||
"On-deck items":"On-deck items",
|
||||
"Shows the current on deck items and allows you to individually (force-) refresh their metadata/subtitles.":"Shows the current on deck items and allows you to individually (force-) refresh their metadata/subtitles.",
|
||||
"Shows the %s recently played items and allows you to individually (force-) refresh their metadata/subtitles.":"Shows the %s recently played items and allows you to individually (force-) refresh their metadata/subtitles.",
|
||||
"Recently-added items":"Recently-added items",
|
||||
"Recently played items":"Recently played items",
|
||||
"Shows the recently added items per section.":"Shows the recently added items per section.",
|
||||
"Show recently added items with missing subtitles":"Show recently added items with missing subtitles",
|
||||
"Lists items with missing subtitles. Click on \"Find recent items with missing subs\" to update list":"Lists items with missing subtitles. Click on \"Find recent items with missing subs\" to update list",
|
||||
"Browse all items":"Browse all items",
|
||||
"Go through your whole library and manage your ignore list. You can also (force-) refresh the metadata/subtitles of individual items.":"Go through your whole library and manage your ignore list. You can also (force-) refresh the metadata/subtitles of individual items.",
|
||||
"Running: %(items_done)s/%(items_searching)s (%(percentage)s%%)":"Running: %(items_done)s/%(items_searching)s (%(percentage)s%%)",
|
||||
"Last run: %s; Next scheduled run: %s; Last runtime: %s":"Last run: %s; Next scheduled run: %s; Last runtime: %s",
|
||||
"Search for missing subtitles (in recently-added items, max-age: %s)":"Search for missing subtitles (in recently-added items, max-age: %s)",
|
||||
"Automatically run periodically by the scheduler, if configured. %s":"Automatically run periodically by the scheduler, if configured. %s",
|
||||
"Display ignore list (%(ignored_count)d)":"Display ignore list (%(ignored_count)d)",
|
||||
"Show the current ignore list (mainly used for the automatic tasks)":"Show the current ignore list (mainly used for the automatic tasks)",
|
||||
"History":"History",
|
||||
"Show the last %i downloaded subtitles":"Show the last %i downloaded subtitles",
|
||||
"Refresh":"Refresh",
|
||||
"Re-lock menu(s)":"Re-lock menu(s)",
|
||||
"Enabled the PIN again for menu(s)":"Enabled the PIN again for menu(s)",
|
||||
"%(throttled_provider)s until %(until_date)s (%(reason)s)":"%(throttled_provider)s until %(until_date)s (%(reason)s)",
|
||||
"Throttled providers: %s":"Throttled providers: %s",
|
||||
"Advanced functions":"Advanced functions",
|
||||
"Use at your own risk":"Use at your own risk",
|
||||
"Items On Deck":"Items On Deck",
|
||||
"Recently Played":"Recently Played",
|
||||
"Items with missing subtitles":"Items with missing subtitles",
|
||||
"Find recent items with missing subtitles":"Find recent items with missing subtitles",
|
||||
"Updating, refresh here ...":"Updating, refresh here ...",
|
||||
"Missing: %s":"Missing: %s",
|
||||
"Add %(kind)s %(title)s to the ignore list":"Add %(kind)s %(title)s to the ignore list",
|
||||
"Remove %(kind)s %(title)s from the ignore list":"Remove %(kind)s %(title)s from the ignore list",
|
||||
"Didn't change the ignore list":"Didn't change the ignore list",
|
||||
"%(title)s added to the ignore list":"%(title)s added to the ignore list",
|
||||
"%(title)s removed from the ignore list":"%(title)s removed from the ignore list",
|
||||
"Sections":"Sections",
|
||||
"All":"All",
|
||||
"Ignore %(kind)s \"%(title)s\"":"Ignore %(kind)s \"%(title)s\"",
|
||||
"Un-ignore %(kind)s \"%(title)s\"":"Un-ignore %(kind)s \"%(title)s\"",
|
||||
"show":"show",
|
||||
"movie":"movie",
|
||||
"Refreshing %(title)s":"Refreshing %(title)s",
|
||||
"Force-refreshing %(title)s":"Force-refreshing %(title)s",
|
||||
"Extracting subtitle %(stream_index)s of %(filename)s":"Extracting subtitle %(stream_index)s of %(filename)s",
|
||||
"<< Back to home":"<< Back to home",
|
||||
"Extract missing %(language)s embedded subtitles":"Extract missing %(language)s embedded subtitles",
|
||||
"Extracts the not yet extracted embedded subtitles of all episodes for the current season with all configured default modifications":"Extracts the not yet extracted embedded subtitles of all episodes for the current season with all configured default modifications",
|
||||
"Extract and activate %(language)s embedded subtitles":"Extract and activate %(language)s embedded subtitles",
|
||||
"Extracts embedded subtitles of all episodes for the current season with all configured default modifications":"Extracts embedded subtitles of all episodes for the current season with all configured default modifications",
|
||||
"Auto-Find subtitles: %s":"Auto-Find subtitles: %s",
|
||||
"Extracting of embedded subtitles for %s triggered":"Extracting of embedded subtitles for %s triggered",
|
||||
"Triggering refresh for %(title)s":"Triggering refresh for %(title)s",
|
||||
"Triggering forced refresh for %(title)s":"Triggering forced refresh for %(title)s",
|
||||
"Refresh of item %(item_id)s triggered":"Refresh of item %(item_id)s triggered",
|
||||
"Forced refresh of item %(item_id)s triggered":"Forced refresh of item %(item_id)s triggered",
|
||||
"< Back to subtitle options for: %s":"< Back to subtitle options for: %s",
|
||||
"Remove last applied mod (%s)":"Remove last applied mod (%s)",
|
||||
"none":"none",
|
||||
"None":"None",
|
||||
"Idle":"Idle",
|
||||
"Manage applied mods":"Manage applied mods",
|
||||
"Reapply applied mods":"Reapply applied mods",
|
||||
"Restore original version":"Restore original version",
|
||||
"< Back to subtitle modification menu":"< Back to subtitle modification menu",
|
||||
"subs constantly getting faster":"subs constantly getting faster",
|
||||
"subs constantly getting slower":"subs constantly getting slower",
|
||||
"%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)":"%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)",
|
||||
"< Back to subtitle modifications":"< Back to subtitle modifications",
|
||||
"Adjust by %(time_and_unit)s":"Adjust by %(time_and_unit)s",
|
||||
"< Back to unit selection":"< Back to unit selection",
|
||||
"added: %(date_added)s, %(mode)s, Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s":"added: %(date_added)s, %(mode)s, Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s",
|
||||
"Remove: %(mod_name)s":"Remove: %(mod_name)s",
|
||||
"%(class_name)s: Subtitle download failed (%(item_id)s)": "%(class_name)s: Subtitle download failed (%(item_id)s)",
|
||||
"Subtitle Language (1)":"Subtitle Language (1)",
|
||||
"Subtitle Language (2)":"Subtitle Language (2)",
|
||||
"Subtitle Language (3)":"Subtitle Language (3)",
|
||||
"Additional Subtitle Languages (use ISO-639-1 codes; comma-separated)":"Additional Subtitle Languages (use ISO-639-1 codes; comma-separated)",
|
||||
"Only download foreign/forced subtitles":"Only download foreign/forced subtitles",
|
||||
"Display languages with country attribute as ISO 639-1 (e.g. pt-BR = pt)":"Display languages with country attribute as ISO 639-1 (e.g. pt-BR = pt)",
|
||||
"Treat languages with country attribute as ISO 639-1 (e.g. don't download pt-BR if pt subtitle exists)":"Treat languages with country attribute as ISO 639-1 (e.g. don't download pt-BR if pt subtitle exists)",
|
||||
"Restrict to one language (skips adding \".lang.\" to the subtitle filename; only uses \"Subtitle Language (1)\")":"Restrict to one language (skips adding \".lang.\" to the subtitle filename; only uses \"Subtitle Language (1)\")",
|
||||
"Embedded subtitles: Treat \"Undefined\" (und) as language 1":"Embedded subtitles: Treat \"Undefined\" (und) as language 1",
|
||||
"I rename my files using":"I rename my files using",
|
||||
"Retrieve original filename from .file_info/file_info index files (see wiki)":"Retrieve original filename from .file_info/file_info index files (see wiki)",
|
||||
"Sonarr URL (add URL base if configured)":"Sonarr URL (add URL base if configured)",
|
||||
"Sonarr API key":"Sonarr API key",
|
||||
"Radarr URL (add URL base if configured, min. version: 0.2.0.897)":"Radarr URL (add URL base if configured, min. version: 0.2.0.897)",
|
||||
"Radarr API key":"Radarr API key",
|
||||
"Provider: Enable OpenSubtitles":"Provider: Enable OpenSubtitles",
|
||||
"Opensubtitles Username":"Opensubtitles Username",
|
||||
"Opensubtitles Password":"Opensubtitles Password",
|
||||
"OpenSubtitles VIP? (ad-free subs, 1000 subs/day, no-cache VIP server: http://v.ht/osvip)":"OpenSubtitles VIP? (ad-free subs, 1000 subs/day, no-cache VIP server: http://v.ht/osvip)",
|
||||
"Provider: Enable Podnapisi.NET":"Provider: Enable Podnapisi.NET",
|
||||
"Provider: Enable Titlovi.com":"Provider: Enable Titlovi.com",
|
||||
"Provider: Enable Addic7ed":"Provider: Enable Addic7ed",
|
||||
"Addic7ed Username":"Addic7ed Username",
|
||||
"Addic7ed Password":"Addic7ed Password",
|
||||
"Addic7ed: boost score (if requirements met)":"Addic7ed: boost score (if requirements met)",
|
||||
"Addic7ed: Use random user agents":"Addic7ed: Use random user agents",
|
||||
"Provider: Enable Legendas TV (mostly pt-BR; UNRAR NEEDED)":"Provider: Enable Legendas TV (mostly pt-BR; UNRAR NEEDED)",
|
||||
"Legendas TV Username":"Legendas TV Username",
|
||||
"Legendas TV Password":"Legendas TV Password",
|
||||
"Provider: Enable TVsubtitles.net":"Provider: Enable TVsubtitles.net",
|
||||
"Provider: Enable NapiProjekt.pl (Polish)":"Provider: Enable NapiProjekt.pl (Polish)",
|
||||
"Provider: Enable SubScene (TV shows)":"Provider: Enable SubScene (TV shows)",
|
||||
"Provider: Enable hosszupuskasub.com (Hungarian)":"Provider: Enable hosszupuskasub.com (Hungarian)",
|
||||
"Provider: Enable aRGENTeaM (Spanish)":"Provider: Enable aRGENTeaM (Spanish)",
|
||||
"Search enabled providers simultaneously (multithreading)":"Search enabled providers simultaneously (multithreading)",
|
||||
"Automatically extract and use embedded subtitles upon media addition (with configured default mods)":"Automatically extract and use embedded subtitles upon media addition (with configured default mods)",
|
||||
"After automatic extraction of embedded subtitles, also immediately search for available subtitles?":"After automatic extraction of embedded subtitles, also immediately search for available subtitles?",
|
||||
"Don't search for subtitles of a language if there are embedded subtitles inside the media file (MKV/MP4)?":"Don't search for subtitles of a language if there are embedded subtitles inside the media file (MKV/MP4)?",
|
||||
"Don't search for subtitles of a language if they already exist on the filesystem (metadata/filesystem)?":"Don't search for subtitles of a language if they already exist on the filesystem (metadata/filesystem)?",
|
||||
"How strict should these subtitles existing on the filesystem be detected?":"How strict should these subtitles existing on the filesystem be detected?",
|
||||
"Include non-text subtitle formats (anything else than .srt/.ssa/.ass/.vtt; embedded or external) in the above?":"Include non-text subtitle formats (anything else than .srt/.ssa/.ass/.vtt; embedded or external) in the above?",
|
||||
"Minimum score for TV (min: 240, def/sane: 337, min-ideal: 352; see http://v.ht/szscores)":"Minimum score for TV (min: 240, def/sane: 337, min-ideal: 352; see http://v.ht/szscores)",
|
||||
"Minimum score for movies (min: 60, def/sane: 69, min-ideal: 82; see http://v.ht/szscores)":"Minimum score for movies (min: 60, def/sane: 69, min-ideal: 82; see http://v.ht/szscores)",
|
||||
"Download hearing impaired subtitles.":"Download hearing impaired subtitles.",
|
||||
"Remove Hearing Impaired tags from downloaded subtitles":"Remove Hearing Impaired tags from downloaded subtitles",
|
||||
"Remove style tags from downloaded subtitles (bold, italic, underline, colors, ...)":"Remove style tags from downloaded subtitles (bold, italic, underline, colors, ...)",
|
||||
"Fix common issues in subtitles":"Fix common issues in subtitles",
|
||||
"Fix common OCR errors in downloaded subtitles":"Fix common OCR errors in downloaded subtitles",
|
||||
"Reverse punctuation in RTL languages (heb)":"Reverse punctuation in RTL languages (heb)",
|
||||
"Change colors of subtitles to":"Change colors of subtitles to",
|
||||
"Store subtitles next to media files (instead of metadata)":"Store subtitles next to media files (instead of metadata)",
|
||||
"Subtitle formats to save (non-SRT only works if the previous option is enabled)":"Subtitle formats to save (non-SRT only works if the previous option is enabled)",
|
||||
"Subtitle Folder (\"current folder\" is the folder the current media file lives in)":"Subtitle Folder (\"current folder\" is the folder the current media file lives in)",
|
||||
"Custom Subtitle folder (overrides \"Subtitle Folder\"; computes to real paths)":"Custom Subtitle folder (overrides \"Subtitle Folder\"; computes to real paths)",
|
||||
"Fall back to metadata storage if filesystem storage failed":"Fall back to metadata storage if filesystem storage failed",
|
||||
"Set subtitle file permissions to (integer, e.g.: 0775)":"Set subtitle file permissions to (integer, e.g.: 0775)",
|
||||
"Automatically delete leftover/unused (externally saved) subtitles":"Automatically delete leftover/unused (externally saved) subtitles",
|
||||
"On media playback: search for missing subtitles (refresh item)":"On media playback: search for missing subtitles (refresh item)",
|
||||
"Scheduler: Periodically search for recent items with missing subtitles":"Scheduler: Periodically search for recent items with missing subtitles",
|
||||
"Scheduler: Item age to be considered recent":"Scheduler: Item age to be considered recent",
|
||||
"Scheduler: Recent items to consider per library":"Scheduler: Recent items to consider per library",
|
||||
"Scheduler: Periodically search for better subtitles":"Scheduler: Periodically search for better subtitles",
|
||||
"Scheduler: Days to search for better subtitles (max: 30 days)":"Scheduler: Days to search for better subtitles (max: 30 days)",
|
||||
"Scheduler: Don't search for better subtitles if the item's air date is older than":"Scheduler: Don't search for better subtitles if the item's air date is older than",
|
||||
"Scheduler: Overwrite manually selected subtitles when better found":"Scheduler: Overwrite manually selected subtitles when better found",
|
||||
"Scheduler: Overwrite subtitles with non-default subtitle modifications when better found":"Scheduler: Overwrite subtitles with non-default subtitle modifications when better found",
|
||||
"History: amount of items to store historical data for":"History: amount of items to store historical data for",
|
||||
"How many download tries per subtitle (on timeout or error)":"How many download tries per subtitle (on timeout or error)",
|
||||
"Ignore folders (with \"subzero.ignore/.subzero.ignore/.nosz\" files in them)":"Ignore folders (with \"subzero.ignore/.subzero.ignore/.nosz\" files in them)",
|
||||
"Ignore anything in the following paths (comma-separated)":"Ignore anything in the following paths (comma-separated)",
|
||||
"Sub-Zero mode":"Sub-Zero mode",
|
||||
"Access PIN (any amount of numbers, 0-9)":"Access PIN (any amount of numbers, 0-9)",
|
||||
"Access PIN valid for minutes":"Access PIN valid for minutes",
|
||||
"Use PIN to restrict access to (needs plugin or PMS restart)":"Use PIN to restrict access to (needs plugin or PMS restart)",
|
||||
"Call this executable upon successful subtitle download (see Wiki for details)":"Call this executable upon successful subtitle download (see Wiki for details)",
|
||||
"Check for correct folder permissions of every library on plugin start":"Check for correct folder permissions of every library on plugin start",
|
||||
"Use new style caching (for subliminal)":"Use new style caching (for subliminal)",
|
||||
"Low impact mode (for remote filesystems)":"Low impact mode (for remote filesystems)",
|
||||
"Timeout for API requests sent to the PMS":"Timeout for API requests sent to the PMS",
|
||||
"HTTP proxy to use for providers (supports credentials)":"HTTP proxy to use for providers (supports credentials)",
|
||||
"How verbose should the logging be?":"How verbose should the logging be?",
|
||||
"How many log backups to keep?":"How many log backups to keep?",
|
||||
"Log subtitle modification (debug)":"Log subtitle modification (debug)",
|
||||
"Log to console (for development/debugging)":"Log to console (for development/debugging)",
|
||||
"Collect anonymous usage statistics":"Collect anonymous usage statistics",
|
||||
"Sonarr/Radarr (fill api info below)":"Sonarr/Radarr (fill api info below)",
|
||||
"Filebot":"Filebot",
|
||||
"Sonarr/Radarr/Filebot":"Sonarr/Radarr/Filebot",
|
||||
"Symlink to original file":"Symlink to original file",
|
||||
"I keep the original filenames":"I keep the original filenames",
|
||||
"none of the above":"none of the above",
|
||||
"exact: media filename match":"exact: media filename match",
|
||||
"loose: filename contains media filename":"loose: filename contains media filename",
|
||||
"any":"any",
|
||||
"prefer":"prefer",
|
||||
"don't prefer":"don't prefer",
|
||||
"force HI":"force HI",
|
||||
"force non-HI":"force non-HI",
|
||||
"don't change":"don't change",
|
||||
"white":"white",
|
||||
"light-grey":"light-grey",
|
||||
"red":"red",
|
||||
"green":"green",
|
||||
"yellow":"yellow",
|
||||
"blue":"blue",
|
||||
"magenta":"magenta",
|
||||
"cyan":"cyan",
|
||||
"black":"black",
|
||||
"dark-red":"dark-red",
|
||||
"dark-green":"dark-green",
|
||||
"dark-yellow":"dark-yellow",
|
||||
"dark-blue":"dark-blue",
|
||||
"dark-magenta":"dark-magenta",
|
||||
"dark-cyan":"dark-cyan",
|
||||
"dark-grey":"dark-grey",
|
||||
"current folder":"current folder",
|
||||
"never":"never",
|
||||
"current media item":"current media item",
|
||||
"next episode (series)":"next episode (series)",
|
||||
"hybrid: current item or next episode":"hybrid: current item or next episode",
|
||||
"hybrid-plus: current item and next episode":"hybrid-plus: current item and next episode",
|
||||
"every 6 hours":"every 6 hours",
|
||||
"every 12 hours":"every 12 hours",
|
||||
"every 24 hours":"every 24 hours",
|
||||
"1 days":"1 days",
|
||||
"2 days":"2 days",
|
||||
"3 days":"3 days",
|
||||
"4 days":"4 days",
|
||||
"1 weeks":"1 weeks",
|
||||
"2 weeks":"2 weeks",
|
||||
"3 weeks":"3 weeks",
|
||||
"4 weeks":"4 weeks",
|
||||
"5 weeks":"5 weeks",
|
||||
"6 weeks":"6 weeks",
|
||||
"12 weeks":"12 weeks",
|
||||
"don't limit":"don't limit",
|
||||
"1 year":"1 year",
|
||||
"2 years":"2 years",
|
||||
"3 years":"3 years",
|
||||
"4 years":"4 years",
|
||||
"5 years":"5 years",
|
||||
"6 years":"6 years",
|
||||
"7 years":"7 years",
|
||||
"8 years":"8 years",
|
||||
"9 years":"9 years",
|
||||
"10 years":"10 years",
|
||||
"agent + interface":"agent + interface",
|
||||
"only agent":"only agent",
|
||||
"only interface":"only interface",
|
||||
"disabled":"disabled",
|
||||
"interface":"interface",
|
||||
"advanced menu":"advanced menu",
|
||||
"CRITICAL":"CRITICAL",
|
||||
"ERROR":"ERROR",
|
||||
"WARNING":"WARNING",
|
||||
"INFO":"INFO",
|
||||
"DEBUG":"DEBUG",
|
||||
"Change the color of the subtitle":"Change the color of the subtitle",
|
||||
"Adds the requested color to every line of the subtitle. Support depends on player.":"Adds the requested color to every line of the subtitle. Support depends on player.",
|
||||
"Basic common fixes":"Basic common fixes",
|
||||
"Fix common and whitespace/punctuation issues in subtitles":"Fix common and whitespace/punctuation issues in subtitles",
|
||||
"Remove all style tags":"Remove all style tags",
|
||||
"Removes all possible style tags from the subtitle, such as font, bold, color etc.":"Removes all possible style tags from the subtitle, such as font, bold, color etc.",
|
||||
"Reverse punctuation in RTL languages":"Reverse punctuation in RTL languages",
|
||||
"Some playback devices don't properly handle right-to-left markers for punctuation. Physically swap punctuation. Applicable to languages: hebrew":"Some playback devices don't properly handle right-to-left markers for punctuation. Physically swap punctuation. Applicable to languages: hebrew",
|
||||
"Change the FPS of the subtitle":"Change the FPS of the subtitle",
|
||||
"Re-syncs the subtitle to the framerate of the current media file.":"Re-syncs the subtitle to the framerate of the current media file.",
|
||||
"Remove Hearing Impaired tags":"Remove Hearing Impaired tags",
|
||||
"Removes tags, text and characters from subtitles that are meant for hearing impaired people":"Removes tags, text and characters from subtitles that are meant for hearing impaired people",
|
||||
"Fix common OCR issues":"Fix common OCR issues",
|
||||
"Fix issues that happen when a subtitle gets converted from bitmap to text through OCR":"Fix issues that happen when a subtitle gets converted from bitmap to text through OCR",
|
||||
"Change the timing of the subtitle":"Change the timing of the subtitle",
|
||||
"Adds or substracts a certain amount of time from the whole subtitle to match your media":"Adds or substracts a certain amount of time from the whole subtitle to match your media",
|
||||
"Available":"Available",
|
||||
"Current":"Current",
|
||||
"Custom path to advanced_settings.json":"Custom path to advanced_settings.json"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,400 @@
|
||||
{
|
||||
"sq": "Albanés",
|
||||
"ar": "Árabe",
|
||||
"be": "Bieloruso",
|
||||
"bs": "Bosnio",
|
||||
"bg": "Búlgaro",
|
||||
"ca": "Catalán",
|
||||
"zh": "Chino",
|
||||
"hr": "Croata",
|
||||
"cs": "Checo",
|
||||
"da": "Danés",
|
||||
"nl": "Neerlandés",
|
||||
"en": "Inglés",
|
||||
"et": "Estonio",
|
||||
"fa": "Persa",
|
||||
"fi": "Finés",
|
||||
"fr": "Francés",
|
||||
"de": "Alemán",
|
||||
"el": "Griego",
|
||||
"he": "Hebreo",
|
||||
"hi": "Hindi",
|
||||
"hu": "Húngaro",
|
||||
"is": "Islandés",
|
||||
"id": "Indonesio",
|
||||
"it": "Italiano",
|
||||
"ja": "Japonés",
|
||||
"ko": "Coreano",
|
||||
"lv": "Letonio",
|
||||
"lt": "Lituano",
|
||||
"mk": "Macedonio",
|
||||
"ms": "Malayo",
|
||||
"no": "Noruego",
|
||||
"pl": "Polaco",
|
||||
"pt": "Portugués",
|
||||
"pt-br": "Portugués (Brasil)",
|
||||
"ro": "Rumano",
|
||||
"ru": "Ruso",
|
||||
"sr": "Serbio",
|
||||
"sr-cyrl": "Serbio (Cirílico)",
|
||||
"sr-latn": "Serbio (Latín)",
|
||||
"sk": "Eslovaco",
|
||||
"sl": "Slovaco",
|
||||
"es": "Español",
|
||||
"sv": "Sueco",
|
||||
"th": "Tailandés",
|
||||
"tr": "Turco",
|
||||
"uk": "Ucraniano",
|
||||
"vi": "Vietnamita",
|
||||
"Internal stuff, pay attention!": "Asunto interno, ¡prestar atención!",
|
||||
"Advanced": "Avanzado",
|
||||
"advanced": "avanzado",
|
||||
"Enter PIN": "Ingresar PIN",
|
||||
"The owner has restricted the access to this menu. Please enter the correct pin": "El dueño ha restringido el acceso a este menú. Por favor ingrese el PIN adecuado",
|
||||
"Restart the plugin": "Reiniciar el plugin",
|
||||
"Get my logs (copy the appearing link and open it in your browser, please)": "Obtener mis bitácoras (copia el enlace que aparece y ábrelo en tu navegador, por favor)",
|
||||
"Copy the appearing link and open it in your browser, please": "Copia el enlace que aparece y ábrelo en tu navegador, por favor",
|
||||
"Trigger find better subtitles": "Provocar búsqueda de Mejores Subtítulos",
|
||||
"Skip next find better subtitles (sets last run to now)": "Evitar la próxima búsqueda de Mejores Subtítulos (fija a Ahora la última búsqueda)",
|
||||
"Trigger subtitle storage maintenance": "Provocar el mantenimiento del almacenamiento de subtítulos",
|
||||
"Trigger subtitle storage migration (expensive)": "Provocar la migración del almacenamiento de subtítulos (lento)",
|
||||
"Trigger cache maintenance (refiners, providers and packs/archives)": "Provocar el mantenimiento de la caché (refinadores, proveedores y paquetes)",
|
||||
"Apply configured default subtitle mods to all (active) stored subtitles": "Aplicar las modificaciones de la configuración de subtítulos a todos los almacenados y activos",
|
||||
"Re-Apply mods of all stored subtitles": "Reaplicar modificaciones a todos los subtítulos almacenados",
|
||||
"Log the plugin's scheduled tasks state storage": "Anotar en el log las tareas de las descargar programadas del plugin",
|
||||
"Log the plugin's internal ignorelist storage": "Anotar en el log la lista a ignorar en las descargas",
|
||||
"Log the plugin's complete state storage": "Anotar en el log el estado completo de las descargas",
|
||||
"Reset the plugin's scheduled tasks state storage": "Reiniciar el plugin de descargas programadas",
|
||||
"Reset the plugin's internal ignorelist storage": "Reiniciar el plugin de la lista a ignorar en las descargas",
|
||||
"Invalidate Sub-Zero metadata caches (subliminal)": "Invalidar el caché de metadata Sub-Zero (subliminal)",
|
||||
"Reset provider throttle states": "Reiniciar estado en proveedores ralentizados",
|
||||
"Restarting the plugin": "Reiniciar el plugin",
|
||||
"Restart triggered, please wait about 5 seconds": "Reinicio provocado, por favor espere 5 segundos",
|
||||
"Reset subtitle storage": "Limpiar carpeta de almacenamiento de subtítulos",
|
||||
"Are you sure?": "¿Estás seguro?",
|
||||
"Are you really sure?": "¿Estás realmente seguro?",
|
||||
"Success": "Éxito",
|
||||
"FindBetterSubtitles triggered": "Buscar Mejores Subtítulos provocado",
|
||||
"FindBetterSubtitles skipped": "Buscar Mejores Subtítulos evitado",
|
||||
"SubtitleStorageMaintenance triggered": "Mantenimiento del almacenamiento de subtítulos provocado",
|
||||
"MigrateSubtitleStorage triggered": "Migración del almacenamiento de subtítulos provocada",
|
||||
"TriggerCacheMaintenance triggered": "Mantenimiento de la caché provocado",
|
||||
"This may take some time ...": "Esto podría tomar algún tiempo...",
|
||||
"Download Logs": "Descargar logs",
|
||||
"Sorry, feature unavailable": "Lo sentimos, característica no disponible",
|
||||
"Universal Plex token not available": "Token universal Plex no disponible",
|
||||
"Copy this link and open this in your browser, please": "Copia este enlace y ábrelo en tu navegador, por favor",
|
||||
"Cache invalidated": "Caché invalidado",
|
||||
"Enter PIN number ": "Ingrese número PIN␣",
|
||||
"PIN correct": "PIN correcto",
|
||||
"Reset": "Resetear",
|
||||
"Menu locked": "Menú bloqueado",
|
||||
"Provider throttles reset": "Reiniciar proveedores ralentizados",
|
||||
"Information Storage (%s) reset": "Almacén de Información (%s) reiniciado",
|
||||
"Information Storage (%s) logged": "Almacén de Información (%s) logueado",
|
||||
"Plex didn't return any information about the item, please refresh it and come back later": "Plex no retornó información del elemento, por favor actualice y vuelva más tarde",
|
||||
"Item not found: %s!": "¡Elemento no encontrado: %s!",
|
||||
"< Back to %s": "< Regresar a %s",
|
||||
"Back to %s > %s": "Regresar a %s > %s",
|
||||
"Refresh: %s": "Actualizar: %s",
|
||||
"Issues a forced refresh, ignoring known subtitles and searching for new ones": "Ejecuta una actualización forzada, ignorando subtítulos presentes y buscando nuevos",
|
||||
"Extract and activate embedded subtitle streams": "Extraer y activar subtítulos integrados",
|
||||
"Inspect currently blacklisted subtitles": "Inspeccionar la actual lista de bloqueados",
|
||||
"Subtitle saved to disk": "Subtítulo guardado en disco",
|
||||
"Remove subtitle from blacklist": "Eliminar subtítulo de la lista de bloqueados",
|
||||
"No subtitles found": "No se han encontrado subtítulos",
|
||||
" (unknown)": "␣(desconocido)",
|
||||
" (forced)": "␣(forzado)",
|
||||
"Extracting of embedded subtitle %s of part %s:%s triggered": "Extracción del subtítulo integrado %s de la parte %s:%s lanzada",
|
||||
"Insufficient permissions": "Permisos insuficientes",
|
||||
"I'm not enabled!": "¡No estoy habilitado!",
|
||||
"Please enable me for some of your libraries in your server settings; currently I do nothing": "Por favor, habilítame para alguna biblioteca en tu servidor; ahora mismo no puedo hacer nada",
|
||||
"Working ... refresh here": "Trabajando... refresque aquí",
|
||||
"Current state: %s; Last state: %s": "Estado actual: %s; Último estado: %s",
|
||||
"On-deck items": "Archivos On-deck",
|
||||
"Shows the %s recently played items and allows you to individually (force-) refresh their metadata/subtitles.": "Muestra los últimos %s elementos reproducidos y permite actualizar individualmente sus metadatos y subtítulos.",
|
||||
"Recently-added items": "Elementos recién añadidos",
|
||||
"Recently played items": "Elementos recién reproducidos",
|
||||
"Shows the recently added items per section.": "Muestra los elementos recién añadidos por sección.",
|
||||
"Show recently added items with missing subtitles": "Muestra los elementos recién añadidos sin subtítulos",
|
||||
"Browse all items": "Ver todos los elementos",
|
||||
"Go through your whole library and manage your ignore list. You can also (force-) refresh the metadata/subtitles of individual items.": "Navega a través de la colección completa y gestiona la Lista de Ignorados. Puede además actualizar individualmente sus metadatos y subtítulos",
|
||||
"Last run: %s; Next scheduled run: %s; Last runtime: %s": "Última ejecución: %s; Próxima ejecución: %s; Duración de la última ejecución: %s",
|
||||
"Search for missing subtitles (in recently-added items, max-age: %s)": "Buscar subtítulos faltantes (en elementos recién añadidos, antigüedad máxima: %s)",
|
||||
"Automatically run periodically by the scheduler, if configured. %s": "Ejecuta automáticamente las tareas programadas, si están configuradas. %s",
|
||||
"Show the current ignore list (mainly used for the automatic tasks)": "Muestra la Lista de Ignorados actual (principalmente usado por tareas automáticas)",
|
||||
"History": "Historial",
|
||||
"Show the last %i downloaded subtitles": "Muestra lo últimos %i subtítulos descargados",
|
||||
"Refresh": "Actualizar",
|
||||
"Re-lock menu(s)": "Bloquear menús",
|
||||
"Enabled the PIN again for menu(s)": "Habilitado el PIN de nuevo en los menús",
|
||||
"Throttled providers: %s": "Proveedores ralentizados: %s",
|
||||
"Advanced functions": "Funciones avanzadas",
|
||||
"Use at your own risk": "Use bajo su responsabilidad",
|
||||
"Items On Deck": "Elementos On Deck",
|
||||
"Recently Played": "Recién Reproducidos",
|
||||
"Items with missing subtitles": "Elementos sin subtítulos",
|
||||
"Find recent items with missing subtitles": "Buscar elementos recientes sin subtítulos",
|
||||
"Updating, refresh here ...": "Actualizando, refresque aquí...",
|
||||
"Missing: %s": "Falta: %s",
|
||||
"Didn't change the ignore list": "La Lista de Ignorados no ha cambiado",
|
||||
"Sections": "Secciones",
|
||||
"All": "Todo",
|
||||
"show": "serie",
|
||||
"movie": "película",
|
||||
"<< Back to home": "<< Volver a Inicio",
|
||||
"Auto-Find subtitles: %s": "Auto-búsqueda de subtítulos: %s ",
|
||||
"Extracting of embedded subtitles for %s triggered": "Extracción lanzada para los subtítulos integrados de %s",
|
||||
"< Back to subtitle options for: %s": "< Regresar a las opciones de subtítulos para: %s",
|
||||
"Remove last applied mod (%s)": "Quitar la última modificación realizada (%s)",
|
||||
"none": "ninguno",
|
||||
"Manage applied mods": "Gestionar modificaciones realizadas",
|
||||
"Reapply applied mods": "Reaplicar modificaciones realizadas",
|
||||
"Restore original version": "Restaurar versión original",
|
||||
"< Back to subtitle modification menu": "< Regresar al menú de modificación de subtítulos",
|
||||
"subs constantly getting faster": "los subtítulos van más rápido constantemente",
|
||||
"subs constantly getting slower": "los subtítulos van más lento constantemente",
|
||||
"< Back to subtitle modifications": "< Regresar a las modificaciones de subtítulos",
|
||||
"< Back to unit selection": "< Regresar a la selección",
|
||||
"Subtitle Language (1)": "Idioma del Subtítulo (1)",
|
||||
"Subtitle Language (2)": "Idioma del Subtítulo (2)",
|
||||
"Subtitle Language (3)": "Idioma del Subtítulo (3)",
|
||||
"Additional Subtitle Languages (use ISO-639-1 codes; comma-separated)": "Idiomas adicionales de subtítulos (use códigos ISO-639-1 separados por comas)",
|
||||
"Only download foreign/forced subtitles": "Descargar sólo subtítulos extranjeros o forzados",
|
||||
"Display languages with country attribute as ISO 639-1 (e.g. pt-BR = pt)": "Mostar idiomas con atributos de país tipo ISO 639-1 (p. ej. pt-BR = pt)",
|
||||
"Treat languages with country attribute as ISO 639-1 (e.g. don't download pt-BR if pt subtitle exists)": "Tratar idiomas con atributos de país como ISO 639-1 (es decir, no descargar pt-BR si existe un subtítulo pt)",
|
||||
"Restrict to one language (skips adding \".lang.\" to the subtitle filename; only uses \"Subtitle Language (1)\")": "Restringir a un idioma (evita añadir \".lang\" al nombre del fichero del subtítulo; solo usa el \"Idioma del Subtítulo (1)\"",
|
||||
"Embedded subtitles: Treat \"Undefined\" (und) as language 1": "Subtítulos integrados: tratar \"Undefined\" (und) como primer idioma",
|
||||
"I rename my files using": "Renombro los archivos usando",
|
||||
"Retrieve original filename from .file_info/file_info index files (see wiki)": "Obtener el nombre original del archivo del los archivos tipo \"file_info\" (ver wiki)",
|
||||
"Sonarr URL (add URL base if configured)": "URL de Sonarr (añadir la URL base si está configurada)",
|
||||
"Sonarr API key": "Clave API de Sonarr",
|
||||
"Radarr URL (add URL base if configured, min. version: 0.2.0.897)": "URL de Radar (añadir la URL base si está configurada, versión mínima: 0.2.0.897)",
|
||||
"Radarr API key": "Clave API de Radarr",
|
||||
"Provider: Enable OpenSubtitles": "Proveedor: Habilitar OpenSubtitles",
|
||||
"Opensubtitles Username": "Usuario de OpenSubtitles",
|
||||
"Opensubtitles Password": "Contraseña de OpenSubtitles",
|
||||
"OpenSubtitles VIP? (ad-free subs, 1000 subs/day, no-cache VIP server: http://v.ht/osvip)": "¿Es usuario VIP de OpenSubtitles? (http://v.ht/osvip)",
|
||||
"Provider: Enable Podnapisi.NET": "Proveedor: Habilitar Podnapisi.net",
|
||||
"Provider: Enable Titlovi.com": "Proveedor: Habilitar Titlovi.com",
|
||||
"Provider: Enable Addic7ed": "Proveedor: Habilitar Addic7ed",
|
||||
"Addic7ed Username": "Usuario de Addic7ed",
|
||||
"Addic7ed Password": "Contraseña de Addic7ed",
|
||||
"Addic7ed: boost score (if requirements met)": "Addic7ed: puntuación incentivada si cumple los requisitos",
|
||||
"Addic7ed: Use random user agents": "Addic7ed: Usar agentes aleatorios",
|
||||
"Provider: Enable Legendas TV (mostly pt-BR; UNRAR NEEDED)": "Proveedor: Habilitar Legendas TV (sobre todo pt-BR, requiere UNRAR)",
|
||||
"Legendas TV Username": "Usuario de Legendas TV",
|
||||
"Legendas TV Password": "Contraseña de Legendas TV",
|
||||
"Provider: Enable TVsubtitles.net": "Proveedor: Habilitar TVsubtitles.net",
|
||||
"Provider: Enable NapiProjekt.pl (Polish)": "Proveedor: Habilitar NapiProjekt.pl (polaco)",
|
||||
"Provider: Enable SubScene (TV shows)": "Proveedor: Habilitar SubScene (series de tv)",
|
||||
"Provider: Enable hosszupuskasub.com (Hungarian)": "Proveedor: Habilitar hosszupuskasub.com (húngaro)",
|
||||
"Provider: Enable aRGENTeaM (Spanish)": "Proveedor: Habilitar aRGENTeaM (español)",
|
||||
"Search enabled providers simultaneously (multithreading)": "Buscar proveedores habilitados simultáneamente (multihebra)",
|
||||
"Automatically extract and use embedded subtitles upon media addition (with configured default mods)": "Extraer automáticamente y usar subtítulos integrados al añadir contenidos (con las modificaciones configuradas por defecto)",
|
||||
"After automatic extraction of embedded subtitles, also immediately search for available subtitles?": "Después de extraer automáticamente subtítulos integrados ¿buscar inmediatamente subtítulos disponibles?",
|
||||
"Don't search for subtitles of a language if there are embedded subtitles inside the media file (MKV/MP4)?": "¿No buscar subtítulos de un idioma si existen subtítulos integrados dentro del archivo (MKV/MP4)?",
|
||||
"Don't search for subtitles of a language if they already exist on the filesystem (metadata/filesystem)?": "¿No buscar subtítulos de un idioma si ya existen en el sistema de ficheros o en los metadatos?",
|
||||
"How strict should these subtitles existing on the filesystem be detected?": "¿Cómo de estricta debe ser la detección de estos subtítulos en el sistema de archivos?",
|
||||
"Include non-text subtitle formats (anything else than .srt/.ssa/.ass/.vtt; embedded or external) in the above?": "¿Incluir subtítulos que no sean tipo texto (diferentes a .srt/.ssa/.ass/.vtt; integrados o externos) en lo anterior?",
|
||||
"Minimum score for TV (min: 240, def/sane: 337, min-ideal: 352; see http://v.ht/szscores)": "Puntuación mínima para Series de TV (mínimo: 240, sano: 337, recomendable: 352; ver http://v.ht/szscores)",
|
||||
"Minimum score for movies (min: 60, def/sane: 69, min-ideal: 82; see http://v.ht/szscores)": "Puntuación mínima para Películas (mínimo: 60, sano: 69, recomendado: 82; ver \nhttp://v.ht/szscores)",
|
||||
"Download hearing impaired subtitles.": "Descargar subtítulos para sordos",
|
||||
"Remove Hearing Impaired tags from downloaded subtitles": "Eliminar etiquetas para sordos de los subtítulos descargados",
|
||||
"Remove style tags from downloaded subtitles (bold, italic, underline, colors, ...)": "Eliminar etiquetas y estilos de los subtítulos descargados (negrita, cursiva, subrayado, colores, ...)",
|
||||
"Fix common issues in subtitles": "Arreglar problemas comunes en los subtítullos",
|
||||
"Fix common OCR errors in downloaded subtitles": "Arreglar errores comunes de OCR en los subtítulos descargados",
|
||||
"Reverse punctuation in RTL languages (heb)": "Invertir puntuación en idiomas RTL (heb)",
|
||||
"Change colors of subtitles to": "Cambiar color de los subtítulos a",
|
||||
"Store subtitles next to media files (instead of metadata)": "Almacenar los subtítulos junto a los archivos de video (en lugar de en los metadatos)",
|
||||
"Subtitle formats to save (non-SRT only works if the previous option is enabled)": "Formatos de subtítulos a guardar (lo que no sean SRT sólo funcionan si la opción anterior está habilitada)",
|
||||
"Subtitle Folder (\"current folder\" is the folder the current media file lives in)": "Carpeta de subtítulos (\"carpeta actual\" es la carpeta donde los archivos de video están guardados)",
|
||||
"Custom Subtitle folder (overrides \"Subtitle Folder\"; computes to real paths)": "Carpeta de subtítulos personalizada (sustituye a la \"Carpeta de subtítulos\", calculada con las rutas reales)",
|
||||
"Fall back to metadata storage if filesystem storage failed": "Activar como segunda opción el almacenamiento en los metadatos si falla en el sistema de almacenamiento",
|
||||
"Set subtitle file permissions to (integer, e.g.: 0775)": "Fijar los permisos de los subtítulos a (nº entero, p. ej.: 0775)",
|
||||
"Automatically delete leftover/unused (externally saved) subtitles": "Borrar automáticamente los subtítulos sin uso (grabados externamente)",
|
||||
"On media playback: search for missing subtitles (refresh item)": "Al reproducir un vídeo: buscar subtítulos automáticamente",
|
||||
"Scheduler: Periodically search for recent items with missing subtitles": "Programador: Buscar subtítulos periódicamente para elementos recién añadidos que no tengan",
|
||||
"Scheduler: Item age to be considered recent": "Programador: Antigüedad del elemento para ser considerado como Reciente",
|
||||
"Scheduler: Recent items to consider per library": "Programador: Elementos recientes a considerar por biblioteca",
|
||||
"Scheduler: Periodically search for better subtitles": "Programador: Buscar periódicamente Mejores Subtítulos",
|
||||
"Scheduler: Days to search for better subtitles (max: 30 days)": "Programador: Días a buscar Mejores Subtítulos (máximo 30)",
|
||||
"Scheduler: Don't search for better subtitles if the item's air date is older than": "Programador: No buscar Mejores Subtítulos si la fecha de emisión del elemento es mayor que",
|
||||
"Scheduler: Overwrite manually selected subtitles when better found": "Programador: Sobreescribir subtítulos seleccionados manualmente cuando se encuentren Mejores Subtítulos",
|
||||
"Scheduler: Overwrite subtitles with non-default subtitle modifications when better found": "Programador: Sobreecribir subtítulos con modificaciones que no sean por defecto cuando se encuentren Mejores Subtítulos",
|
||||
"History: amount of items to store historical data for": "Historial: Cantidad de elementos de los que se guardará datos históricos",
|
||||
"How many download tries per subtitle (on timeout or error)": "¿Cuántos intentos se deben realizar por subtítulos, cuando se produzca un error o supere el tiempo de espera?",
|
||||
"Ignore folders (with \"subzero.ignore/.subzero.ignore/.nosz\" files in them)": "Ignorar carpetas (con archivos tipo \"subzero.ignore/.subzero.ignore/.nosz\" en ellas)",
|
||||
"Ignore anything in the following paths (comma-separated)": "Ignorar cualquier cosa en las siguientes rutas, separadas por comas",
|
||||
"Sub-Zero mode": "Modo Sub-Zero",
|
||||
"Access PIN (any amount of numbers, 0-9)": "PIN de acceso (cualquier cantidad de números, 0-9)",
|
||||
"Access PIN valid for minutes": "Minutos de validez para el PIN de acceso ",
|
||||
"Use PIN to restrict access to (needs plugin or PMS restart)": "Usar PIN para restringir el acceso (necesitar reinicio)",
|
||||
"Call this executable upon successful subtitle download (see Wiki for details)": "Llamar a este ejecutable tras las descarga correcta de un subtítulo (ver detalles en la Wiki)",
|
||||
"Check for correct folder permissions of every library on plugin start": "Comprobar permisos de carpeta para cada biblioteca al iniciar el plugin",
|
||||
"Use new style caching (for subliminal)": "Usar nuevo estilo de caché (para Subliminal)",
|
||||
"Low impact mode (for remote filesystems)": "Modo de bajo impacto (para sistemas de archivo remotos)",
|
||||
"Timeout for API requests sent to the PMS": "Tiempo de espera para peticiones API enviadas al PMS",
|
||||
"HTTP proxy to use for providers (supports credentials)": "Proxy HTTP a usar para proveedores (permite credenciales)",
|
||||
"How verbose should the logging be?": "¿Cómo de extenso debe ser el detalle del log?",
|
||||
"How many log backups to keep?": "¿Cuántas copias del log quiere mantener?",
|
||||
"Log subtitle modification (debug)": "Anotar en el log las modificaciones de subtítulos (en pruebas)",
|
||||
"Log to console (for development/debugging)": "Anotar log en consola (para desarrollar o depurar)",
|
||||
"Collect anonymous usage statistics": "Recolectar estadísticas anónimas de uso",
|
||||
"Sonarr/Radarr (fill api info below)": "Sonarr/Radarr (rellenar información de la API)",
|
||||
"Filebot": "Filebot",
|
||||
"Sonarr/Radarr/Filebot": "Sonarr/Radarr/Filebot",
|
||||
"Symlink to original file": "Enlace simbólico al archivo original",
|
||||
"I keep the original filenames": "Mantener los nombres de archivo originales",
|
||||
"none of the above": "ninguno de los anteriores",
|
||||
"exact: media filename match": "exacta: coincidencia por nombre de archivo del vídeo",
|
||||
"loose: filename contains media filename": "parcial: el nombre del vídeo aparece en el nombre del archivo",
|
||||
"any": "cualquiera",
|
||||
"prefer": "preferir",
|
||||
"don't prefer": "no preferir",
|
||||
"force HI": "forzar Alta",
|
||||
"force non-HI": "forzar No Alta",
|
||||
"don't change": "sin cambios",
|
||||
"white": "blanco",
|
||||
"light-grey": "gris claro",
|
||||
"red": "rojo",
|
||||
"green": "verde",
|
||||
"yellow": "amarillo",
|
||||
"blue": "azul",
|
||||
"magenta": "magenta",
|
||||
"cyan": "cyan",
|
||||
"black": "negro",
|
||||
"dark-red": "rojo-oscuro",
|
||||
"dark-green": "verde-oscuro",
|
||||
"dark-yellow": "amarillo-oscuro",
|
||||
"dark-blue": "azul-oscuro",
|
||||
"dark-magenta": "magenta-oscuro",
|
||||
"dark-cyan": "cyan-oscuro",
|
||||
"dark-grey": "gris-oscuro",
|
||||
"current folder": "carpeta actual",
|
||||
"never": "nunca",
|
||||
"current media item": "elemento multimedia actual",
|
||||
"next episode (series)": "siguiente episodio (serie)",
|
||||
"hybrid: current item or next episode": "híbrido: elemento actual o siguiente episodio",
|
||||
"hybrid-plus: current item and next episode": "híbrido-plus: elemento actual y siguiente episodio",
|
||||
"every 6 hours": "cada 6 horas",
|
||||
"every 12 hours": "cada 12 horas",
|
||||
"every 24 hours": "cada 24 horas",
|
||||
"1 days": "1 día",
|
||||
"2 days": "2 días",
|
||||
"3 days": "3 días",
|
||||
"4 days": "4 días",
|
||||
"1 weeks": "1 semana",
|
||||
"2 weeks": "2 semanas",
|
||||
"3 weeks": "3 semanas",
|
||||
"4 weeks": "4 semanas",
|
||||
"5 weeks": "5 semanas",
|
||||
"6 weeks": "6 semanas",
|
||||
"12 weeks": "12 semanas",
|
||||
"don't limit": "no limitar",
|
||||
"1 year": "1 año",
|
||||
"2 years": "2 años",
|
||||
"3 years": "3 años",
|
||||
"4 years": "4 años",
|
||||
"5 years": "5 años",
|
||||
"6 years": "5 años",
|
||||
"7 years": "7 años",
|
||||
"8 years": "8 años",
|
||||
"9 years": "9 años",
|
||||
"10 years": "10 años",
|
||||
"only agent": "sólo agente",
|
||||
"disabled": "deshabilitado",
|
||||
"advanced menu": "menú avanzado",
|
||||
"CRITICAL": "CRÍTICO",
|
||||
"ERROR": "ERROR",
|
||||
"WARNING": "ADVERTENCIA",
|
||||
"INFO": "INFO",
|
||||
"DEBUG": "DEPURACIÓN",
|
||||
"Force-find subtitles: %(item_title)s": "Forzar búsqueda de subtítulos: %(item_title)s",
|
||||
"File %(file_part_index)s: ": "Archivo %(file_part_index)s:␣",
|
||||
"%(part_summary)sNo current subtitle in storage": "%(part_summary)sNo hay un subtítulo guardado",
|
||||
"%(part_summary)sCurrent subtitle: %(provider_name)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "%(part_summary)sSubtítulos actual: %(provider_name)s (añadido: %(date_added)s, %(mode)s), Idioma: %(language)s, Puntuación: %(score)i, Almacenamiento: %(storage_type)s",
|
||||
"%(part_summary)sManage %(language)s subtitle": "%(part_summary)Gestiona subtítulos en %(language)s",
|
||||
"%(part_summary)sList %(language)s subtitles": "%(part_summary)Muestra subtítulos en %(language)s",
|
||||
"%(part_summary)sEmbedded subtitles (%(languages)s)": "%(part_summary)sSubtítulos integrados en (%(languages)s)",
|
||||
"Select active %(language)s subtitle": "Selecciona subtítulos activos en %(language)s subtitle",
|
||||
"%(count)d subtitles in storage": "%(count)d subtítulos almacenados",
|
||||
"List available %(language)s subtitles": "Muestra subtítulos disponibles en %(language)s",
|
||||
"Modify current %(language)s subtitle": "Modificar el subtítulo actual en %(language)s",
|
||||
"Currently applied mods: %(mod_list)s": "Modificaciones aplicadas actualmente: %(mod_list)s",
|
||||
"Blacklist current %(language)s subtitle and search for a new one": "Bloquear el actual subtítulo en %(language)s y buscar uno nuevo ",
|
||||
"Manage blacklist (%(amount)s contained)": "Gestionar lista de bloqueados (total: %(amount)s) ",
|
||||
"%(current_state)s%(subtitle_name)s, Score: %(score)s": "%(current_state)s%(subtitle_name)s, Puntuación: %(score)s",
|
||||
"Current: ": "Actual: ",
|
||||
"Stored: ": "Almacenado: ",
|
||||
"by %(release_group)s": "por %(release_group)s",
|
||||
"Current: %(provider_name)s (%(score)s) ": "Actual: %(provider_name)s (%(score)s)␣",
|
||||
"Search for %(language)s subs (%(video_data)s)": "Buscar subtítulos en %(language)s (%(video_data)s)",
|
||||
"%(current_info)sFilename: %(filename)s": "%(current_info)sNombre de archivo: %(filename)s",
|
||||
"Searching for %(language)s subs (%(video_data)s), refresh here ...": "Buscando subtítulos en %(language)s para (%(video_data)s), actualice aquí...",
|
||||
" (wrong FPS, sub: %(subtitle_fps)s, media: %(media_fps)s)": "␣(FPS incorrectos, sub: %(subtitle_fps)s, archivo: %(media_fps)s)",
|
||||
" (wrong FPS, sub: %(subtitle_fps)s, media: unknown, low impact mode)": " ␣(FPS incorrectos, sub: %(subtitle_fps)s, archivo: desconocido, modo de bajo impacto)\n",
|
||||
"%(blacklisted_state)s%(current_state)s: %(provider_name)s, score: %(score)s%(wrong_fps_state)s": "%(blacklisted_state)s%(current_state)s: %(provider_name)s, puntuación: %(score)s%(wrong_fps_state)s",
|
||||
"Release: %(release_info)s, Matches: %(matches)s": "Release: %(release_info)s, Coincidencia: %(matches)s",
|
||||
"Downloading subtitle for %(title_or_id)s": "Descargando subtítulo para %(title_or_id)s",
|
||||
"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s with default mods": "Extraer flujo %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s con las modificaciones por defecto",
|
||||
"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s": "Extraer flujo %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s",
|
||||
"%(provider_name)s, %(subtitle_id)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "%(provider_name)s, %(subtitle_id)s (added: %(date_added)s, %(mode)s), Idioma: %(language)s, Puntuación: %(score)i, Almacenamiento: %(storage_type)s",
|
||||
"Insufficient permissions on library %(title)s, folder: %(path)s": "Permisos insuficientes en biblioteca %(title)s, carpeta: %(path)s",
|
||||
"Running: %(items_done)s/%(items_searching)s (%(percentage)s%%)": "Ejecutando: %(items_done)s/%(items_searching)s (%(percentage)s%%)",
|
||||
"Display ignore list (%(ignored_count)d)": "Mostrar lista de ignorados (%(ignored_count)d)",
|
||||
"%(throttled_provider)s until %(until_date)s (%(reason)s)": "%(throttled_provider)s hasta %(until_date)s (%(reason)s)",
|
||||
"Extracting subtitle %(stream_index)s of %(filename)s": "Extrayendo subtítulos %(stream_index)s de %(filename)s",
|
||||
"Extract missing %(language)s embedded subtitles": "Extraer subtítulos integrados faltantes en %(language)s",
|
||||
"Extract and activate %(language)s embedded subtitles": "Extraer y activar subtítulos integrados en %(language)s",
|
||||
"None": "Ninguno",
|
||||
"Idle": "Parado",
|
||||
"%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)": "%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)",
|
||||
"Adjust by %(time_and_unit)s": "Ajustar a %(time_and_unit)s",
|
||||
"added: %(date_added)s, %(mode)s, Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "añadido: %(date_added)s, %(mode)s, Idioma: %(language)s, Puntuación: %(score)i, Almacenamiento: %(storage_type)s\n",
|
||||
"Remove: %(mod_name)s": "Quitar: %(mod_name)s",
|
||||
"%(class_name)s: Subtitle download failed (%(item_id)s)": "%(class_name)s: Fallo la descarga del subtítulos(%(item_id)s)",
|
||||
"agent + interface": "agente + interfaz",
|
||||
"only interface": "sólo interfaz",
|
||||
"interface": "interfaz",
|
||||
"Shows the current on deck items and allows you to individually (force-) refresh their metadata/subtitles.": "Mostrar los elementos En Progreso y permite actualiza individualmente los metadatos y subtítulos",
|
||||
"Lists items with missing subtitles. Click on \"Find recent items with missing subs\" to update list": "Muestra elementos sin subtítulos. Haz clic en \"Buscar elementos recientes sin subtítulos\" para actualizar la lista",
|
||||
"Add %(kind)s %(title)s to the ignore list": "Añadir %(kind)s %(title)s a la lista de ignorados",
|
||||
"Remove %(kind)s %(title)s from the ignore list": "Eliminar %(kind)s %(title)s de la lista de ignorados",
|
||||
"%(title)s added to the ignore list": "%(title)s añadido a la lista de ignorados",
|
||||
"%(title)s removed from the ignore list": "%(title)s eliminados de la lista de ignorados",
|
||||
"Triggering refresh for %(title)s": "Actualización lanzada para %(title)s",
|
||||
"Triggering forced refresh for %(title)s": "Actualización forzada para%(title)s",
|
||||
"Refresh of item %(item_id)s triggered": "Actualización de elementos %(item_id)s lanzada",
|
||||
"Forced refresh of item %(item_id)s triggered": "Actualización de elementos %(item_id)s forzada",
|
||||
"Ignore %(kind)s \"%(title)s\"": "Ignorar %(kind)s \"%(title)s\"",
|
||||
"Un-ignore %(kind)s \"%(title)s\"": "Dejar de ignorar %(kind)s \"%(title)s\"",
|
||||
"Refreshing %(title)s": "Actualizando %(title)s",
|
||||
"Force-refreshing %(title)s": "Actualizando forzosamente %(title)s",
|
||||
"Extracts the not yet extracted embedded subtitles of all episodes for the current season with all configured default modifications": "Extraer los subtítulos integrados no extraídos de todos los episodios de la actual temporada con las modificaciones configuradas por defecto",
|
||||
"Extracts embedded subtitles of all episodes for the current season with all configured default modifications": "Extraer los subtítulos integrados de todos los episodios de la actual temporada con las modificaciones configuradas por defecto",
|
||||
"Refreshes %(the_movie_series_season_episode)s, possibly searching for missing and picking up new subtitles on disk": "Actualiza %(the_movie_series_season_episode)s, posiblemente buscando y tomando nuevos subtítulos del disco",
|
||||
"the movie": "la película",
|
||||
"the series": "la serie",
|
||||
"the episode": "el episodio",
|
||||
"the season": "la temporada",
|
||||
"Change the color of the subtitle": "cambiar el color del subtítulo",
|
||||
"Adds the requested color to every line of the subtitle. Support depends on player.": "Añade el color seleccionado a todos los subtítulos. El funcionamiento depende del reproductor.",
|
||||
"Basic common fixes": "Arreglos comunes básicos",
|
||||
"Fix common and whitespace/punctuation issues in subtitles": "Arregla problemas comunes, espacios y puntuación en los subtítulos",
|
||||
"Remove all style tags": "Elimina toda las etiquetas de estilo",
|
||||
"Removes all possible style tags from the subtitle, such as font, bold, color etc.": "Elimina todas las posibles etiquetas de estilo del subtítulo, como fuente, negrita, color, etc.",
|
||||
"Reverse punctuation in RTL languages": "Invertir puntuación en idiomas RTL",
|
||||
"Some playback devices don't properly handle right-to-left markers for punctuation. Physically swap punctuation. Applicable to languages: hebrew": "Algunos reproductores no saben tratar correctamente la puntuación de derecha a izquierda, que aplica al idioma hebreo",
|
||||
"Change the FPS of the subtitle": "Cambiar los FPS del subtítulo",
|
||||
"Re-syncs the subtitle to the framerate of the current media file.": "Resincronizar los subtítulos a la tasa de frames del archivo original",
|
||||
"Remove Hearing Impaired tags": "Eliminar etiquetas para sordos",
|
||||
"Removes tags, text and characters from subtitles that are meant for hearing impaired people": "Eliminar etiquetas, textos y caracteres de los subtítulos puestos para sordos",
|
||||
"Fix common OCR issues": "Arreglar errores OCR comunes",
|
||||
"Fix issues that happen when a subtitle gets converted from bitmap to text through OCR": "Arreglar fallos que ocurren cuando los subtítulos se convierten de imagen a texto por un OCR",
|
||||
"Change the timing of the subtitle": "Cambiar el \"timing\" de los subtítulos",
|
||||
"Adds or substracts a certain amount of time from the whole subtitle to match your media": "Añadir o quitar cierta cantidad de tiempo de todo el subtítulos para emparejarlo con el vídeo",
|
||||
"Available": "Disponible",
|
||||
"Current": "Actual",
|
||||
"Custom path to advanced_settings.json": "Ruta personalizada para advanced_settings.json"
|
||||
}
|
||||
@@ -0,0 +1,400 @@
|
||||
{
|
||||
"sq": "Albán",
|
||||
"ar": "Arab",
|
||||
"be": "Fehérorosz",
|
||||
"bs": "Bosnyák",
|
||||
"bg": "Bolgár",
|
||||
"ca": "Katalán",
|
||||
"zh": "Kínai",
|
||||
"hr": "Horváth",
|
||||
"cs": "Cseh",
|
||||
"da": "Dán",
|
||||
"nl": "Holland",
|
||||
"en": "Angol",
|
||||
"et": "Észt",
|
||||
"fa": "Perzsa",
|
||||
"fi": "Finn",
|
||||
"fr": "Francia",
|
||||
"de": "Németh",
|
||||
"el": "Görög",
|
||||
"he": "Héber",
|
||||
"hi": "Hindu",
|
||||
"hu": "Magyar",
|
||||
"is": "Izlandi",
|
||||
"id": "Indonéz",
|
||||
"it": "Olasz",
|
||||
"ja": "Japán",
|
||||
"ko": "Koreai",
|
||||
"lv": "Lett",
|
||||
"lt": "Litván",
|
||||
"mk": "Makedón",
|
||||
"ms": "Maláj",
|
||||
"no": "Norwég",
|
||||
"pl": "Lengyel",
|
||||
"pt": "Portugál",
|
||||
"pt-br": "Portugál (Brazil)",
|
||||
"ro": "Román",
|
||||
"ru": "Orosz",
|
||||
"sr": "Szerb",
|
||||
"sr-cyrl": "Szerb (Cirill)",
|
||||
"sr-latn": "Szerb (Latin)",
|
||||
"sk": "Szlovák",
|
||||
"sl": "Szlovén",
|
||||
"es": "Spanyol",
|
||||
"sv": "Svéd",
|
||||
"th": "Thai",
|
||||
"tr": "Török",
|
||||
"uk": "Ukrán",
|
||||
"vi": "Vietnámi",
|
||||
"Internal stuff, pay attention!": "Belső dolog, figyelem!",
|
||||
"Advanced": "Haladó",
|
||||
"advanced": "haladó",
|
||||
"Enter PIN": "Írd be a PIN-t",
|
||||
"The owner has restricted the access to this menu. Please enter the correct pin": "A tulajdonos korlátozta a hozzáférést a menühöz. Kérlek írd be a jó pint-t",
|
||||
"Restart the plugin": "Bővítmény újrainditása",
|
||||
"Get my logs (copy the appearing link and open it in your browser, please)": "Logok lekérése (másold ki a megjelenő linket és nyisd meg a böngészőben)",
|
||||
"Copy the appearing link and open it in your browser, please": "Másold ki a megjelenő linket és nyisd meg a böngészőben",
|
||||
"Trigger find better subtitles": "Jobban passzoló feliratok keresése",
|
||||
"Skip next find better subtitles (sets last run to now)": "Ugrás a következőre, keress jobb feliratot\n",
|
||||
"Trigger subtitle storage maintenance": "Feliarttár karbantartás indítása",
|
||||
"Trigger subtitle storage migration (expensive)": "Felirattár migrálás indítása (költséges)",
|
||||
"Trigger cache maintenance (refiners, providers and packs/archives)": "Gyorsitótár karbantartás indítása (refiners, providers and packs/archives)",
|
||||
"Apply configured default subtitle mods to all (active) stored subtitles": "Alapértelmezett módosítások alkalmazása az összes (aktív) feliratra",
|
||||
"Re-Apply mods of all stored subtitles": "Módosítások újra alkalmazása az összes feliratra",
|
||||
"Log the plugin's scheduled tasks state storage": "Bővítmény ütemezett feladatainak logolása",
|
||||
"Log the plugin's internal ignorelist storage": "A bővítmény mellőzendő listájának naplózása.",
|
||||
"Log the plugin's complete state storage": "Bővítmény teljes állapotának naplózása",
|
||||
"Reset the plugin's scheduled tasks state storage": "Bővítmény ütemezett feladatainak visszaállítása",
|
||||
"Reset the plugin's internal ignorelist storage": "A bővítmény mellőzendő listájának alaphelyzetbe állítása",
|
||||
"Invalidate Sub-Zero metadata caches (subliminal)": "Sub-Zero metaadat tár érvénytelenítése (subliminal)",
|
||||
"Reset provider throttle states": "Szolgáltató túlterhelési állapotának alaphelyzetbe állítása",
|
||||
"Restarting the plugin": "Bővítmény újraindítása",
|
||||
"Restart triggered, please wait about 5 seconds": "Újraindítás folyamatban, várj körülbelül 5 másodpercet",
|
||||
"Reset subtitle storage": "Felirattár alaphelyzetbe állitása",
|
||||
"Are you sure?": "Biztos vagy benne?",
|
||||
"Are you really sure?": "Teljesen biztos vagy benne?",
|
||||
"Success": "Sikerült",
|
||||
"FindBetterSubtitles triggered": "Jobb felirat keresése elindítva",
|
||||
"FindBetterSubtitles skipped": "Jobb felirat keresése kihagyva",
|
||||
"SubtitleStorageMaintenance triggered": "Felirat tár karbantartás elindítva",
|
||||
"MigrateSubtitleStorage triggered": "Felirat tár migrálás elindítva",
|
||||
"TriggerCacheMaintenance triggered": "Gyorsítótár karbantartás elindítva",
|
||||
"This may take some time ...": "Ez egy kis időt vehet igénybe ...",
|
||||
"Download Logs": "Naplófájlok letöltése",
|
||||
"Sorry, feature unavailable": "Sajnálom, ez a funkció nem elérhető",
|
||||
"Universal Plex token not available": "Univerzális Plex Token nem elérhető",
|
||||
"Copy this link and open this in your browser, please": "Kérlek másold ki ezt a linket és nyisd meg a böngésződben",
|
||||
"Cache invalidated": "Gyorsítótár érvénytelenítse",
|
||||
"Enter PIN number ": "Írd be a PIN kódot",
|
||||
"PIN correct": "PIN elfogadva",
|
||||
"Reset": "Alaphelyzetbe állitás",
|
||||
"Menu locked": "Menü zárolva",
|
||||
"Provider throttles reset": "Szolgáltató túlterhelés védelem apahelyzetbe állítása",
|
||||
"Information Storage (%s) reset": "Információs tár ( %s) alaphelyzetbe állítása",
|
||||
"Information Storage (%s) logged": "Információs tár (%s) naplózva",
|
||||
"Plex didn't return any information about the item, please refresh it and come back later": "A plex nem adott vissza semmi információt az elemről. Frissítsd és gyere vissza később.",
|
||||
"Item not found: %s!": "Elem nem található: %s!",
|
||||
"< Back to %s": "< Vissza %s",
|
||||
"Back to %s > %s": "Vissza %s > %s",
|
||||
"Refresh: %s": "Frissítés: %s",
|
||||
"Issues a forced refresh, ignoring known subtitles and searching for new ones": "Kényszerített frissítés, figyelmen kívül hagyja az ismert feliratokat és újakat keres",
|
||||
"Extract and activate embedded subtitle streams": "Beágyazott felirat kitömörítése és aktiválása",
|
||||
"Inspect currently blacklisted subtitles": "Feketelistás feliratok megvizsgálása",
|
||||
"Subtitle saved to disk": "Felirat lemezre mentve",
|
||||
"Remove subtitle from blacklist": "Felirat eltávolítása a feketelistáról",
|
||||
"No subtitles found": "Felirat nem található",
|
||||
" (unknown)": " (ismeretlen)",
|
||||
" (forced)": " (kiegészítő felirat)",
|
||||
"Extracting of embedded subtitle %s of part %s:%s triggered": "Beágyazott felirat %s of part %s:%s kitömörítése elindítva",
|
||||
"Insufficient permissions": "Nincs elegendő engedély",
|
||||
"I'm not enabled!": "Bővitmény nincs bekapcsolva",
|
||||
"Please enable me for some of your libraries in your server settings; currently I do nothing": "Aktiválj valamelyik könyvtáradhoz a server beállításoknál.\njelenleg semmit nem csinálok.",
|
||||
"Working ... refresh here": "Folyamatban ... Frissíts it",
|
||||
"Current state: %s; Last state: %s": "Jelenlegi állapot: %s; Utolsó állapot: %s",
|
||||
"On-deck items": "Lejátszás alatt lévő elemek",
|
||||
"Shows the %s recently played items and allows you to individually (force-) refresh their metadata/subtitles.": "Mutassa a %s most játszott elemeket és adjon lehetőséget a metaadataik egyenként történő frissítésére,",
|
||||
"Recently-added items": "Mostanában hozzáadott elemek",
|
||||
"Recently played items": "Mostanában játszottak elemek",
|
||||
"Shows the recently added items per section.": "Mostanában hozzáadott elemek mutatása könyvtáranként",
|
||||
"Show recently added items with missing subtitles": "Mutasd a mostanában hozzáadott felirat nélküli elemeket",
|
||||
"Browse all items": "Összes elme böngészése",
|
||||
"Go through your whole library and manage your ignore list. You can also (force-) refresh the metadata/subtitles of individual items.": "Végig megy a teljes könyvtáron és kezeli a mellőzendők listáját. Lehetőség van az egyes metaadatok és feliratok (erőltetett-) frissítésre is az egyes elemeknél.",
|
||||
"Last run: %s; Next scheduled run: %s; Last runtime: %s": "Utolsó futás: %s, Következő időzített futás: %s, Utolsó futás hossza: %s",
|
||||
"Search for missing subtitles (in recently-added items, max-age: %s)": "Hiányzó feliratok keresése (újonnan hozzáadott elemek, max. kor: %s)",
|
||||
"Automatically run periodically by the scheduler, if configured. %s": "Automatikus futtatás az ütemező által konfigurálva. %s",
|
||||
"Show the current ignore list (mainly used for the automatic tasks)": "Mellőzendő lista megjelenése (elsősorban automatikus feladatokhoz)",
|
||||
"History": "Előzmények",
|
||||
"Show the last %i downloaded subtitles": "Mutasd az utolsó %i letöltött feliratot",
|
||||
"Refresh": "Frissités",
|
||||
"Re-lock menu(s)": "menü(k) újrazárolása",
|
||||
"Enabled the PIN again for menu(s)": "PIN újra engedélyezése a menü(k)-höz",
|
||||
"Throttled providers: %s": "Túlterhelt szolgáltatók: %s",
|
||||
"Advanced functions": "Fejlett funkciók",
|
||||
"Use at your own risk": "Csak saját felelősségre használd",
|
||||
"Items On Deck": "Lejátszás alatt álló elemek",
|
||||
"Recently Played": "Mostanában játszott elemek",
|
||||
"Items with missing subtitles": "Hiányzó felirattal rendelkező elemek",
|
||||
"Find recent items with missing subtitles": "Mostanában hozzáadott hiányzó felirattal rendelkező elemek keresése",
|
||||
"Updating, refresh here ...": "Frissítés folyamatban, frissíts itt ...",
|
||||
"Missing: %s": "Hiányzó: %s",
|
||||
"Didn't change the ignore list": "Ne változzon a mellőzendő lista ",
|
||||
"Sections": "Könyvtárak",
|
||||
"All": "Mind",
|
||||
"show": "mutasd",
|
||||
"movie": "Film",
|
||||
"<< Back to home": "<< Vissza a kezdőképernyőre",
|
||||
"Auto-Find subtitles: %s": "Felirat autó keresése: %s",
|
||||
"Extracting of embedded subtitles for %s triggered": "Beágyazott felirat kitömörítése a %s -hez elindítva",
|
||||
"< Back to subtitle options for: %s": "< Vissza a felirat beállításokhoz: %s",
|
||||
"Remove last applied mod (%s)": "Utoljára alkalmazott (%s) módosítás visszavonása",
|
||||
"none": "egyik sem",
|
||||
"Manage applied mods": "Használatban lévő módositások kezelése",
|
||||
"Reapply applied mods": "Módosítások újra alkalmazása",
|
||||
"Restore original version": "Eredeti verzió visszaállítása",
|
||||
"< Back to subtitle modification menu": "< Vissza a felirat módosítás menübe",
|
||||
"subs constantly getting faster": "feliratok folyamatosan gyorsabbak lesznek",
|
||||
"subs constantly getting slower": "feliratok folyamatosan lassabbak lesznek",
|
||||
"< Back to subtitle modifications": "< Vissza a felirat módosításokhoz: %s",
|
||||
"< Back to unit selection": "< Vissza a unit választáshoz",
|
||||
"Subtitle Language (1)": "Felirat Nyelve (1)",
|
||||
"Subtitle Language (2)": "Felirat Nyelve (2)",
|
||||
"Subtitle Language (3)": "Felirat Nyelve (3)",
|
||||
"Additional Subtitle Languages (use ISO-639-1 codes; comma-separated)": "További felirat nyelvei (ISO-639-1 kódok vesszővel elválasztva)",
|
||||
"Only download foreign/forced subtitles": "Csak külföldi / kényszerített feliratok letöltése",
|
||||
"Display languages with country attribute as ISO 639-1 (e.g. pt-BR = pt)": "Nyelvek megjelentetési az ISO 639-1 es kódolásnak megfelelő ország attribútummal (pl. pt-BR = pt)",
|
||||
"Treat languages with country attribute as ISO 639-1 (e.g. don't download pt-BR if pt subtitle exists)": "Ország attribútummal rendelkező nyelveket kezeljen ISO 639-1 esként (pl. ne töltsön le pt-BR-t ha pt már le van töltve)",
|
||||
"Restrict to one language (skips adding \".lang.\" to the subtitle filename; only uses \"Subtitle Language (1)\")": "Korlátozás egy nyelvre (nem adja hozzá a \".nyelv\"-et a felirat fájl nevéhez.)",
|
||||
"Embedded subtitles: Treat \"Undefined\" (und) as language 1": "Beágyazott feliratok: \"Ismeretlen\" nyelvet úgy tekinti mintha az elsődleges lenne",
|
||||
"I rename my files using": "Átneveztem a fájlokat a következő segitségével",
|
||||
"Retrieve original filename from .file_info/file_info index files (see wiki)": "Eredeti fájlnév meghatározása a .file_info/file_info index fájlokból. (lásd wiki)",
|
||||
"Sonarr URL (add URL base if configured)": "Sonarr URL (base url hozzáadása ha be van állítva)",
|
||||
"Sonarr API key": "Sonarr API kulcs",
|
||||
"Radarr URL (add URL base if configured, min. version: 0.2.0.897)": "Radarr URL (base url hozzáadása ha be van állítva) min. verzió: 0.2.0.897",
|
||||
"Radarr API key": "Radarr API kulcs",
|
||||
"Provider: Enable OpenSubtitles": "Szolgáltató: OpenSubtitles használata",
|
||||
"Opensubtitles Username": "Opensubtitles Felhasználónév",
|
||||
"Opensubtitles Password": "Opensubtitles Jelszó",
|
||||
"OpenSubtitles VIP? (ad-free subs, 1000 subs/day, no-cache VIP server: http://v.ht/osvip)": "OpenSubtitles VIP? (hirdetésmentes feliratok, 1000 felirat/nap, VIP server: http://v.ht/osvip)",
|
||||
"Provider: Enable Podnapisi.NET": "Szolgáltató: Podnapisi.NET használata",
|
||||
"Provider: Enable Titlovi.com": "Szolgáltató: Titlovi.com használata",
|
||||
"Provider: Enable Addic7ed": "Szolgáltató: Titlovi.com használata",
|
||||
"Addic7ed Username": "Addic7ed Felhasználónév",
|
||||
"Addic7ed Password": "Addic7ed Jelszó",
|
||||
"Addic7ed: boost score (if requirements met)": "Addic7ed: találati esély növelése (ha a feltételek teljesülnek)",
|
||||
"Addic7ed: Use random user agents": "Addic7ed: Random \"user agent\" használata",
|
||||
"Provider: Enable Legendas TV (mostly pt-BR; UNRAR NEEDED)": "Szolgáltató: Legendas TV használata (jellemzően pt-BR nyelvhez) ",
|
||||
"Legendas TV Username": "Legendas TV felhasználói név",
|
||||
"Legendas TV Password": "Legendas TV jelszó",
|
||||
"Provider: Enable TVsubtitles.net": "Szolgáltató: Tvsubtitles.net engedélyezése",
|
||||
"Provider: Enable NapiProjekt.pl (Polish)": "Szolgáltató: NapiProjekt.pl (Lengyel) engedélyezése",
|
||||
"Provider: Enable SubScene (TV shows)": "Szolgáltató: SubScene (TV sorozatok) engedélyezése",
|
||||
"Provider: Enable hosszupuskasub.com (Hungarian)": "Szolgáltató: hosszupuskasub.com (Magyar) engedélyezése",
|
||||
"Provider: Enable aRGENTeaM (Spanish)": "Szolgáltató: aRGENTeaM (Spanyol) engedélyezése",
|
||||
"Search enabled providers simultaneously (multithreading)": "Párhuzamos keresés az engedélyezett szolgáltatóknál ( multithreading )",
|
||||
"Automatically extract and use embedded subtitles upon media addition (with configured default mods)": "Automatikusan tömörítse ki és használja a beágyazott feliratot a media hozzáadásakor (a beállított alapmódosításokkal )",
|
||||
"After automatic extraction of embedded subtitles, also immediately search for available subtitles?": "A beágyazott felirat automatikus kitömörítés után azonnal keressen elérhető feliratot?",
|
||||
"Don't search for subtitles of a language if there are embedded subtitles inside the media file (MKV/MP4)?": "Ne keressen feliratot ahhoz a nyelvhez amihez van beágyazott felirat a média fájlban (MKV/MP4)?",
|
||||
"Don't search for subtitles of a language if they already exist on the filesystem (metadata/filesystem)?": "Ne keressen feliratot olyan nyelvhez ami már megtalálható a fájlrendszeren (metaadat/fájlrendszer)",
|
||||
"How strict should these subtitles existing on the filesystem be detected?": "Mennyire szigorúan nézze ezeknek a feliratoknak a meglétét a fájlrendszeren?",
|
||||
"Include non-text subtitle formats (anything else than .srt/.ssa/.ass/.vtt; embedded or external) in the above?": "Nem szöveg alapú feliratok használat (bármi más mint srt/.ssa/.ass/.vtt; beágyazott vagy külső)",
|
||||
"Minimum score for TV (min: 240, def/sane: 337, min-ideal: 352; see http://v.ht/szscores)": "Minimum pontszám Sorozatokhoz (min: 240, def/sane: 337, min-ideális: 352; bővebben: http://v.ht/szscores)",
|
||||
"Minimum score for movies (min: 60, def/sane: 69, min-ideal: 82; see http://v.ht/szscores)": "Minimum pontszám Filmekhez (min: 60, def/sane: 69, min-ideal: 82; bővebben: http://v.ht/szscores)",
|
||||
"Download hearing impaired subtitles.": "Halláskárosult feliratok letöltése",
|
||||
"Remove Hearing Impaired tags from downloaded subtitles": "Halláskárosult címke törlése a letöltött feliratokról",
|
||||
"Remove style tags from downloaded subtitles (bold, italic, underline, colors, ...)": "Stílus címkék törlése a letöltött feliratokról (vastag, dőlt, aláhúzott, színek, ...)",
|
||||
"Fix common issues in subtitles": "Gyakori hibák javítása a feliratokban",
|
||||
"Fix common OCR errors in downloaded subtitles": "Általános OCR hibák javítása a letöltött feliratokban",
|
||||
"Reverse punctuation in RTL languages (heb)": "Fordított írásjelek RTL nyelveken (heb)",
|
||||
"Change colors of subtitles to": "Felirat színének megváltoztatása erre",
|
||||
"Store subtitles next to media files (instead of metadata)": "Feliratok tárolása a videó fájlok mellet (az adatbázis helyett)",
|
||||
"Subtitle formats to save (non-SRT only works if the previous option is enabled)": "Felirat mentési formátuma (a non-SRT csak akkor működik ha az előző opció be van kapcsolva)",
|
||||
"Subtitle Folder (\"current folder\" is the folder the current media file lives in)": "Felirat mappa (az \"aktuális mappa\" az az aktuális médiafájl mappája)",
|
||||
"Custom Subtitle folder (overrides \"Subtitle Folder\"; computes to real paths)": "Egyéni felirat mappa (felülbírálja a \"Felirat mappa\" -át, valós útvonalnak megfelelően)",
|
||||
"Fall back to metadata storage if filesystem storage failed": "A fájlok tárolásának meghiúsulása esetén térjen vissza a metaadat-tároláshoz",
|
||||
"Set subtitle file permissions to (integer, e.g.: 0775)": "Felirat fájl engedélyeinek beállítása erre (egész szám, például: 0775)",
|
||||
"Automatically delete leftover/unused (externally saved) subtitles": "Elhagyott/használatlan (egyénileg mentett) feliratok automatikus törlése",
|
||||
"On media playback: search for missing subtitles (refresh item)": "Lejátszás esetén: keressen hiányzó feliratot ( elem frissítése )",
|
||||
"Scheduler: Periodically search for recent items with missing subtitles": "Ütemező: Rendszeresen keressen feliratot a felirattal nem rendelkező friss elemekhez",
|
||||
"Scheduler: Item age to be considered recent": "Ütemező: Elem frissnek tekinthető ha a kora",
|
||||
"Scheduler: Recent items to consider per library": "Ütemező: Könyvtáranként ennyi elemet vegyen figyelembe mint friss",
|
||||
"Scheduler: Periodically search for better subtitles": "Ütemező: Rendszeresen keressen jobb feliratot",
|
||||
"Scheduler: Days to search for better subtitles (max: 30 days)": "Ütemező: Ennyi napig keressen jobb feliratot (max 30 nap)",
|
||||
"Scheduler: Don't search for better subtitles if the item's air date is older than": "Ütemező: Ne keressen jobb feliratot ha az elem vetítési dátuma régebbi mint",
|
||||
"Scheduler: Overwrite manually selected subtitles when better found": "Ütemező: Manuálisan kiválasztott felirat felülírása ha van jobb találat",
|
||||
"Scheduler: Overwrite subtitles with non-default subtitle modifications when better found": "Ütemező: Írja felül a feliratot ha van jobb",
|
||||
"History: amount of items to store historical data for": "Előzmények: ennyi elemnek tárolja az előzményeit",
|
||||
"How many download tries per subtitle (on timeout or error)": "Hány letöltési próbálkozás történjen feliratonként (időtúllépés vagy hiba esetén)",
|
||||
"Ignore folders (with \"subzero.ignore/.subzero.ignore/.nosz\" files in them)": "Mappák figyelmen kívül hagyása (amik tartalmazzák a \"subzero.ignore/.subzero.ignore/.nosz\" kifejezést)",
|
||||
"Ignore anything in the following paths (comma-separated)": "Minden kihagyása a következő helyeken (vesszővel elválasztva)",
|
||||
"Sub-Zero mode": "Sub-Zero mód",
|
||||
"Access PIN (any amount of numbers, 0-9)": "PIN Hozzáférés (tetszőleges hosszuságú szám, 0-9)",
|
||||
"Access PIN valid for minutes": "PIN hozzáférés ennyi percig valid: ",
|
||||
"Use PIN to restrict access to (needs plugin or PMS restart)": "PIN használta hogy hozzáférj (Bővítmény vagy PMS újraindítás szükséges)",
|
||||
"Call this executable upon successful subtitle download (see Wiki for details)": "Ennek a programnak az indítása sikeres felirat letöltés esetén (Részletek a Wiki-n)",
|
||||
"Check for correct folder permissions of every library on plugin start": "Megfelelő mappa engedélyek ellenőrzése minden bővítmény indításnál",
|
||||
"Use new style caching (for subliminal)": "Új stílusú gyorsitótár használata (subliminalhoz) ",
|
||||
"Low impact mode (for remote filesystems)": "Alacsony hatású mód (távoli fájlrendszerek esetén)",
|
||||
"Timeout for API requests sent to the PMS": "A PMS-hez küldött API-kérelmek időtúllépése",
|
||||
"HTTP proxy to use for providers (supports credentials)": "HTTP proxy használata a szolgáltatók eléréséhez (supports credentials)",
|
||||
"How verbose should the logging be?": "Milyen mértékű legyen a naplózás?",
|
||||
"How many log backups to keep?": "Hány napló-mentés maradjon?",
|
||||
"Log subtitle modification (debug)": "Felirat módosítások naplózása (Debug esetén)",
|
||||
"Log to console (for development/debugging)": "Naplózás konzolra (fejlesztéshez/hiba kereséshez)",
|
||||
"Collect anonymous usage statistics": "Anonim használati statisztikák gyűjtése",
|
||||
"Sonarr/Radarr (fill api info below)": "Sonarr/Radarr (API infó kitöltése lent)",
|
||||
"Filebot": "Filebot",
|
||||
"Sonarr/Radarr/Filebot": "Sonarr/Radarr/Filebot",
|
||||
"Symlink to original file": "Symlink az eredeti fájlra",
|
||||
"I keep the original filenames": "Megtartottam az eredeti fájl neveket",
|
||||
"none of the above": "Egyiksem",
|
||||
"exact: media filename match": "pontos: média fájl neve egyezik",
|
||||
"loose: filename contains media filename": "gyenge: fájlnév tartalmazza a média fájl nevét.",
|
||||
"any": "bármelyik",
|
||||
"prefer": "javasolt",
|
||||
"don't prefer": "nem javasolt",
|
||||
"force HI": "HI erőltetésé",
|
||||
"force non-HI": "non-Hi eröltetése",
|
||||
"don't change": "nincs módositás",
|
||||
"white": "fehér",
|
||||
"light-grey": "világos-szürke",
|
||||
"red": "piros",
|
||||
"green": "zöld",
|
||||
"yellow": "sárga",
|
||||
"blue": "kék",
|
||||
"magenta": "magenta",
|
||||
"cyan": "cián",
|
||||
"black": "fekete",
|
||||
"dark-red": "sötét-piros",
|
||||
"dark-green": "sötét-zöld",
|
||||
"dark-yellow": "sötét-sárga",
|
||||
"dark-blue": "sötét-két",
|
||||
"dark-magenta": "sötét-magenta",
|
||||
"dark-cyan": "sötét-cián",
|
||||
"dark-grey": "sötét-szürke",
|
||||
"current folder": "jelenlegi mappa",
|
||||
"never": "soha",
|
||||
"current media item": "jelenlegi média elem",
|
||||
"next episode (series)": "következő rész (sorozat)",
|
||||
"hybrid: current item or next episode": "hybrid: jelenlegi elem vagy következő rész",
|
||||
"hybrid-plus: current item and next episode": "hybrid-plus: jelenlegi elem és következő rész",
|
||||
"every 6 hours": "6 óránként",
|
||||
"every 12 hours": "12 óránként",
|
||||
"every 24 hours": "24 óránként",
|
||||
"1 days": "1 nap",
|
||||
"2 days": "2 nap",
|
||||
"3 days": "3 nap",
|
||||
"4 days": "4 nap",
|
||||
"1 weeks": "1 hét",
|
||||
"2 weeks": "2 hét",
|
||||
"3 weeks": "3 hét",
|
||||
"4 weeks": "4 hét",
|
||||
"5 weeks": "5 hét",
|
||||
"6 weeks": "6 hét",
|
||||
"12 weeks": "12 hét",
|
||||
"don't limit": "Nem korlátozott",
|
||||
"1 year": "1 év",
|
||||
"2 years": "2 év",
|
||||
"3 years": "3 év",
|
||||
"4 years": "4 év",
|
||||
"5 years": "5 év",
|
||||
"6 years": "6 év",
|
||||
"7 years": "7 év",
|
||||
"8 years": "8 év",
|
||||
"9 years": "9 év",
|
||||
"10 years": "10 év",
|
||||
"only agent": "csak ügynök",
|
||||
"disabled": "inaktiv",
|
||||
"advanced menu": "fejlett menü",
|
||||
"CRITICAL": "CRITICAL",
|
||||
"ERROR": "ERROR",
|
||||
"WARNING": "WARNING",
|
||||
"INFO": "INFO",
|
||||
"DEBUG": "DEBUG",
|
||||
"Force-find subtitles: %(item_title)s": "Erőltetett felirat keresés: %(item_title)s",
|
||||
"File %(file_part_index)s: ": "Fájl %(file_part_index)s: ",
|
||||
"%(part_summary)sNo current subtitle in storage": "%(part_summary)sNincs jelenlegi felirat",
|
||||
"%(part_summary)sCurrent subtitle: %(provider_name)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "%(part_summary)sJelenlegi felirat: %(provider_name)s (hozzáadva: %(date_added)s, %(mode)s), Nyelv: %(language)s, Pontszám: %(score)i, Tárolás: %(storage_type)s",
|
||||
"%(part_summary)sManage %(language)s subtitle": "%(part_summary)sKezelje a(z) %(language)s feliratot",
|
||||
"%(part_summary)sList %(language)s subtitles": "%(part_summary)sListázza a(z) %(language)s feliratokat",
|
||||
"%(part_summary)sEmbedded subtitles (%(languages)s)": "%(part_summary)sBeágyazott feliratok (%(languages)s)",
|
||||
"Select active %(language)s subtitle": "Aktív %(language)s felirat kiválasztása",
|
||||
"%(count)d subtitles in storage": "%(count)d felirat tárolva",
|
||||
"List available %(language)s subtitles": "%(language)s feliratok listázása",
|
||||
"Modify current %(language)s subtitle": "%(language)s felirat módosítása",
|
||||
"Currently applied mods: %(mod_list)s": "Már alkalmazott módosítások: %(mod_list)s",
|
||||
"Blacklist current %(language)s subtitle and search for a new one": "Tegye feketelistára a mostani %(language)s feliratot és keressen újat",
|
||||
"Manage blacklist (%(amount)s contained)": "Feketelista kezelése ((%(amount)s tartalmaz))",
|
||||
"%(current_state)s%(subtitle_name)s, Score: %(score)s": "%(current_state)s%(subtitle_name)s, Pontszám: %(score)s",
|
||||
"Current: ": "Jelenlegi: ",
|
||||
"Stored: ": "Tárolt: ",
|
||||
"by %(release_group)s": "%(release_group)s alapján",
|
||||
"Current: %(provider_name)s (%(score)s) ": "Jelenlegi: %(provider_name)s (%(score)s)␣",
|
||||
"Search for %(language)s subs (%(video_data)s)": "Keressen %(language)s feliratot (%(video_data)s)",
|
||||
"%(current_info)sFilename: %(filename)s": "%(current_info)sFájlnév: %(filename)s",
|
||||
"Searching for %(language)s subs (%(video_data)s), refresh here ...": "Keresés folyamatban a %(language)s felirathoz (%(video_data)s), \nSearching for %(language)s subs (%(video_data)s), frissíts itt ...",
|
||||
" (wrong FPS, sub: %(subtitle_fps)s, media: %(media_fps)s)": " (rossz FPS, felirat: %(subtitle_fps)s, média: %(media_fps)s)",
|
||||
" (wrong FPS, sub: %(subtitle_fps)s, media: unknown, low impact mode)": " (rossz FPS, felirat: %(subtitle_fps)s, média: ismeretlen, low impact mód)",
|
||||
"%(blacklisted_state)s%(current_state)s: %(provider_name)s, score: %(score)s%(wrong_fps_state)s": "%(blacklisted_state)s%(current_state)s: %(provider_name)s, Pont: %(score)s%(wrong_fps_state)s",
|
||||
"Release: %(release_info)s, Matches: %(matches)s": "Release: %(release_info)s, Találatok: %(matches)s",
|
||||
"Downloading subtitle for %(title_or_id)s": "Felirat letöltése ehhez: %(title_or_id)s",
|
||||
"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s with default mods": "Tömöritsd ki a stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s alap beállításokkal",
|
||||
"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s": "Tömörítsd ki a sream %(stream_index)s -t, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s",
|
||||
"%(provider_name)s, %(subtitle_id)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "%(provider_name)s, %(subtitle_id)s (hozzáadva: %(date_added)s, %(mode)s), Nyelv: %(language)s, Pontszám: %(score)i, Tárolás: %(storage_type)s",
|
||||
"Insufficient permissions on library %(title)s, folder: %(path)s": "Nem megfelelő jogosultság ehhez %(title)s, mappa: %(path)s",
|
||||
"Running: %(items_done)s/%(items_searching)s (%(percentage)s%%)": "Folyamatban: %(items_done)s/%(items_searching)s (%(percentage)s%%)",
|
||||
"Display ignore list (%(ignored_count)d)": "Mutasd a mellőzendők listáját (%(ignored_count)d)",
|
||||
"%(throttled_provider)s until %(until_date)s (%(reason)s)": "%(throttled_provider)s %(until_date)s ig (%(reason)s)",
|
||||
"Extracting subtitle %(stream_index)s of %(filename)s": "Felirat kitömörítése %(stream_index)s a %(filename)s -ból",
|
||||
"Extract missing %(language)s embedded subtitles": "Hiányzó %(language)s beágyazott felirat kitömörítése",
|
||||
"Extract and activate %(language)s embedded subtitles": "Beágyazott %(language)s felirat kitömörítése és aktiválása",
|
||||
"None": "Egyik sem",
|
||||
"Idle": "Tétlen",
|
||||
"%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)": "%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)",
|
||||
"Adjust by %(time_and_unit)s": "Igazítás %(time_and_unit)s -val ",
|
||||
"added: %(date_added)s, %(mode)s, Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "Hozzáadva: %(date_added)s, %(mode)s, Nyelv: %(language)s, Pontszám: %(score)i, Tárolás: %(storage_type)s",
|
||||
"Remove: %(mod_name)s": "Eltávolít: %(mod_name)s",
|
||||
"%(class_name)s: Subtitle download failed (%(item_id)s)": "%(class_name)s: Felirat letöltés nem sikerült (%(item_id)s)",
|
||||
"agent + interface": "Ügynök + interfész",
|
||||
"only interface": "Csak interfész",
|
||||
"interface": "Interfész",
|
||||
"Shows the current on deck items and allows you to individually (force-) refresh their metadata/subtitles.": "Mutassa a most játszott elemeket, és adjon lehetősége egyesével történő metaadat/felirat frissítéshez",
|
||||
"Lists items with missing subtitles. Click on \"Find recent items with missing subs\" to update list": "Hiányzó felirattal rendelkező elemek listázása. Kattints a \"Mostanában hozzáadott hiányzó felirattal rendelkező elemek keresése\"-re hogy frissítsd a listát",
|
||||
"Add %(kind)s %(title)s to the ignore list": "%(kind)s %(title)s hozzáadása a listára",
|
||||
"Remove %(kind)s %(title)s from the ignore list": "%(kind)s %(title)s eltávolítása a listáról ",
|
||||
"%(title)s added to the ignore list": "%(title)s hozzáadva a listára",
|
||||
"%(title)s removed from the ignore list": "%(title)s kivéve a listáról",
|
||||
"Triggering refresh for %(title)s": "Frissítés indítása a(z) %(title)s -hez",
|
||||
"Triggering forced refresh for %(title)s": "Erőltetett frissítés indítása a(z) %(title)s -hez",
|
||||
"Refresh of item %(item_id)s triggered": "Frissítés a %(item_id)s elemhez elindítva",
|
||||
"Forced refresh of item %(item_id)s triggered": "Erőltetett frissítés a %(item_id)s elemhez elindítva",
|
||||
"Ignore %(kind)s \"%(title)s\"": "Hagyd figyelmen kívül: %(kind)s \"%(title)s\"",
|
||||
"Un-ignore %(kind)s \"%(title)s\"": "Ne hagyd figyelmen kívül: Un-ignore %(kind)s \"%(title)s\"",
|
||||
"Refreshing %(title)s": "Frissítés: %(title)s",
|
||||
"Force-refreshing %(title)s": "Erőltetett frissítés: %(title)s",
|
||||
"Extracts the not yet extracted embedded subtitles of all episodes for the current season with all configured default modifications": "A még nem kitömörített beágyazott feliratok kitömörítése a kiválasztott évad összes részéből az összes beállított alapmódosítással",
|
||||
"Extracts embedded subtitles of all episodes for the current season with all configured default modifications": "A beágyazott feliratok kitömörítése a kiválasztott évad összes részéből az összes beállított alapmódosítással",
|
||||
"Refreshes %(the_movie_series_season_episode)s, possibly searching for missing and picking up new subtitles on disk": "Frissítse %(the_movie_series_season_episode)s, új feliratot keres vagy hozzáad a meghajtón lévőkből.",
|
||||
"the movie": "a film",
|
||||
"the series": "a sorozat",
|
||||
"the episode": "az epizód",
|
||||
"the season": "az évadot",
|
||||
"Change the color of the subtitle": "Felirat színének megváltoztatása",
|
||||
"Adds the requested color to every line of the subtitle. Support depends on player.": "Kért szín hozzáadása a felirat minden sorához. Támogatása a lejátszótól függ.",
|
||||
"Basic common fixes": "Általános alap javítások",
|
||||
"Fix common and whitespace/punctuation issues in subtitles": "Általános szóköz/írásjel hibák javítása a feliratokban",
|
||||
"Remove all style tags": "Minden stílus tag eltávolítása",
|
||||
"Removes all possible style tags from the subtitle, such as font, bold, color etc.": "Eltávolítja az összes lehetséges stílust a feliratból, például betűtípus, félkövér, szín stb.",
|
||||
"Reverse punctuation in RTL languages": "Fordított írásjelek RTL nyelveken",
|
||||
"Some playback devices don't properly handle right-to-left markers for punctuation. Physically swap punctuation. Applicable to languages: hebrew": "Néhány lejátszóeszköz nem megfelelően kezeli a jobbról balra történő írásnál az írásjeleket. Fizikálisan felcseréli az írásjeleket. A következő nyelvekhez alkalmazható: héber",
|
||||
"Change the FPS of the subtitle": "Feliratok FPS-ének megváltoztatása",
|
||||
"Re-syncs the subtitle to the framerate of the current media file.": "Felirat képkocka-sebességének szinkronizálása az aktuális médiához",
|
||||
"Remove Hearing Impaired tags": "Hallássérülteknek szánt információ eltávolitása ",
|
||||
"Removes tags, text and characters from subtitles that are meant for hearing impaired people": "Hallás sérültek számára hozzáadott szövegek, karakterek, tagek eltávolítása a feliratokból.",
|
||||
"Fix common OCR issues": "Általános OCR hibák javitása",
|
||||
"Fix issues that happen when a subtitle gets converted from bitmap to text through OCR": "Felirat képből szöveggé történő átalakítása(OCR) során keletkezett hibák javítása",
|
||||
"Change the timing of the subtitle": "Felirat időzítésének módosítása",
|
||||
"Adds or substracts a certain amount of time from the whole subtitle to match your media": "Hozzáad vagy elvesz a feliratból egy bizonyos időtartamot hogy illeszkedjen a médiához.",
|
||||
"Available": "Elérhető",
|
||||
"Current": "Jelenlegi",
|
||||
"Custom path to advanced_settings.json": "Egyéni útvonal az advanced_settings.json fájlhoz"
|
||||
}
|
||||
@@ -0,0 +1,400 @@
|
||||
{
|
||||
"sq": "Albanees",
|
||||
"ar": "Arabisch",
|
||||
"be": "Wit-Russisch",
|
||||
"bs": "Bosnisch",
|
||||
"bg": "Bulgaars",
|
||||
"ca": "Catalaans\n",
|
||||
"zh": "Chinees",
|
||||
"hr": "Kroatisch",
|
||||
"cs": "Czech",
|
||||
"da": "Deens",
|
||||
"nl": "Nederlands",
|
||||
"en": "Engels",
|
||||
"et": "Estlands",
|
||||
"fa": "Perzisch (Farsi)",
|
||||
"fi": "Fins",
|
||||
"fr": "Frans",
|
||||
"de": "Duits",
|
||||
"el": "Grieks",
|
||||
"he": "Hebreeuws",
|
||||
"hi": "Hindi",
|
||||
"hu": "Hongaars",
|
||||
"is": "IJslands",
|
||||
"id": "Indonesisch",
|
||||
"it": "Italiaans",
|
||||
"ja": "Japanees",
|
||||
"ko": "Koreaans",
|
||||
"lv": "Lets",
|
||||
"lt": "Litouws",
|
||||
"mk": "Macedonisch",
|
||||
"ms": "Maleis",
|
||||
"no": "Noors",
|
||||
"pl": "Pools",
|
||||
"pt": "Portugees",
|
||||
"pt-br": "Portugees (Braziliaans)",
|
||||
"ro": "Roemeens",
|
||||
"ru": "Russisch",
|
||||
"sr": "Servisch",
|
||||
"sr-cyrl": "Servisch (Cyrillisch)",
|
||||
"sr-latn": "Servisch (Latijns)",
|
||||
"sk": "Slowaaks",
|
||||
"sl": "Sloveens",
|
||||
"es": "Spaans",
|
||||
"sv": "Zweeds",
|
||||
"th": "Thais",
|
||||
"tr": "Turks",
|
||||
"uk": "Oekraïens",
|
||||
"vi": "Vietnamees",
|
||||
"Internal stuff, pay attention!": "Interne dingen, Opletten!",
|
||||
"Advanced": "Geavanceerd",
|
||||
"advanced": "geavanceerd",
|
||||
"Enter PIN": "PIN invoeren",
|
||||
"The owner has restricted the access to this menu. Please enter the correct pin": "De eigenaar heeft de toegang beperkt tot dit menu. Vul a.u.b. de correcte PIN in.",
|
||||
"Restart the plugin": "Herstart de plugin",
|
||||
"Get my logs (copy the appearing link and open it in your browser, please)": "Haal mijn logs op (kopieer de link en open deze in je browser, a.u.b.)",
|
||||
"Copy the appearing link and open it in your browser, please": "kopieer de link en open deze in je browser, a.u.b.",
|
||||
"Trigger find better subtitles": "Activeer zoek betere ondertiteling",
|
||||
"Skip next find better subtitles (sets last run to now)": "Sla volgende zoek beter ondertiteling over (stelt de laatste uitvoering op nu)",
|
||||
"Trigger subtitle storage maintenance": "Activeer ondertiteling opslag onderhoud",
|
||||
"Trigger subtitle storage migration (expensive)": "Activeer ondertiteling opslag migratie (zwaar)",
|
||||
"Trigger cache maintenance (refiners, providers and packs/archives)": "Activeer Cache onderhoud (filters, providers en packs/archieven)",
|
||||
"Apply configured default subtitle mods to all (active) stored subtitles": "Pas geconfigureerde standaard ondertiteling modificaties toe op alle (actieve) opgeslagen ondertiteling",
|
||||
"Re-Apply mods of all stored subtitles": "Pas modificaties op alle opgeslagen ondertiteling opnieuw toe",
|
||||
"Log the plugin's scheduled tasks state storage": "Log de plugin's geplande takenstaat opslag",
|
||||
"Log the plugin's internal ignorelist storage": "Log de plugin's interne negeerlijst opslag",
|
||||
"Log the plugin's complete state storage": "Log de plugin's compleetstaat opslag",
|
||||
"Reset the plugin's scheduled tasks state storage": "Reset de plugin's geplande takenstaat opslag",
|
||||
"Reset the plugin's internal ignorelist storage": "Reset de plugin's interne negeerlijst opslag",
|
||||
"Invalidate Sub-Zero metadata caches (subliminal)": "Invalideer Sub-Zero metadata caches (subliminal)",
|
||||
"Reset provider throttle states": "Reset provider pauze staten",
|
||||
"Restarting the plugin": "Plugin herstarten",
|
||||
"Restart triggered, please wait about 5 seconds": "Herstart geactiveerd, wacht a.u.b. ongeveer 5 seconden",
|
||||
"Reset subtitle storage": "Reset ondertiteling opslag",
|
||||
"Are you sure?": "Weet je het zeker?",
|
||||
"Are you really sure?": "Weet je het heel zeker?",
|
||||
"Success": "Succes",
|
||||
"FindBetterSubtitles triggered": "ZoekBetereOndertiteling geactiveerd",
|
||||
"FindBetterSubtitles skipped": "ZoekBetereOndertiteling overgeslagen",
|
||||
"SubtitleStorageMaintenance triggered": "OndertitelingOpslagOnderhoud geactiveerd",
|
||||
"MigrateSubtitleStorage triggered": "MigreerOndertitelingOpslag geactiveerd",
|
||||
"TriggerCacheMaintenance triggered": "CacheOnderhoud geactiveerd",
|
||||
"This may take some time ...": "Dit kan een tijd duren...",
|
||||
"Download Logs": "Download Logs",
|
||||
"Sorry, feature unavailable": "Sorry, eigenschap is niet beschikbaar",
|
||||
"Universal Plex token not available": "Universele Plex token niet beschikbaar",
|
||||
"Copy this link and open this in your browser, please": "Kopieer deze link en open deze in je browser, a.u.b.",
|
||||
"Cache invalidated": "Cache is geinvalideerd",
|
||||
"Enter PIN number ": "Voer PIN nummer in ",
|
||||
"PIN correct": "PIN is correct",
|
||||
"Reset": "Reset",
|
||||
"Menu locked": "Menu geblokeerd",
|
||||
"Provider throttles reset": "Provider pauzes reset",
|
||||
"Information Storage (%s) reset": "Informatie opslag (%s) gereset",
|
||||
"Information Storage (%s) logged": "Informatie opslag (%s) geregistreerd",
|
||||
"Plex didn't return any information about the item, please refresh it and come back later": "Plex heeft geen informatie over het item gegeven, ververs a.u.b. het item en kom later terug",
|
||||
"Item not found: %s!": "Item niet gevonden: %s!",
|
||||
"< Back to %s": "< Terug naar %s",
|
||||
"Back to %s > %s": "Terug naar %s > %s",
|
||||
"Refresh: %s": "Ververs: %s",
|
||||
"Issues a forced refresh, ignoring known subtitles and searching for new ones": "Voert een geforceerde vernieuwing uit, negeert bekende ondertiteling en zoekt naar nieuwe",
|
||||
"Extract and activate embedded subtitle streams": "Geëmbedde ondertiteling streams extraheren en activeren",
|
||||
"Inspect currently blacklisted subtitles": "Inspecteer de ondertiteling op de zwarte lijst",
|
||||
"Subtitle saved to disk": "Ondertitel opgeslagen op schijf",
|
||||
"Remove subtitle from blacklist": "Verwijder ondertitel van zwarte lijst",
|
||||
"No subtitles found": "Geen ondertiteling gevonden",
|
||||
" (unknown)": " (onbekend)",
|
||||
" (forced)": " (geforceerd)",
|
||||
"Extracting of embedded subtitle %s of part %s:%s triggered": "Extraheren van geëmbedde ondertitel %s van deel %s:%s geactiveerd",
|
||||
"Insufficient permissions": "Niet genoeg rechten",
|
||||
"I'm not enabled!": "Ik ben niet ingeschakeld!",
|
||||
"Please enable me for some of your libraries in your server settings; currently I do nothing": "Schakel me alstublieft in voor enkele van uw bibliotheken in uw serverinstellingen; momenteel doe ik niets",
|
||||
"Working ... refresh here": "Bezig... ververs hier",
|
||||
"Current state: %s; Last state: %s": "Huidige staat: %s, Laatste staat: %s",
|
||||
"On-deck items": "On-deck items",
|
||||
"Shows the %s recently played items and allows you to individually (force-) refresh their metadata/subtitles.": "Toont de %s recentelijk afgespeelde items en stelt je instaat om hiervan de metadata/ondertiteling individueel (geforceerd) te verversen",
|
||||
"Recently-added items": "Recentelijk toegevoegde items",
|
||||
"Recently played items": "Recentelijk afgespeelde items",
|
||||
"Shows the recently added items per section.": "Toont de recentelijk toegevoegde items per sectie",
|
||||
"Show recently added items with missing subtitles": "Laat de recentelijk toegevoegde items met missende ondertiteling zien",
|
||||
"Browse all items": "Blader door alle items",
|
||||
"Go through your whole library and manage your ignore list. You can also (force-) refresh the metadata/subtitles of individual items.": "Ga door je hele bibliotheek heen en beheer je negeerlijst. Je kan ook de metadata/ondertiteling van individuele items (geforceerd) verversen.",
|
||||
"Last run: %s; Next scheduled run: %s; Last runtime: %s": "Laatste uitvoering: %s; Volgend geplande uitvoering: %s; Laatste uitvoeringstijd: %s",
|
||||
"Search for missing subtitles (in recently-added items, max-age: %s)": "Zoek naar missende ondertiteling (in recentelijk toegevoegde items, maximale leeftijd: %s)",
|
||||
"Automatically run periodically by the scheduler, if configured. %s": "Voer automatisch periodiek uit door de taakplanner, indien ingesteld. %s",
|
||||
"Show the current ignore list (mainly used for the automatic tasks)": "Laat de huidige negeerlijst zien (hoofdzakelijk gebruikt voor automatische taken)",
|
||||
"History": "Geschiedenis",
|
||||
"Show the last %i downloaded subtitles": "Laat de laatste %i gedownloade ondertiteling zien",
|
||||
"Refresh": "Ververs",
|
||||
"Re-lock menu(s)": "Her-blokkeer menu('s)",
|
||||
"Enabled the PIN again for menu(s)": "PIN opnieuw ingeschakeld voor menu('s)",
|
||||
"Throttled providers: %s": "Gepauzeerde providers: %s",
|
||||
"Advanced functions": "Geavanceerde functies",
|
||||
"Use at your own risk": "Gebruik op eigen risico",
|
||||
"Items On Deck": "Items On-deck",
|
||||
"Recently Played": "Recentelijk afgespeeld",
|
||||
"Items with missing subtitles": "Items met missende ondertiteling",
|
||||
"Find recent items with missing subtitles": "Zoek recente items met missende ondertiteling",
|
||||
"Updating, refresh here ...": "Updaten, ververs hier...",
|
||||
"Missing: %s": "Missend: %s",
|
||||
"Didn't change the ignore list": "De negeerlijst is niet gewijzigd",
|
||||
"Sections": "Secties",
|
||||
"All": "Alles",
|
||||
"show": "serie",
|
||||
"movie": "film",
|
||||
"<< Back to home": "<< Terug naar start",
|
||||
"Auto-Find subtitles: %s": "Auto-Vind ondertiteling: %s",
|
||||
"Extracting of embedded subtitles for %s triggered": "Extraheren van geëmbedde ondertiteling voor %s is geactiveerd",
|
||||
"< Back to subtitle options for: %s": "< Teug naar ondertitel opties voor: %s",
|
||||
"Remove last applied mod (%s)": "Verwijder laatst toegepaste modificatie (%s)",
|
||||
"none": "geen",
|
||||
"Manage applied mods": "Beheer toegepaste modificaties",
|
||||
"Reapply applied mods": "Opnieuw toepassen van toegepaste modificaties",
|
||||
"Restore original version": "Herstel originele versie",
|
||||
"< Back to subtitle modification menu": "< Terug naar ondertitel modificatie menu",
|
||||
"subs constantly getting faster": "ondertiteling wordt constant sneller",
|
||||
"subs constantly getting slower": "ondertiteling wordt constant langzamer",
|
||||
"< Back to subtitle modifications": "< Terug naar ondertitel modificaties",
|
||||
"< Back to unit selection": "< Terug naar eenheid selectie",
|
||||
"Subtitle Language (1)": "Ondertitel taal (1)",
|
||||
"Subtitle Language (2)": "Ondertitel taal (2)",
|
||||
"Subtitle Language (3)": "Ondertitel taal (3)",
|
||||
"Additional Subtitle Languages (use ISO-639-1 codes; comma-separated)": "Additionele ondertitel talen (gebruik ISO-639-1 codes; komma-gescheiden)",
|
||||
"Only download foreign/forced subtitles": "Download enkel ondertiteling voor buitenlands gesproken delen (forced)",
|
||||
"Display languages with country attribute as ISO 639-1 (e.g. pt-BR = pt)": "Geef talen weer met landattribuut als ISO 639-1 (bijvoorbeeld pt-BR = pt)",
|
||||
"Treat languages with country attribute as ISO 639-1 (e.g. don't download pt-BR if pt subtitle exists)": "Behandel talen met landattribuut als ISO 639-1 (bijvoorbeeld download geen pt-BR als pt ondertitel bestaat)",
|
||||
"Restrict to one language (skips adding \".lang.\" to the subtitle filename; only uses \"Subtitle Language (1)\")": "Beperken tot één taal (slaat het toevoegen van \".lang.\" aan de ondertitel bestandsnaam over, gebruikt alleen \"Ondertitel taal (1)\")",
|
||||
"Embedded subtitles: Treat \"Undefined\" (und) as language 1": "Geëmbedde ondertiteling: Behandel \"Ongedefineerd\" (und) als \"Ondertitel taal (1)\"",
|
||||
"I rename my files using": "Ik hernoem mijn bestanden met",
|
||||
"Retrieve original filename from .file_info/file_info index files (see wiki)": "Oorspronkelijke bestandsnaam ophalen uit .file_info / file_info indexbestanden (zie wiki)",
|
||||
"Sonarr URL (add URL base if configured)": "Sonarr URL (voeg URL-basis toe indien geconfigureerd)",
|
||||
"Sonarr API key": "Sonarr API sleutel",
|
||||
"Radarr URL (add URL base if configured, min. version: 0.2.0.897)": "Radarr URL (voeg URL-basis toe indien geconfigureerd, minimaal benodigde versie:0.2.0.897)",
|
||||
"Radarr API key": "Radarr API sleutel",
|
||||
"Provider: Enable OpenSubtitles": "Provider: Opensubtitles inschakelen",
|
||||
"Opensubtitles Username": "Opensubtitles gebruikersnaam",
|
||||
"Opensubtitles Password": "Opensubtitles wachtwoord",
|
||||
"OpenSubtitles VIP? (ad-free subs, 1000 subs/day, no-cache VIP server: http://v.ht/osvip)": "OpenSubtitles VIP? (reclame vrije ondertiteling, 1000 ondertitels/dag, geen-cache, VIP server: http://v.ht/osvip) ",
|
||||
"Provider: Enable Podnapisi.NET": "Provider: Podnapisi.NET inschakelen",
|
||||
"Provider: Enable Titlovi.com": "Provider:Titlovi.com inschakelen",
|
||||
"Provider: Enable Addic7ed": "Provider: Addic7ed inschakelen",
|
||||
"Addic7ed Username": "Addic7ed gebruikersnaam",
|
||||
"Addic7ed Password": "Addic7ed wachtwoord",
|
||||
"Addic7ed: boost score (if requirements met)": "Addic7ed: verhoog score (indien aan eisen wordt voldaan)",
|
||||
"Addic7ed: Use random user agents": "Addic7ed: gebruik willekeurige user-agents",
|
||||
"Provider: Enable Legendas TV (mostly pt-BR; UNRAR NEEDED)": "Provider: Legendas TV inschakelen (meestal pt-BR; UNRAR NODIG)",
|
||||
"Legendas TV Username": "Legendas TV gebruikersnaam",
|
||||
"Legendas TV Password": "Legendas TV wachtwoord",
|
||||
"Provider: Enable TVsubtitles.net": "Provider: Tvsubtitles.net inschakelen",
|
||||
"Provider: Enable NapiProjekt.pl (Polish)": "Provider: NapiProjekt.pl inschakelen (Pools)",
|
||||
"Provider: Enable SubScene (TV shows)": "Provider: SubScene inschakelen (TV series)",
|
||||
"Provider: Enable hosszupuskasub.com (Hungarian)": "Provider: hosszupuskasub.com inschakelen (Hongaars)",
|
||||
"Provider: Enable aRGENTeaM (Spanish)": "Provider: aRGENTeaM inschakelen (Spaans)",
|
||||
"Search enabled providers simultaneously (multithreading)": "Zoek gelijkertijd bij ingeschakelde providers (multithreading)",
|
||||
"Automatically extract and use embedded subtitles upon media addition (with configured default mods)": "Extraheer en gebruik geëmbedde ondertiteling automatisch bij media toevoeging (met geconfigureerde standaard modificaties)",
|
||||
"After automatic extraction of embedded subtitles, also immediately search for available subtitles?": "Na het automatisch extraheren van geëmbedde ondertiteling, ook gelijk zoeken naar beschikbare ondertiteling?",
|
||||
"Don't search for subtitles of a language if there are embedded subtitles inside the media file (MKV/MP4)?": "Niet zoeken naar ondertiteling van een taal als er al geëmbedde ondertiteling bestaat in het media bestand (MKV/MP4)?",
|
||||
"Don't search for subtitles of a language if they already exist on the filesystem (metadata/filesystem)?": "Niet zoeken naar ondertiteling van een taal als er ondertiteling bestaat op het bestandssysteem (metadata/bestandssysteem)?",
|
||||
"How strict should these subtitles existing on the filesystem be detected?": "Hoe strikt moet deze ondertiteling op het bestandssysteem worden gedetecteerd?",
|
||||
"Include non-text subtitle formats (anything else than .srt/.ssa/.ass/.vtt; embedded or external) in the above?": "Gebruik niet-tekst ondertiteling formaten (iets anders dan .srt / .ssa / .ass / .vtt; geëmbed of extern) in het bovenstaande?",
|
||||
"Minimum score for TV (min: 240, def/sane: 337, min-ideal: 352; see http://v.ht/szscores)": "Minimale score voor TV (minimaal: 240, verstandig: 337, minimaal ideaal: 352; zie http://v.ht/szscores)",
|
||||
"Minimum score for movies (min: 60, def/sane: 69, min-ideal: 82; see http://v.ht/szscores)": "Minimale score voor films (minimaal: 60, verstandig: 69, minimaal ideaal: 82; zie http://v.ht/szscores)",
|
||||
"Download hearing impaired subtitles.": "Download ondertiteling voor slechthorende",
|
||||
"Remove Hearing Impaired tags from downloaded subtitles": "Verwijder slecthorende-tags uit ondertiteling",
|
||||
"Remove style tags from downloaded subtitles (bold, italic, underline, colors, ...)": "Verwijder stijl-tags uit de ondertiteling (dik gedrukt, schuin, onderlijnt, kleuren, ...)",
|
||||
"Fix common issues in subtitles": "Repareer veel voorkomende fouten in ondertiteling",
|
||||
"Fix common OCR errors in downloaded subtitles": "Repareer veel voorkomende OCR fouten om gedownloade ondertiteling",
|
||||
"Reverse punctuation in RTL languages (heb)": "Draai leestekens in RTL (rechts naar links) talen om (Hebreeuws)",
|
||||
"Change colors of subtitles to": "Wijzig kleur van ondertiteling naar",
|
||||
"Store subtitles next to media files (instead of metadata)": "Sla ondertiteling naast de media bestanden op (in plaats van in de metadata)",
|
||||
"Subtitle formats to save (non-SRT only works if the previous option is enabled)": "Ondertiteling formaten om op te slaan (niet-SRT werkt alleen als de vorige optie is ingeschakeld)",
|
||||
"Subtitle Folder (\"current folder\" is the folder the current media file lives in)": "Ondertiteling map (\"huidige map\" is de map waar de huidige media is opgelsagen)",
|
||||
"Custom Subtitle folder (overrides \"Subtitle Folder\"; computes to real paths)": "Aangepaste ondertiteling map (overschrijft de \"Ondertiteling map\"; gebruikt echte paden)",
|
||||
"Fall back to metadata storage if filesystem storage failed": "Val terug naar metadata opslag indien het bestandssysteem faalt",
|
||||
"Set subtitle file permissions to (integer, e.g.: 0775)": "Stel rechten voor ondertitel bestanden in (geheel getal, bijv .: 0775)",
|
||||
"Automatically delete leftover/unused (externally saved) subtitles": "Verwijder automatisch achtergebleven/ongebruikte (extern opgeslagen) ondertiteling",
|
||||
"On media playback: search for missing subtitles (refresh item)": "Bij media afspelen: zoek naar missende ondertiteling (ververs item)",
|
||||
"Scheduler: Periodically search for recent items with missing subtitles": "Taakplanner: Zoek periodiek naar recente items met missende ondertiteling",
|
||||
"Scheduler: Item age to be considered recent": "Taakplanner: Item leeftijd die als recent moet worden beschouwd",
|
||||
"Scheduler: Recent items to consider per library": "Taakplanner: Recente items om te overwegen per bibliotheek",
|
||||
"Scheduler: Periodically search for better subtitles": "Taakplanner: Zoek periodiek naar betere ondertiteling",
|
||||
"Scheduler: Days to search for better subtitles (max: 30 days)": "Taakplanner: Dagen om te zoeken naar betere ondertiteling (maximaal 30 dagen)",
|
||||
"Scheduler: Don't search for better subtitles if the item's air date is older than": "Taakplanner: Niet zoeken naar betere ondertiteling als de uitzenddatum ouder is dan",
|
||||
"Scheduler: Overwrite manually selected subtitles when better found": "Taakplanner: Overschrijf handmatig geselecteerde ondertiteling als betere ondertiteling is gevonden",
|
||||
"Scheduler: Overwrite subtitles with non-default subtitle modifications when better found": "Taakplanner: Overschrijf ondertiteling met niet-standaard ondertitel modificaties als betere ondertiteling is gevonden",
|
||||
"History: amount of items to store historical data for": "Geschiedenis: aantal items om historische gegevens voor op te slaan",
|
||||
"How many download tries per subtitle (on timeout or error)": "Hoeveel download pogingen per ondertitel (bij time-out of fout)",
|
||||
"Ignore folders (with \"subzero.ignore/.subzero.ignore/.nosz\" files in them)": "Negeer mappen (met \"subzero.ignore/.subzero.ignore/.nosz\" bestanden in de mappen)",
|
||||
"Ignore anything in the following paths (comma-separated)": "Negeer alles in de volgende paden (komma-gescheiden)",
|
||||
"Sub-Zero mode": "Sub-Zero modus",
|
||||
"Access PIN (any amount of numbers, 0-9)": "ToegangsPIN (elk aantal cijfers, 0-9)",
|
||||
"Access PIN valid for minutes": "ToegangsPIN geldig voor minuten",
|
||||
"Use PIN to restrict access to (needs plugin or PMS restart)": "Gebruik PIN om toegang te beperken tot (hiervoor moet de plugin of PMS worden herstart)",
|
||||
"Call this executable upon successful subtitle download (see Wiki for details)": "Voer dit uitvoerbare bestand uit na succesvolle ondertitel download (zie Wiki voor details)",
|
||||
"Check for correct folder permissions of every library on plugin start": "Controleer op juiste map rechten van elke bibliotheek bij het starten van de plugin",
|
||||
"Use new style caching (for subliminal)": "Gebruik nieuwe manier van caching (voor subliminal)",
|
||||
"Low impact mode (for remote filesystems)": "Lage impact modus (voor externe bestandssystemen)",
|
||||
"Timeout for API requests sent to the PMS": "Time-out voor API-aanvragen die naar PMS worden verzonden",
|
||||
"HTTP proxy to use for providers (supports credentials)": "HTTP proxy om te gebruiken voor providers (ondersteunt inloggegevens)",
|
||||
"How verbose should the logging be?": "Hoe uitgebreid moet de logging zijn?",
|
||||
"How many log backups to keep?": "Hoeveel log bestanden moeten worden bewaard?",
|
||||
"Log subtitle modification (debug)": "Log ondertitel modificatie (debug)",
|
||||
"Log to console (for development/debugging)": "Log naar console (voor ontwikkeling/debugging)",
|
||||
"Collect anonymous usage statistics": "Verzamel anonieme gebruiksstatistieken",
|
||||
"Sonarr/Radarr (fill api info below)": "Sonarr/Radarr (vul API informatie hieronder in)",
|
||||
"Filebot": "Filebot",
|
||||
"Sonarr/Radarr/Filebot": "Sonarr/Radarr/Filebot ",
|
||||
"Symlink to original file": "Symlink naar origineel bestand",
|
||||
"I keep the original filenames": "Ik bewaar de originele bestandsnamen",
|
||||
"none of the above": "geen van de bovenstaande",
|
||||
"exact: media filename match": "Precies: media bestandsnaam overeenkomst",
|
||||
"loose: filename contains media filename": "Los: Bestandsnaam bevat media bestandsnaam",
|
||||
"any": "elk",
|
||||
"prefer": "prefereren",
|
||||
"don't prefer": "niet refereren",
|
||||
"force HI": "forceer slechthorend",
|
||||
"force non-HI": "forceer niet slechthorend",
|
||||
"don't change": "niet wijzigen",
|
||||
"white": "wit",
|
||||
"light-grey": "licht grijs",
|
||||
"red": "rood",
|
||||
"green": "groen",
|
||||
"yellow": "geel",
|
||||
"blue": "blauw",
|
||||
"magenta": "magenta",
|
||||
"cyan": "cyaan",
|
||||
"black": "zwart",
|
||||
"dark-red": "donker rood",
|
||||
"dark-green": "donker groen",
|
||||
"dark-yellow": "donker geel",
|
||||
"dark-blue": "donker blauw",
|
||||
"dark-magenta": "donker magenta",
|
||||
"dark-cyan": "donker cyaan",
|
||||
"dark-grey": "donker grijs",
|
||||
"current folder": "huidige map",
|
||||
"never": "nooit",
|
||||
"current media item": "huidig media item",
|
||||
"next episode (series)": "volgende aflevering (series)",
|
||||
"hybrid: current item or next episode": "Hybride: huidig item of volgende aflevering",
|
||||
"hybrid-plus: current item and next episode": "Hybride-plus: huidig item en volgende aflevering",
|
||||
"every 6 hours": "elke 6 uur",
|
||||
"every 12 hours": "elke 12 uur",
|
||||
"every 24 hours": "elk 24 uur",
|
||||
"1 days": "1 dag",
|
||||
"2 days": "2 dagen",
|
||||
"3 days": "3 dagen",
|
||||
"4 days": "4 dagen",
|
||||
"1 weeks": "1 week",
|
||||
"2 weeks": "2 weken",
|
||||
"3 weeks": "3 weken",
|
||||
"4 weeks": "4 weken",
|
||||
"5 weeks": "5 weken",
|
||||
"6 weeks": "6 weken",
|
||||
"12 weeks": "12 weken",
|
||||
"don't limit": "niet limiteren",
|
||||
"1 year": "1 jaar",
|
||||
"2 years": "2 jaar",
|
||||
"3 years": "3 jaar",
|
||||
"4 years": "4 jaar",
|
||||
"5 years": "5 jaar",
|
||||
"6 years": "6 jaar",
|
||||
"7 years": "7 jaar",
|
||||
"8 years": "8 jaar",
|
||||
"9 years": "9 jaar",
|
||||
"10 years": "10 jaar",
|
||||
"only agent": "enkel agent",
|
||||
"disabled": "uitgeschakeld",
|
||||
"advanced menu": "geavanceerd menu",
|
||||
"CRITICAL": "KRITISCH",
|
||||
"ERROR": "ERROR",
|
||||
"WARNING": "WAARSCHUWING",
|
||||
"INFO": "INFO",
|
||||
"DEBUG": "DEBUG",
|
||||
"Force-find subtitles: %(item_title)s": "Geforceerd ondertiteling zoeken: %(item_title)s",
|
||||
"File %(file_part_index)s: ": "Bestand %(file_part_index)s: ",
|
||||
"%(part_summary)sNo current subtitle in storage": "%(part_summary)sGeen huidige ondertitel gevonden in opslag",
|
||||
"%(part_summary)sCurrent subtitle: %(provider_name)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "%(part_summary)sHuidige ondertitel: %(provider_name)s (toegevoegd: %(date_added)s, %(mode)s), Taal: %(language)s, Score: %(score)i, Opslag: %(storage_type)s",
|
||||
"%(part_summary)sManage %(language)s subtitle": "%(part_summary)sBeheer %(language)se ondertitel",
|
||||
"%(part_summary)sList %(language)s subtitles": "%(part_summary)s %(language)se ondertiteling weergeven",
|
||||
"%(part_summary)sEmbedded subtitles (%(languages)s)": " %(part_summary)sGeëmbedde ondertiteling (%(languages)s) ",
|
||||
"Select active %(language)s subtitle": "Selecteer actieve %(language)se ondertitel",
|
||||
"%(count)d subtitles in storage": "%(count)d ondertitels gevonden in opslag",
|
||||
"List available %(language)s subtitles": "Beschikbare %(language)se ondertiteling weergeven",
|
||||
"Modify current %(language)s subtitle": "Wijzig huidige %(language)se ondertitel",
|
||||
"Currently applied mods: %(mod_list)s": "Huidig toegepaste modificaties: %(mod_list)s",
|
||||
"Blacklist current %(language)s subtitle and search for a new one": "Zet de huidige %(language)se ondertitel op de zwarte lijst en zoek naar nieuwe",
|
||||
"Manage blacklist (%(amount)s contained)": "Beheer de zwarte lijst (bevat er %(amount)s)",
|
||||
"%(current_state)s%(subtitle_name)s, Score: %(score)s": "%(current_state)s%(subtitle_name)s, Score: %(score)s",
|
||||
"Current: ": "Huidig: ",
|
||||
"Stored: ": "Opgeslagen: ",
|
||||
"by %(release_group)s": " door %(release_group)s ",
|
||||
"Current: %(provider_name)s (%(score)s) ": "Huidig: %(provider_name)s (%(score)s) ",
|
||||
"Search for %(language)s subs (%(video_data)s)": "Zoek naar %(language)se ondertiteling (%(video_data)s)",
|
||||
"%(current_info)sFilename: %(filename)s": "%(current_info)sBestandsnaam: %(filename)s",
|
||||
"Searching for %(language)s subs (%(video_data)s), refresh here ...": "Zoeken naar %(language)se ondertiteling (%(video_data)s), ververs hier",
|
||||
" (wrong FPS, sub: %(subtitle_fps)s, media: %(media_fps)s)": " (verkeerde FPS, ondertitel: %(subtitle_fps)s, media: %(media_fps)s)",
|
||||
" (wrong FPS, sub: %(subtitle_fps)s, media: unknown, low impact mode)": " (verkeerde FPS, ondertitel: %(subtitle_fps)s, media: onbekend, lage impact modus)",
|
||||
"%(blacklisted_state)s%(current_state)s: %(provider_name)s, score: %(score)s%(wrong_fps_state)s": "%(blacklisted_state)s%(current_state)s: %(provider_name)s, score: %(score)s%(wrong_fps_state)s",
|
||||
"Release: %(release_info)s, Matches: %(matches)s": "Uitgave: %(release_info)s, Overeenkomst: %(matches)s",
|
||||
"Downloading subtitle for %(title_or_id)s": "Ondertitel downloaden voor %(title_or_id)s",
|
||||
"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s with default mods": "Extraheer stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s met standaard modificaties",
|
||||
"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s": "Extraheer stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s%(stream_title)s",
|
||||
"%(provider_name)s, %(subtitle_id)s (added: %(date_added)s, %(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "%(provider_name)s, %(subtitle_id)s (Toegevoegd: %(date_added)s, %(mode)s), Taal: %(language)s, Score: %(score)i, Opslag: %(storage_type)s",
|
||||
"Insufficient permissions on library %(title)s, folder: %(path)s": "Niet genoeg rechten op bibliotheek %(title)s, map: %(path)s",
|
||||
"Running: %(items_done)s/%(items_searching)s (%(percentage)s%%)": "Uitvoeren: %(items_done)s/%(items_searching)s (%(percentage)s%%)",
|
||||
"Display ignore list (%(ignored_count)d)": "Negeerlijst weergeven (%(ignored_count)d)",
|
||||
"%(throttled_provider)s until %(until_date)s (%(reason)s)": "%(throttled_provider)s tot %(until_date)s (%(reason)s)",
|
||||
"Extracting subtitle %(stream_index)s of %(filename)s": "Extraheren van ondertitel %(stream_index)s van %(filename)s",
|
||||
"Extract missing %(language)s embedded subtitles": "Extraheer missende %(language)s geëmbedde ondertiteling",
|
||||
"Extract and activate %(language)s embedded subtitles": "Extraheer en activeer %(language)s geëmbedde ondertiteling",
|
||||
"None": "Geen",
|
||||
"Idle": "Idle",
|
||||
"%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)": "%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)",
|
||||
"Adjust by %(time_and_unit)s": "Aanpassen met %(time_and_unit)s",
|
||||
"added: %(date_added)s, %(mode)s, Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s": "Toegevoegd: %(date_added)s, %(mode)s, Taal: %(language)s, Score: %(score)i, Opslag: %(storage_type)s",
|
||||
"Remove: %(mod_name)s": "Verwijder: %(mod_name)s ",
|
||||
"%(class_name)s: Subtitle download failed (%(item_id)s)": "%(class_name)s: Downloaden van ondertitel mislukt (%(item_id)s)",
|
||||
"agent + interface": "agent + interface",
|
||||
"only interface": "enkel de interface",
|
||||
"interface": "interface",
|
||||
"Shows the current on deck items and allows you to individually (force-) refresh their metadata/subtitles.": "Toont de huidige on-deck items en stelt je instaat om hiervan de metadata/ondertiteling individueel (geforceerd) te verversen",
|
||||
"Lists items with missing subtitles. Click on \"Find recent items with missing subs\" to update list": "Items met missende ondertiteling weergeven. Klik op \"Zoek recente items met missende ondertiteling\" om de lijst te updaten",
|
||||
"Add %(kind)s %(title)s to the ignore list": "Voeg %(kind)s %(title)s toe aan negeerlijst",
|
||||
"Remove %(kind)s %(title)s from the ignore list": "Verwijder %(kind)s %(title)s van negeerlijst",
|
||||
"%(title)s added to the ignore list": "%(title)s toegevoegd aan negeerlijst",
|
||||
"%(title)s removed from the ignore list": "%(title)s verwijderd van negeerlijst",
|
||||
"Triggering refresh for %(title)s": "Activeer een verversing voor %(title)s",
|
||||
"Triggering forced refresh for %(title)s": "Activeer een geforceerde verversing voor %(title)s",
|
||||
"Refresh of item %(item_id)s triggered": "Verversing van item %(item_id)s geactiveerd",
|
||||
"Forced refresh of item %(item_id)s triggered": "Geforceerde verversing van item %(item_id)s geactiveerd",
|
||||
"Ignore %(kind)s \"%(title)s\"": "Negeer %(kind)s \"%(title)s\" ",
|
||||
"Un-ignore %(kind)s \"%(title)s\"": "%(kind)s \"%(title)s\" niet meer negeren",
|
||||
"Refreshing %(title)s": "%(title)s aan het verversen",
|
||||
"Force-refreshing %(title)s": "%(title)s aan het geforceerd verversen",
|
||||
"Extracts the not yet extracted embedded subtitles of all episodes for the current season with all configured default modifications": "Extraheert de nog niet geëxtraheerde geëmbedde ondertiteling van alle afleveringen voor het huidige seizoen met alle geconfigureerde standaard modificaties",
|
||||
"Extracts embedded subtitles of all episodes for the current season with all configured default modifications": "Extraheert geëmbedde ondertiteling van alle afleveringen voor het huidig seizoen met alle geconfigureerde standaard modificaties",
|
||||
"Refreshes %(the_movie_series_season_episode)s, possibly searching for missing and picking up new subtitles on disk": "Ververst %(the_movie_series_season_episode)s, mogelijk zoeken naar missende ondertiteling en nieuwe ondertiteling op schijf",
|
||||
"the movie": "de film",
|
||||
"the series": "de serie",
|
||||
"the episode": "de aflevering",
|
||||
"the season": "het zeizoen",
|
||||
"Change the color of the subtitle": "Wijzig de kleur van de ondertiteling",
|
||||
"Adds the requested color to every line of the subtitle. Support depends on player.": "Voegt de ingestelde kleur toe aan elke regel van de ondertiteling. Ondersteuning is afhankelijk van de speler.",
|
||||
"Basic common fixes": "Basis veel voorkomende reparaties",
|
||||
"Fix common and whitespace/punctuation issues in subtitles": "Repareer veel voorkomende en wit ruimte/leestekens fouten in ondertiteling",
|
||||
"Remove all style tags": "Verwijder alle stijl-tags",
|
||||
"Removes all possible style tags from the subtitle, such as font, bold, color etc.": "Verwijder alle mogelijke stijl-tags uit de ondertiteling, zoals lettertype, dik gedrukt, kleur enz.",
|
||||
"Reverse punctuation in RTL languages": "Draai leestekens in RTL (rechts naar links) talen om",
|
||||
"Some playback devices don't properly handle right-to-left markers for punctuation. Physically swap punctuation. Applicable to languages: hebrew": "Sommige afspeelapparaten kunnen de leestekens van rechts naar links niet goed verwerken. Wissel interpunctie fysiek. Van toepassing op talen: hebreeuws",
|
||||
"Change the FPS of the subtitle": "Wijzig de FPS van de ondertitel",
|
||||
"Re-syncs the subtitle to the framerate of the current media file.": "Synchroniseert de ondertitel naar de framerate van het huidige mediabestand opnieuw.",
|
||||
"Remove Hearing Impaired tags": "Verwijder slecthorende-tags",
|
||||
"Removes tags, text and characters from subtitles that are meant for hearing impaired people": "Verwijderd tags. tekst en karakters uit ondertiteling die zijn bedoeld voor slechthorende mensen",
|
||||
"Fix common OCR issues": "Repareer veel voorkomende OCR fouten",
|
||||
"Fix issues that happen when a subtitle gets converted from bitmap to text through OCR": "Repareer fouten die optreden als een ondertitel is geconverteerd van bitmap naar tekst met OCR",
|
||||
"Change the timing of the subtitle": "Wijzig de timing van de ondertitel",
|
||||
"Adds or substracts a certain amount of time from the whole subtitle to match your media": "Voegt een bepaalde hoeveelheid tijd toe of trekt een bepaalde tijd af van de hele ondertitel zodat deze overeenkomt met uw media",
|
||||
"Available": "Beschikbaar",
|
||||
"Current": "Huidig",
|
||||
"Custom path to advanced_settings.json": "Aangepast pad naar advanced_settings.json"
|
||||
}
|
||||
@@ -24,6 +24,8 @@ Don't expect support if you mess this up.
|
||||
"find_better_as_extracted_tv_score": 352,
|
||||
"find_better_as_extracted_movie_score": 82,
|
||||
|
||||
"debug_i18n": false,
|
||||
|
||||
// per-provider-config
|
||||
"providers": {
|
||||
// enabled_for: specifies which media type to enable the provider for. does not override global/throttled
|
||||
@@ -40,6 +42,8 @@ Don't expect support if you mess this up.
|
||||
},
|
||||
"opensubtitles": {
|
||||
"enabled_for": ["series", "movies"],
|
||||
"use_https": true,
|
||||
"timeout": 15,
|
||||
},
|
||||
"podnapisi": {
|
||||
"enabled_for": ["series", "movies"],
|
||||
@@ -65,5 +69,15 @@ Don't expect support if you mess this up.
|
||||
"argenteam": {
|
||||
"enabled_for": ["series", "movies"],
|
||||
}
|
||||
},
|
||||
|
||||
"refiners": {
|
||||
"sonarr": {
|
||||
// don't verify HTTPS certificates? Set to True for self-signed certificates
|
||||
"ssl_no_verify": false,
|
||||
},
|
||||
"radarr": {
|
||||
"ssl_no_verify": false,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
MIT License
|
||||
|
||||
Modified version of The Unlicense.
|
||||
Copyright (c) 2018 Hannes Tismer
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means, as long as the author of this software is contacted beforehands
|
||||
and confirms and consents to such use of this software, as well as where
|
||||
and in which software and in which form it is used.
|
||||
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:
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
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 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.
|
||||
|
||||
For more information, please refer to <http://unlicense.org>
|
||||
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.
|
||||
|
||||
|
||||
Copyright for portions of project Sub-Zero are held by Bram Walet, 2014 as part of project Subliminal.bundle.
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Copyright 2013 Dean Gardiner <gardiner91@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
@@ -0,0 +1,25 @@
|
||||
Copyright (c) 2015, by the respective authors (see AUTHORS file).
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of the BabelFish authors nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,27 @@
|
||||
Beautiful Soup is made available under the MIT license:
|
||||
|
||||
Copyright (c) 2004-2017 Leonard Richardson
|
||||
|
||||
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.
|
||||
|
||||
Beautiful Soup incorporates code from the html5lib library, which is
|
||||
also made available under the MIT license. Copyright (c) 2006-2013
|
||||
James Graham and other contributors
|
||||
@@ -0,0 +1,21 @@
|
||||
This packge contains a modified version of ca-bundle.crt:
|
||||
|
||||
ca-bundle.crt -- Bundle of CA Root Certificates
|
||||
|
||||
Certificate data from Mozilla as of: Thu Nov 3 19:04:19 2011#
|
||||
This is a bundle of X.509 certificates of public Certificate Authorities
|
||||
(CA). These were automatically extracted from Mozilla's root certificates
|
||||
file (certdata.txt). This file can be found in the mozilla source tree:
|
||||
http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1#
|
||||
It contains the certificates in PEM format and therefore
|
||||
can be directly used with curl / libcurl / php_curl, or with
|
||||
an Apache+mod_ssl webserver for SSL client authentication.
|
||||
Just configure this file as the SSLCACertificateFile.#
|
||||
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
This Source Code Form is subject to the terms of the Mozilla Public License,
|
||||
v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain
|
||||
one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $
|
||||
@@ -0,0 +1,504 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
Copyright (c) 2014 by Armin Ronacher.
|
||||
|
||||
Click uses parts of optparse written by Gregory P. Ward and maintained by the
|
||||
Python software foundation. This is limited to code in the parser.py
|
||||
module:
|
||||
|
||||
Copyright (c) 2001-2006 Gregory P. Ward. All rights reserved.
|
||||
Copyright (c) 2002-2006 Python Software Foundation. All rights reserved.
|
||||
|
||||
Some rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* The names of the contributors may not be used to endorse or
|
||||
promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,54 @@
|
||||
Copyright 2017- Paul Ganssle <paul@ganssle.io>
|
||||
Copyright 2017- dateutil contributors (see AUTHORS file)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
The above license applies to all contributions after 2017-12-01, as well as
|
||||
all contributions that have been re-licensed (see AUTHORS file for the list of
|
||||
contributors who have re-licensed their code).
|
||||
--------------------------------------------------------------------------------
|
||||
dateutil - Extensions to the standard Python datetime module.
|
||||
|
||||
Copyright (c) 2003-2011 - Gustavo Niemeyer <gustavo@niemeyer.net>
|
||||
Copyright (c) 2012-2014 - Tomi Pieviläinen <tomi.pievilainen@iki.fi>
|
||||
Copyright (c) 2014-2016 - Yaron de Leeuw <me@jarondl.net>
|
||||
Copyright (c) 2015- - Paul Ganssle <paul@ganssle.io>
|
||||
Copyright (c) 2015- - dateutil contributors (see AUTHORS file)
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The above BSD License Applies to all code, even that also covered by Apache 2.0.
|
||||
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2011-2018 Mike Bayer
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author or contributors may not be used to endorse or
|
||||
promote products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
@@ -0,0 +1,13 @@
|
||||
Copyright 2013 Antoine Bertin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,7 @@
|
||||
Copyright (c) 2017 Thomas Roten
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,20 @@
|
||||
Copyright (C) 2013 Rob Speer (rob@luminoso.com)
|
||||
MIT License
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,48 @@
|
||||
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
||||
--------------------------------------------
|
||||
|
||||
1. This LICENSE AGREEMENT is between the Python Software Foundation
|
||||
("PSF"), and the Individual or Organization ("Licensee") accessing and
|
||||
otherwise using this software ("Python") in source or binary form and
|
||||
its associated documentation.
|
||||
|
||||
2. Subject to the terms and conditions of this License Agreement, PSF
|
||||
hereby grants Licensee a nonexclusive, royalty-free, world-wide
|
||||
license to reproduce, analyze, test, perform and/or display publicly,
|
||||
prepare derivative works, distribute, and otherwise use Python
|
||||
alone or in any derivative version, provided, however, that PSF's
|
||||
License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
|
||||
2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights
|
||||
Reserved" are retained in Python alone or in any derivative version
|
||||
prepared by Licensee.
|
||||
|
||||
3. In the event Licensee prepares a derivative work that is based on
|
||||
or incorporates Python or any part thereof, and wants to make
|
||||
the derivative work available to others as provided herein, then
|
||||
Licensee hereby agrees to include in any such work a brief summary of
|
||||
the changes made to Python.
|
||||
|
||||
4. PSF is making Python available to Licensee on an "AS IS"
|
||||
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
|
||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
|
||||
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
|
||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
6. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
|
||||
7. Nothing in this License Agreement shall be deemed to create any
|
||||
relationship of agency, partnership, or joint venture between PSF and
|
||||
Licensee. This License Agreement does not grant permission to use PSF
|
||||
trademarks or trade name in a trademark sense to endorse or promote
|
||||
products or services of Licensee, or any third party.
|
||||
|
||||
8. By copying, installing or otherwise using Python, Licensee
|
||||
agrees to be bound by the terms and conditions of this License
|
||||
Agreement.
|
||||
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2006-2013 James Graham and other contributors
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
---------- Revised BSD License ----------
|
||||
|
||||
Copyright (c) 2018, Mark V.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the organization nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Dean Gardiner
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Dean Gardiner
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2015 by Stefan Lehmann
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2011-12, Arun K R <the1.arun@gmail.com>.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are
|
||||
those of the authors and should not be interpreted as representing official
|
||||
policies, either expressed or implied, of Arun K R <the1.arun@gmail.com>.
|
||||
@@ -0,0 +1,675 @@
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. [http://fsf.org/]
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {name of author}
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see [http://www.gnu.org/licenses/].
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
{project} Copyright (C) {year} {fullname}
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
[http://www.gnu.org/licenses/].
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
[http://www.gnu.org/philosophy/why-not-lgpl.html].
|
||||
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2014-2017 Tomas Karabela
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,279 @@
|
||||
A. HISTORY OF THE SOFTWARE
|
||||
==========================
|
||||
|
||||
Python was created in the early 1990s by Guido van Rossum at Stichting
|
||||
Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
|
||||
as a successor of a language called ABC. Guido remains Python's
|
||||
principal author, although it includes many contributions from others.
|
||||
|
||||
In 1995, Guido continued his work on Python at the Corporation for
|
||||
National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
|
||||
in Reston, Virginia where he released several versions of the
|
||||
software.
|
||||
|
||||
In May 2000, Guido and the Python core development team moved to
|
||||
BeOpen.com to form the BeOpen PythonLabs team. In October of the same
|
||||
year, the PythonLabs team moved to Digital Creations (now Zope
|
||||
Corporation, see http://www.zope.com). In 2001, the Python Software
|
||||
Foundation (PSF, see http://www.python.org/psf/) was formed, a
|
||||
non-profit organization created specifically to own Python-related
|
||||
Intellectual Property. Zope Corporation is a sponsoring member of
|
||||
the PSF.
|
||||
|
||||
All Python releases are Open Source (see http://www.opensource.org for
|
||||
the Open Source Definition). Historically, most, but not all, Python
|
||||
releases have also been GPL-compatible; the table below summarizes
|
||||
the various releases.
|
||||
|
||||
Release Derived Year Owner GPL-
|
||||
from compatible? (1)
|
||||
|
||||
0.9.0 thru 1.2 1991-1995 CWI yes
|
||||
1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
|
||||
1.6 1.5.2 2000 CNRI no
|
||||
2.0 1.6 2000 BeOpen.com no
|
||||
1.6.1 1.6 2001 CNRI yes (2)
|
||||
2.1 2.0+1.6.1 2001 PSF no
|
||||
2.0.1 2.0+1.6.1 2001 PSF yes
|
||||
2.1.1 2.1+2.0.1 2001 PSF yes
|
||||
2.2 2.1.1 2001 PSF yes
|
||||
2.1.2 2.1.1 2002 PSF yes
|
||||
2.1.3 2.1.2 2002 PSF yes
|
||||
2.2.1 2.2 2002 PSF yes
|
||||
2.2.2 2.2.1 2002 PSF yes
|
||||
2.2.3 2.2.2 2003 PSF yes
|
||||
2.3 2.2.2 2002-2003 PSF yes
|
||||
2.3.1 2.3 2002-2003 PSF yes
|
||||
2.3.2 2.3.1 2002-2003 PSF yes
|
||||
2.3.3 2.3.2 2002-2003 PSF yes
|
||||
2.3.4 2.3.3 2004 PSF yes
|
||||
2.3.5 2.3.4 2005 PSF yes
|
||||
2.4 2.3 2004 PSF yes
|
||||
2.4.1 2.4 2005 PSF yes
|
||||
2.4.2 2.4.1 2005 PSF yes
|
||||
2.4.3 2.4.2 2006 PSF yes
|
||||
2.4.4 2.4.3 2006 PSF yes
|
||||
2.5 2.4 2006 PSF yes
|
||||
2.5.1 2.5 2007 PSF yes
|
||||
2.5.2 2.5.1 2008 PSF yes
|
||||
2.5.3 2.5.2 2008 PSF yes
|
||||
2.6 2.5 2008 PSF yes
|
||||
2.6.1 2.6 2008 PSF yes
|
||||
2.6.2 2.6.1 2009 PSF yes
|
||||
2.6.3 2.6.2 2009 PSF yes
|
||||
2.6.4 2.6.3 2009 PSF yes
|
||||
2.6.5 2.6.4 2010 PSF yes
|
||||
2.7 2.6 2010 PSF yes
|
||||
|
||||
Footnotes:
|
||||
|
||||
(1) GPL-compatible doesn't mean that we're distributing Python under
|
||||
the GPL. All Python licenses, unlike the GPL, let you distribute
|
||||
a modified version without making your changes open source. The
|
||||
GPL-compatible licenses make it possible to combine Python with
|
||||
other software that is released under the GPL; the others don't.
|
||||
|
||||
(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
|
||||
because its license has a choice of law clause. According to
|
||||
CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
|
||||
is "not incompatible" with the GPL.
|
||||
|
||||
Thanks to the many outside volunteers who have worked under Guido's
|
||||
direction to make these releases possible.
|
||||
|
||||
|
||||
B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
|
||||
===============================================================
|
||||
|
||||
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
||||
--------------------------------------------
|
||||
|
||||
1. This LICENSE AGREEMENT is between the Python Software Foundation
|
||||
("PSF"), and the Individual or Organization ("Licensee") accessing and
|
||||
otherwise using this software ("Python") in source or binary form and
|
||||
its associated documentation.
|
||||
|
||||
2. Subject to the terms and conditions of this License Agreement, PSF hereby
|
||||
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
|
||||
analyze, test, perform and/or display publicly, prepare derivative works,
|
||||
distribute, and otherwise use Python alone or in any derivative version,
|
||||
provided, however, that PSF's License Agreement and PSF's notice of copyright,
|
||||
i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
2011, 2012 Python Software Foundation; All Rights Reserved" are retained in Python
|
||||
alone or in any derivative version prepared by Licensee.
|
||||
|
||||
3. In the event Licensee prepares a derivative work that is based on
|
||||
or incorporates Python or any part thereof, and wants to make
|
||||
the derivative work available to others as provided herein, then
|
||||
Licensee hereby agrees to include in any such work a brief summary of
|
||||
the changes made to Python.
|
||||
|
||||
4. PSF is making Python available to Licensee on an "AS IS"
|
||||
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
|
||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
|
||||
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
|
||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
6. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
|
||||
7. Nothing in this License Agreement shall be deemed to create any
|
||||
relationship of agency, partnership, or joint venture between PSF and
|
||||
Licensee. This License Agreement does not grant permission to use PSF
|
||||
trademarks or trade name in a trademark sense to endorse or promote
|
||||
products or services of Licensee, or any third party.
|
||||
|
||||
8. By copying, installing or otherwise using Python, Licensee
|
||||
agrees to be bound by the terms and conditions of this License
|
||||
Agreement.
|
||||
|
||||
|
||||
BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
|
||||
-------------------------------------------
|
||||
|
||||
BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
|
||||
|
||||
1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
|
||||
office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
|
||||
Individual or Organization ("Licensee") accessing and otherwise using
|
||||
this software in source or binary form and its associated
|
||||
documentation ("the Software").
|
||||
|
||||
2. Subject to the terms and conditions of this BeOpen Python License
|
||||
Agreement, BeOpen hereby grants Licensee a non-exclusive,
|
||||
royalty-free, world-wide license to reproduce, analyze, test, perform
|
||||
and/or display publicly, prepare derivative works, distribute, and
|
||||
otherwise use the Software alone or in any derivative version,
|
||||
provided, however, that the BeOpen Python License is retained in the
|
||||
Software, alone or in any derivative version prepared by Licensee.
|
||||
|
||||
3. BeOpen is making the Software available to Licensee on an "AS IS"
|
||||
basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
|
||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
|
||||
4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
|
||||
SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
|
||||
AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
|
||||
DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
5. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
|
||||
6. This License Agreement shall be governed by and interpreted in all
|
||||
respects by the law of the State of California, excluding conflict of
|
||||
law provisions. Nothing in this License Agreement shall be deemed to
|
||||
create any relationship of agency, partnership, or joint venture
|
||||
between BeOpen and Licensee. This License Agreement does not grant
|
||||
permission to use BeOpen trademarks or trade names in a trademark
|
||||
sense to endorse or promote products or services of Licensee, or any
|
||||
third party. As an exception, the "BeOpen Python" logos available at
|
||||
http://www.pythonlabs.com/logos.html may be used according to the
|
||||
permissions granted on that web page.
|
||||
|
||||
7. By copying, installing or otherwise using the software, Licensee
|
||||
agrees to be bound by the terms and conditions of this License
|
||||
Agreement.
|
||||
|
||||
|
||||
CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
|
||||
---------------------------------------
|
||||
|
||||
1. This LICENSE AGREEMENT is between the Corporation for National
|
||||
Research Initiatives, having an office at 1895 Preston White Drive,
|
||||
Reston, VA 20191 ("CNRI"), and the Individual or Organization
|
||||
("Licensee") accessing and otherwise using Python 1.6.1 software in
|
||||
source or binary form and its associated documentation.
|
||||
|
||||
2. Subject to the terms and conditions of this License Agreement, CNRI
|
||||
hereby grants Licensee a nonexclusive, royalty-free, world-wide
|
||||
license to reproduce, analyze, test, perform and/or display publicly,
|
||||
prepare derivative works, distribute, and otherwise use Python 1.6.1
|
||||
alone or in any derivative version, provided, however, that CNRI's
|
||||
License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
|
||||
1995-2001 Corporation for National Research Initiatives; All Rights
|
||||
Reserved" are retained in Python 1.6.1 alone or in any derivative
|
||||
version prepared by Licensee. Alternately, in lieu of CNRI's License
|
||||
Agreement, Licensee may substitute the following text (omitting the
|
||||
quotes): "Python 1.6.1 is made available subject to the terms and
|
||||
conditions in CNRI's License Agreement. This Agreement together with
|
||||
Python 1.6.1 may be located on the Internet using the following
|
||||
unique, persistent identifier (known as a handle): 1895.22/1013. This
|
||||
Agreement may also be obtained from a proxy server on the Internet
|
||||
using the following URL: http://hdl.handle.net/1895.22/1013".
|
||||
|
||||
3. In the event Licensee prepares a derivative work that is based on
|
||||
or incorporates Python 1.6.1 or any part thereof, and wants to make
|
||||
the derivative work available to others as provided herein, then
|
||||
Licensee hereby agrees to include in any such work a brief summary of
|
||||
the changes made to Python 1.6.1.
|
||||
|
||||
4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
|
||||
basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
|
||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
|
||||
5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||
1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
|
||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
6. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
|
||||
7. This License Agreement shall be governed by the federal
|
||||
intellectual property law of the United States, including without
|
||||
limitation the federal copyright law, and, to the extent such
|
||||
U.S. federal law does not apply, by the law of the Commonwealth of
|
||||
Virginia, excluding Virginia's conflict of law provisions.
|
||||
Notwithstanding the foregoing, with regard to derivative works based
|
||||
on Python 1.6.1 that incorporate non-separable material that was
|
||||
previously distributed under the GNU General Public License (GPL), the
|
||||
law of the Commonwealth of Virginia shall govern this License
|
||||
Agreement only as to issues arising under or with respect to
|
||||
Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
|
||||
License Agreement shall be deemed to create any relationship of
|
||||
agency, partnership, or joint venture between CNRI and Licensee. This
|
||||
License Agreement does not grant permission to use CNRI trademarks or
|
||||
trade name in a trademark sense to endorse or promote products or
|
||||
services of Licensee, or any third party.
|
||||
|
||||
8. By clicking on the "ACCEPT" button where indicated, or by copying,
|
||||
installing or otherwise using Python 1.6.1, Licensee agrees to be
|
||||
bound by the terms and conditions of this License Agreement.
|
||||
|
||||
ACCEPT
|
||||
|
||||
|
||||
CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
|
||||
--------------------------------------------------
|
||||
|
||||
Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
|
||||
The Netherlands. All rights reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Stichting Mathematisch
|
||||
Centrum or CWI not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior
|
||||
permission.
|
||||
|
||||
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
||||
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2003-2017 Stuart Bishop <stuart@stuartbishop.net>
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
Copyright (c) 2005-2016 Marko Kreen <markokr@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Rémi Alvergnat
|
||||
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
Copyright 2017 Kenneth Reitz
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,13 @@
|
||||
Copyright 2014 invl
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2012, Ben Hoyt
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Ben Hoyt nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user