From 36eec828383724d8196a66eecfa124c198d32bc3 Mon Sep 17 00:00:00 2001 From: JinRonin Date: Mon, 1 Jan 2018 09:29:44 +0100 Subject: [plugin.video.dazn] 1.0.6 --- plugin.video.dazn/resources/__init__.py | 0 plugin.video.dazn/resources/fanart.jpg | Bin 0 -> 298149 bytes plugin.video.dazn/resources/icon.png | Bin 0 -> 11344 bytes .../language/resource.language.de_de/strings.po | 181 ++++++++++++++++++ .../language/resource.language.en_gb/strings.po | 181 ++++++++++++++++++ .../language/resource.language.fr_ca/strings.po | 181 ++++++++++++++++++ .../language/resource.language.fr_fr/strings.po | 181 ++++++++++++++++++ plugin.video.dazn/resources/lib/__init__.py | 0 plugin.video.dazn/resources/lib/client.py | 203 +++++++++++++++++++++ plugin.video.dazn/resources/lib/common.py | 157 ++++++++++++++++ plugin.video.dazn/resources/lib/context.py | 59 ++++++ plugin.video.dazn/resources/lib/items.py | 82 +++++++++ plugin.video.dazn/resources/lib/parser.py | 81 ++++++++ plugin.video.dazn/resources/lib/playback.py | 18 ++ plugin.video.dazn/resources/lib/rails.py | 13 ++ plugin.video.dazn/resources/lib/resources.py | 47 +++++ .../resources/lib/simple_requests/__init__.py | 6 + .../resources/lib/simple_requests/api.py | 194 ++++++++++++++++++++ .../lib/simple_requests/constants/__init__.py | 1 + .../lib/simple_requests/constants/codes.py | 5 + plugin.video.dazn/resources/lib/tiles.py | 85 +++++++++ .../resources/media/screenshot-01.jpg | Bin 0 -> 93116 bytes .../resources/media/screenshot-02.jpg | Bin 0 -> 191833 bytes .../resources/media/screenshot-03.jpg | Bin 0 -> 190071 bytes .../resources/media/screenshot-04.jpg | Bin 0 -> 92075 bytes plugin.video.dazn/resources/settings.xml | 17 ++ 26 files changed, 1692 insertions(+) create mode 100644 plugin.video.dazn/resources/__init__.py create mode 100644 plugin.video.dazn/resources/fanart.jpg create mode 100644 plugin.video.dazn/resources/icon.png create mode 100644 plugin.video.dazn/resources/language/resource.language.de_de/strings.po create mode 100644 plugin.video.dazn/resources/language/resource.language.en_gb/strings.po create mode 100644 plugin.video.dazn/resources/language/resource.language.fr_ca/strings.po create mode 100644 plugin.video.dazn/resources/language/resource.language.fr_fr/strings.po create mode 100644 plugin.video.dazn/resources/lib/__init__.py create mode 100644 plugin.video.dazn/resources/lib/client.py create mode 100644 plugin.video.dazn/resources/lib/common.py create mode 100644 plugin.video.dazn/resources/lib/context.py create mode 100644 plugin.video.dazn/resources/lib/items.py create mode 100644 plugin.video.dazn/resources/lib/parser.py create mode 100644 plugin.video.dazn/resources/lib/playback.py create mode 100644 plugin.video.dazn/resources/lib/rails.py create mode 100644 plugin.video.dazn/resources/lib/resources.py create mode 100644 plugin.video.dazn/resources/lib/simple_requests/__init__.py create mode 100644 plugin.video.dazn/resources/lib/simple_requests/api.py create mode 100644 plugin.video.dazn/resources/lib/simple_requests/constants/__init__.py create mode 100644 plugin.video.dazn/resources/lib/simple_requests/constants/codes.py create mode 100644 plugin.video.dazn/resources/lib/tiles.py create mode 100644 plugin.video.dazn/resources/media/screenshot-01.jpg create mode 100644 plugin.video.dazn/resources/media/screenshot-02.jpg create mode 100644 plugin.video.dazn/resources/media/screenshot-03.jpg create mode 100644 plugin.video.dazn/resources/media/screenshot-04.jpg create mode 100644 plugin.video.dazn/resources/settings.xml (limited to 'plugin.video.dazn/resources') diff --git a/plugin.video.dazn/resources/__init__.py b/plugin.video.dazn/resources/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugin.video.dazn/resources/fanart.jpg b/plugin.video.dazn/resources/fanart.jpg new file mode 100644 index 0000000..2875c1b Binary files /dev/null and b/plugin.video.dazn/resources/fanart.jpg differ diff --git a/plugin.video.dazn/resources/icon.png b/plugin.video.dazn/resources/icon.png new file mode 100644 index 0000000..5de8b25 Binary files /dev/null and b/plugin.video.dazn/resources/icon.png differ diff --git a/plugin.video.dazn/resources/language/resource.language.de_de/strings.po b/plugin.video.dazn/resources/language/resource.language.de_de/strings.po new file mode 100644 index 0000000..545383e --- /dev/null +++ b/plugin.video.dazn/resources/language/resource.language.de_de/strings.po @@ -0,0 +1,181 @@ +# Kodi Media Center language file +# Addon Name: DAZN +# Addon id: plugin.video.dazn +# Addon Provider: Jin + +msgid "" +msgstr "" + +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: de_DE\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgctxt "#30001" +msgid "Login successful: save credentials?" +msgstr "Anmeldung erfolgreich: Anmeldeinformationen speichern?" + +msgctxt "#30002" +msgid " Login: Email" +msgstr " Login: E-Mail" + +msgctxt "#30003" +msgid " Login: Password" +msgstr " Login: Passwort" + +msgctxt "#30004" +msgid "Please sign in using your account details. Go to www.dazn.com on another device to retrieve your forgotten email or password." +msgstr "Melde dich mit deinen Kontodetails an. Besuche www.dazn.com von einem anderen Gerät aus, um deine vergessene E-Mail-Adresse oder dein Passwort zu erhalten." + +msgctxt "#30010" +msgid "View" +msgstr "Ansicht" + +msgctxt "#30011" +msgid "Override View" +msgstr "Ansicht überschreiben" + +msgctxt "#30012" +msgid "View: Content" +msgstr "Ansicht: Inhalt" + +msgctxt "#30013" +msgid "View: ID" +msgstr "Ansicht: ID" + +msgctxt "#30020" +msgid "Videoplayer" +msgstr "Videoplayer" + +msgctxt "#30021" +msgid "Open Videoplayer Settings" +msgstr "Öffne Videoplayer Einstellungen" + +msgctxt "#30051" +msgid "Failed to get Device ID. Please Retry." +msgstr "Fehler beim Abrufen der Geräte-ID. Bitte versuche es in Kürze erneut." + +msgctxt "#30101" +msgid "Sorry, DAZN is not available in your country yet." +msgstr "Sorry, DAZN ist noch nicht in deinem Land verfügbar." + +msgctxt "#30107" +msgid "Access to the requested content has been denied." +msgstr "Der Zugriff auf den angeforderten Inhalt wurde verweigert." + +msgctxt "#30108" +msgid "You can only play two videos on your connected devices at the same time. To continue watching, then close DAZN on one of your other devices." +msgstr "Du kannst nur zwei Videos gleichzeitig auf deinen Geräten angucken. Schließe DAZN auf einem deiner Geräte, um weiterzuschauen." + +msgctxt "#30151" +msgid "Your email or password is incorrect. Please try again." +msgstr "Deine Email oder dein Passwort ist nicht korrekt. Bitte versuche es noch mal." + +msgctxt "#30161" +msgid "Continue watching sport on DAZN by reactivating your subscription in 'My Account'." +msgstr "Schaue weiterhin deinen Lieblingssport auf DAZN, indem du dein Abo in 'Mein Konto' wieder aktivierst." + +msgctxt "#30201" +msgid "Catch Up" +msgstr "Re-Live" + +msgctxt "#30202" +msgid "Coming Up" +msgstr "Demnächst" + +msgctxt "#30203" +msgid "DAZN Picks" +msgstr "DAZN Picks" + +msgctxt "#30204" +msgid "Features" +msgstr "Features" + +msgctxt "#30205" +msgid "Live Now" +msgstr "Jetzt Live" + +msgctxt "#30206" +msgid "Everyone's Watching" +msgstr "Jetzt angesagt" + +msgctxt "#30207" +msgid "Your Sports" +msgstr "Deine Sportarten" + +msgctxt "#30208" +msgid "What's On" +msgstr "Was läuft" + +msgctxt "#30209" +msgid "All Sports" +msgstr "Alle Sportarten" + +msgctxt "#30210" +msgid "Tournaments" +msgstr "Wettbewerbe" + +msgctxt "#30211" +msgid "Competitors" +msgstr "Konkurrenten" + +msgctxt "#30212" +msgid "Schedule" +msgstr "Vorschau" + +msgctxt "#30213" +msgid "Watch highlights" +msgstr "Highlights ansehen" + +msgctxt "#30214" +msgid "Change to sport" +msgstr "Zum Sport wechseln" + +msgctxt "#30215" +msgid "Change to competition" +msgstr "Zum Wettbewerb wechseln" + +msgctxt "#30221" +msgid "Today" +msgstr "Heute" + +msgctxt "#30222" +msgid "Tomorrow" +msgstr "Morgen" + +msgctxt "#30223" +msgid "Monday" +msgstr "Montag" + +msgctxt "#30224" +msgid "Tuesday" +msgstr "Dienstag" + +msgctxt "#30225" +msgid "Wednesday" +msgstr "Mittwoch" + +msgctxt "#30226" +msgid "Thursday" +msgstr "Donnerstag" + +msgctxt "#30227" +msgid "Friday" +msgstr "Freitag" + +msgctxt "#30228" +msgid "Saturday" +msgstr "Samstag" + +msgctxt "#30229" +msgid "Sunday" +msgstr "Sonntag" + +msgctxt "#30230" +msgid "Enter Date" +msgstr "Datum eingeben" + +msgctxt "#30231" +msgid "Show highlights only" +msgstr "Nur Highlights anzeigen" diff --git a/plugin.video.dazn/resources/language/resource.language.en_gb/strings.po b/plugin.video.dazn/resources/language/resource.language.en_gb/strings.po new file mode 100644 index 0000000..73be772 --- /dev/null +++ b/plugin.video.dazn/resources/language/resource.language.en_gb/strings.po @@ -0,0 +1,181 @@ +# Kodi Media Center language file +# Addon Name: DAZN +# Addon id: plugin.video.dazn +# Addon Provider: Jin + +msgid "" +msgstr "" + +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: en_GB\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgctxt "#30001" +msgid "Login successful: save credentials?" +msgstr "" + +msgctxt "#30002" +msgid " Login: Email" +msgstr "" + +msgctxt "#30003" +msgid " Login: Password" +msgstr "" + +msgctxt "#30004" +msgid "Please sign in using your account details. Go to www.dazn.com on another device to retrieve your forgotten email or password." +msgstr "" + +msgctxt "#30010" +msgid "View" +msgstr "" + +msgctxt "#30011" +msgid "Override View" +msgstr "" + +msgctxt "#30012" +msgid "View: Content" +msgstr "" + +msgctxt "#30013" +msgid "View: ID" +msgstr "" + +msgctxt "#30020" +msgid "Videoplayer" +msgstr "" + +msgctxt "#30021" +msgid "Open Videoplayer Settings" +msgstr "" + +msgctxt "#30051" +msgid "Failed to get Device ID. Please Retry." +msgstr "" + +msgctxt "#30101" +msgid "Sorry, DAZN is not available in your country yet." +msgstr "" + +msgctxt "#30107" +msgid "Access to the requested content has been denied." +msgstr "" + +msgctxt "#30108" +msgid "You can only play two videos on your connected devices at the same time. To continue watching, then close DAZN on one of your other devices." +msgstr "" + +msgctxt "#30151" +msgid "Your email or password is incorrect. Please try again." +msgstr "" + +msgctxt "#30161" +msgid "Continue watching sport on DAZN by reactivating your subscription in 'My Account'." +msgstr "" + +msgctxt "#30201" +msgid "Catch Up" +msgstr "" + +msgctxt "#30202" +msgid "Coming Up" +msgstr "" + +msgctxt "#30203" +msgid "DAZN Picks" +msgstr "" + +msgctxt "#30204" +msgid "Features" +msgstr "" + +msgctxt "#30205" +msgid "Live Now" +msgstr "" + +msgctxt "#30206" +msgid "Everyone's Watching" +msgstr "" + +msgctxt "#30207" +msgid "Your Sports" +msgstr "" + +msgctxt "#30208" +msgid "What's On" +msgstr "" + +msgctxt "#30209" +msgid "All Sports" +msgstr "" + +msgctxt "#30210" +msgid "Tournaments" +msgstr "" + +msgctxt "#30211" +msgid "Competitors" +msgstr "" + +msgctxt "#30212" +msgid "Schedule" +msgstr "" + +msgctxt "#30213" +msgid "Watch highlights" +msgstr "" + +msgctxt "#30214" +msgid "Change to sport" +msgstr "" + +msgctxt "#30215" +msgid "Change to competition" +msgstr "" + +msgctxt "#30221" +msgid "Today" +msgstr "" + +msgctxt "#30222" +msgid "Tomorrow" +msgstr "" + +msgctxt "#30223" +msgid "Monday" +msgstr "" + +msgctxt "#30224" +msgid "Tuesday" +msgstr "" + +msgctxt "#30225" +msgid "Wednesday" +msgstr "" + +msgctxt "#30226" +msgid "Thursday" +msgstr "" + +msgctxt "#30227" +msgid "Friday" +msgstr "" + +msgctxt "#30228" +msgid "Saturday" +msgstr "" + +msgctxt "#30229" +msgid "Sunday" +msgstr "" + +msgctxt "#30230" +msgid "Enter Date" +msgstr "" + +msgctxt "#30231" +msgid "Show highlights only" +msgstr "" diff --git a/plugin.video.dazn/resources/language/resource.language.fr_ca/strings.po b/plugin.video.dazn/resources/language/resource.language.fr_ca/strings.po new file mode 100644 index 0000000..3c05ea4 --- /dev/null +++ b/plugin.video.dazn/resources/language/resource.language.fr_ca/strings.po @@ -0,0 +1,181 @@ +# Kodi Media Center language file +# Addon Name: DAZN +# Addon id: plugin.video.dazn +# Addon Provider: Jin + +msgid "" +msgstr "" + +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fr_CA\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgctxt "#30001" +msgid "Login successful: save credentials?" +msgstr "Connexion réussie: Enregistrer les informations d'identification?" + +msgctxt "#30002" +msgid " Login: Email" +msgstr " Login: Email" + +msgctxt "#30003" +msgid " Login: Password" +msgstr " Login: Mot de passe" + +msgctxt "#30004" +msgid "Please sign in using your account details. Go to www.dazn.com on another device to retrieve your forgotten email or password." +msgstr "Veuillez vous connecter avec vos renseignements de compte. Rendez-vous sur www.dazn.com sur un autre appareil pour récupérer votre adresse courriel ou votre mot de passe oubliés." + +msgctxt "#30010" +msgid "View" +msgstr "Vue" + +msgctxt "#30011" +msgid "Override View" +msgstr "Vue de priorité" + +msgctxt "#30012" +msgid "View: Content" +msgstr "Vue: Content" + +msgctxt "#30013" +msgid "View: ID" +msgstr "Vue: ID" + +msgctxt "#30020" +msgid "Videoplayer" +msgstr "Lecteur Vidéo" + +msgctxt "#30021" +msgid "Open Videoplayer Settings" +msgstr "Ouvrir Les Paramètres Du Lecteur Vidéo" + +msgctxt "#30051" +msgid "Failed to get Device ID. Please Retry." +msgstr "Impossible d'obtenir l'ID de périphérique. Réessayez." + +msgctxt "#30101" +msgid "Sorry, DAZN is not available in your country yet." +msgstr "Désolé : DAZN n’est pas encore disponible dans votre pays." + +msgctxt "#30107" +msgid "Access to the requested content has been denied." +msgstr "L'accès au contenu demandé a été refusé." + +msgctxt "#30108" +msgid "You can only play two videos on your connected devices at the same time. To continue watching, then close DAZN on one of your other devices." +msgstr "Vous ne pouvez visionner que deux vidéos à la fois sur vos appareils connectés. Pour continuer à regarder, fermez DAZN sur l’un de vos autres appareils." + +msgctxt "#30151" +msgid "Your email or password is incorrect. Please try again." +msgstr "Votre adresse courriel ou votre mot de passe est incorrect. Veuillez réessayer." + +msgctxt "#30161" +msgid "Continue watching sport on DAZN by reactivating your subscription in 'My Account'." +msgstr "Continuez à regarder le sport sur DAZN en réactivant votre abonnement dans Mon compte." + +msgctxt "#30201" +msgid "Catch Up" +msgstr "Regarder plus tard" + +msgctxt "#30202" +msgid "Coming Up" +msgstr "Regarder bientôt" + +msgctxt "#30203" +msgid "DAZN Picks" +msgstr "Choix de DAZN" + +msgctxt "#30204" +msgid "Features" +msgstr "Caractéristiques" + +msgctxt "#30205" +msgid "Live Now" +msgstr "En direct maintenant" + +msgctxt "#30206" +msgid "Everyone's Watching" +msgstr "Programme familial" + +msgctxt "#30207" +msgid "Your Sports" +msgstr "Vos Sports" + +msgctxt "#30208" +msgid "What's On" +msgstr "En ce moment" + +msgctxt "#30209" +msgid "All Sports" +msgstr "Tous les Sports" + +msgctxt "#30210" +msgid "Tournaments" +msgstr "Tournois" + +msgctxt "#30211" +msgid "Competitors" +msgstr "Concurrents" + +msgctxt "#30212" +msgid "Schedule" +msgstr "Horaire" + +msgctxt "#30213" +msgid "Watch highlights" +msgstr "Faits saillants" + +msgctxt "#30214" +msgid "Change to sport" +msgstr "Aller à la sport" + +msgctxt "#30215" +msgid "Change to competition" +msgstr "Aller à la concurrence" + +msgctxt "#30221" +msgid "Today" +msgstr "Aujourd'hui" + +msgctxt "#30222" +msgid "Tomorrow" +msgstr "Demain" + +msgctxt "#30223" +msgid "Monday" +msgstr "Lundi" + +msgctxt "#30224" +msgid "Tuesday" +msgstr "Mardi" + +msgctxt "#30225" +msgid "Wednesday" +msgstr "Mercredi" + +msgctxt "#30226" +msgid "Thursday" +msgstr "Jeudi" + +msgctxt "#30227" +msgid "Friday" +msgstr "Vendredi" + +msgctxt "#30228" +msgid "Saturday" +msgstr "Samedi" + +msgctxt "#30229" +msgid "Sunday" +msgstr "Dimanche" + +msgctxt "#30230" +msgid "Enter Date" +msgstr "Entrer la date" + +msgctxt "#30231" +msgid "Show highlights only" +msgstr "Afficher uniquement les faits saillants" diff --git a/plugin.video.dazn/resources/language/resource.language.fr_fr/strings.po b/plugin.video.dazn/resources/language/resource.language.fr_fr/strings.po new file mode 100644 index 0000000..d5e4fde --- /dev/null +++ b/plugin.video.dazn/resources/language/resource.language.fr_fr/strings.po @@ -0,0 +1,181 @@ +# Kodi Media Center language file +# Addon Name: DAZN +# Addon id: plugin.video.dazn +# Addon Provider: Jin + +msgid "" +msgstr "" + +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fr_FR\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgctxt "#30001" +msgid "Login successful: save credentials?" +msgstr "Connexion réussie: Enregistrer les informations d'identification?" + +msgctxt "#30002" +msgid " Login: Email" +msgstr " Login: Email" + +msgctxt "#30003" +msgid " Login: Password" +msgstr " Login: Mot de passe" + +msgctxt "#30004" +msgid "Please sign in using your account details. Go to www.dazn.com on another device to retrieve your forgotten email or password." +msgstr "Veuillez vous connecter avec vos renseignements de compte. Rendez-vous sur www.dazn.com sur un autre appareil pour récupérer votre adresse courriel ou votre mot de passe oubliés." + +msgctxt "#30010" +msgid "View" +msgstr "Vue" + +msgctxt "#30011" +msgid "Override View" +msgstr "Vue de priorité" + +msgctxt "#30012" +msgid "View: Content" +msgstr "Vue: Content" + +msgctxt "#30013" +msgid "View: ID" +msgstr "Vue: ID" + +msgctxt "#30020" +msgid "Videoplayer" +msgstr "Lecteur Vidéo" + +msgctxt "#30021" +msgid "Open Videoplayer Settings" +msgstr "Ouvrir Les Paramètres Du Lecteur Vidéo" + +msgctxt "#30051" +msgid "Failed to get Device ID. Please Retry." +msgstr "Impossible d'obtenir l'ID de périphérique. Réessayez." + +msgctxt "#30101" +msgid "Sorry, DAZN is not available in your country yet." +msgstr "Désolé : DAZN n’est pas encore disponible dans votre pays." + +msgctxt "#30107" +msgid "Access to the requested content has been denied." +msgstr "L'accès au contenu demandé a été refusé." + +msgctxt "#30108" +msgid "You can only play two videos on your connected devices at the same time. To continue watching, then close DAZN on one of your other devices." +msgstr "Vous ne pouvez visionner que deux vidéos à la fois sur vos appareils connectés. Pour continuer à regarder, fermez DAZN sur l’un de vos autres appareils." + +msgctxt "#30151" +msgid "Your email or password is incorrect. Please try again." +msgstr "Votre adresse courriel ou votre mot de passe est incorrect. Veuillez réessayer." + +msgctxt "#30161" +msgid "Continue watching sport on DAZN by reactivating your subscription in 'My Account'." +msgstr "Continuez à regarder le sport sur DAZN en réactivant votre abonnement dans Mon compte." + +msgctxt "#30201" +msgid "Catch Up" +msgstr "Regarder plus tard" + +msgctxt "#30202" +msgid "Coming Up" +msgstr "Regarder bientôt" + +msgctxt "#30203" +msgid "DAZN Picks" +msgstr "Choix de DAZN" + +msgctxt "#30204" +msgid "Features" +msgstr "Caractéristiques" + +msgctxt "#30205" +msgid "Live Now" +msgstr "En direct maintenant" + +msgctxt "#30206" +msgid "Everyone's Watching" +msgstr "Programme familial" + +msgctxt "#30207" +msgid "Your Sports" +msgstr "Vos Sports" + +msgctxt "#30208" +msgid "What's On" +msgstr "En ce moment" + +msgctxt "#30209" +msgid "All Sports" +msgstr "Tous les Sports" + +msgctxt "#30210" +msgid "Tournaments" +msgstr "Tournois" + +msgctxt "#30211" +msgid "Competitors" +msgstr "Concurrents" + +msgctxt "#30212" +msgid "Schedule" +msgstr "Horaire" + +msgctxt "#30213" +msgid "Watch highlights" +msgstr "Faits saillants" + +msgctxt "#30214" +msgid "Change to sport" +msgstr "Aller à la sport" + +msgctxt "#30215" +msgid "Change to competition" +msgstr "Aller à la concurrence" + +msgctxt "#30221" +msgid "Today" +msgstr "Aujourd'hui" + +msgctxt "#30222" +msgid "Tomorrow" +msgstr "Demain" + +msgctxt "#30223" +msgid "Monday" +msgstr "Lundi" + +msgctxt "#30224" +msgid "Tuesday" +msgstr "Mardi" + +msgctxt "#30225" +msgid "Wednesday" +msgstr "Mercredi" + +msgctxt "#30226" +msgid "Thursday" +msgstr "Jeudi" + +msgctxt "#30227" +msgid "Friday" +msgstr "Vendredi" + +msgctxt "#30228" +msgid "Saturday" +msgstr "Samedi" + +msgctxt "#30229" +msgid "Sunday" +msgstr "Dimanche" + +msgctxt "#30230" +msgid "Enter Date" +msgstr "Entrer la date" + +msgctxt "#30231" +msgid "Show highlights only" +msgstr "Afficher uniquement les faits saillants" diff --git a/plugin.video.dazn/resources/lib/__init__.py b/plugin.video.dazn/resources/lib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugin.video.dazn/resources/lib/client.py b/plugin.video.dazn/resources/lib/client.py new file mode 100644 index 0000000..b09521e --- /dev/null +++ b/plugin.video.dazn/resources/lib/client.py @@ -0,0 +1,203 @@ +# -*- coding: utf-8 -*- + +import simple_requests as requests + +class Client: + + def __init__(self, plugin): + self.plugin = plugin + + self.DEVICE_ID = self.plugin.get_setting('device_id') + self.TOKEN = self.plugin.get_setting('token') + self.COUNTRY = self.plugin.get_setting('country') + self.LANGUAGE = self.plugin.get_setting('language') + self.POST_DATA = {} + self.ERRORS = 0 + + self.HEADERS = { + 'Content-Type': 'application/json', + 'Referer': self.plugin.api_base + } + + self.PARAMS = { + '$format': 'json' + } + + self.STARTUP = self.plugin.api_base + 'v2/Startup' + self.RAIL = self.plugin.api_base + 'v2/Rail' + self.RAILS = self.plugin.api_base + 'v3/Rails' + self.EPG = self.plugin.api_base + 'v1/Epg' + self.EVENT = self.plugin.api_base + 'v2/Event' + self.PLAYBACK = self.plugin.api_base + 'v1/Playback' + self.SIGNIN = self.plugin.api_base + 'v3/SignIn' + self.SIGNOUT = self.plugin.api_base + 'v1/SignOut' + self.REFRESH = self.plugin.api_base + 'v3/RefreshAccessToken' + self.PROFILE = self.plugin.api_base + 'v1/UserProfile' + + def content_data(self, url): + data = self.request(url) + if data.get('odata.error', None): + self.errorHandler(data) + return data + + def rails(self, id_, params=''): + self.PARAMS['groupId'] = id_ + self.PARAMS['params'] = params + return self.content_data(self.RAILS) + + def rail(self, id_, params=''): + self.PARAMS['id'] = id_ + self.PARAMS['params'] = params + return self.content_data(self.RAIL) + + def epg(self, params): + self.PARAMS['date'] = params + return self.content_data(self.EPG) + + def event(self, id_): + self.PARAMS['Id'] = id_ + return self.content_data(self.EVENT) + + def playback_data(self, id_): + self.POST_DATA = { + 'AssetId': id_, + 'Format': 'MPEG-DASH', + 'PlayerId': 'DAZN-' + self.DEVICE_ID, + 'Secure': 'true', + 'PlayReadyInitiator': 'false', + 'BadManifests': [], + 'LanguageCode': self.LANGUAGE, + } + return self.request(self.PLAYBACK) + + def playback(self, id_): + data = self.playback_data(id_) + if data.get('odata.error', None): + self.errorHandler(data) + if self.TOKEN: + data = self.playback_data(id_) + return data + + def userProfile(self): + data = self.request(self.PROFILE) + if data.get('odata.error', None): + self.errorHandler(data) + else: + self.plugin.set_setting('viewer_id', data['ViewerId']) + + def setToken(self, auth, result): + self.plugin.log('[{0}] signin: {1}'.format(self.plugin.addon_id, result)) + if auth and result == 'SignedIn': + self.TOKEN = auth['Token'] + else: + if result == 'HardOffer': + self.plugin.dialog_ok(30161) + self.signOut() + self.plugin.set_setting('token', self.TOKEN) + + def signIn(self): + credentials = self.plugin.get_credentials() + if credentials: + self.POST_DATA = { + 'Email': credentials['email'], + 'Password': credentials['password'], + 'DeviceId': self.DEVICE_ID, + 'Platform': 'web' + } + data = self.request(self.SIGNIN) + if data.get('odata.error', None): + self.errorHandler(data) + else: + self.setToken(data['AuthToken'], data.get('Result', 'SignInError')) + self.userProfile() + else: + self.plugin.dialog_ok(30004) + + def signOut(self): + self.POST_DATA = { + 'DeviceId': self.DEVICE_ID + } + r = self.request(self.SIGNOUT) + self.TOKEN = '' + self.plugin.set_setting('token', self.TOKEN) + + def refreshToken(self): + self.POST_DATA = { + 'DeviceId': self.DEVICE_ID + } + data = self.request(self.REFRESH) + if data.get('odata.error', None): + self.signOut() + self.errorHandler(data) + else: + self.setToken(data['AuthToken'], data.get('Result', 'RefreshAccessTokenError')) + + def startUp(self, device_id=''): + kodi_language = self.plugin.get_language() + if device_id != '': + self.DEVICE_ID = device_id + self.POST_DATA = { + 'LandingPageKey': 'generic', + 'Languages': '{0}, {1}'.format(kodi_language, self.LANGUAGE), + 'Platform': 'web', + 'Manufacturer': '', + 'PromoCode': '' + } + data = self.request(self.STARTUP) + region = data.get('Region', {}) + if region.get('isAllowed', False): + self.COUNTRY = region['Country'] + self.LANGUAGE = region['Language'] + languages = data['SupportedLanguages'] + for i in languages: + if i == kodi_language: + self.LANGUAGE = i + break + self.plugin.set_setting('language', self.LANGUAGE) + self.plugin.set_setting('country', self.COUNTRY) + if self.TOKEN: + self.refreshToken() + else: + self.signIn() + else: + self.TOKEN = '' + self.plugin.dialog_ok(30101) + + def request(self, url): + self.HEADERS['Authorization'] = 'Bearer ' + self.TOKEN + self.PARAMS['LanguageCode'] = self.LANGUAGE + self.PARAMS['Country'] = self.COUNTRY + + if self.POST_DATA: + r = requests.post(url, headers=self.HEADERS, data=self.POST_DATA, params=self.PARAMS) + self.POST_DATA = {} + else: + r = requests.get(url, headers=self.HEADERS, params=self.PARAMS) + + if r.headers.get('content-type', '').startswith('application/json'): + return r.json() + else: + if not r.status_code == 204: + self.plugin.log('[{0}] error: {1} ({2}, {3})'.format(self.plugin.addon_id, url, str(r.status_code), r.headers.get('content-type', ''))) + return {} + + def errorHandler(self, data): + self.ERRORS += 1 + msg = data['odata.error']['message']['value'] + code = str(data['odata.error']['code']) + self.plugin.log('[{0}] version: {1} country: {2} language: {3}'.format(self.plugin.addon_id, self.plugin.addon_version, self.COUNTRY, self.LANGUAGE)) + self.plugin.log('[{0}] error: {1} ({2})'.format(self.plugin.addon_id, msg, code)) + if code == '10000' and self.ERRORS < 3: + self.refreshToken() + elif (code == '401' or code == '10033') and self.ERRORS < 3: + self.signIn() + elif code == '7': + self.plugin.dialog_ok(30107) + elif code == '3001': + self.startUp() + elif code == '10006': + self.plugin.dialog_ok(30101) + elif code == '10008': + self.plugin.dialog_ok(30108) + elif code == '10049': + self.plugin.dialog_ok(30151) diff --git a/plugin.video.dazn/resources/lib/common.py b/plugin.video.dazn/resources/lib/common.py new file mode 100644 index 0000000..d171d9a --- /dev/null +++ b/plugin.video.dazn/resources/lib/common.py @@ -0,0 +1,157 @@ +# -*- coding: utf-8 -*- + +import datetime +import hashlib +import time +import urllib +import uuid +import xbmc +import xbmcaddon +import xbmcgui +from inputstreamhelper import Helper +from resources import resources + +class Common: + + def __init__(self, addon_handle=None, addon_url=None): + self.api_base = 'https://isl.dazn.com/misl/' + self.time_format = '%Y-%m-%dT%H:%M:%SZ' + self.date_format = '%Y-%m-%d' + + addon = self.get_addon() + self.addon_handle = addon_handle + self.addon_url = addon_url + self.addon_id = addon.getAddonInfo('id') + self.addon_name = addon.getAddonInfo('name') + self.addon_version = addon.getAddonInfo('version') + self.addon_icon = addon.getAddonInfo('icon') + self.addon_fanart = addon.getAddonInfo('fanart') + self.content = addon.getSetting('content') + self.view_id = addon.getSetting('view_id') + self.force_view = addon.getSetting('force_view') == 'true' + + def utfenc(self, text): + result = text + if isinstance(text, unicode): + result = text.encode('utf-8') + return result + + def get_addon(self): + return xbmcaddon.Addon() + + def get_dialog(self): + return xbmcgui.Dialog() + + def set_setting(self, key, value): + return self.get_addon().setSetting(key, value) + + def get_setting(self, key): + return self.get_addon().getSetting(key) + + def get_string(self, id_): + return self.utfenc(self.get_addon().getLocalizedString(id_)) + + def dialog_ok(self, id_): + self.get_dialog().ok(self.addon_name, self.get_string(id_)) + + def get_resource(self, string): + result = self.utfenc(string) + id_ = resources(string) + if id_ != 0: + result = self.get_string(id_) + return result + + def get_credentials(self): + email = self.get_dialog().input(self.addon_name + self.get_string(30002), type=xbmcgui.INPUT_ALPHANUM) + if '@' in email: + password = self.get_dialog().input(self.addon_name + self.get_string(30003), type=xbmcgui.INPUT_ALPHANUM, option=xbmcgui.ALPHANUM_HIDE_INPUT) + if len(password) > 4: + return { + 'email': email, + 'password': password + } + return None + + def log(self, msg): + xbmc.log(str(msg), xbmc.LOGDEBUG) + + def build_url(self, query): + return self.addon_url + '?' + urllib.urlencode(query) + + def get_language(self): + language = xbmc.getLanguage().split(' (')[0] + return xbmc.convertLanguage(language, xbmc.ISO_639_1) + + def time_now(self): + return datetime.datetime.now().strftime(self.time_format) + + def time_stamp(self, str_date): + return datetime.datetime.fromtimestamp(time.mktime(time.strptime(str_date, self.time_format))) + + def timedelta_total_seconds(self, timedelta): + return ( + timedelta.microseconds + 0.0 + + (timedelta.seconds + timedelta.days * 24 * 3600) * 10 ** 6) / 10 ** 6 + + def utc2local(self, date_string): + if str(date_string).startswith('2'): + utc = datetime.datetime(*(time.strptime(date_string, self.time_format)[0:6])) + epoch = time.mktime(utc.timetuple()) + offset = datetime.datetime.fromtimestamp(epoch) - datetime.datetime.utcfromtimestamp(epoch) + return (utc + offset).strftime(self.time_format) + + def uniq_id(self): + device_id = '' + mac_addr = xbmc.getInfoLabel('Network.MacAddress') + if not ":" in mac_addr: + mac_addr = xbmc.getInfoLabel('Network.MacAddress') + # hack response busy + i = 0 + while not ":" in mac_addr and i < 3: + i += 1 + time.sleep(1) + mac_addr = xbmc.getInfoLabel('Network.MacAddress') + if ":" in mac_addr: + device_id = str(uuid.UUID(hashlib.md5(str(mac_addr.decode("utf-8"))).hexdigest())) + else: + log("[{0}] error: failed to get device id ({1})".format(self.addon_id, str(mac_addr))) + self.dialog_ok(30051) + self.set_setting('device_id', device_id) + return device_id + + def open_is_settings(self): + xbmcaddon.Addon(id='inputstream.adaptive').openSettings() + + def start_is_helper(self): + helper = Helper(protocol='mpd', drm='widevine') + return helper.check_inputstream() + + def days(self, title, now, start): + today = datetime.date.today() + if start and not title == 'Live': + if now[:10] == start[:10]: + return 'Today' + elif str(today + datetime.timedelta(days=1)) == start[:10]: + return 'Tomorrow' + else: + for i in range(2,8): + if str(today + datetime.timedelta(days=i)) == start[:10]: + return (today + datetime.timedelta(days=i)).strftime('%A') + return title + + def epg_date(self, date): + return datetime.datetime.fromtimestamp(time.mktime(time.strptime(date, self.date_format))) + + def get_prev_day(self, date): + return (date - datetime.timedelta(days=1)) + + def get_next_day(self, date): + return (date + datetime.timedelta(days=1)) + + def get_date(self): + date = 'today' + dlg = self.get_dialog().numeric(1, self.get_string(30230)) + if dlg: + spl = dlg.split('/') + date = '%s-%s-%s' % (spl[2], spl[1], spl[0]) + return date diff --git a/plugin.video.dazn/resources/lib/context.py b/plugin.video.dazn/resources/lib/context.py new file mode 100644 index 0000000..d84cbb1 --- /dev/null +++ b/plugin.video.dazn/resources/lib/context.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- + +class Context: + + def __init__(self, plugin): + self.cm = [] + self.plugin = plugin + + def epg_date(self): + d = { + 'mode': 'epg', + 'id': 'date' + } + self.cm.append((self.plugin.get_string(30230), 'ActivateWindow(Videos, {0})'.format(self.plugin.build_url(d)))) + return self.cm + + def highlights(self, item, mode): + d = { + 'mode': mode, + 'title': self.plugin.utfenc(item['title']), + 'id': item.get('id', ''), + 'params': item.get('params','') + } + self.cm.append((self.plugin.get_string(30231), 'ActivateWindow(Videos, {0})'.format(self.plugin.build_url(d)))) + return self.cm + + def related(self, cm_items): + for i in cm_items: + d = { + 'mode': 'play_context', + 'title': self.plugin.utfenc(i['title']), + 'id': i.get('id', ''), + 'params': i.get('params','') + } + self.cm.append((self.plugin.get_string(30213), 'XBMC.RunPlugin({0})'.format(self.plugin.build_url(d)))) + return self.cm + + def goto(self, item): + if item.get('sport', None): + i = item['sport'] + d = { + 'mode': 'rails', + 'title': self.plugin.utfenc(i['Title']), + 'id': 'sport', + 'params': i['Id'] + } + self.cm.append((self.plugin.get_string(30214), 'ActivateWindow(Videos, {0})'.format(self.plugin.build_url(d)))) + + if item.get('competition', None): + i = item['competition'] + d = { + 'mode': 'rails', + 'title': self.plugin.utfenc(i['Title']), + 'id': 'competition', + 'params': i['Id'] + } + self.cm.append((self.plugin.get_string(30215), 'ActivateWindow(Videos, {0})'.format(self.plugin.build_url(d)))) + + return self.cm diff --git a/plugin.video.dazn/resources/lib/items.py b/plugin.video.dazn/resources/lib/items.py new file mode 100644 index 0000000..9e08127 --- /dev/null +++ b/plugin.video.dazn/resources/lib/items.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- + +import xbmc +import xbmcgui +import xbmcplugin + +class Items: + + def __init__(self, plugin): + self.cache = True + self.video = False + self.plugin = plugin + + def list_items(self, focus=False, upd=False): + if self.video: + xbmcplugin.setContent(self.plugin.addon_handle, self.plugin.content) + xbmcplugin.endOfDirectory(self.plugin.addon_handle, cacheToDisc=self.cache, updateListing=upd) + + if self.plugin.force_view: + xbmc.executebuiltin('Container.SetViewMode({0})'.format(self.plugin.view_id)) + + if focus: + try: + wnd = xbmcgui.Window(xbmcgui.getCurrentWindowId()) + wnd.getControl(wnd.getFocusId()).selectItem(focus) + except: + pass + + def add_item(self, item): + data = { + 'mode': item['mode'], + 'title': item['title'], + 'id': item.get('id', ''), + 'params': item.get('params','') + } + + art = { + 'thumb': item.get('thumb', self.plugin.addon_icon), + 'poster': item.get('thumb', self.plugin.addon_icon), + 'fanart': item.get('fanart', self.plugin.addon_fanart) + } + + labels = { + 'title': item['title'], + 'plot': item.get('plot', item['title']), + 'premiered': item.get('date', ''), + 'episode': item.get('episode', 0) + } + + listitem = xbmcgui.ListItem(item['title']) + listitem.setArt(art) + listitem.setInfo(type='Video', infoLabels=labels) + + if 'play' in item['mode']: + self.cache = False + self.video = True + folder = False + listitem.addStreamInfo('video', {'duration':item.get('duration', 0)}) + listitem.setProperty('IsPlayable', 'true') + else: + folder = True + + if item.get('cm', None): + listitem.addContextMenuItems( item['cm'] ) + + xbmcplugin.addDirectoryItem(self.plugin.addon_handle, self.plugin.build_url(data), listitem, folder) + + def play_item(self, item, name, context): + path = item.ManifestUrl + listitem = xbmcgui.ListItem() + listitem.setContentLookup(False) + listitem.setMimeType('application/dash+xml') + listitem.setProperty('inputstreamaddon', 'inputstream.adaptive') + listitem.setProperty('inputstream.adaptive.manifest_type', 'mpd') + listitem.setProperty('inputstream.adaptive.license_type', 'com.widevine.alpha') + listitem.setProperty('inputstream.adaptive.license_key', item.LaUrl+'&_widevineChallenge=B{SSM}|||JBlicense') + if context: + listitem.setInfo('video', {'Title': name}) + xbmc.Player().play(path, listitem) + else: + listitem.setPath(path) + xbmcplugin.setResolvedUrl(self.plugin.addon_handle, True, listitem) diff --git a/plugin.video.dazn/resources/lib/parser.py b/plugin.video.dazn/resources/lib/parser.py new file mode 100644 index 0000000..55d70c7 --- /dev/null +++ b/plugin.video.dazn/resources/lib/parser.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +from items import Items +from rails import Rails +from tiles import Tiles +from playback import Playback +from context import Context + +class Parser: + + def __init__(self, plugin): + self.plugin = plugin + self.items = Items(self.plugin) + + def rails_items(self, data, id_): + if id_ == 'home': + epg = { + 'mode': 'epg', + 'title': self.plugin.get_string(30212), + 'plot': 'Schedule', + 'params': 'today', + } + epg['cm'] = Context(self.plugin).highlights(epg, mode='epg_highlights') + self.items.add_item(epg) + for i in data.get('Rails', []): + item = Rails(self.plugin, i).item + if item.get('id', '') == 'CatchUp': + item['cm'] = Context(self.plugin).highlights(item, mode='rail_highlights') + self.items.add_item(item) + self.items.list_items() + + def rail_items(self, data, mode, list=True): + highlights = True if 'highlights' in mode else False + focus = data.get('StartPosition', False) + for i in data.get('Tiles', []): + context = Context(self.plugin) + item = Tiles(self.plugin, i).item + if highlights: + if item['type'] == 'Highlights': + item['cm'] = context.goto(item) + self.items.add_item(item) + elif item.get('related', []): + for i in item['related']: + if i.get('Videos', []): + _item = Tiles(self.plugin, i).item + _item['cm'] = context.goto(_item) + self.items.add_item(_item) + else: + if item.get('related', []): + cm_items = [] + for i in item['related']: + if i.get('Videos', []): + cm_items.append(Tiles(self.plugin, i).item) + context.related(cm_items) + item['cm'] = context.goto(item) + self.items.add_item(item) + if list: + self.items.list_items(focus) + + def epg_items(self, data, params, mode): + update = False if params == 'today' else True + if data.get('Date'): + date = self.plugin.epg_date(data['Date']) + cm = Context(self.plugin).epg_date() + + def date_item(day): + return { + 'mode': mode, + 'title': '{0} ({1})'.format(self.plugin.get_resource(day.strftime('%A')), day.strftime(self.plugin.date_format)), + 'plot': '{0} ({1})'.format(self.plugin.get_resource(date.strftime('%A')), date.strftime(self.plugin.date_format)), + 'params': day, + 'cm': cm + } + + self.items.add_item(date_item(self.plugin.get_prev_day(date))) + self.rail_items(data, mode, list=False) + self.items.add_item(date_item(self.plugin.get_next_day(date))) + self.items.list_items(upd=update) + + def playback(self, data, name=False, context=False): + self.items.play_item(Playback(data), name, context) diff --git a/plugin.video.dazn/resources/lib/playback.py b/plugin.video.dazn/resources/lib/playback.py new file mode 100644 index 0000000..a7ae0c4 --- /dev/null +++ b/plugin.video.dazn/resources/lib/playback.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +import simple_requests as requests + +class Playback: + + def __init__(self, data): + self.ManifestUrl = '' + self.LaUrl = '' + self.parse_data(data.get('PlaybackDetails', [])) + + def parse_data(self, data): + for i in data: + r = requests.head(i['ManifestUrl']) + if r.status_code == 200: + self.ManifestUrl = i['ManifestUrl'] + self.LaUrl = i['LaUrl'] + break diff --git a/plugin.video.dazn/resources/lib/rails.py b/plugin.video.dazn/resources/lib/rails.py new file mode 100644 index 0000000..427af78 --- /dev/null +++ b/plugin.video.dazn/resources/lib/rails.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + +class Rails: + + def __init__(self, plugin, i): + self.item = {} + self.plugin = plugin + self.item['mode'] = 'rail' + self.item['title'] = self.plugin.get_resource(i['Id']) + self.item['id'] = i['Id'] + self.item['plot'] = i['Id'] + if i.get('Params', ''): + self.item['params'] = i['Params'] diff --git a/plugin.video.dazn/resources/lib/resources.py b/plugin.video.dazn/resources/lib/resources.py new file mode 100644 index 0000000..35fd423 --- /dev/null +++ b/plugin.video.dazn/resources/lib/resources.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +def resources(string): + if string == 'CatchUp': + return 30201 + elif string == 'ComingUp': + return 30202 + elif string == 'UpComing': + return 30202 + elif string == 'Editorial': + return 30203 + elif string == 'Feature': + return 30204 + elif string == 'Live': + return 30205 + elif string == 'MostPopular': + return 30206 + elif string == 'Personal': + return 30207 + elif string == 'Scheduled': + return 30208 + elif string == 'Sport': + return 30209 + elif string == 'Competition': + return 30210 + elif string == 'Competitor': + return 30211 + elif string == 'Today': + return 30221 + elif string == 'Tomorrow': + return 30222 + elif string == 'Monday': + return 30223 + elif string == 'Tuesday': + return 30224 + elif string == 'Wednesday': + return 30225 + elif string == 'Thursday': + return 30226 + elif string == 'Friday': + return 30227 + elif string == 'Saturday': + return 30228 + elif string == 'Sunday': + return 30229 + else: + return 0 diff --git a/plugin.video.dazn/resources/lib/simple_requests/__init__.py b/plugin.video.dazn/resources/lib/simple_requests/__init__.py new file mode 100644 index 0000000..fa1fd74 --- /dev/null +++ b/plugin.video.dazn/resources/lib/simple_requests/__init__.py @@ -0,0 +1,6 @@ +__author__ = 'bromix' + +__ALL__ = ['get', 'post', 'put', 'delete', 'head', 'codes'] + +from .constants import codes +from api import get, post, put, delete, head diff --git a/plugin.video.dazn/resources/lib/simple_requests/api.py b/plugin.video.dazn/resources/lib/simple_requests/api.py new file mode 100644 index 0000000..35f6148 --- /dev/null +++ b/plugin.video.dazn/resources/lib/simple_requests/api.py @@ -0,0 +1,194 @@ +__author__ = 'bromix' + +import urllib +import urllib2 +from StringIO import StringIO +import gzip + +import json as real_json + + +class ErrorHandler(urllib2.HTTPDefaultErrorHandler): + def http_error_default(self, req, fp, code, msg, hdrs): + infourl = urllib.addinfourl(fp, hdrs, req.get_full_url()) + infourl.status = code + infourl.code = code + return infourl + + +class NoRedirectHandler(urllib2.HTTPRedirectHandler): + def http_error_302(self, req, fp, code, msg, headers): + infourl = urllib.addinfourl(fp, headers, req.get_full_url()) + infourl.status = code + infourl.code = code + return infourl + + http_error_300 = http_error_302 + http_error_301 = http_error_302 + http_error_303 = http_error_302 + http_error_307 = http_error_302 + + +class Response(): + def __init__(self): + self.headers = {} + self.code = -1 + self.text = u'' + self.status_code = -1 + + def read(self): + return self.text + + def json(self): + return real_json.loads(self.text) + + pass + + +def _request(method, url, + params=None, + data=None, + headers=None, + cookies=None, + files=None, + auth=None, + timeout=None, + allow_redirects=True, + proxies=None, + hooks=None, + stream=None, + verify=None, + cert=None, + json=None): + if not headers: + headers = {} + pass + + url = urllib.quote(url, safe="%/:=&?~#+!$,;'@()*[]") + + handlers = [] + + import sys + # starting with python 2.7.9 urllib verifies every https request + if False == verify and sys.version_info >= (2, 7, 9): + import ssl + + ssl_context = ssl.create_default_context() + ssl_context.check_hostname = False + ssl_context.verify_mode = ssl.CERT_NONE + handlers.append(urllib2.HTTPSHandler(context=ssl_context)) + pass + + # handlers.append(urllib2.HTTPCookieProcessor()) + # handlers.append(ErrorHandler) + if not allow_redirects: + handlers.append(NoRedirectHandler) + pass + opener = urllib2.build_opener(*handlers) + + query = '' + if params: + for key in params: + value = params[key] + if isinstance(value, str): + value = value.decode('utf-8') + pass + params[key] = value.encode('utf-8') + pass + query = urllib.urlencode(params) + pass + if query: + url += '?%s' % query + pass + request = urllib2.Request(url) + if headers: + for key in headers: + request.add_header(key, str(unicode(headers[key]).encode('utf-8'))) + pass + pass + if data or json: + if headers.get('Content-Type', '').startswith('application/x-www-form-urlencoded') and data: + # transform a string into a map of values + if isinstance(data, basestring): + _data = data.split('&') + data = {} + for item in _data: + name, value = item.split('=') + data[name] = value + pass + pass + + # encode each value + for key in data: + data[key] = data[key].encode('utf-8') + pass + + # urlencode + request.data = urllib.urlencode(data) + pass + elif headers.get('Content-Type', '').startswith('application/json') and data: + request.data = real_json.dumps(data).encode('utf-8') + pass + elif json: + request.data = real_json.dumps(json).encode('utf-8') + pass + else: + if not isinstance(data, basestring): + data = str(data) + pass + + if isinstance(data, str): + data = data.encode('utf-8') + pass + request.data = data + pass + pass + elif method.upper() in ['POST', 'PUT']: + request.data = "null" + pass + request.get_method = lambda: method + result = Response() + response = None + try: + response = opener.open(request) + except urllib2.HTTPError as e: + # HTTPError implements addinfourl, so we can use the exception to construct a response + if isinstance(e, urllib2.addinfourl): + response = e + pass + pass + + # process response + result.headers.update(response.headers) + result.status_code = response.getcode() + if response.headers.get('Content-Encoding', '').startswith('gzip'): + buf = StringIO(response.read()) + f = gzip.GzipFile(fileobj=buf) + result.text = f.read() + pass + else: + result.text = response.read() + + return result + + +def get(url, **kwargs): + kwargs.setdefault('allow_redirects', True) + return _request('GET', url, **kwargs) + + +def post(url, data=None, json=None, **kwargs): + kwargs.setdefault('allow_redirects', True) + return _request('POST', url, data=data, json=json, **kwargs) + + +def put(url, data=None, json=None, **kwargs): + return _request('PUT', url, data=data, json=json, **kwargs) + + +def delete(url, **kwargs): + return _request('DELETE', url, **kwargs) + + +def head(url, **kwargs): + return _request('HEAD', url, **kwargs) \ No newline at end of file diff --git a/plugin.video.dazn/resources/lib/simple_requests/constants/__init__.py b/plugin.video.dazn/resources/lib/simple_requests/constants/__init__.py new file mode 100644 index 0000000..50f773a --- /dev/null +++ b/plugin.video.dazn/resources/lib/simple_requests/constants/__init__.py @@ -0,0 +1 @@ +__author__ = 'bromix' diff --git a/plugin.video.dazn/resources/lib/simple_requests/constants/codes.py b/plugin.video.dazn/resources/lib/simple_requests/constants/codes.py new file mode 100644 index 0000000..5536a63 --- /dev/null +++ b/plugin.video.dazn/resources/lib/simple_requests/constants/codes.py @@ -0,0 +1,5 @@ +__author__ = 'bromix' + +ok = 200 + +unauthorized = 401 \ No newline at end of file diff --git a/plugin.video.dazn/resources/lib/tiles.py b/plugin.video.dazn/resources/lib/tiles.py new file mode 100644 index 0000000..b3e0060 --- /dev/null +++ b/plugin.video.dazn/resources/lib/tiles.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- + +class Tiles: + + def __init__(self, plugin, i): + self.item = {} + self.plugin = plugin + self.title = self.plugin.utfenc(i['Title']) + self.subtitle = i.get('SubTitle', '') + self.description = self.plugin.utfenc(i['Description']) + self.start = self.plugin.utc2local(i.get('Start', '')) + self.end = self.plugin.utc2local(i.get('End', '')) + self.now = self.plugin.time_now() + self.sport = i.get('Sport', []) + self.competition = i.get('Competition', []) + self.type = i.get('Type', '') + self.nav = i.get('NavigateTo', '') + self.related = i.get('Related', []) + if self.nav: + self.mode = 'rails' + self.id = i['NavigateTo'] + self.params = i['NavParams'] + else: + self.mode = 'play' + self.id = i['AssetId'] + self.params = i['EventId'] + self.update_item(i) + + def add_duration(self, i): + if 'UpComing' in self.type: + self.end = self.start + self.start = self.now + elif 'Live' in self.type: + self.start = self.now + if self.start and self.end: + self.item['duration'] = self.plugin.timedelta_total_seconds(self.plugin.time_stamp(self.end)-self.plugin.time_stamp(self.start)) + + def add_thumb(self, i): + url = self.plugin.api_base+'v2/image?id={0}&Quality=95&Width={1}&Height={2}&ResizeAction=fill&VerticalAlignment=top&Format={3}' + image = i.get('Image', '') + if image: + self.item['thumb'] = url.format(image['Id'], '720', '404', image['ImageMimeType']) + self.item['fanart'] = url.format(image['Id'], '1280', '720', image['ImageMimeType']) + background = i.get('BackgroundImage', '') + if background: + self.item['fanart'] = url.format(background['Id'], '1280', '720', background['ImageMimeType']) + + def update_item(self, i): + self.item['mode'] = self.mode + self.item['title'] = self.title + self.item['plot'] = self.description + self.item['id'] = self.id + self.item['type'] = self.plugin.get_resource(self.type) + + if self.params: + self.item['params'] = self.params + + if 'Epg' in i.get('Id', ''): + if self.competition: + competition = self.plugin.utfenc(self.competition['Title']) + if self.sport: + sport = self.plugin.utfenc(self.sport['Title']) + time_ = self.start[11:][:5] + if self.type == 'Live': + self.item['title'] = '[COLOR red]{0}[/COLOR] [COLOR dimgray]{1}[/COLOR] {2} [COLOR dimgray]{3}[/COLOR]'.format(time_, sport, self.title, competition) + else: + self.item['title'] = '{0} [COLOR dimgray]{1}[/COLOR] {2} [COLOR dimgray]{3}[/COLOR]'.format(time_, sport, self.title, competition) + + elif (self.type == 'UpComing' or 'Scheduled' in i.get('Id', '')) or (self.type == 'Highlights'): + if self.type == 'UpComing': + day = self.plugin.get_resource(self.plugin.days(self.type, self.now, self.start)) + sub_title = '{0} {1}'.format(day, self.start[11:][:5]) + else: + sub_title = self.plugin.get_resource(self.type) + self.item['title'] = '{0} ({1})'.format(self.title, sub_title) + + if self.start: + self.item['date'] = self.start[:10] + + self.item['related'] = self.related + self.item['sport'] = self.sport + self.item['competition'] = self.competition + + self.add_thumb(i) + self.add_duration(i) diff --git a/plugin.video.dazn/resources/media/screenshot-01.jpg b/plugin.video.dazn/resources/media/screenshot-01.jpg new file mode 100644 index 0000000..c007491 Binary files /dev/null and b/plugin.video.dazn/resources/media/screenshot-01.jpg differ diff --git a/plugin.video.dazn/resources/media/screenshot-02.jpg b/plugin.video.dazn/resources/media/screenshot-02.jpg new file mode 100644 index 0000000..c210762 Binary files /dev/null and b/plugin.video.dazn/resources/media/screenshot-02.jpg differ diff --git a/plugin.video.dazn/resources/media/screenshot-03.jpg b/plugin.video.dazn/resources/media/screenshot-03.jpg new file mode 100644 index 0000000..132aef9 Binary files /dev/null and b/plugin.video.dazn/resources/media/screenshot-03.jpg differ diff --git a/plugin.video.dazn/resources/media/screenshot-04.jpg b/plugin.video.dazn/resources/media/screenshot-04.jpg new file mode 100644 index 0000000..50fdc46 Binary files /dev/null and b/plugin.video.dazn/resources/media/screenshot-04.jpg differ diff --git a/plugin.video.dazn/resources/settings.xml b/plugin.video.dazn/resources/settings.xml new file mode 100644 index 0000000..0fd6046 --- /dev/null +++ b/plugin.video.dazn/resources/settings.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3