Пример #1
0
class View(tsumufs.Debuggable):
  '''
  Base class for tsumufs views development.
  Tsumufs views are virtual directories that provides custom presentation
  of the overlay files like sorting, custom appearance, staring, etc.
  This is possible since tsumufs based on CouchedFilesystem api from the
  python-ufo library that manage the metadatas of the filesystem in a
  CouchDb database.

  A tsumufs view is based on a python-ufo view, the minimal code required
  is the following:

    # Import the python-ufo view class
    from ufo.views import SortedByTypeSyncDocument

    class SortedByTypeView(View):

      # Name of the view.
      name = "Sorted by type"

      # Specify the levels of the view. Levels are the representation of
      # the depth levels of the view file tree.
      #
      # For the view that sort files by mimetype, an example tree could be:
      #
      # - "Sorted By Type" - "application"
      #                           - "pdf"
      #                           - "doc"
      #                           - "x-directory"
      #
      #                    - "text"
      #                           - "xml"
      #                           - "plain"
      #                           - "python"
      #                           - "x-empty"
      #
      levels = ['category', 'type']

      # Specify the python-ufo views class imported at head.
      docClass = SortedByTypeSyncDocument

    # Assign the tsumufs view class to the global variable viewClass
    # to allow to the view loader to know which class has to be
    # instantiated at startup.
    viewClass = SortedByTypeView

  All system calls could be called on a view instance by the views manager,
  so its could be overridden to provides a custom behavior in each view.
  If a system call is'nt overridden in the view class, the default system
  call for all view will be call.

  At the user side, views are accessible in the overlay mount point,
  in the directory specified by the tsumufs mount option 'viewspoint'.
  '''

  name = ""               # Displayed name of the view root directory.

  levels = []             # Ordered list of the depth levels names
                          # of the view.

  bindings = {}           # Hash of real files paths corresponding
                          # to virtual files paths in a view.

  docClass = None         # Document class of the view.

  fileClass = None        # File class of the view.

  viewDocuments = None    # Document helper to get the view documents.

  parentFolder = None     # Parent folder for the view.

  def __init__(self):
    self.viewDocuments = DocumentHelper(self.docClass, tsumufs.dbName)

    if not self.parentFolder:
      self.parentFolder = tsumufs.viewsPoint

  def getRootDocs(self):
    yield SyncDocument(dirpath=self.parentFolder,
                       filename=self.name,
                       mode=0555 | stat.S_IFDIR)

  def getDirents(self, path):
    '''
    Return the dirents from a view depth level. The levels correspond to
    the path nodes after the root directory of the view.

     - When the number of levels of the path is equal or higher than the
       number of the views ones, the returned document are documents
       contained in the filesystem. It's also called the 'file' level.

     - When the number of levels of the path is lower than the number of
       the views ones, documents returned are virtual folders that does'nt
       exist in the filesystem.

    This method computes the levels strings required to call the 'getDocuments'
    method of a view from the fusepath, and handles each returned documents to
    ensure unique filenames in the result dirents.
    '''

    fields = {}
    occurrences = {}

    if self.levels:
      filters = self.hackedPath(path).split('/')[1:]
      for index, filter in enumerate(filters):
        fields[self.levels[index]] = filter

    # Fills the result list with result filenames, handles duplicated
    # names and save the real paths corresponding to of virtual files paths
    # for further use.
    for doc in self.viewDocuments.getDocuments(**fields):
      try:
        if occurrences.has_key(doc.filename):
          occurrences[doc.filename] += 1
          filename, fileext = os.path.splitext(doc.filename)
          customname = filename + " (" + str(occurrences[doc.filename]) + ")" + fileext

        else:
          occurrences[doc.filename] = 0
          customname = doc.filename

        if self.isFileLevel(os.path.join(path, customname)):
          self.bindings[os.path.join(path, customname)] = os.path.join(doc.dirpath, doc.filename)

        doc.filename = customname

      except Exception, e:
        exc_info = sys.exc_info()

        self._debug('*** Unhandled exception occurred')
        self._debug('***     Type: %s' % str(exc_info[0]))
        self._debug('***    Value: %s' % str(exc_info[1]))
        self._debug('*** Traceback:')

        for line in traceback.extract_tb(exc_info[2]):
          self._debug('***    %s(%d) in %s: %s' % line)

        continue

      yield doc