Author: dmeyer
Date: Fri Feb 17 19:56:27 2006
New Revision: 1186
Modified:
trunk/WIP/vfs/src/client.py
trunk/WIP/vfs/src/db.py
trunk/WIP/vfs/src/item.py
trunk/WIP/vfs/src/monitor.py
trunk/WIP/vfs/src/parser.py
trunk/WIP/vfs/src/query.py
trunk/WIP/vfs/src/server.py
Log:
more updates
Modified: trunk/WIP/vfs/src/client.py
==============================================================================
--- trunk/WIP/vfs/src/client.py (original)
+++ trunk/WIP/vfs/src/client.py Fri Feb 17 19:56:27 2006
@@ -59,11 +59,11 @@
db = os.path.abspath(db)
# monitor function from the server to start a new monitor for a query
self._server = ipc.IPCClient('vfs').get_object('vfs')(db)
- self.monitor = self._server.monitor
+ self._server_monitor = self._server.monitor
# read only version of the database
self.database = Database(db, self)
# connect to server notifications
- self._server.connect(self)
+ self.id = self._server.connect(self, self._vfs_notify)
# internal list of active queries
self._queries = []
# internal list of items to update
@@ -81,31 +81,19 @@
"""
Return an object for the given filename.
"""
- 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)
+ return Query(self, filename=os.path.realpath(filename)).result
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,
- **query).start(0.1)
+ OneShotTimer(self._server_monitor, self.id, result.id, query,
+ __ipc_noproxy_args=True, __ipc_oneway=True).start(0.01)
return result
-
+
# def query(self, **query):
# """
# Do a query to the databse. This will return a Query object.
@@ -130,13 +118,22 @@
# return result
- def notify(self, id, msg, *args, **kwargs):
+ def _vfs_request(self, filename):
+ """
+ Request information about a filename.
+ """
+ return self._server.request(filename, __ipc_noproxy_result=True,
+ __ipc_noproxy_args=True)
+
+
+ def _vfs_notify(self, id, msg, *args, **kwargs):
"""
Internal notification callback from the server. The Monitor does not
has a reference to the Query because this would result in circular
dependencies. So this function is needed to find the correct Query
for a request.
"""
+ print 'NOTIFY', id, msg
for query in self._queries:
if query and query.id == id:
if hasattr(query, '_vfs_%s' % msg):
@@ -145,37 +142,37 @@
log.error('Error: unknown message from server: %s' % msg)
return
-
+
# not found, possibly already deleted, check for dead weakrefs
for query in self._queries[:]:
if not query:
self._queries.remove(query)
- def update(self, item=None):
- """
- Update item in next main loop interation.
- """
- if not item:
- # do the update now
- items = []
- for i in self._changed:
- changes = {}
- for var in i.changes:
- changes[var] = i[var]
- i.changes = []
- items.append((i.dbid, changes))
- self._changed = []
- self._server.update(items, __ipc_oneway=True,
__ipc_noproxy_args=True)
- return
-
- if not self._changed:
- # register timer to do the changes
- OneShotTimer(self.update).start(0.1)
- self._changed.append(item)
+# def update(self, item=None):
+# """
+# Update item in next main loop interation.
+# """
+# if not item:
+# # do the update now
+# items = []
+# for i in self._changed:
+# changes = {}
+# for var in i.changes:
+# changes[var] = i[var]
+# i.changes = []
+# items.append((i.dbid, changes))
+# self._changed = []
+# self._server.update(items, __ipc_oneway=True,
__ipc_noproxy_args=True)
+# return
+
+# if not self._changed:
+# # register timer to do the changes
+# OneShotTimer(self.update).start(0.1)
+# self._changed.append(item)
- def __str__(self):
+ def __repr__(self):
"""
Convert object to string (usefull for debugging)
"""
Modified: trunk/WIP/vfs/src/db.py
==============================================================================
--- trunk/WIP/vfs/src/db.py (original)
+++ trunk/WIP/vfs/src/db.py Fri Feb 17 19:56:27 2006
@@ -43,14 +43,15 @@
from kaa.base import db
from kaa.base.db import *
-# kaa.vfs imports
-import item
-
# get logging object
log = logging.getLogger('vfs')
MAX_BUFFER_CHANGES = 20
+# Item generation mapping
+from item import Directory as create_dir
+from item import File as create_file
+
class Mountpoint(object):
"""
Internal class for mountpoints. More a list of attributes important
@@ -112,25 +113,25 @@
return True
- def item(self):
- """
- Get the id of the mountpoint. This functions needs the database
- and _must_ be called from the same thread as the db itself.
- Return the root item for the mountpoint.
- """
- if not self.id:
- return None
- media = self.db.query(type='media', id=self.id[1])
- content = media[0]['content']
- if content == 'file':
- # a simple data dir
- current = self.db.query(type="dir", name='', parent=self.id)[0]
- return item.create(current, None, self)
- # a track of something else
- return [ item.create(x, self, self) for x in \
- self.db.query(type='track_%s' % content, parent=self.id) ]
- # TODO: support other media
- return None
+# def item(self):
+# """
+# Get the id of the mountpoint. This functions needs the database
+# and _must_ be called from the same thread as the db itself.
+# Return the root item for the mountpoint.
+# """
+# if not self.id:
+# return None
+# media = self.db.query(type='media', id=self.id[1])
+# content = media[0]['content']
+# if content == 'file':
+# # a simple data dir
+# current = self.db.query(type="dir", name='', parent=self.id)[0]
+# return item.create(current, None, self)
+# # a track of something else
+# return [ item.create(x, self, self) for x in \
+# self.db.query(type='track_%s' % content, parent=self.id) ]
+# # TODO: support other media
+# return None
def __str__(self):
@@ -245,24 +246,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_dir(current, media)
+ return create_dir(current, media)
parent = self._get_dir(os.path.dirname(dirname), media)
name = os.path.basename(dirname)
if not parent._vfs_id:
- return item.create_dir(name, parent)
+ return 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)
+ return create_dir(name, parent)
if not current:
current = self._db.add_object("dir", name=name,
parent=parent._vfs_id)
self._db.commit()
else:
current = current[0]
- return item.create_dir(current, parent)
+ return create_dir(current, parent)
def commit(self):
@@ -270,6 +271,10 @@
Commit changes to the database. All changes in the internal list
are done first.
"""
+ if not self.changes:
+ return
+
+ print 'COMMIT'
t1 = time.time()
changes = self.changes
for function, arg1, args, kwargs in self.changes:
@@ -296,9 +301,9 @@
commit is called just after this function is called.
"""
log.debug('DELETE %s' % entry)
- for child in self._db.query(parent = (entry['type'], entry['id'])):
+ for child in self._db.query(parent = entry._vfs_id):
self._delete(child)
- self._db.delete_object((entry['type'], entry['id']))
+ self._db.delete_object((entry._vfs_id))
def _query_dir(self, parent):
@@ -306,11 +311,11 @@
A query to get all files in a directory.
"""
dirname = parent.filename[:-1]
- items = [ item.create_file(f, parent) for f in \
+ items = [ 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))
+ items.sort(lambda x,y: cmp(x._vfs_name, y._vfs_name))
# TODO: this could block for cdrom drives and network filesystems.
Maybe
# put the listdir in a thread
@@ -319,16 +324,17 @@
# 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, overlay) in enumerate(parent._vfs_listdir()):
if pos == len(items):
# new file at the end
if os.path.isdir(parent.filename + f):
if not overlay:
- items.append(item.create_dir(f, parent))
+ items.append(create_dir(f, parent))
continue
- items.append(item.create_file(f, parent, overlay))
+ items.append(create_file(f, parent, overlay))
continue
- while f > items[pos].url:
+ while f > items[pos]._vfs_name:
# file deleted
i = items[pos]
items.remove(i)
@@ -338,15 +344,15 @@
# list. It will be deleted right before the next commit.
self.changes.append((self._delete, i, [], {}))
# delete
- if f == items[pos].url:
+ if f == items[pos]._vfs_name:
# same file
continue
# new file
if os.path.isdir(parent.filename + f):
if not overlay:
- items.append(item.create_dir(f, parent))
+ items.insert(pos, create_dir(f, parent))
continue
- items.insert(pos, item.create_file(f, parent, overlay))
+ items.insert(pos, create_file(f, parent, overlay))
if pos + 1 < len(items):
# deleted files at the end
@@ -359,6 +365,7 @@
if self.changes:
# need commit because some items were deleted from the db
self.commit()
+ items.sort(lambda x,y: cmp(x.url, y.url))
return items
@@ -379,6 +386,10 @@
Internal query function inside the thread. This function will use the
corrent internal query function based on special keywords.
"""
+ print 'QUERY', query
+ # make sure db is ok
+ self.commit()
+
if 'filename' in query and len(query) == 1:
# return item for filename, can't be in overlay
filename = query['filename']
@@ -396,8 +407,8 @@
# 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)
+ return create_dir(basename, parent)
+ return create_file(basename, parent)
if 'id' in query and len(query) == 1:
@@ -412,17 +423,17 @@
break
else:
raise AttributeError('bad media %s' % i['parent'])
- return item.create_dir(i, m)
+ return 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)
+ return create_dir(i, parent)
if parent._vfs_isdir:
# parent is dir, this item is not
- return item.create_file(i, parent)
+ return create_file(i, parent)
# neither dir nor file, something else
- return item.create_item(i, parent)
+ return create_item(i, parent)
if 'parent' in query and len(query) == 1:
@@ -450,13 +461,13 @@
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))
+ result.append(create_dir(r, parent))
elif parent._vfs_isdir:
# parent is dir, this item is not
- result.append(item.create_file(r, parent))
+ result.append(create_file(r, parent))
else:
# neither dir nor file, something else
- result.append(item.create_item(r, parent))
+ result.append(create_item(r, parent))
return result
Modified: trunk/WIP/vfs/src/item.py
==============================================================================
--- trunk/WIP/vfs/src/item.py (original)
+++ trunk/WIP/vfs/src/item.py Fri Feb 17 19:56:27 2006
@@ -34,6 +34,7 @@
import os
+import stat
UNKNOWN = -1
@@ -55,6 +56,7 @@
self._vfs_media = media
self._vfs_isdir = False
self._vfs_changes = []
+ self._vfs_name = data['name']
def __repr__(self):
@@ -74,6 +76,17 @@
# get db
return self._vfs_media.client
+ def _vfs_mtime(self):
+ # return mtime
+ return 0
+
+ def _vfs_changed(self):
+ return self._vfs_mtime() != self._vfs_data['mtime']
+
+
+ def _vfs_tree(self):
+ return ParentIterator(self)
+
def getattr(self, key):
# FIXME: make sure we have db data
@@ -94,7 +107,22 @@
def keys(self):
return self._vfs_data.keys()
-
+
+class ParentIterator(object):
+
+ def __init__(self, item):
+ self.item = item
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if not self.item:
+ raise StopIteration
+ ret = self.item
+ self.item = self.item._vfs_parent
+ return ret
+
class Directory(Item):
"""
A directory based item.
@@ -110,6 +138,8 @@
id = None
self.filename = parent.filename + data + '/'
data = { 'name': data, 'mtime': UNKNOWN }
+ if parent and parent._vfs_id:
+ data['parent_type'], data['parent_id'] = parent._vfs_id
media = parent._vfs_media
elif isinstance(parent, Directory):
# db data
@@ -131,8 +161,8 @@
def listdir(self):
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()
+
self._vfs_database_update(self._vfs_db()._vfs_request(self.filename[:-1]))
+ return self._vfs_db().query(parent=self)
def _vfs_listdir(self):
@@ -151,6 +181,32 @@
result += [ ( x, False ) for x in listdir if not x.startswith('.') ]
result.sort(lambda x,y: cmp(x[0], y[0]))
return result
+
+
+ def _vfs_os_listdir(self):
+ if hasattr(self, '_vfs_os_listdir_cache'):
+ return self._vfs_os_listdir_cache
+
+ try:
+ result = [ (x, self.filename + x) for x in
os.listdir(self.filename)
+ if not x.startswith('.') ]
+ except OSError:
+ return []
+
+ media = self._vfs_media
+ overlay = media.overlay + '/' + self.filename[len(media.directory):]
+ try:
+ result += [ ( x, overlay + x ) for x in os.listdir(overlay) \
+ if not x.startswith('.') and not x in listdir ]
+ except OSError:
+ pass
+ self._vfs_os_listdir_cache = result
+ return result
+
+ def _vfs_mtime(self):
+ # TODO: add overlay dir to mtime
+ return os.stat(self.filename)[stat.ST_MTIME]
+
# def listdir(self):
# """
@@ -196,6 +252,8 @@
id = None
self.filename = parent.filename + data
data = { 'name': data, 'mtime': UNKNOWN }
+ if parent and parent._vfs_id:
+ data['parent_type'], data['parent_id'] = parent._vfs_id
media = parent._vfs_media
elif isinstance(parent, Directory):
# db data
@@ -207,6 +265,21 @@
self._vfs_overlay = overlay
+ def _vfs_mtime(self):
+ # 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.
+ search = self._vfs_data['name']
+ if search.rfind('.') > 0:
+ search = search[:search.rfind('.')]
+ mtime = 0
+ for basename, filename in self._vfs_parent._vfs_os_listdir():
+ if basename.startswith(search):
+ mtime += os.stat(filename)[stat.ST_MTIME]
+ return mtime
+
+
def __repr__(self):
"""
Convert object to string (usefull for debugging)
@@ -219,15 +292,3 @@
# make it possible to override these
-def create_dir(data, parent):
- """
- Create a Directory item.
- """
- return Directory(data, parent)
-
-
-def create_file(data, parent, overlay=False):
- """
- Create a File item.
- """
- return File(data, parent, overlay)
Modified: trunk/WIP/vfs/src/monitor.py
==============================================================================
--- trunk/WIP/vfs/src/monitor.py (original)
+++ trunk/WIP/vfs/src/monitor.py Fri Feb 17 19:56:27 2006
@@ -38,7 +38,7 @@
# kaa imports
from kaa.base.weakref import weakref
-from kaa.notifier import OneShotTimer, WeakTimer
+from kaa.notifier import OneShotTimer, WeakTimer, Timer, execute_in_timer
# kaa.vfs imports
import parser
@@ -55,7 +55,7 @@
self.id = id
def __call__(self, *args, **kwargs):
- self.remote(self.id, __ipc_oneway=True, *args, **kwargs)
+ self.remote(self.id, __ipc_oneway=True, __ipc_noproxy_args=True,
*args, **kwargs)
class Monitor(object):
@@ -71,46 +71,79 @@
self._db = db
self._query = query
self._checker = None
- if self._query.has_key('dirname') and \
- (not self._query.has_key('recursive') or not
self._query['recursive']):
- # TODO: use inotify for monitoring, this will also fix the
- # problem when files grow because they are copied right
- # now and the first time we had no real information
- dirname = self._query['dirname']
- for m in self._db._mountpoints:
- if dirname.startswith(m.directory):
- break
- WeakTimer(self.check, dirname, m).start(1)
- if self._query.has_key('device'):
- # monitor a media
- # TODO: support other stuff except cdrom
- # FIXME: support removing the monitor :)
- cdrom.monitor(query['device'], weakref(self), db, self._server)
-
+ self.items = self._db.query(**self._query)
+ self._scan(True)
+ self._poll()
+
+# if self._query.has_key('dirname') and \
+# (not self._query.has_key('recursive') or not
self._query['recursive']):
+# # TODO: use inotify for monitoring, this will also fix the
+# # problem when files grow because they are copied right
+# # now and the first time we had no real information
+# dirname = self._query['dirname']
+# for m in self._db._mountpoints:
+# if dirname.startswith(m.directory):
+# break
+# WeakTimer(self.check, dirname, m).start(1)
+# if self._query.has_key('device'):
+# # monitor a media
+# # TODO: support other stuff except cdrom
+# # FIXME: support removing the monitor :)
+# cdrom.monitor(query['device'], weakref(self), db, self._server)
- def check(self, dirname, mountpoint):
+
+ @execute_in_timer(WeakTimer, 1)
+ def _poll(self):
if self._checker:
# still checking
return True
- current = util.listdir(dirname, mountpoint)
+ current = self._db.query(**self._query)
if len(current) != len(self.items):
- OneShotTimer(self.update, True).start(0)
+ self.callback('changed')
+ self.items = current
+ self._scan()
return True
- for pos, url in enumerate(current):
- if self.items[pos].url != url:
- OneShotTimer(self.update, True).start(0)
+ for pos, c in enumerate(current):
+ if self.items[pos].url != c.url:
+ self.items = current
+ self._scan()
+ self.callback('changed')
return True
return True
- def update(self, send_checked=True):
- to_check = []
- import time
- t1 = time.time()
- self.items = self._db.query(**self._query)
- print 'monitor query took', time.time() - t1
+ def _scan(self, notify=False):
+ self._scan_step(self.items[:], [], notify)
+
+
+ @execute_in_timer(Timer, 0.001, type='once')
+ def _scan_step(self, items, changed, notify):
+ """
+ Find changed items in 'items' and add them to changed.
+ """
+ if not items:
+ self._update(changed, notify)
+ return False
+ c = 0
+ while items:
+ c += 1
+ if c > 20:
+ return True
+ i = items.pop(0)
+ # FIXME: check parents
+ if i._vfs_changed():
+ changed.append(weakref(i))
+ return True
+
+
+ def _update(self, changed, notify):
+ self._checker = weakref(parser.Checker(weakref(self), self._db,
changed, notify))
+
- return
+ def send_update(self, changed):
+ changed = [ (x.url, x._vfs_data) for x in changed ]
+ changed.sort(lambda x,y: cmp(x[0], y[0]))
+ self.callback('updated', changed)
# if self._query.has_key('device'):
# log.info('unable to update device query, just send notification
here')
@@ -164,9 +197,9 @@
# self.callback('checked')
- def __str__(self):
+ def __repr__(self):
return '<vfs.Monitor for %s>' % self._query
def __del__(self):
- log.debug('del %s' % self)
+ log.debug('del %s', repr(self))
Modified: trunk/WIP/vfs/src/parser.py
==============================================================================
--- trunk/WIP/vfs/src/parser.py (original)
+++ trunk/WIP/vfs/src/parser.py Fri Feb 17 19:56:27 2006
@@ -48,37 +48,9 @@
# get logging object
log = logging.getLogger('vfs')
-def get_mtime(item):
- if not item.filename:
- log.info('no filename == no mtime :(')
- return 0
- if not item._vfs_parent:
- log.info('no parent == no mtime :(')
- return 0
-
- if item._vfs_isdir:
- # TODO: add overlay dir to mtime
- 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.
-
- search = item.basename
- if search.rfind('.') > 0:
- search = search[:search.rfind('.')]
-
- mtime = 0
- for basename, url in item.parent.os_listdir():
- if basename.startswith(search):
- mtime += os.stat(url[5:])[stat.ST_MTIME]
- return mtime
-
-
def parse(db, item, store=False):
print 'check', item
- mtime = get_mtime(item)
+ mtime = item._vfs_mtime()
if not mtime:
log.info('oops, no mtime %s' % item)
return
@@ -140,30 +112,46 @@
class Checker(object):
- def __init__(self, monitor, db, items):
+ def __init__(self, monitor, db, items, notify):
self.monitor = monitor
self.db = db
self.items = items
self.max = len(items)
self.pos = 0
+ self.updated = []
+ self.do_notify = notify
Timer(self.check).start(0.01)
def check(self):
+ if self.items:
+ self.pos += 1
+ item = self.items[0]
+ self.items = self.items[1:]
+ if item:
+ self.notify('progress', self.pos, self.max, item.url)
+ parse(self.db, item)
+ if item._vfs_id:
+ self.monitor.send_update([item])
+ else:
+ self.updated.append(item)
+
if not self.items:
self.db.commit()
if self.monitor:
+ self.monitor.callback('changed')
+ if self.monitor and self.do_notify:
self.monitor.callback('checked')
- if self.monitor:
- self.monitor.update(False)
+
+ updated = []
+ while self.updated and self.updated[0]._vfs_id:
+ updated.append(self.updated.pop(0))
+ if updated:
+ self.monitor.send_update(updated)
+
+ if not self.items:
return False
- self.pos += 1
- item = self.items[0]
- self.items = self.items[1:]
- if item:
- self.notify('progress', self.pos, self.max, item.url)
- parse(self.db, item)
return True
Modified: trunk/WIP/vfs/src/query.py
==============================================================================
--- trunk/WIP/vfs/src/query.py (original)
+++ trunk/WIP/vfs/src/query.py Fri Feb 17 19:56:27 2006
@@ -57,28 +57,15 @@
self._query = query
self._monitor = None
self._client = client
- self._result = []
- 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):
- """
- Get the result of the query.
- """
- if self._query.has_key('device'):
- return self._result
- return self._result[:]
+ self.result = self._client.database.query(**query)
+
def _vfs_connect(self, monitor):
"""
Connect message from server.
"""
+ print 'CONNECT', monitor
self._monitor = monitor
@@ -94,74 +81,42 @@
"""
Checked message from server.
"""
- # The server checked the query, we should redo the query
- # to get possible updates.
- result = self._client.database.query(**self._query)
- log.info('check db results against current list of items')
-
- if self._query.has_key('device'):
- self._result = result
- self._result.db = self._client
- self.signals['changed'].emit()
- return
-
- changed = False
- if not result or not hasattr(result[0], 'url'):
- # normal string results
- if result != self._result:
- self._result = result
- self.signals['changed'].emit()
- self.signals['up-to-date'].emit()
- return
-
- # check old and new item lists. Both lists are sorted, so
- # checking can be done with simple cmp of the urls.
- for pos, dbitem in enumerate(result):
- if not len(self._result) > pos:
- # change the internal db of the item to out client
- dbitem.db = self._client
- self._result.append(dbitem)
- changed = True
- continue
- current = self._result[pos]
- while current and dbitem.url > current.url:
- self._result.remove(current)
- if len(self._result) > pos:
- current = self._result[pos]
- else:
- current = None
- changed = True
- if current and dbitem.url == current.url:
- if current.data['mtime'] != dbitem.data['mtime'] or \
- current.dbid != dbitem.dbid:
- changed = True
- current.data = dbitem.data
- current.dbid = dbitem.dbid
- # TODO: this is not 100% correct. Maybe the parent changed, or
- # the parent of the parent and we have now a new cover
- current.parent = dbitem.parent
- continue
- # change the internal db of the item to out client
- dbitem.db = self._client
- changed = True
- self._result.insert(pos, dbitem)
-
- if len(self._result) > pos + 1:
- changed = True
- self._result = self._result[:pos+1]
-
- if changed:
- # send changed signal
- log.debug('db has changed for %s, send signal %s'\
- % (self._query, self.signals['changed']._callbacks))
- self.signals['changed'].emit()
- # send up-to-date signal
- self.signals['up-to-date'].emit()
+ return
+
+
+ def _vfs_updated(self, items):
+ """
+ Checked message from server.
+ """
+ print 'UPDATE'
+ url, data = items.pop(0)
+ for r in self.result:
+ if r.url == url:
+ r._vfs_database_update(data)
+ if not items:
+ break
+ url, data = items.pop(0)
+ if items:
+ log.error('not all items found')
- def __str__(self):
+ def _vfs_changed(self):
+ self.result = self._client.database.query(**self._query)
+
+
+ def __repr__(self):
"""
Convert object to string (usefull for debugging)
"""
return '<vfs.Client.Query for %s>' % self._query
+
+ def __del__(self):
+ """
+ Memory debug
+ """
+ print 'del', repr(self)
+
+
+ def __iter__(self):
+ return self.result.__iter__()
Modified: trunk/WIP/vfs/src/server.py
==============================================================================
--- trunk/WIP/vfs/src/server.py (original)
+++ trunk/WIP/vfs/src/server.py Fri Feb 17 19:56:27 2006
@@ -59,7 +59,8 @@
"""
def __init__(self, dbdir):
self._db = Database(dbdir, None)
-
+ self._next_client = 0
+
# files
self.register_file_type_attrs("video",
@@ -104,7 +105,7 @@
# list of current clients
self._clients = []
-
+
# add root mountpoint
self.add_mountpoint(None, '/')
self.set_mountpoint('/', 'kaa.vfs.root')
@@ -131,18 +132,23 @@
return self._db.register_object_type_attrs('track_%s' % name, **kwargs)
- def monitor(self, callback, id, **query):
+ def monitor(self, client_id, request_id, query):
"""
Create a monitor object to monitor a query for a client.
"""
+ print 'MONITOR', client_id, request_id, query
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)
+ for id, client, callback in self._clients:
+ if id == client_id:
+ break
+ else:
+ raise AttributeError('Unknown client id %s', client_id)
+ monitor = Monitor(callback, self._db, self, request_id, query)
log.debug('create %s' % monitor)
- callback(id, 'connect', monitor)
- monitor.update()
+ callback(request_id, 'connect', monitor)
return None
@@ -151,7 +157,7 @@
Add a mountpoint to the system.
"""
if self._db.add_mountpoint(device, directory):
- for client in self._clients:
+ for id, client, notification in self._clients:
client.database.add_mountpoint(device, directory,
__ipc_oneway=True)
@@ -160,20 +166,22 @@
Set mountpoint to the given name (e.g. load media)
"""
if self._db.set_mountpoint(directory, name):
- for client in self._clients:
+ for id, client, notification in self._clients:
client.database.set_mountpoint(directory, name)
return True
return False
- def connect(self, client):
+ def connect(self, client, callback):
"""
Connect a new client to the server.
"""
- self._clients.append(client)
+ self._next_client += 1
+ self._clients.append((self._next_client, client, callback))
for device, directory, name in self._db.get_mountpoints():
client.database.add_mountpoint(device, directory)
client.database.set_mountpoint(directory, name)
+ return self._next_client
def update(self, items):
@@ -186,13 +194,14 @@
self._db.commit()
- def vfs_request(self, filename):
+ def 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
+ for i in data._vfs_tree():
+ if i._vfs_id:
+ break
+ items.append(i)
while items:
parser.parse(self._db, items.pop(), store=True)
self._db.commit()
-------------------------------------------------------
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