utils.py 6.55 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
##############################################################################
#
# Copyright (c) 2007 Nexedi SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################

28
import os.path
29
from Products.ERP5Type import tarfile
30 31 32 33 34
import xml.parsers.expat
import xml.dom.minidom
from urllib import url2pathname


35
class BusinessTemplateInfoBase:
36

37 38
  def __init__(self, target):
    self.target = target
39 40 41 42 43 44 45 46 47 48 49 50 51
    self.setUp()

  def setUp(self):
    self.title = ''
    self.modules = {}
    self.allowed_content_types = {}
    self.actions = {}

    self.setUpTitle()
    self.setUpModules()
    self.setUpAllowedContentTypes()
    self.setUpActions()

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
  def findFileInfosByName(self, startswith='', endswith=''):
    raise NotImplementedError

  def getFileInfo(self, name):
    raise NotImplementedError

  def getFileInfoName(self, fileinfo):
    raise NotImplementedError

  def readFileInfo(self, fileinfo):
    raise NotImplementedError

  def getPrefix(self):
    raise NotImplementedError

67
  def setUpTitle(self):
68 69
    for i in self.findFileInfosByName(endswith='/bt/title'):
      self.title = self.readFileInfo(i)
70 71

  def setUpModules(self):
72
    name = '%s/ModuleTemplateItem/' % self.getPrefix()
Yoshinori Okuji's avatar
Yoshinori Okuji committed
73
    for i in self.findFileInfosByName(startswith=name, endswith='.xml'):
74 75 76 77 78
      source = self.readFileInfo(i)
      doc = xml.dom.minidom.parseString(source)
      module_id = doc.getElementsByTagName('id')[0].childNodes[0].data
      portal_type = doc.getElementsByTagName('portal_type')[0].childNodes[0].data
      self.modules[module_id] = portal_type
79 80

  def setUpAllowedContentTypes(self):
81
    name = '%s/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml' % self.getPrefix()
82
    try:
83 84
      fileinfo = self.getFileInfo(name)
    except NotFoundError:
85
      return
86
    source = self.readFileInfo(fileinfo)
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
    doc = xml.dom.minidom.parseString(source)
    for portal_type_node in doc.getElementsByTagName('portal_type'):
      portal_type = portal_type_node.getAttribute('id')
      self.allowed_content_types[portal_type] = []
      for item in portal_type_node.getElementsByTagName('item'):
        self.allowed_content_types[portal_type].append(item.childNodes[0].data)

  def setUpActions(self):
    class Handler:
      cur_key = None
      old_tag = None
      cur_tag = None
      key_val = None
      value_val = None

      def __init__(self):
        self.data = {}

      def start(self, name, attrs):
        if not name in ('item', 'key', 'value', 'string', 'int', 'float'):
          return
        self.old_tag = self.cur_tag
        self.cur_tag = name
        if name=='key':
          self.cur_key = name

      def end(self, name):
        self.cur_tag = None
        if name=='item':
          self.data[self.key_val] = self.value_val
          self.cur_key = None
          self.key_val = None
          self.value_val = None

      def char(self, data):
        if self.cur_tag in ('string', 'int', 'float'):
          f = getattr(self, 'to%s' % self.cur_tag)
          if self.old_tag=='key':
            self.key_val = f(data)
          elif self.old_tag=='value':
            self.value_val = f(data)

      def tostring(self, value):
        return str(value)

      def toint(self, value):
        return int(value)

      def tofloat(self, value):
        return float(value)

    def parse(source):
      handler = Handler()
      p = xml.parsers.expat.ParserCreate()
      p.StartElementHandler = handler.start
      p.EndElementHandler = handler.end
      p.CharacterDataHandler = handler.char
      p.Parse(source)
      return handler.data

147
    name = '%s/ActionTemplateItem/portal_types/' % self.getPrefix()
Yoshinori Okuji's avatar
Yoshinori Okuji committed
148
    for i in self.findFileInfosByName(startswith=name, endswith='.xml'):
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
      portal_type = url2pathname(self.getFileInfoName(i).split('/')[-2])
      if not portal_type in self.actions:
        self.actions[portal_type] = []
      data = parse(self.readFileInfo(i))
      self.actions[portal_type].append(data)


class NotFoundError(Exception):
  """FileInfo does not exists."""


class BusinessTemplateInfoTar(BusinessTemplateInfoBase):

  def __init__(self, target):
    self.target = tarfile.open(target, 'r:gz')
    self.setUp()

  def getPrefix(self):
    return self.title

  def findFileInfosByName(self, startswith='', endswith=''):
    for tarinfo in self.target.getmembers():
      if (tarinfo.name.startswith(startswith) and
          tarinfo.name.endswith(endswith) and
          tarinfo.type==tarfile.REGTYPE):
        yield tarinfo

  def getFileInfo(self, name):
    try:
      return self.target.getmember(name)
    except KeyError:
      raise NotFoundError

  def getFileInfoName(self, fileinfo):
    return fileinfo.name

  def readFileInfo(self, fileinfo):
    return self.target.extractfile(fileinfo).read()


class BusinessTemplateInfoDir(BusinessTemplateInfoBase):

  def getPrefix(self):
    return self.target

  def findFileInfosByName(self, startswith='', endswith=''):
    allfiles = []
    def visit(arg, dirname, names):
      if '.svn' in dirname:
        return
      for i in names:
        path = os.path.join(self.target, dirname, i)
        if os.path.isfile(path):
          allfiles.append(path)
    os.path.walk(self.target, visit, None)
    for i in allfiles:
      if i.startswith(startswith) and i.endswith(endswith):
        yield i

  def getFileInfo(self, name):
    if not os.path.isfile(name):
      raise NotFoundError
    return name

  def getFileInfoName(self, fileinfo):
    return fileinfo

  def readFileInfo(self, fileinfo):
    return file(fileinfo).read()