gmyth-dbus/src/gmyth-dbus-server.c
author renatofilho
Thu Oct 25 22:08:12 2007 +0100 (2007-10-25)
branchtrunk
changeset 874 fc582534792b
parent 873 f580fba841bf
child 876 007c65343f31
permissions -rw-r--r--
[svn r880] fixed connection bug
     1 /**
     2  * GMyth Library
     3  *
     4  * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
     5  * @author Renato Filho  <renato.filho@indt.org.br>
     6  *
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU Lesser General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  *
    18  * You should have received a copy of the GNU Lesser General Public License
    19  * along with this program; if not, write to the Free Software
    20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    21  */
    22 
    23 
    24 #ifdef HAVE_CONFIG_H
    25 #include "config.h"
    26 #endif
    27 
    28 
    29 #include <gmyth/gmyth.h>
    30 #include <dbus/dbus-glib-bindings.h>
    31 
    32 
    33 #include "gmyth-dbus-common.h"
    34 #include "gmyth-dbus-server.h"
    35 
    36 #define MYTH_DEFAULT_DB             "mythconverg"
    37 
    38 typedef struct _GMythDbusServerPrivate GMythDbusServerPrivate;
    39 
    40 struct _GMythDbusServerPrivate
    41 {
    42     GMythBackendInfo *myth_backend;
    43     gboolean         connected;
    44     GMythEPG         *myth_epg;
    45     GMythScheduler   *myth_scheduler;
    46 };
    47 
    48 #define GMYTH_DBUS_SERVER_GET_PRIVATE(o) \
    49     (G_TYPE_INSTANCE_GET_PRIVATE ((o), GMYTH_DBUS_SERVER_TYPE, GMythDbusServerPrivate))
    50 
    51 static void gmyth_dbus_server_class_init (GMythDbusServerClass *klass);
    52 static void gmyth_dbus_server_init       (GMythDbusServer *self);
    53 static void gmyth_dbus_server_dispose    (GObject *object);
    54 static void gmyth_dbus_server_finalize   (GObject *object);
    55 
    56 /* Dbus */
    57 static gboolean gmyth_dbus_server_connect           (GObject *obj,
    58                                                      const gchar *host,
    59                                                      guint port,
    60                                                      const gchar *user,
    61                                                      const gchar *password,
    62                                                      gboolean *result,
    63                                                      GError **error);
    64 static gboolean gmyth_dbus_server_get_channel_list  (GObject *obj,
    65                                                      GPtrArray **channels,
    66                                                      GError **error);
    67 static gboolean gmyth_dbus_server_get_channel_info  (GObject *obj,
    68                                                      gint channel_id,
    69                                                      GValueArray **info,
    70                                                      GError **error);
    71 static gboolean gmyth_dbus_server_file_exists       (GObject *obj,
    72                                                      const gchar *file_name,
    73                                                      gboolean *exists,
    74                                                      GError **error);
    75 static gboolean gmyth_dbus_server_get_recorded_list (GObject *obj,
    76                                                      GPtrArray **channels,
    77                                                      GError **error);
    78 static gboolean gmyth_dbus_server_get_recorded_info (GObject *obj,
    79                                                      const gchar *basename,
    80                                                      GValueArray **info,
    81                                                      GError **error);
    82 static gboolean gmyth_dbus_server_get_program_list  (GObject *obj,
    83                                                      gint channel_id,
    84                                                      const gchar *start_time,
    85                                                      const gchar *end_time,
    86                                                      GPtrArray **program_list);
    87 static gboolean gmyth_dbus_server_get_schedule_list (GObject *obj,
    88                                                      GPtrArray **schedule_list);
    89 
    90 static gboolean gmyth_dbus_server_connected         (GObject *obj,
    91                                                      gboolean *status,
    92                                                      GError **error);
    93 static gboolean gmyth_dbus_server_disconnect        (GObject *obj,
    94                                                      GError **error);
    95 static gboolean gmyth_dbus_server_get_server_info   (GObject *obj,
    96                                                      guint64 *total_space,
    97                                                      guint64 *used_space,
    98                                                      guint64 *free_space,
    99                                                      GError **error);
   100 static gboolean gmyth_dbus_server_get_thumbnail     (GObject *obj,
   101                                                      const gchar *uri,
   102                                                      GByteArray **image,
   103                                                      GError **error);
   104 static gboolean gmyth_dbus_server_get_channel_icon  (GObject *obj,
   105                                                      guint channel_id,
   106                                                      GByteArray **icon,
   107                                                      GError **error);
   108 static gboolean gmyth_dbus_server_stop_recording    (GObject *obj,
   109                                                      guint channel_id,
   110                                                      gboolean *result,
   111                                                      GError **error);
   112 static gboolean gmyth_dbus_server_add_schedule      (GObject *obj,
   113                                                      guint channel_id,
   114                                                      guint program_id,
   115                                                      const gchar *start_time,
   116                                                      const gchar *end_time,
   117                                                      gboolean recurring,
   118                                                      const gchar *description,
   119                                                      guint *schedule_id,
   120                                                      GError **error);
   121 static gboolean gmyth_dbus_server_add_exception     (GObject *obj,
   122                                                      guint schedule_id,
   123                                                      guint channel_id,
   124                                                      guint program_id,
   125                                                      const gchar *start_time,
   126                                                      const gchar *end_time,
   127                                                      const gchar *description,
   128                                                      GError **error);
   129 static gboolean gmyth_dbus_server_remove_schedule   (GObject *obj,
   130                                                      guint schedule_id,
   131                                                      GError **error);
   132 
   133 
   134 #include "gmyth-dbus-server-glue.h"
   135 
   136 
   137 G_DEFINE_TYPE (GMythDbusServer, gmyth_dbus_server, G_TYPE_OBJECT);
   138 
   139 static void
   140 gmyth_dbus_server_class_init (GMythDbusServerClass *klass)
   141 {
   142     GObjectClass *object_class = G_OBJECT_CLASS (klass);
   143 
   144     g_type_class_add_private (klass, sizeof (GMythDbusServerPrivate));
   145 
   146     object_class->dispose = gmyth_dbus_server_dispose;
   147     object_class->finalize = gmyth_dbus_server_finalize;
   148 
   149     dbus_g_object_type_install_info (GMYTH_DBUS_SERVER_TYPE,
   150                                      &dbus_glib_gmyth_dbus_server_object_info);
   151 }
   152 
   153 static void
   154 gmyth_dbus_server_init (GMythDbusServer *self)
   155 {
   156 }
   157 
   158 static void
   159 gmyth_dbus_server_dispose (GObject *object)
   160 {
   161     G_OBJECT_CLASS (gmyth_dbus_server_parent_class)->dispose (object);
   162 }
   163 
   164 static void
   165 gmyth_dbus_server_finalize (GObject *object)
   166 {
   167     G_OBJECT_CLASS (gmyth_dbus_server_parent_class)->finalize (object);
   168 }
   169 
   170 static gboolean
   171 gmyth_dbus_server_connect_epg (GMythDbusServer *server)
   172 {
   173     GMythDbusServerPrivate *priv;
   174     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (server);
   175 
   176     if (!priv->connected)
   177         return FALSE;
   178 
   179     if (!priv->myth_epg)
   180     {
   181         priv->myth_epg = gmyth_epg_new();
   182         if (!gmyth_epg_connect (priv->myth_epg, priv->myth_backend))
   183         {
   184             g_object_unref (priv->myth_epg);
   185             priv->myth_epg = NULL;
   186             return FALSE;
   187         }
   188     }
   189 
   190     return TRUE;
   191 }
   192 
   193 static gboolean
   194 gmyth_dbus_server_connect_scheduler (GMythDbusServer *server)
   195 {
   196     GMythDbusServerPrivate *priv;
   197     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (server);
   198 
   199     if (!priv->connected)
   200         return FALSE;
   201 
   202     if (!priv->myth_scheduler)
   203     {
   204         priv->myth_scheduler = gmyth_scheduler_new ();
   205         if (!gmyth_scheduler_connect (priv->myth_scheduler,
   206                                       priv->myth_backend))
   207         {
   208             g_object_unref (priv->myth_scheduler);
   209             priv->myth_scheduler = NULL;
   210             return FALSE;
   211         }
   212     }
   213 
   214     return TRUE;
   215 }
   216 
   217 static gboolean
   218 gmyth_dbus_server_connect  (GObject *obj,
   219                             const gchar *host,
   220                             guint port,
   221                             const gchar *user,
   222                             const gchar *password,
   223                             gboolean *result,
   224                             GError **error)
   225 {
   226     GMythSocket *s;
   227     GMythDbusServerPrivate *priv;
   228 
   229     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   230 
   231     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   232 
   233     if (priv->myth_backend)
   234         return TRUE;
   235 
   236     priv->myth_backend = gmyth_backend_info_new_full (host,
   237                                                       user,
   238                                                       password,
   239                                                       MYTH_DEFAULT_DB,
   240                                                       port);
   241 
   242     s = gmyth_backend_info_get_connected_socket (priv->myth_backend);
   243     if (s)
   244     {
   245         g_object_unref (s);
   246         *result = TRUE;
   247     }
   248     else
   249     {
   250         g_debug ("FAIL TO CONNECT");
   251         g_object_unref (priv->myth_backend);
   252         priv->myth_backend = NULL;
   253         *result = FALSE;
   254     }
   255 
   256     priv->connected = *result;
   257     return *result;
   258 }
   259 
   260 static gboolean
   261 gmyth_dbus_server_connected (GObject *obj,
   262                              gboolean *status,
   263                              GError **error)
   264 {
   265     GMythDbusServerPrivate *priv;
   266 
   267     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   268 
   269     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   270 
   271     if (priv->myth_backend)
   272         *status = TRUE;
   273     else
   274         *status = FALSE;
   275     return TRUE;
   276 }
   277 
   278 static gboolean
   279 gmyth_dbus_server_disconnect (GObject *obj,
   280                               GError **error)
   281 {
   282     GMythDbusServerPrivate *priv;
   283 
   284     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   285 
   286     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   287 
   288     if (priv->myth_epg)
   289     {
   290         g_object_unref (priv->myth_epg);
   291         priv->myth_epg = NULL;
   292     }
   293 
   294 
   295     if (priv->myth_backend)
   296     {
   297         g_object_unref (priv->myth_backend);
   298         priv->myth_backend = NULL;
   299     }
   300 
   301     if (priv->myth_scheduler)
   302     {
   303         g_object_unref (priv->myth_scheduler);
   304         priv->myth_scheduler = NULL;
   305     }
   306 
   307 
   308     return TRUE;
   309 }
   310 
   311 static gboolean
   312 gmyth_dbus_server_get_server_info (GObject *obj,
   313                                    guint64 *total_space,
   314                                    guint64 *used_space,
   315                                    guint64 *free_space,
   316                                    GError **error)
   317 {
   318     GMythBackendDetails *details;
   319     GMythDbusServerPrivate *priv;
   320     gboolean ret = FALSE;
   321     GMythSocket *socket;
   322 
   323     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   324     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   325 
   326     g_return_val_if_fail (priv->myth_backend != NULL, FALSE);
   327 
   328     socket = gmyth_backend_info_get_connected_socket (priv->myth_backend);
   329 
   330     details = NULL;
   331     gmyth_util_get_backend_details (socket,
   332                                     &details);
   333     if (details)
   334     {
   335         *total_space = details->total_space;
   336         *used_space = details->used_space;
   337         *free_space = *total_space - *used_space;
   338         gmyth_util_backend_details_free (details);
   339 
   340         ret = TRUE;
   341     }
   342 
   343     g_object_unref (socket);
   344 
   345     return ret;
   346 }
   347 
   348 
   349 static void
   350 gmyth_dbus_server_parse_channel_info (GMythChannelInfo *info,
   351                                       GValue *val)
   352 {
   353     dbus_g_type_struct_set (val,
   354                             0, info->channel_ID,
   355                             1, info->channel_num->str,
   356                             2, info->channel_name->str,
   357                             3, info->channel_icon->str,
   358                             G_MAXUINT);
   359 }
   360 
   361 static gboolean 
   362 gmyth_dbus_server_get_channel_info  (GObject *obj,
   363                                      gint channel_id,
   364                                      GValueArray **info,
   365                                      GError **error)
   366 {
   367     GType ch_type;
   368     GMythChannelInfo *ch_info;
   369     GMythDbusServerPrivate *priv;
   370 
   371     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   372     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   373 
   374     g_return_val_if_fail (priv->myth_backend != NULL, FALSE);
   375 
   376     if (!gmyth_dbus_server_connect_epg (GMYTH_DBUS_SERVER (obj)))
   377         return FALSE;
   378 
   379     ch_type = GMYTH_DBUS_CHANNEL_G_TYPE;
   380 
   381     ch_info = gmyth_epg_get_channel_info (priv->myth_epg, channel_id);
   382     if (ch_info)
   383     {
   384         GValue v = { 0, };
   385         g_value_init (&v, ch_type);
   386         g_value_take_boxed (&v, dbus_g_type_specialized_construct (ch_type));
   387         gmyth_dbus_server_parse_channel_info (ch_info, &v);
   388 
   389         *info = g_value_get_boxed (&v);
   390         return TRUE;
   391     }
   392 
   393     return FALSE;
   394 }
   395 
   396 
   397 static gboolean
   398 gmyth_dbus_server_get_channel_list (GObject *obj,
   399                                     GPtrArray **channels,
   400                                     GError **error)
   401 {
   402     GList *lst;
   403     GList *walk;
   404     int len;
   405     GType ch_type;
   406     GMythDbusServerPrivate *priv;
   407 
   408     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   409     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   410 
   411     g_return_val_if_fail (priv->myth_backend != NULL, FALSE);
   412     if (!gmyth_dbus_server_connect_epg (GMYTH_DBUS_SERVER (obj)))
   413         return FALSE;
   414 
   415 
   416     lst = NULL;
   417     len = gmyth_epg_get_channel_list (priv->myth_epg, &lst);
   418 
   419     *channels = g_ptr_array_sized_new (len);
   420     ch_type = GMYTH_DBUS_CHANNEL_G_TYPE;
   421 
   422     for (walk = lst; walk != NULL; walk = walk->next)
   423     {
   424         GValue ch = { 0, };
   425         GMythChannelInfo *data;
   426 
   427         data = (GMythChannelInfo *) walk->data;
   428 
   429         g_value_init (&ch, ch_type);
   430         g_value_take_boxed (&ch, dbus_g_type_specialized_construct (ch_type));
   431         gmyth_dbus_server_parse_channel_info (data, &ch);
   432         g_ptr_array_add (*channels, g_value_get_boxed (&ch));
   433     }
   434 
   435     gmyth_free_channel_list (lst);
   436     return TRUE;
   437 }
   438 
   439 static gboolean
   440 gmyth_dbus_server_file_exists (GObject *obj,
   441                                const gchar *file_name,
   442                                gboolean *exists,
   443                                GError **error)
   444 {
   445     GMythDbusServerPrivate *priv;
   446     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   447     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   448 
   449     g_return_val_if_fail (priv->myth_backend, FALSE);
   450 
   451     *exists = gmyth_util_file_exists (priv->myth_backend, file_name);
   452 
   453     return TRUE;
   454 }
   455 
   456 static gboolean
   457 gmyth_dbus_server_get_program_list (GObject *obj,
   458                                     gint channel_id,
   459                                     const gchar *start_time,
   460                                     const gchar *end_time,
   461                                     GPtrArray **programs)
   462 {
   463     GList *list;
   464     GList *walk;
   465     gint len;
   466     GType program_type;
   467     GTimeVal start_time_val;
   468     GTimeVal end_time_val;
   469     GMythDbusServerPrivate *priv;
   470 
   471     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   472     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   473 
   474     g_return_val_if_fail (priv->myth_backend, FALSE);
   475     if (!gmyth_dbus_server_connect_epg (GMYTH_DBUS_SERVER (obj)))
   476         return FALSE;
   477 
   478     g_time_val_from_iso8601 (start_time, &start_time_val);
   479     g_time_val_from_iso8601 (end_time, &end_time_val);
   480 
   481     list = NULL;
   482     len = gmyth_epg_get_program_list (priv->myth_epg,
   483                                       &list,
   484                                       channel_id,
   485                                       &start_time_val,
   486                                       &end_time_val);
   487 
   488     *programs = g_ptr_array_sized_new (len);
   489     program_type = GMYTH_DBUS_PROGRAM_G_TYPE;
   490 
   491     for (walk = list; walk != NULL; walk = walk->next)
   492     {
   493         GValue program = { 0, };
   494         gchar *start_str;
   495         gchar *end_str;
   496         GMythProgramInfo *data;
   497 
   498         data = (GMythProgramInfo *) walk->data;
   499 
   500         if (!data)
   501             continue;
   502 
   503         g_value_init (&program, program_type);
   504         g_value_take_boxed (&program,
   505                             dbus_g_type_specialized_construct (program_type));
   506 
   507         start_str = g_time_val_to_iso8601 (data->startts);
   508         end_str = g_time_val_to_iso8601 (data->endts);
   509 
   510         dbus_g_type_struct_set (&program,
   511                                 0, data->chanid->str,
   512                                 1, start_str,
   513                                 2, end_str,
   514                                 3, data->title->str,
   515                                 4, data->subtitle->str,
   516                                 5, data->description->str,
   517                                 6, data->category->str,
   518                                 G_MAXUINT);
   519 
   520         g_ptr_array_add (*programs, g_value_get_boxed (&program));
   521         g_free (start_str);
   522         g_free (end_str);
   523     }
   524 
   525     if (list)
   526         gmyth_free_program_list (list);
   527 
   528     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   529     return TRUE;
   530 }
   531 
   532 static void
   533 gmyth_dbus_server_parse_recorded_info (RecordedInfo *info,
   534                                        GValue *val)
   535 {
   536     gchar *start_str;
   537     gchar *end_str;
   538 
   539     start_str = g_time_val_to_iso8601 (info->start_time);
   540     end_str = g_time_val_to_iso8601 (info->end_time);
   541 
   542     dbus_g_type_struct_set (val,
   543                             0, info->record_id,
   544                             1, info->program_id,
   545                             2, info->channel_id,
   546                             3, start_str,
   547                             4, end_str,
   548                             5, info->title->str,
   549                             6, info->subtitle->str,
   550                             7, info->description->str,
   551                             8, info->category->str,
   552                             9, info->basename->str,
   553                             10, info->filesize,
   554                             G_MAXUINT);
   555     g_free (start_str);
   556     g_free (end_str);
   557 }
   558 
   559 static gboolean
   560 gmyth_dbus_server_get_recorded_info (GObject *obj,
   561                                      const gchar *basename,
   562                                      GValueArray **info,
   563                                      GError **error)
   564 {
   565     GType record_type;
   566     GMythDbusServerPrivate *priv;
   567     RecordedInfo *record_info;
   568 
   569 
   570     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   571     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   572 
   573     g_return_val_if_fail (priv->myth_backend, FALSE);
   574 
   575     if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)))
   576         return FALSE;
   577 
   578     record_type = GMYTH_DBUS_RECORD_G_TYPE;
   579 
   580     record_info = gmyth_scheduler_get_recorded_info (priv->myth_scheduler,
   581                                                      basename);
   582 
   583     if (record_info)
   584     {
   585         GValue r = { 0, };
   586 
   587         g_value_init (&r, record_type);
   588         g_value_take_boxed (&r,
   589                             dbus_g_type_specialized_construct (record_type));
   590 
   591         gmyth_dbus_server_parse_recorded_info (record_info, &r);
   592         gmyth_recorded_info_free (record_info);
   593 
   594         *info = g_value_get_boxed (&r);
   595 
   596         return TRUE;
   597     }
   598 
   599     return FALSE;
   600 }
   601 
   602 
   603 static gboolean
   604 gmyth_dbus_server_get_recorded_list (GObject *obj,
   605                                      GPtrArray **records,
   606                                      GError **error)
   607 {
   608     GList *list;
   609     GList *walk;
   610     gint len;
   611     GType record_type;
   612     GMythDbusServerPrivate *priv;
   613 
   614     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   615     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   616 
   617     g_return_val_if_fail (priv->myth_backend != NULL, FALSE);
   618     if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)))
   619         return FALSE;
   620 
   621 
   622     len = gmyth_scheduler_get_recorded_list (priv->myth_scheduler,
   623                                              &list);
   624 
   625     record_type = GMYTH_DBUS_RECORD_G_TYPE;
   626     *records = g_ptr_array_sized_new (len);
   627 
   628     for (walk = list; walk != NULL; walk = walk->next)
   629     {
   630         GValue record = { 0, };
   631         RecordedInfo *data;
   632 
   633         data = (RecordedInfo *) walk->data;
   634 
   635         g_value_init (&record, record_type);
   636         g_value_take_boxed (&record,
   637                             dbus_g_type_specialized_construct (record_type));
   638 
   639         gmyth_dbus_server_parse_recorded_info (data, &record);
   640 
   641         g_ptr_array_add (*records, g_value_get_boxed (&record));
   642         //g_value_unset (&record);
   643     }
   644 
   645     gmyth_recorded_info_list_free (list);
   646 
   647     return TRUE;
   648 
   649 }
   650 
   651 static gboolean
   652 gmyth_dbus_server_get_schedule_list (GObject *obj,
   653                                      GPtrArray **schedules)
   654 {
   655     GList *list;
   656     GList *walk;
   657     gint len;
   658     GType schedule_type;
   659     GMythDbusServerPrivate *priv;
   660 
   661     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   662     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   663 
   664     g_return_val_if_fail (priv->myth_backend, FALSE);
   665     if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)))
   666         return FALSE;
   667 
   668 
   669     len = gmyth_scheduler_get_schedule_list (priv->myth_scheduler,
   670                                              &list);
   671 
   672     *schedules = g_ptr_array_sized_new (len);
   673     schedule_type = GMYTH_DBUS_SCHEDULE_G_TYPE;
   674 
   675     for (walk = list; walk != NULL; walk = walk->next)
   676     {
   677         GValue schedule = { 0, };
   678         ScheduleInfo *data;
   679         gchar *start_str_time;
   680         gchar *end_str_time;
   681 
   682         data = (ScheduleInfo *) walk->data;
   683 
   684         g_value_init (&schedule, schedule_type);
   685         g_value_take_boxed (&schedule,
   686                             dbus_g_type_specialized_construct (schedule_type));
   687 
   688         start_str_time = g_time_val_to_iso8601 (data->start_time);
   689         end_str_time = g_time_val_to_iso8601 (data->end_time);
   690 
   691         dbus_g_type_struct_set (&schedule,
   692                             0, data->schedule_id,
   693                             1, data->program_id,
   694                             2, data->channel_id,
   695                             3, start_str_time,
   696                             4, end_str_time,
   697                             5, data->title->str,
   698                             6, data->subtitle->str,
   699                             7, data->description->str,
   700                             8, data->category->str,
   701                             9, data->type,
   702                             G_MAXUINT);
   703 
   704         g_ptr_array_add (*schedules, g_value_get_boxed (&schedule));
   705 
   706         g_free (start_str_time);
   707         g_free (end_str_time);
   708     }
   709 
   710     gmyth_schedule_info_list_free (list);
   711 
   712     return TRUE;
   713 }
   714 
   715 
   716 static gboolean
   717 gmyth_dbus_server_get_thumbnail (GObject *obj,
   718                                 const gchar *uri,
   719                                 GByteArray **image,
   720                                 GError **error)
   721 {
   722     GMythFileTransfer *file_transfer;
   723     glong filesize;
   724     GMythFileReadResult result;
   725     GMythDbusServerPrivate *priv;
   726 
   727     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   728 
   729     file_transfer = NULL;
   730 
   731     g_return_val_if_fail (priv->myth_backend, FALSE);
   732 
   733     if (!gmyth_util_file_exists (priv->myth_backend, uri))
   734         goto fail;
   735 
   736     file_transfer = gmyth_file_transfer_new (priv->myth_backend);
   737 
   738     if (!gmyth_file_transfer_open (file_transfer, uri))
   739         goto fail;
   740 
   741     filesize = gmyth_file_transfer_get_filesize (file_transfer);
   742     if (filesize <= 0)
   743         goto fail;
   744 
   745     *image = g_byte_array_new ();
   746     result = gmyth_file_transfer_read (file_transfer, *image, filesize, FALSE);
   747     if (result == GMYTH_FILE_READ_ERROR)
   748        goto fail;
   749 
   750     gmyth_file_transfer_close (file_transfer);
   751     g_object_unref (file_transfer);
   752 
   753     if (filesize > (*image)->len)
   754         goto fail;
   755 
   756     return TRUE;
   757 
   758 fail:
   759     if (*image)
   760         g_byte_array_free (*image, TRUE);
   761     g_object_unref(file_transfer);
   762     return FALSE;
   763 }
   764 
   765 static gboolean
   766 gmyth_dbus_server_get_channel_icon (GObject *obj,
   767                                     guint channel_id,
   768                                     GByteArray **icon,
   769                                     GError **error)
   770 {
   771     GMythChannelInfo *channel = NULL;
   772     guint8 *icon_data;
   773     guint icon_length;
   774     GMythDbusServerPrivate *priv;
   775 
   776     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   777     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   778     g_return_val_if_fail (priv->myth_backend, FALSE);
   779 
   780     channel = gmyth_epg_get_channel_info (priv->myth_epg,
   781                                          (gint) channel_id);
   782 
   783     *icon = NULL;
   784 
   785     if (channel == NULL)
   786         return FALSE;
   787 
   788     if (!gmyth_epg_channel_has_icon(priv->myth_epg, channel))
   789     {
   790         gmyth_channel_info_free (channel);
   791         g_debug("Channel does not have icon available");
   792         return FALSE;
   793     }
   794 
   795     icon_data = NULL;
   796     icon_length = 0;
   797     if (!gmyth_epg_channel_get_icon (priv->myth_epg,
   798                                      channel,
   799                                      &icon_data,
   800                                      &icon_length)) 
   801     {
   802         gmyth_channel_info_free (channel);
   803         g_warning("Could not get channel icon for channel id = %u", channel_id);
   804         return FALSE;
   805     }
   806 
   807     *icon = g_byte_array_sized_new (icon_length);
   808     *icon = g_byte_array_append (*icon, icon_data, icon_length);
   809 
   810     g_free (icon_data);
   811     gmyth_channel_info_free(channel);
   812     return TRUE;
   813 }
   814 
   815 
   816 static gboolean
   817 gmyth_dbus_server_stop_recording (GObject *obj,
   818                                   guint channel_id,
   819                                   gboolean *result,
   820                                   GError **error)
   821 {
   822     gboolean ret = FALSE;
   823     GMythDbusServerPrivate *priv;
   824 
   825     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   826     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   827 
   828     g_return_val_if_fail (priv->myth_backend, FALSE);
   829     if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)))
   830         return FALSE;
   831 
   832     ret = gmyth_scheduler_stop_recording (priv->myth_scheduler,
   833                                           channel_id);
   834 
   835     return ret;
   836 }
   837 
   838 static ScheduleInfo*
   839 gmyth_dbus_server_new_schedule_info (const gchar* description,
   840                                      guint channel_id,
   841                                      guint program_id,
   842                                      GTimeVal *start_vtime,
   843                                      GTimeVal *end_vtime)
   844 {
   845     ScheduleInfo   *new_sched_info;
   846 
   847     new_sched_info = g_new0(ScheduleInfo, 1);
   848 
   849     /* record_id == -1 for generating a new id */
   850     new_sched_info->schedule_id = -1;
   851 
   852     new_sched_info->channel_id = channel_id;
   853     new_sched_info->program_id = program_id;
   854     new_sched_info->start_time = g_new0 (GTimeVal, 1);
   855     *new_sched_info->start_time = *start_vtime;
   856     new_sched_info->end_time = g_new0 (GTimeVal, 1);
   857     *new_sched_info->end_time = *end_vtime;
   858 
   859     /* TODO: there is no frequency field */
   860     /*new_sched_info->frequency = -1;*/
   861 
   862     if (description != NULL) {
   863         /* FIXME: description parameter is used as title and description */
   864         new_sched_info->title = g_string_new(description);
   865         new_sched_info->description = g_string_new(description);
   866     }
   867 
   868     return new_sched_info;
   869 }
   870 
   871 static gboolean
   872 gmyth_dbus_server_add_schedule (GObject *obj,
   873                                 guint channel_id,
   874                                 guint program_id,
   875                                 const gchar *start_time,
   876                                 const gchar *end_time,
   877                                 gboolean recurring,
   878                                 const gchar *description,
   879                                 guint *schedule_id,
   880                                 GError **error)
   881 {
   882     ScheduleInfo *sch_info;
   883     GTimeVal start_vtime;
   884     GTimeVal end_vtime;
   885     GMythDbusServerPrivate *priv;
   886 
   887     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   888     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   889 
   890     *schedule_id = 0;
   891 
   892     g_return_val_if_fail (priv->myth_backend, FALSE);
   893 
   894     if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)))
   895         return FALSE;
   896 
   897 
   898     g_time_val_from_iso8601 (start_time, &start_vtime);
   899     g_time_val_from_iso8601 (end_time, &end_vtime);
   900     sch_info = gmyth_dbus_server_new_schedule_info (description,
   901                                                     channel_id,
   902                                                     program_id,
   903                                                     &start_vtime,
   904                                                     &end_vtime);
   905     if (sch_info != NULL) {
   906         GMythScheduleType type;
   907         GTimeVal t_now;
   908         gboolean has_record;
   909 
   910         type = (recurring ?
   911                 GMYTH_SCHEDULE_ALL_OCCURRENCES :
   912                 GMYTH_SCHEDULE_ONE_OCCURRENCE);
   913 
   914         g_get_current_time (&t_now);
   915 
   916         has_record = gmyth_scheduler_was_recorded_before (priv->myth_scheduler, 
   917                                                           channel_id,
   918                                                           (time_t) start_vtime.tv_sec);
   919 
   920 
   921         if ((t_now.tv_sec >= start_vtime.tv_sec)
   922             && (t_now.tv_sec <= end_vtime.tv_sec) && has_record)
   923         {
   924             GMythSocket    *socket;
   925             gboolean        res = FALSE;
   926 
   927             socket = gmyth_backend_info_get_connected_socket (priv->myth_backend);
   928             res = gmyth_scheduler_reactivate_schedule(priv->myth_scheduler,
   929                                                       channel_id,
   930                                                       (time_t) start_vtime.tv_sec);
   931             if (res) {
   932                 GMythStringList *slist = gmyth_string_list_new();
   933 
   934                 gmyth_string_list_append_char_array(slist, "RESCHEDULE_RECORDINGS 0");
   935                 gmyth_socket_sendreceive_stringlist(socket, slist);
   936                 res = (gmyth_string_list_get_int(slist, 0) == 1);
   937                 g_object_unref(slist);
   938             }
   939 
   940             g_object_unref(socket);
   941             return res;
   942         }
   943         else
   944         {
   945             if (!gmyth_scheduler_add_schedule_full (priv->myth_scheduler,
   946                                                     sch_info,
   947                                                     type))
   948             {
   949                 g_warning("Could not add schedule entry");
   950                 return FALSE;
   951             }
   952 
   953             (*schedule_id) = sch_info->schedule_id;
   954             gmyth_schedule_info_free (sch_info);
   955             return TRUE;
   956         }
   957     }
   958     return FALSE;
   959 }
   960 
   961 static gboolean
   962 gmyth_dbus_server_add_exception (GObject *obj,
   963                                  guint schedule_id,
   964                                  guint channel_id,
   965                                  guint program_id,
   966                                  const gchar *start_time,
   967                                  const gchar *end_time,
   968                                  const gchar *description,
   969                                  GError **error)
   970 {
   971     ScheduleInfo *sch_info;
   972     GTimeVal start_vtime;
   973     GTimeVal end_vtime;
   974     GMythDbusServerPrivate *priv;
   975 
   976     g_debug ("%s:%d", __FUNCTION__, __LINE__);
   977     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
   978 
   979     g_return_val_if_fail (priv->myth_backend, FALSE);
   980 
   981     if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)))
   982         return FALSE;
   983 
   984     g_time_val_from_iso8601 (start_time, &start_vtime);
   985     g_time_val_from_iso8601 (end_time, &end_vtime);
   986 
   987     sch_info = gmyth_dbus_server_new_schedule_info (description,
   988                                                    channel_id,
   989                                                    program_id,
   990                                                    &start_vtime,
   991                                                    &end_vtime);
   992     if (sch_info != NULL)
   993     {
   994        if (!gmyth_scheduler_add_exception (priv->myth_scheduler,
   995                                            schedule_id,
   996                                            sch_info))
   997        {
   998            g_warning ("Could not add schedule exception");
   999            gmyth_schedule_info_free (sch_info);
  1000            return FALSE;
  1001        }
  1002 
  1003        gmyth_schedule_info_free (sch_info);
  1004        return TRUE;
  1005     }
  1006     return FALSE;
  1007 }
  1008 
  1009 static gboolean
  1010 gmyth_dbus_server_remove_schedule (GObject *obj,
  1011                                    guint schedule_id,
  1012                                    GError **error)
  1013 {
  1014     GMythDbusServerPrivate *priv;
  1015 
  1016     g_debug ("%s:%d", __FUNCTION__, __LINE__);
  1017     priv = GMYTH_DBUS_SERVER_GET_PRIVATE (obj);
  1018 
  1019     g_return_val_if_fail (priv->myth_backend, FALSE);
  1020 
  1021     if (!gmyth_dbus_server_connect_scheduler (GMYTH_DBUS_SERVER (obj)))
  1022         return FALSE;
  1023 
  1024     return gmyth_scheduler_delete_schedule (priv->myth_scheduler, schedule_id);
  1025 }
  1026 
  1027 GMythDbusServer*
  1028 gmyth_dbus_server_start_dbus_service (void)
  1029 {
  1030     GError *error = NULL;
  1031     DBusGProxy *proxy;
  1032     DBusGConnection *bus;
  1033     guint request_ret;
  1034     GMythDbusServer *self;
  1035 
  1036     self = g_object_new (GMYTH_DBUS_SERVER_TYPE, NULL);
  1037     g_return_val_if_fail (self, FALSE);
  1038 
  1039     /* TODO: should verify if this service was already started */
  1040 
  1041     /* connect to session bus */
  1042     bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
  1043     if (bus == NULL) 
  1044     {
  1045         g_warning ("Could not connect to dbus: %s", error->message);
  1046         g_error_free (error);
  1047         goto fail;
  1048     }
  1049 
  1050     /* register dbus object */
  1051     dbus_g_connection_register_g_object (bus,
  1052         GMYTH_DBUS_SERVER_PATH, G_OBJECT (self));
  1053 
  1054     proxy = dbus_g_proxy_new_for_name (bus, DBUS_SERVICE_DBUS,
  1055                                        DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
  1056 
  1057     /* registering download manager service */
  1058     if (!org_freedesktop_DBus_request_name (proxy, GMYTH_DBUS_SERVER_IFACE,
  1059                                             0, &request_ret, &error)) 
  1060     {
  1061         g_warning ("Unable to register dbus service: %d %s",
  1062                    error->code, error->message);
  1063         g_error_free (error);
  1064         goto fail;
  1065     }
  1066 
  1067     if (request_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) 
  1068     {
  1069         g_warning ("Got result code %u from requesting name", request_ret);
  1070         goto fail;
  1071     }
  1072 
  1073     return self;
  1074 
  1075 fail:
  1076     g_object_unref (self);
  1077     return NULL;
  1078 }
  1079