Compare commits
147 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be477f2433 | ||
|
|
d3a3e27649 | ||
|
|
c832f74a26 | ||
|
|
721aa664a8 | ||
|
|
96982d52f1 | ||
|
|
a59d711c1e | ||
|
|
0559903fd6 | ||
|
|
a904c6a62e | ||
|
|
d73e144511 | ||
|
|
4730138dc1 | ||
|
|
6dd37bd8d2 | ||
|
|
05452e6f46 | ||
|
|
b7593b4042 | ||
|
|
000a48cc57 | ||
|
|
a89d0a6dc2 | ||
|
|
caa014a0ac | ||
|
|
8199642f35 | ||
|
|
da6525120d | ||
|
|
362760d3ab | ||
|
|
1cce67702d | ||
|
|
ff761dd088 | ||
|
|
beda70b1f9 | ||
|
|
eb9eb2009f | ||
|
|
73bcfef007 | ||
|
|
3104d5aec9 | ||
|
|
0d3c39cc0a | ||
|
|
e57059cf3c | ||
|
|
18e9a99d17 | ||
|
|
7b7549fef0 | ||
|
|
251f43fb77 | ||
|
|
6c4077b143 | ||
|
|
00a7e92ef7 | ||
|
|
61c1a3db8e | ||
|
|
bdcd65d6c9 | ||
|
|
f7a427b809 | ||
|
|
e96e727c7c | ||
|
|
f2ea26b529 | ||
|
|
7b10c48e8f | ||
|
|
0c71e82675 | ||
|
|
7fa7c8f9f8 | ||
|
|
102eb934af | ||
|
|
099e0193e9 | ||
|
|
c68b4bf392 | ||
|
|
14b2a10fdf | ||
|
|
a9ba96e08b | ||
|
|
d4c3ebab24 | ||
|
|
4f5396f945 | ||
|
|
59a5f72f7c | ||
|
|
47fbf495f1 | ||
|
|
55529f49e3 | ||
|
|
dd0f410161 | ||
|
|
6ee2f9c962 | ||
|
|
f24e20a902 | ||
|
|
1cf0155622 | ||
|
|
aa208d2ae5 | ||
|
|
1d8b9824ad | ||
|
|
bd1917a8a7 | ||
|
|
50a43e8e01 | ||
|
|
bee8be9698 | ||
|
|
774c9ba12d | ||
|
|
8be5c1b9eb | ||
|
|
9ada09e809 | ||
|
|
007a997f8f | ||
|
|
d70f9290f5 | ||
|
|
d32be4aba7 | ||
|
|
359dd05972 | ||
|
|
c005d331ee | ||
|
|
e51f136c4e | ||
|
|
95ee6e4e24 | ||
|
|
677d3a4a76 | ||
|
|
bd9f63de4c | ||
|
|
0a51bd366e | ||
|
|
2c959b0e00 | ||
|
|
291c3533e2 | ||
|
|
6080a3e6ec | ||
|
|
97785abff4 | ||
|
|
511f44e806 | ||
|
|
f5a97b4730 | ||
|
|
a47ba79413 | ||
|
|
429eaf76a5 | ||
|
|
da9136a08b | ||
|
|
cb0097a4e0 | ||
|
|
f66d2c55ca | ||
|
|
a30e58677d | ||
|
|
11d1898dc2 | ||
|
|
24548a081c | ||
|
|
09982b9f60 | ||
|
|
b56036b71e | ||
|
|
52fe89170f | ||
|
|
474043a569 | ||
|
|
7451605dbb | ||
|
|
860c487074 | ||
|
|
b1303413c6 | ||
|
|
6ad76560ed | ||
|
|
d6f449930c | ||
|
|
ebdf501115 | ||
|
|
34861fb9b9 | ||
|
|
2f3fe8ae6b | ||
|
|
4ee91654ea | ||
|
|
3190658e0c | ||
|
|
c330523b9e | ||
|
|
5a5c865135 | ||
|
|
f5ae301c97 | ||
|
|
d910441470 | ||
|
|
b667bf4117 | ||
|
|
4d8b4c9d43 | ||
|
|
02c44eef82 | ||
|
|
c21d10d7f9 | ||
|
|
d2d14e4c19 | ||
|
|
1da8bca9d1 | ||
|
|
dffbfd8860 | ||
|
|
7247c51b10 | ||
|
|
2517e30f55 | ||
|
|
caa0e47399 | ||
|
|
8ce6ec49e1 | ||
|
|
276b18650c | ||
|
|
a69a8a269f | ||
|
|
921628b2a1 | ||
|
|
53225b427c | ||
|
|
6aad1eb92d | ||
|
|
d4bccb9b05 | ||
|
|
02e9886e2e | ||
|
|
a05363d202 | ||
|
|
78fd1e206b | ||
|
|
74951b9dec | ||
|
|
5ac21ea240 | ||
|
|
086e92da4b | ||
|
|
e54c4c1bec | ||
|
|
5bb20e482f | ||
|
|
569462f755 | ||
|
|
658050548c | ||
|
|
4d635f6eb4 | ||
|
|
a0b1e9177b | ||
|
|
7a1a7843e6 | ||
|
|
66d4e02024 | ||
|
|
04a46f0cd9 | ||
|
|
4e0ac5330f | ||
|
|
32288aba97 | ||
|
|
801f119a5c | ||
|
|
567a02872b | ||
|
|
cfc19cafc5 | ||
|
|
44823f5043 | ||
|
|
bad5f8e561 | ||
|
|
075e1e8974 | ||
|
|
06f78ce620 | ||
|
|
cce9acb182 | ||
|
|
048b8f0385 |
2
.github/tools/reformat_changelog.py
vendored
2
.github/tools/reformat_changelog.py
vendored
@@ -23,7 +23,7 @@ class SectionType(TypedDict):
|
||||
|
||||
def reformat(item_format: str, output_emoji: bool) -> None:
|
||||
data = [
|
||||
emojize(x.strip(), use_aliases=True, variant="emoji_type")
|
||||
emojize(x.strip(), variant="emoji_type")
|
||||
for x in sys.stdin.readlines()
|
||||
if x.strip()
|
||||
]
|
||||
|
||||
2
.github/workflows/build.yaml
vendored
2
.github/workflows/build.yaml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python 3.x
|
||||
uses: actions/setup-python@v3
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
|
||||
2
.github/workflows/codeql.yaml
vendored
2
.github/workflows/codeql.yaml
vendored
@@ -30,7 +30,7 @@ jobs:
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v3
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.version }}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Update Draft
|
||||
uses: release-drafter/release-drafter@v5.20.0
|
||||
uses: release-drafter/release-drafter@v5.21.1
|
||||
id: draft
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}
|
||||
|
||||
6
.github/workflows/publish.yaml
vendored
6
.github/workflows/publish.yaml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
py_version: [ 'py2', 'py3' ]
|
||||
steps:
|
||||
- name: Update Draft
|
||||
uses: release-drafter/release-drafter@v5.20.0
|
||||
uses: release-drafter/release-drafter@v5.21.1
|
||||
if: ${{ matrix.py_version == 'py3' }}
|
||||
with:
|
||||
publish: true
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python 3.x
|
||||
uses: actions/setup-python@v3
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
remote_key: ${{ secrets.DEPLOY_KEY }}
|
||||
|
||||
- name: Add to Kodi repo and clean up
|
||||
uses: appleboy/ssh-action@v0.1.4
|
||||
uses: appleboy/ssh-action@v0.1.5
|
||||
with:
|
||||
host: ${{ secrets.DEPLOY_HOST }}
|
||||
username: ${{ secrets.DEPLOY_USER }}
|
||||
|
||||
2
.github/workflows/release-drafter.yaml
vendored
2
.github/workflows/release-drafter.yaml
vendored
@@ -11,6 +11,6 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Update Release Draft
|
||||
uses: release-drafter/release-drafter@v5.20.0
|
||||
uses: release-drafter/release-drafter@v5.21.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}
|
||||
|
||||
2
.github/workflows/test.yaml
vendored
2
.github/workflows/test.yaml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python ${{ matrix.py_version }}
|
||||
uses: actions/setup-python@v3
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.py_version }}
|
||||
|
||||
|
||||
43
README.md
43
README.md
@@ -1,6 +1,47 @@
|
||||
# JellyCon
|
||||
|
||||
JellyCon is a lightweight Kodi addon that lets you browse and play media files from your Jellyfin server directly within the Kodi interface.
|
||||
JellyCon is a lightweight Kodi add-on that lets you browse and play media files directly from your Jellyfin server within the Kodi interface. It can be thought of as a thin frontend for a Jellyfin server.
|
||||
|
||||
JellyCon can be used with Movie, TV Show, Music Video, and Music libraries, in addition to viewing LiveTV from the server. It can easily switch between multiple user accounts at will. It's easy to integrate with any customizable Kodi skin with a large collection of custom menus. Media items are populated from the server dynamically, and menu speed will vary based on local device speed.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
#### 1. Adding the Jellyfin repository
|
||||
|
||||
https://jellyfin.org/docs/general/clients/kodi.html#install-add-on-repository
|
||||
|
||||
#### 2. Install JellyCon Add-on
|
||||
|
||||
- From within Kodi, navigate to "Add-on Browser"
|
||||
- Select "Install from Repository"
|
||||
- Choose "Kodi Jellyfin Add-ons", followed by "Video Add-ons"
|
||||
- Select the JellyCon add-on and choose install
|
||||
|
||||
#### 3. Login
|
||||
|
||||
- Within a few seconds after the installation you should be prompted for your server details.
|
||||
- If a Jellyfin server is detected on your local network, it will displayed in a dialog. Otherwise, you will be prompted to enter the URL of your Jellyfin server
|
||||
- If Quick Connect is enabled in the server, a code will be displayed that you can use to log in via Quick Connect in the web UI or a mobile app.
|
||||
- If Quick Connect is not enabled, or if you select the "Manual Login" button, you will be able to select a user from the list, or manually login using your username and password.
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
#### Configuring Home
|
||||
|
||||
Many Kodi skins allow for customizing of the home menu with custom nodes and widgets. However, all of these use slightly different layouts and terminology. Rather than a step by step guide, this section serves as an barebones introduction to customizing a skin.
|
||||
Examples
|
||||
|
||||
If you would like a link on the home screen to open a library in your Jellyfin server called "Kid's Movies", you would point the menu item to the path: Add-On -> Video Add-On -> JellyCon -> Jellyfin Libraries -> Kid's Movies -> Create menu item to here.
|
||||
|
||||
Beyond just modifying where the home menu headers go, many skins also allow you to use widgets. Widgets help populate the home screen with data, often the posters of media in the selected image. If you would like to display the most recent movies across all of your Jellyfin libraries on the home screen, the path would be: Add-On -> Video Add-On -> JellyCon -> Global Lists -> Movies -> Movies - Recently Added (20) -> Use as widget
|
||||
|
||||
Another common use case of widgets would be to display the next available episodes of shows that you may be watching. As above, this can be done both with individual libraries or with all libraries combined:
|
||||
|
||||
Add-On -> Video Add-On -> JellyCon -> Jellyfin Libraries -> Anime -> Anime - Next Up (20) -> Use as widget
|
||||
Add-On -> Video Add-On -> JellyCon -> Global Lists -> TV Shows -> TV Shows - Next Up (20) -> Use as widget
|
||||
|
||||
|
||||
## License
|
||||
|
||||
|
||||
12
build.py
12
build.py
@@ -35,7 +35,7 @@ def create_addon_xml(config: dict, source: str, py_version: str) -> None:
|
||||
Create addon.xml from template file
|
||||
"""
|
||||
# Load template file
|
||||
with open('{}/.config/template.xml'.format(source), 'r') as f:
|
||||
with open(f'{source}/.config/template.xml', 'r') as f:
|
||||
tree = ET.parse(f)
|
||||
root = tree.getroot()
|
||||
|
||||
@@ -46,7 +46,7 @@ def create_addon_xml(config: dict, source: str, py_version: str) -> None:
|
||||
|
||||
# Populate version string
|
||||
addon_version = config.get('version')
|
||||
root.attrib['version'] = '{}+{}'.format(addon_version, py_version)
|
||||
root.attrib['version'] = f'{addon_version}+{py_version}'
|
||||
|
||||
# Populate Changelog
|
||||
date = datetime.today().strftime('%Y-%m-%d')
|
||||
@@ -54,22 +54,22 @@ def create_addon_xml(config: dict, source: str, py_version: str) -> None:
|
||||
for section in root.findall('extension'):
|
||||
news = section.findall('news')
|
||||
if news:
|
||||
news[0].text = 'v{} ({}):\n{}'.format(addon_version, date, changelog)
|
||||
news[0].text = f'v{addon_version} ({date}):\n{changelog}'
|
||||
|
||||
# Format xml tree
|
||||
indent(root)
|
||||
|
||||
# Write addon.xml
|
||||
tree.write('{}/addon.xml'.format(source), encoding='utf-8', xml_declaration=True)
|
||||
tree.write(f'{source}/addon.xml', encoding='utf-8', xml_declaration=True)
|
||||
|
||||
|
||||
def zip_files(py_version: str, source: str, target: str, dev: bool) -> None:
|
||||
"""
|
||||
Create installable addon zip archive
|
||||
"""
|
||||
archive_name = 'plugin.video.jellycon+{}.zip'.format(py_version)
|
||||
archive_name = f'plugin.video.jellycon+{py_version}.zip'
|
||||
|
||||
with zipfile.ZipFile('{}/{}'.format(target, archive_name), 'w') as z:
|
||||
with zipfile.ZipFile(f'{target}/{archive_name}', 'w') as z:
|
||||
for root, dirs, files in os.walk(args.source):
|
||||
for filename in filter(file_filter, files):
|
||||
file_path = os.path.join(root, filename)
|
||||
|
||||
53
release.yaml
53
release.yaml
@@ -1,60 +1,17 @@
|
||||
version: '0.5.0'
|
||||
version: '0.6.1'
|
||||
changelog: |-
|
||||
New features and improvements
|
||||
-----------------------------
|
||||
+ Make sure manual login shows when connecting to a 10.7 server (#167) @mcarlton00
|
||||
+ Add genres and alpha picker to music (#161) @mcarlton00
|
||||
+ Add button to the bitrate selector (#160) @mcarlton00
|
||||
+ Add quick connect authentication (#159) @mcarlton00
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
+ Fix playing all files (#162) @mcarlton00
|
||||
+ Ensure server is present in API requests (#157) @mcarlton00
|
||||
+ Fix errors when stopping transcoded playback (#156) @mcarlton00
|
||||
+ Fix content update checks (#155) @mcarlton00
|
||||
+ Fix stale data after storage migration (#153) @mcarlton00
|
||||
+ Fix legacy skin shortcuts (#150) @mcarlton00
|
||||
+ Use timezone when calculating last activity date (#147) @mcarlton00
|
||||
+ Fix live tv playback (#144) @mcarlton00
|
||||
+ Fix browsing the Live TV programs menu (#145) @mcarlton00
|
||||
+ Force login if no saved credentials (#139) @mcarlton00
|
||||
+ Fix movie recommendations (#132) @mcarlton00
|
||||
+ Fix remote control (#134) @mcarlton00
|
||||
+ Don't throw errors when non-JellyCon content is playing (#135) @mcarlton00
|
||||
+ Fallback to empty lists instead of failing (#136) @mcarlton00
|
||||
+ Make widgets respect episode name format setting (#137) @mcarlton00
|
||||
+ Make requests respect the verify certificate setting (#131) @mcarlton00
|
||||
+ Fix manual user login (#123) @mcarlton00
|
||||
+ Rework user data storage (#119) @mcarlton00
|
||||
+ Initialize variable before it's used (#238) @mcarlton00
|
||||
+ Don't crash if quickconnect is disabled on the server (#235) @mcarlton00
|
||||
|
||||
Code or Repo Maintenance
|
||||
------------------------
|
||||
+ Use offscreen option when generating all listitems (#168) @mcarlton00
|
||||
+ Remove safe delete code (#166) @mcarlton00
|
||||
+ Address flake8 warnings (#165) @mcarlton00
|
||||
+ Simplify url param dict definitions (#164) @mcarlton00
|
||||
+ Optimize loops while building menus (#163) @mcarlton00
|
||||
+ Verify certificates by default (#154) @mcarlton00
|
||||
+ Rework live tv playback (#148) @mcarlton00
|
||||
+ Remove trakt integration (#133) @mcarlton00
|
||||
+ Copy translate_path from Jf4Kodi, fix LazyLogger (#130) @oddstr13
|
||||
+ Rework the network stack (#124) @mcarlton00
|
||||
+ Rework user data storage (#119) @mcarlton00
|
||||
+ Code reorganizing (#111) @mcarlton00
|
||||
+ Remove unused and commented out code (#109) @mcarlton00
|
||||
+ refact: use f-string instead of format (#239) @EwertonBello
|
||||
|
||||
CI & build changes
|
||||
------------------
|
||||
+ Bump release-drafter/release-drafter from 5.19.0 to 5.20.0 (#152) @dependabot
|
||||
+ Bump github/codeql-action from 1 to 2 (#143) @dependabot
|
||||
+ Bump actions/upload-artifact from 2 to 3 (#141) @dependabot
|
||||
+ Bump release-drafter/release-drafter from 5.18.1 to 5.19.0 (#138) @dependabot
|
||||
+ Bump actions/checkout from 2 to 3 (#127) @dependabot
|
||||
+ Bump actions/setup-python from 2 to 3 (#126) @dependabot
|
||||
+ Bump release-drafter/release-drafter from 5.17.5 to 5.18.1 (#122) @dependabot
|
||||
+ Bump release-drafter/release-drafter from 5.15.0 to 5.17.5 (#118) @dependabot
|
||||
+ Bump burnett01/rsync-deployments from 5.1 to 5.2 (#113) @dependabot
|
||||
+ Bump release-drafter/release-drafter from 5.21.0 to 5.21.1 (#234) @dependabot
|
||||
dependencies:
|
||||
py2:
|
||||
- addon: 'xbmc.python'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-06-09 21:22+0000\n"
|
||||
"PO-Revision-Date: 2022-08-25 20:11+0000\n"
|
||||
"Last-Translator: DJSweder <djsweder@gmail.com>\n"
|
||||
"Language-Team: Czech <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/cs/>\n"
|
||||
@@ -9,7 +9,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 4.10.1\n"
|
||||
"X-Generator: Weblate 4.13.1\n"
|
||||
|
||||
msgctxt "#30016"
|
||||
msgid "Device display name"
|
||||
@@ -58,3 +58,43 @@ msgstr "Port"
|
||||
msgctxt "#30000"
|
||||
msgid "Host"
|
||||
msgstr "Hostitel"
|
||||
|
||||
msgctxt "#30027"
|
||||
msgid "Enable debug logging"
|
||||
msgstr "Povolit protokolování ladění"
|
||||
|
||||
msgctxt "#30026"
|
||||
msgid "Widget item select action"
|
||||
msgstr "Akce pro výběr položky widgetu"
|
||||
|
||||
msgctxt "#30025"
|
||||
msgid "Password:"
|
||||
msgstr "Heslo:"
|
||||
|
||||
msgctxt "#30024"
|
||||
msgid "Username:"
|
||||
msgstr "Uživatelské jméno:"
|
||||
|
||||
msgctxt "#30023"
|
||||
msgid "Hide unwatched episode details"
|
||||
msgstr "Schovat podrobnosti nezhlédnutých epizod"
|
||||
|
||||
msgctxt "#30022"
|
||||
msgid "Advanced"
|
||||
msgstr "Pokročilé"
|
||||
|
||||
msgctxt "#30021"
|
||||
msgid "Show all episodes item"
|
||||
msgstr "Zobrazit všechny epizody"
|
||||
|
||||
msgctxt "#30019"
|
||||
msgid "Filtered episode name format"
|
||||
msgstr "Formát názvu filtrované epizody"
|
||||
|
||||
msgctxt "#30018"
|
||||
msgid "Number of items to show in filtered lists"
|
||||
msgstr "Počet položek k zobrazení ve filtrovaném seznamu"
|
||||
|
||||
msgctxt "#30017"
|
||||
msgid "Show connected clients"
|
||||
msgstr "Zobrazit připojené klienty"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-06-12 12:22+0000\n"
|
||||
"Last-Translator: Moritz <moritz.leick@googlemail.com>\n"
|
||||
"PO-Revision-Date: 2022-10-04 05:54+0000\n"
|
||||
"Last-Translator: Adammantium <flubber98@web.de>\n"
|
||||
"Language-Team: German <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/de/>\n"
|
||||
"Language: de\n"
|
||||
@@ -9,7 +9,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.10.1\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
msgctxt "#30120"
|
||||
msgid "Show load progress"
|
||||
@@ -1105,3 +1105,15 @@ msgstr "Schnellverbindung"
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Künstler"
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "Wiedergabe fortsetzen"
|
||||
|
||||
msgctxt "#30446"
|
||||
msgid "There was an error logging in"
|
||||
msgstr "Bei der Anmeldung ist ein Fehler aufgetreten"
|
||||
|
||||
msgctxt "#30439"
|
||||
msgid "Show play next episode at time left in seconds"
|
||||
msgstr "Zeige \"Nächste Episode\" bei verbleibender Zeit in Sekunden"
|
||||
|
||||
@@ -1077,8 +1077,8 @@ msgid "Play cinema intros"
|
||||
msgstr "Play cinema intros"
|
||||
|
||||
msgctxt "#30439"
|
||||
msgid "Show play next episode at time left"
|
||||
msgstr "Show play next episode at time left"
|
||||
msgid "Show play next episode at time left in seconds"
|
||||
msgstr "Show play next episode at time left in seconds"
|
||||
|
||||
msgctxt "#30440"
|
||||
msgid "Play next"
|
||||
@@ -1099,3 +1099,12 @@ msgstr "Quick Connect"
|
||||
msgctxt "#30444"
|
||||
msgid "Login using Quick Connect"
|
||||
msgstr "Login using Quick Connect"
|
||||
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "Continue Watching"
|
||||
|
||||
msgctxt "#30446"
|
||||
msgid "There was an error logging in"
|
||||
msgstr "There was an error logging in"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-06-08 04:22+0000\n"
|
||||
"PO-Revision-Date: 2022-08-10 20:22+0000\n"
|
||||
"Last-Translator: WWWesten <wwwesten@gmail.com>\n"
|
||||
"Language-Team: Esperanto <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/eo/>\n"
|
||||
@@ -1097,3 +1097,7 @@ msgstr "Rapida Konekto"
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Artistoj"
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "Daŭrigi Spektadon"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-05-17 04:13+0000\n"
|
||||
"Last-Translator: José Albano <josealbano@disroot.org>\n"
|
||||
"PO-Revision-Date: 2022-09-24 20:54+0000\n"
|
||||
"Last-Translator: Ariel Martín Estévez <arudamartineti@gmail.com>\n"
|
||||
"Language-Team: Spanish <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/es/>\n"
|
||||
"Language: es\n"
|
||||
@@ -9,7 +9,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.10.1\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
msgctxt "#30442"
|
||||
msgid "Simple new content check"
|
||||
@@ -1080,7 +1080,7 @@ msgstr "Frecuencia de registro de datos"
|
||||
|
||||
msgctxt "#30000"
|
||||
msgid "Host"
|
||||
msgstr "Host"
|
||||
msgstr "Anfitrión"
|
||||
|
||||
msgctxt "#30276"
|
||||
msgid "Extra Resume Prompt Detected"
|
||||
@@ -1089,3 +1089,23 @@ msgstr "Detectada solicitud adicional a reanudar"
|
||||
msgctxt "#30260"
|
||||
msgid "BoxSets"
|
||||
msgstr "Colecciones"
|
||||
|
||||
msgctxt "#30444"
|
||||
msgid "Login using Quick Connect"
|
||||
msgstr "Inicia sesión usando Conexión Rápida"
|
||||
|
||||
msgctxt "#30443"
|
||||
msgid "Quick Connect"
|
||||
msgstr "Conexión rápida"
|
||||
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Artistas"
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "Continuar viendo"
|
||||
|
||||
msgctxt "#30439"
|
||||
msgid "Show play next episode at time left in seconds"
|
||||
msgstr "Mostrar reproducir el próximo episodio a los segundos restantes"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-06-12 12:22+0000\n"
|
||||
"PO-Revision-Date: 2022-10-04 05:54+0000\n"
|
||||
"Last-Translator: Oskari Lavinto <olavinto@protonmail.com>\n"
|
||||
"Language-Team: Finnish <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/fi/>\n"
|
||||
@@ -9,7 +9,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.10.1\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
msgctxt "#30442"
|
||||
msgid "Simple new content check"
|
||||
@@ -1099,3 +1099,17 @@ msgstr "Pikayhdistys"
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Esittäjät"
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "Jatka katselua"
|
||||
|
||||
msgctxt "#30439"
|
||||
msgid "Show play next episode at time left in seconds"
|
||||
msgstr ""
|
||||
"Nykyisen jakson jäljellä oelva toistoaika sekunteina, jolloin näytetään "
|
||||
"ilmoitus seuraavasta jaksosta"
|
||||
|
||||
msgctxt "#30446"
|
||||
msgid "There was an error logging in"
|
||||
msgstr "Kirjauduttaessa tapahtui virhe"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-05-20 04:22+0000\n"
|
||||
"Last-Translator: MoFanFr <hennebelle.benoit@gmail.com>\n"
|
||||
"PO-Revision-Date: 2022-10-26 13:50+0000\n"
|
||||
"Last-Translator: Kilian <kilian.pichard@protonmail.com>\n"
|
||||
"Language-Team: French <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/fr/>\n"
|
||||
"Language: fr\n"
|
||||
@@ -9,7 +9,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 4.10.1\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
msgctxt "#30018"
|
||||
msgid "Number of items to show in filtered lists"
|
||||
@@ -151,7 +151,7 @@ msgstr "Interface"
|
||||
|
||||
msgctxt "#30091"
|
||||
msgid "Confirm delete?"
|
||||
msgstr "Confirmer la suppression ?"
|
||||
msgstr "Confirmer la suppression ?"
|
||||
|
||||
msgctxt "#30052"
|
||||
msgid "Deleting"
|
||||
@@ -169,10 +169,9 @@ msgctxt "#30210"
|
||||
msgid "HTTP direct stream"
|
||||
msgstr "Stream direct HTTP"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30208"
|
||||
msgid "Max stream bitrate (Kbits)"
|
||||
msgstr "Bitrate maximum du flux (Kbps)"
|
||||
msgstr "Débit maximum du flux (Kbps)"
|
||||
|
||||
msgctxt "#30207"
|
||||
msgid "Playback"
|
||||
@@ -734,17 +733,14 @@ msgctxt "#30349"
|
||||
msgid " - Recently Played"
|
||||
msgstr "- Lus récemment"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30347"
|
||||
msgid "Getting Existing Images"
|
||||
msgstr "Récupération des images existantes"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30346"
|
||||
msgid "Deleteing Cached Images"
|
||||
msgstr "Suppression des images en cache"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30345"
|
||||
msgid "Cache Jellyfin server data requests"
|
||||
msgstr "Garder les requêtes de données serveur de Jellyfin en cache"
|
||||
@@ -761,7 +757,6 @@ msgctxt "#30322"
|
||||
msgid "Auto resume"
|
||||
msgstr "Reprise automatique"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30314"
|
||||
msgid "Play"
|
||||
msgstr "Lecture"
|
||||
@@ -899,31 +894,224 @@ msgctxt "#30126"
|
||||
msgid "Processing Item : "
|
||||
msgstr "Traitement de l'élément :"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30356"
|
||||
msgid "Loading existing image list"
|
||||
msgstr "Chargement de la liste des images existantes"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30354"
|
||||
msgid "Go To Series"
|
||||
msgstr "Voir les Séries"
|
||||
msgstr "Voir les Séries"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30319"
|
||||
msgid "Music - All Album Artists"
|
||||
msgstr "Musique - Tous les Albums par Artistes"
|
||||
msgstr "Musique - Tous les Artistes de l'Album"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30343"
|
||||
msgid "Changes Require Kodi Restart"
|
||||
msgstr "Les modifications nécessite le redémarrage de Kodi"
|
||||
msgstr "Les modifications nécessitent le redémarrage de Kodi"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30341"
|
||||
msgid "Background image update interval (0 = disabled)"
|
||||
msgstr "Intervalle de mise à jours des imades en arrière plan (0=désactivé)"
|
||||
msgstr "Intervalle de mise à jour des images en arrière plan (0=désactivé)"
|
||||
|
||||
msgctxt "#30333"
|
||||
msgid "Cache artwork in the background"
|
||||
msgstr "Mise en cache des illustrations en arrière plan"
|
||||
|
||||
msgctxt "#30366"
|
||||
msgid "Manually enter user details"
|
||||
msgstr "Renseigner manuellement les détails utilisateurs"
|
||||
|
||||
msgctxt "#30359"
|
||||
msgid "Building full image list"
|
||||
msgstr "Construction de la liste complète des images"
|
||||
|
||||
msgctxt "#30358"
|
||||
msgid "Retreiving remote image list"
|
||||
msgstr "Récupération de la liste des images distantes"
|
||||
|
||||
msgctxt "#30357"
|
||||
msgid "Processing existing image list"
|
||||
msgstr "Traitement de la liste des images existantes"
|
||||
|
||||
msgctxt "#30355"
|
||||
msgid "Kodi Settings->Services->Allow remote control via HTTP"
|
||||
msgstr "Paramètres de Kodi->Services->Autoriser le contrôle à distance par HTTP"
|
||||
|
||||
msgctxt "#30348"
|
||||
msgid "Add user ratings"
|
||||
msgstr "Ajouter une note"
|
||||
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Artistes"
|
||||
|
||||
msgctxt "#30394"
|
||||
msgid "Cache files deleted"
|
||||
msgstr "Fichiers du cache supprimés"
|
||||
|
||||
msgctxt "#30393"
|
||||
msgid "Clear Cache Result"
|
||||
msgstr "Effacer le cache des résultats"
|
||||
|
||||
msgctxt "#30388"
|
||||
msgid "Server details"
|
||||
msgstr "Détails du serveur"
|
||||
|
||||
msgctxt "#30387"
|
||||
msgid "Unused images removed : "
|
||||
msgstr "Images inutilisées supprimées :"
|
||||
|
||||
msgctxt "#30371"
|
||||
msgid "Could not connect to the URL you entered, do you want to try again?"
|
||||
msgstr ""
|
||||
"Impossible de se connecter à l'adresse saisie, voulez-vous essayer à nouveau "
|
||||
"?"
|
||||
|
||||
msgctxt "#30370"
|
||||
msgid "Do you want to manually enter a server url?"
|
||||
msgstr "Voulez-vous saisir manuellement une adresse de serveur ?"
|
||||
|
||||
msgctxt "#30369"
|
||||
msgid "Do you want to clear your saved password?"
|
||||
msgstr "Voulez-vous effacer votre mot de passe sauvegardé ?"
|
||||
|
||||
msgctxt "#30368"
|
||||
msgid "Clear Password?"
|
||||
msgstr "Effacer le mot de passe ?"
|
||||
|
||||
msgctxt "#30374"
|
||||
msgid "Sending request"
|
||||
msgstr "Envoyer une requête"
|
||||
|
||||
msgctxt "#30377"
|
||||
msgid "Sending request"
|
||||
msgstr "Envoyer une requête"
|
||||
|
||||
msgctxt "#30376"
|
||||
msgid "Checking server url"
|
||||
msgstr "Vérifier l'url du serveur"
|
||||
|
||||
msgctxt "#30373"
|
||||
msgid "Scanning for local servers"
|
||||
msgstr "Recherche de serveurs locaux"
|
||||
|
||||
msgctxt "#30408"
|
||||
msgid "Custom Widgets"
|
||||
msgstr "Widgets personnalisés"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30416"
|
||||
msgid "HTTP timeout seconds"
|
||||
msgstr "Délai HTTP en secondes"
|
||||
|
||||
msgctxt "#30378"
|
||||
msgid "Persist user details"
|
||||
msgstr "Persistance des détails de l'utilisateur"
|
||||
|
||||
msgctxt "#30379"
|
||||
msgid "External subtitle prompt"
|
||||
msgstr "Invite de sous-titres externes"
|
||||
|
||||
msgctxt "#30395"
|
||||
msgid "Clear cached server data"
|
||||
msgstr "Effacer les données du serveur en cache"
|
||||
|
||||
msgctxt "#30434"
|
||||
msgid "Force transcode stream bitrate (Kbits)"
|
||||
msgstr "Forcer le débit du flux de transcodage (Kbps)"
|
||||
|
||||
msgctxt "#30026"
|
||||
msgid "Widget item select action"
|
||||
msgstr "Action de sélection de l'élément du widget"
|
||||
|
||||
msgctxt "#30413"
|
||||
msgid " - Tags"
|
||||
msgstr "- Tags"
|
||||
|
||||
msgctxt "#30433"
|
||||
msgid "Allow direct file playback"
|
||||
msgstr "Autoriser la lecture directe des fichiers"
|
||||
|
||||
msgctxt "#30435"
|
||||
msgid "Connection speed test"
|
||||
msgstr "Test de vitesse de connexion"
|
||||
|
||||
msgctxt "#30440"
|
||||
msgid "Play next"
|
||||
msgstr "Jouer la suite"
|
||||
|
||||
msgctxt "#30441"
|
||||
msgid "Use cached widget data"
|
||||
msgstr "Utiliser les données du widget mises en cache"
|
||||
|
||||
msgctxt "#30442"
|
||||
msgid "Simple new content check"
|
||||
msgstr "Vérification simple du nouveau contenu"
|
||||
|
||||
msgctxt "#30443"
|
||||
msgid "Quick Connect"
|
||||
msgstr "Quick Connect"
|
||||
|
||||
msgctxt "#30367"
|
||||
msgid "Allow fast user switching password saving"
|
||||
msgstr ""
|
||||
"Autoriser la sauvegarde rapide du changement de mot de passe de l'utilisateur"
|
||||
|
||||
msgctxt "#30375"
|
||||
msgid "Receiving data packet"
|
||||
msgstr "Réception du paquet de données"
|
||||
|
||||
msgctxt "#30384"
|
||||
msgid "Random movies interval minutes (0 = disabled)"
|
||||
msgstr "Intervalle de films aléatoires en minutes (0 = désactivé)"
|
||||
|
||||
msgctxt "#30385"
|
||||
msgid "Existing images before delete : "
|
||||
msgstr "Images existantes avant la suppression :"
|
||||
|
||||
msgctxt "#30400"
|
||||
msgid "Cache images interval minutes (0 = disabled)"
|
||||
msgstr "Intervalle de mise en cache des images en minutes (0 = désactivé)"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30409"
|
||||
msgid "Add-on Actions"
|
||||
msgstr "Actions complémentaires"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30430"
|
||||
msgid "Label"
|
||||
msgstr "Étiquette"
|
||||
|
||||
msgctxt "#30432"
|
||||
msgid "Hide watched items in lists"
|
||||
msgstr "Masquer les éléments surveillés dans les listes"
|
||||
|
||||
msgctxt "#30436"
|
||||
msgid "Speed test data size (MB)"
|
||||
msgstr "Taille des données du test de vitesse (Mo)"
|
||||
|
||||
msgctxt "#30438"
|
||||
msgid "Play cinema intros"
|
||||
msgstr "Lecture des intros de cinéma"
|
||||
|
||||
msgctxt "#30418"
|
||||
msgid "Audio bitrate (Kbits)"
|
||||
msgstr "Bitrate audio (Kbps)"
|
||||
|
||||
msgctxt "#30439"
|
||||
msgid "Show play next episode at time left in seconds"
|
||||
msgstr "Afficher la lecture du prochain épisode au temps restant en secondes"
|
||||
|
||||
msgctxt "#30444"
|
||||
msgid "Login using Quick Connect"
|
||||
msgstr "Connectez-vous en utilisant Quick Connect"
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "Continuer à regarder"
|
||||
|
||||
msgctxt "#30446"
|
||||
msgid "There was an error logging in"
|
||||
msgstr "Il y a eu une erreur de connexion"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-06-08 04:22+0000\n"
|
||||
"PO-Revision-Date: 2022-10-04 05:54+0000\n"
|
||||
"Last-Translator: Csaba <csab0825@gmail.com>\n"
|
||||
"Language-Team: Hungarian <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/hu/>\n"
|
||||
@@ -9,7 +9,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.10.1\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
msgctxt "#30441"
|
||||
msgid "Use cached widget data"
|
||||
@@ -1099,3 +1099,15 @@ msgstr "Gyors Csatlakozás"
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Művészek"
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "Megtekintés folytatása"
|
||||
|
||||
msgctxt "#30439"
|
||||
msgid "Show play next episode at time left in seconds"
|
||||
msgstr "A következő epizód lejátszása a másodpercben hátralévő időpontban"
|
||||
|
||||
msgctxt "#30446"
|
||||
msgid "There was an error logging in"
|
||||
msgstr "Hiba történt a bejelentkezéskor"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-05-20 04:22+0000\n"
|
||||
"Last-Translator: liimee <git.taaa@fedora.email>\n"
|
||||
"PO-Revision-Date: 2022-08-15 12:40+0000\n"
|
||||
"Last-Translator: Arief Hidayat <kekesed97@gmail.com>\n"
|
||||
"Language-Team: Indonesian <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/id/>\n"
|
||||
"Language: id\n"
|
||||
@@ -9,7 +9,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 4.10.1\n"
|
||||
"X-Generator: Weblate 4.13.1\n"
|
||||
|
||||
msgctxt "#30414"
|
||||
msgid " - Favorites"
|
||||
@@ -482,3 +482,622 @@ msgstr "Kata sandi"
|
||||
msgctxt "#30005"
|
||||
msgid "Username"
|
||||
msgstr "Nama pengguna"
|
||||
|
||||
msgctxt "#30315"
|
||||
msgid "Suppress notifications for connection errors"
|
||||
msgstr "Menekan notifikasi untuk kesalahan koneksi"
|
||||
|
||||
msgctxt "#30016"
|
||||
msgid "Device display name"
|
||||
msgstr "Nama tampilan perangkat"
|
||||
|
||||
msgctxt "#30015"
|
||||
msgid "Log timing data"
|
||||
msgstr "Catat data waktu"
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "Lanjutkan Tonton"
|
||||
|
||||
msgctxt "#30444"
|
||||
msgid "Login using Quick Connect"
|
||||
msgstr "Login dengan Koneksi Cepat"
|
||||
|
||||
msgctxt "#30443"
|
||||
msgid "Quick Connect"
|
||||
msgstr "Koneksi Cepat"
|
||||
|
||||
msgctxt "#30442"
|
||||
msgid "Simple new content check"
|
||||
msgstr "Cek konten baru sederhana"
|
||||
|
||||
msgctxt "#30441"
|
||||
msgid "Use cached widget data"
|
||||
msgstr "Gunakan data widget yang di-cache"
|
||||
|
||||
msgctxt "#30439"
|
||||
msgid "Show play next episode at time left"
|
||||
msgstr "Tampilkan putar episode pada waktu tersisa"
|
||||
|
||||
msgctxt "#30438"
|
||||
msgid "Play cinema intros"
|
||||
msgstr "Mainkan intro sinema"
|
||||
|
||||
msgctxt "#30437"
|
||||
msgid "Playback options"
|
||||
msgstr "Opsi pemutaran"
|
||||
|
||||
msgctxt "#30436"
|
||||
msgid "Speed test data size (MB)"
|
||||
msgstr "Besar data untuk uji kecepatan (MB)"
|
||||
|
||||
msgctxt "#30435"
|
||||
msgid "Connection speed test"
|
||||
msgstr "Uji kecepatan koneksi"
|
||||
|
||||
msgctxt "#30434"
|
||||
msgid "Force transcode stream bitrate (Kbits)"
|
||||
msgstr "Memaksa kecepatan bit aliran transkode (Kbps)"
|
||||
|
||||
msgctxt "#30433"
|
||||
msgid "Allow direct file playback"
|
||||
msgstr "Izinkan pemutaran berkas langsung"
|
||||
|
||||
msgctxt "#30432"
|
||||
msgid "Hide watched items in lists"
|
||||
msgstr "Sembunyikan item yang telah ditonton dari daftar"
|
||||
|
||||
msgctxt "#30429"
|
||||
msgid "Genre"
|
||||
msgstr "Genre"
|
||||
|
||||
msgctxt "#30428"
|
||||
msgid "Rating"
|
||||
msgstr "Penilaian"
|
||||
|
||||
msgctxt "#30424"
|
||||
msgid "Default"
|
||||
msgstr "Default"
|
||||
|
||||
msgctxt "#30423"
|
||||
msgid "NotSet"
|
||||
msgstr "Belum Diatur"
|
||||
|
||||
msgctxt "#30422"
|
||||
msgid "Sorting"
|
||||
msgstr "Urutkan"
|
||||
|
||||
msgctxt "#30421"
|
||||
msgid "Views"
|
||||
msgstr "Tampilan"
|
||||
|
||||
msgctxt "#30420"
|
||||
msgid "Audio max channels"
|
||||
msgstr "Channel maks. Audio"
|
||||
|
||||
msgctxt "#30419"
|
||||
msgid "Audio codec"
|
||||
msgstr "Kodek Audio"
|
||||
|
||||
msgctxt "#30418"
|
||||
msgid "Audio bitrate (Kbits)"
|
||||
msgstr "Bitrate Audio (Kbps)"
|
||||
|
||||
msgctxt "#30416"
|
||||
msgid "HTTP timeout seconds"
|
||||
msgstr "Detik HTTP timeout"
|
||||
|
||||
msgctxt "#30415"
|
||||
msgid " - Favorite Collections"
|
||||
msgstr "- Koleksi Favorit"
|
||||
|
||||
msgctxt "#30413"
|
||||
msgid " - Tags"
|
||||
msgstr "- Tag"
|
||||
|
||||
msgctxt "#30412"
|
||||
msgid " - Decades"
|
||||
msgstr "- Dekade"
|
||||
|
||||
msgctxt "#30411"
|
||||
msgid " - Years"
|
||||
msgstr "- Tahun"
|
||||
|
||||
msgctxt "#30410"
|
||||
msgid " - Collections"
|
||||
msgstr "- Koleksi"
|
||||
|
||||
msgctxt "#30409"
|
||||
msgid "Add-on Actions"
|
||||
msgstr "Aksi Add-on"
|
||||
|
||||
msgctxt "#30408"
|
||||
msgid "Custom Widgets"
|
||||
msgstr "Widget Kustom"
|
||||
|
||||
msgctxt "#30407"
|
||||
msgid "Global Lists"
|
||||
msgstr "Daftar Global"
|
||||
|
||||
msgctxt "#30406"
|
||||
msgid "Jellyfin Libraries"
|
||||
msgstr "Pustaka Jellyfin"
|
||||
|
||||
msgctxt "#30400"
|
||||
msgid "Cache images interval minutes (0 = disabled)"
|
||||
msgstr "Interval cache gambar dalam menit (0 = dimatikan)"
|
||||
|
||||
msgctxt "#30397"
|
||||
msgid " - Pages"
|
||||
msgstr "- Halaman"
|
||||
|
||||
msgctxt "#30395"
|
||||
msgid "Clear cached server data"
|
||||
msgstr "Hapus server data yang di-cache"
|
||||
|
||||
msgctxt "#30394"
|
||||
msgid "Cache files deleted"
|
||||
msgstr "File cache dihapus"
|
||||
|
||||
msgctxt "#30393"
|
||||
msgid "Clear Cache Result"
|
||||
msgstr "Hapus Hasil Cache"
|
||||
|
||||
msgctxt "#30387"
|
||||
msgid "Unused images removed : "
|
||||
msgstr "Gambar yang tidak digunakan dihapus:"
|
||||
|
||||
msgctxt "#30386"
|
||||
msgid "Unused Jellyfin images : "
|
||||
msgstr "Gambar Jellyfin yang tidak digunakan:"
|
||||
|
||||
msgctxt "#30385"
|
||||
msgid "Existing images before delete : "
|
||||
msgstr "Gambar yang ada sebelum dihapus:"
|
||||
|
||||
msgctxt "#30384"
|
||||
msgid "Random movies interval minutes (0 = disabled)"
|
||||
msgstr "Menit interval film acak (0 = dinonaktifkan)"
|
||||
|
||||
msgctxt "#30379"
|
||||
msgid "External subtitle prompt"
|
||||
msgstr "Perintah subtitle eksternal"
|
||||
|
||||
msgctxt "#30378"
|
||||
msgid "Persist user details"
|
||||
msgstr "Pertahankan detail pengguna"
|
||||
|
||||
msgctxt "#30375"
|
||||
msgid "Receiving data packet"
|
||||
msgstr "Menerima paket data"
|
||||
|
||||
msgctxt "#30370"
|
||||
msgid "Do you want to manually enter a server url?"
|
||||
msgstr "Apakah Anda ingin untuk memasukkan url server secara manual?"
|
||||
|
||||
msgctxt "#30369"
|
||||
msgid "Do you want to clear your saved password?"
|
||||
msgstr "Apakah Anda ingin untuk menghapus kata sandi tersimpan?"
|
||||
|
||||
msgctxt "#30368"
|
||||
msgid "Clear Password?"
|
||||
msgstr "Kosongkan Kata Sandi?"
|
||||
|
||||
msgctxt "#30367"
|
||||
msgid "Allow fast user switching password saving"
|
||||
msgstr "Izinkan untuk menyimpan kata sandi dari pengguna yang telah beralih"
|
||||
|
||||
msgctxt "#30366"
|
||||
msgid "Manually enter user details"
|
||||
msgstr "Masukkan detail pengguna secara manual"
|
||||
|
||||
msgctxt "#30365"
|
||||
msgid "Manual Login"
|
||||
msgstr "Login Manual"
|
||||
|
||||
msgctxt "#30359"
|
||||
msgid "Building full image list"
|
||||
msgstr "Membangun daftar gambar penuh"
|
||||
|
||||
msgctxt "#30358"
|
||||
msgid "Retreiving remote image list"
|
||||
msgstr "Menerima daftar gambar jarak jauh"
|
||||
|
||||
msgctxt "#30357"
|
||||
msgid "Processing existing image list"
|
||||
msgstr "Memproses gambar yang telah ada"
|
||||
|
||||
msgctxt "#30356"
|
||||
msgid "Loading existing image list"
|
||||
msgstr "Muat gambar yang telah ada"
|
||||
|
||||
msgctxt "#30355"
|
||||
msgid "Kodi Settings->Services->Allow remote control via HTTP"
|
||||
msgstr "Pengaturan Kodi->Layanan->Izinkan kendali jarak jauh HTTP"
|
||||
|
||||
msgctxt "#30354"
|
||||
msgid "Go To Series"
|
||||
msgstr "Pergi ke Seri"
|
||||
|
||||
msgctxt "#30321"
|
||||
msgid " - Album Artists"
|
||||
msgstr "- Artis Album"
|
||||
|
||||
msgctxt "#30319"
|
||||
msgid "Music - All Album Artists"
|
||||
msgstr "Musik - Semua Artis Album"
|
||||
|
||||
msgctxt "#30351"
|
||||
msgid "Music - Recently Played"
|
||||
msgstr "Musik - Baru-baru ini diputar"
|
||||
|
||||
msgctxt "#30349"
|
||||
msgid " - Recently Played"
|
||||
msgstr "- Baru-baru ini diputar"
|
||||
|
||||
msgctxt "#30348"
|
||||
msgid "Add user ratings"
|
||||
msgstr "Tambahkan rating pengguna"
|
||||
|
||||
msgctxt "#30347"
|
||||
msgid "Getting Existing Images"
|
||||
msgstr "Mengambil gambar yang telah ada"
|
||||
|
||||
msgctxt "#30346"
|
||||
msgid "Deleteing Cached Images"
|
||||
msgstr "Menghapus Gambar yang di-cache"
|
||||
|
||||
msgctxt "#30345"
|
||||
msgid "Cache Jellyfin server data requests"
|
||||
msgstr "Cache permintaan server data Jellyfin"
|
||||
|
||||
msgctxt "#30344"
|
||||
msgid "Number of images removed from cache"
|
||||
msgstr "Jumlah gambar yang dihapus dari cache"
|
||||
|
||||
msgctxt "#30343"
|
||||
msgid "Changes Require Kodi Restart"
|
||||
msgstr "Perubahan Memerlukan Pemuatan Ulang Kodi"
|
||||
|
||||
msgctxt "#30342"
|
||||
msgid "New content check interval (0 = disabled)"
|
||||
msgstr "Interval pemeriksaan konten baru (0 = dimatikan)"
|
||||
|
||||
msgctxt "#30340"
|
||||
msgid "Group movies into collections"
|
||||
msgstr "Gabungkan film ke dalam koleksi"
|
||||
|
||||
msgctxt "#30334"
|
||||
msgid "Use JellyCon context menu"
|
||||
msgstr "Gunakan konteks menu JellyCon"
|
||||
|
||||
msgctxt "#30333"
|
||||
msgid "Cache artwork in the background"
|
||||
msgstr "Cache karya seni di latar belakang"
|
||||
|
||||
msgctxt "#30332"
|
||||
msgid "Stop media playback on screensaver activation"
|
||||
msgstr "Hentikan pemutaran media ketika screensaver aktif"
|
||||
|
||||
msgctxt "#30328"
|
||||
msgid "Show empty folders (shows, seasons, collections)"
|
||||
msgstr "Tampilkan folder kosong (acara, musim, koleksi)"
|
||||
|
||||
msgctxt "#30330"
|
||||
msgid "Show change user dialog"
|
||||
msgstr "Tampilkan dialog pergantian pengguna"
|
||||
|
||||
msgctxt "#30329"
|
||||
msgid "Screensaver"
|
||||
msgstr "Screensaver"
|
||||
|
||||
msgctxt "#30327"
|
||||
msgid "Go To Season"
|
||||
msgstr "Pergi ke Musim"
|
||||
|
||||
msgctxt "#30325"
|
||||
msgid " - Genres"
|
||||
msgstr "- Genre"
|
||||
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Artis"
|
||||
|
||||
msgctxt "#30322"
|
||||
msgid "Auto resume"
|
||||
msgstr "Lanjutkan otomatis"
|
||||
|
||||
msgctxt "#30316"
|
||||
msgid "Connection Error"
|
||||
msgstr "Kesalahan Koneksi"
|
||||
|
||||
msgctxt "#30311"
|
||||
msgid "Library - "
|
||||
msgstr "Pustaka -"
|
||||
|
||||
msgctxt "#30310"
|
||||
msgid "Enable Jellyfin remote control"
|
||||
msgstr "Nyalakan kendali jarak jauh Jellyfin"
|
||||
|
||||
msgctxt "#30308"
|
||||
msgid "Select Trailer"
|
||||
msgstr "Pilih Trailer"
|
||||
|
||||
msgctxt "#30307"
|
||||
msgid "Play Trailer"
|
||||
msgstr "Mulai Trailer"
|
||||
|
||||
msgctxt "#30304"
|
||||
msgid "Cached Jellyfin images : "
|
||||
msgstr "Gambar Jellyfin yang di-cache:"
|
||||
|
||||
msgctxt "#30303"
|
||||
msgid "Missing Jellyfin images : "
|
||||
msgstr "Gambar Jellyfin yang hilang:"
|
||||
|
||||
msgctxt "#30302"
|
||||
msgid "Existing images : "
|
||||
msgstr "Gambar yang Ada:"
|
||||
|
||||
msgctxt "#30301"
|
||||
msgid "Caching Images"
|
||||
msgstr "Sedang Caching Gambar"
|
||||
|
||||
msgctxt "#30300"
|
||||
msgid "Cache all Jellyfin images as local Kodi images?"
|
||||
msgstr "Cache semua gambar Jellyfin sebagai gambar Kodi lokal?"
|
||||
|
||||
msgctxt "#30299"
|
||||
msgid "Cache Images"
|
||||
msgstr "Gambar Cache"
|
||||
|
||||
msgctxt "#30298"
|
||||
msgid "Deleting Kodi Images"
|
||||
msgstr "Menghapus Gambar Kodi"
|
||||
|
||||
msgctxt "#30295"
|
||||
msgid "To use this feature you need HTTP control enabled"
|
||||
msgstr "Anda perlu menyalakan kontrol HTTP untuk menggunakan fitur ini"
|
||||
|
||||
msgctxt "#30294"
|
||||
msgid "Notice"
|
||||
msgstr "Peringatan"
|
||||
|
||||
msgctxt "#30293"
|
||||
msgid "Cache images"
|
||||
msgstr "Gambar Cache"
|
||||
|
||||
msgctxt "#30292"
|
||||
msgid "Select Subtitle Stream"
|
||||
msgstr "Pilih Stream Subtitle"
|
||||
|
||||
msgctxt "#30291"
|
||||
msgid "Select Audio Stream"
|
||||
msgstr "Pilih Audio Stream"
|
||||
|
||||
msgctxt "#30289"
|
||||
msgid "TV Shows - Genres"
|
||||
msgstr "Acara TV - Genre"
|
||||
|
||||
msgctxt "#30281"
|
||||
msgid "Refresh Cached Images"
|
||||
msgstr "Segarkan Gambar yang Di-cache"
|
||||
|
||||
msgctxt "#30280"
|
||||
msgid "Missing Title"
|
||||
msgstr "Judul yang Hilang"
|
||||
|
||||
msgctxt "#30277"
|
||||
msgid "JellyCon needs to prompt for resume on partily played items, Kodi can also prompt, this can cause a double prompt. Do you want to remove the double prompt?"
|
||||
msgstr ""
|
||||
"JellyCon perlu meminta resume pada item yang dimainkan sebagian, Kodi juga "
|
||||
"dapat meminta, ini dapat menyebabkan prompt ganda. Apakah Anda ingin "
|
||||
"menghapus perintah ganda?"
|
||||
|
||||
msgctxt "#30276"
|
||||
msgid "Extra Resume Prompt Detected"
|
||||
msgstr "Prompt Resume Ekstra Terdeteksi"
|
||||
|
||||
msgctxt "#30275"
|
||||
msgid "Force Transcode"
|
||||
msgstr "Paksa Transkode"
|
||||
|
||||
msgctxt "#30273"
|
||||
msgid "Unset Favourite"
|
||||
msgstr "Hapus Favorit"
|
||||
|
||||
msgctxt "#30272"
|
||||
msgid "Set Favourite"
|
||||
msgstr "Atur Favorit"
|
||||
|
||||
msgctxt "#30267"
|
||||
msgid " - In Progress"
|
||||
msgstr "- Sedang Ditonton"
|
||||
|
||||
msgctxt "#30266"
|
||||
msgid "Movies - Pages"
|
||||
msgstr "Film - Halaman"
|
||||
|
||||
msgctxt "#30264"
|
||||
msgid "Episodes - In Progress"
|
||||
msgstr "Episode - Sedang Ditonton"
|
||||
|
||||
msgctxt "#30260"
|
||||
msgid "BoxSets"
|
||||
msgstr "Set Kotak"
|
||||
|
||||
msgctxt "#30258"
|
||||
msgid "Movies - In Progress"
|
||||
msgstr "Film - Sedang ditonton"
|
||||
|
||||
msgctxt "#30251"
|
||||
msgid "Movies - Genres"
|
||||
msgstr "Film - Genre"
|
||||
|
||||
msgctxt "#30250"
|
||||
msgid "Unknown"
|
||||
msgstr "Tidak diketahui"
|
||||
|
||||
msgctxt "#30247"
|
||||
msgid "Custom Widget Content"
|
||||
msgstr "Konten Widget Kustom"
|
||||
|
||||
msgctxt "#30241"
|
||||
msgid "Force transcode mpeg4"
|
||||
msgstr "Paksa transkode mpeg4"
|
||||
|
||||
msgctxt "#30240"
|
||||
msgid "Force transcode msmpeg4v3 (divx)"
|
||||
msgstr "Paksa transkode msmmpeg4v3 (divx)"
|
||||
|
||||
msgctxt "#30239"
|
||||
msgid "Force transcode mpeg2"
|
||||
msgstr "Paksa transkode mpeg2"
|
||||
|
||||
msgctxt "#30238"
|
||||
msgid "Playback stream options"
|
||||
msgstr "Opsi stream pemutaran"
|
||||
|
||||
msgctxt "#30236"
|
||||
msgid "Force transcode h265 (hevc)"
|
||||
msgstr "Paksa transkode h265 (hevc)"
|
||||
|
||||
msgctxt "#30223"
|
||||
msgid "Page Size and Filtering"
|
||||
msgstr "Ukuran Halaman dan Filter"
|
||||
|
||||
msgctxt "#30220"
|
||||
msgid "Prompt to delete movie after %"
|
||||
msgstr "Tanyakan untuk menghapus film setelah %"
|
||||
|
||||
msgctxt "#30219"
|
||||
msgid " - Prompt before play"
|
||||
msgstr "- Tanyakan sebelum memutar"
|
||||
|
||||
msgctxt "#30218"
|
||||
msgid "Play next episode after %"
|
||||
msgstr "Putar episode selanjutnya setelah %"
|
||||
|
||||
msgctxt "#30217"
|
||||
msgid "Prompt to delete episode after %"
|
||||
msgstr "Tanyakan untuk menghapus episode setelah %"
|
||||
|
||||
msgctxt "#30215"
|
||||
msgid "On playback stop (100% = disabled)"
|
||||
msgstr "Henti ketika menonton (100% = dimatikan)"
|
||||
|
||||
msgctxt "#30214"
|
||||
msgid "Events"
|
||||
msgstr "Acara"
|
||||
|
||||
msgctxt "#30213"
|
||||
msgid "Video force 8 bit"
|
||||
msgstr "Paksa video 8 bit"
|
||||
|
||||
msgctxt "#30212"
|
||||
msgid "Video max width"
|
||||
msgstr "Lebar maks. video"
|
||||
|
||||
msgctxt "#30211"
|
||||
msgid "Transcode options"
|
||||
msgstr "Opsi transkode"
|
||||
|
||||
msgctxt "#30210"
|
||||
msgid "HTTP direct stream"
|
||||
msgstr "Stream HTTP langsung"
|
||||
|
||||
msgctxt "#30209"
|
||||
msgid "File direct path"
|
||||
msgstr "Jalur file langsung"
|
||||
|
||||
msgctxt "#30208"
|
||||
msgid "Max stream bitrate (Kbits)"
|
||||
msgstr "Maks. stream bitrate (Kbps)"
|
||||
|
||||
msgctxt "#30183"
|
||||
msgid "Include people"
|
||||
msgstr "Termasuk oran"
|
||||
|
||||
msgctxt "#30182"
|
||||
msgid "Include media stream info"
|
||||
msgstr "Termasuk info stream media"
|
||||
|
||||
msgctxt "#30181"
|
||||
msgid "Include plot"
|
||||
msgstr "Termasuk plot"
|
||||
|
||||
msgctxt "#30139"
|
||||
msgid "No Media Type Set"
|
||||
msgstr "Tidak ada tipe media yang ditetapkan"
|
||||
|
||||
msgctxt "#30125"
|
||||
msgid "Done"
|
||||
msgstr "Selesai"
|
||||
|
||||
msgctxt "#30121"
|
||||
msgid "On resume"
|
||||
msgstr "Sedang diteruskan"
|
||||
|
||||
msgctxt "#30120"
|
||||
msgid "Show load progress"
|
||||
msgstr "Tampilkan progres muat"
|
||||
|
||||
msgctxt "#30118"
|
||||
msgid "Add resume percent to names"
|
||||
msgstr "Tambahkan persen resume ke nama"
|
||||
|
||||
msgctxt "#30116"
|
||||
msgid "Add unwatched counts to names"
|
||||
msgstr "Tambahkan jumlah yang belum ditonton ke nama"
|
||||
|
||||
msgctxt "#30114"
|
||||
msgid "Jump back seconds"
|
||||
msgstr "Kembali beberapa detik"
|
||||
|
||||
msgctxt "#30112"
|
||||
msgid "Loading Content"
|
||||
msgstr "Memuat konten"
|
||||
|
||||
msgctxt "#30063"
|
||||
msgid "N/A"
|
||||
msgstr "Tidak ada"
|
||||
|
||||
msgctxt "#30053"
|
||||
msgid "Waiting for server to delete"
|
||||
msgstr "Menunggu server untuk menghapus"
|
||||
|
||||
msgctxt "#30027"
|
||||
msgid "Enable debug logging"
|
||||
msgstr "Nyalakan debug logging"
|
||||
|
||||
msgctxt "#30026"
|
||||
msgid "Widget item select action"
|
||||
msgstr "Aksi ketika item widget terpilih"
|
||||
|
||||
msgctxt "#30020"
|
||||
msgid "Flatten single season"
|
||||
msgstr "Ratakan musim tunggal"
|
||||
|
||||
msgctxt "#30019"
|
||||
msgid "Filtered episode name format"
|
||||
msgstr "Format penamaan episode terfilter"
|
||||
|
||||
msgctxt "#30018"
|
||||
msgid "Number of items to show in filtered lists"
|
||||
msgstr "Jumlah item yang ditunjukkan di daftar terfilter"
|
||||
|
||||
msgctxt "#30012"
|
||||
msgid "[Change user]"
|
||||
msgstr "[Ganti pengguna]"
|
||||
|
||||
msgctxt "#30011"
|
||||
msgid "[Detect local server]"
|
||||
msgstr "[Deteksi server lokal]"
|
||||
|
||||
msgctxt "#30010"
|
||||
msgid "Number of performance profiles to capture"
|
||||
msgstr "Jumlah profil performa"
|
||||
|
||||
msgctxt "#30000"
|
||||
msgid "Host"
|
||||
msgstr "Host"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2021-12-02 18:05+0000\n"
|
||||
"Last-Translator: Alfonso Scarpino <alfonso.scarpino@gmail.com>\n"
|
||||
"PO-Revision-Date: 2022-10-21 02:50+0000\n"
|
||||
"Last-Translator: Angus Fraser <angusmglfraser@yahoo.co.uk>\n"
|
||||
"Language-Team: Italian <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/it/>\n"
|
||||
"Language: it\n"
|
||||
@@ -9,11 +9,11 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.5.2\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
msgctxt "#30120"
|
||||
msgid "Show load progress"
|
||||
msgstr "Mostra avanzamento del caricamento"
|
||||
msgstr "Mostra progressione del caricamento"
|
||||
|
||||
msgctxt "#30118"
|
||||
msgid "Add resume percent to names"
|
||||
@@ -97,7 +97,7 @@ msgstr "Avanzate"
|
||||
|
||||
msgctxt "#30021"
|
||||
msgid "Show all episodes item"
|
||||
msgstr "Mostra elemento tutti gli episodi"
|
||||
msgstr "Mostra tutti gli episodi"
|
||||
|
||||
msgctxt "#30020"
|
||||
msgid "Flatten single season"
|
||||
@@ -426,3 +426,144 @@ msgstr "Percorso diretto del file"
|
||||
msgctxt "#30208"
|
||||
msgid "Max stream bitrate (Kbits)"
|
||||
msgstr "Bitrate massimo del flusso (Kbits)"
|
||||
|
||||
msgctxt "#30277"
|
||||
msgid "JellyCon needs to prompt for resume on partily played items, Kodi can also prompt, this can cause a double prompt. Do you want to remove the double prompt?"
|
||||
msgstr ""
|
||||
"JellyCon richiede una finestra per continuare la riproduzione di elementi, "
|
||||
"anche Kodi può richiedere una finestra, causando lapertura di una doppia "
|
||||
"finestra. Vuoi rimuovere la doppia finestra?"
|
||||
|
||||
msgctxt "#30213"
|
||||
msgid "Video force 8 bit"
|
||||
msgstr "Forza video 8 bit"
|
||||
|
||||
msgctxt "#30114"
|
||||
msgid "Jump back seconds"
|
||||
msgstr "Riavvolgi secondi"
|
||||
|
||||
msgctxt "#30331"
|
||||
msgid "Movies per page"
|
||||
msgstr "Film per pagina"
|
||||
|
||||
msgctxt "#30329"
|
||||
msgid "Screensaver"
|
||||
msgstr "Salvaschermo"
|
||||
|
||||
msgctxt "#30337"
|
||||
msgid "Song"
|
||||
msgstr "Canzone"
|
||||
|
||||
msgctxt "#30327"
|
||||
msgid "Go To Season"
|
||||
msgstr "Vai Alla Stagione"
|
||||
|
||||
msgctxt "#30325"
|
||||
msgid " - Genres"
|
||||
msgstr "- Generi"
|
||||
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Artisti"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30311"
|
||||
msgid "Library - "
|
||||
msgstr "Libreria -"
|
||||
|
||||
msgctxt "#30296"
|
||||
msgid "Delete"
|
||||
msgstr "Elimina"
|
||||
|
||||
msgctxt "#30288"
|
||||
msgid " - Latest"
|
||||
msgstr "- Ultimo"
|
||||
|
||||
msgctxt "#30280"
|
||||
msgid "Missing Title"
|
||||
msgstr "Titolo Mancante"
|
||||
|
||||
msgctxt "#30278"
|
||||
msgid " - Next Up"
|
||||
msgstr "- Prossimo"
|
||||
|
||||
msgctxt "#30312"
|
||||
msgid "All - "
|
||||
msgstr "Tutto -"
|
||||
|
||||
msgctxt "#30320"
|
||||
msgid " - Albums"
|
||||
msgstr "- Album"
|
||||
|
||||
msgctxt "#30279"
|
||||
msgid "TV Shows - Unwatched"
|
||||
msgstr "Serie TV - Non guardati"
|
||||
|
||||
msgctxt "#30282"
|
||||
msgid "No Jellyfin servers detected on your local network."
|
||||
msgstr "Nessun server Jellyfin rilevato nella tua rete locale."
|
||||
|
||||
msgctxt "#30286"
|
||||
msgid "Movies - Unwatched"
|
||||
msgstr "Film - Non guardati"
|
||||
|
||||
msgctxt "#30287"
|
||||
msgid "TV Shows - Latest"
|
||||
msgstr "Serie TV - Ultimi"
|
||||
|
||||
msgctxt "#30289"
|
||||
msgid "TV Shows - Genres"
|
||||
msgstr "Serie TV - Generi"
|
||||
|
||||
msgctxt "#30290"
|
||||
msgid "All"
|
||||
msgstr "Tutti"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30291"
|
||||
msgid "Select Audio Stream"
|
||||
msgstr "Seleziona fonte audio"
|
||||
|
||||
msgctxt "#30297"
|
||||
msgid "Delete unused images?"
|
||||
msgstr "Eliminare immagini non usati?"
|
||||
|
||||
msgctxt "#30305"
|
||||
msgid "Not Found"
|
||||
msgstr "Non trovato"
|
||||
|
||||
msgctxt "#30306"
|
||||
msgid "Playback starting"
|
||||
msgstr "Avvio riproduzione"
|
||||
|
||||
msgctxt "#30307"
|
||||
msgid "Play Trailer"
|
||||
msgstr "Riproduci Trailer"
|
||||
|
||||
msgctxt "#30308"
|
||||
msgid "Select Trailer"
|
||||
msgstr "Seleziona Trailer"
|
||||
|
||||
msgctxt "#30313"
|
||||
msgid "Menu"
|
||||
msgstr "Menù"
|
||||
|
||||
msgctxt "#30314"
|
||||
msgid "Play"
|
||||
msgstr "Riproduci"
|
||||
|
||||
msgctxt "#30316"
|
||||
msgid "Connection Error"
|
||||
msgstr "Errore di connessione"
|
||||
|
||||
msgctxt "#30318"
|
||||
msgid "Music - Albums"
|
||||
msgstr "Musica - Album"
|
||||
|
||||
msgctxt "#30322"
|
||||
msgid "Auto resume"
|
||||
msgstr "Ripresa automatica"
|
||||
|
||||
msgctxt "#30328"
|
||||
msgid "Show empty folders (shows, seasons, collections)"
|
||||
msgstr "Mostra cartelle vuote (serie, stagioni, collezioni)"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-06-08 04:22+0000\n"
|
||||
"PO-Revision-Date: 2022-08-10 20:22+0000\n"
|
||||
"Last-Translator: WWWesten <wwwesten@gmail.com>\n"
|
||||
"Language-Team: Kazakh <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/kk/>\n"
|
||||
@@ -1101,3 +1101,7 @@ msgstr "Jyldam qosylu"
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Oryndauşylar"
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "Qaraudy jalğastyru"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-06-01 17:51+0000\n"
|
||||
"Last-Translator: B v H <bobsieflopsie@outlook.com>\n"
|
||||
"PO-Revision-Date: 2022-10-01 13:54+0000\n"
|
||||
"Last-Translator: Thanos <ahmetspam.42@hotmail.com>\n"
|
||||
"Language-Team: Dutch <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/nl/>\n"
|
||||
"Language: nl\n"
|
||||
@@ -9,7 +9,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.10.1\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
msgctxt "#30257"
|
||||
msgid "Movies - Recently Added"
|
||||
@@ -219,13 +219,14 @@ msgctxt "#30120"
|
||||
msgid "Show load progress"
|
||||
msgstr "Toon laadvoortgang"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30118"
|
||||
msgid "Add resume percent to names"
|
||||
msgstr "Voeg percentage bekeken to aan namen"
|
||||
msgstr "Voeg percentage bekeken toe aan namen"
|
||||
|
||||
msgctxt "#30116"
|
||||
msgid "Add unwatched counts to names"
|
||||
msgstr "Voeg hoeveelheid niet bekeken to aan namen"
|
||||
msgstr "Voeg hoeveelheid niet bekeken toe aan namen"
|
||||
|
||||
msgctxt "#30114"
|
||||
msgid "Jump back seconds"
|
||||
@@ -233,7 +234,7 @@ msgstr "Spring seconden terug"
|
||||
|
||||
msgctxt "#30113"
|
||||
msgid "Retrieving Data"
|
||||
msgstr "Data Ophalen"
|
||||
msgstr "Data aan het ophalen"
|
||||
|
||||
msgctxt "#30112"
|
||||
msgid "Loading Content"
|
||||
@@ -253,11 +254,11 @@ msgstr "Waarschuwing: Deze stap zal mediabestanden van de server verwijderen."
|
||||
|
||||
msgctxt "#30091"
|
||||
msgid "Confirm delete?"
|
||||
msgstr "Bevestig verwijderen?"
|
||||
msgstr "Verwijderen bevestigen?"
|
||||
|
||||
msgctxt "#30063"
|
||||
msgid "N/A"
|
||||
msgstr "N/A"
|
||||
msgstr "NB"
|
||||
|
||||
msgctxt "#30053"
|
||||
msgid "Waiting for server to delete"
|
||||
@@ -279,6 +280,7 @@ msgctxt "#30027"
|
||||
msgid "Enable debug logging"
|
||||
msgstr "Schakel debug logging in"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30026"
|
||||
msgid "Widget item select action"
|
||||
msgstr "Widget item selecteer actie"
|
||||
@@ -305,7 +307,7 @@ msgstr "Toon alle afleveringen"
|
||||
|
||||
msgctxt "#30019"
|
||||
msgid "Filtered episode name format"
|
||||
msgstr "Naamformat gefilterde aflevering"
|
||||
msgstr "Naamformat van gefilterde aflevering"
|
||||
|
||||
msgctxt "#30018"
|
||||
msgid "Number of items to show in filtered lists"
|
||||
@@ -457,7 +459,7 @@ msgstr "Kodi Afbeeldingen Verwijderen"
|
||||
|
||||
msgctxt "#30297"
|
||||
msgid "Delete unused images?"
|
||||
msgstr "Verwijder niet gebruikte afbeeldingen?"
|
||||
msgstr "Niet gebruikte afbeeldingen verwijderen?"
|
||||
|
||||
msgctxt "#30296"
|
||||
msgid "Delete"
|
||||
@@ -485,7 +487,7 @@ msgstr "Speel Volgende Aflevering Af?"
|
||||
|
||||
msgctxt "#30282"
|
||||
msgid "No Jellyfin servers detected on your local network."
|
||||
msgstr "Geen Jellyfin Servers Gevonden Op Uw Locale Netwerk."
|
||||
msgstr "Geen Jellyfin Servers Gevonden Op Uw Lokale Netwerk."
|
||||
|
||||
msgctxt "#30280"
|
||||
msgid "Missing Title"
|
||||
@@ -533,4 +535,584 @@ msgstr "Films - Favorieten"
|
||||
|
||||
msgctxt "#30258"
|
||||
msgid "Movies - In Progress"
|
||||
msgstr "Films - In Uitvoering"
|
||||
msgstr "Films - Aan Het Kijken"
|
||||
|
||||
msgctxt "#30334"
|
||||
msgid "Use JellyCon context menu"
|
||||
msgstr "Het JellyCon-contextmenu gebruiken"
|
||||
|
||||
msgctxt "#30333"
|
||||
msgid "Cache artwork in the background"
|
||||
msgstr "Cache-artwork op de achtergrond"
|
||||
|
||||
msgctxt "#30332"
|
||||
msgid "Stop media playback on screensaver activation"
|
||||
msgstr "Stop het afspelen bij activering van de screensaver"
|
||||
|
||||
msgctxt "#30330"
|
||||
msgid "Show change user dialog"
|
||||
msgstr "Dialoogvenster gebruiker wijzigen tonen"
|
||||
|
||||
msgctxt "#30329"
|
||||
msgid "Screensaver"
|
||||
msgstr "Screensaver"
|
||||
|
||||
msgctxt "#30328"
|
||||
msgid "Show empty folders (shows, seasons, collections)"
|
||||
msgstr "Lege mappen weergeven (shows, seizoenen, collecties)"
|
||||
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Artiesten"
|
||||
|
||||
msgctxt "#30312"
|
||||
msgid "All - "
|
||||
msgstr "Alles -"
|
||||
|
||||
msgctxt "#30311"
|
||||
msgid "Library - "
|
||||
msgstr "Bibliotheek -"
|
||||
|
||||
msgctxt "#30310"
|
||||
msgid "Enable Jellyfin remote control"
|
||||
msgstr "Jellyfin-afstandsbediening inschakelen"
|
||||
|
||||
msgctxt "#30309"
|
||||
msgid "Select Media Source"
|
||||
msgstr "Selecteer mediabron"
|
||||
|
||||
msgctxt "#30306"
|
||||
msgid "Playback starting"
|
||||
msgstr "Afspelen starten"
|
||||
|
||||
msgctxt "#30304"
|
||||
msgid "Cached Jellyfin images : "
|
||||
msgstr "Gecached Jellyfin-afbeeldingen:"
|
||||
|
||||
msgctxt "#30303"
|
||||
msgid "Missing Jellyfin images : "
|
||||
msgstr "Ontbrekende Jellyfin-afbeeldingen:"
|
||||
|
||||
msgctxt "#30300"
|
||||
msgid "Cache all Jellyfin images as local Kodi images?"
|
||||
msgstr ""
|
||||
"Alle Jellyfin-afbeeldingen in de cache opslaan als lokale Kodi-afbeeldingen?"
|
||||
|
||||
msgctxt "#30301"
|
||||
msgid "Caching Images"
|
||||
msgstr "Afbeeldingen Worden In Cache Geplaatst"
|
||||
|
||||
msgctxt "#30293"
|
||||
msgid "Cache images"
|
||||
msgstr "Afbeeldingen Cachen"
|
||||
|
||||
msgctxt "#30299"
|
||||
msgid "Cache Images"
|
||||
msgstr "Afbeeldingen Cachen"
|
||||
|
||||
msgctxt "#30295"
|
||||
msgid "To use this feature you need HTTP control enabled"
|
||||
msgstr "Om deze functie te gebruiken, moet HTTP-control zijn ingeschakeld"
|
||||
|
||||
msgctxt "#30294"
|
||||
msgid "Notice"
|
||||
msgstr "Melding"
|
||||
|
||||
msgctxt "#30292"
|
||||
msgid "Select Subtitle Stream"
|
||||
msgstr "Selecteer Ondertitelstream"
|
||||
|
||||
msgctxt "#30291"
|
||||
msgid "Select Audio Stream"
|
||||
msgstr "Selecteer Audiostream"
|
||||
|
||||
msgctxt "#30289"
|
||||
msgid "TV Shows - Genres"
|
||||
msgstr "TV Shows - Genres"
|
||||
|
||||
msgctxt "#30287"
|
||||
msgid "TV Shows - Latest"
|
||||
msgstr "TV Shows - Nieuwste"
|
||||
|
||||
msgctxt "#30281"
|
||||
msgid "Refresh Cached Images"
|
||||
msgstr "Ververs afbeeldingen in cache"
|
||||
|
||||
msgctxt "#30279"
|
||||
msgid "TV Shows - Unwatched"
|
||||
msgstr "TV Shows - Niet bekeken"
|
||||
|
||||
msgctxt "#30277"
|
||||
msgid "JellyCon needs to prompt for resume on partily played items, Kodi can also prompt, this can cause a double prompt. Do you want to remove the double prompt?"
|
||||
msgstr ""
|
||||
"JellyFin moet vragen om hervatting van gedeeltelijk gespeelde items, Kodi "
|
||||
"kan dit ook vragen, dit kan een dubbele prompt veroorzaken. Wilt u de "
|
||||
"dubbele prompt verwijderen?"
|
||||
|
||||
msgctxt "#30276"
|
||||
msgid "Extra Resume Prompt Detected"
|
||||
msgstr "Extra Hervat Prompt Gedetecteerd"
|
||||
|
||||
msgctxt "#30267"
|
||||
msgid " - In Progress"
|
||||
msgstr "- Aan Het Kijken"
|
||||
|
||||
msgctxt "#30266"
|
||||
msgid "Movies - Pages"
|
||||
msgstr "Films - Pagina's"
|
||||
|
||||
msgctxt "#30265"
|
||||
msgid "Episodes - Next Up"
|
||||
msgstr "Afleveringen - Volgende in de lijst"
|
||||
|
||||
msgctxt "#30264"
|
||||
msgid "Episodes - In Progress"
|
||||
msgstr "Afleveringen - Aan Het Kijken"
|
||||
|
||||
msgctxt "#30263"
|
||||
msgid "Episodes - Recently Added"
|
||||
msgstr "Afleveringen - Recent Toegevoegd"
|
||||
|
||||
msgctxt "#30262"
|
||||
msgid "TV Shows - Favorites"
|
||||
msgstr "TV Shows - Favorieten"
|
||||
|
||||
msgctxt "#30261"
|
||||
msgid "TV Shows"
|
||||
msgstr "TV Shows"
|
||||
|
||||
msgctxt "#30260"
|
||||
msgid "BoxSets"
|
||||
msgstr "Boxsets"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30020"
|
||||
msgid "Flatten single season"
|
||||
msgstr "Enkel seizoen afvlakken"
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "Doorgaan met kijken"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30444"
|
||||
msgid "Login using Quick Connect"
|
||||
msgstr "Log in met snel verbinden"
|
||||
|
||||
msgctxt "#30443"
|
||||
msgid "Quick Connect"
|
||||
msgstr "Snel verbinden"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30442"
|
||||
msgid "Simple new content check"
|
||||
msgstr "Simpele nieuwe content check"
|
||||
|
||||
msgctxt "#30441"
|
||||
msgid "Use cached widget data"
|
||||
msgstr "Gebruik gecachte widgetgegevens"
|
||||
|
||||
msgctxt "#30440"
|
||||
msgid "Play next"
|
||||
msgstr "Volgende afspelen"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30439"
|
||||
msgid "Show play next episode at time left in seconds"
|
||||
msgstr "Toon speel volgende aflevering in laatste % seconden"
|
||||
|
||||
msgctxt "#30438"
|
||||
msgid "Play cinema intros"
|
||||
msgstr "Filmintro's afspelen"
|
||||
|
||||
msgctxt "#30437"
|
||||
msgid "Playback options"
|
||||
msgstr "Afspeelopties"
|
||||
|
||||
msgctxt "#30436"
|
||||
msgid "Speed test data size (MB)"
|
||||
msgstr "Gegevensgrootte snelheidstest (MB)"
|
||||
|
||||
msgctxt "#30435"
|
||||
msgid "Connection speed test"
|
||||
msgstr "Verbindingssnelheidtest"
|
||||
|
||||
msgctxt "#30434"
|
||||
msgid "Force transcode stream bitrate (Kbits)"
|
||||
msgstr "Forceer transcode streambitsnelheid (Kbps)"
|
||||
|
||||
msgctxt "#30433"
|
||||
msgid "Allow direct file playback"
|
||||
msgstr "Rechtstreeks afspelen van bestanden toestaan"
|
||||
|
||||
msgctxt "#30432"
|
||||
msgid "Hide watched items in lists"
|
||||
msgstr "Verberg bekeken items in lijst"
|
||||
|
||||
msgctxt "#30431"
|
||||
msgid "Seasons"
|
||||
msgstr "Seizoenen"
|
||||
|
||||
msgctxt "#30430"
|
||||
msgid "Label"
|
||||
msgstr "Label"
|
||||
|
||||
msgctxt "#30429"
|
||||
msgid "Genre"
|
||||
msgstr "Genre"
|
||||
|
||||
msgctxt "#30428"
|
||||
msgid "Rating"
|
||||
msgstr "Beoordeling"
|
||||
|
||||
msgctxt "#30427"
|
||||
msgid "Added"
|
||||
msgstr "Toegevoegd"
|
||||
|
||||
msgctxt "#30426"
|
||||
msgid "Title"
|
||||
msgstr "Titel"
|
||||
|
||||
msgctxt "#30425"
|
||||
msgid "Year"
|
||||
msgstr "Jaar"
|
||||
|
||||
msgctxt "#30424"
|
||||
msgid "Default"
|
||||
msgstr "Standaard"
|
||||
|
||||
msgctxt "#30423"
|
||||
msgid "NotSet"
|
||||
msgstr "Niet ingesteld"
|
||||
|
||||
msgctxt "#30422"
|
||||
msgid "Sorting"
|
||||
msgstr "Sorteren"
|
||||
|
||||
msgctxt "#30421"
|
||||
msgid "Views"
|
||||
msgstr "Keer bekeken"
|
||||
|
||||
msgctxt "#30420"
|
||||
msgid "Audio max channels"
|
||||
msgstr "Maximum audio kanalen"
|
||||
|
||||
msgctxt "#30419"
|
||||
msgid "Audio codec"
|
||||
msgstr "Audio codec"
|
||||
|
||||
msgctxt "#30418"
|
||||
msgid "Audio bitrate (Kbits)"
|
||||
msgstr "Audiobisnelheid (Kbps)"
|
||||
|
||||
msgctxt "#30417"
|
||||
msgid "You do not have permision to delete this item"
|
||||
msgstr "Je bent niet gemachtigd om dit item te verwijderen"
|
||||
|
||||
msgctxt "#30416"
|
||||
msgid "HTTP timeout seconds"
|
||||
msgstr "HTTP timeout seconden"
|
||||
|
||||
msgctxt "#30415"
|
||||
msgid " - Favorite Collections"
|
||||
msgstr "- Favoriete Collecties"
|
||||
|
||||
msgctxt "#30414"
|
||||
msgid " - Favorites"
|
||||
msgstr "- Favorieten"
|
||||
|
||||
msgctxt "#30413"
|
||||
msgid " - Tags"
|
||||
msgstr "- Tags"
|
||||
|
||||
msgctxt "#30412"
|
||||
msgid " - Decades"
|
||||
msgstr "- Millenia"
|
||||
|
||||
msgctxt "#30411"
|
||||
msgid " - Years"
|
||||
msgstr "- Jaren"
|
||||
|
||||
msgctxt "#30410"
|
||||
msgid " - Collections"
|
||||
msgstr "- Collecties"
|
||||
|
||||
msgctxt "#30409"
|
||||
msgid "Add-on Actions"
|
||||
msgstr "Add-on Acties"
|
||||
|
||||
msgctxt "#30408"
|
||||
msgid "Custom Widgets"
|
||||
msgstr "Aangepaste widgets"
|
||||
|
||||
msgctxt "#30407"
|
||||
msgid "Global Lists"
|
||||
msgstr "Globale lijsten"
|
||||
|
||||
msgctxt "#30406"
|
||||
msgid "Jellyfin Libraries"
|
||||
msgstr "Jellyfin-bibliotheken"
|
||||
|
||||
msgctxt "#30405"
|
||||
msgid " - Show All"
|
||||
msgstr "- Toon alles"
|
||||
|
||||
msgctxt "#30404"
|
||||
msgid " - A-Z"
|
||||
msgstr "- A-Z"
|
||||
|
||||
msgctxt "#30403"
|
||||
msgid "Movies - Recommendations"
|
||||
msgstr "Films - Aanbevelingen"
|
||||
|
||||
msgctxt "#30402"
|
||||
msgid "Add to Kodi Playlist"
|
||||
msgstr "Voeg toe aan Kodi afspeellijst"
|
||||
|
||||
msgctxt "#30401"
|
||||
msgid "Info"
|
||||
msgstr "Info"
|
||||
|
||||
msgctxt "#30400"
|
||||
msgid "Cache images interval minutes (0 = disabled)"
|
||||
msgstr "Cache afbeeldingen interval in minuten (0 = uitgeschakeld)"
|
||||
|
||||
msgctxt "#30399"
|
||||
msgid "Hide"
|
||||
msgstr "Verbergen"
|
||||
|
||||
msgctxt "#30398"
|
||||
msgid "Refresh Jellyfin Metadata"
|
||||
msgstr "Ververs Jellyfin Metadata"
|
||||
|
||||
msgctxt "#30397"
|
||||
msgid " - Pages"
|
||||
msgstr "- Pagina's"
|
||||
|
||||
msgctxt "#30395"
|
||||
msgid "Clear cached server data"
|
||||
msgstr "Verwijderd gecachede servergegevens"
|
||||
|
||||
msgctxt "#30394"
|
||||
msgid "Cache files deleted"
|
||||
msgstr "Cachebestanden verwijderd"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30393"
|
||||
msgid "Clear Cache Result"
|
||||
msgstr "Cache-resultaat wissen"
|
||||
|
||||
msgctxt "#30392"
|
||||
msgid "HTTPS"
|
||||
msgstr "HTTPS"
|
||||
|
||||
msgctxt "#30391"
|
||||
msgid "HTTP"
|
||||
msgstr "HTTP"
|
||||
|
||||
msgctxt "#30390"
|
||||
msgid "Protocol"
|
||||
msgstr "Protocol"
|
||||
|
||||
msgctxt "#30389"
|
||||
msgid "User details"
|
||||
msgstr "Gebruikersgegevens"
|
||||
|
||||
msgctxt "#30388"
|
||||
msgid "Server details"
|
||||
msgstr "Servergegevens"
|
||||
|
||||
msgctxt "#30386"
|
||||
msgid "Unused Jellyfin images : "
|
||||
msgstr "Aantal ongebruikte Jellyfin afbeeldingen:"
|
||||
|
||||
msgctxt "#30387"
|
||||
msgid "Unused images removed : "
|
||||
msgstr "Aantal ongebruikte afbeeldingen verwijderd:"
|
||||
|
||||
msgctxt "#30385"
|
||||
msgid "Existing images before delete : "
|
||||
msgstr "Bestaande afbeeldingen vóór verwijderen:"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30384"
|
||||
msgid "Random movies interval minutes (0 = disabled)"
|
||||
msgstr "Willekeurige films interval in minuten (0 = uitgeschakeld)"
|
||||
|
||||
msgctxt "#30383"
|
||||
msgid "System - "
|
||||
msgstr "Systeem -"
|
||||
|
||||
msgctxt "#30382"
|
||||
msgid "Always"
|
||||
msgstr "Altijd"
|
||||
|
||||
msgctxt "#30381"
|
||||
msgid "More than one"
|
||||
msgstr "Meer dan één"
|
||||
|
||||
msgctxt "#30380"
|
||||
msgid "Never"
|
||||
msgstr "Nooit"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30379"
|
||||
msgid "External subtitle prompt"
|
||||
msgstr "Externe ondertitel prompt"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30378"
|
||||
msgid "Persist user details"
|
||||
msgstr "Blijvende gebruikersgegevens"
|
||||
|
||||
msgctxt "#30377"
|
||||
msgid "Sending request"
|
||||
msgstr "Verzoek verzenden"
|
||||
|
||||
msgctxt "#30376"
|
||||
msgid "Checking server url"
|
||||
msgstr "Server-URL controleren"
|
||||
|
||||
msgctxt "#30375"
|
||||
msgid "Receiving data packet"
|
||||
msgstr "Gegevenspakket ontvangen"
|
||||
|
||||
msgctxt "#30374"
|
||||
msgid "Sending request"
|
||||
msgstr "Verzoek verzenden"
|
||||
|
||||
msgctxt "#30373"
|
||||
msgid "Scanning for local servers"
|
||||
msgstr "Op zoek naar lokale servers"
|
||||
|
||||
msgctxt "#30372"
|
||||
msgid "Server URL"
|
||||
msgstr "Server URL"
|
||||
|
||||
msgctxt "#30371"
|
||||
msgid "Could not connect to the URL you entered, do you want to try again?"
|
||||
msgstr ""
|
||||
"Kon geen verbinding maken met de URL die u heeft ingevoerd, wilt u het "
|
||||
"opnieuw proberen?"
|
||||
|
||||
msgctxt "#30369"
|
||||
msgid "Do you want to clear your saved password?"
|
||||
msgstr "Wilt u de opgeslagen wachtwoord verwijderen?"
|
||||
|
||||
msgctxt "#30370"
|
||||
msgid "Do you want to manually enter a server url?"
|
||||
msgstr "Wilt u handmatig een server-url invoeren?"
|
||||
|
||||
msgctxt "#30368"
|
||||
msgid "Clear Password?"
|
||||
msgstr "Wachtwoord verwijderen?"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30367"
|
||||
msgid "Allow fast user switching password saving"
|
||||
msgstr "Snel opslaan van het geschakelde gebruikerswachtwoord toestaan"
|
||||
|
||||
msgctxt "#30366"
|
||||
msgid "Manually enter user details"
|
||||
msgstr "Gebruikersgegevens handmatig invoeren"
|
||||
|
||||
msgctxt "#30365"
|
||||
msgid "Manual Login"
|
||||
msgstr "Manueel inloggen"
|
||||
|
||||
msgctxt "#30364"
|
||||
msgid "Do you want to save the password?"
|
||||
msgstr "Wil je deze wachtwoord opslaan?"
|
||||
|
||||
msgctxt "#30363"
|
||||
msgid "Save Password?"
|
||||
msgstr "Wachtwoord opslaan?"
|
||||
|
||||
msgctxt "#30362"
|
||||
msgid " - Recordings"
|
||||
msgstr "- Opnames"
|
||||
|
||||
msgctxt "#30361"
|
||||
msgid " - Programs"
|
||||
msgstr "- Programma's"
|
||||
|
||||
msgctxt "#30360"
|
||||
msgid " - Channels"
|
||||
msgstr "- Kanalen"
|
||||
|
||||
msgctxt "#30359"
|
||||
msgid "Building full image list"
|
||||
msgstr "Volledige afbeeldingenlijst aan het opbouwen"
|
||||
|
||||
msgctxt "#30356"
|
||||
msgid "Loading existing image list"
|
||||
msgstr "Bestaande afbeeldingenlijst aan het laden"
|
||||
|
||||
msgctxt "#30358"
|
||||
msgid "Retreiving remote image list"
|
||||
msgstr "Externe afbeeldingenlijst aan het ophalen"
|
||||
|
||||
msgctxt "#30357"
|
||||
msgid "Processing existing image list"
|
||||
msgstr "De bestaande afbeeldingenlijst aan het verwerken"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30355"
|
||||
msgid "Kodi Settings->Services->Allow remote control via HTTP"
|
||||
msgstr "Kodi Instellingen->Services->Toegang van afstand via HTTP toestaan"
|
||||
|
||||
msgctxt "#30354"
|
||||
msgid "Go To Series"
|
||||
msgstr "Ga Naar Serie"
|
||||
|
||||
msgctxt "#30353"
|
||||
msgid " - Frequently Played"
|
||||
msgstr "- Vaak Afgespeeld"
|
||||
|
||||
msgctxt "#30321"
|
||||
msgid " - Album Artists"
|
||||
msgstr "- Album Artiesten"
|
||||
|
||||
msgctxt "#30319"
|
||||
msgid "Music - All Album Artists"
|
||||
msgstr "Muziek - Alle Album Artiesten"
|
||||
|
||||
msgctxt "#30349"
|
||||
msgid " - Recently Played"
|
||||
msgstr "- Recent afgespeeld"
|
||||
|
||||
msgctxt "#30348"
|
||||
msgid "Add user ratings"
|
||||
msgstr "Gebruikersbeoordelingen toevoegen"
|
||||
|
||||
msgctxt "#30347"
|
||||
msgid "Getting Existing Images"
|
||||
msgstr "Bestaande afbeeldingen ophalen"
|
||||
|
||||
msgctxt "#30346"
|
||||
msgid "Deleteing Cached Images"
|
||||
msgstr "Gecachte afbeeldingen aan het verwijderen"
|
||||
|
||||
msgctxt "#30345"
|
||||
msgid "Cache Jellyfin server data requests"
|
||||
msgstr "Jellyfin server data verzoeken cachen"
|
||||
|
||||
msgctxt "#30344"
|
||||
msgid "Number of images removed from cache"
|
||||
msgstr "Aantal afbeeldingen uit cache verwijderd"
|
||||
|
||||
msgctxt "#30343"
|
||||
msgid "Changes Require Kodi Restart"
|
||||
msgstr "Door de veranderingen moet Kodi opnieuw opstarten"
|
||||
|
||||
msgctxt "#30342"
|
||||
msgid "New content check interval (0 = disabled)"
|
||||
msgstr "Nieuwe content controle interval (0 = uitgeschakeld)"
|
||||
|
||||
msgctxt "#30341"
|
||||
msgid "Background image update interval (0 = disabled)"
|
||||
msgstr "Achtergrondafbeelding update interval (0 = uitgeschakeld)"
|
||||
|
||||
msgctxt "#30340"
|
||||
msgid "Group movies into collections"
|
||||
msgstr "Groepeer films in collecties"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2021-12-13 17:05+0000\n"
|
||||
"PO-Revision-Date: 2022-06-28 13:22+0000\n"
|
||||
"Last-Translator: Marcin Woliński <cierdek@gmail.com>\n"
|
||||
"Language-Team: Polish <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/pl/>\n"
|
||||
@@ -10,7 +10,7 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||
"|| n%100>=20) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 4.5.2\n"
|
||||
"X-Generator: Weblate 4.10.1\n"
|
||||
|
||||
msgctxt "#30313"
|
||||
msgid "Menu"
|
||||
@@ -1089,3 +1089,15 @@ msgstr "Odtwórz kinowe intro"
|
||||
msgctxt "#30437"
|
||||
msgid "Playback options"
|
||||
msgstr "Opcje odtwarzania"
|
||||
|
||||
msgctxt "#30444"
|
||||
msgid "Login using Quick Connect"
|
||||
msgstr "Zaloguj używając Szybkiego Połączenia"
|
||||
|
||||
msgctxt "#30443"
|
||||
msgid "Quick Connect"
|
||||
msgstr "Szybkie połączenie"
|
||||
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Artyści"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-06-08 04:22+0000\n"
|
||||
"PO-Revision-Date: 2022-08-10 20:22+0000\n"
|
||||
"Last-Translator: WWWesten <wwwesten@gmail.com>\n"
|
||||
"Language-Team: Russian <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/ru/>\n"
|
||||
@@ -1098,3 +1098,7 @@ msgstr "Быстрое подключение"
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Исполнители"
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "Продолжение просмотра"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-06-04 10:22+0000\n"
|
||||
"Last-Translator: hogenf <hogen.fasth@gmail.com>\n"
|
||||
"PO-Revision-Date: 2022-10-17 05:50+0000\n"
|
||||
"Last-Translator: daniel knutzen <daniel@knutzen.se>\n"
|
||||
"Language-Team: Swedish <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/sv/>\n"
|
||||
"Language: sv\n"
|
||||
@@ -9,7 +9,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.10.1\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
msgctxt "#30283"
|
||||
msgid "Play Next Episode?"
|
||||
@@ -489,7 +489,7 @@ msgstr "Hoppa tillbaka sekunder"
|
||||
|
||||
msgctxt "#30125"
|
||||
msgid "Done"
|
||||
msgstr "Färdig"
|
||||
msgstr "Klar"
|
||||
|
||||
msgctxt "#30139"
|
||||
msgid "No Media Type Set"
|
||||
@@ -649,7 +649,7 @@ msgstr "Adress:"
|
||||
|
||||
msgctxt "#30110"
|
||||
msgid "Interface"
|
||||
msgstr "Användargränssnitt"
|
||||
msgstr "Gränssnitt"
|
||||
|
||||
msgctxt "#30135"
|
||||
msgid "Error"
|
||||
@@ -657,7 +657,7 @@ msgstr "Error"
|
||||
|
||||
msgctxt "#30113"
|
||||
msgid "Retrieving Data"
|
||||
msgstr "Hämtar data"
|
||||
msgstr "Hämtar Data"
|
||||
|
||||
msgctxt "#30112"
|
||||
msgid "Loading Content"
|
||||
@@ -669,7 +669,7 @@ msgstr "Användarnamn kunde inte hittas"
|
||||
|
||||
msgctxt "#30012"
|
||||
msgid "[Change user]"
|
||||
msgstr "[Ändra användare]"
|
||||
msgstr "[Byt användare]"
|
||||
|
||||
msgctxt "#30025"
|
||||
msgid "Password:"
|
||||
@@ -681,7 +681,7 @@ msgstr "Användarnamn:"
|
||||
|
||||
msgctxt "#30017"
|
||||
msgid "Show connected clients"
|
||||
msgstr "Visa anslutna enheter"
|
||||
msgstr "Visa anslutna klienter"
|
||||
|
||||
msgctxt "#30014"
|
||||
msgid "Jellyfin"
|
||||
@@ -711,10 +711,9 @@ msgctxt "#30330"
|
||||
msgid "Show change user dialog"
|
||||
msgstr "Visa ändra användardialogrutan"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30315"
|
||||
msgid "Suppress notifications for connection errors"
|
||||
msgstr "Undertryck aviseringar för anslutningsfel"
|
||||
msgstr "Visa inte varningar angående anslutningsfel"
|
||||
|
||||
msgctxt "#30304"
|
||||
msgid "Cached Jellyfin images : "
|
||||
@@ -748,10 +747,9 @@ msgctxt "#30295"
|
||||
msgid "To use this feature you need HTTP control enabled"
|
||||
msgstr "För att använda den här funktionen måste du aktivera HTTP-kontroll"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30294"
|
||||
msgid "Notice"
|
||||
msgstr "Notis"
|
||||
msgstr "Bevisning"
|
||||
|
||||
msgctxt "#30293"
|
||||
msgid "Cache images"
|
||||
@@ -765,24 +763,21 @@ msgctxt "#30291"
|
||||
msgid "Select Audio Stream"
|
||||
msgstr "Välj ljudström"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30118"
|
||||
msgid "Add resume percent to names"
|
||||
msgstr "Lägg till fortsättningsprocent i namn"
|
||||
msgstr "Lägg till \"procent kvar\" bredvid namnen"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30116"
|
||||
msgid "Add unwatched counts to names"
|
||||
msgstr "Lägg till ej sedda räkningar till namn"
|
||||
msgstr "Lägg in en \"inte än sedd\" räknare bredvid namnen"
|
||||
|
||||
msgctxt "#30279"
|
||||
msgid "TV Shows - Unwatched"
|
||||
msgstr "TV Serier- Ej sedd"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30286"
|
||||
msgid "Movies - Unwatched"
|
||||
msgstr "Film - Ej sedd"
|
||||
msgstr "Film - Osädda"
|
||||
|
||||
msgctxt "#30285"
|
||||
msgid " - Unwatched"
|
||||
@@ -796,23 +791,20 @@ msgctxt "#30281"
|
||||
msgid "Refresh Cached Images"
|
||||
msgstr "Uppdatera cachelagrade bilder"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30278"
|
||||
msgid " - Next Up"
|
||||
msgstr "- Nästa upp"
|
||||
msgstr "- Nästa"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30277"
|
||||
msgid "JellyCon needs to prompt for resume on partily played items, Kodi can also prompt, this can cause a double prompt. Do you want to remove the double prompt?"
|
||||
msgstr ""
|
||||
"JellyCon måste fråga om återuppta på partiellt spelade objekt, Kodi kan "
|
||||
"också fråga, detta kan orsaka en dubbel prompt. Vill du ta bort den dubbla "
|
||||
"prompten?"
|
||||
"JellyCon måste fråga om att fortsätta uppspelada halvsedda filmer, Kodi kan "
|
||||
"också fråga, detta kan orsaka två prompter. Vill du ta bort den dubbla "
|
||||
"prompter?"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30276"
|
||||
msgid "Extra Resume Prompt Detected"
|
||||
msgstr "Extra uppmaning om återuppta upptäckt"
|
||||
msgstr "Extra uppmaning om att fortsätta upspelning upptäckt"
|
||||
|
||||
msgctxt "#30247"
|
||||
msgid "Custom Widget Content"
|
||||
@@ -826,7 +818,6 @@ msgctxt "#30220"
|
||||
msgid "Prompt to delete movie after %"
|
||||
msgstr "Uppmaning att radera film efter %"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30219"
|
||||
msgid " - Prompt before play"
|
||||
msgstr "- Fråga före uppspelning"
|
||||
@@ -835,15 +826,13 @@ msgctxt "#30217"
|
||||
msgid "Prompt to delete episode after %"
|
||||
msgstr "Uppmaning att radera avsnitt efter %"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30215"
|
||||
msgid "On playback stop (100% = disabled)"
|
||||
msgstr "Vid uppspelningsstopp (100 % = avaktiverad)"
|
||||
msgstr "Vid uppspelnings stopp (100 % = avaktiverad)"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30210"
|
||||
msgid "HTTP direct stream"
|
||||
msgstr "HTTP direktström"
|
||||
msgstr "HTTP direkt stream"
|
||||
|
||||
msgctxt "#30209"
|
||||
msgid "File direct path"
|
||||
@@ -855,48 +844,43 @@ msgstr "Högsta strömbithastighet (kbps)"
|
||||
|
||||
msgctxt "#30126"
|
||||
msgid "Processing Item : "
|
||||
msgstr "Bearbetning av objektet:"
|
||||
msgstr "Bearbetning av Objektet:"
|
||||
|
||||
msgctxt "#30120"
|
||||
msgid "Show load progress"
|
||||
msgstr "Visa laddningsförloppet"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30063"
|
||||
msgid "N/A"
|
||||
msgstr "Ej tillgängligt"
|
||||
msgstr "N/A"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30053"
|
||||
msgid "Waiting for server to delete"
|
||||
msgstr "Väntar på att servern ska radera"
|
||||
|
||||
msgctxt "#30044"
|
||||
msgid "Incorrect Username/Password"
|
||||
msgstr "Fel användarnamn/lösenord"
|
||||
msgstr "Fel Användarnamn/Lösenord"
|
||||
|
||||
msgctxt "#30027"
|
||||
msgid "Enable debug logging"
|
||||
msgstr "Aktivera felsökningsloggning"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30026"
|
||||
msgid "Widget item select action"
|
||||
msgstr "Välj åtgärd för widgetobjekt"
|
||||
|
||||
msgctxt "#30023"
|
||||
msgid "Hide unwatched episode details"
|
||||
msgstr "Dölj detaljer om avsnittet som inte har setts"
|
||||
msgstr "Dölj detaljer om avsnitt som inte har setts"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30020"
|
||||
msgid "Flatten single season"
|
||||
msgstr "Platta enstaka säsong"
|
||||
msgstr "Platta enskild säsong"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30019"
|
||||
msgid "Filtered episode name format"
|
||||
msgstr "Filtrerat avsnittsnamnformat"
|
||||
msgstr "Filtrerat format för avsnittsnamn"
|
||||
|
||||
msgctxt "#30018"
|
||||
msgid "Number of items to show in filtered lists"
|
||||
@@ -906,12 +890,219 @@ msgctxt "#30016"
|
||||
msgid "Device display name"
|
||||
msgstr "Enhetens visningsnamn"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30015"
|
||||
msgid "Log timing data"
|
||||
msgstr "Logga tidsdata"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30010"
|
||||
msgid "Number of performance profiles to capture"
|
||||
msgstr "Antal prestandaprofiler som ska fångas"
|
||||
msgstr "Antal prestanda profiler som ska räknas"
|
||||
|
||||
msgctxt "#30375"
|
||||
msgid "Receiving data packet"
|
||||
msgstr "Tar emot datapaket"
|
||||
|
||||
msgctxt "#30371"
|
||||
msgid "Could not connect to the URL you entered, do you want to try again?"
|
||||
msgstr ""
|
||||
"Det gick inte att ansluta till webbadressen du angav, vill du försöka igen?"
|
||||
|
||||
msgctxt "#30370"
|
||||
msgid "Do you want to manually enter a server url?"
|
||||
msgstr "Vill du ange en server-url manuellt?"
|
||||
|
||||
msgctxt "#30369"
|
||||
msgid "Do you want to clear your saved password?"
|
||||
msgstr "Vill du rensa ditt sparade lösenord?"
|
||||
|
||||
msgctxt "#30368"
|
||||
msgid "Clear Password?"
|
||||
msgstr "Rensa lösenord?"
|
||||
|
||||
msgctxt "#30366"
|
||||
msgid "Manually enter user details"
|
||||
msgstr "Ange användarinformation manuellt"
|
||||
|
||||
msgctxt "#30358"
|
||||
msgid "Retreiving remote image list"
|
||||
msgstr "Hämtar extern bildlista"
|
||||
|
||||
msgctxt "#30357"
|
||||
msgid "Processing existing image list"
|
||||
msgstr "Bearbetar den befintliga bildlistan"
|
||||
|
||||
msgctxt "#30356"
|
||||
msgid "Loading existing image list"
|
||||
msgstr "Laddar befintlig bildlista"
|
||||
|
||||
msgctxt "#30355"
|
||||
msgid "Kodi Settings->Services->Allow remote control via HTTP"
|
||||
msgstr "Kodi Inställningar->Tjänster->Tillåt fjärrstyrning via HTTP"
|
||||
|
||||
msgctxt "#30319"
|
||||
msgid "Music - All Album Artists"
|
||||
msgstr "Musik - Alla Albumartister"
|
||||
|
||||
msgctxt "#30352"
|
||||
msgid "Music - Frequently Played"
|
||||
msgstr "Musik - Ofta spelad"
|
||||
|
||||
msgctxt "#30347"
|
||||
msgid "Getting Existing Images"
|
||||
msgstr "Hämtar befintliga bilder"
|
||||
|
||||
msgctxt "#30344"
|
||||
msgid "Number of images removed from cache"
|
||||
msgstr "Mängden bilder borttagna från cache"
|
||||
|
||||
msgctxt "#30343"
|
||||
msgid "Changes Require Kodi Restart"
|
||||
msgstr "Ändringar kräver omstart av Kodi"
|
||||
|
||||
msgctxt "#30342"
|
||||
msgid "New content check interval (0 = disabled)"
|
||||
msgstr "Kontrollintervall för nytt innehåll (0 = inaktiverad)"
|
||||
|
||||
msgctxt "#30341"
|
||||
msgid "Background image update interval (0 = disabled)"
|
||||
msgstr "Uppdateringsintervall för bakgrundsbild (0 = inaktiverad)"
|
||||
|
||||
msgctxt "#30340"
|
||||
msgid "Group movies into collections"
|
||||
msgstr "Gruppera filmer i samlingar"
|
||||
|
||||
msgctxt "#30334"
|
||||
msgid "Use JellyCon context menu"
|
||||
msgstr "Använd JellyCons kontextmeny"
|
||||
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "Artister"
|
||||
|
||||
msgctxt "#30420"
|
||||
msgid "Audio max channels"
|
||||
msgstr "Antal kanaler för ljudsystem"
|
||||
|
||||
msgctxt "#30419"
|
||||
msgid "Audio codec"
|
||||
msgstr "Ljud codec"
|
||||
|
||||
msgctxt "#30418"
|
||||
msgid "Audio bitrate (Kbits)"
|
||||
msgstr "Ljud bitrate (Kbps)"
|
||||
|
||||
msgctxt "#30416"
|
||||
msgid "HTTP timeout seconds"
|
||||
msgstr "HTTP tidsutlösning i sekunder"
|
||||
|
||||
msgctxt "#30415"
|
||||
msgid " - Favorite Collections"
|
||||
msgstr "- Favorit Samlingar"
|
||||
|
||||
msgctxt "#30414"
|
||||
msgid " - Favorites"
|
||||
msgstr "- Favoriter"
|
||||
|
||||
msgctxt "#30409"
|
||||
msgid "Add-on Actions"
|
||||
msgstr "Extra functioner"
|
||||
|
||||
msgctxt "#30408"
|
||||
msgid "Custom Widgets"
|
||||
msgstr "Anpassade widgets"
|
||||
|
||||
msgctxt "#30407"
|
||||
msgid "Global Lists"
|
||||
msgstr "Globala Listor"
|
||||
|
||||
msgctxt "#30398"
|
||||
msgid "Refresh Jellyfin Metadata"
|
||||
msgstr "Uppdatera Jellyfin Metadata"
|
||||
|
||||
msgctxt "#30387"
|
||||
msgid "Unused images removed : "
|
||||
msgstr "Oanvända bilder raderade:"
|
||||
|
||||
msgctxt "#30376"
|
||||
msgid "Checking server url"
|
||||
msgstr "Kontrollerar server URL"
|
||||
|
||||
msgctxt "#30359"
|
||||
msgid "Building full image list"
|
||||
msgstr "Skapar fullständing bildmedia katalog"
|
||||
|
||||
msgctxt "#30345"
|
||||
msgid "Cache Jellyfin server data requests"
|
||||
msgstr "Cacha Jellyfin server data förfrågningar"
|
||||
|
||||
msgctxt "#30333"
|
||||
msgid "Cache artwork in the background"
|
||||
msgstr "Cacha bildmedia i bakgrunden"
|
||||
|
||||
msgctxt "#30444"
|
||||
msgid "Login using Quick Connect"
|
||||
msgstr "Logga in med \"Quick Connect\""
|
||||
|
||||
msgctxt "#30434"
|
||||
msgid "Force transcode stream bitrate (Kbits)"
|
||||
msgstr "manuell transcode stream bitrate (Kbps)"
|
||||
|
||||
msgctxt "#30436"
|
||||
msgid "Speed test data size (MB)"
|
||||
msgstr "hastighets test storlek (MB)"
|
||||
|
||||
msgctxt "#30438"
|
||||
msgid "Play cinema intros"
|
||||
msgstr "Spela upp intros"
|
||||
|
||||
msgctxt "#30439"
|
||||
msgid "Show play next episode at time left in seconds"
|
||||
msgstr "Visa nästa avsnitt några sekunder innan slutet"
|
||||
|
||||
msgctxt "#30442"
|
||||
msgid "Simple new content check"
|
||||
msgstr "Uppdatera content"
|
||||
|
||||
msgctxt "#30443"
|
||||
msgid "Quick Connect"
|
||||
msgstr "\"Quick Connect\""
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "Fortsätt se"
|
||||
|
||||
msgctxt "#30446"
|
||||
msgid "There was an error logging in"
|
||||
msgstr "Det var ett problem med att logga in"
|
||||
|
||||
msgctxt "#30367"
|
||||
msgid "Allow fast user switching password saving"
|
||||
msgstr "Acceptera spara en annan använderes lösenord snabbt"
|
||||
|
||||
msgctxt "#30378"
|
||||
msgid "Persist user details"
|
||||
msgstr "Behåll användarinformation"
|
||||
|
||||
msgctxt "#30379"
|
||||
msgid "External subtitle prompt"
|
||||
msgstr "Extern undertext prompt"
|
||||
|
||||
msgctxt "#30384"
|
||||
msgid "Random movies interval minutes (0 = disabled)"
|
||||
msgstr "Slumpmässiga filmer intervall minuter (0 = inaktiverad)"
|
||||
|
||||
msgctxt "#30385"
|
||||
msgid "Existing images before delete : "
|
||||
msgstr "Befintliga bilder före radering:"
|
||||
|
||||
msgctxt "#30400"
|
||||
msgid "Cache images interval minutes (0 = disabled)"
|
||||
msgstr "Cachebilder intervall minuter (0 = inaktiverad)"
|
||||
|
||||
msgctxt "#30423"
|
||||
msgid "NotSet"
|
||||
msgstr "Inte inställd"
|
||||
|
||||
msgctxt "#30435"
|
||||
msgid "Connection speed test"
|
||||
msgstr "hastighets test"
|
||||
|
||||
@@ -1,2 +1,328 @@
|
||||
msgid ""
|
||||
msgstr "X-Generator: Weblate\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit"
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-10-01 13:54+0000\n"
|
||||
"Last-Translator: Thanos <ahmetspam.42@hotmail.com>\n"
|
||||
"Language-Team: Turkish <https://translate.jellyfin.org/projects/jellycon/"
|
||||
"jellycon/tr/>\n"
|
||||
"Language: tr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
msgctxt "#30237"
|
||||
msgid "Start from beginning"
|
||||
msgstr "Baştan başla"
|
||||
|
||||
msgctxt "#30236"
|
||||
msgid "Force transcode h265 (hevc)"
|
||||
msgstr "H265 (hevc) kodunu dönüştürmeye zorla"
|
||||
|
||||
msgctxt "#30235"
|
||||
msgid "Episodes"
|
||||
msgstr "Bölümler"
|
||||
|
||||
msgctxt "#30231"
|
||||
msgid "Movies"
|
||||
msgstr "Filmler"
|
||||
|
||||
msgctxt "#30229"
|
||||
msgid "TV Shows"
|
||||
msgstr "TV Şovları"
|
||||
|
||||
msgctxt "#30224"
|
||||
msgid "Interaction"
|
||||
msgstr "Etkileşim"
|
||||
|
||||
msgctxt "#30223"
|
||||
msgid "Page Size and Filtering"
|
||||
msgstr "Sayfa Boyutu ve Filtreleme"
|
||||
|
||||
msgctxt "#30222"
|
||||
msgid "Item Layout"
|
||||
msgstr "Öğe Düzeni"
|
||||
|
||||
msgctxt "#30220"
|
||||
msgid "Prompt to delete movie after %"
|
||||
msgstr "%'den sonra filmi silme istemi"
|
||||
|
||||
msgctxt "#30219"
|
||||
msgid " - Prompt before play"
|
||||
msgstr "- Oynamadan önce sor"
|
||||
|
||||
msgctxt "#30218"
|
||||
msgid "Play next episode after %"
|
||||
msgstr "% sonra sonraki bölümü oynat"
|
||||
|
||||
msgctxt "#30217"
|
||||
msgid "Prompt to delete episode after %"
|
||||
msgstr "%'den sonra bölümü silme istemi"
|
||||
|
||||
msgctxt "#30216"
|
||||
msgid "Item Details"
|
||||
msgstr "Ürün Detayları"
|
||||
|
||||
msgctxt "#30215"
|
||||
msgid "On playback stop (100% = disabled)"
|
||||
msgstr "Oynatma durduğunda (%100 = devre dışı)"
|
||||
|
||||
msgctxt "#30214"
|
||||
msgid "Events"
|
||||
msgstr "Olaylar"
|
||||
|
||||
msgctxt "#30213"
|
||||
msgid "Video force 8 bit"
|
||||
msgstr "Video 8 bit kullanimini zorla"
|
||||
|
||||
msgctxt "#30212"
|
||||
msgid "Video max width"
|
||||
msgstr "Video maksimum genişliği"
|
||||
|
||||
msgctxt "#30211"
|
||||
msgid "Transcode options"
|
||||
msgstr "Kod dönüştürme seçenekleri"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30210"
|
||||
msgid "HTTP direct stream"
|
||||
msgstr "HTTP doğrudan akışı"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30209"
|
||||
msgid "File direct path"
|
||||
msgstr "Dosyanin doğrudan yolu"
|
||||
|
||||
msgctxt "#30208"
|
||||
msgid "Max stream bitrate (Kbits)"
|
||||
msgstr "Maksimum akış bit hızı (Kbps)"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30207"
|
||||
msgid "Playback"
|
||||
msgstr "Geri çalma"
|
||||
|
||||
msgctxt "#30206"
|
||||
msgid "Playback type"
|
||||
msgstr "Oynatma türü"
|
||||
|
||||
msgctxt "#30201"
|
||||
msgid "Unable to connect to server"
|
||||
msgstr "Sunucuya bağlanılamıyor"
|
||||
|
||||
msgctxt "#30200"
|
||||
msgid "URL error"
|
||||
msgstr "URL hatası"
|
||||
|
||||
msgctxt "#30183"
|
||||
msgid "Include people"
|
||||
msgstr "Kişileri dahil et"
|
||||
|
||||
msgctxt "#30182"
|
||||
msgid "Include media stream info"
|
||||
msgstr "Medya akışı bilgilerini dahil et"
|
||||
|
||||
msgctxt "#30181"
|
||||
msgid "Include plot"
|
||||
msgstr "Konuyu dahil et"
|
||||
|
||||
msgctxt "#30180"
|
||||
msgid "Select User"
|
||||
msgstr "Kullanıcı seç"
|
||||
|
||||
msgctxt "#30169"
|
||||
msgid "Address: "
|
||||
msgstr "Adres:"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30167"
|
||||
msgid "Selected Server Address"
|
||||
msgstr "Seçilen Sunucunun Adresi"
|
||||
|
||||
msgctxt "#30166"
|
||||
msgid "Select Server"
|
||||
msgstr "Sunucu seç"
|
||||
|
||||
msgctxt "#30163"
|
||||
msgid "Add (cc) if subtitle is available"
|
||||
msgstr "Altyazı varsa (cc) ekleyin"
|
||||
|
||||
msgctxt "#30139"
|
||||
msgid "No Media Type Set"
|
||||
msgstr "Medya Türü Ayarı Yok"
|
||||
|
||||
msgctxt "#30135"
|
||||
msgid "Error"
|
||||
msgstr "Hata"
|
||||
|
||||
msgctxt "#30126"
|
||||
msgid "Processing Item : "
|
||||
msgstr "Öğenin İşlenmesi:"
|
||||
|
||||
msgctxt "#30125"
|
||||
msgid "Done"
|
||||
msgstr "Tamamlandı"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30121"
|
||||
msgid "On resume"
|
||||
msgstr "Sürdürunce"
|
||||
|
||||
msgctxt "#30120"
|
||||
msgid "Show load progress"
|
||||
msgstr "Yükleme ilerlemesini göster"
|
||||
|
||||
msgctxt "#30118"
|
||||
msgid "Add resume percent to names"
|
||||
msgstr "İsimlere özgeçmiş yüzdesi ekle"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30116"
|
||||
msgid "Add unwatched counts to names"
|
||||
msgstr "Adlara izlenmeyen sayıları ekleyin"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30114"
|
||||
msgid "Jump back seconds"
|
||||
msgstr "Saniyeler geri atla"
|
||||
|
||||
msgctxt "#30113"
|
||||
msgid "Retrieving Data"
|
||||
msgstr "Veri Aliniyor"
|
||||
|
||||
msgctxt "#30112"
|
||||
msgid "Loading Content"
|
||||
msgstr "İçerik Yükleniyor"
|
||||
|
||||
msgctxt "#30111"
|
||||
msgid "Services"
|
||||
msgstr "Hizmetler"
|
||||
|
||||
msgctxt "#30110"
|
||||
msgid "Interface"
|
||||
msgstr "Arayüz"
|
||||
|
||||
msgctxt "#30092"
|
||||
msgid "Warning: This action will delete the media files from the server."
|
||||
msgstr "Uyarı: Bu eylem, medya dosyalarını sunucudan siler."
|
||||
|
||||
msgctxt "#30091"
|
||||
msgid "Confirm delete?"
|
||||
msgstr "Silmeyi onayla?"
|
||||
|
||||
msgctxt "#30063"
|
||||
msgid "N/A"
|
||||
msgstr "Yok"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30053"
|
||||
msgid "Waiting for server to delete"
|
||||
msgstr "Sunucunun silmesi bekleniyor"
|
||||
|
||||
msgctxt "#30052"
|
||||
msgid "Deleting"
|
||||
msgstr "Siliniyor"
|
||||
|
||||
msgctxt "#30045"
|
||||
msgid "Username not found"
|
||||
msgstr "Kullanıcı bulunamadı"
|
||||
|
||||
msgctxt "#30044"
|
||||
msgid "Incorrect Username/Password"
|
||||
msgstr "Yanlış kullanıcı/şifre"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30027"
|
||||
msgid "Enable debug logging"
|
||||
msgstr "Hata ayıklama günlüğünü etkinleştir"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30026"
|
||||
msgid "Widget item select action"
|
||||
msgstr "Widget öğesi seçme eylemi"
|
||||
|
||||
msgctxt "#30025"
|
||||
msgid "Password:"
|
||||
msgstr "Şifre:"
|
||||
|
||||
msgctxt "#30024"
|
||||
msgid "Username:"
|
||||
msgstr "Kullanıcı:"
|
||||
|
||||
msgctxt "#30023"
|
||||
msgid "Hide unwatched episode details"
|
||||
msgstr "İzlenmeyen bölüm ayrıntılarını gizle"
|
||||
|
||||
msgctxt "#30022"
|
||||
msgid "Advanced"
|
||||
msgstr "Gelişmiş"
|
||||
|
||||
msgctxt "#30021"
|
||||
msgid "Show all episodes item"
|
||||
msgstr "Tüm bölümleri göster"
|
||||
|
||||
msgctxt "#30020"
|
||||
msgid "Flatten single season"
|
||||
msgstr "Tek sezon düzleştirin"
|
||||
|
||||
msgctxt "#30019"
|
||||
msgid "Filtered episode name format"
|
||||
msgstr "Filtrelenmiş bölüm adı biçimi"
|
||||
|
||||
msgctxt "#30018"
|
||||
msgid "Number of items to show in filtered lists"
|
||||
msgstr "Filtrelenmiş listelerde gösterilecek öğe sayısı"
|
||||
|
||||
msgctxt "#30017"
|
||||
msgid "Show connected clients"
|
||||
msgstr "Bağlı istemcileri göster"
|
||||
|
||||
msgctxt "#30016"
|
||||
msgid "Device display name"
|
||||
msgstr "Cihazın görünen adı"
|
||||
|
||||
msgctxt "#30015"
|
||||
msgid "Log timing data"
|
||||
msgstr "Zamanlama verilerini günlüğe kaydet"
|
||||
|
||||
msgctxt "#30014"
|
||||
msgid "Jellyfin"
|
||||
msgstr "Jellyfin"
|
||||
|
||||
msgctxt "#30012"
|
||||
msgid "[Change user]"
|
||||
msgstr "[Kullanıcıyı değiştir]"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30011"
|
||||
msgid "[Detect local server]"
|
||||
msgstr "[Yerel sunucuyu algıla]"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "#30010"
|
||||
msgid "Number of performance profiles to capture"
|
||||
msgstr "Yakalanacak performans profili sayısı"
|
||||
|
||||
msgctxt "#30008"
|
||||
msgid "Samba password"
|
||||
msgstr "Samba Şifre"
|
||||
|
||||
msgctxt "#30007"
|
||||
msgid "Samba username"
|
||||
msgstr "Samba Kullanıcı"
|
||||
|
||||
msgctxt "#30006"
|
||||
msgid "Password"
|
||||
msgstr "Şifre"
|
||||
|
||||
msgctxt "#30005"
|
||||
msgid "Username"
|
||||
msgstr "Kullanıcı"
|
||||
|
||||
msgctxt "#30003"
|
||||
msgid "Verify HTTPS certificate"
|
||||
msgstr "HTTPS sertifikasını doğrulayın"
|
||||
|
||||
msgctxt "#30000"
|
||||
msgid "Host"
|
||||
msgstr "Sunucu"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2022-03-04 12:13+0000\n"
|
||||
"Last-Translator: 小造xu_zh <ngc7331@outlook.com>\n"
|
||||
"PO-Revision-Date: 2022-10-21 02:50+0000\n"
|
||||
"Last-Translator: wolong gl <wolong98@gmail.com>\n"
|
||||
"Language-Team: Chinese (Simplified) <https://translate.jellyfin.org/projects/"
|
||||
"jellycon/jellycon/zh_Hans/>\n"
|
||||
"Language: zh_Hans\n"
|
||||
@@ -9,7 +9,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 4.10.1\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
msgctxt "#30442"
|
||||
msgid "Simple new content check"
|
||||
@@ -1082,3 +1082,27 @@ msgstr "端口"
|
||||
msgctxt "#30000"
|
||||
msgid "Host"
|
||||
msgstr "主机"
|
||||
|
||||
msgctxt "#30444"
|
||||
msgid "Login using Quick Connect"
|
||||
msgstr "使用 Quick Connect 登录"
|
||||
|
||||
msgctxt "#30443"
|
||||
msgid "Quick Connect"
|
||||
msgstr "Quick Connect"
|
||||
|
||||
msgctxt "#30323"
|
||||
msgid "Artists"
|
||||
msgstr "艺术家"
|
||||
|
||||
msgctxt "#30445"
|
||||
msgid "Continue Watching"
|
||||
msgstr "继续观看"
|
||||
|
||||
msgctxt "#30439"
|
||||
msgid "Show play next episode at time left in seconds"
|
||||
msgstr "显示播放下一集的剩余时间(s)"
|
||||
|
||||
msgctxt "#30446"
|
||||
msgid "There was an error logging in"
|
||||
msgstr "登录时出错"
|
||||
|
||||
@@ -204,43 +204,3 @@ class PlayNextDialog(xbmcgui.WindowXMLDialog):
|
||||
|
||||
def get_play_called(self):
|
||||
return self.play_called
|
||||
|
||||
|
||||
class QuickConnectDialog(xbmcgui.WindowXMLDialog):
|
||||
connect_method = -1
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs)
|
||||
log.debug("QuickConnectDialog INITIALISED")
|
||||
|
||||
self.code = ''
|
||||
|
||||
def onInit(self):
|
||||
self.action_exitkeys_id = [10, 13]
|
||||
|
||||
message_control = self.getControl(3)
|
||||
message_control.setText(self.code)
|
||||
|
||||
message_control = self.getControl(4)
|
||||
message_control.setLabel(translate_string(30443))
|
||||
|
||||
self.getControl(3010).setLabel(translate_string(30444))
|
||||
self.getControl(3011).setLabel(translate_string(30365))
|
||||
|
||||
def onFocus(self, controlId):
|
||||
pass
|
||||
|
||||
def doAction(self, actionID):
|
||||
pass
|
||||
|
||||
def onClick(self, controlID):
|
||||
|
||||
if controlID == 3010:
|
||||
self.connect_method = 1
|
||||
self.close()
|
||||
if controlID == 3011:
|
||||
self.connect_method = 0
|
||||
self.close()
|
||||
|
||||
def getConnectMethod(self):
|
||||
return self.connect_method
|
||||
|
||||
@@ -68,6 +68,11 @@ def get_content(url, params):
|
||||
content_type = 'episodes'
|
||||
elif media_type == "playlists":
|
||||
view_type = "Playlists"
|
||||
elif media_type == "musicvideos":
|
||||
view_type = "Music Videos"
|
||||
content_type = 'musicvideos'
|
||||
elif media_type == "mixed":
|
||||
content_type = 'videos'
|
||||
|
||||
log.debug("media_type:{0} content_type:{1} view_type:{2} ".format(media_type, content_type, view_type))
|
||||
|
||||
@@ -244,10 +249,13 @@ def process_directory(url, progress, params, use_cache_data=False):
|
||||
# Fix skin shortcuts from pre-0.5.0
|
||||
item_limit = int(settings.getSetting("show_x_filtered_items"))
|
||||
url = url.replace('{server}', '')
|
||||
url = url.replace('{userid}', user_id)
|
||||
url = url.replace('{field_filters}', default_filters)
|
||||
url = url.replace('{ItemLimit}', str(item_limit))
|
||||
|
||||
# Need to replace at runtime so it always pulls the current user
|
||||
url = unquote(url)
|
||||
url = url.replace('{userid}', user_id)
|
||||
|
||||
cache_file, item_list, total_records, cache_thread = data_manager.get_items(url, gui_options, use_cache)
|
||||
|
||||
# flatten single season
|
||||
@@ -259,7 +267,7 @@ def process_directory(url, progress, params, use_cache_data=False):
|
||||
series_id = item_list[0].series_id
|
||||
season_url = ('/Shows/' + series_id +
|
||||
'/Episodes'
|
||||
'?userId={}'.format(user_id) +
|
||||
'?userId={userid}' +
|
||||
'&seasonId=' + season_id +
|
||||
'&IsVirtualUnAired=false' +
|
||||
'&IsMissing=false' +
|
||||
@@ -324,14 +332,16 @@ def process_directory(url, progress, params, use_cache_data=False):
|
||||
if item_details.item_type == "Series":
|
||||
u = ('/Shows/' + item_details.id +
|
||||
'/Seasons'
|
||||
'?userId={}'.format(user_id) +
|
||||
'?userId={userid}' +
|
||||
'&Fields={}'.format(default_filters) +
|
||||
'&format=json')
|
||||
if not show_empty_folders:
|
||||
u = u + '&isMissing=False'
|
||||
|
||||
elif item_details.item_type == "Season":
|
||||
u = ('/Shows/' + item_details.series_id +
|
||||
'/Episodes'
|
||||
'?userId={}'.format(user_id) +
|
||||
'?userId={userid}' +
|
||||
'&seasonId=' + item_details.id +
|
||||
'&IsVirtualUnAired=false' +
|
||||
'&IsMissing=false' +
|
||||
@@ -339,7 +349,7 @@ def process_directory(url, progress, params, use_cache_data=False):
|
||||
'&format=json')
|
||||
|
||||
else:
|
||||
u = ('/Users/{}/items'.format(user_id) +
|
||||
u = ('/Users/{userid}/items' +
|
||||
'?ParentId=' + item_details.id +
|
||||
'&IsVirtualUnAired=false' +
|
||||
'&IsMissing=false' +
|
||||
@@ -356,7 +366,7 @@ def process_directory(url, progress, params, use_cache_data=False):
|
||||
log.debug("Dropping empty folder item : {0}".format(item_details.__dict__))
|
||||
|
||||
elif item_details.item_type == "MusicArtist":
|
||||
u = ('/Users/{}/items'.format(user_id) +
|
||||
u = ('/Users/{userid}/items' +
|
||||
'?ArtistIds=' + item_details.id +
|
||||
'&IncludeItemTypes=MusicAlbum' +
|
||||
'&CollapseBoxSetItems=false' +
|
||||
@@ -380,7 +390,7 @@ def process_directory(url, progress, params, use_cache_data=False):
|
||||
and first_season_item.series_id is not None):
|
||||
series_url = ('/Shows/' + first_season_item.series_id +
|
||||
'/Episodes'
|
||||
'?userId={}'.format(user_id) +
|
||||
'?userId={userid}' +
|
||||
'&IsVirtualUnAired=false' +
|
||||
'&IsMissing=false' +
|
||||
'&Fields=SpecialEpisodeNumbers,{}'.format(default_filters) +
|
||||
|
||||
@@ -153,14 +153,14 @@ def main_entry_point():
|
||||
|
||||
file_time_stamp = time.strftime("%Y%m%d-%H%M%S")
|
||||
tab_file_name = __addondir__ + "profile(" + file_time_stamp + ").txt"
|
||||
s = StringIO.StringIO()
|
||||
s = StringIO()
|
||||
ps = pstats.Stats(pr, stream=s)
|
||||
ps = ps.sort_stats('cumulative')
|
||||
ps.print_stats()
|
||||
ps.strip_dirs()
|
||||
ps = ps.sort_stats('tottime')
|
||||
ps.print_stats()
|
||||
with open(tab_file_name, 'wb') as f:
|
||||
with open(tab_file_name, 'w') as f:
|
||||
f.write(s.getvalue())
|
||||
|
||||
log.debug("===== JellyCon FINISHED =====")
|
||||
@@ -343,22 +343,22 @@ def show_menu(params):
|
||||
|
||||
action_items = []
|
||||
|
||||
if result["Type"] in ["Episode", "Movie", "Music", "Video", "Audio", "TvChannel", "Program"]:
|
||||
if result["Type"] in ["Episode", "Movie", "Music", "Video", "Audio", "TvChannel", "Program", "MusicVideo"]:
|
||||
li = xbmcgui.ListItem(translate_string(30314), offscreen=True)
|
||||
li.setProperty('menu_id', 'play')
|
||||
action_items.append(li)
|
||||
|
||||
if result["Type"] in ["Season", "MusicAlbum", "Playlist"]:
|
||||
if result["Type"] in ["Season", "MusicArtist", "MusicAlbum", "Playlist"]:
|
||||
li = xbmcgui.ListItem(translate_string(30317), offscreen=True)
|
||||
li.setProperty('menu_id', 'play_all')
|
||||
action_items.append(li)
|
||||
|
||||
if result["Type"] in ["Episode", "Movie", "Video", "TvChannel", "Program"]:
|
||||
if result["Type"] in ["Episode", "Movie", "Video", "TvChannel", "Program", "MusicVideo"]:
|
||||
li = xbmcgui.ListItem(translate_string(30275), offscreen=True)
|
||||
li.setProperty('menu_id', 'transcode')
|
||||
action_items.append(li)
|
||||
|
||||
if result["Type"] in ["Episode", "Movie", "Music", "Video", "Audio"]:
|
||||
if result["Type"] in ["Episode", "Movie", "Music", "Video", "Audio", "MusicArtist", "MusicAlbum", "MusicVideo"]:
|
||||
li = xbmcgui.ListItem(translate_string(30402), offscreen=True)
|
||||
li.setProperty('menu_id', 'add_to_playlist')
|
||||
action_items.append(li)
|
||||
|
||||
@@ -4,10 +4,11 @@ import sys
|
||||
from six.moves.urllib.parse import quote
|
||||
|
||||
from datetime import datetime
|
||||
from dateutil import tz
|
||||
|
||||
import xbmcgui
|
||||
|
||||
from .utils import datetime_from_string, get_art_url, image_url, kodi_version
|
||||
from .utils import datetime_from_string, get_art_url, image_url, get_current_datetime
|
||||
from .lazylogger import LazyLogger
|
||||
from six import ensure_text
|
||||
|
||||
@@ -402,12 +403,15 @@ def add_gui_item(url, item_details, display_options, folder=True, default_sort=F
|
||||
end_time = datetime_from_string(item_details.program_end_date)
|
||||
|
||||
duration = (end_time - start_time).total_seconds()
|
||||
time_done = (datetime.now().astimezone() - start_time).total_seconds()
|
||||
now = get_current_datetime()
|
||||
time_done = (now - start_time).total_seconds()
|
||||
percentage_done = (float(time_done) / float(duration)) * 100.0
|
||||
capped_percentage = int(percentage_done)
|
||||
|
||||
start_time_string = start_time.strftime("%H:%M")
|
||||
end_time_string = end_time.strftime("%H:%M")
|
||||
# Convert dates to local timezone for display
|
||||
local = tz.tzlocal()
|
||||
start_time_string = start_time.astimezone(local).strftime("%H:%M")
|
||||
end_time_string = end_time.astimezone(local).strftime("%H:%M")
|
||||
|
||||
item_details.duration = int(duration)
|
||||
item_details.resume_time = int(time_done)
|
||||
@@ -499,6 +503,8 @@ def add_gui_item(url, item_details, display_options, folder=True, default_sort=F
|
||||
mediatype = 'artist'
|
||||
elif item_type == 'audio' or item_type == 'music':
|
||||
mediatype = 'song'
|
||||
elif item_type == 'musicvideo':
|
||||
mediatype = 'musicvideo'
|
||||
|
||||
info_labels["mediatype"] = mediatype
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import xbmcaddon
|
||||
from kodi_six.utils import py2_decode
|
||||
|
||||
import requests
|
||||
import json
|
||||
|
||||
from .utils import get_device_id, get_version, load_user_details
|
||||
from .lazylogger import LazyLogger
|
||||
@@ -24,8 +25,8 @@ class API:
|
||||
self.verify_cert = settings.getSetting('verify_cert') == 'true'
|
||||
|
||||
def get(self, path):
|
||||
if 'x-mediabrowser-token' not in self.headers:
|
||||
self.create_headers()
|
||||
if 'x-mediabrowser-token' not in self.headers or self.token not in self.headers:
|
||||
self.create_headers(True)
|
||||
|
||||
# Fixes initial login where class is initialized before wizard completes
|
||||
if not self.server:
|
||||
@@ -36,33 +37,50 @@ class API:
|
||||
|
||||
r = requests.get(url, headers=self.headers, verify=self.verify_cert)
|
||||
try:
|
||||
response_data = r.json()
|
||||
try:
|
||||
'''
|
||||
The requests library defaults to using simplejson to handle
|
||||
json decoding. On low power devices and using Py3, this is
|
||||
significantly slower than the builtin json library. Skip that
|
||||
and just parse the json ourselves. Fall back to using
|
||||
requests/simplejson if there's a parsing error.
|
||||
'''
|
||||
r.raise_for_status()
|
||||
response_data = json.loads(r.text)
|
||||
except ValueError:
|
||||
response_data = r.json()
|
||||
except:
|
||||
response_data = {}
|
||||
return response_data
|
||||
|
||||
def post(self, url, payload={}):
|
||||
if 'x-mediabrowser-token' not in self.headers:
|
||||
self.create_headers()
|
||||
if 'x-mediabrowser-token' not in self.headers or self.token not in self.headers:
|
||||
self.create_headers(True)
|
||||
|
||||
url = '{}{}'.format(self.server, url)
|
||||
|
||||
r = requests.post(url, json=payload, headers=self.headers, verify=self.verify_cert)
|
||||
try:
|
||||
response_data = r.json()
|
||||
try:
|
||||
# Much faster on low power devices, see above comment
|
||||
response_data = json.loads(r.text)
|
||||
except ValueError:
|
||||
response_data = r.json()
|
||||
except:
|
||||
response_data = {}
|
||||
return response_data
|
||||
|
||||
def delete(self, url):
|
||||
if 'x-mediabrowser-token' not in self.headers:
|
||||
self.create_headers()
|
||||
if 'x-mediabrowser-token' not in self.headers or self.token not in self.headers:
|
||||
self.create_headers(True)
|
||||
|
||||
url = '{}{}'.format(self.server, url)
|
||||
|
||||
requests.delete(url, headers=self.headers, verify=self.verify_cert)
|
||||
|
||||
def authenticate(self, auth_data):
|
||||
# Always force create fresh headers during authentication
|
||||
self.create_headers(True)
|
||||
response = self.post('/Users/AuthenticateByName', auth_data)
|
||||
token = response.get('AccessToken')
|
||||
if token:
|
||||
@@ -75,10 +93,10 @@ class API:
|
||||
log.error('Unable to authenticate to Jellyfin server')
|
||||
return {}
|
||||
|
||||
def create_headers(self):
|
||||
def create_headers(self, force=False):
|
||||
|
||||
# If the headers already exist with an auth token, return
|
||||
if self.headers and 'x-mediabrowser-token' in self.headers:
|
||||
# If the headers already exist with an auth token, return unless we're regenerating
|
||||
if self.headers and 'x-mediabrowser-token' in self.headers and force is False:
|
||||
return
|
||||
|
||||
headers = {}
|
||||
@@ -101,8 +119,8 @@ class API:
|
||||
|
||||
headers['x-emby-authorization'] = authorization
|
||||
|
||||
# If we have a valid token, ensure it's included in the headers
|
||||
if self.token:
|
||||
# If we have a valid token, ensure it's included in the headers unless we're regenerating
|
||||
if self.token and force is False:
|
||||
headers['x-mediabrowser-token'] = self.token
|
||||
else:
|
||||
# Check for updated credentials since initialization
|
||||
|
||||
@@ -75,7 +75,7 @@ def show_movie_tags(menu_params):
|
||||
if parent_id:
|
||||
menu_params["ParentId"] = parent_id
|
||||
|
||||
item_url = get_jellyfin_url("/Users/{}/Items".format(user_id), url_params)
|
||||
item_url = get_jellyfin_url("/Users/{userid}/Items", url_params)
|
||||
|
||||
art = {"thumb": "http://localhost:24276/{}".format(ensure_text(base64.b64encode(ensure_binary(item_url))))}
|
||||
|
||||
@@ -164,7 +164,7 @@ def show_movie_years(menu_params):
|
||||
if parent_id:
|
||||
params["ParentId"] = parent_id
|
||||
|
||||
item_url = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
item_url = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
|
||||
art = {"thumb": "http://localhost:24276/{}".format(ensure_text(base64.b64encode(ensure_binary(item_url))))}
|
||||
|
||||
@@ -237,7 +237,7 @@ def show_movie_pages(menu_params):
|
||||
if parent_id:
|
||||
params["ParentId"] = parent_id
|
||||
|
||||
item_url = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
item_url = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
|
||||
page_upper = start_index + page_limit
|
||||
if page_upper > total_results:
|
||||
@@ -280,6 +280,9 @@ def show_genre_list(menu_params):
|
||||
elif item_type == 'MusicAlbum':
|
||||
jellyfin_type = 'MusicAlbum'
|
||||
kodi_type = 'albums'
|
||||
elif item_type == 'mixed':
|
||||
jellyfin_type = 'Movie,Series'
|
||||
kodi_type = 'videos'
|
||||
|
||||
params = {
|
||||
"IncludeItemTypes": jellyfin_type,
|
||||
@@ -323,7 +326,7 @@ def show_genre_list(menu_params):
|
||||
if parent_id is not None:
|
||||
params["ParentId"] = parent_id
|
||||
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
|
||||
art = {"thumb": "http://localhost:24276/{}".format(ensure_text(base64.b64encode(ensure_binary(path))))}
|
||||
|
||||
@@ -389,7 +392,7 @@ def show_movie_alpha_list(menu_params):
|
||||
if 'NameLessThan' in params:
|
||||
params.pop('NameLessThan')
|
||||
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
|
||||
art = {"thumb": "http://localhost:24276/{}".format(ensure_text(base64.b64encode(ensure_binary(path))))}
|
||||
|
||||
@@ -439,7 +442,7 @@ def show_tvshow_alpha_list(menu_params):
|
||||
if 'NameLessThan' in params:
|
||||
params.pop('NameLessThan')
|
||||
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
|
||||
art = {"thumb": "http://localhost:24276/{}".format(ensure_text(base64.b64encode(ensure_binary(path))))}
|
||||
|
||||
@@ -451,6 +454,55 @@ def show_tvshow_alpha_list(menu_params):
|
||||
xbmcplugin.endOfDirectory(int(sys.argv[1]))
|
||||
|
||||
|
||||
def show_mixed_alpha_list(menu_params):
|
||||
log.debug("== ENTER: showTvShowAlphaList() ==")
|
||||
|
||||
server = settings.getSetting('server_address')
|
||||
if server is None:
|
||||
return
|
||||
|
||||
parent_id = menu_params.get("parent_id")
|
||||
|
||||
prefixes = '#' + string.ascii_uppercase
|
||||
|
||||
params = {
|
||||
"Fields": get_default_filters(),
|
||||
"ImageTypeLimit": 1,
|
||||
"IncludeItemTypes": "Series,Movie",
|
||||
"SortBy": "Name",
|
||||
"SortOrder": "Ascending",
|
||||
"Recursive": True,
|
||||
"IsMissing": False
|
||||
}
|
||||
|
||||
for alpha_name in prefixes:
|
||||
|
||||
if parent_id is not None:
|
||||
params["ParentId"] = parent_id
|
||||
|
||||
if alpha_name == "#":
|
||||
params["NameLessThan"] = "A"
|
||||
# Ensure we don't try to search both at once
|
||||
if 'NameStartsWith' in params:
|
||||
params.pop('NameStartsWith')
|
||||
else:
|
||||
params["NameStartsWith"] = alpha_name
|
||||
# Ensure we don't try to search both at once
|
||||
if 'NameLessThan' in params:
|
||||
params.pop('NameLessThan')
|
||||
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
|
||||
art = {"thumb": "http://localhost:24276/{}".format(ensure_text(base64.b64encode(ensure_binary(path))))}
|
||||
|
||||
url = (sys.argv[0] + "?url=" + quote(path) +
|
||||
"&mode=GET_CONTENT&media_type=mixed")
|
||||
log.debug("addMenuDirectoryItem: {0} ({1})".format(alpha_name, url))
|
||||
add_menu_directory_item(alpha_name, url, art=art)
|
||||
|
||||
xbmcplugin.endOfDirectory(int(sys.argv[1]))
|
||||
|
||||
|
||||
def show_artist_alpha_list(menu_params):
|
||||
log.debug("== ENTER: showArtistAlphaList() ==")
|
||||
|
||||
@@ -501,7 +553,7 @@ def show_artist_alpha_list(menu_params):
|
||||
if 'NameLessThan' in params:
|
||||
params.pop('NameLessThan')
|
||||
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
|
||||
art = {"thumb": "http://localhost:24276/{}".format(ensure_text(base64.b64encode(ensure_binary(path))))}
|
||||
|
||||
@@ -554,6 +606,18 @@ def display_menu(params):
|
||||
def show_global_types(params):
|
||||
handle = int(sys.argv[1])
|
||||
|
||||
user_id = get_current_user_id()
|
||||
|
||||
continue_watching_url_params = {
|
||||
"Fields": get_default_filters(),
|
||||
"ImageTypeLimit": 1,
|
||||
}
|
||||
continue_watching_url = get_jellyfin_url("/Users/{userid}/Items/Resume", continue_watching_url_params)
|
||||
add_menu_directory_item(translate_string(30445),
|
||||
"plugin://plugin.video.jellycon/?mode=GET_CONTENT&url=" + quote(continue_watching_url) +
|
||||
"&media_type=movies" +
|
||||
"&name_format="+quote("Episode|episode_name_format"))
|
||||
|
||||
add_menu_directory_item(translate_string(30256),
|
||||
"plugin://plugin.video.jellycon/?mode=SHOW_ADDON_MENU&type=global_list_movies")
|
||||
add_menu_directory_item(translate_string(30261),
|
||||
@@ -577,7 +641,7 @@ def display_homevideos_type(menu_params, view):
|
||||
"Fields": get_default_filters(),
|
||||
"ImageTypeLimit": 1
|
||||
}
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), base_params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", base_params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=homevideos"
|
||||
add_menu_directory_item(view_name + translate_string(30405), url)
|
||||
|
||||
@@ -587,7 +651,7 @@ def display_homevideos_type(menu_params, view):
|
||||
params["Filters"] = "IsResumable"
|
||||
params["Recursive"] = True
|
||||
params["Limit"] = item_limit
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=homevideos"
|
||||
add_menu_directory_item(view_name + translate_string(30267) + " (" + item_limit + ")", url)
|
||||
|
||||
@@ -601,7 +665,7 @@ def display_homevideos_type(menu_params, view):
|
||||
if hide_watched:
|
||||
params["IsPlayed"] = False
|
||||
params["Limit"] = item_limit
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=homevideos"
|
||||
add_menu_directory_item(view_name + translate_string(30268) + " (" + item_limit + ")", url)
|
||||
|
||||
@@ -644,7 +708,7 @@ def display_tvshow_type(menu_params, view):
|
||||
}
|
||||
if view is not None:
|
||||
base_params["ParentId"] = view.get("Id")
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), base_params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", base_params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=tvshows"
|
||||
add_menu_directory_item(view_name + translate_string(30405), url)
|
||||
|
||||
@@ -652,7 +716,7 @@ def display_tvshow_type(menu_params, view):
|
||||
params = {}
|
||||
params.update(base_params)
|
||||
params["Filters"] = "IsFavorite"
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=tvshows"
|
||||
add_menu_directory_item(view_name + translate_string(30414), url)
|
||||
|
||||
@@ -660,7 +724,7 @@ def display_tvshow_type(menu_params, view):
|
||||
params = {}
|
||||
params.update(base_params)
|
||||
params["IsPlayed"] = False
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=tvshows"
|
||||
add_menu_directory_item(view_name + translate_string(30285), url)
|
||||
|
||||
@@ -672,7 +736,7 @@ def display_tvshow_type(menu_params, view):
|
||||
params["SortOrder"] = "Descending"
|
||||
params["Filters"] = "IsResumable"
|
||||
params["IncludeItemTypes"] = "Episode"
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=Episodes&sort=none"
|
||||
url += "&name_format=" + quote('Episode|episode_name_format')
|
||||
add_menu_directory_item(view_name + translate_string(30267) + " (" + item_limit + ")", url)
|
||||
@@ -684,7 +748,7 @@ def display_tvshow_type(menu_params, view):
|
||||
params["SortBy"] = "DateCreated"
|
||||
params["SortOrder"] = "Descending"
|
||||
params["IncludeItemTypes"] = "Episode"
|
||||
path = get_jellyfin_url("/Users/{}/Items/Latest".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items/Latest", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=tvshows&sort=none"
|
||||
add_menu_directory_item(view_name + translate_string(30288) + " (" + item_limit + ")", url)
|
||||
|
||||
@@ -696,7 +760,7 @@ def display_tvshow_type(menu_params, view):
|
||||
params["SortOrder"] = "Descending"
|
||||
params["Filters"] = "IsNotFolder"
|
||||
params["IncludeItemTypes"] = "Episode"
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=Episodes&sort=none"
|
||||
url += "&name_format=" + quote('Episode|episode_name_format')
|
||||
add_menu_directory_item(view_name + translate_string(30268) + " (" + item_limit + ")", url)
|
||||
@@ -705,7 +769,7 @@ def display_tvshow_type(menu_params, view):
|
||||
params = {}
|
||||
params.update(base_params)
|
||||
params["Limit"] = item_limit
|
||||
params["Userid"] = user_id
|
||||
params["Userid"] = '{userid}'
|
||||
params["SortBy"] = "DateCreated"
|
||||
params["SortOrder"] = "Descending"
|
||||
params["Filters"] = "IsNotFolder"
|
||||
@@ -744,7 +808,7 @@ def display_music_type(menu_params, view):
|
||||
"ImageTypeLimit": 1,
|
||||
"IncludeItemTypes": "MusicAlbum"
|
||||
}
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbums"
|
||||
add_menu_directory_item(view_name + translate_string(30320), url)
|
||||
|
||||
@@ -755,7 +819,7 @@ def display_music_type(menu_params, view):
|
||||
"IncludeItemTypes": "Audio",
|
||||
"Limit": item_limit
|
||||
}
|
||||
path = get_jellyfin_url("/Users/{}/Items/Latest".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items/Latest", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbums"
|
||||
add_menu_directory_item(view_name + translate_string(30268) + " (" + item_limit + ")", url)
|
||||
|
||||
@@ -770,7 +834,7 @@ def display_music_type(menu_params, view):
|
||||
"SortBy": "DatePlayed",
|
||||
"SortOrder": "Descending"
|
||||
}
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbum"
|
||||
add_menu_directory_item(view_name + translate_string(30349) + " (" + item_limit + ")", url)
|
||||
|
||||
@@ -785,7 +849,7 @@ def display_music_type(menu_params, view):
|
||||
"SortBy": "PlayCount",
|
||||
"SortOrder": "Descending"
|
||||
}
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=MusicAlbum"
|
||||
add_menu_directory_item(view_name + translate_string(30353) + " (" + item_limit + ")", url)
|
||||
|
||||
@@ -830,7 +894,7 @@ def display_musicvideos_type(params, view):
|
||||
"IsMissing": False,
|
||||
"Fields": get_default_filters()
|
||||
}
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=musicvideos"
|
||||
add_menu_directory_item(view_name + translate_string(30405), url)
|
||||
|
||||
@@ -846,7 +910,7 @@ def display_livetv_type(menu_params, view):
|
||||
|
||||
# channels
|
||||
params = {
|
||||
"UserId": user_id,
|
||||
"UserId": '{userid}',
|
||||
"Recursive": False,
|
||||
"ImageTypeLimit": 1,
|
||||
"Fields": get_default_filters()
|
||||
@@ -857,7 +921,7 @@ def display_livetv_type(menu_params, view):
|
||||
|
||||
# programs
|
||||
params = {
|
||||
"UserId": user_id,
|
||||
"UserId": '{userid}',
|
||||
"IsAiring": True,
|
||||
"ImageTypeLimit": 1,
|
||||
"Fields": get_default_filters() + ",ChannelInfo",
|
||||
@@ -869,7 +933,7 @@ def display_livetv_type(menu_params, view):
|
||||
|
||||
# recordings
|
||||
params = {
|
||||
"UserId": user_id,
|
||||
"UserId": '{userid}',
|
||||
"Recursive": False,
|
||||
"ImageTypeLimit": 1,
|
||||
"Fields": get_default_filters(),
|
||||
@@ -908,7 +972,7 @@ def display_movies_type(menu_params, view):
|
||||
base_params["ParentId"] = view.get("Id")
|
||||
|
||||
# All Movies
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), base_params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", base_params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies"
|
||||
add_menu_directory_item('{}{}'.format(view_name, translate_string(30405)), url)
|
||||
|
||||
@@ -918,7 +982,7 @@ def display_movies_type(menu_params, view):
|
||||
params["CollapseBoxSetItems"] = False
|
||||
params["GroupItemsIntoCollections"] = False
|
||||
params["Filters"] = "IsFavorite"
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies"
|
||||
add_menu_directory_item('{}{}'.format(view_name, translate_string(30414)), url)
|
||||
|
||||
@@ -928,7 +992,7 @@ def display_movies_type(menu_params, view):
|
||||
params["CollapseBoxSetItems"] = False
|
||||
params["GroupItemsIntoCollections"] = False
|
||||
params["IsPlayed"] = False
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies"
|
||||
add_menu_directory_item('{}{}'.format(view_name, translate_string(30285)), url)
|
||||
|
||||
@@ -941,7 +1005,7 @@ def display_movies_type(menu_params, view):
|
||||
params["CollapseBoxSetItems"] = False
|
||||
params["GroupItemsIntoCollections"] = False
|
||||
params["Limit"] = item_limit
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies&sort=none"
|
||||
add_menu_directory_item('{}{} ({})'.format(view_name, translate_string(30349), item_limit), url)
|
||||
|
||||
@@ -952,7 +1016,7 @@ def display_movies_type(menu_params, view):
|
||||
params["SortBy"] = "DatePlayed"
|
||||
params["SortOrder"] = "Descending"
|
||||
params["Limit"] = item_limit
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies&sort=none"
|
||||
add_menu_directory_item('{}{} ({})'.format(view_name, translate_string(30267), item_limit), url)
|
||||
|
||||
@@ -964,7 +1028,7 @@ def display_movies_type(menu_params, view):
|
||||
params["SortBy"] = "DateCreated"
|
||||
params["SortOrder"] = "Descending"
|
||||
params["Filters"] = "IsNotFolder"
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=movies&sort=none"
|
||||
add_menu_directory_item('{}{} ({})'.format(view_name, translate_string(30268), item_limit), url)
|
||||
|
||||
@@ -976,13 +1040,13 @@ def display_movies_type(menu_params, view):
|
||||
params["ImageTypeLimit"] = 1
|
||||
params["IncludeItemTypes"] = "Boxset"
|
||||
params["Recursive"] = True
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=boxsets"
|
||||
add_menu_directory_item('{}{}'.format(view_name, translate_string(30410)), url)
|
||||
|
||||
# Favorite Collections
|
||||
params["Filters"] = "IsFavorite"
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=boxsets"
|
||||
add_menu_directory_item('{}{}'.format(view_name, translate_string(30415)), url)
|
||||
|
||||
@@ -1025,6 +1089,111 @@ def display_movies_type(menu_params, view):
|
||||
xbmcplugin.endOfDirectory(handle)
|
||||
|
||||
|
||||
def display_mixed_type(params, view):
|
||||
handle = int(sys.argv[1])
|
||||
|
||||
view_name = translate_string(30261)
|
||||
if view is not None:
|
||||
view_name = view.get("Name")
|
||||
|
||||
item_limit = settings.getSetting("show_x_filtered_items")
|
||||
|
||||
# All Mixed content
|
||||
base_params = {
|
||||
"Fields": get_default_filters(),
|
||||
"ImageTypeLimit": 1,
|
||||
"IsMissing": False,
|
||||
"IncludeItemTypes": "Series,Movie",
|
||||
"Recursive": True
|
||||
}
|
||||
if view is not None:
|
||||
base_params["ParentId"] = view.get("Id")
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", base_params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=mixed"
|
||||
add_menu_directory_item(view_name + translate_string(30405), url)
|
||||
|
||||
# Favorite Mixed
|
||||
params = {}
|
||||
params.update(base_params)
|
||||
params["Filters"] = "IsFavorite"
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=mixed"
|
||||
add_menu_directory_item(view_name + translate_string(30414), url)
|
||||
|
||||
# Unplayed Mixed
|
||||
params = {}
|
||||
params.update(base_params)
|
||||
params["IsPlayed"] = False
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=mixed"
|
||||
add_menu_directory_item(view_name + translate_string(30285), url)
|
||||
|
||||
# In progress mixed
|
||||
params = {}
|
||||
params.update(base_params)
|
||||
params["Limit"] = item_limit
|
||||
params["SortBy"] = "DatePlayed"
|
||||
params["SortOrder"] = "Descending"
|
||||
params["Filters"] = "IsResumable"
|
||||
params["IncludeItemTypes"] = "Episode"
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=mixed&sort=none"
|
||||
url += "&name_format=" + quote('Episode|episode_name_format')
|
||||
add_menu_directory_item(view_name + translate_string(30267) + " (" + item_limit + ")", url)
|
||||
|
||||
# Latest mixed
|
||||
params = {}
|
||||
params.update(base_params)
|
||||
params["Limit"] = item_limit
|
||||
params["SortBy"] = "DateCreated"
|
||||
params["SortOrder"] = "Descending"
|
||||
params["IncludeItemTypes"] = "Episode"
|
||||
path = get_jellyfin_url("/Users/{userid}/Items/Latest", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=mixed&sort=none"
|
||||
add_menu_directory_item(view_name + translate_string(30288) + " (" + item_limit + ")", url)
|
||||
|
||||
# Recently Added
|
||||
params = {}
|
||||
params.update(base_params)
|
||||
params["Limit"] = item_limit
|
||||
params["SortBy"] = "DateCreated"
|
||||
params["SortOrder"] = "Descending"
|
||||
params["Filters"] = "IsNotFolder"
|
||||
params["IncludeItemTypes"] = "Episode"
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=mixed&sort=none"
|
||||
url += "&name_format=" + quote('Episode|episode_name_format')
|
||||
add_menu_directory_item(view_name + translate_string(30268) + " (" + item_limit + ")", url)
|
||||
|
||||
# Next Up Episodes
|
||||
params = {}
|
||||
params.update(base_params)
|
||||
params["Limit"] = item_limit
|
||||
params["Userid"] = '{userid}'
|
||||
params["SortBy"] = "DateCreated"
|
||||
params["SortOrder"] = "Descending"
|
||||
params["Filters"] = "IsNotFolder"
|
||||
params["IncludeItemTypes"] = "Episode"
|
||||
path = get_jellyfin_url("/Shows/NextUp", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=Episodes&sort=none"
|
||||
url += "&name_format=" + quote('Episode|episode_name_format')
|
||||
add_menu_directory_item(view_name + translate_string(30278) + " (" + item_limit + ")", url)
|
||||
|
||||
# Mixed Genres
|
||||
path = "plugin://plugin.video.jellycon/?mode=GENRES&item_type=mixed"
|
||||
if view is not None:
|
||||
path += "&parent_id=" + view.get("Id")
|
||||
add_menu_directory_item(view_name + translate_string(30325), path)
|
||||
|
||||
# Mixed Alpha picker
|
||||
path = "plugin://plugin.video.jellycon/?mode=TVSHOW_ALPHA"
|
||||
if view is not None:
|
||||
path += "&parent_id=" + view.get("Id")
|
||||
add_menu_directory_item(view_name + translate_string(30404), path)
|
||||
|
||||
xbmcplugin.endOfDirectory(handle)
|
||||
|
||||
|
||||
def display_library_views(params):
|
||||
handle = int(sys.argv[1])
|
||||
xbmcplugin.setContent(handle, 'files')
|
||||
@@ -1040,10 +1209,10 @@ def display_library_views(params):
|
||||
return []
|
||||
views = views.get("Items", [])
|
||||
|
||||
view_types = ["movies", "tvshows", "homevideos", "boxsets", "playlists", "music", "musicvideos", "livetv", "Channel"]
|
||||
view_types = ["movies", "tvshows", "homevideos", "boxsets", "playlists", "music", "musicvideos", "livetv", "Channel", "mixed"]
|
||||
|
||||
for view in views:
|
||||
collection_type = view.get('CollectionType', None)
|
||||
collection_type = view.get('CollectionType', 'mixed')
|
||||
item_type = view.get('Type', None)
|
||||
if collection_type in view_types or item_type == "Channel":
|
||||
view_name = view.get("Name")
|
||||
@@ -1072,7 +1241,7 @@ def get_playlist_path(view_info):
|
||||
}
|
||||
user_id = get_current_user_id()
|
||||
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=playlists"
|
||||
return url
|
||||
|
||||
@@ -1090,7 +1259,7 @@ def get_collection_path(view_info):
|
||||
}
|
||||
user_id = get_current_user_id()
|
||||
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=boxsets"
|
||||
return url
|
||||
|
||||
@@ -1104,7 +1273,7 @@ def get_channel_path(view):
|
||||
}
|
||||
user_id = get_current_user_id()
|
||||
|
||||
path = get_jellyfin_url("/Users/{}/Items".format(user_id), params)
|
||||
path = get_jellyfin_url("/Users/{userid}/Items", params)
|
||||
url = sys.argv[0] + "?url=" + quote(path) + "&mode=GET_CONTENT&media_type=files"
|
||||
return url
|
||||
|
||||
@@ -1118,7 +1287,7 @@ def display_library_view(params):
|
||||
|
||||
log.debug("VIEW_INFO : {0}".format(view_info))
|
||||
|
||||
collection_type = view_info.get("CollectionType", None)
|
||||
collection_type = view_info.get("CollectionType", "mixed")
|
||||
|
||||
if collection_type == "movies":
|
||||
display_movies_type(params, view_info)
|
||||
@@ -1132,6 +1301,8 @@ def display_library_view(params):
|
||||
display_musicvideos_type(params, view_info)
|
||||
elif collection_type == "livetv":
|
||||
display_livetv_type(params, view_info)
|
||||
elif collection_type == "mixed":
|
||||
display_mixed_type(params, view_info)
|
||||
|
||||
|
||||
def show_widgets():
|
||||
@@ -1199,8 +1370,8 @@ def set_library_window_values(force=False):
|
||||
index = 0
|
||||
for item in result:
|
||||
|
||||
collection_type = item.get("CollectionType")
|
||||
if collection_type in ["movies", "boxsets", "music", "tvshows"]:
|
||||
collection_type = item.get("CollectionType", "mixed")
|
||||
if collection_type in ["movies", "boxsets", "music", "tvshows", "mixed"]:
|
||||
name = item.get("Name")
|
||||
item_id = item.get("Id")
|
||||
|
||||
|
||||
@@ -5,17 +5,19 @@ import xbmc
|
||||
import xbmcgui
|
||||
import xbmcaddon
|
||||
import xbmcvfs
|
||||
import xbmcplugin
|
||||
|
||||
from datetime import timedelta
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
from six.moves.urllib.parse import urlencode
|
||||
import sys
|
||||
|
||||
from .jellyfin import api
|
||||
from .lazylogger import LazyLogger
|
||||
from .dialogs import ResumeDialog
|
||||
from .utils import send_event_notification, convert_size, get_device_id, translate_string, load_user_details, translate_path
|
||||
from .utils import send_event_notification, convert_size, get_device_id, translate_string, load_user_details, translate_path, get_jellyfin_url, download_external_sub
|
||||
from .kodi_utils import HomeWindow
|
||||
from .datamanager import clear_old_cache_data
|
||||
from .item_functions import extract_item_info, add_gui_item, get_art
|
||||
@@ -254,13 +256,18 @@ def play_file(play_info):
|
||||
return
|
||||
|
||||
# if this is a season, playlist or album then play all items in that parent
|
||||
if result.get("Type") in ["Season", "MusicAlbum", "Playlist"]:
|
||||
if result.get("Type") in ["Season", "MusicArtist", "MusicAlbum", "Playlist"]:
|
||||
log.debug("PlayAllFiles for parent item id: {0}".format(item_id))
|
||||
url = ('/Users/{}/items'.format(api.user_id) +
|
||||
'?ParentId=%s' +
|
||||
'&Fields=MediaSources' +
|
||||
'&format=json')
|
||||
url = url % (item_id,)
|
||||
url_root = '/Users/{}/Items'.format(api.user_id)
|
||||
# Look specifically for episodes or audio files
|
||||
url_params = {
|
||||
'ParentId': item_id,
|
||||
'Fields': 'MediaSources',
|
||||
'IncludeItemTypes': 'Episode,Audio',
|
||||
'Recursive': True
|
||||
}
|
||||
|
||||
url = get_jellyfin_url(url_root, url_params)
|
||||
result = api.get(url)
|
||||
log.debug("PlayAllFiles items: {0}".format(result))
|
||||
|
||||
@@ -409,7 +416,7 @@ def play_file(play_info):
|
||||
display_options["addSubtitleAvailable"] = False
|
||||
display_options["addUserRatings"] = False
|
||||
|
||||
gui_item = add_gui_item("", item_details, display_options, False)
|
||||
gui_item = add_gui_item(item_id, item_details, display_options, False)
|
||||
list_item = gui_item[1]
|
||||
|
||||
if playback_type == "2": # if transcoding then prompt for audio and subtitle
|
||||
@@ -449,12 +456,20 @@ def play_file(play_info):
|
||||
if len(intro_items) > 0:
|
||||
playlist = play_all_files(intro_items, play_items=False)
|
||||
playlist.add(playurl, list_item)
|
||||
player.play(playlist)
|
||||
else:
|
||||
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
|
||||
playlist.clear()
|
||||
playlist.add(playurl, list_item)
|
||||
|
||||
player.play(playlist)
|
||||
if len(sys.argv) > 1 and int(sys.argv[1]) > 0:
|
||||
# Play from info menu
|
||||
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, list_item)
|
||||
else:
|
||||
'''
|
||||
Play from remote control or addon menus. Doesn't have a handle,
|
||||
so need to call player directly
|
||||
'''
|
||||
playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
|
||||
playlist.clear()
|
||||
playlist.add(playurl, list_item)
|
||||
player.play(playlist)
|
||||
|
||||
if seek_time != 0:
|
||||
player.pause()
|
||||
@@ -723,13 +738,19 @@ def audio_subs_pref(url, list_item, media_source, item_id, audio_stream_index, s
|
||||
index = stream['Index']
|
||||
|
||||
if 'Audio' in stream['Type']:
|
||||
codec = stream['Codec']
|
||||
codec = stream.get('Codec', None)
|
||||
channel_layout = stream.get('ChannelLayout', "")
|
||||
|
||||
try:
|
||||
track = "%s - %s - %s %s" % (index, stream['Language'], codec, channel_layout)
|
||||
except:
|
||||
track = "%s - %s %s" % (index, codec, channel_layout)
|
||||
if not codec:
|
||||
# Probably tvheadend and has no other info
|
||||
track = "%s - default" % (index)
|
||||
else:
|
||||
try:
|
||||
# Track includes language
|
||||
track = "%s - %s - %s %s" % (index, stream['Language'], codec, channel_layout)
|
||||
except:
|
||||
# Track doesn't include language
|
||||
track = "%s - %s %s" % (index, codec, channel_layout)
|
||||
|
||||
audio_streams_list[track] = index
|
||||
audio_streams.append(track)
|
||||
@@ -803,10 +824,7 @@ def audio_subs_pref(url, list_item, media_source, item_id, audio_stream_index, s
|
||||
else: # User backed out of selection
|
||||
playurlprefs += "&SubtitleStreamIndex=%s" % default_sub
|
||||
|
||||
if url.find("|verifypeer=false") != -1:
|
||||
new_url = url.replace("|verifypeer=false", playurlprefs + "|verifypeer=false")
|
||||
else:
|
||||
new_url = url + playurlprefs
|
||||
new_url = url + playurlprefs
|
||||
|
||||
return new_url
|
||||
|
||||
@@ -836,26 +854,32 @@ def external_subs(media_source, list_item, item_id):
|
||||
source_id = media_source['Id']
|
||||
|
||||
language = stream.get('Language', '')
|
||||
if language and stream['IsDefault']:
|
||||
language = '{}.default'.format(language)
|
||||
if language and stream['IsForced']:
|
||||
language = '{}.forced'.format(language)
|
||||
is_sdh = stream.get('Title') and stream['Title'] in ('sdh', 'cc')
|
||||
if language and is_sdh:
|
||||
language = '{}.{}'.format(language, stream['Title'])
|
||||
codec = stream.get('Codec', '')
|
||||
|
||||
url_root = '{}/Videos/{}/{}/Subtitles/{}'.format(server, item_id, source_id, index)
|
||||
url = '{}{}'.format(server, stream.get('DeliveryUrl'))
|
||||
if language:
|
||||
url = '{}/0/Stream.{}.{}?api_key={}'.format(
|
||||
url_root, language, codec, token)
|
||||
'''
|
||||
Starting in 10.8, the server no longer provides language
|
||||
specific download points. We have to download the file
|
||||
and name it with the language code ourselves so Kodi
|
||||
will parse it correctly
|
||||
'''
|
||||
subtitle_file = download_external_sub(language, codec, url)
|
||||
else:
|
||||
url = '{}/0/Stream.{}?api_key={}'.format(url_root, codec, token)
|
||||
# If there is no language defined, we can go directly to the server
|
||||
subtitle_file = url
|
||||
|
||||
default = ""
|
||||
if stream['IsDefault']:
|
||||
default = "default"
|
||||
forced = ""
|
||||
if stream['IsForced']:
|
||||
forced = "forced"
|
||||
|
||||
sub_name = '{} ( {} ) {} {}'.format(language, codec, default, forced)
|
||||
sub_name = '{} ( {} )'.format(language, codec)
|
||||
|
||||
sub_names.append(sub_name)
|
||||
externalsubs.append(url)
|
||||
externalsubs.append(subtitle_file)
|
||||
|
||||
if len(externalsubs) == 0:
|
||||
return
|
||||
@@ -1116,13 +1140,11 @@ def get_play_url(media_source, play_session_id, channel_id=None):
|
||||
# get all the options
|
||||
server = settings.getSetting('server_address')
|
||||
use_https = settings.getSetting('protocol') == "1"
|
||||
verify_cert = settings.getSetting('verify_cert') == 'true'
|
||||
allow_direct_file_play = settings.getSetting('allow_direct_file_play') == 'true'
|
||||
|
||||
can_direct_play = media_source["SupportsDirectPlay"]
|
||||
can_direct_stream = media_source["SupportsDirectStream"]
|
||||
can_transcode = media_source["SupportsTranscoding"]
|
||||
container = media_source["Container"]
|
||||
|
||||
playurl = None
|
||||
playback_type = None
|
||||
@@ -1134,6 +1156,7 @@ def get_play_url(media_source, play_session_id, channel_id=None):
|
||||
direct_path = direct_path.strip()
|
||||
|
||||
# handle DVD structure
|
||||
container = media_source["Container"]
|
||||
if container == "dvd":
|
||||
direct_path = direct_path + "/VIDEO_TS/VIDEO_TS.IFO"
|
||||
elif container == "bluray":
|
||||
@@ -1151,17 +1174,9 @@ def get_play_url(media_source, play_session_id, channel_id=None):
|
||||
# check if file can be direct streamed/played
|
||||
if (can_direct_stream or can_direct_play) and playurl is None:
|
||||
item_id = media_source.get('Id')
|
||||
# We need to include the channel ID if this is a live stream
|
||||
if channel_id:
|
||||
url_root = '{}/Videos/{}/stream'.format(server, channel_id)
|
||||
play_params = {
|
||||
'static': True,
|
||||
'PlaySessionId': play_session_id,
|
||||
'MediaSourceId': item_id,
|
||||
'LiveStreamId': media_source.get('LiveStreamId')
|
||||
}
|
||||
play_param_string = urlencode(play_params)
|
||||
playurl = '{}?{}'.format(url_root, play_param_string)
|
||||
# live tv has to be transcoded by the server
|
||||
playurl = None
|
||||
else:
|
||||
url_root = '{}/Videos/{}/stream'.format(server, item_id)
|
||||
play_params = {
|
||||
@@ -1171,8 +1186,6 @@ def get_play_url(media_source, play_session_id, channel_id=None):
|
||||
}
|
||||
play_param_string = urlencode(play_params)
|
||||
playurl = '{}?{}'.format(url_root, play_param_string)
|
||||
if use_https and not verify_cert:
|
||||
playurl += "|verifypeer=false"
|
||||
playback_type = "1"
|
||||
|
||||
# check is file can be transcoded
|
||||
@@ -1209,7 +1222,8 @@ def get_play_url(media_source, play_session_id, channel_id=None):
|
||||
|
||||
# We need to include the channel ID if this is a live stream
|
||||
if channel_id:
|
||||
transcode_params['LiveStreamId'] = media_source.get('LiveStreamId')
|
||||
if media_source.get('LiveStreamId'):
|
||||
transcode_params['LiveStreamId'] = media_source.get('LiveStreamId')
|
||||
transcode_path = urlencode(transcode_params)
|
||||
playurl = '{}/Videos/{}/master.m3u8?{}'.format(
|
||||
server, channel_id, transcode_path)
|
||||
@@ -1218,9 +1232,6 @@ def get_play_url(media_source, play_session_id, channel_id=None):
|
||||
playurl = '{}/Videos/{}/master.m3u8?{}'.format(
|
||||
server, item_id, transcode_path)
|
||||
|
||||
if use_https and not verify_cert:
|
||||
playurl += "|verifypeer=false"
|
||||
|
||||
playback_type = "2"
|
||||
|
||||
return playurl, playback_type, []
|
||||
|
||||
@@ -13,8 +13,7 @@ import xbmc
|
||||
from .kodi_utils import HomeWindow
|
||||
from .jellyfin import API
|
||||
from .lazylogger import LazyLogger
|
||||
from .utils import datetime_from_string, translate_string, save_user_details, load_user_details
|
||||
from .dialogs import QuickConnectDialog
|
||||
from .utils import datetime_from_string, translate_string, save_user_details, load_user_details, get_current_datetime, get_saved_users
|
||||
|
||||
log = LazyLogger(__name__)
|
||||
|
||||
@@ -203,6 +202,8 @@ def check_server(force=False, change_user=False, notify=False):
|
||||
# do we need to change the user
|
||||
current_username = settings.getSetting('username')
|
||||
user_details = load_user_details()
|
||||
home_window = HomeWindow()
|
||||
home_window.set_property('user_name', current_username)
|
||||
|
||||
# if asked or we have no current user then show user selection screen
|
||||
if something_changed or change_user or len(current_username) == 0 or not user_details:
|
||||
@@ -210,60 +211,93 @@ def check_server(force=False, change_user=False, notify=False):
|
||||
# stop playback when switching users
|
||||
xbmc.Player().stop()
|
||||
|
||||
auth = quick_connect(api)
|
||||
# Initialize auth variable
|
||||
auth = {}
|
||||
|
||||
if auth:
|
||||
users = []
|
||||
user_selection = -1
|
||||
selected_user_name = auth.get('User', {}).get('Name')
|
||||
something_changed = True
|
||||
else:
|
||||
users, user_selection = user_select(api, current_username)
|
||||
|
||||
if not auth and user_selection > -1:
|
||||
# Check if quick connect is active on the server, initiate connection
|
||||
quick = api.get('/QuickConnect/Initiate')
|
||||
code = quick.get('Code')
|
||||
secret = quick.get('Secret')
|
||||
users, user_selection = user_select(api, current_username, code)
|
||||
|
||||
if user_selection > -1:
|
||||
# The user made a selection in the dialog
|
||||
something_changed = True
|
||||
selected_user = users[user_selection]
|
||||
selected_user_name = selected_user.getLabel()
|
||||
secured = selected_user.getProperty("secure") == "true"
|
||||
manual = selected_user.getProperty("manual") == "true"
|
||||
quick_connect = selected_user.getProperty("quickconnect") == "true"
|
||||
count = 0
|
||||
if quick_connect:
|
||||
# Try to authenticate to server with secret code 10 times
|
||||
while count < 10:
|
||||
log.debug('Checking for quick connect auth: attempt {}'.format(count))
|
||||
check = api.get('/QuickConnect/Connect?secret={}'.format(secret))
|
||||
if check.get('Authenticated'):
|
||||
break
|
||||
count += 1
|
||||
xbmc.sleep(1000)
|
||||
|
||||
home_window = HomeWindow()
|
||||
auth = api.post('/Users/AuthenticateWithQuickConnect',
|
||||
{'secret': secret})
|
||||
|
||||
# If using a manual login, ask for username
|
||||
if manual:
|
||||
kb = xbmc.Keyboard()
|
||||
kb.setHeading(translate_string(30005))
|
||||
if current_username:
|
||||
kb.setDefault(current_username)
|
||||
kb.doModal()
|
||||
if kb.isConfirmed():
|
||||
selected_user_name = kb.getText()
|
||||
log.debug("Manual entered username: {0}".format(selected_user_name))
|
||||
# If authentication was successful, save the username
|
||||
if auth:
|
||||
selected_user_name = auth['User'].get('Name')
|
||||
else:
|
||||
return
|
||||
# Login failed, we don't want to change anything
|
||||
something_changed = False
|
||||
log.info("There was an error logging in with quick connect")
|
||||
|
||||
home_window.set_property('user_name', selected_user_name)
|
||||
user_details = load_user_details()
|
||||
else:
|
||||
selected_user_name = selected_user.getLabel()
|
||||
secured = selected_user.getProperty("secure") == "true"
|
||||
manual = selected_user.getProperty("manual") == "true"
|
||||
|
||||
# Ask for password if user has one
|
||||
password = ''
|
||||
if secured and not user_details.get('token'):
|
||||
kb = xbmc.Keyboard()
|
||||
kb.setHeading(translate_string(30006))
|
||||
kb.setHiddenInput(True)
|
||||
kb.doModal()
|
||||
if kb.isConfirmed():
|
||||
password = kb.getText()
|
||||
# If using a manual login, ask for username
|
||||
if manual:
|
||||
kb = xbmc.Keyboard()
|
||||
kb.setHeading(translate_string(30005))
|
||||
if current_username:
|
||||
kb.setDefault(current_username)
|
||||
kb.doModal()
|
||||
if kb.isConfirmed():
|
||||
selected_user_name = kb.getText()
|
||||
log.debug("Manual entered username: {0}".format(selected_user_name))
|
||||
else:
|
||||
return
|
||||
|
||||
home_window.set_property('user_name', selected_user_name)
|
||||
settings.setSetting('username', selected_user_name)
|
||||
user_details = load_user_details()
|
||||
|
||||
if not user_details:
|
||||
# Ask for password if user has one
|
||||
password = ''
|
||||
if secured and not user_details.get('token'):
|
||||
kb = xbmc.Keyboard()
|
||||
kb.setHeading(translate_string(30006))
|
||||
kb.setHiddenInput(True)
|
||||
kb.doModal()
|
||||
if kb.isConfirmed():
|
||||
password = kb.getText()
|
||||
|
||||
auth_payload = {'username': selected_user_name, 'pw': password}
|
||||
auth = api.authenticate(auth_payload)
|
||||
if not auth:
|
||||
# Login failed, we don't want to change anything
|
||||
something_changed = False
|
||||
log.info('There was an error logging in with user {}'.format(selected_user_name))
|
||||
xbmcgui.Dialog().ok(__addon_name__, translate_string(30446))
|
||||
|
||||
auth_payload = {'username': selected_user_name, 'pw': password}
|
||||
auth = api.authenticate(auth_payload)
|
||||
|
||||
if something_changed:
|
||||
home_window = HomeWindow()
|
||||
home_window.clear_property("jellycon_widget_reload")
|
||||
token = auth.get('AccessToken')
|
||||
user_id = auth.get('User').get('Id')
|
||||
if auth:
|
||||
token = auth.get('AccessToken')
|
||||
user_id = auth.get('User').get('Id')
|
||||
else:
|
||||
token = user_details.get('token')
|
||||
user_id = user_details.get('user_id')
|
||||
save_user_details(selected_user_name, user_id, token)
|
||||
xbmc.executebuiltin("ActivateWindow(Home)")
|
||||
if "estuary_jellycon" in xbmc.getSkinDir():
|
||||
@@ -271,65 +305,38 @@ def check_server(force=False, change_user=False, notify=False):
|
||||
xbmc.executebuiltin("ReloadSkin()")
|
||||
|
||||
|
||||
def quick_connect(api):
|
||||
'''
|
||||
Log in using quick connect funcion
|
||||
'''
|
||||
settings = xbmcaddon.Addon()
|
||||
addon_path = settings.getAddonInfo('path')
|
||||
|
||||
result = api.get('/QuickConnect/Initiate')
|
||||
|
||||
if not isinstance(result, dict) or not result:
|
||||
log.debug('Quick connect is disabled on the server')
|
||||
return {}
|
||||
|
||||
code = result.get('Code')
|
||||
secret = result.get('Secret')
|
||||
|
||||
# Open Quick Connect dialog, ask to proceed
|
||||
qc_dialog = QuickConnectDialog("QuickConnectDialog.xml", addon_path, "default", "720p")
|
||||
qc_dialog.code = code
|
||||
qc_dialog.doModal()
|
||||
connect_method = qc_dialog.getConnectMethod()
|
||||
del qc_dialog
|
||||
|
||||
if connect_method < 1:
|
||||
# User backed out or selected manual login
|
||||
return {}
|
||||
|
||||
count = 0
|
||||
while count < 15:
|
||||
# Check the server to see if the auth request has been completed
|
||||
log.debug('Checking for quick connect auth: attempt {}'.format(count))
|
||||
check = api.get('/QuickConnect/Connect?secret={}'.format(secret))
|
||||
if check.get('Authenticated'):
|
||||
break
|
||||
count += 1
|
||||
xbmc.sleep(1000)
|
||||
|
||||
if not check.get('Authenticated'):
|
||||
log.info('Quick connect not authorized in 15 seconds, defaulting to manual authentication')
|
||||
return {}
|
||||
|
||||
# Retrieve authentication information
|
||||
auth = api.post('/Users/AuthenticateWithQuickConnect',
|
||||
{'secret': secret})
|
||||
|
||||
return auth
|
||||
|
||||
|
||||
def user_select(api, current_username):
|
||||
def user_select(api, current_username, code):
|
||||
'''
|
||||
Display user selection screen
|
||||
'''
|
||||
# Retrieve list of public users from server
|
||||
result = api.get('/Users/Public')
|
||||
public = api.get('/Users/Public')
|
||||
|
||||
# Get list of saved users
|
||||
saved_users = get_saved_users()
|
||||
|
||||
# Combine public and saved users
|
||||
for user in saved_users:
|
||||
name = user.get('Name')
|
||||
# Check if saved user is in public list
|
||||
if name not in [x.get('Name', '') for x in public]:
|
||||
# If saved user is not already in list, add it
|
||||
public.append(user)
|
||||
|
||||
# Build user display
|
||||
selected_id = -1
|
||||
users = []
|
||||
for user in result:
|
||||
# If quick connect is active, make it the first entry
|
||||
if code:
|
||||
user_item = xbmcgui.ListItem(code)
|
||||
user_image = "DefaultUser.png"
|
||||
art = {"Thumb": user_image}
|
||||
user_item.setArt(art)
|
||||
user_item.setLabel2(translate_string(30443))
|
||||
user_item.setProperty('quickconnect', "true")
|
||||
users.append(user_item)
|
||||
|
||||
for user in public:
|
||||
user_item = create_user_listitem(api.server, user)
|
||||
if user_item:
|
||||
users.append(user_item)
|
||||
@@ -357,7 +364,7 @@ def user_select(api, current_username):
|
||||
selection_title,
|
||||
users,
|
||||
preselect=selected_id,
|
||||
autoclose=20000,
|
||||
autoclose=60000,
|
||||
useDetails=True)
|
||||
|
||||
return (users, user_selection)
|
||||
@@ -368,6 +375,7 @@ def create_user_listitem(server, user):
|
||||
Create a user listitem for the user selection screen
|
||||
'''
|
||||
config = user.get("Configuration")
|
||||
now = get_current_datetime()
|
||||
if config is not None:
|
||||
name = user.get("Name")
|
||||
time_ago = ""
|
||||
@@ -375,7 +383,7 @@ def create_user_listitem(server, user):
|
||||
# Calculate how long it's been since the user was last active
|
||||
if last_active:
|
||||
last_active_date = datetime_from_string(last_active)
|
||||
ago = datetime.now().astimezone() - last_active_date
|
||||
ago = now - last_active_date
|
||||
# Check days
|
||||
if ago.days > 0:
|
||||
time_ago += ' {}d'.format(ago.days)
|
||||
|
||||
@@ -15,6 +15,7 @@ import time
|
||||
import math
|
||||
import os
|
||||
import hashlib
|
||||
import requests
|
||||
from datetime import datetime
|
||||
from dateutil import tz
|
||||
import re
|
||||
@@ -104,14 +105,20 @@ def datetime_from_string(time_string):
|
||||
# https://bugs.python.org/issue27400
|
||||
dt = datetime(*(time.strptime(time_string, "%Y-%m-%dT%H:%M:%S.%f %Z")[0:6]))
|
||||
|
||||
# Convert server dates from UTC to local time
|
||||
# Dates received from the server are in UTC, but parsing them results in naive objects
|
||||
utc = tz.tzutc()
|
||||
local = tz.tzlocal()
|
||||
|
||||
utc_dt = dt.replace(tzinfo=utc)
|
||||
local_dt = utc_dt.astimezone(local)
|
||||
|
||||
return local_dt
|
||||
return utc_dt
|
||||
|
||||
|
||||
def get_current_datetime():
|
||||
# Get current time in UTC
|
||||
now = datetime.utcnow()
|
||||
utc = tz.tzutc()
|
||||
now_dt = now.replace(tzinfo=utc)
|
||||
|
||||
return now_dt
|
||||
|
||||
|
||||
def convert_size(size_bytes):
|
||||
@@ -136,12 +143,16 @@ def translate_string(string_id):
|
||||
def get_device_id():
|
||||
|
||||
window = HomeWindow()
|
||||
username = window.get_property('username')
|
||||
username = window.get_property('user_name')
|
||||
client_id = window.get_property("client_id")
|
||||
hashed_name = hashlib.md5(username.encode()).hexdigest()
|
||||
|
||||
if client_id:
|
||||
if client_id and username:
|
||||
return '{}-{}'.format(client_id, hashed_name)
|
||||
elif client_id and not username:
|
||||
# Quick Connect, needs to be unique so sessions don't overwrite
|
||||
rand_id = uuid4().hex
|
||||
return '{}-{}'.format(client_id, rand_id)
|
||||
|
||||
jellyfin_guid_path = py2_decode(translate_path("special://temp/jellycon_guid"))
|
||||
log.debug("jellyfin_guid_path: {0}".format(jellyfin_guid_path))
|
||||
@@ -219,6 +230,10 @@ def load_user_details():
|
||||
return {}
|
||||
|
||||
user_data = auth_data.get(user_name, {})
|
||||
# User doesn't exist yet
|
||||
if not user_data:
|
||||
return {}
|
||||
|
||||
user_id = user_data.get('user_id')
|
||||
auth_token = user_data.get('token')
|
||||
|
||||
@@ -233,6 +248,36 @@ def load_user_details():
|
||||
return {}
|
||||
|
||||
|
||||
def get_saved_users():
|
||||
settings = xbmcaddon.Addon()
|
||||
save_user_to_settings = settings.getSetting('save_user_to_settings') == 'true'
|
||||
addon_data = translate_path(xbmcaddon.Addon().getAddonInfo('profile'))
|
||||
if not save_user_to_settings:
|
||||
return []
|
||||
|
||||
try:
|
||||
with open(os.path.join(addon_data, 'auth.json'), 'rb') as infile:
|
||||
auth_data = json.load(infile)
|
||||
except:
|
||||
# File doesn't exist yet
|
||||
return []
|
||||
|
||||
users = []
|
||||
for user,values in auth_data.items():
|
||||
users.append(
|
||||
{
|
||||
'Name': user,
|
||||
'Id': values.get('user_id'),
|
||||
# We need something here for the listitem function
|
||||
'Configuration': {'Dummy': True}
|
||||
}
|
||||
)
|
||||
|
||||
return users
|
||||
|
||||
|
||||
|
||||
|
||||
def get_current_user_id():
|
||||
user_details = load_user_details()
|
||||
user_id = user_details.get('user_id')
|
||||
@@ -357,3 +402,20 @@ def translate_path(path):
|
||||
return xbmcvfs.translatePath(path)
|
||||
else:
|
||||
return xbmc.translatePath(path)
|
||||
|
||||
|
||||
def download_external_sub(language, codec, url):
|
||||
addon_settings = xbmcaddon.Addon()
|
||||
verify_cert = addon_settings.getSetting('verify_cert') == 'true'
|
||||
|
||||
# Download the subtitle file
|
||||
r = requests.get(url, verify=verify_cert)
|
||||
r.raise_for_status()
|
||||
|
||||
# Write the subtitle file to the local filesystem
|
||||
file_name = 'Stream.{}.{}'.format(language, codec)
|
||||
file_path = py2_decode(translate_path('special://temp/{}'.format(file_name)))
|
||||
with open(file_path, 'wb') as f:
|
||||
f.write(r.content)
|
||||
|
||||
return file_path
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<window id="3301" type="dialog">
|
||||
<defaultcontrol always="true">3010</defaultcontrol>
|
||||
<zorder>2</zorder>
|
||||
<coordinates>
|
||||
<system>1</system>
|
||||
<left>450</left>
|
||||
<top>200</top>
|
||||
</coordinates>
|
||||
<controls>
|
||||
|
||||
<control type="image">
|
||||
<left>0</left>
|
||||
<top>0</top>
|
||||
<width>400</width>
|
||||
<height>270</height>
|
||||
<texture border="40">bg.png</texture>
|
||||
</control>
|
||||
|
||||
<control type="label" id="4">
|
||||
<left>20</left>
|
||||
<top>5</top>
|
||||
<width>360</width>
|
||||
<height>50</height>
|
||||
<label>Heading</label>
|
||||
<font>font45_title</font>
|
||||
<align>center</align>
|
||||
</control>
|
||||
|
||||
<control type="textbox" id="3">
|
||||
<left>20</left>
|
||||
<top>65</top>
|
||||
<width>360</width>
|
||||
<height>50</height>
|
||||
<font>font45</font>
|
||||
<align>center</align>
|
||||
</control>
|
||||
|
||||
<control type="button" id="3010">
|
||||
<texturenofocus border="1" colordiffuse="ff161616">white.png</texturenofocus>
|
||||
<texturefocus border="1" colordiffuse="ff525252">white.png</texturefocus>
|
||||
<left>20</left>
|
||||
<top>135</top>
|
||||
<width>360</width>
|
||||
<height>40</height>
|
||||
<label></label>
|
||||
<onup></onup>
|
||||
<ondown>3011</ondown>
|
||||
<font>font14</font>
|
||||
<align>center</align>
|
||||
</control>
|
||||
|
||||
<control type="button" id="3011">
|
||||
<texturenofocus border="1" colordiffuse="ff161616">white.png</texturenofocus>
|
||||
<texturefocus border="1" colordiffuse="ff525252">white.png</texturefocus>
|
||||
<left>20</left>
|
||||
<top>195</top>
|
||||
<width>360</width>
|
||||
<height>40</height>
|
||||
<label></label>
|
||||
<onup>3010</onup>
|
||||
<ondown>3012</ondown>
|
||||
<font>font14</font>
|
||||
<align>center</align>
|
||||
</control>
|
||||
|
||||
</controls>
|
||||
</window>
|
||||
10
service.py
10
service.py
@@ -29,7 +29,7 @@ if log_timing_data:
|
||||
|
||||
# clear user and token when logging in
|
||||
home_window = HomeWindow()
|
||||
home_window.clear_property("userid")
|
||||
home_window.clear_property("user_name")
|
||||
home_window.clear_property("AccessToken")
|
||||
home_window.clear_property("Params")
|
||||
|
||||
@@ -99,7 +99,7 @@ if enable_logging:
|
||||
time=8000,
|
||||
icon=xbmcgui.NOTIFICATION_WARNING)
|
||||
|
||||
prev_user_id = home_window.get_property("userid")
|
||||
prev_user = home_window.get_property("user_name")
|
||||
first_run = True
|
||||
home_window.set_property('exit', 'False')
|
||||
|
||||
@@ -118,9 +118,9 @@ while home_window.get_property('exit') == 'False':
|
||||
|
||||
if not screen_saver_active:
|
||||
user_changed = False
|
||||
if prev_user_id != home_window.get_property("userid"):
|
||||
if prev_user != home_window.get_property("user_name"):
|
||||
log.debug("user_change_detected")
|
||||
prev_user_id = home_window.get_property("userid")
|
||||
prev_user = home_window.get_property("user_name")
|
||||
user_changed = True
|
||||
|
||||
if user_changed or first_run:
|
||||
@@ -186,7 +186,7 @@ if context_monitor:
|
||||
context_monitor.stop_monitor()
|
||||
|
||||
# clear user and token when loggin off
|
||||
home_window.clear_property("userid")
|
||||
home_window.clear_property("user_name")
|
||||
home_window.clear_property("AccessToken")
|
||||
home_window.clear_property("userimage")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user