branches/gmyth-0.1b/src/gmyth_epg.c
branchtrunk
changeset 326 81b1f3006eb2
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/branches/gmyth-0.1b/src/gmyth_epg.c	Tue Feb 06 00:33:35 2007 +0000
     1.3 @@ -0,0 +1,299 @@
     1.4 +/**
     1.5 + * GMyth Library
     1.6 + *
     1.7 + * @file gmyth/gmyth_epg.c
     1.8 + * 
     1.9 + * @brief <p> GMythEPG class provides access to the program and channel data
    1.10 + * from the Electronic Program Guide (EPG) of the Mythtv backend.
    1.11 + *
    1.12 + * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
    1.13 + * @author Leonardo Sobral Cunha <leonardo.cunha@indt.org.br>
    1.14 + *
    1.15 + *//*
    1.16 + * 
    1.17 + * This program is free software; you can redistribute it and/or modify
    1.18 + * it under the terms of the GNU Lesser General Public License as published by
    1.19 + * the Free Software Foundation; either version 2 of the License, or
    1.20 + * (at your option) any later version.
    1.21 + *
    1.22 + * This program is distributed in the hope that it will be useful,
    1.23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.25 + * GNU General Public License for more details.
    1.26 + *
    1.27 + * You should have received a copy of the GNU Lesser General Public License
    1.28 + * along with this program; if not, write to the Free Software
    1.29 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.30 + */
    1.31 + 
    1.32 +#ifdef HAVE_CONFIG_H
    1.33 +#include "config.h"
    1.34 +#endif
    1.35 +
    1.36 +#include <mysql/mysql.h>
    1.37 +#include <stdlib.h>
    1.38 +#include <string.h>
    1.39 +#include <assert.h>
    1.40 +
    1.41 +#include "gmyth_epg.h"
    1.42 +#include "gmyth_programinfo.h"
    1.43 +#include "gmyth_util.h"
    1.44 +#include "gmyth_debug.h"
    1.45 +
    1.46 +static void gmyth_epg_class_init          (GMythEPGClass *klass);
    1.47 +static void gmyth_epg_init                (GMythEPG *object);
    1.48 +
    1.49 +static void gmyth_epg_dispose  (GObject *object);
    1.50 +static void gmyth_epg_finalize (GObject *object);
    1.51 +
    1.52 +G_DEFINE_TYPE(GMythEPG, gmyth_epg, G_TYPE_OBJECT)
    1.53 +    
    1.54 +static void
    1.55 +gmyth_epg_class_init (GMythEPGClass *klass)
    1.56 +{
    1.57 +	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
    1.58 +	
    1.59 +    gobject_class->dispose  = gmyth_epg_dispose;
    1.60 +    gobject_class->finalize = gmyth_epg_finalize;	
    1.61 +}
    1.62 +
    1.63 +static void
    1.64 +gmyth_epg_init (GMythEPG *gmyth_epg)
    1.65 +{
    1.66 +
    1.67 +}
    1.68 +
    1.69 +static void
    1.70 +gmyth_epg_dispose  (GObject *object)
    1.71 +{
    1.72 +    //GMythEPG *gmyth_epg = GMYTH_EPG(object);
    1.73 +   
    1.74 +	G_OBJECT_CLASS (gmyth_epg_parent_class)->dispose (object);
    1.75 +}
    1.76 +
    1.77 +static void
    1.78 +gmyth_epg_finalize (GObject *object)
    1.79 +{
    1.80 +    g_signal_handlers_destroy (object);
    1.81 +
    1.82 +    G_OBJECT_CLASS (gmyth_epg_parent_class)->finalize (object);
    1.83 +}
    1.84 +
    1.85 +/**
    1.86 + * Creates a new instance of GMythEPG.
    1.87 + * 
    1.88 + * @return a new instance of GMythEPG.
    1.89 + */
    1.90 +GMythEPG*
    1.91 +gmyth_epg_new (void)
    1.92 +{
    1.93 +    GMythEPG *epg = GMYTH_EPG (g_object_new(GMYTH_EPG_TYPE, NULL));
    1.94 +
    1.95 +    return epg;
    1.96 +}
    1.97 +
    1.98 +/** Connects to the Mysql database in the backend. The backend address
    1.99 + * is loaded from the GMythSettings instance.
   1.100 + * 
   1.101 + * @param gmyth_epg the GMythEPG instance to be connected.
   1.102 + * @return true if connection was success, false if failed.
   1.103 + */
   1.104 +gboolean
   1.105 +gmyth_epg_connect (GMythEPG *gmyth_epg, GMythBackendInfo *backend_info)
   1.106 +{
   1.107 +    assert(gmyth_epg);
   1.108 +
   1.109 +    if (gmyth_epg->sqlquery	== NULL) {
   1.110 +	gmyth_debug ("[%s] Creating gmyth_query", __FUNCTION__);
   1.111 +        gmyth_epg->sqlquery = gmyth_query_new ( );
   1.112 +    }
   1.113 +
   1.114 +    if (!gmyth_query_connect(gmyth_epg->sqlquery, backend_info)) {
   1.115 +        g_warning ("[%s] Error while connecting to db", __FUNCTION__);
   1.116 +        return FALSE;
   1.117 +    }
   1.118 +
   1.119 +    return TRUE;	
   1.120 +}
   1.121 +
   1.122 +/** Disconnects from the Mysql database in the backend.
   1.123 + * 
   1.124 + * @param gmyth_epg the GMythEPG instance to be disconnected
   1.125 + * @return true if disconnection was success, false if failed.
   1.126 + */
   1.127 +gboolean
   1.128 +gmyth_epg_disconnect (GMythEPG *gmyth_epg)
   1.129 +{
   1.130 +	assert(gmyth_epg);
   1.131 +
   1.132 +	if (gmyth_epg->sqlquery	!= NULL) {	
   1.133 +		g_object_unref (gmyth_epg->sqlquery);
   1.134 +        gmyth_epg->sqlquery = NULL;
   1.135 +	}
   1.136 +	
   1.137 +	return TRUE;
   1.138 +}
   1.139 +
   1.140 +/** Retrieves the available list of channels from the backend Mysql database.
   1.141 + * 
   1.142 + * @param gmyth_epg the GMythEPG instance.
   1.143 + * @param glist_ptr the GList pointer to be filled with the loaded list address.
   1.144 + * @return The amount of channels retrieved from database,  or -1 if error.
   1.145 + */
   1.146 +gint
   1.147 +gmyth_epg_get_channel_list (GMythEPG *gmyth_epg, GList **glist_ptr)
   1.148 +{
   1.149 +	MYSQL_RES *msql_res;
   1.150 +
   1.151 +    assert(gmyth_epg);
   1.152 +
   1.153 +    msql_res = gmyth_query_process_statement (gmyth_epg->sqlquery, 
   1.154 +    		"SELECT chanid, channum, name FROM channel;");
   1.155 +
   1.156 +	(*glist_ptr) = NULL;
   1.157 +	
   1.158 +    if (msql_res == NULL) {
   1.159 +        g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
   1.160 +		return -1;
   1.161 +    } else {
   1.162 +        MYSQL_ROW row;
   1.163 +		GMythChannelInfo *channel_info;        
   1.164 +
   1.165 +        while ((row = mysql_fetch_row (msql_res)) != NULL){
   1.166 +
   1.167 +        	channel_info = g_new0(GMythChannelInfo, 1);
   1.168 +            channel_info->channel_ID = g_ascii_strtoull (row[0], NULL, 10);
   1.169 +            channel_info->channel_num = g_string_new (row[1]);
   1.170 +            channel_info->channel_name = g_string_new (row[2]);
   1.171 +       
   1.172 +            gmyth_channel_info_print(channel_info);
   1.173 +            
   1.174 +            (*glist_ptr) = g_list_append ((*glist_ptr), channel_info);
   1.175 +    	}
   1.176 +    }
   1.177 +    mysql_free_result (msql_res);
   1.178 +    return (!(*glist_ptr)) ?  0 : g_list_length (*glist_ptr);
   1.179 +}
   1.180 +
   1.181 +/** 
   1.182 + * Retrieves the available list of channels from the backend Mysql database.
   1.183 + * 
   1.184 + * @param gmyth_epg the GMythEPG instance.
   1.185 + * @param proglist the GList pointer to be filled with the loaded list.
   1.186 + * @param chan_num the channel num on which to search for program.
   1.187 + * @param starttime the start time to search for programs.
   1.188 + * @param endtime the end time to search for programs.
   1.189 + * @return The amount of channels retrieved from database, or -1 if error.
   1.190 + */
   1.191 +gint
   1.192 +gmyth_epg_get_program_list (GMythEPG *gmyth_epg, GList **proglist,
   1.193 +		const gint chan_num, GTimeVal *starttime, GTimeVal *endtime)
   1.194 +{
   1.195 +
   1.196 +    gchar *startts = gmyth_util_time_to_string_from_time_val(starttime);
   1.197 +    gchar *endts = gmyth_util_time_to_string_from_time_val(endtime);
   1.198 +    MYSQL_ROW row;
   1.199 +    GString *querystr;
   1.200 +    
   1.201 +    assert(gmyth_epg);
   1.202 +    
   1.203 +    querystr = g_string_new(
   1.204 +        "SELECT DISTINCT program.chanid, program.starttime, program.endtime, "
   1.205 +        "    program.title, program.subtitle, program.description, "
   1.206 +        "    program.category, channel.channum, channel.callsign, "
   1.207 +        "    channel.name, program.previouslyshown, channel.commfree, "
   1.208 +        "    channel.outputfilters, program.seriesid, program.programid, "
   1.209 +        "    program.airdate, program.stars, program.originalairdate, "
   1.210 +        "    program.category_type, oldrecstatus.recordid, "
   1.211 +        "    oldrecstatus.rectype, oldrecstatus.recstatus, "
   1.212 +        "    oldrecstatus.findid "
   1.213 +        "FROM program "
   1.214 +        "LEFT JOIN channel ON program.chanid = channel.chanid "
   1.215 +        "LEFT JOIN oldrecorded AS oldrecstatus ON "
   1.216 +        "    program.title = oldrecstatus.title AND "
   1.217 +        "    channel.callsign = oldrecstatus.station AND "
   1.218 +        "    program.starttime = oldrecstatus.starttime "
   1.219 +        );
   1.220 +        
   1.221 +    g_string_append_printf (querystr, 
   1.222 +        "WHERE program.chanid = %d "
   1.223 +        "  AND program.endtime >= '%s' "
   1.224 +        "  AND program.starttime <= '%s' "
   1.225 +        "  AND program.manualid = 0 ",
   1.226 +        chan_num, startts, endts);
   1.227 +
   1.228 +    if (!g_strrstr(querystr->str, " GROUP BY "))
   1.229 +        querystr = g_string_append(querystr,
   1.230 +            " GROUP BY program.starttime, channel.channum, "
   1.231 +            "  channel.callsign, program.title ");
   1.232 +
   1.233 +    if (!g_strrstr(querystr->str, " LIMIT "))
   1.234 +        querystr = g_string_append(querystr, " LIMIT 1000 ");
   1.235 +
   1.236 +    MYSQL_RES *res_set = 
   1.237 +        gmyth_query_process_statement(gmyth_epg->sqlquery, querystr->str);
   1.238 +
   1.239 +    if (res_set == NULL) {
   1.240 +        g_warning ("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
   1.241 +		return -1;
   1.242 +    }
   1.243 +
   1.244 +    (*proglist) = NULL;        
   1.245 +    while ((row = mysql_fetch_row (res_set)) != NULL) {
   1.246 +
   1.247 +        GMythProgramInfo *p = gmyth_program_info_new ();
   1.248 +        p->chanid = g_string_new (row[0]);
   1.249 +
   1.250 +        p->startts = gmyth_util_string_to_time_val (row[1]);
   1.251 +        p->endts = gmyth_util_string_to_time_val (row[2]);
   1.252 +                                                     
   1.253 +        p->recstartts = g_new0 (GTimeVal, 1);
   1.254 +	p->recstartts->tv_sec  = p->startts->tv_sec;
   1.255 +	p->recstartts->tv_usec = p->startts->tv_usec;
   1.256 +
   1.257 +        p->recendts = g_new0 (GTimeVal, 1);
   1.258 +	p->recendts->tv_sec  = p->endts->tv_sec;
   1.259 +	p->recendts->tv_usec = p->endts->tv_usec;
   1.260 +
   1.261 +        p->lastmodified = g_new0 (GTimeVal, 1);
   1.262 +	p->lastmodified->tv_sec  = p->startts->tv_sec;
   1.263 +	p->lastmodified->tv_usec = p->startts->tv_usec;
   1.264 +    
   1.265 +        p->title = g_string_new (row[3]);
   1.266 +        p->subtitle = g_string_new (row[4]);
   1.267 +        p->description = g_string_new (row[5]);
   1.268 +        p->category = g_string_new (row[6]);
   1.269 +        p->chanstr = g_string_new (row[7]);
   1.270 +        p->chansign = g_string_new (row[8]);
   1.271 +        p->channame = g_string_new (row[9]);
   1.272 +        p->repeat = g_ascii_strtoull(row[10], NULL, 10);
   1.273 +        p->chancommfree = g_ascii_strtoull(row[11], NULL, 10);
   1.274 +        p->chanOutputFilters = g_string_new (row[12]);
   1.275 +        p->seriesid = g_string_new (row[13]);
   1.276 +        p->programid = g_string_new (row[14]);
   1.277 +        p->year = g_string_new (row[15]);
   1.278 +        p->stars = g_ascii_strtod(row[16], NULL);
   1.279 +
   1.280 +        if (!row[17] || !strcmp(row[17], "")) {
   1.281 +            p->originalAirDate = 0;
   1.282 +            p->hasAirDate = FALSE;
   1.283 +        } else {
   1.284 +            p->originalAirDate = gmyth_util_string_to_time_val (row[17]);
   1.285 +            p->hasAirDate = TRUE;
   1.286 +        }
   1.287 +        
   1.288 +        p->catType = g_string_new (row[18]);
   1.289 +
   1.290 +        *proglist = g_list_append((*proglist), p);
   1.291 +
   1.292 +#if 0        
   1.293 +        gmyth_program_info_print(p);
   1.294 +#endif        
   1.295 +    }
   1.296 +
   1.297 +    /* deallocate */
   1.298 +    mysql_free_result (res_set);
   1.299 +    g_string_free(querystr, TRUE);
   1.300 +
   1.301 +    return TRUE;
   1.302 +}