def read(self): try: message = self.socket.recv(4096) except Exception as e: Log.e(getExceptionInfo(e)) return Client.ReadError if len(message) == 0: return Client.NoMessage self.buf += message while len(self.buf) > 4: length = int(self.buf[0:4]) if not len(self.buf) >= length + 4: break msg = self.buf[4:length + 4] self.buf = self.buf[length + 4:] message = Message() if not message.loads(msg): Log.w(u'Unknown Message') else: self.requests.put(message) return Client.NewMessage
def handleSaveClicked(self): readable = self.readableEdit.text() username = self.nameEdit.text() password = self.passwordEdit.text() if len(username) > 0 and len(password) > 0: resourceId = uuid.uuid4().hex account = { 'id': resourceId, 'desc': readable, 'username': username, 'password': password } self.wantSaveAccount.emit(account) clientId = application.getRandomClientId() message = Message(cmd=Message.CMD_ADD_ACCOUNT) message['account'] = account if clientId: EventManager.trigger( Event('Client.replyReady.' + clientId, message)) application.addResource(resourceId, clientId) toolBarId = application.lookUpToolBarIdByResourceId(resourceId) if toolBarId: EventManager.trigger( Event('ToolBar.changeState.' + toolBarId, True)) else: Log.e(u'未找到对应的服务器,增加失败') else: Log.w(u'用户名和密码均不为空时才能保存')
def read(self): try: message = self.socket.recv(4096) except Exception as e: Log.e(getExceptionInfo(e)) return Client.ReadError if len(message) == 0: return Client.NoMessage self.buf += message while len(self.buf) > 4: length = int(self.buf[0:4]) if not len(self.buf) >= length + 4: break msg = self.buf[4: length + 4] self.buf = self.buf[length + 4:] message = Message() if not message.loads(msg): Log.w(u'Unknown Message') else: self.requests.put(message) return Client.NewMessage
def handleAddGpsOk(self, request): toolBarId = application.lookUpToolBarIdByResourceId(request['id']) if toolBarId: EventManager.trigger( Event('ToolBar.changeState.' + toolBarId, False)) else: Log.e(u'未找到需要改变状态的ToolBar')
def getParam(self, name): param = None try: param = self.request[name] except Exception as e: Log.e(getExceptionInfo(e)) return param
def load(self, name, vmId, port, password): self.vmInfo = { 'name': name, 'port': port, 'password': password, 'obj': self } try: self.mach = self.vbox.findMachine(name) desc = self.mach.getGuestPropertyValue('vm_desc') self.vmInfo['desc'] = str(desc) if desc else '' type_ = self.mach.getGuestPropertyValue('vm_type') if not type_ or int(type_) not in (VirtualMachine.Type_Stand, VirtualMachine.Type_Id_Extract): self.vmInfo['status'] = VirtualMachine.Status_Invalid self.vmInfo['type'] = -1 return self.vmInfo self.vmInfo['type'] = int(type_) if self.mach.state == self.mgr.constants.MachineState_Running: self.vmInfo['status'] = VirtualMachine.Status_Running return self.vmInfo self.session = self.mgr.mgr.getSessionObject(self.vbox) self.mach.lockMachine(self.session, self.mgr.constants.LockType_Write) mutable = self.session.machine mutable.setGuestPropertyValue('vm_vmId', vmId) mutable.VRDEServer.setVRDEProperty('VNCPassword', str(password)) mutable.VRDEServer.setVRDEProperty('TCP/Ports', str(port)) mutable.VRDEServer.enabled = True mutable.saveSettings() self.session.unlockMachine() except Exception, e: Log.e(getExceptionInfo(e)) return
def __getitem__(self, item): param = None try: param = self.params[item] except Exception as e: Log.e(getExceptionInfo(e)) return param
def dumps(self): if 'cmd' not in self.params: Log.e('cmd不存在') return None message = json.dumps(self.params) Log.i('生成Message: ' + message) return bytes(message).encode('utf-8')
def deleteSelectedItems(self): selection = self.gpsTable.selectionModel() indexes = selection.selectedRows() #uuids: {clientId: [uuid,]} uuids = {} for index in indexes: uuid_ = self.gpsModel.gpsItems[index.row()].id() clientId = application.lookUpClientIdByResourceId(uuid_) if clientId in uuids: uuids[clientId].append(uuid_) else: uuids[clientId] = [uuid_] if len(uuids) == 0: return for clientId in uuids: message = Message(cmd=Message.CMD_DELETE_GPS) message['ids'] = uuids[clientId] EventManager.trigger(Event('Client.replyReady.' + clientId, message)) self.deleteGpsItems(uuids[clientId]) for uuid_ in uuids[clientId]: toolBarId = application.lookUpToolBarIdByResourceId(uuid_) if toolBarId: EventManager.trigger(Event('ToolBar.changeState.' + toolBarId, True)) else: Log.e(u'未找到对应的ToolBar')
def queryVms(self, request): clientId = request.getParam('clientId') if not clientId: Log.e('ExternalDispatcher.queryVms: 权限不足') return if clientId not in self.server.clients: Log.e('ExternalDispatcher.queryVms: 该客户端在服务器中不存在') return vms = self.vm.getAllMachines() vms_ = {} for index, vmId in enumerate(vms): vm = vms[vmId] vms_[vm['name']] = { 'status': vm['status'], 'vmId': vmId, 'vmType': vm['type'], 'desc': vm['desc'] } message = Message(cmd=Message.CMD_QUERY_VMS_OK) message['vms'] = { 'name': '服务器', 'serverId': clientId, 'desc': '', 'vms': vms_ } EventManager.trigger(Event('Socket.addReply.' + clientId, message))
def load(self, name, vmId, port, password): self.vmInfo = {'name': name, 'port': port, 'password': password, 'obj': self} try: self.mach = self.vbox.findMachine(name) desc = self.mach.getGuestPropertyValue('vm_desc') self.vmInfo['desc'] = str(desc) if desc else '' type_ = self.mach.getGuestPropertyValue('vm_type') if not type_ or int(type_) not in (VirtualMachine.Type_Stand, VirtualMachine.Type_Id_Extract): self.vmInfo['status'] = VirtualMachine.Status_Invalid self.vmInfo['type'] = -1 return self.vmInfo self.vmInfo['type'] = int(type_) if self.mach.state == self.mgr.constants.MachineState_Running: self.vmInfo['status'] = VirtualMachine.Status_Running return self.vmInfo self.session = self.mgr.mgr.getSessionObject(self.vbox) self.mach.lockMachine(self.session, self.mgr.constants.LockType_Write) mutable = self.session.machine mutable.setGuestPropertyValue('vm_vmId', vmId) mutable.VRDEServer.setVRDEProperty('VNCPassword', str(password)) mutable.VRDEServer.setVRDEProperty('TCP/Ports', str(port)) mutable.VRDEServer.enabled = True mutable.saveSettings() self.session.unlockMachine() except Exception, e: Log.e(getExceptionInfo(e)) return
def update(self, table, name, value, **kwargs): model = QSqlTableModel(self, self.db) model.setTable(table) modelFilter = '' for key in kwargs: if len(modelFilter) != 0: modelFilter += 'and' if isinstance(kwargs[key], str) or isinstance(kwargs[key], unicode): newFilter = key + "={value}".format(value="'" + kwargs[key] + "'") else: newFilter = key + "={value}".format(value=kwargs[key]) modelFilter += newFilter model.setFilter(modelFilter) model.select() if model.rowCount() == 1: record = model.record(0) record.setValue(name, value) model.setRecord(0, record) if not model.submitAll(): Log.e('更新记录失败') return False return True elif model.rowCount() == 0: Log.w('没找到相关记录, 添加新记录') self.addRecord(table, **{name: value}) else: Log.e('更新失败') return False
def updateGps(self, request): clientId = request.getParam('clientId') if not clientId: Log.e('ExternalDispatcher.updateGps: 权限不足') return if clientId not in self.server.clients: Log.e('ExternalDispatcher.updateGps: 该客户端在服务器中不存在') return EventManager.trigger(Event('DataCenter.updateGps', request['id'], request['desc'], clientId))
def queryAccount(self, request): clientId = request.getParam('clientId') if not clientId: Log.e('ExternalDispatcher.queryAccount: 权限不足') return if clientId not in self.server.clients: Log.e('ExternalDispatcher.queryAccount: 该客户端在服务器中不存在') return EventManager.trigger(Event('DataCenter.loadAllAccount', clientId))
def lastInsertRowId(self): query = QSqlQuery(self.db) if not query.exec_('SELECT last_insert_rowid()'): Log.e('获取最后插入id失败') return False if not query.next(): Log.e('获取最后插入id失败') return False return query.value(0)
def handleDeleteGpsOk(self, request): ids = request['ids'] for id_ in ids: toolBarId = application.lookUpToolBarIdByResourceId(id_) if toolBarId: EventManager.trigger(Event('ToolBar.changeState.' + toolBarId, False)) else: Log.e(u'未找到需要改变状态的ToolBar') application.delItemFromToolBar(id_)
def acceptNewClient(self): Log.i('connect in') s, addr = self.serverSocket.accept() if not s: Log.e('Cannot accept connection') return identifier = uuid.uuid4().hex self.clients[identifier] = Socket(s, identifier) self.clients[identifier].addReply(Message(cmd=Message.CMD_CLIENT_VALIDATED, clientId=identifier)) Log.i(self.clients)
def deleteGps(self, request): clientId = request.getParam('clientId') if not clientId: Log.e('ExternalDispatcher.deleteGps: 权限不足') return if clientId not in self.server.clients: Log.e('ExternalDispatcher.deleteGps: 该客户端在服务器中不存在') return EventManager.trigger( Event('DataCenter.deleteGps', request['ids'], clientId))
def reply(self): reply = self.replies.get() data = reply.dumps() if data: try: self.socket.send(bytes(str(len(data)).zfill(4)) + data) return self.WriteSuccess except Exception as e: Log.e("Can't send reply: " + getExceptionInfo(e)) return self.WriteError
def clearVmForClient(self, clientId): if clientId in self.externalToVm: for vm in self.externalToVm[clientId]: success, vmInfo = self.vm.closeMachine(vm[0]) if not success: Log.e('关闭虚拟机失败:' + vm[1]['name']) continue message = Message(cmd=Message.CMD_VM_UPDATED, vmId=vm[0], status=VirtualMachine.Status_Idle) EventManager.trigger(Event('Message.broadcast', message, ())) del self.externalToVm[clientId]
def handleDeleteGpsOk(self, request): ids = request['ids'] for id_ in ids: toolBarId = application.lookUpToolBarIdByResourceId(id_) if toolBarId: EventManager.trigger( Event('ToolBar.changeState.' + toolBarId, False)) else: Log.e(u'未找到需要改变状态的ToolBar') application.delItemFromToolBar(id_)
def addRecord(self, table, **kwargs): model = QSqlTableModel(self, self.db) model.setTable(table) record = model.record() for field in kwargs: record.setValue(field, kwargs[field]) if not model.insertRecord(-1, record): Log.e('添加记录失败') return False else: model.submitAll()
def addAccount(self, request): clientId = request.getParam('clientId') account = request['account'] if not clientId: Log.e('ExternalDispatcher.addAccount: 权限不足') return if clientId not in self.server.clients: Log.e('ExternalDispatcher.addAccount: 该客户端在服务器中不存在') return EventManager.trigger( Event('DataCenter.addAccount', account['id'], account['desc'], account['username'], account['password'], clientId))
def dispatchRequest(self, request): cmd = request.getCMD() if cmd in self.callbacks: self.callbacks[cmd](request) elif Message.CMD_BRIDGE_START <= cmd < Message.CMD_WEBCHAT_END: try: webchatId = request.getParam('webchatId') EventManager.trigger(Event('Socket.addReply.' + webchatId, request)) except Exception as e: Log.e(getExceptionInfo(e)) else: Log.w('未实现的命令: ' + str(cmd))
def addGps(self, request): clientId = request.getParam('clientId') gps = request['gps'] if not clientId: Log.e('ExternalDispatcher.updateGps: 权限不足') return if clientId not in self.server.clients: Log.e('ExternalDispatcher.updateGps: 该客户端在服务器中不存在') return EventManager.trigger( Event('DataCenter.addGps', gps['id'], gps['desc'], gps['lng'], gps['lat'], clientId))
def loads(self, message): try: message = message.decode('utf-8') except UnicodeError: Log.e('无法使用utf-8解码消息: ' + binascii.hexlify(message)) return False try: self.params = json.loads(message) Log.i('成功解析Message: ' + str(self.params)) except Exception as e: Log.e(getExceptionInfo(e)) return False return True
def updateVm(self, request): clientId = request.getParam('clientId') if not clientId: Log.e('ExternalDispatcher.updateVm: 权限不足') return if clientId not in self.server.clients: Log.e('ExternalDispatcher.updateVm: 该客户端在服务器中不存在') vmId = request['vmId'] self.vm.setGuestPropertyValue(vmId, 'desc', request['desc']) message = Message(cmd=Message.CMD_UPDATE_VM_OK, vmId=vmId) EventManager.trigger(Event('Socket.addReply.' + clientId, message)) message = Message(cmd=Message.CMD_VM_UPDATED, vmId=vmId, desc=request['desc']) EventManager.trigger(Event('Message.broadcast', message, (clientId,)))
def addAccount(self, request): clientId = request.getParam('clientId') account = request['account'] if not clientId: Log.e('ExternalDispatcher.addAccount: 权限不足') return if clientId not in self.server.clients: Log.e('ExternalDispatcher.addAccount: 该客户端在服务器中不存在') return EventManager.trigger( Event('DataCenter.addAccount', account['id'], account['desc'], account['username'], account['password'], clientId) )
def dispatchRequest(self, request): cmd = request.getCMD() if cmd in self.callbacks: self.callbacks[cmd](request) elif Message.CMD_BRIDGE_START <= cmd < Message.CMD_WEBCHAT_END: try: webchatId = request.getParam('webchatId') EventManager.trigger( Event('Socket.addReply.' + webchatId, request)) except Exception as e: Log.e(getExceptionInfo(e)) else: Log.w('未实现的命令: ' + str(cmd))
def setGuestPropertyValue(self, key, value=None): if not self.mach: return try: self.session = self.mgr.mgr.getSessionObject(self.vbox) self.mach.lockMachine(self.session, self.mgr.constants.LockType_Shared) mutable = self.session.machine mutable.setGuestPropertyValue(key, value) mutable.saveSettings() self.session.unlockMachine() return True except Exception, e: Log.e(getExceptionInfo(e))
def closeVM(self, request): clientId = request.getParam('clientId') if not clientId: Log.e('ExternalDispatcher.closeVM: 权限不足') return if clientId not in self.server.clients: Log.e('ExternalDispatcher.closeVM: 该客户端在服务器中不存在') return vmId = request.getParam('vmId') if not vmId: Log.e('ExternalDispatcher.closeVM: 缺少虚拟机Id参数') return for vm in self.externalToVm[clientId]: if vm[0] == vmId: success, vmInfo = self.vm.closeMachine(vmId) if not success: break self.externalToVm[clientId].remove(vm) message = Message(cmd=Message.CMD_VM_UPDATED, vmId=vmId, status=VirtualMachine.Status_Idle) EventManager.trigger(Event('Message.broadcast', message, ())) return True Log.e("关闭虚拟机失败")
def start(self): if self.mach is None: print u'虚拟机分配失败,无法启动' elif self.mach.state == self.mgr.constants.MachineState_Running: print u'虚拟机已经在运行中,不能重复启动' else: try: self.session = self.mgr.mgr.getSessionObject(self.vbox) self.progress = self.mach.launchVMProcess(self.session, "headless", "") self.progress.waitForCompletion(-1) self.console = self.session.console return True except Exception, e: Log.e(getExceptionInfo(e))
def createConnection(self): self.db = QSqlDatabase('QSQLITE') self.db.setHostName('localhost') homeDir = QDir().home() if not homeDir.exists('.ivy-common/'): homeDir.mkdir('.ivy-common/') self.db.setDatabaseName(QDir().homePath() + '/.ivy-common/' + self.name) self.db.setUserName('arch') self.db.setPassword('arch') if not self.db.open(): Log.e('数据库打开失败,请重启程序') return False return True
def connectToServer(self, address): """address格式为(url, port)""" if self.hasConnected(address): Log.w('已经连接到服务器') return clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) clientSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: clientSocket.connect(address) client = Client(clientSocket, -1) self.clients[client] = (address, -1) Log.i('成功连接到服务器') return True except Exception as e: Log.e(getExceptionInfo(e))
def updateVm(self, request): clientId = request.getParam('clientId') if not clientId: Log.e('ExternalDispatcher.updateVm: 权限不足') return if clientId not in self.server.clients: Log.e('ExternalDispatcher.updateVm: 该客户端在服务器中不存在') vmId = request['vmId'] self.vm.setGuestPropertyValue(vmId, 'desc', request['desc']) message = Message(cmd=Message.CMD_UPDATE_VM_OK, vmId=vmId) EventManager.trigger(Event('Socket.addReply.' + clientId, message)) message = Message(cmd=Message.CMD_VM_UPDATED, vmId=vmId, desc=request['desc']) EventManager.trigger(Event('Message.broadcast', message, (clientId, )))
def start(self): if self.mach is None: print u'虚拟机分配失败,无法启动' elif self.mach.state == self.mgr.constants.MachineState_Running: print u'虚拟机已经在运行中,不能重复启动' else: try: self.session = self.mgr.mgr.getSessionObject(self.vbox) self.progress = self.mach.launchVMProcess( self.session, "headless", "") self.progress.waitForCompletion(-1) self.console = self.session.console return True except Exception, e: Log.e(getExceptionInfo(e))
def queryVms(self, request): clientId = request.getParam('clientId') if not clientId: Log.e('ExternalDispatcher.queryVms: 权限不足') return if clientId not in self.server.clients: Log.e('ExternalDispatcher.queryVms: 该客户端在服务器中不存在') return vms = self.vm.getAllMachines() vms_ = {} for index, vmId in enumerate(vms): vm = vms[vmId] vms_[vm['name']] = {'status': vm['status'], 'vmId': vmId, 'vmType': vm['type'], 'desc': vm['desc']} message = Message(cmd=Message.CMD_QUERY_VMS_OK) message['vms'] = {'name': '服务器', 'serverId': clientId, 'desc': '', 'vms': vms_} EventManager.trigger(Event('Socket.addReply.' + clientId, message))
def data(self, index, role=None): if not index.isValid() or index.column() < 0 or index.column() > self.columnCount(): return QVariant() item = self.items[index.row()] if role == Qt.DisplayRole or role == Qt.EditRole: column = index.column() if column == AccountModel.Description: return item.description() elif column == AccountModel.Username: return str(item.username()) elif column == AccountModel.Password: return str(item.password()) else: Log.e('Unknown column index') if role == Qt.TextAlignmentRole: return Qt.AlignLeft | Qt.AlignVCenter return QVariant()
def data(self, index, role=None): if not index.isValid() or index.column() < 0 or index.column() > self.columnCount(): return QVariant() item = self.gpsItems[index.row()] if role == Qt.DisplayRole or role == Qt.EditRole: column = index.column() if column == GpsModel.Description: return item.description() elif column == GpsModel.Lng: return str(item.lng()) elif column == GpsModel.Lat: return str(item.lat()) else: Log.e('Unknown column index') if role == Qt.TextAlignmentRole: return Qt.AlignLeft | Qt.AlignVCenter return QVariant()
def editLocation(self, index, unused, roles): """同步修改到服务器,对于GPS坐标来说,客户端只能更改坐标备注""" if Qt.EditRole not in roles: self.gpsTable.update() return item = self.gpsModel.itemForIndex(index) resourceId = item.id() clientId = application.lookUpClientIdByResourceId(resourceId) if clientId: message = Message(cmd=Message.CMD_UPDATE_GPS) message['id'] = resourceId message['desc'] = item.description() EventManager.trigger(Event('Client.replyReady.' + clientId, message)) toolBarId = application.lookUpToolBarIdByResourceId(resourceId) if toolBarId: print 'ToolBar.changeState.' + toolBarId EventManager.trigger(Event('ToolBar.changeState.' + toolBarId, True)) else: Log.e(u'未找到对应的服务器,修改失败')
def dumps(self): reply = '{' if 'cmd' not in self.params: Log.e('cmd不存在') return None else: for count, name in enumerate(self.params): if count > 0: reply += ', ' reply += '"{name}": '.format(name=name) value = self.params[name] if isinstance(value, str) or isinstance(value, unicode): reply += '"{value}"'.format(value=value) else: reply += str(value) reply.rstrip(' ') reply += '}' Log.i('生成Reply: ' + reply) self.reply = bytes(reply).encode('utf-8') return self.reply
def data(self, index, role=None): if not self.rootItem or not index.isValid() or index.column() < 0 or index.column() > VMModel.ColumnCount: return QVariant() item = self.itemForIndex(index) if role == Qt.DisplayRole or role == Qt.EditRole: column = index.column() if column == VMModel.Name: return item.name() elif column == VMModel.Type: return ('站街/聊天', '提取id')[item.type()] if item.type() != -1 else '' elif column == VMModel.Description: return item.description() else: Log.e('Unknown column index') if role == Qt.TextAlignmentRole: if index.column() == VMModel.Name: return Qt.AlignLeft | Qt.AlignVCenter else: return Qt.AlignCenter
def createTable(self, table, fields): if not hasattr(self, 'db'): Log.e('数据库未连接') return False if self.isTableExist(table): Log.w(table + ' 已存在') return query = QSqlQuery(self.db) sql = 'CREATE TABLE ' + table + '(id INTEGER PRIMARY KEY' for field in fields: if fields[field] not in Database.TYPES: raise TypeError else: sql += ', ' + field + ' ' + fields[field] sql += ')' if not query.exec_(sql): Log.e('数据库' + table + '创建失败') return False
def data(self, index, role=None): if not index.isValid( ) or index.column() < 0 or index.column() > self.columnCount(): return QVariant() item = self.items[index.row()] if role == Qt.DisplayRole or role == Qt.EditRole: column = index.column() if column == AccountModel.Description: return item.description() elif column == AccountModel.Username: return str(item.username()) elif column == AccountModel.Password: return str(item.password()) else: Log.e('Unknown column index') if role == Qt.TextAlignmentRole: return Qt.AlignLeft | Qt.AlignVCenter return QVariant()