Author: dmeyer
Date: Sun Oct 30 08:32:59 2005
New Revision: 882

Modified:
   trunk/vfs/src/client.py
   trunk/vfs/src/server.py
   trunk/vfs/test/client.py
   trunk/vfs/test/server.py

Log:
some basic testing code working

Modified: trunk/vfs/src/client.py
==============================================================================
--- trunk/vfs/src/client.py     (original)
+++ trunk/vfs/src/client.py     Sun Oct 30 08:32:59 2005
@@ -1,11 +1,50 @@
-from kaa.base import ipc
-from kaa.notifier import Signal
+import time
+from kaa.base import ipc, weakref
+from kaa.notifier import Signal, Callback
 
+class Query(object):
+    def __init__(self, query, remote_object):
+        self._query = query
+        self.remote_object = remote_object
+        t1 = time.time()
+        self.items = remote_object.execute(__ipc_copy_result=True)
+        t2 = time.time()
+        print 'init query took %s' % (t2 - t1)
+        
+    def update(self):
+        self.remote_query.update(__ipc_oneway=True)
+
+    def notify(self, event, *args, **kwargs):
+        if event == 'progress':
+            print 'progress: %s of %s' % (args[0], args[1])
+            return
+        if event == 'changed':
+            print 'remote object changed'
+            t1 = time.time()
+            self.items = self.remote_object.execute(__ipc_copy_result=True)
+            t2 = time.time()
+            print 'update query took %s' % (t2 - t1)
+            
+        
 class Client(object):
     def __init__(self):
         self._ipc = ipc.IPCClient('vfs')
         self._server = self._ipc.get_object('vfs')
+        self._active_queries = []
 
-    def listdir(self, dirname):
-        return self._server.query(dir=dirname)
+    def query(self, **kwargs):
+        remote_query = self._server.query(self.notify, **kwargs)
+        query = Query(kwargs, remote_query)
+        self._active_queries.append(weakref(query))
+        return query
         
+    def listdir(self, dirname):
+        return self.query(dir=dirname)
+    
+    def notify(self, object, *args, **kwargs):
+        for q in self._active_queries:
+            if not q:
+                continue
+            if q.remote_object._query == object:
+                q.notify(*args, **kwargs)
+                

Modified: trunk/vfs/src/server.py
==============================================================================
--- trunk/vfs/src/server.py     (original)
+++ trunk/vfs/src/server.py     Sun Oct 30 08:32:59 2005
@@ -1,23 +1,48 @@
 import os
+import stat
 
-from kaa.base import ipc
+from kaa.base import ipc, weakref
 from kaa.base.db import *
-from kaa.notifier import Signal
+from kaa.notifier import Signal, OneShotTimer, Timer
+import kaa.metadata
 
 class Item(object):
     def __init__(self, data, parent, db):
         self.data = data
         self.parent = parent
         self.db = db
-        if isinstance(self.data, dict) and parent and parent.isdir():
 
-            # TODO: handle parents not based on file:
+        # self.dirname always ends with a slash
+        # if the item is a dir, self.filename also ends with a slash
+        # self.url does not end with a slash (except root)
+        
+        # If parent is not set, this is a root node. A root node
+        # is always part of the db already
+        if not parent:
+            self.url = 'file:/' + self.data['name']
+            self.dirname = self.data['name']
+            self.filename = self.data['name']
+            self.isdir = True
+            self.basename = '/'
+            return
+
+        if isinstance(self.data, dict):
+            self.basename = self.data['name']
+        else:
+            self.basename = self.data
 
-            if self.parent['url'] == 'file:/':
-                self.data['url'] = 'file:/' + self.data['name']
+        # check if the item s based on a file
+        if parent.filename:
+            self.url = 'file:/' + parent.filename + self.basename
+            self.dirname = parent.filename
+            self.filename = parent.filename + self.basename
+            if os.path.isdir(self.filename):
+                self.filename += '/'
+                self.isdir = True
             else:
-                self.data['url'] = self.parent['url'] + '/' + self.data['name']
-        self.__changes = {}
+                self.isdir = False
+                    
+        # TODO: handle files/parents not based on file:
 
 
     def __id__(self):
@@ -42,24 +67,138 @@
         return None
 
 
-    def isdir(self):
-        if isinstance(self.data, (str, unicode)):
-            return os.path.isdir(self.parent['url'][5:] + '/' + self.data)
-        return self.data['type'] == 'dir'
+#     def __del__(self):
+#         print 'del %s' % self
 
+
+def get_mtime(item):
+    if not item.filename:
+        print 'no filename == no mtime :('
+        return 0
+
+    mtime = 0
+    if item.isdir:
+        return os.stat(item.filename)[stat.ST_MTIME]
+
+    # mtime is the the mtime for all files having the same
+    # base. E.g. the mtime of foo.jpg is the sum of the
+    # mtimeof foo.jpg and foo.jpg.xml or for foo.mp3 the
+    # mtime is the sum of foo.mp3 and foo.jpg.
+    
+    base = os.path.splitext(item.filename)[0]
+    
+    # TODO: add overlay support
+    
+    # TODO: Make this much faster. We should cache the listdir
+    # and the stat results somewhere, maybe already split by ext
+    # But since this is done in background, this is not so
+    # important right now.
+    files = map(lambda x: item.dirname + x, os.listdir(item.dirname))
+    for f in filter(lambda x: x.startswith(base), files):
+        mtime += os.stat(f)[stat.ST_MTIME]
+    return mtime
     
 
+def parse(db, item):
+    mtime = get_mtime(item)
+    if not mtime:
+        print 'oops, no mtime', item
+        return
+    attributes = { 'mtime': mtime }
+    metadata = kaa.metadata.parse(item.filename)
+    if isinstance(item.data, dict):
+        type = item.data['type']
+    elif metadata and metadata['media'] and \
+             db._object_types.has_key(metadata['media']):
+        type = metadata['media']
+    elif item.isdir:
+        type = 'dir'
+    else:
+        type = 'file'
+
+    type_list = db._object_types[type]
+    for key in type_list[1].keys():
+        if metadata and metadata.has_key(key) and metadata[key] != None:
+            attributes[key] = metadata[key]
+
+    # TODO: do some more stuff here:
+    # - check metadata for thumbnail or cover (audio) and use kaa.thumb to 
store it
+    # - schedule thumbnail genereation with kaa.thumb
+    # - search for covers based on the file (should be done by kaa.metadata)
+    # - maybe the item is now in th db so we can't add it again
+    if isinstance(item.data, dict):
+        # update
+        id = item.data['id']
+        db.update_object((type, id), **attributes)
+        item.data.update(attributes)
+    else:
+        # create
+        item.data = db.add_object(type, name=item.basename,
+                                  parent=item.parent.__id__(),
+                                  **attributes)
+    return True
 
+class Checker(object):
+    def __init__(self, db, items, progress, callback):
+        self.db = db
+        self.items = items
+        self.max = len(items)
+        self.pos = 0
+        self.progress = progress
+        self.callback = callback
+        Timer(self.check).start(0.01)
+
+    def check(self):
+        if not self.items:
+            self.db.commit()
+            self.callback()
+            return False
+        self.pos += 1
+        self.progress(self.pos, self.max)
+        item = self.items[0]
+        parse(self.db, item)
+        self.items = self.items[1:]
+        return True
+    
 class Query(object):
-    def __init__(self, db):
+    def __init__(self, server, db, query):
+        self._server = server
         self._db = db
-        self.items = []
+        self._items = []
+        self._query = query
+        
+    def __del__(self):
+        print 'DEL'
 
+    def check_query(self):
+        need_update = []
+        for i in self._items:
+            if not i.filename:
+                # FIXME: handle non file items
+                pass
+            elif not isinstance(i.data, dict):
+                # Never scanned by the db
+                need_update.append(i)
+            elif get_mtime(i) != i.data['mtime']:
+                # updated on disc
+                need_update.append(i)
+        self.progress(0, len(need_update))
+        if need_update:
+            Checker(self._db, need_update, self.progress, self.changed)
+
+    def progress(self, pos, all):
+        self._server.notify(self, 'progress', pos, all, __ipc_oneway=True)
+        
+    def changed(self):
+        self._server.notify(self, 'changed', __ipc_oneway=True)
+        
 class DirectoryQuery(Query):
     def __init__(self, server, db, **kwargs):
-        Query.__init__(self, db)
+        Query.__init__(self, server, db, kwargs)
         self.dir = server.get_dir(kwargs['dir'])
         
+    def execute(self):
+        self._items = []
         dirname = os.path.normpath(self.dir['url'][5:])
         files = self._db.query(parent = ("dir", self.dir["id"]))
         fs_listing = os.listdir(dirname)
@@ -71,7 +210,7 @@
             if f['name'] in fs_listing:
                 # file still there
                 fs_listing.remove(f['name'])
-                self.items.append(Item(f, self, self._db))
+                self._items.append(Item(f, self.dir, self._db))
             else:
                 # file deleted
                 files.remove(f)
@@ -79,18 +218,18 @@
 
         for f in fs_listing:
             # new files
-            self.items.append(Item(f, self, self._db))
+            self._items.append(Item(f, self.dir, self._db))
             
-        for i in self.items:
-            print i
-        print 'DONE'
+#         for i in self._items:
+#             print i
+        OneShotTimer(self.check_query).start(0.01)
+        return self._items
+
         
 class Server(object):
     def __init__(self, dbdir):
-        self.signals = {
-            "updated": Signal(),
-        }
-
+        if not os.path.isdir(dbdir):
+            os.makedirs(dbdir)
         self._db = Database(dbdir + '/db')
 
         self.register_object_type_attrs("dir",
@@ -126,7 +265,7 @@
             mtime = (int, ATTR_SIMPLE),
             width = (int, ATTR_SEARCHABLE),
             height = (int, ATTR_SEARCHABLE),
-            date = (int, ATTR_SEARCHABLE))
+            date = (unicode, ATTR_SEARCHABLE))
 
         # TODO: add more known types
         
@@ -145,17 +284,19 @@
         self._ipc = ipc.IPCServer('vfs')
         self._ipc.signals["client_closed"].connect_weak(self._client_closed)
         self._ipc.register_object(self, "vfs")
-
+        self._active_queries = []
 
     def register_object_type_attrs(self, *args, **kwargs):
         return self._db.register_object_type_attrs(*args, **kwargs)
 
     
-    def query(self, **kwargs):
+    def query(self, callback, **kwargs):
         if 'dir' in kwargs:
-            return DirectoryQuery(self, self._db, **kwargs)
-        raise AttributeError('query not supported')
-
+            query = DirectoryQuery(self, self._db, **kwargs)
+        else:
+            raise AttributeError('query not supported')
+        self._active_queries.append((weakref(query), callback))
+        return query
         
     def get_dir(self, dirname):
         if dirname in self._dir_cache:
@@ -179,9 +320,16 @@
         self._parent_cache[current.__id__()] = current
         return current
 
-        
+    def notify(self, object, *args, **kwargs):
+        for local, remote in self._active_queries:
+            if local == object:
+#                 print 'found'
+                remote(object._query, *args, **kwargs)
+        pass
+    
     def _client_closed(self, client):
-        for signal in self.signals.values():
-            for callback in signal:
-                if ipc.get_ipc_from_proxy(callback) == client:
-                    signal.disconnect(callback)
+        pass
+#         for signal in self.signals.values():
+#             for callback in signal:
+#                 if ipc.get_ipc_from_proxy(callback) == client:
+#                     signal.disconnect(callback)

Modified: trunk/vfs/test/client.py
==============================================================================
--- trunk/vfs/test/client.py    (original)
+++ trunk/vfs/test/client.py    Sun Oct 30 08:32:59 2005
@@ -1,15 +1,31 @@
 import kaa.vfs.client
+from kaa.notifier import Timer
+import sys
 import kaa
+import time
 
-def foo(self):
-    print 'done 2'
+def foo():
+    print 'delete all'
+    global l
+    l = None
+
+def progress(pos, max):
+    print pos, max
     
 c = kaa.vfs.client.Client()
-l = c.listdir('/home/dmeyer/video')
-print l
-for i in l.items:
-    print i
+t1 = time.time()
+l = c.listdir('/home/dmeyer/images/eemshaven/mager')
+t2 = time.time()
+print 'client thinks query took %s for %s items' % (t2 - t1, len(l.items))
+#print l
+#for i in l.items:
+#    print i
 #l.update(__ipc_async = foo)
 print 'done'
-print l
+#l.signals['progress'].connect(progress)
+
+#print l.update()
+
+# Timer(foo).start(5)
+print 'loop'
 kaa.main()

Modified: trunk/vfs/test/server.py
==============================================================================
--- trunk/vfs/test/server.py    (original)
+++ trunk/vfs/test/server.py    Sun Oct 30 08:32:59 2005
@@ -1,5 +1,19 @@
 import kaa.vfs.server
+from kaa.notifier import Timer
 import kaa
+import gc
+
+def do_gc():
+    g = gc.collect()
+    print g
+    if g:
+        print 'gc: deleted %s objects' % g
+    if gc.garbage:
+        print 'gc: found %s garbage objects' % len(gc.garbage)
+        for g in gc.garbage:
+            print g
+    return True
 
 guide = kaa.vfs.server.Server("foo")
+Timer(do_gc).start(1)
 kaa.main()


-------------------------------------------------------
This SF.Net email is sponsored by the JBoss Inc.
Get Certified Today * Register for a JBoss Training Course
Free Certification Exam for All Training Attendees Through End of 2005
Visit http://www.jboss.com/services/certification for more information
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to