gmyth/src/gmyth_scheduler.c
author rosfran
Wed May 23 16:11:29 2007 +0100 (2007-05-23)
branchtrunk
changeset 698 9019388af980
parent 592 0f77fcb97269
child 701 2f28edb4d804
permissions -rw-r--r--
[svn r704] Added gmyth-upnp-search, to search for MythTV UPnP devices.
leo_sobral@1
     1
/**
leo_sobral@1
     2
 * GMyth Library
leo_sobral@1
     3
 *
leo_sobral@1
     4
 * @file gmyth/gmyth_scheduler.c
leo_sobral@1
     5
 * 
leo_sobral@1
     6
 * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
leo_sobral@1
     7
 * and modifying the recorded content.
leo_sobral@1
     8
 *
leo_sobral@1
     9
 * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
leo_sobral@1
    10
 * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
leo_sobral@1
    11
 *
rosfran@698
    12
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              *//*
rosfran@698
    13
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * 
rosfran@698
    14
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * This program is free software; you can redistribute it and/or modify
rosfran@698
    15
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * it under the terms of the GNU Lesser General Public License as published by
rosfran@698
    16
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * the Free Software Foundation; either version 2 of the License, or
rosfran@698
    17
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * (at your option) any later version.
rosfran@698
    18
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 *
rosfran@698
    19
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * This program is distributed in the hope that it will be useful,
rosfran@698
    20
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * but WITHOUT ANY WARRANTY; without even the implied warranty of
rosfran@698
    21
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
rosfran@698
    22
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * GNU General Public License for more details.
rosfran@698
    23
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 *
rosfran@698
    24
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * You should have received a copy of the GNU Lesser General Public License
rosfran@698
    25
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * along with this program; if not, write to the Free Software
rosfran@698
    26
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
rosfran@698
    27
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 */
rosfran@698
    28
leo_sobral@213
    29
#ifdef HAVE_CONFIG_H
leo_sobral@213
    30
#include "config.h"
leo_sobral@213
    31
#endif
leo_sobral@1
    32
leo_sobral@213
    33
#include <assert.h>
leo_sobral@1
    34
rosfran@214
    35
#include <glib/gprintf.h>
rosfran@214
    36
rosfran@214
    37
#include "gmyth_scheduler.h"
leo_sobral@1
    38
#include "gmyth_util.h"
leo_sobral@1
    39
#include "gmyth_query.h"
melunko@117
    40
#include "gmyth_socket.h"
renatofilho@131
    41
#include "gmyth_debug.h"
leo_sobral@1
    42
rosfran@698
    43
static void gmyth_scheduler_class_init (GMythSchedulerClass * klass);
rosfran@698
    44
static void gmyth_scheduler_init (GMythScheduler * object);
leo_sobral@1
    45
rosfran@698
    46
static void gmyth_scheduler_dispose (GObject * object);
rosfran@698
    47
static void gmyth_scheduler_finalize (GObject * object);
leo_sobral@1
    48
rosfran@698
    49
static gint get_record_id_from_database (GMythScheduler * scheduler);
rosfran@698
    50
static gboolean update_backend (GMythScheduler * scheduler, gint record_id);
leo_sobral@1
    51
rosfran@698
    52
G_DEFINE_TYPE (GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT)
rosfran@698
    53
     static void gmyth_scheduler_class_init (GMythSchedulerClass * klass)
leo_sobral@1
    54
{
melunko@117
    55
    GObjectClass *gobject_class;
leo_sobral@1
    56
leo_sobral@1
    57
    gobject_class = (GObjectClass *) klass;
leo_sobral@1
    58
rosfran@698
    59
    gobject_class->dispose = gmyth_scheduler_dispose;
rosfran@698
    60
    gobject_class->finalize = gmyth_scheduler_finalize;
leo_sobral@1
    61
}
leo_sobral@1
    62
leo_sobral@1
    63
static void
rosfran@698
    64
gmyth_scheduler_init (GMythScheduler * sched)
leo_sobral@1
    65
{
rosfran@698
    66
    sched->recordid = 0;
leo_sobral@1
    67
    sched->type = 0;
leo_sobral@1
    68
    sched->search = 0;
rosfran@698
    69
    sched->profile = g_string_new ("");
rosfran@698
    70
leo_sobral@1
    71
    sched->dupin = 0;
leo_sobral@1
    72
    sched->dupmethod = 0;
leo_sobral@1
    73
    sched->autoexpire = 0;
leo_sobral@1
    74
    sched->autotranscode = 0;
leo_sobral@1
    75
    sched->transcoder = 0;
leo_sobral@1
    76
leo_sobral@1
    77
    sched->autocommflag = 0;
leo_sobral@1
    78
    sched->autouserjob1 = 0;
leo_sobral@1
    79
    sched->autouserjob2 = 0;
leo_sobral@1
    80
    sched->autouserjob3 = 0;
leo_sobral@1
    81
    sched->autouserjob4 = 0;
rosfran@698
    82
leo_sobral@1
    83
    sched->startoffset = 0;
leo_sobral@1
    84
    sched->endoffset = 0;
leo_sobral@1
    85
    sched->maxepisodes = 0;
leo_sobral@1
    86
    sched->maxnewest = 0;
leo_sobral@1
    87
leo_sobral@1
    88
    sched->recpriority = 0;
rosfran@698
    89
    sched->recgroup = g_string_new ("");
rosfran@698
    90
    sched->playgroup = g_string_new ("");
rosfran@698
    91
leo_sobral@1
    92
    sched->prefinput = 0;
leo_sobral@1
    93
    sched->inactive = 0;
rosfran@698
    94
rosfran@698
    95
    sched->search_type = g_string_new ("");
rosfran@698
    96
    sched->search_what = g_string_new ("");
rosfran@698
    97
leo_sobral@1
    98
    sched->msqlquery = gmyth_query_new ();
leo_sobral@1
    99
}
leo_sobral@1
   100
leo_sobral@1
   101
static void
rosfran@698
   102
gmyth_scheduler_dispose (GObject * object)
leo_sobral@1
   103
{
melunko@117
   104
    GMythScheduler *scheduler = GMYTH_SCHEDULER (object);
melunko@117
   105
leo_sobral@391
   106
    if (scheduler->backend_info) {
leo_sobral@391
   107
        g_object_unref (scheduler->backend_info);
leo_sobral@390
   108
        scheduler->backend_info = NULL;
melunko@117
   109
    }
melunko@117
   110
leo_sobral@391
   111
    if (scheduler->msqlquery) {
leo_sobral@391
   112
        g_object_unref (scheduler->msqlquery);
leo_sobral@390
   113
        scheduler->msqlquery = NULL;
leo_sobral@387
   114
    }
leo_sobral@387
   115
leo_sobral@402
   116
    g_string_free (scheduler->profile, TRUE);
leo_sobral@402
   117
    g_string_free (scheduler->recgroup, TRUE);
leo_sobral@402
   118
    g_string_free (scheduler->playgroup, TRUE);
leo_sobral@402
   119
    g_string_free (scheduler->search_type, TRUE);
leo_sobral@402
   120
    g_string_free (scheduler->search_what, TRUE);
leo_sobral@387
   121
melunko@117
   122
    G_OBJECT_CLASS (gmyth_scheduler_parent_class)->dispose (object);
leo_sobral@1
   123
}
leo_sobral@1
   124
leo_sobral@1
   125
static void
rosfran@698
   126
gmyth_scheduler_finalize (GObject * object)
leo_sobral@1
   127
{
melunko@117
   128
    g_signal_handlers_destroy (object);
leo_sobral@1
   129
leo_sobral@1
   130
    G_OBJECT_CLASS (gmyth_scheduler_parent_class)->finalize (object);
leo_sobral@1
   131
}
leo_sobral@1
   132
leo_sobral@1
   133
/** Creates a new instance of GMythScheduler.
leo_sobral@1
   134
 * 
leo_sobral@1
   135
 * @return a new instance of GMythScheduler.
leo_sobral@1
   136
 */
rosfran@698
   137
GMythScheduler *
leo_sobral@1
   138
gmyth_scheduler_new ()
leo_sobral@1
   139
{
rosfran@698
   140
    GMythScheduler *scheduler =
rosfran@698
   141
        GMYTH_SCHEDULER (g_object_new (GMYTH_SCHEDULER_TYPE, NULL));
rosfran@698
   142
leo_sobral@1
   143
    return scheduler;
leo_sobral@1
   144
}
leo_sobral@1
   145
melunko@257
   146
gboolean
rosfran@698
   147
gmyth_scheduler_connect (GMythScheduler * scheduler,
rosfran@698
   148
    GMythBackendInfo * backend_info)
melunko@257
   149
{
melunko@257
   150
    return gmyth_scheduler_connect_with_timeout (scheduler, backend_info, 0);
melunko@257
   151
}
melunko@257
   152
leo_sobral@1
   153
/** Connects to the Mysql database in the backend. The backend address
leo_sobral@1
   154
 * is loaded from the GMythSettings instance.
leo_sobral@1
   155
 * 
leo_sobral@1
   156
 * @param scheduler the GMythScheduler instance to be connected.
leo_sobral@1
   157
 * @return true if connection was success, false if failed.
leo_sobral@1
   158
 */
leo_sobral@1
   159
gboolean
rosfran@698
   160
gmyth_scheduler_connect_with_timeout (GMythScheduler * scheduler,
rosfran@698
   161
    GMythBackendInfo * backend_info, guint timeout)
leo_sobral@1
   162
{
rosfran@698
   163
    assert (scheduler);
melunko@117
   164
    g_return_val_if_fail (backend_info != NULL, FALSE);
rosfran@698
   165
renatofilho@558
   166
    if (scheduler->backend_info)
renatofilho@558
   167
        g_object_unref (scheduler->backend_info);
rosfran@698
   168
renatofilho@558
   169
    scheduler->backend_info = g_object_ref (backend_info);
leo_sobral@1
   170
leo_sobral@1
   171
    if (scheduler->msqlquery == NULL) {
leo_sobral@32
   172
        g_warning ("[%s] GMythScheduler db initializing", __FUNCTION__);
rosfran@698
   173
        scheduler->msqlquery = gmyth_query_new ();
melunko@256
   174
    }
leo_sobral@1
   175
rosfran@698
   176
    if (!gmyth_query_connect_with_timeout (scheduler->msqlquery,
rosfran@698
   177
            scheduler->backend_info, timeout)) {
leo_sobral@390
   178
        g_warning ("[%s] Error while connecting to db", __FUNCTION__);
leo_sobral@1
   179
        return FALSE;
leo_sobral@1
   180
    }
leo_sobral@1
   181
leo_sobral@1
   182
    return TRUE;
leo_sobral@1
   183
}
leo_sobral@1
   184
leo_sobral@1
   185
/** Disconnects from the Mysql database in the backend.
leo_sobral@1
   186
 * 
leo_sobral@1
   187
 * @param scheduler the GMythScheduler instance to be disconnected
leo_sobral@1
   188
 * @return true if disconnection was success, false if failed.
leo_sobral@1
   189
 */
leo_sobral@1
   190
gboolean
rosfran@698
   191
gmyth_scheduler_disconnect (GMythScheduler * scheduler)
leo_sobral@1
   192
{
rosfran@698
   193
    assert (scheduler);
leo_sobral@1
   194
leo_sobral@1
   195
    if (scheduler->msqlquery != NULL) {
melunko@117
   196
        gmyth_query_disconnect (scheduler->msqlquery);
leo_sobral@1
   197
    }
leo_sobral@1
   198
leo_sobral@1
   199
    return TRUE;
leo_sobral@1
   200
}
leo_sobral@1
   201
leo_sobral@1
   202
/** Retrieves from the backend Mysql database the list of recording schedules.
leo_sobral@1
   203
 * 
leo_sobral@1
   204
 * @param scheduler The GMythScheduler instance.
leo_sobral@1
   205
 * @param schedule_list the GList pointer to be filled with the loaded list of ScheduleInfo items.
leo_sobral@1
   206
 * @return The amount of schedules retrieved from database, or -1 if error.
leo_sobral@1
   207
 */
leo_sobral@1
   208
gint
rosfran@698
   209
gmyth_scheduler_get_schedule_list (GMythScheduler * scheduler,
rosfran@698
   210
    GList ** schedule_list)
leo_sobral@1
   211
{
melunko@117
   212
    ScheduleInfo *schedule;
melunko@117
   213
    MYSQL_RES *msql_res;
leo_sobral@1
   214
    GString *query_str = g_string_new ("");
rosfran@214
   215
    gchar *date_time = NULL;
rosfran@698
   216
rosfran@698
   217
    assert (scheduler);
rosfran@698
   218
rosfran@698
   219
    g_string_printf (query_str,
rosfran@698
   220
        "SELECT recordid,programid,chanid,starttime,startdate,"
rosfran@698
   221
        "endtime,enddate,title,subtitle,description,category FROM record;");
leo_sobral@1
   222
melunko@117
   223
    if (scheduler->msqlquery == NULL) {
rosfran@698
   224
        g_warning ("[%s] Scheduler db connection not initialized",
rosfran@698
   225
            __FUNCTION__);
leo_sobral@390
   226
        return -1;
melunko@117
   227
    }
rosfran@698
   228
    msql_res =
rosfran@698
   229
        gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
leo_sobral@1
   230
leo_sobral@1
   231
    if (msql_res == NULL) {
leo_sobral@1
   232
        g_warning ("DB retrieval of schedule list failed");
leo_sobral@1
   233
        return -1;
leo_sobral@1
   234
    } else {
leo_sobral@1
   235
        MYSQL_ROW row;
rosfran@698
   236
leo_sobral@1
   237
        *schedule_list = NULL;
rosfran@698
   238
rosfran@698
   239
        while ((row = mysql_fetch_row (msql_res)) != NULL) {
rosfran@698
   240
            schedule = g_new0 (ScheduleInfo, 1);
rosfran@698
   241
rosfran@698
   242
            schedule->schedule_id = (guint) g_ascii_strtoull (row[0], NULL, 10);
leo_sobral@390
   243
            schedule->program_id = (guint) g_ascii_strtoull (row[1], NULL, 10);
leo_sobral@387
   244
            schedule->channel_id = (guint) g_ascii_strtoull (row[2], NULL, 10);
rosfran@698
   245
leo_sobral@1
   246
            /* generate a time_t from a time and a date db field */
melunko@524
   247
            date_time = g_strdup_printf ("%sT%s", row[4], row[3]);
rosfran@214
   248
            schedule->start_time = gmyth_util_string_to_time_val (date_time);
melunko@524
   249
            g_free (date_time);
rosfran@698
   250
leo_sobral@1
   251
            /* generate a time_t from a time and a date db field */
melunko@524
   252
            date_time = g_strdup_printf ("%sT%s", row[6], row[5]);
rosfran@214
   253
            schedule->end_time = gmyth_util_string_to_time_val (date_time);
melunko@524
   254
            g_free (date_time);
leo_sobral@1
   255
rosfran@698
   256
            schedule->title = g_string_new (row[7]);
rosfran@698
   257
            schedule->subtitle = g_string_new (row[8]);
leo_sobral@1
   258
            schedule->description = g_string_new (row[9]);
rosfran@698
   259
            schedule->category = g_string_new (row[10]);
leo_sobral@1
   260
leo_sobral@390
   261
            (*schedule_list) = g_list_append (*(schedule_list), schedule);
leo_sobral@391
   262
        }
leo_sobral@1
   263
    }
leo_sobral@1
   264
leo_sobral@1
   265
    mysql_free_result (msql_res);
rosfran@698
   266
    g_string_free (query_str, TRUE);
leo_sobral@1
   267
leo_sobral@1
   268
    return (*schedule_list == NULL) ? 0 : g_list_length (*schedule_list);
leo_sobral@1
   269
}
leo_sobral@1
   270
leo_sobral@1
   271
/** Retrieves from the backend Mysql database the list of recorded programs.
leo_sobral@1
   272
 * 
leo_sobral@1
   273
 * @param scheduler The GMythScheduler instance.
leo_sobral@1
   274
 * @param recorded_list the GList pointer to be filled with the loaded RecordInfo items.
leo_sobral@1
   275
 * @return The amount of recorded retrieved from database, or -1 if error.
leo_sobral@1
   276
 */
leo_sobral@1
   277
gint
rosfran@698
   278
gmyth_scheduler_get_recorded_list (GMythScheduler * scheduler,
rosfran@698
   279
    GList ** recorded_list)
leo_sobral@1
   280
{
melunko@117
   281
    RecordedInfo *record;
melunko@117
   282
    MYSQL_RES *msql_res;
leo_sobral@1
   283
    GString *query_str = g_string_new ("");
rosfran@698
   284
rosfran@698
   285
    assert (scheduler);
rosfran@698
   286
rosfran@698
   287
    g_string_printf (query_str,
rosfran@698
   288
        "SELECT recordid,programid,chanid,starttime,progstart,"
rosfran@698
   289
        "endtime,progend,title,subtitle,description,category,"
leo_sobral@387
   290
        "filesize,basename FROM recorded WHERE recgroup != 'LiveTV'");
leo_sobral@1
   291
melunko@313
   292
    if (scheduler->msqlquery == NULL) {
rosfran@698
   293
        g_warning ("[%s] Scheduler db connection not initialized",
rosfran@698
   294
            __FUNCTION__);
leo_sobral@387
   295
        return -1;
melunko@313
   296
    }
leo_sobral@1
   297
rosfran@698
   298
    msql_res =
rosfran@698
   299
        gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
leo_sobral@1
   300
leo_sobral@1
   301
    if (msql_res == NULL) {
leo_sobral@1
   302
        g_warning ("DB retrieval of recording list failed");
leo_sobral@1
   303
        return -1;
melunko@313
   304
    } else {
leo_sobral@1
   305
        MYSQL_ROW row;
rosfran@698
   306
leo_sobral@387
   307
        (*recorded_list) = NULL;
rosfran@698
   308
rosfran@698
   309
        while ((row = mysql_fetch_row (msql_res)) != NULL) {
rosfran@698
   310
            record = g_new0 (RecordedInfo, 1);
rosfran@698
   311
rosfran@698
   312
            record->record_id = (guint) g_ascii_strtoull (row[0], NULL, 10);
melunko@207
   313
            record->program_id = (guint) g_ascii_strtoull (row[1], NULL, 10);
melunko@207
   314
            record->channel_id = (guint) g_ascii_strtoull (row[2], NULL, 10);
rosfran@698
   315
melunko@313
   316
            record->start_time = gmyth_util_string_to_time_val (row[3]);
rosfran@698
   317
            record->end_time = gmyth_util_string_to_time_val (row[5]);
rosfran@698
   318
rosfran@698
   319
            record->title = g_string_new (row[7]);
rosfran@698
   320
            record->subtitle = g_string_new (row[8]);
leo_sobral@1
   321
            record->description = g_string_new (row[9]);
rosfran@698
   322
            record->category = g_string_new (row[10]);
rosfran@698
   323
            record->filesize = g_ascii_strtoull (row[11], NULL, 10);
rosfran@698
   324
            record->basename = g_string_new (row[12]);
leo_sobral@1
   325
leo_sobral@387
   326
            (*recorded_list) = g_list_append ((*recorded_list), record);
leo_sobral@391
   327
        }
leo_sobral@1
   328
    }
rosfran@698
   329
leo_sobral@1
   330
    mysql_free_result (msql_res);
rosfran@698
   331
    g_string_free (query_str, TRUE);
leo_sobral@1
   332
leo_sobral@1
   333
    return (*recorded_list == NULL) ? 0 : g_list_length (*recorded_list);
leo_sobral@1
   334
}
leo_sobral@1
   335
melunko@567
   336
static void
rosfran@698
   337
_set_value (GMythQuery * myth_query, char *field, gchar * value, gint rec_id)
melunko@567
   338
{
rosfran@698
   339
    gchar *query =
rosfran@698
   340
        g_strdup_printf
rosfran@698
   341
        ("UPDATE record SET recordid = %d, %s = \"%s\" WHERE recordid = %d;",
rosfran@698
   342
        rec_id, field, value, rec_id);
melunko@567
   343
melunko@567
   344
    gmyth_query_process_statement (myth_query, query);
rosfran@698
   345
    g_free (query);
melunko@567
   346
}
melunko@567
   347
melunko@567
   348
static void
rosfran@698
   349
_set_int_value (GMythQuery * myth_query, char *field, gint value, gint rec_id)
melunko@567
   350
{
melunko@567
   351
    gchar *str_value = g_strdup_printf ("%d", value);
rosfran@698
   352
melunko@567
   353
    _set_value (myth_query, field, str_value, rec_id);
melunko@567
   354
    g_free (str_value);
melunko@567
   355
}
melunko@567
   356
leo_sobral@1
   357
/** Requests the Mysql database in the backend to add a new schedule.
leo_sobral@1
   358
 * 
leo_sobral@1
   359
 * @param scheduler the GMythScheduler instance.
leo_sobral@1
   360
 * @param schedule_info the ScheduleInfo with recording schedule information
leo_sobral@1
   361
 * to be added. record_id = -1 to add a new schedule, otherwise this
leo_sobral@1
   362
 * function will update the schedule in the db
leo_sobral@1
   363
 * @return gboolean returns FALSE if some error occurs, TRUE otherwise
leo_sobral@1
   364
 */
leo_sobral@1
   365
gboolean
rosfran@698
   366
gmyth_scheduler_add_schedule (GMythScheduler * scheduler,
rosfran@698
   367
    ScheduleInfo * schedule_info)
leo_sobral@1
   368
{
melunko@117
   369
    MYSQL_RES *msql_res;
melunko@567
   370
    gchar *query_str = "INSERT record (recordid) VALUE (0);";
melunko@567
   371
    gchar *station = NULL;
melunko@567
   372
    gulong rec_id;
rosfran@698
   373
rosfran@698
   374
    assert (scheduler);
rosfran@698
   375
melunko@117
   376
    if (scheduler->msqlquery == NULL) {
rosfran@698
   377
        g_warning ("[%s] Scheduler db connection not initialized",
rosfran@698
   378
            __FUNCTION__);
leo_sobral@390
   379
        return FALSE;
melunko@117
   380
    }
melunko@567
   381
rosfran@698
   382
    msql_res =
rosfran@698
   383
        gmyth_query_process_statement_with_increment (scheduler->msqlquery,
rosfran@698
   384
        query_str, &rec_id);
melunko@567
   385
    mysql_free_result (msql_res);
rosfran@698
   386
melunko@567
   387
    // Retrieves the station info
rosfran@698
   388
    query_str =
rosfran@698
   389
        g_strdup_printf ("SELECT callsign FROM channel WHERE chanid = \"%d\";",
rosfran@698
   390
        schedule_info->channel_id);
melunko@567
   391
    msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str);
melunko@567
   392
    if (msql_res == NULL) {
melunko@567
   393
        g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
melunko@567
   394
        return FALSE;
melunko@567
   395
    } else {
melunko@567
   396
        MYSQL_ROW row;
rosfran@698
   397
melunko@567
   398
        if ((row = mysql_fetch_row (msql_res)) != NULL) {
melunko@567
   399
            station = g_strdup (row[0]);
melunko@567
   400
        }
melunko@567
   401
    }
melunko@567
   402
    mysql_free_result (msql_res);
melunko@567
   403
    g_free (query_str);
leo_sobral@1
   404
melunko@567
   405
    // _set_value (field, value, id);
rosfran@698
   406
    _set_int_value (scheduler->msqlquery, "chanid", schedule_info->channel_id,
rosfran@698
   407
        rec_id);
melunko@567
   408
    _set_value (scheduler->msqlquery, "station", station, rec_id);
rosfran@698
   409
    _set_value (scheduler->msqlquery, "title", schedule_info->title->str,
rosfran@698
   410
        rec_id);
melunko@567
   411
    /// subtitle, description    
rosfran@698
   412
    _set_value (scheduler->msqlquery, "starttime",
rosfran@698
   413
        gmyth_util_time_to_string_only_time (schedule_info->
rosfran@698
   414
            start_time), rec_id);
rosfran@698
   415
    _set_value (scheduler->msqlquery, "startdate",
rosfran@698
   416
        gmyth_util_time_to_string_only_date (schedule_info->
rosfran@698
   417
            start_time), rec_id);
rosfran@698
   418
    _set_value (scheduler->msqlquery, "endtime",
rosfran@698
   419
        gmyth_util_time_to_string_only_time (schedule_info->end_time), rec_id);
rosfran@698
   420
    _set_value (scheduler->msqlquery, "enddate",
rosfran@698
   421
        gmyth_util_time_to_string_only_date (schedule_info->end_time), rec_id);
melunko@567
   422
    /// category, series id, program id
melunko@567
   423
    //_set_value (scheduler->msqlquery, "findday", (gmyth_util_time_val_to_date( schedule_info->start_time ))->tm_wday, rec_id);
melunko@567
   424
    //_set_value (scheduler->msqlquery, "findtime", gmyth_util_time_to_string_only_time( schedule_info->start_time), rec_id);
melunko@567
   425
    //_set_int_value (scheduler->msqlquery, "findid", (gint)(schedule_info->start_time->tv_sec/60/60/24 + 719528), rec_id);
melunko@567
   426
    _set_value (scheduler->msqlquery, "parentid", "0", rec_id);
melunko@567
   427
    _set_value (scheduler->msqlquery, "search", "0", rec_id);
melunko@567
   428
    _set_value (scheduler->msqlquery, "type", "1", rec_id);
melunko@567
   429
    _set_value (scheduler->msqlquery, "recpriority", "0", rec_id);
melunko@567
   430
    _set_value (scheduler->msqlquery, "startoffset", "0", rec_id);
melunko@567
   431
    _set_value (scheduler->msqlquery, "endoffset", "0", rec_id);
rosfran@698
   432
    _set_value (scheduler->msqlquery, "dupmethod", "6", rec_id);    // ?
rosfran@698
   433
    _set_value (scheduler->msqlquery, "dupin", "15", rec_id);   // ?
melunko@567
   434
melunko@567
   435
    _set_value (scheduler->msqlquery, "prefinput", "0", rec_id);
melunko@567
   436
    _set_value (scheduler->msqlquery, "inactive", "0", rec_id);
melunko@567
   437
    _set_value (scheduler->msqlquery, "profile", "Default", rec_id);
melunko@567
   438
    _set_value (scheduler->msqlquery, "recgroup", "Default", rec_id);
melunko@567
   439
    _set_value (scheduler->msqlquery, "storagegroup", "Default", rec_id);
melunko@567
   440
    _set_value (scheduler->msqlquery, "playgroup", "Default", rec_id);
melunko@567
   441
    _set_value (scheduler->msqlquery, "autoexpire", "1", rec_id);
melunko@567
   442
    _set_value (scheduler->msqlquery, "maxepisodes", "0", rec_id);
melunko@567
   443
    _set_value (scheduler->msqlquery, "maxnewest", "0", rec_id);
melunko@567
   444
    _set_value (scheduler->msqlquery, "autocommflag", "1", rec_id);
melunko@567
   445
    _set_value (scheduler->msqlquery, "autotranscode", "0", rec_id);
melunko@567
   446
    _set_value (scheduler->msqlquery, "transcoder", "0", rec_id);
melunko@567
   447
melunko@567
   448
    _set_value (scheduler->msqlquery, "autouserjob1", "0", rec_id);
melunko@567
   449
    _set_value (scheduler->msqlquery, "autouserjob2", "0", rec_id);
melunko@567
   450
    _set_value (scheduler->msqlquery, "autouserjob3", "0", rec_id);
melunko@567
   451
    _set_value (scheduler->msqlquery, "autouserjob4", "0", rec_id);
melunko@567
   452
melunko@592
   453
    schedule_info->schedule_id = rec_id;
melunko@581
   454
leo_sobral@1
   455
    /* Notify the backend of changes */
rosfran@698
   456
    return update_backend (scheduler, rec_id);
leo_sobral@1
   457
}
leo_sobral@1
   458
leo_sobral@1
   459
/** Requests the Mysql database in the backend to remove an existing schedule.
leo_sobral@1
   460
 * 
leo_sobral@1
   461
 * @param scheduler the GMythScheduler instance.
leo_sobral@1
   462
 * @param record_id The schedule's record id to be removed
leo_sobral@1
   463
 * @return gboolean TRUE if success, FALSE if error
leo_sobral@1
   464
 */
leo_sobral@1
   465
gboolean
rosfran@698
   466
gmyth_scheduler_delete_schedule (GMythScheduler * scheduler, gint record_id)
leo_sobral@1
   467
{
leo_sobral@1
   468
melunko@117
   469
    MYSQL_RES *msql_res;
leo_sobral@1
   470
    GString *query_str = g_string_new ("");
leo_sobral@1
   471
rosfran@698
   472
    assert (scheduler);
rosfran@698
   473
melunko@117
   474
    if (scheduler->msqlquery == NULL) {
rosfran@698
   475
        g_warning ("[%s] Scheduler db connection not initialized",
rosfran@698
   476
            __FUNCTION__);
leo_sobral@387
   477
        return FALSE;
melunko@117
   478
    }
rosfran@698
   479
    //========================================
rosfran@698
   480
    g_string_printf (query_str,
rosfran@698
   481
        "DELETE FROM record WHERE recordid=%d", record_id);
leo_sobral@1
   482
rosfran@698
   483
    msql_res =
rosfran@698
   484
        gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
leo_sobral@1
   485
leo_sobral@1
   486
leo_sobral@1
   487
    mysql_free_result (msql_res);
rosfran@698
   488
    g_string_free (query_str, TRUE);
rosfran@698
   489
melunko@567
   490
    // Notify the backend of the changes
rosfran@698
   491
    return update_backend (scheduler, record_id);
leo_sobral@1
   492
}
leo_sobral@1
   493
leo_sobral@1
   494
/** Requests the Mysql database in the backend to remove an existing recorded item.
leo_sobral@1
   495
 * 
leo_sobral@1
   496
 * @param scheduler the GMythScheduler instance.
leo_sobral@1
   497
 * @param record_id The recorded item id to be removed
leo_sobral@1
   498
 * @return gboolean TRUE if success, FALSE if error
leo_sobral@1
   499
 */
leo_sobral@1
   500
gboolean
rosfran@698
   501
gmyth_scheduler_delete_recorded (GMythScheduler * scheduler, gint record_id)
leo_sobral@1
   502
{
leo_sobral@1
   503
melunko@117
   504
    MYSQL_RES *msql_res;
melunko@117
   505
leo_sobral@1
   506
    GString *query_str = g_string_new ("");
leo_sobral@1
   507
rosfran@698
   508
    assert (scheduler);
rosfran@698
   509
leo_sobral@390
   510
    if (scheduler->msqlquery == NULL) {
rosfran@698
   511
        g_warning ("[%s] Scheduler db connection not initialized",
rosfran@698
   512
            __FUNCTION__);
leo_sobral@390
   513
        return FALSE;
leo_sobral@390
   514
    }
leo_sobral@1
   515
    //========================================
rosfran@698
   516
    g_string_printf (query_str,
rosfran@698
   517
        "DELETE FROM recorded WHERE recordid=%d", record_id);
leo_sobral@1
   518
melunko@526
   519
    // FIXME: Mythtv implementation runs also: DELETE FROM oldfind WHERE recordid = x
melunko@526
   520
rosfran@698
   521
    msql_res =
rosfran@698
   522
        gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
rosfran@698
   523
leo_sobral@1
   524
    mysql_free_result (msql_res);
rosfran@698
   525
    g_string_free (query_str, TRUE);
rosfran@698
   526
melunko@567
   527
    // Notify the backend of the changes
rosfran@698
   528
    return update_backend (scheduler, record_id);
leo_sobral@1
   529
}
leo_sobral@1
   530
leo_sobral@1
   531
/** Retrieves an existing recorded item information from database. The information
leo_sobral@1
   532
 * is used to fill the returned GMythProgramInfo.
leo_sobral@1
   533
 * 
leo_sobral@1
   534
 * @param scheduler The GMythScheduler instance.
leo_sobral@1
   535
 * @param channel The channel associated to the record
leo_sobral@1
   536
 * @param starttime The record start time
leo_sobral@1
   537
 * @return A GMythProgramInfo struct with the requested record item
leo_sobral@1
   538
 * information, or NULL if error.
leo_sobral@1
   539
 */
rosfran@698
   540
GMythProgramInfo *
rosfran@698
   541
gmyth_scheduler_get_recorded (GMythScheduler * scheduler,
rosfran@698
   542
    GString * channel, GTimeVal * starttime)
leo_sobral@1
   543
{
leo_sobral@390
   544
    MYSQL_RES *msql_res;
leo_sobral@390
   545
    GMythProgramInfo *proginfo = NULL;
rosfran@698
   546
    GString *query_str = g_string_new ("");
leo_sobral@390
   547
    gchar *time_str = gmyth_util_time_to_string_from_time_val (starttime);
leo_sobral@1
   548
rosfran@698
   549
    assert (scheduler);
melunko@412
   550
melunko@412
   551
    gmyth_debug ("[%s] channel: %s", __FUNCTION__, channel->str);
rosfran@698
   552
leo_sobral@390
   553
    if (scheduler->msqlquery == NULL) {
rosfran@698
   554
        g_warning ("[%s] Scheduler db connection not initialized",
rosfran@698
   555
            __FUNCTION__);
leo_sobral@390
   556
        return NULL;
leo_sobral@390
   557
    }
leo_sobral@1
   558
rosfran@698
   559
    g_string_printf (query_str,
rosfran@698
   560
        "SELECT recorded.chanid,starttime,endtime,title, "
rosfran@698
   561
        "subtitle,description,channel.channum, "
rosfran@698
   562
        "channel.callsign,channel.name,channel.commfree, "
rosfran@698
   563
        "channel.outputfilters,seriesid,programid,filesize, "
rosfran@698
   564
        "lastmodified,stars,previouslyshown,originalairdate, "
rosfran@698
   565
        "hostname,recordid,transcoder,playgroup, "
rosfran@698
   566
        "recorded.recpriority,progstart,progend,basename,recgroup "
rosfran@698
   567
        "FROM recorded " "LEFT JOIN channel "
rosfran@698
   568
        "ON recorded.chanid = channel.chanid "
rosfran@698
   569
        "WHERE recorded.chanid = \"%s\" "
rosfran@698
   570
        "AND starttime = \"%s\" ;", channel->str, time_str);
leo_sobral@1
   571
rosfran@698
   572
    msql_res =
rosfran@698
   573
        gmyth_query_process_statement (scheduler->msqlquery, query_str->str);
leo_sobral@1
   574
rosfran@698
   575
    if (msql_res /*&& query.size() > 0 */ ) {
leo_sobral@391
   576
        MYSQL_ROW msql_row = mysql_fetch_row (msql_res);
rosfran@698
   577
leo_sobral@391
   578
        if (msql_row) {
rosfran@698
   579
            proginfo = gmyth_program_info_new ();
leo_sobral@1
   580
leo_sobral@391
   581
            proginfo->chanid = g_string_new (msql_row[0]);
leo_sobral@391
   582
            proginfo->startts = gmyth_util_string_to_time_val (msql_row[23]);
leo_sobral@391
   583
            proginfo->endts = gmyth_util_string_to_time_val (msql_row[24]);
leo_sobral@391
   584
            proginfo->recstartts = gmyth_util_string_to_time_val (msql_row[1]);
leo_sobral@391
   585
            proginfo->recendts = gmyth_util_string_to_time_val (msql_row[2]);
leo_sobral@391
   586
            proginfo->title = g_string_new (msql_row[3]);
leo_sobral@391
   587
            proginfo->subtitle = g_string_new (msql_row[4]);
leo_sobral@391
   588
            proginfo->description = g_string_new (msql_row[5]);
leo_sobral@390
   589
leo_sobral@391
   590
            proginfo->chanstr = g_string_new (msql_row[6]);
leo_sobral@391
   591
            proginfo->chansign = g_string_new (msql_row[7]);
leo_sobral@391
   592
            proginfo->channame = g_string_new (msql_row[0]);
rosfran@698
   593
            proginfo->chancommfree =
rosfran@698
   594
                (gint) g_ascii_strtoull (msql_row[9], NULL, 10);
leo_sobral@391
   595
            proginfo->chanOutputFilters = g_string_new (msql_row[10]);
leo_sobral@391
   596
            proginfo->seriesid = g_string_new (msql_row[11]);
leo_sobral@391
   597
            proginfo->programid = g_string_new (msql_row[12]);
leo_sobral@391
   598
            proginfo->filesize = g_ascii_strtoull (msql_row[13], NULL, 10);
leo_sobral@1
   599
rosfran@698
   600
            proginfo->lastmodified =
rosfran@698
   601
                gmyth_util_string_to_time_val (msql_row[14]);
leo_sobral@391
   602
            proginfo->stars = g_ascii_strtod (msql_row[15], NULL);
leo_sobral@391
   603
            proginfo->repeat = (gint) g_ascii_strtoull (msql_row[16], NULL, 10);
leo_sobral@390
   604
leo_sobral@391
   605
            if (msql_row[17] == NULL) {
leo_sobral@391
   606
                proginfo->originalAirDate = 0;
leo_sobral@391
   607
                proginfo->hasAirDate = FALSE;
leo_sobral@391
   608
            } else {
rosfran@698
   609
                proginfo->originalAirDate =
rosfran@698
   610
                    gmyth_util_string_to_time_val (msql_row[17]);
leo_sobral@391
   611
                proginfo->hasAirDate = TRUE;
leo_sobral@391
   612
            }
leo_sobral@390
   613
rosfran@698
   614
            proginfo->hostname = g_string_new (msql_row[18]);
rosfran@698
   615
            proginfo->recordid =
rosfran@698
   616
                (gint) g_ascii_strtoull (msql_row[19], NULL, 10);
rosfran@698
   617
            proginfo->transcoder =
rosfran@698
   618
                (gint) g_ascii_strtoull (msql_row[20], NULL, 10);
leo_sobral@391
   619
            //proginfo->spread = -1;
leo_sobral@391
   620
            //proginfo->programflags = proginfo->getProgramFlags();
leo_sobral@391
   621
leo_sobral@391
   622
            proginfo->recgroup = g_string_new (msql_row[26]);
leo_sobral@391
   623
            proginfo->playgroup = g_string_new (msql_row[21]);
rosfran@698
   624
            proginfo->recpriority =
rosfran@698
   625
                (gint) g_ascii_strtoull (msql_row[22], NULL, 10);
leo_sobral@391
   626
rosfran@698
   627
            proginfo->pathname = g_string_new (g_strdup (msql_row[25]));
leo_sobral@391
   628
leo_sobral@391
   629
            gmyth_debug ("One program info loaded from mysql database\n");
leo_sobral@391
   630
        }
leo_sobral@1
   631
    }
leo_sobral@1
   632
melunko@313
   633
    mysql_free_result (msql_res);
rosfran@698
   634
    g_string_free (query_str, TRUE);
rosfran@698
   635
    g_free (time_str);
leo_sobral@1
   636
leo_sobral@1
   637
    return proginfo;
leo_sobral@1
   638
}
leo_sobral@1
   639
leo_sobral@1
   640
/** Retrieves the next record id.
leo_sobral@1
   641
 * 
leo_sobral@1
   642
 * @param scheduler The GMythScheduler instance.
leo_sobral@1
   643
 * @return gint record_id if success, -1 otherwise 
leo_sobral@1
   644
 */
leo_sobral@1
   645
static gint
rosfran@698
   646
get_record_id_from_database (GMythScheduler * scheduler)
leo_sobral@1
   647
{
leo_sobral@1
   648
    gint record_id;
leo_sobral@1
   649
rosfran@698
   650
    assert (scheduler);
rosfran@698
   651
leo_sobral@390
   652
    if (scheduler->msqlquery == NULL) {
rosfran@698
   653
        g_warning ("[%s] Scheduler db connection not initialized",
rosfran@698
   654
            __FUNCTION__);
leo_sobral@390
   655
        return 0;
leo_sobral@390
   656
    }
leo_sobral@1
   657
leo_sobral@1
   658
    record_id = mysql_insert_id (scheduler->msqlquery->conn);
leo_sobral@1
   659
leo_sobral@390
   660
    return record_id;
rosfran@698
   661
}
rosfran@698
   662
leo_sobral@1
   663
/** Notifies the backend of an update in the db.
leo_sobral@1
   664
 * 
leo_sobral@1
   665
 * @param record_id the id of the modified recording.
leo_sobral@1
   666
 */
melunko@567
   667
static gboolean
rosfran@698
   668
update_backend (GMythScheduler * scheduler, gint record_id) //fixme: put void and discovery record_id inside
leo_sobral@1
   669
{
melunko@117
   670
    GMythSocket *socket;
leo_sobral@1
   671
    GMythStringList *strlist = gmyth_string_list_new ();
leo_sobral@1
   672
    GString *datastr = g_string_new ("RESCHEDULE_RECORDINGS ");
melunko@567
   673
    gboolean ret = FALSE;
leo_sobral@1
   674
leo_sobral@1
   675
    g_string_append_printf (datastr, "%d", record_id);
leo_sobral@1
   676
    gmyth_string_list_append_string (strlist, datastr);
leo_sobral@1
   677
melunko@276
   678
    socket = gmyth_socket_new ();
rosfran@698
   679
    if (gmyth_socket_connect_to_backend
rosfran@698
   680
        (socket, scheduler->backend_info->hostname,
rosfran@698
   681
            scheduler->backend_info->port, TRUE)) {
melunko@567
   682
        ret = (gmyth_socket_sendreceive_stringlist (socket, strlist) > 0);
melunko@117
   683
    } else {
leo_sobral@387
   684
        g_warning ("[%s] Connection to backend failed!", __FUNCTION__);
melunko@117
   685
    }
rosfran@698
   686
rosfran@698
   687
    g_string_free (datastr, TRUE);
rosfran@698
   688
    g_object_unref (strlist);
melunko@567
   689
melunko@567
   690
    return ret;
leo_sobral@1
   691
}
renatofilho@129
   692
renatofilho@129
   693
void
rosfran@698
   694
gmyth_scheduler_recorded_info_get_preview (RecordedInfo * info,
rosfran@698
   695
    GByteArray * data)
renatofilho@129
   696
{
renatofilho@129
   697
}
renatofilho@129
   698
renatofilho@129
   699
void
rosfran@698
   700
gmyth_recorded_info_free (RecordedInfo * info)
renatofilho@129
   701
{
renatofilho@129
   702
    if (info->title != NULL)
renatofilho@129
   703
        g_string_free (info->title, TRUE);
renatofilho@129
   704
renatofilho@129
   705
    if (info->subtitle != NULL)
renatofilho@129
   706
        g_string_free (info->subtitle, TRUE);
renatofilho@129
   707
renatofilho@129
   708
    if (info->description != NULL)
renatofilho@129
   709
        g_string_free (info->description, TRUE);
renatofilho@129
   710
renatofilho@129
   711
    if (info->category != NULL)
renatofilho@129
   712
        g_string_free (info->category, TRUE);
renatofilho@129
   713
renatofilho@129
   714
    if (info->basename != NULL)
renatofilho@129
   715
        g_string_free (info->basename, TRUE);
renatofilho@129
   716
leo_sobral@387
   717
    if (info != NULL)
leo_sobral@387
   718
        g_free (info->start_time);
leo_sobral@387
   719
leo_sobral@387
   720
    if (info != NULL)
leo_sobral@387
   721
        g_free (info->end_time);
leo_sobral@387
   722
renatofilho@129
   723
    g_free (info);
renatofilho@129
   724
}
renatofilho@129
   725
melunko@591
   726
static void
melunko@591
   727
free_recorded_info_item (gpointer data, gpointer user_data)
melunko@591
   728
{
rosfran@698
   729
    RecordedInfo *info = (RecordedInfo *) data;
melunko@591
   730
melunko@591
   731
    gmyth_recorded_info_free (info);
melunko@591
   732
}
melunko@591
   733
renatofilho@129
   734
void
rosfran@698
   735
gmyth_recorded_info_list_free (GList * list)
renatofilho@129
   736
{
melunko@591
   737
    g_return_if_fail (list != NULL);
melunko@591
   738
melunko@591
   739
    g_list_foreach (list, free_recorded_info_item, NULL);
melunko@591
   740
    g_list_free (list);
melunko@591
   741
}
melunko@591
   742
melunko@591
   743
void
rosfran@698
   744
gmyth_schedule_info_free (ScheduleInfo * info)
melunko@591
   745
{
melunko@591
   746
melunko@591
   747
    g_return_if_fail (info != NULL);
melunko@591
   748
renatofilho@129
   749
    if (info->title != NULL)
renatofilho@129
   750
        g_string_free (info->title, TRUE);
renatofilho@129
   751
renatofilho@129
   752
    if (info->subtitle != NULL)
renatofilho@129
   753
        g_string_free (info->subtitle, TRUE);
renatofilho@129
   754
renatofilho@129
   755
    if (info->description != NULL)
renatofilho@129
   756
        g_string_free (info->description, TRUE);
renatofilho@129
   757
renatofilho@129
   758
    if (info->category != NULL)
renatofilho@129
   759
        g_string_free (info->category, TRUE);
renatofilho@129
   760
leo_sobral@387
   761
    if (info != NULL)
leo_sobral@387
   762
        g_free (info->start_time);
leo_sobral@387
   763
leo_sobral@387
   764
    if (info != NULL)
leo_sobral@387
   765
        g_free (info->end_time);
leo_sobral@387
   766
renatofilho@129
   767
    g_free (info);
renatofilho@129
   768
}
renatofilho@129
   769
melunko@591
   770
static void
melunko@591
   771
free_schedule_info_item (gpointer data, gpointer user_data)
melunko@591
   772
{
rosfran@698
   773
    ScheduleInfo *info = (ScheduleInfo *) data;
melunko@591
   774
melunko@591
   775
    gmyth_schedule_info_free (info);
melunko@591
   776
}
melunko@591
   777
melunko@591
   778
void
rosfran@698
   779
gmyth_schedule_info_list_free (GList * list)
melunko@591
   780
{
melunko@591
   781
    g_return_if_fail (list != NULL);
melunko@591
   782
melunko@591
   783
    g_list_foreach (list, free_schedule_info_item, NULL);
melunko@591
   784
    g_list_free (list);
melunko@591
   785
}