gmyth/gmyth/gmyth_scheduler.c
author melunko
Thu Mar 13 16:29:38 2008 +0000 (2008-03-13)
branchtrunk
changeset 942 c93bfa74c71f
parent 939 1418e08cee7a
child 944 ec1d5934d8e8
permissions -rw-r--r--
[svn r951] gmyth now is 0.8.1. Added methods epg_is_connected() and scheduler_is_connected()
leo_sobral@1
     1
/**
leo_sobral@1
     2
 * GMyth Library
leo_sobral@1
     3
 *
leo_sobral@1
     4
 * @file gmyth/gmyth_scheduler.c
renatofilho@771
     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
 *
renatofilho@771
    12
 *
rosfran@701
    13
 * This program is free software; you can redistribute it and/or modify
rosfran@701
    14
 * it under the terms of the GNU Lesser General Public License as published by
rosfran@701
    15
 * the Free Software Foundation; either version 2 of the License, or
rosfran@701
    16
 * (at your option) any later version.
rosfran@701
    17
 *
rosfran@701
    18
 * This program is distributed in the hope that it will be useful,
rosfran@701
    19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
rosfran@701
    20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
rosfran@701
    21
 * GNU General Public License for more details.
rosfran@701
    22
 *
rosfran@701
    23
 * You should have received a copy of the GNU Lesser General Public License
rosfran@701
    24
 * along with this program; if not, write to the Free Software
rosfran@701
    25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
rosfran@701
    26
 */
rosfran@698
    27
leo_sobral@213
    28
#ifdef HAVE_CONFIG_H
leo_sobral@213
    29
#include "config.h"
leo_sobral@213
    30
#endif
leo_sobral@1
    31
leo_sobral@213
    32
#include <assert.h>
leo_sobral@1
    33
renatofilho@890
    34
#include <glib.h>
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"
melunko@934
    42
#include "gmyth_remote_util.h"
leo_sobral@1
    43
renatofilho@754
    44
static void     gmyth_scheduler_class_init(GMythSchedulerClass * klass);
renatofilho@754
    45
static void     gmyth_scheduler_init(GMythScheduler * object);
leo_sobral@1
    46
renatofilho@754
    47
static void     gmyth_scheduler_dispose(GObject * object);
renatofilho@754
    48
static void     gmyth_scheduler_finalize(GObject * object);
leo_sobral@1
    49
melunko@934
    50
melunko@934
    51
static gint
melunko@934
    52
gmyth_scheduler_is_program_live_recorded (GMythScheduler * scheduler,
melunko@934
    53
                                          ScheduleInfo *schedule_info,
melunko@934
    54
                                          GMythProgramInfo **prog_info);
melunko@934
    55
static gboolean
melunko@934
    56
gmyth_scheduler_set_live_record (GMythScheduler * scheduler,
melunko@934
    57
                                ScheduleInfo * schedule_info,
melunko@934
    58
                                gint recorder_num, gboolean enable);
melunko@934
    59
static gboolean
melunko@934
    60
gmyth_scheduler_change_record_group (GMythScheduler* scheduler,
melunko@934
    61
                                     GMythProgramInfo *prog_info,
melunko@934
    62
                                     gchar *new_group);
melunko@934
    63
melunko@935
    64
static gint
melunko@935
    65
gmyth_scheduler_query_schedule_list (GMythScheduler * scheduler,
melunko@935
    66
                                     GList ** schedule_list,
melunko@935
    67
                                     gchar *filter);
melunko@939
    68
static gint 
melunko@939
    69
gmyth_scheduler_query_schedule_id (GMythScheduler *scheduler,
melunko@939
    70
                                   GMythProgramInfo *prog_info);
melunko@939
    71
static gint gmyth_scheduler_query_old_schedule (GMythScheduler *scheduler,
melunko@939
    72
                                    gint channel_id, GTimeVal *startts,
melunko@939
    73
                                    gboolean reactivate);
melunko@934
    74
renatofilho@750
    75
static gboolean update_backend(GMythScheduler * scheduler, gint record_id);
leo_sobral@1
    76
renatofilho@750
    77
G_DEFINE_TYPE(GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT)
renatofilho@754
    78
    static void     gmyth_scheduler_class_init(GMythSchedulerClass * klass)
leo_sobral@1
    79
{
renatofilho@754
    80
    GObjectClass   *gobject_class;
leo_sobral@1
    81
renatofilho@754
    82
    gobject_class = (GObjectClass *) klass;
leo_sobral@1
    83
renatofilho@754
    84
    gobject_class->dispose = gmyth_scheduler_dispose;
renatofilho@754
    85
    gobject_class->finalize = gmyth_scheduler_finalize;
leo_sobral@1
    86
}
leo_sobral@1
    87
leo_sobral@1
    88
static void
renatofilho@750
    89
gmyth_scheduler_init(GMythScheduler * sched)
leo_sobral@1
    90
{
renatofilho@754
    91
    sched->recordid = 0;
renatofilho@754
    92
    sched->type = 0;
renatofilho@754
    93
    sched->search = 0;
renatofilho@754
    94
    sched->profile = g_string_new("");
rosfran@698
    95
renatofilho@754
    96
    sched->dupin = 0;
renatofilho@754
    97
    sched->dupmethod = 0;
renatofilho@754
    98
    sched->autoexpire = 0;
renatofilho@754
    99
    sched->autotranscode = 0;
renatofilho@754
   100
    sched->transcoder = 0;
leo_sobral@1
   101
renatofilho@754
   102
    sched->autocommflag = 0;
renatofilho@754
   103
    sched->autouserjob1 = 0;
renatofilho@754
   104
    sched->autouserjob2 = 0;
renatofilho@754
   105
    sched->autouserjob3 = 0;
renatofilho@754
   106
    sched->autouserjob4 = 0;
rosfran@698
   107
renatofilho@754
   108
    sched->startoffset = 0;
renatofilho@754
   109
    sched->endoffset = 0;
renatofilho@754
   110
    sched->maxepisodes = 0;
renatofilho@754
   111
    sched->maxnewest = 0;
leo_sobral@1
   112
renatofilho@754
   113
    sched->recpriority = 0;
renatofilho@754
   114
    sched->recgroup = g_string_new("");
renatofilho@754
   115
    sched->playgroup = g_string_new("");
rosfran@698
   116
renatofilho@754
   117
    sched->prefinput = 0;
renatofilho@754
   118
    sched->inactive = 0;
rosfran@698
   119
renatofilho@754
   120
    sched->search_type = g_string_new("");
renatofilho@754
   121
    sched->search_what = g_string_new("");
rosfran@698
   122
renatofilho@754
   123
    sched->msqlquery = gmyth_query_new();
leo_sobral@1
   124
}
leo_sobral@1
   125
leo_sobral@1
   126
static void
renatofilho@750
   127
gmyth_scheduler_dispose(GObject * object)
leo_sobral@1
   128
{
renatofilho@754
   129
    GMythScheduler *scheduler = GMYTH_SCHEDULER(object);
melunko@117
   130
renatofilho@754
   131
    if (scheduler->backend_info) {
renatofilho@754
   132
        g_object_unref(scheduler->backend_info);
renatofilho@754
   133
        scheduler->backend_info = NULL;
renatofilho@754
   134
    }
melunko@117
   135
renatofilho@754
   136
    if (scheduler->msqlquery) {
renatofilho@754
   137
        g_object_unref(scheduler->msqlquery);
renatofilho@754
   138
        scheduler->msqlquery = NULL;
renatofilho@754
   139
    }
leo_sobral@387
   140
renatofilho@754
   141
    g_string_free(scheduler->profile, TRUE);
renatofilho@754
   142
    g_string_free(scheduler->recgroup, TRUE);
renatofilho@754
   143
    g_string_free(scheduler->playgroup, TRUE);
renatofilho@754
   144
    g_string_free(scheduler->search_type, TRUE);
renatofilho@754
   145
    g_string_free(scheduler->search_what, TRUE);
leo_sobral@387
   146
renatofilho@754
   147
    G_OBJECT_CLASS(gmyth_scheduler_parent_class)->dispose(object);
leo_sobral@1
   148
}
leo_sobral@1
   149
leo_sobral@1
   150
static void
renatofilho@750
   151
gmyth_scheduler_finalize(GObject * object)
leo_sobral@1
   152
{
renatofilho@754
   153
    g_signal_handlers_destroy(object);
leo_sobral@1
   154
renatofilho@754
   155
    G_OBJECT_CLASS(gmyth_scheduler_parent_class)->finalize(object);
leo_sobral@1
   156
}
leo_sobral@1
   157
leo_sobral@1
   158
/** Creates a new instance of GMythScheduler.
leo_sobral@1
   159
 * 
leo_sobral@1
   160
 * @return a new instance of GMythScheduler.
leo_sobral@1
   161
 */
rosfran@698
   162
GMythScheduler *
renatofilho@750
   163
gmyth_scheduler_new()
leo_sobral@1
   164
{
renatofilho@754
   165
    GMythScheduler *scheduler =
renatofilho@754
   166
        GMYTH_SCHEDULER(g_object_new(GMYTH_SCHEDULER_TYPE, NULL));
rosfran@698
   167
renatofilho@754
   168
    return scheduler;
leo_sobral@1
   169
}
leo_sobral@1
   170
melunko@257
   171
gboolean
renatofilho@750
   172
gmyth_scheduler_connect(GMythScheduler * scheduler,
renatofilho@754
   173
                        GMythBackendInfo * backend_info)
melunko@257
   174
{
renatofilho@754
   175
    return gmyth_scheduler_connect_with_timeout(scheduler, backend_info,
renatofilho@754
   176
                                                0);
melunko@257
   177
}
melunko@257
   178
leo_sobral@1
   179
/** Connects to the Mysql database in the backend. The backend address
leo_sobral@1
   180
 * is loaded from the GMythSettings instance.
morphbr@766
   181
 *
leo_sobral@1
   182
 * @param scheduler the GMythScheduler instance to be connected.
leo_sobral@1
   183
 * @return true if connection was success, false if failed.
leo_sobral@1
   184
 */
leo_sobral@1
   185
gboolean
renatofilho@750
   186
gmyth_scheduler_connect_with_timeout(GMythScheduler * scheduler,
renatofilho@754
   187
                                     GMythBackendInfo * backend_info,
renatofilho@754
   188
                                     guint timeout)
leo_sobral@1
   189
{
renatofilho@754
   190
    assert(scheduler);
renatofilho@754
   191
    g_return_val_if_fail(backend_info != NULL, FALSE);
rosfran@698
   192
renatofilho@754
   193
    if (scheduler->backend_info)
renatofilho@754
   194
        g_object_unref(scheduler->backend_info);
rosfran@698
   195
renatofilho@754
   196
    scheduler->backend_info = g_object_ref(backend_info);
leo_sobral@1
   197
renatofilho@754
   198
    if (scheduler->msqlquery == NULL) {
renatofilho@754
   199
        g_warning("[%s] GMythScheduler db initializing", __FUNCTION__);
renatofilho@754
   200
        scheduler->msqlquery = gmyth_query_new();
renatofilho@754
   201
    }
leo_sobral@1
   202
renatofilho@754
   203
    if (!gmyth_query_connect_with_timeout(scheduler->msqlquery,
renatofilho@754
   204
                                          scheduler->backend_info,
renatofilho@754
   205
                                          timeout)) {
renatofilho@754
   206
        g_warning("[%s] Error while connecting to db", __FUNCTION__);
renatofilho@754
   207
        return FALSE;
renatofilho@754
   208
    }
leo_sobral@1
   209
renatofilho@754
   210
    return TRUE;
leo_sobral@1
   211
}
leo_sobral@1
   212
melunko@942
   213
gboolean
melunko@942
   214
gmyth_scheduler_is_connected (GMythScheduler *scheduler)
melunko@942
   215
{
melunko@942
   216
    g_return_val_if_fail (scheduler != NULL, FALSE);
melunko@942
   217
melunko@942
   218
    return gmyth_query_is_alive (scheduler->msqlquery);
melunko@942
   219
}
melunko@942
   220
leo_sobral@1
   221
/** Disconnects from the Mysql database in the backend.
morphbr@766
   222
 *
leo_sobral@1
   223
 * @param scheduler the GMythScheduler instance to be disconnected
leo_sobral@1
   224
 * @return true if disconnection was success, false if failed.
leo_sobral@1
   225
 */
leo_sobral@1
   226
gboolean
renatofilho@750
   227
gmyth_scheduler_disconnect(GMythScheduler * scheduler)
leo_sobral@1
   228
{
renatofilho@754
   229
    assert(scheduler);
leo_sobral@1
   230
renatofilho@754
   231
    if (scheduler->msqlquery != NULL) {
renatofilho@754
   232
        gmyth_query_disconnect(scheduler->msqlquery);
renatofilho@754
   233
    }
leo_sobral@1
   234
renatofilho@754
   235
    return TRUE;
leo_sobral@1
   236
}
leo_sobral@1
   237
leo_sobral@1
   238
/** Retrieves from the backend Mysql database the list of recording schedules.
leo_sobral@1
   239
 * 
leo_sobral@1
   240
 * @param scheduler The GMythScheduler instance.
leo_sobral@1
   241
 * @param schedule_list the GList pointer to be filled with the loaded list of ScheduleInfo items.
leo_sobral@1
   242
 * @return The amount of schedules retrieved from database, or -1 if error.
leo_sobral@1
   243
 */
leo_sobral@1
   244
gint
melunko@935
   245
gmyth_scheduler_get_schedule_list (GMythScheduler * scheduler,
melunko@935
   246
                                   GList ** schedule_list)
leo_sobral@1
   247
{
melunko@935
   248
    return gmyth_scheduler_query_schedule_list (scheduler, schedule_list, NULL);
melunko@935
   249
}
melunko@935
   250
melunko@935
   251
ScheduleInfo*
melunko@935
   252
gmyth_scheduler_get_schedule (GMythScheduler * scheduler, gint sched_id)
melunko@935
   253
{
melunko@935
   254
    GList *sched_list = NULL;
melunko@935
   255
    ScheduleInfo *schedule = NULL;
melunko@935
   256
    gchar *filter;
melunko@935
   257
    gint count;
melunko@935
   258
melunko@935
   259
    filter = g_strdup_printf ("WHERE recordid=%d", sched_id);
melunko@935
   260
melunko@935
   261
    count = gmyth_scheduler_query_schedule_list (scheduler, &sched_list, filter);
melunko@935
   262
    if ((count > 0) && (sched_list != NULL)) {
melunko@935
   263
        schedule = (ScheduleInfo*) sched_list->data;
melunko@935
   264
	g_list_free (sched_list);
melunko@935
   265
    }
melunko@935
   266
melunko@935
   267
    g_free (filter);
melunko@935
   268
    return schedule;
melunko@935
   269
}
melunko@935
   270
melunko@935
   271
static gint
melunko@935
   272
gmyth_scheduler_query_schedule_list (GMythScheduler * scheduler,
melunko@935
   273
		                     GList ** schedule_list,
melunko@935
   274
				     gchar *filter)
melunko@935
   275
{
melunko@935
   276
	
renatofilho@754
   277
    ScheduleInfo   *schedule;
renatofilho@754
   278
    MYSQL_RES      *msql_res;
renatofilho@754
   279
    GString        *query_str = g_string_new("");
renatofilho@754
   280
    gchar          *date_time = NULL;
rosfran@698
   281
renatofilho@754
   282
    assert(scheduler);
renatofilho@754
   283
    if (scheduler->msqlquery == NULL) {
renatofilho@754
   284
        g_warning("[%s] Scheduler db connection not initialized",
renatofilho@754
   285
                  __FUNCTION__);
renatofilho@754
   286
        return -1;
renatofilho@754
   287
    }
melunko@935
   288
melunko@935
   289
    if (filter == NULL) {
melunko@935
   290
        g_string_printf(query_str,
melunko@935
   291
                        "SELECT recordid,programid,chanid,starttime,startdate,"
melunko@935
   292
                        "endtime,enddate,title,subtitle,description,category,type,parentid,seriesid FROM record;");
melunko@935
   293
    } else {
melunko@935
   294
        g_string_printf(query_str,
melunko@935
   295
                        "SELECT recordid,programid,chanid,starttime,startdate,"
melunko@935
   296
                        "endtime,enddate,title,subtitle,description,category,type,parentid,seriesid FROM record "
melunko@935
   297
			"%s;", filter);
melunko@935
   298
melunko@935
   299
    }
melunko@935
   300
renatofilho@754
   301
    msql_res =
renatofilho@754
   302
        gmyth_query_process_statement(scheduler->msqlquery,
renatofilho@754
   303
                                      query_str->str);
leo_sobral@1
   304
renatofilho@754
   305
    if (msql_res == NULL) {
renatofilho@754
   306
        g_warning("DB retrieval of schedule list failed");
renatofilho@754
   307
        return -1;
renatofilho@754
   308
    } else {
renatofilho@754
   309
        MYSQL_ROW       row;
rosfran@698
   310
renatofilho@754
   311
        *schedule_list = NULL;
rosfran@698
   312
renatofilho@754
   313
        while ((row = mysql_fetch_row(msql_res)) != NULL) {
renatofilho@754
   314
            schedule = g_new0(ScheduleInfo, 1);
melunko@836
   315
            gint type = 0;
rosfran@698
   316
renatofilho@754
   317
            schedule->schedule_id =
renatofilho@754
   318
                (guint) g_ascii_strtoull(row[0], NULL, 10);
renatofilho@895
   319
            schedule->program_id = g_string_new (row[1]);
renatofilho@895
   320
            schedule->channel_id = (gint) g_ascii_strtoull (row[2], NULL, 10);
rosfran@698
   321
renatofilho@754
   322
            /*
renatofilho@754
   323
             * generate a time_t from a time and a date db field 
renatofilho@754
   324
             */
renatofilho@754
   325
            date_time = g_strdup_printf("%sT%s", row[4], row[3]);
renatofilho@754
   326
            schedule->start_time =
renatofilho@754
   327
                gmyth_util_string_to_time_val(date_time);
renatofilho@754
   328
            g_free(date_time);
rosfran@698
   329
renatofilho@754
   330
            /*
renatofilho@754
   331
             * generate a time_t from a time and a date db field 
renatofilho@754
   332
             */
renatofilho@754
   333
            date_time = g_strdup_printf("%sT%s", row[6], row[5]);
renatofilho@754
   334
            schedule->end_time = gmyth_util_string_to_time_val(date_time);
renatofilho@754
   335
            g_free(date_time);
leo_sobral@1
   336
renatofilho@754
   337
            schedule->title = g_string_new(row[7]);
renatofilho@754
   338
            schedule->subtitle = g_string_new(row[8]);
renatofilho@754
   339
            schedule->description = g_string_new(row[9]);
renatofilho@754
   340
            schedule->category = g_string_new(row[10]);
melunko@836
   341
            type = g_ascii_strtoull (row[11], NULL, 10);
melunko@836
   342
            if (type == 4) {
melunko@836
   343
                schedule->type = GMYTH_SCHEDULE_ALL_OCCURRENCES;
melunko@836
   344
            } else if (type == 1) {
melunko@836
   345
                schedule->type = GMYTH_SCHEDULE_ONE_OCCURRENCE;
melunko@836
   346
            } else if (type == 8) {
melunko@836
   347
                schedule->type = GMYTH_SCHEDULE_EXCEPTION;
melunko@836
   348
                schedule->parentid = (gint) g_ascii_strtoull (row[12], NULL, 10);
melunko@836
   349
            }
leo_sobral@1
   350
renatofilho@886
   351
            schedule->seriesid = g_string_new (row[13]);
renatofilho@886
   352
renatofilho@754
   353
            (*schedule_list) = g_list_append(*(schedule_list), schedule);
renatofilho@754
   354
        }
renatofilho@754
   355
    }
leo_sobral@1
   356
renatofilho@754
   357
    mysql_free_result(msql_res);
renatofilho@754
   358
    g_string_free(query_str, TRUE);
leo_sobral@1
   359
renatofilho@754
   360
    return (*schedule_list == NULL) ? 0 : g_list_length(*schedule_list);
leo_sobral@1
   361
}
leo_sobral@1
   362
leo_sobral@1
   363
/** Retrieves from the backend Mysql database the list of recorded programs.
leo_sobral@1
   364
 * 
leo_sobral@1
   365
 * @param scheduler The GMythScheduler instance.
leo_sobral@1
   366
 * @param recorded_list the GList pointer to be filled with the loaded RecordInfo items.
leo_sobral@1
   367
 * @return The amount of recorded retrieved from database, or -1 if error.
leo_sobral@1
   368
 */
leo_sobral@1
   369
gint
renatofilho@750
   370
gmyth_scheduler_get_recorded_list(GMythScheduler * scheduler,
renatofilho@754
   371
                                  GList ** recorded_list)
leo_sobral@1
   372
{
renatofilho@754
   373
    RecordedInfo   *record;
renatofilho@754
   374
    MYSQL_RES      *msql_res;
renatofilho@754
   375
    GString        *query_str = g_string_new("");
rosfran@698
   376
renatofilho@754
   377
    assert(scheduler);
rosfran@698
   378
renatofilho@754
   379
    g_string_printf(query_str,
renatofilho@754
   380
                    "SELECT recordid,programid,chanid,starttime,progstart,"
renatofilho@754
   381
                    "endtime,progend,title,subtitle,description,category,"
renatofilho@886
   382
                    "filesize,basename,seriesid FROM recorded WHERE recgroup != 'LiveTV'");
leo_sobral@1
   383
renatofilho@754
   384
    if (scheduler->msqlquery == NULL) {
renatofilho@754
   385
        g_warning("[%s] Scheduler db connection not initialized",
renatofilho@754
   386
                  __FUNCTION__);
renatofilho@754
   387
        return -1;
renatofilho@754
   388
    }
leo_sobral@1
   389
renatofilho@754
   390
    msql_res =
renatofilho@754
   391
        gmyth_query_process_statement(scheduler->msqlquery,
renatofilho@754
   392
                                      query_str->str);
leo_sobral@1
   393
renatofilho@754
   394
    if (msql_res == NULL) {
renatofilho@754
   395
        g_warning("DB retrieval of recording list failed");
renatofilho@754
   396
        return -1;
renatofilho@754
   397
    } else {
renatofilho@754
   398
        MYSQL_ROW       row;
rosfran@698
   399
renatofilho@754
   400
        (*recorded_list) = NULL;
rosfran@698
   401
renatofilho@754
   402
        while ((row = mysql_fetch_row(msql_res)) != NULL) {
renatofilho@754
   403
            record = g_new0(RecordedInfo, 1);
rosfran@698
   404
renatofilho@754
   405
            record->record_id = (guint) g_ascii_strtoull(row[0], NULL, 10);
renatofilho@895
   406
            record->program_id = g_string_new (row[1]);
renatofilho@895
   407
            record->channel_id = (gint) g_ascii_strtoull(row[2], NULL, 10);
renatofilho@754
   408
            record->start_time = gmyth_util_string_to_time_val(row[3]);
renatofilho@754
   409
            record->end_time = gmyth_util_string_to_time_val(row[5]);
rosfran@698
   410
renatofilho@754
   411
            record->title = g_string_new(row[7]);
renatofilho@754
   412
            record->subtitle = g_string_new(row[8]);
renatofilho@754
   413
            record->description = g_string_new(row[9]);
renatofilho@754
   414
            record->category = g_string_new(row[10]);
renatofilho@754
   415
            record->filesize = g_ascii_strtoull(row[11], NULL, 10);
renatofilho@754
   416
            record->basename = g_string_new(row[12]);
renatofilho@886
   417
            record->seriesid = g_string_new(row[13]);
leo_sobral@1
   418
renatofilho@754
   419
            (*recorded_list) = g_list_append((*recorded_list), record);
renatofilho@754
   420
        }
renatofilho@754
   421
    }
rosfran@698
   422
renatofilho@754
   423
    mysql_free_result(msql_res);
renatofilho@754
   424
    g_string_free(query_str, TRUE);
leo_sobral@1
   425
renatofilho@754
   426
    return (*recorded_list == NULL) ? 0 : g_list_length(*recorded_list);
leo_sobral@1
   427
}
leo_sobral@1
   428
renatofilho@771
   429
RecordedInfo*
renatofilho@755
   430
gmyth_scheduler_get_recorded_info (GMythScheduler *scheduler,
renatofilho@771
   431
                                   const gchar* basename)
renatofilho@755
   432
{
renatofilho@769
   433
    RecordedInfo   *record = NULL;
renatofilho@755
   434
    MYSQL_RES      *msql_res;
renatofilho@755
   435
    GString        *query_str = g_string_new("");
renatofilho@755
   436
renatofilho@755
   437
    assert(scheduler);
renatofilho@755
   438
renatofilho@755
   439
    g_string_printf(query_str,
renatofilho@755
   440
                    "SELECT recordid,programid,chanid,starttime,progstart,"
renatofilho@755
   441
                    "endtime,progend,title,subtitle,description,category,"
renatofilho@886
   442
                    "filesize,basename,seriesid FROM recorded "
renatofilho@771
   443
                    "WHERE recgroup != 'LiveTV' AND basename = '%s'", basename);
renatofilho@755
   444
renatofilho@755
   445
    if (scheduler->msqlquery == NULL) {
renatofilho@755
   446
        g_warning("[%s] Scheduler db connection not initialized", 
renatofilho@755
   447
                        __FUNCTION__);
renatofilho@769
   448
        return NULL;
renatofilho@755
   449
    }
renatofilho@755
   450
renatofilho@755
   451
    msql_res =
renatofilho@755
   452
        gmyth_query_process_statement(scheduler->msqlquery,
renatofilho@755
   453
                                      query_str->str);
renatofilho@755
   454
renatofilho@755
   455
    if (msql_res == NULL) {
renatofilho@755
   456
        g_warning("DB retrieval of recording list failed");
renatofilho@769
   457
        return NULL;
renatofilho@755
   458
    } else {
renatofilho@755
   459
        MYSQL_ROW       row;
renatofilho@755
   460
        row = mysql_fetch_row(msql_res);
renatofilho@755
   461
        if (row != NULL) {
renatofilho@755
   462
            record = g_new0(RecordedInfo, 1);
renatofilho@755
   463
            record->record_id = (guint) g_ascii_strtoull(row[0], NULL, 10);
renatofilho@895
   464
            record->program_id = g_string_new (row[1]);
renatofilho@895
   465
            record->channel_id = (gint) g_ascii_strtoull(row[2], NULL, 10);
renatofilho@755
   466
            record->start_time = gmyth_util_string_to_time_val(row[3]);
renatofilho@755
   467
            record->end_time = gmyth_util_string_to_time_val(row[5]);
renatofilho@755
   468
            record->title = g_string_new(row[7]);
renatofilho@755
   469
            record->subtitle = g_string_new(row[8]);
renatofilho@755
   470
            record->description = g_string_new(row[9]);
renatofilho@755
   471
            record->category = g_string_new(row[10]);
renatofilho@755
   472
            record->filesize = g_ascii_strtoull(row[11], NULL, 10);
renatofilho@755
   473
            record->basename = g_string_new(row[12]);
renatofilho@886
   474
            record->seriesid = g_string_new(row[13]);
renatofilho@755
   475
        }
renatofilho@755
   476
    }
renatofilho@755
   477
renatofilho@755
   478
    mysql_free_result(msql_res);
renatofilho@755
   479
    g_string_free(query_str, TRUE);
renatofilho@755
   480
renatofilho@755
   481
    return record;
renatofilho@755
   482
}
renatofilho@755
   483
renatofilho@755
   484
melunko@567
   485
static void
renatofilho@754
   486
_set_value(GMythQuery * myth_query, char *field, gchar * value,
renatofilho@754
   487
           gint rec_id)
melunko@567
   488
{
renatofilho@754
   489
    gchar          *query =
renatofilho@754
   490
        g_strdup_printf
renatofilho@754
   491
        ("UPDATE record SET recordid = %d, %s = \"%s\" WHERE recordid = %d;",
renatofilho@754
   492
         rec_id, field, value, rec_id);
melunko@567
   493
renatofilho@754
   494
    gmyth_query_process_statement(myth_query, query);
renatofilho@754
   495
    g_free(query);
melunko@567
   496
}
melunko@567
   497
melunko@567
   498
static void
renatofilho@754
   499
_set_int_value(GMythQuery * myth_query, char *field, gint value,
renatofilho@754
   500
               gint rec_id)
melunko@567
   501
{
melunko@814
   502
    gchar *str_value = g_strdup_printf("%d", value);
rosfran@698
   503
renatofilho@754
   504
    _set_value(myth_query, field, str_value, rec_id);
renatofilho@754
   505
    g_free(str_value);
melunko@567
   506
}
melunko@567
   507
renatofilho@886
   508
ScheduleInfo*
renatofilho@886
   509
gmyth_scheduler_add_schedule_program (GMythScheduler * scheduler,
renatofilho@886
   510
                                      GMythProgramInfo *program,
renatofilho@886
   511
                                      GMythScheduleType type)
renatofilho@886
   512
{
renatofilho@886
   513
    ScheduleInfo *info;
renatofilho@886
   514
renatofilho@886
   515
    info = g_new0 (ScheduleInfo, 1);
renatofilho@895
   516
    info->program_id = g_string_new (program->program_id->str);
renatofilho@895
   517
    info->channel_id = program->channel_id;
renatofilho@886
   518
    info->start_time = g_new0 (GTimeVal, 1);
renatofilho@886
   519
    *info->start_time = *program->startts;
renatofilho@886
   520
    info->end_time = g_new0 (GTimeVal, 1);
renatofilho@886
   521
    *info->end_time = *program->endts;
renatofilho@886
   522
    info->seriesid = g_string_new (program->seriesid->str);
renatofilho@886
   523
    info->title = g_string_new (program->title->str);
renatofilho@886
   524
    info->subtitle = g_string_new (program->subtitle->str);
renatofilho@886
   525
    info->description = g_string_new (program->description->str);
renatofilho@886
   526
    info->category = g_string_new (program->category->str);
renatofilho@886
   527
    info->type = type;
renatofilho@886
   528
renatofilho@886
   529
    if (gmyth_scheduler_add_schedule_full (scheduler, info, type))
renatofilho@886
   530
    {
renatofilho@886
   531
        if (!program->recstartts)
renatofilho@886
   532
            program->recstartts = g_new0 (GTimeVal, 1);
renatofilho@886
   533
        *program->recstartts = *info->start_time;
renatofilho@886
   534
renatofilho@886
   535
        if (!program->recendts)
renatofilho@886
   536
            program->recendts = g_new0 (GTimeVal, 1);
renatofilho@886
   537
        *program->recendts = *info->end_time;
renatofilho@886
   538
renatofilho@886
   539
        program->recordid = info->schedule_id;
renatofilho@886
   540
        return info;
renatofilho@886
   541
    }
renatofilho@886
   542
renatofilho@886
   543
    gmyth_schedule_info_free (info);
renatofilho@886
   544
    return NULL;
renatofilho@886
   545
}
renatofilho@886
   546
renatofilho@886
   547
leo_sobral@1
   548
gboolean
melunko@801
   549
gmyth_scheduler_add_schedule_full (GMythScheduler * scheduler,
melunko@939
   550
                             ScheduleInfo *schedule_info, GMythScheduleType type)
leo_sobral@1
   551
{
renatofilho@754
   552
    MYSQL_RES      *msql_res;
melunko@935
   553
    gchar          *query_str = NULL;
renatofilho@754
   554
    gchar          *station = NULL;
renatofilho@754
   555
    gulong          rec_id;
rosfran@698
   556
renatofilho@890
   557
    g_return_val_if_fail (IS_GMYTH_SCHEDULER (scheduler), FALSE);
rosfran@698
   558
renatofilho@754
   559
    if (scheduler->msqlquery == NULL) {
renatofilho@754
   560
        g_warning("[%s] Scheduler db connection not initialized",
renatofilho@754
   561
                  __FUNCTION__);
renatofilho@754
   562
        return FALSE;
renatofilho@754
   563
    }
melunko@567
   564
melunko@934
   565
    /*
melunko@934
   566
    if (!gmyth_query_is_alive (scheduler->msqlquery)) {
melunko@934
   567
	g_warning ("[%s] MySql connection is not alive", __FUNCTION__);
melunko@934
   568
        return FALSE;
melunko@934
   569
    }
melunko@934
   570
    */
melunko@934
   571
melunko@934
   572
    {
melunko@934
   573
        /* Before adding the schedule, we need to check if program is been played */
melunko@934
   574
        GMythProgramInfo *prog_info = NULL;
melunko@934
   575
	gint recorder_num = 
melunko@934
   576
                gmyth_scheduler_is_program_live_recorded (scheduler, schedule_info,
melunko@934
   577
                                                          &prog_info);
melunko@935
   578
	if ((recorder_num > 0) && (prog_info != NULL)) {
melunko@939
   579
	    gboolean res;
melunko@934
   580
            gmyth_scheduler_change_record_group (scheduler, prog_info, "Default");
melunko@934
   581
melunko@939
   582
            res = gmyth_scheduler_set_live_record (scheduler, schedule_info,
melunko@934
   583
			recorder_num, TRUE);
melunko@939
   584
	    schedule_info->schedule_id = gmyth_scheduler_query_schedule_id (scheduler, prog_info);
melunko@939
   585
            return res;
melunko@939
   586
	} 
melunko@939
   587
    }
melunko@939
   588
melunko@939
   589
    /* Now, verifies if there is an old schedule for this program */
melunko@939
   590
    /* If threre is one, we reactivate it */
melunko@939
   591
    {
melunko@939
   592
        gint sched_id;
melunko@939
   593
	time_t now = time (NULL);
melunko@939
   594
melunko@939
   595
	if (schedule_info->start_time->tv_sec < now) {
melunko@939
   596
	    sched_id = gmyth_scheduler_query_old_schedule (scheduler, schedule_info->channel_id,
melunko@939
   597
			                               schedule_info->start_time, TRUE);
melunko@939
   598
	    if (sched_id > 0) {
melunko@939
   599
                schedule_info->schedule_id = sched_id;
melunko@939
   600
	        return TRUE;
melunko@939
   601
            } 
melunko@934
   602
	}
melunko@934
   603
    }
melunko@934
   604
renatofilho@754
   605
    msql_res =
renatofilho@754
   606
        gmyth_query_process_statement_with_increment(scheduler->msqlquery,
melunko@935
   607
			              "INSERT record (recordid) VALUE (0);",
melunko@935
   608
                                      &rec_id);
renatofilho@754
   609
    mysql_free_result(msql_res);
rosfran@698
   610
renatofilho@754
   611
    // Retrieves the station info
renatofilho@754
   612
    query_str =
renatofilho@754
   613
        g_strdup_printf
renatofilho@890
   614
        ("SELECT callsign FROM channel WHERE chanid = %d;",
renatofilho@895
   615
         schedule_info->channel_id);
renatofilho@754
   616
    msql_res =
renatofilho@754
   617
        gmyth_query_process_statement(scheduler->msqlquery, query_str);
renatofilho@754
   618
    if (msql_res == NULL) {
renatofilho@754
   619
        g_warning("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
renatofilho@754
   620
        return FALSE;
renatofilho@754
   621
    } else {
renatofilho@754
   622
        MYSQL_ROW       row;
rosfran@698
   623
renatofilho@754
   624
        if ((row = mysql_fetch_row(msql_res)) != NULL) {
renatofilho@754
   625
            station = g_strdup(row[0]);
renatofilho@754
   626
        }
renatofilho@754
   627
    }
renatofilho@754
   628
    mysql_free_result(msql_res);
renatofilho@754
   629
    g_free(query_str);
leo_sobral@1
   630
renatofilho@754
   631
    // _set_value (field, value, id);
renatofilho@890
   632
    _set_int_value(scheduler->msqlquery, "chanid",
renatofilho@895
   633
                   schedule_info->channel_id, rec_id);
renatofilho@754
   634
    _set_value(scheduler->msqlquery, "station", station, rec_id);
renatofilho@754
   635
    _set_value(scheduler->msqlquery, "title", schedule_info->title->str,
renatofilho@754
   636
               rec_id);
renatofilho@754
   637
    // / subtitle, description 
renatofilho@754
   638
    _set_value(scheduler->msqlquery, "starttime",
renatofilho@754
   639
               gmyth_util_time_to_string_only_time(schedule_info->
renatofilho@754
   640
                                                   start_time), rec_id);
renatofilho@754
   641
    _set_value(scheduler->msqlquery, "startdate",
renatofilho@754
   642
               gmyth_util_time_to_string_only_date(schedule_info->
renatofilho@754
   643
                                                   start_time), rec_id);
renatofilho@754
   644
    _set_value(scheduler->msqlquery, "endtime",
renatofilho@754
   645
               gmyth_util_time_to_string_only_time(schedule_info->
renatofilho@754
   646
                                                   end_time), rec_id);
renatofilho@754
   647
    _set_value(scheduler->msqlquery, "enddate",
renatofilho@754
   648
               gmyth_util_time_to_string_only_date(schedule_info->
renatofilho@754
   649
                                                   end_time), rec_id);
renatofilho@754
   650
    // / category, series id, program id
renatofilho@754
   651
    // _set_value (scheduler->msqlquery, "findday",
renatofilho@754
   652
    // (gmyth_util_time_val_to_date( schedule_info->start_time
renatofilho@754
   653
    // ))->tm_wday, rec_id);
renatofilho@754
   654
    // _set_value (scheduler->msqlquery, "findtime",
renatofilho@754
   655
    // gmyth_util_time_to_string_only_time( schedule_info->start_time),
renatofilho@754
   656
    // rec_id);
renatofilho@754
   657
    // _set_int_value (scheduler->msqlquery, "findid",
renatofilho@754
   658
    // (gint)(schedule_info->start_time->tv_sec/60/60/24 + 719528),
renatofilho@754
   659
    // rec_id);
melunko@801
   660
renatofilho@890
   661
    if (schedule_info->seriesid)
renatofilho@890
   662
       _set_value(scheduler->msqlquery, "seriesid",
renatofilho@890
   663
                  schedule_info->seriesid->str, rec_id);
renatofilho@890
   664
 
renatofilho@754
   665
    _set_value(scheduler->msqlquery, "parentid", "0", rec_id);
renatofilho@754
   666
    _set_value(scheduler->msqlquery, "search", "0", rec_id);
melunko@801
   667
melunko@801
   668
    if (type == GMYTH_SCHEDULE_ALL_OCCURRENCES) {
morphbr@841
   669
        _set_int_value(scheduler->msqlquery, "type", 3, rec_id);
melunko@814
   670
    } else if (type == GMYTH_SCHEDULE_ONE_OCCURRENCE) {
melunko@814
   671
        _set_int_value(scheduler->msqlquery, "type", 1, rec_id);
melunko@814
   672
    } else if (type == GMYTH_SCHEDULE_EXCEPTION) {
melunko@814
   673
        _set_int_value(scheduler->msqlquery, "type", 8, rec_id);
melunko@836
   674
        _set_int_value(scheduler->msqlquery, "parentid", schedule_info->parentid,
melunko@814
   675
		       rec_id);
melunko@801
   676
    }
melunko@801
   677
renatofilho@754
   678
    _set_value(scheduler->msqlquery, "recpriority", "0", rec_id);
renatofilho@754
   679
    _set_value(scheduler->msqlquery, "startoffset", "0", rec_id);
renatofilho@754
   680
    _set_value(scheduler->msqlquery, "endoffset", "0", rec_id);
renatofilho@754
   681
    _set_value(scheduler->msqlquery, "dupmethod", "6", rec_id); // ?
renatofilho@754
   682
    _set_value(scheduler->msqlquery, "dupin", "15", rec_id);    // ?
melunko@567
   683
renatofilho@754
   684
    _set_value(scheduler->msqlquery, "prefinput", "0", rec_id);
renatofilho@754
   685
    _set_value(scheduler->msqlquery, "inactive", "0", rec_id);
renatofilho@754
   686
    _set_value(scheduler->msqlquery, "profile", "Default", rec_id);
renatofilho@754
   687
    _set_value(scheduler->msqlquery, "recgroup", "Default", rec_id);
renatofilho@754
   688
    _set_value(scheduler->msqlquery, "storagegroup", "Default", rec_id);
renatofilho@754
   689
    _set_value(scheduler->msqlquery, "playgroup", "Default", rec_id);
renatofilho@754
   690
    _set_value(scheduler->msqlquery, "autoexpire", "1", rec_id);
renatofilho@754
   691
    _set_value(scheduler->msqlquery, "maxepisodes", "0", rec_id);
renatofilho@754
   692
    _set_value(scheduler->msqlquery, "maxnewest", "0", rec_id);
renatofilho@754
   693
    _set_value(scheduler->msqlquery, "autocommflag", "1", rec_id);
renatofilho@754
   694
    _set_value(scheduler->msqlquery, "autotranscode", "0", rec_id);
renatofilho@754
   695
    _set_value(scheduler->msqlquery, "transcoder", "0", rec_id);
melunko@567
   696
renatofilho@754
   697
    _set_value(scheduler->msqlquery, "autouserjob1", "0", rec_id);
renatofilho@754
   698
    _set_value(scheduler->msqlquery, "autouserjob2", "0", rec_id);
renatofilho@754
   699
    _set_value(scheduler->msqlquery, "autouserjob3", "0", rec_id);
renatofilho@754
   700
    _set_value(scheduler->msqlquery, "autouserjob4", "0", rec_id);
melunko@567
   701
renatofilho@754
   702
    schedule_info->schedule_id = rec_id;
melunko@581
   703
melunko@836
   704
    /* Notify the backend of changes */
renatofilho@754
   705
    return update_backend(scheduler, rec_id);
leo_sobral@1
   706
}
leo_sobral@1
   707
melunko@801
   708
/** Requests the Mysql database in the backend to add a new schedule.
melunko@801
   709
 * 
melunko@801
   710
 * @param scheduler the GMythScheduler instance.
melunko@801
   711
 * @param schedule_info the ScheduleInfo with recording schedule information
melunko@801
   712
 * to be added. record_id = -1 to add a new schedule, otherwise this
melunko@801
   713
 * function will update the schedule in the db
melunko@801
   714
 * @return gboolean returns FALSE if some error occurs, TRUE otherwise
melunko@801
   715
 */
melunko@801
   716
gboolean
melunko@801
   717
gmyth_scheduler_add_schedule (GMythScheduler * scheduler,
melunko@801
   718
                             ScheduleInfo * schedule_info)
melunko@801
   719
{
melunko@801
   720
    return gmyth_scheduler_add_schedule_full (scheduler, schedule_info, 
melunko@801
   721
                                              GMYTH_SCHEDULE_ONE_OCCURRENCE);
melunko@801
   722
}
melunko@801
   723
melunko@939
   724
static gint
melunko@939
   725
gmyth_scheduler_query_schedule_id (GMythScheduler *scheduler,
melunko@939
   726
		                   GMythProgramInfo *prog_info)
melunko@939
   727
{
melunko@939
   728
    MYSQL_RES *mysql_res;
melunko@939
   729
    gint sched_id = -1;
melunko@939
   730
    gchar *query_str, *startts;
melunko@939
   731
melunko@939
   732
    startts = gmyth_util_time_to_string_from_time_val (prog_info->recstartts);
melunko@939
   733
    query_str = g_strdup_printf ("SELECT recordid from recorded "
melunko@939
   734
		    "WHERE chanid= \"%d\" AND starttime = \"%s\";",
melunko@939
   735
                    prog_info->channel_id, startts);
melunko@939
   736
melunko@939
   737
    mysql_res = gmyth_query_process_statement(scheduler->msqlquery, query_str);
melunko@939
   738
melunko@939
   739
    if (mysql_res) {
melunko@939
   740
        MYSQL_ROW msql_row = mysql_fetch_row(mysql_res);
melunko@939
   741
        if (msql_row) {
melunko@939
   742
            sched_id = g_ascii_strtoull (msql_row[0], NULL, 10);
melunko@939
   743
        } 
melunko@939
   744
    }
melunko@939
   745
melunko@939
   746
    return sched_id;
melunko@939
   747
}
melunko@939
   748
melunko@939
   749
/* Queries if there is an old schedule previously set to this program.
melunko@939
   750
 * If reactivate flag is set, the recording will be reactivated.
melunko@939
   751
 * @returns the schedule id.
melunko@939
   752
 */
melunko@939
   753
static int
melunko@939
   754
gmyth_scheduler_query_old_schedule (GMythScheduler *scheduler,
melunko@939
   755
		                    gint channel_id, GTimeVal *startts,
melunko@939
   756
                                    gboolean reactivate)
melunko@939
   757
{
melunko@939
   758
    MYSQL_RES *mysql_res;
melunko@939
   759
    gint sched_id = -1;
melunko@939
   760
    gchar *query_str, *startts_str;
melunko@939
   761
melunko@939
   762
    startts_str = gmyth_util_time_to_string_from_time_val (startts);
melunko@939
   763
    query_str = g_strdup_printf ("SELECT recordid from oldrecorded "
melunko@939
   764
                    "WHERE chanid= \"%d\" AND starttime=\"%s\";",
melunko@939
   765
                    channel_id, startts_str);
melunko@939
   766
melunko@939
   767
    mysql_res = gmyth_query_process_statement(scheduler->msqlquery, query_str);
melunko@939
   768
    g_free (query_str);
melunko@939
   769
melunko@939
   770
    if (mysql_res) {
melunko@939
   771
        MYSQL_ROW msql_row = mysql_fetch_row(mysql_res);
melunko@939
   772
        if (msql_row) {
melunko@939
   773
            sched_id = g_ascii_strtoull (msql_row[0], NULL, 10);
melunko@939
   774
            if ((sched_id > 0) && (reactivate)) {
melunko@939
   775
                query_str = g_strdup_printf ("UPDATE oldrecorded SET reactivate = 1 "
melunko@939
   776
                    "WHERE chanid= \"%d\" AND starttime=\"%s\";",
melunko@939
   777
                    channel_id, startts_str);
melunko@939
   778
                update_backend (scheduler, 0);
melunko@939
   779
            }
melunko@939
   780
        }
melunko@939
   781
    }
melunko@939
   782
melunko@939
   783
    return sched_id;
melunko@939
   784
}
melunko@939
   785
melunko@934
   786
/** Queries if the given schedule info is currently been recorded by any 
melunko@934
   787
 * backend recorder.
melunko@934
   788
 * @return The recorder num currently recording the scheduled item, or -1
melunko@934
   789
 * if program is not been recorded.
melunko@934
   790
 */
melunko@934
   791
static gint
melunko@934
   792
gmyth_scheduler_is_program_live_recorded (GMythScheduler * scheduler,
melunko@934
   793
                                         ScheduleInfo *schedule_info,
melunko@934
   794
                                         GMythProgramInfo **prog_info)
melunko@934
   795
{
melunko@934
   796
   GList *list; 
melunko@934
   797
   gint recorder_num = -1;
melunko@934
   798
melunko@934
   799
   if (gmyth_remote_util_get_recorder_list (scheduler->backend_info, &list) > 0) {
melunko@934
   800
        GList *iter = list;
melunko@934
   801
	while (iter) {
melunko@934
   802
	    GMythRecorder *recorder = GMYTH_RECORDER ( iter->data );
melunko@934
   803
	    
melunko@934
   804
            if (gmyth_recorder_is_recording (recorder)) {
melunko@934
   805
                GMythProgramInfo *pinfo = gmyth_recorder_get_current_program_info (recorder);
melunko@934
   806
		if (pinfo != NULL) {
melunko@935
   807
		    if ((schedule_info->channel_id == pinfo->channel_id) &&
melunko@935
   808
			(schedule_info->start_time->tv_sec == pinfo->startts->tv_sec)) {
melunko@934
   809
			recorder_num = recorder->recorder_num;
melunko@934
   810
                        *prog_info = pinfo;
melunko@934
   811
			break;
melunko@934
   812
		    }
melunko@934
   813
		    g_object_unref (pinfo);
melunko@934
   814
		}
melunko@934
   815
	    }
melunko@934
   816
melunko@934
   817
	    iter = iter->next;
melunko@934
   818
	}
melunko@934
   819
melunko@934
   820
	g_list_foreach (list, (GFunc) g_object_unref, NULL);
melunko@934
   821
	g_list_free (list);
melunko@934
   822
   }
melunko@934
   823
melunko@934
   824
   return recorder_num;
melunko@934
   825
melunko@934
   826
}
melunko@934
   827
melunko@934
   828
static gboolean
melunko@934
   829
gmyth_scheduler_set_live_record (GMythScheduler * scheduler,
melunko@934
   830
                                ScheduleInfo * schedule_info,
melunko@934
   831
				gint recorder_num, gboolean enable)
melunko@934
   832
{
melunko@934
   833
    gchar* datastr;
melunko@934
   834
    GMythSocket *socket;
melunko@934
   835
    gboolean ret = FALSE;
melunko@934
   836
    GMythStringList *strlist = gmyth_string_list_new();
melunko@934
   837
melunko@934
   838
    datastr = g_strdup_printf ("QUERY_RECORDER %d", recorder_num);
melunko@934
   839
    gmyth_string_list_append_char_array (strlist, datastr);
melunko@934
   840
    gmyth_string_list_append_char_array (strlist, "SET_LIVE_RECORDING");
melunko@934
   841
    gmyth_string_list_append_int (strlist, enable ? 1 : 0);
melunko@934
   842
melunko@934
   843
    socket = gmyth_backend_info_get_connected_socket (scheduler->backend_info);
melunko@934
   844
    if (socket != NULL) {
melunko@934
   845
        ret = (gmyth_socket_sendreceive_stringlist(socket, strlist) > 0);
melunko@934
   846
        g_object_unref (socket);
melunko@934
   847
    } else {
melunko@934
   848
        g_warning("[%s] Connection to backend failed!", __FUNCTION__);
melunko@934
   849
    }
melunko@934
   850
melunko@934
   851
    g_free(datastr);
melunko@934
   852
    g_object_unref(strlist);
melunko@934
   853
    return ret;
melunko@934
   854
}
melunko@934
   855
melunko@934
   856
static gboolean
melunko@934
   857
gmyth_scheduler_change_record_group (GMythScheduler* scheduler,
melunko@934
   858
                                     GMythProgramInfo *prog_info,
melunko@934
   859
                                     gchar *new_group)
melunko@934
   860
melunko@934
   861
{
melunko@934
   862
    gchar *query_str = NULL;
melunko@934
   863
    gchar* startts = NULL;
melunko@934
   864
melunko@934
   865
    if (prog_info == NULL) {
melunko@934
   866
        g_warning ("Scheduler receiver a NULL program info to change its record group");
melunko@934
   867
        return FALSE;
melunko@934
   868
    }
melunko@934
   869
melunko@934
   870
    startts = gmyth_util_time_to_string_from_time_val (prog_info->recstartts);
melunko@934
   871
melunko@934
   872
    query_str = g_strdup_printf("UPDATE recorded SET recgroup = \"%s\" "
melunko@939
   873
                    "WHERE chanid = \"%d\" AND starttime = \"%s\";",
melunko@934
   874
                     new_group, prog_info->channel_id, startts);
melunko@934
   875
melunko@934
   876
    gmyth_query_process_statement(scheduler->msqlquery, query_str);
melunko@934
   877
melunko@934
   878
    g_free (query_str);
melunko@934
   879
    g_free (startts);
melunko@934
   880
    
melunko@934
   881
    return TRUE ;
melunko@934
   882
}
melunko@934
   883
melunko@934
   884
melunko@934
   885
leo_sobral@1
   886
/** Requests the Mysql database in the backend to remove an existing schedule.
leo_sobral@1
   887
 * 
leo_sobral@1
   888
 * @param scheduler the GMythScheduler instance.
melunko@814
   889
 * @param schedule_id The schedule's record id to be removed
leo_sobral@1
   890
 * @return gboolean TRUE if success, FALSE if error
leo_sobral@1
   891
 */
leo_sobral@1
   892
gboolean
melunko@935
   893
gmyth_scheduler_delete_schedule (GMythScheduler * scheduler, gint schedule_id)
leo_sobral@1
   894
{
melunko@935
   895
    MYSQL_RES *msql_res;
melunko@935
   896
    GString *query_str = NULL;
leo_sobral@1
   897
melunko@814
   898
    g_return_val_if_fail (scheduler != NULL, FALSE);
melunko@814
   899
renatofilho@754
   900
    if (scheduler->msqlquery == NULL) {
renatofilho@754
   901
        g_warning("[%s] Scheduler db connection not initialized",
renatofilho@754
   902
                  __FUNCTION__);
renatofilho@754
   903
        return FALSE;
renatofilho@754
   904
    }
melunko@814
   905
melunko@935
   906
    {
melunko@935
   907
        /* Before adding the schedule, we need to check if program is been played */
melunko@935
   908
        GMythProgramInfo *prog_info = NULL;
melunko@935
   909
        ScheduleInfo *sched_info = NULL;
melunko@935
   910
melunko@935
   911
        sched_info = gmyth_scheduler_get_schedule (scheduler, schedule_id);
melunko@935
   912
        if (sched_info != NULL) {
melunko@935
   913
            gint recorder_num =
melunko@935
   914
                gmyth_scheduler_is_program_live_recorded (scheduler, sched_info,
melunko@935
   915
                                                          &prog_info);
melunko@935
   916
            if ((recorder_num > 0) && (prog_info != NULL)) {
melunko@935
   917
		gboolean ret;
melunko@935
   918
                gmyth_scheduler_change_record_group (scheduler, prog_info, "LiveTV");
melunko@935
   919
melunko@935
   920
                ret = gmyth_scheduler_set_live_record (scheduler, sched_info,
melunko@935
   921
                            recorder_num, FALSE);
melunko@935
   922
                gmyth_schedule_info_free (sched_info);
melunko@935
   923
		return ret;		
melunko@935
   924
            } 
melunko@935
   925
	}
melunko@939
   926
			    
melunko@935
   927
    }
melunko@935
   928
melunko@814
   929
    query_str = g_string_new("");
renatofilho@754
   930
    g_string_printf(query_str,
melunko@814
   931
                    "DELETE FROM record WHERE recordid=%d", schedule_id);
leo_sobral@1
   932
renatofilho@754
   933
    msql_res =
renatofilho@754
   934
        gmyth_query_process_statement(scheduler->msqlquery,
renatofilho@754
   935
                                      query_str->str);
leo_sobral@1
   936
leo_sobral@1
   937
renatofilho@754
   938
    mysql_free_result(msql_res);
renatofilho@754
   939
    g_string_free(query_str, TRUE);
rosfran@698
   940
renatofilho@754
   941
    // Notify the backend of the changes
melunko@814
   942
    return update_backend(scheduler, schedule_id);
melunko@814
   943
}
melunko@814
   944
melunko@814
   945
/*
melunko@814
   946
 * Add an exception program to be removed from the schedule list, when programs
melunko@814
   947
 * where scheduled with the GMYTH_SCHEDULE_ALL_OCCURRENCES option.
melunko@814
   948
 * @param scheduler the GMythScheduler instance.
melunko@814
   949
 * @param schedule_id the schedule id of the all occurrence schedule to be changed
melunko@814
   950
 * @param exception_info the ScheduleInfo to be removed from all schedule occurrences
melunko@814
   951
 * @return TRUE if success, FALSE if any error happens
melunko@814
   952
 */
melunko@814
   953
gboolean
melunko@814
   954
gmyth_scheduler_add_exception (GMythScheduler *scheduler, gint schedule_id,
melunko@814
   955
			       ScheduleInfo *exception_info)
melunko@814
   956
{
melunko@814
   957
    gboolean res;
melunko@814
   958
melunko@814
   959
    g_return_val_if_fail (scheduler != NULL, FALSE);
melunko@814
   960
    g_return_val_if_fail (exception_info != NULL, FALSE);
melunko@814
   961
melunko@814
   962
    exception_info->parentid = schedule_id;
melunko@814
   963
    res = gmyth_scheduler_add_schedule_full (scheduler, exception_info, GMYTH_SCHEDULE_EXCEPTION);
melunko@814
   964
melunko@814
   965
    return res;
leo_sobral@1
   966
}
leo_sobral@1
   967
leo_sobral@1
   968
/** Requests the Mysql database in the backend to remove an existing recorded item.
leo_sobral@1
   969
 * 
leo_sobral@1
   970
 * @param scheduler the GMythScheduler instance.
leo_sobral@1
   971
 * @param record_id The recorded item id to be removed
leo_sobral@1
   972
 * @return gboolean TRUE if success, FALSE if error
leo_sobral@1
   973
 */
leo_sobral@1
   974
gboolean
renatofilho@750
   975
gmyth_scheduler_delete_recorded(GMythScheduler * scheduler, gint record_id)
leo_sobral@1
   976
{
leo_sobral@1
   977
renatofilho@754
   978
    MYSQL_RES      *msql_res;
melunko@117
   979
renatofilho@754
   980
    GString        *query_str = g_string_new("");
leo_sobral@1
   981
renatofilho@754
   982
    assert(scheduler);
rosfran@698
   983
renatofilho@754
   984
    if (scheduler->msqlquery == NULL) {
renatofilho@754
   985
        g_warning("[%s] Scheduler db connection not initialized",
renatofilho@754
   986
                  __FUNCTION__);
renatofilho@754
   987
        return FALSE;
renatofilho@754
   988
    }
renatofilho@754
   989
    // ========================================
renatofilho@754
   990
    g_string_printf(query_str,
renatofilho@754
   991
                    "DELETE FROM recorded WHERE recordid=%d", record_id);
leo_sobral@1
   992
renatofilho@754
   993
    // FIXME: Mythtv implementation runs also: DELETE FROM oldfind WHERE
renatofilho@754
   994
    // recordid = x
melunko@526
   995
renatofilho@754
   996
    msql_res =
renatofilho@754
   997
        gmyth_query_process_statement(scheduler->msqlquery,
renatofilho@754
   998
                                      query_str->str);
rosfran@698
   999
renatofilho@754
  1000
    mysql_free_result(msql_res);
renatofilho@754
  1001
    g_string_free(query_str, TRUE);
rosfran@698
  1002
renatofilho@754
  1003
    // Notify the backend of the changes
renatofilho@754
  1004
    return update_backend(scheduler, record_id);
leo_sobral@1
  1005
}
leo_sobral@1
  1006
leo_sobral@1
  1007
/** Retrieves an existing recorded item information from database. The information
leo_sobral@1
  1008
 * is used to fill the returned GMythProgramInfo.
leo_sobral@1
  1009
 * 
leo_sobral@1
  1010
 * @param scheduler The GMythScheduler instance.
leo_sobral@1
  1011
 * @param channel The channel associated to the record
leo_sobral@1
  1012
 * @param starttime The record start time
leo_sobral@1
  1013
 * @return A GMythProgramInfo struct with the requested record item
leo_sobral@1
  1014
 * information, or NULL if error.
leo_sobral@1
  1015
 */
rosfran@698
  1016
GMythProgramInfo *
renatofilho@750
  1017
gmyth_scheduler_get_recorded(GMythScheduler * scheduler,
renatofilho@754
  1018
                             GString * channel, GTimeVal * starttime)
leo_sobral@1
  1019
{
renatofilho@754
  1020
    MYSQL_RES      *msql_res;
renatofilho@754
  1021
    GMythProgramInfo *proginfo = NULL;
renatofilho@754
  1022
    GString        *query_str = g_string_new("");
renatofilho@754
  1023
    gchar          *time_str =
renatofilho@754
  1024
        gmyth_util_time_to_string_from_time_val(starttime);
leo_sobral@1
  1025
renatofilho@754
  1026
    assert(scheduler);
melunko@412
  1027
renatofilho@754
  1028
    gmyth_debug("[%s] channel: %s", __FUNCTION__, channel->str);
rosfran@698
  1029
renatofilho@754
  1030
    if (scheduler->msqlquery == NULL) {
renatofilho@754
  1031
        g_warning("[%s] Scheduler db connection not initialized",
renatofilho@754
  1032
                  __FUNCTION__);
renatofilho@754
  1033
        return NULL;
renatofilho@754
  1034
    }
leo_sobral@1
  1035
renatofilho@754
  1036
    g_string_printf(query_str,
renatofilho@754
  1037
                    "SELECT recorded.chanid,starttime,endtime,title, "
renatofilho@754
  1038
                    "subtitle,description,channel.channum, "
renatofilho@754
  1039
                    "channel.callsign,channel.name,channel.commfree, "
renatofilho@754
  1040
                    "channel.outputfilters,seriesid,programid,filesize, "
renatofilho@754
  1041
                    "lastmodified,stars,previouslyshown,originalairdate, "
renatofilho@754
  1042
                    "hostname,recordid,transcoder,playgroup, "
renatofilho@754
  1043
                    "recorded.recpriority,progstart,progend,basename,recgroup "
renatofilho@754
  1044
                    "FROM recorded " "LEFT JOIN channel "
renatofilho@754
  1045
                    "ON recorded.chanid = channel.chanid "
renatofilho@754
  1046
                    "WHERE recorded.chanid = \"%s\" "
renatofilho@754
  1047
                    "AND starttime = \"%s\" ;", channel->str, time_str);
leo_sobral@1
  1048
renatofilho@754
  1049
    msql_res =
renatofilho@754
  1050
        gmyth_query_process_statement(scheduler->msqlquery,
renatofilho@754
  1051
                                      query_str->str);
leo_sobral@1
  1052
renatofilho@754
  1053
    if (msql_res /* && query.size() > 0 */ ) {
renatofilho@754
  1054
        MYSQL_ROW       msql_row = mysql_fetch_row(msql_res);
rosfran@698
  1055
renatofilho@754
  1056
        if (msql_row) {
renatofilho@754
  1057
            proginfo = gmyth_program_info_new();
leo_sobral@1
  1058
renatofilho@895
  1059
            proginfo->channel_id = (gint) g_ascii_strtoull (msql_row[0], NULL, 10);
renatofilho@754
  1060
            proginfo->startts =
renatofilho@754
  1061
                gmyth_util_string_to_time_val(msql_row[23]);
renatofilho@754
  1062
            proginfo->endts = gmyth_util_string_to_time_val(msql_row[24]);
renatofilho@754
  1063
            proginfo->recstartts =
renatofilho@754
  1064
                gmyth_util_string_to_time_val(msql_row[1]);
renatofilho@754
  1065
            proginfo->recendts =
renatofilho@754
  1066
                gmyth_util_string_to_time_val(msql_row[2]);
renatofilho@754
  1067
            proginfo->title = g_string_new(msql_row[3]);
renatofilho@754
  1068
            proginfo->subtitle = g_string_new(msql_row[4]);
renatofilho@754
  1069
            proginfo->description = g_string_new(msql_row[5]);
leo_sobral@390
  1070
renatofilho@754
  1071
            proginfo->chanstr = g_string_new(msql_row[6]);
renatofilho@754
  1072
            proginfo->chansign = g_string_new(msql_row[7]);
renatofilho@754
  1073
            proginfo->channame = g_string_new(msql_row[0]);
renatofilho@754
  1074
            proginfo->chancommfree =
renatofilho@754
  1075
                (gint) g_ascii_strtoull(msql_row[9], NULL, 10);
renatofilho@754
  1076
            proginfo->chanOutputFilters = g_string_new(msql_row[10]);
renatofilho@754
  1077
            proginfo->seriesid = g_string_new(msql_row[11]);
renatofilho@895
  1078
            proginfo->program_id = g_string_new(msql_row[12]);
renatofilho@754
  1079
            proginfo->filesize = g_ascii_strtoull(msql_row[13], NULL, 10);
leo_sobral@1
  1080
renatofilho@754
  1081
            proginfo->lastmodified =
renatofilho@754
  1082
                gmyth_util_string_to_time_val(msql_row[14]);
renatofilho@754
  1083
            proginfo->stars = g_ascii_strtod(msql_row[15], NULL);
renatofilho@754
  1084
            proginfo->repeat =
renatofilho@754
  1085
                (gint) g_ascii_strtoull(msql_row[16], NULL, 10);
leo_sobral@390
  1086
renatofilho@754
  1087
            if (msql_row[17] == NULL) {
renatofilho@754
  1088
                proginfo->originalAirDate = 0;
renatofilho@754
  1089
                proginfo->hasAirDate = FALSE;
renatofilho@754
  1090
            } else {
renatofilho@754
  1091
                proginfo->originalAirDate =
renatofilho@754
  1092
                    gmyth_util_string_to_time_val(msql_row[17]);
renatofilho@754
  1093
                proginfo->hasAirDate = TRUE;
renatofilho@754
  1094
            }
leo_sobral@390
  1095
renatofilho@754
  1096
            proginfo->hostname = g_string_new(msql_row[18]);
renatofilho@754
  1097
            proginfo->recordid =
renatofilho@754
  1098
                (gint) g_ascii_strtoull(msql_row[19], NULL, 10);
renatofilho@754
  1099
            proginfo->transcoder =
renatofilho@754
  1100
                (gint) g_ascii_strtoull(msql_row[20], NULL, 10);
renatofilho@754
  1101
            // proginfo->spread = -1;
renatofilho@754
  1102
            // proginfo->programflags = proginfo->getProgramFlags();
leo_sobral@391
  1103
renatofilho@754
  1104
            proginfo->recgroup = g_string_new(msql_row[26]);
renatofilho@754
  1105
            proginfo->playgroup = g_string_new(msql_row[21]);
renatofilho@754
  1106
            proginfo->recpriority =
renatofilho@754
  1107
                (gint) g_ascii_strtoull(msql_row[22], NULL, 10);
leo_sobral@391
  1108
renatofilho@754
  1109
            proginfo->pathname = g_string_new(g_strdup(msql_row[25]));
leo_sobral@391
  1110
renatofilho@754
  1111
            gmyth_debug("One program info loaded from mysql database\n");
renatofilho@754
  1112
        }
renatofilho@754
  1113
    }
leo_sobral@1
  1114
renatofilho@754
  1115
    mysql_free_result(msql_res);
renatofilho@754
  1116
    g_string_free(query_str, TRUE);
renatofilho@754
  1117
    g_free(time_str);
leo_sobral@1
  1118
renatofilho@754
  1119
    return proginfo;
leo_sobral@1
  1120
}
leo_sobral@1
  1121
renatofilho@864
  1122
leo_sobral@1
  1123
/** Notifies the backend of an update in the db.
leo_sobral@1
  1124
 * 
leo_sobral@1
  1125
 * @param record_id the id of the modified recording.
leo_sobral@1
  1126
 */
renatofilho@769
  1127
// fixme: put void and discovery record_id inside
renatofilho@769
  1128
static gboolean
renatofilho@769
  1129
update_backend (GMythScheduler * scheduler, 
renatofilho@769
  1130
                gint record_id)  
leo_sobral@1
  1131
{
renatofilho@754
  1132
    GMythSocket    *socket;
renatofilho@754
  1133
    GMythStringList *strlist = gmyth_string_list_new();
renatofilho@754
  1134
    GString        *datastr = g_string_new("RESCHEDULE_RECORDINGS ");
renatofilho@754
  1135
    gboolean        ret = FALSE;
leo_sobral@1
  1136
renatofilho@754
  1137
    g_string_append_printf(datastr, "%d", record_id);
renatofilho@754
  1138
    gmyth_string_list_append_string(strlist, datastr);
leo_sobral@1
  1139
renatofilho@769
  1140
    socket = gmyth_backend_info_get_connected_socket (scheduler->backend_info);
renatofilho@769
  1141
    if (socket != NULL) { 
renatofilho@754
  1142
        ret = (gmyth_socket_sendreceive_stringlist(socket, strlist) > 0);
renatofilho@769
  1143
        g_object_unref (socket);
renatofilho@754
  1144
    } else {
renatofilho@754
  1145
        g_warning("[%s] Connection to backend failed!", __FUNCTION__);
renatofilho@754
  1146
    }
rosfran@698
  1147
renatofilho@754
  1148
    g_string_free(datastr, TRUE);
renatofilho@754
  1149
    g_object_unref(strlist);
renatofilho@754
  1150
    return ret;
leo_sobral@1
  1151
}
renatofilho@129
  1152
renatofilho@129
  1153
void
renatofilho@750
  1154
gmyth_scheduler_recorded_info_get_preview(RecordedInfo * info,
renatofilho@754
  1155
                                          GByteArray * data)
renatofilho@129
  1156
{
renatofilho@129
  1157
}
renatofilho@129
  1158
renatofilho@129
  1159
void
renatofilho@750
  1160
gmyth_recorded_info_free(RecordedInfo * info)
renatofilho@129
  1161
{
renatofilho@890
  1162
    g_return_if_fail (info != NULL);
renatofilho@890
  1163
renatofilho@895
  1164
    if (info->program_id)
renatofilho@895
  1165
        g_string_free (info->program_id, TRUE);
renatofilho@886
  1166
renatofilho@754
  1167
    if (info->title != NULL)
renatofilho@754
  1168
        g_string_free(info->title, TRUE);
renatofilho@129
  1169
renatofilho@754
  1170
    if (info->subtitle != NULL)
renatofilho@754
  1171
        g_string_free(info->subtitle, TRUE);
renatofilho@129
  1172
renatofilho@754
  1173
    if (info->description != NULL)
renatofilho@754
  1174
        g_string_free(info->description, TRUE);
renatofilho@129
  1175
renatofilho@754
  1176
    if (info->category != NULL)
renatofilho@754
  1177
        g_string_free(info->category, TRUE);
renatofilho@129
  1178
renatofilho@754
  1179
    if (info->basename != NULL)
renatofilho@754
  1180
        g_string_free(info->basename, TRUE);
renatofilho@129
  1181
renatofilho@754
  1182
    if (info != NULL)
renatofilho@754
  1183
        g_free(info->start_time);
leo_sobral@387
  1184
renatofilho@754
  1185
    if (info != NULL)
renatofilho@754
  1186
        g_free(info->end_time);
leo_sobral@387
  1187
renatofilho@754
  1188
    g_free(info);
renatofilho@129
  1189
}
renatofilho@129
  1190
melunko@591
  1191
static void
renatofilho@750
  1192
free_recorded_info_item(gpointer data, gpointer user_data)
melunko@591
  1193
{
renatofilho@754
  1194
    RecordedInfo   *info = (RecordedInfo *) data;
melunko@591
  1195
renatofilho@754
  1196
    gmyth_recorded_info_free(info);
melunko@591
  1197
}
melunko@591
  1198
renatofilho@129
  1199
void
renatofilho@750
  1200
gmyth_recorded_info_list_free(GList * list)
renatofilho@129
  1201
{
renatofilho@754
  1202
    g_return_if_fail(list != NULL);
melunko@591
  1203
renatofilho@754
  1204
    g_list_foreach(list, free_recorded_info_item, NULL);
renatofilho@754
  1205
    g_list_free(list);
melunko@591
  1206
}
melunko@591
  1207
melunko@591
  1208
void
renatofilho@750
  1209
gmyth_schedule_info_free(ScheduleInfo * info)
melunko@591
  1210
{
melunko@591
  1211
renatofilho@754
  1212
    g_return_if_fail(info != NULL);
melunko@591
  1213
renatofilho@895
  1214
    if (info->program_id)
renatofilho@895
  1215
        g_string_free (info->program_id, TRUE);
renatofilho@886
  1216
renatofilho@754
  1217
    if (info->title != NULL)
renatofilho@754
  1218
        g_string_free(info->title, TRUE);
renatofilho@129
  1219
renatofilho@754
  1220
    if (info->subtitle != NULL)
renatofilho@754
  1221
        g_string_free(info->subtitle, TRUE);
renatofilho@129
  1222
renatofilho@754
  1223
    if (info->description != NULL)
renatofilho@754
  1224
        g_string_free(info->description, TRUE);
renatofilho@129
  1225
renatofilho@754
  1226
    if (info->category != NULL)
renatofilho@754
  1227
        g_string_free(info->category, TRUE);
renatofilho@129
  1228
renatofilho@754
  1229
    if (info != NULL)
renatofilho@754
  1230
        g_free(info->start_time);
leo_sobral@387
  1231
renatofilho@754
  1232
    if (info != NULL)
renatofilho@754
  1233
        g_free(info->end_time);
leo_sobral@387
  1234
renatofilho@754
  1235
    g_free(info);
renatofilho@129
  1236
}
renatofilho@129
  1237
melunko@591
  1238
static void
renatofilho@750
  1239
free_schedule_info_item(gpointer data, gpointer user_data)
melunko@591
  1240
{
renatofilho@754
  1241
    ScheduleInfo   *info = (ScheduleInfo *) data;
melunko@591
  1242
renatofilho@754
  1243
    gmyth_schedule_info_free(info);
melunko@591
  1244
}
melunko@591
  1245
melunko@591
  1246
void
renatofilho@750
  1247
gmyth_schedule_info_list_free(GList * list)
melunko@591
  1248
{
renatofilho@754
  1249
    g_return_if_fail(list != NULL);
melunko@591
  1250
renatofilho@754
  1251
    g_list_foreach(list, free_schedule_info_item, NULL);
renatofilho@754
  1252
    g_list_free(list);
melunko@591
  1253
}