diff -r 000000000000 -r 3eeb6b565018 myth-dbus/src/gmyth-dbus-server.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/myth-dbus/src/gmyth-dbus-server.c Wed Oct 24 20:01:02 2007 +0100
@@ -0,0 +1,1005 @@
+/**
+ * GMyth Library
+ *
+ * @file gmyth/gmyth_backend_info.c
+ *
+ * @brief
This component represents all the MythTV backend server
+ * configuration information.
+ *
+ * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
+ * @author Renato Filho
+ *
+ *
+ * This program 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.
+ *
+ * This program 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include
+#include
+
+
+#include "gmyth-dbus-common.h"
+#include "gmyth-dbus-server.h"
+
+#define MYTH_DEFAULT_DB "mythconverg"
+
+
+typedef struct _GMythDbusServerPrivate GMythDbusServerPrivate;
+
+struct _GMythDbusServerPrivate
+{
+ GMythBackendInfo *myth_backend;
+ GMythEPG *myth_epg;
+ GMythScheduler *myth_scheduler;
+};
+
+#define GMYTH_DBUS_SERVER_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GMYTH_DBUS_SERVER_TYPE, GMythDbusServerPrivate))
+
+static void gmyth_dbus_server_class_init (GMythDbusServerClass *klass);
+static void gmyth_dbus_server_init (GMythDbusServer *self);
+static void gmyth_dbus_server_dispose (GObject *object);
+static void gmyth_dbus_server_finalize (GObject *object);
+
+/* Dbus */
+static gboolean gmyth_dbus_server_connect (GObject *obj,
+ const gchar *host,
+ guint port,
+ const gchar *user,
+ const gchar *password,
+ gboolean *result,
+ GError **error);
+static gboolean gmyth_dbus_server_get_channel_list (GObject *obj,
+ GPtrArray **channels,
+ GError **error);
+static gboolean gmyth_dbus_server_get_channel_info (GObject *obj,
+ gint channel_id,
+ GValue **info,
+ GError **error);
+static gboolean gmyth_dbus_server_file_exists (GObject *obj,
+ const gchar *file_name,
+ gboolean *exists,
+ GError **error);
+static gboolean gmyth_dbus_server_get_recorded_list (GObject *obj,
+ GPtrArray **channels,
+ GError **error);
+static gboolean gmyth_dbus_server_get_recorded_info (GObject *obj,
+ const gchar *basename,
+ GValue **info,
+ GError **error);
+static gboolean gmyth_dbus_server_get_program_list (GObject *obj,
+ gint channel_id,
+ const gchar *start_time,
+ const gchar *end_time,
+ GPtrArray **program_list);
+static gboolean gmyth_dbus_server_get_schedule_list (GObject *obj,
+ GPtrArray **schedule_list);
+
+static gboolean gmyth_dbus_server_connected (GObject *obj,
+ gboolean *status,
+ GError **error);
+static gboolean gmyth_dbus_server_disconnect (GObject *obj,
+ GError **error);
+static gboolean gmyth_dbus_server_get_server_info (GObject *obj,
+ guint64 *total_space,
+ guint64 *used_space,
+ guint64 *free_space,
+ GError **error);
+static gboolean gmyth_dbus_server_get_thumbnail (GObject *obj,
+ const gchar *uri,
+ GByteArray **image,
+ GError **error);
+static gboolean gmyth_dbus_server_get_channel_icon (GObject *obj,
+ guint channel_id,
+ GByteArray **icon,
+ GError **error);
+static gboolean gmyth_dbus_server_stop_recording (GObject *obj,
+ guint channel_id,
+ gboolean *result,
+ GError **error);
+static gboolean gmyth_dbus_server_add_schedule (GObject *obj,
+ guint channel_id,
+ guint program_id,
+ const gchar *start_time,
+ const gchar *end_time,
+ gboolean recurring,
+ const gchar *description,
+ guint *schedule_id,
+ GError **error);
+static gboolean gmyth_dbus_server_add_exception (GObject *obj,
+ guint schedule_id,
+ guint channel_id,
+ guint program_id,
+ const gchar *start_time,
+ const gchar *end_time,
+ const gchar *description,
+ GError **error);
+static gboolean gmyth_dbus_server_remove_schedule (GObject *obj,
+ guint schedule_id,
+ GError **error);
+
+
+#include "gmyth-dbus-server-glue.h"
+
+
+G_DEFINE_TYPE (GMythDbusServer, gmyth_dbus_server, G_TYPE_OBJECT);
+
+static void
+gmyth_dbus_server_class_init (GMythDbusServerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GMythDbusServerPrivate));
+
+ object_class->dispose = gmyth_dbus_server_dispose;
+ object_class->finalize = gmyth_dbus_server_finalize;
+
+ dbus_g_object_type_install_info (GMYTH_DBUS_SERVER_TYPE,
+ &dbus_glib_gmyth_dbus_server_object_info);
+}
+
+static void
+gmyth_dbus_server_init (GMythDbusServer *self)
+{
+}
+
+static void
+gmyth_dbus_server_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (gmyth_dbus_server_parent_class)->dispose (object);
+}
+
+static void
+gmyth_dbus_server_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (gmyth_dbus_server_parent_class)->finalize (object);
+}
+
+static gboolean
+gmyth_dbus_server_connect_epg (GMythDbusServer *server)
+{
+ GMythDbusServerPrivate *priv;
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (server);
+
+ if (!priv->myth_epg)
+ {
+ priv->myth_epg = gmyth_epg_new();
+ if (!gmyth_epg_connect (priv->myth_epg, priv->myth_backend))
+ {
+ g_object_unref (priv->myth_epg);
+ priv->myth_epg = NULL;
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
+gmyth_dbus_server_connect_scheduler (GMythDbusServer *server)
+{
+ GMythDbusServerPrivate *priv;
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (server);
+
+ if (!priv->myth_scheduler)
+ {
+ priv->myth_scheduler = gmyth_scheduler_new ();
+ if (!gmyth_scheduler_connect (priv->myth_scheduler,
+ priv->myth_backend))
+ {
+ g_object_unref (priv->myth_scheduler);
+ priv->myth_scheduler = NULL;
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
+gmyth_dbus_server_connect (GObject *obj,
+ const gchar *host,
+ guint port,
+ const gchar *user,
+ const gchar *password,
+ gboolean *result,
+ GError **error)
+{
+ GMythDbusServerPrivate *priv;
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ if (priv->myth_backend)
+ return TRUE;
+
+ priv->myth_backend = gmyth_backend_info_new_full (host,
+ user,
+ password,
+ MYTH_DEFAULT_DB,
+ port);
+ *result = TRUE;
+ return TRUE;
+}
+
+static gboolean
+gmyth_dbus_server_connected (GObject *obj,
+ gboolean *status,
+ GError **error)
+{
+ GMythDbusServerPrivate *priv;
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ if (priv->myth_backend)
+ *status = TRUE;
+ else
+ *status = FALSE;
+ return TRUE;
+}
+
+static gboolean
+gmyth_dbus_server_disconnect (GObject *obj,
+ GError **error)
+{
+ GMythDbusServerPrivate *priv;
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ if (priv->myth_epg)
+ {
+ g_object_unref (priv->myth_epg);
+ priv->myth_epg = NULL;
+ }
+
+
+ if (priv->myth_backend)
+ {
+ g_object_unref (priv->myth_backend);
+ priv->myth_backend = NULL;
+ }
+
+ if (priv->myth_scheduler)
+ {
+ g_object_unref (priv->myth_scheduler);
+ priv->myth_scheduler = NULL;
+ }
+
+
+ return TRUE;
+}
+
+static gboolean
+gmyth_dbus_server_get_server_info (GObject *obj,
+ guint64 *total_space,
+ guint64 *used_space,
+ guint64 *free_space,
+ GError **error)
+{
+ GMythBackendDetails *details;
+ GMythDbusServerPrivate *priv;
+ gboolean ret = FALSE;
+ GMythSocket *socket;
+
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ g_return_val_if_fail (priv->myth_backend != NULL, FALSE);
+
+ socket = gmyth_backend_info_get_connected_socket (priv->myth_backend);
+
+ details = NULL;
+ gmyth_util_get_backend_details (socket,
+ &details);
+ if (details)
+ {
+ *total_space = details->total_space;
+ *used_space = details->used_space;
+ *free_space = *total_space - *used_space;
+ gmyth_util_backend_details_free (details);
+
+ ret = TRUE;
+ }
+
+ g_object_unref (socket);
+
+ return ret;
+}
+
+
+static void
+gmyth_dbus_server_parse_channel_info (GMythChannelInfo *info,
+ GValue *val)
+{
+ dbus_g_type_struct_set (val,
+ 0, info->channel_ID,
+ 1, info->channel_num->str,
+ 2, info->channel_name->str,
+ 3, info->channel_icon->str,
+ G_MAXUINT);
+}
+
+static gboolean
+gmyth_dbus_server_get_channel_info (GObject *obj,
+ gint channel_id,
+ GValue **info,
+ GError **error)
+{
+ GType ch_type;
+ GMythChannelInfo *ch_info;
+ GMythDbusServerPrivate *priv;
+
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ g_return_val_if_fail (priv->myth_backend != NULL, FALSE);
+ g_return_val_if_fail (gmyth_dbus_server_connect_epg (GMYTH_DBUS_SERVER (obj)), FALSE);
+
+ ch_type = GMYTH_DBUS_CHANNEL_G_TYPE;
+
+ ch_info = gmyth_epg_get_channel_info (priv->myth_epg, channel_id);
+ if (ch_info)
+ {
+ *info = g_new0 (GValue, 1);
+ g_value_init (*info, ch_type);
+ g_value_set_static_boxed (*info, dbus_g_type_specialized_construct (ch_type));
+ gmyth_dbus_server_parse_channel_info (ch_info, *info);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static gboolean
+gmyth_dbus_server_get_channel_list (GObject *obj,
+ GPtrArray **channels,
+ GError **error)
+{
+ GList *lst;
+ GList *walk;
+ int len;
+ GType ch_type;
+ GMythDbusServerPrivate *priv;
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ g_return_val_if_fail (priv->myth_backend != NULL, FALSE);
+ g_return_val_if_fail (gmyth_dbus_server_connect_epg (GMYTH_DBUS_SERVER (obj)), FALSE);
+
+
+ len = gmyth_epg_get_channel_list (priv->myth_epg, &lst);
+
+ *channels = g_ptr_array_sized_new (len);
+ ch_type = GMYTH_DBUS_CHANNEL_G_TYPE;
+
+ for (walk = lst; walk != NULL; walk = walk->next)
+ {
+ GValue ch = { 0, };
+ GMythChannelInfo *data;
+
+ data = (GMythChannelInfo *) walk->data;
+
+ g_value_init (&ch, ch_type);
+ g_value_set_static_boxed (&ch, dbus_g_type_specialized_construct (ch_type));
+ gmyth_dbus_server_parse_channel_info (data, &ch);
+ g_ptr_array_add (*channels, g_value_get_boxed (&ch));
+ }
+
+ gmyth_free_channel_list (lst);
+ return TRUE;
+}
+
+static gboolean
+gmyth_dbus_server_file_exists (GObject *obj,
+ const gchar *file_name,
+ gboolean *exists,
+ GError **error)
+{
+ GMythDbusServerPrivate *priv;
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ g_return_val_if_fail (priv->myth_backend, FALSE);
+
+ *exists = gmyth_util_file_exists (priv->myth_backend, file_name);
+
+ return TRUE;
+}
+
+static gboolean
+gmyth_dbus_server_get_program_list (GObject *obj,
+ gint program_id,
+ const gchar *start_time,
+ const gchar *end_time,
+ GPtrArray **programs)
+{
+ GList *list;
+ GList *walk;
+ gint len;
+ GType program_type;
+ GTimeVal start_time_val;
+ GTimeVal end_time_val;
+ GMythDbusServerPrivate *priv;
+
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ g_return_val_if_fail (priv->myth_backend, FALSE);
+ g_return_val_if_fail (gmyth_dbus_server_connect_epg (GMYTH_DBUS_SERVER (obj)), FALSE);
+
+
+ g_time_val_from_iso8601 (start_time, &start_time_val);
+ g_time_val_from_iso8601 (end_time, &end_time_val);
+
+ len = gmyth_epg_get_program_list (priv->myth_epg,
+ &list,
+ program_id,
+ &start_time_val,
+ &end_time_val);
+
+ *programs = g_ptr_array_sized_new (len);
+ program_type = GMYTH_DBUS_PROGRAM_G_TYPE;
+
+ for (walk = list; walk != NULL; walk = walk->next)
+ {
+ GValue program = { 0, };
+ gchar *start_str;
+ gchar *end_str;
+ GMythProgramInfo *data;
+
+ data = (GMythProgramInfo *) walk->data;
+
+ g_value_init (&program, program_type);
+ g_value_set_static_boxed (&program,
+ dbus_g_type_specialized_construct (program_type));
+
+ start_str = g_time_val_to_iso8601 (data->startts);
+ end_str = g_time_val_to_iso8601 (data->endts);
+
+ dbus_g_type_struct_set (&program,
+ 0, data->chanid,
+ 1, start_str,
+ 2, end_str,
+ 3, data->title->str,
+ 4, data->subtitle->str,
+ 5, data->description->str,
+ 6, data->category->str,
+ G_MAXUINT);
+
+ g_ptr_array_add (*programs, g_value_get_boxed (&program));
+ g_free (start_str);
+ g_free (end_str);
+ }
+
+ gmyth_free_program_list (list);
+
+ return TRUE;
+}
+
+static void
+gmyth_dbus_server_parse_recorded_info (RecordedInfo *info,
+ GValue *val)
+{
+ gchar *start_str;
+ gchar *end_str;
+
+ start_str = g_time_val_to_iso8601 (info->start_time);
+ end_str = g_time_val_to_iso8601 (info->end_time);
+ dbus_g_type_struct_set (val,
+ 0, info->record_id,
+ 1, info->program_id,
+ 2, info->channel_id,
+ 3, start_str,
+ 4, end_str,
+ 5, info->title->str,
+ 6, info->subtitle->str,
+ 7, info->description->str,
+ 8, info->category->str,
+ 9, info->basename->str,
+ 10, info->filesize,
+ G_MAXUINT);
+
+ g_free (start_str);
+ g_free (end_str);
+}
+
+static gboolean
+gmyth_dbus_server_get_recorded_info (GObject *obj,
+ const gchar *basename,
+ GValue **info,
+ GError **error)
+{
+ GType record_type;
+ GMythDbusServerPrivate *priv;
+ RecordedInfo *record_info;
+
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ g_return_val_if_fail (priv->myth_backend, FALSE);
+ g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
+
+ record_type = GMYTH_DBUS_RECORD_G_TYPE;
+
+ record_info = gmyth_scheduler_get_recorded_info (priv->myth_scheduler,
+ basename);
+
+ if (record_info)
+ {
+ *info = g_new0 (GValue, 1);
+ g_value_init (*info, record_type);
+ g_value_set_static_boxed (*info,
+ dbus_g_type_specialized_construct (record_type));
+ gmyth_dbus_server_parse_recorded_info (record_info, *info);
+
+ gmyth_recorded_info_free (record_info);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static gboolean
+gmyth_dbus_server_get_recorded_list (GObject *obj,
+ GPtrArray **records,
+ GError **error)
+{
+ GList *list;
+ GList *walk;
+ gint len;
+ GType record_type;
+ GMythDbusServerPrivate *priv;
+
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ g_return_val_if_fail (priv->myth_backend, FALSE);
+ g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
+
+
+ len = gmyth_scheduler_get_recorded_list (priv->myth_scheduler,
+ &list);
+
+ *records = g_ptr_array_sized_new (len);
+ record_type = GMYTH_DBUS_RECORD_G_TYPE;
+
+ for (walk = list; walk != NULL; walk = walk->next)
+ {
+ GValue record = { 0, };
+ RecordedInfo *data;
+
+ data = (RecordedInfo *) walk->data;
+
+ g_value_init (&record, record_type);
+ g_value_set_static_boxed (&record,
+ dbus_g_type_specialized_construct (record_type));
+ gmyth_dbus_server_parse_recorded_info (data, &record);
+ g_ptr_array_add (*records, g_value_get_boxed (&record));
+ }
+
+ gmyth_recorded_info_list_free (list);
+
+ return TRUE;
+
+}
+
+static gboolean
+gmyth_dbus_server_get_schedule_list (GObject *obj,
+ GPtrArray **schedules)
+{
+ GList *list;
+ GList *walk;
+ gint len;
+ GType schedule_type;
+ GMythDbusServerPrivate *priv;
+
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ g_return_val_if_fail (priv->myth_backend, FALSE);
+ g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
+
+
+ len = gmyth_scheduler_get_schedule_list (priv->myth_scheduler,
+ &list);
+
+ *schedules = g_ptr_array_sized_new (len);
+ schedule_type = GMYTH_DBUS_SCHEDULE_G_TYPE;
+
+ for (walk = list; walk != NULL; walk = walk->next)
+ {
+ GValue schedule = { 0, };
+ ScheduleInfo *data;
+ gchar *start_str_time;
+ gchar *end_str_time;
+
+ data = (ScheduleInfo *) walk->data;
+
+ g_value_init (&schedule, schedule_type);
+ g_value_set_static_boxed (&schedule,
+ dbus_g_type_specialized_construct (schedule_type));
+
+ start_str_time = g_time_val_to_iso8601 (data->start_time);
+ end_str_time = g_time_val_to_iso8601 (data->end_time);
+
+ dbus_g_type_struct_set (&schedule,
+ 0, data->schedule_id,
+ 1, data->program_id,
+ 2, data->channel_id,
+ 3, start_str_time,
+ 4, end_str_time,
+ 5, data->title->str,
+ 6, data->subtitle->str,
+ 7, data->description->str,
+ 8, data->category->str,
+ 9, data->type,
+ G_MAXUINT);
+
+ g_ptr_array_add (*schedules, g_value_get_boxed (&schedule));
+
+ g_free (start_str_time);
+ g_free (end_str_time);
+ }
+
+ gmyth_schedule_info_list_free (list);
+
+ return TRUE;
+}
+
+
+static gboolean
+gmyth_dbus_server_get_thumbnail (GObject *obj,
+ const gchar *uri,
+ GByteArray **image,
+ GError **error)
+{
+ GMythFileTransfer *file_transfer;
+ glong filesize;
+ GMythFileReadResult result;
+ GMythDbusServerPrivate *priv;
+
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ g_return_val_if_fail (priv->myth_backend, FALSE);
+
+ if (!gmyth_util_file_exists (priv->myth_backend, uri))
+ goto fail;
+
+ file_transfer = gmyth_file_transfer_new (priv->myth_backend);
+
+ if (!gmyth_file_transfer_open (file_transfer, uri))
+ goto fail;
+
+ filesize = gmyth_file_transfer_get_filesize (file_transfer);
+ if (filesize <= 0)
+ goto fail;
+
+ *image = g_byte_array_new ();
+ result = gmyth_file_transfer_read (file_transfer, *image, filesize, FALSE);
+ if (result == GMYTH_FILE_READ_ERROR)
+ goto fail;
+
+ gmyth_file_transfer_close (file_transfer);
+ g_object_unref (file_transfer);
+
+ if (filesize > (*image)->len)
+ goto fail;
+
+ return TRUE;
+
+fail:
+ g_object_unref(file_transfer);
+ return FALSE;
+}
+
+static gboolean
+gmyth_dbus_server_get_channel_icon (GObject *obj,
+ guint channel_id,
+ GByteArray **icon,
+ GError **error)
+{
+ GMythChannelInfo *channel = NULL;
+ guint8 *icon_data;
+ guint icon_length;
+ GMythDbusServerPrivate *priv;
+
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+ g_return_val_if_fail (priv->myth_backend, FALSE);
+
+ channel = gmyth_epg_get_channel_info (priv->myth_epg,
+ (gint) channel_id);
+
+ *icon = NULL;
+
+ if (channel == NULL)
+ return FALSE;
+
+ if (!gmyth_epg_channel_has_icon(priv->myth_epg, channel))
+ {
+ gmyth_channel_info_free (channel);
+ g_debug("Channel does not have icon available");
+ return FALSE;
+ }
+
+ icon_data = NULL;
+ icon_length = 0;
+ if (!gmyth_epg_channel_get_icon (priv->myth_epg,
+ channel,
+ &icon_data,
+ &icon_length))
+ {
+ gmyth_channel_info_free (channel);
+ g_warning("Could not get channel icon for channel id = %u", channel_id);
+ return FALSE;
+ }
+
+ *icon = g_byte_array_sized_new (icon_length);
+ *icon = g_byte_array_append (*icon, icon_data, icon_length);
+
+ g_free (icon_data);
+ gmyth_channel_info_free(channel);
+ return TRUE;
+}
+
+
+static gboolean
+gmyth_dbus_server_stop_recording (GObject *obj,
+ guint channel_id,
+ gboolean *result,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GMythDbusServerPrivate *priv;
+
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ g_return_val_if_fail (priv->myth_backend, FALSE);
+ g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
+
+ ret = gmyth_scheduler_stop_recording (priv->myth_scheduler,
+ channel_id);
+
+ return ret;
+}
+
+static ScheduleInfo*
+gmyth_dbus_server_new_schedule_info (const gchar* description,
+ guint channel_id,
+ guint program_id,
+ GTimeVal *start_vtime,
+ GTimeVal *end_vtime)
+{
+ ScheduleInfo *new_sched_info;
+
+ new_sched_info = g_new0(ScheduleInfo, 1);
+
+ /* record_id == -1 for generating a new id */
+ new_sched_info->schedule_id = -1;
+
+ new_sched_info->channel_id = channel_id;
+ new_sched_info->program_id = program_id;
+ new_sched_info->start_time = g_new0 (GTimeVal, 1);
+ *new_sched_info->start_time = *start_vtime;
+ new_sched_info->end_time = g_new0 (GTimeVal, 1);
+ *new_sched_info->end_time = *end_vtime;
+
+ /* TODO: there is no frequency field */
+ /*new_sched_info->frequency = -1;*/
+
+ if (description != NULL) {
+ /* FIXME: description parameter is used as title and description */
+ new_sched_info->title = g_string_new(description);
+ new_sched_info->description = g_string_new(description);
+ }
+
+ return new_sched_info;
+}
+
+static gboolean
+gmyth_dbus_server_add_schedule (GObject *obj,
+ guint channel_id,
+ guint program_id,
+ const gchar *start_time,
+ const gchar *end_time,
+ gboolean recurring,
+ const gchar *description,
+ guint *schedule_id,
+ GError **error)
+{
+ ScheduleInfo *sch_info;
+ GTimeVal start_vtime;
+ GTimeVal end_vtime;
+ GMythDbusServerPrivate *priv;
+
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ *schedule_id = 0;
+
+ g_return_val_if_fail (priv->myth_backend, FALSE);
+ g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
+
+
+ g_time_val_from_iso8601 (start_time, &start_vtime);
+ g_time_val_from_iso8601 (end_time, &end_vtime);
+ sch_info = gmyth_dbus_server_new_schedule_info (description,
+ channel_id,
+ program_id,
+ &start_vtime,
+ &end_vtime);
+ if (sch_info != NULL) {
+ GMythScheduleType type;
+ GTimeVal t_now;
+ gboolean has_record;
+
+ type = (recurring ?
+ GMYTH_SCHEDULE_ALL_OCCURRENCES :
+ GMYTH_SCHEDULE_ONE_OCCURRENCE);
+
+ g_get_current_time (&t_now);
+
+ has_record = gmyth_scheduler_was_recorded_before (priv->myth_scheduler,
+ channel_id,
+ (time_t) start_vtime.tv_sec);
+
+
+ if ((t_now.tv_sec >= start_vtime.tv_sec)
+ && (t_now.tv_sec <= end_vtime.tv_sec) && has_record)
+ {
+ GMythSocket *socket;
+ gboolean res = FALSE;
+
+ socket = gmyth_backend_info_get_connected_socket (priv->myth_backend);
+ res = gmyth_scheduler_reactivate_schedule(priv->myth_scheduler,
+ channel_id,
+ (time_t) start_vtime.tv_sec);
+ if (res) {
+ GMythStringList *slist = gmyth_string_list_new();
+
+ gmyth_string_list_append_char_array(slist, "RESCHEDULE_RECORDINGS 0");
+ gmyth_socket_sendreceive_stringlist(socket, slist);
+ res = (gmyth_string_list_get_int(slist, 0) == 1);
+ g_object_unref(slist);
+ }
+
+ g_object_unref(socket);
+ return res;
+ }
+ else
+ {
+ if (!gmyth_scheduler_add_schedule_full (priv->myth_scheduler,
+ sch_info,
+ type))
+ {
+ g_warning("Could not add schedule entry");
+ return FALSE;
+ }
+
+ (*schedule_id) = sch_info->schedule_id;
+ gmyth_schedule_info_free (sch_info);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static gboolean
+gmyth_dbus_server_add_exception (GObject *obj,
+ guint schedule_id,
+ guint channel_id,
+ guint program_id,
+ const gchar *start_time,
+ const gchar *end_time,
+ const gchar *description,
+ GError **error)
+{
+ ScheduleInfo *sch_info;
+ GTimeVal start_vtime;
+ GTimeVal end_vtime;
+ GMythDbusServerPrivate *priv;
+
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ g_return_val_if_fail (priv->myth_backend, FALSE);
+ g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
+
+ g_time_val_from_iso8601 (start_time, &start_vtime);
+ g_time_val_from_iso8601 (end_time, &end_vtime);
+
+ sch_info = gmyth_dbus_server_new_schedule_info (description,
+ channel_id,
+ program_id,
+ &start_vtime,
+ &end_vtime);
+ if (sch_info != NULL)
+ {
+ if (!gmyth_scheduler_add_exception (priv->myth_scheduler,
+ schedule_id,
+ sch_info))
+ {
+ g_warning ("Could not add schedule exception");
+ gmyth_schedule_info_free (sch_info);
+ return FALSE;
+ }
+
+ gmyth_schedule_info_free (sch_info);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean
+gmyth_dbus_server_remove_schedule (GObject *obj,
+ guint schedule_id,
+ GError **error)
+{
+ GMythDbusServerPrivate *priv;
+
+ priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
+
+ g_return_val_if_fail (priv->myth_backend, FALSE);
+ g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
+
+ return gmyth_scheduler_delete_schedule (priv->myth_scheduler, schedule_id);
+}
+
+GMythDbusServer*
+gmyth_dbus_server_start_dbus_service (void)
+{
+ GError *error = NULL;
+ DBusGProxy *proxy;
+ DBusGConnection *bus;
+ guint request_ret;
+ GMythDbusServer *self;
+
+ self = g_object_new (GMYTH_DBUS_SERVER_TYPE, NULL);
+ g_return_val_if_fail (self, FALSE);
+
+ /* TODO: should verify if this service was already started */
+
+ /* connect to session bus */
+ bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (bus == NULL)
+ {
+ g_warning ("Could not connect to dbus: %s", error->message);
+ g_error_free (error);
+ goto fail;
+ }
+
+ /* register dbus object */
+ dbus_g_connection_register_g_object (bus,
+ GMYTH_DBUS_SERVER_PATH, G_OBJECT (self));
+
+ proxy = dbus_g_proxy_new_for_name (bus, DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+
+ /* registering download manager service */
+ if (!org_freedesktop_DBus_request_name (proxy, GMYTH_DBUS_SERVER_IFACE,
+ 0, &request_ret, &error))
+ {
+ g_warning ("Unable to register dbus service: %d %s",
+ error->code, error->message);
+ g_error_free (error);
+ goto fail;
+ }
+
+ if (request_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+ {
+ g_warning ("Got result code %u from requesting name", request_ret);
+ goto fail;
+ }
+
+ return self;
+
+fail:
+ g_object_unref (self);
+ return NULL;
+}
+