def _exportDatabaseToServer( self ): ftpini = FtpIni( "ftp.ini" ) ftp = Ftp( ftpini ) try: ftp.connect() ftp.upload( "immo.db", "immo.db" ) box = InfoBox( "Immo-Datenbak exportieren", "Exportieren abgeschlossen.", "", "OK" ) box.exec_() except Exception as ex: box = ErrorBox( "File Transfer failed", "Can't export immo.db to server:\n", str(ex) ) box.exec_() finally: ftp.quit()
def updateFriendList(self, friendDict): # 拉取好友头像 friend = json.loads(friendDict["friend_info"]) ftp = Ftp() ftp.downloadfile("/home/meicorl/ChatServer/" + friend["portrait"], friend["portrait"]) ftp.quit() self.addFriend(friend["name"], friend["signature"], friend["portrait"]) # 将新添加的好友信息存入本地文件 file = open("user/" + self.userName.text() + "/friend_list.txt", "a", encoding="UTF-8") file.write(json.dumps(friend)) file.close()
def __InitFriendList(self): # 初始化好友列表 self.list.clear() self.friendList.clear() friendListPath = "./user/" + self.userName.text() + "/friend_list.txt" # 如果本地好友列表丢失,则从服务器拉取好友列表 if not os.path.exists(friendListPath): ftp = Ftp() ftp.downloadfile( "/home/meicorl/ChatServer/user/" + self.userName.text() + "/friend_list.txt", friendListPath) ftp.quit() if os.path.exists(friendListPath): file = open(friendListPath, encoding='UTF-8') while 1: line = file.readline() if not line: break friend = json.loads(line) self.addFriend(friend["name"], friend["signature"], friend["portrait"]) file.close()
def __login(self): self.__setEnabled(True) Room.user_name = self.userName.text() FriendWind.user_name = self.userName.text() # 更新窗口标题和Icon home_path = "user/" + self.userName.text() + "/self_info.txt" if not os.path.exists(home_path): ftp = Ftp() ftp.downloadfile( "/home/meicorl/ChatServer/user/" + self.userName.text() + "/self_info.txt", home_path) ftp.quit() file = open(home_path, encoding='UTF-8') line = file.readline() file.close() self_info = json.loads(line) self.setWindowTitle(self_info["name"] + "(" + self_info["signature"] + ")") self.setWindowIcon(QIcon(self_info["portrait"])) # 初始化好友列表 self.list.setEnabled(True) self.__InitFriendList()
def _importDatabaseFromServer( self ): ftpini = FtpIni( "ftp.ini" ) dlg = QInputDialog() dlg.move( self._mainwin.cursor().pos() ) name, ok = dlg.getText( self._mainwin, "Immo-Datenbank importieren", "Datenbank wird ins Verzeichnis\n\n'%s'\n\n importiert.\n\n" "<<<<Sie wird nicht für die laufende Anwendung verwendet!!>>>>\n\n" "Lokalen Namen für die Datenbank angeben: " % ftpini.getLocalPath(), QLineEdit.Normal, "immo.db.imported" ) if not ( ok and name ): return ftp = Ftp( ftpini ) try: ftp.connect() ftp.download( "immo.db", name ) box = InfoBox( "Immo-Datenbak importieren", "Importieren abgeschlossen.", "", "OK" ) box.move( self._mainwin.cursor().pos() ) box.exec_() except Exception as ex: box = ErrorBox( "File Transfer failed", "Can't export immo.db to server:\n", str( ex ) ) box.exec_() finally: ftp.quit()
class IccStateHandler: """ IccFileTransfer handles all ftp up- and downloads concerning the ImmoControlCenter application. - beauskunftet den Status der immo-Datenbanken a) auf dem Server b) lokal using file immo_state. Uploads and downloads immo_state and immo.db. Structure of file immo_state: state=not_in_use last_update=2021-04-22 - processes up- and donwloads as needed """ attributename_state = "state" attributename_lastupdate = "last_update" state_in_use = "in_use" state_not_in_use = "not_in_use" state_last_update_unknown = "unknown" immostate_sep = "=" def __init__(self, ftpini_pathnfile: str): self._ftpini_pathnfile = ftpini_pathnfile self.immostate_filename = "immo_state" # remote and local filename self.immostate_localfilename_tmp = "immo_state.tmp" # local name after download self.immo_dbname = "immo.db" # remote and local filename self._ftp: Ftp = None self._ftpini: FtpIni = None self.currentState: ImmoState = None def startApplication(self): """ Connects to FTP-Server. Checks state. Downloads database. Might throw exception. Don't forget calling stopApplication before exiting the application. :return: """ if self._ftp: # FTP connection already established return # get paths and filenames needed to establish a FTP connection: self._ftpini = FtpIni(self._ftpini_pathnfile) # initialize Ftp class and connect to FTP server self._ftp = Ftp(self._ftpini) self._ftp.connect() # for comparing purposes download serverside immo_state try: serverstate: ImmoState = self._getServerState() except Exception as ex: raise Exception( "IccStateHandler.startApplication():\nCan't get serverside state:\n%s" % str(ex)) if serverstate.isInUse: raise Exception( "IccStateHandler.startApplication():\nCan't start application - Database is in use" ) try: localstate: ImmoState = self._getLocalState() except Exception as ex: raise Exception( "IccStateHandler.startApplication():\nCan't get local state:\n%s" % str(ex)) # compare serverside and locas last updates and raise exception if local last update is newer than # serverside last update if serverstate.lastUpdate < localstate.lastUpdate: raise Exception( "IccStateHandler.startApplication():\n" "Expected serverside last update to be newer than local last update but found:\n" "serverside = %s -- local = %s" % (serverstate.lastUpdate, localstate.lastUpdate)) else: # Everything is okay. We may download the serverside database now for local use. try: self._ftp.download(self.immo_dbname, self.immo_dbname) except Exception as ex: raise Exception("IccStateHandler.startApplication():\n" "Download of serverside immo.db failed:\n%s" % str(ex)) # Set is-in-use state in local and serverside immo_state files. # Attribute last_update remains unchanged. localstate.isInUse = True try: self._setStateAndSave(localstate) except Exception as ex: raise Exception( "IccStateHandler.startApplication():\n" "After download of serverside immo.db:\nFailed to set state:\n%s" % str(ex)) def stopApplication(self): """ Uploads database Sets state and last_update attributes in immo_state. Uploads immo_state Disconnects from FTP-Server Might throw exception. :return: """ try: self._ftp.upload(self.immo_dbname, self.immo_dbname) except Exception as ex: raise Exception("IccStateHandler.stopApplication():\n" "Upload immo.db failed:\n%s" % str(ex)) state = ImmoState() state.isInUse = False state.lastUpdate = datehelper.getCurrentTimestampIso() try: self._setStateAndSave(state) except Exception as ex: raise Exception( "IccStateHandler.stopApplication():\n" "After upload of local immo.db:\nFailed to set state:\n%s" % str(ex)) self._ftp.quit() self._ftp = None def _getServerState(self) -> ImmoState: self._ftp.download(self.immostate_filename, self.immostate_localfilename_tmp) localpathnfile_tmp = self._ftpini.getLocalPath( ) + self.immostate_localfilename_tmp serverstate: ImmoState = self._readAttributesFromState( localpathnfile_tmp) return serverstate def _setStateAndSave(self, immoState: ImmoState) -> None: state = self.state_in_use if immoState.isInUse else self.state_not_in_use last_update = immoState.lastUpdate stateline = self.attributename_state + self.immostate_sep + state lastupdateline = self.attributename_lastupdate + self.immostate_sep + last_update self._setLocalAndServerStateAndSave([stateline, "\n", lastupdateline]) def _setLocalAndServerStateAndSave(self, lines: list) -> None: """ :param lines: attribute names and values to write into immo_state :return: """ pathnfile = self._ftpini.getLocalPath() + self.immostate_filename try: with open(pathnfile, "w") as statefile: for line in lines: statefile.write(line) except Exception as ex: raise Exception( "IccStateHandler._setLocalAndServerStateAndSave():\n" "Local storage of file immo_state failed.\n%s" % str(ex)) try: self._ftp.upload(self.immostate_filename, self.immostate_filename) except Exception as ex: raise Exception( "IccStateHandler._setLocalAndServerStateAndSave():\n" "Serverside storage of file immo_state failed.\n%s" % str(ex)) def _getLocalState(self) -> ImmoState: """ gets state attributes from local immo_state file :return: """ localpathnfile = self._ftpini.getLocalPath() + self.immostate_filename localstate: ImmoState = self._readAttributesFromState(localpathnfile) return localstate def _readAttributesFromState(self, pathnfile: str) -> ImmoState: """ provides informations "database last update" and "database is in use" from file <pathnfile> :param pathnfile: immo_state file server or local side in the prescribed structure (see class comment) :return: an ImmoState object containing the attributes found in <pathnfile> """ immostate = ImmoState() serverstatefile = open(pathnfile, "r") content = serverstatefile.read() serverstatefile.close() lines = content.splitlines() for line in lines: parts = line.split( self.immostate_sep) # list like so: ['state', 'not_in_use'] if len(parts) != 2: raise Exception( "IccFileTransfer._readAttributesFromState: Attribute invalid\n" "Expected <attribute_name>=<attribute_value> -- found: %s" % parts) if parts[0] == self.attributename_state: immostate.isInUse = True if parts[ 1] == self.state_in_use else False elif parts[0] == self.attributename_lastupdate: immostate.lastUpdate = parts[1] return immostate