def register_for_in_process(self, session_func, sqla_declarative_base): self._json_caller = JsonCaller( session_func, sqla_declarative_base, configuration.get("DownloadSite", "base_url")) self._register_service_for_in_process(self.indicators) self._register_service_for_in_process(self.filters) self._register_service_for_in_process(self.employees)
def main(self): server = HTTPServer( ('', int(configuration.get("DownloadSite", "port"))), MyHandler) while True: server.handle_request()
def open_a_file_on_os(filepath): if filepath.endswith(".pdf"): pdf_cmd = configuration.get('Programs', 'pdf_viewer') mainlog.debug("Opening PDF {} with {}".format(filepath, pdf_cmd)) if pdf_cmd: # Start our own viewer (which is way faster than acrobat) p1 = subprocess.Popen([pdf_cmd, filepath]) p1.wait() else: os.startfile(filepath) return if sys.platform.startswith('darwin'): subprocess.call(('open', filepath)) elif os.name == 'nt': if filepath.endswith(".docx"): import win32com.client # See http://stackoverflow.com/questions/26907177/key-error-while-using-cx-freeze-for-making-exe # word = win32com.delivery_slips.gencache.EnsureDispatch('Word.Application') word = win32com.client.dynamic.Dispatch('Word.Application') word.Visible = True doc = word.Documents.Open(filepath) else: os.startfile(filepath) elif os.name == 'posix': subprocess.call(('xdg-open', filepath))
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 open_pdf(filename): # os.startfile(tmpfile[1]) # Use the OS's default PDF viewer pdf_cmd = configuration.get('Programs', 'pdf_viewer') mainlog.debug("Opening PDF {} with {}".format(filename, pdf_cmd)) if pdf_cmd: # Start our own viewer (which is way faster than acrobat) p1 = subprocess.Popen([pdf_cmd, filename]) p1.wait()
def show_intro(self): self._log("<b>This is {} !".format(configuration.get( "Globals", "name"))) self._log("<b>" + copyright()) self._log("<b>" + license_short()) self._log("") if platform.system() == "Windows" and not isUserAdmin(): self._log_warning( "You don't have amdinistrative rights ! Therefore some of the functionality in this program won't work." ) self._log( "To change that, use the 'run as administrator' functionality of Windows. Right-click on the {} admnististration program in the start menu and select 'run as administrator'" .format(configuration.get("Globals", "name"))) if self.check_backup_directory() != True: self._log_error("The backup directory is not correct !")
def instanciate_template(tpl_id): urlopener = build_opener(HTTPHandler(), HTTPSHandler()) url = configuration.get( "DownloadSite", "base_url") + "/instanciate_template?tpl_id={}".format(tpl_id) op = urlopener.open(url) doc_id = int(op.read().decode()) op.close() return doc_id
def create_root_account(self): if not configuration.get("Database", "url"): self._log_error("Can't read Database/url ini config file") return login = "******" password = "******" self._clear_log() self._log("<b>Creating or recreating a root account") try: init_db_session(configuration.get("Database", "url")) create_root_account(login, password) self._log_success( "Root account successfully reset to login:{}, password:{}". format(login, password)) except Exception as ex: self._log_error("Root account creation failed") self._log_error(ex)
def __init__(self, parent, user_session): super(LoginDialog, self).__init__(parent) self.user = None self.user_session = user_session title = _("{} Login").format(configuration.get("Globals", "name")) self.setWindowTitle(title) self.title_widget = TitleWidget(title, self) self.userid = QLineEdit() self.password = QLineEdit() self.password.setEchoMode(QLineEdit.Password) self.remember_me = QCheckBox() form_layout = QFormLayout() form_layout.addRow(_("User ID"), self.userid) form_layout.addRow(_("Password"), self.password) form_layout.addRow(_("Remember me"), self.remember_me) self.buttons = QDialogButtonBox() self.buttons.addButton(QDialogButtonBox.Ok) top_layout = QVBoxLayout() top_layout.addWidget(self.title_widget) top_layout.addWidget(QLabel(_("Please identify yourself"))) top_layout.addLayout(form_layout) top_layout.addWidget(self.buttons) self.setLayout(top_layout) # QWidget takes ownership of the layout self.buttons.accepted.connect(self.try_login) self.buttons.rejected.connect(self.cancel) self.userid.textEdited.connect(self.login_changed) if configuration.get("AutoLogin", "user"): self.remember_me.setCheckState(Qt.Checked) self.userid.setText(configuration.get("AutoLogin", "user")) self.password.setText(configuration.get("AutoLogin", "password")) mainlog.debug("__init__ login dialog")
def remove_documents(doc_ids): mainlog.debug("Deleting document {} from server".format(str(doc_ids))) urlopener = build_opener(HTTPHandler(), HTTPSHandler()) for doc_id in doc_ids: mainlog.debug("Deleting document {} from server".format(doc_id)) url = configuration.get( "DownloadSite", "base_url") + "/remove_file?file_id={}".format(doc_id) urlopener.open(url)
def check_backup_directory(self): self._log("Testing the backup directory") directory = configuration.get("Backup", "backup_directory") try: f = open(os.path.join(directory, "test_file"), "w") f.write("TestBackup") f.close() self._log("<b><font color='green'>Backup directory is fine !") return True except Exception as ex: return str(ex)
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 upgrade_client(self): d = VersionDialog(self) d.exec_() if d.result() == QDialog.Accepted: pg_url = self.public_url_edit.text() host = re.search("(@.*:)", pg_url).groups()[0].replace("@", "").replace(":", "") port = configuration.get("DownloadSite", "port") self._upgrade_client_to_version("1.0.42", pg_url, host, port)
def install_on_start_tasks(self): self.stop_server_manually() self._clear_log() self._log("<b>Installing on-start services...") self._log( "Installing backup as a scheduled task (once every night)...") cmd = [ "SCHTASKS", "/Create", "/F", "/SC", "DAILY", "/ST", "00:30", "/TN", self.BACKUP_NAME, "/TR", configuration.get("Commands", "horse_backup") ] self._run_shell(cmd)
def download_document(doc_id, progress_tracker=None, destination=None): """ Download document to a given or temporary file. The temporary file name reflects the original name and extension. :param progress_tracker: a progress tacker :param destination: Where to store the file (full path, with filename). :return: the full path to the downloaded file. You'll have to delete that file if you need to. """ url = configuration.get( "DownloadSite", "base_url") + "/download_file?file_id={}".format(doc_id) return download_file(url, progress_tracker, destination)
def install_service(self): self.stop_server_manually() self._clear_log() self._log("<b>Installing services...") self._log("Installing backup as a scheduled task...") cmd = [ "SCHTASKS", "/Create", "/F", "/SC", "DAILY", "/ST", "00:30", "/TN", "HorseDailyBackup", "/TR", configuration.get("Commands", "horse_backup") ] self._run_shell(cmd) self._log("Installing PostgreSQL as a service...") cmd = [ configuration.get("Commands", "pg_ctl"), "register", "-N", self.POSTGRESQL_SERVICE_NAME, "-D", configuration.get("Database", "db_path") ] self._run_shell(cmd) cmd = ["sc", "start", self.POSTGRESQL_SERVICE_NAME] self._run_shell(cmd) cmd = ["sc", "query", self.POSTGRESQL_SERVICE_NAME] self._run_shell(cmd) self._log("Installing server as a service...") cmd = [ configuration.get("Commands", "horse_server"), "--install", self.SERVER_NAME_SUFFIX ] self._run_shell(cmd) self._log("<b>Services installed") cmd = ["sc", "start", self.SERVER_NAME + self.SERVER_NAME_SUFFIX] self._run_shell(cmd)
def _save(self): try: old_server_ip = configuration.get("DEFAULT", "public_ip") cfg_path = os.path.join(get_data_dir(), "server.cfg") f = open(cfg_path, "w") f.write(self.text_edit_widget.toPlainText()) f.close() self._log._log_success( "Server configuration saved in {}".format(cfg_path)) load_configuration(cfg_path, "server_config_check.cfg") self._log._log_success("Server configuration reloaded") server_ip = configuration.get("DEFAULT", "public_ip") if old_server_ip != server_ip: self._log._log_success( "Updating IP address in the downloadable delivery_slips") inject_public_ip_in_client(server_ip) except Exception as ex: self._log._log_error( "Something went wrong while saving the configuration : {}". format(ex)) self._log._log("Reloading server configuration") import threading def open_server(url): try: urlopen(url) except ConnectionResetError as ex: pass threading.Thread(target=open_server, args=['http://127.0.0.1:8079/reload']).start()
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 default(self, attr='abc'): message = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html><head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"><style> p,h2 {text-align:center; font-family:Verdana; } table, th, td { border: 1px solid #2900af; border-collapse:collapse; padding:0; margin:0; } img {background-color:white;} </style></head> <body> <br/> <p><img src="logo.png"/></p> <br/> <table width="100%" height="1"><tr><td></td><tr/></table><br/><br/> <h2>This is the #NAME# download site !</h2> <p>The current version is <b>{version}</b>.</p> <p>To download the latest delivery_slips, <a href='/file'>click here</a>.</p> <br/><br/><br/><br/> <div style='color:grey'> <p>#COPYRIGHT#</p> <p>#LICENSE#</p> </div> </body></html> """.replace("#COPYRIGHT#", copyright()).replace("#LICENSE#", license_short()).replace( "#NAME#", configuration.get("Globals", "name")) try: message = message.replace( "{version}", configuration.get("DownloadSite", "current_version")) except Exception as ex: pass return message
def _make_path_to_document(self, doc_id, filename): # The path must be absolute because CherryPy likes it # when it serves files. doc_root = configuration.get("DocumentsDatabase", "documents_root") if not doc_root: raise Exception( "Can't find the document root directory in the configuration, so I'll be unable to locate documents.." ) fs_encoding = 'ISO-8859-1' # FIXME Put that in the server config file if os.path.supports_unicode_filenames: fs_encoding = 'UTF-8' else: mainlog.warning("File system doesn't support unicode...") fn = u"{}_{}_{}".format(configuration.get("Globals", "codename"), doc_id, filename) fn = fn.encode(fs_encoding, 'replace').decode(fs_encoding).replace('?', '_') fn = fn.replace(os.sep, '_') fn = fn.replace(' ', '_') return os.path.join(doc_root, fn)
def init_base(): init_logging() mainlog.setLevel(logging.INFO) load_configuration("server.cfg") parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, description='This is an Horse! migration script.', epilog="For example --db-url {}".format( configuration.get("Database", "admin_url"))) parser.add_argument('--db-url', default=configuration.database_url, help='Database URL') args = parser.parse_args() mainlog.info("Connecting to {}".format(args.db_url)) init_i18n() from koi.db_mapping import metadata init_db_session(args.db_url, metadata, False) # True or configuration.echo_query)
def __init__(self, parent): super(AboutDialog, self).__init__(parent) title = _("About {}...").format(configuration.get("Globals", "name")) self.setWindowTitle(title) top_layout = QVBoxLayout() self.title_widget = TitleWidget(title, self) top_layout.addWidget(self.title_widget) text = QLabel(u"{}<br/>Version : {}<br/><br/>".format( copyright(), str(configuration.this_version)) + _("""This program is given to you with a few important freedoms and duties as specified in the license below. <b>We believe they will help to make a better world</b>. They are also <b>legally binding</b> (see Free Software Foundation's website), so make sure you read the license carefully. We give you the right to <ul> <li>run the program,</li> <li>inspect it to make sure it is safe to use,</li> <li>modify it to suit your needs,</li> <li>distribute copies of it,</li> </ul> as long as you give those freedoms and duties to anybody you give this program to. """)) text.setTextFormat(Qt.RichText) text.setWordWrap(True) # text.setMaximumWidth(400) top_layout.addWidget(text) browser = QTextBrowser() browser.setLineWrapMode(QTextEdit.NoWrap) browser.setPlainText(license()) browser.setMinimumWidth(browser.document().documentLayout(). documentSize().toSize().width()) browser.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) top_layout.addWidget(browser) self.buttons = QDialogButtonBox() self.buttons.addButton(QDialogButtonBox.Ok) top_layout.addWidget(self.buttons) self.setLayout(top_layout) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject)
def show_client_dowload_page(self): import webbrowser self._log("<hr>") url = configuration.get("DownloadSite", "public_url") self._log( "<b>Opening delivery_slips download page at : {}".format(url)) if True or url: try: webbrowser.open(url) except Exception as ex: self._log_error( "Unable to open the page because of an error: {}".format( ex)) else: self._log( "Could not open the delivery_slips page because URL is empty. The configuration is not good." )
def find_highest_installed_version(): codename = configuration.get("Globals", "codename") mainlog.debug("Looking for new version of '{}' in {}".format( codename, get_data_dir())) select = re.compile(codename + r'-([0-9]+\.[0-9]+\.[0-9]+)$') highest_version = None for dirname in os.listdir(get_data_dir()): res = select.match(dirname) if res: d = os.path.join(get_data_dir(), dirname) if os.path.isdir(d): version = StrictVersion(res.group(1)) if not highest_version or version > highest_version: highest_version = version return highest_version
def base_init(): global services, json_rpc_dispatcher init_db_session(configuration.get('Database', 'url'), metadata, False or configuration.echo_query) dao.set_session(session()) json_rpc_dispatcher = HorseJsonRpc() make_server_json_server_dispatcher( json_rpc_dispatcher, JsonCallWrapper(ClockService(), JsonCallWrapper.CHERRYPY_MODE)) make_server_json_server_dispatcher( json_rpc_dispatcher, JsonCallWrapper(DocumentsService(), JsonCallWrapper.CHERRYPY_MODE)) make_server_json_server_dispatcher( json_rpc_dispatcher, JsonCallWrapper(IndicatorsService(), JsonCallWrapper.CHERRYPY_MODE)) services = Services() services.register_for_server(session, Base)
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 create_database(self, localhost=False): # If in command line, skip requesting confirmation for database creation if self.isVisible() and not self._confirm_dangerous_operation(): return self._clear_log() if not configuration.get("Database", "admin_url"): self._log_error("Can't read Database/admin_url ini config file") return if not configuration.get("Database", "url"): self._log_error("Can't read Database/url ini config file") return admin_url = configuration.get("Database", "admin_url") local_url = configuration.get("Database", "url") if check_postgres_connection(configuration.get("Database", "admin_url")): self._log("Successfuly connected to PostgreSQL server") else: self._log_error("Failed to connect to PostgreSQL server") return False self._log("<b>Creating a database") try: create_blank_database(configuration.get("Database", "admin_url"), configuration.get("Database", "url")) self._log("<b><font color='green'>Database created") except Exception as ex: self._log_error("Database creation failed") self._log_error(ex) disconnect_db() return
def _ensure_document_storage(self): doc_root = configuration.get("DocumentsDatabase", "documents_root") if not os.path.exists(doc_root) or not os.path.isdir(doc_root): raise Exception("The storage path {} is not a directory")
from koi.Configurator import init_i18n, load_configuration, configuration, resource_dir init_logging() init_i18n() load_configuration("server.cfg") from koi.db_mapping import metadata from koi.datalayer.database_session import init_db_session, db_engine, session from koi.people_admin.people_admin_mapping import * parser = argparse.ArgumentParser( description='This is an Horse! migration script.') parser.add_argument('--db-url', default=configuration.database_url, help='Database connection URL {}'.format( configuration.get("Database", "admin_url"))) from sqlalchemy import create_engine from sqlalchemy.schema import CreateTable def dump(sql, *multiparams, **params): print(sql.compile(dialect=engine.dialect)) engine = create_engine('postgresql://', strategy='mock', executor=dump) # print(CreateTable(Operation.__table__).compile(engine)) def alter_structure(): pass