[rygel] media-export: Simplify virtual folder parsing
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] media-export: Simplify virtual folder parsing
- Date: Mon, 22 Mar 2010 17:07:15 +0000 (UTC)
commit 3346c553ee30f309eed8df59a0413456f2093e63
Author: Jens Georg <mail jensge org>
Date: Sun Mar 14 11:01:40 2010 +0100
media-export: Simplify virtual folder parsing
Virtual folders now contain the complete hierarchy from the beginning. The
format of the virtual folder definition has changed to use ? as
placeholder; also the complete hierarchy has to be defined before hand.
Example: virtual-folder:dc:date,?,upnp:artist,?,upnp:album,?
Will present a hierarchy that let's you browse by date, then by artist who
did something in that year and then by artist.
.../rygel-media-export-query-container.vala | 80 ++++++++++++--------
.../rygel-media-export-root-container.vala | 7 +-
2 files changed, 50 insertions(+), 37 deletions(-)
---
diff --git a/src/plugins/media-export/rygel-media-export-query-container.vala b/src/plugins/media-export/rygel-media-export-query-container.vala
index 42199d9..b1f3484 100644
--- a/src/plugins/media-export/rygel-media-export-query-container.vala
+++ b/src/plugins/media-export/rygel-media-export-query-container.vala
@@ -23,61 +23,56 @@ using GUPnP;
internal class Rygel.MediaExportQueryContainer : Rygel.MediaDBContainer {
public static const string PREFIX = "virtual-container:";
- private bool item_container;
private string attribute;
private SearchExpression expression;
private static HashMap<string,string> virtual_container_map = null;
public string plaintext_id;
+ private string pattern = "";
public MediaExportQueryContainer (MediaDB media_db,
string id,
string name) {
// parse the id
// Following the schema:
- // virtual-folder:<class> -> get all of that class (eg. Albums)
+ // virtual-folder:<class>,? -> get all of that class (eg. Albums)
// virtual-folder:<class>,<item> -> get all that is contained in that
// class
// If an item suffix is present, the children are items, otherwise
// containers
- // example: virtual-folder:upnp:album -> All albums
+ // To define a complete hierarchy of containers, use multiple
+ // levels:
+ // virtual-folder:<meta_data>,?,<meta_data>,? etc.
+ // example: virtual-folder:upnp:album,? -> All albums
// virtual-folder:upnp:album,The White Album -> All tracks of
// the White Album
- // virtual-folder:dc:creator,The Beatles,upnp:album ->
- // All Albums by the Beatles
+ // virtual-folder:dc:creator,The Beatles,upnp:album,? -> All
+ // Albums by the Beatles
// the parts not prefixed by virtual-folder: are URL-escaped
+ // virtual-folder:dc:creator,?,upnp:album,? -> start of
+ // hierarchy starting with artists then containing albums of
+ // that artist
base (media_db, id, name);
this.plaintext_id = get_virtual_container_definition (id);
debug ("plaintext id is: %s", this.plaintext_id);
var args = this.plaintext_id.split(",");
- // build SearchExpression from container-id
- int i = args.length - 1 - args.length % 2;
- while (i >= 1 - args.length % 2) {
- var exp = new RelationalExpression ();
- var op1 = args[i - 1].replace (PREFIX, "");
- exp.operand1 = Uri.unescape_string (op1);
- exp.op = SearchCriteriaOp.EQ;
- exp.operand2 = Uri.unescape_string (args[i]);
- if (this.expression != null) {
- var exp2 = new LogicalExpression ();
- exp2.operand1 = this.expression;
- exp2.operand2 = exp;
- exp2.op = LogicalOperator.AND;
- this.expression = exp2;
- } else {
- this.expression = exp;
- }
-
- i -= 2;
+ if ((args.length % 2) != 0) {
+ assert_not_reached ();
}
- if (args.length % 2 == 0) {
- // we will contain items
- this.item_container = true;
- } else {
- this.item_container = false;
- this.attribute = args[args.length - 1].replace (PREFIX, "");
+ int i = 0;
+ while (i < args.length) {
+ if (args[i + 1] != "?") {
+ update_search_expression (args[i], args[i + 1]);
+ } else {
+ args[i + 1] = "%s";
+ this.attribute = args[i].replace (PREFIX, "");
+ this.attribute = Uri.unescape_string (this.attribute);
+ this.pattern = string.joinv(",", args);
+ break;
+ }
+ i += 2;
}
}
@@ -114,7 +109,7 @@ internal class Rygel.MediaExportQueryContainer : Rygel.MediaDBContainer {
uint max_count,
Cancellable? cancellable)
throws GLib.Error {
- if (item_container) {
+ if (pattern == "") {
uint total_matches;
return yield this.search (this.expression,
offset,
@@ -139,8 +134,10 @@ internal class Rygel.MediaExportQueryContainer : Rygel.MediaDBContainer {
continue;
}
- var new_id = this.plaintext_id + ",";
- new_id += Uri.escape_string (meta_data, "", true);
+ var new_id = Uri.escape_string (meta_data, "", true);
+ // pattern contains URL escaped text. This means it might
+ // contain '%' chars which will makes sprintf crash
+ new_id = this.pattern.replace ("%s", new_id);
new_id = register_virtual_container (new_id);
var container = new MediaExportQueryContainer (this.media_db,
new_id,
@@ -175,4 +172,21 @@ internal class Rygel.MediaExportQueryContainer : Rygel.MediaDBContainer {
return null;
}
+
+ private void update_search_expression (string op1_, string op2) {
+ var exp = new RelationalExpression ();
+ var op1 = op1_.replace (PREFIX, "");
+ exp.operand1 = Uri.unescape_string (op1);
+ exp.op = SearchCriteriaOp.EQ;
+ exp.operand2 = Uri.unescape_string (op2);
+ if (this.expression != null) {
+ var exp2 = new LogicalExpression ();
+ exp2.operand1 = this.expression;
+ exp2.operand2 = exp;
+ exp2.op = LogicalOperator.AND;
+ this.expression = exp2;
+ } else {
+ this.expression = exp;
+ }
+ }
}
diff --git a/src/plugins/media-export/rygel-media-export-root-container.vala b/src/plugins/media-export/rygel-media-export-root-container.vala
index be96e7f..ee88d51 100644
--- a/src/plugins/media-export/rygel-media-export-root-container.vala
+++ b/src/plugins/media-export/rygel-media-export-root-container.vala
@@ -109,14 +109,14 @@ public class Rygel.MediaExportRootContainer : Rygel.MediaDBContainer {
return new MediaExportQueryContainer (
this.media_db,
MediaExportQueryContainer.register_virtual_container
- ("virtual-container:upnp:album"),
+ ("virtual-container:upnp:album,?"),
"Albums");
case "object.container.person.musicArtist":
return new MediaExportQueryContainer (
this.media_db,
MediaExportQueryContainer.register_virtual_container
- ("virtual-container:dc:creator"),
+ ("virtual-container:dc:creator,?,upnp:album,?"),
"Artists");
default:
return null;
@@ -189,8 +189,7 @@ public class Rygel.MediaExportRootContainer : Rygel.MediaDBContainer {
Uri.escape_string (exp_.operand2, "", true) +
cont.plaintext_id.replace ("virtual-container:", ",");
debug ("Translated search request to %s", new_id);
- new_id = MediaExportQueryContainer.register_virtual_container
- (new_id);
+ new_id = MediaExportQueryContainer.register_virtual_container (new_id);
var query_cont_ = new MediaExportQueryContainer (this.media_db,
new_id,
exp_.operand2);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]