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