55 Commits

Author SHA1 Message Date
mcarlton00
caa014a0ac Merge pull request #232 from jellyfin/prepare-0.5.8
Some checks failed
Build JellyCon / build (py2) (push) Has been cancelled
Build JellyCon / build (py3) (push) Has been cancelled
Prepare for release v0.5.8
2022-10-11 15:01:08 -04:00
Matt
8199642f35 0.6.0 2022-10-11 14:59:12 -04:00
jellyfin-bot
da6525120d bump version to 0.5.8 2022-10-11 18:57:57 +00:00
mcarlton00
362760d3ab Merge pull request #231 from mcarlton00/musicvideo-resume
Add play option to music video context menu
2022-10-11 14:47:13 -04:00
Hans Christian Madsen
1cce67702d Translated using Weblate (Swedish)
Currently translated at 88.2% (241 of 273 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/sv/
2022-10-10 11:54:40 -04:00
mcarlton00
ff761dd088 Merge branch 'master' into musicvideo-resume 2022-10-08 16:46:00 -04:00
Matt
beda70b1f9 Add play option to music video context menu 2022-10-08 16:43:57 -04:00
Paulo
eb9eb2009f Translated using Weblate (French)
Currently translated at 87.1% (238 of 273 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/fr/
2022-10-05 13:54:38 -04:00
Oskari Lavinto
73bcfef007 Translated using Weblate (Finnish)
Currently translated at 100.0% (273 of 273 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/fi/
2022-10-04 01:54:39 -04:00
Benjamin
3104d5aec9 Translated using Weblate (Swedish)
Currently translated at 82.4% (225 of 273 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/sv/
2022-10-04 01:54:39 -04:00
Adammantium
0d3c39cc0a Translated using Weblate (German)
Currently translated at 100.0% (273 of 273 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/de/
2022-10-04 01:54:39 -04:00
Csaba
e57059cf3c Translated using Weblate (Hungarian)
Currently translated at 100.0% (273 of 273 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/hu/
2022-10-04 01:54:39 -04:00
mcarlton00
18e9a99d17 Merge pull request #228 from mcarlton00/remove-old-verify
Cleanup old https verify method
2022-10-03 10:15:52 -04:00
mcarlton00
7b7549fef0 Merge pull request #227 from mcarlton00/mixed-content
Add support for mixed content libraries
2022-10-03 09:11:46 -04:00
Matt
251f43fb77 Remove unused variable 2022-10-02 08:12:02 -04:00
Matt
6c4077b143 Cleanup old https verify method 2022-10-02 08:10:44 -04:00
Matt
00a7e92ef7 Remove unused variable 2022-10-02 08:07:40 -04:00
Matt
61c1a3db8e Add support for mixed content libraries 2022-10-01 22:15:44 -04:00
mcarlton00
bdcd65d6c9 Merge pull request #226 from mcarlton00/redesign-quickconnect
Move quickconnect code into user selection list
2022-10-01 21:06:38 -04:00
Matt
f7a427b809 Remove unneeded dialog template 2022-10-01 18:17:53 -04:00
Matt
e96e727c7c Move quickconnect code into user selection list 2022-10-01 17:40:26 -04:00
mcarlton00
f2ea26b529 Merge pull request #225 from mcarlton00/display-saved-users
Show saved users in the user selection list
2022-10-01 13:32:27 -04:00
Matt
7b10c48e8f Show saved users in the user selection list 2022-10-01 10:59:10 -04:00
Weevild
0c71e82675 Translated using Weblate (Swedish)
Currently translated at 75.3% (205 of 272 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/sv/
2022-10-01 09:54:38 -04:00
Thanos
7fa7c8f9f8 Translated using Weblate (Dutch)
Currently translated at 95.5% (260 of 272 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/nl/
2022-10-01 09:54:38 -04:00
Thanos
102eb934af Translated using Weblate (Turkish)
Currently translated at 23.5% (64 of 272 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/tr/
2022-10-01 09:54:38 -04:00
mcarlton00
099e0193e9 Merge pull request #223 from jellyfin/dependabot/github_actions/release-drafter/release-drafter-5.21.0
Bump release-drafter/release-drafter from 5.20.1 to 5.21.0
2022-09-29 21:38:44 -04:00
mcarlton00
c68b4bf392 Merge pull request #222 from mcarlton00/stale-menus
Fix stale menu links when user switching
2022-09-29 21:38:11 -04:00
mcarlton00
14b2a10fdf Merge pull request #221 from mcarlton00/unique-client-id
Force unique client IDs when using quick connect
2022-09-29 21:37:52 -04:00
mcarlton00
a9ba96e08b Merge pull request #220 from mcarlton00/auth-error-message
Add an error message when authentication fails
2022-09-29 21:37:36 -04:00
Ariel Martín Estévez
d4c3ebab24 Translated using Weblate (Spanish)
Currently translated at 100.0% (272 of 272 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/es/
2022-09-24 16:54:34 -04:00
Fabien LARTIGUE
4f5396f945 Translated using Weblate (French)
Currently translated at 87.5% (238 of 272 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/fr/
2022-09-22 05:54:34 -04:00
mcarlton00
59a5f72f7c Merge pull request #224 from aiosk/subtitle_not_working_on_self_sign_certificate_server
subtitle not working on self sign certificate
2022-09-21 10:07:41 -04:00
Oskari Lavinto
47fbf495f1 Translated using Weblate (Finnish)
Currently translated at 100.0% (272 of 272 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/fi/
2022-09-21 04:54:33 -04:00
Ad-Blokker
55529f49e3 Translated using Weblate (Dutch)
Currently translated at 61.3% (167 of 272 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/nl/
2022-09-21 04:54:33 -04:00
Csaba
dd0f410161 Translated using Weblate (Hungarian)
Currently translated at 100.0% (272 of 272 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/hu/
2022-09-21 04:54:33 -04:00
andry.yosua
6ee2f9c962 subtitle not working on self sign certificate
`requests.get` when download subtitle file do not respect "Verify HTTPS
certificate" setting.

STEPS TO REPRODUCE:
- i have installed self sign certificate on jellyfin server
- i have set "Verify HTTPS certificate" to false on addon setting

EXPECTED RESULTS:
i can play movies

ACTUAL RESULTS:
i can not play movies.

this happened because `requests.get` when download subtitle file do not
respect "Verify HTTPS certificate" setting.

this PR add "Verify HTTPS certificate" setting when downloading subtitle
file
2022-09-20 05:51:43 +07:00
dependabot[bot]
f24e20a902 Bump release-drafter/release-drafter from 5.20.1 to 5.21.0
Bumps [release-drafter/release-drafter](https://github.com/release-drafter/release-drafter) from 5.20.1 to 5.21.0.
- [Release notes](https://github.com/release-drafter/release-drafter/releases)
- [Commits](https://github.com/release-drafter/release-drafter/compare/v5.20.1...v5.21.0)

---
updated-dependencies:
- dependency-name: release-drafter/release-drafter
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-19 16:16:26 +00:00
lollolgag
1cf0155622 Translated using Weblate (German)
Currently translated at 100.0% (272 of 272 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/de/
2022-09-19 06:54:33 -04:00
Matt
aa208d2ae5 Fix stale menu links when user switching 2022-09-18 18:34:30 -04:00
Matt
1d8b9824ad Force unique client IDs when using quick connect 2022-09-18 09:36:00 -04:00
Matt
bd1917a8a7 Add an error message when authentication fails 2022-09-18 08:49:06 -04:00
mcarlton00
50a43e8e01 Merge pull request #217 from mcarlton00/playnext-dialog
Make it clear that the play next episode setting is in seconds
2022-09-18 08:32:46 -04:00
Matt
bee8be9698 Make it clear that the play next episode setting is in seconds 2022-09-17 12:42:09 -04:00
mcarlton00
774c9ba12d Merge pull request #208 from jellyfin/dependabot/github_actions/release-drafter/release-drafter-5.20.1
Bump release-drafter/release-drafter from 5.20.0 to 5.20.1
2022-09-17 11:48:48 -04:00
mcarlton00
8be5c1b9eb Merge pull request #213 from mcarlton00/tvheadend-fix
Fix playing livetv from tvheadend
2022-09-17 11:48:21 -04:00
wolong gl
9ada09e809 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (272 of 272 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/zh_Hans/
2022-09-14 21:11:37 -04:00
Matt
007a997f8f Fix playing livetv from tvheadend 2022-09-11 12:01:02 -04:00
mcarlton00
d70f9290f5 Merge pull request #211 from jellyfin/prepare-0.5.7
Some checks failed
Build JellyCon / build (py2) (push) Has been cancelled
Build JellyCon / build (py3) (push) Has been cancelled
Prepare for release v0.5.7
2022-08-26 14:28:52 -04:00
jellyfin-bot
d32be4aba7 bump version to 0.5.7 2022-08-26 18:28:17 +00:00
mcarlton00
359dd05972 Merge pull request #210 from mcarlton00/user-switching-watch-status
Apply watched status to the correct user
2022-08-26 14:14:21 -04:00
Matt
c005d331ee Apply watched status to the correct user 2022-08-26 13:38:15 -04:00
DJSweder
e51f136c4e Translated using Weblate (Czech)
Currently translated at 8.0% (22 of 272 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/cs/
2022-08-25 16:11:29 -04:00
dependabot[bot]
95ee6e4e24 Bump release-drafter/release-drafter from 5.20.0 to 5.20.1
Bumps [release-drafter/release-drafter](https://github.com/release-drafter/release-drafter) from 5.20.0 to 5.20.1.
- [Release notes](https://github.com/release-drafter/release-drafter/releases)
- [Commits](https://github.com/release-drafter/release-drafter/compare/v5.20.0...v5.20.1)

---
updated-dependencies:
- dependency-name: release-drafter/release-drafter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-22 16:14:52 +00:00
lyaschuchenko
677d3a4a76 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (272 of 272 strings)

Translation: Jellycon/Jellycon
Translate-URL: https://translate.jellyfin.org/projects/jellycon/jellycon/uk/
2022-08-20 22:11:27 -04:00
27 changed files with 1597 additions and 360 deletions

View File

@@ -10,7 +10,7 @@ jobs:
steps:
- name: Update Draft
uses: release-drafter/release-drafter@v5.20.0
uses: release-drafter/release-drafter@v5.21.0
id: draft
env:
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}

View File

@@ -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.0
if: ${{ matrix.py_version == 'py3' }}
with:
publish: true

View File

@@ -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.0
env:
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}

View File

@@ -1,18 +1,29 @@
version: '0.5.6'
version: '0.6.0'
changelog: |-
:tada: New features and improvements
------------------------------------
+ Add Continue Watching Widget (#199) @aiosk
+ Add support for mixed content libraries (#227) @mcarlton00
+ Move quickconnect code into user selection list (#226) @mcarlton00
+ Show saved users in the user selection list (#225) @mcarlton00
Bug Fixes
---------
+ Fix user switching (#204) @mcarlton00
+ Don't request empty folders from api if setting is disabled (#198) @mcarlton00
+ Don't error when switching to a cached user (#200) @mcarlton00
+ Add play option to music video context menu (#231) @mcarlton00
+ Fix stale menu links when user switching (#222) @mcarlton00
+ Force unique client IDs when using quick connect (#221) @mcarlton00
+ Add an error message when authentication fails (#220) @mcarlton00
+ subtitle not working on self sign certificate (#224) @aiosk
+ Make it clear that the play next episode setting is in seconds (#217) @mcarlton00
+ Fix playing livetv from tvheadend (#213) @mcarlton00
Code or Repo Maintenance
------------------------
+ Cleanup old https verify method (#228) @mcarlton00
CI & build changes
------------------
+ Bump appleboy/ssh-action from 0.1.4 to 0.1.5 (#202) @dependabot
+ Bump release-drafter/release-drafter from 5.20.1 to 5.21.0 (#223) @dependabot
+ Bump release-drafter/release-drafter from 5.20.0 to 5.20.1 (#208) @dependabot
dependencies:
py2:
- addon: 'xbmc.python'

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"
@@ -1103,4 +1103,8 @@ msgstr "Login using Quick Connect"
msgctxt "#30445"
msgid "Continue Watching"
msgstr "Continue Watching"
msgstr "Continue Watching"
msgctxt "#30446"
msgid "There was an error logging in"
msgstr "There was an error logging in"

View File

@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"PO-Revision-Date: 2022-08-15 12:40+0000\n"
"Last-Translator: Francisco Álamo García <fran.minecraft.mta@gmail.com>\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.13.1\n"
"X-Generator: Weblate 4.14.1\n"
msgctxt "#30442"
msgid "Simple new content check"
@@ -1105,3 +1105,7 @@ 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"

View File

@@ -1,6 +1,6 @@
msgid ""
msgstr ""
"PO-Revision-Date: 2022-08-09 05: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"
@@ -1103,3 +1103,13 @@ 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"

View File

@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"PO-Revision-Date: 2022-08-10 20:22+0000\n"
"Last-Translator: Thomas Schwery <thomas@inf3.ch>\n"
"PO-Revision-Date: 2022-10-05 17:54+0000\n"
"Last-Translator: Paulo <paulletilly@gmail.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"
@@ -984,3 +984,15 @@ msgstr "Voulez-vous effacer votre mot de passe sauvé ?"
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"

View File

@@ -1,6 +1,6 @@
msgid ""
msgstr ""
"PO-Revision-Date: 2022-08-09 05: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"
@@ -1103,3 +1103,11 @@ 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"

View File

@@ -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"

View File

@@ -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-10 15:54+0000\n"
"Last-Translator: Hans Christian Madsen <hcbille@gmail.com>\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"
@@ -855,48 +855,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,7 +901,6 @@ msgctxt "#30016"
msgid "Device display name"
msgstr "Enhetens visningsnamn"
#, fuzzy
msgctxt "#30015"
msgid "Log timing data"
msgstr "Logga tidsdata"
@@ -915,3 +909,147 @@ msgstr "Logga tidsdata"
msgctxt "#30010"
msgid "Number of performance profiles to capture"
msgstr "Antal prestandaprofiler som ska fångas"
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"
#, fuzzy
msgctxt "#30420"
msgid "Audio max channels"
msgstr "Max antal Ljudkanaler"
msgctxt "#30419"
msgid "Audio codec"
msgstr "Ljud codec"
msgctxt "#30418"
msgid "Audio bitrate (Kbits)"
msgstr "Ljud bitrate (Kbps)"
#, fuzzy
msgctxt "#30416"
msgid "HTTP timeout seconds"
msgstr "HTTP timeout sekunder"
msgctxt "#30415"
msgid " - Favorite Collections"
msgstr "- Favorit Samlingar"
msgctxt "#30414"
msgid " - Favorites"
msgstr "- Favoriter"
#, fuzzy
msgctxt "#30409"
msgid "Add-on Actions"
msgstr "Tilläg Alternativ"
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"

View File

@@ -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"

View File

@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"PO-Revision-Date: 2022-07-07 17:22+0000\n"
"Last-Translator: Fedir Smilianets <fedor.smile@gmail.com>\n"
"PO-Revision-Date: 2022-08-21 02:11+0000\n"
"Last-Translator: lyaschuchenko <lyaschuchenko@gmail.com>\n"
"Language-Team: Ukrainian <https://translate.jellyfin.org/projects/jellycon/"
"jellycon/uk/>\n"
"Language: uk\n"
@@ -10,7 +10,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 4.10.1\n"
"X-Generator: Weblate 4.13.1\n"
msgctxt "#30434"
msgid "Force transcode stream bitrate (Kbits)"
@@ -1100,3 +1100,7 @@ msgstr "Порт"
msgctxt "#30000"
msgid "Host"
msgstr "Хост"
msgctxt "#30445"
msgid "Continue Watching"
msgstr "Продовжити перегляд"

View File

@@ -1,6 +1,6 @@
msgid ""
msgstr ""
"PO-Revision-Date: 2022-06-20 16:22+0000\n"
"PO-Revision-Date: 2022-09-15 01:11+0000\n"
"Last-Translator: wolong gl <wolong98@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://translate.jellyfin.org/projects/"
"jellycon/jellycon/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.13.1\n"
msgctxt "#30442"
msgid "Simple new content check"
@@ -1094,3 +1094,7 @@ msgstr "Quick Connect"
msgctxt "#30323"
msgid "Artists"
msgstr "艺术家"
msgctxt "#30445"
msgid "Continue Watching"
msgstr "继续观看"

View File

@@ -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

View File

@@ -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,7 +332,7 @@ 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:
@@ -333,7 +341,7 @@ def process_directory(url, progress, params, use_cache_data=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' +
@@ -341,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' +
@@ -358,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' +
@@ -382,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) +

View File

@@ -343,7 +343,7 @@ 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)
@@ -353,12 +353,12 @@ def show_menu(params):
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", "MusicArtist", "MusicAlbum"]:
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)

View File

@@ -503,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

View File

@@ -25,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:
@@ -53,8 +53,8 @@ class API:
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)
@@ -70,8 +70,8 @@ class API:
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)

View File

@@ -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))))}
@@ -560,7 +612,7 @@ def show_global_types(params):
"Fields": get_default_filters(),
"ImageTypeLimit": 1,
}
continue_watching_url = get_jellyfin_url("/Users/{}/Items/Resume".format(user_id), continue_watching_url_params)
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" +
@@ -589,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)
@@ -599,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)
@@ -613,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)
@@ -656,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)
@@ -664,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)
@@ -672,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)
@@ -684,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)
@@ -696,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)
@@ -708,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)
@@ -717,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"
@@ -756,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)
@@ -767,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)
@@ -782,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)
@@ -797,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)
@@ -842,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)
@@ -858,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()
@@ -869,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",
@@ -881,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(),
@@ -920,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)
@@ -930,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)
@@ -940,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)
@@ -953,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)
@@ -964,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)
@@ -976,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)
@@ -988,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)
@@ -1037,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')
@@ -1052,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")
@@ -1084,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
@@ -1102,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
@@ -1116,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
@@ -1130,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)
@@ -1144,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():
@@ -1211,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")

View File

@@ -738,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)
@@ -818,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
@@ -1137,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
@@ -1155,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":
@@ -1172,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 = {
@@ -1192,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
@@ -1230,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)
@@ -1239,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, []

View File

@@ -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, get_current_datetime
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__)
@@ -212,54 +211,80 @@ def check_server(force=False, change_user=False, notify=False):
# stop playback when switching users
xbmc.Player().stop()
auth = quick_connect(api)
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)
# 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))
auth = api.post('/Users/AuthenticateWithQuickConnect',
{'secret': secret})
# 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)
settings.setSetting('username', 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"
if not user_details:
# Ask for password if user has one
password = ''
if secured and not user_details.get('token'):
# If using a manual login, ask for username
if manual:
kb = xbmc.Keyboard()
kb.setHeading(translate_string(30006))
kb.setHiddenInput(True)
kb.setHeading(translate_string(30005))
if current_username:
kb.setDefault(current_username)
kb.doModal()
if kb.isConfirmed():
password = kb.getText()
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()
@@ -277,65 +302,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)
@@ -363,7 +361,7 @@ def user_select(api, current_username):
selection_title,
users,
preselect=selected_id,
autoclose=20000,
autoclose=60000,
useDetails=True)
return (users, user_selection)

View File

@@ -144,14 +144,15 @@ def get_device_id():
window = HomeWindow()
username = window.get_property('user_name')
if not username:
settings = xbmcaddon.Addon()
username = settings.getSetting('username')
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))
@@ -247,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')
@@ -374,9 +405,11 @@ def translate_path(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)
r = requests.get(url, verify=verify_cert)
r.raise_for_status()
# Write the subtitle file to the local filesystem

View File

@@ -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>

View File

@@ -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")