From 7089836a670c9c0b1e214ef2af993739a523bcae Mon Sep 17 00:00:00 2001 From: "Zeeshan Ali (Khattak)" Date: Sat, 6 Feb 2010 15:39:29 +0200 Subject: [PATCH] tracker: Implement MediaContainer.add_item() Make sure the new created item goes into the tracker DB and rygel gets it's actual ID. --- src/plugins/tracker/Makefile.am | 2 + .../tracker/rygel-tracker-category-container.vala | 18 ++- .../tracker/rygel-tracker-insertion-query.vala | 62 +++++++++ src/plugins/tracker/rygel-tracker-interfaces.vala | 1 + .../tracker/rygel-tracker-item-creation.vala | 144 +++++++++++++++++++++ 5 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 src/plugins/tracker/rygel-tracker-insertion-query.vala create mode 100644 src/plugins/tracker/rygel-tracker-item-creation.vala diff --git a/src/plugins/tracker/Makefile.am b/src/plugins/tracker/Makefile.am index 76cd327..c8c0136 100644 --- a/src/plugins/tracker/Makefile.am +++ b/src/plugins/tracker/Makefile.am @@ -22,9 +22,11 @@ librygel_media_tracker_la_SOURCES = \ rygel-tracker-search-container.vala \ rygel-tracker-query.vala \ rygel-tracker-selection-query.vala \ + rygel-tracker-insertion-query.vala \ rygel-tracker-query-triplet.vala \ rygel-tracker-query-triplets.vala \ rygel-tracker-item-factory.vala \ + rygel-tracker-item-creation.vala \ rygel-tracker-video-item-factory.vala \ rygel-tracker-music-item-factory.vala \ rygel-tracker-picture-item-factory.vala \ diff --git a/src/plugins/tracker/rygel-tracker-category-container.vala b/src/plugins/tracker/rygel-tracker-category-container.vala index 889724a..8be6a0c 100644 --- a/src/plugins/tracker/rygel-tracker-category-container.vala +++ b/src/plugins/tracker/rygel-tracker-category-container.vala @@ -39,7 +39,6 @@ public class Rygel.TrackerCategoryContainer : Rygel.SimpleContainer { try { var uri = Filename.to_uri (item_factory.upload_dir, null); - this.uris.add (uri); } catch (ConvertError error) { warning ("Failed to contstruct URI for directory '%s': %s", @@ -47,5 +46,22 @@ public class Rygel.TrackerCategoryContainer : Rygel.SimpleContainer { error.message); } } + + public async override void add_item (MediaItem item, + Cancellable? cancellable) + throws Error { + assert (this.uris.size > 0); + + yield base.add_item (item, cancellable); + assert (item.uris.size > 0); + + var creation = new TrackerItemCreation (item, this, cancellable); + + yield creation.run (); + + if (creation.error != null) { + throw creation.error; + } + } } diff --git a/src/plugins/tracker/rygel-tracker-insertion-query.vala b/src/plugins/tracker/rygel-tracker-insertion-query.vala new file mode 100644 index 0000000..5677b3a --- /dev/null +++ b/src/plugins/tracker/rygel-tracker-insertion-query.vala @@ -0,0 +1,62 @@ +/* + * Copyright (C) 20010 Nokia Corporation. + * + * Author: Zeeshan Ali + * + * 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 Insertion query + */ +public class Rygel.TrackerInsertionQuery : Rygel.TrackerQuery { + public string id; + + public TrackerInsertionQuery (MediaItem item, string category) { + var triplets = new TrackerQueryTriplets (); + triplets.add (new TrackerQueryTriplet (item.id, + "a", + category, + false)); + triplets.add (new TrackerQueryTriplet (item.id, + "nie:mimeType", + "\"" + item.mime_type + "\"", + false)); + triplets.add (new TrackerQueryTriplet (item.id, + "nie:url", + "\"" + item.uris[0] + "\"", + false)); + base (triplets, null); + + this.id = item.id; + } + + public override async void execute (TrackerResourcesIface resources) + throws DBus.Error { + var str = this.to_string (); + + debug ("Executing SPARQL query: %s", str); + + yield resources.sparql_update (str); + } + + public override string to_string () { + return "INSERT INTO " + this.id + " { " + base.to_string () + " }"; + } +} diff --git a/src/plugins/tracker/rygel-tracker-interfaces.vala b/src/plugins/tracker/rygel-tracker-interfaces.vala index dda79e3..8fcae64 100644 --- a/src/plugins/tracker/rygel-tracker-interfaces.vala +++ b/src/plugins/tracker/rygel-tracker-interfaces.vala @@ -32,6 +32,7 @@ public interface Rygel.TrackerStatsIface : DBus.Object { public interface Rygel.TrackerResourcesIface: DBus.Object { public abstract async string[,] sparql_query (string query) throws DBus.Error; + public abstract async void sparql_update (string query) throws DBus.Error; } [DBus (name = "org.freedesktop.Tracker1.Resources.Class")] diff --git a/src/plugins/tracker/rygel-tracker-item-creation.vala b/src/plugins/tracker/rygel-tracker-item-creation.vala new file mode 100644 index 0000000..bef4ec0 --- /dev/null +++ b/src/plugins/tracker/rygel-tracker-item-creation.vala @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2008-2010 Nokia Corporation. + * + * Author: Zeeshan Ali (Khattak) + * + * + * 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. + */ + +public errordomain TrackerItemCreationError { + TIMEOUT +} + +/** + * StateMachine interface. + */ +public class Rygel.TrackerItemCreation : GLib.Object, Rygel.StateMachine { + /* class-wide constants */ + private const string TRACKER_SERVICE = "org.freedesktop.Tracker1"; + private const string RESOURCES_PATH = "/org/freedesktop/Tracker1/Resources"; + private const uint ITEM_CREATION_TIMEOUT = 5; + + public Cancellable cancellable { get; set; } + public Error error { get; set; } + + private MediaItem item; + private TrackerCategoryContainer category_container; + private TrackerResourcesIface resources; + + private SourceFunc run_continue = null; + private bool added = false; + + public TrackerItemCreation (MediaItem item, + TrackerCategoryContainer category_container, + Cancellable? cancellable) + throws Error { + this.item = item; + this.category_container = category_container; + this.cancellable = cancellable; + this.create_proxies (); + } + + public async void run () { + this.item.id = "<" + this.item.uris[0] + ">"; + + var category = this.category_container.item_factory.category; + var query = new TrackerInsertionQuery (this.item, category); + + var handler_id = this.category_container.container_updated.connect + (this.on_container_updated); + + try { + yield query.execute (this.resources); + } catch (DBus.Error error) { + this.error = error; + + return; + } + + if (!added) { + // The new item still haven't been picked up, lets wait for it + // a bit + this.run_continue = this.run.callback; + + Timeout.add_seconds (ITEM_CREATION_TIMEOUT, + this.on_item_creation_timeout); + + yield; + } + + SignalHandler.disconnect (this.category_container, handler_id); + } + + private void on_container_updated (MediaContainer updated_container) { + this.on_container_updated_async.begin (updated_container); + } + + private bool on_item_creation_timeout () { + this.run_continue (); + this.error = new TrackerItemCreationError.TIMEOUT ( + "Timeout while waiting for item" + + "creation signal from Tracker"); + + return false; + } + + private async void on_container_updated_async ( + MediaContainer updated_container) { + Gee.List children; + + try { + children = yield updated_container.get_children (0, + -1, + this.cancellable); + } catch (Error error) { + warning ("Error listing children of '%s': %s", + updated_container.id, + error.message); + + return; + } + + foreach (var child in children) { + foreach (var uri in child.uris) { + if (uri == this.item.uris[0]) { + added = true; + + break; + } + } + + if (added) { + if (this.run_continue != null) { + this.run_continue (); + } + + break; + } + } + } + + private void create_proxies () throws DBus.Error { + DBus.Connection connection = DBus.Bus.get (DBus.BusType.SESSION); + + this.resources = connection.get_object (TRACKER_SERVICE, + RESOURCES_PATH) + as TrackerResourcesIface; + } +} + -- 2.7.4