Example #1
0
 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)
Example #2
0
 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)
Example #3
0
 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)
Example #4
0
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()
Example #5
0
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)
Example #6
0
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()
Example #7
0
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')
Example #8
0
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()
Example #9
0
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)
Example #10
0
    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)
Example #11
0
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")