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