media.ccc.de integration ("Mediathek")
authorChristian Weiske <cweiske@cweiske.de>
Sat, 30 Dec 2017 14:03:07 +0000 (15:03 +0100)
committerChristian Weiske <cweiske@cweiske.de>
Sat, 30 Dec 2017 14:03:07 +0000 (15:03 +0100)
usr/lib/enigma2/python/Plugins/Extensions/MediaPortal/additions/additions.xml
usr/lib/enigma2/python/Plugins/Extensions/MediaPortal/additions/mediatheken/ccc.py [new file with mode: 0644]

index 62143f9..c39a21a 100644 (file)
@@ -42,6 +42,7 @@
                <plugin type="mod" modfile="mediatheken.arte" confopt="showArte" default="True" confcat="mediatheken" gz="0" name="arte Mediathek" icon="arte" filter="Mediathek" screen="arteFirstScreen" param1="" param2=""/>
                <plugin type="mod" modfile="mediatheken.atv" confopt="showatv" default="True" confcat="mediatheken" gz="0" name="ATV Mediathek" icon="atv" filter="Mediathek" screen="atvGenreScreen" param1="" param2=""/>
                <plugin type="mod" modfile="mediatheken.br_tv" confopt="showBRTV" default="True" confcat="mediatheken" gz="0" name="BR Mediathek" icon="brtv" filter="Mediathek" screen="BRGenreScreen" param1="" param2=""/>
+               <plugin type="mod" modfile="mediatheken.ccc" confopt="showCCC" default="True" confcat="mediatheken" gz="0" name="Chaos Computer Club" icon="ccc" filter="Mediathek" screen="CccOverviewScreen" param1="" param2=""/>
                <plugin type="mod" modfile="mediatheken.dmax" confopt="showDMAX" default="True" confcat="mediatheken" gz="0" name="DMAX" icon="dmax" filter="Mediathek" screen="show_DMAX_Genre" param1="dmax" param2="DMAX.de"/>
                <plugin type="mod" modfile="mediatheken.kindertube" confopt="showkindertube" default="True" confcat="mediatheken" gz="0" name="KinderTube" icon="kindertube" filter="Mediathek" screen="kindertubeMain" param1="" param2="" kids="1"/>
                <plugin type="mod" modfile="mediatheken.myspass" confopt="showmyspass" default="True" confcat="mediatheken" gz="0" name="MySpass" icon="myspass" filter="Mediathek" screen="myspassGenreScreen" param1="" param2=""/>
                <plugin type="mod" modfile="porn.updatetube" confopt="showpornsharing" default="False" confcat="porn" gz="0" name="PornSharing" icon="pornsharing" filter="Porn" screen="updatetubeGenreScreen" param1="pornsharing" param2="" search="1" delim="+" searchurl="http://www.pornsharing.com/search/?q=%s" searchscreen="updatetubeFilmScreen" searchparam=", &quot;pornsharing.com&quot;, &quot;www.pornsharing.com&quot;"/>
                <plugin type="mod" modfile="porn.wetplace" confopt="showwetplace" default="False" confcat="porn" gz="0" name="WetPlace" icon="wetplace" filter="Porn" screen="wetplaceGenreScreen" param1="" param2="" search="1" delim="+" searchurl="http://www.wetplace.com/search/?q=%s" searchscreen="wetplaceFilmScreen" searchparam=""/>
        </set>
-</plugins>
\ No newline at end of file
+</plugins>
diff --git a/usr/lib/enigma2/python/Plugins/Extensions/MediaPortal/additions/mediatheken/ccc.py b/usr/lib/enigma2/python/Plugins/Extensions/MediaPortal/additions/mediatheken/ccc.py
new file mode 100644 (file)
index 0000000..f0423a7
--- /dev/null
@@ -0,0 +1,203 @@
+# -*- coding: utf-8 -*-
+# Display media.ccc.de conferences, events and videos
+#
+# API docs:
+# https://github.com/percidae/media.ccc.de
+#
+# Example URLs:
+# - https://api.media.ccc.de/public/conferences
+# - https://api.media.ccc.de/public/conferences/117
+# - https://api.media.ccc.de/public/events/4377
+
+from Plugins.Extensions.MediaPortal.plugin import _
+from Plugins.Extensions.MediaPortal.resources.imports import *
+default_cover = "file://%s/arte.png" % (config.mediaportal.iconcachepath.value + "logos")
+
+class CccOverviewScreen(MPScreen):
+
+       def __init__(self, session):
+               MPScreen.__init__(self, session, skin='MP_PluginDescr')
+
+               self["actions"] = ActionMap(["MP_Actions"], {
+                       "0"             : self.closeAll,
+                       "ok"    : self.keyOK,
+                       "cancel": self.keyCancel,
+                       # those are needed to update conference info area
+                       "up"    : self.keyUp,
+                       "down"  : self.keyDown,
+                       "right" : self.keyRight,
+                       "left"  : self.keyLeft
+               }, -1)
+
+               self['title'] = Label("Chaos Computer Club")
+               self['ContentTitle'] = Label(_("Konferenz:"))
+               self['name'] = Label(_("Selection:"))
+
+               self.keyLocked = True
+               self.filmliste = []
+               self.ml = MenuList([], enableWrapAround=True, content=eListboxPythonMultiContent)
+               self['liste'] = self.ml
+
+               self.onLayoutFinish.append(self.loadConferences)
+
+
+       def loadConferences(self):
+               getPage('https://api.media.ccc.de/public/conferences', agent=std_headers, headers={'Content-Type': 'application/json'}).addCallback(self.parseConferences).addErrback(self.dataError)
+
+        def parseConferences(self, data):
+               try:
+                       conferences = json.loads(data)
+                       if conferences.has_key('conferences'):
+                               for conference in conferences['conferences']:
+                                       title = conference.get('title').encode('utf-8')
+                                       url = conference.get('url').encode('utf-8')
+                                       image_url = conference.get('logo_url').encode('utf-8')
+                                       self.filmliste.append((title, url, image_url));
+               except:
+                       pass
+
+               #FIXME: sort by updated_at
+               if len(self.filmliste) == 0:
+                       self.filmliste.append((_('No conferences found!'), '',''))
+
+               self.ml.setList(map(self._defaultlistcenter, self.filmliste))
+               self.keyLocked = False
+               # show initial info
+               self.showInfos()
+
+       def showInfos(self):
+               exist = self['liste'].getCurrent()
+               if self.keyLocked or exist == None:
+                       return
+
+               title = self['liste'].getCurrent()[0][0]
+               imageUrl = self['liste'].getCurrent()[0][2]
+               self['name'].setText(title)
+               #FIXME: image is not shown for unknown reasons
+               CoverHelper(self['coverArt']).getCover(imageUrl)
+
+       def keyOK(self):
+               if self.keyLocked:
+                       return
+               title = self['liste'].getCurrent()[0][0]
+               url = self['liste'].getCurrent()[0][1]
+               if url != '':
+                       self.session.open(CccConferenceScreen, url, title)
+
+class CccConferenceScreen(MPScreen):
+       """Show all events of a given conference"""
+
+       def __init__(self, session, url, title):
+               MPScreen.__init__(self, session, skin='MP_PluginDescr')
+
+               self["actions"] = ActionMap(["MP_Actions"], {
+                       "0"     : self.closeAll,
+                       "ok"    : self.keyOK,
+                       "cancel": self.keyCancel,
+                       # those are needed to update event info area
+                       "up"    : self.keyUp,
+                       "down"  : self.keyDown,
+                       "right" : self.keyRight,
+                       "left"  : self.keyLeft
+               }, -1)
+
+               self['title'] = Label("Chaos Computer Club")
+               self['ContentTitle'] = Label(_("Events in %s") % title)
+               self['name'] = Label(_("Selection:"))
+
+               self.keyLocked = True
+               self.filmliste = []
+               self.ml = MenuList([], enableWrapAround=True, content=eListboxPythonMultiContent)
+               self['liste'] = self.ml
+
+               self.url = url
+               self.onLayoutFinish.append(self.loadEvents)
+
+
+       def loadEvents(self):
+               getPage(self.url, agent=std_headers, headers={'Content-Type': 'application/json'}).addCallback(self.parseEvents).addErrback(self.dataError)
+
+        def parseEvents(self, data):
+               try:
+                       events = json.loads(data)
+                       if events.has_key('events'):
+                               for event in events['events']:
+                                       title = event.get('title').encode('utf-8')
+                                       url = event.get('url').encode('utf-8')
+                                       image_url = event.get('poster_url').encode('utf-8')
+                                       description = ""
+                                       if event.get('subtitle') != None:
+                                               description += event.get('subtitle').encode('utf-8') + "\n"
+                                       description += str(int(event.get('duration') / 60)) + ' min'
+                                       description += ", Veröffentlichung: " + event.get('release_date').encode('utf-8')
+                                       description += ", " + str(event.get('view_count')) + " Abrufe\n"
+                                       if event.get('description') != None:
+                                               description += event.get('description').encode('utf-8')
+                                       self.filmliste.append((title, url, image_url, description));
+               except:
+                       pass
+
+               if len(self.filmliste) == 0:
+                       self.filmliste.append((_('No events found!'), '',''))
+
+               self.ml.setList(map(self._defaultlistcenter, self.filmliste))
+               self.keyLocked = False
+               # show initial info
+               self.showInfos()
+
+       def showInfos(self):
+               exist = self['liste'].getCurrent()
+               if self.keyLocked or exist == None:
+                       return
+
+               title       = self['liste'].getCurrent()[0][0]
+               imageUrl    = self['liste'].getCurrent()[0][2]
+               description = self['liste'].getCurrent()[0][3]
+
+               self['name'].setText(title)
+               self['handlung'].setText(description)
+               #FIXME: image is not shown for unknown reasons
+               CoverHelper(self['coverArt']).getCover(imageUrl)
+
+       def keyOK(self):
+               if self.keyLocked:
+                       return
+               url = self['liste'].getCurrent()[0][1]
+               if url == '':
+                       return
+               getPage(url, headers={'Content-Type': 'application/json', }).addCallback(self.parseAndPlayEvent).addErrback(self.dataError)
+
+       def parseAndPlayEvent(self, data):
+               url = None
+               hq_url = None
+               hqmp4_url = None
+               try:
+                       event = json.loads(data)
+                       title     = event.get('title').encode('utf-8')
+                       image_url = event.get('poster_url').encode('utf-8')
+
+                       if event.has_key('recordings'):
+                               for recording in event['recordings']:
+                                       mimetype = recording.get('mime_type').encode('utf-8')
+                                       url = recording.get('recording_url').encode('utf-8')
+                                       if recording.get('high_quality'):
+                                               hq_url = url
+                                       if recording.get('high_quality') and mimetype == 'video/mp4':
+                                               hqmp4_url = url
+
+               except:
+                       pass
+
+               if hqmp4_url != None:
+                       #dreambox dm7080 can jump better in mp4 than in webm
+                       # so we prefer mp4 for now
+                       url = hqmp4_url
+               elif hqmp4_url != None:
+                       url = hq_url
+
+               if url == None:
+                       #FIXME: show "no video found" message
+                       return
+
+               self.session.open(SimplePlayer, [(title, url, image_url)], showPlaylist=False, ltype='ccc')
+