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