From ffb46e3ae01bd05cfbd43d2f50fa7743db45b531 Mon Sep 17 00:00:00 2001 From: Christophe Guiraud Date: Thu, 21 Mar 2013 14:09:13 +0100 Subject: [API] Add new GetMetaData Media Object API - Add a new method GetMetaData to the org.gnome.UPnP.MediaObject2 interface to allow the retrieval of the Meta data information of an object in DIDL-Lite XML format. - MediaConsole python test app updated. - Doc updated. - Fix issue https://github.com/01org/dleyna-server/issues/25 Signed-off-by: Christophe Guiraud --- doc/server/dbus/API.txt | 4 +++ libdleyna/server/device.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ libdleyna/server/device.h | 4 +++ libdleyna/server/interface.h | 2 ++ libdleyna/server/server.c | 10 ++++++ libdleyna/server/task.c | 15 ++++++--- libdleyna/server/task.h | 5 +++ libdleyna/server/upnp.c | 17 ++++++++++ libdleyna/server/upnp.h | 4 +++ test/dbus/mediaconsole.py | 3 ++ 10 files changed, 135 insertions(+), 4 deletions(-) diff --git a/doc/server/dbus/API.txt b/doc/server/dbus/API.txt index 1545512..6c816eb 100644 --- a/doc/server/dbus/API.txt +++ b/doc/server/dbus/API.txt @@ -497,6 +497,10 @@ The same property cannot appear in both ToAddUpdate and ToDelete. Only the following properties can be updated: 'Date', 'DisplayName', 'Artists', 'Album', 'Type', 'TrackNumber'. +GetMetaData() -> s + +Returns the object meta data information in DIDL-Lite XML format. + org.gnome.MediaContainer2 ---------------------- diff --git a/libdleyna/server/device.c b/libdleyna/server/device.c index c6b7dc4..a3dfcf0 100644 --- a/libdleyna/server/device.c +++ b/libdleyna/server/device.c @@ -4346,3 +4346,78 @@ void dls_device_playlist_upload(dls_client_t *client, DLEYNA_LOG_DEBUG("Exit"); } + +static void prv_get_object_metadata_cb(GUPnPServiceProxy *proxy, + GUPnPServiceProxyAction *action, + gpointer user_data) +{ + GError *upnp_error = NULL; + dls_async_task_t *cb_data = user_data; + gchar *result = NULL; + + DLEYNA_LOG_DEBUG("Enter"); + + if (!gupnp_service_proxy_end_action(cb_data->proxy, cb_data->action, + &upnp_error, + "Result", G_TYPE_STRING, &result, + NULL)) { + DLEYNA_LOG_WARNING("Browse Object operation failed: %s", + upnp_error->message); + + cb_data->error = g_error_new(DLEYNA_SERVER_ERROR, + DLEYNA_ERROR_OPERATION_FAILED, + "Browse operation failed: %s", + upnp_error->message); + goto on_complete; + } + + cb_data->task.result = g_variant_ref_sink(g_variant_new_string(result)); + + DLEYNA_LOG_DEBUG("prv_get_object_metadata_cb result: %s", result); + + g_free(result); + +on_complete: + + (void) g_idle_add(dls_async_task_complete, cb_data); + g_cancellable_disconnect(cb_data->cancellable, cb_data->cancel_id); + + if (upnp_error) + g_error_free(upnp_error); + + DLEYNA_LOG_DEBUG("Exit"); +} + +void dls_device_get_object_metadata(dls_client_t *client, + dls_task_t *task, + const gchar *upnp_filter) +{ + dls_async_task_t *cb_data = (dls_async_task_t *)task; + dls_device_context_t *context; + + DLEYNA_LOG_DEBUG("Enter"); + + context = dls_device_get_context(task->target.device, client); + + cb_data->action = gupnp_service_proxy_begin_action( + context->service_proxy, "Browse", + prv_get_object_metadata_cb, cb_data, + "ObjectID", G_TYPE_STRING, task->target.id, + "BrowseFlag", G_TYPE_STRING, "BrowseMetadata", + "Filter", G_TYPE_STRING, "*", + "StartingIndex", G_TYPE_INT, 0, + "RequestedCount", G_TYPE_INT, 0, + "SortCriteria", G_TYPE_STRING, "", + NULL); + + cb_data->proxy = context->service_proxy; + + g_object_add_weak_pointer((G_OBJECT(context->service_proxy)), + (gpointer *)&cb_data->proxy); + + cb_data->cancel_id = g_cancellable_connect(cb_data->cancellable, + G_CALLBACK(dls_async_task_cancelled_cb), + cb_data, NULL); + + DLEYNA_LOG_DEBUG("Exit"); +} diff --git a/libdleyna/server/device.h b/libdleyna/server/device.h index ef3e3df..fa74ac8 100644 --- a/libdleyna/server/device.h +++ b/libdleyna/server/device.h @@ -126,4 +126,8 @@ void dls_device_playlist_upload(dls_client_t *client, dls_task_t *task, const gchar *parent_id); +void dls_device_get_object_metadata(dls_client_t *client, + dls_task_t *task, + const gchar *parent_id); + #endif /* DLS_DEVICE_H__ */ diff --git a/libdleyna/server/interface.h b/libdleyna/server/interface.h index fb2695e..33fcc3b 100644 --- a/libdleyna/server/interface.h +++ b/libdleyna/server/interface.h @@ -187,5 +187,7 @@ enum dls_interface_type_ { #define DLS_INTERFACE_DESCRIPTION "Description" #define DLS_INTERFACE_PLAYLIST_ITEMS "PlaylistItems" +#define DLS_INTERFACE_GET_METADATA "GetMetaData" +#define DLS_INTERFACE_METADATA "MetaData" #endif /* DLEYNA_SERVER_INTERFACE_H__ */ diff --git a/libdleyna/server/server.c b/libdleyna/server/server.c index 6cfa036..4fbbc7e 100644 --- a/libdleyna/server/server.c +++ b/libdleyna/server/server.c @@ -138,6 +138,10 @@ static const gchar g_server_introspection[] = " " " " + " " + " " + " " " " " " " " @@ -607,6 +611,10 @@ static void prv_process_async_task(dls_task_t *task) dls_upnp_create_playlist_in_any(g_context.upnp, client, task, prv_async_task_complete); break; + case DLS_TASK_GET_OBJECT_METADATA: + dls_upnp_get_object_metadata(g_context.upnp, client, task, + prv_async_task_complete); + break; default: break; } @@ -843,6 +851,8 @@ static void prv_object_method_call(dleyna_connector_id_t conn, else if (!strcmp(method, DLS_INTERFACE_UPDATE)) task = dls_task_update_new(invocation, object, parameters, &error); + else if (!strcmp(method, DLS_INTERFACE_GET_METADATA)) + task = dls_task_get_metadata_new(invocation, object, &error); else goto finished; diff --git a/libdleyna/server/task.c b/libdleyna/server/task.c index 6a8cf85..3d74c56 100644 --- a/libdleyna/server/task.c +++ b/libdleyna/server/task.c @@ -419,10 +419,6 @@ dls_task_t *dls_task_get_upload_ids_new(dleyna_connector_msg_id_t invocation, task = prv_m2spec_task_new(DLS_TASK_GET_UPLOAD_IDS, invocation, path, "(@au)", error, TRUE); - if (!task) - goto finished; - -finished: return task; } @@ -530,6 +526,17 @@ finished: return task; } +dls_task_t *dls_task_get_metadata_new(dleyna_connector_msg_id_t invocation, + const gchar *path, GError **error) +{ + dls_task_t *task; + + task = prv_m2spec_task_new(DLS_TASK_GET_OBJECT_METADATA, invocation, + path, "(@s)", error, FALSE); + + return task; +} + void dls_task_complete(dls_task_t *task) { GVariant *variant = NULL; diff --git a/libdleyna/server/task.h b/libdleyna/server/task.h index 0257a9f..061c84e 100644 --- a/libdleyna/server/task.h +++ b/libdleyna/server/task.h @@ -50,6 +50,7 @@ enum dls_task_type_t_ { DLS_TASK_CREATE_CONTAINER, DLS_TASK_CREATE_CONTAINER_IN_ANY, DLS_TASK_UPDATE_OBJECT, + DLS_TASK_GET_OBJECT_METADATA, DLS_TASK_CREATE_PLAYLIST, DLS_TASK_CREATE_PLAYLIST_IN_ANY }; @@ -256,6 +257,10 @@ dls_task_t *dls_task_update_new(dleyna_connector_msg_id_t invocation, const gchar *path, GVariant *parameters, GError **error); +dls_task_t *dls_task_get_metadata_new(dleyna_connector_msg_id_t invocation, + const gchar *path, + GError **error); + void dls_task_cancel(dls_task_t *task); void dls_task_complete(dls_task_t *task); diff --git a/libdleyna/server/upnp.c b/libdleyna/server/upnp.c index dcb9876..a61ab44 100644 --- a/libdleyna/server/upnp.c +++ b/libdleyna/server/upnp.c @@ -1046,6 +1046,23 @@ on_error: DLEYNA_LOG_DEBUG("Exit failure"); } +void dls_upnp_get_object_metadata(dls_upnp_t *upnp, dls_client_t *client, + dls_task_t *task, dls_upnp_task_complete_t cb) +{ + dls_async_task_t *cb_data = (dls_async_task_t *)task; + + DLEYNA_LOG_DEBUG("Enter"); + + cb_data->cb = cb; + + DLEYNA_LOG_DEBUG("Root Path %s Id %s", task->target.root_path, + task->target.id); + + dls_device_get_object_metadata(client, task, task->target.id); + + DLEYNA_LOG_DEBUG("Exit"); +} + void dls_upnp_unsubscribe(dls_upnp_t *upnp) { GHashTableIter iter; diff --git a/libdleyna/server/upnp.h b/libdleyna/server/upnp.h index dfe2d1b..ed3e6f9 100644 --- a/libdleyna/server/upnp.h +++ b/libdleyna/server/upnp.h @@ -101,6 +101,10 @@ void dls_upnp_create_playlist_in_any(dls_upnp_t *upnp, dls_client_t *client, dls_task_t *task, dls_upnp_task_complete_t cb); +void dls_upnp_get_object_metadata(dls_upnp_t *upnp, dls_client_t *client, + dls_task_t *task, + dls_upnp_task_complete_t cb); + void dls_upnp_unsubscribe(dls_upnp_t *upnp); gboolean dls_upnp_device_context_exist(dls_device_t *device, diff --git a/test/dbus/mediaconsole.py b/test/dbus/mediaconsole.py index b0a0057..2dc552e 100644 --- a/test/dbus/mediaconsole.py +++ b/test/dbus/mediaconsole.py @@ -64,6 +64,9 @@ class MediaObject(object): def update(self, to_add_update, to_delete): return self.__objIF.Update(to_add_update, to_delete) + def get_metadata(self): + return self.__objIF.GetMetaData() + class Item(MediaObject): def __init__(self, path): MediaObject.__init__(self, path) -- cgit v1.2.1