renatofilho@870: /** renatofilho@870: * GMyth Library renatofilho@870: * renatofilho@870: * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia. renatofilho@870: * @author Renato Filho renatofilho@870: * renatofilho@870: * renatofilho@870: * This program is free software; you can redistribute it and/or modify renatofilho@870: * it under the terms of the GNU Lesser General Public License as published by renatofilho@870: * the Free Software Foundation; either version 2 of the License, or renatofilho@870: * (at your option) any later version. renatofilho@870: * renatofilho@870: * This program is distributed in the hope that it will be useful, renatofilho@870: * but WITHOUT ANY WARRANTY; without even the implied warranty of renatofilho@870: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the renatofilho@870: * GNU General Public License for more details. renatofilho@870: * renatofilho@870: * You should have received a copy of the GNU Lesser General Public License renatofilho@870: * along with this program; if not, write to the Free Software renatofilho@870: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA renatofilho@870: */ renatofilho@870: renatofilho@870: renatofilho@870: #ifdef HAVE_CONFIG_H renatofilho@870: #include "config.h" renatofilho@870: #endif renatofilho@870: renatofilho@870: renatofilho@877: #include renatofilho@870: #include renatofilho@870: #include renatofilho@870: renatofilho@870: #include "gmyth-dbus-common.h" renatofilho@870: #include "gmyth-dbus-server.h" renatofilho@870: renatofilho@870: #define MYTH_DEFAULT_DB "mythconverg" renatofilho@870: renatofilho@877: enum renatofilho@877: { renatofilho@881: SHUTDOWN, renatofilho@878: LAST_SIGNAL renatofilho@878: }; renatofilho@878: renatofilho@878: enum renatofilho@878: { renatofilho@877: GMYTH_DBUS_ERROR_MYTHTV, renatofilho@877: GMYTH_DBUS_ERROR_CONNECTION, renatofilho@877: GMYTH_DBUS_ERROR_EPG, renatofilho@877: GMYTH_DBUS_ERROR_SCHEDULE renatofilho@877: }; renatofilho@877: renatofilho@877: #define GMYTH_DBUS_ERROR gmyth_dbus_error_quark () renatofilho@877: renatofilho@877: GQuark renatofilho@877: gmyth_dbus_error_quark (void) renatofilho@877: { renatofilho@877: return g_quark_from_static_string ("gmyth-dbus-error-quark"); renatofilho@877: } renatofilho@877: renatofilho@870: typedef struct _GMythDbusServerPrivate GMythDbusServerPrivate; renatofilho@870: renatofilho@870: struct _GMythDbusServerPrivate renatofilho@870: { renatofilho@870: GMythBackendInfo *myth_backend; renatofilho@874: gboolean connected; renatofilho@870: GMythEPG *myth_epg; renatofilho@870: GMythScheduler *myth_scheduler; renatofilho@881: renatofilho@881: guint shutdown_cb_id; renatofilho@870: }; renatofilho@870: renatofilho@870: #define GMYTH_DBUS_SERVER_GET_PRIVATE(o) \ renatofilho@870: (G_TYPE_INSTANCE_GET_PRIVATE ((o), GMYTH_DBUS_SERVER_TYPE, GMythDbusServerPrivate)) renatofilho@870: renatofilho@881: static void gmyth_dbus_server_class_init (GMythDbusServerClass *klass); renatofilho@881: static void gmyth_dbus_server_init (GMythDbusServer *self); renatofilho@881: static void gmyth_dbus_server_dispose (GObject *object); renatofilho@881: static void gmyth_dbus_server_finalize (GObject *object); renatofilho@881: static void gmyth_dbus_server_cancel_shutdown (GMythDbusServer *self); renatofilho@881: static gboolean gmyth_dbus_server_shutdown_cb (GMythDbusServer *self); renatofilho@870: renatofilho@870: /* Dbus */ renatofilho@870: static gboolean gmyth_dbus_server_connect (GObject *obj, renatofilho@870: const gchar *host, melunko@904: gint port, renatofilho@870: const gchar *user, renatofilho@870: const gchar *password, renatofilho@870: GError **error); melunko@912: static gboolean gmyth_dbus_server_check_db_connection (GObject *self, melunko@912: const gchar *host, melunko@912: gint port, melunko@912: const gchar *user, melunko@912: const gchar *password, melunko@912: GError **error); melunko@913: static gboolean melunko@913: gmyth_dbus_server_check_server_connection (GObject *obj, melunko@913: const gchar *host, melunko@913: gint port, melunko@913: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_get_channel_list (GObject *obj, renatofilho@870: GPtrArray **channels, renatofilho@870: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_get_channel_info (GObject *obj, renatofilho@870: gint channel_id, renatofilho@870: GValueArray **info, renatofilho@870: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_file_exists (GObject *obj, renatofilho@870: const gchar *file_name, renatofilho@870: gboolean *exists, renatofilho@870: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_get_recorded_list (GObject *obj, renatofilho@870: GPtrArray **channels, renatofilho@870: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_get_recorded_info (GObject *obj, renatofilho@870: const gchar *basename, renatofilho@870: GValueArray **info, renatofilho@870: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_get_program_list (GObject *obj, renatofilho@870: gint channel_id, renatofilho@870: const gchar *start_time, renatofilho@870: const gchar *end_time, renatofilho@877: GPtrArray **program_list, renatofilho@877: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_get_schedule_list (GObject *obj, renatofilho@877: GPtrArray **schedule_list, renatofilho@877: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_connected (GObject *obj, renatofilho@870: gboolean *status, renatofilho@870: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_disconnect (GObject *obj, renatofilho@870: GError **error); renatofilho@878: static void gmyth_dbus_server_internal_disconnect renatofilho@878: (GObject *obj, renatofilho@878: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_get_server_info (GObject *obj, renatofilho@870: guint64 *total_space, renatofilho@870: guint64 *used_space, renatofilho@870: guint64 *free_space, renatofilho@870: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_get_thumbnail (GObject *obj, renatofilho@870: const gchar *uri, renatofilho@870: GByteArray **image, renatofilho@870: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_get_channel_icon (GObject *obj, renatofilho@870: guint channel_id, renatofilho@870: GByteArray **icon, renatofilho@870: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_stop_recording (GObject *obj, renatofilho@870: guint channel_id, renatofilho@870: gboolean *result, renatofilho@870: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_add_schedule (GObject *obj, melunko@904: gint channel_id, renatofilho@891: const gchar *program_id, renatofilho@870: const gchar *start_time, renatofilho@870: const gchar *end_time, renatofilho@870: gboolean recurring, renatofilho@870: const gchar *description, renatofilho@870: guint *schedule_id, renatofilho@870: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_add_exception (GObject *obj, renatofilho@870: guint schedule_id, melunko@904: gint channel_id, renatofilho@891: const gchar *program_id, renatofilho@870: const gchar *start_time, renatofilho@870: const gchar *end_time, renatofilho@870: const gchar *description, renatofilho@870: GError **error); renatofilho@870: static gboolean gmyth_dbus_server_remove_schedule (GObject *obj, renatofilho@870: guint schedule_id, renatofilho@870: GError **error); renatofilho@870: renatofilho@870: renatofilho@870: #include "gmyth-dbus-server-glue.h" renatofilho@870: renatofilho@870: renatofilho@878: static guint signals[LAST_SIGNAL] = { 0 }; renatofilho@878: renatofilho@870: G_DEFINE_TYPE (GMythDbusServer, gmyth_dbus_server, G_TYPE_OBJECT); renatofilho@870: renatofilho@870: static void renatofilho@870: gmyth_dbus_server_class_init (GMythDbusServerClass *klass) renatofilho@870: { renatofilho@870: GObjectClass *object_class = G_OBJECT_CLASS (klass); renatofilho@870: renatofilho@870: g_type_class_add_private (klass, sizeof (GMythDbusServerPrivate)); renatofilho@870: renatofilho@870: object_class->dispose = gmyth_dbus_server_dispose; renatofilho@870: object_class->finalize = gmyth_dbus_server_finalize; renatofilho@870: renatofilho@881: signals[SHUTDOWN] = renatofilho@881: g_signal_new ("shutdown", renatofilho@878: G_OBJECT_CLASS_TYPE (object_class), renatofilho@878: G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, renatofilho@878: 0, renatofilho@878: NULL, NULL, renatofilho@878: g_cclosure_marshal_VOID__VOID, renatofilho@878: G_TYPE_NONE, 0, G_TYPE_NONE); renatofilho@878: renatofilho@870: dbus_g_object_type_install_info (GMYTH_DBUS_SERVER_TYPE, renatofilho@870: &dbus_glib_gmyth_dbus_server_object_info); renatofilho@870: } renatofilho@870: renatofilho@870: static void renatofilho@870: gmyth_dbus_server_init (GMythDbusServer *self) renatofilho@870: { renatofilho@870: } renatofilho@870: renatofilho@870: static void renatofilho@870: gmyth_dbus_server_dispose (GObject *object) renatofilho@870: { renatofilho@870: G_OBJECT_CLASS (gmyth_dbus_server_parent_class)->dispose (object); renatofilho@870: } renatofilho@870: renatofilho@870: static void renatofilho@870: gmyth_dbus_server_finalize (GObject *object) renatofilho@870: { renatofilho@870: G_OBJECT_CLASS (gmyth_dbus_server_parent_class)->finalize (object); renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@877: gmyth_dbus_server_connect_epg (GMythDbusServer *server, GError **error) renatofilho@870: { renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (server); renatofilho@870: renatofilho@874: if (!priv->connected) renatofilho@877: { renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_CONNECTION, renatofilho@877: _("Not connected")); renatofilho@877: renatofilho@891: gmyth_debug ("Not connected with MythTV Server"); renatofilho@874: return FALSE; renatofilho@877: } renatofilho@874: renatofilho@870: if (!priv->myth_epg) renatofilho@870: { renatofilho@870: priv->myth_epg = gmyth_epg_new(); renatofilho@870: if (!gmyth_epg_connect (priv->myth_epg, priv->myth_backend)) renatofilho@870: { renatofilho@870: g_object_unref (priv->myth_epg); renatofilho@870: priv->myth_epg = NULL; renatofilho@877: renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_EPG, renatofilho@877: _("Fail to connect with EPG")); renatofilho@891: gmyth_debug ("Fail to connected with EPG"); renatofilho@870: return FALSE; renatofilho@879: renatofilho@870: } renatofilho@870: } renatofilho@870: renatofilho@891: gmyth_debug ("Connected EPG"); renatofilho@870: return TRUE; renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@877: gmyth_dbus_server_connect_scheduler (GMythDbusServer *server, renatofilho@877: GError **error) renatofilho@870: { renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (server); renatofilho@870: renatofilho@874: if (!priv->connected) renatofilho@877: { renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_CONNECTION, renatofilho@877: _("Not connected")); renatofilho@877: renatofilho@891: gmyth_debug ("Not connected with MythTV Server"); renatofilho@874: return FALSE; renatofilho@877: } renatofilho@874: renatofilho@870: if (!priv->myth_scheduler) renatofilho@870: { renatofilho@870: priv->myth_scheduler = gmyth_scheduler_new (); renatofilho@870: if (!gmyth_scheduler_connect (priv->myth_scheduler, renatofilho@870: priv->myth_backend)) renatofilho@870: { renatofilho@870: g_object_unref (priv->myth_scheduler); renatofilho@870: priv->myth_scheduler = NULL; renatofilho@877: renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_SCHEDULE, renatofilho@877: _("Fail to connect with Schedule")); renatofilho@877: renatofilho@891: gmyth_debug (_("Fail to connect with Schedule")); renatofilho@870: return FALSE; renatofilho@870: } renatofilho@870: } renatofilho@870: renatofilho@891: gmyth_debug ("Connected with Schedule"); renatofilho@870: return TRUE; renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_connect (GObject *obj, renatofilho@870: const gchar *host, melunko@904: gint port, renatofilho@870: const gchar *user, renatofilho@870: const gchar *password, renatofilho@870: GError **error) renatofilho@870: { renatofilho@874: GMythSocket *s; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@873: renatofilho@873: renatofilho@891: gmyth_debug (""); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@877: if (priv->connected) renatofilho@876: { renatofilho@891: gmyth_debug ("Release Old connection"); renatofilho@879: gmyth_dbus_server_internal_disconnect (obj, NULL); renatofilho@876: } renatofilho@870: renatofilho@881: gmyth_dbus_server_cancel_shutdown (GMYTH_DBUS_SERVER (obj)); renatofilho@881: renatofilho@870: priv->myth_backend = gmyth_backend_info_new_full (host, renatofilho@870: user, renatofilho@870: password, renatofilho@870: MYTH_DEFAULT_DB, renatofilho@870: port); renatofilho@874: renatofilho@874: s = gmyth_backend_info_get_connected_socket (priv->myth_backend); renatofilho@874: if (s) renatofilho@874: { renatofilho@891: gmyth_debug ("Connected"); renatofilho@879: priv->connected = TRUE; renatofilho@874: g_object_unref (s); renatofilho@874: } renatofilho@874: else renatofilho@874: { renatofilho@891: gmyth_debug ("Fail to connect with MythTVServer"); renatofilho@879: priv->connected = FALSE; renatofilho@874: g_object_unref (priv->myth_backend); renatofilho@874: priv->myth_backend = NULL; renatofilho@877: renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_CONNECTION, renatofilho@877: _("Fail to connect with backend")); renatofilho@874: } renatofilho@874: renatofilho@879: return priv->connected; renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_connected (GObject *obj, renatofilho@870: gboolean *status, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@873: renatofilho@873: renatofilho@891: gmyth_debug (""); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: if (priv->myth_backend) renatofilho@870: *status = TRUE; renatofilho@870: else renatofilho@870: *status = FALSE; renatofilho@870: return TRUE; renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_disconnect (GObject *obj, renatofilho@870: GError **error) renatofilho@870: { renatofilho@879: GMythDbusServerPrivate *priv; renatofilho@878: renatofilho@879: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@879: if (priv->connected) renatofilho@879: { renatofilho@879: gmyth_dbus_server_internal_disconnect (obj, error); renatofilho@881: priv->shutdown_cb_id = g_timeout_add (60000, renatofilho@881: (GSourceFunc) gmyth_dbus_server_shutdown_cb, obj); renatofilho@879: } renatofilho@878: renatofilho@878: return TRUE; renatofilho@878: } renatofilho@878: renatofilho@878: static void renatofilho@878: gmyth_dbus_server_internal_disconnect (GObject *obj, renatofilho@878: GError **error) renatofilho@878: { renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@873: renatofilho@873: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@873: renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: if (priv->myth_epg) renatofilho@870: { renatofilho@870: g_object_unref (priv->myth_epg); renatofilho@870: priv->myth_epg = NULL; renatofilho@870: } renatofilho@870: renatofilho@870: renatofilho@870: if (priv->myth_backend) renatofilho@870: { renatofilho@870: g_object_unref (priv->myth_backend); renatofilho@870: priv->myth_backend = NULL; renatofilho@870: } renatofilho@870: renatofilho@870: if (priv->myth_scheduler) renatofilho@870: { renatofilho@870: g_object_unref (priv->myth_scheduler); renatofilho@870: priv->myth_scheduler = NULL; renatofilho@870: } renatofilho@879: renatofilho@879: priv->connected = FALSE; renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_get_server_info (GObject *obj, renatofilho@870: guint64 *total_space, renatofilho@870: guint64 *used_space, renatofilho@870: guint64 *free_space, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: GMythBackendDetails *details; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: gboolean ret = FALSE; renatofilho@870: GMythSocket *socket; renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: g_return_val_if_fail (priv->myth_backend != NULL, FALSE); renatofilho@870: renatofilho@870: socket = gmyth_backend_info_get_connected_socket (priv->myth_backend); renatofilho@870: renatofilho@877: if (!socket) renatofilho@877: { renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_MYTHTV, renatofilho@877: _("MythTv not avaliable")); renatofilho@877: return FALSE; renatofilho@877: renatofilho@877: } renatofilho@877: renatofilho@870: details = NULL; renatofilho@870: gmyth_util_get_backend_details (socket, renatofilho@870: &details); renatofilho@870: if (details) renatofilho@870: { renatofilho@870: *total_space = details->total_space; renatofilho@870: *used_space = details->used_space; renatofilho@870: *free_space = *total_space - *used_space; renatofilho@870: gmyth_util_backend_details_free (details); renatofilho@870: renatofilho@870: ret = TRUE; renatofilho@870: } renatofilho@877: else renatofilho@877: { renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_MYTHTV, renatofilho@877: _("Fail to get MythTv details")); renatofilho@879: } renatofilho@870: renatofilho@870: g_object_unref (socket); renatofilho@870: renatofilho@870: return ret; renatofilho@870: } renatofilho@870: renatofilho@870: renatofilho@870: static void renatofilho@870: gmyth_dbus_server_parse_channel_info (GMythChannelInfo *info, renatofilho@870: GValue *val) renatofilho@870: { renatofilho@870: dbus_g_type_struct_set (val, renatofilho@870: 0, info->channel_ID, renatofilho@870: 1, info->channel_num->str, renatofilho@870: 2, info->channel_name->str, renatofilho@870: 3, info->channel_icon->str, renatofilho@870: G_MAXUINT); renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_get_channel_info (GObject *obj, renatofilho@870: gint channel_id, renatofilho@870: GValueArray **info, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: GType ch_type; renatofilho@870: GMythChannelInfo *ch_info; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: g_return_val_if_fail (priv->myth_backend != NULL, FALSE); renatofilho@873: renatofilho@877: if (!gmyth_dbus_server_connect_epg (GMYTH_DBUS_SERVER (obj), error)) renatofilho@877: { renatofilho@873: return FALSE; renatofilho@877: } renatofilho@870: renatofilho@870: ch_type = GMYTH_DBUS_CHANNEL_G_TYPE; renatofilho@870: renatofilho@870: ch_info = gmyth_epg_get_channel_info (priv->myth_epg, channel_id); renatofilho@870: if (ch_info) renatofilho@870: { renatofilho@870: GValue v = { 0, }; renatofilho@870: g_value_init (&v, ch_type); renatofilho@870: g_value_take_boxed (&v, dbus_g_type_specialized_construct (ch_type)); renatofilho@870: gmyth_dbus_server_parse_channel_info (ch_info, &v); renatofilho@870: renatofilho@870: *info = g_value_get_boxed (&v); renatofilho@870: return TRUE; renatofilho@870: } renatofilho@877: else renatofilho@877: { renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_EPG, renatofilho@877: _("no channel info avaliable")); renatofilho@877: } renatofilho@870: renatofilho@870: return FALSE; renatofilho@870: } renatofilho@870: renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_get_channel_list (GObject *obj, renatofilho@870: GPtrArray **channels, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: GList *lst; renatofilho@870: GList *walk; renatofilho@870: int len; renatofilho@870: GType ch_type; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: g_return_val_if_fail (priv->myth_backend != NULL, FALSE); renatofilho@877: if (!gmyth_dbus_server_connect_epg (GMYTH_DBUS_SERVER (obj), error)) renatofilho@873: return FALSE; renatofilho@870: renatofilho@870: renatofilho@873: lst = NULL; renatofilho@870: len = gmyth_epg_get_channel_list (priv->myth_epg, &lst); renatofilho@870: renatofilho@870: *channels = g_ptr_array_sized_new (len); renatofilho@870: ch_type = GMYTH_DBUS_CHANNEL_G_TYPE; renatofilho@870: renatofilho@870: for (walk = lst; walk != NULL; walk = walk->next) renatofilho@870: { renatofilho@870: GValue ch = { 0, }; renatofilho@870: GMythChannelInfo *data; renatofilho@870: renatofilho@870: data = (GMythChannelInfo *) walk->data; renatofilho@870: renatofilho@870: g_value_init (&ch, ch_type); renatofilho@870: g_value_take_boxed (&ch, dbus_g_type_specialized_construct (ch_type)); renatofilho@870: gmyth_dbus_server_parse_channel_info (data, &ch); renatofilho@870: g_ptr_array_add (*channels, g_value_get_boxed (&ch)); renatofilho@870: } renatofilho@870: renatofilho@870: gmyth_free_channel_list (lst); renatofilho@870: return TRUE; renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_file_exists (GObject *obj, renatofilho@870: const gchar *file_name, renatofilho@870: gboolean *exists, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: g_return_val_if_fail (priv->myth_backend, FALSE); renatofilho@870: renatofilho@870: *exists = gmyth_util_file_exists (priv->myth_backend, file_name); renatofilho@870: renatofilho@870: return TRUE; renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_get_program_list (GObject *obj, renatofilho@870: gint channel_id, renatofilho@870: const gchar *start_time, renatofilho@870: const gchar *end_time, renatofilho@877: GPtrArray **programs, renatofilho@877: GError **error) renatofilho@870: { renatofilho@870: GList *list; renatofilho@870: GList *walk; renatofilho@870: gint len; renatofilho@870: GType program_type; renatofilho@870: GTimeVal start_time_val; renatofilho@870: GTimeVal end_time_val; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: g_return_val_if_fail (priv->myth_backend, FALSE); renatofilho@877: if (!gmyth_dbus_server_connect_epg (GMYTH_DBUS_SERVER (obj), error)) renatofilho@873: return FALSE; renatofilho@870: renatofilho@870: g_time_val_from_iso8601 (start_time, &start_time_val); renatofilho@870: g_time_val_from_iso8601 (end_time, &end_time_val); renatofilho@870: renatofilho@870: list = NULL; renatofilho@870: len = gmyth_epg_get_program_list (priv->myth_epg, renatofilho@870: &list, renatofilho@870: channel_id, renatofilho@870: &start_time_val, renatofilho@870: &end_time_val); renatofilho@870: renatofilho@870: *programs = g_ptr_array_sized_new (len); renatofilho@870: program_type = GMYTH_DBUS_PROGRAM_G_TYPE; renatofilho@870: renatofilho@870: for (walk = list; walk != NULL; walk = walk->next) renatofilho@870: { renatofilho@870: GValue program = { 0, }; renatofilho@870: gchar *start_str; renatofilho@870: gchar *end_str; renatofilho@870: GMythProgramInfo *data; renatofilho@870: renatofilho@870: data = (GMythProgramInfo *) walk->data; renatofilho@870: renatofilho@870: if (!data) renatofilho@870: continue; renatofilho@870: renatofilho@870: g_value_init (&program, program_type); renatofilho@870: g_value_take_boxed (&program, renatofilho@870: dbus_g_type_specialized_construct (program_type)); renatofilho@870: renatofilho@870: start_str = g_time_val_to_iso8601 (data->startts); renatofilho@870: end_str = g_time_val_to_iso8601 (data->endts); renatofilho@870: renatofilho@870: dbus_g_type_struct_set (&program, renatofilho@896: 0, data->channel_id, renatofilho@870: 1, start_str, renatofilho@870: 2, end_str, renatofilho@870: 3, data->title->str, renatofilho@870: 4, data->subtitle->str, renatofilho@870: 5, data->description->str, renatofilho@870: 6, data->category->str, renatofilho@870: G_MAXUINT); renatofilho@870: renatofilho@870: g_ptr_array_add (*programs, g_value_get_boxed (&program)); renatofilho@870: g_free (start_str); renatofilho@870: g_free (end_str); renatofilho@870: } renatofilho@870: renatofilho@870: if (list) renatofilho@870: gmyth_free_program_list (list); renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: return TRUE; renatofilho@870: } renatofilho@870: renatofilho@870: static void renatofilho@870: gmyth_dbus_server_parse_recorded_info (RecordedInfo *info, renatofilho@870: GValue *val) renatofilho@870: { renatofilho@870: gchar *start_str; renatofilho@870: gchar *end_str; renatofilho@870: renatofilho@870: start_str = g_time_val_to_iso8601 (info->start_time); renatofilho@870: end_str = g_time_val_to_iso8601 (info->end_time); renatofilho@870: renatofilho@870: dbus_g_type_struct_set (val, renatofilho@870: 0, info->record_id, renatofilho@896: 1, info->program_id->str, renatofilho@896: 2, info->channel_id, renatofilho@870: 3, start_str, renatofilho@870: 4, end_str, renatofilho@870: 5, info->title->str, renatofilho@870: 6, info->subtitle->str, renatofilho@870: 7, info->description->str, renatofilho@870: 8, info->category->str, renatofilho@870: 9, info->basename->str, renatofilho@870: 10, info->filesize, renatofilho@870: G_MAXUINT); renatofilho@870: g_free (start_str); renatofilho@870: g_free (end_str); renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_get_recorded_info (GObject *obj, renatofilho@870: const gchar *basename, renatofilho@870: GValueArray **info, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: GType record_type; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: RecordedInfo *record_info; renatofilho@870: renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: g_return_val_if_fail (priv->myth_backend, FALSE); renatofilho@873: renatofilho@877: if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj), error)) renatofilho@873: return FALSE; renatofilho@870: renatofilho@870: record_type = GMYTH_DBUS_RECORD_G_TYPE; renatofilho@870: renatofilho@870: record_info = gmyth_scheduler_get_recorded_info (priv->myth_scheduler, renatofilho@870: basename); renatofilho@870: renatofilho@870: if (record_info) renatofilho@870: { renatofilho@870: GValue r = { 0, }; renatofilho@870: renatofilho@870: g_value_init (&r, record_type); renatofilho@870: g_value_take_boxed (&r, renatofilho@870: dbus_g_type_specialized_construct (record_type)); renatofilho@870: renatofilho@870: gmyth_dbus_server_parse_recorded_info (record_info, &r); renatofilho@870: gmyth_recorded_info_free (record_info); renatofilho@870: renatofilho@870: *info = g_value_get_boxed (&r); renatofilho@870: renatofilho@870: return TRUE; renatofilho@870: } renatofilho@877: else renatofilho@877: { renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_EPG, renatofilho@877: _("no record info avaliable")); renatofilho@877: renatofilho@877: } renatofilho@870: renatofilho@870: return FALSE; renatofilho@870: } renatofilho@870: renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_get_recorded_list (GObject *obj, renatofilho@870: GPtrArray **records, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: GList *list; renatofilho@870: GList *walk; renatofilho@870: gint len; renatofilho@870: GType record_type; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@874: g_return_val_if_fail (priv->myth_backend != NULL, FALSE); renatofilho@877: if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj), error)) renatofilho@873: return FALSE; renatofilho@870: renatofilho@870: renatofilho@870: len = gmyth_scheduler_get_recorded_list (priv->myth_scheduler, renatofilho@870: &list); renatofilho@870: renatofilho@870: record_type = GMYTH_DBUS_RECORD_G_TYPE; renatofilho@870: *records = g_ptr_array_sized_new (len); renatofilho@870: renatofilho@870: for (walk = list; walk != NULL; walk = walk->next) renatofilho@870: { renatofilho@870: GValue record = { 0, }; renatofilho@870: RecordedInfo *data; renatofilho@870: renatofilho@870: data = (RecordedInfo *) walk->data; renatofilho@870: renatofilho@870: g_value_init (&record, record_type); renatofilho@870: g_value_take_boxed (&record, renatofilho@870: dbus_g_type_specialized_construct (record_type)); renatofilho@870: renatofilho@870: gmyth_dbus_server_parse_recorded_info (data, &record); renatofilho@870: renatofilho@870: g_ptr_array_add (*records, g_value_get_boxed (&record)); renatofilho@870: //g_value_unset (&record); renatofilho@870: } renatofilho@870: renatofilho@870: gmyth_recorded_info_list_free (list); renatofilho@870: renatofilho@870: return TRUE; renatofilho@870: renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_get_schedule_list (GObject *obj, renatofilho@877: GPtrArray **schedules, renatofilho@877: GError **error) renatofilho@870: { renatofilho@870: GList *list; renatofilho@870: GList *walk; renatofilho@870: gint len; renatofilho@870: GType schedule_type; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: g_return_val_if_fail (priv->myth_backend, FALSE); renatofilho@877: if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj), error)) renatofilho@873: return FALSE; renatofilho@870: renatofilho@870: renatofilho@870: len = gmyth_scheduler_get_schedule_list (priv->myth_scheduler, renatofilho@870: &list); renatofilho@870: renatofilho@870: *schedules = g_ptr_array_sized_new (len); renatofilho@870: schedule_type = GMYTH_DBUS_SCHEDULE_G_TYPE; renatofilho@870: renatofilho@870: for (walk = list; walk != NULL; walk = walk->next) renatofilho@870: { renatofilho@870: GValue schedule = { 0, }; renatofilho@870: ScheduleInfo *data; renatofilho@870: gchar *start_str_time; renatofilho@870: gchar *end_str_time; renatofilho@870: renatofilho@870: data = (ScheduleInfo *) walk->data; renatofilho@870: renatofilho@870: g_value_init (&schedule, schedule_type); renatofilho@870: g_value_take_boxed (&schedule, renatofilho@870: dbus_g_type_specialized_construct (schedule_type)); renatofilho@870: renatofilho@870: start_str_time = g_time_val_to_iso8601 (data->start_time); renatofilho@870: end_str_time = g_time_val_to_iso8601 (data->end_time); renatofilho@870: renatofilho@870: dbus_g_type_struct_set (&schedule, renatofilho@870: 0, data->schedule_id, renatofilho@896: 1, data->program_id->str, renatofilho@896: 2, data->channel_id, renatofilho@870: 3, start_str_time, renatofilho@870: 4, end_str_time, renatofilho@870: 5, data->title->str, renatofilho@870: 6, data->subtitle->str, renatofilho@870: 7, data->description->str, renatofilho@870: 8, data->category->str, renatofilho@870: 9, data->type, renatofilho@870: G_MAXUINT); renatofilho@870: renatofilho@870: g_ptr_array_add (*schedules, g_value_get_boxed (&schedule)); renatofilho@870: renatofilho@870: g_free (start_str_time); renatofilho@870: g_free (end_str_time); renatofilho@870: } renatofilho@870: renatofilho@870: gmyth_schedule_info_list_free (list); renatofilho@870: renatofilho@870: return TRUE; renatofilho@870: } renatofilho@870: renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_get_thumbnail (GObject *obj, renatofilho@870: const gchar *uri, renatofilho@870: GByteArray **image, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: GMythFileTransfer *file_transfer; renatofilho@870: glong filesize; renatofilho@870: GMythFileReadResult result; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@873: file_transfer = NULL; renatofilho@873: renatofilho@870: g_return_val_if_fail (priv->myth_backend, FALSE); renatofilho@870: renatofilho@870: if (!gmyth_util_file_exists (priv->myth_backend, uri)) renatofilho@877: { renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_MYTHTV, renatofilho@877: _("File not exists")); renatofilho@877: renatofilho@870: goto fail; renatofilho@877: } renatofilho@870: renatofilho@870: file_transfer = gmyth_file_transfer_new (priv->myth_backend); renatofilho@870: renatofilho@870: if (!gmyth_file_transfer_open (file_transfer, uri)) renatofilho@877: { renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_MYTHTV, renatofilho@877: _("Fail to open file")); renatofilho@870: goto fail; renatofilho@877: } renatofilho@870: renatofilho@870: filesize = gmyth_file_transfer_get_filesize (file_transfer); renatofilho@870: if (filesize <= 0) renatofilho@870: goto fail; renatofilho@870: renatofilho@870: *image = g_byte_array_new (); renatofilho@870: result = gmyth_file_transfer_read (file_transfer, *image, filesize, FALSE); renatofilho@870: if (result == GMYTH_FILE_READ_ERROR) renatofilho@877: { renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_MYTHTV, renatofilho@877: _("Fail to read file")); renatofilho@877: renatofilho@870: goto fail; renatofilho@877: } renatofilho@870: renatofilho@870: gmyth_file_transfer_close (file_transfer); renatofilho@870: g_object_unref (file_transfer); renatofilho@870: renatofilho@870: if (filesize > (*image)->len) renatofilho@877: { renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_MYTHTV, renatofilho@877: _("Empty file")); renatofilho@877: renatofilho@870: goto fail; renatofilho@877: } renatofilho@870: renatofilho@870: return TRUE; renatofilho@870: renatofilho@870: fail: renatofilho@870: if (*image) renatofilho@870: g_byte_array_free (*image, TRUE); renatofilho@870: g_object_unref(file_transfer); renatofilho@870: return FALSE; renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_get_channel_icon (GObject *obj, renatofilho@870: guint channel_id, renatofilho@870: GByteArray **icon, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: GMythChannelInfo *channel = NULL; renatofilho@870: guint8 *icon_data; renatofilho@870: guint icon_length; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: g_return_val_if_fail (priv->myth_backend, FALSE); renatofilho@870: renatofilho@870: channel = gmyth_epg_get_channel_info (priv->myth_epg, renatofilho@870: (gint) channel_id); renatofilho@870: renatofilho@870: *icon = NULL; renatofilho@870: renatofilho@870: if (channel == NULL) renatofilho@877: { renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_MYTHTV, renatofilho@877: _("Invalid channel")); renatofilho@877: renatofilho@870: return FALSE; renatofilho@877: } renatofilho@870: renatofilho@870: if (!gmyth_epg_channel_has_icon(priv->myth_epg, channel)) renatofilho@870: { renatofilho@870: gmyth_channel_info_free (channel); renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_MYTHTV, renatofilho@877: _("Channel does not have icon available")); renatofilho@877: renatofilho@870: return FALSE; renatofilho@870: } renatofilho@870: renatofilho@870: icon_data = NULL; renatofilho@870: icon_length = 0; renatofilho@870: if (!gmyth_epg_channel_get_icon (priv->myth_epg, renatofilho@870: channel, renatofilho@870: &icon_data, renatofilho@870: &icon_length)) renatofilho@870: { renatofilho@870: gmyth_channel_info_free (channel); renatofilho@877: g_set_error (error, renatofilho@877: GMYTH_DBUS_ERROR, renatofilho@877: GMYTH_DBUS_ERROR_MYTHTV, renatofilho@877: _("Could not get channel icon for channel id = %u"), renatofilho@877: channel_id); renatofilho@870: return FALSE; renatofilho@870: } renatofilho@870: renatofilho@870: *icon = g_byte_array_sized_new (icon_length); renatofilho@870: *icon = g_byte_array_append (*icon, icon_data, icon_length); renatofilho@870: renatofilho@870: g_free (icon_data); renatofilho@870: gmyth_channel_info_free(channel); renatofilho@870: return TRUE; renatofilho@870: } renatofilho@870: renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_stop_recording (GObject *obj, renatofilho@870: guint channel_id, renatofilho@870: gboolean *result, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: gboolean ret = FALSE; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: g_return_val_if_fail (priv->myth_backend, FALSE); renatofilho@877: if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj), error)) renatofilho@873: return FALSE; renatofilho@870: renatofilho@870: ret = gmyth_scheduler_stop_recording (priv->myth_scheduler, renatofilho@870: channel_id); renatofilho@870: renatofilho@870: return ret; renatofilho@870: } renatofilho@870: renatofilho@870: static ScheduleInfo* renatofilho@870: gmyth_dbus_server_new_schedule_info (const gchar* description, renatofilho@870: guint channel_id, renatofilho@891: const gchar* program_id, renatofilho@870: GTimeVal *start_vtime, renatofilho@870: GTimeVal *end_vtime) renatofilho@870: { renatofilho@870: ScheduleInfo *new_sched_info; renatofilho@870: renatofilho@870: new_sched_info = g_new0(ScheduleInfo, 1); renatofilho@870: renatofilho@870: /* record_id == -1 for generating a new id */ renatofilho@870: new_sched_info->schedule_id = -1; renatofilho@870: renatofilho@896: new_sched_info->channel_id = channel_id; renatofilho@896: new_sched_info->program_id = g_string_new (program_id); renatofilho@870: new_sched_info->start_time = g_new0 (GTimeVal, 1); renatofilho@870: *new_sched_info->start_time = *start_vtime; renatofilho@870: new_sched_info->end_time = g_new0 (GTimeVal, 1); renatofilho@870: *new_sched_info->end_time = *end_vtime; renatofilho@870: renatofilho@870: /* TODO: there is no frequency field */ renatofilho@870: /*new_sched_info->frequency = -1;*/ renatofilho@870: renatofilho@870: if (description != NULL) { renatofilho@870: /* FIXME: description parameter is used as title and description */ renatofilho@870: new_sched_info->title = g_string_new(description); renatofilho@870: new_sched_info->description = g_string_new(description); renatofilho@870: } renatofilho@870: renatofilho@870: return new_sched_info; renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_add_schedule (GObject *obj, melunko@904: gint channel_id, renatofilho@891: const gchar *program_id, renatofilho@870: const gchar *start_time, renatofilho@870: const gchar *end_time, renatofilho@870: gboolean recurring, renatofilho@870: const gchar *description, renatofilho@870: guint *schedule_id, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: ScheduleInfo *sch_info; renatofilho@870: GTimeVal start_vtime; renatofilho@870: GTimeVal end_vtime; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: *schedule_id = 0; renatofilho@870: renatofilho@870: g_return_val_if_fail (priv->myth_backend, FALSE); renatofilho@873: renatofilho@877: if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj), error)) renatofilho@873: return FALSE; renatofilho@870: renatofilho@870: renatofilho@870: g_time_val_from_iso8601 (start_time, &start_vtime); renatofilho@870: g_time_val_from_iso8601 (end_time, &end_vtime); melunko@904: renatofilho@870: sch_info = gmyth_dbus_server_new_schedule_info (description, renatofilho@870: channel_id, renatofilho@870: program_id, renatofilho@870: &start_vtime, renatofilho@870: &end_vtime); renatofilho@891: renatofilho@870: if (sch_info != NULL) { renatofilho@870: GMythScheduleType type; renatofilho@870: GTimeVal t_now; renatofilho@870: gboolean has_record; renatofilho@870: renatofilho@870: type = (recurring ? renatofilho@870: GMYTH_SCHEDULE_ALL_OCCURRENCES : renatofilho@870: GMYTH_SCHEDULE_ONE_OCCURRENCE); renatofilho@870: renatofilho@870: g_get_current_time (&t_now); renatofilho@870: renatofilho@870: has_record = gmyth_scheduler_was_recorded_before (priv->myth_scheduler, renatofilho@870: channel_id, renatofilho@870: (time_t) start_vtime.tv_sec); renatofilho@870: renatofilho@870: renatofilho@870: if ((t_now.tv_sec >= start_vtime.tv_sec) renatofilho@870: && (t_now.tv_sec <= end_vtime.tv_sec) && has_record) renatofilho@870: { renatofilho@870: GMythSocket *socket; renatofilho@870: gboolean res = FALSE; renatofilho@870: renatofilho@870: socket = gmyth_backend_info_get_connected_socket (priv->myth_backend); renatofilho@870: res = gmyth_scheduler_reactivate_schedule(priv->myth_scheduler, renatofilho@870: channel_id, renatofilho@870: (time_t) start_vtime.tv_sec); renatofilho@870: if (res) { renatofilho@870: GMythStringList *slist = gmyth_string_list_new(); renatofilho@870: renatofilho@870: gmyth_string_list_append_char_array(slist, "RESCHEDULE_RECORDINGS 0"); renatofilho@870: gmyth_socket_sendreceive_stringlist(socket, slist); renatofilho@870: res = (gmyth_string_list_get_int(slist, 0) == 1); renatofilho@870: g_object_unref(slist); renatofilho@870: } renatofilho@870: renatofilho@870: g_object_unref(socket); renatofilho@870: return res; renatofilho@870: } renatofilho@870: else renatofilho@870: { renatofilho@870: if (!gmyth_scheduler_add_schedule_full (priv->myth_scheduler, renatofilho@870: sch_info, renatofilho@870: type)) renatofilho@870: { renatofilho@870: g_warning("Could not add schedule entry"); renatofilho@870: return FALSE; renatofilho@870: } renatofilho@870: renatofilho@870: (*schedule_id) = sch_info->schedule_id; renatofilho@870: gmyth_schedule_info_free (sch_info); renatofilho@870: return TRUE; renatofilho@870: } renatofilho@870: } renatofilho@870: return FALSE; renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_add_exception (GObject *obj, renatofilho@870: guint schedule_id, melunko@904: gint channel_id, renatofilho@891: const gchar *program_id, renatofilho@870: const gchar *start_time, renatofilho@870: const gchar *end_time, renatofilho@870: const gchar *description, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: ScheduleInfo *sch_info; renatofilho@870: GTimeVal start_vtime; renatofilho@870: GTimeVal end_vtime; renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: g_return_val_if_fail (priv->myth_backend, FALSE); renatofilho@873: renatofilho@877: if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj), error)) renatofilho@873: return FALSE; renatofilho@870: renatofilho@870: g_time_val_from_iso8601 (start_time, &start_vtime); renatofilho@870: g_time_val_from_iso8601 (end_time, &end_vtime); renatofilho@870: renatofilho@870: sch_info = gmyth_dbus_server_new_schedule_info (description, renatofilho@870: channel_id, renatofilho@870: program_id, renatofilho@870: &start_vtime, renatofilho@870: &end_vtime); renatofilho@870: if (sch_info != NULL) renatofilho@870: { renatofilho@870: if (!gmyth_scheduler_add_exception (priv->myth_scheduler, renatofilho@870: schedule_id, renatofilho@870: sch_info)) renatofilho@870: { renatofilho@870: g_warning ("Could not add schedule exception"); renatofilho@870: gmyth_schedule_info_free (sch_info); renatofilho@870: return FALSE; renatofilho@870: } renatofilho@870: renatofilho@870: gmyth_schedule_info_free (sch_info); renatofilho@870: return TRUE; renatofilho@870: } renatofilho@870: return FALSE; renatofilho@870: } renatofilho@870: renatofilho@870: static gboolean renatofilho@870: gmyth_dbus_server_remove_schedule (GObject *obj, renatofilho@870: guint schedule_id, renatofilho@870: GError **error) renatofilho@870: { renatofilho@870: GMythDbusServerPrivate *priv; renatofilho@870: renatofilho@870: g_debug ("%s:%d", __FUNCTION__, __LINE__); renatofilho@870: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj); renatofilho@870: renatofilho@870: g_return_val_if_fail (priv->myth_backend, FALSE); renatofilho@873: renatofilho@877: if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj), error)) renatofilho@873: return FALSE; renatofilho@870: renatofilho@870: return gmyth_scheduler_delete_schedule (priv->myth_scheduler, schedule_id); renatofilho@870: } renatofilho@870: renatofilho@870: GMythDbusServer* renatofilho@870: gmyth_dbus_server_start_dbus_service (void) renatofilho@870: { renatofilho@870: GError *error = NULL; renatofilho@870: DBusGProxy *proxy; renatofilho@870: DBusGConnection *bus; renatofilho@870: guint request_ret; renatofilho@870: GMythDbusServer *self; renatofilho@870: renatofilho@870: self = g_object_new (GMYTH_DBUS_SERVER_TYPE, NULL); renatofilho@870: g_return_val_if_fail (self, FALSE); renatofilho@870: renatofilho@870: /* TODO: should verify if this service was already started */ renatofilho@870: renatofilho@870: /* connect to session bus */ renatofilho@870: bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); renatofilho@870: if (bus == NULL) renatofilho@870: { renatofilho@870: g_warning ("Could not connect to dbus: %s", error->message); renatofilho@870: g_error_free (error); renatofilho@870: goto fail; renatofilho@870: } renatofilho@870: renatofilho@870: /* register dbus object */ renatofilho@870: dbus_g_connection_register_g_object (bus, renatofilho@870: GMYTH_DBUS_SERVER_PATH, G_OBJECT (self)); renatofilho@870: renatofilho@870: proxy = dbus_g_proxy_new_for_name (bus, DBUS_SERVICE_DBUS, renatofilho@870: DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); renatofilho@870: renatofilho@870: /* registering download manager service */ renatofilho@870: if (!org_freedesktop_DBus_request_name (proxy, GMYTH_DBUS_SERVER_IFACE, renatofilho@870: 0, &request_ret, &error)) renatofilho@870: { renatofilho@870: g_warning ("Unable to register dbus service: %d %s", renatofilho@870: error->code, error->message); renatofilho@870: g_error_free (error); renatofilho@870: goto fail; renatofilho@870: } renatofilho@870: renatofilho@870: if (request_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) renatofilho@870: { renatofilho@870: g_warning ("Got result code %u from requesting name", request_ret); renatofilho@870: goto fail; renatofilho@870: } renatofilho@870: renatofilho@870: return self; renatofilho@870: renatofilho@870: fail: renatofilho@870: g_object_unref (self); renatofilho@870: return NULL; renatofilho@870: } renatofilho@870: renatofilho@881: renatofilho@881: static void renatofilho@881: gmyth_dbus_server_cancel_shutdown (GMythDbusServer *self) renatofilho@881: { renatofilho@881: GMythDbusServerPrivate *priv; renatofilho@881: renatofilho@881: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (self); renatofilho@881: renatofilho@881: if (priv->shutdown_cb_id) renatofilho@881: { renatofilho@881: g_source_remove (priv->shutdown_cb_id); renatofilho@881: priv->shutdown_cb_id = 0; renatofilho@881: } renatofilho@881: } renatofilho@881: renatofilho@881: static gboolean renatofilho@881: gmyth_dbus_server_shutdown_cb (GMythDbusServer *self) renatofilho@881: { renatofilho@881: GMythDbusServerPrivate *priv; renatofilho@881: renatofilho@881: priv = GMYTH_DBUS_SERVER_GET_PRIVATE (self); renatofilho@881: renatofilho@881: priv->shutdown_cb_id = 0; renatofilho@881: g_signal_emit (self, signals[SHUTDOWN], 0); renatofilho@881: return FALSE; renatofilho@881: } renatofilho@881: melunko@912: static gboolean melunko@912: gmyth_dbus_server_check_db_connection (GObject *obj, melunko@912: const gchar *host, melunko@912: gint port, melunko@912: const gchar *user, melunko@912: const gchar *password, melunko@912: GError **error) melunko@912: { melunko@912: GMythQuery *query = gmyth_query_new (); melunko@912: GMythBackendInfo *binfo; melunko@912: gboolean ret; melunko@912: melunko@912: gmyth_debug (""); melunko@912: melunko@912: binfo = gmyth_backend_info_new_full (host, user, password, MYTH_DEFAULT_DB, port); melunko@912: melunko@912: ret = gmyth_query_connect_with_timeout (query, binfo, 2 /*seconds*/); melunko@912: gmyth_query_disconnect (query); melunko@912: melunko@912: g_object_unref (query); melunko@912: g_object_unref (binfo); melunko@912: melunko@912: if (!ret) { melunko@912: g_set_error (error, GMYTH_DBUS_ERROR, GMYTH_DBUS_ERROR_CONNECTION, melunko@913: _("Fail to connect with backend database")); melunko@913: } melunko@913: melunko@913: return ret; melunko@913: } melunko@913: melunko@913: static gboolean melunko@913: gmyth_dbus_server_check_server_connection (GObject *obj, melunko@913: const gchar *host, melunko@913: gint port, melunko@913: GError **error) melunko@913: { melunko@913: GMythSocket *msocket = gmyth_socket_new (); melunko@913: gboolean ret; melunko@913: melunko@913: gmyth_debug (""); melunko@913: melunko@913: g_debug ("Checking server connection"); melunko@913: ret = gmyth_socket_connect_with_timeout (msocket, host, port, 2); melunko@913: g_debug ("Return %s", ret ? "ok" : "bad"); melunko@913: gmyth_socket_close_connection (msocket); melunko@913: melunko@913: g_object_unref (msocket); melunko@913: melunko@913: if (!ret) { melunko@913: g_set_error (error, GMYTH_DBUS_ERROR, GMYTH_DBUS_ERROR_CONNECTION, melunko@912: _("Fail to connect with backend")); melunko@912: } melunko@912: melunko@912: return ret; melunko@912: } melunko@912: