Esempio n. 1
0
 def __init__(self, script_path, site_name=None, _config=None, _gnrconfig=None, counter=None, noclean=None,
              options=None):
     global GNRSITE
     GNRSITE = self
     counter = int(counter or '0')
     self._currentPages = {}
     abs_script_path = os.path.abspath(script_path)
     if os.path.isfile(abs_script_path):
         self.site_path = os.path.dirname(abs_script_path)
     else:
         self.site_path = PathResolver().site_name_to_path(script_path)
     self.site_name = site_name or os.path.basename(self.site_path)
     if _gnrconfig:
         self.gnr_config = _gnrconfig
     else:
         self.gnr_config = self.load_gnr_config()
         self.set_environment()
         
     if _config:
         self.config = _config
     else:
         self.config = self.load_site_config()
         
     self.default_uri = self.config['wsgi?home_uri'] or '/'
     if self.default_uri[-1] != '/':
         self.default_uri += '/'
     self.mainpackage = self.config['wsgi?mainpackage']
     self.default_page = self.config['wsgi?default_page']
     self.allConnectionsFolder = os.path.join(self.site_path, 'data', '_connections')
     self.allUsersFolder = os.path.join(self.site_path, 'data', '_users')
     
     self.homepage = self.config['wsgi?homepage'] or self.default_uri + 'index'
     self.indexpage = self.config['wsgi?homepage'] or '/index'
     self._guest_counter = 0
     if not self.homepage.startswith('/'):
         self.homepage = '%s%s' % (self.default_uri, self.homepage)
     self.secret = self.config['wsgi?secret'] or 'supersecret'
     self.config['secret'] = self.secret
     self.debug = options.debug if options else boolean(self.config['wsgi?debug'])
     self.cache_max_age = self.config['wsgi?cache_max_age'] or 2592000
     self.statics = StaticHandlerManager(self)
     self.statics.addAllStatics()
     
     self.gnrapp = self.build_gnrapp()
     self.wsgiapp = self.build_wsgiapp()
     self.db = self.gnrapp.db
     self.dbstores = self.db.dbstores
     self.resource_loader = ResourceLoader(self)
     self.pages_dir = os.path.join(self.site_path, 'pages')
     self.site_static_dir = self.config['resources?site'] or '.'
     if self.site_static_dir and not os.path.isabs(self.site_static_dir):
         self.site_static_dir = os.path.normpath(os.path.join(self.site_path, self.site_static_dir))
     self.find_gnrjs_and_dojo()
     self.page_factory_lock = RLock()
     self.webtools = self.resource_loader.find_webtools()
     self.services = ServiceHandlerManager(self)
     self.print_handler = self.addService(PrintHandler, service_name='print')
     self.mail_handler = self.addService(MailHandler, service_name='mail')
     self.addSiteServices()
     self.register = SiteRegister(self)
     if counter == 0 and self.debug:
         self.onInited(clean=not noclean)
Esempio n. 2
0
class GnrWsgiSite(object):
    """add???"""
    #cache = memoize()
    def siteLock(self, **kwargs):
        """add???
        
        :returns: add???
        """
        return SiteLock(self, **kwargs)
        
    @property
    def shared_data(self):
        """add???
        
        :returns: add???
        """
        if not hasattr(self, '_shared_data'):
            memcache_config = self.config['memcache']
            if memcache_config:
                self._shared_data = GnrSharedData_memcache(self, memcache_config,
                                                           debug=self.config.getAttr('memcache').get('debug'))
            else:
                self._shared_data = GnrSharedData_dict(self)
        return self._shared_data
        
    @property
    def guest_counter(self):
        """add???
        
        :returns: add???
        """
        self._guest_counter += 1
        return self._guest_counter
        
    def log_print(self, msg, code=None):
        """add???
        
        :param msg: add??
        :param code: add???. Default value is ``None``
        """
        if getattr(self, 'debug', True):
            if code and code in OP_TO_LOG:
                print '***** %s : %s' % (code, msg)
            elif not code:
                print '***** OTHER : %s' % (msg)
                
    def __call__(self, environ, start_response):
        return self.wsgiapp(environ, start_response)
        
    def __init__(self, script_path, site_name=None, _config=None, _gnrconfig=None, counter=None, noclean=None,
                 options=None):
        global GNRSITE
        GNRSITE = self
        counter = int(counter or '0')
        self._currentPages = {}
        abs_script_path = os.path.abspath(script_path)
        if os.path.isfile(abs_script_path):
            self.site_path = os.path.dirname(abs_script_path)
        else:
            self.site_path = PathResolver().site_name_to_path(script_path)
        self.site_name = site_name or os.path.basename(self.site_path)
        if _gnrconfig:
            self.gnr_config = _gnrconfig
        else:
            self.gnr_config = self.load_gnr_config()
            self.set_environment()
            
        if _config:
            self.config = _config
        else:
            self.config = self.load_site_config()
            
        self.default_uri = self.config['wsgi?home_uri'] or '/'
        if self.default_uri[-1] != '/':
            self.default_uri += '/'
        self.mainpackage = self.config['wsgi?mainpackage']
        self.default_page = self.config['wsgi?default_page']
        self.allConnectionsFolder = os.path.join(self.site_path, 'data', '_connections')
        self.allUsersFolder = os.path.join(self.site_path, 'data', '_users')
        
        self.homepage = self.config['wsgi?homepage'] or self.default_uri + 'index'
        self.indexpage = self.config['wsgi?homepage'] or '/index'
        self._guest_counter = 0
        if not self.homepage.startswith('/'):
            self.homepage = '%s%s' % (self.default_uri, self.homepage)
        self.secret = self.config['wsgi?secret'] or 'supersecret'
        self.config['secret'] = self.secret
        self.debug = options.debug if options else boolean(self.config['wsgi?debug'])
        self.cache_max_age = self.config['wsgi?cache_max_age'] or 2592000
        self.statics = StaticHandlerManager(self)
        self.statics.addAllStatics()
        
        self.gnrapp = self.build_gnrapp()
        self.wsgiapp = self.build_wsgiapp()
        self.db = self.gnrapp.db
        self.dbstores = self.db.dbstores
        self.resource_loader = ResourceLoader(self)
        self.pages_dir = os.path.join(self.site_path, 'pages')
        self.site_static_dir = self.config['resources?site'] or '.'
        if self.site_static_dir and not os.path.isabs(self.site_static_dir):
            self.site_static_dir = os.path.normpath(os.path.join(self.site_path, self.site_static_dir))
        self.find_gnrjs_and_dojo()
        self.page_factory_lock = RLock()
        self.webtools = self.resource_loader.find_webtools()
        self.services = ServiceHandlerManager(self)
        self.print_handler = self.addService(PrintHandler, service_name='print')
        self.mail_handler = self.addService(MailHandler, service_name='mail')
        self.addSiteServices()
        self.register = SiteRegister(self)
        if counter == 0 and self.debug:
            self.onInited(clean=not noclean)
            
    def addSiteServices(self):
        """add???"""
        service_names=[]
        if 'preferences.services' in self.config:
            service_names=self.config['preferences.services'].digest('#k')
        if service_names:
            self.services.addSiteServices(service_names=service_names)
            
    def addService(self, service_handler, service_name=None, **kwargs):
        """add???
        
        :param service_handler: add???
        :param service_name: add???. Default value is ``None``
        :returns: add???
        """
        return self.services.add(service_handler, service_name=service_name, **kwargs)
        
    def getService(self, service_name):
        """add???
        
        :param service_name: add???
        :returns: add???
        """
        return self.services.get(service_name)
        
    def addStatic(self, static_handler_factory, **kwargs):
        """add???
        
        :param service_handler_factory: add???
        :returns: add???
        """
        return self.statics.add(static_handler_factory, **kwargs)
        
    def getStaticPath(self, static, *args, **kwargs):
        """add???
        
        :param static: add???
        :returns: add???
        """
        autocreate = kwargs.get('autocreate', False)
        static_name, static_path = static.split(':')
        args = self.adaptStaticArgs(static_name, static_path, args)
        dest_path = self.getStatic(static_name).path(*args)
        if autocreate:
            assert autocreate == True or autocreate < 0
            if autocreate != True:
                autocreate_args = args[:autocreate]
            else:
                autocreate_args = args
            dest_dir = self.getStatic(static_name).path(*autocreate_args)
            if not os.path.exists(dest_dir):
                os.makedirs(dest_dir)
        return dest_path
        
    def getStaticUrl(self, static, *args, **kwargs):
        """add???
        
        :param static: add???
        :returns: add???
        """
        static_name, static_url = static.split(':')
        args = self.adaptStaticArgs(static_name, static_url, args)
        if kwargs:
            return self.getStatic(static_name).kwargs_url(*args, **kwargs)
        else:
            return self.getStatic(static_name).url(*args)

    def adaptStaticArgs(self, static_name, static_path, args):
        """add???
        
        :param static_name: add???
        :param static_path: add???
        :param args: add???
        :returns: add???
        """
        args = tuple(static_path.split('/')) + args
        if static_name == 'user':
            args = (self.currentPage.user,) + args #comma does matter
        elif static_name == 'conn':
            args = (self.currentPage.connection_id) + args
        elif static_name == 'page':
            args = (self.currentPage.connection_id, self.currentPage.page_id) + args
        return args
        
    def getStatic(self, static_name):
        """add???
        
        :param static_name: add???
        :returns: add???
        """
        return self.statics.get(static_name)
        
    def exception(self, message):
        """add???
        
        :param message: add???
        :returns: add???
        """
        e = GnrSiteException(message=message)
        if self.currentPage:
            e.setLocalizer(self.currentPage.localizer)
        return e
        
        #def connFolderRemove(self, connection_id, rnd=True):
        #    shutil.rmtree(os.path.join(self.allConnectionsFolder, connection_id),True)
        #    if rnd and random.random() > 0.9:
        #        live_connections=self.register_connection.connections()
        #        connection_to_remove=[connection_id for connection_id in os.listdir(self.allConnectionsFolder) if connection_id not in live_connections and os.path.isdir(connection_id)]
        #        for connection_id in connection_to_remove:
        #            self.connFolderRemove(connection_id, rnd=False)
        #
        
    def _get_automap(self):
        return self.resource_loader.automap
        
    automap = property(_get_automap)
        
    def onInited(self, clean):
        """add???
        
        :param clean: add???
        """
        if clean:
            self.dropConnectionFolder()
            self.initializePackages()
        else:
            pass
            
    def on_reloader_restart(self):
        """add???"""
        self.shared_data.dump()
        
    def initializePackages(self):
        """add???"""
        for pkg in self.gnrapp.packages.values():
            if hasattr(pkg, 'onSiteInited'):
                pkg.onSiteInited()
                
    def resource_name_to_path(self, res_id, safe=True):
        """add???
        
        :param res_id: add???
        :param safe: boolean. add???. Default value is ``True``
        """
        project_resource_path = os.path.join(self.site_path, '..', '..', 'resources', res_id)
        if os.path.isdir(project_resource_path):
            return project_resource_path
        if 'resources' in self.gnr_config['gnr.environment_xml']:
            for path in self.gnr_config['gnr.environment_xml'].digest('resources:#a.path'):
                res_path = expandpath(os.path.join(path, res_id))
                if os.path.isdir(res_path):
                    return res_path
        if safe:
            raise Exception('Error: resource %s not found' % res_id)
            
    def find_gnrjs_and_dojo(self):
        """add???"""
        self.dojo_path = {}
        self.gnr_path = {}
        for lib, path, cdn in self.gnr_config['gnr.environment_xml.static'].digest('js:#k,#a.path,#a.cdn'):
            if lib.startswith('dojo_'):
                self.dojo_path[lib[5:]] = path
            elif lib.startswith('gnr_'):
                self.gnr_path[lib[4:]] = path
                
    def set_environment(self):
        """add???"""
        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[var] = str(value)
                
    def load_gnr_config(self):
        """add???
        
        :returns: add???
        """
        config_path = expandpath('~/.gnr')
        if os.path.isdir(config_path):
            return Bag(config_path)
        config_path = expandpath(os.path.join('/etc/gnr'))
        if os.path.isdir(config_path):
            return Bag(config_path)
        return Bag()
        
    def load_site_config(self):
        """add???"""
        site_config_path = os.path.join(self.site_path, 'siteconfig.xml')
        site_config = self.gnr_config['gnr.siteconfig.default_xml']
        path_list = []
        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:
                if path == os.path.dirname(self.site_path):
                    if site_config:
                        site_config.update(self.gnr_config['gnr.siteconfig.%s_xml' % site_template] or Bag())
                    else:
                        site_config = self.gnr_config['gnr.siteconfig.%s_xml' % site_template]
        if site_config:
            site_config.update(Bag(site_config_path))
        else:
            site_config = Bag(site_config_path)
        return site_config
        
    def _get_sitemap(self):
        return self.resource_loader.sitemap
        
    sitemap = property(_get_sitemap)
    
    def loadResource(self, pkg, *path):
        """add???
        
        :param pkg: add???
        :param \*path: add???
        :returns: add???
        """
        return self.resource_loader.loadResource(pkg, *path)
        
    def get_path_list(self, path_info):
        """add???
        
        :param path_info: add???
        :returns: add???
        """
        # No path -> indexpage is served
        if path_info == '/' or path_info == '':
            path_info = self.indexpage
        if path_info.endswith('.py'):
            path_info = path_info[:-3]
        path_list = path_info.strip('/').split('/')
        path_list = [p for p in path_list if p]
        # if url starts with _ go to static file handling
        return path_list
        
    def _get_home_uri(self):
        if self.currentPage and self.currentPage.storename:
            return '%s%s/' % (self.default_uri, self.currentPage.storename)
        else:
            return self.default_uri
            
    home_uri = property(_get_home_uri)
        
    def parse_request_params(self, params):
        """add???
        
        :param params: add???
        :returns: add???
        """
        out_dict = dict()
        for name, value in params.items():
            if name.endswith('[]'):
                out_dict.setdefault(name[:-2], []).append(value)
            else:
                out_dict[name] = value
        return out_dict
        
    def dispatcher(self, environ, start_response):
        """Main WSGI dispatcher, calls serve_staticfile for static files and self.createWebpage
        for GnrWebPages
        
        :param environ: add???
        :param start_response: add???
        :returns: add???
        """
        t = time()
        request = Request(environ)
        response = Response()
        self.external_host = self.config['wsgi?external_host'] or request.host_url
        # Url parsing start
        path_list = self.get_path_list(request.path_info)
        if path_list == ['favicon.ico']:
            path_list = ['_site', 'favicon.ico']
            self.log_print('', code='FAVICON')
            # return response(environ, start_response)
            
        request_kwargs = self.parse_request_params(request.params)
        request_kwargs.pop('_no_cache_', None)
        storename = None
        #print 'site dispatcher: ',path_list
        
        if path_list[0] in self.dbstores:
            storename = path_list.pop(0)
        if path_list[0] == '_ping':
            self.log_print('kwargs: %s' % str(request_kwargs), code='PING')
            result = self.serve_ping(response, environ, start_response, **request_kwargs)
            if not isinstance(result, basestring):
                return result
            response = self.setResultInResponse(result, response, totaltime=time() - t)
            return response(environ, start_response)
            
        if path_list and path_list[0].startswith('_tools'):
            self.log_print('%s : kwargs: %s' % (path_list, str(request_kwargs)), code='TOOLS')
            return self.serve_tool(path_list, environ, start_response, **request_kwargs)
        elif path_list and path_list[0].startswith('_'):
            self.log_print('%s : kwargs: %s' % (path_list, str(request_kwargs)), code='STATIC')
            return self.statics.static_dispatcher(path_list, environ, start_response, **request_kwargs)
        else:
            self.log_print('%s : kwargs: %s' % (path_list, str(request_kwargs)), code='RESOURCE')
            if self.debug:
                try:
                    page = self.resource_loader(path_list, request, response, environ=environ)
                except httpexceptions.HTTPException, exc:
                    return exc.wsgi_application(environ, start_response)
            else: