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 __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
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)
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
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)
def __init__(self): QReadWriteLock.__init__(self, QReadWriteLock.Recursive) self.writer = WriteLocker(self) self.reader = ReadLocker(self) self.owner = None
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)
def __init__(self, debug=False): self.debug = debug self._dict = dict() self._prepare_dir() self._remove_tmps() self._lock = QReadWriteLock()
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()
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")
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
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()
# -*- 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()
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()
# 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()