4 * @file gmyth/gmyth_backend_info.c
6 * @brief <p> This component represents all the MythTV backend server
7 * configuration information.
9 * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
10 * @author Renato Filho <renato.filho@indt.org.br>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include <gmyth/gmyth.h>
35 #include <dbus/dbus-glib-bindings.h>
38 #include "gmyth-dbus-common.h"
39 #include "gmyth-dbus-server.h"
41 #define MYTH_DEFAULT_DB "mythconverg"
44 typedef struct _GMythDbusServerPrivate GMythDbusServerPrivate;
46 struct _GMythDbusServerPrivate
48 GMythBackendInfo *myth_backend;
50 GMythScheduler *myth_scheduler;
53 #define GMYTH_DBUS_SERVER_GET_PRIVATE(o) \
54 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GMYTH_DBUS_SERVER_TYPE, GMythDbusServerPrivate))
56 static void gmyth_dbus_server_class_init (GMythDbusServerClass *klass);
57 static void gmyth_dbus_server_init (GMythDbusServer *self);
58 static void gmyth_dbus_server_dispose (GObject *object);
59 static void gmyth_dbus_server_finalize (GObject *object);
62 static gboolean gmyth_dbus_server_connect (GObject *obj,
66 const gchar *password,
69 static gboolean gmyth_dbus_server_get_channel_list (GObject *obj,
72 static gboolean gmyth_dbus_server_get_channel_info (GObject *obj,
76 static gboolean gmyth_dbus_server_file_exists (GObject *obj,
77 const gchar *file_name,
80 static gboolean gmyth_dbus_server_get_recorded_list (GObject *obj,
83 static gboolean gmyth_dbus_server_get_recorded_info (GObject *obj,
84 const gchar *basename,
87 static gboolean gmyth_dbus_server_get_program_list (GObject *obj,
89 const gchar *start_time,
90 const gchar *end_time,
91 GPtrArray **program_list);
92 static gboolean gmyth_dbus_server_get_schedule_list (GObject *obj,
93 GPtrArray **schedule_list);
95 static gboolean gmyth_dbus_server_connected (GObject *obj,
98 static gboolean gmyth_dbus_server_disconnect (GObject *obj,
100 static gboolean gmyth_dbus_server_get_server_info (GObject *obj,
101 guint64 *total_space,
105 static gboolean gmyth_dbus_server_get_thumbnail (GObject *obj,
109 static gboolean gmyth_dbus_server_get_channel_icon (GObject *obj,
113 static gboolean gmyth_dbus_server_stop_recording (GObject *obj,
117 static gboolean gmyth_dbus_server_add_schedule (GObject *obj,
120 const gchar *start_time,
121 const gchar *end_time,
123 const gchar *description,
126 static gboolean gmyth_dbus_server_add_exception (GObject *obj,
130 const gchar *start_time,
131 const gchar *end_time,
132 const gchar *description,
134 static gboolean gmyth_dbus_server_remove_schedule (GObject *obj,
139 #include "gmyth-dbus-server-glue.h"
142 G_DEFINE_TYPE (GMythDbusServer, gmyth_dbus_server, G_TYPE_OBJECT);
145 gmyth_dbus_server_class_init (GMythDbusServerClass *klass)
147 GObjectClass *object_class = G_OBJECT_CLASS (klass);
149 g_type_class_add_private (klass, sizeof (GMythDbusServerPrivate));
151 object_class->dispose = gmyth_dbus_server_dispose;
152 object_class->finalize = gmyth_dbus_server_finalize;
154 dbus_g_object_type_install_info (GMYTH_DBUS_SERVER_TYPE,
155 &dbus_glib_gmyth_dbus_server_object_info);
159 gmyth_dbus_server_init (GMythDbusServer *self)
164 gmyth_dbus_server_dispose (GObject *object)
166 G_OBJECT_CLASS (gmyth_dbus_server_parent_class)->dispose (object);
170 gmyth_dbus_server_finalize (GObject *object)
172 G_OBJECT_CLASS (gmyth_dbus_server_parent_class)->finalize (object);
176 gmyth_dbus_server_connect_epg (GMythDbusServer *server)
178 GMythDbusServerPrivate *priv;
179 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (server);
183 priv->myth_epg = gmyth_epg_new();
184 if (!gmyth_epg_connect (priv->myth_epg, priv->myth_backend))
186 g_object_unref (priv->myth_epg);
187 priv->myth_epg = NULL;
196 gmyth_dbus_server_connect_scheduler (GMythDbusServer *server)
198 GMythDbusServerPrivate *priv;
199 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (server);
201 if (!priv->myth_scheduler)
203 priv->myth_scheduler = gmyth_scheduler_new ();
204 if (!gmyth_scheduler_connect (priv->myth_scheduler,
207 g_object_unref (priv->myth_scheduler);
208 priv->myth_scheduler = NULL;
217 gmyth_dbus_server_connect (GObject *obj,
221 const gchar *password,
225 GMythDbusServerPrivate *priv;
226 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
228 if (priv->myth_backend)
231 priv->myth_backend = gmyth_backend_info_new_full (host,
241 gmyth_dbus_server_connected (GObject *obj,
245 GMythDbusServerPrivate *priv;
246 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
248 if (priv->myth_backend)
256 gmyth_dbus_server_disconnect (GObject *obj,
259 GMythDbusServerPrivate *priv;
260 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
264 g_object_unref (priv->myth_epg);
265 priv->myth_epg = NULL;
269 if (priv->myth_backend)
271 g_object_unref (priv->myth_backend);
272 priv->myth_backend = NULL;
275 if (priv->myth_scheduler)
277 g_object_unref (priv->myth_scheduler);
278 priv->myth_scheduler = NULL;
286 gmyth_dbus_server_get_server_info (GObject *obj,
287 guint64 *total_space,
292 GMythBackendDetails *details;
293 GMythDbusServerPrivate *priv;
294 gboolean ret = FALSE;
297 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
299 g_return_val_if_fail (priv->myth_backend != NULL, FALSE);
301 socket = gmyth_backend_info_get_connected_socket (priv->myth_backend);
304 gmyth_util_get_backend_details (socket,
308 *total_space = details->total_space;
309 *used_space = details->used_space;
310 *free_space = *total_space - *used_space;
311 gmyth_util_backend_details_free (details);
316 g_object_unref (socket);
323 gmyth_dbus_server_parse_channel_info (GMythChannelInfo *info,
326 dbus_g_type_struct_set (val,
328 1, info->channel_num->str,
329 2, info->channel_name->str,
330 3, info->channel_icon->str,
335 gmyth_dbus_server_get_channel_info (GObject *obj,
341 GMythChannelInfo *ch_info;
342 GMythDbusServerPrivate *priv;
344 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
346 g_return_val_if_fail (priv->myth_backend != NULL, FALSE);
347 g_return_val_if_fail (gmyth_dbus_server_connect_epg (GMYTH_DBUS_SERVER (obj)), FALSE);
349 ch_type = GMYTH_DBUS_CHANNEL_G_TYPE;
351 ch_info = gmyth_epg_get_channel_info (priv->myth_epg, channel_id);
354 *info = g_new0 (GValue, 1);
355 g_value_init (*info, ch_type);
356 g_value_set_static_boxed (*info, dbus_g_type_specialized_construct (ch_type));
357 gmyth_dbus_server_parse_channel_info (ch_info, *info);
366 gmyth_dbus_server_get_channel_list (GObject *obj,
367 GPtrArray **channels,
374 GMythDbusServerPrivate *priv;
375 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
377 g_return_val_if_fail (priv->myth_backend != NULL, FALSE);
378 g_return_val_if_fail (gmyth_dbus_server_connect_epg (GMYTH_DBUS_SERVER (obj)), FALSE);
381 len = gmyth_epg_get_channel_list (priv->myth_epg, &lst);
383 *channels = g_ptr_array_sized_new (len);
384 ch_type = GMYTH_DBUS_CHANNEL_G_TYPE;
386 for (walk = lst; walk != NULL; walk = walk->next)
389 GMythChannelInfo *data;
391 data = (GMythChannelInfo *) walk->data;
393 g_value_init (&ch, ch_type);
394 g_value_set_static_boxed (&ch, dbus_g_type_specialized_construct (ch_type));
395 gmyth_dbus_server_parse_channel_info (data, &ch);
396 g_ptr_array_add (*channels, g_value_get_boxed (&ch));
399 gmyth_free_channel_list (lst);
404 gmyth_dbus_server_file_exists (GObject *obj,
405 const gchar *file_name,
409 GMythDbusServerPrivate *priv;
410 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
412 g_return_val_if_fail (priv->myth_backend, FALSE);
414 *exists = gmyth_util_file_exists (priv->myth_backend, file_name);
420 gmyth_dbus_server_get_program_list (GObject *obj,
422 const gchar *start_time,
423 const gchar *end_time,
424 GPtrArray **programs)
430 GTimeVal start_time_val;
431 GTimeVal end_time_val;
432 GMythDbusServerPrivate *priv;
434 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
436 g_return_val_if_fail (priv->myth_backend, FALSE);
437 g_return_val_if_fail (gmyth_dbus_server_connect_epg (GMYTH_DBUS_SERVER (obj)), FALSE);
440 g_time_val_from_iso8601 (start_time, &start_time_val);
441 g_time_val_from_iso8601 (end_time, &end_time_val);
443 len = gmyth_epg_get_program_list (priv->myth_epg,
449 *programs = g_ptr_array_sized_new (len);
450 program_type = GMYTH_DBUS_PROGRAM_G_TYPE;
452 for (walk = list; walk != NULL; walk = walk->next)
454 GValue program = { 0, };
457 GMythProgramInfo *data;
459 data = (GMythProgramInfo *) walk->data;
461 g_value_init (&program, program_type);
462 g_value_set_static_boxed (&program,
463 dbus_g_type_specialized_construct (program_type));
465 start_str = g_time_val_to_iso8601 (data->startts);
466 end_str = g_time_val_to_iso8601 (data->endts);
468 dbus_g_type_struct_set (&program,
473 4, data->subtitle->str,
474 5, data->description->str,
475 6, data->category->str,
478 g_ptr_array_add (*programs, g_value_get_boxed (&program));
483 gmyth_free_program_list (list);
489 gmyth_dbus_server_parse_recorded_info (RecordedInfo *info,
495 start_str = g_time_val_to_iso8601 (info->start_time);
496 end_str = g_time_val_to_iso8601 (info->end_time);
497 dbus_g_type_struct_set (val,
504 6, info->subtitle->str,
505 7, info->description->str,
506 8, info->category->str,
507 9, info->basename->str,
516 gmyth_dbus_server_get_recorded_info (GObject *obj,
517 const gchar *basename,
522 GMythDbusServerPrivate *priv;
523 RecordedInfo *record_info;
525 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
527 g_return_val_if_fail (priv->myth_backend, FALSE);
528 g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
530 record_type = GMYTH_DBUS_RECORD_G_TYPE;
532 record_info = gmyth_scheduler_get_recorded_info (priv->myth_scheduler,
537 *info = g_new0 (GValue, 1);
538 g_value_init (*info, record_type);
539 g_value_set_static_boxed (*info,
540 dbus_g_type_specialized_construct (record_type));
541 gmyth_dbus_server_parse_recorded_info (record_info, *info);
543 gmyth_recorded_info_free (record_info);
553 gmyth_dbus_server_get_recorded_list (GObject *obj,
561 GMythDbusServerPrivate *priv;
563 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
565 g_return_val_if_fail (priv->myth_backend, FALSE);
566 g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
569 len = gmyth_scheduler_get_recorded_list (priv->myth_scheduler,
572 *records = g_ptr_array_sized_new (len);
573 record_type = GMYTH_DBUS_RECORD_G_TYPE;
575 for (walk = list; walk != NULL; walk = walk->next)
577 GValue record = { 0, };
580 data = (RecordedInfo *) walk->data;
582 g_value_init (&record, record_type);
583 g_value_set_static_boxed (&record,
584 dbus_g_type_specialized_construct (record_type));
585 gmyth_dbus_server_parse_recorded_info (data, &record);
586 g_ptr_array_add (*records, g_value_get_boxed (&record));
589 gmyth_recorded_info_list_free (list);
596 gmyth_dbus_server_get_schedule_list (GObject *obj,
597 GPtrArray **schedules)
603 GMythDbusServerPrivate *priv;
605 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
607 g_return_val_if_fail (priv->myth_backend, FALSE);
608 g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
611 len = gmyth_scheduler_get_schedule_list (priv->myth_scheduler,
614 *schedules = g_ptr_array_sized_new (len);
615 schedule_type = GMYTH_DBUS_SCHEDULE_G_TYPE;
617 for (walk = list; walk != NULL; walk = walk->next)
619 GValue schedule = { 0, };
621 gchar *start_str_time;
624 data = (ScheduleInfo *) walk->data;
626 g_value_init (&schedule, schedule_type);
627 g_value_set_static_boxed (&schedule,
628 dbus_g_type_specialized_construct (schedule_type));
630 start_str_time = g_time_val_to_iso8601 (data->start_time);
631 end_str_time = g_time_val_to_iso8601 (data->end_time);
633 dbus_g_type_struct_set (&schedule,
634 0, data->schedule_id,
640 6, data->subtitle->str,
641 7, data->description->str,
642 8, data->category->str,
646 g_ptr_array_add (*schedules, g_value_get_boxed (&schedule));
648 g_free (start_str_time);
649 g_free (end_str_time);
652 gmyth_schedule_info_list_free (list);
659 gmyth_dbus_server_get_thumbnail (GObject *obj,
664 GMythFileTransfer *file_transfer;
666 GMythFileReadResult result;
667 GMythDbusServerPrivate *priv;
669 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
671 g_return_val_if_fail (priv->myth_backend, FALSE);
673 if (!gmyth_util_file_exists (priv->myth_backend, uri))
676 file_transfer = gmyth_file_transfer_new (priv->myth_backend);
678 if (!gmyth_file_transfer_open (file_transfer, uri))
681 filesize = gmyth_file_transfer_get_filesize (file_transfer);
685 *image = g_byte_array_new ();
686 result = gmyth_file_transfer_read (file_transfer, *image, filesize, FALSE);
687 if (result == GMYTH_FILE_READ_ERROR)
690 gmyth_file_transfer_close (file_transfer);
691 g_object_unref (file_transfer);
693 if (filesize > (*image)->len)
699 g_object_unref(file_transfer);
704 gmyth_dbus_server_get_channel_icon (GObject *obj,
709 GMythChannelInfo *channel = NULL;
712 GMythDbusServerPrivate *priv;
714 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
715 g_return_val_if_fail (priv->myth_backend, FALSE);
717 channel = gmyth_epg_get_channel_info (priv->myth_epg,
725 if (!gmyth_epg_channel_has_icon(priv->myth_epg, channel))
727 gmyth_channel_info_free (channel);
728 g_debug("Channel does not have icon available");
734 if (!gmyth_epg_channel_get_icon (priv->myth_epg,
739 gmyth_channel_info_free (channel);
740 g_warning("Could not get channel icon for channel id = %u", channel_id);
744 *icon = g_byte_array_sized_new (icon_length);
745 *icon = g_byte_array_append (*icon, icon_data, icon_length);
748 gmyth_channel_info_free(channel);
754 gmyth_dbus_server_stop_recording (GObject *obj,
759 gboolean ret = FALSE;
760 GMythDbusServerPrivate *priv;
762 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
764 g_return_val_if_fail (priv->myth_backend, FALSE);
765 g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
767 ret = gmyth_scheduler_stop_recording (priv->myth_scheduler,
774 gmyth_dbus_server_new_schedule_info (const gchar* description,
777 GTimeVal *start_vtime,
780 ScheduleInfo *new_sched_info;
782 new_sched_info = g_new0(ScheduleInfo, 1);
784 /* record_id == -1 for generating a new id */
785 new_sched_info->schedule_id = -1;
787 new_sched_info->channel_id = channel_id;
788 new_sched_info->program_id = program_id;
789 new_sched_info->start_time = g_new0 (GTimeVal, 1);
790 *new_sched_info->start_time = *start_vtime;
791 new_sched_info->end_time = g_new0 (GTimeVal, 1);
792 *new_sched_info->end_time = *end_vtime;
794 /* TODO: there is no frequency field */
795 /*new_sched_info->frequency = -1;*/
797 if (description != NULL) {
798 /* FIXME: description parameter is used as title and description */
799 new_sched_info->title = g_string_new(description);
800 new_sched_info->description = g_string_new(description);
803 return new_sched_info;
807 gmyth_dbus_server_add_schedule (GObject *obj,
810 const gchar *start_time,
811 const gchar *end_time,
813 const gchar *description,
817 ScheduleInfo *sch_info;
818 GTimeVal start_vtime;
820 GMythDbusServerPrivate *priv;
822 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
826 g_return_val_if_fail (priv->myth_backend, FALSE);
827 g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
830 g_time_val_from_iso8601 (start_time, &start_vtime);
831 g_time_val_from_iso8601 (end_time, &end_vtime);
832 sch_info = gmyth_dbus_server_new_schedule_info (description,
837 if (sch_info != NULL) {
838 GMythScheduleType type;
843 GMYTH_SCHEDULE_ALL_OCCURRENCES :
844 GMYTH_SCHEDULE_ONE_OCCURRENCE);
846 g_get_current_time (&t_now);
848 has_record = gmyth_scheduler_was_recorded_before (priv->myth_scheduler,
850 (time_t) start_vtime.tv_sec);
853 if ((t_now.tv_sec >= start_vtime.tv_sec)
854 && (t_now.tv_sec <= end_vtime.tv_sec) && has_record)
857 gboolean res = FALSE;
859 socket = gmyth_backend_info_get_connected_socket (priv->myth_backend);
860 res = gmyth_scheduler_reactivate_schedule(priv->myth_scheduler,
862 (time_t) start_vtime.tv_sec);
864 GMythStringList *slist = gmyth_string_list_new();
866 gmyth_string_list_append_char_array(slist, "RESCHEDULE_RECORDINGS 0");
867 gmyth_socket_sendreceive_stringlist(socket, slist);
868 res = (gmyth_string_list_get_int(slist, 0) == 1);
869 g_object_unref(slist);
872 g_object_unref(socket);
877 if (!gmyth_scheduler_add_schedule_full (priv->myth_scheduler,
881 g_warning("Could not add schedule entry");
885 (*schedule_id) = sch_info->schedule_id;
886 gmyth_schedule_info_free (sch_info);
894 gmyth_dbus_server_add_exception (GObject *obj,
898 const gchar *start_time,
899 const gchar *end_time,
900 const gchar *description,
903 ScheduleInfo *sch_info;
904 GTimeVal start_vtime;
906 GMythDbusServerPrivate *priv;
908 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
910 g_return_val_if_fail (priv->myth_backend, FALSE);
911 g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
913 g_time_val_from_iso8601 (start_time, &start_vtime);
914 g_time_val_from_iso8601 (end_time, &end_vtime);
916 sch_info = gmyth_dbus_server_new_schedule_info (description,
921 if (sch_info != NULL)
923 if (!gmyth_scheduler_add_exception (priv->myth_scheduler,
927 g_warning ("Could not add schedule exception");
928 gmyth_schedule_info_free (sch_info);
932 gmyth_schedule_info_free (sch_info);
939 gmyth_dbus_server_remove_schedule (GObject *obj,
943 GMythDbusServerPrivate *priv;
945 priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
947 g_return_val_if_fail (priv->myth_backend, FALSE);
948 g_return_val_if_fail (gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)), FALSE);
950 return gmyth_scheduler_delete_schedule (priv->myth_scheduler, schedule_id);
954 gmyth_dbus_server_start_dbus_service (void)
956 GError *error = NULL;
958 DBusGConnection *bus;
960 GMythDbusServer *self;
962 self = g_object_new (GMYTH_DBUS_SERVER_TYPE, NULL);
963 g_return_val_if_fail (self, FALSE);
965 /* TODO: should verify if this service was already started */
967 /* connect to session bus */
968 bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
971 g_warning ("Could not connect to dbus: %s", error->message);
972 g_error_free (error);
976 /* register dbus object */
977 dbus_g_connection_register_g_object (bus,
978 GMYTH_DBUS_SERVER_PATH, G_OBJECT (self));
980 proxy = dbus_g_proxy_new_for_name (bus, DBUS_SERVICE_DBUS,
981 DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
983 /* registering download manager service */
984 if (!org_freedesktop_DBus_request_name (proxy, GMYTH_DBUS_SERVER_IFACE,
985 0, &request_ret, &error))
987 g_warning ("Unable to register dbus service: %d %s",
988 error->code, error->message);
989 g_error_free (error);
993 if (request_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
995 g_warning ("Got result code %u from requesting name", request_ret);
1002 g_object_unref (self);