[rygel] core,plugins: Special interface for writable containers



commit 41183d6a2bda2d74b6cc52640a49676da3c922a0
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Wed Oct 20 17:40:45 2010 +0300

    core,plugins: Special interface for writable containers
    
    Containers that allow creation, editing and/or removal of new items under them
    are now supposed to implement this new interface.

 src/plugins/external/rygel-external-container.vala |    8 ---
 .../external/rygel-external-dummy-container.vala   |    8 ---
 .../rygel-media-export-db-container.vala           |   18 +++++--
 .../rygel-media-export-dummy-container.vala        |    2 +-
 .../rygel-media-export-media-cache.vala            |    2 +-
 .../rygel-media-export-null-container.vala         |    8 ---
 .../rygel-tracker-category-all-container.vala      |   18 ++++---
 .../tracker/rygel-tracker-search-container.vala    |    8 ---
 src/rygel/Makefile.am                              |    1 +
 src/rygel/rygel-item-creator.vala                  |   20 +++++---
 src/rygel/rygel-media-container.vala               |   48 ++----------------
 src/rygel/rygel-relational-expression.vala         |    7 ++-
 src/rygel/rygel-simple-container.vala              |    8 ---
 src/rygel/rygel-writable-container.vala            |   51 ++++++++++++++++++++
 14 files changed, 99 insertions(+), 108 deletions(-)
---
diff --git a/src/plugins/external/rygel-external-container.vala b/src/plugins/external/rygel-external-container.vala
index 0e002f6..9e20ff0 100644
--- a/src/plugins/external/rygel-external-container.vala
+++ b/src/plugins/external/rygel-external-container.vala
@@ -175,14 +175,6 @@ public class Rygel.External.Container : Rygel.MediaContainer {
         return media_object;
     }
 
-    public override async void add_item (MediaItem item,
-                                         Cancellable? cancellable)
-                                         throws Error {
-        throw new ContentDirectoryError.RESTRICTED_PARENT (
-                                        _("Object creation in %s not allowed"),
-                                        this.id);
-    }
-
     private async MediaObjects create_media_objects (
                                         HashTable<string,Variant>[] all_props,
                                         MediaContainer?             parent
diff --git a/src/plugins/external/rygel-external-dummy-container.vala b/src/plugins/external/rygel-external-dummy-container.vala
index f8d2b3b..40b6095 100644
--- a/src/plugins/external/rygel-external-dummy-container.vala
+++ b/src/plugins/external/rygel-external-dummy-container.vala
@@ -44,12 +44,4 @@ internal class Rygel.External.DummyContainer : MediaContainer {
                                                       throws Error {
         return new MediaObjects ();
     }
-
-    public override async void add_item (MediaItem item,
-                                         Cancellable? cancellable)
-                                         throws Error {
-        throw new ContentDirectoryError.RESTRICTED_PARENT (
-                                        _("Object creation in %s not allowed"),
-                                        this.id);
-    }
 }
diff --git a/src/plugins/media-export/rygel-media-export-db-container.vala b/src/plugins/media-export/rygel-media-export-db-container.vala
index 68f0a57..b145b6f 100644
--- a/src/plugins/media-export/rygel-media-export-db-container.vala
+++ b/src/plugins/media-export/rygel-media-export-db-container.vala
@@ -20,13 +20,23 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 using GUPnP;
+using Gee;
 
-public class Rygel.MediaExport.DBContainer : MediaContainer {
+public class Rygel.MediaExport.DBContainer : MediaContainer, WritableContainer {
     protected MediaCache media_db;
 
+    public ArrayList<string> create_classes { get; set; }
+
     public DBContainer (MediaCache media_db, string id, string title) {
         base (id, null, title, 0);
 
+        this.create_classes = new ArrayList<string> ();
+        this.create_classes.add (ImageItem.UPNP_CLASS);
+        this.create_classes.add (PhotoItem.UPNP_CLASS);
+        this.create_classes.add (VideoItem.UPNP_CLASS);
+        this.create_classes.add (AudioItem.UPNP_CLASS);
+        this.create_classes.add (MusicItem.UPNP_CLASS);
+
         this.media_db = media_db;
         this.container_updated.connect (on_db_container_updated);
         this.on_db_container_updated (this, this);
@@ -86,12 +96,10 @@ public class Rygel.MediaExport.DBContainer : MediaContainer {
         return this.media_db.get_object (id);
     }
 
-    public override async void add_item (Rygel.MediaItem item,
-                                         Cancellable?    cancellable)
-                                         throws Error {
+    public async void add_item (Rygel.MediaItem item, Cancellable? cancellable)
+                                throws Error {
         item.parent = this;
         item.id = MediaCache.get_id (File.new_for_uri (item.uris[0]));
         this.media_db.save_item (item);
     }
-
 }
diff --git a/src/plugins/media-export/rygel-media-export-dummy-container.vala b/src/plugins/media-export/rygel-media-export-dummy-container.vala
index 515ac5b..50c68d3 100644
--- a/src/plugins/media-export/rygel-media-export-dummy-container.vala
+++ b/src/plugins/media-export/rygel-media-export-dummy-container.vala
@@ -29,7 +29,7 @@ internal class Rygel.MediaExport.DummyContainer : NullContainer {
         this.title = file.get_basename ();
         this.parent_ref = parent;
         this.file = file;
-        this.set_uri (file.get_uri ());
+        this.uris.add (file.get_uri ());
         try {
             this.children = MediaCache.get_default ().get_child_ids (this.id);
             this.child_count = this.children.size;
diff --git a/src/plugins/media-export/rygel-media-export-media-cache.vala b/src/plugins/media-export/rygel-media-export-media-cache.vala
index d8f88ff..ff8faa4 100644
--- a/src/plugins/media-export/rygel-media-export-media-cache.vala
+++ b/src/plugins/media-export/rygel-media-export-media-cache.vala
@@ -537,7 +537,7 @@ public class Rygel.MediaExport.MediaCache : Object {
                 var container = object as MediaContainer;
                 var uri = statement.column_text (DetailColumn.URI);
                 if (uri != null) {
-                    container.set_uri (uri);
+                    container.uris.add (uri);
                 }
                 break;
             case 1:
diff --git a/src/plugins/media-export/rygel-media-export-null-container.vala b/src/plugins/media-export/rygel-media-export-null-container.vala
index 25c1054..1be8b7c 100644
--- a/src/plugins/media-export/rygel-media-export-null-container.vala
+++ b/src/plugins/media-export/rygel-media-export-null-container.vala
@@ -36,12 +36,4 @@ internal class Rygel.NullContainer : MediaContainer {
                                                       throws Error {
         return new MediaObjects ();
     }
-
-    public override async void add_item (MediaItem item,
-                                         Cancellable? cancellable)
-                                         throws Error {
-        throw new ContentDirectoryError.RESTRICTED_PARENT (
-                                        _("Object creation in %s not allowed"),
-                                        this.id);
-    }
 }
diff --git a/src/plugins/tracker/rygel-tracker-category-all-container.vala b/src/plugins/tracker/rygel-tracker-category-all-container.vala
index a697380..555c885 100644
--- a/src/plugins/tracker/rygel-tracker-category-all-container.vala
+++ b/src/plugins/tracker/rygel-tracker-category-all-container.vala
@@ -27,18 +27,24 @@ using Gee;
 /**
  * A search container that contains all the items in a category.
  */
-public class Rygel.Tracker.CategoryAllContainer : SearchContainer {
+public class Rygel.Tracker.CategoryAllContainer : SearchContainer,
+                                                  WritableContainer {
     /* class-wide constants */
     private const string TRACKER_SERVICE = "org.freedesktop.Tracker1";
     private const string RESOURCES_PATH = "/org/freedesktop/Tracker1/Resources";
     private const string MINER_SERVICE = "org.freedesktop.Tracker1.Miner.Files";
     private const string MINER_PATH = "/org/freedesktop/Tracker1/Miner/Files";
 
+    public ArrayList<string> create_classes { get; set; }
+
     private ResourcesIface resources;
 
     public CategoryAllContainer (CategoryContainer parent) {
         base ("All" + parent.id, parent, "All", parent.item_factory);
 
+        this.create_classes = new ArrayList<string> ();
+        this.create_classes.add (item_factory.upnp_class);
+
         try {
             this.resources = Bus.get_proxy_sync (BusType.SESSION,
                                                  TRACKER_SERVICE,
@@ -50,10 +56,7 @@ public class Rygel.Tracker.CategoryAllContainer : SearchContainer {
 
         try {
             var uri = Filename.to_uri (item_factory.upload_dir, null);
-            var create_classes = new ArrayList<string> ();
-
-            create_classes.add (item_factory.upnp_class);
-            this.set_uri (uri, create_classes);
+            this.uris.add (uri);
         } catch (ConvertError error) {
             warning (_("Failed to construct URI for folder '%s': %s"),
                      item_factory.upload_dir,
@@ -61,9 +64,8 @@ public class Rygel.Tracker.CategoryAllContainer : SearchContainer {
         }
     }
 
-    public async override void add_item (MediaItem    item,
-                                         Cancellable? cancellable)
-                                         throws Error {
+    public async void add_item (MediaItem item, Cancellable? cancellable)
+                                throws Error {
         var urn = yield this.create_entry_in_store (item);
 
         item.id = this.create_child_id_for_urn (urn);
diff --git a/src/plugins/tracker/rygel-tracker-search-container.vala b/src/plugins/tracker/rygel-tracker-search-container.vala
index f6f596b..81a7112 100644
--- a/src/plugins/tracker/rygel-tracker-search-container.vala
+++ b/src/plugins/tracker/rygel-tracker-search-container.vala
@@ -169,14 +169,6 @@ public class Rygel.Tracker.SearchContainer : Rygel.MediaContainer {
         }
     }
 
-    public override async void add_item (MediaItem item,
-                                         Cancellable? cancellable)
-                                         throws Error {
-        throw new ContentDirectoryError.RESTRICTED_PARENT (
-                                        _("Object creation in %s not allowed"),
-                                        this.id);
-    }
-
     public string create_child_id_for_urn (string urn) {
         return this.id + "," + urn;
     }
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index 300159b..641ef2d 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -81,6 +81,7 @@ VAPI_SOURCE_FILES = rygel-configuration.vala \
 		    rygel-media-objects.vala \
 		    rygel-media-container.vala \
 		    rygel-simple-container.vala \
+		    rygel-writable-container.vala \
 		    rygel-media-item.vala \
 		    rygel-audio-item.vala \
 		    rygel-music-item.vala \
diff --git a/src/rygel/rygel-item-creator.vala b/src/rygel/rygel-item-creator.vala
index 2fcfc57..e28ad55 100644
--- a/src/rygel/rygel-item-creator.vala
+++ b/src/rygel/rygel-item-creator.vala
@@ -145,7 +145,7 @@ internal class Rygel.ItemCreator: GLib.Object, Rygel.StateMachine {
         }
     }
 
-    private async MediaContainer fetch_container () throws Error {
+    private async WritableContainer fetch_container () throws Error {
         MediaObject media_object = null;
 
         if (this.container_id == "DLNA.ORG_AnyContainer") {
@@ -172,12 +172,16 @@ internal class Rygel.ItemCreator: GLib.Object, Rygel.StateMachine {
                                         this.cancellable);
         }
 
-        if (media_object == null || !(media_object is MediaContainer)) {
+        if (media_object == null) {
             throw new ContentDirectoryError.NO_SUCH_OBJECT (
                                         _("No such object"));
+        } else if (!(media_object is WritableContainer)) {
+            throw new ContentDirectoryError.RESTRICTED_PARENT (
+                                        _("Object creation in %s not allowed"),
+                                        media_object.id);
         }
 
-        return media_object as MediaContainer;
+        return media_object as WritableContainer;
     }
 
     private void conclude () {
@@ -216,10 +220,10 @@ internal class Rygel.ItemCreator: GLib.Object, Rygel.StateMachine {
         }
     }
 
-    private MediaItem create_item (string         id,
-                                   MediaContainer parent,
-                                   string         title,
-                                   string         upnp_class) throws Error {
+    private MediaItem create_item (string            id,
+                                   WritableContainer parent,
+                                   string            title,
+                                   string            upnp_class) throws Error {
         switch (upnp_class) {
         case ImageItem.UPNP_CLASS:
             return new ImageItem (id, parent, title);
@@ -257,7 +261,7 @@ internal class Rygel.ItemCreator: GLib.Object, Rygel.StateMachine {
         return true;
     }
 
-    public async string create_uri (MediaContainer container, string title)
+    public async string create_uri (WritableContainer container, string title)
                                     throws Error {
         var dir = yield container.get_writable (this.cancellable);
         if (dir == null) {
diff --git a/src/rygel/rygel-media-container.vala b/src/rygel/rygel-media-container.vala
index 6710ae2..b1eee51 100644
--- a/src/rygel/rygel-media-container.vala
+++ b/src/rygel/rygel-media-container.vala
@@ -46,9 +46,6 @@ public abstract class Rygel.MediaContainer : MediaObject {
     public int child_count;
     public uint32 update_id;
 
-    // List of classes that an object in this container could be created of
-    public ArrayList<string> create_classes;
-
     public MediaContainer (string          id,
                            MediaContainer? parent,
                            string          title,
@@ -59,7 +56,6 @@ public abstract class Rygel.MediaContainer : MediaObject {
         this.child_count = child_count;
         this.update_id = 0;
         this.upnp_class = STORAGE_FOLDER;
-        this.create_classes = new ArrayList<string> ();
 
         this.container_updated.connect (on_container_updated);
     }
@@ -84,18 +80,6 @@ public abstract class Rygel.MediaContainer : MediaObject {
                                                       throws Error;
 
     /**
-     * Add a new item directly under this container.
-     *
-     * @param item The item to add to this container
-     * @param cancellable optional cancellable for this operation
-     *
-     * return nothing.
-     *
-     */
-    public async abstract void add_item (MediaItem item, Cancellable? cancellable)
-                                         throws Error;
-
-    /**
      * Recursively searches for all media objects the satisfy the given search
      * expression in this container.
      *
@@ -223,29 +207,6 @@ public abstract class Rygel.MediaContainer : MediaObject {
         this.container_updated (this);
     }
 
-    /**
-     * Sets the URI of this container and optionally the create_classes.
-     *
-     * @param uri the URI to set.
-     * @param create_classes list of item classes.
-     */
-    public void set_uri (string uri, ArrayList<string>? create_classes = null) {
-        this.uris.clear ();
-        this.uris.add (uri);
-
-        this.create_classes.clear ();
-
-        if (create_classes != null) {
-            this.create_classes.add_all (create_classes);
-        } else {
-            this.create_classes.add (ImageItem.UPNP_CLASS);
-            this.create_classes.add (PhotoItem.UPNP_CLASS);
-            this.create_classes.add (VideoItem.UPNP_CLASS);
-            this.create_classes.add (AudioItem.UPNP_CLASS);
-            this.create_classes.add (MusicItem.UPNP_CLASS);
-        }
-    }
-
     internal override DIDLLiteObject serialize (DIDLLiteWriter writer,
                                                 HTTPServer     http_server)
                                                 throws Error {
@@ -260,16 +221,19 @@ public abstract class Rygel.MediaContainer : MediaObject {
         didl_container.title = this.title;
         didl_container.child_count = this.child_count;
         didl_container.upnp_class = this.upnp_class;
-        didl_container.restricted = this.uris.size <= 0;
         didl_container.searchable = true;
 
-        if (!didl_container.restricted) {
+        if (this is WritableContainer && this.uris.size > 0) {
+            didl_container.restricted = false;
             weak Xml.Node node = (Xml.Node) didl_container.xml_node;
             weak Xml.Ns ns = (Xml.Ns) didl_container.upnp_namespace;
 
-            foreach (var create_class in this.create_classes) {
+            var writable = this as WritableContainer;
+            foreach (var create_class in writable.create_classes) {
                 node.new_child (ns, "createClass", create_class);
             }
+        } else {
+            didl_container.restricted = true;
         }
 
         return didl_container;
diff --git a/src/rygel/rygel-relational-expression.vala b/src/rygel/rygel-relational-expression.vala
index 476ed20..c6d1c2d 100644
--- a/src/rygel/rygel-relational-expression.vala
+++ b/src/rygel/rygel-relational-expression.vala
@@ -41,11 +41,12 @@ public class Rygel.RelationalExpression :
         case "dc:title":
             return this.compare_string (media_object.title);
         case "upnp:createClass":
-            if (!(media_object is MediaContainer)) {
+            if (!(media_object is WritableContainer)) {
                 return false;
             }
 
-            return this.compare_create_class (media_object as MediaContainer);
+            return this.compare_create_class (
+                                        media_object as WritableContainer);
         case "dc:creator":
             if (!(media_object is PhotoItem)) {
                 return false;
@@ -73,7 +74,7 @@ public class Rygel.RelationalExpression :
         return "%s %d %s".printf (this.operand1, this.op, this.operand2);
     }
 
-    private bool compare_create_class (MediaContainer container) {
+    private bool compare_create_class (WritableContainer container) {
         var ret = false;
 
         foreach (var create_class in container.create_classes) {
diff --git a/src/rygel/rygel-simple-container.vala b/src/rygel/rygel-simple-container.vala
index da51bf9..18f0542 100644
--- a/src/rygel/rygel-simple-container.vala
+++ b/src/rygel/rygel-simple-container.vala
@@ -94,12 +94,4 @@ public class Rygel.SimpleContainer : Rygel.MediaContainer {
 
         return media_object;
     }
-
-    public override async void add_item (MediaItem item,
-                                         Cancellable? cancellable)
-                                         throws Error {
-        throw new ContentDirectoryError.RESTRICTED_PARENT (
-                                        _("Object creation in %s not allowed"),
-                                        this.id);
-    }
 }
diff --git a/src/rygel/rygel-writable-container.vala b/src/rygel/rygel-writable-container.vala
new file mode 100644
index 0000000..1c173e7
--- /dev/null
+++ b/src/rygel/rygel-writable-container.vala
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ * Copyright (C) 2010 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ *                               <zeeshan ali nokia com>
+ *
+ * This file is part of Rygel.
+ *
+ * Rygel is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+using Gee;
+
+/**
+ * Interface to be implemented by 'writable' container: ones that allow
+ * creation, removal and editing of items directly under them. Currently, only
+ * addition is supported.
+ *
+ * In addition to implementing this interface, a writable container must also
+ * provide one URI that points to a writable folder on a GIO supported
+ * filesystem.
+ */
+public interface Rygel.WritableContainer : MediaContainer {
+    // List of classes that an object in this container could be created of
+    public abstract ArrayList<string> create_classes { get; set; }
+
+    /**
+     * Add a new item directly under this container.
+     *
+     * @param item The item to add to this container
+     * @param cancellable optional cancellable for this operation
+     *
+     * return nothing.
+     *
+     */
+    public async abstract void add_item (MediaItem    item,
+                                         Cancellable? cancellable) throws Error;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]