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
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 )
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)})
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
def _callEventCallback(self, event, eventType): try: event["callback"](eventType, event["callbackArguments"]) except: self._logger.error("_callEventCallback: unexpected error: %s" % (sys.exc_info()[0])) printTraceback()
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 )
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
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()
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
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)
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
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 )
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()
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
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
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)
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
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
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
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
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 ) } )
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
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
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
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
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
def _callEventCallback( self, event, eventType ): try: event["callback"]( eventType, event["callbackArguments"] ) except: self._logger.error( "_callEventCallback: unexpected error: %s" % ( sys.exc_info()[0] ) ) printTraceback()