class Reduce(QObject):
    def __init__(self,reduce='../../bin/redcsl'):
        traceLogger.debug("######### reduce is %s", reduce)
        super(Reduce,self).__init__()
        self.__process = procNew(sys.path[0] + "/" + reduce)
        self.__processId = self.__process['processId']
        self.__process = self.__process['handle']
        self.__mutex = QMutex()

    def __del__(self):
        traceLogger.warning("about to delete Reduce process - this is good!")
        procDelete(self.__process)

    def compute(self,c):
        self.__mutex.lock()
        l = c.split('\n')
        for sc in l:
            a = self.__compute(sc)
        self.__mutex.unlock()
        return a

    def __compute(self,c):
        a = ansNew(self.__process,c)
        ansDelete(a['handle'])
        return a['data']

    def signal(self,c):
        signalLogger.debug("c=%s" % c)
        os.system('/bin/kill -' + c + ' ' + str(self.__processId))
Exemple #2
0
class WorkThread(QThread):
    def __init__(self, runnable):
        super(WorkThread, self).__init__()
        self.runnable = runnable
        self.stopped = False
        self.mutex = QMutex()

    def run(self, *args, **kwargs):
        self.runnable()
        self.stop()
        self.finished.connect(self.deleteLater)

    def stop(self):
        try:
            self.mutex.lock()
            self.stopped = False
        finally:
            self.mutex.unlock()

    def isStopped(self):
        try:
            self.mutex.lock()
            return self.stopped
        finally:
            self.mutex.unlock()
Exemple #3
0
class SyncThread(QThread):
    """Sync notes with evernote thread"""
    force_sync_signal = Signal()
    sync_state_changed = Signal(int)

    def __init__(self, app, *args, **kwargs):
        QThread.__init__(self, *args, **kwargs)
        self.app = app
        self.status = STATUS_NONE
        self.last_sync = datetime.now()
        self.timer = QTimer()
        self.timer.timeout.connect(self.sync)
        self.update_timer()
        self.wait_condition = QWaitCondition()
        self.mutex = QMutex()

    def update_timer(self):
        self.timer.stop()
        delay = int(self.app.settings.value('sync_delay') or 0) or DEFAULT_SYNC_DELAY
        if delay != SYNC_MANUAL:
            self.timer.start(delay)

    def run(self):
        self.session = get_db_session()
        self.sq = self.session.query
        self.auth_token = get_auth_token()
        self.note_store = get_note_store(self.auth_token)
        self.perform()
        while True:
            self.mutex.lock()
            self.wait_condition.wait(self.mutex)
            self.perform()
            self.mutex.unlock()

    def force_sync(self):
        self.timer.stop()
        self.sync()
        self.update_timer()

    @Slot()
    def sync(self):
        self.wait_condition.wakeAll()

    def perform(self):
        """Perform all sync"""
        self.status = STATUS_SYNC
        self.last_sync = datetime.now()
        self.sync_state_changed.emit(SYNC_STATE_START)
        try:
            self.local_changes()
            self.remote_changes()
        except Exception, e:  # maybe log this
            self.session.rollback()
        finally:
Exemple #4
0
class Buffer(QObject):
    """
    Class buffers annotation objects to cache from database for given frame or frame interval.
    :param video: reference to video object
    :type video: tovian.models.entity.Video
    :param parent: parent widget
    :type parent: PySide.QtCore.QObject
    """

    checkBufferState = Signal()
    buffering = Signal()
    buffered = Signal()
    initialized = Signal()

    MAX_MEMORY_USAGE = 52428800     # 50MB

    def __init__(self, video, user_id, parent=None):
        super(Buffer, self).__init__(parent)
        self.mutex = QMutex()
        self.video = video
        self.last_frame_accessed = (0, 0)
        self.displayed_frames_range = 1     # must be odd
        self.video_frame_count = self.video.frame_count
        self.video_frame_fps = self.video.fps
        self.user_id = user_id

        self.cache = {}
        self.cached_min_frame = 0
        self.cached_max_frame = 0
        self.cached_time = 10               # seconds
        self.cached_time_border = 0.25      # 25 percent from cached interval, where it starts to buffer new objects

        self.checkBufferState.connect(self.__checkBuffer)

    def initBuffer(self):
        """
        Called just first time after initializing buffed and moving to separated thread.
        """
        new_start = 0
        new_stop = int(self.cached_time * self.video_frame_fps)
        new_stop = new_stop if new_stop < self.video_frame_count else self.video_frame_count

        logger.debug("Filling buffer on interval [%s, %s]", new_start, new_stop)
        self.__bufferObjects(new_start, new_stop)
        self.initialized.emit()

    def setDisplayedFrameRange(self, length):
        """
        Sets how long frame interval is displayed (non-vis annotations).
        i.e. 11 meas [currentframe-5, currentframe+5]
        :param length: range length
        :type length: int
        """
        logger.debug("Setting new displayed range value %s", length)
        self.mutex.lock()
        self.displayed_frames_range = length
        self.mutex.unlock()

    def getObjectsInFrame(self, frame):
        """
        Returns list of annotation objects for given frame. When accessing to cache, cached is locked for other access.
        :type frame: int
        :rtype: tuple of (tovian.models.entity.AnnotationObject, int, int)
        :raise AttributeError: if given frame number is out of range [0, video.frame_count]
        """
        logger.debug("Called get an_object from buffer for frame: %s", frame)

        if frame < 0 or frame > self.video_frame_count:
            raise AttributeError("Given frame number %s is out of range [0, %s]" % (frame, self.video_frame_count))

        # --- locked ----
        self.mutex.lock()
        try:
            objects = self.cache[frame]
        except KeyError:
            logger.error("Buffer objects could not be found for frame: %s", frame)
            models.repository.logs.insert('gui.exception.get_obj_from_buffer_error',
                                          "Buffer objects could not be found for frame: %s" % frame,
                                          annotator_id=self.user_id)
            objects = self.video.annotation_objects_in_frame(frame)
        else:
            objects = objects.values()

        finally:
            self.last_frame_accessed = (frame, frame)
            self.mutex.unlock()                 # don't forget to release lock
        # ---------------

        self.checkBufferState.emit()
        return tuple(objects)

    def getObjectsInFrameInterval(self, frame_from, frame_to):
        """
        Returns list of annotation objects for given frame interval.
        :type frame_from: int
        :type frame_to: int
        :rtype: tuple of (tovian.models.entity.AnnotationObject, int, int)
        :raise AttributeError: if given frame number interval is not in range [0, video.frame_count] or is invalid
        """
        logger.debug("Called get an_object from buffer for frame interval [%s, %s]", frame_from, frame_to)

        if frame_from > frame_to:
            raise AttributeError("frame_from '%s' is greater than frame_to '%s'" % (frame_from, frame_to))

        if frame_from < 0 or frame_to < 0 or frame_to > self.video_frame_count or frame_from > self.video_frame_count:
            raise AttributeError("Given frame interval [%s, %s] is out of range [0, %s]"
                                 % (frame_from, frame_to, self.video_frame_count))

        if frame_from == frame_to:
            objects = self.getObjectsInFrame(frame_from)
            return objects

        objects = []
        self.mutex.lock()
        try:
            for frame in range(frame_from, frame_to + 1):
                try:
                    data = self.cache[frame]
                except KeyError:
                    logger.error("Buffer objects could not be found for frame: %s", frame)
                    models.repository.logs.insert('gui.exception.get_obj_from_buffer_error',
                                                  "Buffer objects could not be found for frame: %s" % frame,
                                                  annotator_id=self.user_id)
                    data = self.video.annotation_objects_in_frame(frame)
                else:
                    data = data.values()

                objects.extend(data)       # converts iterator to values
        finally:
            self.last_frame_accessed = (frame_from, frame_from)
            self.mutex.unlock()

        self.checkBufferState.emit()
        return tuple(set(objects))

    def resetBuffer(self, frame, clear_all=False, clear_object=None):
        """
        Reset buffer - loads new objects depending on given frame number (i.e. when seeking to new frame).
        Method requests lock when clearing cache!
        :param frame: target frame
        :type frame: int
        :param clear_all: manually clears buffer
        :type clear_all: bool
        :param clear_object:  object that has to be refreshed in buffer (object_id, old_start_frame, old_end_frame)
        :raise ValueError: if given frame number is out of range [0, video.frame_count] |
        when new min and max cached frame are equaled or invalid
        """
        #logger.debug("Locking thread")
        #self.mutex.lock()
        #self.last_frame_accessed = (min_frame_interval, max_frame_interval)
        #self.mutex.unlock()
        #logger.debug("Thread unlocked")

        if frame < 0 or frame > self.video_frame_count:
            raise ValueError("Given frame number %s is out of range [0, %s]" % (frame, self.video_frame_count))

        if not clear_all and not clear_object:
            # if new frame has been already cached
            if frame in self.cache:
                min_frame = frame - ((self.displayed_frames_range - 1) / 2.0)
                max_frame = frame + ((self.displayed_frames_range - 1) / 2.0)

                min_frame = 0 if min_frame < 0 else min_frame
                max_frame = self.video_frame_count if max_frame > self.video_frame_count else max_frame

                # if new frame display frame range is also cached
                if self.cached_min_frame <= min_frame and self.cached_max_frame >= max_frame:
                    logger.debug("New frame and displayed frame interval is cached and no need to reset")
                    return
                else:
                    logger.debug("Target frame is cached, but displayed frame range isn't.")
            else:
                logger.debug("Target frame is not cached.")
        # calculate new start_frame and stop_frame
        new_start_frame = frame - int((self.cached_time / 2.0) * self.video_frame_fps)
        new_stop_frame = frame + int((self.cached_time / 2.0) * self.video_frame_fps)
        new_start_frame = 0 if new_start_frame < 0 else new_start_frame
        new_stop_frame = self.video_frame_count if new_stop_frame > self.video_frame_count else new_stop_frame

        if new_stop_frame == new_start_frame or new_stop_frame < new_start_frame:
            logger.error("New start_frame '%s' and stop_frame '%s' are equal or invalid.",
                         new_start_frame, new_stop_frame)
            raise ValueError("New start_frame '%s' and stop_frame '%s' are equal or invalid."
                             % (new_start_frame, new_stop_frame))

        if clear_object:
            object_id, old_start, old_end = clear_object

            logger.debug("Deleting old object data from cache")
            self.mutex.lock()
            for i in range(old_start, old_end + 1):
                cache_data = self.cache[i]
                del cache_data[object_id]
            self.mutex.unlock()
            logger.debug("Thread unlocked")

            ## TODO DELETE !!!!!!!!!!!!!!!!!!!!!!!! FOR DEBUGGING PURPOSES
            #for key, value in self.cache.iteritems():
            #    if object_id in value:
            #        print key, value
            #        raise Exception()

            logger.debug("Clearing object id '%s' from buffer and resetting for new frame: %s", object_id, frame)
            self.__bufferObjectByID(frame, object_id)

        else:
            logger.debug("Resetting and clearing whole buffer for new frame: %s", frame)

            self.mutex.lock()
            self.cache = {}
            self.mutex.unlock()
            self.__bufferObjects(new_start_frame, new_stop_frame)       # manually invoked buffering

    def __bufferObjects(self, frame_from, frame_to):
        """
        Called to buffer new objects from database for given frame interval.
        Method requests lock when writing to cache!
        :type frame_from: int
        :type frame_to: int
        :raise ValueError: When frame_from or frame_to has invalid value (out of range, etc.)
        """
        logger.debug("Tries buffer new frame interval [%s, %s]...", frame_from, frame_to)
        if frame_from > frame_to or frame_from < 0 or frame_to > self.video_frame_count:
            raise ValueError("Invalid frame_from '%s' and frame_to values '%s'", frame_from, frame_to)

        self.mutex.lock()
        try:
            objectsTuples = self.video.annotation_objects_in_frame_intervals([(frame_from, frame_to)])
        except Exception:
            # TODO display error to user
            logger.exception("Error when buffering new objects from database on interval [%s, %s]", frame_from, frame_to)
            models.repository.logs.insert('gui.exception.buffering_new_obj_error',
                                          "Error when buffering new objects from database on interval [%s, %s]" %
                                          (frame_from, frame_to),
                                          annotator_id=self.user_id)
            self.mutex.unlock()         # don't forget to release lock
            return

        cleared = not self.cache
        self.buffering.emit()

        #logger.debug("Locking thread -> adding new data to cache")
        #self.mutex.lock()               # request lock
        try:
            for frame in range(frame_from, frame_to + 1):
                try:
                    frame_dict = self.cache[frame]
                except KeyError:
                    self.cache[frame] = {}
                    frame_dict = self.cache[frame]

                # add record to cache
                for objectTuple in objectsTuples:
                    an_object, start_frame, end_frame = objectTuple
                    if start_frame <= frame <= end_frame:
                        frame_dict[an_object.id] = objectTuple

            # if cache has been cleared when method called, set min and max pointers as usually
            if cleared:
                self.cached_max_frame = frame_to
                self.cached_min_frame = frame_from

            # if don't, cache has been extended, so moves pointer a bit
            else:
                if frame_from < self.cached_min_frame:
                    self.cached_min_frame = frame_from
                if frame_to > self.cached_max_frame:
                    self.cached_max_frame = frame_to

        finally:
            self.mutex.unlock()         # don't forget to release lock

        self.buffered.emit()
        logger.debug("Buffered new time interval [%s, %s]", frame_from, frame_to)

    def __bufferObjectByID(self, target_frame, object_id):
        """
        Buffer new object by given ID from database on given frame
        :type target_frame: int
        :type object_id: int
        :raise ValueError: When frame is out of range
        """
        logger.debug("Trying to buffer new object id '%s' on frame '%s'", object_id, target_frame)
        if target_frame < 0 or target_frame > self.video_frame_count:
            raise ValueError("Given frame number is out of video frame count range")

        try:
            objectTuples = self.video.annotation_objects_in_frame_intervals([(target_frame, target_frame)],
                                                                            [object_id, ])
        except Exception:
            # TODO display error to user
            logger.exception("Error when buffering new object id '%s' from database on on frame '%s'",
                             object_id, target_frame)
            models.repository.logs.insert('gui.exception.buffering_new_obj_error',
                                          "Error when buffering new object id '%s' from database on on frame '%s'" %
                                          (object_id, target_frame),
                                          annotator_id=self.user_id)
            return

        if not objectTuples:
            logger.warning("No object id '%s' for frame '%s' in database!")
            return
        elif len(objectTuples) > 1:
            logger.warning("Returned more than one object by id from database!")

        self.buffering.emit()

        logger.debug("Locking thread -> adding to cache new data")
        self.mutex.lock()
        try:
            an_object, start_frame, end_frame = objectTuples[0]

            for frame in range(start_frame, end_frame + 1):
                try:
                    frame_dict = self.cache[frame]
                except KeyError:
                    self.cache[frame] = {}
                    frame_dict = self.cache[frame]

                frame_dict[an_object.id] = objectTuples[0]

        finally:
            self.mutex.unlock()
            logger.debug("Thread unlocked")

        self.buffered.emit()
        logger.debug("Buffered new by id '%s' on frame '%s'", object_id, target_frame)

    @Slot()
    def __checkBuffer(self):
        """
        Method called when some data in cache has been accessed to check,
        if needs to be loaded new objects from database.
        """
        memory_usage = sys.getsizeof(self.cache)

        if memory_usage > self.MAX_MEMORY_USAGE:
            logger.warning("Reached maximum allowed memory usage '%s' bytes -> resetting buffer", self.MAX_MEMORY_USAGE)
            lower_accessed_frame, higher_accessed_frame = self.last_frame_accessed
            if lower_accessed_frame == higher_accessed_frame:
                frame = higher_accessed_frame
            else:
                frame = ((higher_accessed_frame - lower_accessed_frame) / 2) + lower_accessed_frame

            self.resetBuffer(frame, clear_all=True)
            return

        cached_min_border = self.cached_min_frame - self.last_frame_accessed[0]
        cached_max_border = self.cached_max_frame - self.last_frame_accessed[1]
        allowed_border = self.cached_time_border * self.cached_time * self.video_frame_fps

        # ----
        # If the last_accessed_frame pointer is between borders (typically between 25% and 75% cache), do nothing.
        # else cache new interval and merge cached data
        # i.e. cache status  =   |bottom|--------------0current0--|top|   => max border passed, cache new objects =>
        #      => new status =   |bottom|--------------0current0--(-----------------------------)|top|
        # ----

        # bottom border
        if cached_min_border > -allowed_border:
            new_stop = self.cached_min_frame - 1
            new_start = new_stop - int(self.cached_time * self.video_frame_fps)

            new_start = 0 if new_start < 0 else new_start
            new_start = self.video_frame_count if new_start > self.video_frame_count else new_start
            new_stop = 0 if new_stop < 0 else new_stop
            new_stop = self.video_frame_count if new_stop > self.video_frame_count else new_stop

            if new_start != new_stop:
                logger.debug("Check buffer - buffer needs to load new objects, direction down")

                self.__bufferObjects(new_start, new_stop)

        # upper border
        elif cached_max_border < allowed_border:
            new_start = self.cached_max_frame + 1
            new_stop = new_start + int(self.cached_time * self.video_frame_fps)

            new_start = 0 if new_start < 0 else new_start
            new_start = self.video_frame_count if new_start > self.video_frame_count else new_start
            new_stop = 0 if new_stop < 0 else new_stop
            new_stop = self.video_frame_count if new_stop > self.video_frame_count else new_stop

            if new_start != new_stop:
                logger.debug("Check buffer - buffer needs to load new objects, direction up")

                self.__bufferObjects(new_start, new_stop)

        else:
            logger.debug("Check buffer - status OK")

    @staticmethod
    def bufferFinished():
        """
        Called when buffer thread is finished (closed).
        """
        logger.debug("Buffer thread closed.")

    @staticmethod
    def bufferTerminated():
        """
        Called when buffer thread is terminated (forced to close).
        """
        logger.warning("Buffer thread terminated!")
Exemple #5
0
class SyncThread(QThread):
    """Sync notes with evernote thread"""
    force_sync_signal = Signal()
    sync_state_changed = Signal(int)
    data_changed = Signal()

    def __init__(self, app, *args, **kwargs):
        QThread.__init__(self, *args, **kwargs)
        self.app = app
        self.status = STATUS_NONE
        self.last_sync = datetime.now()
        self.update_count = 0
        self.timer = QTimer()
        self.timer.timeout.connect(self.sync)
        self.update_timer()
        self.wait_condition = QWaitCondition()
        self.mutex = QMutex()

    def update_timer(self):
        self.timer.stop()
        delay = int(self.app.settings.value('sync_delay') or 0) or DEFAULT_SYNC_DELAY
        if delay != SYNC_MANUAL:
            self.timer.start(delay)

    def run(self):
        self.init_db()
        self.init_network()
        while True:
            self.mutex.lock()
            self.wait_condition.wait(self.mutex)
            self.perform()
            self.mutex.unlock()
            time.sleep(1)  # prevent cpu eating

    def init_db(self):
        self.session = get_db_session()
        self.sq = self.session.query

    def init_network(self):
        while True:
            try:
                self.auth_token = get_auth_token()
                self.note_store = get_note_store(self.auth_token)
                break
            except socket.error:
                time.sleep(30)

    def force_sync(self):
        self.timer.stop()
        self.sync()
        self.update_timer()

    @Slot()
    def sync(self):
        self.wait_condition.wakeAll()

    def perform(self):
        """Perform all sync"""
        self.status = STATUS_SYNC
        self.last_sync = datetime.now()
        self.sync_state_changed.emit(SYNC_STATE_START)
        if self._need_to_update():
            self.need_to_update = True
            self.all_notes = list(self._iter_all_notes())
        try:
            if self.need_to_update:
                self.remote_changes()
            self.local_changes()
        except Exception, e:  # maybe log this
            self.session.rollback()
            self.init_db()
            self.app.log(e)
        finally:
Exemple #6
0
class manager(QObject):

	_scanParams = []
	_scanRunning = 0
	# _storageEnabled = 0
	#_folderStorage = None
	#_fileStorage = None
	#_storagePath = None
	_resultsToPrint = []

	

	def __init__(self, theMainWindow, parent=None):
		global abnormalTermination
		global scanPath
		global homeDir
		global scanReportPath
		global scanReportFolder
		global infectionsList
		global infectedFiles
		super(manager, self).__init__(parent)
		
		# Opening Configuration File
		if config.debug:
			self.confileName = os.getcwd() + "/conf/config.ini"
		else:		
			self.confileName = os.path.expanduser("~") + "/.avgui/config.ini"
		#self.confileName = os.path.expanduser("~") + "/.avgui/config.ini"
		self.configparser = SafeConfigParser()
		self.configparser.read(self.confileName)
		self.mutexPrint = QMutex()
		
		self._theMainWindow = theMainWindow
		self.setupConnections(self._theMainWindow)
		self.theTimer = QTimer()
		abnormalTermination = 0
		self.scanReportStorageEnabled = 0
		scanReportPath = None
		scanReportFolder = None
		scanPath = None
		homeDir = expanduser("~")
	
	def displayAVGinfo(self):
		self._theMainWindow.theavgavInfo.show()

	def displayAVGuiinfo(self):
		self._theMainWindow.theavguiInfo	.show()

				
	def setupConnections(self, theMainWindow):
		# Main Window
		self._theMainWindow.btnHistory.clicked.connect(self.emitHistory)
		self._theMainWindow.btnScan.clicked.connect(self.emitScan)
		self._theMainWindow.btnUpdate.clicked.connect(self.emitUpdate)
		self._theMainWindow.sigMainSent.connect(self.handleMainWindowEmits)
		self._theMainWindow.btnStatus.clicked.connect(self.showStatus)
		self._theMainWindow.comLangsel.currentIndexChanged.connect(self.setLanguage)
		self._theMainWindow.action_AVG.triggered.connect(self.displayAVGinfo)
		self._theMainWindow.action_AVGui.triggered.connect(self.displayAVGuiinfo)
		
		# Scan Dialog
		self._theMainWindow.theScan.btnSelectF.clicked.connect(self.selectWhatToScan)
		self._theMainWindow.theScan.btnBeginScan.clicked.connect(self.beginScan)
		self._theMainWindow.theScan.btnScanSettings.clicked.connect(self.setScanSettings)
		self._theMainWindow.theScan.sigCleanScanDialog.connect(self.cleanUpScanSettings)
		
		# Scan Select Dialog
		# self._theMainWindow.theScan.theSelect.sigSelectType.connect(self.handleSelectScanTypeEmits)
		self._theMainWindow.theScan.theSelect.radioFile.clicked.connect(self.emitFileSelected)
		self._theMainWindow.theScan.theSelect.radioFolder.clicked.connect(self.emitFolderSelected)
		
		# Scan Settings Dialog
		self._theMainWindow.theScan.theScanSettings.btnOK.clicked.connect(self.getScanSettings)
		self._theMainWindow.theScan.theScanSettings.chkbFileStore.stateChanged.connect(self.enableStorage)
		self._theMainWindow.theScan.theScanSettings.btnSelectFolder.clicked.connect(self.selectScanReportFolder)
		
		# Scan Progress Dialog
		self._theMainWindow.theScan.theScanProgress.btnExitScan.clicked.connect(self.terminateScan)
		self._theMainWindow.theScan.theScanProgress.sigCloseEvent.connect(self.terminateScan)
		
		# Scan History Dialog
		self._theMainWindow.theHistory.btnExecute.clicked.connect(self.execSearch)
		self._theMainWindow.theHistory.btnHistoryDB.clicked.connect(self.retrieveDBHistory)
		self._theMainWindow.theHistory.theResults.btnExtractTxt.clicked.connect(self.extractToText)
		self._theMainWindow.theHistory.theResults.sigCloseEvent.connect(self.clearResults)

		# Update Dialog
		self._theMainWindow.theUpdate.btnUpdateCheck.clicked.connect(self.checkUpdates)
		self._theMainWindow.theUpdate.btnUpdate.clicked.connect(self.performUpdate)		   
		self._theMainWindow.theUpdate.btnUpdateSet.clicked.connect(self.setUpdateSettings)
		self._theMainWindow.theUpdate.theUpdateSettings.btnOK.clicked.connect(self.setUpdateSettings)
		self._theMainWindow.theUpdate.theUpdateSettings.btnCancel.clicked.connect(self.setUpdateSettings)
		
				
	def emitScan(self):
		self._theMainWindow.sigMainSent.emit("SCAN")
		
		
	def emitHistory(self):
		self._theMainWindow.sigMainSent.emit("HISTORY")

		
	def emitUpdate(self):
		self._theMainWindow.sigMainSent.emit("UPDATE")
		
		
	def handleMainWindowEmits(self, param):
		#print(param)
		if param == "SCAN":
			self._theMainWindow.theScan.clear()
			self._theMainWindow.theScan.theSelect.clear()
			self._theMainWindow.theScan.show()
		elif param == "UPDATE":
			self._theMainWindow.theUpdate.show()
		elif param == "HISTORY":
			self._theMainWindow.theHistory.show()
			# populating combo boxes
			availMal = utilities.populateMalware()
			modelMalware = utilities.malwareModel(availMal)
			self._theMainWindow.theHistory.comMalware.setModel(modelMalware)
			availDBs = utilities.populateVirusDBs()
			modelDBs = utilities.virusDBModel(availDBs)
			
			#populating date fields
			self.curDateList = date.today().isoformat().split('-')
			self.curQDate = QDate(int(self.curDateList[0]), int(self.curDateList[1]), int(self.curDateList[2]))
			self._theMainWindow.theHistory.comStartDate.setDate(self.curQDate )
			self._theMainWindow.theHistory.comEndDate.setDate(self.curQDate )
			
			self._theMainWindow.theHistory.comDatabase.setModel(modelDBs)
			
		else:
			QMessageBox.critical(None, langmodule.attention, langmodule.applicationError, 
								 QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)
	
	def selectWhatToScan(self):
		self._theMainWindow.theScan.theSelect.clear()
		self._theMainWindow.theScan.theSelect.show()
		
	def emitFileSelected(self):
		global scanPath
		options = QFileDialog.DontResolveSymlinks 
		scanPath = QFileDialog.getOpenFileName(self._theMainWindow.theScan.theSelect, langmodule.chooseFileToScan, '/home', 'All files (*.*)', "",  options)[0]
		print("scan path is: " + scanPath)
		if scanPath == "":
			scanPath=None
			return
		else:
			self._theMainWindow.theScan.infoLabel.setText(langmodule.scanFileTitle)
			self._theMainWindow.theScan.fileToScanLabel.setText(str(scanPath))
		self._theMainWindow.theScan.theSelect.close()
		
	def emitFolderSelected(self):
		global scanPath
		options = QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly
		scanPath = QFileDialog.getExistingDirectory(self._theMainWindow.theScan.theSelect, langmodule.chooseFolderToScan, '/home', options)
		print("scan path is: " + scanPath)
		if scanPath == "":
			scanPath=None
			return
		else:
			self._theMainWindow.theScan.infoLabel.setText(langmodule.scanFolderTitle)
			self._theMainWindow.theScan.fileToScanLabel.setText(str(scanPath))
		self._theMainWindow.theScan.theSelect.close()
		
############################################ Setting Language #############################################################

	def setLanguage(self):
		
		oldLang = self.configparser.get('Language', 'lang')
		print("oldLang: " + oldLang)
		newLang = self._theMainWindow.comLangsel.currentText()
		self.configparser.set('Language', 'lang', newLang)
		print("newLang: " + newLang)
		if oldLang != newLang:
			QMessageBox.information(None, langmodule.attention, langmodule.needRestartTitle, 
									QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)
			self.configparser.set('Language', 'lang', newLang)
			with open(self.confileName, 'r+') as confile:
				self.configparser.write(confile)


################################### Methods related to setting the Scan Settings ##########################################

	def setScanSettings(self):
		self._theMainWindow.theScan.theScanSettings.show()
		
	
	def getScanSettings(self):
		global scanParameters
		global scanReportFolder
		global scanReportFile
		global scanReportPath
		#global scanReportStorageEnabled
		
		closeWidget = True
		
		#print("Setting up scan settings...")
		scanParams = []
		# scan for specific file extensions
		if self._theMainWindow.theScan.theScanSettings.chkbIfType.isChecked():
			#print("Getting file extension")
			filesToScan = self._theMainWindow.theScan.theScanSettings.textIfType.toPlainText()
			print("files to scan BEFORE: " + str(filesToScan))
			if (utilities.checkIsExtension(filesToScan)):
				scanParams.append("--ext")
				scanParams.append(filesToScan)
				#print("files to scan AFTER: " + str(filesToScan))
				#print("Just after setting file extensions: " + str(scanParams))
		fileStorageOK = self.validateFileStorage()
		if (self.scanReportStorageEnabled == 1) & (fileStorageOK):
			scanParams.append("--report")
			scanParams.append(scanReportPath)
			#print(scanParams)
		if self._theMainWindow.theScan.theScanSettings.chkbBackUpFiles.isChecked():
			scanParams.append("--vv-backup")
		if self._theMainWindow.theScan.theScanSettings.chkbArchive.isChecked():
			scanParams.append("--arc")
		if self._theMainWindow.theScan.theScanSettings.chkbBootSec.isChecked():
			scanParams.append("--boot-sector")
		if self._theMainWindow.theScan.theScanSettings.chkbCookies.isChecked():
			scanParams.append("--coo")
		if self._theMainWindow.theScan.theScanSettings.chkbMultimedia.isChecked():
			scanParams.append("--media")
		# check which radio button is set 
			# and create parameter
		if self._theMainWindow.theScan.theScanSettings.radioDelete.isChecked():
			scanParams.append("--delete")
		elif self._theMainWindow.theScan.theScanSettings.radioHeal.isChecked():
			scanParams.append("--heal")
		elif self._theMainWindow.theScan.theScanSettings.radioVault.isChecked():
			scanParams.append("--vv-move")
		
		#print("Inside function the scanParams are: " + str(scanParams))
		scanParameters = scanParams
		#print("Just set manager._scanParams: " + str(manager._scanParams))
		#scanParameters = scanParams
		print("Just set scanParameters: " + str(scanParameters))
		
		#print("Clicked OK_1: " + "self.validateFileStorage: " + str(self.validateFileStorage()) + " scanReportStorageEnabled: " + str(self.scanReportStorageEnabled) )
		if self.scanReportStorageEnabled == 1:
			print("Level 1")
			if fileStorageOK:
				print("Level 2")
				self._theMainWindow.theScan.theScanSettings.close()
				print("just closed")
		elif self.scanReportStorageEnabled == 0:
			self._theMainWindow.theScan.theScanSettings.close()
		#print("Clicked OK_2: " + "self.validateFileStorage: " + str(self.validateFileStorage()) + " scanReportStorageEnabled: " + str(self.scanReportStorageEnabled) )
		#self._theMainWindow.theScan.theScanSettings.close()
		
	def selectScanReportFolder(self):
		global scanReportFolder
		#global scanReportStorageEnabled
		result = False
		#if self._theMainWindow.theScan.theScanSettings.chkbFileStore.isChecked():
		if self.scanReportStorageEnabled == 1:
			reportDir = ""
			while not result:
				self._theMainWindow.theScan.theScanSettings.theStoreFileDialog.ShowDirsOnly
				self._theMainWindow.theScan.theSelect.selectDialog.setFileMode(QFileDialog.Directory)
				reportDir = self._theMainWindow.theScan.theSelect.selectDialog.getExistingDirectory()
				if reportDir == "":
					return
				result = utilities.checkFolderPermissions(reportDir)
				if not result:
					QMessageBox.information(None, langmodule.attention, langmodule.noAccessRights, 
									QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)
				else:					
					scanReportFolder = reportDir
					self._theMainWindow.theScan.theScanSettings.btnSelectFolder.setText(scanReportFolder)
			
	
	def validateFileStorage(self):
		global scanReportFolder
		global scanReportPath
		storagePathOK = True
		
		if (self._theMainWindow.theScan.theScanSettings.textStoreFile.toPlainText() == "") & (self.scanReportStorageEnabled == 1):
			print("here...")
			QMessageBox.information(None, langmodule.attention, langmodule.noFileNameProvided, 
								 QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)
			storagePathOK = False
		elif (self._theMainWindow.theScan.theScanSettings.textStoreFile.toPlainText() != "") & (self.scanReportStorageEnabled == 1):
			print("scanReportFolder is: " + str(scanReportFolder))
			scanReportFile = self._theMainWindow.theScan.theScanSettings.textStoreFile.toPlainText()
			if scanReportFolder != None:
				scanReportPath = scanReportFolder + "/" + scanReportFile
			else:
				scanReportPath = scanReportFile
			storagePathOK = True
		return storagePathOK
		#print("scanReportPath is: " + str(scanReportPath))
		
		return storagePathOK
			 
	def enableStorage(self):
		#global scanReportStorageEnabled
			   
		if self.scanReportStorageEnabled == 0:
			self._theMainWindow.theScan.theScanSettings.btnSelectFolder.setEnabled(True)
			self._theMainWindow.theScan.theScanSettings.textStoreFile.setEnabled(True)
			#print("setting to 1")
			#print("sender: " + str(self.sender().objectName()))
			self.scanReportStorageEnabled = 1
		else:
			self._theMainWindow.theScan.theScanSettings.btnSelectFolder.setDisabled(True)
			self._theMainWindow.theScan.theScanSettings.textStoreFile.setDisabled(True)
			#print("Setting to 0")
			#print("sender: " + str(self.sender().objectName()))
			self.scanReportStorageEnabled = 0

################################################################################
############################### DB Updates History #############################
################################################################################

	def retrieveDBHistory(self):
		self.thedbHistoryWorker = utilities.dbHistoryWorker()
		#self.thedbHistoryWorker.finished.connect(self.showdbHistoryResults)
		self.thedbHistoryWorker.sigHistoryRetrieved.connect(self.showdbHistoryResults)
		self.thedbHistoryWorker.start()
		
	def showdbHistoryResults(self, theResults):
		if theResults:
			print("theResults = " + str(theResults))
			modelHisDBRes = utilities.dbHistoryTableModel(theResults)
			self._theMainWindow.theHistory.theHistdbResults.tblViewHistoryDB.setModel(modelHisDBRes)
			self._theMainWindow.theHistory.theHistdbResults.tblViewHistoryDB.resizeColumnsToContents()
			self._theMainWindow.theHistory.theHistdbResults.show()
			self.thedbHistoryWorker.exit()
		else:
			QMessageBox.information(None, langmodule.noResults, langmodule.noUpdatesYes, 
								 QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)

################################################################################
################################### SCAN #######################################
################################################################################

	def beginScan(self):
		global infectionsList
		global infectedFiles
		global infectionsList
		self._theMainWindow.theScan.theScanProgress.theShowScanResults.tableWidget.clear()
		self.isCleanScan = False
		global scanPath
		global abnormalTermination
		global scanParameters
		self.getScanSettings()
		infectedFiles = []
		infectionsList = []
		abnormalTermination = 0
		self._theMainWindow.theScan.theScanProgress.btnExitScan.setText(langmodule.terminateScan)
		#print("Scan path is: " + str(scanPath))
		if scanPath == None:
			QMessageBox.information(None, langmodule.attention, langmodule.noFilesChosen, 
								 QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)
			return -1
		
		# preparing to start scan in a new thread
		self.theScanWorker = utilities.scanWorker(scanPath, scanParameters)
		#self.theScanWorker.finished.connect(self.onScanFinish)
		self.theScanWorker.sigWriteScan.connect(self.printToWidget)
		self.theScanWorker.sigScanTerminated.connect(self.onScanFinish)
		
		self._theMainWindow.theScan.theScanProgress.textScanProg.clear()
		self._theMainWindow.theScan.theScanProgress.show()
		self.theScanWorker.start()
			
		#preparing to store scan event in a new thread
		self.theSQLITEWorker = utilities.sqliteWorker()
		self.theSQLITEWorker.finished.connect(self.onSQLiteFinish)

	def onSQLiteFinish(self):
		pass
		#print("Data Insertion Completed!!!!")

	def printToWidget(self, linetoappend):
		self.mutexPrint.lock()
		global infectionsList
		global infectedFiles
		lineList = (linetoappend.split())
		if ("Trojan" in lineList):
			position = lineList.index('Trojan')
			infectedFiles.append(lineList[position - 1])
			infectionsList.append(lineList[position +2])
		if ("Virus" in lineList):
			if ("identified" in lineList):
				position = lineList.index('Virus')
				infectedFiles.append(lineList[position - 1])
				infectionsList.append(lineList[position +2])
		if ("Could" in lineList):
			position = lineList.index('Could')
			infectedFiles.append(lineList[position - 1])
			infectionsList.append(lineList[position +3])
		print("Infected Files: " + str(infectedFiles))
		print("List of Infections: " + str(infectionsList))
		for i,j in langmodule.translationDict.items(): 
			linetoappend = linetoappend.replace(i,j)
		# curDateTime = datetime.now().isoformat(' ')[:19]
		self._theMainWindow.theScan.theScanProgress.textScanProg.appendPlainText(linetoappend)
		self.mutexPrint.unlock()

	def terminateScan(self):
		global infectionsList
		
		infectionsList = []
		
		if not self.isCleanScan:
			global abnormalTermination
			print("Entering terminateScan from signalManager")
			if hasattr(self, 'theScanWorker'):
				if (self.theScanWorker.getScanState() == QProcess.ProcessState.Running) | (self.theScanWorker.getScanState() == QProcess.ProcessState.Starting):
					print("Seems it was running, calling killScan method")
					self.theScanWorker.killScan()
			self.isCleanScan = True
			self._theMainWindow.theScan.theScanProgress.hide()
			manager._scanParams = []
		

	def onScanFinish(self, normalTermination):
		global infectionsList
		self.theScanWorker.sigWriteScan.disconnect()
		# infectionsList = []
		
		print("Entering onScanFinish, from signalManager, normalTermination = " + str(normalTermination))
		if hasattr(self, 'theScanWorker'):
			self.theScanWorker.exit()
			while not self.theScanWorker.wait():
				print("Waiting for scan worker to finish")
		self._theMainWindow.theScan.theScanProgress.btnExitScan.setText(langmodule.btnExitUpdateProgTitle)
		
		if hasattr(self, 'theScanWorker'):
			del self.theScanWorker
			print("The Scan Worker is being Deleted")
		else:
			print("The Scan Worker Was Already Deleted")
		try:
			lockerFinish = QMutexLocker(mutexTermination)		   
			if normalTermination=="True":
				if infectionsList:
					header1 = QTableWidgetItem("Threats")
					header2 = QTableWidgetItem(("Files"))
					self._theMainWindow.theScan.theScanProgress.theShowScanResults.tableWidget.setColumnCount(2)
					self._theMainWindow.theScan.theScanProgress.theShowScanResults.tableWidget.setRowCount(len(infectionsList))
					self._theMainWindow.theScan.theScanProgress.theShowScanResults.tableWidget.setHorizontalHeaderItem(0, header1)
					self._theMainWindow.theScan.theScanProgress.theShowScanResults.tableWidget.setHorizontalHeaderItem(1, header2)
					self._theMainWindow.theScan.theScanProgress.theShowScanResults.tableWidget.horizontalHeader().setStretchLastSection(True)
					for i in range(1, len(infectionsList) + 1):
							newItem0 = QTableWidgetItem(infectionsList[i-1])
							newItem1 = QTableWidgetItem(infectedFiles[i-1])
							print("line " + str(i) + ": " + newItem0.text())
							print("line " + str(i) + ": " + newItem1.text())
							self._theMainWindow.theScan.theScanProgress.theShowScanResults.tableWidget.setItem(i-1, 0, newItem0)
							self._theMainWindow.theScan.theScanProgress.theShowScanResults.tableWidget.setItem(i-1, 1, newItem1)
							self._theMainWindow.theScan.theScanProgress.theShowScanResults.tableWidget.resizeColumnsToContents()
					self._theMainWindow.theScan.theScanProgress.theShowScanResults.show()
				self.theSQLITEWorker.start() 
		except Exception as errmut2:
			print(str(errmut2))
			exit(-1)

		gc.collect()
	

	def cleanUpScanSettings(self):
		global scanPath
		print("Running cleanup")
		scanPath = None
		manager._scanParams = []
		
######################################################## END OF SCAN ###############################################
	
	def execSearch(self):
		flag = 0
		
		if (self._theMainWindow.theHistory.comStartDate.date() > self._theMainWindow.theHistory.comEndDate.date()):
			QMessageBox.information(None, langmodule.wrongDates1, langmodule.wrongDates2, 
								 QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)
			return
		
		dateFrom = self._theMainWindow.theHistory.comStartDate.date().toString('yyyy-MM-dd')
		dateTo = self._theMainWindow.theHistory.comEndDate.date().toString('yyyy-MM-dd')
		#dateFrom = self._theMainWindow.theHistory.comStartDate.date().toString('yyyy-MM-dd') + ' 23:59:59'
		#dateTo = self._theMainWindow.theHistory.comEndDate.date().toString('yyyy-MM-dd') + ' 23:59:59'
		if dateFrom == dateTo:
			dateFrom = dateFrom + ' 00:00:00'
		dateTo = dateTo + ' 23:59:59'
		
		malware = self._theMainWindow.theHistory.comMalware.currentText()
		virusDB = self._theMainWindow.theHistory.comDatabase.currentText()
		results = utilities.scanSearchQuery(dateFrom, dateTo, malware, virusDB)
		if not results:
			QMessageBox.information(None, langmodule.noResults, langmodule.noResultsCriteria, 
								 QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)
		else:
			
			if (malware == '') & (virusDB == ''):
				flag = 0
			elif (malware =='') & (virusDB != ''):
				flag = 1
			elif (malware != '') & (virusDB == ''):
				flag = 2
			else:
				flag = 3
		
			nestedResults = []
			for item in results:
				tempList = []
				for i in item:
					tempList.append(str(i))
				nestedResults.append(tempList)
			manager._resultsToPrint = nestedResults
			modelResults = utilities.scanResultsTableModel(nestedResults, flag)
			# print("Nested Results: " + str(nestedResults))
			self._theMainWindow.theHistory.theResults.tblVscanResults.setModel(modelResults)
			#self._theMainWindow.theHistory.theResults.tblVscanResults.resizeColumnsToContents()
			if flag == 0:
				for i in range(3):
					self._theMainWindow.theHistory.theResults.tblVscanResults.setColumnWidth(i, 300)
			if flag == 2:
				self._theMainWindow.theHistory.theResults.tblVscanResults.setColumnWidth(0, 170)
				self._theMainWindow.theHistory.theResults.tblVscanResults.setColumnWidth(1, 180)
				self._theMainWindow.theHistory.theResults.tblVscanResults.setColumnWidth(2, 200)
									  
			if flag == 3:
				self._theMainWindow.theHistory.theResults.tblVscanResults.setColumnWidth(0, 150)
				self._theMainWindow.theHistory.theResults.tblVscanResults.setColumnWidth(1, 170)
				self._theMainWindow.theHistory.theResults.tblVscanResults.setColumnWidth(2, 190)
				self._theMainWindow.theHistory.theResults.tblVscanResults.setColumnWidth(3, 170)
			#print("flag = " + str(flag))
			#qsize = QSize(2000, 2000)
			#self._theMainWindow.theHistory.theResults.tblVscanResults.resize(qsize)
			self._theMainWindow.theHistory.theResults.show()

	def extractToText(self):
		try:
			now = datetime.now().isoformat().split('T')
			filename='scanLog_' + now[0][0:10] + '_' + now[1][0:8] + '.txt'
			flags = QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly
			folder = QFileDialog.getExistingDirectory(self._theMainWindow.theHistory.theResults, langmodule.chooseFolderToStoreText, homeDir, flags)
			print(filename)
			print(manager._resultsToPrint)
			path = folder + '/' + filename
			with open(path, 'w') as file:
				file.write(langmodule.userTitle + '\t\t\t' + langmodule.noOfResultsTitle  + '\t\t' + langmodule.scanDateTimeTitle + '\n') # linux specific newline - not portable!
				file.write("----------------------------------------------------------------------------------" + '\n') # linux specific newline - not portable!
				for inlist in manager._resultsToPrint:
					file.write(inlist[0] + '\t\t\t')
					file.write(inlist[1] + '\t\t\t\t\t')
					file.write(inlist[2] + '\n') # linux specific newline - not portable!
				file.close()	
		except IOError as error:
			print(str(error)[0:13])
			if "Permission denied" in str(error):
				QMessageBox.critical(None, langmodule.attention, langmodule.noAccessRightsInFolder, 
								 QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)
		except Exception:
			QMessageBox.critical(None, langmodule.attention, langmodule.errorStoringFile, 
								 QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)
	def clearResults(self):
		manager._resultsToPrint = []
		#print("Test")
	
			
################################################## UPDATES ###########################################################

################################################## Check Updates #####################################################

	def checkUpdates(self):
		self.abnormalTermination = False
		self.isCleanCheck = False
		self._theMainWindow.theUpdate.theCheckPanel.txtCheck.clear()
		self._theMainWindow.theUpdate.theCountDown.countDownLCD.display(30)
		self.theChecker = utilities.chkUpdateWorker()
		self.theChecker.sigFailed.connect(self.handleCheckTermination)
		self.theChecker.sigCheckFinished.connect(self.handleCheckTermination)
		self.theChecker.started.connect(self.beginDaemonChecker)
		self._theMainWindow.theUpdate.theCountDown.sigCloseEvent.connect(self.closeCounterWidget)
		self.theDaemonChecker = utilities.checkDaemonD()
		self.theDaemonChecker.sigDstarted.connect(self.startTimer)
		self._theMainWindow.theUpdate.theCountDown.show()
		self.theChecker.start()
		while not self.theChecker.isRunning():
			print("Waiting for checker to start")


	def beginDaemonChecker(self):
		#print("beginning daemon checker")
		self.theDaemonChecker.start()
		while not self.theDaemonChecker.isRunning():
			print("Waiting for daemon checker to start")

		
	def startTimer(self, result):
		try:
			self.theTimer.timeout.disconnect()
		except Exception as err:
			print("Error disconnecting timeout signal from timer")
		if result == 1: # process failed to start
			QMessageBox.critical(None, langmodule.attention, langmodule.restartUpdate, 
				QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)
			self._theMainWindow.theUpdate.theCountDown.close()
		if result == 2:
			self._theMainWindow.theUpdate.theCountDown.close()
			return # user cancelled the operation
		else: # normal process initiation
			#print("starting timer...")
			self.theTimer.timeout.connect(self.decrementLCD)
			self.theTimer.start(1000)

	def decrementLCD(self):
		currentValue = self._theMainWindow.theUpdate.theCountDown.countDownLCD.intValue()
		#print("decrementing: current value is: " + str(currentValue))
		self._theMainWindow.theUpdate.theCountDown.countDownLCD.display(currentValue - 1)
		
	def closeCounterWidget(self):
		if not self.isCleanCheck:
			print("In Close Counter Widget")
			if hasattr(self, 'theChecker'):
				print("it has!")
				self.theChecker.cleanUp()
			self.isCleanCheck = True
		else:
			pass
	
	def handleCheckTermination(self, abnormalTermination, theOutput):
		self.abnormalTermination = abnormalTermination
		if self._theMainWindow.theUpdate.theCountDown.isVisible():
			print("was visible")
			self._theMainWindow.theUpdate.theCountDown.close()
		print("inside with abnormalTermination: " + str(self.abnormalTermination))
		self.theTimer.stop()
		if hasattr(self, 'theChecker'):
			if self.theChecker.isRunning():
				self.theChecker.exit()
		if hasattr(self, 'theDaemonChecker'):
			if self.theDaemonChecker.isRunning():
				self.theDaemonChecker.exit()
			while not self.theDaemonChecker.wait():
				print("Waiting for daemon checker to exit")
		if hasattr(self, 'theDaemonChecker'):
			del self.theDaemonChecker
		if hasattr(self, 'theChecker'):
			#self.theChecker.exit()
			print("Trying to delete the checker")
			del self.theChecker
		gc.collect()
		#if hasattr(self, 'theChecker'):
		#	 print("Failed to delete the checker")
		#self._theMainWindow.theUpdate.theCountDown.close()
		if not self.abnormalTermination:
			self._theMainWindow.theUpdate.theCheckPanel.txtCheck.appendPlainText(theOutput)
			self._theMainWindow.theUpdate.theCheckPanel.show()
		gc.collect()

############################################### Run Update #######################################################

	def performUpdate(self):
		self.isClean = False
		self._theMainWindow.theUpdate.theUpdateProgress.sigCloseEvent.connect(self.closeUpdateProgress)
		self.theUpdater = utilities.updateWorker()
		self.theUpdater.sigWriteUpdate.connect(self.printToUpdateWidget)
		self.theUpdater.sigUpdateTerminated.connect(self.onUpdateFinish)
		self.theUpdater.started.connect(self.startChecker)
		self.theUpdateChecker = utilities.checkDaemonD()
		self.theUpdateChecker.sigDstarted.connect(self.showProgress)
		self.theUpdater.start()
	
	def closeUpdateProgress(self):
		print("is clean: " + str(self.isClean))
		if self.isClean:
			pass
		else:
			if hasattr(self, "theUpdater"):
				self.theUpdater.cleanUp()
			self.isClean = True

	def startChecker(self):
		self.theUpdateChecker.start()
		while not self.theUpdateChecker.isRunning():
			print("Waiting for checker to start")		 

	def showProgress(self, result):
		print("result is: " + str(result))
		self._theMainWindow.theUpdate.theUpdateProgress.textUpdateProg.clear()
		if result == 0:
			self._theMainWindow.theUpdate.theUpdateProgress.show()
			self._theMainWindow.theUpdate.theUpdateProgress.btnExit.setEnabled(False)
		else:
			pass
	
	def printToUpdateWidget(self, theInput):
		 self._theMainWindow.theUpdate.theUpdateProgress.textUpdateProg.appendPlainText(theInput)

	def onUpdateFinish(self, exitCode):
		print("EXIT CODE IS: " + str(exitCode))
		if exitCode == 1: # process did not start
			QMessageBox.critical(None, langmodule.attention, langmodule.restartUpdate, 
								 QMessageBox.Ok | QMessageBox.Default, QMessageBox.NoButton)
			if hasattr(self, 'theUpdateChecker'):
				self.theUpdateChecker.exit()
			if hasattr(self, 'theUpdater'):
				self.theUpdater.exit()
		elif exitCode == 0 | exitCode == 255: # nornal process termination
			# print(str(self.theUpdater.isRunning()))
			# signals need to be disconnected in both cases
			self.theUpdater.started.disconnect()
			self.theUpdater.sigUpdateTerminated.disconnect()
			self.theUpdater.sigWriteUpdate.disconnect()
			self.theUpdateChecker.sigDstarted.disconnect()
		if exitCode == 0:
			self._theMainWindow.theUpdate.theUpdateProgress.btnExit.setEnabled(True)
		if exitCode == 299: # abnormalTermination
			if self._theMainWindow.theUpdate.theUpdateProgress.isVisible():
				self._theMainWindow.theUpdate.theUpdateProgress.hide

		###	 cleanup code, always runs	###
		if hasattr(self, 'theUpdateChecker'):
			print("here 1")
			self.theUpdateChecker.exit()
			while self.theUpdateChecker.isRunning():
				print("here 2")
				self.theUpdateChecker.exit()
				QApplication.processEvents()
		if hasattr(self, 'theUpdateChecker'):
			del self.theUpdateChecker
		if hasattr(self, 'theUpdater'):
			while self.theUpdater.isRunning():
				print("now waiting updater...")
				self.theUpdater.exit()
				QApplication.processEvents()
		if hasattr(self, 'theUpdater'):
			print("trying to delete the updater")
			del self.theUpdater
			#if self._theMainWindow.theUpdate.theUpdateProgress.isVisible():
			#print("set it")
		gc.collect()

###################################################### Update Settings ##############################################
	
	#@QtCore.Slot()
	def setUpdateSettings(self):
		self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyMode.currentIndexChanged.connect(self.updateProxyModeSettings)			
		self._theMainWindow.theUpdate.theUpdateSettings.chkUseLogin.stateChanged.connect(self.updateProxyModeSettings)			
		self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyAuthType.currentIndexChanged.connect(self.updateProxyModeSettings)
		if self.sender().objectName() == "btnUpdateSet":
			self.getSettings()
			print("getting settings")
			if self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyMode.currentIndex() == 0:
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyName.setEnabled(False)
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyPort.setEnabled(False)
				if (self._theMainWindow.theUpdate.theUpdateSettings.chkUseLogin.isEnabled()):
					self._theMainWindow.theUpdate.theUpdateSettings.chkUseLogin.setEnabled(False)
				self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyAuthType.setEnabled(False)
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyUsername.setEnabled(False)
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyPass.setEnabled(False)
			self._theMainWindow.theUpdate.theUpdateSettings.show()
		elif self.sender().objectName() == "btnOK":
			try:
				print("test")
				self.setSettings()
				self._theMainWindow.theUpdate.theUpdateSettings.close()
			except Exception as err:
				raise err
		elif self.sender().objectName() == "btnCancel":
			self._theMainWindow.theUpdate.theUpdateSettings.close()

	def updateProxyModeSettings(self):
		if (str(self.sender().objectName())) == "cmbBoxProxyMode":
			print("sender was cmbBoxProxyMode")
			if self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyMode.currentIndex() == 0:
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyName.setEnabled(False)
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyPort.setEnabled(False)
				if (self._theMainWindow.theUpdate.theUpdateSettings.chkUseLogin.isEnabled()):
					self._theMainWindow.theUpdate.theUpdateSettings.chkUseLogin.setEnabled(False)
				self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyAuthType.setEnabled(False)
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyUsername.setEnabled(False)
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyPass.setEnabled(False)
			else:
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyName.setEnabled(True)
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyPort.setEnabled(True)
				self._theMainWindow.theUpdate.theUpdateSettings.chkUseLogin.setEnabled(True)
				if	self._theMainWindow.theUpdate.theUpdateSettings.chkUseLogin.isChecked():
					self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyAuthType.setEnabled(True)
					self._theMainWindow.theUpdate.theUpdateSettings.leditProxyUsername.setEnabled(True)
					self._theMainWindow.theUpdate.theUpdateSettings.leditProxyPass.setEnabled(True)
		elif (str(self.sender().objectName())) == "chkUseLogin":
			if self._theMainWindow.theUpdate.theUpdateSettings.chkUseLogin.isChecked():
				self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyAuthType.setEnabled(True)
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyUsername.setEnabled(True)
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyPass.setEnabled(True)
			else:
				self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyAuthType.setEnabled(False)
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyUsername.setEnabled(False)
				self._theMainWindow.theUpdate.theUpdateSettings.leditProxyPass.setEnabled(False)

	def showStatus(self):
		# !!!! NOT PORTABLE !!!! #
		statusList = subprocess.check_output(["avgctl", "--stat-all"]).decode("utf").split('\n')
		
			
		avgVersion = statusList[5].split()[-1]
		self._theMainWindow.theCurrentStatus.lblAVGtitle.setStyleSheet("QLabel { font-weight : bold; }");
		self._theMainWindow.theCurrentStatus.lblAVGvalue.setText(avgVersion)
		
		if ("-" not in statusList[8]): # checking if at least one update has taken place
			lastUpdate = statusList[8].split()[4] + "/" + statusList[8].split()[5] + "/" + statusList[8].split()[6] + ", " + statusList[8].split()[7]
			self._theMainWindow.theCurrentStatus.lblLastUpdateTitle.setStyleSheet("QLabel { font-weight : bold; }");
			self._theMainWindow.theCurrentStatus.lblLastUpdateValue.setText(lastUpdate)
		
		licence = statusList[11].split()[-1]
		licenceNo = statusList[12].split()[-1]
		self._theMainWindow.theCurrentStatus.lblLicenceTitle.setStyleSheet("QLabel { font-weight : bold; }");
		self._theMainWindow.theCurrentStatus.lblLicenceValue.setText(licence + " / " + licenceNo)
		
		aviVersion = statusList[45].split()[-1]
		self._theMainWindow.theCurrentStatus.lblDatabaseTitle.setStyleSheet("QLabel { font-weight : bold; }");
		self._theMainWindow.theCurrentStatus.lblDatabaseValue.setText(aviVersion)
		
		aviDate = statusList[46].split()[6] + "/" + statusList[46].split()[7] + "/" + statusList[46].split()[8] + ", " + statusList[46].split()[9]
		self._theMainWindow.theCurrentStatus.lblDBDateTitle.setStyleSheet("QLabel { font-weight : bold; }");
		self._theMainWindow.theCurrentStatus.lblDBDateValue.setText(aviDate)
		
		oadStatus1 = statusList[21].split('\t')[2]
		self._theMainWindow.theCurrentStatus.lblOADTitle.setStyleSheet("QLabel { font-weight : bold; }");
		if oadStatus1 == "running":
			self._theMainWindow.theCurrentStatus.lblOADValue.setStyleSheet("QLabel { color : green; }");
			oadStatus = langmodule.genericON
			# perhaps add background color
		else:
			self._theMainWindow.theCurrentStatus.lblOADValue.setStyleSheet("QLabel { color : red; }");
			oadStatus = langmodule.genericOFF
		self._theMainWindow.theCurrentStatus.lblOADValue.setText(oadStatus)
		
		schedStatus1 = statusList[22].split('\t')[2]
		self._theMainWindow.theCurrentStatus.lblSchedTitle.setStyleSheet("QLabel { font-weight : bold; }");
		if schedStatus1 == "running":
			self._theMainWindow.theCurrentStatus.lblSchedValue.setStyleSheet("QLabel { color : green; }");
			schedStatus = langmodule.genericON
			# perhaps add background color
		else:
			self._theMainWindow.theCurrentStatus.lblSchedValue.setStyleSheet("QLabel { color : red; }");
			schedStatus = langmodule.genericOFF
		self._theMainWindow.theCurrentStatus.lblSchedValue.setText(schedStatus)

		if ("-" not in statusList[29]): # checking if at least one virus update has taken place
			lastVirUpdate = statusList[29].split()[3] + "/" + statusList[29].split()[4] + "/" + statusList[29].split()[5] + ", " + statusList[29].split()[6]
			self._theMainWindow.theCurrentStatus.lblNextVUpdateTitle.setStyleSheet("QLabel { font-weight : bold; }");
			self._theMainWindow.theCurrentStatus.lblNextVUpdateValue.setText(lastVirUpdate)
		else: 
			self._theMainWindow.theCurrentStatus.lblNextVUpdateValue.setText(" ")
		
		if ("-" not in statusList[30]): # checking if at least one program update has taken place
			lastProgUpdate = statusList[30].split()[3] + "/" + statusList[30].split()[4] + "/" + statusList[30].split()[5] + ", " + statusList[30].split()[6]
			self._theMainWindow.theCurrentStatus.lblNextPUpdateTitle.setStyleSheet("QLabel { font-weight : bold; }");
			self._theMainWindow.theCurrentStatus.lblNextPUpdateValue.setText(lastProgUpdate)
		else:
			self._theMainWindow.theCurrentStatus.lblNextPUpdateTitle.setStyleSheet("QLabel { font-weight : bold; }");
			self._theMainWindow.theCurrentStatus.lblNextPUpdateValue.setText(" ")
		
		self._theMainWindow.theCurrentStatus.show()

	def getSettings(self):
		# Automatic Program Update
		self.autoProgUpdateOut = subprocess.check_output(["avgcfgctl", "UpdateProgram.sched.Task.Disabled"])
		self.tmp_autoProgUpdate = self.autoProgUpdateOut.decode("utf").rstrip().split("=",1)[-1].capitalize()
		if self.tmp_autoProgUpdate == "False":
			self.autoProgUpdate = True
		else:
			self.autoProgUpdate = False
		self._theMainWindow.theUpdate.theUpdateSettings.chkAutoUpdateProg.setChecked(self.autoProgUpdate)
		# Automatic Virus Database Update
		self.autoVirUpdateOut = subprocess.check_output(["avgcfgctl", "UpdateVir.sched.Task.Disabled"])
		self.tmp_autoVirUpdate = self.autoVirUpdateOut.decode("utf").rstrip().split("=",1)[-1].capitalize()
		if self.tmp_autoVirUpdate == "False":
			self.autoVirUpdate = True
		else:
			self.autoVirUpdate = False
		self._theMainWindow.theUpdate.theUpdateSettings.chkAutoUpdateVir.setChecked(self.autoVirUpdate)
		# Minimum Speed 
		self.minSpeedOut = subprocess.check_output(["avgcfgctl", "Default.update.Inet.disconnect_speed_limit"])
		self.minSpeed = int(str(self.minSpeedOut.decode("utf")).split("=",1)[-1])
		self._theMainWindow.theUpdate.theUpdateSettings.leditMinSpeed.setText(str(self.minSpeed))
		# Maximum Time
		self.maxTimeOut = subprocess.check_output(["avgcfgctl", "Default.update.Inet.disconnect_time_limit"])
		self.maxTime = int(str(self.maxTimeOut.decode("utf")).split("=",1)[-1])
		self._theMainWindow.theUpdate.theUpdateSettings.leditMaxTime.setText(str(self.maxTime))
		# Proxy Name
		self.proxyNameOut = subprocess.check_output(["avgcfgctl", "Default.update.Options.Proxy.Server"])
		self.proxyName = str(self.proxyNameOut.decode("utf")).split("=",1)[-1]
		self._theMainWindow.theUpdate.theUpdateSettings.leditProxyName.setText(str(self.proxyName))
		# Proxy Username
		self.proxyUsernameOut = subprocess.check_output(["avgcfgctl", "Default.update.Options.Proxy.Login"])
		self.proxyUsername = str(self.proxyUsernameOut.decode("utf")).split("=",1)[-1]
		self._theMainWindow.theUpdate.theUpdateSettings.leditProxyUsername.setText(str(self.proxyUsername))
		# Proxy Password
		self.proxyPassOut = subprocess.check_output(["avgcfgctl", "Default.update.Options.Proxy.Password"])
		self.proxyPass = str(self.proxyPassOut.decode("utf")).split("=",1)[-1]
		self._theMainWindow.theUpdate.theUpdateSettings.leditProxyPass.setText(str(self.proxyPass))
		# Proxy Port
		self.proxyPortOut = subprocess.check_output(["avgcfgctl", "Default.update.Options.Proxy.Port"])
		self.proxyPort = int(str(self.proxyPortOut.decode("utf")).split("=",1)[-1])
		self._theMainWindow.theUpdate.theUpdateSettings.leditProxyPort.setText(str(self.proxyPort))
		# Proxy Set up
		self.proxyModeOut = subprocess.check_output(["avgcfgctl", "Default.update.Options.Proxy.Mode"])
		self.proxyMode = int(str(self.proxyModeOut.decode("utf")).split("=",1)[-1])
		self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyMode.setCurrentIndex(self.proxyMode)
		# Proxy Auth Type
		self.proxyAuthTypeOut = subprocess.check_output(["avgcfgctl", "Default.update.Options.Proxy.AuthenticationType"])
		self.proxyAuthType = int(str(self.proxyModeOut.decode("utf")).split("=",1)[-1])
		self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyAuthType.setCurrentIndex(self.proxyAuthType)
		# Proxy Log In Required
		self.proxyLoginRequiredOut = subprocess.check_output(["avgcfgctl", "Default.update.Options.Proxy.UseLogin"])
		self.tmp_proxyLoginRequired = self.proxyLoginRequiredOut.decode("utf").rstrip().split("=",1)[-1].capitalize()
		if self.tmp_proxyLoginRequired == 'False':
			self.proxyLoginRequired = False
		else:
			self.proxyLoginRequired = True
		self._theMainWindow.theUpdate.theUpdateSettings.chkUseLogin.setChecked(self.proxyLoginRequired)

	def setSettings(self):
		self.command = ""
		# Automatic Program Update
		self.newAutoProgUpdate = self._theMainWindow.theUpdate.theUpdateSettings.chkAutoUpdateProg.isChecked()
		if (self.newAutoProgUpdate != self.autoProgUpdate):
			self.command = self.command + " UpdateProgram.sched.Task.Disabled=" + str(not self.newAutoProgUpdate)
		# Automatic Virus Database Update
		self.newAutoVirUpdate = self._theMainWindow.theUpdate.theUpdateSettings.chkAutoUpdateVir.isChecked()
		if (self.newAutoVirUpdate != self.autoVirUpdate):
			self.command = self.command + " UpdateVir.sched.Task.Disabled=" + str(not self.newAutoVirUpdate)		
		# Minimum Speed
		self.newMinSpeed = int(self._theMainWindow.theUpdate.theUpdateSettings.leditMinSpeed.text())
		if (self.newMinSpeed != self.minSpeed):
			self.command = self.command + "Default.update.Inet.disconnect_speed_limit=" + str(self.newMinSpeed)
		# Maximum Time
		self.newMaxTime = int(self._theMainWindow.theUpdate.theUpdateSettings.leditMaxTime.text())
		if (self.newMaxTime != self.maxTime):
			self.command = self.command + " Default.update.Inet.disconnect_time_limit=" + str(self.newMaxTime)
		# Proxy Name
		self.newProxyName = self._theMainWindow.theUpdate.theUpdateSettings.leditProxyName.text()
		if (self.newProxyName != self.proxyName):
			self.command = self.command + " Default.update.Options.Proxy.Server="+self.newProxyName.replace(" ", "")
		# Proxy Username
		self.newProxyUsername = self._theMainWindow.theUpdate.theUpdateSettings.leditProxyUsername.text()
		if (self.newProxyUsername != self.proxyUsername):
			self.command = self.command + " Default.update.Options.Proxy.Login="******" Default.update.Options.Proxy.Password="******" Default.update.Options.Proxy.Port=" + str(self.newProxyPort)
		# Proxy Set up
		self.newProxyMode = int(self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyMode.currentIndex())
		if (self.newProxyMode != self.proxyMode):
			self.command = self.command + " Default.update.Options.Proxy.Mode=" + str(self.newProxyMode)
		# Proxy Auth Type
		self.newProxyAuthType = int(self._theMainWindow.theUpdate.theUpdateSettings.cmbBoxProxyAuthType.currentIndex())
		if (self.newProxyAuthType != self.proxyAuthType):
			self.command = self.command + " Default.update.Options.Proxy.AuthenticationType=" + str(self.newProxyAuthType)
		# Proxy Log in Required
		self.newProxyLoginRequired = self._theMainWindow.theUpdate.theUpdateSettings.chkUseLogin.isChecked()
		print(self.newProxyLoginRequired)
		print(self.proxyLoginRequired)
		if (self.newProxyLoginRequired != self.proxyLoginRequired):
			self.command = self.command + " Default.update.Options.Proxy.UseLogin="******"command is: " + self.command)
		self.command = " ".join(self.command.split()) 
		print("new command is: " + self.command)
		if self.command != "":
			try:
				subprocess.call(["gksu", "avgcfgctl -w " + self.command])
			except Exception as err:
				print("Error setting new update settings")
				raise err
Exemple #7
0
class SyncThread(QThread, SyncAgent):
    """Sync notes with evernote thread"""
    force_sync_signal = Signal()
    sync_state_changed = Signal(int)
    data_changed = Signal()

    def __init__(self, *args, **kwargs):
        QThread.__init__(self, *args, **kwargs)
        self.app = AppClass.instance()
        self.status = STATUS_NONE
        self.last_sync = datetime.now()
        self.update_count = 0
        self.timer = QTimer()
        self.timer.timeout.connect(self.sync)
        self.update_timer()
        self.wait_condition = QWaitCondition()
        self.mutex = QMutex()

    def update_timer(self):
        self.timer.stop()
        delay = int(self.app.settings.value('sync_delay')
                    or 0) or DEFAULT_SYNC_DELAY
        if delay != SYNC_MANUAL:
            self.timer.start(delay)

    def run(self):
        self.init_db()
        self.init_network()
        while True:
            self.mutex.lock()
            self.wait_condition.wait(self.mutex)
            self.perform()
            self.mutex.unlock()
            time.sleep(1)  # prevent cpu eating

    def init_db(self):
        self.session = get_db_session()
        self.sq = self.session.query

    def init_network(self):
        while True:
            try:
                self.auth_token = get_auth_token()
                self.note_store = get_note_store(self.auth_token)
                break
            except socket.error:
                time.sleep(30)

    def force_sync(self):
        self.timer.stop()
        self.sync()
        self.update_timer()

    @Slot()
    def sync(self):
        self.wait_condition.wakeAll()

    def perform(self):
        """Perform all sync"""
        self.status = STATUS_SYNC
        self.last_sync = datetime.now()
        self.sync_state_changed.emit(SYNC_STATE_START)
        if self._need_to_update():
            self.need_to_update = True
            self.all_notes = list(self._iter_all_notes())
        try:
            if self.need_to_update:
                self.remote_changes()
            self.local_changes()
            self.sharing_changes()
        except Exception, e:  # maybe log this
            self.session.rollback()
            self.init_db()
            self.app.log(e)
        finally:
Exemple #8
0
class PusThread(QThread):
    """
    This class overrides a QThread object to be able to
    define custom safe threads with custom signals. This
    class is used to be able to make a simulation of a connection
    with the robot where the packets arrives with an interval
    between them without blocking the rest of the functionality
    of the application. The simulation is done by reading the
    packets from a json file.

    """
    def __init__(self, controller, model):
        """
        This is the constructor of the class
        :param file: The json file where the packets are defined
        :param model: The model of the application
        """
        QThread.__init__(self)
        self.model = model
        self.controller = controller
        self.add_table_signal = AddTableSignal()
        self.add_table_signal.signal.connect(self.model.add)
        self.filter_table_signal = AddTableSignal()
        self.filter_table_signal.signal.connect(
            self.controller.open_filter_callback)
        self.json_file = None
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_packets)
        self.json_file_loaded = QWaitCondition()
        self.mutex = QMutex()

    def run(self):
        """
        This method runs the thread reading from
        the json defined and making an sleep of T
        seconds between packet and packet according
        to the interval defined in the json file.
        """

        self.timer.start(1000)

        while True:
            self.mutex.lock()
            self.json_file_loaded.wait(self.mutex)
            file = self.json_file
            self.mutex.unlock()

            pt = PacketTranslator()
            mt = MakoTranslate()
            if file is not None:
                with open(file) as jfile:
                    jsondata = mt.replace(jfile.read())
                    activities = json.loads(jsondata)[TestTags.ACTIVITIES_TAG]
                    for activity in activities:
                        interval = activity[TestTags.INTERVAL_TAG]
                        self.sleep(interval)
                        if TestTags.PACKET_TAG in activity:
                            packet = pt.json2packet(
                                activity[TestTags.PACKET_TAG])
                            pb.pus_notify_sendPacket(packet)
                            self.add_table_signal.throw(packet)
                        elif TestTags.ACTIONS_TAG in activity:
                            if activity[TestTags.
                                        ACTIONS_TAG] == TestTags.SAVEDB_TAG:
                                file = activity[TestTags.PARAMS_TAG]

                                d = Database(file)
                                d.create_dump_table()
                                packages = [
                                    tuple(e[1:-1]) for e in self.model.table
                                ]

                                d.insert_db(
                                    "INSERT INTO packages VALUES(?,?,?,?,?,?,?,?,?,?)",
                                    packages)

                            elif activity[
                                    TestTags.
                                    ACTIONS_TAG] == TestTags.SETFILTER_TAG:
                                filter_ = FilterModel()
                                type_ = activity[TestTags.PARAMS_TAG]["type"]
                                svc = activity[TestTags.PARAMS_TAG]["svc"]
                                msg = activity[TestTags.PARAMS_TAG]["msg"]
                                filter_.set_filter_options(type_, svc, msg)
                                filter_index = self.model.set_filter(
                                    filter_.get_filter_options())
                                self.filter_table_signal.throw(filter_index)
            self.mutex.lock()
            self.json_file = None
            self.mutex.unlock()

    def update_packets(self):
        for _ in range(10):
            packet = pb.pusPacket_t()
            if pb.pusError_t.PUS_NO_ERROR == pb.pus_notify_readTm(
                    packet):  # Comprobar si null
                self.add_table_signal.throw(packet)

    def load_test(self, json_file):
        self.mutex.lock()
        self.json_file = json_file
        if json_file is not None:
            self.json_file_loaded.wakeAll()
        self.mutex.unlock()
Exemple #9
0
class Buffer(QObject):
    """
    Class buffers annotation objects to cache from database for given frame or frame interval.
    :param video: reference to video object
    :type video: tovian.models.entity.Video
    :param parent: parent widget
    :type parent: PySide.QtCore.QObject
    """

    checkBufferState = Signal()
    buffering = Signal()
    buffered = Signal()
    initialized = Signal()

    MAX_MEMORY_USAGE = 52428800  # 50MB

    def __init__(self, video, user_id, parent=None):
        super(Buffer, self).__init__(parent)
        self.mutex = QMutex()
        self.video = video
        self.last_frame_accessed = (0, 0)
        self.displayed_frames_range = 1  # must be odd
        self.video_frame_count = self.video.frame_count
        self.video_frame_fps = self.video.fps
        self.user_id = user_id

        self.cache = {}
        self.cached_min_frame = 0
        self.cached_max_frame = 0
        self.cached_time = 10  # seconds
        self.cached_time_border = 0.25  # 25 percent from cached interval, where it starts to buffer new objects

        self.checkBufferState.connect(self.__checkBuffer)

    def initBuffer(self):
        """
        Called just first time after initializing buffed and moving to separated thread.
        """
        new_start = 0
        new_stop = int(self.cached_time * self.video_frame_fps)
        new_stop = new_stop if new_stop < self.video_frame_count else self.video_frame_count

        logger.debug("Filling buffer on interval [%s, %s]", new_start,
                     new_stop)
        self.__bufferObjects(new_start, new_stop)
        self.initialized.emit()

    def setDisplayedFrameRange(self, length):
        """
        Sets how long frame interval is displayed (non-vis annotations).
        i.e. 11 meas [currentframe-5, currentframe+5]
        :param length: range length
        :type length: int
        """
        logger.debug("Setting new displayed range value %s", length)
        self.mutex.lock()
        self.displayed_frames_range = length
        self.mutex.unlock()

    def getObjectsInFrame(self, frame):
        """
        Returns list of annotation objects for given frame. When accessing to cache, cached is locked for other access.
        :type frame: int
        :rtype: tuple of (tovian.models.entity.AnnotationObject, int, int)
        :raise AttributeError: if given frame number is out of range [0, video.frame_count]
        """
        logger.debug("Called get an_object from buffer for frame: %s", frame)

        if frame < 0 or frame > self.video_frame_count:
            raise AttributeError(
                "Given frame number %s is out of range [0, %s]" %
                (frame, self.video_frame_count))

        # --- locked ----
        self.mutex.lock()
        try:
            objects = self.cache[frame]
        except KeyError:
            logger.error("Buffer objects could not be found for frame: %s",
                         frame)
            models.repository.logs.insert(
                'gui.exception.get_obj_from_buffer_error',
                "Buffer objects could not be found for frame: %s" % frame,
                annotator_id=self.user_id)
            objects = self.video.annotation_objects_in_frame(frame)
        else:
            objects = objects.values()

        finally:
            self.last_frame_accessed = (frame, frame)
            self.mutex.unlock()  # don't forget to release lock
        # ---------------

        self.checkBufferState.emit()
        return tuple(objects)

    def getObjectsInFrameInterval(self, frame_from, frame_to):
        """
        Returns list of annotation objects for given frame interval.
        :type frame_from: int
        :type frame_to: int
        :rtype: tuple of (tovian.models.entity.AnnotationObject, int, int)
        :raise AttributeError: if given frame number interval is not in range [0, video.frame_count] or is invalid
        """
        logger.debug(
            "Called get an_object from buffer for frame interval [%s, %s]",
            frame_from, frame_to)

        if frame_from > frame_to:
            raise AttributeError(
                "frame_from '%s' is greater than frame_to '%s'" %
                (frame_from, frame_to))

        if frame_from < 0 or frame_to < 0 or frame_to > self.video_frame_count or frame_from > self.video_frame_count:
            raise AttributeError(
                "Given frame interval [%s, %s] is out of range [0, %s]" %
                (frame_from, frame_to, self.video_frame_count))

        if frame_from == frame_to:
            objects = self.getObjectsInFrame(frame_from)
            return objects

        objects = []
        self.mutex.lock()
        try:
            for frame in range(frame_from, frame_to + 1):
                try:
                    data = self.cache[frame]
                except KeyError:
                    logger.error(
                        "Buffer objects could not be found for frame: %s",
                        frame)
                    models.repository.logs.insert(
                        'gui.exception.get_obj_from_buffer_error',
                        "Buffer objects could not be found for frame: %s" %
                        frame,
                        annotator_id=self.user_id)
                    data = self.video.annotation_objects_in_frame(frame)
                else:
                    data = data.values()

                objects.extend(data)  # converts iterator to values
        finally:
            self.last_frame_accessed = (frame_from, frame_from)
            self.mutex.unlock()

        self.checkBufferState.emit()
        return tuple(set(objects))

    def resetBuffer(self, frame, clear_all=False, clear_object=None):
        """
        Reset buffer - loads new objects depending on given frame number (i.e. when seeking to new frame).
        Method requests lock when clearing cache!
        :param frame: target frame
        :type frame: int
        :param clear_all: manually clears buffer
        :type clear_all: bool
        :param clear_object:  object that has to be refreshed in buffer (object_id, old_start_frame, old_end_frame)
        :raise ValueError: if given frame number is out of range [0, video.frame_count] |
        when new min and max cached frame are equaled or invalid
        """
        #logger.debug("Locking thread")
        #self.mutex.lock()
        #self.last_frame_accessed = (min_frame_interval, max_frame_interval)
        #self.mutex.unlock()
        #logger.debug("Thread unlocked")

        if frame < 0 or frame > self.video_frame_count:
            raise ValueError("Given frame number %s is out of range [0, %s]" %
                             (frame, self.video_frame_count))

        if not clear_all and not clear_object:
            # if new frame has been already cached
            if frame in self.cache:
                min_frame = frame - ((self.displayed_frames_range - 1) / 2.0)
                max_frame = frame + ((self.displayed_frames_range - 1) / 2.0)

                min_frame = 0 if min_frame < 0 else min_frame
                max_frame = self.video_frame_count if max_frame > self.video_frame_count else max_frame

                # if new frame display frame range is also cached
                if self.cached_min_frame <= min_frame and self.cached_max_frame >= max_frame:
                    logger.debug(
                        "New frame and displayed frame interval is cached and no need to reset"
                    )
                    return
                else:
                    logger.debug(
                        "Target frame is cached, but displayed frame range isn't."
                    )
            else:
                logger.debug("Target frame is not cached.")
        # calculate new start_frame and stop_frame
        new_start_frame = frame - int(
            (self.cached_time / 2.0) * self.video_frame_fps)
        new_stop_frame = frame + int(
            (self.cached_time / 2.0) * self.video_frame_fps)
        new_start_frame = 0 if new_start_frame < 0 else new_start_frame
        new_stop_frame = self.video_frame_count if new_stop_frame > self.video_frame_count else new_stop_frame

        if new_stop_frame == new_start_frame or new_stop_frame < new_start_frame:
            logger.error(
                "New start_frame '%s' and stop_frame '%s' are equal or invalid.",
                new_start_frame, new_stop_frame)
            raise ValueError(
                "New start_frame '%s' and stop_frame '%s' are equal or invalid."
                % (new_start_frame, new_stop_frame))

        if clear_object:
            object_id, old_start, old_end = clear_object

            logger.debug("Deleting old object data from cache")
            self.mutex.lock()
            for i in range(old_start, old_end + 1):
                cache_data = self.cache[i]
                del cache_data[object_id]
            self.mutex.unlock()
            logger.debug("Thread unlocked")

            ## TODO DELETE !!!!!!!!!!!!!!!!!!!!!!!! FOR DEBUGGING PURPOSES
            #for key, value in self.cache.iteritems():
            #    if object_id in value:
            #        print key, value
            #        raise Exception()

            logger.debug(
                "Clearing object id '%s' from buffer and resetting for new frame: %s",
                object_id, frame)
            self.__bufferObjectByID(frame, object_id)

        else:
            logger.debug(
                "Resetting and clearing whole buffer for new frame: %s", frame)

            self.mutex.lock()
            self.cache = {}
            self.mutex.unlock()
            self.__bufferObjects(new_start_frame,
                                 new_stop_frame)  # manually invoked buffering

    def __bufferObjects(self, frame_from, frame_to):
        """
        Called to buffer new objects from database for given frame interval.
        Method requests lock when writing to cache!
        :type frame_from: int
        :type frame_to: int
        :raise ValueError: When frame_from or frame_to has invalid value (out of range, etc.)
        """
        logger.debug("Tries buffer new frame interval [%s, %s]...", frame_from,
                     frame_to)
        if frame_from > frame_to or frame_from < 0 or frame_to > self.video_frame_count:
            raise ValueError(
                "Invalid frame_from '%s' and frame_to values '%s'", frame_from,
                frame_to)

        self.mutex.lock()
        try:
            objectsTuples = self.video.annotation_objects_in_frame_intervals([
                (frame_from, frame_to)
            ])
        except Exception:
            # TODO display error to user
            logger.exception(
                "Error when buffering new objects from database on interval [%s, %s]",
                frame_from, frame_to)
            models.repository.logs.insert(
                'gui.exception.buffering_new_obj_error',
                "Error when buffering new objects from database on interval [%s, %s]"
                % (frame_from, frame_to),
                annotator_id=self.user_id)
            self.mutex.unlock()  # don't forget to release lock
            return

        cleared = not self.cache
        self.buffering.emit()

        #logger.debug("Locking thread -> adding new data to cache")
        #self.mutex.lock()               # request lock
        try:
            for frame in range(frame_from, frame_to + 1):
                try:
                    frame_dict = self.cache[frame]
                except KeyError:
                    self.cache[frame] = {}
                    frame_dict = self.cache[frame]

                # add record to cache
                for objectTuple in objectsTuples:
                    an_object, start_frame, end_frame = objectTuple
                    if start_frame <= frame <= end_frame:
                        frame_dict[an_object.id] = objectTuple

            # if cache has been cleared when method called, set min and max pointers as usually
            if cleared:
                self.cached_max_frame = frame_to
                self.cached_min_frame = frame_from

            # if don't, cache has been extended, so moves pointer a bit
            else:
                if frame_from < self.cached_min_frame:
                    self.cached_min_frame = frame_from
                if frame_to > self.cached_max_frame:
                    self.cached_max_frame = frame_to

        finally:
            self.mutex.unlock()  # don't forget to release lock

        self.buffered.emit()
        logger.debug("Buffered new time interval [%s, %s]", frame_from,
                     frame_to)

    def __bufferObjectByID(self, target_frame, object_id):
        """
        Buffer new object by given ID from database on given frame
        :type target_frame: int
        :type object_id: int
        :raise ValueError: When frame is out of range
        """
        logger.debug("Trying to buffer new object id '%s' on frame '%s'",
                     object_id, target_frame)
        if target_frame < 0 or target_frame > self.video_frame_count:
            raise ValueError(
                "Given frame number is out of video frame count range")

        try:
            objectTuples = self.video.annotation_objects_in_frame_intervals(
                [(target_frame, target_frame)], [
                    object_id,
                ])
        except Exception:
            # TODO display error to user
            logger.exception(
                "Error when buffering new object id '%s' from database on on frame '%s'",
                object_id, target_frame)
            models.repository.logs.insert(
                'gui.exception.buffering_new_obj_error',
                "Error when buffering new object id '%s' from database on on frame '%s'"
                % (object_id, target_frame),
                annotator_id=self.user_id)
            return

        if not objectTuples:
            logger.warning("No object id '%s' for frame '%s' in database!")
            return
        elif len(objectTuples) > 1:
            logger.warning(
                "Returned more than one object by id from database!")

        self.buffering.emit()

        logger.debug("Locking thread -> adding to cache new data")
        self.mutex.lock()
        try:
            an_object, start_frame, end_frame = objectTuples[0]

            for frame in range(start_frame, end_frame + 1):
                try:
                    frame_dict = self.cache[frame]
                except KeyError:
                    self.cache[frame] = {}
                    frame_dict = self.cache[frame]

                frame_dict[an_object.id] = objectTuples[0]

        finally:
            self.mutex.unlock()
            logger.debug("Thread unlocked")

        self.buffered.emit()
        logger.debug("Buffered new by id '%s' on frame '%s'", object_id,
                     target_frame)

    @Slot()
    def __checkBuffer(self):
        """
        Method called when some data in cache has been accessed to check,
        if needs to be loaded new objects from database.
        """
        memory_usage = sys.getsizeof(self.cache)

        if memory_usage > self.MAX_MEMORY_USAGE:
            logger.warning(
                "Reached maximum allowed memory usage '%s' bytes -> resetting buffer",
                self.MAX_MEMORY_USAGE)
            lower_accessed_frame, higher_accessed_frame = self.last_frame_accessed
            if lower_accessed_frame == higher_accessed_frame:
                frame = higher_accessed_frame
            else:
                frame = ((higher_accessed_frame - lower_accessed_frame) /
                         2) + lower_accessed_frame

            self.resetBuffer(frame, clear_all=True)
            return

        cached_min_border = self.cached_min_frame - self.last_frame_accessed[0]
        cached_max_border = self.cached_max_frame - self.last_frame_accessed[1]
        allowed_border = self.cached_time_border * self.cached_time * self.video_frame_fps

        # ----
        # If the last_accessed_frame pointer is between borders (typically between 25% and 75% cache), do nothing.
        # else cache new interval and merge cached data
        # i.e. cache status  =   |bottom|--------------0current0--|top|   => max border passed, cache new objects =>
        #      => new status =   |bottom|--------------0current0--(-----------------------------)|top|
        # ----

        # bottom border
        if cached_min_border > -allowed_border:
            new_stop = self.cached_min_frame - 1
            new_start = new_stop - int(self.cached_time * self.video_frame_fps)

            new_start = 0 if new_start < 0 else new_start
            new_start = self.video_frame_count if new_start > self.video_frame_count else new_start
            new_stop = 0 if new_stop < 0 else new_stop
            new_stop = self.video_frame_count if new_stop > self.video_frame_count else new_stop

            if new_start != new_stop:
                logger.debug(
                    "Check buffer - buffer needs to load new objects, direction down"
                )

                self.__bufferObjects(new_start, new_stop)

        # upper border
        elif cached_max_border < allowed_border:
            new_start = self.cached_max_frame + 1
            new_stop = new_start + int(self.cached_time * self.video_frame_fps)

            new_start = 0 if new_start < 0 else new_start
            new_start = self.video_frame_count if new_start > self.video_frame_count else new_start
            new_stop = 0 if new_stop < 0 else new_stop
            new_stop = self.video_frame_count if new_stop > self.video_frame_count else new_stop

            if new_start != new_stop:
                logger.debug(
                    "Check buffer - buffer needs to load new objects, direction up"
                )

                self.__bufferObjects(new_start, new_stop)

        else:
            logger.debug("Check buffer - status OK")

    @staticmethod
    def bufferFinished():
        """
        Called when buffer thread is finished (closed).
        """
        logger.debug("Buffer thread closed.")

    @staticmethod
    def bufferTerminated():
        """
        Called when buffer thread is terminated (forced to close).
        """
        logger.warning("Buffer thread terminated!")
class AsyncResolver(QThread):

    object_resolved = QtCore.Signal('object_resolved(QVariant)')

    def __init__(self):
        super(AsyncResolver, self).__init__()
        self._task_queue = []
        self._mutex = QMutex()
        self._semaphore = QSemaphore()
        self.working = False

    def synchronized(f):
        def wrap(self, *args, **kwargs):
            self._mutex.lock()
            try:
                return f(self, *args, **kwargs)
            finally:
                self._mutex.unlock()
        return wrap

    def add_task(self, dn):
        self._task_queue.append(dn)
        #print self._semaphore.available()
        self._semaphore.release()
        #print 'before release'

    @synchronized
    def _append_task(self, task):
        self._task_queue.append(task)

    @synchronized
    def _pop_task(self, task):
        return self._task_queue.pop()

    def consume_task(self):
        #print self._semaphore.available()
        self._semaphore.acquire()
        #print 'after acq'
        obj = self._task_queue.pop()
        return obj

    def stop_work(self):
        self.working = False
        if self._task_queue:
            self._append_task(None)
        self._semaphore.release()

    @synchronized
    def _do_task(self, task):
        return task()

    def run(self):
        self.working = True
        while self.working:
            task = self.consume_task()
            if task:
                try:
                    obj = self._do_task(task)
                except UcsmError:
                    pass
                else:
                    self.emit(SIGNAL('object_resolved(QVariant)'), obj)
            else:
                break