Beispiel #1
0
    def _createScheduleFromDbDict(cls, conn, data):
        schedule = None
        if data:
            try:
                schedule = cls(data["id"])
                schedule.type = data["type"]
                schedule.channelId = data["channel_id"]
                schedule.startTime = data["start_time"]
                schedule.endTime = data["end_time"]
                schedule.title = data["title"]
                schedule.preferHd = data["prefer_hd"]
                schedule.preferUnscrambled = data["prefer_unscrambled"]
                schedule.dupMethod = data["dup_method"]
                schedule.startEarly = data["start_early"]
                schedule.endLate = data["end_late"]
                schedule.inactive = data["inactive"]

                if schedule.channelId != -1:
                    schedule.channel = Channel.getFromDb(
                        conn, schedule.channelId)
                    if not schedule.channel:
                        schedule.channelId = -1

                Cache().cache("schedules", schedule.id, schedule)

            except:
                cls._logger.error(
                    "_createScheduleFromDbDict: unexpected error: %s" %
                    (sys.exc_info()[0]))
                printTraceback()
        return schedule
Beispiel #2
0
    def run( self ):
        self._logger.debug( "Scheduler.run()" )

        # Keep the thread alive
        while self._running:
            self._event.wait()
            if self._running:
                try:
                    self._reschedule()
                except:
                    self._logger.error( "run: unexpected error: %s" % ( sys.exc_info()[0] ) )
                    printTraceback()
            self._event.clear()

        self._logger.warning( "Scheduler is about to shutdown, stop and remove timers" )

        with self._lock:
            for timerId in self._timers.keys():
                timer = self._timers[timerId]
                self._logger.debug( "Timer %d still active" % ( timerId ) )

                # When recording has not started yet, recordingId is not set yet.
                if timer.has_key( "recordingId" ):
                    self._logger.warning( "Timer %d has an active recording!" % ( timerId ) )
                    self._abortRecording( Timer.TIME_TRIGGER_EVENT, timerId )
                else:
                    timer["timer"].cancel()
                    del self._timers[timerId]

        # If recordings were active, their timers will be removed when the recording is fully stopped
        while len( self._timers ) > 0:
            time.sleep( 0.1 )
Beispiel #3
0
    def postLog(self, logData="[]"):
        self._logger.debug("postLog( %s )" % (logData))
        try:
            logs = json.loads(logData)
            for log in logs:
                logger = logging.getLogger("aminopvr.Log.%s" % (log["module"]))
                if log["level"] == 0:
                    logger.debug(
                        "%d %s" %
                        (log["timestamp"], urllib.unquote(log["log_text"])))
                elif log["level"] == 1:
                    logger.info(
                        "%d %s" %
                        (log["timestamp"], urllib.unquote(log["log_text"])))
                elif log["level"] == 2:
                    logger.warning(
                        "%d %s" %
                        (log["timestamp"], urllib.unquote(log["log_text"])))
                elif log["level"] == 3:
                    logger.error(
                        "%d %s" %
                        (log["timestamp"], urllib.unquote(log["log_text"])))
                elif log["level"] == 4:
                    logger.critical(
                        "%d %s" %
                        (log["timestamp"], urllib.unquote(log["log_text"])))
        except:
            self._logger.exception("postLog: exception: logData=%s" %
                                   (logData))
            printTraceback()

        return self._createResponse(API.STATUS_SUCCESS, {"numLogs": len(logs)})
Beispiel #4
0
    def _createScheduleFromDbDict( cls, conn, data ):
        schedule = None
        if data:
            try:
                schedule                    = cls( data["id"] )
                schedule.type               = data["type"]
                schedule.channelId          = data["channel_id"]
                schedule.startTime          = data["start_time"]
                schedule.endTime            = data["end_time"]
                schedule.title              = data["title"]
                schedule.preferHd           = data["prefer_hd"]
                schedule.preferUnscrambled  = data["prefer_unscrambled"]
                schedule.dupMethod          = data["dup_method"]
                schedule.startEarly         = data["start_early"]
                schedule.endLate            = data["end_late"]
                schedule.inactive           = data["inactive"]

                if schedule.channelId != -1:
                    schedule.channel = Channel.getFromDb( conn, schedule.channelId )
                    if not schedule.channel:
                        schedule.channelId = -1

                Cache().cache( "schedules", schedule.id, schedule )

            except:
                cls._logger.error( "_createScheduleFromDbDict: unexpected error: %s" % ( sys.exc_info()[0] ) )
                printTraceback()
        return schedule
Beispiel #5
0
 def _callEventCallback(self, event, eventType):
     try:
         event["callback"](eventType, event["callbackArguments"])
     except:
         self._logger.error("_callEventCallback: unexpected error: %s" %
                            (sys.exc_info()[0]))
         printTraceback()
Beispiel #6
0
 def _dataCallback( self, id_, data ):
     if data:
         try:
             self._output.write( data )
         except:
             self._logger.error( "ActiveRecording._dataCallback: error while writing to recording %s" % ( self._outputFile ) )
             printTraceback()
             self.stop( True )
     else:
         self._logger.warning( "ActiveRecording._dataCallback: didn't receive data" )
         self.stop( True )
Beispiel #7
0
    def checkDbVersion( self ):
        try:
            result = self.connection.execute( "SELECT db_version FROM db_version" )
        except:
            _logger.error( "checkDbVersion: db_version table not found!" )
            printTraceback()
            return 0

        if result:
            return int( result[0]["db_version"] )
        else:
            return 0
Beispiel #8
0
 def _watchdogTimeout( self ):
     self._logger.warning( "VirtualTuner.run: watchdog timed out; close stream; remove watchdog %s" % ( self._watchdogId ) )
     try:
         if self._inputStream:
             self._inputStream.close()
             self._inputStream = None
     except:
         self._logger.error( "VirtualTuner.run: unable to close input stream" )
         printTraceback()
         pass
     Watchdog().remove( self._watchdogId )
     self._terminateTuner()
Beispiel #9
0
    def checkDbVersion(self):
        try:
            result = self.connection.execute(
                "SELECT db_version FROM db_version")
        except:
            _logger.error("checkDbVersion: db_version table not found!")
            printTraceback()
            return 0

        if result:
            return int(result[0]["db_version"])
        else:
            return 0
Beispiel #10
0
 def _dataCallback(self, id_, data):
     if data:
         try:
             self._output.write(data)
         except:
             self._logger.error(
                 "ActiveRecording._dataCallback: error while writing to recording %s"
                 % (self._outputFile))
             printTraceback()
             self.stop(True)
     else:
         self._logger.warning(
             "ActiveRecording._dataCallback: didn't receive data")
         self.stop(True)
Beispiel #11
0
 def _createChannelUrlFromDbDict( cls, channelUrlData, channelId ):
     url = None
     if channelUrlData:
         try:
             url             = cls( channelUrlData["type"] )
             url.protocol    = channelUrlData["protocol"]
             url.ip          = channelUrlData["ip"]
             url.port        = channelUrlData["port"]
             url.arguments   = channelUrlData["arguments"]
             url.scrambled   = channelUrlData["scrambled"]
             url._id         = channelId
         except:
             cls._logger.error( "_createChannelUrlFromDbDict: unexpected error: %s" % ( sys.exc_info()[0] ) )
             printTraceback()
     return url
Beispiel #12
0
 def start( self ):
     if self._tuner:
         self._tuner.addListener( self._id, self._dataCallback )
         try:
             fd = os.open( self._outputFile, os.O_WRONLY | os.O_CREAT, 0644 )
             os.chmod( self._outputFile, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH )
             self._output = os.fdopen( fd, "wb" )
             self._notifyListener( ActiveRecording.STARTED )
         except:
             self._logger.error( "ActiveRecording.__init__: error while creating recording %s" % ( self._outputFile ) )
             printTraceback()
             self._notifyListener( ActiveRecording.ABORTED )
     else:
         self._logger.error( "ActiveRecording.__init__: Unable to get tuner" )
         self._notifyListener( ActiveRecording.ABORTED )
Beispiel #13
0
    def run( self ):
        try:
            self._inputStream = InputStreamAbstract.createInputStream( self._protocol, self._url )
            if self._inputStream:
                if self._inputStream.open():
                    self._logger.info( "VirtualTuner.run: start reading from %s on protocol %d" % ( self._url, self._protocol ) )

                    self._watchdogId = uuid.uuid1()
                    Watchdog().add( self._watchdogId, self._watchdogTimeout )
                    Watchdog().kick( self._watchdogId, WATCHDOG_KICK_PERIOD )

                    while self._running and len( self._listeners ) > 0:
                        data = self._inputStream.read( BUFFER_SIZE )

                        # If date == None, then there was a timeout
                        if data:
                            Watchdog().kick( self._watchdogId, WATCHDOG_KICK_PERIOD )
                            with self._listenerLock:
                                for listener in self._listeners:
                                    if listener["callback"]:
                                        listener["callback"]( listener["id"], data )
                                    else:
                                        try:
                                            listener["fifo"].put( data, True, 1.0 )
                                        except Queue.Full:
                                            self._logger.info( "VirtualTuner.run: listener's queue full, remove listener" )
                                            self._listeners.remove( listener )

                    try:
                        self._inputStream.close()
                        self._inputStream = None
                    except:
                        pass
                    Watchdog().remove( self._watchdogId )
                    self._terminateTuner()
                else:
                    self._logger.critical( "VirtualTuner.run: Could not open input stream with url=%r on protocol=%d" % ( self._url, self._protocol ) )
                    self._terminateTuner()
            else:
                self._logger.critical( "VirtualTuner.run: Could not create input stream with url=%r on protocol=%d" % ( self._url, self._protocol ) )
                self._terminateTuner()

        except:
            self._logger.error( "VirtualTuner.run: error while reading from %s on protocol=%d" % ( self._url, self._protocol ) )
            printTraceback()
            if self._inputStream:
                self._inputStream.close()
            self._terminateTuner()
Beispiel #14
0
 def _createChannelUrlFromDbDict(cls, channelUrlData, channelId):
     url = None
     if channelUrlData:
         try:
             url = cls(channelUrlData["type"])
             url.protocol = channelUrlData["protocol"]
             url.ip = channelUrlData["ip"]
             url.port = channelUrlData["port"]
             url.arguments = channelUrlData["arguments"]
             url.scrambled = channelUrlData["scrambled"]
             url._id = channelId
         except:
             cls._logger.error(
                 "_createChannelUrlFromDbDict: unexpected error: %s" %
                 (sys.exc_info()[0]))
             printTraceback()
     return url
Beispiel #15
0
 def fromDict( cls, channelData, id=-1 ):  # @ReservedAssignment
     channel = None
     if channelData:
         try:
             channel             = cls( id )
             channel.number      = channelData["id"]         # TODO: be consistent, json should use same naming as toDict uses.
             channel.epgId       = channelData["epg_id"]
             channel.name        = channelData["name"]
             channel.nameShort   = channelData["name_short"]
             channel.logo        = channelData["logo"]
             channel.thumbnail   = channelData["thumbnail"]
             channel.radio       = channelData["radio"]
             channel.inactive    = channelData["inactive"] if "inactive" in channelData else False
         except:
             cls._logger.error( "fromDict: unexpected error: %s" % ( sys.exc_info()[0] ) )
             printTraceback()
             channel = None
     return channel
Beispiel #16
0
 def start(self):
     if self._tuner:
         self._tuner.addListener(self._id, self._dataCallback)
         try:
             fd = os.open(self._outputFile, os.O_WRONLY | os.O_CREAT, 0644)
             os.chmod(
                 self._outputFile,
                 stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
             self._output = os.fdopen(fd, "wb")
             self._notifyListener(ActiveRecording.STARTED)
         except:
             self._logger.error(
                 "ActiveRecording.__init__: error while creating recording %s"
                 % (self._outputFile))
             printTraceback()
             self._notifyListener(ActiveRecording.ABORTED)
     else:
         self._logger.error("ActiveRecording.__init__: Unable to get tuner")
         self._notifyListener(ActiveRecording.ABORTED)
Beispiel #17
0
    def _createRecordingFromDbDict(cls, conn, data):
        recording = None
        if data:
            try:
                recording = cls(data["id"])
                recording.scheduleId = data["schedule_id"]
                recording.epgProgramId = data["epg_program_id"]
                recording.channelId = data["channel_id"]
                recording.channelName = data["channel_name"]
                recording.channelUrlType = data["channel_url_type"]
                recording.startTime = data["start_time"]
                recording.endTime = data["end_time"]
                recording.length = data["length"]
                recording.title = data["title"]
                recording.filename = data["filename"]
                recording.fileSize = data["file_size"]
                recording.streamArguments = data["stream_arguments"]
                recording.type = data["type"]
                recording.scrambled = data["scrambled"]
                recording.marker = data["marker"]
                recording.status = data["status"]
                recording.rerecord = data["rerecord"]

                if recording.epgProgramId != -1:
                    recording.epgProgram = RecordingProgram.getFromDb(
                        conn, recording.epgProgramId)
                    if not recording.epgProgram:
                        recording.epgProgramId = -1

                if recording.channelId != -1:
                    recording.channel = Channel.getFromDb(
                        conn, recording.channelId)
                    if not recording.channel:
                        recording.channelId = -1

                Cache().cache(cls._tableName, recording.id, recording)
            except:
                cls._logger.error(
                    "_createRecordingFromDbDict: unexpected error: %s" %
                    (sys.exc_info()[0]))
                printTraceback()

        return recording
Beispiel #18
0
 def execute(self, query, args=None, logger=None):
     if query == None:
         return
     with self._lock:
         sqlResult = None
         attempt = 0
         while attempt < 5:
             try:
                 if args == None:
                     sqlResult = self._cursor.execute(query)
                 else:
                     sqlResult = self._cursor.execute(query, args)
                 if logger:
                     logger.debug("Executing query: %s with args=%r" %
                                  (query, args))
                 if not self._delayCommit and not query.lower().startswith(
                         "select"):
                     self._conn.commit()
                 if query.lower().startswith("select"):
                     sqlResult = sqlResult.fetchall()
                     ResourceMonitor.reportDb("select", 1, len(sqlResult))
                 elif query.lower().startswith("update"):
                     ResourceMonitor.reportDb("update", 1,
                                              self._cursor.rowcount)
                 elif query.lower().startswith("delete"):
                     ResourceMonitor.reportDb("delete", 1,
                                              self._cursor.rowcount)
                 break
             except sqlite3.OperationalError, e:
                 if "unable to open database file" in e.message or "database is locked" in e.message:
                     self._logger.warning("DB error: %s" % (e.message))
                     attempt += 1
                     time.sleep(1)
                 else:
                     self._logger.error("DB error: %s" % (e.message))
                     printTraceback()
                     raise
             except sqlite3.DatabaseError, e:
                 self._logger.error("Fatal error executing query: %s" %
                                    (e.message))
                 printTraceback()
                 raise
Beispiel #19
0
 def fromDict( cls, data, id=-1 ):  # @ReservedAssignment
     schedule = None
     if data:
         try:
             schedule                    = cls( id )
             schedule.type               = data["type"]
             schedule.channelId          = data["channel_id"]
             schedule.startTime          = data["start_time"]
             schedule.endTime            = data["end_time"]
             schedule.title              = data["title"]
             schedule.preferHd           = data["prefer_hd"]
             schedule.preferUnscrambled  = data["prefer_unscrambled"]
             schedule.dupMethod          = data["dup_method"]
             schedule.startEarly         = data["start_early"]
             schedule.endLate            = data["end_late"]
             schedule.inactive           = data["inactive"]
         except:
             cls._logger.error( "fromDict: unexpected error: %s" % ( sys.exc_info()[0] ) )
             printTraceback()
     return schedule
Beispiel #20
0
    def _createChannelFromDbDict( cls, conn, channelData ):
        channel = None
        if channelData:
            try:
                channel             = cls( channelData["id"] )
                channel.number      = channelData["number"]
                channel.epgId       = channelData["epg_id"]
                channel.name        = channelData["name"]
                channel.nameShort   = channelData["name_short"]
                channel.logo        = channelData["logo"]
                channel.thumbnail   = channelData["thumbnail"]
                channel.radio       = channelData["radio"]
                channel.inactive    = channelData["inactive"]
                channel.getUrlsFromDb( conn )

                Cache().cache( cls._tableName, channel.id, channel )
            except:
                cls._logger.error( "_createChannelFromDbDict: unexpected error: %s" % ( sys.exc_info()[0] ) )
                printTraceback()
                channel = None
        return channel
Beispiel #21
0
    def postLog( self, logData="[]" ):
        self._logger.debug( "postLog( %s )" % ( logData ) )
        try:
            logs = json.loads( logData )
            for log in logs:
                logger = logging.getLogger( "aminopvr.Log.%s" % ( log["module"] ) )
                if log["level"] == 0:
                    logger.debug( "%d %s" % ( log["timestamp"], urllib.unquote( log["log_text"] ) ) )
                elif log["level"] == 1:
                    logger.info( "%d %s" % ( log["timestamp"], urllib.unquote( log["log_text"] ) ) )
                elif log["level"] == 2:
                    logger.warning( "%d %s" % ( log["timestamp"], urllib.unquote( log["log_text"] ) ) )
                elif log["level"] == 3:
                    logger.error( "%d %s" % ( log["timestamp"], urllib.unquote( log["log_text"] ) ) )
                elif log["level"] == 4:
                    logger.critical( "%d %s" % ( log["timestamp"], urllib.unquote( log["log_text"] ) ) )
        except:
            self._logger.exception( "postLog: exception: logData=%s" % ( logData ) )
            printTraceback()

        return self._createResponse( API.STATUS_SUCCESS, { "numLogs": len( logs ) } )
Beispiel #22
0
 def fromDict(cls, data, id=-1):  # @ReservedAssignment
     schedule = None
     if data:
         try:
             schedule = cls(id)
             schedule.type = data["type"]
             schedule.channelId = data["channel_id"]
             schedule.startTime = data["start_time"]
             schedule.endTime = data["end_time"]
             schedule.title = data["title"]
             schedule.preferHd = data["prefer_hd"]
             schedule.preferUnscrambled = data["prefer_unscrambled"]
             schedule.dupMethod = data["dup_method"]
             schedule.startEarly = data["start_early"]
             schedule.endLate = data["end_late"]
             schedule.inactive = data["inactive"]
         except:
             cls._logger.error("fromDict: unexpected error: %s" %
                               (sys.exc_info()[0]))
             printTraceback()
     return schedule
Beispiel #23
0
 def fromDict(cls, channelData, id=-1):  # @ReservedAssignment
     channel = None
     if channelData:
         try:
             channel = cls(id)
             channel.number = channelData[
                 "id"]  # TODO: be consistent, json should use same naming as toDict uses.
             channel.epgId = channelData["epg_id"]
             channel.name = channelData["name"]
             channel.nameShort = channelData["name_short"]
             channel.logo = channelData["logo"]
             channel.thumbnail = channelData["thumbnail"]
             channel.radio = channelData["radio"]
             channel.inactive = channelData[
                 "inactive"] if "inactive" in channelData else False
         except:
             cls._logger.error("fromDict: unexpected error: %s" %
                               (sys.exc_info()[0]))
             printTraceback()
             channel = None
     return channel
Beispiel #24
0
    def _createRecordingFromDbDict( cls, conn, data ):
        recording = None
        if data:
            try:
                recording                   = cls( data["id"] )
                recording.scheduleId        = data["schedule_id"]
                recording.epgProgramId      = data["epg_program_id"]
                recording.channelId         = data["channel_id"]
                recording.channelName       = data["channel_name"]
                recording.channelUrlType    = data["channel_url_type"]
                recording.startTime         = data["start_time"]
                recording.endTime           = data["end_time"]
                recording.length            = data["length"]
                recording.title             = data["title"]
                recording.filename          = data["filename"]
                recording.fileSize          = data["file_size"]
                recording.streamArguments   = data["stream_arguments"]
                recording.type              = data["type"]
                recording.scrambled         = data["scrambled"]
                recording.marker            = data["marker"]
                recording.status            = data["status"]
                recording.rerecord          = data["rerecord"]

                if recording.epgProgramId != -1:
                    recording.epgProgram = RecordingProgram.getFromDb( conn, recording.epgProgramId )
                    if not recording.epgProgram:
                        recording.epgProgramId = -1

                if recording.channelId != -1:
                    recording.channel = Channel.getFromDb( conn, recording.channelId )
                    if not recording.channel:
                        recording.channelId = -1

                Cache().cache( cls._tableName, recording.id, recording )
            except:
                cls._logger.error( "_createRecordingFromDbDict: unexpected error: %s" % ( sys.exc_info()[0] ) )
                printTraceback()

        return recording
Beispiel #25
0
    def _createChannelFromDbDict(cls, conn, channelData):
        channel = None
        if channelData:
            try:
                channel = cls(channelData["id"])
                channel.number = channelData["number"]
                channel.epgId = channelData["epg_id"]
                channel.name = channelData["name"]
                channel.nameShort = channelData["name_short"]
                channel.logo = channelData["logo"]
                channel.thumbnail = channelData["thumbnail"]
                channel.radio = channelData["radio"]
                channel.inactive = channelData["inactive"]
                channel.getUrlsFromDb(conn)

                Cache().cache(cls._tableName, channel.id, channel)
            except:
                cls._logger.error(
                    "_createChannelFromDbDict: unexpected error: %s" %
                    (sys.exc_info()[0]))
                printTraceback()
                channel = None
        return channel
Beispiel #26
0
 def execute( self, query, args=None, logger=None ):
     if query == None:
         return
     with self._lock:
         sqlResult = None
         attempt   = 0
         while attempt < 5:
             try:
                 if args == None:
                     sqlResult = self._cursor.execute( query )
                 else:
                     sqlResult = self._cursor.execute( query, args )
                 if logger:
                     logger.debug( "Executing query: %s with args=%r" % ( query, args ) )
                 if not self._delayCommit and not query.lower().startswith( "select" ):
                     self._conn.commit()
                 if query.lower().startswith( "select" ):
                     sqlResult = sqlResult.fetchall()
                     ResourceMonitor.reportDb( "select", 1, len( sqlResult ) )
                 elif query.lower().startswith( "update" ):
                     ResourceMonitor.reportDb( "update", 1, self._cursor.rowcount )
                 elif query.lower().startswith( "delete" ):
                     ResourceMonitor.reportDb( "delete", 1, self._cursor.rowcount )
                 break
             except sqlite3.OperationalError, e:
                 if "unable to open database file" in e.message or "database is locked" in e.message:
                     self._logger.warning( "DB error: %s" % ( e.message ) )
                     attempt += 1
                     time.sleep( 1 )
                 else:
                     self._logger.error( "DB error: %s" % ( e.message ) )
                     printTraceback()
                     raise
             except sqlite3.DatabaseError, e:
                 self._logger.error( "Fatal error executing query: %s" % ( e.message ) )
                 printTraceback()
                 raise
Beispiel #27
0
 def _callEventCallback( self, event, eventType ):
     try:
         event["callback"]( eventType, event["callbackArguments"] )
     except:
         self._logger.error( "_callEventCallback: unexpected error: %s" % ( sys.exc_info()[0] ) )
         printTraceback()