misc/cwfs/cwfs.py
changeset 11057 0b59724cb3f2
parent 11052 058bb3dc685f
child 11058 23eb30449fe5
equal deleted inserted replaced
11052:058bb3dc685f 11057:0b59724cb3f2
     1 # copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
       
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     3 #
       
     4 # This file is part of CubicWeb.
       
     5 #
       
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
       
     7 # terms of the GNU Lesser General Public License as published by the Free
       
     8 # Software Foundation, either version 2.1 of the License, or (at your option)
       
     9 # any later version.
       
    10 #
       
    11 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT
       
    12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
       
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
       
    14 # details.
       
    15 #
       
    16 # You should have received a copy of the GNU Lesser General Public License along
       
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
       
    18 """
       
    19 
       
    20 """
       
    21 class Schema :
       
    22 
       
    23     def __init__(self, schema) :
       
    24         self._schema = schema
       
    25 
       
    26     def get_attrs(self, entity) :
       
    27         return self._schema[entity][0]
       
    28 
       
    29     def get_relations(self, entity) :
       
    30         return self._schema[entity][1]
       
    31 
       
    32     def get_attr_index(self, entity, attr) :
       
    33         return list(self._schema[entity][0]).index(attr)
       
    34 
       
    35 SCHEMA = Schema({'societe': ( ('nom','ville'),
       
    36                               [('concerne_par','affaire'),
       
    37                                ] ),
       
    38                  'affaire': ( ('ref',),
       
    39                               [('concerne','societe'),
       
    40                                ('concerne_par', 'document')
       
    41                                ] ),
       
    42                  'document':( ('fichier', 'annee','mois','jour','type'),
       
    43                               [('concerne','affaire'),
       
    44                                ] ),
       
    45                  })
       
    46 
       
    47 
       
    48 
       
    49 DATA = { 'societe': [ ('CETIAD', 'Dijon'),
       
    50                       ('EDF_R&D', 'Clamart'),
       
    51                       ('Logilab', 'Paris'),
       
    52                       ],
       
    53          'affaire': [ ('CTIA01', 'CETIAD'),
       
    54                       ('EDFR01', 'EDF_R&D'),
       
    55                       ('EDFR02', 'EDF_R&D'),
       
    56                       ],
       
    57          'document':[ ('CTIA01-040906-PRE-1-01.pdf','2004','09','06','PRE','CTIA01'),
       
    58                       ('EDFR01-050201-CLI-1-01.pdf','2005','02','01','CLI','EDFR01'),
       
    59                       ('EDFR01-050322-OFR-1-01.pdf','2005','03','22','OFR','EDFR01'),
       
    60                       ],
       
    61          }
       
    62 
       
    63 def get_data(entity, where=[]) :
       
    64     for value in DATA[entity] :
       
    65         for index, val in where :
       
    66             if value[index] != val :
       
    67                 break
       
    68         else :
       
    69             yield value
       
    70 
       
    71 class PathParser :
       
    72 
       
    73     def __init__(self, schema, path) :
       
    74         self.schema = schema
       
    75         self.path = path
       
    76         self._components = iter([comp for comp in self.path.split('/') if comp])
       
    77         self._entity = None
       
    78         self._attr = None
       
    79         self._rel = None
       
    80         self._restrictions = []
       
    81 
       
    82     def parse(self) :
       
    83         self._entity = next(self._components)
       
    84         try:
       
    85             self.process_entity()
       
    86         except StopIteration :
       
    87             pass
       
    88 
       
    89     def process_entity(self) :
       
    90         _next = next(self._components)
       
    91         if _next in self.schema.get_attrs(self._entity) :
       
    92             self._attr = _next
       
    93             _next = next(self._components)
       
    94             self._restrictions.append( (self._entity, self._attr, _next) )
       
    95             self._attr = None
       
    96             self._rel = None
       
    97             self.process_entity()
       
    98 
       
    99     def get_list(self) :
       
   100         if self._rel :
       
   101             return
       
   102         elif self._attr :
       
   103             where = []
       
   104             for e,a,v in self._restrictions :
       
   105                 i = self.schema.get_attr_index(e, a)
       
   106                 where.append( (i,v) )
       
   107             i = self.schema.get_attr_index(self._entity, self._attr)
       
   108             for values in get_data(self._entity,where) :
       
   109                 yield values[i]+'/'
       
   110         else :
       
   111             attr_restrict = [a for e,a,v in self._restrictions]
       
   112             for attr in self.schema.get_attrs(self._entity) :
       
   113                 if attr not in attr_restrict :
       
   114                     yield attr+'/'
       
   115             for data in DATA[self._entity]:
       
   116                 yield data[0]
       
   117             for nom, entity in self.schema.get_relations(self._entity) :
       
   118                 yield nom+'/'
       
   119                 yield entity+'/'
       
   120 
       
   121 def ls(path) :
       
   122     p = PathParser(SCHEMA,path)
       
   123     p.parse()
       
   124     return list(p.get_list())
       
   125 
       
   126 
       
   127 class SytPathParser :
       
   128 
       
   129     def __init__(self, schema, path) :
       
   130         self.schema = schema
       
   131         self.path = path
       
   132         self._components = iter([comp for comp in self.path.split('/') if comp])
       
   133         self._e_type = None
       
   134         self._restrictions = []
       
   135         self._alphabet = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
       
   136 
       
   137     def parse(self):
       
   138         self._var = self._alphabet.pop(0)
       
   139         self._e_type = next(self._components)
       
   140         e_type = self._e_type.capitalize()
       
   141         self._restrictions.append('%s is %s' % (self._var, e_type))
       
   142         try:
       
   143             self.process_entity()
       
   144         except StopIteration :
       
   145             pass
       
   146         return 'Any %s WHERE %s' % (self._var, ', '.join(self._restrictions))
       
   147 
       
   148     def process_entity(self) :
       
   149         _next = next(self._components)
       
   150         if _next in self.schema.get_attrs(self._e_type) :
       
   151             attr = _next
       
   152             try:
       
   153                 _next = next(self._components)
       
   154                 self._restrictions.append('%s %s %s' % (self._var, attr, _next))
       
   155             except StopIteration:
       
   156                 a_var = self._alphabet.pop(0)
       
   157                 self._restrictions.append('%s %s %s' % (self._var, attr, a_var) )
       
   158                 self._var = a_var
       
   159                 raise
       
   160         elif _next in [r for r,e in self.schema.get_relations(self._e_type)]:
       
   161             rel = _next
       
   162             r_var = self._alphabet.pop(0)
       
   163             self._restrictions.append('%s %s %s' % (self._var, rel, r_var))
       
   164             self._var = r_var
       
   165             try:
       
   166                 _next = next(self._components)
       
   167                 self._restrictions.append('%s is %s' % (r_var, _next.capitalize()))
       
   168             except StopIteration:
       
   169                 raise
       
   170         self.process_entity()
       
   171 
       
   172 
       
   173 def to_rql(path) :
       
   174     p = SytPathParser(SCHEMA,path)
       
   175     return p.parse()