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