branches/gmyth-0.1b/src/gmyth_epg.c
author rosfran
Tue Feb 13 23:17:35 2007 +0000 (2007-02-13)
branchtrunk
changeset 358 06009f72d657
permissions -rw-r--r--
[svn r360] Removed a lot of GStaticMutex references.
renatofilho@320
     1
/**
renatofilho@320
     2
 * GMyth Library
renatofilho@320
     3
 *
renatofilho@320
     4
 * @file gmyth/gmyth_epg.c
renatofilho@320
     5
 * 
renatofilho@320
     6
 * @brief <p> GMythEPG class provides access to the program and channel data
renatofilho@320
     7
 * from the Electronic Program Guide (EPG) of the Mythtv backend.
renatofilho@320
     8
 *
renatofilho@320
     9
 * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
renatofilho@320
    10
 * @author Leonardo Sobral Cunha <leonardo.cunha@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 <mysql/mysql.h>
renatofilho@320
    34
#include <stdlib.h>
renatofilho@320
    35
#include <string.h>
renatofilho@320
    36
#include <assert.h>
renatofilho@320
    37
renatofilho@320
    38
#include "gmyth_epg.h"
renatofilho@320
    39
#include "gmyth_programinfo.h"
renatofilho@320
    40
#include "gmyth_util.h"
renatofilho@320
    41
#include "gmyth_debug.h"
renatofilho@320
    42
renatofilho@320
    43
static void gmyth_epg_class_init          (GMythEPGClass *klass);
renatofilho@320
    44
static void gmyth_epg_init                (GMythEPG *object);
renatofilho@320
    45
renatofilho@320
    46
static void gmyth_epg_dispose  (GObject *object);
renatofilho@320
    47
static void gmyth_epg_finalize (GObject *object);
renatofilho@320
    48
renatofilho@320
    49
G_DEFINE_TYPE(GMythEPG, gmyth_epg, G_TYPE_OBJECT)
renatofilho@320
    50
    
renatofilho@320
    51
static void
renatofilho@320
    52
gmyth_epg_class_init (GMythEPGClass *klass)
renatofilho@320
    53
{
renatofilho@320
    54
	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
renatofilho@320
    55
	
renatofilho@320
    56
    gobject_class->dispose  = gmyth_epg_dispose;
renatofilho@320
    57
    gobject_class->finalize = gmyth_epg_finalize;	
renatofilho@320
    58
}
renatofilho@320
    59
renatofilho@320
    60
static void
renatofilho@320
    61
gmyth_epg_init (GMythEPG *gmyth_epg)
renatofilho@320
    62
{
renatofilho@320
    63
renatofilho@320
    64
}
renatofilho@320
    65
renatofilho@320
    66
static void
renatofilho@320
    67
gmyth_epg_dispose  (GObject *object)
renatofilho@320
    68
{
renatofilho@320
    69
    //GMythEPG *gmyth_epg = GMYTH_EPG(object);
renatofilho@320
    70
   
renatofilho@320
    71
	G_OBJECT_CLASS (gmyth_epg_parent_class)->dispose (object);
renatofilho@320
    72
}
renatofilho@320
    73
renatofilho@320
    74
static void
renatofilho@320
    75
gmyth_epg_finalize (GObject *object)
renatofilho@320
    76
{
renatofilho@320
    77
    g_signal_handlers_destroy (object);
renatofilho@320
    78
renatofilho@320
    79
    G_OBJECT_CLASS (gmyth_epg_parent_class)->finalize (object);
renatofilho@320
    80
}
renatofilho@320
    81
renatofilho@320
    82
/**
renatofilho@320
    83
 * Creates a new instance of GMythEPG.
renatofilho@320
    84
 * 
renatofilho@320
    85
 * @return a new instance of GMythEPG.
renatofilho@320
    86
 */
renatofilho@320
    87
GMythEPG*
renatofilho@320
    88
gmyth_epg_new (void)
renatofilho@320
    89
{
renatofilho@320
    90
    GMythEPG *epg = GMYTH_EPG (g_object_new(GMYTH_EPG_TYPE, NULL));
renatofilho@320
    91
renatofilho@320
    92
    return epg;
renatofilho@320
    93
}
renatofilho@320
    94
renatofilho@320
    95
/** Connects to the Mysql database in the backend. The backend address
renatofilho@320
    96
 * is loaded from the GMythSettings instance.
renatofilho@320
    97
 * 
renatofilho@320
    98
 * @param gmyth_epg the GMythEPG instance to be connected.
renatofilho@320
    99
 * @return true if connection was success, false if failed.
renatofilho@320
   100
 */
renatofilho@320
   101
gboolean
renatofilho@320
   102
gmyth_epg_connect (GMythEPG *gmyth_epg, GMythBackendInfo *backend_info)
renatofilho@320
   103
{
renatofilho@320
   104
    assert(gmyth_epg);
renatofilho@320
   105
renatofilho@320
   106
    if (gmyth_epg->sqlquery	== NULL) {
renatofilho@320
   107
	gmyth_debug ("[%s] Creating gmyth_query", __FUNCTION__);
renatofilho@320
   108
        gmyth_epg->sqlquery = gmyth_query_new ( );
renatofilho@320
   109
    }
renatofilho@320
   110
renatofilho@320
   111
    if (!gmyth_query_connect(gmyth_epg->sqlquery, backend_info)) {
renatofilho@320
   112
        g_warning ("[%s] Error while connecting to db", __FUNCTION__);
renatofilho@320
   113
        return FALSE;
renatofilho@320
   114
    }
renatofilho@320
   115
renatofilho@320
   116
    return TRUE;	
renatofilho@320
   117
}
renatofilho@320
   118
renatofilho@320
   119
/** Disconnects from the Mysql database in the backend.
renatofilho@320
   120
 * 
renatofilho@320
   121
 * @param gmyth_epg the GMythEPG instance to be disconnected
renatofilho@320
   122
 * @return true if disconnection was success, false if failed.
renatofilho@320
   123
 */
renatofilho@320
   124
gboolean
renatofilho@320
   125
gmyth_epg_disconnect (GMythEPG *gmyth_epg)
renatofilho@320
   126
{
renatofilho@320
   127
	assert(gmyth_epg);
renatofilho@320
   128
renatofilho@320
   129
	if (gmyth_epg->sqlquery	!= NULL) {	
renatofilho@320
   130
		g_object_unref (gmyth_epg->sqlquery);
renatofilho@320
   131
        gmyth_epg->sqlquery = NULL;
renatofilho@320
   132
	}
renatofilho@320
   133
	
renatofilho@320
   134
	return TRUE;
renatofilho@320
   135
}
renatofilho@320
   136
renatofilho@320
   137
/** Retrieves the available list of channels from the backend Mysql database.
renatofilho@320
   138
 * 
renatofilho@320
   139
 * @param gmyth_epg the GMythEPG instance.
renatofilho@320
   140
 * @param glist_ptr the GList pointer to be filled with the loaded list address.
renatofilho@320
   141
 * @return The amount of channels retrieved from database,  or -1 if error.
renatofilho@320
   142
 */
renatofilho@320
   143
gint
renatofilho@320
   144
gmyth_epg_get_channel_list (GMythEPG *gmyth_epg, GList **glist_ptr)
renatofilho@320
   145
{
renatofilho@320
   146
	MYSQL_RES *msql_res;
renatofilho@320
   147
renatofilho@320
   148
    assert(gmyth_epg);
renatofilho@320
   149
renatofilho@320
   150
    msql_res = gmyth_query_process_statement (gmyth_epg->sqlquery, 
renatofilho@320
   151
    		"SELECT chanid, channum, name FROM channel;");
renatofilho@320
   152
renatofilho@320
   153
	(*glist_ptr) = NULL;
renatofilho@320
   154
	
renatofilho@320
   155
    if (msql_res == NULL) {
renatofilho@320
   156
        g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
renatofilho@320
   157
		return -1;
renatofilho@320
   158
    } else {
renatofilho@320
   159
        MYSQL_ROW row;
renatofilho@320
   160
		GMythChannelInfo *channel_info;        
renatofilho@320
   161
renatofilho@320
   162
        while ((row = mysql_fetch_row (msql_res)) != NULL){
renatofilho@320
   163
renatofilho@320
   164
        	channel_info = g_new0(GMythChannelInfo, 1);
renatofilho@320
   165
            channel_info->channel_ID = g_ascii_strtoull (row[0], NULL, 10);
renatofilho@320
   166
            channel_info->channel_num = g_string_new (row[1]);
renatofilho@320
   167
            channel_info->channel_name = g_string_new (row[2]);
renatofilho@320
   168
       
renatofilho@320
   169
            gmyth_channel_info_print(channel_info);
renatofilho@320
   170
            
renatofilho@320
   171
            (*glist_ptr) = g_list_append ((*glist_ptr), channel_info);
renatofilho@320
   172
    	}
renatofilho@320
   173
    }
renatofilho@320
   174
    mysql_free_result (msql_res);
renatofilho@320
   175
    return (!(*glist_ptr)) ?  0 : g_list_length (*glist_ptr);
renatofilho@320
   176
}
renatofilho@320
   177
renatofilho@320
   178
/** 
renatofilho@320
   179
 * Retrieves the available list of channels from the backend Mysql database.
renatofilho@320
   180
 * 
renatofilho@320
   181
 * @param gmyth_epg the GMythEPG instance.
renatofilho@320
   182
 * @param proglist the GList pointer to be filled with the loaded list.
renatofilho@320
   183
 * @param chan_num the channel num on which to search for program.
renatofilho@320
   184
 * @param starttime the start time to search for programs.
renatofilho@320
   185
 * @param endtime the end time to search for programs.
renatofilho@320
   186
 * @return The amount of channels retrieved from database, or -1 if error.
renatofilho@320
   187
 */
renatofilho@320
   188
gint
renatofilho@320
   189
gmyth_epg_get_program_list (GMythEPG *gmyth_epg, GList **proglist,
renatofilho@320
   190
		const gint chan_num, GTimeVal *starttime, GTimeVal *endtime)
renatofilho@320
   191
{
renatofilho@320
   192
renatofilho@320
   193
    gchar *startts = gmyth_util_time_to_string_from_time_val(starttime);
renatofilho@320
   194
    gchar *endts = gmyth_util_time_to_string_from_time_val(endtime);
renatofilho@320
   195
    MYSQL_ROW row;
renatofilho@320
   196
    GString *querystr;
renatofilho@320
   197
    
renatofilho@320
   198
    assert(gmyth_epg);
renatofilho@320
   199
    
renatofilho@320
   200
    querystr = g_string_new(
renatofilho@320
   201
        "SELECT DISTINCT program.chanid, program.starttime, program.endtime, "
renatofilho@320
   202
        "    program.title, program.subtitle, program.description, "
renatofilho@320
   203
        "    program.category, channel.channum, channel.callsign, "
renatofilho@320
   204
        "    channel.name, program.previouslyshown, channel.commfree, "
renatofilho@320
   205
        "    channel.outputfilters, program.seriesid, program.programid, "
renatofilho@320
   206
        "    program.airdate, program.stars, program.originalairdate, "
renatofilho@320
   207
        "    program.category_type, oldrecstatus.recordid, "
renatofilho@320
   208
        "    oldrecstatus.rectype, oldrecstatus.recstatus, "
renatofilho@320
   209
        "    oldrecstatus.findid "
renatofilho@320
   210
        "FROM program "
renatofilho@320
   211
        "LEFT JOIN channel ON program.chanid = channel.chanid "
renatofilho@320
   212
        "LEFT JOIN oldrecorded AS oldrecstatus ON "
renatofilho@320
   213
        "    program.title = oldrecstatus.title AND "
renatofilho@320
   214
        "    channel.callsign = oldrecstatus.station AND "
renatofilho@320
   215
        "    program.starttime = oldrecstatus.starttime "
renatofilho@320
   216
        );
renatofilho@320
   217
        
renatofilho@320
   218
    g_string_append_printf (querystr, 
renatofilho@320
   219
        "WHERE program.chanid = %d "
renatofilho@320
   220
        "  AND program.endtime >= '%s' "
renatofilho@320
   221
        "  AND program.starttime <= '%s' "
renatofilho@320
   222
        "  AND program.manualid = 0 ",
renatofilho@320
   223
        chan_num, startts, endts);
renatofilho@320
   224
renatofilho@320
   225
    if (!g_strrstr(querystr->str, " GROUP BY "))
renatofilho@320
   226
        querystr = g_string_append(querystr,
renatofilho@320
   227
            " GROUP BY program.starttime, channel.channum, "
renatofilho@320
   228
            "  channel.callsign, program.title ");
renatofilho@320
   229
renatofilho@320
   230
    if (!g_strrstr(querystr->str, " LIMIT "))
renatofilho@320
   231
        querystr = g_string_append(querystr, " LIMIT 1000 ");
renatofilho@320
   232
renatofilho@320
   233
    MYSQL_RES *res_set = 
renatofilho@320
   234
        gmyth_query_process_statement(gmyth_epg->sqlquery, querystr->str);
renatofilho@320
   235
renatofilho@320
   236
    if (res_set == NULL) {
renatofilho@320
   237
        g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
renatofilho@320
   238
		return -1;
renatofilho@320
   239
    }
renatofilho@320
   240
renatofilho@320
   241
    (*proglist) = NULL;        
renatofilho@320
   242
    while ((row = mysql_fetch_row (res_set)) != NULL) {
renatofilho@320
   243
renatofilho@320
   244
        GMythProgramInfo *p = gmyth_program_info_new ();
renatofilho@320
   245
        p->chanid = g_string_new (row[0]);
renatofilho@320
   246
renatofilho@320
   247
        p->startts = gmyth_util_string_to_time_val (row[1]);
renatofilho@320
   248
        p->endts = gmyth_util_string_to_time_val (row[2]);
renatofilho@320
   249
                                                     
renatofilho@320
   250
        p->recstartts = g_new0 (GTimeVal, 1);
renatofilho@320
   251
	p->recstartts->tv_sec  = p->startts->tv_sec;
renatofilho@320
   252
	p->recstartts->tv_usec = p->startts->tv_usec;
renatofilho@320
   253
renatofilho@320
   254
        p->recendts = g_new0 (GTimeVal, 1);
renatofilho@320
   255
	p->recendts->tv_sec  = p->endts->tv_sec;
renatofilho@320
   256
	p->recendts->tv_usec = p->endts->tv_usec;
renatofilho@320
   257
renatofilho@320
   258
        p->lastmodified = g_new0 (GTimeVal, 1);
renatofilho@320
   259
	p->lastmodified->tv_sec  = p->startts->tv_sec;
renatofilho@320
   260
	p->lastmodified->tv_usec = p->startts->tv_usec;
renatofilho@320
   261
    
renatofilho@320
   262
        p->title = g_string_new (row[3]);
renatofilho@320
   263
        p->subtitle = g_string_new (row[4]);
renatofilho@320
   264
        p->description = g_string_new (row[5]);
renatofilho@320
   265
        p->category = g_string_new (row[6]);
renatofilho@320
   266
        p->chanstr = g_string_new (row[7]);
renatofilho@320
   267
        p->chansign = g_string_new (row[8]);
renatofilho@320
   268
        p->channame = g_string_new (row[9]);
renatofilho@320
   269
        p->repeat = g_ascii_strtoull(row[10], NULL, 10);
renatofilho@320
   270
        p->chancommfree = g_ascii_strtoull(row[11], NULL, 10);
renatofilho@320
   271
        p->chanOutputFilters = g_string_new (row[12]);
renatofilho@320
   272
        p->seriesid = g_string_new (row[13]);
renatofilho@320
   273
        p->programid = g_string_new (row[14]);
renatofilho@320
   274
        p->year = g_string_new (row[15]);
renatofilho@320
   275
        p->stars = g_ascii_strtod(row[16], NULL);
renatofilho@320
   276
renatofilho@320
   277
        if (!row[17] || !strcmp(row[17], "")) {
renatofilho@320
   278
            p->originalAirDate = 0;
renatofilho@320
   279
            p->hasAirDate = FALSE;
renatofilho@320
   280
        } else {
renatofilho@320
   281
            p->originalAirDate = gmyth_util_string_to_time_val (row[17]);
renatofilho@320
   282
            p->hasAirDate = TRUE;
renatofilho@320
   283
        }
renatofilho@320
   284
        
renatofilho@320
   285
        p->catType = g_string_new (row[18]);
renatofilho@320
   286
renatofilho@320
   287
        *proglist = g_list_append((*proglist), p);
renatofilho@320
   288
renatofilho@320
   289
#if 0        
renatofilho@320
   290
        gmyth_program_info_print(p);
renatofilho@320
   291
#endif        
renatofilho@320
   292
    }
renatofilho@320
   293
renatofilho@320
   294
    /* deallocate */
renatofilho@320
   295
    mysql_free_result (res_set);
renatofilho@320
   296
    g_string_free(querystr, TRUE);
renatofilho@320
   297
renatofilho@320
   298
    return TRUE;
renatofilho@320
   299
}