[Erp5-report] r42772 rafael - in /erp5/trunk/utils/erp5.recipe.btrepository: ./ src/ src/er...

nobody at svn.erp5.org nobody at svn.erp5.org
Sun Jan 30 00:54:14 CET 2011


Author: rafael
Date: Sun Jan 30 00:54:14 2011
New Revision: 42772

URL: http://svn.erp5.org?rev=42772&view=rev
Log:
Initial import (draft)

Added:
    erp5/trunk/utils/erp5.recipe.btrepository/CHANGES.txt   (with props)
    erp5/trunk/utils/erp5.recipe.btrepository/README.txt   (with props)
    erp5/trunk/utils/erp5.recipe.btrepository/setup.cfg
    erp5/trunk/utils/erp5.recipe.btrepository/setup.py
    erp5/trunk/utils/erp5.recipe.btrepository/src/
    erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/
    erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/__init__.py
    erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/
    erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/__init__.py
    erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/
    erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/__init__.py
    erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/genbt5list.py
    erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/repository.py

Added: erp5/trunk/utils/erp5.recipe.btrepository/CHANGES.txt
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.recipe.btrepository/CHANGES.txt?rev=42772&view=auto
==============================================================================
    (empty)

Propchange: erp5/trunk/utils/erp5.recipe.btrepository/CHANGES.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: erp5/trunk/utils/erp5.recipe.btrepository/README.txt
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.recipe.btrepository/README.txt?rev=42772&view=auto
==============================================================================
    (empty)

Propchange: erp5/trunk/utils/erp5.recipe.btrepository/README.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: erp5/trunk/utils/erp5.recipe.btrepository/setup.cfg
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.recipe.btrepository/setup.cfg?rev=42772&view=auto
==============================================================================
    (empty)

Added: erp5/trunk/utils/erp5.recipe.btrepository/setup.py
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.recipe.btrepository/setup.py?rev=42772&view=auto
==============================================================================
--- erp5/trunk/utils/erp5.recipe.btrepository/setup.py (added)
+++ erp5/trunk/utils/erp5.recipe.btrepository/setup.py [utf8] Sun Jan 30 00:54:14 2011
@@ -0,0 +1,36 @@
+from setuptools import setup, find_packages
+import os
+
+name = "erp5.recipe.btrepository"
+version = '0.0.1'
+
+def read(*rnames):
+  return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+long_description=( read('README.txt')
+                   + '\n' +
+                   read('CHANGES.txt')
+                 )
+
+setup(
+  name = name,
+  version = version,
+  author = 'Rafael Monnerat',
+  author_email = 'rafael at nexedi.com',
+  description = 
+    "zc.buildout recipe that creates an repository of business template",
+  long_description = long_description,
+  license = "ZPL 2.1",
+  keywords = "businesstemplates buildout",
+  classifiers = [
+    "License :: OSI Approved :: Zope Public License",
+    "Framework :: Buildout",
+  ],
+
+  package_dir = {'': 'src'},
+  packages = find_packages('src'),
+  namespace_packages = ['erp5', 'erp5.recipe'],
+  include_package_data = True,
+  install_requires = ['setuptools', 'zc.recipe.egg'],
+  entry_points = {'zc.buildout': ['default = %s:Recipe' % name]},
+  )

Added: erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/__init__.py
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/__init__.py?rev=42772&view=auto
==============================================================================
--- erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/__init__.py (added)
+++ erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/__init__.py [utf8] Sun Jan 30 00:54:14 2011
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__) 

Added: erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/__init__.py
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/__init__.py?rev=42772&view=auto
==============================================================================
--- erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/__init__.py (added)
+++ erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/__init__.py [utf8] Sun Jan 30 00:54:14 2011
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__) 

Added: erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/__init__.py
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/__init__.py?rev=42772&view=auto
==============================================================================
--- erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/__init__.py (added)
+++ erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/__init__.py [utf8] Sun Jan 30 00:54:14 2011
@@ -0,0 +1,81 @@
+##############################################################################
+#
+# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
+#                    Rafael Monnerat <rafael at nexedi.com>
+#
+# 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.
+#
+##############################################################################
+
+import os
+from string import Template
+import logging
+import zc.buildout
+import zc.buildout.easy_install
+import zc.recipe.egg
+import ConfigParser
+
+class Recipe(object):
+  def __init__(self, buildout, name, options):
+    self.buildout, self.options, self.name = buildout, options, name
+    self.egg = zc.recipe.egg.Egg(buildout, options['recipe'], options)
+    self.logger = logging.getLogger(self.name)
+
+    options.setdefault('location',
+                   os.path.join(
+                     buildout['buildout']['parts-directory'],
+                     self.name))
+    options.setdefault("command", 
+                   "svn co --trust-server-cert --non-interactive --quiet")
+    options.setdefault("download_folder", 
+                   "%s__download__" % options.get('location'))
+    options.setdefault("preserve-download", True)
+
+  def install_script(self):
+    """ Create default scripts
+    """
+    options = self.options
+    url = options.get("url")
+    requirements, ws = self.egg.working_set(['erp5.recipe.btrepository'])
+    script_name = "%s_update" % self.name
+    scripts = zc.buildout.easy_install.scripts(
+        [(script_name,'erp5.recipe.btrepository.repository', 'main')],
+        ws, options['executable'], "bin",
+        arguments = ("\n        url_list = %s ,     "
+                     "\n        destination = '%s' ,"
+                     "\n        download_dir = '%s',"
+                     "\n        download_cmd = '%s'," 
+                     "\n        preserve_download = %s " % (
+                                      url.split(),
+                                      options.get('location'),
+                                      options.get("download_folder"),
+                                      options.get("command"),
+                                      int(options.get("preserve-download")))))
+
+  def install(self):
+    options = self.options
+    if not os.path.exists(options.get("location")):
+      os.mkdir(options.get("location"))
+    self.install_script()
+    return []
+
+  update = install

Added: erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/genbt5list.py
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/genbt5list.py?rev=42772&view=auto
==============================================================================
--- erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/genbt5list.py (added)
+++ erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/genbt5list.py [utf8] Sun Jan 30 00:54:14 2011
@@ -0,0 +1,282 @@
+#! /usr/bin/python
+##############################################################################
+#
+# Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
+#                    Yoshinori Okuji <yo at nexedi.com>
+#
+# 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.
+#
+##############################################################################
+
+
+"""Generate repository information on Business Templates.
+"""
+
+import tarfile
+import os
+import os.path
+import sys
+import tempfile
+import shutil
+import cgi
+
+property_list = '''
+title
+version
+revision
+description
+license
+dependency_list
+provision_list
+copyright_list
+'''.strip().splitlines()
+
+bt_title_path = os.path.join('bt', 'title')
+
+def info(message):
+  """Print a message to stdout.
+  """
+  sys.stdout.write(message)
+
+def err(message):
+  """Print a message to stderr.
+  """
+  sys.stderr.write(message)
+
+def readProperty(property_dict, property_name, property_file):
+    try:
+      text = property_file.read()
+      if property_name.endswith('_list'):
+        property_dict[property_name[:-5]] = text and text.split('\n') or []
+      else:
+        property_dict[property_name] = text
+    finally:
+      property_file.close()
+
+def readBusinessTemplate(tar):
+  """Read an archived Business Template info.
+  """
+  property_dict = {}
+  for info in tar:
+    name_list = info.name.split('/')
+    if len(name_list) == 3 and name_list[1] == 'bt' and name_list[2] in property_list:
+      property_file = tar.extractfile(info)
+      property_name = name_list[2]
+      readProperty(property_dict, property_name, property_file)
+
+  return property_dict
+
+def readBusinessTemplateDirectory(dir):
+  """Read Business Template Directory info.
+  """
+  property_dict = {}
+  for property_name in property_list:
+    filename = os.path.join(dir, 'bt', property_name)
+    if os.path.isfile(filename):
+      property_file = open(filename, 'rb')
+      readProperty(property_dict, property_name, property_file)
+
+  return property_dict
+
+def generateInformation(fd):
+  os.write(fd, '<?xml version="1.0"?>\n')
+  os.write(fd, '<repository>\n')
+
+  for file in sorted(os.listdir(os.getcwd())):
+    if file.endswith('.bt5'):
+      info('Reading %s... ' % (file,))
+      try:
+        tar = tarfile.open(file, 'r:gz')
+      except tarfile.TarError:
+        err('An error happened in %s; skipping\n' % (file,))
+        continue
+      try:
+        property_dict = readBusinessTemplate(tar)
+      finally:
+        tar.close()
+    elif os.path.isfile(os.path.join(file, bt_title_path)):
+      info('Reading Directory %s... ' % (file,))
+      property_dict = readBusinessTemplateDirectory(file)
+    else:
+      continue
+    property_id_list = property_dict.keys()
+    property_id_list.sort()
+    os.write(fd, '  <template id="%s">\n' % (file,))
+    for property_id in property_id_list:
+      property_value = property_dict[property_id]
+      if type(property_value) == type(''):
+        os.write(fd, '    <%s>%s</%s>\n' % (
+              property_id, cgi.escape(property_value), property_id))
+      else:
+        for value in property_value:
+          os.write(fd, '    <%s>%s</%s>\n' % (
+                property_id, cgi.escape(value), property_id))
+    os.write(fd, '  </template>\n')
+    info('done\n')
+  os.write(fd, '</repository>\n')
+
+def main():
+  if len(sys.argv) < 2:
+    dir_list = ['.']
+  else:
+    dir_list = sys.argv[1:]
+
+  cwd = os.getcwd()
+  for d in dir_list:
+    os.chdir(d)
+    fd, path = tempfile.mkstemp()
+    try:
+      try:
+        generateInformation(fd)
+      finally:
+        os.close(fd)
+    except:
+      os.remove(path)
+      raise
+    else:
+      shutil.move(path, 'bt5list')
+      cur_umask = os.umask(0666)
+      os.chmod('bt5list', 0666 & ~cur_umask)
+      os.umask(cur_umask)
+    os.chdir(cwd)
+
+# monkey patch tarfile library if python version is 2.4.
+if sys.version_info[0:2] == (2, 4):
+    from tarfile import BLOCKSIZE, GNUTYPE_SPARSE, SUPPORTED_TYPES, TarFile, \
+         TarInfo, calc_chksum, normpath, nts
+
+    def frombuf(cls, buf):
+        """Construct a TarInfo object from a 512 byte string buffer.
+        """
+        tarinfo = cls()
+        tarinfo.name   = nts(buf[0:100])
+        tarinfo.mode   = int(buf[100:108], 8)
+        tarinfo.uid    = int(buf[108:116],8)
+        tarinfo.gid    = int(buf[116:124],8)
+
+        # There are two possible codings for the size field we
+        # have to discriminate, see comment in tobuf() below.
+        if buf[124] != chr(0200):
+            tarinfo.size = long(buf[124:136], 8)
+        else:
+            tarinfo.size = 0L
+            for i in range(11):
+                tarinfo.size <<= 8
+                tarinfo.size += ord(buf[125 + i])
+
+        tarinfo.mtime  = long(buf[136:148], 8)
+        tarinfo.chksum = int(buf[148:156], 8)
+        tarinfo.type   = buf[156:157]
+        tarinfo.linkname = nts(buf[157:257])
+        tarinfo.uname  = nts(buf[265:297])
+        tarinfo.gname  = nts(buf[297:329])
+        try:
+            tarinfo.devmajor = int(buf[329:337], 8)
+            tarinfo.devminor = int(buf[337:345], 8)
+        except ValueError:
+            tarinfo.devmajor = tarinfo.devmajor = 0
+        tarinfo.prefix = buf[345:500]
+
+        # The prefix field is used for filenames > 100 in
+        # the POSIX standard.
+        # name = prefix + '/' + name
+        if tarinfo.type != GNUTYPE_SPARSE:
+            tarinfo.name = normpath(os.path.join(nts(tarinfo.prefix), tarinfo.name))
+
+        # Directory names should have a '/' at the end.
+        if tarinfo.isdir() and tarinfo.name[-1:] != "/":
+            tarinfo.name += "/"
+        return tarinfo
+
+    TarInfo.frombuf = classmethod(frombuf)
+
+    def next(self):
+        """Return the next member of the archive as a TarInfo object, when
+           TarFile is opened for reading. Return None if there is no more
+           available.
+        """
+        self._check("ra")
+        if self.firstmember is not None:
+            m = self.firstmember
+            self.firstmember = None
+            return m
+
+        # Read the next block.
+        self.fileobj.seek(self.offset)
+        while True:
+            buf = self.fileobj.read(BLOCKSIZE)
+            if not buf:
+                return None
+            try:
+                tarinfo = TarInfo.frombuf(buf)
+            except ValueError:
+                if self.ignore_zeros:
+                    if buf.count(NUL) == BLOCKSIZE:
+                        adj = "empty"
+                    else:
+                        adj = "invalid"
+                    self._dbg(2, "0x%X: %s block" % (self.offset, adj))
+                    self.offset += BLOCKSIZE
+                    continue
+                else:
+                    # Block is empty or unreadable.
+                    if self.offset == 0:
+                        # If the first block is invalid. That does not
+                        # look like a tar archive we can handle.
+                        raise ReadError,"empty, unreadable or compressed file"
+                    return None
+            break
+
+        # We shouldn't rely on this checksum, because some tar programs
+        # calculate it differently and it is merely validating the
+        # header block. We could just as well skip this part, which would
+        # have a slight effect on performance...
+        if tarinfo.chksum != calc_chksum(buf):
+            self._dbg(1, "tarfile: Bad Checksum %r" % tarinfo.name)
+
+        # Set the TarInfo object's offset to the current position of the
+        # TarFile and set self.offset to the position where the data blocks
+        # should begin.
+        tarinfo.offset = self.offset
+        self.offset += BLOCKSIZE
+
+        # Check if the TarInfo object has a typeflag for which a callback
+        # method is registered in the TYPE_METH. If so, then call it.
+        if tarinfo.type in self.TYPE_METH:
+            return self.TYPE_METH[tarinfo.type](self, tarinfo)
+
+        tarinfo.offset_data = self.offset
+        if tarinfo.isreg() or tarinfo.type not in SUPPORTED_TYPES:
+            # Skip the following data blocks.
+            self.offset += self._block(tarinfo.size)
+
+        if tarinfo.isreg() and tarinfo.name[:-1] == "/":
+            # some old tar programs don't know DIRTYPE
+            tarinfo.type = DIRTYPE
+
+        self.members.append(tarinfo)
+        return tarinfo
+
+    TarFile.next = next
+
+if __name__ == "__main__":
+  main()

Added: erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/repository.py
URL: http://svn.erp5.org/erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/repository.py?rev=42772&view=auto
==============================================================================
--- erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/repository.py (added)
+++ erp5/trunk/utils/erp5.recipe.btrepository/src/erp5/recipe/btrepository/repository.py [utf8] Sun Jan 30 00:54:14 2011
@@ -0,0 +1,101 @@
+#! /usr/bin/python
+##############################################################################
+#
+# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
+#                    Rafael Monnerat <rafael at nexedi.com>
+#
+# 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.
+#
+##############################################################################
+from optparse import OptionParser
+try:
+  from hashlib import md5
+except ImportError:
+  from md5 import new as md5
+import os
+import shutil
+import genbt5list
+
+
+def load_options():
+  parser = OptionParser()
+  parser.add_option("-u", "--url", dest="url",
+                    help="write report to FILE", metavar="URL", 
+                    default="https://svn.erp5.org/repos/public/erp5/trunk/bt5,"\
+                            "https://svn.erp5.org/repos/public/erp5/trunk/products/ERP5/bootstrap")
+  
+  parser.add_option("-r", "--repository",
+                    dest="repository", default=os.getcwd(),
+                    help="don't print status messages to stdout")
+  
+  return parser.parse_args()
+
+# Lock file name
+LOCKFILE="/tmp/update_repository.lock"
+WORKDIR = "/tmp/update_repository_work"
+DOWNLOADDIR = "/tmp/update_repository_download"
+DOWNLOAD_COMMAND = "svn co --trust-server-cert --non-interactive --quiet"
+
+def main(url_list, destination,
+         download_dir=DOWNLOADDIR, 
+         download_cmd=DOWNLOAD_COMMAND, 
+         preserve_download=True):
+
+  if os.path.exists(LOCKFILE):
+      raise ValueError("Lock file %s exists" % LOCKFILE)
+
+  try: 
+    f = open(LOCKFILE, "w+"); f.close()
+    if not os.path.exists(download_dir):
+      os.mkdir(download_dir)
+    os.mkdir(WORKDIR)
+    for url in url_list:
+      if url != "":
+        os.chdir(download_dir)
+        repos = md5(url).hexdigest()
+        os.system("%s %s %s" % (download_cmd, url, repos))
+        os.chdir(repos)
+        for bt in os.listdir("."):
+          if "." in bt:
+            # We could use tarfile instead.
+            os.system('tar -zcf "%s/%s.bt5" --exclude .svn "%s"' % (WORKDIR,bt,bt))
+
+    ### # Publish the repository
+    for bt in os.listdir(WORKDIR):
+      bt_path = os.path.join(destination,bt)
+      if os.path.exists(bt_path):
+        os.remove(bt_path)
+      shutil.move('%s/%s' % (WORKDIR,bt), destination)
+    
+    os.chdir(destination)
+    genbt5list.main()
+  finally:
+    if os.path.exists(LOCKFILE):
+      os.remove(LOCKFILE)
+    shutil.rmtree(WORKDIR)
+    if not preserve_download:
+      shutil.rmtree(download_dir)
+  return True
+
+if __name__ == "__main__":
+  (options, args) = load_options()
+  main(url_list = options.url.split(","), destination = options.repository)



More information about the Erp5-report mailing list