c3vocupdater: GST doesn't really like playlists, so we preparse the stream m3u8 manually
[enigma2-plugins.git] / c3vocupdater / src / plugin.py
1 # -*- coding: utf-8 -*-
2 from Screens.Screen import Screen
3 from Components.Label import Label
4 from Components.ActionMap import ActionMap
5 from Plugins.Plugin import PluginDescriptor
6 from Screens.MessageBox import MessageBox
7 from enigma import eDVBDB, getDesktop
8 import requests
9 import json
10 import shutil
11 import re
12
13 sz_w = getDesktop(0).size().width()
14
15 class C3vocScreen (Screen):
16         if sz_w == 1920:
17                 skin = """
18                 <screen position="center,center" size="840,180" title="c3voc Updater" >
19                 <widget font="Regular;30" halign="center" name="myText" position="10,10" size="820,70" valign="center" />
20                 <eLabel backgroundColor="grey" position="10,90" size="820,1" />
21                 <ePixmap pixmap="Default-FHD/skin_default/buttons/red.svg" position="20,100" size="300,70" />
22                 <ePixmap pixmap="Default-FHD/skin_default/buttons/green.svg" position="520,100" size="300,70" />
23                 <widget backgroundColor="#9f1313" font="Regular;30" halign="center" name="myRedBtn" position="20,100" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="300,70" transparent="1" valign="center" zPosition="1" />
24                 <widget backgroundColor="#1f771f" font="Regular;30" halign="center" name="myGreenBtn" position="520,100" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="300,70" transparent="1" valign="center" zPosition="1" />
25                 </screen>"""
26         else:
27                 skin = """
28                 <screen position="center,center" size="520,130" title="c3voc Updater" >
29                 <widget name="myText" position="10,5" size="500,55" font="Regular;22" halign="center" valign="center"/>
30                 <eLabel position="10,65" size="500,1" backgroundColor="grey"/>
31                 <ePixmap pixmap="skin_default/buttons/red.png" position="10,75" size="200,40"/>
32                 <ePixmap pixmap="skin_default/buttons/green.png" position="310,75" size="200,40"/>
33                 <widget name="myRedBtn" position="10,75" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2"/>
34                 <widget name="myGreenBtn" position="310,75" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2"/>
35                 </screen>"""
36
37         def __init__ (self, session):
38                 self.session = session
39                 Screen.__init__(self, session)
40
41                 self["myText"] = Label(_("Update the c3voc stream bouquet?"))
42                 self["myRedBtn"] = Label(_("Cancel"))
43                 self["myGreenBtn"] = Label(_("OK"))
44                 self["myActionsMap"] = ActionMap(["SetupActions", "ColorActions"],
45                         {
46                                 "ok": self.getinput,
47                                 "green": self.getinput,
48                                 "red": self.close,
49                                 "cancel": self.close,
50                         }, -1)
51
52         def getinput(self):
53                 try:
54                         req = requests.session()
55                         page = req.get("http://streaming.media.ccc.de/streams/v2.json", headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36'})
56                         data = json.loads(page.content)
57
58                         with open("/tmp/c3voc", "a") as myfile:
59                                 myfile.write("#NAME c3voc (TV)\n")
60                                 myfile.close()
61
62                         for conference in data:
63                                 conference_name = conference["conference"]
64                                 for group in conference["groups"]:
65                                         rooms = group["rooms"]
66                                         if not rooms:
67                                                 continue
68
69                                         for room in rooms:
70                                                 schedule_name = room["schedulename"]
71                                                 url = self.get_hls_url(room["streams"], "hd-native")
72                                                 page = req.get(url, headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36'})
73                                                 page.content
74                                                 streamurl = re.findall('#EXT-X-STREAM-INF.*?\n(.*?)\n', page.content, re.S)
75                                                 if not streamurl[0].startswith('http'):
76                                                         streamurl = url.rsplit('/',1)[0]+'/'+streamurl[0]
77                                                 else:
78                                                         streamurl = streamurl[0]
79                                                 with open("/tmp/c3voc", "a") as myfile:
80                                                         myfile.write("#SERVICE 4097:0:1:0:0:0:0:0:0:0:%s\n#DESCRIPTION %s, %s\n" % (streamurl.replace(":", "%3a"), conference_name, schedule_name))
81                                                         myfile.close()
82
83                         if 'c3voc' not in open('/etc/enigma2/bouquets.tv').read():
84                                 with open("/etc/enigma2/bouquets.tv", "a") as myfile:
85                                         myfile.write("#SERVICE 1:7:1:0:0:0:0:0:0:0:FROM BOUQUET \"userbouquet.c3voc__tv_.tv\" ORDER BY bouquet")
86                                         myfile.close()
87
88                         shutil.move("/tmp/c3voc","/etc/enigma2/userbouquet.c3voc__tv_.tv")
89                         eDVBDB.getInstance().reloadBouquets()
90                         self.session.open(MessageBox, text = _("c3voc stream bouquet updated"), type = MessageBox.TYPE_INFO, timeout=4)
91                 except: pass
92
93                 self.close()
94
95         def get_hls_url(self, streams, slug):
96                 for stream in streams:
97                         if stream["slug"] != slug:
98                                 continue
99                         return stream["urls"]["hls"]["url"]
100
101 def main(session, **kwargs):
102         session.open(C3vocScreen)
103
104 def Plugins(**kwargs):
105         return PluginDescriptor(name="C3vocUpdater", description="update the c3voc stream bouquet", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main)