home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / pyshared / checkbox / lib / template.py < prev    next >
Encoding:
Python Source  |  2009-04-27  |  5.5 KB  |  162 lines

  1. #
  2. # This file is part of Checkbox.
  3. #
  4. # Copyright 2008 Canonical Ltd.
  5. #
  6. # Checkbox is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # Checkbox is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with Checkbox.  If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. import os
  20. import re
  21. import logging
  22. import posixpath
  23.  
  24.  
  25. class Template(object):
  26.  
  27.     def __init__(self, filename_field=None, unique_fields=[]):
  28.         self._filename_field = filename_field
  29.         self._unique_fields = unique_fields
  30.  
  31.     def _reader(self, file, size=4096, delimiter="\n\n"):
  32.         buffer_old = ""
  33.         while True:
  34.             buffer_new = file.read(size)
  35.             if not buffer_new:
  36.                 break
  37.  
  38.             lines = (buffer_old + buffer_new).split(delimiter)
  39.             buffer_old = lines.pop(-1)
  40.  
  41.             for line in lines:
  42.                 yield line
  43.  
  44.         yield buffer_old
  45.  
  46.     def load_file(self, file, filename="<stream>"):
  47.         elements = []
  48.         for string in self._reader(file):
  49.             if not string:
  50.                 break
  51.  
  52.             element = {}
  53.  
  54.             def _save(field, value, extended):
  55.                 extended = extended.rstrip("\n")
  56.                 if field:
  57.                     if element.has_key(field):
  58.                         raise Exception, \
  59.                             "Template %s has a duplicate field '%s'" \
  60.                             " with a new value '%s'." \
  61.                                 % (filename, field, value)
  62.                     element[field] = value
  63.                     if extended:
  64.                         element["%s_extended" % field] = extended
  65.  
  66.             string = string.strip("\n")
  67.             field = value = extended = ""
  68.             for line in string.split("\n"):
  69.                 line.strip()
  70.                 match = re.search(r"^([-_.A-Za-z0-9]*):\s?(.*)", line)
  71.                 if match:
  72.                     _save(field, value, extended)
  73.                     field = match.groups()[0].lower()
  74.                     value = match.groups()[1].rstrip()
  75.                     extended = ""
  76.                     continue
  77.  
  78.                 if re.search(r"^\s\.$", line):
  79.                     extended += "\n\n"
  80.                     continue
  81.  
  82.                 match = re.search(r"^\s(\s+.*)", line)
  83.                 if match:
  84.                     bit = match.groups()[0].rstrip()
  85.                     if len(extended) and not re.search(r"[\n ]$", extended):
  86.                         extended += "\n"
  87.  
  88.                     extended += bit + "\n"
  89.                     continue
  90.  
  91.                 match = re.search(r"^\s(.*)", line)
  92.                 if match:
  93.                     bit = match.groups()[0].rstrip()
  94.                     if len(extended) and not re.search(r"[\n ]$", extended):
  95.                         extended += " "
  96.  
  97.                     extended += bit
  98.                     continue
  99.  
  100.                 raise Exception, "Template %s parse error at: %s" \
  101.                     % (filename, line)
  102.  
  103.             _save(field, value, extended)
  104.  
  105.             # Sanity checks
  106.             if self._filename_field:
  107.                 if self._filename_field in element:
  108.                     raise Exception, \
  109.                         "Template %s already contains filename field: %s" \
  110.                         % (filename, self._filename_field)
  111.                 element[self._filename_field] = posixpath.basename(filename)
  112.  
  113.             for unique_field in self._unique_fields:
  114.                 if [e for e in elements \
  115.                    if e[unique_field] == element[unique_field]]:
  116.                     raise Exception, \
  117.                         "Template %s contains duplicate fields: %s" \
  118.                         % (filename, unique_field)
  119.  
  120.             elements.append(element)
  121.  
  122.         return elements
  123.  
  124.     def load_filename(self, filename):
  125.         logging.info("Loading elements from filename: %s", filename)
  126.  
  127.         file = open(filename, "r")
  128.         return self.load_file(file, filename)
  129.  
  130.     def load_directory(self, directory, blacklist=[], whitelist=[]):
  131.         logging.info("Loading filenames from directory: %s", directory)
  132.  
  133.         whitelist_patterns = [re.compile(r"^%s$" % r) for r in whitelist]
  134.         blacklist_patterns = [re.compile(r"^%s$" % r) for r in blacklist]
  135.  
  136.         elements = []
  137.         for name in os.listdir(directory):
  138.             if name.startswith(".") or name.endswith("~"):
  139.                 logging.info("Ignored filename: %s", name)
  140.                 continue
  141.  
  142.             if whitelist_patterns:
  143.                 if not [name for p in whitelist_patterns if p.match(name)]:
  144.                     logging.info("Not whitelisted filename: %s", name)
  145.                     continue
  146.             elif blacklist_patterns:
  147.                 if [name for p in blacklist_patterns if p.match(name)]:
  148.                     logging.info("Blacklisted filename: %s", name)
  149.                     continue
  150.  
  151.             filename = posixpath.join(directory, name)
  152.             elements.extend(self.load_filename(filename))
  153.  
  154.         return elements
  155.  
  156.     def load_directories(self, directories, blacklist=[], whitelist=[]):
  157.         elements = []
  158.         for directory in directories:
  159.             elements.extend(self.load_directory(directory, blacklist, whitelist))
  160.  
  161.         return elements
  162.