diff -r 000000000000 -r c91d9f4d142f gmyth-dbus/src/gmyth-dbus-server.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gmyth-dbus/src/gmyth-dbus-server.c Thu Oct 25 18:43:23 2007 +0100 @@ -0,0 +1,1029 @@ +/** + * GMyth Library + * + * 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, + GValueArray **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, + GValueArray **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; + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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, + GValueArray **info, + GError **error) +{ + GType ch_type; + GMythChannelInfo *ch_info; + GMythDbusServerPrivate *priv; + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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) + { + GValue v = { 0, }; + g_value_init (&v, ch_type); + g_value_take_boxed (&v, dbus_g_type_specialized_construct (ch_type)); + gmyth_dbus_server_parse_channel_info (ch_info, &v); + + *info = g_value_get_boxed (&v); + 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; + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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_take_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; + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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 channel_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; + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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); + + list = NULL; + len = gmyth_epg_get_program_list (priv->myth_epg, + &list, + channel_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; + + if (!data) + continue; + + g_value_init (&program, program_type); + g_value_take_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->str, + 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); + } + + if (list) + gmyth_free_program_list (list); + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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, + GValueArray **info, + GError **error) +{ + GType record_type; + GMythDbusServerPrivate *priv; + RecordedInfo *record_info; + + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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) + { + GValue r = { 0, }; + + g_value_init (&r, record_type); + g_value_take_boxed (&r, + dbus_g_type_specialized_construct (record_type)); + + gmyth_dbus_server_parse_recorded_info (record_info, &r); + gmyth_recorded_info_free (record_info); + + *info = g_value_get_boxed (&r); + + 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; + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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); + + record_type = GMYTH_DBUS_RECORD_G_TYPE; + *records = g_ptr_array_sized_new (len); + + 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_take_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)); + //g_value_unset (&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; + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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_take_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: + if (*image) + g_byte_array_free (*image, TRUE); + 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; + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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; + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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; + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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; + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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; + + g_debug ("%s:%d", __FUNCTION__, __LINE__); + 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; +} +