[rygel] tracker: Use property map in meta-data containers
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] tracker: Use property map in meta-data containers
- Date: Fri, 27 Jul 2012 21:25:50 +0000 (UTC)
commit e7993915a35f9e56e3abc921d5a31ac2df78aafc
Author: Jens Georg <mail jensge org>
Date: Sat Jul 14 18:39:25 2012 +0200
tracker: Use property map in meta-data containers
Split off Tags container since tags are multi-valued and don't work with
property functions
src/plugins/tracker/Makefile.am | 1 +
src/plugins/tracker/rygel-tracker-albums.vala | 6 +-
src/plugins/tracker/rygel-tracker-artists.vala | 6 +-
src/plugins/tracker/rygel-tracker-genre.vala | 4 +-
.../tracker/rygel-tracker-key-chain-map.vala | 1 -
.../rygel-tracker-metadata-multivalues.vala | 197 ++++++++++++++++++++
.../tracker/rygel-tracker-metadata-values.vala | 42 +---
src/plugins/tracker/rygel-tracker-tags.vala | 3 +-
src/plugins/tracker/rygel-tracker-titles.vala | 4 +-
src/plugins/tracker/rygel-tracker-years.vala | 4 +-
10 files changed, 217 insertions(+), 51 deletions(-)
---
diff --git a/src/plugins/tracker/Makefile.am b/src/plugins/tracker/Makefile.am
index c50394e..446f7de 100644
--- a/src/plugins/tracker/Makefile.am
+++ b/src/plugins/tracker/Makefile.am
@@ -13,6 +13,7 @@ librygel_tracker_la_SOURCES = \
rygel-tracker-videos.vala \
rygel-tracker-pictures.vala \
rygel-tracker-metadata-values.vala \
+ rygel-tracker-metadata-multivalues.vala \
rygel-tracker-tags.vala \
rygel-tracker-years.vala \
rygel-tracker-titles.vala \
diff --git a/src/plugins/tracker/rygel-tracker-albums.vala b/src/plugins/tracker/rygel-tracker-albums.vala
index 8fcee2d..7fc7c6c 100644
--- a/src/plugins/tracker/rygel-tracker-albums.vala
+++ b/src/plugins/tracker/rygel-tracker-albums.vala
@@ -26,15 +26,11 @@
*/
public class Rygel.Tracker.Albums : MetadataValues {
public Albums (Music parent) {
- var key_chain = new string[] { "nmm:musicAlbum",
- "nmm:albumTitle",
- null };
-
base (parent.id + "Albums",
parent,
_("Albums"),
parent.item_factory,
- key_chain,
+ "upnp:album",
MediaContainer.MUSIC_ALBUM);
}
}
diff --git a/src/plugins/tracker/rygel-tracker-artists.vala b/src/plugins/tracker/rygel-tracker-artists.vala
index 646b4ab..73aab9a 100644
--- a/src/plugins/tracker/rygel-tracker-artists.vala
+++ b/src/plugins/tracker/rygel-tracker-artists.vala
@@ -26,15 +26,11 @@
*/
public class Rygel.Tracker.Artists : MetadataValues {
public Artists (Music parent) {
- var key_chain = new string[] { "nmm:performer",
- "nmm:artistName",
- null };
-
base (parent.id + "Artists",
parent,
_("Artists"),
parent.item_factory,
- key_chain,
+ "upnp:artist",
MediaContainer.MUSIC_ARTIST);
}
}
diff --git a/src/plugins/tracker/rygel-tracker-genre.vala b/src/plugins/tracker/rygel-tracker-genre.vala
index 4fac786..bf6acb7 100644
--- a/src/plugins/tracker/rygel-tracker-genre.vala
+++ b/src/plugins/tracker/rygel-tracker-genre.vala
@@ -26,13 +26,11 @@
*/
public class Rygel.Tracker.Genre : MetadataValues {
public Genre (Music parent) {
- var key_chain = new string[] { "nfo:genre", null };
-
base (parent.id + "Genre",
parent,
_("Genre"),
parent.item_factory,
- key_chain,
+ "upnp:genre",
MediaContainer.MUSIC_GENRE);
}
}
diff --git a/src/plugins/tracker/rygel-tracker-key-chain-map.vala b/src/plugins/tracker/rygel-tracker-key-chain-map.vala
index 9ae0264..bcbbd42 100644
--- a/src/plugins/tracker/rygel-tracker-key-chain-map.vala
+++ b/src/plugins/tracker/rygel-tracker-key-chain-map.vala
@@ -124,4 +124,3 @@ public class Rygel.Tracker.KeyChainMap : Object {
this.add_function (property, str.str);
}
}
-
diff --git a/src/plugins/tracker/rygel-tracker-metadata-multivalues.vala b/src/plugins/tracker/rygel-tracker-metadata-multivalues.vala
new file mode 100644
index 0000000..0cd1ad3
--- /dev/null
+++ b/src/plugins/tracker/rygel-tracker-metadata-multivalues.vala
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ * Copyright (C) 2008-2012 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali <zeenix gmail com>
+ * Jens Georg <jensg openismus 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 GUPnP;
+using Gee;
+using Tracker;
+
+/**
+ * Container listing possible values of a particuler Tracker metadata key.
+ */
+public abstract class Rygel.Tracker.MetadataMultiValues : Rygel.SimpleContainer {
+ /* class-wide constants */
+ private const string TRACKER_SERVICE = "org.freedesktop.Tracker1";
+ private const string RESOURCES_PATH = "/org/freedesktop/Tracker1/Resources";
+
+ private ItemFactory item_factory;
+ private bool update_in_progress = false;
+
+ // In tracker 0.7, we might don't get values of keys in place so you need a
+ // chain of keys to reach to final destination. For instances:
+ // nmm:Performer -> nmm:artistName
+ public string[] key_chain;
+
+ private string child_class;
+
+ private Sparql.Connection resources;
+
+ public MetadataMultiValues (string id,
+ MediaContainer parent,
+ string title,
+ ItemFactory item_factory,
+ string[] key_chain,
+ string? child_class = null) {
+ base (id, parent, title);
+
+ this.item_factory = item_factory;
+ this.key_chain = key_chain;
+ this.child_class = child_class;
+
+ try {
+ this.resources = Sparql.Connection.get ();
+ } catch (Error error) {
+ critical (_("Failed to create Tracker connection: %s"), error.message);
+
+ return;
+ }
+
+ this.fetch_metadata_values.begin ();
+ }
+
+ internal async void fetch_metadata_values () {
+ if (this.update_in_progress) {
+ return;
+ }
+
+ this.update_in_progress = true;
+ // First thing, clear the existing hierarchy, if any
+ this.clear ();
+
+ int i;
+ var triplets = new QueryTriplets ();
+
+ triplets.add (new QueryTriplet (SelectionQuery.ITEM_VARIABLE,
+ "a",
+ this.item_factory.category));
+
+ // All variables used in the query
+ var num_keys = this.key_chain.length - 1;
+ var variables = new string[num_keys];
+ for (i = 0; i < num_keys; i++) {
+ variables[i] = "?" + key_chain[i].replace (":", "_");
+
+ string subject;
+ if (i == 0) {
+ subject = SelectionQuery.ITEM_VARIABLE;
+ } else {
+ subject = variables[i - 1];
+ }
+
+ triplets.add (new QueryTriplet (subject,
+ this.key_chain[i],
+ variables[i]));
+ }
+
+ // Variables to select from query
+ var selected = new ArrayList<string> ();
+ // Last variable is the only thing we are interested in the result
+ var last_variable = variables[num_keys - 1];
+ selected.add ("DISTINCT " + last_variable);
+
+ var query = new SelectionQuery (selected,
+ triplets,
+ null,
+ last_variable);
+
+ try {
+ yield query.execute (this.resources);
+
+ while (query.result.next ()) {
+ string value = query.result.get_string (0);
+
+ if (value == "") {
+ continue;
+ }
+
+ var title = this.create_title_for_value (value);
+ if (title == null) {
+ continue;
+ }
+
+ var id = this.create_id_for_title (title);
+ if (id == null || !this.is_child_id_unique (id)) {
+ continue;
+ }
+
+ // The child container can use the same triplets we used in our
+ // query.
+ var child_triplets = new QueryTriplets.clone (triplets);
+
+ // However we constrain the object of our last triplet.
+ var filters = new ArrayList<string> ();
+ var filter = this.create_filter (child_triplets.last ().obj, value);
+ filters.add (filter);
+
+ var container = new SearchContainer (id,
+ this,
+ title,
+ this.item_factory,
+ child_triplets,
+ filters);
+ if (this.child_class != null) {
+ container.upnp_class = child_class;
+ }
+
+ this.add_child_container (container);
+ }
+ } catch (Error error) {
+ critical (_("Error getting all values for '%s': %s"),
+ string.joinv (" -> ", this.key_chain),
+ error.message);
+ this.update_in_progress = false;
+
+ return;
+ }
+
+
+ this.updated ();
+ this.update_in_progress = false;
+ }
+
+ public override async MediaObject? find_object (string id,
+ Cancellable? cancellable)
+ throws GLib.Error {
+ if (this.is_our_child (id)) {
+ return yield base.find_object (id, cancellable);
+ } else {
+ return null;
+ }
+ }
+
+ protected virtual string? create_id_for_title (string title) {
+ return this.id + ":" + Uri.escape_string (title, "", true);
+ }
+
+ protected virtual string? create_title_for_value (string value) {
+ return value;
+ }
+
+ protected virtual string create_filter (string variable, string value) {
+ return variable + " = \"" + Query.escape_string (value) + "\"";
+ }
+
+ private bool is_our_child (string id) {
+ return id.has_prefix (this.id + ":");
+ }
+}
diff --git a/src/plugins/tracker/rygel-tracker-metadata-values.vala b/src/plugins/tracker/rygel-tracker-metadata-values.vala
index 11407e9..b333be7 100644
--- a/src/plugins/tracker/rygel-tracker-metadata-values.vala
+++ b/src/plugins/tracker/rygel-tracker-metadata-values.vala
@@ -37,10 +37,7 @@ public abstract class Rygel.Tracker.MetadataValues : Rygel.SimpleContainer {
private ItemFactory item_factory;
private bool update_in_progress = false;
- // In tracker 0.7, we might don't get values of keys in place so you need a
- // chain of keys to reach to final destination. For instances:
- // nmm:Performer -> nmm:artistName
- public string[] key_chain;
+ private string property;
private string child_class;
@@ -50,12 +47,12 @@ public abstract class Rygel.Tracker.MetadataValues : Rygel.SimpleContainer {
MediaContainer parent,
string title,
ItemFactory item_factory,
- string[] key_chain,
+ string property,
string? child_class = null) {
base (id, parent, title);
this.item_factory = item_factory;
- this.key_chain = key_chain;
+ this.property = property;
this.child_class = child_class;
try {
@@ -85,34 +82,16 @@ public abstract class Rygel.Tracker.MetadataValues : Rygel.SimpleContainer {
"a",
this.item_factory.category));
- // All variables used in the query
- var num_keys = this.key_chain.length - 1;
- var variables = new string[num_keys];
- for (i = 0; i < num_keys; i++) {
- variables[i] = "?" + key_chain[i].replace (":", "_");
-
- string subject;
- if (i == 0) {
- subject = SelectionQuery.ITEM_VARIABLE;
- } else {
- subject = variables[i - 1];
- }
-
- triplets.add (new QueryTriplet (subject,
- this.key_chain[i],
- variables[i]));
- }
-
- // Variables to select from query
+ var key_chain_map = KeyChainMap.get_key_chain_map ();
var selected = new ArrayList<string> ();
- // Last variable is the only thing we are interested in the result
- var last_variable = variables[num_keys - 1];
- selected.add ("DISTINCT " + last_variable);
+ selected.add ("DISTINCT " +
+ key_chain_map.map_property (this.property) +
+ " AS x");
var query = new SelectionQuery (selected,
triplets,
null,
- last_variable);
+ "?x");
try {
yield query.execute (this.resources);
@@ -140,7 +119,8 @@ public abstract class Rygel.Tracker.MetadataValues : Rygel.SimpleContainer {
// However we constrain the object of our last triplet.
var filters = new ArrayList<string> ();
- var filter = this.create_filter (child_triplets.last ().obj, value);
+ var property = key_chain_map.map_property (this.property);
+ var filter = this.create_filter (property, value);
filters.add (filter);
var container = new SearchContainer (id,
@@ -157,7 +137,7 @@ public abstract class Rygel.Tracker.MetadataValues : Rygel.SimpleContainer {
}
} catch (Error error) {
critical (_("Error getting all values for '%s': %s"),
- string.joinv (" -> ", this.key_chain),
+ this.id,
error.message);
this.update_in_progress = false;
diff --git a/src/plugins/tracker/rygel-tracker-tags.vala b/src/plugins/tracker/rygel-tracker-tags.vala
index 0f8d2e5..d6fd035 100644
--- a/src/plugins/tracker/rygel-tracker-tags.vala
+++ b/src/plugins/tracker/rygel-tracker-tags.vala
@@ -27,9 +27,10 @@ using Gee;
/**
* Container listing all available tag labels in Tracker DB.
*/
-public class Rygel.Tracker.Tags : MetadataValues {
+public class Rygel.Tracker.Tags : MetadataMultiValues {
/* class-wide constants */
private const string TITLE = "Tags";
+
private const string[] KEY_CHAIN = { "nao:hasTag", "nao:prefLabel", null };
public Tags (MediaContainer parent, ItemFactory item_factory) {
diff --git a/src/plugins/tracker/rygel-tracker-titles.vala b/src/plugins/tracker/rygel-tracker-titles.vala
index 3e48d5c..23ef384 100644
--- a/src/plugins/tracker/rygel-tracker-titles.vala
+++ b/src/plugins/tracker/rygel-tracker-titles.vala
@@ -50,14 +50,14 @@
* |..
*/
public class Rygel.Tracker.Titles : MetadataValues {
- private const string[] KEY_CHAIN = { "nie:title", null };
+ private const string[] KEY_CHAIN = { "dc:title", null };
public Titles (MediaContainer parent, ItemFactory item_factory) {
base (parent.id + "Titles",
parent,
_("Titles"),
item_factory,
- KEY_CHAIN);
+ "dc:title");
}
// The parent class will only create a child container for each unique
diff --git a/src/plugins/tracker/rygel-tracker-years.vala b/src/plugins/tracker/rygel-tracker-years.vala
index 1b6c8f5..9276ae4 100644
--- a/src/plugins/tracker/rygel-tracker-years.vala
+++ b/src/plugins/tracker/rygel-tracker-years.vala
@@ -27,14 +27,12 @@ using Gee;
* Container listing content hierarchy by year of creation.
*/
public class Rygel.Tracker.Years : MetadataValues {
- private const string[] KEY_CHAIN = { "nie:contentCreated", null };
-
public Years (MediaContainer parent, ItemFactory item_factory) {
base (parent.id + "Year",
parent,
_("Year"),
item_factory,
- KEY_CHAIN);
+ "date");
}
protected override string? create_title_for_value (string value) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]