text: import os
  import fnmatch
  
  
  class IncorrectDataFormatException(Exception):
          ''' Build-info data is in incorrect format. '''
  
  
  class BuildInfo:
      def __init__(self, fn):
          self.index = 0
          self.lines = []
          self.build_info_array = [{}]
          self.file_info_array = [{}]
          self.fields_defined = [
                  "format-version", "files-pattern", "build-name", "theme",
                  "license-type", "auth-groups", "collect-user-data",
                  "license-text",
                  # Deprecated
                  "openid-launchpad-teams",
                  ]
          self.full_file_name = fn
          self.search_path = self.get_search_path(fn)
          self.fname = os.path.basename(fn)
          self.build_info_file = os.path.join(self.search_path, "BUILD-INFO.txt")
          self.readFile()
          self.parseData(self.lines)
          self.file_info_array = self.getInfoForFile()
          self.remove_false_positives()
          self.max_index = len(self.file_info_array)
  
      @classmethod
      def get_search_path(cls, path):
          "Return BUILD-INFO.txt search path for a given filesystem path."
          if not os.path.isdir(path):
              path = os.path.dirname(path)
          return path
  
      @classmethod
      def build_info_exists(cls, path):
          "Check if BUILD-INFO.txt exists for a given filesystem path."
          return os.path.exists(
                  os.path.join(cls.get_search_path(path), "BUILD-INFO.txt"))
  
      def _set(self, key, value):
          """Record set of directives applying to a file pattern
          key: file pattern
          value: list of dicts of field/val pairs"""
          if key in self.build_info_array[self.index]:
              # A repeated key indicates we have found another chunk of
              # build-info
  
              self.build_info_array[self.index][key].append(value[0])
          else:
              self.build_info_array[self.index][key] = value
  
      def readFile(self):
          with open(self.build_info_file, "r") as infile:
              lines = infile.readlines()
          for line in lines:
              if line.strip() != '':
                  self.lines.append(line.rstrip())
  
      def getInfoForFile(self):
          for block in self.build_info_array:
  
              if self.fname in block:
                  # File name matches a key directly - don't need to iterate
                  # through each using fnmatch to implement globs.
                  return block[self.fname]
  
              if self.full_file_name == self.search_path:
                  # Searching for directory match. This will only match the "*"
                  # glob.
                  if "*" in block:
                      return block["*"]
                  else:
                      return [{}]
  
              for key in block:
                  if key != "format-version":
                      if fnmatch.fnmatch(self.full_file_name,
                                         os.path.join(self.search_path, key)):
                          return block[key]
          return [{}]
  
      def getFormatVersion(self):
          for block in self.build_info_array:
              if "format-version" in block:
                  return block["format-version"]
              else:
                  return False
  
      # Get value of specified field in block index for
      # corresponding file
      def get(self, field, index=0):
          if index > self.max_index:
              return False
          block = self.file_info_array[index]
          return block.get(field, False)
  
      def parseLine(self, line):
          values = line.split(":", 1)
          if len(values) != 2:
              raise IncorrectDataFormatException(
                      "'%s': Line is not in the correct format." % line)
          else:
              field = values[0].strip().lower()
              value = values[1].strip()
              if not self.isValidField(field):
                  raise IncorrectDataFormatException(
                          "Field '%s' not allowed." % field)
              else:
                  # Rename any deprecated field names to new names
                  field_renames = {"openid-launchpad-teams": "auth-groups"}
                  field = field_renames.get(field, field)
                  return {field: value}
  
      def isValidField(self, field_name):
          if field_name in self.fields_defined:
              return True
          else:
              return False
  
      def parseData(self, lines):
          if not isinstance(lines, list):
              raise IncorrectDataFormatException("No array provided.")
          if not list:
              raise IncorrectDataFormatException("Empty BUILD-INFO")
          format_line = lines.pop(0)
          values = self.parseLine(format_line)
          if not "format-version" in values:
              raise IncorrectDataFormatException(
                      "Format-Version field not found.")
          self._set("format-version", values["format-version"])
  
          self.line_no = 0
          while self.line_no < len(lines):
              line = lines[self.line_no]
              values = self.parseLine(line)
              if "files-pattern" in values:
                  self.line_no += 1
                  block = self.parseBlock(lines)
                  if isinstance(block, list):
                      for pattern in values["files-pattern"].split(","):
                              self._set(pattern.strip(), block)
  
      def parseBlock(self, lines):
          result = [{}]
          while self.line_no < len(lines):
              line = lines[self.line_no]
              values = self.parseLine(line)
              if "license-text" in values:
                  text = values["license-text"]
                  self.line_no += 1
                  text += self.parseContinuation(lines)
                  result[0]["license-text"] = text
              elif "files-pattern" in values:
                  return result
              else:
                  self.line_no += 1
                  key = values.keys()[0]
                  result[0][key] = values[key]
          return result
  
      def parseContinuation(self, lines):
          text = ''
          while self.line_no < len(lines) and len(lines[self.line_no]) > 0:
              if lines[self.line_no][0] == ' ':
                  text += "\n" + lines[self.line_no][1:]
                  self.line_no += 1
              else:
                  break
          return text
  
      def remove_false_positives(self):
          open_type = []
          protected_type = []
          index = 0
          if self.file_info_array == [{}]:
              return False
          for block in self.file_info_array:
              if 'license-type' in block.keys():
                  if block["license-type"] == 'open':
                      open_type.append(index)
                  if block["license-type"] == 'protected':
                      protected_type.append(index)
                  index += 1
              else:
                  return False
          if len(protected_type) != 0 and len(open_type) != 0:
              for index in open_type:
                  self.file_info_array.pop(index)
  
      @classmethod
      def write_from_array(cls, build_info_array, file_path):
          if len(build_info_array[0]):
              with open(file_path, "w") as outfile:
                  outfile.write("Format-Version: 0.5\n\n")
                  for key in build_info_array[0]:
                      if key != "format-version":
                          outfile.write("Files-Pattern: %s\n" % key)
                          for item in build_info_array[0][key][0]:
                              text = build_info_array[0][key][0][item]
                              if item == "license-text":
                                  text = text.replace("\n", "\n ")
                              outfile.write("%s: %s\n" % (item, text))
                          outfile.write("\n")
  
  
  if __name__ == "__main__":
      import sys
      bi = BuildInfo(sys.argv[1])
      for field in bi.fields_defined:
          print field + " = " + str(bi.get(field))
  