Beispiel #1
0
    def __init__(self, inp_host, inp_port):
        super().__init__()

        self.lock = QReadWriteLock()

        self.recordSignal = RecordSignal()
        self.recordSignal.sendSignal.connect(self.my_record)

        self.tcpServer = TcpServer(self.recordSignal, self.lock)
        if not self.tcpServer.listen(QHostAddress(inp_host), inp_port):
            QMessageBox.critical(
                self, '交易服务器',
                '服务器启动失败:{0}'.format(self.tcpServer.errorString()))
            rec_text = my_cur_time() + ' 服务器启动失败!'
            try:
                self.lock.lockForWrite()
                self.recordSignal.sendSignal.emit(rec_text)
            finally:
                self.lock.unlock()
            self.close()
            return
        else:
            self._initUI()
            rec_text = my_cur_time() + ' 开启交易服务器!'
            try:
                self.lock.lockForWrite()
                self.recordSignal.sendSignal.emit(rec_text)
            finally:
                self.lock.unlock()
Beispiel #2
0
 def __init__(self, device: NexDevice, poll_interval_ms: int):
     super().__init__()
     self._device = device
     self._logger = logging.getLogger("pynextion.NexEventPoller")
     self._run_poll_loop = True
     self._run_poll_loop_lock = QReadWriteLock()
     self._thread_local = threading.local()
     self._poll_interval_ms = poll_interval_ms
Beispiel #3
0
class NexEventPoller(QRunnable):
    def __init__(self, device: NexDevice, poll_interval_ms: int):
        super().__init__()
        self._device = device
        self._logger = logging.getLogger("pynextion.NexEventPoller")
        self._run_poll_loop = True
        self._run_poll_loop_lock = QReadWriteLock()
        self._thread_local = threading.local()
        self._poll_interval_ms = poll_interval_ms

    def stop(self):
        self._logger.info("Stopping Nextion event poller loop")
        try:
            self._run_poll_loop_lock.lockForWrite()
            self._run_poll_loop = False
        finally:
            self._run_poll_loop_lock.unlock()

    def run(self):
        self._logger.info(
            "Starting Nextion event poller with a %d [ms] interval",
            self._poll_interval_ms)
        while True:
            try:
                self._run_poll_loop_lock.lockForRead()
                self._thread_local.run = self._run_poll_loop
            finally:
                self._run_poll_loop_lock.unlock()

            if not self._thread_local.run:
                self._logger.info("Exiting Nextion event poller loop")
                break

            self._device.poll()
            QThread.msleep(self._poll_interval_ms)
Beispiel #4
0
class WorkerThread(QThread):
    lock = QReadWriteLock()
    cancelled = False

    def cancel(self):
        WorkerThread.cancelled = True

    def resume(self):
        WorkerThread.cancelled = False

    def setFunc(self, func):
        self.func = func

    def run(self):
        self.func()
class Thread(QThread):

    lock = QReadWriteLock()
    sinOut1 = pyqtSignal(str)  #信号量变量
    sinOut2 = pyqtSignal(str)  # 信号量变量
    sinOut3 = pyqtSignal(str)

    #socket = QTcpSocket()
    def __init__(self, socketId, parent):
        super(Thread, self).__init__(parent)
        self.socketId = socketId

    def run(self):
        self.socket = QTcpSocket()
        self.myclientid1 = 0
        if not self.socket.setSocketDescriptor(self.socketId):
            self.error.connect(self.socket.error)
            return
        self.sinOut1.emit(
            str(self.socketId) + "#" +
            QDateTime.currentDateTime().toString("yyyy-MM-dd HH:mm:ss")
        )  #发送信号量 //建立连接

        while self.socket.state() == QAbstractSocket.ConnectedState:
            if (self.socket.waitForReadyRead(1000 * 60 * 10)
                    and self.socket.bytesAvailable() > 0):
                #waitForReadyRead(1000*60*10)说明,单位为毫秒,时间内等待接收数据,超时为假
                mygetdata = self.socket.readAll()
                mygetdata = bytes(mygetdata)
                #print(mygetdata)
                self.sinOut2.emit("get data:" + str(mygetdata))  #client发送来的数据
                #分析客户端数据中的ID值
                myclientid = self.myanalyseframe(mygetdata)

                if myclientid != 0 and myclientid != self.myclientid1:
                    self.myclientid1 = myclientid
                    # 利用client数据,标识处TCP连接的对象ID值,指令中的值
                    self.sinOut1.emit(
                        str(self.socketId) + "#" +
                        QDateTime.currentDateTime().toString(
                            "yyyy-MM-dd HH:mm:ss") + "#" + str(myclientid))

            else:
                self.senddata(self.socket, 'TCP time out')
                self.sinOut3.emit(str(self.socketId))  #超时,线程结束,删除前台listw中的条目

                return  #超时,线程结束

    def sendStr(self, socket, msg):
        mysentdata = msg.encode('utf-8')
        socket.write(mysentdata)

    def senddata(self, socket, data):
        if isinstance(data, str) == True:
            mysentdata = data.encode('utf-8')
        elif isinstance(data, list) == True:
            mysentdata = bytes(data)
        elif isinstance(data, int) == True or isinstance(data, float) == True:
            mysentdata = str(data)
            mysentdata = mysentdata.encode('utf-8')
        else:
            mysentdata = data
        #print(mysentdata)
        socket.write(mysentdata)
        self.sinOut2.emit("send data:" + str(mysentdata))

    def getUIsenddata(self, data):
        pass
        mystr1 = data.split(',')
        mystr1 = [int(x) // 10 * 16 + int(x) % 10 for x in mystr1]
        mystr1 = bytes(mystr1)
        self.senddata(self.socket, mystr1)


##########################################
##############业务逻辑部分#############

    def myanalyseframe(self, mydata):
        pass
        if isinstance(mydata, str) == True:
            mygetdata = mydata.encode('utf-8')
        elif isinstance(mydata, list) == True:
            mygetdata = bytes(mydata)
        elif isinstance(mydata, int) == True or isinstance(mydata,
                                                           float) == True:
            mygetdata = str(mydata)
            mygetdata = mygetdata.encode('utf-8')
        else:
            mygetdata = mydata
        mydata1 = mygetdata
        if len(mydata1) != 6:
            pass
            return 0
        if mydata1[0] == 0x10 and mydata1[5] == 0x16:
            myclientid = int(mydata1[2]) + int(mydata1[3]) * 256
            pass
            return myclientid
        else:
            pass
            return 0
Beispiel #6
0
class Thread(QThread):

  lock = QReadWriteLock()

  def __init__(self, socketId, parent):
    super(Thread, self).__init__(parent)
    self.socketId = socketId


  def run(self):
    socket = QTcpSocket()
    if not socket.setSocketDescriptor(self.socketId):
      #self.emit(SIGNAL("error(int)"), socket.error())
      self.error.connect(socket.error)
      return
    while socket.state() == QAbstractSocket.ConnectedState:
      nextBlockSize = 0
      stream = QDataStream(socket)
      stream.setVersion(QDataStream.Qt_5_7)
      if (socket.waitForReadyRead() and
        socket.bytesAvailable() >= SIZEOF_UINT16):
        nextBlockSize = stream.readUInt16()
      else:
        self.sendError(socket, "Cannot read client request")
        return
      if socket.bytesAvailable() < nextBlockSize:
        if (not socket.waitForReadyRead(60000) or
          socket.bytesAvailable() < nextBlockSize):
          self.sendError(socket, "Cannot read client data")
          return
      action = ""
      room = ""
      date = QDate()
      action=stream.readQString()
      if action in ("BOOK", "UNBOOK"):
        room=stream.readQString()
        stream >> date
        try:
          Thread.lock.lockForRead()
          bookings = Bookings.get(date.toPyDate())
        finally:
          Thread.lock.unlock()
        uroom = str(room)
      if action == "BOOK":
        newlist = False
        try:
          Thread.lock.lockForRead()
          if bookings is None:
            newlist = True
        finally:
          Thread.lock.unlock()
        if newlist:
          try:
            Thread.lock.lockForWrite()
            bookings = Bookings[date.toPyDate()]
          finally:
            Thread.lock.unlock()
        error = None
        insert = False
        try:
          Thread.lock.lockForRead()
          if len(bookings) < MAX_BOOKINGS_PER_DAY:
            if uroom in bookings:
              error = "Cannot accept duplicate booking"
            else:
              insert = True
          else:
            error = "{0} is fully booked".format(date.toString(Qt.ISODate))
        finally:
          Thread.lock.unlock()
        if insert:
          try:
            Thread.lock.lockForWrite()
            bisect.insort(bookings, uroom)
          finally:
            Thread.lock.unlock()
          self.sendReply(socket, action, room, date)
        else:
          self.sendError(socket, error)
      elif action == "UNBOOK":
        error = None
        remove = False
        try:
          Thread.lock.lockForRead()
          if bookings is None or uroom not in bookings:
            error = "Cannot unbook nonexistent booking"
          else:
            remove = True
        finally:
          Thread.lock.unlock()
        if remove:
          try:
            Thread.lock.lockForWrite()
            bookings.remove(uroom)
          finally:
            Thread.lock.unlock()
          self.sendReply(socket, action, room, date)
        else:
          self.sendError(socket, error)
      else:
        self.sendError(socket, "Unrecognized request")
      socket.waitForDisconnected()
      try:
        Thread.lock.lockForRead()
        printBookings()
      finally:
        Thread.lock.unlock()


  def sendError(self, socket, msg):
    reply = QByteArray()
    stream = QDataStream(reply, QIODevice.WriteOnly)
    stream.setVersion(QDataStream.Qt_5_7)
    stream.writeUInt16(0)
    stream.writeQString("ERROR")
    stream.writeQString(msg)
    stream.device().seek(0)
    stream.writeUInt16(reply.size() - SIZEOF_UINT16)
    socket.write(reply)

  def sendReply(self, socket, action, room, date):
    reply = QByteArray()
    stream = QDataStream(reply, QIODevice.WriteOnly)
    stream.setVersion(QDataStream.Qt_5_7)
    stream.writeUInt16(0)
    stream.writeQString(action)
    stream.writeQString(room)
    stream<<date
    stream.device().seek(0)
    stream.writeUInt16(reply.size() - SIZEOF_UINT16)
    socket.write(reply)
Beispiel #7
0
 def __init__(self):
     QReadWriteLock.__init__(self, QReadWriteLock.Recursive)
     self.writer = WriteLocker(self)
     self.reader = ReadLocker(self)
     self.owner = None
Beispiel #8
0
class CSerWind(QMainWindow):
    """
    主窗口
    """
    def __init__(self, inp_host, inp_port):
        super().__init__()

        self.lock = QReadWriteLock()

        self.recordSignal = RecordSignal()
        self.recordSignal.sendSignal.connect(self.my_record)

        self.tcpServer = TcpServer(self.recordSignal, self.lock)
        if not self.tcpServer.listen(QHostAddress(inp_host), inp_port):
            QMessageBox.critical(
                self, '交易服务器',
                '服务器启动失败:{0}'.format(self.tcpServer.errorString()))
            rec_text = my_cur_time() + ' 服务器启动失败!'
            try:
                self.lock.lockForWrite()
                self.recordSignal.sendSignal.emit(rec_text)
            finally:
                self.lock.unlock()
            self.close()
            return
        else:
            self._initUI()
            rec_text = my_cur_time() + ' 开启交易服务器!'
            try:
                self.lock.lockForWrite()
                self.recordSignal.sendSignal.emit(rec_text)
            finally:
                self.lock.unlock()

    def _initUI(self):
        self.setFixedSize(600, 400)
        self.move(0, 60)
        self.setWindowTitle('服务器:交易跟单——复制信号')
        self.setWindowIcon(QIcon('myIcon.ico'))

        # TableView设置MT4账号及Files文件夹路径
        self.model = QStandardItemModel(2, 2)
        self.model.setHorizontalHeaderLabels(['MT4账号', 'Files文件夹路径'])
        row = 0
        for key, value in account_dir.items():
            self.model.setItem(row, 0, QStandardItem(key))
            self.model.setItem(row, 1, QStandardItem(value))
            row += 1
        self.table = QTableView(self)
        self.table.setModel(self.model)
        self.table.resize(500, 180)
        self.table.move(10, 15)
        self.table.horizontalHeader().setStretchLastSection(True)

        tbn_append = QPushButton('添 加', self)
        tbn_append.resize(70, 25)
        tbn_append.move(520, 30)
        tbn_append.clicked.connect(self.my_btn_append_clicked)
        btn_delete = QPushButton('删 除', self)
        btn_delete.resize(70, 25)
        btn_delete.move(520, 90)
        btn_delete.clicked.connect(self.my_btn_delete_clicked)
        btn_save = QPushButton('保 存', self)
        btn_save.resize(70, 25)
        btn_save.move(520, 150)
        btn_save.clicked.connect(self.my_btn_save_clicked)

        # 逐条显示交易服务器操作的每个记录
        self.text_browser = QTextBrowser(self)
        self.text_browser.resize(580, 180)
        self.text_browser.move(10, 210)

        self.show()

    def closeEvent(self, event):
        reply = QMessageBox.question(self, '操作提示!', '您确定要关闭“交易服务器”?',
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            rec_text = my_cur_time() + ' 关闭交易服务器!'
            try:
                self.lock.lockForWrite()
                self.recordSignal.sendSignal.emit(rec_text)
            finally:
                self.lock.unlock()
            event.accept()
        else:
            event.ignore()

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.showMinimized()

    def my_btn_append_clicked(self):
        """
        增加一个MT4账户
        """
        self.model.appendRow([QStandardItem(''), QStandardItem('')])

    def my_btn_delete_clicked(self):
        """
        删除当前行的MT4账号信息
        """
        reply = QMessageBox.question(self, '操作提示!', '确定要删除这条数据?',
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            index = self.table.currentIndex()
            self.model.removeRow(index.row())

    def my_btn_save_clicked(self):
        """
        保存MT4账户信息到account_dir.txt文件中
        """
        reply = QMessageBox.question(self, '操作提示!', '确定要覆盖原有数据?',
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            account_dir_new = {}
            rows = self.model.rowCount()
            for row in range(rows):
                key = self.model.item(row, 0).text()
                # 对MT4账号进行正则表达式匹配检查
                if not re.match(r'^[1-9]\d+$', key):
                    QMessageBox.critical(
                        self, '错误提示!',
                        self.tr('第 %s 行MT4账号格式不对!' % str(row + 1)))
                    return
                value = self.model.item(row, 1).text()
                if not os.path.exists(value) or value.find('\MQL4\Files') < 0:
                    QMessageBox.critical(
                        self, '错误提示!',
                        self.tr('第 %s 行Files文件路径不对!' % str(row + 1)))
                    return
                account_dir_new[key] = value
            # 保存文件
            try:
                account_dir = account_dir_new
                with open('account_dir.txt', 'w') as file_object:
                    file_object.write(str(account_dir))
            except Exception as e:
                QMessageBox.critical(
                    self, '错误提示!',
                    self.tr('保存MT4账户信息出现错误!{0}'.format(str(Exception))))
            # 记录这一操作
            rec_text = my_cur_time() + ' 已经保存了当前列表中MT4账户信息!'
            try:
                self.lock.lockForWrite()
                self.recordSignal.sendSignal.emit(rec_text)
            finally:
                self.lock.unlock()

    def my_record(self, inp_text):
        """
        记录服务器操作日志保存到日志文件,并在主窗口TextBrowser组件中显示出来
        """
        now = time.localtime()
        file_name = 'ser_' + time.strftime('%Y-%m-%d', now) + '.txt'
        rec_text = inp_text + '\n'

        with open(file_name, 'a+', encoding='UTF-8') as file_object:
            file_object.write(rec_text)

        # text_browser只显示当天的操作记录
        pre_text = self.text_browser.toPlainText()
        if len(pre_text) > 0 and pre_text[0:10] != inp_text[0:10]:
            self.text_browser.setText('')
        self.text_browser.append(inp_text)
Beispiel #9
0
 def __init__(self, debug=False):
     self.debug = debug
     self._dict = dict()
     self._prepare_dir()
     self._remove_tmps()
     self._lock = QReadWriteLock()
Beispiel #10
0
class __Config(object):
    def __init__(self, debug=False):
        self.debug = debug
        self._dict = dict()
        self._prepare_dir()
        self._remove_tmps()
        self._lock = QReadWriteLock()

    def __getitem__(self, key):
        self._lock.lockForRead()
        r = self._dict[key]
        self._lock.unlock()
        return r

    def __setitem__(self, key, value):
        self._lock.lockForWrite()
        self._dict[key] = value
        self._lock.unlock()

    def get(self, key, default=None):
        self._lock.lockForRead()
        r = self._dict.get(key, default)
        self._lock.unlock()
        return r

    def pop(self, key, default=None):
        self._lock.lockForWrite()
        r = self._dict.pop(key, default)
        self._lock.unlock()
        return r

    def __contains__(self, key):
        self._lock.lockForRead()
        r = self._dict.__contains__(key)
        self._lock.unlock()
        return r

    def __str__(self):
        self._lock.lockForRead()
        s = "".join(
            [
                "Config(",
                ", ".join("{0}: {1}".format(k, v) for (k, v) in self._dict),
                ")",
            ]
        )
        self._lock.unlock()
        return s

    @property
    def _config_dir(self):
        # Windows
        if sys.platform.startswith("win"):
            if "LOCALAPPDATA" in os.environ:
                return os.path.join(os.environ["LOCALAPPDATA"], "LDOCE5Viewer")
            else:
                return os.path.join(os.environ["APPDATA"], "LDOCE5Viewer")
        # Mac OS X
        elif sys.platform.startswith("darwin"):
            return os.path.expanduser("~/Library/Application Support/LDOCE5Viewer")
        # Linux
        else:
            base = os.path.join(os.path.expanduser("~"), ".config")
            # XDG
            try:
                import xdg.BaseDirectory

                base = xdg.BaseDirectory.xdg_config_home
            except ImportError:
                if "XDG_CONFIG_HOME" in os.environ:
                    base = os.environ["XDG_CONFIG_HOME"]
            return os.path.join(base, "ldoce5viewer")

    @property
    def _data_dir(self):
        # Windows
        if sys.platform.startswith("win"):
            return self._config_dir
        # Mac OS X
        elif sys.platform.startswith("darwin"):
            return self._config_dir
        # Linux
        else:
            base = os.path.join(os.path.expanduser("~"), ".local/share/")
            # XDG
            try:
                import xdg.BaseDirectory

                base = xdg.BaseDirectory.xdg_data_home
            except ImportError:
                if "XDG_DATA_HOME" in os.environ:
                    base = os.environ["XDG_DATA_HOME"]
            return os.path.join(base, "ldoce5viewer")

    @property
    def app_name(self):
        return "LDOCE5 Viewer"

    @property
    def _config_path(self):
        return os.path.join(self._config_dir, "config.pickle")

    @property
    def filemap_path(self):
        return os.path.join(self._data_dir, "filemap.cdb")

    @property
    def variations_path(self):
        return os.path.join(self._data_dir, "variations.cdb")

    @property
    def incremental_path(self):
        return os.path.join(self._data_dir, "incremental.db")

    @property
    def fulltext_hwdphr_path(self):
        return os.path.join(self._data_dir, "fulltext_hp")

    @property
    def fulltext_defexa_path(self):
        return os.path.join(self._data_dir, "fulltext_de")

    @property
    def scan_tmp_path(self):
        return os.path.join(self._data_dir, "scan" + self.tmp_suffix)

    @property
    def tmp_suffix(self):
        return ".tmp"

    def _remove_tmps(self):
        for name in os.listdir(self._config_dir) + os.listdir(self._data_dir):
            if name.endswith(self.tmp_suffix):
                path = os.path.join(self._config_dir, name)
                try:
                    if os.path.isfile(path):
                        os.remove(path)
                    elif os.path.isdir(path):
                        shutil.rmtree(path)
                except OSError:
                    pass

    def _prepare_dir(self):
        if not os.path.exists(self._config_dir):
            os.makedirs(self._config_dir)
        if not os.path.exists(self._data_dir):
            os.makedirs(self._data_dir)

    def load(self):
        self._lock.lockForWrite()
        try:
            with open(self._config_path, "rb") as f:
                self._dict.clear()
                try:
                    data = pickle.load(f)
                except:
                    pass
                else:
                    self._dict.update(data)
        except IOError:
            self._dict.clear()
        self._lock.unlock()

    def save(self):
        self._lock.lockForRead()

        if sys.platform == "win32":
            with open(self._config_path, "wb") as f:
                pickle.dump(self._dict, f)
        else:
            f = tempfile.NamedTemporaryFile(
                dir=self._config_dir, delete=False, suffix=self.tmp_suffix
            )
            pickle.dump(self._dict, f, protocol=0)
            f.close()
            os.rename(f.name, self._config_path)

        self._lock.unlock()
Beispiel #11
0
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)

        self.mutex = QMutex()
        self.fileCount = 0
        self.filenamesForWords = collections.defaultdict(set)
        self.commonWords = set()
        self.lock = QReadWriteLock()
        self.path = QDir.homePath()
        pathLabel = QLabel("Indexing path:")
        self.pathLabel = QLabel()
        self.pathLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.pathButton = QPushButton("Set &Path...")
        self.pathButton.setAutoDefault(False)
        findLabel = QLabel("&Find word:")
        self.findEdit = QLineEdit()
        findLabel.setBuddy(self.findEdit)
        commonWordsLabel = QLabel("&Common words:")
        self.commonWordsListWidget = QListWidget()
        commonWordsLabel.setBuddy(self.commonWordsListWidget)
        filesLabel = QLabel("Files containing the &word:")
        self.filesListWidget = QListWidget()
        filesLabel.setBuddy(self.filesListWidget)
        filesIndexedLabel = QLabel("Files indexed")
        self.filesIndexedLCD = QLCDNumber()
        self.filesIndexedLCD.setSegmentStyle(QLCDNumber.Flat)
        wordsIndexedLabel = QLabel("Words indexed")
        self.wordsIndexedLCD = QLCDNumber()
        self.wordsIndexedLCD.setSegmentStyle(QLCDNumber.Flat)
        commonWordsLCDLabel = QLabel("Common words")
        self.commonWordsLCD = QLCDNumber()
        self.commonWordsLCD.setSegmentStyle(QLCDNumber.Flat)
        self.statusLabel = QLabel("Click the 'Set Path' "
                                  "button to start indexing")
        self.statusLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)

        topLayout = QHBoxLayout()
        topLayout.addWidget(pathLabel)
        topLayout.addWidget(self.pathLabel, 1)
        topLayout.addWidget(self.pathButton)
        topLayout.addWidget(findLabel)
        topLayout.addWidget(self.findEdit, 1)
        leftLayout = QVBoxLayout()
        leftLayout.addWidget(filesLabel)
        leftLayout.addWidget(self.filesListWidget)
        rightLayout = QVBoxLayout()
        rightLayout.addWidget(commonWordsLabel)
        rightLayout.addWidget(self.commonWordsListWidget)
        middleLayout = QHBoxLayout()
        middleLayout.addLayout(leftLayout, 1)
        middleLayout.addLayout(rightLayout)
        bottomLayout = QHBoxLayout()
        bottomLayout.addWidget(filesIndexedLabel)
        bottomLayout.addWidget(self.filesIndexedLCD)
        bottomLayout.addWidget(wordsIndexedLabel)
        bottomLayout.addWidget(self.wordsIndexedLCD)
        bottomLayout.addWidget(commonWordsLCDLabel)
        bottomLayout.addWidget(self.commonWordsLCD)
        bottomLayout.addStretch()
        layout = QVBoxLayout()
        layout.addLayout(topLayout)
        layout.addLayout(middleLayout)
        layout.addLayout(bottomLayout)
        layout.addWidget(self.statusLabel)
        self.setLayout(layout)

        self.walkers = []
        self.completed = []
        self.pathButton.clicked.connect(self.setPath)
        self.findEdit.returnPressed.connect(self.find)
        self.setWindowTitle("Page Indexer")
Beispiel #12
0
class Form(QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)

        self.mutex = QMutex()
        self.fileCount = 0
        self.filenamesForWords = collections.defaultdict(set)
        self.commonWords = set()
        self.lock = QReadWriteLock()
        self.path = QDir.homePath()
        pathLabel = QLabel("Indexing path:")
        self.pathLabel = QLabel()
        self.pathLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.pathButton = QPushButton("Set &Path...")
        self.pathButton.setAutoDefault(False)
        findLabel = QLabel("&Find word:")
        self.findEdit = QLineEdit()
        findLabel.setBuddy(self.findEdit)
        commonWordsLabel = QLabel("&Common words:")
        self.commonWordsListWidget = QListWidget()
        commonWordsLabel.setBuddy(self.commonWordsListWidget)
        filesLabel = QLabel("Files containing the &word:")
        self.filesListWidget = QListWidget()
        filesLabel.setBuddy(self.filesListWidget)
        filesIndexedLabel = QLabel("Files indexed")
        self.filesIndexedLCD = QLCDNumber()
        self.filesIndexedLCD.setSegmentStyle(QLCDNumber.Flat)
        wordsIndexedLabel = QLabel("Words indexed")
        self.wordsIndexedLCD = QLCDNumber()
        self.wordsIndexedLCD.setSegmentStyle(QLCDNumber.Flat)
        commonWordsLCDLabel = QLabel("Common words")
        self.commonWordsLCD = QLCDNumber()
        self.commonWordsLCD.setSegmentStyle(QLCDNumber.Flat)
        self.statusLabel = QLabel("Click the 'Set Path' "
                                  "button to start indexing")
        self.statusLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)

        topLayout = QHBoxLayout()
        topLayout.addWidget(pathLabel)
        topLayout.addWidget(self.pathLabel, 1)
        topLayout.addWidget(self.pathButton)
        topLayout.addWidget(findLabel)
        topLayout.addWidget(self.findEdit, 1)
        leftLayout = QVBoxLayout()
        leftLayout.addWidget(filesLabel)
        leftLayout.addWidget(self.filesListWidget)
        rightLayout = QVBoxLayout()
        rightLayout.addWidget(commonWordsLabel)
        rightLayout.addWidget(self.commonWordsListWidget)
        middleLayout = QHBoxLayout()
        middleLayout.addLayout(leftLayout, 1)
        middleLayout.addLayout(rightLayout)
        bottomLayout = QHBoxLayout()
        bottomLayout.addWidget(filesIndexedLabel)
        bottomLayout.addWidget(self.filesIndexedLCD)
        bottomLayout.addWidget(wordsIndexedLabel)
        bottomLayout.addWidget(self.wordsIndexedLCD)
        bottomLayout.addWidget(commonWordsLCDLabel)
        bottomLayout.addWidget(self.commonWordsLCD)
        bottomLayout.addStretch()
        layout = QVBoxLayout()
        layout.addLayout(topLayout)
        layout.addLayout(middleLayout)
        layout.addLayout(bottomLayout)
        layout.addWidget(self.statusLabel)
        self.setLayout(layout)

        self.walkers = []
        self.completed = []
        self.pathButton.clicked.connect(self.setPath)
        self.findEdit.returnPressed.connect(self.find)
        self.setWindowTitle("Page Indexer")

    def stopWalkers(self):
        for walker in self.walkers:
            if isAlive(walker) and walker.isRunning():
                walker.stop()
        for walker in self.walkers:
            if isAlive(walker) and walker.isRunning():
                walker.wait()
        self.walkers = []
        self.completed = []

    def setPath(self):
        self.stopWalkers()
        self.pathButton.setEnabled(False)
        path = QFileDialog.getExistingDirectory(self, "Choose a Path to Index",
                                                self.path)
        if not path:
            self.statusLabel.setText("Click the 'Set Path' "
                                     "button to start indexing")
            self.pathButton.setEnabled(True)
            return
        self.statusLabel.setText("Scanning directories...")
        QApplication.processEvents()  # Needed for Windows
        self.path = QDir.toNativeSeparators(path)
        self.findEdit.setFocus()
        self.pathLabel.setText(self.path)
        self.statusLabel.clear()
        self.filesListWidget.clear()
        self.fileCount = 0
        self.filenamesForWords = collections.defaultdict(set)
        self.commonWords = set()
        nofilesfound = True
        files = []
        index = 0
        for root, dirs, fnames in os.walk(str(self.path)):
            for name in [
                    name for name in fnames if name.endswith((".htm", ".html"))
            ]:
                files.append(os.path.join(root, name))
                if len(files) == 1000:
                    self.processFiles(index, files[:])
                    files = []
                    index += 1
                    nofilesfound = False
        if files:
            self.processFiles(index, files[:])
            nofilesfound = False
        if nofilesfound:
            self.finishedIndexing()
            self.statusLabel.setText("No HTML files found in the given path")

    def processFiles(self, index, files):
        thread = walker.Walker(index, self.lock, files, self.filenamesForWords,
                               self.commonWords, self)
        thread.indexed[str, int].connect(self.indexed)
        thread.finished[bool, int].connect(self.finished)
        thread.finished.connect(thread.deleteLater)
        self.walkers.append(thread)
        self.completed.append(False)
        thread.start()
        thread.wait(300)  # Needed for Windows

    def find(self):
        word = str(self.findEdit.text())
        if not word:
            try:
                self.mutex.lock()
                self.statusLabel.setText("Enter a word to find in files")
            finally:
                self.mutex.unlock()
            return
        try:
            self.mutex.lock()
            self.statusLabel.clear()
            self.filesListWidget.clear()
        finally:
            self.mutex.unlock()
        word = word.lower()
        if " " in word:
            word = word.split()[0]
        try:
            self.lock.lockForRead()
            found = word in self.commonWords
        finally:
            self.lock.unlock()
        if found:
            try:
                self.mutex.lock()
                self.statusLabel.setText("Common words like '{0}' "
                                         "are not indexed".format(word))
            finally:
                self.mutex.unlock()
            return
        try:
            self.lock.lockForRead()
            files = self.filenamesForWords.get(word, set()).copy()
        finally:
            self.lock.unlock()
        if not files:
            try:
                self.mutex.lock()
                self.statusLabel.setText("No indexed file contains "
                                         "the word '{0}'".format(word))
            finally:
                self.mutex.unlock()
            return
        files = [
            QDir.toNativeSeparators(name)
            for name in sorted(files, key=str.lower)
        ]
        try:
            self.mutex.lock()
            self.filesListWidget.addItems(files)
            self.statusLabel.setText(
                "{0} indexed files contain the word '{1}'".format(
                    len(files), word))
        finally:
            self.mutex.unlock()

    def indexed(self, fname, index):
        try:
            self.mutex.lock()
            self.statusLabel.setText(fname)
            self.fileCount += 1
            count = self.fileCount
        finally:
            self.mutex.unlock()
        if count % 25 == 0:
            try:
                self.lock.lockForRead()
                indexedWordCount = len(self.filenamesForWords)
                commonWordCount = len(self.commonWords)
            finally:
                self.lock.unlock()
            try:
                self.mutex.lock()
                self.filesIndexedLCD.display(count)
                self.wordsIndexedLCD.display(indexedWordCount)
                self.commonWordsLCD.display(commonWordCount)
            finally:
                self.mutex.unlock()
        elif count % 101 == 0:
            try:
                self.lock.lockForRead()
                words = self.commonWords.copy()
            finally:
                self.lock.unlock()
            try:
                self.mutex.lock()
                self.commonWordsListWidget.clear()
                self.commonWordsListWidget.addItems(sorted(words))
            finally:
                self.mutex.unlock()

    def finished(self, completed, index):
        done = False
        if self.walkers:
            self.completed[index] = True
            if all(self.completed):
                try:
                    self.mutex.lock()
                    self.statusLabel.setText("Finished")
                    done = True
                finally:
                    self.mutex.unlock()
        else:
            try:
                self.mutex.lock()
                self.statusLabel.setText("Finished")
                done = True
            finally:
                self.mutex.unlock()
        if done:
            self.finishedIndexing()

    def reject(self):
        if not all(self.completed):
            self.stopWalkers()
            self.finishedIndexing()
        else:
            self.accept()

    def closeEvent(self, event=None):
        self.stopWalkers()

    def finishedIndexing(self):
        self.filesIndexedLCD.display(self.fileCount)
        self.wordsIndexedLCD.display(len(self.filenamesForWords))
        self.commonWordsLCD.display(len(self.commonWords))
        self.pathButton.setEnabled(True)
        QApplication.processEvents()  # Needed for Windows
Beispiel #13
0
class __Config(object):
    def __init__(self, debug=False):
        self.debug = debug
        self._dict = dict()
        self._prepare_dir()
        self._remove_tmps()
        self._lock = QReadWriteLock()

    def __getitem__(self, key):
        self._lock.lockForRead()
        r = self._dict[key]
        self._lock.unlock()
        return r

    def __setitem__(self, key, value):
        self._lock.lockForWrite()
        self._dict[key] = value
        self._lock.unlock()

    def get(self, key, default=None):
        self._lock.lockForRead()
        r = self._dict.get(key, default)
        self._lock.unlock()
        return r

    def pop(self, key, default=None):
        self._lock.lockForWrite()
        r = self._dict.pop(key, default)
        self._lock.unlock()
        return r

    def __contains__(self, key):
        self._lock.lockForRead()
        r = self._dict.__contains__(key)
        self._lock.unlock()
        return r

    def __str__(self):
        self._lock.lockForRead()
        s = ''.join([
            'Config(',
            ', '.join("{0}: {1}".format(k, v) for (k, v) in self._dict), ')'
        ])
        self._lock.unlock()
        return s

    @property
    def _config_dir(self):
        # Windows
        if sys.platform.startswith('win'):
            if 'LOCALAPPDATA' in os.environ:
                return os.path.join(os.environ['LOCALAPPDATA'], 'LDOCE5Viewer')
            else:
                return os.path.join(os.environ['APPDATA'], 'LDOCE5Viewer')
        # Mac OS X
        elif sys.platform.startswith('darwin'):
            return os.path.expanduser(
                '~/Library/Application Support/LDOCE5Viewer')
        # Linux
        else:
            base = os.path.join(os.path.expanduser('~'), '.config')
            # XDG
            try:
                import xdg.BaseDirectory
                base = xdg.BaseDirectory.xdg_config_home
            except ImportError:
                if 'XDG_CONFIG_HOME' in os.environ:
                    base = os.environ['XDG_CONFIG_HOME']
            return os.path.join(base, 'ldoce5viewer')

    @property
    def _data_dir(self):
        # Windows
        if sys.platform.startswith('win'):
            return self._config_dir
        # Mac OS X
        elif sys.platform.startswith('darwin'):
            return self._config_dir
        # Linux
        else:
            base = os.path.join(os.path.expanduser('~'), '.local/share/')
            # XDG
            try:
                import xdg.BaseDirectory
                base = xdg.BaseDirectory.xdg_data_home
            except ImportError:
                if 'XDG_DATA_HOME' in os.environ:
                    base = os.environ['XDG_DATA_HOME']
            return os.path.join(base, 'ldoce5viewer')

    @property
    def app_name(self):
        return 'LDOCE5 Viewer'

    @property
    def _config_path(self):
        return os.path.join(self._config_dir, 'config.pickle')

    @property
    def filemap_path(self):
        return os.path.join(self._data_dir, 'filemap.cdb')

    @property
    def variations_path(self):
        return os.path.join(self._data_dir, 'variations.cdb')

    @property
    def incremental_path(self):
        return os.path.join(self._data_dir, 'incremental.db')

    @property
    def fulltext_hwdphr_path(self):
        return os.path.join(self._data_dir, 'fulltext_hp')

    @property
    def fulltext_defexa_path(self):
        return os.path.join(self._data_dir, 'fulltext_de')

    @property
    def scan_tmp_path(self):
        return os.path.join(self._data_dir, 'scan' + self.tmp_suffix)

    @property
    def tmp_suffix(self):
        return '.tmp'

    def _remove_tmps(self):
        for name in os.listdir(self._config_dir) + os.listdir(self._data_dir):
            if name.endswith(self.tmp_suffix):
                path = os.path.join(self._config_dir, name)
                try:
                    if os.path.isfile(path):
                        os.remove(path)
                    elif os.path.isdir(path):
                        shutil.rmtree(path)
                except OSError:
                    pass

    def _prepare_dir(self):
        if not os.path.exists(self._config_dir):
            os.makedirs(self._config_dir)
        if not os.path.exists(self._data_dir):
            os.makedirs(self._data_dir)

    def load(self):
        self._lock.lockForWrite()
        try:
            with open(self._config_path, 'rb') as f:
                self._dict.clear()
                try:
                    data = pickle.load(f)
                except:
                    pass
                else:
                    self._dict.update(data)
        except IOError:
            self._dict.clear()
        self._lock.unlock()

    def save(self):
        self._lock.lockForRead()

        if sys.platform == 'win32':
            with open(self._config_path, 'wb') as f:
                pickle.dump(self._dict, f)
        else:
            f = tempfile.NamedTemporaryFile(dir=self._config_dir,
                                            delete=False,
                                            suffix=self.tmp_suffix)
            pickle.dump(self._dict, f, protocol=0)
            f.close()
            os.rename(f.name, self._config_path)

        self._lock.unlock()
Beispiel #14
0
# -*- coding: utf-8 -*-
from PyQt5.QtCore import QReadWriteLock

_store = {}
_lock = QReadWriteLock()


class Globals(object):
    @staticmethod
    def getAttr(name):
        _lock.lockForRead()
        attr = _store[name] if name in _store else None
        _lock.unlock()
        return attr

    @staticmethod
    def setAttr(name, value=None):
        _lock.lockForWrite()
        if value:
            _store[name] = value
        elif name in _store:
            del _store[name]
        _lock.unlock()
Beispiel #15
0
class Thread(QThread, QWidget):  # 这个线程为自动采集所用的。运行这个线程就会启动tcp 允许别人连上
    lock = QReadWriteLock()
    # 该线程内部定义的信号,携带了三个字 用于解决数据库问题
    pushDeviceInfoSignal = pyqtSignal(str, str, str, str)
    popDeviceSignal = pyqtSignal(str)
    pushPictureSizeSignal = pyqtSignal(str, str, str)
    pushFileInfoSignal = pyqtSignal(str, str)
    pushResultInfoSignal = pyqtSignal(str, str, str, str, int)
    sendFileSignal = pyqtSignal(str)

    def __init__(self, socketId, parent):
        super(Thread, self).__init__(parent)
        self.myParent = parent
        self.socketId = socketId  # socketID 可能是为socket编号
        self.hdmi_old_result = ""  # 为自动识别提供的 变量,可防止重复数据不停地输出
        self.av_old_result = ""  # 不共享变量
        self.handleSql = pushToSql.handleSql()
        self.pushDeviceInfoSignal.connect(self.pushDeviceInfo)
        self.pushResultInfoSignal.connect(self.pushResultInfo)
        self.pushPictureSizeSignal.connect(self.pushPictureSize)
        self.pushFileInfoSignal.connect(self.pushFileInfo)
        self.popDeviceSignal.connect(self.popDevice)

    def pushDeviceInfo(self, deviceFixId, regionProvince, regionCity,
                       regionArea):
        self.handleSql.pushDeviceInfo(str(deviceFixId), regionProvince,
                                      regionCity, regionArea)

    def pushResultInfo(
            self, deviceFixId, kind, result, startTime,
            usedTime):  # (self, deviceFixId, kind, result, startTime, usedTime

        self.handleSql.pushResultInfo(str(deviceFixId), kind, result,
                                      startTime, usedTime)

    def pushPictureSize(self, pictureSize, deviceFixId, kind):  # 将图片信息转入数据库
        pictureSizeDict = eval(pictureSize)
        # print(type(pictureSizeDict), pictureSizeDict)
        # print(pictureSizeDict)
        for key, value in pictureSizeDict.items():
            self.handleSql.pushPictureSize(deviceFixId, key, kind, value[0],
                                           value[1], value[2], value[3])

    def pushFileInfo(self, fileInfo, deviceFixId):
        fileInfo = eval(fileInfo)
        for fileInfoItem in fileInfo:
            fileAbsolutePath = fileInfoItem['fileAbsolutePath']
            fileSize = fileInfoItem['fileSize']
            lastUpdatedDate = fileInfoItem['lastUpdatedDate']
            self.handleSql.pushFileInfo(deviceFixId, fileAbsolutePath,
                                        fileSize, lastUpdatedDate)

    def popDevice(self, deviceId):
        self.handleSql.updateDeviceStatus(deviceId, 0)

    def run(self):
        print('-----------------------')
        socket = QTcpSocket()

        count = 0

        if not socket.setSocketDescriptor(self.socketId):  # 可能是分配的东西,具体作用不知道
            # self.emit(SIGNAL("error(int)"), socket.error())
            self.error.connect(socket.error)

            return

        while socket.state() == QAbstractSocket.ConnectedState:
            nextBlockSize = 0
            stream = QDataStream(socket)
            stream.setVersion(QDataStream.Qt_5_8)
            sockeIdToSocketDict[self.socketId] = socket
            # print(sockeIdToSocketDict)  # 将所有连接上来的socket保存起来
            # print(fixIdToSocketIdDict)
            aim_ip = socket.peerAddress().toString()  # 获得连上来的IP地址
            # print(aim_ip)

            if (socket.waitForReadyRead()
                    and socket.bytesAvailable() >= SIZEOF_UINT64):
                print('wait')
                nextBlockSize = stream.readUInt64()

            else:
                print('错误')  # 客户端主动断开时,去掉字典中的对应,在这里做一部分操作。
                # 客户端主动断开的时候,要将其从self.myParent.sockeIdToSocketDict   self.myParent.fixIdToSocketIdDict 中删掉
                sockeIdToSocketDict.pop(self.socketId)  # 客户端主动断开的时候删掉。
                fixIdToSocketIdDict.pop(fixID)
                threadDict.pop(self.socketId)
                self.popDeviceSignal.emit(fixID)
                self.sendError(socket, "Cannot read client request")
                return
            if socket.bytesAvailable() < nextBlockSize:
                print("错误2")
                if (not socket.waitForReadyRead(60000)
                        or socket.bytesAvailable() < nextBlockSize):
                    self.sendError(socket, "Cannot read client data")
                    return

            # 这段数据流上 第一个是state 根据state判断接下来的状态,
            # 发送成功的状态,发送来 success    日期  信号类型 识别结果 识别开始时间 识别时间

            state = stream.readQString()  # 读状态

            print('#61    ' + state)
            if state == 'successResult':  # 如果状态是success,说明下一个发来的是识别的结果
                resultBytes = stream.readBytes()
                try:
                    Thread.lock.lockForRead()
                finally:
                    Thread.lock.unlock()
                resultObject = pickle.loads(resultBytes)
                # print(fixID)
                # print(resultObject.dateNow)
                # print(resultObject.kind)
                # print(resultObject.result)
                # print(resultObject.startTime)
                # print(resultObject.usedTime)

                if resultObject.kind == "HDMI" and self.hdmi_old_result != resultObject.result:

                    # 自动采集的不需要时间,他需要 日期 时间识别结果 发走的信息只有 类型 识别结果 ip地址 全是strhandleSql.pushResultInfo('123425','HDMI','北京卫视','2018-12-23 12:23:21',12)
                    self.pushResultInfoSignal.emit(
                        fixID, resultObject.kind,
                        resultObject.result, resultObject.startTime,
                        int(resultObject.usedTime
                            ))  # 发射信号,携带了信号类型,识别结果,aim_ip(当做区分控件的id)结果从这里发出去
                    self.hdmi_old_result = resultObject.result

                elif resultObject.kind == 'AV' and self.av_old_result != resultObject.result:
                    self.pushResultInfoSignal.emit(
                        fixID, resultObject.kind, resultObject.result,
                        resultObject.startTime, int(resultObject.usedTime)
                    )  # 发射信号,携带了信号类型,识别结果,aim_ip(当做区分空间的id) getMessgetMessageAllTcpageAllTcp
                    self.av_old_result = resultObject.result
            elif state == 'sendImage':  # 如果状态是wait_to_recognize,说明下一端是图片的16位整数# 图片的暂时不考虑,因为还不知道发给谁
                kind = stream.readQString()  # 读台标信号类型
                try:
                    Thread.lock.lockForRead()
                finally:
                    Thread.lock.unlock()
                file = stream.readBytes()
                with open('image.jpg', 'wb') as f:
                    f.write(file)

            elif state == 'deviceInfo':  # 收到deviceInfo对象
                deviceInfoByte = stream.readBytes()
                try:
                    Thread.lock.lockForRead()
                finally:
                    Thread.lock.unlock()
                # pictureSizeByte = stream.readBytes()
                deviceInfo = pickle.loads(deviceInfoByte)
                # pictureSize = pickle.loads(pictureSizeByte)

                fixID = deviceInfo['deviceFixId']
                fixIdToSocketIdDict[fixID] = self.socketId
                print(deviceInfo['pictureSize'])
                self.pushDeviceInfoSignal.emit(deviceInfo['deviceFixId'],
                                               deviceInfo['regionProvince'],
                                               deviceInfo['regionCity'],
                                               deviceInfo['regionArea'])
                print("___________________________")
                print(deviceInfo['fileInfo'])
                self.pushPictureSizeSignal.emit(str(deviceInfo['pictureSize']),
                                                deviceInfo['deviceFixId'],
                                                deviceInfo['kind'])
                self.pushFileInfoSignal.emit(str(deviceInfo['fileInfo']),
                                             deviceInfo['deviceFixId'])

            elif state == 'sendFile':  # 准备接受 文件
                fileName = stream.readQString()  # 读取文件名称
                fileSize = stream.readQString()  # 读取文件大小
                fileBytes = stream.readBytes()  # 读取文件部分字节
                try:
                    Thread.lock.lockForRead()
                finally:
                    Thread.lock.unlock()
                # print(fileSize)
                with open('../TEST/' + fileName, 'ab') as f:
                    f.write(fileBytes)
                count = count + fileBytes.__len__()
                # print(fileBytes.__len__())
                # print(count / int(fileSize))
                # print(count)

    def sendError(self, socket, msg):
        reply = QByteArray()
        stream = QDataStream(reply, QIODevice.WriteOnly)
        stream.setVersion(QDataStream.Qt_5_7)
        stream.writeUInt16(0)
        stream.writeQString("ERROR")
        stream.writeQString(msg)
        stream.device().seek(0)
        stream.writeUInt16(reply.size() - SIZEOF_UINT16)
        socket.write(reply)

    def sendReply(self, socket):  # 用于测试
        reply = QByteArray()
        stream = QDataStream(reply, QIODevice.WriteOnly)
        stream.setVersion(QDataStream.Qt_5_7)
        stream.writeUInt16(0)
        stream.writeQString("test")
        stream.writeQString('收到')
        stream.device().seek(0)
        stream.writeUInt16(reply.size() - SIZEOF_UINT16)
        socket.write(reply)
        socket.waitForBytesWritten()

    def sendBackOrder(self, socket, order):  # 回传一条命令
        reply = QByteArray()
        stream = QDataStream(reply, QIODevice.WriteOnly)
        stream.setVersion(QDataStream.Qt_5_7)
        stream.writeUInt16(0)
        stream.writeQString("ORDER")  # 回传一条命令,命令自己定义。
        stream.writeQString(order)
        stream.device().seek(0)
        stream.writeUInt16(reply.size() - SIZEOF_UINT16)
        socket.write(reply)
        socket.waitForBytesWritten()

    def sendBackFile(self, socket, filePath):  #
        file = QFile(filePath)
        print(file.size())
        count = 0
        with open(filePath, 'rb') as f:
            while 1:
                sleep(0.1)
                filedata = f.read(20480)
                if not filedata:
                    break
                reply = QByteArray()
                stream = QDataStream(reply, QIODevice.WriteOnly)
                stream.setVersion(QDataStream.Qt_5_7)
                stream.writeUInt16(0)

                stream.writeQString('SENDFILE')
                stream.writeQString(file.fileName())
                stream.writeInt(file.size())
                stream.writeBytes(filedata)

                stream.device().seek(0)
                stream.writeUInt16(reply.size() - SIZEOF_UINT16)
                socket.write(reply)
                socket.waitForBytesWritten()
                count = count + filedata.__len__()
                print(count)

    def fileToBytes(self, fileName):  # 将文件转换成二进制
        with open(fileName, 'rb') as f:
            return f.read()
Beispiel #16
0
# task class
class Task(QThread):
    def __init__(self, proc, args):
        super(Task, self).__init__()
        self.proc = proc
        self.args = args

    def run(self):
        mytask = QProcess()
        mytask.execute(self.proc, self.args)


work_queue = [("python", "test.py"), ("nmap", "-sV www.v.zzu.edu.cn"),
              ("whois", "baidu.com")]
current_work_queue = work_queue
queuemutex = QReadWriteLock()


# monitor task queue and execute new task
class ServerThread(QThread):
    def __init__(self):
        super(ServerThread, self).__init__()

    def run(self):
        while True:
            if len(current_work_queue) != 0:
                print("current queue: " + str(current_work_queue))
                print("next task: ", end='')
                # execute task
                self.execute_task()