this.action_invoked["Browse"].connect (this.browse_cb);
this.action_invoked["Search"].connect (this.search_cb);
this.action_invoked["CreateObject"].connect (this.create_object_cb);
+ this.action_invoked["CreateReference"].connect
+ (this.create_reference_cb);
this.action_invoked["DestroyObject"].connect (this.destroy_object_cb);
this.action_invoked["UpdateObject"].connect (this.update_object_cb);
this.action_invoked["ImportResource"].connect (this.import_resource_cb);
creator.run.begin ();
}
+ /* CreateReference action implementation */
+ private void create_reference_cb (Service content_dir,
+ ServiceAction action) {
+ var creator = new ReferenceCreator (this, action);
+
+ creator.run.begin ();
+ }
+
/* DestroyObject action implementation */
private void destroy_object_cb (Service content_dir,
ServiceAction action) {
--- /dev/null
+/*
+ * Copyright (C) 2013 Intel Corporation.
+ *
+ * Author: 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;
+
+internal class Rygel.ReferenceCreator : GLib.Object, Rygel.StateMachine {
+ private ContentDirectory content_directory;
+ private ServiceAction action;
+
+ // Props
+ public Cancellable cancellable { get; set; }
+ public string container_id;
+
+ // Local props
+ public string object_id;
+
+ public ReferenceCreator (ContentDirectory content_dir,
+ owned ServiceAction action) {
+ this.content_directory = content_dir;
+ this.cancellable = content_dir.cancellable;
+ this.action = (owned) action;
+ }
+
+ public void parse_arguments () throws Error {
+ this.action.get ("ContainerID",
+ typeof (string), out this.container_id,
+ "ObjectID",
+ typeof (string), out this.object_id);
+ if (this.container_id == null) {
+ // FIXME: Add translation
+ throw new ContentDirectoryError.INVALID_ARGS
+ (("'ContainerID' agument missing."));
+ }
+
+ if (this.object_id == null) {
+ // FIXME: Add translation
+ throw new ContentDirectoryError.INVALID_ARGS
+ (("'ObjectID' argument missing."));
+ }
+ }
+
+ public async void run () {
+ try {
+ this.parse_arguments ();
+ var container = yield this.fetch_container ();
+ var root_container = this.content_directory.root_container;
+ var object = yield root_container.find_object
+ (this.object_id, this.cancellable);
+ if (object == null) {
+ throw new ContentDirectoryError.NO_SUCH_OBJECT
+ (_("No such object"));
+ }
+
+ var new_id = yield container.add_reference (object,
+ this.cancellable);
+
+ this.action.set ("NewID", typeof (string), new_id);
+ this.action.return ();
+ this.completed ();
+ } catch (Error error) {
+ this.action.return_error (error.code, error.message);
+
+ warning (_("Failed to create object under '%s': %s"),
+ this.container_id,
+ error.message);
+
+ this.completed ();
+
+ return;
+ }
+ }
+
+ /**
+ * Get the container to create the item in.
+ *
+ * This will either try to fetch the container supplied by the caller or
+ * search for a container if the caller supplied the "DLNA.ORG_AnyContainer"
+ * id.
+ *
+ * @return an instance of WritableContainer matching the criteria
+ * @throws ContentDirectoryError for various problems
+ */
+ private async WritableContainer fetch_container () throws Error {
+ MediaObject media_object = null;
+
+ var root_container = this.content_directory.root_container;
+ media_object = yield root_container.find_object (this.container_id,
+ this.cancellable);
+
+ if (media_object == null || !(media_object is MediaContainer)) {
+ throw new ContentDirectoryError.NO_SUCH_OBJECT
+ (_("No such object"));
+ } else if (!(OCMFlags.UPLOAD in media_object.ocm_flags) ||
+ !(media_object is WritableContainer)) {
+ throw new ContentDirectoryError.RESTRICTED_PARENT
+ (_("Object creation in %s not allowed"),
+ media_object.id);
+ }
+
+ // FIXME: Check for @restricted=1 missing?
+
+ return media_object as WritableContainer;
+ }
+
+
+}