Author: dmeyer
Date: Tue Feb 14 20:01:59 2006
New Revision: 1184

Modified:
   trunk/vfs/src/client.py
   trunk/vfs/src/db.py
   trunk/vfs/src/item.py
   trunk/vfs/src/monitor.py
   trunk/vfs/src/parser.py
   trunk/vfs/src/query.py
   trunk/vfs/src/server.py

Log:
some internal redesign, breaking some stuff

Modified: trunk/vfs/src/client.py
==============================================================================
--- trunk/vfs/src/client.py     (original)
+++ trunk/vfs/src/client.py     Tue Feb 14 20:01:59 2006
@@ -61,7 +61,7 @@
         self._server = ipc.IPCClient('vfs').get_object('vfs')(db)
         self.monitor = self._server.monitor
         # read only version of the database
-        self.database = Database(db, True)
+        self.database = Database(db, self)
         # connect to server notifications
         self._server.connect(self)
         # internal list of active queries
@@ -77,28 +77,57 @@
         self._server.add_mountpoint(device, directory)
 
 
-    def query(self, **query):
+    def get(self, filename):
         """
-        Do a query to the databse. This will return a Query object.
+        Return an object for the given filename.
         """
-        # make sure filename in a query are normalized
-        if 'dirname' in query:
-            query['dirname'] = os.path.realpath(query['dirname'])
-        if 'files' in query:
-            query['files'] = [ os.path.realpath(x) for x in query['files'] ]
-        # TODO: reuse Query with same 'query'
-        result = Query(self, query)
-        self._queries.append(weakref(result))
+        result = Query(self, filename=os.path.realpath(filename))
+        return result.get()[0]
+
+
+    def vfs_request(self, id):
+        return self._server.vfs_request(id, __ipc_noproxy_result=True,
+                                        __ipc_noproxy_args=True)
 
+
+    def query(self, **query):
+        result = Query(self, **query)
+        self._queries.append(weakref(result))
         # start the remote query 100 ms seconds later. It is faster
         # that way because a) ipc takes some time and b) it avoids
         # doing the same stuff at the same time
 
         # TODO: create a client id to avoid sending self.notify to the
         # client at this point.
+        if 'parent' in query:
+            query['parent'] = query['parent']._vfs_id
         OneShotTimer(self.monitor, self.notify, result.id,
-                     __ipc_oneway=True, **query).start(0.1)
+                     **query).start(0.1)
         return result
+        
+    
+#     def query(self, **query):
+#         """
+#         Do a query to the databse. This will return a Query object.
+#         """
+#         # make sure filename in a query are normalized
+#         if 'dirname' in query:
+#             query['dirname'] = os.path.realpath(query['dirname'])
+#         if 'files' in query:
+#             query['files'] = [ os.path.realpath(x) for x in query['files'] ]
+#         # TODO: reuse Query with same 'query'
+#         result = Query(self, query)
+#         self._queries.append(weakref(result))
+
+#         # start the remote query 100 ms seconds later. It is faster
+#         # that way because a) ipc takes some time and b) it avoids
+#         # doing the same stuff at the same time
+
+#         # TODO: create a client id to avoid sending self.notify to the
+#         # client at this point.
+#         OneShotTimer(self.monitor, self.notify, result.id,
+#                      __ipc_oneway=True, **query).start(0.1)
+#         return result
 
 
     def notify(self, id, msg, *args, **kwargs):

Modified: trunk/vfs/src/db.py
==============================================================================
--- trunk/vfs/src/db.py (original)
+++ trunk/vfs/src/db.py Tue Feb 14 20:01:59 2006
@@ -45,7 +45,6 @@
 
 # kaa.vfs imports
 import item
-import util
 
 # get logging object
 log = logging.getLogger('vfs')
@@ -63,17 +62,17 @@
     # functions to it. But we need different kinds of classes for client
     # and server because the client needs to use ipc for the mounting.
 
-    def __init__(self, device, directory, vfsdir, db, read_only):
+    def __init__(self, device, directory, vfsdir, db, client):
         self.device = device
         self.directory = directory
         self.name = None
         self.id = None
         self.vfsdir = vfsdir
         self.db = db
-        self.read_only = read_only
         self.overlay = ''
         self.url = ''
-
+        self.client = client
+        
     def load(self, name):
         """
         Set name of the mountpoint (== load new media)
@@ -90,16 +89,17 @@
                 # known, set internal id
                 media = media[0]
                 self.id = ('media', media['id'])
-            elif not self.read_only:
+            elif not self.client:
+                # no client == server == write access
                 # create media entry and root filesystem
                 log.info('create media entry for %s' % self.name)
                 media = self.db.add_object("media", name=self.name, 
content='file')
                 self.id = ('media', media['id'])
             if not self.db.query(type='dir', name='', parent=self.id) and \
-                   not self.read_only:
+                   not self.client:
                 log.info('create root filesystem for %s' % self.name)
                 self.db.add_object("dir", name="", parent=self.id)
-            if not self.read_only:
+            if not self.client:
                 self.db.commit()
             if media:
                 self.url = media['content'] + '//' + self.directory
@@ -149,7 +149,7 @@
     A kaa.db based database.
     """
 
-    def __init__(self, dbdir, read_only):
+    def __init__(self, dbdir, client):
         """
         Init function
         """
@@ -157,9 +157,10 @@
         # overlay dir for the vfs
         self.dbdir = dbdir
 
-        # flag if the db should be read only
-        self.read_only = read_only
-
+        # remeber client
+        # no client == server == write access
+        self.client = client
+        
         # handle changes in a list and add them to the database
         # on commit.
         self.changes = []
@@ -203,7 +204,8 @@
         for mountpoint in self._mountpoints:
             if mountpoint.directory == directory:
                 return False
-        mountpoint = Mountpoint(device, directory, self.dbdir, self._db, 
self.read_only)
+        mountpoint = Mountpoint(device, directory, self.dbdir, self._db,
+                                self.client)
         self._mountpoints.append(mountpoint)
         self._mountpoints.sort(lambda x,y: -cmp(x.directory, y.directory))
         return True
@@ -228,18 +230,6 @@
         else:
             raise AttributeError('unknown mountpoint')
 
-        
-    def __getattr__(self, attr):
-        """
-        Interface to the db.
-        """
-        if attr == 'object_types':
-            # Return the attribute _object_types from the db.
-            # TODO: Make this a real variable which only contains the stuff
-            # we need here and make sure it is in sync between server and 
clients
-            return self._db._object_types
-        raise AttributeError(attr)
-
 
     def _get_dir(self, dirname, media):
         """
@@ -255,23 +245,24 @@
         if dirname == media.directory:
             # we know that '/' is in the db
             current = self._db.query(type="dir", name='', parent=media.id)[0]
-            return item.create(current, None, media)
+            return item.create_dir(current, media)
 
         parent = self._get_dir(os.path.dirname(dirname), media)
-        if parent == None:
-            return None
-
         name = os.path.basename(dirname)
-        current = self._db.query(type="dir", name=name, parent=parent.dbid)
-        if not current and self.read_only:
-            log.info('not in db and read only db')
-            return None
+
+        if not parent._vfs_id:
+            return item.create_dir(name, parent)
+            
+        current = self._db.query(type="dir", name=name, parent=parent._vfs_id)
+        if not current and self.client:
+            return item.create_dir(name, parent)
+
         if not current:
-            current = self._db.add_object("dir", name=name, parent=parent.dbid)
+            current = self._db.add_object("dir", name=name, 
parent=parent._vfs_id)
             self._db.commit()
         else:
             current = current[0]
-        return item.create(current, parent, media)
+        return item.create_dir(current, parent)
 
 
     def commit(self):
@@ -310,32 +301,13 @@
         self._db.delete_object((entry['type'], entry['id']))
 
 
-    def _query_dirname(self, **query):
+    def _query_dir(self, parent):
         """
-        A query to get all files in a directory. Special keyword 'dirname' in
-        the query is used for that.
+        A query to get all files in a directory.
         """
-        dirname = query['dirname']
-
-        # find correct mountpoint
-        for m in self._mountpoints:
-            if dirname.startswith(m.directory):
-                break
-
-        # get parent item (may be None for client)
-        parent = None
-        if 'parent' in query:
-            parent = query['parent']
-
-        if not parent:
-            parent = self._get_dir(dirname, m)
-
-        if parent and parent.dbid:
-            items = [ item.create(f, parent, m) for f in \
-                      self._db.query(parent = parent.dbid) ]
-        else:
-            items = []
-
+        dirname = parent.filename[:-1]
+        items = [ item.create_file(f, parent) for f in \
+                  self._db.query(parent = parent._vfs_id) ]
         # sort items based on url. The listdir is also sorted, that makes
         # checking much faster
         items.sort(lambda x,y: cmp(x.url, y.url))
@@ -347,16 +319,21 @@
         # it scan time or something like that. Also make it an option so the
         # user can turn the feature off.
         pos = -1
-        for pos, f in enumerate(util.listdir(dirname, m)):
+        for pos, (f, overlay) in enumerate(parent._vfs_listdir()):
             if pos == len(items):
                 # new file at the end
-                items.append(item.create(f, parent, m))
+                if os.path.isdir(parent.filename + f):
+                    if not overlay:
+                        items.append(item.create_dir(f, parent))
+                    continue
+                items.append(item.create_file(f, parent, overlay))
                 continue
             while f > items[pos].url:
                 # file deleted
                 i = items[pos]
                 items.remove(i)
-                if not self.read_only:
+                if not self.client:
+                    # no client == server == write access
                     # delete from database by adding it to the internal changes
                     # list. It will be deleted right before the next commit.
                     self.changes.append((self._delete, i, [], {}))
@@ -365,11 +342,16 @@
                 # same file
                 continue
             # new file
-            items.insert(pos, item.create(f, parent, m))
+            if os.path.isdir(parent.filename + f):
+                if not overlay:
+                    items.append(item.create_dir(f, parent))
+                continue
+            items.insert(pos, item.create_file(f, parent, overlay))
 
         if pos + 1 < len(items):
             # deleted files at the end
-            if not self.read_only:
+            if not self.client:
+                # no client == server == write access
                 for i in items[pos+1-len(items):]:
                     self.changes.append((self._delete, i, [], {}))
             items = items[:pos+1-len(items)]
@@ -377,86 +359,107 @@
         if self.changes:
             # need commit because some items were deleted from the db
             self.commit()
-
-        if 'recursive' in query and query['recursive']:
-            # recursive, replace the directories with the content of the dir
-            # This can take a long time on a big hd, so we need to step to keep
-            # the main loop alive.
-            # FIXME: both the step() and the fact that this can take several
-            # minutes is very bad. This should not be used at all. It can also
-            # block the server in the monitoring when checking all mtimes.
-            subdirs = [ x for x in items if x.isdir ]
-            items = [ x for x in items if not x.isdir ]
-            for subdir in subdirs:
-                items += self._query_dirname(dirname=subdir.filename[:-1],
-                                             parent=subdir, recursive=True)
-            # step now
-            kaa.notifier.step(False)
         return items
 
 
-    def _query_files(self, *args, **kwargs):
+#     def _query_attr(self, *args, **kwargs):
+#         """
+#         A query to get a list of possible values of one attribute. Special
+#         keyword 'attr' the query is used for that. This query will not return
+#         a list of items.
+#         """
+#         kwargs['distinct'] = True
+#         kwargs['attrs'] = [ kwargs['attr'] ]
+#         del kwargs['attr']
+#         return [ x[1] for x in self._db.query_raw(**kwargs)[1] if x[1] ]
+
+
+    def query(self, **query):
         """
-        A query to get a list of files. Special keyword 'filenames' (list) in
-        the query is used for that.
+        Internal query function inside the thread. This function will use the
+        corrent internal query function based on special keywords.
         """
-        files = kwargs['files']
-        del kwargs['files']
-
-        items = []
-        for f in files:
-            dirname = os.path.dirname(f)
-            basename = os.path.basename(f)
-            # TODO: cache parents here
+        if 'filename' in query and len(query) == 1:
+            # return item for filename, can't be in overlay
+            filename = query['filename']
+            dirname = os.path.dirname(filename)
+            basename = os.path.basename(filename)
             # find correct mountpoint
             for m in self._mountpoints:
                 if dirname.startswith(m.directory):
                     break
             parent = self._get_dir(dirname, m)
-            if parent:
-                dbentry = self._db.query(parent = parent.dbid, name=basename)
-                if not dbentry:
-                    dbentry = 'file://' + f
+            if parent._vfs_id:
+                # parent is a valid db item, query
+                e = self._db.query(parent=parent._vfs_id, name=basename)
+                if e:
+                    # entry is in the db
+                    basename = e[0]
+            if os.path.isdir(filename):
+                return item.create_dir(basename, parent)
+            return item.create_file(basename, parent)
+
+
+        if 'id' in query and len(query) == 1:
+            # return item based on id (id is type,id)
+            
+            i = self._db.query(type=query['id'][0], id=query['id'][1])[0]
+            # now we need a parent
+            if i['name'] == '':
+                # root node found, find correct mountpoint
+                for m in self._mountpoints:
+                    if m.id == i['parent']:
+                        break
                 else:
-                    dbentry = dbentry[0]
+                    raise AttributeError('bad media %s' % i['parent'])
+                return item.create_dir(i, m)
+            # query for parent
+            parent = self.query(id=i['parent'])
+            if i['type'] == 'dir':
+                # it is a directory, make a dir item
+                return item.create_dir(i, parent)
+            if parent._vfs_isdir:
+                # parent is dir, this item is not
+                return item.create_file(i, parent)
+            # neither dir nor file, something else
+            return item.create_item(i, parent)
+
+            
+        if 'parent' in query and len(query) == 1:
+            # return all items for the given parent (parent is an object)
+            parent = query['parent']
+            if parent._vfs_isdir:
+                return self._query_dir(parent)
+            raise AttributeError('oops, fix me')
+            
+#         if 'attr' in kwargs:
+#             return self._query_attr(*args, **kwargs)
+#         if 'device' in kwargs:
+#             # A query to monitor a media (mountpoint). Special keyword 
'media' in
+#             # the query is used for that.
+#             for m in self._mountpoints:
+#                 if m.device == kwargs['device']:
+#                     return m
+#             raise AttributeError('Unknown device' % kwargs['device'])
+#         return self._db.query(*args, **kwargs)
+
+        result = []
+        for r in self._db.query(**query):
+            # get the parent of the item
+            # FIXME: cache results here
+            parent = self.query(id=r['parent'])
+            if r['type'] == 'dir':
+                # it is a directory, make a dir item
+                result.append(item.create_dir(r, parent))
+            elif parent._vfs_isdir:
+                # parent is dir, this item is not
+                result.append(item.create_file(r, parent))
             else:
-                dbentry = basename
-            items.append(item.create(dbentry, parent, m))
-        return items
-
-
-    def _query_attr(self, *args, **kwargs):
-        """
-        A query to get a list of possible values of one attribute. Special
-        keyword 'attr' the query is used for that. This query will not return
-        a list of items.
-        """
-        kwargs['distinct'] = True
-        kwargs['attrs'] = [ kwargs['attr'] ]
-        del kwargs['attr']
-        return [ x[1] for x in self._db.query_raw(**kwargs)[1] if x[1] ]
+                # neither dir nor file, something else
+                result.append(item.create_item(r, parent))
+        return result
 
 
-    def query(self, *args, **kwargs):
-        """
-        Internal query function inside the thread. This function will use the
-        corrent internal query function based on special keywords.
-        """
-        if 'dirname' in kwargs:
-            return self._query_dirname(*args, **kwargs)
-        if 'files' in kwargs:
-            return self._query_files(*args, **kwargs)
-        if 'attr' in kwargs:
-            return self._query_attr(*args, **kwargs)
-        if 'device' in kwargs:
-            # A query to monitor a media (mountpoint). Special keyword 'media' 
in
-            # the query is used for that.
-            for m in self._mountpoints:
-                if m.device == kwargs['device']:
-                    return m
-            raise AttributeError('Unknown device' % kwargs['device'])
-        return self._db.query(*args, **kwargs)
-
 
     def add_object(self, type, *args, **kwargs):
         """
@@ -510,6 +513,13 @@
             self.commit()
 
 
+    def object_types(self):
+        """
+        Return the list of object types
+        """
+        return self._db._object_types
+
+        
     def register_object_type_attrs(self, type, *args, **kwargs):
         """
         Register a new object with attributes. Special keywords like name and

Modified: trunk/vfs/src/item.py
==============================================================================
--- trunk/vfs/src/item.py       (original)
+++ trunk/vfs/src/item.py       Tue Feb 14 20:01:59 2006
@@ -32,173 +32,202 @@
 #
 # -----------------------------------------------------------------------------
 
-import os
 
-import util
+import os
 
 UNKNOWN = -1
 
 class Item(object):
-    def __init__(self, dbid, url, data, parent, media):
-        self.dbid = dbid
+    """
+    Object Attributes:
+    url, getattr, setattr, keys
+
+    Do not access attributes starting with _vfs outside kaa.vfs
+    """
+    def __init__(self, _vfs_id, url, data, parent, media):
+        # url of the item
         self.url = url
-        self.data = data
-        self.parent = parent
-        self.db = None
-        self.media = media
-        self.changes = []
 
-    def __str__(self):
+        # internal data
+        self._vfs_id = _vfs_id
+        self._vfs_data = data
+        self._vfs_parent = parent
+        self._vfs_media = media
+        self._vfs_isdir = False
+        self._vfs_changes = []
+
+
+    def __repr__(self):
         """
         Convert object to string (usefull for debugging)
         """
         return '<vfs.Item %s>' % self.url
 
 
-    def set_data(self, data):
-        """
-        Callback for add_object.
-        """
-        # TODO: do we need to set more attributes?
-        self.data = data
-        self.dbid = data['type'], data['id']
-            
-
-    def __getitem__(self, key):
-        if self.data.has_key(key):
-            return self.data[key]
-        if self.data.has_key('tmp:' + key):
-            return self.data['tmp:' + key]
+    def _vfs_database_update(self, data):
+        # callback from db
+        self._vfs_data = data
+        self._vfs_id = (data['type'], data['id'])
 
-        # TODO: maybe get cover from parent (e.g. cover in a dir)
-        # Or should that be stored in each item
+        
+    def _vfs_db(self):
+        # get db
+        return self._vfs_media.client
 
+    
+    def getattr(self, key):
+        # FIXME: make sure we have db data
+        if self._vfs_data.has_key(key):
+            return self._vfs_data[key]
         return None
 
 
-    def __setitem__(self, key, value):
-        self.data[key] = value
-        if not self.changes and self.dbid:
+    def setattr(self, key, value):
+        self._vfs_data[key] = value
+        if not self._vfs_changes and self._vfs_id:
             # FIXME: how to update an item not in the db yet?
             self.db.update(self)
-        if not key in self.changes:
-            self.changes.append(key)
+        if not key in self._vfs_changes:
+            self._vfs_changes.append(key)
         
             
     def keys(self):
-        return self.data.keys()
+        return self._vfs_data.keys()
 
     
 class Directory(Item):
     """
     A directory based item.
+    Object Attributes:
+    url, filename, getattr, setattr, keys, listdir
+
+    Do not access attributes starting with _vfs outside kaa.vfs
     """
-    def __init__(self, dbid, basename, filename, url, data, parent,
-                 overlay, media):
-        Item.__init__(self, dbid, url, data, parent, media)
-        self.basename = basename
-        self.filename = filename
-        self.isdir = True
-        self.overlay = overlay
-        self._os_listdir = None
+    def __init__(self, data, parent):
+        # Notes: filename end with '/'
+        if isinstance(data, str):
+            # fake item, there is no database entry
+            id = None
+            self.filename = parent.filename + data + '/' 
+            data = { 'name': data, 'mtime': UNKNOWN }
+            media = parent._vfs_media
+        elif isinstance(parent, Directory):
+            # db data
+            id = (data['type'], data['id'])
+            media = parent._vfs_media
+            self.filename = parent.filename + data['name'] + '/'
+        else:
+            # root directory
+            id = (data['type'], data['id'])
+            media = parent
+            parent = None
+            self.filename = media.directory
+
+        Item.__init__(self, id, 'file://' + self.filename, data, parent, media)
+        self._vfs_overlay = False
+        self._vfs_isdir = True
 
 
     def listdir(self):
-        """
-        List the directory. This returns a database object.
-        """
-        if self.db:
-            return self.db.query(dirname=self.filename)
-        raise AttributeError('item has no db object')
-
+        if not self._vfs_id:
+            # item is not in db, request information now
+            
self._vfs_database_update(self._vfs_db().vfs_request(self.filename[:-1]))
+        return self._vfs_db().query(parent=self).get()
+        
 
-    def os_listdir(self):
-        """
-        Return (cached) os.listdir information including the overlay dir.
-        The result is a list of basename, url.
-        """
-        if self._os_listdir == None:
-            listing = util.listdir(self.filename[:-1], self.media)
-            self._os_listdir = [ (x[x.rfind('/')+1:], x) for x in listing ]
-        return self._os_listdir
+    def _vfs_listdir(self):
+        try:
+            listdir = os.listdir(self.filename)
+        except OSError:
+            return []
+
+        media = self._vfs_media
+        overlay = media.overlay + '/' + self.filename[len(media.directory):]
+        try:
+            result = [ ( x, True ) for x in os.listdir(overlay) \
+                       if not x.startswith('.') and not x in listdir ]
+        except OSError:
+            result = []
+        result += [ ( x, False ) for x in listdir if not x.startswith('.') ]
+        result.sort(lambda x,y: cmp(x[0], y[0]))
+        return result
+        
+#     def listdir(self):
+#         """
+#         List the directory. This returns a database object.
+#         """
+#         if self.db:
+#             return self.db.query(dirname=self.filename)
+#         raise AttributeError('item has no db object')
+
+
+#     def os_listdir(self):
+#         """
+#         Return (cached) os.listdir information including the overlay dir.
+#         The result is a list of basename, url.
+#         """
+#         if self._os_listdir == None:
+#             listing = util.listdir(self.filename[:-1], self.media)
+#             self._os_listdir = [ (x[x.rfind('/')+1:], x) for x in listing ]
+#         return self._os_listdir
 
         
-    def __str__(self):
+    def __repr__(self):
         """
         Convert object to string (usefull for debugging)
         """
         str = '<vfs.Directory %s' % self.filename
-        if self.data['mtime'] == UNKNOWN:
-            str += '(new)'
+        if self._vfs_data['mtime'] == UNKNOWN:
+            str += ' (new)'
         return str + '>'
     
 
 class File(Item):
     """
     A file based item.
+    Object Attributes:
+    url, filename, getattr, setattr, keys
+
+    Do not access attributes starting with _vfs outside kaa.vfs
     """
-    def __init__(self, dbid, basename, filename, url, data, parent,
-                 overlay, media):
-        Item.__init__(self, dbid, url, data, parent, media)
-        self.basename = basename
-        self.filename = filename
-        self.overlay = overlay
-        self.isdir = False
+    def __init__(self, data, parent, overlay=False):
+        if isinstance(data, str):
+            # fake item, there is no database entry
+            id = None
+            self.filename = parent.filename + data
+            data = { 'name': data, 'mtime': UNKNOWN }
+            media = parent._vfs_media
+        elif isinstance(parent, Directory):
+            # db data
+            id = (data['type'], data['id'])
+            media = parent._vfs_media
+            self.filename = parent.filename + data['name']
+
+        Item.__init__(self, id, 'file://' + self.filename, data, parent, media)
+        self._vfs_overlay = overlay
 
 
-    def __str__(self):
+    def __repr__(self):
         """
         Convert object to string (usefull for debugging)
         """
         str = '<vfs.File %s' % self.filename
-        if self.data['mtime'] == UNKNOWN:
-            str += '(new)'
+        if self._vfs_data['mtime'] == UNKNOWN:
+            str += ' (new)'
         return str + '>'
 
 
-# TODO: add media class or mountpoint
+# make it possible to override these
 
-def create(data, parent, media):
+def create_dir(data, parent):
     """
-    Create an Item object or an inherted class if possible.
+    Create a Directory item.
     """
+    return Directory(data, parent)
 
-    # FIXME: handle items not based on files here
-
-    if isinstance(data, dict):
-        if parent == None:
-            # root fileystem for the media, always valid and in the db
-            dirname = media.directory
-            return Directory((data['type'], data['id']), '', dirname,
-                             'file:/%s/' % dirname, data, parent, False, media)
-        # Data is based on a db entry. This means we also have
-        # a parent as db entry
-        dbid = data['type'], data['id']
-        type = data['type']
-
-        if type.startswith('track'):
-            # data is a track of a dvd/vcd/audiocd an a media or in a file
-            return Item(dbid, parent.url + '/' + data['name'], data, parent, 
media)
-        basename = data['name']
-        overlay = data['overlay']
-        filename = parent.filename + basename
-        if overlay:
-            filename = media.overlay + filename
-        url = 'file://' + filename
-    else:
-        # Looks like data is string (url). This means no db entry, maybe the 
parent
-        # is also not set (client db read only). The media is always valid.
-        url = data
-        filename = data[7:]
-        basename = os.path.basename(filename)
-        dbid = None
-        data = { 'name': data, 'mtime': UNKNOWN }
-        type = ''
-        overlay = filename.startswith(media.overlay)
-
-    if type == 'dir' or (not type and os.path.isdir(filename)):
-        # it is a directory
-        return Directory(dbid, basename, filename + '/',
-                         url, data, parent, overlay, media)
-    # it is a file
-    return File(dbid, basename, filename, url, data, parent, overlay, media)
+    
+def create_file(data, parent, overlay=False):
+    """
+    Create a File item.
+    """
+    return File(data, parent, overlay)

Modified: trunk/vfs/src/monitor.py
==============================================================================
--- trunk/vfs/src/monitor.py    (original)
+++ trunk/vfs/src/monitor.py    Tue Feb 14 20:01:59 2006
@@ -109,56 +109,59 @@
         t1 = time.time()
         self.items = self._db.query(**self._query)
         print 'monitor query took', time.time() - t1
-        if self._query.has_key('device'):
-            log.info('unable to update device query, just send notification 
here')
-            # device query, can't update it
-            if send_checked:
-                log.info('client.checked')
-                self.callback('checked')
-                return
 
-        last_parent = None
-        t1 = time.time()
-        for i in self.items:
-            # FIXME: this does not scale very good. For many items like a
-            # recursive dir search it can take several seconds to scan all 
mtimes
-            # and this is not an option.
-            if not isinstance(i, item.Item):
-                # TODO: don't know how to monitor other types
-                continue
-
-            # check parent and parent.parent mtime. Notice. The root
-            # dir has also a parent, the media itself. So we need to stop at
-            # parent.parent == None.
-            parent = i.parent
-            parent_check = []
-            while last_parent != parent and parent and parent.parent:
-                mtime = parser.get_mtime(parent)
-                if mtime and parent.data['mtime'] != mtime and not parent in 
to_check:
-                    parent_check.append(weakref(parent))
-                parent = parent.parent
-            if parent_check:
-                parent_check.reverse()
-                to_check += parent_check
-            last_parent = i.parent
+        return
+    
+    #     if self._query.has_key('device'):
+#             log.info('unable to update device query, just send notification 
here')
+#             # device query, can't update it
+#             if send_checked:
+#                 log.info('client.checked')
+#                 self.callback('checked')
+#                 return
+
+#         last_parent = None
+#         t1 = time.time()
+#         for i in self.items:
+#             # FIXME: this does not scale very good. For many items like a
+#             # recursive dir search it can take several seconds to scan all 
mtimes
+#             # and this is not an option.
+#             if not isinstance(i, item.Item):
+#                 # TODO: don't know how to monitor other types
+#                 continue
+
+#             # check parent and parent.parent mtime. Notice. The root
+#             # dir has also a parent, the media itself. So we need to stop at
+#             # parent.parent == None.
+#             parent = i.parent
+#             parent_check = []
+#             while last_parent != parent and parent and parent.parent:
+#                 mtime = parser.get_mtime(parent)
+#                 if mtime and parent.data['mtime'] != mtime and not parent in 
to_check:
+#                     parent_check.append(weakref(parent))
+#                 parent = parent.parent
+#             if parent_check:
+#                 parent_check.reverse()
+#                 to_check += parent_check
+#             last_parent = i.parent
             
-            mtime = parser.get_mtime(i)
-            if not mtime:
-                continue
-            if i.data['mtime'] == mtime:
-                continue
-            to_check.append(weakref(i))
-
-        print 'mtime query took %s, %s items to check' % (time.time()-t1, 
len(to_check))
-
-        if to_check:
-            # FIXME: a constantly growing file like a recording will result in
-            # a huge db activity on both client and server because checker 
calls
-            # update again and the mtime changed.
-            self._checker = weakref(parser.Checker(weakref(self), self._db, 
to_check))
-        elif send_checked:
-            log.info('client.checked')
-            self.callback('checked')
+#             mtime = parser.get_mtime(i)
+#             if not mtime:
+#                 continue
+#             if i.data['mtime'] == mtime:
+#                 continue
+#             to_check.append(weakref(i))
+
+#         print 'mtime query took %s, %s items to check' % (time.time()-t1, 
len(to_check))
+
+#         if to_check:
+#             # FIXME: a constantly growing file like a recording will result 
in
+#             # a huge db activity on both client and server because checker 
calls
+#             # update again and the mtime changed.
+#             self._checker = weakref(parser.Checker(weakref(self), self._db, 
to_check))
+#         elif send_checked:
+#             log.info('client.checked')
+#             self.callback('checked')
 
 
     def __str__(self):

Modified: trunk/vfs/src/parser.py
==============================================================================
--- trunk/vfs/src/parser.py     (original)
+++ trunk/vfs/src/parser.py     Tue Feb 14 20:01:59 2006
@@ -52,11 +52,11 @@
     if not item.filename:
         log.info('no filename == no mtime :(')
         return 0
-    if not item.parent:
+    if not item._vfs_parent:
         log.info('no parent == no mtime :(')
         return 0
 
-    if item.isdir:
+    if item._vfs_isdir:
         # TODO: add overlay dir to mtime
         return os.stat(item.filename)[stat.ST_MTIME]
 
@@ -76,33 +76,36 @@
     return mtime
 
 
-def parse(db, item):
+def parse(db, item, store=False):
+    print 'check', item
     mtime = get_mtime(item)
     if not mtime:
         log.info('oops, no mtime %s' % item)
         return
-    if not item.parent:
+    parent = item._vfs_parent
+    if not parent:
         log.error('no parent %s' % item)
         return
-    if not item.parent.dbid:
+
+    if not parent._vfs_id:
         # There is a parent without id, update the parent now. We know that the
         # parent should be in the db, so commit and it should work
         db.commit()
-        if not item.parent.dbid:
+        if not parent._vfs_id:
             # this should never happen
             raise AttributeError('parent for %s has no dbid' % item)
-    if item.data['mtime'] == mtime:
+    if item._vfs_data['mtime'] == mtime:
         log.debug('up-to-date %s' % item)
         return
     log.info('scan %s' % item)
     attributes = { 'mtime': mtime }
     metadata = kaa.metadata.parse(item.filename)
-    if item.data.has_key('type'):
-        type = item.data['type']
+    if item._vfs_data.has_key('type'):
+        type = item._vfs_data['type']
     elif metadata and metadata['media'] and \
-             db.object_types.has_key(metadata['media']):
+             db.object_types().has_key(metadata['media']):
         type = metadata['media']
-    elif item.isdir:
+    elif item._vfs_isdir:
         type = 'dir'
     else:
         type = 'file'
@@ -120,16 +123,19 @@
     # Note: the items are not updated yet, the changes are still in
     # the queue and will be added to the db on commit.
 
-    if item.dbid:
+    if item._vfs_id:
         # Update
-        db.update_object(item.dbid, **attributes)
-        item.data.update(attributes)
+        db.update_object(item._vfs_id, **attributes)
+        item._vfs_data.update(attributes)
     else:
         # Create. Maybe the object is already in the db. This could happen 
because
         # of bad timing but should not matter. Only one entry will be there 
after
         # the next update
-        db.add_object(type, name=item.basename, parent=item.parent.dbid,
-                      overlay=item.overlay, callback=item.set_data, 
**attributes)
+        db.add_object(type, name=item._vfs_data['name'], parent=parent._vfs_id,
+                      overlay=item._vfs_overlay, 
callback=item._vfs_database_update,
+                      **attributes)
+    if store:
+        db.commit()
     return True
 
 

Modified: trunk/vfs/src/query.py
==============================================================================
--- trunk/vfs/src/query.py      (original)
+++ trunk/vfs/src/query.py      Tue Feb 14 20:01:59 2006
@@ -46,7 +46,7 @@
     """
     NEXT_ID = 1
 
-    def __init__(self, client, query):
+    def __init__(self, client, **query):
         self.signals = {
             'changed': Signal(),
             'progress': Signal(),
@@ -58,10 +58,13 @@
         self._monitor = None
         self._client = client
         self._result = []
-        for r in self._client.database.query(**query):
-            r.db = self._client
-            self._result.append(r)
-
+        result = self._client.database.query(**query)
+        if isinstance(result, list):
+            for r in result:
+                self._result.append(r)
+        else:
+            self._result.append(result)
+    
 
     def get(self):
         """

Modified: trunk/vfs/src/server.py
==============================================================================
--- trunk/vfs/src/server.py     (original)
+++ trunk/vfs/src/server.py     Tue Feb 14 20:01:59 2006
@@ -42,6 +42,7 @@
 from kaa.notifier import OneShotTimer
 
 # kaa.vfs imports
+import parser
 from db import *
 from monitor import Monitor
 
@@ -57,7 +58,7 @@
     scanning / monitoring of queries.
     """
     def __init__(self, dbdir):
-        self._db = Database(dbdir, False)
+        self._db = Database(dbdir, None)
 
         # files
         
@@ -134,6 +135,10 @@
         """
         Create a monitor object to monitor a query for a client.
         """
+        if 'parent' in query:
+            type, id = query['parent']
+            query['parent'] = self._db.query(type=type, id=id)[0]
+
         monitor = Monitor(callback, self._db, self, id, query)
         log.debug('create %s' % monitor)
         callback(id, 'connect', monitor)
@@ -181,6 +186,19 @@
         self._db.commit()
 
         
+    def vfs_request(self, filename):
+        self._db.commit()
+        data = self._db.query(filename=filename)
+        items = []
+        while not data._vfs_id:
+            items.append(data)
+            data = data._vfs_parent
+        while items:
+            parser.parse(self._db, items.pop(), store=True)
+        self._db.commit()
+        return data._vfs_data
+
+    
     def __del__(self):
         """
         Debug in __del__.


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to