def importXmlData(self, path): """Populates a database from an XML file :param path: the file path""" data = Bag(path) for table, pkg in data.digest('#k,#a.pkg'): for n in data[table]: self.table(table, pkg=pkg).insertOrUpdate(n.attr)
def importFile(self, fullname): try: b = Bag(fullname) except: time.sleep(10) # 4D may be still writing the file, wait some seconds and try again b = Bag(fullname) if 'transaction' in b: for tr, attr in b.digest('#v,#a'): n = tr.getNode('trigger') attr.update(n.getAttr()) self.writeTransaction(n.value, attr, file_name=fullname) else: self.writeImport(b, file_name=fullname)
def importFile(self, fullname): try: b = Bag(fullname) except: time.sleep( 10 ) # 4D may be still writing the file, wait some seconds and try again b = Bag(fullname) if 'transaction' in b: for tr, attr in b.digest('#v,#a'): n = tr.getNode('trigger') attr.update(n.getAttr()) self.writeTransaction(n.value, attr, file_name=fullname) else: self.writeImport(b, file_name=fullname)
class NewServer(object): min_args = 0 usage = '[start|stop|restart|status] [var=value]' summary = "Start this genropy application" description = """\ This command serves a genropy web application. If start/stop/restart is given, then --daemon is implied, and it will start (normal operation), stop (--stop-daemon), or do both. """ LOGGING_LEVELS = {'notset': logging.NOTSET, 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL} parser = optparse.OptionParser(usage) if hasattr(os, 'fork'): parser.add_option('--daemon', dest="daemon", action="store_true", help="Run in daemon (background) mode") parser.add_option('--pid-file', dest='pid_file', metavar='FILENAME', help="Save PID to file (default to paster.pid if running in daemon mode)") parser.add_option('-L', '--log-level', dest="log_level", metavar="LOG_LEVEL", help="Logging level", choices=LOGGING_LEVELS.keys(), default="warning") parser.add_option('--log-file', dest='log_file', metavar='LOG_FILE', help="Save output to the given log file (redirects stdout)") parser.add_option('--reload', dest='reload', action='store_true', help="Use auto-restart file monitor") parser.add_option('--noreload', dest='reload', action='store_false', help="Do not use auto-restart file monitor") parser.add_option('--debug', dest='debug', action='store_true', help="Use weberror debugger") parser.add_option('--nodebug', dest='debug', action='store_false', help="Don't use weberror debugger") parser.add_option('--profile', dest='profile', action='store_true', help="Use profiler at /__profile__ url") parser.add_option('--bonjour', dest='bonjour', action='store_true', help="Use bonjour server announcing") parser.add_option('--reload-interval', dest='reload_interval', default=1, help="Seconds between checking files (low number can cause significant CPU usage)") parser.add_option('-c', '--config', dest='config_path', help="gnrserve directory path") parser.add_option('-p', '--port', dest='port', help="Sets server listening port (Default: 8080)") parser.add_option('-H', '--host', dest='host', help="Sets server listening address (Default: 0.0.0.0)") parser.add_option('--monitor-restart', dest='monitor_restart', action='store_true', help="Auto-restart server if it dies") parser.add_option('--status', action='store_true', dest='show_status', help="Show the status of the (presumably daemonized) server") if hasattr(os, 'setuid'): # I don't think these are available on Windows parser.add_option('--user', dest='set_user', metavar="USERNAME", help="Set the user (usually only possible when run as root)") parser.add_option('--group', dest='set_group', metavar="GROUP", help="Set the group (usually only possible when run as root)") parser.add_option('--stop-daemon', dest='stop_daemon', action='store_true', help='Stop a daemonized server (given a PID file, or default paster.pid file)') parser.add_option('--verbose', dest='verbose', action='store_true', help='Verbose') parser.add_option('-s', '--site', dest='site_name', help="Use command on site identified by supplied name") parser.add_option('-n', '--noclean', dest='noclean', help="Don't perform a clean (full reset) restart", action='store_true') parser.add_option('--counter', dest='counter', help="Startup counter") _scheme_re = re.compile(r'^[a-z][a-z]+:', re.I) default_verbosity = 1 _reloader_environ_key = 'PYTHON_RELOADER_SHOULD_RUN' _monitor_environ_key = 'PASTE_MONITOR_SHOULD_RUN' possible_subcommands = ('start', 'stop', 'restart', 'status') def __init__(self, site_script=None, server_name='Genro Server', server_description='Development'): self.site_script = site_script self.server_description = server_description self.server_name = server_name (self.options, self.args) = self.parser.parse_args() enable_colored_logging(level=self.LOGGING_LEVELS[self.options.log_level]) self.load_gnr_config() self.set_environment() self.site_name = self.options.site_name or (self.args and self.args[0]) if self.site_name: if not self.gnr_config: raise ServerException( 'Error: no ~/.gnr/ or /etc/gnr/ found') self.site_path, self.site_template = self.site_name_to_path(self.site_name) self.site_script = os.path.join(self.site_path, 'root.py') if not os.path.isfile(self.site_script): raise ServerException( 'Error: no root.py in the site provided (%s)' % self.site_name) else: self.site_path = os.path.dirname(os.path.realpath(site_script)) self.init_options() def site_name_to_path(self, site_name): path_list = [] if 'sites' in self.gnr_config['gnr.environment_xml']: path_list.extend([(expandpath(path), site_template) for path, site_template in self.gnr_config['gnr.environment_xml.sites'].digest('#a.path,#a.site_template') if os.path.isdir(expandpath(path))]) if 'projects' in self.gnr_config['gnr.environment_xml']: projects = [(expandpath(path), site_template) for path, site_template in self.gnr_config['gnr.environment_xml.projects'].digest('#a.path,#a.site_template') if os.path.isdir(expandpath(path))] for project_path, site_template in projects: sites = glob.glob(os.path.join(project_path, '*/sites')) path_list.extend([(site_path, site_template) for site_path in sites]) for path, site_template in path_list: site_path = os.path.join(path, site_name) if os.path.isdir(site_path): return site_path, site_template raise ServerException( 'Error: no site named %s found' % site_name) def load_gnr_config(self): if hasattr(self.options, 'config_path') and self.options.config_path: config_path = self.options.config_path else: if sys.platform == 'win32': config_path = '~\gnr' else: config_path = '~/.gnr' config_path = self.config_path = expandpath(config_path) if os.path.isdir(config_path): self.gnr_config = Bag(config_path) else: self.gnr_config = Bag() def set_environment(self): for var, value in self.gnr_config['gnr.environment_xml'].digest('environment:#k,#a.value'): var = var.upper() if not os.getenv(var): os.environ[str(var)] = str(value) def init_options(self): self.siteconfig = self.get_config() options = self.options.__dict__ for option in options.keys(): if options.get(option, None) is None: # not specified on the command-line site_option = self.siteconfig['wsgi?%s' % option] self.options.__dict__[option] = site_option or wsgi_options.get(option) def get_config(self): site_config_path = os.path.join(self.site_path, 'siteconfig.xml') base_site_config = Bag(site_config_path) site_config = self.gnr_config['gnr.siteconfig.default_xml'] or Bag() template = site_config['site?template'] or getattr(self, 'site_template', None) if template: site_config.update(self.gnr_config['gnr.siteconfig.%s_xml' % template] or Bag()) if 'sites' in self.gnr_config['gnr.environment_xml']: for path, site_template in self.gnr_config.digest('gnr.environment_xml.sites:#a.path,#a.site_template'): if path == os.path.dirname(self.site_path): site_config.update(self.gnr_config['gnr.siteconfig.%s_xml' % site_template] or Bag()) site_config.update(Bag(site_config_path)) return site_config def set_user(self): if not hasattr(self.options, 'set_user'): # Windows case: self.options.set_user = self.options.set_group = None # @@: Is this the right stage to set the user at? self.change_user_group( self.options.set_user, self.options.set_group) if (len(self.args) > 1 and self.args[1] in self.possible_subcommands): self.cmd = self.args[1] self.restvars = self.args[2:] else: self.cmd = None self.restvars = self.args[1:] else: if (self.args and self.args[0] in self.possible_subcommands): self.cmd = self.args[0] self.restvars = self.args[1:] else: self.cmd = None self.restvars = self.args[:] def set_bonjour(self): start_bonjour(host=self.options.host, port=self.options.port, server_name=self.site_name, server_description=self.server_description, home_uri=self.siteconfig['wsgi?home_uri'] or '/') def check_cmd(self): if self.cmd not in (None, 'start', 'stop', 'restart', 'status'): raise ServerException( 'Error: must give start|stop|restart (not %s)' % self.cmd) if self.cmd == 'status' or self.options.show_status: return self.show_status() if self.cmd == 'restart' or self.cmd == 'stop': result = self.stop_daemon() if result: if self.cmd == 'restart': print "Could not stop daemon; aborting" else: print "Could not stop daemon" return result if self.cmd == 'stop': return result def check_logfile(self): if getattr(self.options, 'daemon', False): if not self.options.log_file: self.options.log_file = 'genro.log' if self.options.log_file: try: writeable_log_file = open(self.options.log_file, 'a') except IOError, ioe: msg = 'Error: Unable to write to log file: %s' % ioe raise ServerException(msg) writeable_log_file.close()
class Server(object): def __init__(self, site_name=None): self.options = attrDict() self.load_gnr_config() self.set_environment() self.site_name = site_name if self.site_name: if not self.gnr_config: raise ServerException('Error: no ~/.gnr/ or /etc/gnr/ found') self.site_path, self.site_template = self.site_name_to_path( self.site_name) self.site_script = os.path.join(self.site_path, 'root.py') if not os.path.isfile(self.site_script): raise ServerException( 'Error: no root.py in the site provided (%s)' % self.site_name) else: self.site_script = os.path.join('.', 'root.py') self.init_options() self.gnr_site = GnrWsgiSite(self.site_script, site_name=self.site_name, _config=self.siteconfig, _gnrconfig=self.gnr_config, counter=self.options.get('counter'), noclean=self.options.get('noclean'), options=self.options) @property def code_monitor(self): if not hasattr(self, '_code_monitor'): if self.options.get('reload') in ('false', 'False', False, None): self._code_monitor = None else: self._code_monitor = GnrReloaderMonitor() menu_path = os.path.join(self.site_path, 'menu.xml') site_config_path = os.path.join(self.site_path, 'siteconfig.xml') for file_path in (menu_path, site_config_path): if os.path.isfile(file_path): self._code_monitor.watch_file(file_path) config_path = expandpath(self.config_path) if os.path.isdir(config_path): for file_path in listdirs(config_path): self._code_monitor.watch_file(file_path) self._code_monitor.add_reloader_callback( self.gnr_site.on_reloader_restart) return self._code_monitor def site_name_to_path(self, site_name): path_list = [] if 'sites' in self.gnr_config['gnr.environment_xml']: path_list.extend([ (expandpath(path), site_template) for path, site_template in self.gnr_config['gnr.environment_xml.sites'].digest( '#a.path,#a.site_template') if os.path.isdir(expandpath(path)) ]) if 'projects' in self.gnr_config['gnr.environment_xml']: projects = [(expandpath(path), site_template) for path, site_template in self.gnr_config['gnr.environment_xml.projects'].digest( '#a.path,#a.site_template') if os.path.isdir(expandpath(path))] for project_path, site_template in projects: sites = glob.glob(os.path.join(project_path, '*/sites')) path_list.extend([(site_path, site_template) for site_path in sites]) for path, site_template in path_list: site_path = os.path.join(path, site_name) if os.path.isdir(site_path): return site_path, site_template raise ServerException('Error: no site named %s found' % site_name) def load_gnr_config(self): if self.options.get('config_path'): config_path = self.options['config_path'] else: if sys.platform == 'win32': config_path = '~\gnr' else: config_path = '~/.gnr' config_path = self.config_path = expandpath(config_path) if os.path.isdir(config_path): self.gnr_config = Bag(config_path) else: self.gnr_config = Bag() def set_environment(self): for var, value in self.gnr_config['gnr.environment_xml'].digest( 'environment:#k,#a.value'): var = var.upper() if not os.getenv(var): os.environ[str(var)] = str(value) def init_options(self): self.siteconfig = self.get_config() options = self.options for option in wsgi_options.keys(): if options.get(option, None) is None: # not specified on the command-line site_option = self.siteconfig['wsgi?%s' % option] self.options[option] = site_option or wsgi_options.get(option) def get_config(self): site_config_path = os.path.join(self.site_path, 'siteconfig.xml') base_site_config = Bag(site_config_path) site_config = self.gnr_config['gnr.siteconfig.default_xml'] or Bag() template = site_config['site?template'] or getattr( self, 'site_template', None) if template: site_config.update( self.gnr_config['gnr.siteconfig.%s_xml' % template] or Bag()) if 'sites' in self.gnr_config['gnr.environment_xml']: for path, site_template in self.gnr_config.digest( 'gnr.environment_xml.sites:#a.path,#a.site_template'): if path == os.path.dirname(self.site_path): site_config.update( self.gnr_config['gnr.siteconfig.%s_xml' % site_template] or Bag()) site_config.update(base_site_config) return site_config def __call__(self, environ, start_response): return self.gnr_site(environ, start_response)
class DbStoresHandler(object): """Handler for using multi-database""" def __init__(self, db): self.db = db if db.application: self.config_folder = os.path.join(db.application.instanceFolder, 'dbstores') else: self.config_folder = None self.dbstores = {} self.load_config() self.create_stores() def load_config(self): """TODO""" self.config = Bag() if self.config_folder and os.path.isdir(self.config_folder): self.config = Bag(self.config_folder)['#0'] or Bag() def save_config(self): """TODO""" config = self.config.digest('#a.file_name,#v.#0?#') try: if os.path.isdir(self.config_folder): config_files = os.listdir(self.config_folder) for config_file in config_files: filepath = os.path.join(self.config_folder, config_file) if os.path.isfile(filepath): os.remove(filepath) except OSError: pass for name, params in config: dbstore_config = Bag() dbstore_config.setItem('db', None, **params) dbstore_config.toXml(os.path.join(self.config_folder, '%s.xml' % name), autocreate=True) def create_stores(self, check=False): """TODO""" for name in self.config.digest('#a.file_name'): self.add_store(name, check=check) def add_store(self, storename, check=False,dbattr=None): """TODO :param storename: TODO :param check: TODO""" attr = dbattr or self.config.getAttr('%s_xml.db' % storename) self.dbstores[storename] = dict(database=attr.get('dbname', storename), host=attr.get('host', self.db.host), user=attr.get('user', self.db.user), password=attr.get('password', self.db.password), port=attr.get('port', self.db.port), remote_host=attr.get('remote_host'), remote_port=attr.get('remote_port')) if check: self.dbstore_align(storename) def drop_dbstore_config(self, storename): """TODO :param storename: TODO""" return self.config.pop('%s_xml' % storename) def drop_store(self,storename): config = self.drop_dbstore_config(storename) if not config: return try: self.db.dropDb(config['db?dbname']) except Exception: print Exception self.save_config() def add_dbstore_config(self, storename, dbname=None, host=None, user=None, password=None, port=None, save=True): """TODO :param storename: TODO :param dbname: the database name :param host: the database server host :param user: the username :param password: the username's password :param port: TODO :param save: TODO""" self.config.setItem('%s_xml' % storename, None, file_name=storename) self.config.setItem('%s_xml.db' % storename, None, dbname=dbname, host=host, user=user, password=password, port=port) if save: self.save_config() self.load_config() self.add_store(storename, check=True) def dbstore_check(self, storename, verbose=False): """checks if dbstore exists and if it needs to be aligned :param storename: TODO :param verbose: TODO""" with self.db.tempEnv(storename=storename): self.db.use_store(storename) changes = self.db.model.check() if changes and not verbose: return False elif changes and verbose: return changes else: #not changes return True def dbstore_align(self, storename, changes=None): """TODO :param storename: TODO :param changes: TODO. """ with self.db.tempEnv(storename=storename): changes = changes or self.db.model.check() if changes: self.db.model.applyModelChanges()
class DbStoresHandler(object): """Handler for using multi-database""" def __init__(self, db): self.db = db self.config_folder = os.path.join(db.application.instanceFolder, 'dbstores') self.dbstores = {} self.load_config() self.create_stores() def load_config(self): """add???""" self.config = Bag() if os.path.isdir(self.config_folder): self.config = Bag(self.config_folder)['#0'] or Bag() def save_config(self): """add???""" try: shutil.rmtree(self.config_folder, True) except OSError: pass for name, params in self.config.digest('#a.file_name,#v.#0?#'): dbstore_config = Bag() dbstore_config.setItem('db', None, **params) dbstore_config.toXml(os.path.join(self.config_folder, '%s.xml' % name), autocreate=True) def create_stores(self): """add???""" for name in self.config.digest('#a.file_name'): self.add_store(name) def add_store(self, storename, check=False): """add??? :param storename: add??? :param check: add???. Default value is ``False`` """ attr = self.config.getAttr('%s_xml.db' % storename) self.dbstores[storename] = dict(database=attr.get('dbname', storename), host=attr.get('host', self.db.host), user=attr.get('user', self.db.user), password=attr.get( 'password', self.db.password), port=attr.get('port', self.db.port)) if check: self.dbstore_align(storename) def drop_dbstore_config(self, storename): """add??? :param storename: add??? """ self.config.pop('%s_xml' % storename) def add_dbstore_config(self, storename, dbname=None, host=None, user=None, password=None, port=None, save=True): """add??? :param storename: add??? :param dbname: add???. Default value is ``None`` :param host: add???. Default value is ``None`` :param user: add???. Default value is ``None`` :param password: add???. Default value is ``None`` :param port: add???. Default value is ``None`` :param save: add???. Default value is ``True`` """ self.config.setItem('%s_xml' % storename, None, file_name=storename) self.config.setItem('%s_xml.db' % storename, None, dbname=dbname, host=host, user=user, password=password, port=port) if save: self.save_config() self.load_config() self.add_store(storename, check=True) def dbstore_check(self, storename, verbose=False): """checks if dbstore exists and if it needs to be aligned :param storename: add??? :param verbose: add???. Default value is ``False`` """ with self.db.tempEnv(storename=storename): self.db.use_store(storename) changes = self.db.model.check() if changes and not verbose: return False elif changes and verbose: return changes else: #not changes return True def dbstore_align(self, storename, changes=None): """add??? :param storename: add??? :param changes: add???. Default value is ``None`` """ with self.db.tempEnv(storename=storename): self.db.use_store(storename) changes = changes or self.db.model.check() if changes: self.db.model.applyModelChanges() self.db.use_store('_main_db')
class NewServer(object): min_args = 0 usage = '[start|stop|restart|status] [var=value]' summary = "Start this genropy application" description = """\ This command serves a genropy web application. If start/stop/restart is given, then --daemon is implied, and it will start (normal operation), stop (--stop-daemon), or do both. """ LOGGING_LEVELS = { 'notset': logging.NOTSET, 'debug': logging.DEBUG, 'info': logging.INFO, 'warning': logging.WARNING, 'error': logging.ERROR, 'critical': logging.CRITICAL } parser = optparse.OptionParser(usage) if hasattr(os, 'fork'): parser.add_option('--daemon', dest="daemon", action="store_true", help="Run in daemon (background) mode") parser.add_option( '--pid-file', dest='pid_file', metavar='FILENAME', help= "Save PID to file (default to paster.pid if running in daemon mode)") parser.add_option('-L', '--log-level', dest="log_level", metavar="LOG_LEVEL", help="Logging level", choices=LOGGING_LEVELS.keys(), default="warning") parser.add_option( '--log-file', dest='log_file', metavar='LOG_FILE', help="Save output to the given log file (redirects stdout)") parser.add_option('--reload', dest='reload', action='store_true', help="Use auto-restart file monitor") parser.add_option('--noreload', dest='reload', action='store_false', help="Do not use auto-restart file monitor") parser.add_option('--debug', dest='debug', action='store_true', help="Use weberror debugger") parser.add_option('--nodebug', dest='debug', action='store_false', help="Don't use weberror debugger") parser.add_option('--profile', dest='profile', action='store_true', help="Use profiler at /__profile__ url") parser.add_option('--bonjour', dest='bonjour', action='store_true', help="Use bonjour server announcing") parser.add_option( '--reload-interval', dest='reload_interval', default=1, help= "Seconds between checking files (low number can cause significant CPU usage)" ) parser.add_option('-c', '--config', dest='config_path', help="gnrserve directory path") parser.add_option('-p', '--port', dest='port', help="Sets server listening port (Default: 8080)") parser.add_option('-H', '--host', dest='host', help="Sets server listening address (Default: 0.0.0.0)") parser.add_option('--monitor-restart', dest='monitor_restart', action='store_true', help="Auto-restart server if it dies") parser.add_option( '--status', action='store_true', dest='show_status', help="Show the status of the (presumably daemonized) server") if hasattr(os, 'setuid'): # I don't think these are available on Windows parser.add_option( '--user', dest='set_user', metavar="USERNAME", help="Set the user (usually only possible when run as root)") parser.add_option( '--group', dest='set_group', metavar="GROUP", help="Set the group (usually only possible when run as root)") parser.add_option( '--stop-daemon', dest='stop_daemon', action='store_true', help= 'Stop a daemonized server (given a PID file, or default paster.pid file)' ) parser.add_option('--verbose', dest='verbose', action='store_true', help='Verbose') parser.add_option('-s', '--site', dest='site_name', help="Use command on site identified by supplied name") parser.add_option('-n', '--noclean', dest='noclean', help="Don't perform a clean (full reset) restart", action='store_true') parser.add_option('--counter', dest='counter', help="Startup counter") _scheme_re = re.compile(r'^[a-z][a-z]+:', re.I) default_verbosity = 1 _reloader_environ_key = 'PYTHON_RELOADER_SHOULD_RUN' _monitor_environ_key = 'PASTE_MONITOR_SHOULD_RUN' possible_subcommands = ('start', 'stop', 'restart', 'status') def __init__(self, site_script=None, server_name='Genro Server', server_description='Development'): self.site_script = site_script self.server_description = server_description self.server_name = server_name (self.options, self.args) = self.parser.parse_args() enable_colored_logging( level=self.LOGGING_LEVELS[self.options.log_level]) self.load_gnr_config() self.set_environment() self.site_name = self.options.site_name or (self.args and self.args[0]) if self.site_name: if not self.gnr_config: raise ServerException('Error: no ~/.gnr/ or /etc/gnr/ found') self.site_path, self.site_template = self.site_name_to_path( self.site_name) self.site_script = os.path.join(self.site_path, 'root.py') if not os.path.isfile(self.site_script): raise ServerException( 'Error: no root.py in the site provided (%s)' % self.site_name) else: self.site_path = os.path.dirname(os.path.realpath(site_script)) self.init_options() def site_name_to_path(self, site_name): path_list = [] if 'sites' in self.gnr_config['gnr.environment_xml']: path_list.extend([ (expandpath(path), site_template) for path, site_template in self.gnr_config['gnr.environment_xml.sites'].digest( '#a.path,#a.site_template') if os.path.isdir(expandpath(path)) ]) if 'projects' in self.gnr_config['gnr.environment_xml']: projects = [(expandpath(path), site_template) for path, site_template in self.gnr_config['gnr.environment_xml.projects'].digest( '#a.path,#a.site_template') if os.path.isdir(expandpath(path))] for project_path, site_template in projects: sites = glob.glob(os.path.join(project_path, '*/sites')) path_list.extend([(site_path, site_template) for site_path in sites]) for path, site_template in path_list: site_path = os.path.join(path, site_name) if os.path.isdir(site_path): return site_path, site_template raise ServerException('Error: no site named %s found' % site_name) def load_gnr_config(self): if hasattr(self.options, 'config_path') and self.options.config_path: config_path = self.options.config_path else: if sys.platform == 'win32': config_path = '~\gnr' else: config_path = '~/.gnr' config_path = self.config_path = expandpath(config_path) if os.path.isdir(config_path): self.gnr_config = Bag(config_path) else: self.gnr_config = Bag() def set_environment(self): for var, value in self.gnr_config['gnr.environment_xml'].digest( 'environment:#k,#a.value'): var = var.upper() if not os.getenv(var): os.environ[str(var)] = str(value) def init_options(self): self.siteconfig = self.get_config() options = self.options.__dict__ for option in options.keys(): if options.get(option, None) is None: # not specified on the command-line site_option = self.siteconfig['wsgi?%s' % option] self.options.__dict__[ option] = site_option or wsgi_options.get(option) def get_config(self): site_config_path = os.path.join(self.site_path, 'siteconfig.xml') base_site_config = Bag(site_config_path) site_config = self.gnr_config['gnr.siteconfig.default_xml'] or Bag() template = site_config['site?template'] or getattr( self, 'site_template', None) if template: site_config.update( self.gnr_config['gnr.siteconfig.%s_xml' % template] or Bag()) if 'sites' in self.gnr_config['gnr.environment_xml']: for path, site_template in self.gnr_config.digest( 'gnr.environment_xml.sites:#a.path,#a.site_template'): if path == os.path.dirname(self.site_path): site_config.update( self.gnr_config['gnr.siteconfig.%s_xml' % site_template] or Bag()) site_config.update(Bag(site_config_path)) return site_config def set_user(self): if not hasattr(self.options, 'set_user'): # Windows case: self.options.set_user = self.options.set_group = None # @@: Is this the right stage to set the user at? self.change_user_group(self.options.set_user, self.options.set_group) if (len(self.args) > 1 and self.args[1] in self.possible_subcommands): self.cmd = self.args[1] self.restvars = self.args[2:] else: self.cmd = None self.restvars = self.args[1:] else: if (self.args and self.args[0] in self.possible_subcommands): self.cmd = self.args[0] self.restvars = self.args[1:] else: self.cmd = None self.restvars = self.args[:] def set_bonjour(self): start_bonjour(host=self.options.host, port=self.options.port, server_name=self.site_name, server_description=self.server_description, home_uri=self.siteconfig['wsgi?home_uri'] or '/') def check_cmd(self): if self.cmd not in (None, 'start', 'stop', 'restart', 'status'): raise ServerException( 'Error: must give start|stop|restart (not %s)' % self.cmd) if self.cmd == 'status' or self.options.show_status: return self.show_status() if self.cmd == 'restart' or self.cmd == 'stop': result = self.stop_daemon() if result: if self.cmd == 'restart': print "Could not stop daemon; aborting" else: print "Could not stop daemon" return result if self.cmd == 'stop': return result def check_logfile(self): if getattr(self.options, 'daemon', False): if not self.options.log_file: self.options.log_file = 'genro.log' if self.options.log_file: try: writeable_log_file = open(self.options.log_file, 'a') except IOError, ioe: msg = 'Error: Unable to write to log file: %s' % ioe raise ServerException(msg) writeable_log_file.close()
class Server(object): def __init__(self, site_name=None): self.options = attrDict() self.load_gnr_config() self.set_environment() self.site_name = site_name if self.site_name: if not self.gnr_config: raise ServerException( 'Error: no ~/.gnr/ or /etc/gnr/ found') self.site_path, self.site_template = self.site_name_to_path(self.site_name) self.site_script = os.path.join(self.site_path, 'root.py') if not os.path.isfile(self.site_script): raise ServerException( 'Error: no root.py in the site provided (%s)' % self.site_name) else: self.site_script = os.path.join('.', 'root.py') self.init_options() self.gnr_site = GnrWsgiSite(self.site_script, site_name=self.site_name, _config=self.siteconfig, _gnrconfig=self.gnr_config, counter=self.options.get('counter'), noclean=self.options.get('noclean'), options=self.options) @property def code_monitor(self): if not hasattr(self, '_code_monitor'): if self.options.get('reload') in ('false', 'False', False, None): self._code_monitor = None else: self._code_monitor = GnrReloaderMonitor() menu_path = os.path.join(self.site_path, 'menu.xml') site_config_path = os.path.join(self.site_path, 'siteconfig.xml') for file_path in (menu_path, site_config_path): if os.path.isfile(file_path): self._code_monitor.watch_file(file_path) config_path = expandpath(self.config_path) if os.path.isdir(config_path): for file_path in listdirs(config_path): self._code_monitor.watch_file(file_path) self._code_monitor.add_reloader_callback(self.gnr_site.on_reloader_restart) return self._code_monitor def site_name_to_path(self, site_name): path_list = [] if 'sites' in self.gnr_config['gnr.environment_xml']: path_list.extend([(expandpath(path), site_template) for path, site_template in self.gnr_config['gnr.environment_xml.sites'].digest('#a.path,#a.site_template') if os.path.isdir(expandpath(path))]) if 'projects' in self.gnr_config['gnr.environment_xml']: projects = [(expandpath(path), site_template) for path, site_template in self.gnr_config['gnr.environment_xml.projects'].digest('#a.path,#a.site_template') if os.path.isdir(expandpath(path))] for project_path, site_template in projects: sites = glob.glob(os.path.join(project_path, '*/sites')) path_list.extend([(site_path, site_template) for site_path in sites]) for path, site_template in path_list: site_path = os.path.join(path, site_name) if os.path.isdir(site_path): return site_path, site_template raise ServerException( 'Error: no site named %s found' % site_name) def load_gnr_config(self): if self.options.get('config_path'): config_path = self.options['config_path'] else: if sys.platform == 'win32': config_path = '~\gnr' else: config_path = '~/.gnr' config_path = self.config_path = expandpath(config_path) if os.path.isdir(config_path): self.gnr_config = Bag(config_path) else: self.gnr_config = Bag() def set_environment(self): for var, value in self.gnr_config['gnr.environment_xml'].digest('environment:#k,#a.value'): var = var.upper() if not os.getenv(var): os.environ[str(var)] = str(value) def init_options(self): self.siteconfig = self.get_config() options = self.options for option in wsgi_options.keys(): if options.get(option, None) is None: # not specified on the command-line site_option = self.siteconfig['wsgi?%s' % option] self.options[option] = site_option or wsgi_options.get(option) def get_config(self): site_config_path = os.path.join(self.site_path, 'siteconfig.xml') base_site_config = Bag(site_config_path) site_config = self.gnr_config['gnr.siteconfig.default_xml'] or Bag() template = site_config['site?template'] or getattr(self, 'site_template', None) if template: site_config.update(self.gnr_config['gnr.siteconfig.%s_xml' % template] or Bag()) if 'sites' in self.gnr_config['gnr.environment_xml']: for path, site_template in self.gnr_config.digest('gnr.environment_xml.sites:#a.path,#a.site_template'): if path == os.path.dirname(self.site_path): site_config.update(self.gnr_config['gnr.siteconfig.%s_xml' % site_template] or Bag()) site_config.update(base_site_config) return site_config def __call__(self, environ, start_response): return self.gnr_site(environ, start_response)
def _th_menu_sources(self,pane): inattr = pane.getInheritedAttributes() th_root = inattr['th_root'] table = inattr['table'] gridId = '%s_grid' %th_root #SOURCE MENUQUERIES pane.dataController("""TH(th_root).querymanager.onChangedQuery(currentQuery); """,currentQuery='^.query.currentQuery',th_root=th_root) pane.dataController(""" genro.dlg.thIframePalette({table:'adm.userobject',palette_top:'100px',palette_right:'600px',current_tbl:tbl,current_pkg:pkg,title:title,viewResource:'ViewCustomColumn',formResource:'FormCustomColumn'}) """,tbl=table,_fired='^.handle_custom_column',pkg=table.split('.')[0],title='!!Custom columns') q = Bag() pyqueries = self._th_hook('query',mangler=th_root,asDict=True) for k,v in pyqueries.items(): pars = dictExtract(dict(v.__dict__),'query_') code = pars.get('code') q.setItem(code,None,tip=pars.get('description'),selectmethod=v,**pars) pane.data('.query.pyqueries',q) pane.dataRemote('.query.menu',self.th_menuQueries,pyqueries='=.query.pyqueries', favoriteQueryPath='=.query.favoriteQueryPath', table=table,th_root=th_root,caption='Queries',cacheTime=15) pane.dataController("TH(th_root).querymanager.queryEditor(open);", th_root=th_root,open="^.query.queryEditor") if not 'adm' in self.db.packages: return pane.dataRemote('.query.savedqueries',self.th_menuQueries, favoriteQueryPath='=.query.favoriteQueryPath', table=table,th_root=th_root,cacheTime=5,editor=False) pane.dataRemote('.query.helper.in.savedsets',self.th_menuSets, objtype='list_in',table=table,cacheTime=5) pane.dataRpc('dummy',self.db.table('adm.userobject').deleteUserObject,pkey='=.query.queryAttributes.pkey',_fired='^.query.delete', _onResult='FIRE .query.currentQuery="__newquery__";FIRE .query.refreshMenues;') #SOURCE MENUVIEWS pane.dataController("""genro.grid_configurator.loadView(gridId, (currentView || favoriteView),th_root); """, currentView="^.grid.currViewPath", favoriteView='^.grid.favoriteViewPath', gridId=gridId,th_root=th_root) q = Bag() pyviews = self._th_hook('struct',mangler=th_root,asDict=True) for k,v in pyviews.items(): prefix,name=k.split('_struct_') q.setItem(name,self._prepareGridStruct(v,table=table),caption=v.__doc__) pane.data('.grid.resource_structs',q) pane.dataRemote('.grid.structMenuBag',self.th_menuViews,pyviews=q.digest('#k,#a.caption'),currentView="=.grid.currViewPath", table=table,th_root=th_root,favoriteViewPath='=.grid.favoriteViewPath',cacheTime=30) options = self._th_hook('options',mangler=pane)() or dict() #SOURCE MENUPRINT pane.dataRemote('.resources.print.menu',self.th_printMenu,table=table,flags=options.get('print_flags'), from_resource=options.get('print_from_resource',True),cacheTime=5) #SOURCE MENUMAIL pane.dataRemote('.resources.mail.menu',self.th_mailMenu,table=table,flags=options.get('mail_flags'), from_resource=options.get('mail_from_resource',True),cacheTime=5) #SOURCE MENUACTIONS pane.dataRemote('.resources.action.menu',self.table_script_resource_tree_data, res_type='action', table=table,cacheTime=5)
class DbStoresHandler(object): """Handler for using multi-database""" def __init__(self, db): self.db = db self.config_folder = os.path.join(db.application.instanceFolder, "dbstores") self.dbstores = {} self.load_config() self.create_stores() def load_config(self): """add???""" self.config = Bag() if os.path.isdir(self.config_folder): self.config = Bag(self.config_folder)["#0"] or Bag() def save_config(self): """add???""" try: shutil.rmtree(self.config_folder, True) except OSError: pass for name, params in self.config.digest("#a.file_name,#v.#0?#"): dbstore_config = Bag() dbstore_config.setItem("db", None, **params) dbstore_config.toXml(os.path.join(self.config_folder, "%s.xml" % name), autocreate=True) def create_stores(self): """add???""" for name in self.config.digest("#a.file_name"): self.add_store(name) def add_store(self, storename, check=False): """add??? :param storename: add??? :param check: add???. Default value is ``False`` """ attr = self.config.getAttr("%s_xml.db" % storename) self.dbstores[storename] = dict( database=attr.get("dbname", storename), host=attr.get("host", self.db.host), user=attr.get("user", self.db.user), password=attr.get("password", self.db.password), port=attr.get("port", self.db.port), ) if check: self.dbstore_align(storename) def drop_dbstore_config(self, storename): """add??? :param storename: add??? """ self.config.pop("%s_xml" % storename) def add_dbstore_config(self, storename, dbname=None, host=None, user=None, password=None, port=None, save=True): """add??? :param storename: add??? :param dbname: add???. Default value is ``None`` :param host: add???. Default value is ``None`` :param user: add???. Default value is ``None`` :param password: add???. Default value is ``None`` :param port: add???. Default value is ``None`` :param save: add???. Default value is ``True`` """ self.config.setItem("%s_xml" % storename, None, file_name=storename) self.config.setItem( "%s_xml.db" % storename, None, dbname=dbname, host=host, user=user, password=password, port=port ) if save: self.save_config() self.load_config() self.add_store(storename, check=True) def dbstore_check(self, storename, verbose=False): """checks if dbstore exists and if it needs to be aligned :param storename: add??? :param verbose: add???. Default value is ``False`` """ with self.db.tempEnv(storename=storename): self.db.use_store(storename) changes = self.db.model.check() if changes and not verbose: return False elif changes and verbose: return changes else: # not changes return True def dbstore_align(self, storename, changes=None): """add??? :param storename: add??? :param changes: add???. Default value is ``None`` """ with self.db.tempEnv(storename=storename): self.db.use_store(storename) changes = changes or self.db.model.check() if changes: self.db.model.applyModelChanges() self.db.use_store("_main_db")