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