def set_public_ip(self): d = AskIPAddress(self) d.exec_() guessed_ip = d.address.text() ip_in_zip = load_public_ip() if ip_in_zip != guessed_ip: if confirmationBox( _("Setting IP addresse in delivery_slips zip"), _("The IP address configured in the zipped delivery_slips ({}) is not the " + "same as the one you gave ({}). Maybe the server has " + "changed network. Should I fix that ?").format( ip_in_zip, guessed_ip)): inject_public_ip_in_client(guessed_ip) server_ip = configuration.get("DEFAULT", "public_ip") if guessed_ip != server_ip: if confirmationBox( _("Setting IP addresse in server configuration"), _("The IP address configured for the server ({}) is not the " + "same as the one you gave ({}). Maybe the server has " + "changed network. Should I fix that ?").format( server_ip, guessed_ip)): configuration.set("DEFAULT", "public_ip", guessed_ip) configuration.save() window.edit_config.load_configuration()
def init_configuration(): p = path_to_config("server.cfg") if not os.path.exists(p): ps = os.path.join(resource_dir, "server_config_check.cfg") if os.path.exists(ps): make_empty_configuration_file(p, ps) load_configuration_server(p, ps) configuration.set_server_network_address( ip_or_host=guess_server_url(), port=8079, overwrite=True) set_default_document_root(configuration) configuration.save() mainlog.info("Configuration file created at {}".format(p)) return True else: mainlog.error( "Can't find the specification configuration file, there : {}". format(ps)) return False else: mainlog.error( "Can't initialize configuration file because it already exists, there : {}" .format(p)) return False
def upgrade_mediafire(version): """ Upgrade to the given version. The upgrades will be downloaded from mediafire. The version can be higher or lower than the current one. This allows to downgrade (in case of a failed upgrade) """ codename = configuration.get("Globals", "codename") filename = "{}-{}.zip".format(codename, version) dest = os.path.join(get_data_dir(), filename) mainlog.info("Downloading a new version {} into {} proxyport={}".format( filename, dest, configuration.get("Proxy", "proxy_port"))) client = MediaFireClient() client.login(email=configuration.get("MediaFire", "email"), password=configuration.get("MediaFire", "password"), app_id=configuration.get("MediaFire", "appid"), api_key=configuration.get("MediaFire", "sessionkey")) client.download_file("mf:/" + filename, dest) configuration.set("DownloadSite", "current_version", str(version)) configuration.set("DownloadSite", "client_path", dest) configuration.save() return
def save_and_accept(self): super(EditConfigurationDialog, self).accept() configuration.font_select = self.font_select.isChecked() configuration.set_server_network_address( self.server_address.text().strip(), overwrite=True) configuration.save() showWarningBox( _("Restart needed"), _("The modifications you have requested needs a restart of the application to be applied. They will take effect when you restart the application." )) self.deleteLater()
def initialize_session(self): # if not user_session.is_active(): # the configuration may have forced a user self.user_session.open(self.user) if self.remember_me.checkState() == Qt.Checked: configuration.set("AutoLogin", "user", self.user_session.login) configuration.set("AutoLogin", "password", self.password.text()) configuration.save() elif configuration.get("AutoLogin", "user") or configuration.get( "AutoLogin", "password"): configuration.set("AutoLogin", "user", "") configuration.set("AutoLogin", "password", "") configuration.save()
def upgrade_http(version, url, proxy_url=None, proxy_port=None): codename = configuration.get("Globals", "codename") filename = "{}-{}.zip".format(codename, version) dest = os.path.join(get_data_dir(), filename) mainlog.info( "Upgrading from {} to version {}. File will be sotred in {}".format( url, version, dest)) http_download(url, dest, configuration.get("Proxy", "proxy_url"), configuration.get("Proxy", "proxy_port")) configuration.set("DownloadSite", "current_version", str(version)) configuration.set("DownloadSite", "client_path", dest) configuration.save() return "Successfully downloaded version {} from {}. Config was updated.".format( str(version), url)
def upgrade_file(path): global configuration re_file = re.compile(r'koi-delivery_slips-([0-9]+\.[0-9]+\.[0-9]+)\.zip') exe_filename = "{}/{}.exe".format(configuration.get("Globals", "codename"), configuration.get("Globals", "codename")) if os.path.exists(path): match = re_file.match(os.path.basename(path)) if match: version = match.groups()[0] candidates = [] exe_correct = False with zipfile.ZipFile(path, 'r') as zin: for item in zin.infolist(): if item.filename == exe_filename: exe_correct = True break elif ".exe" in item.filename: candidates.append(item.filename) if exe_correct: configuration.set("DownloadSite", "current_version", str(version)) configuration.set("DownloadSite", "client_path", path) configuration.save() mainlog.info( "Configuration successfully updated with delivery_slips version {}." .format(version)) mainlog.warning( "Don't forget to restart the server to take it into account !" ) return True else: mainlog.error( "Didn't find {} inside the file you've given. Possible candidates {}" .format(exe_filename, ", ".join(candidates))) else: mainlog.error( "I don't recognize the filename. It should be 'koi-delivery_slips-a.b.c.zip'." ) else: mainlog.error("The file {} was not found.".format(path)) return False
def set_default_document_root(configuration): if configuration.is_set("DocumentsDatabase", "documents_root"): d = configuration.get("DocumentsDatabase", "documents_root") else: d = None config_needs_update = False if not d: d = os.path.join(get_data_dir(), "documents") config_needs_update = True if not os.path.exists(d): os.mkdir(d) if not os.path.isdir(d): raise Exception("The path {} should be a directory".format(d)) if config_needs_update: configuration.set("DocumentsDatabase", "documents_root", d) configuration.save() return True
def set_backup_directory(self): dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.Directory) dialog.setOption(QFileDialog.ShowDirsOnly, True) dialog.setWindowTitle("Please select a backup directory") if configuration.get("Backup", "backup_directory"): dialog.setDirectory(configuration.get("Backup", "backup_directory")) if dialog.exec_(): mainlog.debug(dialog.selectedFiles()) directory = dialog.selectedFiles()[0] self._log("Testing the backup directory") try: f = open(os.path.join(directory, "test_file"), "w") f.write("TestBackup") f.close() except Exception as ex: box = QMessageBox( QMessageBox.Warning, "Unable to write into the backup directory", u"I can't write in the backup directory you selected. Have I the necessary permissions on that directory ({})? The error was : {}" .format(directory, str(ex))) box.exec_() return self.backup_directory_edit.setText(directory) configuration.set("Backup", "backup_directory", directory) self._log("Saving the backup directory in the configuration") configuration.save() dialog.close()
def restore_backup(self): self._clear_log() self._log("Restore procedure started") url = self.url_edit.text() psql_path = configuration.get("Commands", "psql") if not psql_path: self._log_error( "The Commands/psql path is not set in the server.cfg") self._log("Please fix the configuration file (on the right)") return if not configuration.get("Commands", "pg_restore"): self._log_error( "The Commands/pg_restore path is not set in the server.cfg") self._log("Please fix the configuration file (on the right)") return if not configuration.get("Backup", "backup_directory"): self._log( "The Backup/backup_directory path is not set in the server.cfg" ) self._log("I'm setting it myself.") configuration.set("Backup", "backup_directory", get_data_dir()) configuration.set("DocumentsDatabase", "documents_root", os.path.join(get_data_dir(), "documents")) configuration.save() self.edit_config.load_configuration() login_clt, password_clt, dummy, dummy, dummy = self._extract_db_params_from_url( configuration.get("Database", "url")) login_adm, password_adm, dbname, host, port = self._extract_db_params_from_url( configuration.get("Database", "admin_url")) self._log("{} / {}".format(login_adm, password_adm)) full_path_backup = None d = "" if configuration.get("Backup", "backup_directory"): d = configuration.get("Backup", "backup_directory") if platform.system() == "Windows": if configuration.get("Backup", "backup_directory"): d = configuration.get("Backup", "backup_directory") # Using the static method gives a more native FileDialog. # with support for network backup_file = QFileDialog.getOpenFileName( self, _("Please select a backup file"), d, "{} database backup (*.pgbackup)".format( configuration.get("Globals", "name")))[0] if not backup_file: self._log("Restore aborted") return full_path_backup = backup_file if not os.path.isdir(full_path_backup): self._log( "{} is not a directory, so I'll go up a level".format( full_path_backup)) full_path_backup = os.path.dirname(full_path_backup) if not os.path.isdir(full_path_backup): self._log_error( "{} is not a directory either. Aborting restore.". format(full_path_backup)) return elif platform.system() == "Linux": d = AskWindowsShare(None) d.exec_() if d.result() == QDialog.Accepted: # //192.168.0.6/postgresqlbackup script_path = "/tmp/horse_mount.sh" script = open(script_path, "w") script.write("""#!/bin/bash echo "Creating transfer directory" mkdir /tmp/backup_win echo "Unmounting previous transfer directory (can fail)" umount /tmp/backup_win echo "Mouting the backup directory" mount -t cifs -ousername={},password={} {} /tmp/backup_win """.format(d.user.text().strip(), d.password.text().strip(), d.address.text().strip())) script.close() import stat os.chmod(script_path, stat.S_IEXEC | stat.S_IWRITE | stat.S_IREAD) cmd = [ 'gksudo', '--sudo-mode', '--message', 'Allow Koi to connect to the backup server.', script_path ] # gksudo seems to like to have the DISPLAY set. So I basically copy # it from the calling environment. ret, dummy, dummy = self._run_shell( cmd, {'DISPLAY': os.environ.get('DISPLAY')}) if ret > 0: self._log_error( "The mount operation failed. Please review the parameters you've given." ) self._log_error( "Network address : {}, windows user name : {}".format( d.address.text() or "?", d.user.text() or "?")) return full_path_backup = "/tmp/backup_win" else: dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.Directory) dialog.setNameFilters(['Koi database backup (*.pgbackup)']) dialog.setWindowTitle("Please select a backup file") if configuration.get("Backup", "backup_directory"): dialog.setDirectory( configuration.get("Backup", "backup_directory")) if dialog.exec_(): full_path_backup = dialog.selectedFiles()[0] else: self._log_error( "Without proper source directory, I can't continue !") return else: self._log_error("Unsupported operating system") # At this poitn full_path_backup is the path to the backup # directory of Horse that we want to restore. # It is different than the current backup directory. if full_path_backup: full_restore(configuration, full_path_backup, backup_file, True, mainlog) self._log_success("Backup successfully restored !")
def configure_server(): mainlog.info("Configuring the server") # 'server.socket_host': '64.72.221.48', # Bind to all local addresses => Might be a security concern # But that way I don't have to look explicitly for an address # to bind to (and so this service is available outside localhost) cherrypy.config.update( {'server.socket_host': configuration.get('DownloadSite', 'host')}) cherrypy.config.update( {'server.socket_port': configuration.get('DownloadSite', 'port')}) # The auto reload thing is super dangerous in production. for example If one updates # a python file that cherrypy relies on via aptitude, then cherrypy tries to respawn # and that fails with my package set up !!! # It is also problematic when running as a Windows service cherrypy.config.update({'engine.autoreload.on': False}) cherrypy.config.update({"tools.encode.on": True}) cherrypy.config.update({"tools.encode.encoding": "utf-8"}) # cherrypy.tools.jsonify = cherrypy.Tool('before_finalize', jsonify_tool_callback, priority=30) cherrypy.config.update({"tools.json_out.handler": horse_json_handler}) # Specific for Windows service cherrypy.config.update({ 'global': { 'log.screen': False, 'engine.autoreload.on': False, 'engine.SIGHUP': None, 'engine.SIGTERM': None } }) # Static content requires absolute path conf = { '/logo.png': { "tools.staticfile.on": True, "tools.staticfile.filename": os.path.abspath(os.path.join(resource_dir, "file_server_logo.png")) } } mainlog.debug("/logo.png will be found in {}".format( conf['/logo.png']['tools.staticfile.filename'])) application = cherrypy.tree.mount(HorseWebServer(), '', conf) cherrypy.log.screen = False cherrypy.log.access_log = mainlog cherrypy.log.error_log = mainlog application.log.screen = False application.log.access_log = mainlog application.log.error_log = mainlog d = configuration.get("DocumentsDatabase", "documents_root") config_needs_update = False if not d: d = os.path.join(get_data_dir(), "documents") config_needs_update = True if not os.path.exists(d): os.mkdir(d) if not os.path.isdir(d): raise Exception("The path {} should be a directory".format(d)) if config_needs_update: mainlog.debug("Updating the configuration file") configuration.set("DocumentsDatabase", "documents_root", d) configuration.save() # import sys # from PySide.QtGui import QApplication # app = QApplication(sys.argv) mainlog.info("Done configuration")