core,tracker: Fix upload of files
authorMarcin Kazmierczak <marcin.kazmierczak@live.com>
Wed, 22 Feb 2012 14:03:12 +0000 (15:03 +0100)
committerJens Georg <jensg@openismus.com>
Mon, 8 Apr 2013 14:32:52 +0000 (16:32 +0200)
core:
MediaContainer: Add empty children counter. Add check_search_expression
function, which set create_mode on true, when "upnp:createClass" operand
was detected.
SearchableContainer: Use check_search_expression in simple_search function
to determine child counter.
SimpleContainer: Use check_search_expression to search both in empty and
non-empty children, during adding new item.

tests: searchable-container-test: Add children counter to MediaContainer
class. Add empty function check_search_expression in class MediaContainer.

Previously it was impossible to add new item, when matched container was
empty. For example user can't add picture, when don't have any picture.
Now it's possible, because now search function return also empty children
container, when search expression contains "upnp:createClass" operand. This
works when HttpPost was used to upload file.

https://bugzilla.gnome.org/show_bug.cgi?id=660885

src/librygel-server/rygel-media-container.vala
src/librygel-server/rygel-searchable-container.vala
src/librygel-server/rygel-simple-container.vala
tests/rygel-searchable-container-test.vala

index f805ef6..b65e968 100644 (file)
@@ -108,8 +108,15 @@ public abstract class Rygel.MediaContainer : MediaObject {
     public signal void sub_tree_updates_finished (MediaObject sub_tree_root);
 
     public int child_count { get; set construct; }
+    protected int empty_child_count;
+    public int all_child_count {
+        get {
+            return this.child_count + this.empty_child_count;
+        }
+    }
     public uint32 update_id;
     public int64 storage_used;
+    public bool create_mode_enabled;
 
     // This is an uint32 in UPnP. SystemUpdateID should reach uint32.MAX way
     // before this variable and cause a SystemResetProcedure.
@@ -190,10 +197,12 @@ public abstract class Rygel.MediaContainer : MediaObject {
     public override void constructed () {
         base.constructed ();
 
+        this.empty_child_count = 0;
         this.update_id = 0;
         this.storage_used = -1;
         this.total_deleted_child_count = 0;
         this.upnp_class = STORAGE_FOLDER;
+        this.create_mode_enabled = false;
 
         this.container_updated.connect (on_container_updated);
         this.sub_tree_updates_finished.connect (on_sub_tree_updates_finished);
@@ -370,4 +379,15 @@ public abstract class Rygel.MediaContainer : MediaObject {
             this.parent.sub_tree_updates_finished (sub_tree_root);
         }
     }
+
+    internal void check_search_expression (SearchExpression? expression) {
+        this.create_mode_enabled = false;
+        if (expression != null && expression is RelationalExpression) {
+            var relational_exp = expression as RelationalExpression;
+            if (relational_exp.op == SearchCriteriaOp.DERIVED_FROM &&
+                relational_exp.operand1 == "upnp:createClass") {
+                this.create_mode_enabled = true;
+            }
+        }
+    }
 }
index e9563d6..63328a0 100644 (file)
@@ -86,8 +86,15 @@ public interface Rygel.SearchableContainer : MediaContainer {
                                               throws Error {
         var result = new MediaObjects ();
 
+        int count = this.child_count;
+        this.check_search_expression (expression);
+
+        if (this.create_mode_enabled) {
+            count = this.all_child_count;
+        }
+
         var children = yield this.get_children (0,
-                                                this.child_count,
+                                                count,
                                                 sort_criteria,
                                                 cancellable);
 
index 5a1d6fb..167abaa 100644 (file)
@@ -119,6 +119,7 @@ public class Rygel.SimpleContainer : Rygel.MediaContainer,
                    "until it has any children to offer.",
                    child.id);
             this.empty_children.add (child);
+            this.empty_child_count++;
             child.container_updated.connect (this.on_container_updated);
         }
     }
@@ -183,13 +184,21 @@ public class Rygel.SimpleContainer : Rygel.MediaContainer,
                                                      Cancellable? cancellable)
                                                      throws Error {
         uint stop = offset + max_count;
-        stop = stop.clamp (0, this.child_count);
+        MediaObjects unsorted_children;
 
-        var sorted_children = this.children.slice (0, this.child_count)
+        if (this.create_mode_enabled) {
+            stop = stop.clamp (0, this.all_child_count);
+            unsorted_children = this.get_all_children ();
+        } else {
+            stop = stop.clamp (0, this.child_count);
+
+            unsorted_children = this.children.slice (0, this.child_count)
                                         as MediaObjects;
-        sorted_children.sort_by_criteria (sort_criteria);
+        }
+
+        unsorted_children.sort_by_criteria (sort_criteria);
 
-        return sorted_children.slice ((int) offset, (int) stop)
+        return unsorted_children.slice ((int) offset, (int) stop)
                                         as MediaObjects;
     }
 
@@ -197,14 +206,22 @@ public class Rygel.SimpleContainer : Rygel.MediaContainer,
                                                     Cancellable? cancellable)
                                                     throws Error {
         MediaObject media_object = null;
+        var max_count = 0;
         var restart_count = 0;
         var restart = false;
 
+        if (this.create_mode_enabled) {
+            max_count = this.all_child_count;
+        } else {
+            max_count = this.child_count;
+        }
+        var children_to_search = yield this.get_children (0, max_count, "", cancellable);
+
         do {
             restart = false;
             ulong updated_id = 0;
 
-            foreach (var child in this.children) {
+            foreach (var child in children_to_search) {
                 if (child.id == id) {
                     media_object = child;
 
@@ -278,6 +295,7 @@ public class Rygel.SimpleContainer : Rygel.MediaContainer,
             }
 
             this.empty_children.remove (updated);
+            this.empty_child_count--;
 
             this.add_child (updated);
 
@@ -292,6 +310,7 @@ public class Rygel.SimpleContainer : Rygel.MediaContainer,
 
             this.remove_child (updated);
             this.empty_children.add (updated);
+            this.empty_child_count++;
 
             this.updated ();
 
index 99ba4cb..39a723d 100644 (file)
@@ -42,7 +42,11 @@ public class MediaObject : Object {
 
 public class MediaContainer : MediaObject {
     public string sort_criteria = "+dc:title";
-    public uint child_count = 10;
+    public int child_count = 10;
+    public bool create_mode_enabled = false;
+    public int all_child_count {
+        get { return this.child_count; }
+    }
     public async MediaObjects? get_children (
                                             uint offset,
                                             uint max_count,
@@ -59,6 +63,8 @@ public class MediaContainer : MediaObject {
 
         return result;
     }
+
+    internal void check_search_expression (SearchExpression? expression) {}
 }
 
 public class TestContainer : MediaContainer, Rygel.SearchableContainer {