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