Store information about watched conferences and events in sqlite
authorChristian Weiske <cweiske@cweiske.de>
Tue, 2 Jan 2018 22:06:08 +0000 (23:06 +0100)
committerChristian Weiske <cweiske@cweiske.de>
Tue, 2 Jan 2018 22:06:08 +0000 (23:06 +0100)
usr/lib/enigma2/python/Plugins/Extensions/MediaPortal/additions/mediatheken/ccc.py

index 7521aa5..e81d0c6 100644 (file)
@@ -9,11 +9,15 @@
 # - https://api.media.ccc.de/public/conferences/117
 # - https://api.media.ccc.de/public/events/4377
 
+import json
+import sqlite3
+import os.path as os_path
+
 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):
+       """Show a list of all conferences"""
 
        def __init__(self, session):
                MPScreen.__init__(self, session, skin='MP_PluginDescr')
@@ -34,6 +38,7 @@ class CccOverviewScreen(MPScreen):
                self['name'] = Label(_("Selection:"))
 
                self.keyLocked = True
+               self.watchdb = CccWatchDb('ccc-conferences')
                self.filmliste = []
                self.ml = MenuList([], enableWrapAround=True, content=eListboxPythonMultiContent)
                self['liste'] = self.ml
@@ -45,6 +50,12 @@ class CccOverviewScreen(MPScreen):
                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):
+               watcheduids = []
+               for row in self.watchdb.getWatched(3):
+                       watcheduids.append(row['uid'])
+
+               recent = []
+               alls   = []
                try:
                        conferences = json.loads(data)
                        if conferences.has_key('conferences'):
@@ -52,21 +63,22 @@ class CccOverviewScreen(MPScreen):
                                        title = conference.get('title').encode('utf-8')
                                        url = conference.get('url').encode('utf-8')
                                        image_url = conference.get('logo_url').encode('utf-8')
-                                       updated = conference.get('updated_at').encode('utf-8')
-                                       self.filmliste.append((title, url, image_url, updated));
+                                       acronym = conference.get('acronym').encode('utf-8')
+                                       if acronym in watcheduids:
+                                               recent.append((title, url, True, False, image_url, acronym))
+                                       alls.append((title, url, self.watchdb.hasBeenWatched(acronym), False, image_url, acronym))
                except:
                        pass
 
-               if len(self.filmliste) == 0:
-                       self.filmliste.append((_('No conferences found!'), '',''))
+               if len(recent + alls) == 0:
+                       alls.append((_('No conferences found!'), '', False, False, '', ''))
 
-               ##sort by title
-               self.filmliste.sort(key=lambda t : t[0].lower())
-               ##sort by updated_at
-               ##makes no sense, updated_at is no release date and changes
-               #self.filmliste.sort(key=lambda t : t[3])
+               #sort by title
+               alls.sort(key=lambda t : t[0].lower())
+
+               self.filmliste = recent + alls
 
-               self.ml.setList(map(self._defaultlistleft, self.filmliste))
+               self.ml.setList(map(self._defaultlistleftmarked, self.filmliste))
                self.keyLocked = False
                # show initial info
                self.showInfos()
@@ -76,8 +88,9 @@ class CccOverviewScreen(MPScreen):
                if self.keyLocked or exist == None:
                        return
 
-               title = self['liste'].getCurrent()[0][0]
-               imageUrl = self['liste'].getCurrent()[0][2]
+               current = self['liste'].getCurrent()[0]
+               title    = current[0]
+               imageUrl = current[4]
                self['name'].setText(title)
                #FIXME: image is not shown for unknown reasons
                CoverHelper(self['coverArt']).getCover(imageUrl)
@@ -85,15 +98,17 @@ class CccOverviewScreen(MPScreen):
        def keyOK(self):
                if self.keyLocked:
                        return
-               title = self['liste'].getCurrent()[0][0]
-               url = self['liste'].getCurrent()[0][1]
+               current = self['liste'].getCurrent()[0]
+               title   = current[0]
+               url     = current[1]
+               acronym = current[5]
                if url != '':
-                       self.session.open(CccConferenceScreen, url, title)
+                       self.session.open(CccConferenceScreen, url, title, acronym)
 
 class CccConferenceScreen(MPScreen):
        """Show all events of a given conference"""
 
-       def __init__(self, session, url, title):
+       def __init__(self, session, url, title, acronym):
                MPScreen.__init__(self, session, skin='MP_PluginDescr')
 
                self["actions"] = ActionMap(["MP_Actions"], {
@@ -111,6 +126,9 @@ class CccConferenceScreen(MPScreen):
                self['ContentTitle'] = Label(_("Events in %s") % title)
                self['name'] = Label(_("Selection:"))
 
+               #conference acronym for watchdb
+               self.acronym = acronym
+               self.watchdb = CccWatchDb('ccc-videos')
                self.keyLocked = True
                self.filmliste = []
                self.ml = MenuList([], enableWrapAround=True, content=eListboxPythonMultiContent)
@@ -139,8 +157,8 @@ class CccConferenceScreen(MPScreen):
                                        description += ", " + str(event.get('view_count')) + " Abrufe\n"
                                        if event.get('description') != None:
                                                description += event.get('description').encode('utf-8')
-                                       # the two False are for the marked list
-                                       self.filmliste.append((title, url, False, False, image_url, description));
+                                       # the second False is for the marked list
+                                       self.filmliste.append((title, url, self.watchdb.hasBeenWatched(event.get('guid').encode('utf-8')), False, image_url, description));
                except:
                        pass
 
@@ -184,6 +202,8 @@ class CccConferenceScreen(MPScreen):
                        event = json.loads(data)
                        title     = event.get('title').encode('utf-8')
                        image_url = event.get('poster_url').encode('utf-8')
+                       title     = event.get('title').encode('utf-8')
+                       guid      = event.get('guid').encode('utf-8')
 
                        if event.has_key('recordings'):
                                for recording in event['recordings']:
@@ -208,5 +228,60 @@ class CccConferenceScreen(MPScreen):
                        #FIXME: show "no video found" message
                        return
 
+               self.watchdb.addWatched(guid)
+               self.watchdb.addWatched(self.acronym, group = 'ccc-conferences')
                self.session.open(SimplePlayer, [(title, url, image_url)], showPlaylist=False, ltype='ccc')
-               
+
+class CccWatchDb:
+       """Store information what videos have been watched already
+          Could be used as generic has-been-watched database for all additions
+       """
+
+       def __init__(self, group):
+               self.__dbfile = config.mediaportal.watchlistpath.value + "mp_watched.db"
+               self.__conn = None
+               self.group = group
+               self.__connect()
+
+       def __connect(self):
+               if not os_path.exists(self.__dbfile):
+                       self.__conn = sqlite3.connect(self.__dbfile)
+                       self.__createDB()
+               else:
+                       self.__conn = sqlite3.connect(self.__dbfile)
+               self.__conn.row_factory = sqlite3.Row
+
+       def __createDB(self):
+               c = self.__conn.cursor()
+               #sqlite has an automatic special ROWID column
+               c.execute('CREATE TABLE watched (`group` TEXT, uid TEXT, created TEXT, additional TEXT)')
+               c.execute('CREATE UNIQUE INDEX watchkeys ON watched (`group`, uid)')
+               self.__conn.commit()
+               c.close()
+
+       def addWatched(self, uid, additionalData = None, group = None):
+               if group is None:
+                       group = self.group
+               sql = "INSERT OR REPLACE INTO watched (`group`, uid, created, additional) VALUES (?, ?, datetime('now'), ?)"
+               c = self.__conn.cursor()
+               c.execute(sql, (group, uid, json.dumps(additionalData)))
+               self.__conn.commit()
+               c.close()
+
+       def hasBeenWatched(self, uid):
+               sql = "SELECT COUNT(*) as num FROM watched WHERE `group` = ? AND uid = ?"
+               c = self.__conn.cursor()
+               c.execute(sql, (self.group, uid))
+               row = c.fetchone()
+               c.close()
+               return row['num'] > 0
+
+       def getWatched(self, limit = 10, offset = 0):
+               sql = "SELECT * FROM watched WHERE `group` = ?"\
+                     + " ORDER BY created DESC"\
+                     + " LIMIT ?, ?"
+               c = self.__conn.cursor()
+               c.execute(sql, (self.group, offset, limit))
+               rows = c.fetchall()
+               c.close()
+               return rows