[Subversion] / CityKid / citykid / data.py  

Diff of /CityKid/citykid/data.py

Parent Directory | Revision Log

version 2126, Wed Apr 12 06:03:49 2006 UTC version 2720, Mon Jun 2 04:24:35 2014 UTC
Line 2 
Line 2 
 from peak.api import *  from peak.api import *
 from datetime import datetime  from datetime import datetime
 from peak.util.imports import importString  from peak.util.imports import importString
 import re  import re, os, shutil, json, mimetypes
   from pkg_resources import ensure_directory
   dt = lambda d: datetime.fromordinal(d.toordinal())
   dt.str = lambda d: d.strftime("%Y-%m-%d %H:%M:%S")
   
 FOG = re.compile('PTMFOG(\d+)(\.[A-Za-z]*)?')  FOG = re.compile('PTMFOG(\d+)(\.[A-Za-z]*)?')
   BRACKET = re.compile(r'\[\[([^]]+)]]')
   
 def sql_equals(data, clauses=(), sep=' AND ', pre=' WHERE '):  def sql_equals(data, clauses=(), sep=' AND ', pre=' WHERE '):
     clauses = [c for c in clauses if c]      clauses = [c for c in clauses if c]
Line 23 
Line 27 
 def sqlWHERE(data, clauses=()):  def sqlWHERE(data, clauses=()):
     return sql_equals(data, clauses)      return sql_equals(data, clauses)
   
   try:
       sorted = sorted
   except NameError:
       def sorted(seq,key=None):
           if key:
               d = [(key(v),v) for v in seq]
           d.sort()
           if key:
               d = [v[1] for v in d]
           return d
   
   
   
   
   
   
 class SQL_DM(storage.EntityDM):  class SQL_DM(storage.EntityDM):
Line 73 
Line 73 
             self.db('UPDATE '+tbl+sSet+sWhere, values+what)              self.db('UPDATE '+tbl+sSet+sWhere, values+what)
   
   
   class Base(Persistent):
       class __metaclass__(binding.Activator, Persistent.__class__): pass
   
   
   
   
   
   
   
 class Base(Persistent):  
     class __metaclass__(binding.Activator, Persistent.__class__): pass  
   
 class Item(Base):  class Item(Base):
     """An item that's editable in CityDesk"""      """An item that's editable in CityDesk"""
   
Line 97 
Line 94 
             + self.ext              + self.ext
     )      )
   
     def linkTo(self,tgt):      def linkTo(self,tgt,root=None):
           if root:
               return root[:len(root)-root.endswith('/')]+'/'+tgt.path
         src, tgt = self.path.split('/'), tgt.path.split('/')          src, tgt = self.path.split('/'), tgt.path.split('/')
         if src==tgt:          if src==tgt:
             return tgt[-1]              return tgt[-1]
Line 105 
Line 104 
             del src[0], tgt[0]              del src[0], tgt[0]
         dots = len(src) - bool(tgt)          dots = len(src) - bool(tgt)
         return '/'.join( ['..']*dots + tgt)          return '/'.join( ['..']*dots + tgt)
   
         # (1)     : (2/3/4)   -> ../../1    src - 1          # (1)     : (2/3/4)   -> ../../1    src - 1
         # 1/2     : 1/2/(3)   -> ..         src          # 1/2     : 1/2/(3)   -> ..         src
         # 1/(2)   : 1/(3)     -> 2          src - 1          # 1/(2)   : 1/(3)     -> 2          src - 1
Line 113 
Line 111 
   
     parent = None      parent = None
     ext = ''    # XXX      ext = ''    # XXX
       active = 1
   
       def save(self, dir):
           dir = os.path.dirname(self.filename(dir))
           if not os.path.isdir(dir):
               os.makedirs(dir)
   
       def filename(self, dir):
           return os.path.join(dir, *self.path.split('/'))
   
       def _write_file(self, dir, data, suffix=''):
           Item.save(self, dir)
           filename = self.filename(dir)+suffix
           if os.path.isfile(filename):
               old = open(filename,'rb').read()
               if old==str(data):
                   return
           open(filename,'wb').write(data)
   
       def _dump(self, dir, metadata, data):
           metadata = json.dumps(metadata, sort_keys=True, indent=0)
           if is_text(self.path.split('/')[-1]):
               self._write_file(dir,
                   "---\n%s\n---\n%s" % (metadata, data)
               )
           else:
               self._write_file(dir, data)
               self._write_file(dir, metadata, '.json')
   
   
   def is_text(filename):
       if filename=='.htaccess':
           return True
       mt = mimetypes.guess_type(filename, False)[0]
       if mt:
           return mt.startswith('text/')
   
   
   
   
   
   
   
   
   
   
   
   
 class Folder(Item):  
     """A Folder"""  
   
 class File(Item):  
     """A File"""  
   
   
 class Article(Item):  class Article(Item):
Line 134 
Line 175 
     )      )
   
     body = binding.Make(lambda self: str(self._article.sArticle).decode('utf16'))      body = binding.Make(lambda self: str(self._article.sArticle).decode('utf16'))
       author   = binding.Obtain("_article/sAuthor")
     teaser   = binding.Obtain("_article/sTeaser")      teaser   = binding.Obtain("_article/sTeaser")
     sidebar  = binding.Obtain("_article/sSidebar")      sidebar  = binding.Obtain("_article/sSidebar")
     about    = binding.Obtain("_article/sAboutTheAuthor")      about    = binding.Obtain("_article/sAboutTheAuthor")
     extra1   = binding.Obtain("_article/sExtra1")      extra1   = binding.Obtain("_article/sExtra1")
     extra2   = binding.Obtain("_article/sExtra2")      extra2   = binding.Obtain("_article/sExtra2")
   
     # get the extension and 'kid' objects from the template      # get the extension and 'kid' objects from the template
     kid = ext = binding.Delegate("template")      kid = ext = binding.Delegate("template")
   
     def __call__(self, **kw):      def __call__(self, **kw):
         text = str(self.template(my=self, **kw))          text = self.template(my=self, **kw).serialize(output=self.format)
         return FOG.sub(self.defog, text)          return FOG.sub(self.defog, text)
   
     def defog(self, match):      def defog(self, match, root=None):
         item = self._p_jar[int(match.group(1))]          item = self._p_jar[int(match.group(1))]
         return self.linkTo(item)          return self.linkTo(item, root)
   
     def active(self):      def active(self):
         now = datetime.now()          now = datetime.now()
         return (          return (
             (self.effective is None or self.effective<=now) and              (self.effective is None or dt(self.effective)<=now) and
             (self.retire    is None or self.retire   >=now)              (self.retire    is None or dt(self.retire)   >=now)
         )          )
     active = binding.Make(active)      active = binding.Make(active)
   
       text = binding.Make(lambda self: FOG.sub(self.defog, self.body))
   
   
       def teaser_for(self, tgt, root=None):
           return BRACKET.sub(
               lambda m: '<a href="%s#begin-post">%s</a>' %
                   (self.linkTo(tgt,root), m.group(1)),
               tgt.teaser
           )
   
       def save(self, dir):
           self._write_file(dir, self())
   
       format = binding.Make(lambda self: self.ext=='xml' and 'xml' or 'xhtml')
   
       def abstext(self, root=None):
           return FOG.sub(lambda t: self.defog(t,root), self.body)
   
       _dump_map = dict([(k,k) for k in [
           "author", "teaser", "sidebar", "about", "extra1", "extra2", "headline",
           "audience", "keywords"
       ]], **{"Fog-ID":"_p_oid"})
       del k
   
       def dump(self, dir):
           Item.save(self, dir)
           #self._write_file(dir, self.body.encode('utf8'))
           data = dict([
               (k, getattr(self,v)) for k,v in self._dump_map.items()
                   if getattr(self,v)
           ])
           for k in ["effective", "retire", "filed", "modified"]:
               v = getattr(self, k, None)
               if v:
                   data[k] = dt.str(v)
           data["template"] = self.template.name
           #data = json.dumps(data, sort_keys=True, indent=0)
           #data = '---\n%s\n---\n%s' % (data, self.body.encode('utf8'))
           self._dump(dir, data, self.body.encode('utf8')) #, '.json')
   
   
   
   
   
   class Folder(Item):
       """A Folder"""
   
       def delete_orphans(self, dir, items=None, dump=False):
           """Remove files or dirs that aren't in `items`"""
           if items is None:
               items = self._p_jar.where(ixParent=self._p_oid)
   
           # Build a mapping of known item file/dir names
           d = dict.fromkeys(
               [item.path.split('/')[-1] for item in items if item.parent is self]
           )
   
           if dump:
               for key in d.keys():
                   if not is_text(key):
                       d[key+'.json'] = None
   
           filename = self.filename(dir)
   
           for f in os.listdir(filename):
               if f not in d:
                   f = os.path.join(filename, f)
                   if os.path.isdir(f) and not os.path.islink(f):
                       shutil.rmtree(f)
                   else:
                       os.unlink(f)
   
       def save(self, dir):
           dir = self.filename(dir)
           if not os.path.isdir(dir):
               os.makedirs(dir)
   
       dump = save
   
   
   
   
   
   
   
   class File(Item):
       """A File"""
   
       raw_data = binding.Make(
           lambda self:
           (~self._p_jar.db(
               "select oleFile from tblFiles WHERE ixStructure=?", (self._p_oid,)
           ))[0]
       )
   
       def save(self, dir):
           Item.save(self, dir)
           data = self.raw_data
           if self.path.endswith('.html'):
               def defog(match, root=None):
                   item = self._p_jar[int(match.group(1))]
                   return self.linkTo(item, root)
               data =  FOG.sub(defog, data)
           self._write_file(dir, data)
   
       def dump(self, dir):
           Item.save(self, dir)
           self._write_file(dir, self.raw_data)
           self._dump(dir, {"Fog-ID": self._p_oid}, self.raw_data)
   
   
 item_types = {  item_types = {
     1.0: Folder,      1.0: Folder,
     2.0: Article,      2.0: Article,
     3.0: File,      3.0: File,
 }  }
   
   
   
   
   
   
   
   
   
   
 class Template(Base):  class Template(Base):
     """A CityDesk template"""      """A CityDesk template"""
   
     kid = binding.Make(      kid = binding.Make(
         lambda self: importString('kid.Template')(          lambda self: self.load_template(str(self.body).replace('\000',''))
             source = str(self.body).replace('\000',''),  
         ).module.Template  
     )      )
   
     def __call__(self, **kw):      name = binding.Make(
         return self.kid(          lambda self:(~self._p_jar.db(
             templates = self._p_jar.templates, site = self._p_jar.vars, **kw              "select * from tblTemplateStructure where ixTemplateStructure=?", (self._p_oid,)
           )).sName
         )          )
   
       def __call__(self, **kw):
           return self.call_template(self.kid, **kw)
   
       call_template = load_template = binding.Delegate('_p_jar')
   
   
 class TemplateDM(SQL_DM):  class TemplateDM(SQL_DM):
     resetStatesAfterTxn = False      resetStatesAfterTxn = False
     defaultClass = Template      defaultClass = Template
Line 197 
Line 360 
     def stateForRow(self, row):      def stateForRow(self, row):
         return dict(ext = str(row.sExt), body = row.utf8Template)          return dict(ext = str(row.sExt), body = row.utf8Template)
   
     vars = binding.Obtain('vars')      cmd = binding.Obtain('..')
     templates = binding.Obtain('templates')      call_template = load_template = binding.Delegate('cmd')
   
   
   
   
   
   
   
   
   
   
Line 217 
Line 387 
     _select = """      _select = """
     SELECT iType, ixItem, sName, sPublishAs, sKeywords, ixTemplateStructure,      SELECT iType, ixItem, sName, sPublishAs, sKeywords, ixTemplateStructure,
            dtModified, dtFiled, dtEffective, dtRetire, ixParent, sHeadline,             dtModified, dtFiled, dtEffective, dtRetire, ixParent, sHeadline,
            ixArticle, i.ixStructure             ixArticle, ixAudience, i.ixStructure
       FROM (tblStructure i LEFT OUTER JOIN tblArticleSet s ON s.ixSet=i.ixItem)        FROM (tblStructure i LEFT OUTER JOIN tblArticleSet s ON s.ixSet=i.ixItem)
            LEFT OUTER JOIN tblArticle a ON a.ixSet=s.ixSet             LEFT OUTER JOIN tblArticle a ON a.ixSet=s.ixSet
     """      """
Line 226 
Line 396 
   
     def stateForRow(self, row):      def stateForRow(self, row):
         state = dict(          state = dict(
             _itemType = row.iType,              _itemType = row.iType, _itemNo   = row.ixItem,
             _itemNo   = row.ixItem,              name      = row.sName, publishAs = str(row.sPublishAs),
             name      = row.sName,  
             publishAs = str(row.sPublishAs),  
             keywords  = row.sKeywords,              keywords  = row.sKeywords,
             filed = row.dtFiled,              filed = row.dtFiled,
             effective = row.dtEffective,              effective = row.dtEffective,
Line 237 
Line 405 
             modified = row.dtModified,              modified = row.dtModified,
             headline = row.sHeadline,              headline = row.sHeadline,
             _articleNo = row.ixArticle,              _articleNo = row.ixArticle,
               audience = self.audiences[row.ixAudience]
         )          )
         if row.ixTemplateStructure:          if row.ixTemplateStructure:
             state['template'] = self.templateDM[row.ixTemplateStructure]              state['template'] = self.templateDM[row.ixTemplateStructure]
Line 244 
Line 413 
             state['parent'] = self[row.ixParent]              state['parent'] = self[row.ixParent]
         return state          return state
   
   
     def rowsForOb(self, ob):      def rowsForOb(self, ob):
         yield (          yield (
             'tblStructure',              'tblStructure',
Line 269 
Line 439 
                 dict(ixArticle=ob._articleNo)                  dict(ixArticle=ob._articleNo)
             )              )
   
       audiences = binding.Make(
           lambda self: dict(
               list(self.db(
                   "SELECT ixAudience,sAudience FROM tblAudience WHERE fDeleted=0"
               )) + [(0, "(Everyone)"), (None, None)]
           )
       )
   
   
   


Generate output suitable for use with a patch program
Legend:
Removed from v.2126  
changed lines
  Added in v.2720

cvs-admin@eby-sarna.com

Powered by ViewCVS 1.0-dev

ViewCVS and CVS Help