[rygel] tracker: Initial port to 0.7 APIs
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [rygel] tracker: Initial port to 0.7 APIs
- Date: Sat, 5 Dec 2009 01:19:43 +0000 (UTC)
commit f991f5c021b14010a8a37135066f0c6dce307cab
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date: Sat Nov 21 01:31:59 2009 +0200
tracker: Initial port to 0.7 APIs
src/plugins/tracker/Makefile.am | 1 +
src/plugins/tracker/rygel-tracker-image-item.vala | 21 +-
src/plugins/tracker/rygel-tracker-interfaces.vala | 45 +---
src/plugins/tracker/rygel-tracker-item.vala | 74 ++----
src/plugins/tracker/rygel-tracker-keywords.vala | 66 +-----
.../tracker/rygel-tracker-metadata-values.vala | 101 +++++---
src/plugins/tracker/rygel-tracker-music-item.vala | 22 +-
.../tracker/rygel-tracker-plugin-factory.vala | 15 +-
src/plugins/tracker/rygel-tracker-query.vala | 168 ++++++++++++
.../tracker/rygel-tracker-root-container.vala | 27 ++-
.../tracker/rygel-tracker-search-container.vala | 277 +++++++++-----------
src/plugins/tracker/rygel-tracker-video-item.vala | 23 +-
12 files changed, 453 insertions(+), 387 deletions(-)
---
diff --git a/src/plugins/tracker/Makefile.am b/src/plugins/tracker/Makefile.am
index 2418883..8ed89e8 100644
--- a/src/plugins/tracker/Makefile.am
+++ b/src/plugins/tracker/Makefile.am
@@ -15,6 +15,7 @@ librygel_media_tracker_la_SOURCES = \
rygel-tracker-metadata-values.vala \
rygel-tracker-keywords.vala \
rygel-tracker-search-container.vala \
+ rygel-tracker-query.vala \
rygel-tracker-item.vala \
rygel-tracker-video-item.vala \
rygel-tracker-music-item.vala \
diff --git a/src/plugins/tracker/rygel-tracker-image-item.vala b/src/plugins/tracker/rygel-tracker-image-item.vala
index 3abaf55..a827b46 100644
--- a/src/plugins/tracker/rygel-tracker-image-item.vala
+++ b/src/plugins/tracker/rygel-tracker-image-item.vala
@@ -28,7 +28,7 @@ using DBus;
* Represents Tracker image item.
*/
public class Rygel.TrackerImageItem : Rygel.TrackerItem {
- public const string SERVICE = "Images";
+ public const string CATEGORY = "nmm:Photo";
public TrackerImageItem (string id,
string path,
@@ -37,24 +37,21 @@ public class Rygel.TrackerImageItem : Rygel.TrackerItem {
throws GLib.Error {
base (id, path, parent, MediaItem.IMAGE_CLASS, metadata);
- if (metadata[Metadata.IMAGE_TITLE] != "")
- this.title = metadata[Metadata.IMAGE_TITLE];
+ if (metadata[Metadata.TITLE] != "")
+ this.title = metadata[Metadata.TITLE];
else
/* If title wasn't provided, use filename instead */
this.title = metadata[Metadata.FILE_NAME];
- if (metadata[Metadata.IMAGE_WIDTH] != "")
- this.width = metadata[Metadata.IMAGE_WIDTH].to_int ();
+ if (metadata[Metadata.WIDTH] != "")
+ this.width = metadata[Metadata.WIDTH].to_int ();
- if (metadata[Metadata.IMAGE_HEIGHT] != "")
- this.height = metadata[Metadata.IMAGE_HEIGHT].to_int ();
+ if (metadata[Metadata.HEIGHT] != "")
+ this.height = metadata[Metadata.HEIGHT].to_int ();
- if (metadata[Metadata.IMAGE_DATE] != "") {
- this.date = seconds_to_iso8601 (metadata[Metadata.IMAGE_DATE]);
+ if (metadata[Metadata.DATE] != "") {
+ this.date = seconds_to_iso8601 (metadata[Metadata.DATE]);
}
-
- this.author = metadata[Metadata.CREATOR];
- this.album = metadata[Metadata.IMAGE_ALBUM];
}
}
diff --git a/src/plugins/tracker/rygel-tracker-interfaces.vala b/src/plugins/tracker/rygel-tracker-interfaces.vala
index 98194f1..7b9bb3c 100644
--- a/src/plugins/tracker/rygel-tracker-interfaces.vala
+++ b/src/plugins/tracker/rygel-tracker-interfaces.vala
@@ -23,44 +23,13 @@
using DBus;
-[DBus (name = "org.freedesktop.Tracker")]
-public interface Rygel.TrackerIface : DBus.Object {
- public abstract async int get_version () throws DBus.Error;
+[DBus (name = "org.freedesktop.Tracker1.Statistics")]
+public interface Rygel.TrackerStatsIface : DBus.Object {
+ public abstract async string[,] get_statistics () throws DBus.Error;
}
-[DBus (name = "org.freedesktop.Tracker.Keywords")]
-public interface Rygel.TrackerKeywordsIface : DBus.Object {
- public abstract async string[,] get_list (string service) throws DBus.Error;
-}
-
-[DBus (name = "org.freedesktop.Tracker.Metadata")]
-public interface Rygel.TrackerMetadataIface: DBus.Object {
- public abstract async string[,] get_unique_values (string service,
- string[] meta_types,
- string query,
- bool descending,
- int offset,
- int max_hits)
- throws DBus.Error;
-
- public abstract async string[] @get (string service_type,
- string uri,
- string[] keys)
- throws DBus.Error;
-}
-
-[DBus (name = "org.freedesktop.Tracker.Search")]
-public interface Rygel.TrackerSearchIface: DBus.Object {
- public abstract async string[,] query (int live_query_id,
- string service,
- string[] fields,
- string search_text,
- string[] keywords,
- string query_condition,
- bool sort_by_service,
- string[] sort_fields,
- bool sort_descending,
- int offset,
- int max_hits)
- throws DBus.Error;
+[DBus (name = "org.freedesktop.Tracker1.Resources")]
+public interface Rygel.TrackerResourcesIface: DBus.Object {
+ public abstract async string[,] sparql_query (string query)
+ throws DBus.Error;
}
diff --git a/src/plugins/tracker/rygel-tracker-item.vala b/src/plugins/tracker/rygel-tracker-item.vala
index 8a76e6f..7bc2b26 100644
--- a/src/plugins/tracker/rygel-tracker-item.vala
+++ b/src/plugins/tracker/rygel-tracker-item.vala
@@ -30,33 +30,22 @@ using DBus;
public abstract class Rygel.TrackerItem : Rygel.MediaItem {
protected enum Metadata {
FILE_NAME,
+ TITLE,
MIME,
SIZE,
DATE,
- // Image
- IMAGE_TITLE,
- IMAGE_WIDTH,
- IMAGE_HEIGHT,
- IMAGE_ALBUM,
- IMAGE_DATE,
- CREATOR,
+ // Image and Video
+ HEIGHT,
+ WIDTH,
+
+ // Audio and Video
+ DURATION,
// Audio
- AUDIO_TITLE,
- AUDIO_DURATION,
AUDIO_ALBUM,
- ARTIST,
- TRACK_NUM,
- RELEASE,
- DATE_ADDED,
-
- // Video
- VIDEO_TITLE,
- VIDEO_WIDTH,
- VIDEO_HEIGHT,
- VIDEO_DURATION,
- AUTHOR,
+ AUDIO_ARTIST,
+ AUDIO_TRACK_NUM,
LAST_KEY
}
@@ -86,38 +75,31 @@ public abstract class Rygel.TrackerItem : Rygel.MediaItem {
public static string[] get_metadata_keys () {
string[] keys = new string[Metadata.LAST_KEY];
- keys[Metadata.FILE_NAME] = "File:Name";
- keys[Metadata.MIME] = "File:Mime";
- keys[Metadata.SIZE] = "File:Size";
- keys[Metadata.DATE] = "DC:Date";
-
- // Image metadata
- keys[Metadata.IMAGE_TITLE] = "Image:Title";
- keys[Metadata.CREATOR] = "Image:Creator";
- keys[Metadata.IMAGE_WIDTH] = "Image:Width";
- keys[Metadata.IMAGE_HEIGHT] = "Image:Height";
- keys[Metadata.IMAGE_ALBUM] = "Image:Album";
- keys[Metadata.IMAGE_DATE] = "Image:Date";
+ keys[Metadata.FILE_NAME] = "nfo:fileName";
+ keys[Metadata.TITLE] = "nie:title";
+ keys[Metadata.MIME] = "nie:mimeType";
+ keys[Metadata.SIZE] = "nfo:fileSize";
+ keys[Metadata.DATE] = "dc:date";
+
+ // Image and Video metadata
+ keys[Metadata.WIDTH] = "nfo:width";
+ keys[Metadata.HEIGHT] = "nfo:height";
+
+ // Audio and Video metadata
+ keys[Metadata.DURATION] = "nmm:length";
// Audio metadata
- keys[Metadata.AUDIO_TITLE] = "Audio:Title";
- keys[Metadata.AUDIO_DURATION] = "Audio:Duration";
- keys[Metadata.ARTIST] = "Audio:Artist";
- keys[Metadata.AUDIO_ALBUM] = "Audio:Album";
- keys[Metadata.TRACK_NUM] = "Audio:TrackNo";
- keys[Metadata.RELEASE] = "Audio:ReleaseDate";
- keys[Metadata.DATE_ADDED] = "Audio:DateAdded";
-
- // Video metadata
- keys[Metadata.VIDEO_DURATION] = "Video:Duration";
- keys[Metadata.VIDEO_TITLE] = "Video:Title";
- keys[Metadata.AUTHOR] = "Video:Author";
- keys[Metadata.VIDEO_WIDTH] = "Video:Width";
- keys[Metadata.VIDEO_HEIGHT] = "Video:Height";
+ keys[Metadata.AUDIO_ARTIST] = "nmm:performer";
+ keys[Metadata.AUDIO_ALBUM] = "nmm:musicAlbum";
+ keys[Metadata.AUDIO_TRACK_NUM] = "nmm:trackNumber";
return keys;
}
+ public int get_num_metadata_keys () {
+ return Metadata.LAST_KEY;
+ }
+
protected string seconds_to_iso8601 (string seconds) {
string date;
diff --git a/src/plugins/tracker/rygel-tracker-keywords.vala b/src/plugins/tracker/rygel-tracker-keywords.vala
index 6bbf2a9..84f73e1 100644
--- a/src/plugins/tracker/rygel-tracker-keywords.vala
+++ b/src/plugins/tracker/rygel-tracker-keywords.vala
@@ -26,73 +26,17 @@ using DBus;
using Gee;
/**
- * Container listing all available keywords (tags) in Tracker DB.
+ * Container listing all available photo tags in Tracker DB.
*/
-public class Rygel.TrackerKeywords : Rygel.SimpleContainer {
+public class Rygel.TrackerKeywords : Rygel.TrackerMetadataValues {
/* class-wide constants */
- private const string TRACKER_SERVICE = "org.freedesktop.Tracker";
- private const string KEYWORDS_PATH = "/org/freedesktop/Tracker/Keywords";
-
- private const string SERVICE = "Files";
private const string TITLE = "Tags";
-
- public TrackerKeywordsIface keywords;
+ private const string CATEGORY = "nmm:Photo";
+ private const string[] KEY_CHAIN = { "nao:hasTag", "nao:prefLabel", null };
public TrackerKeywords (string id,
MediaContainer parent) {
- base (id, parent, TITLE);
-
- try {
- this.create_proxies ();
- } catch (DBus.Error error) {
- critical ("Failed to create to Session bus: %s\n",
- error.message);
-
- return;
- }
-
- this.fetch_keywords.begin ();
- }
-
- private async void fetch_keywords () {
- string[,] keywords_list;
-
- try {
- /* FIXME: We need to hook to some tracker signals to keep
- * this field up2date at all times
- */
- keywords_list = yield this.keywords.get_list (SERVICE);
- } catch (DBus.Error error) {
- critical ("error getting all keywords: %s", error.message);
-
- return;
- }
-
- /* Iterate through all the values */
- for (uint i = 0; i < keywords_list.length[0]; i++) {
- string keyword = keywords_list[i, 0];
-
- var keywords = new string[] { keyword };
-
- var container = new TrackerSearchContainer (keyword,
- this,
- keyword,
- SERVICE,
- "",
- keywords);
-
- this.add_child (container);
- }
-
- this.updated ();
- }
-
- private void create_proxies () throws DBus.Error {
- DBus.Connection connection = DBus.Bus.get (DBus.BusType.SESSION);
-
- this.keywords = connection.get_object (TRACKER_SERVICE,
- KEYWORDS_PATH)
- as TrackerKeywordsIface;
+ base (id, parent, TITLE, CATEGORY, KEY_CHAIN);
}
}
diff --git a/src/plugins/tracker/rygel-tracker-metadata-values.vala b/src/plugins/tracker/rygel-tracker-metadata-values.vala
index a8fceb2..1b3bb0b 100644
--- a/src/plugins/tracker/rygel-tracker-metadata-values.vala
+++ b/src/plugins/tracker/rygel-tracker-metadata-values.vala
@@ -30,27 +30,28 @@ using Gee;
*/
public class Rygel.TrackerMetadataValues : Rygel.SimpleContainer {
/* class-wide constants */
- private const string TRACKER_SERVICE = "org.freedesktop.Tracker";
- private const string METADATA_PATH = "/org/freedesktop/Tracker/Metadata";
+ private const string TRACKER_SERVICE = "org.freedesktop.Tracker1";
+ private const string RESOURCES_PATH = "/org/freedesktop/Tracker1/Resources";
+ private const string ITEM_VARIABLE = "?item";
- private const string SERVICE = "Files";
- private const string QUERY_CONDITION =
- "<rdfq:equals>\n" +
- "<rdfq:Property name=\"%s\" />\n" +
- "<rdf:String>%s</rdf:String>\n" +
- "</rdfq:equals>\n";
+ private string category;
- public TrackerMetadataIface metadata;
+ // 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;
- public string key;
+ private TrackerResourcesIface resources;
- public TrackerMetadataValues (string key,
- string id,
+ public TrackerMetadataValues (string id,
MediaContainer parent,
- string title) {
+ string title,
+ string category,
+ string[] key_chain) {
base (id, parent, title);
- this.key = key;
+ this.category = category;
+ this.key_chain = key_chain;
try {
this.create_proxies ();
@@ -65,44 +66,78 @@ public class Rygel.TrackerMetadataValues : Rygel.SimpleContainer {
}
private async void fetch_metadata_values () {
- string[,] values;
+ int i;
+ var mandatory = new ArrayList<TrackerQueryTriplet> ();
+
+ // 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 = null;
+ } else {
+ subject = variables[i - 1];
+ }
- try {
- var keys = new string[] { this.key };
+ mandatory.add (new TrackerQueryTriplet (subject,
+ this.key_chain[i],
+ variables[i],
+ false));
+ }
+
+ mandatory.insert (0, new TrackerQueryTriplet (ITEM_VARIABLE,
+ "a",
+ this.category,
+ false));
+ // 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 TrackerQuery (selected,
+ mandatory,
+ null,
+ null,
+ last_variable);
+
+ string[,] values;
+ try {
/* FIXME: We need to hook to some tracker signals to keep
* this field up2date at all times
*/
- values = yield this.metadata.get_unique_values (SERVICE,
- keys,
- "",
- false,
- 0,
- -1);
+ debug ("Executing SPARQL query: %s", query.to_string ());
+ values = yield this.resources.sparql_query (query.to_string ());
} catch (DBus.Error error) {
critical ("error getting all values for '%s': %s",
- this.key,
+ string.joinv (" -> ", this.key_chain),
error.message);
return;
}
/* Iterate through all the values */
- for (uint i = 0; i < values.length[0]; i++) {
+ for (i = 0; i < values.length[0]; i++) {
string value = values[i, 0];
if (value == "") {
continue;
}
- var query_condition = QUERY_CONDITION.printf (
- this.key,
- Markup.escape_text (value));
+ // The child container can use the same mandatory triplets we used
+ // in our query except that last value is now fixed
+ mandatory.last ().obj = "\"" + value + "\"";
+
var container = new TrackerSearchContainer (value,
this,
value,
- SERVICE,
- query_condition);
+ this.category,
+ mandatory,
+ null);
this.add_child (container);
}
@@ -113,9 +148,9 @@ public class Rygel.TrackerMetadataValues : Rygel.SimpleContainer {
private void create_proxies () throws DBus.Error {
DBus.Connection connection = DBus.Bus.get (DBus.BusType.SESSION);
- this.metadata = connection.get_object (TRACKER_SERVICE,
- METADATA_PATH)
- as TrackerMetadataIface;
+ this.resources = connection.get_object (TRACKER_SERVICE,
+ RESOURCES_PATH)
+ as TrackerResourcesIface;
}
}
diff --git a/src/plugins/tracker/rygel-tracker-music-item.vala b/src/plugins/tracker/rygel-tracker-music-item.vala
index d7903ad..681bffd 100644
--- a/src/plugins/tracker/rygel-tracker-music-item.vala
+++ b/src/plugins/tracker/rygel-tracker-music-item.vala
@@ -28,7 +28,7 @@ using DBus;
* Represents Tracker music item.
*/
public class Rygel.TrackerMusicItem : Rygel.TrackerItem {
- public const string SERVICE = "Music";
+ public const string CATEGORY = "nmm:MusicPiece";
public TrackerMusicItem (string id,
string path,
@@ -37,25 +37,23 @@ public class Rygel.TrackerMusicItem : Rygel.TrackerItem {
throws GLib.Error {
base (id, path, parent, MediaItem.MUSIC_CLASS, metadata);
- if (metadata[Metadata.AUDIO_TITLE] != "")
- this.title = metadata[Metadata.AUDIO_TITLE];
+ if (metadata[Metadata.TITLE] != "")
+ this.title = metadata[Metadata.TITLE];
else
/* If title wasn't provided, use filename instead */
this.title = metadata[Metadata.FILE_NAME];
- if (metadata[Metadata.AUDIO_DURATION] != "")
- this.duration = metadata[Metadata.AUDIO_DURATION].to_int ();
+ if (metadata[Metadata.DURATION] != "")
+ this.duration = metadata[Metadata.DURATION].to_int ();
- if (metadata[Metadata.TRACK_NUM] != "")
- this.track_number = metadata[Metadata.TRACK_NUM].to_int ();
+ if (metadata[Metadata.AUDIO_TRACK_NUM] != "")
+ this.track_number = metadata[Metadata.AUDIO_TRACK_NUM].to_int ();
- if (metadata[Metadata.RELEASE] != "") {
- this.date = seconds_to_iso8601 (metadata[Metadata.RELEASE]);
- } else {
- this.date = seconds_to_iso8601 (metadata[Metadata.DATE_ADDED]);
+ if (metadata[Metadata.DATE] != "") {
+ this.date = seconds_to_iso8601 (metadata[Metadata.DATE]);
}
- this.author = metadata[Metadata.ARTIST];
+ this.author = metadata[Metadata.AUDIO_ARTIST];
this.album = metadata[Metadata.AUDIO_ALBUM];
}
}
diff --git a/src/plugins/tracker/rygel-tracker-plugin-factory.vala b/src/plugins/tracker/rygel-tracker-plugin-factory.vala
index f057752..5558fdc 100644
--- a/src/plugins/tracker/rygel-tracker-plugin-factory.vala
+++ b/src/plugins/tracker/rygel-tracker-plugin-factory.vala
@@ -40,21 +40,22 @@ public void module_init (PluginLoader loader) {
}
public class TrackerPluginFactory {
- private const string TRACKER_SERVICE = "org.freedesktop.Tracker";
- private const string TRACKER_OBJECT = "/org/freedesktop/Tracker";
+ private const string TRACKER_SERVICE = "org.freedesktop.Tracker1";
+ private const string STATISTICS_OBJECT =
+ "/org/freedesktop/Tracker1/Statistics";
- TrackerIface tracker;
+ TrackerStatsIface stats;
PluginLoader loader;
public TrackerPluginFactory (PluginLoader loader) throws DBus.Error {
var connection = DBus.Bus.get (DBus.BusType.SESSION);
- this.tracker = connection.get_object (TRACKER_SERVICE,
- TRACKER_OBJECT)
- as TrackerIface;
+ this.stats = connection.get_object (TRACKER_SERVICE,
+ STATISTICS_OBJECT)
+ as TrackerStatsIface;
this.loader = loader;
- this.tracker.get_version ();
+ this.stats.get_statistics ();
this.loader.add_plugin (new TrackerPlugin ());
}
diff --git a/src/plugins/tracker/rygel-tracker-query.vala b/src/plugins/tracker/rygel-tracker-query.vala
new file mode 100644
index 0000000..35709cb
--- /dev/null
+++ b/src/plugins/tracker/rygel-tracker-query.vala
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali <zeenix gmail 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;
+
+/**
+ * Represents Tracker SPARQL query
+ */
+public class Rygel.TrackerQuery {
+ public ArrayList<TrackerQueryTriplet> mandatory;
+ public ArrayList<TrackerQueryTriplet> optional;
+
+ public ArrayList<string> variables;
+ public ArrayList<string> filters;
+
+ public string order_by;
+ public int offset;
+ public int max_count;
+
+ public TrackerQuery (ArrayList<string> variables,
+ ArrayList<TrackerQueryTriplet> mandatory,
+ ArrayList<TrackerQueryTriplet>? optional,
+ ArrayList<string>? filters,
+ string? order_by = null,
+ int offset = 0,
+ int max_count = -1) {
+ this.variables = variables;
+ this.mandatory = mandatory;
+
+ if (optional != null) {
+ this.optional = optional;
+ } else {
+ this.optional = new ArrayList<TrackerQueryTriplet> ();
+ }
+
+ if (filters != null) {
+ this.filters = filters;
+ } else {
+ this.filters = new ArrayList<string> ();
+ }
+
+ this.order_by = order_by;
+
+ this.offset = offset;
+ this.max_count = max_count;
+ }
+
+ public TrackerQuery.from_template (TrackerQuery template) {
+ this (template.variables,
+ template.mandatory,
+ template.optional,
+ template.filters,
+ template.order_by,
+ template.offset,
+ template.max_count);
+ }
+
+ public string to_string () {
+ string query = "SELECT";
+
+ foreach (var variable in this.variables) {
+ query += " " + variable;
+ }
+
+ query += " WHERE { " +
+ this.serialize_triplets (this.mandatory) +
+ " . " +
+ this.serialize_triplets (this.optional);
+
+ foreach (var filter in this.filters) {
+ query += " " + filter;
+ }
+
+ query += " }";
+
+ if (this.order_by != null) {
+ query += " ORDER BY " + order_by;
+ }
+
+ query += " OFFSET " + this.offset.to_string ();
+
+ if (this.max_count != -1) {
+ query += " LIMIT " + this.max_count.to_string ();
+ }
+
+ return query;
+ }
+
+ private string serialize_triplets (Gee.List<TrackerQueryTriplet> triplets) {
+ string str = "";
+
+ for (int i = 0; i < triplets.size; i++) {
+ str += triplets[i].to_string ();
+
+ if (i < triplets.size - 1) {
+ if (triplets[i + 1].subject != null) {
+ str += " . ";
+ } else {
+ // This implies that next triplet shares the subject with
+ // this one so we need to end this one with a semi-colon.
+ str += " ; ";
+ }
+ }
+ }
+
+ return str;
+ }
+}
+
+/**
+ * Represents SPARQL Triplet
+ */
+public class Rygel.TrackerQueryTriplet {
+ public string subject;
+ public string predicate;
+ public string obj;
+
+ public bool optional;
+
+ public TrackerQueryTriplet (string? subject,
+ string predicate,
+ string obj,
+ bool optional = true) {
+ this.subject = subject;
+ this.predicate = predicate;
+ this.obj = obj;
+ this.optional = optional;
+ }
+
+ public string to_string () {
+ string str = "";
+
+ if (this.optional) {
+ str += "OPTIONAL {";
+ }
+
+ if (this.subject != null) {
+ str += " " + subject;
+ }
+
+ str += " " + predicate + " " + obj;
+
+ if (this.optional) {
+ str += " }";
+ }
+
+ return str;
+ }
+}
diff --git a/src/plugins/tracker/rygel-tracker-root-container.vala b/src/plugins/tracker/rygel-tracker-root-container.vala
index de7ac8e..23c9176 100644
--- a/src/plugins/tracker/rygel-tracker-root-container.vala
+++ b/src/plugins/tracker/rygel-tracker-root-container.vala
@@ -37,25 +37,34 @@ public class Rygel.TrackerRootContainer : Rygel.SimpleContainer {
"16",
this,
"Pictures",
- TrackerImageItem.SERVICE));
+ TrackerImageItem.CATEGORY));
this.add_child (new TrackerSearchContainer (
"14",
this,
"Music",
- TrackerMusicItem.SERVICE));
+ TrackerMusicItem.CATEGORY));
this.add_child (new TrackerSearchContainer (
"15",
this,
"Videos",
- TrackerVideoItem.SERVICE));
- this.add_child (new TrackerMetadataValues ("Audio:Artist",
- "17",
+ TrackerVideoItem.CATEGORY));
+
+ var key_chain = new string[] { "nmm:performer",
+ "nmm:artistName",
+ null };
+ this.add_child (new TrackerMetadataValues ("17",
this,
- "Artists"));
- this.add_child (new TrackerMetadataValues ("Audio:Album",
- "18",
+ "Artists",
+ TrackerMusicItem.CATEGORY,
+ key_chain));
+
+ key_chain = new string[] { "nmm:musicAlbum", "nmm:albumTitle", null };
+ this.add_child (new TrackerMetadataValues ("18",
this,
- "Albums"));
+ "Albums",
+ TrackerMusicItem.CATEGORY,
+ key_chain));
+
this.add_child (new TrackerKeywords ("19", this));
}
}
diff --git a/src/plugins/tracker/rygel-tracker-search-container.vala b/src/plugins/tracker/rygel-tracker-search-container.vala
index 7221f3d..45799b4 100644
--- a/src/plugins/tracker/rygel-tracker-search-container.vala
+++ b/src/plugins/tracker/rygel-tracker-search-container.vala
@@ -30,30 +30,53 @@ using Gee;
*/
public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
/* class-wide constants */
- private const string TRACKER_SERVICE = "org.freedesktop.Tracker";
- private const string TRACKER_PATH = "/org/freedesktop/Tracker";
- private const string SEARCH_PATH = "/org/freedesktop/Tracker/Search";
- private const string METADATA_PATH = "/org/freedesktop/Tracker/Metadata";
+ private const string TRACKER_SERVICE = "org.freedesktop.Tracker1";
+ private const string RESOURCES_PATH = "/org/freedesktop/Tracker1/Resources";
- public TrackerSearchIface search_proxy;
+ private const string ITEM_VARIABLE = "?item";
- public string service;
+ public TrackerQuery query;
+ public string category;
- public string query_condition;
+ private TrackerResourcesIface resources;
- public string[] keywords;
-
- public TrackerSearchContainer (string id,
- MediaContainer parent,
- string title,
- string service,
- string query_condition = "",
- string[] keywords = new string[0]) {
+ public TrackerSearchContainer (string id,
+ MediaContainer parent,
+ string title,
+ string category,
+ ArrayList<TrackerQueryTriplet> mandatory =
+ new ArrayList<TrackerQueryTriplet> (),
+ ArrayList<string>? filters =
+ null) {
base (id, parent, title, 0);
- this.service = service;
- this.keywords = keywords;
- this.query_condition = query_condition;
+ this.category = category;
+
+ var variables = new ArrayList<string> ();
+ variables.add (ITEM_VARIABLE);
+
+ mandatory.add (new TrackerQueryTriplet (ITEM_VARIABLE,
+ "a",
+ category,
+ false));
+
+ var optional = new ArrayList<TrackerQueryTriplet> ();
+ foreach (var key in TrackerItem.get_metadata_keys ()) {
+ var variable = "?" + key.replace (":", "_");
+
+ variables.add (variable);
+
+ var triplet = new TrackerQueryTriplet (ITEM_VARIABLE,
+ key,
+ variable);
+ optional.add (triplet);
+ }
+
+ this.query = new TrackerQuery (variables,
+ mandatory,
+ optional,
+ filters,
+ ITEM_VARIABLE);
try {
this.create_proxies ();
@@ -69,37 +92,22 @@ public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
private async void get_children_count () {
try {
- // We are performing actual search (though an optimized one) to get
- // the hitcount rather than GetHitCount because GetHitCount only
- // allows us to get hit count for Text searches.
- string query;
-
- if (this.query_condition != "") {
- query = "<rdfq:Condition>\n" +
- this.query_condition +
- "</rdfq:Condition>";
- } else {
- query = "";
- }
-
- var search_result = yield this.search_proxy.query (
- 0,
- this.service,
- new string[0],
- "",
- this.keywords,
- query,
- false,
- new string[0],
- false,
- 0,
- -1);
-
- this.child_count = search_result.length[0];
+ var query = new TrackerQuery.from_template (this.query);
+
+ query.variables = new ArrayList<string> ();
+ query.variables.add ("COUNT(" + ITEM_VARIABLE + ") AS x");
+ query.optional = new ArrayList<TrackerQueryTriplet> ();
+
+ var query_str = query.to_string ();
+
+ debug ("Executing SPARQL query: %s", query_str);
+ var result = yield this.resources.sparql_query (query_str);
+
+ this.child_count = result[0,0].to_int ();
this.updated ();
} catch (GLib.Error error) {
- critical ("error getting items under service '%s': %s",
- this.service,
+ critical ("error getting item count under category '%s': %s",
+ this.category,
error.message);
return;
@@ -132,9 +140,10 @@ public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
out uint total_matches,
Cancellable? cancellable)
throws GLib.Error {
- string query = this.create_query_from_expression (expression);
var results = new ArrayList<MediaObject> ();
-
+ var query = this.create_query (expression,
+ (int) offset,
+ (int) max_count);
if (query == null) {
/* FIXME: chain-up when bug#601558 is fixed
return yield base.search (expression,
@@ -145,28 +154,17 @@ public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
return results;
}
- string[] keys = TrackerItem.get_metadata_keys ();
-
- var search_result = yield this.search_proxy.query (
- 0,
- this.service,
- keys,
- "",
- this.keywords,
- query,
- false,
- new string[0],
- false,
- (int) offset,
- (int) max_count);
+ var query_str = query.to_string ();
+
+ debug ("Executing SPARQL query: %s", query_str);
+ var search_result = yield this.resources.sparql_query (query_str);
/* Iterate through all items */
for (uint i = 0; i < search_result.length[0]; i++) {
- string path = search_result[i, 0];
- string service = search_result[i, 1];
- string[] metadata = this.slice_strvv_tail (search_result, i, 2);
+ string uri = search_result[i, 0];
+ string[] metadata = this.slice_strvv_tail (search_result, i, 1);
- var item = this.create_item (service, path, metadata);
+ var item = this.create_item (uri, metadata);
results.add (item);
}
@@ -175,110 +173,81 @@ public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
return results;
}
- private string? create_query_from_expression (SearchExpression expression) {
- string query = null;
-
+ private TrackerQuery? create_query (SearchExpression expression,
+ int offset,
+ int max_count) {
if (expression == null || !(expression is RelationalExpression)) {
- return query;
+ return null;
}
var rel_expression = expression as RelationalExpression;
- var query_op = this.get_op_for_expression (rel_expression);
+ string filter = null;
- if (rel_expression.operand1 == "@id" && query_op != null) {
- query = create_query_for_id (rel_expression, query_op);
+ if (rel_expression.operand1 == "@id") {
+ filter = create_filter_for_id (rel_expression);
} else if (rel_expression.operand1 == "@parentID" &&
- rel_expression.compare_string (this.id)) {
- if (this.query_condition != "") {
- query = "<rdfq:Condition>\n" +
- this.query_condition +
- "</rdfq:Condition>";
- } else {
- query = "";
- }
+ !rel_expression.compare_string (this.id)) {
+ return null;
}
- return query;
- }
+ var query = new TrackerQuery.from_template (this.query);
- private string? create_query_for_id (RelationalExpression expression,
- string query_op) {
- string query = null;
- string parent_id;
- string service;
-
- var path = this.get_item_info (expression.operand2,
- out parent_id,
- out service);
-
- if (path != null && parent_id != null && parent_id == this.id) {
- var dir = Path.get_dirname (path);
- var basename = Path.get_basename (path);
-
- var search_condition = "<rdfq:and>\n" +
- "<" + query_op + ">\n" +
- "<rdfq:Property " +
- "name=\"File:Path\" />\n" +
- "<rdf:String>" +
- dir +
- "</rdf:String>\n" +
- "</" + query_op + ">\n" +
- "<" + query_op + ">\n" +
- "<rdfq:Property " +
- "name=\"File:Name\" />\n" +
- "<rdf:String>" +
- basename +
- "</rdf:String>\n" +
- "</" + query_op + ">\n" +
- "</rdfq:and>\n";
-
- if (this.query_condition != "") {
- query = "<rdfq:Condition>\n" +
- "<rdfq:and>\n" +
- search_condition +
- this.query_condition +
- "</rdfq:and>\n" +
- "</rdfq:Condition>";
- } else {
- query = "<rdfq:Condition>\n" +
- search_condition +
- "</rdfq:Condition>";
- }
+ if (filter != null) {
+ var filters = query.filters;
+ query.filters = new ArrayList<string> ();
+ query.filters.add_all (filters);
+ query.filters.add (filter);
}
+ query.offset = offset;
+ query.max_count = max_count;
+
return query;
}
- private string? get_op_for_expression (RelationalExpression expression) {
+ private string? create_filter_for_id (RelationalExpression expression) {
+ string filter = null;
+
switch (expression.op) {
- case SearchCriteriaOp.EQ:
- return "rdfq:equals";
- case SearchCriteriaOp.CONTAINS:
- return "rdfq:contains";
- default:
- return null;
+ case SearchCriteriaOp.EQ:
+ string parent_id;
+
+ var uri = this.get_item_info (expression.operand2,
+ out parent_id);
+ if (uri == null || parent_id == null || parent_id != this.id) {
+ break;
+ }
+
+ filter = ITEM_VARIABLE + " = " + uri;
+ break;
+ case SearchCriteriaOp.CONTAINS:
+ filter = "regex(" + ITEM_VARIABLE + ", " +
+ expression.operand2 +
+ ")";
+ break;
}
+
+ return filter;
}
- private MediaItem? create_item (string service,
- string path,
+ private MediaItem? create_item (string uri,
string[] metadata)
throws GLib.Error {
- var id = service + ":" + this.id + ":" + path;
+ var id = this.id + ":" + uri;
- if (service == TrackerVideoItem.SERVICE) {
+ if (this.category == TrackerVideoItem.CATEGORY) {
return new TrackerVideoItem (id,
- path,
+ uri,
this,
metadata);
- } else if (service == TrackerImageItem.SERVICE) {
+ } else if (this.category == TrackerImageItem.CATEGORY) {
return new TrackerImageItem (id,
- path,
+ uri,
this,
metadata);
- } else if (service == TrackerMusicItem.SERVICE) {
+ } else if (this.category == TrackerMusicItem.CATEGORY) {
return new TrackerMusicItem (id,
- path,
+ uri,
this,
metadata);
} else {
@@ -286,18 +255,16 @@ public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
}
}
- // Returns the path, ID of the parent and service this item belongs to, or
- // null item_id is invalid
+ // Returns the URI and the ID of the parent this item belongs to, or null
+ // if item_id is invalid
private string? get_item_info (string item_id,
- out string parent_id,
- out string service) {
- var tokens = item_id.split (":", 3);
+ out string parent_id) {
+ var tokens = item_id.split (":", 2);
- if (tokens[0] != null && tokens[1] != null && tokens[2] != null) {
- service = tokens[0];
- parent_id = tokens[1];
+ if (tokens[0] != null && tokens[1] != null) {
+ parent_id = tokens[0];
- return tokens[2];
+ return tokens[1];
} else {
return null;
}
@@ -306,9 +273,9 @@ public class Rygel.TrackerSearchContainer : Rygel.MediaContainer {
private void create_proxies () throws DBus.Error {
DBus.Connection connection = DBus.Bus.get (DBus.BusType.SESSION);
- this.search_proxy = connection.get_object (TRACKER_SERVICE,
- SEARCH_PATH)
- as TrackerSearchIface;
+ this.resources = connection.get_object (TRACKER_SERVICE,
+ RESOURCES_PATH)
+ as TrackerResourcesIface;
}
/**
diff --git a/src/plugins/tracker/rygel-tracker-video-item.vala b/src/plugins/tracker/rygel-tracker-video-item.vala
index d87ec08..8c777bd 100644
--- a/src/plugins/tracker/rygel-tracker-video-item.vala
+++ b/src/plugins/tracker/rygel-tracker-video-item.vala
@@ -28,7 +28,7 @@ using DBus;
* Represents Tracker video item.
*/
public class Rygel.TrackerVideoItem : Rygel.TrackerItem {
- public const string SERVICE = "Videos";
+ public const string CATEGORY = "nmm:Video";
public TrackerVideoItem (string id,
string path,
@@ -37,25 +37,20 @@ public class Rygel.TrackerVideoItem : Rygel.TrackerItem {
throws GLib.Error {
base (id, path, parent, MediaItem.VIDEO_CLASS, metadata);
- if (metadata[Metadata.VIDEO_TITLE] != "")
- this.title = metadata[Metadata.VIDEO_TITLE];
+ if (metadata[Metadata.TITLE] != "")
+ this.title = metadata[Metadata.TITLE];
else
/* If title wasn't provided, use filename instead */
this.title = metadata[Metadata.FILE_NAME];
- if (metadata[Metadata.VIDEO_WIDTH] != "")
- this.width = metadata[Metadata.VIDEO_WIDTH].to_int ();
+ if (metadata[Metadata.WIDTH] != "")
+ this.width = metadata[Metadata.WIDTH].to_int ();
- if (metadata[Metadata.VIDEO_HEIGHT] != "")
- this.height = metadata[Metadata.VIDEO_HEIGHT].to_int ();
+ if (metadata[Metadata.HEIGHT] != "")
+ this.height = metadata[Metadata.HEIGHT].to_int ();
- if (metadata[Metadata.VIDEO_DURATION] != "")
- this.duration = metadata[Metadata.VIDEO_DURATION].to_int ();
-
- if (metadata[Metadata.VIDEO_DURATION] != "")
- this.duration = metadata[Metadata.VIDEO_DURATION].to_int ();
-
- this.author = metadata[Metadata.AUTHOR];
+ if (metadata[Metadata.DURATION] != "")
+ this.duration = metadata[Metadata.DURATION].to_int ();
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]