Esempio n. 1
0
 def build_automap(self):
     """add???"""
     def handleNode(node, pkg=None):
         attr = node.attr
         file_name = attr['file_name']
         node.attr = dict(
                 name='!!%s' % file_name.capitalize(),
                 pkg=pkg
                 )
         if attr['file_ext'] == 'py':
             node.attr['path'] = attr['rel_path']
         node.label = file_name
         if node._value is None:
             node._value = ''
             
     self.automap = DirectoryResolver(os.path.join(self.site_path, 'pages'), ext='py', include='*.py',
                                      exclude='_*,.*,*.pyc')()
                                      
     self.automap.walk(handleNode, _mode='', pkg='*')
     for package in self.site.gnrapp.packages.values():
         packagemap = DirectoryResolver(os.path.join(package.packageFolder, 'webpages'),
                                        include='*.py', exclude='_*,.*')()
         packagemap.walk(handleNode, _mode='', pkg=package.id)
         self.automap.setItem(package.id, packagemap, name=package.attributes.get('name_long') or package.id)
     self.automap.toXml(os.path.join(self.site_path, 'automap.xml'))
Esempio n. 2
0
 def rpc_getLoadedFiles(self, uploadPath=None, **kwargs):
     path = self.site.getStaticPath(uploadPath)
     result = Bag()
     b = DirectoryResolver(path)
     for i, n in enumerate(
             [(t[1], t[2]) for t in b.digest('#a.file_ext,#a.file_name,#a.abs_path') if t[0] == 'xls']):
         result.setItem('r_%i' % i, None, filename=n[0], filepath=n[1])
     return result
Esempio n. 3
0
 def rpc_getLoadedFiles(self, uploadPath=None, **kwargs):
     path = self.site.getStaticPath(uploadPath)
     result = Bag()
     b = DirectoryResolver(path)
     for i, n in enumerate(
             [(t[1], t[2]) for t in b.digest('#a.file_ext,#a.file_name,#a.abs_path') if t[0] == 'xls']):
         result.setItem('r_%i' % i, None, filename=n[0], filepath=n[1])
     return result
Esempio n. 4
0
 def updateLocalizationFiles(self,scan_all=True):
     for s in self.slots:
         if scan_all or s['destFolder'] != self.genroroot:
             locbag = Bag()
             for root in s['roots']:
                 d = DirectoryResolver(root,include='*.py,*.js')()
                 d.walk(self._updateModuleLocalization,locbag=locbag,_mode='deep',destFolder=s['destFolder'] )
             locbag.toXml(os.path.join(s['destFolder'],'localization.xml'),pretty=True,typeattrs=False, typevalue=False)
     self.buildLocalizationDict()
Esempio n. 5
0
 def updateLocalizationFiles(self, scan_all=True):
     for s in self.slots:
         if scan_all or s['destFolder'] != self.genroroot:
             locbag = Bag()
             for root in s['roots']:
                 d = DirectoryResolver(root, include='*.py,*.js')()
                 d.walk(self._updateModuleLocalization,
                        locbag=locbag,
                        _mode='deep',
                        destFolder=s['destFolder'])
             locbag.toXml(os.path.join(s['destFolder'], 'localization.xml'),
                          pretty=True,
                          typeattrs=False,
                          typevalue=False)
     self.buildLocalizationDict()
Esempio n. 6
0
 def test_2_treegrid(self, pane):
     resolver = DirectoryResolver('/')
     pane.data('.root.genropy', resolver())
     box = pane.div(height='400px',
                    margin='60px',
                    border='1px solid silver',
                    position='relative')
     tg = box.treeGrid(storepath='.root.genropy', headers=True)
     tg.column('nodecaption', header='Name')
     tg.column('rel_path', dtype='T', header='Rel Path', size=150)
     tg.column('mtime',
               dtype='DH',
               header='mtime',
               size=100,
               format='short')
     tg.column('atime',
               dtype='DH',
               header='atime',
               size=100,
               format='short')
     tg.column('ctime',
               dtype='DH',
               header='ctime',
               size=100,
               format='short')
     tg.column('size', dtype='L', header='size', size=100, format='bytes')
Esempio n. 7
0
 def main(self, root, **kwargs):
     bc = root.borderContainer(datapath='files')
     top = bc.contentPane(region='top', height='30%')
     center = bc.contentPane(region='center')
     top.button(
         'Import timer setup files',
         action="""genro.dlg.multiUploaderDialog('Upload timer setup files',
                     {uploadPath:uploadPath,onResult:function(res){genro.bp(true)}});""",
         uploadPath='site:timer_setup_importer')
     right = bc.contentPane(region='right', width='30%')
     sn = self.site.storageNode('site:timer_setup_importer')
     path_dir = sn.internal_path
     # path_file = os.sep.join([path_dir])
     resolver = DirectoryResolver(path_dir)
     top.data('.files.timer_setup_importer', resolver())
     top.tree(
         storepath='.files.timer_setup_importer',
         hideValues=False,
         autoCollapse=True,
         checkChildren=True,
         checkedPaths='.checked',
         checkedPaths_joiner='\n',
         checked_abs_path='.checked_abspath:\n',
     )
     #   labelAttribute='nodecaption')
     center.button('Import file in Database', action='FIRE .leggi')
     center.div('^.lettura')
     center.dataRpc('.lettura',
                    self.leggi,
                    _fire='^.leggi',
                    files='=.checked_abspath')
Esempio n. 8
0
 def main(self, root, **kwargs):
     root.data('tree.data', self.treedata())
     root.h1('A simple tree')
     root.tree(storepath='tree.data')
     root.h1('See the attributes with shift mouseover')
     #root.tree(storepath='tree.data',inspect='shift')
     root.tree(storepath='pages', hideValues=True, inspect='shift')
     root.data('pages', Bag(dict(root=DirectoryResolver('/'))))
Esempio n. 9
0
 def test_2_disk(self, pane):
     """Disk Directory Drag"""
     root = pane.div(height='200px', overflow='auto')
     root.data('.disk', Bag(dict(root=DirectoryResolver('/'))))
     root.tree(storepath='.disk',
               hideValues=True,
               inspect='shift',
               draggable=True,
               dragClass='draggedItem')
Esempio n. 10
0
 def treePane(self, pane):
     resolver = DirectoryResolver('/')
     pane.data('.root.genropy', resolver())
     pane.tree(storepath='.root',
               hideValues=True,
               autoCollapse=True,
               checkChildren=True,
               checkedPaths='.checked',
               checkedPaths_joiner='\n',
               checked_abs_path='.checked_abspath:\n',
               labelAttribute='nodecaption')
Esempio n. 11
0
    def build_automap(self):
        """add???"""
        def handleNode(node, pkg=None):
            attr = node.attr
            file_name = attr['file_name']
            node.attr = dict(name='!!%s' % file_name.capitalize(), pkg=pkg)
            if attr['file_ext'] == 'py':
                node.attr['path'] = attr['rel_path']
            node.label = file_name
            if node._value is None:
                node._value = ''

        self.automap = DirectoryResolver(os.path.join(self.site_path, 'pages'),
                                         ext='py',
                                         include='*.py',
                                         exclude='_*,.*,*.pyc')()

        self.automap.walk(handleNode, _mode='', pkg='*')
        for package in self.site.gnrapp.packages.values():
            packagemap = DirectoryResolver(os.path.join(
                package.packageFolder, 'webpages'),
                                           include='*.py',
                                           exclude='_*,.*')()
            packagemap.walk(handleNode, _mode='', pkg=package.id)
            self.automap.setItem(package.id,
                                 packagemap,
                                 name=package.attributes.get('name_long')
                                 or package.id)
        self.automap.toXml(os.path.join(self.site_path, 'automap.xml'))
Esempio n. 12
0
    def drawerPane(self, frame):
        b = Bag()
        frame.top.slotToolbar('*,searchOn,2',
                              height='20px',
                              datapath='main.dir')
        for k, pkgobj in self.application.packages.items():
            b.setItem('projects.%s' % k,
                      DirectoryResolver(pkgobj.packageFolder,
                                        cacheTime=10,
                                        include='*.py',
                                        exclude='_*,.*',
                                        dropext=True,
                                        readOnly=False)(),
                      caption=pkgobj.attributes.get('name_long', k))
        b.setItem('genropy',
                  DirectoryResolver(getGenroRoot(),
                                    cacheTime=10,
                                    include='*.py',
                                    exclude='_*,.*',
                                    dropext=True,
                                    readOnly=False)(),
                  caption='Genropy')

        frame.data('.directories.root', b, nodecaption='!!Folders')
        pane = frame.center.contentPane(overflow='auto')
        pane.div(padding='10px').tree(
            nodeId='drawer_tree',
            storepath='.directories',
            persist=True,
            connect_ondblclick="""var ew = dijit.getEnclosingWidget($1.target);
                                              if(ew.item && ew.item.attr.file_ext!='directory'){
                                                    genro.publish('openModuleToEditorStack',{module:ew.item.attr.abs_path})
                                              }
                                             """,
            _class='branchtree noIcon pdb_tree',
            hideValues=True,
            openOnClick=True,
            labelAttribute='nodecaption',
            font_size='')
Esempio n. 13
0
 def fileTreeTab(self, tc, mode):
     pane = tc.contentPane(title=mode, datapath='.tree_%s' % mode)
     resolver = DirectoryResolver(PATH, include='*.%s' % mode, ext=mode)
     pane.data('.data', resolver())
     pane.bagEditor(storepath='.data',
                    hideValues=True,
                    font_family='courier',
                    selectedLabelClass='selectedTreeNode',
                    selected_abs_path='.abs_path',
                    labelAttribute='name',
                    searchOn=True,
                    export=True,
                    autoCollapse=True)
Esempio n. 14
0
 def main(self, root, **kwargs):
     currdir = os.path.dirname(self.filepath)
     folder = DirectoryResolver(currdir,
                                cacheTime=10,
                                include='*.py',
                                exclude='_*,.*,%s' % self.filename,
                                dropext=True,
                                readOnly=False)()
     root.div('Package:%s' % self.package.name,
              margin='20px',
              font_size='18px',
              color='#145698')
     box = root.div(margin='20px',
                    border='2px solid #AFCBEC',
                    rounded=6,
                    padding='10px',
                    color='#444',
                    font_weight='bold',
                    _class='treecont')
     if not folder.keys():
         box.div(
             'No pages in this package: create one in folder "webpages"')
     else:
         root.style(
             '.treecont .dijitTreeLabel{cursor:pointer;} .treecont .dijitTreeLabel:hover{text-decoration:underline} '
         )
         root.data('directoryIndex.root', folder)
         root.data('directoryIndex', folder)
         box.tree(storepath='directoryIndex',
                  cursor='pointer',
                  connect_onClick="""
                         var attr = $1.attr;
                         if(attr.file_ext=='py'){
                             genro.gotoURL((window.location.pathname+'/'+attr.rel_path).replace('//','/'));
                         }
                         """,
                  labelAttribute='caption',
                  hideValues=True)
Esempio n. 15
0
 def compileSiteMenu(self, menubag, basepath=None, level=None):
     basepath = basepath or []
     level = level or 0
     result = Bag()
     level = level or 0
     for node in menubag.nodes:
         attributes = {}
         attributes.update(node.getAttr())
         currbasepath = basepath
         if 'pkg' in attributes:
             if 'dir' in attributes:
                 url_info = self.site.getUrlInfo(
                     [attributes['pkg'], attributes['dir']])
                 dirpath = os.path.join(url_info.basepath,
                                        *url_info.request_args)
                 value = DirectoryResolver(dirpath,
                                           cacheTime=10,
                                           include='*.py',
                                           exclude='__*,.*',
                                           dropext=True,
                                           readOnly=False)
                 currbasepath = [attributes['pkg'], attributes['dir']]
             else:
                 value = self.packages[attributes['pkg']].pkgMenu['#0']
         else:
             value = node.getStaticValue()
         if 'basepath' in attributes:
             newbasepath = attributes.pop('basepath')
             if newbasepath.startswith('/'):
                 currbasepath = [self.site.home_uri + newbasepath[1:]]
             else:
                 currbasepath = basepath + [newbasepath]
         if isinstance(value, Bag):
             value = self.compileSiteMenu(value,
                                          currbasepath,
                                          level=level + 1)
         elif not isinstance(value, DirectoryResolver):
             value = None
             filepath = attributes.get('file')
             if filepath:
                 if not filepath.startswith('/'):
                     attributes['file'] = os.path.join(*(currbasepath +
                                                         [filepath]))
                 else:
                     attributes[
                         'file'] = self.site.home_uri + filepath.lstrip('/')
         result.setItem(node.label, value, attributes)
     if len(result) == 1 and not level:
         result = result['#0']
     return result
Esempio n. 16
0
    def main(self,root,**kwargs):
        root.div('Ciao Silvano io sono la pagina %s' %id(self))
        root.button('Saluti al server',action='FIRE test')
        root.div('^risultato',color='green')
        root.dataRpc('risultato',self.salutiAlServer,_fired='^test')
        dirresolver = DirectoryResolver(self.site.getStaticPath('vol:dropbox'))
        root.data('dir.root',dirresolver())
        root.tree(storepath='dir')

        root.button('Fai foto da telecamera',action='FIRE camera_id=camera_id;',
                    ask=dict(title='Nome Camera',fields=[dict(name='camera_id',lbl='Camera ID')]))

        root.iframe(src='^risultato_foto')
        root.dataRpc('risultato_foto',self.faiFoto,camera_id='^camera_id')
Esempio n. 17
0
 def main(self,root):
     currdir = os.path.dirname(self.filepath)
     folder = DirectoryResolver(currdir,cacheTime=10,
                         include='*.py', 
                         exclude='_*,.*,%s' %self.filename,dropext=True,
                         readOnly=False)()
     root.div('Package:%s' % self.package.name,margin='20px',font_size='18px',color='#145698')
     box = root.div(margin='20px',border='2px solid #AFCBEC',rounded=6,
                             padding='10px',color='#444',font_weight='bold',_class='treecont')
     if not folder.keys():
         box.div('No pages in this package: create one in folder "webpages"')
     else:
         root.style('.treecont .dijitTreeLabel{cursor:pointer;} .treecont .dijitTreeLabel:hover{text-decoration:underline} ')
         root.data('directoryIndex.root',folder)
         root.data('directoryIndex',folder)
         box.tree(storepath='directoryIndex',
             cursor='pointer',
             connect_onClick="""
                         var attr = $1.attr;
                         if(attr.file_ext=='py'){
                             genro.gotoURL((window.location.pathname+'/'+attr.rel_path).replace('//','/'));
                         }
                         """,
                             labelAttribute='caption',hideValues=True)
Esempio n. 18
0
    def dirbag(self, path='', base='', include='', exclude=None, ext=''):
        if base == 'site':
            path = os.path.join(self.siteFolder, path)
        elif base == 'root':
            path = os.path.join(self.rootFolder(), path)
        else:
            path = os.path.join(self.pageFolder(), path)

        result = Bag()
        path = os.path.normpath(path)
        path = path.rstrip('/')
        if not os.path.exists(path):
            os.makedirs(path)
        result[os.path.basename(path)] = DirectoryResolver(path, include=include, exclude=exclude, dropext=True,
                                                           ext=ext)
        return result
Esempio n. 19
0
 def main(self, root, **kwargs):
     bc = root.borderContainer(datapath='diskviewer')
     left = bc.contentPane(region='top',
                           height='50%',
                           padding='4px',
                           splitter=True)
     left.data('.root.genropy', DirectoryResolver(PATH)())
     left.tree(storepath='.root',
               hideValues=True,
               selectedLabelClass='selectedTreeNode',
               selected_abs_path='.abs_path',
               labelAttribute='nodecaption',
               autoCollapse=True)
     left.dataRpc('.content', self.getContent, filepath='^.abs_path')
     bc.contentPane(region='center').pre(value='^.content',
                                         font_size='.8em')
Esempio n. 20
0
 def resourcesAtPath(self, pkg, path, ext):
     """add???
     
     :param pkg: add???
     :param path: add???
     :param ext: add???
     :returns: add???
     """
     result = Bag()
     locations = list(self.package_resourceDirs(pkg))
     for dpath in locations:
         dirpath = os.path.join(dpath, path)
         if os.path.isdir(dirpath):
             b = DirectoryResolver(dirpath, include='*.py', dropext=True)
             result.update(b, resolved=True)
     return result
Esempio n. 21
0
 def main(self, root, **kwargs):
     url_info = self.site.getUrlInfo(self.getCallArgs())
     dirpath = os.path.join(url_info.basepath, *url_info.request_args)
     bc = root.borderContainer(datapath='main')
     center = bc.contentPane(region='center', datapath='.current')
     left = bc.contentPane(region='left',
                           width='200px',
                           splitter=True,
                           background='#eee',
                           datapath='.tree',
                           overflow_y='auto')
     left.data(
         '.store',
         DirectoryResolver(dirpath,
                           cacheTime=10,
                           include='*.py',
                           exclude='_*,.*',
                           dropext=True,
                           readOnly=False)())
     center.dataFormula(
         ".url",
         "(window.location.pathname+'/'+rel_path).replace('//','/')",
         _if="file_ext=='py'",
         _else="''",
         rel_path='^.rel_path',
         file_ext='=.file_ext')
     left.tree(
         storepath='.store',
         hideValues=True,
         inspect='shift',
         labelAttribute='caption',
         getIconClass='return node.attr.iconClass || "treeNoIcon"',
         getLabelClass=
         """var _class= (node._resolver || node._value) ? 'menu_shape menu_level_0' :  'menu_shape menu_level_2';
                                         return _class""",
         isTree=False,
         selected_rel_path='main.current.rel_path',
         _class='menutree',
         openOnClick=True,
         autoCollapse=True,
         connect_ondblclick=
         'window.open(GET main.current.url,GET main.current.caption);',
         selected_caption='main.current.caption',
         selected_file_ext='main.current.file_ext')
     center.iframe(border='0px', width='100%', height='100%', src='^.url')
     return
Esempio n. 22
0
 def resourcesAtPath(self,page=None, pkg=None, path=None, ext='py'):
     """TODO
     
     :param pkg: the :ref:`package <packages>` object
     :param path: TODO
     :param ext: TODO"""
     result = Bag()
     if pkg:
         locations = list(self.package_resourceDirs(pkg))
     else:
         locations = page.resourceDirs
     for dpath in locations:
         dirpath = os.path.join(dpath, path)
         if os.path.isdir(dirpath):
             b = DirectoryResolver(dirpath, include='*.py', dropext=True)
             result.update(b, resolved=True)
     return result
Esempio n. 23
0
    def test_7_dir_resolver(self, pane):
        #d = DirectoryResolver(,cacheTime=10,include='*.py', exclude='__*,.*',dropext=True,readOnly=False)()
        pane.data(
            '.store',
            DirectoryResolver(expandpath('~/sviluppo'),
                              cacheTime=10,
                              include='*.py',
                              exclude='_*,.*',
                              dropext=True,
                              readOnly=False)())

        ddm = pane.div(height='50px', width='50px', background='lime')
        ddm.menu(action='console.log($1)',
                 modifiers='*',
                 storepath='.store',
                 _class='smallmenu',
                 id='test99menu')
Esempio n. 24
0
    def source_viewer_addFileMenu(self, pane):
        b = Bag()
        for k, pkgobj in self.application.packages.items():
            b.setItem(k,
                      DirectoryResolver(pkgobj.packageFolder,
                                        cacheTime=10,
                                        include='*.py',
                                        exclude='_*,.*',
                                        dropext=True,
                                        readOnly=False)(),
                      caption=pkgobj.attributes.get('name_long', k))

        pane.data('.directories', b)
        pane.menu(action='FIRE .new_source_viewer_page = $1.abs_path;',
                  modifiers='*',
                  storepath='.directories',
                  _class='smallmenu')
Esempio n. 25
0
class ResourceLoader(object):
    """add???"""
    def __init__(self, site=None):
        self.site = site
        self.site_path = self.site.site_path
        self.site_name = self.site.site_name
        self.gnr_config = self.site.gnr_config
        self.gnrapp = self.site.gnrapp
        self.debug = self.site.debug
        self.gnr_static_handler = self.site.getStatic('gnr')
        self.build_automap()
        self.page_factories = {}
        self.default_path = self.site.default_page and self.site.default_page.split(
            '/')

    def find_webtools(self):
        """add???"""
        def isgnrwebtool(cls):
            return inspect.isclass(cls) and issubclass(
                cls, BaseWebtool) and cls is not BaseWebtool

        tools = {}
        webtool_pathlist = []
        if 'webtools' in self.gnr_config['gnr.environment_xml']:
            for path in self.gnr_config['gnr.environment_xml'].digest(
                    'webtools:#a.path'):
                webtool_pathlist.append(expandpath(path))
        for package in self.gnrapp.packages.values():
            webtool_pathlist.append(
                os.path.join(package.packageFolder, 'webtools'))
        project_resource_path = os.path.join(self.site_path, '..', '..',
                                             'webtools')
        webtool_pathlist.append(os.path.normpath(project_resource_path))
        for path in webtool_pathlist:
            if not os.path.isdir(path):
                continue
            for tool_module in os.listdir(path):
                if tool_module.endswith('.py'):
                    module_path = os.path.join(path, tool_module)
                    try:
                        module = gnrImport(module_path, avoidDup=True)
                        tool_classes = inspect.getmembers(module, isgnrwebtool)
                        tool_classes = [(name.lower(), value)
                                        for name, value in tool_classes]
                        tools.update(dict(tool_classes))
                    except ImportError:
                        pass
        return tools

    def build_automap(self):
        """add???"""
        def handleNode(node, pkg=None):
            attr = node.attr
            file_name = attr['file_name']
            node.attr = dict(name='!!%s' % file_name.capitalize(), pkg=pkg)
            if attr['file_ext'] == 'py':
                node.attr['path'] = attr['rel_path']
            node.label = file_name
            if node._value is None:
                node._value = ''

        self.automap = DirectoryResolver(os.path.join(self.site_path, 'pages'),
                                         ext='py',
                                         include='*.py',
                                         exclude='_*,.*,*.pyc')()

        self.automap.walk(handleNode, _mode='', pkg='*')
        for package in self.site.gnrapp.packages.values():
            packagemap = DirectoryResolver(os.path.join(
                package.packageFolder, 'webpages'),
                                           include='*.py',
                                           exclude='_*,.*')()
            packagemap.walk(handleNode, _mode='', pkg=package.id)
            self.automap.setItem(package.id,
                                 packagemap,
                                 name=package.attributes.get('name_long')
                                 or package.id)
        self.automap.toXml(os.path.join(self.site_path, 'automap.xml'))

    @property
    def sitemap(self):
        """add???"""
        if not hasattr(self, '_sitemap'):
            sitemap_path = os.path.join(self.site_path, 'sitemap.xml')
            if not os.path.isfile(sitemap_path):
                sitemap_path = os.path.join(self.site_path, 'automap.xml')
            _sitemap = Bag(sitemap_path)
            _sitemap.setBackRef()
            self._sitemap = _sitemap
        return self._sitemap

    def get_page_node(self, path_list, default=False):
        """Get the deepest node in the sitemap bag associated with the given url
        
        :param path_list: add???
        :param default: add???. Default value is ``False``
        """
        def escape_path_list(path_list):
            return [p.replace('.', '\\.') for p in path_list]

        def unescape_path_list(path_list):
            return [p.replace('\\.', '.') for p in path_list]

        path_list = escape_path_list(path_list)
        page_node = self.sitemap.getDeepestNode('.'.join(path_list))
        if not page_node and self.site.mainpackage:  # try in the main package
            page_node = self.sitemap.getDeepestNode(
                '.'.join([self.site.mainpackage] + path_list))
        if page_node:
            page_node_attributes = page_node.getInheritedAttributes()
            if page_node_attributes.get('path'):
                page_node._tail_list = unescape_path_list(
                    getattr(page_node, '_tail_list', []))
                return page_node, page_node_attributes
            else:
                page_node = self.sitemap.getDeepestNode('.'.join(path_list +
                                                                 ['index']))
                if page_node:
                    page_node_attributes = page_node.getInheritedAttributes()
                    if page_node_attributes.get('path'):
                        page_node._tail_list = unescape_path_list(
                            getattr(page_node, '_tail_list', []))
                        return page_node, page_node_attributes
        if self.default_path and not default:
            page_node, page_node_attributes = self.get_page_node(
                self.default_path, default=True)
            page_node._tail_list = unescape_path_list(path_list)
            return page_node, page_node_attributes
        return None, None

    def __call__(self, path_list, request, response, environ=None):
        page_node, page_node_attributes = self.get_page_node(path_list)
        if not page_node:
            return None
        request_args = page_node._tail_list
        path = page_node_attributes.get('path')
        pkg = page_node_attributes.get('pkg')
        page_class = self.get_page_class(path=path, pkg=pkg)
        page = page_class(site=self.site,
                          request=request,
                          response=response,
                          request_kwargs=self.site.parse_request_params(
                              request.params),
                          request_args=request_args,
                          filepath=path,
                          packageId=pkg,
                          basename=path,
                          environ=environ)
        return page

    def get_page_class(self, path=None, pkg=None):
        """add???
        
        :param path: add???. Default value is ``None``
        :param pkg: add???. Default value is ``None``
        :returns: add???
        """
        if pkg == '*':
            module_path = os.path.join(self.site_path, path)
            pkg = self.site.config['packages?default']
        else:
            module_path = os.path.join(self.gnrapp.packages[pkg].packageFolder,
                                       'webpages', path)

        # if module_path in self.page_factories:
        #    return self.page_factories[module_path]
        page_module = gnrImport(module_path, avoidDup=True)
        page_factory = getattr(page_module, 'page_factory', GnrWebPage)
        custom_class = getattr(page_module, 'GnrCustomWebPage')
        py_requires = splitAndStrip(getattr(custom_class, 'py_requires', ''),
                                    ',')
        plugin_webpage_classes = self.plugin_webpage_classes(path, pkg=pkg)
        for plugin_webpage_class in plugin_webpage_classes:
            plugin_py_requires = splitAndStrip(
                getattr(plugin_webpage_class, 'py_requires', ''), ',')
            py_requires.extend(plugin_py_requires)
        page_class = cloneClass('GnrCustomWebPage', page_factory)
        page_class.__module__ = page_module
        self.page_class_base_mixin(page_class, pkg=pkg)
        page_class.dojo_version = getattr(
            custom_class, 'dojo_version',
            None) or self.site.config['dojo?version'] or '11'
        page_class.theme = getattr(
            custom_class, 'theme',
            None) or self.site.config['dojo?theme'] or 'tundra'
        page_class.gnrjsversion = getattr(
            custom_class, 'gnrjsversion',
            None) or self.site.config['gnrjs?version'] or '11'
        page_class.maintable = getattr(custom_class, 'maintable', None)
        page_class.recordLock = getattr(custom_class, 'recordLock', None)
        page_class.user_polling = int(
            getattr(custom_class, 'user_polling', None)
            or self.site.config['polling?user'] or 3)
        page_class.auto_polling = int(
            getattr(custom_class, 'auto_polling', None)
            or self.site.config['polling?auto'] or 30)
        page_class.eagers = getattr(custom_class, 'eagers', {})
        page_class.css_requires = []
        page_class.js_requires = splitAndStrip(
            getattr(custom_class, 'js_requires', ''), ',')
        page_class.pageOptions = getattr(custom_class, 'pageOptions', {})
        page_class.auth_tags = getattr(custom_class, 'auth_tags', '')
        page_class.resourceDirs = self.page_class_resourceDirs(page_class,
                                                               module_path,
                                                               pkg=pkg)
        self.page_pyrequires_mixin(page_class, py_requires)
        classMixin(page_class, custom_class, only_callables=False)
        page_class.css_requires.extend([
            x for x in splitAndStrip(getattr(custom_class, 'css_requires', ''),
                                     ',') if x
        ])
        page_class.tpldirectories = page_class.resourceDirs + [
            self.gnr_static_handler.path(page_class.gnrjsversion, 'tpl')
        ]
        page_class._packageId = pkg
        self.page_class_plugin_mixin(page_class, plugin_webpage_classes)
        self.page_class_custom_mixin(page_class, path, pkg=pkg)
        self.page_factories[module_path] = page_class
        return page_class

    def page_class_base_mixin(self, page_class, pkg=None):
        """Look for custom classes in the package
        
        :param page_classe: add???
        :param pkg: add???. Default value is ``None``
        """
        if pkg:
            package = self.gnrapp.packages[pkg]
        if package and package.webPageMixin:
            classMixin(page_class, package.webPageMixin,
                       only_callables=False)  # first the package standard
        if self.gnrapp.webPageCustom:
            classMixin(page_class,
                       self.gnrapp.webPageCustom,
                       only_callables=False)  # then the application custom
        if package and package.webPageMixinCustom:
            classMixin(page_class,
                       package.webPageMixinCustom,
                       only_callables=False)  # finally the package custom

    def plugin_webpage_classes(self, path, pkg=None):
        """Look in the plugins folders for a file named as the current webpage and get all classes
        
        :param path: add???
        :param pkg: add???. Default value is ``None``
        """
        plugin_webpage_classes = []
        path = path.split(os.path.sep)
        pkg = pkg and self.site.gnrapp.packages[pkg]
        if pkg:
            pkg_plugins = pkg.getPlugins()
            for plugin in pkg_plugins:
                pluginPagePath = os.path.join(plugin.webpages_path, *path)
                if os.path.isfile(pluginPagePath):
                    component_page_module = gnrImport(pluginPagePath,
                                                      avoidDup=True)
                    component_page_class = getattr(component_page_module,
                                                   'GnrCustomWebPage', None)
                    if component_page_class:
                        plugin_webpage_classes.append(component_page_class)
        return plugin_webpage_classes

    def page_class_plugin_mixin(self, page_class, plugin_webpage_classes):
        """Mixin the current class with the *plugin_webpage_classes* attribute
        
        :param page_class: add???
        :param plugin_webpage_classes: add???
        """
        for plugin_webpage_class in plugin_webpage_classes:
            classMixin(page_class, plugin_webpage_class, only_callables=False)

    def page_class_custom_mixin(self, page_class, path, pkg=None):
        """Look in the instance custom folder for a file named as the current webpage
        
        :param page_class: add???
        :param pkg: add???. Default value is ``None``
        """
        path = path.split(os.path.sep)
        if pkg:
            customPagePath = os.path.join(self.gnrapp.customFolder, pkg,
                                          'webpages', *path)
            if os.path.isfile(customPagePath):
                component_page_module = gnrImport(customPagePath,
                                                  avoidDup=True)
                component_page_class = getattr(component_page_module,
                                               'WebPage', None)
                if component_page_class:
                    classMixin(page_class,
                               component_page_class,
                               only_callables=False)

    def page_class_resourceDirs(self, page_class, path, pkg=None):
        """Build page resources directories
        
        :param page_class: add???
        :param pkg: add???. Default value is ``None``
        """
        if pkg:
            pagesPath = os.path.join(self.gnrapp.packages[pkg].packageFolder,
                                     'webpages')
        else:
            pagesPath = os.path.join(self.site_path, 'pages')
        curdir = os.path.dirname(os.path.join(pagesPath, path))
        resourcePkg = None
        result = []  # result is now empty
        if pkg:  # for index page or other pages at root level (out of any package)
            resourcePkg = self.gnrapp.packages[pkg].attributes.get(
                'resourcePkg')
            fpath = os.path.join(self.site_path, '_custom', pkg, '_resources')
            if os.path.isdir(fpath):
                result.append(
                    fpath
                )  # we add a custom resource folder for current package
        fpath = os.path.join(self.site_path, '_resources')

        if os.path.isdir(fpath):
            result.append(
                fpath)  # we add a custom resource folder for common package

        while curdir.startswith(pagesPath):
            fpath = os.path.join(curdir, '_resources')
            if os.path.isdir(fpath):
                result.append(fpath)
            curdir = os.path.dirname(
                curdir)  # we add a resource folder for folder
            # of current page
        if resourcePkg:
            for rp in resourcePkg.split(','):
                fpath = os.path.join(self.gnrapp.packages[rp].packageFolder,
                                     'webpages', '_resources')
                if os.path.isdir(fpath):
                    result.append(fpath)
            #result.extend(self.siteResources)
        resources_list = self.site.resources_dirs
        result.extend(resources_list)
        return result

    def package_resourceDirs(self, pkg):
        """add???
        
        :param pkg: add???
        """
        pkg = self.gnrapp.packages[pkg]
        if not hasattr(pkg, '_resourceDirs'):
            pagesPath = os.path.join(pkg.packageFolder, 'webpages')
            resourcePkg = None
            result = []  # result is now empty
            resourcePkg = pkg.attributes.get('resourcePkg')
            fpath = os.path.join(self.site_path, '_custom', pkg.id,
                                 '_resources')
            if os.path.isdir(fpath):
                result.append(
                    fpath
                )  # we add a custom resource folder for current package

            if resourcePkg:
                for rp in resourcePkg.split(','):
                    fpath = os.path.join(self.site_path, '_custom', pkg.id,
                                         '_resources')
                    if os.path.isdir(fpath):
                        result.append(fpath)
            fpath = os.path.join(pagesPath, '_resources')
            if os.path.isdir(fpath):
                result.append(
                    fpath)  # we add a resource folder for common package
            result.extend(self.site.resources_dirs)
            pkg._resourceDirs = result
            # so we return a list of any possible resource folder starting from
        # most customized and ending with most generic ones
        return pkg._resourceDirs

    def site_resources(self):
        """add???"""
        resources = Bag()
        for pkg in self.site.gnrapp.packages.values():
            rsrc_path = os.path.join(pkg.packageFolder, 'resources')
            label = 'pkg_%s' % (pkg.id)
            if os.path.isdir(rsrc_path):
                resources[label] = rsrc_path
            plugins = [p for p in pkg.getPlugins() if p.resources_path]
            for plugin in plugins:
                label = 'pkg_%s_%s' % (pkg.id, plugin.id)
                if os.path.isdir(plugin.resources_path):
                    resources[label] = plugin.resources_path

        resources_list = [(resource.label, resource.attr.get('path'))
                          for resource in self.site.config['resources'] or []]
        for label, rsrc_path in resources_list:
            if rsrc_path:
                resources[label] = rsrc_path
            else:
                rsrc_path = self.resource_name_to_path(label)
                resources[label] = rsrc_path
        auto_resource_path = self.resource_name_to_path(self.site_name,
                                                        safe=False)
        if auto_resource_path:
            resources[self.site_name] = os.path.realpath(auto_resource_path)
        return resources

    def resource_name_to_path(self, res_id, safe=True):
        """add???
        
        :param res_id: add???
        :param safe: add???. Default value is ``True``
        """
        project_resource_path = os.path.normpath(
            os.path.join(self.site_path, '..', '..', 'resources', res_id))
        if os.path.isdir(project_resource_path):
            log.debug('resource_name_to_path(%s) -> %s (project)' %
                      (repr(res_id), repr(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):
                    log.debug('resource_name_to_path(%s) -> %s (gnr config)' %
                              (repr(res_id), repr(res_path)))
                    return res_path
        log.debug('resource_name_to_path(%s) not found.' % repr(res_id))
        if safe:
            raise Exception('Error: resource %s not found' % res_id)

    def page_pyrequires_mixin(self, page_class, py_requires):
        """add???
        
        :param page_class: add???
        :param py_requires: add???
        """
        for mix in py_requires:
            if mix:
                self.mixinResource(page_class, page_class.resourceDirs, mix)

    def mixinResource(self, kls, resourceDirs, *path):
        """add???
        
        :param kls: add???
        :param resourceDirs: add???
        :param \*path: add???
        """
        path = os.path.join(*path)
        if ':' in path:
            modName, clsName = path.split(':')
        else:
            modName, clsName = path, '*'
        modPathList = self.getResourceList(resourceDirs, modName, 'py') or []
        if modPathList:
            modPathList.reverse()
            for modPath in modPathList:
                classMixin(kls,
                           '%s:%s' % (modPath, clsName),
                           only_callables=False,
                           site=self)
        else:
            raise GnrMixinError('Cannot import component %s' % modName)

    def py_requires_iterator(self, source_class, target_class):
        """add???
        
        :param source_class: add???
        :param target_class: add???
        """
        resourceDirs = target_class.resourceDirs
        py_requires = [
            x for x in splitAndStrip(getattr(source_class, 'py_requires', ''),
                                     ',') if x
        ] or []
        for path in py_requires:
            if ':' in path:
                modName, clsName = path.split(':')
            else:
                modName, clsName = path, '*'
            modPathList = self.getResourceList(resourceDirs, modName,
                                               'py') or []
            if modPathList:
                modPathList.reverse()
                for modPath in modPathList:
                    yield '%s:%s' % (modPath, clsName)
                    #classMixin(kls,'%s:%s'%(modPath,clsName),only_callables=False,site=self)
            else:
                raise GnrMixinError('Cannot import component %s' % modName)

    def getResourceList(self, resourceDirs, path, ext=None):
        """Find a resource in the current ``_resources`` folder or in parent folders one
        
        :param resourceDirs: add???
        :param path: add???
        :param ext: add???. Default value is ``None``
        """
        result = []
        if ext == 'css' or ext == 'js':
            locations = resourceDirs[:]
            locations.reverse()
        else:
            locations = resourceDirs
        if ext and not path.endswith('.%s' % ext): path = '%s.%s' % (path, ext)
        if '*' in path:
            searchpath = os.path.split(path.split('*')[0])[0]
            use_glob = True
        else:
            searchpath = path
            use_glob = False
        for dpath in locations:
            fpath = os.path.join(dpath, searchpath)
            if os.path.exists(fpath):
                if use_glob:
                    result.extend(glob.glob(os.path.join(dpath, path)))
                else:
                    result.append(fpath)
        return result

    def loadResource(self, pkg, *path):
        """add???
        
        :param pkg: add???
        :param \* path: add???
        :returns: add???
        """
        resourceDirs = self.package_resourceDirs(pkg)
        resource_class = cloneClass('CustomResource', BaseResource)
        resource_class.resourceDirs = resourceDirs
        self.mixinResource(resource_class, resourceDirs, *path)
        return resource_class()

    def mixinPageComponent(self, page, pkg, *path):
        """add???
        
        :param page: add???
        :param pkg: add???
        :param \* path: add???
        """
        component = self.loadResource(pkg, *path)
        css_requires = getattr(component, 'css_requires', [])
        js_requires = getattr(component, 'js_requires', [])
        for css in css_requires:
            if css and not css in page.css_requires:
                page.css_requires.append(css)
        for js in js_requires:
            if js and not js in page.js_requires:
                page.js_requires.append(js)
        page.mixin(component)

    def loadTableScript(self,
                        page,
                        table=None,
                        respath=None,
                        class_name=None,
                        _onDefault=None):
        """add???
        
        :param page: add???
        :param table: add???. Default value is ``None``
        :param respath: add???. Default value is ``None``
        :param class_name: add???. Default value is ``None``
        :param _onDefault: add???. Default value is ``None``
        """
        class_name = class_name or 'Main'
        application = self.gnrapp
        if not table:
            _onDefault = True
        if ':' in respath:
            table, respath = respath.split(':')
        if _onDefault:
            tablename = '_default'
            resourceDirs = page.resourceDirs
        else:
            if isinstance(table, basestring):
                table = application.db.table(table)
            tablename = table.name
            resourceDirs = self.package_resourceDirs(table.pkg.name)
        modName = os.path.join('tables', tablename, *(respath.split('/')))
        #resourceDirs = application.packages[table.pkg.name].resourceDirs
        modPathList = self.getResourceList(resourceDirs, modName, 'py') or []
        if modPathList:
            modPathList.reverse()
            basePath = modPathList.pop(0)
            resource_module = gnrImport(basePath, avoidDup=True)
            resource_class = getattr(resource_module, class_name, None)
            resource_obj = resource_class(page=page, resource_table=table)
            for modPath in modPathList:
                resource_module = gnrImport(modPath, avoidDup=True)
                resource_class = getattr(resource_module, class_name, None)
                if resource_class:
                    instanceMixin(resource_obj,
                                  resource_class,
                                  only_callables=False)
            return resource_obj
        elif not _onDefault:
            return self.loadTableScript(page,
                                        table=table,
                                        respath=respath,
                                        _onDefault=True)
        else:
            raise GnrWebServerError('Cannot import component %s' % modName)

    def resourcesAtPath(self, pkg, path, ext):
        """add???
        
        :param pkg: add???
        :param path: add???
        :param ext: add???
        :returns: add???
        """
        result = Bag()
        locations = list(self.package_resourceDirs(pkg))
        for dpath in locations:
            dirpath = os.path.join(dpath, path)
            if os.path.isdir(dirpath):
                b = DirectoryResolver(dirpath, include='*.py', dropext=True)
                result.update(b, resolved=True)
        return result
Esempio n. 26
0
class ResourceLoader(object):
    """Base class to load :ref:`intro_resources`"""
    def __init__(self, site=None):
        self.site = site
        self.site_path = self.site.site_path
        self.site_name = self.site.site_name
        self.gnr_config = self.site.gnr_config
        self.gnrapp = self.site.gnrapp
        self.debug = self.site.debug
        self.gnr_static_handler = self.site.getStatic('gnr')
        self.build_automap()
        self.page_factories = {}
        self.default_path = self.site.default_page and self.site.default_page.split('/')
        
    def find_webtools(self):
        """TODO"""
        def isgnrwebtool(cls):
            return inspect.isclass(cls) and issubclass(cls, BaseWebtool) and cls is not BaseWebtool
            
        tools = {}
        webtool_pathlist = []
        if 'webtools' in self.gnr_config['gnr.environment_xml']:
            for path in self.gnr_config['gnr.environment_xml'].digest('webtools:#a.path'):
                webtool_pathlist.append(expandpath(path))
        for package in self.gnrapp.packages.values():
            webtool_pathlist.append(os.path.join(package.packageFolder, 'webtools'))
        project_resource_path = os.path.join(self.site_path, '..', '..', 'webtools')
        webtool_pathlist.append(os.path.normpath(project_resource_path))
        for path in webtool_pathlist:
            if not os.path.isdir(path):
                continue
            for tool_module in os.listdir(path):
                if tool_module.endswith('.py'):
                    module_path = os.path.join(path, tool_module)
                    try:
                        module = gnrImport(module_path, avoidDup=True)
                        tool_classes = inspect.getmembers(module, isgnrwebtool)
                        tool_classes = [(name.lower(), value) for name, value in tool_classes]
                        tools.update(dict(tool_classes))
                    except ImportError:
                        pass
        return tools
        
    def build_automap(self):
        """Build the :ref:`automap` file"""
        def handleNode(node, pkg=None, plugin=None):
            attr = node.attr
            file_name = attr['file_name']
            node.attr = dict(
                    name='!!%s' % file_name.capitalize(),
                    pkg=pkg
                    )
            if plugin:
                node.attr['plugin']=plugin
            if attr['file_ext'] == 'py':
                node.attr['path'] = attr['rel_path']
            node.label = file_name
            if node._value is None:
                node._value = ''
                
        self.automap = DirectoryResolver(os.path.join(self.site_path, 'pages'), ext='py', include='*.py',
                                         exclude='_*,.*,*.pyc')()
                                         
        self.automap.walk(handleNode, _mode='', pkg='*')
        for package in self.site.gnrapp.packages.values():
            packagemap = DirectoryResolver(os.path.join(package.packageFolder, 'webpages'),
                                           include='*.py', exclude='_*,.*')()
            packagemap.walk(handleNode, _mode='', pkg=package.id)
            self.automap.setItem(package.id, packagemap, name=package.attributes.get('name_long') or package.id)
            for pluginname,plugin in package.plugins.items():
                pluginmap = DirectoryResolver(plugin.webpages_path,
                                               include='*.py', exclude='_*,.*')()
                pluginmap.walk(handleNode, _mode='', pkg=package.id,plugin=plugin.id)
                self.automap.setItem("%s._plugin.%s"%(package.id,plugin.id), pluginmap, name=plugin.id)
        self.automap.toXml(os.path.join(self.site_path, 'automap.xml'))
        
    @property
    def sitemap(self):
        """Return the sitemap Bag (if there is no sitemap, creates it)"""
        if not hasattr(self, '_sitemap'):
            sitemap_path = os.path.join(self.site_path, 'sitemap.xml')
            if not os.path.isfile(sitemap_path):
                sitemap_path = os.path.join(self.site_path, 'automap.xml')
            _sitemap = Bag(sitemap_path)
            _sitemap.setBackRef()
            self._sitemap = _sitemap
        return self._sitemap
        
    def get_page_node(self, path_list, default_path=None):
        """Get the deepest :ref:`bagnode` in the sitemap :ref:`bag` associated with the given url
        
        :param path_list: TODO
        :param default: TODO"""
        def escape_path_list(path_list):
            return [p.replace('.','\\.') for p in path_list]
        def unescape_path_list(path_list):
            return [p.replace('\\.','.') for p in path_list]
        path_list = escape_path_list(path_list)
        page_node = self.sitemap.getDeepestNode('.'.join(path_list))
        if not page_node and self.site.mainpackage: # try in the main package
            page_node = self.sitemap.getDeepestNode('.'.join([self.site.mainpackage] + path_list))
        if page_node:
            page_node_attributes = page_node.getInheritedAttributes()
            if page_node_attributes.get('path'):
                page_node._tail_list=unescape_path_list(getattr(page_node,'_tail_list',[]))
                return page_node, page_node_attributes
            else:
                page_node = self.sitemap.getDeepestNode('.'.join(path_list + ['index']))
                if page_node:
                    page_node_attributes = page_node.getInheritedAttributes()
                    if page_node_attributes.get('path'):
                        page_node._tail_list=unescape_path_list(getattr(page_node,'_tail_list',[]))
                        return page_node, page_node_attributes
        if not page_node and default_path:
            page_node, page_node_attributes = self.get_page_node(default_path)
            if page_node:
                page_node._tail_list =  unescape_path_list(path_list)
            return page_node, page_node_attributes
        return None, None
        
    def __call__(self, path_list, request, response, environ=None,request_kwargs=None):
        page_node = None
        request_kwargs = request_kwargs or dict()
        mobile = request_kwargs.pop('_mobile',False)
        if mobile:
            page_node, page_node_attributes = self.get_page_node(['mobile']+path_list)
        if not page_node:
            page_node, page_node_attributes = self.get_page_node(path_list, default_path=self.default_path)
        if not page_node:
            return None
        request_args = page_node._tail_list
        path = page_node_attributes.get('path')
        pkg = page_node_attributes.get('pkg')
        plugin = page_node_attributes.get('plugin')
        page_class = self.get_page_class(path=path, pkg=pkg, plugin=plugin,request_args=request_args,request_kwargs=request_kwargs)
        page = page_class(site=self.site, request=request, response=response,
                          request_kwargs=request_kwargs, request_args=request_args,
                          filepath=path, packageId=page_class._packageId, pluginId=plugin,  basename=path, environ=environ)
        return page
        
    def get_page_class(self, path=None, pkg=None, plugin=None,request_args=None,request_kwargs=None):
        """TODO
        
        :param path: TODO
        :param pkg: the :ref:`package <packages>` object"""
        if pkg == '*':
            module_path = os.path.join(self.site_path, path)
            pkg = self.site.config['packages?default']
        else:
            if plugin:
                module_path= os.path.join(self.gnrapp.packages[pkg].plugins[plugin].webpages_path, path)
            else:
                module_path = os.path.join(self.gnrapp.packages[pkg].packageFolder, 'webpages', path)
            
        # if module_path in self.page_factories:
        #    return self.page_factories[module_path]
        page_module = gnrImport(module_path, avoidDup=True)
        page_factory = getattr(page_module, 'page_factory', GnrWebPage)
        custom_class = getattr(page_module, 'GnrCustomWebPage')
        mainPkg = pkg
        if hasattr(custom_class,'getMainPackage'):
            kw = dict()
            if 'page_id' in request_kwargs:
                kw = self.site.register.pageStore(request_kwargs['page_id']).getItem('pageArgs') or dict()
                kw.update(request_kwargs)
            mainPkg = custom_class.getMainPackage(request_args=request_args,request_kwargs=kw)
        py_requires = splitAndStrip(getattr(custom_class, 'py_requires', ''), ',')
        plugin_webpage_classes = self.plugin_webpage_classes(path, pkg=mainPkg)
        for plugin_webpage_class in plugin_webpage_classes:
            plugin_py_requires = splitAndStrip(getattr(plugin_webpage_class, 'py_requires', ''), ',')
            py_requires.extend(plugin_py_requires)
        page_class = cloneClass('GnrCustomWebPage', page_factory)
        page_class.__module__ = page_module.__name__
        self.page_class_base_mixin(page_class, pkg=mainPkg)
        page_class.dojo_version = getattr(custom_class, 'dojo_version', None) or self.site.config[
                                                                                 'dojo?version'] or '11'
        page_class.theme = getattr(custom_class, 'theme', None) or self.site.config['dojo?theme'] or 'tundra'
        page_class.gnrjsversion = getattr(custom_class, 'gnrjsversion', None) or self.site.config[
                                                                                 'gnrjs?version'] or '11'
        page_class.maintable = getattr(custom_class, 'maintable', None)
        page_class.recordLock = getattr(custom_class, 'recordLock', None)
        page_class.user_polling = int(
                getattr(custom_class, 'user_polling', None) or self.site.config['polling?user'] or 3)
        page_class.auto_polling = int(
                getattr(custom_class, 'auto_polling', None) or self.site.config['polling?auto'] or 30)
        if hasattr(custom_class,'polling_enabled'):
            page_class.polling_enabled = getattr(custom_class, 'polling_enabled')
        page_class.eagers = getattr(custom_class, 'eagers', {})
        page_class.css_requires = []
        page_class.js_requires = splitAndStrip(getattr(custom_class, 'js_requires', ''), ',')
        page_class.pageOptions = getattr(custom_class, 'pageOptions', {})
        page_class.auth_tags = getattr(custom_class, 'auth_tags', '')
        page_class.resourceDirs = self.page_class_resourceDirs(page_class, module_path, pkg=mainPkg)
        self.page_pyrequires_mixin(page_class, py_requires)
        classMixin(page_class, custom_class, only_callables=False)
        page_class.css_requires.extend([x for x in splitAndStrip(getattr(custom_class, 'css_requires', ''), ',') if x])
        page_class.tpldirectories = page_class.resourceDirs + [
                self.gnr_static_handler.path(page_class.gnrjsversion, 'tpl')]
        page_class._packageId = mainPkg
        self.page_class_plugin_mixin(page_class, plugin_webpage_classes)
        self.page_class_custom_mixin(page_class, path, pkg=mainPkg)
        self.page_factories[module_path] = page_class
        return page_class
        
    def page_class_base_mixin(self, page_class, pkg=None):
        """Look for custom classes in the package
        
        :param page_class: TODO
        :param pkg: the :ref:`package <packages>` object"""
        if pkg:
            package = self.gnrapp.packages[pkg]
        if package and package.webPageMixin:
            classMixin(page_class, package.webPageMixin, only_callables=False) # first the package standard
        if self.gnrapp.webPageCustom:
            classMixin(page_class, self.gnrapp.webPageCustom, only_callables=False) # then the application custom
        if package and package.webPageMixinCustom:
            classMixin(page_class, package.webPageMixinCustom, only_callables=False) # finally the package custom
            
    def plugin_webpage_classes(self, path, pkg=None):
        """Look in the plugins folders for a file named as the current webpage and get all classes
        
        :param path: TODO
        :param pkg: the :ref:`package <packages>` object"""
        plugin_webpage_classes = []
        path = path.split(os.path.sep)
        pkg = pkg and self.site.gnrapp.packages[pkg]
        if pkg:
            pkg_plugins = pkg.getPlugins()
            for plugin in pkg_plugins:
                pluginPagePath = os.path.join(plugin.webpages_path, *path)
                if os.path.isfile(pluginPagePath):
                    component_page_module = gnrImport(pluginPagePath, avoidDup=True)
                    component_page_class = getattr(component_page_module, 'GnrCustomWebPage', None)
                    if component_page_class:
                        plugin_webpage_classes.append(component_page_class)
        return plugin_webpage_classes
        
    def page_class_plugin_mixin(self, page_class, plugin_webpage_classes):
        """Mixin the current class with the *plugin_webpage_classes* attribute
        
        :param page_class: TODO
        :param plugin_webpage_classes: TODO"""
        for plugin_webpage_class in plugin_webpage_classes:
            classMixin(page_class, plugin_webpage_class, only_callables=False)
            
    def page_class_custom_mixin(self, page_class, path, pkg=None):
        """Look in the instance custom folder for a file named as the current webpage
        
        :param page_class: TODO
        :param path: TODO
        :param pkg: the :ref:`package <packages>` object"""
        path = path.split(os.path.sep)
        if pkg:
            customPagePath = os.path.join(self.gnrapp.customFolder, pkg, 'webpages', *path)
            if os.path.isfile(customPagePath):
                component_page_module = gnrImport(customPagePath, avoidDup=True)
                component_page_class = getattr(component_page_module, 'WebPage', None)
                if component_page_class:
                    classMixin(page_class, component_page_class, only_callables=False)
    
    def _appendPathIfExists(self,result, path):
        if os.path.exists(path):
            result.append(path)
                    
    def page_class_resourceDirs(self, page_class, path, pkg=None):
        """Build page resources directories
        
        :param page_class: TODO
        :param path: TODO
        :param pkg: the :ref:`package <packages>` object"""
        if pkg:
            pagesPath = os.path.join(self.gnrapp.packages[pkg].packageFolder, 'webpages')
            packageResourcePath =  os.path.join(self.gnrapp.packages[pkg].packageFolder, 'resources')
        else:
            pagesPath = os.path.join(self.site_path, 'pages')
        #curdir = os.path.dirname(os.path.join(pagesPath, path))
        #resourcePkg = None
        result = [] # result is now empty
        fpath = os.path.join(self.site_path, 'resources')
        self._appendPathIfExists(result, fpath) # we add a custom resource folder for current package
        if pkg: # for index page or other pages at root level (out of any package)
            #resourcePkg = self.gnrapp.packages[pkg].attributes.get('resourcePkg')
            fpath = os.path.join(self.site_path, '_custom', pkg, '_resources')
            self._appendPathIfExists(result, fpath) # we add a custom resource folder for current package
        
        fpath = os.path.join(self.site_path, '_resources')
        self._appendPathIfExists(result, fpath) # we add a custom resource folder for common package
            
        #while curdir.startswith(pagesPath):
        #    fpath = os.path.join(curdir, '_resources')
        #    if os.path.isdir(fpath):
        #        result.append(fpath)
        #    curdir = os.path.dirname(curdir) # we add a resource folder for folder 
            # of current page
        #if resourcePkg:
        #    for rp in resourcePkg.split(','):
        #        fpath = os.path.join(self.gnrapp.packages[rp].packageFolder, 'webpages', '_resources')
        #        if os.path.isdir(fpath):
        #            result.append(fpath)
            #result.extend(self.siteResources)
        if packageResourcePath:
            self._appendPathIfExists(result, packageResourcePath)
        resources_list = self.site.resources_dirs
        result.extend(resources_list)
        return result
        
    def package_resourceDirs(self, pkg, omitSiteResources=False, pluginId=None):
        """TODO
        
        :param pkg: the :ref:`package <packages>` object
        :param omitSiteResources: boolean. TODO"""
        pkg = self.gnrapp.packages[pkg]
        result = []
        if not hasattr(pkg, '_resourceDirs'):
            pagesPath = os.path.join(pkg.packageFolder, 'webpages')
            resourcePkg = None
            pkgResourceDirs = [] # result is now empty
            resourcePkg = pkg.attributes.get('resourcePkg')
            fpath = os.path.join(self.site_path, '_custom', pkg.id, '_resources')
            if os.path.isdir(fpath):
                pkgResourceDirs.append(fpath) # we add a custom resource folder for current package
                
            if resourcePkg:
                for rp in resourcePkg.split(','):
                    fpath = os.path.join(self.site_path, '_custom', pkg.id, '_resources')
                    if os.path.isdir(fpath):
                        pkgResourceDirs.append(fpath)
            fpath = os.path.join(pagesPath, '_resources')
            if os.path.isdir(fpath):
                pkgResourceDirs.append(fpath) # we add a resource folder for common package
            rsrc_path = os.path.join(pkg.packageFolder, 'resources')
            if os.path.isdir(rsrc_path):
                pkgResourceDirs.append(rsrc_path)
            pkg._siteResourceDirs = self.site.resources_dirs
            pkg._resourceDirs = pkgResourceDirs
        if pluginId and pluginId in pkg.plugins:
            plugin = pkg.plugins[pluginId]
            if plugin.resources_path:
                result.append(plugin.resources_path)
        result.extend(list(pkg._resourceDirs))
        if not omitSiteResources:
            result.extend(pkg._siteResourceDirs)
            # so we return a list of any possible resource folder starting from
        # most customized and ending with most generic ones
        return result
        
    def site_resources(self):
        """TODO"""
        resources = Bag()
        resources['site'] = os.path.join(self.site_path, 'resources')
        resources_list = [(resource.label, resource.attr.get('path')) for resource in
                          self.site.config['resources'] or []]
        for label, rsrc_path in resources_list:
            if rsrc_path:
                resources[label] = rsrc_path
            else:
                rsrc_path = self.resource_name_to_path(label)
                resources[label] = rsrc_path
        auto_resource_path = self.resource_name_to_path(self.site_name, safe=False)
        if auto_resource_path:
            resources[self.site_name] = os.path.realpath(auto_resource_path)

        for pkg in self.site.gnrapp.packages.values():
            rsrc_path = os.path.join(pkg.packageFolder, 'resources')
            label = 'pkg_%s' % (pkg.id)
            if os.path.isdir(rsrc_path):
                resources[label] = rsrc_path
            plugins = [p for p in pkg.getPlugins() if p.resources_path]
            for plugin in plugins:
                label = 'pkg_%s_%s' % (pkg.id,plugin.id)
                if os.path.isdir(plugin.resources_path):
                    resources[label] = plugin.resources_path
        return resources
        
    def resource_name_to_path(self, res_id, safe=True):
        """TODO
        
        :param res_id: TODO
        :param safe: TODO"""
        project_resource_path = os.path.normpath(os.path.join(self.site_path, '..', '..', 'resources', res_id))
        if os.path.isdir(project_resource_path):
            log.debug('resource_name_to_path(%s) -> %s (project)' % (repr(res_id),repr(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):
                    log.debug('resource_name_to_path(%s) -> %s (gnr config)' % (repr(res_id), repr(res_path)))
                    return res_path
        log.debug('resource_name_to_path(%s) not found.' % repr(res_id))
        if safe:
            raise Exception('Error: resource %s not found' % res_id)
            
    def page_pyrequires_mixin(self, page_class, py_requires):
        """Allow to mixin the :ref:`webpage python requirements <webpages_py_requires>`
        
        :param page_class: TODO
        :param py_requires: TODO"""
        for mix in py_requires:
            if mix:
                self.mixinResource(page_class, page_class.resourceDirs, mix)
                
    def mixinResource(self, kls, resourceDirs, *path):        
        """TODO
        
        :param kls: TODO
        :param resourceDirs: TODO
        :param \*path: TODO"""
        path = os.path.join(*path)
        if ':' in path:
            modName, clsName = path.split(':')
        else:
            modName, clsName = path, '*'
        modPathList = self.getResourceList(resourceDirs, modName, 'py') or []
        if modPathList:
            modPathList.reverse()
            for modPath in modPathList:
                classMixin(kls, '%s:%s' % (modPath, clsName), only_callables=False, site=self)
        else:
            raise GnrMixinError('Cannot import component %s' % modName)
            
    def py_requires_iterator(self, source_class, target_class):
        """TODO
        
        :param source_class: TODO
        :param target_class: TODO"""
        resourceDirs = target_class.resourceDirs
        py_requires = [x for x in splitAndStrip(getattr(source_class, 'py_requires', ''), ',') if x] or []
        for path in py_requires:
            if ':' in path:
                modName, clsName = path.split(':')
            else:
                modName, clsName = path, '*'
            modPathList = self.getResourceList(resourceDirs, modName, 'py') or []
            if modPathList:
                modPathList.reverse()
                for modPath in modPathList:
                    yield '%s:%s' % (modPath, clsName)
                    #classMixin(kls,'%s:%s'%(modPath,clsName),only_callables=False,site=self)
            else:
                raise GnrMixinError('Cannot import component %s' % modName)
                
    def getResourceList(self, resourceDirs, path, ext=None,pkg=None):
        """Find a resource in the current ``_resources`` folder or in parent folders one
        
        :param resourceDirs: TODO
        :param path: TODO
        :param ext: TODO"""
        result = []
        if ext == 'css' or ext == 'js':
            locations = resourceDirs[:]
            locations.reverse()
        else:
            locations = resourceDirs
        if ext and not path.endswith('.%s' % ext): path = '%s.%s' % (path, ext)
        if '*' in path:
            searchpath=os.path.split(path.split('*')[0])[0]
            use_glob=True
        else:
            searchpath=path
            use_glob=False
        for dpath in locations:
            fpath = os.path.join(dpath, searchpath)
            if os.path.exists(fpath):
                if use_glob:
                    result.extend(glob.glob(os.path.join(dpath,path)))
                else:
                    result.append(fpath)
        return uniquify(result)
        
    def loadResource(self, *path, **kwargs):
        """TODO"""
        resource_class = cloneClass('CustomResource', BaseResource)
        pkg=kwargs.pop('pkg', None)
        page=kwargs.pop('page', None)
        pluginId=kwargs.pop('pluginId', None)
        pkgOnly=kwargs.pop('pkgOnly', False)
        if pkg:
            resourceDirs = self.package_resourceDirs(pkg)
            lookupDirs = self.package_resourceDirs(pkg, omitSiteResources=pkgOnly, pluginId=pluginId)
        else:
            resourceDirs = lookupDirs = page.resourceDirs
        resource_class.resourceDirs = resourceDirs
        self.mixinResource(resource_class, lookupDirs, *path)
        return resource_class()
                 
    def mixinPageComponent(self, page, *path,**kwargs):
        """This method is used to mixin a component to a :ref:`webpage` at any time
        
        :param page: the target :ref:`webpage`
        :param \* path: the path of the :ref:`component <components>`"""
        pkg=kwargs.pop('pkg', None)
        pkgOnly=kwargs.pop('pkgOnly', False)
        pluginId=kwargs.pop('pluginId', None)
        component=self.loadResource(*path, page=page, pkg=pkg, pkgOnly=pkgOnly, pluginId=pluginId)
        setattr(component,'__mixin_pkg', pkg)
        setattr(component, '__mixin_path' ,'/'.join(path))
        css_requires = getattr(component,'css_requires',[])
        js_requires = getattr(component,'js_requires',[])
        for css in css_requires:
            if css and not css in page.dynamic_css_requires and not css in page.css_requires:
                page.dynamic_css_requires[css] = page.getResourceUri(css,'css',add_mtime=True,pkg=pkg)
        for js in js_requires:
            if js and not js in page.dynamic_js_requires and not js in page.js_requires:
                page.dynamic_js_requires[js] = page.getResourceUri(js,'js',add_mtime=True,pkg=pkg)
        page.mixin(component,**kwargs)
    
        
    def loadTableScript(self, page, table=None, respath=None, class_name=None):
        """TODO
        
        :param page: TODO
        :param table: the :ref:`database table <table>` name on which the query will be executed,
                      in the form ``packageName.tableName`` (packageName is the name of the
                      :ref:`package <packages>` to which the table belongs to)
        :param respath: TODO
        :param class_name: TODO
        """
        class_name = class_name or 'Main'
        application = self.gnrapp
        if ':' in respath:
            table, respath = respath.split(':')
        if isinstance(table, basestring):
            table = application.db.table(table)
        if not table:
            tablename = '_default'
            modName = os.path.join('tables', tablename, *(respath.split('/')))
        else:
            tablename = table.name
            pkgname = table.pkg.name
            modName = os.path.join('tables','_packages',pkgname, tablename, *(respath.split('/')))
        resourceDirs = page.resourceDirs
        modPathList = self.getResourceList(resourceDirs, modName, 'py')
        if not modPathList and table is not None:
            resourceDirs = self.package_resourceDirs(table.pkg.name)
            modName = os.path.join('tables', tablename, *(respath.split('/')))
            modPathList = self.getResourceList(resourceDirs, modName, 'py')
            if not modPathList:
                tablename = '_default'
                resourceDirs = page.resourceDirs
                modName = os.path.join('tables', tablename, *(respath.split('/')))
                modPathList = self.getResourceList(resourceDirs, modName, 'py')
        modPathList = self.getResourceList(resourceDirs, modName, 'py') or []
        if modPathList:
            modPathList.reverse()
            basePath = modPathList.pop(0)
            resource_module = gnrImport(basePath, avoidDup=True)
            resource_class = getattr(resource_module, class_name, None)
            for modPath in modPathList:
                resource_module = gnrImport(modPath, avoidDup=True)
                resource_class =cloneClass('CustomResource', resource_class)
                custom_resource_class = getattr(resource_module, class_name, None)
                if resource_class:
                    classMixin(resource_class, custom_resource_class, only_callables=False)
            resource_obj = resource_class(page=page, resource_table=table)
            return resource_obj
        else:
            raise GnrWebServerError('Cannot import component %s' % modName)
    
    def resourcesAtPath(self,page=None, pkg=None, path=None, ext='py'):
        """TODO
        
        :param pkg: the :ref:`package <packages>` object
        :param path: TODO
        :param ext: TODO"""
        result = Bag()
        if pkg:
            locations = list(self.package_resourceDirs(pkg))
        else:
            locations = page.resourceDirs
        for dpath in locations:
            dirpath = os.path.join(dpath, path)
            if os.path.isdir(dirpath):
                b = DirectoryResolver(dirpath, include='*.py', dropext=True)
                result.update(b, resolved=True)
        return result
Esempio n. 27
0
 def directoryTree(self, path=''):
     return DirectoryResolver(path, exclude='*.pyc')
Esempio n. 28
0
 def explorer_directory(self, path=None):
     return DirectoryResolver(path or '/')(), dict(title='Directory: %s' % path)
Esempio n. 29
0
 def get_diskdir(self, path):
     """docstring for get_diskdir"""
     return  DirectoryResolver(path)()