Author: dmeyer
Date: Sat Jul 21 16:10:09 2007
New Revision: 2763

Log:
Make it possible to add and delete items in a directory not
based on files. Such a file will stay in the dir until it
is deleted again or the directory is deleted.


Modified:
   trunk/WIP/beacon2/src/__init__.py
   trunk/WIP/beacon2/src/client.py
   trunk/WIP/beacon2/src/db.py
   trunk/WIP/beacon2/src/item.py
   trunk/WIP/beacon2/src/server/server.py

Modified: trunk/WIP/beacon2/src/__init__.py
==============================================================================
--- trunk/WIP/beacon2/src/__init__.py   (original)
+++ trunk/WIP/beacon2/src/__init__.py   Sat Jul 21 16:10:09 2007
@@ -145,6 +145,15 @@
     return _client.monitor(directory)
 
 
+def add_item(url, type, parent, **kwargs):
+    """
+    Add an item to the database (not to be used for files).
+    """
+    if not _client:
+        connect()
+    return _client.add_item(url, type, parent, **kwargs)
+
+    
 def register_file_type_attrs(name, **kwargs):
     """
     Register new attrs and types for files.

Modified: trunk/WIP/beacon2/src/client.py
==============================================================================
--- trunk/WIP/beacon2/src/client.py     (original)
+++ trunk/WIP/beacon2/src/client.py     Sat Jul 21 16:10:09 2007
@@ -42,6 +42,7 @@
 # kaa imports
 import kaa
 import kaa.rpc
+import kaa.strutils
 from kaa.weakref import weakref
 from kaa.notifier import OneShotTimer, Signal
 
@@ -49,6 +50,7 @@
 from db import Database
 from query import Query
 from media import medialist
+from item import Item
 
 # get logging object
 log = logging.getLogger('beacon')
@@ -123,6 +125,29 @@
         return result
 
 
+    def add_item(self, url, type, parent, **kwargs):
+        """
+        Add non-file item item.
+        """
+        if self.status == DISCONNECTED:
+            return None
+        if isinstance(url, unicode):
+            url = kaa.strutils.unicode_to_str(url)
+        kwargs['scheme'] = url[:url.find('://')]
+        kwargs['name'] = url
+        i = Item(None, url, kwargs, parent, parent._beacon_media)
+        rpc = self.rpc('item.create', type=type, parent=parent._beacon_id, 
**kwargs)
+        rpc.connect(i._beacon_database_update)
+        return i
+
+
+    def delete_item(self, item):
+        """
+        Delete non-file item item.
+        """
+        self.rpc('item.delete', item._beacon_id)
+
+
     def monitor(self, directory):
         """
         Monitor a directory with subdirectories for changes. This is done in

Modified: trunk/WIP/beacon2/src/db.py
==============================================================================
--- trunk/WIP/beacon2/src/db.py (original)
+++ trunk/WIP/beacon2/src/db.py Sat Jul 21 16:10:09 2007
@@ -56,6 +56,13 @@
 from file import File as create_file
 from item import create_item
 
+def create_by_type(data, parent, overlay=False, isdir=False):
+    if data.get('scheme') not in (None, 'file'):
+        return create_item(data, parent)
+    return create_file(data, parent, overlay, isdir)
+
+def create_directory(data, parent):
+    return create_file(data, parent, isdir=True)
 
 class Database(object):
     """
@@ -157,7 +164,7 @@
         media._beacon_id = dbid
         root = self._db.query(parent=dbid)[0]
         if root['type'] == 'dir':
-            media.root = create_file(root, media, isdir=True)
+            media.root = create_directory(root, media)
         else:
             media.root = create_item(root, media)
         return result
@@ -189,8 +196,9 @@
 
         items = []
         if parent._beacon_id:
-            items = [ create_file(i, parent, isdir=i['type'] == 'dir') \
+            items = [ create_by_type(i, parent, isdir=i['type'] == 'dir') \
                       for i in self._db.query(parent = parent._beacon_id) ]
+
         # sort items based on name. The listdir is also sorted by name,
         # that makes checking much faster
         items.sort(lambda x,y: cmp(x._beacon_name, y._beacon_name))
@@ -208,19 +216,24 @@
         while self.delete_object and self.read_lock.is_locked():
             yield self.read_lock.yield_unlock()
 
-        for pos, (f, fullname, overlay, stat_res) in enumerate(listing[0]):
+        pos = -1
+        for f, fullname, overlay, stat_res in listing[0]:
+            pos += 1
             isdir = stat.S_ISDIR(stat_res[stat.ST_MODE])
             if pos == len(items):
                 # new file at the end
                 if isdir:
                     if not overlay:
-                        items.append(create_file(f, parent, isdir=True))
+                        items.append(create_directory(f, parent))
                     continue
-                items.append(create_file(f, parent, overlay, isdir=False))
+                items.append(create_file(f, parent, overlay))
                 continue
             while pos < len(items) and f > items[pos]._beacon_name:
                 # file deleted
                 i = items[pos]
+                if i.get('scheme') not in (None, 'file'):
+                    pos += 1
+                    continue
                 items.remove(i)
                 if self.delete_object:
                     # delete from database by adding it to the internal changes
@@ -232,16 +245,20 @@
             # new file
             if isdir:
                 if not overlay:
-                    items.insert(pos, create_file(f, parent, isdir=True))
+                    items.insert(pos, create_directory(f, parent))
                 continue
-            items.insert(pos, create_file(f, parent, overlay, isdir=False))
+            items.insert(pos, create_file(f, parent, overlay))
 
         if pos + 1 < len(items):
             # deleted files at the end
-            if self.delete_object:
-                for i in items[pos+1-len(items):]:
+            for i in items[pos+1-len(items):]:
+                if i.get('scheme') not in (None, 'file'):
+                    continue
+                items.remove(i)
+                if self.delete_object:
+                    # delete from database by adding it to the internal changes
+                    # list. It will be deleted right before the next commit.
                     self.delete_object(i)
-            items = items[:pos+1-len(items)]
 
         # no need to sort the items again, they are already sorted based
         # on name, let us keep it that way. And name is unique in a directory.
@@ -280,11 +297,11 @@
                 continue
             for i in self._db.query(parent = parent._beacon_id):
                 if i['type'] == 'dir':
-                    child = create_file(i, parent, isdir=True)
+                    child = create_directory(i, parent)
                     if not child._beacon_islink:
                         directories.append(child)
                 else:
-                    items.append(create_file(i, parent, isdir=False))
+                    items.append(create_by_type(i, parent))
             if time.time() > timer + 0.1:
                 # we are in async mode and already use too much time.
                 # call yield YieldContinue at this point to continue
@@ -309,7 +326,7 @@
             m = medialist.get_by_beacon_id(i['parent'])
             if not m:
                 raise AttributeError('bad media %s' % str(i['parent']))
-            return create_file(i, m, isdir=True)
+            return create_directory(i, m)
 
         # query for parent
         pid = i['parent']
@@ -322,12 +339,8 @@
 
         if i['type'] == 'dir':
             # it is a directory, make a dir item
-            return create_file(i, parent, isdir=True)
-        if parent._beacon_isdir:
-            # parent is dir, this item is not
-            return create_file(i, parent)
-        # neither dir nor file, something else
-        return create_item(i, parent)
+            return create_directory(i, parent)
+        return create_by_type(i, parent)
 
 
     def _db_query_attr(self, query):
@@ -379,13 +392,10 @@
             # create item
             if r['type'] == 'dir':
                 # it is a directory, make a dir item
-                result.append(create_file(r, parent, isdir=True))
-            elif parent._beacon_isdir:
-                # parent is dir, this item is not
-                result.append(create_file(r, parent))
+                result.append(create_directory(r, parent))
             else:
-                # neither dir nor file, something else
-                result.append(create_item(r, parent))
+                # file or something else
+                result.append(create_by_type(r, parent))
 
             counter += 1
             if not counter % 50 and time.time() > timer + 0.05:
@@ -416,7 +426,7 @@
             m != medialist.get_by_directory(dirname)) or filename == '/':
             # the filename is the mountpoint itself
             e = self._db.query(parent=m._beacon_id, name='')
-            return create_file(e[0], m, isdir=True)
+            return create_directory(e[0], m)
         parent = self._query_filename_get_dir(dirname, m)
         if parent._beacon_id:
             # parent is a valid db item, query
@@ -435,7 +445,7 @@
         if dirname == media.mountpoint or dirname +'/' == media.mountpoint:
             # we know that '/' is in the db
             c = self._db.query(type="dir", name='', parent=media._beacon_id)[0]
-            return create_file(c, media, isdir=True)
+            return create_directory(c, media)
 
         if dirname == '/':
             raise RuntimeError('media %s not found' % media)
@@ -444,18 +454,18 @@
         name = os.path.basename(dirname)
 
         if not parent._beacon_id:
-            return create_file(name, parent, isdir=True)
+            return create_directory(name, parent)
 
         c = self._db.query(type="dir", name=name, parent=parent._beacon_id)
         if c:
-            return create_file(c[0], parent, isdir=True)
+            return create_directory(c[0], parent)
 
         if not self.add_object:
             # we have no add_object function. This means we have
             # to return a dummy object (client)
-            return create_file(name, parent, isdir=True)
+            return create_directory(name, parent)
         # add object to the database.
-        # NOTICE: this function will chnage the database even when
+        # NOTICE: this function will change the database even when
         # the db is locked. I do not see a good way around it and
         # it should not happen often. To make the write lock a very
         # short time we commit just after adding.
@@ -463,7 +473,7 @@
         if self.read_lock.is_locked():
             # commit changes
             self.commit()
-        return create_file(c, parent, isdir=True)
+        return create_directory(c, parent)
 
 
     # -------------------------------------------------------------------------

Modified: trunk/WIP/beacon2/src/item.py
==============================================================================
--- trunk/WIP/beacon2/src/item.py       (original)
+++ trunk/WIP/beacon2/src/item.py       Sat Jul 21 16:10:09 2007
@@ -207,6 +207,13 @@
         return not self._beacon_isdir and self.filename != ''
 
 
+    def delete(self):
+        """
+        Delete item from the database (does not work on files)
+        """
+        return self.get_controller().delete_item(self)
+
+
     # -------------------------------------------------------------------------
     # Internal API for client and server
     # -------------------------------------------------------------------------
@@ -297,6 +304,8 @@
     data = dict(data)
     if 'url' in data:
         url = data['url']
+    elif '://' in data['name']:
+        url = data['name']
     else:
         url = parent.url
         if data['name']:

Modified: trunk/WIP/beacon2/src/server/server.py
==============================================================================
--- trunk/WIP/beacon2/src/server/server.py      (original)
+++ trunk/WIP/beacon2/src/server/server.py      Sat Jul 21 16:10:09 2007
@@ -352,7 +352,6 @@
         Update items from the client.
         """
         while self._db.read_lock.is_locked():
-            log.info('wait3')
             yield self._db.read_lock.yield_unlock()
         for dbid, attributes in items:
             self._db.update_object(dbid, **attributes)
@@ -382,6 +381,32 @@
         yield data._beacon_data
 
 
+    @kaa.rpc.expose('item.create')
+    @kaa.notifier.yield_execution()
+    def item_create(self, type, parent, **kwargs):
+        """
+        Create a new item.
+        """
+        data = self._db.query(id=parent)
+        if isinstance(data, kaa.notifier.InProgress):
+            yield data
+            data = data()
+        while self._db.read_lock.is_locked():
+            yield self._db.read_lock.yield_unlock()
+        yield self._db.add_object(type, parent=parent, **kwargs)
+
+    
+    @kaa.rpc.expose('item.delete')
+    @kaa.notifier.yield_execution()
+    def item_delete(self, id):
+        """
+        Create a new item.
+        """
+        while self._db.read_lock.is_locked():
+            yield self._db.read_lock.yield_unlock()
+        self._db.delete_object(id)
+
+    
     @kaa.rpc.expose('beacon.shutdown')
     def shutdown(self):
         """

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to