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