renatofilho@320: /** renatofilho@320: * GMyth Library renatofilho@320: * renatofilho@320: * @file gmyth/gmyth_scheduler.c renatofilho@320: * renatofilho@320: * @brief

The scheduler encapsulates all functions for browsing, scheduling renatofilho@320: * and modifying the recorded content. renatofilho@320: * renatofilho@320: * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia. renatofilho@320: * @author Alexsandro Jose Virginio dos Santos renatofilho@320: * renatofilho@320: *//* renatofilho@320: * renatofilho@320: * This program is free software; you can redistribute it and/or modify renatofilho@320: * it under the terms of the GNU Lesser General Public License as published by renatofilho@320: * the Free Software Foundation; either version 2 of the License, or renatofilho@320: * (at your option) any later version. renatofilho@320: * renatofilho@320: * This program is distributed in the hope that it will be useful, renatofilho@320: * but WITHOUT ANY WARRANTY; without even the implied warranty of renatofilho@320: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the renatofilho@320: * GNU General Public License for more details. renatofilho@320: * renatofilho@320: * You should have received a copy of the GNU Lesser General Public License renatofilho@320: * along with this program; if not, write to the Free Software renatofilho@320: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA renatofilho@320: */ renatofilho@320: renatofilho@320: #ifdef HAVE_CONFIG_H renatofilho@320: #include "config.h" renatofilho@320: #endif renatofilho@320: renatofilho@320: #include renatofilho@320: renatofilho@320: #include renatofilho@320: renatofilho@320: #include "gmyth_scheduler.h" renatofilho@320: #include "gmyth_util.h" renatofilho@320: #include "gmyth_query.h" renatofilho@320: #include "gmyth_socket.h" renatofilho@320: #include "gmyth_debug.h" renatofilho@320: renatofilho@320: static void gmyth_scheduler_class_init (GMythSchedulerClass *klass); renatofilho@320: static void gmyth_scheduler_init (GMythScheduler *object); renatofilho@320: renatofilho@320: static void gmyth_scheduler_dispose (GObject *object); renatofilho@320: static void gmyth_scheduler_finalize (GObject *object); renatofilho@320: renatofilho@320: static gint get_record_id_from_database (GMythScheduler *scheduler); renatofilho@320: static void update_backend (GMythScheduler *scheduler, gint record_id); renatofilho@320: renatofilho@320: G_DEFINE_TYPE(GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT) renatofilho@320: renatofilho@320: static void renatofilho@320: gmyth_scheduler_class_init (GMythSchedulerClass *klass) renatofilho@320: { renatofilho@320: GObjectClass *gobject_class; renatofilho@320: renatofilho@320: gobject_class = (GObjectClass *) klass; renatofilho@320: renatofilho@320: gobject_class->dispose = gmyth_scheduler_dispose; renatofilho@320: gobject_class->finalize = gmyth_scheduler_finalize; renatofilho@320: } renatofilho@320: renatofilho@320: static void renatofilho@320: gmyth_scheduler_init (GMythScheduler *sched) renatofilho@320: { renatofilho@320: sched->recordid =0; renatofilho@320: sched->type = 0; renatofilho@320: sched->search = 0; renatofilho@320: sched->profile = g_string_new(""); renatofilho@320: renatofilho@320: sched->dupin = 0; renatofilho@320: sched->dupmethod = 0; renatofilho@320: sched->autoexpire = 0; renatofilho@320: sched->autotranscode = 0; renatofilho@320: sched->transcoder = 0; renatofilho@320: renatofilho@320: sched->autocommflag = 0; renatofilho@320: sched->autouserjob1 = 0; renatofilho@320: sched->autouserjob2 = 0; renatofilho@320: sched->autouserjob3 = 0; renatofilho@320: sched->autouserjob4 = 0; renatofilho@320: renatofilho@320: sched->startoffset = 0; renatofilho@320: sched->endoffset = 0; renatofilho@320: sched->maxepisodes = 0; renatofilho@320: sched->maxnewest = 0; renatofilho@320: renatofilho@320: sched->recpriority = 0; renatofilho@320: sched->recgroup = 0; renatofilho@320: sched->playgroup = 0; renatofilho@320: renatofilho@320: sched->prefinput = 0; renatofilho@320: sched->inactive = 0; renatofilho@320: renatofilho@320: sched->searchType = g_string_new(""); renatofilho@320: sched->searchForWhat = g_string_new(""); renatofilho@320: renatofilho@320: sched->msqlquery = gmyth_query_new (); renatofilho@320: } renatofilho@320: renatofilho@320: static void renatofilho@320: gmyth_scheduler_dispose (GObject *object) renatofilho@320: { renatofilho@320: GMythScheduler *scheduler = GMYTH_SCHEDULER (object); renatofilho@320: renatofilho@320: if (scheduler->backend_info) { renatofilho@320: g_object_unref (scheduler->backend_info); renatofilho@320: scheduler->backend_info = NULL; renatofilho@320: } renatofilho@320: renatofilho@320: G_OBJECT_CLASS (gmyth_scheduler_parent_class)->dispose (object); renatofilho@320: } renatofilho@320: renatofilho@320: static void renatofilho@320: gmyth_scheduler_finalize (GObject *object) renatofilho@320: { renatofilho@320: g_signal_handlers_destroy (object); renatofilho@320: renatofilho@320: G_OBJECT_CLASS (gmyth_scheduler_parent_class)->finalize (object); renatofilho@320: } renatofilho@320: renatofilho@320: /** Creates a new instance of GMythScheduler. renatofilho@320: * renatofilho@320: * @return a new instance of GMythScheduler. renatofilho@320: */ renatofilho@320: GMythScheduler* renatofilho@320: gmyth_scheduler_new () renatofilho@320: { renatofilho@320: GMythScheduler *scheduler = renatofilho@320: GMYTH_SCHEDULER (g_object_new(GMYTH_SCHEDULER_TYPE, NULL)); renatofilho@320: renatofilho@320: return scheduler; renatofilho@320: } renatofilho@320: renatofilho@320: gboolean renatofilho@320: gmyth_scheduler_connect (GMythScheduler *scheduler, GMythBackendInfo *backend_info) renatofilho@320: { renatofilho@320: return gmyth_scheduler_connect_with_timeout (scheduler, backend_info, 0); renatofilho@320: } renatofilho@320: renatofilho@320: /** Connects to the Mysql database in the backend. The backend address renatofilho@320: * is loaded from the GMythSettings instance. renatofilho@320: * renatofilho@320: * @param scheduler the GMythScheduler instance to be connected. renatofilho@320: * @return true if connection was success, false if failed. renatofilho@320: */ renatofilho@320: gboolean renatofilho@320: gmyth_scheduler_connect_with_timeout (GMythScheduler *scheduler, renatofilho@320: GMythBackendInfo *backend_info, guint timeout) renatofilho@320: { renatofilho@320: assert(scheduler); renatofilho@320: g_return_val_if_fail (backend_info != NULL, FALSE); renatofilho@320: renatofilho@320: g_object_ref (backend_info); renatofilho@320: scheduler->backend_info = backend_info; renatofilho@320: renatofilho@320: if (scheduler->msqlquery == NULL) { renatofilho@320: g_warning ("[%s] GMythScheduler db initializing", __FUNCTION__); renatofilho@320: scheduler->msqlquery = gmyth_query_new (); renatofilho@320: } renatofilho@320: renatofilho@320: if (!gmyth_query_connect_with_timeout (scheduler->msqlquery, renatofilho@320: scheduler->backend_info, timeout)) { renatofilho@320: g_warning ("[%s] Error while connecting to db", __FUNCTION__); renatofilho@320: return FALSE; renatofilho@320: } renatofilho@320: renatofilho@320: return TRUE; renatofilho@320: } renatofilho@320: renatofilho@320: /** Disconnects from the Mysql database in the backend. renatofilho@320: * renatofilho@320: * @param scheduler the GMythScheduler instance to be disconnected renatofilho@320: * @return true if disconnection was success, false if failed. renatofilho@320: */ renatofilho@320: gboolean renatofilho@320: gmyth_scheduler_disconnect (GMythScheduler *scheduler) renatofilho@320: { renatofilho@320: assert(scheduler); renatofilho@320: renatofilho@320: if (scheduler->msqlquery != NULL) { renatofilho@320: gmyth_query_disconnect (scheduler->msqlquery); renatofilho@320: g_object_unref (scheduler->msqlquery); renatofilho@320: } renatofilho@320: renatofilho@320: return TRUE; renatofilho@320: } renatofilho@320: renatofilho@320: /** Retrieves from the backend Mysql database the list of recording schedules. renatofilho@320: * renatofilho@320: * @param scheduler The GMythScheduler instance. renatofilho@320: * @param schedule_list the GList pointer to be filled with the loaded list of ScheduleInfo items. renatofilho@320: * @return The amount of schedules retrieved from database, or -1 if error. renatofilho@320: */ renatofilho@320: gint renatofilho@320: gmyth_scheduler_get_schedule_list ( GMythScheduler *scheduler, GList **schedule_list) renatofilho@320: { renatofilho@320: ScheduleInfo *schedule; renatofilho@320: MYSQL_RES *msql_res; renatofilho@320: GString *query_str = g_string_new (""); renatofilho@320: gchar *date_time = NULL; renatofilho@320: renatofilho@320: assert(scheduler); renatofilho@320: renatofilho@320: g_string_printf (query_str, renatofilho@320: "SELECT recordid,programid,chanid,starttime,startdate," renatofilho@320: "endtime,enddate,title,subtitle,description,category FROM record;"); renatofilho@320: renatofilho@320: if (scheduler->msqlquery == NULL) { renatofilho@320: g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__); renatofilho@320: return -1; renatofilho@320: } renatofilho@320: msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str); renatofilho@320: renatofilho@320: if (msql_res == NULL) { renatofilho@320: g_warning ("DB retrieval of schedule list failed"); renatofilho@320: return -1; renatofilho@320: } else { renatofilho@320: MYSQL_ROW row; renatofilho@320: *schedule_list = NULL; renatofilho@320: renatofilho@320: while((row = mysql_fetch_row (msql_res)) != NULL) { renatofilho@320: schedule = g_new0(ScheduleInfo, 1); renatofilho@320: renatofilho@320: schedule->record_id = g_ascii_strtoull (row[0], NULL, 10); renatofilho@320: schedule->program_id = g_ascii_strtoull (row[1], NULL, 10); renatofilho@320: schedule->channel_id = g_ascii_strtoull (row[2], NULL, 10); renatofilho@320: renatofilho@320: /* generate a time_t from a time and a date db field */ renatofilho@320: g_sprintf (date_time, "%sT%s", row[4], row[3]); renatofilho@320: renatofilho@320: schedule->start_time = gmyth_util_string_to_time_val (date_time); renatofilho@320: renatofilho@320: /* generate a time_t from a time and a date db field */ renatofilho@320: g_sprintf (date_time, "%sT%s", row[6], row[5]); renatofilho@320: renatofilho@320: schedule->end_time = gmyth_util_string_to_time_val (date_time); renatofilho@320: renatofilho@320: schedule->title = g_string_new (row[7]); renatofilho@320: schedule->subtitle = g_string_new (row[8]); renatofilho@320: schedule->description = g_string_new (row[9]); renatofilho@320: schedule->category = g_string_new (row[10]); renatofilho@320: renatofilho@320: (*schedule_list) = g_list_append (*(schedule_list), schedule); renatofilho@320: } renatofilho@320: } renatofilho@320: renatofilho@320: mysql_free_result (msql_res); renatofilho@320: g_string_free(query_str, TRUE); renatofilho@320: g_free(date_time); renatofilho@320: renatofilho@320: return (*schedule_list == NULL) ? 0 : g_list_length (*schedule_list); renatofilho@320: } renatofilho@320: renatofilho@320: /** Retrieves from the backend Mysql database the list of recorded programs. renatofilho@320: * renatofilho@320: * @param scheduler The GMythScheduler instance. renatofilho@320: * @param recorded_list the GList pointer to be filled with the loaded RecordInfo items. renatofilho@320: * @return The amount of recorded retrieved from database, or -1 if error. renatofilho@320: */ renatofilho@320: gint renatofilho@320: gmyth_scheduler_get_recorded_list (GMythScheduler *scheduler, GList **recorded_list) renatofilho@320: { renatofilho@320: RecordedInfo *record; renatofilho@320: MYSQL_RES *msql_res; renatofilho@320: GString *query_str = g_string_new (""); renatofilho@320: renatofilho@320: assert(scheduler); renatofilho@320: renatofilho@320: g_string_printf (query_str, renatofilho@320: "SELECT recordid,programid,chanid,starttime,progstart," renatofilho@320: "endtime,progend,title,subtitle,description,category,filesize,basename FROM recorded WHERE recgroup != 'LiveTV'"); renatofilho@320: renatofilho@320: if (scheduler->msqlquery == NULL) { renatofilho@320: g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__); renatofilho@320: return -1; renatofilho@320: } renatofilho@320: renatofilho@320: msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str); renatofilho@320: renatofilho@320: if (msql_res == NULL) { renatofilho@320: g_warning ("DB retrieval of recording list failed"); renatofilho@320: return -1; renatofilho@320: } else { renatofilho@320: MYSQL_ROW row; renatofilho@320: *recorded_list = NULL; renatofilho@320: renatofilho@320: while((row = mysql_fetch_row (msql_res))!=NULL){ renatofilho@320: record = g_new0(RecordedInfo, 1); renatofilho@320: renatofilho@320: record->record_id = (guint) g_ascii_strtoull (row[0], NULL, 10); renatofilho@320: record->program_id = (guint) g_ascii_strtoull (row[1], NULL, 10); renatofilho@320: record->channel_id = (guint) g_ascii_strtoull (row[2], NULL, 10); renatofilho@320: renatofilho@320: record->start_time = gmyth_util_string_to_time_val (row[3]); renatofilho@320: record->end_time = gmyth_util_string_to_time_val (row[5]); renatofilho@320: renatofilho@320: record->title = g_string_new (row[7]); renatofilho@320: record->subtitle = g_string_new (row[8]); renatofilho@320: record->description = g_string_new (row[9]); renatofilho@320: record->category = g_string_new (row[10]); renatofilho@320: record->filesize = g_ascii_strtoull (row[11], NULL, 10); renatofilho@320: record->basename = g_string_new (row[12]); renatofilho@320: renatofilho@320: *recorded_list = g_list_append (*recorded_list, record); renatofilho@320: } renatofilho@320: } renatofilho@320: renatofilho@320: mysql_free_result (msql_res); renatofilho@320: g_string_free(query_str, TRUE); renatofilho@320: renatofilho@320: return (*recorded_list == NULL) ? 0 : g_list_length (*recorded_list); renatofilho@320: } renatofilho@320: renatofilho@320: /** Requests the Mysql database in the backend to add a new schedule. renatofilho@320: * renatofilho@320: * @param scheduler the GMythScheduler instance. renatofilho@320: * @param schedule_info the ScheduleInfo with recording schedule information renatofilho@320: * to be added. record_id = -1 to add a new schedule, otherwise this renatofilho@320: * function will update the schedule in the db renatofilho@320: * @return gboolean returns FALSE if some error occurs, TRUE otherwise renatofilho@320: */ renatofilho@320: gboolean renatofilho@320: gmyth_scheduler_add_schedule (GMythScheduler *scheduler, renatofilho@320: ScheduleInfo *schedule_info) renatofilho@320: { renatofilho@320: //GTimeVal *start_tm; renatofilho@320: //GTimeVal *end_tm; renatofilho@320: renatofilho@320: MYSQL_RES *msql_res; renatofilho@320: GString *query_str = g_string_new (""); renatofilho@320: renatofilho@320: gchar *date_time = NULL; renatofilho@320: renatofilho@320: assert(scheduler); renatofilho@320: renatofilho@320: if (scheduler->msqlquery == NULL) { renatofilho@320: g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__); renatofilho@320: return FALSE; renatofilho@320: } renatofilho@320: renatofilho@320: //TODO: verify if this funtion realy does what it should do! renatofilho@320: g_string_printf (query_str, "REPLACE INTO record " renatofilho@320: "(recordid, type, chanid, starttime, " renatofilho@320: "startdate, endtime, enddate, title," renatofilho@320: "profile, recpriority, maxnewest, inactive, " renatofilho@320: "maxepisodes, autoexpire, startoffset, endoffset, " renatofilho@320: "recgroup, dupmethod, dupin, station, " renatofilho@320: "autocommflag, findday, findtime, findid, " renatofilho@320: "search, autotranscode, transcoder, tsdefault, " renatofilho@320: "autouserjob1, autouserjob2, autouserjob3, autouserjob4) " renatofilho@320: " values ( %d, 1, %d, \"%s\"," //recordid, type, chanid, starttime renatofilho@320: " \"%s\", \"%s\", \"%s\", \"%s\"," renatofilho@320: //startdate, endtime, enddate, title renatofilho@320: "DEFAULT, 0, 0, 0, " //profile, recpriority, maxnewest, inactive renatofilho@320: "0, 1, 0, 0, " //maxepisodes, autoexpire, startoffset, endoffset renatofilho@320: "DEFAULT, 6, 15, %d, " //recgroup, dupmethod, dupin, station renatofilho@320: "1, %d, \"%s\", %d, " //autocommflag, findday, findtime, findid renatofilho@320: "5, 0, 29, 1, " //search, autotranscode, transcoder, tsdefault renatofilho@320: "0, 0, 0, 0 );", //autouserjob1, autouserjob2, autouserjob3, autouserjob4 renatofilho@320: schedule_info->record_id, schedule_info->channel_id, renatofilho@320: gmyth_util_time_to_string_only_time( schedule_info->start_time ), renatofilho@320: gmyth_util_time_to_string_only_date( schedule_info->start_time ), renatofilho@320: gmyth_util_time_to_string_only_time( schedule_info->end_time ), renatofilho@320: gmyth_util_time_to_string_only_date( schedule_info->end_time ), renatofilho@320: schedule_info->title->str, //title renatofilho@320: schedule_info->channel_id,//station renatofilho@320: (gmyth_util_time_val_to_date( schedule_info->start_time ))->tm_wday, //findday renatofilho@320: gmyth_util_time_to_string_only_time( schedule_info->start_time ), //findtime renatofilho@320: (gint)(schedule_info->start_time->tv_sec/60/60/24 + 719528)//findid renatofilho@320: ); renatofilho@320: renatofilho@320: gmyth_debug ( "Sending query to MySQL = %s.", query_str->str ); renatofilho@320: renatofilho@320: msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str); renatofilho@320: renatofilho@320: /* FIXME: currently no way to detect db error in UPDATE, REPLACES! renatofilho@320: if (msql_res == NULL) { renatofilho@320: g_warning ("DB retrieval of recording list failed"); renatofilho@320: return -1; renatofilho@320: }*/ renatofilho@320: renatofilho@320: /* TODO: verify record_id = -1 semantics */ renatofilho@320: if (schedule_info->record_id <= 0) renatofilho@320: schedule_info->record_id = get_record_id_from_database(scheduler); renatofilho@320: renatofilho@320: /* Notify the backend of changes */ renatofilho@320: update_backend(scheduler, schedule_info->record_id); renatofilho@320: renatofilho@320: /* free allocated memory */ renatofilho@320: mysql_free_result (msql_res); renatofilho@320: g_string_free(query_str, TRUE); renatofilho@320: renatofilho@320: return 1; renatofilho@320: } renatofilho@320: renatofilho@320: /** Requests the Mysql database in the backend to remove an existing schedule. renatofilho@320: * renatofilho@320: * @param scheduler the GMythScheduler instance. renatofilho@320: * @param record_id The schedule's record id to be removed renatofilho@320: * @return gboolean TRUE if success, FALSE if error renatofilho@320: */ renatofilho@320: gboolean renatofilho@320: gmyth_scheduler_delete_schedule (GMythScheduler *scheduler, gint record_id) renatofilho@320: { renatofilho@320: renatofilho@320: MYSQL_RES *msql_res; renatofilho@320: GString *query_str = g_string_new (""); renatofilho@320: renatofilho@320: assert(scheduler); renatofilho@320: renatofilho@320: if (scheduler->msqlquery == NULL) { renatofilho@320: g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__); renatofilho@320: return FALSE; renatofilho@320: } renatofilho@320: renatofilho@320: //======================================== renatofilho@320: g_string_printf (query_str, renatofilho@320: "DELETE FROM record WHERE recordid=%d", record_id); renatofilho@320: renatofilho@320: msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str); renatofilho@320: renatofilho@320: if (msql_res == NULL) { renatofilho@320: g_warning ("[%s] Error while trying to delete a schedule in the database", __FUNCTION__); renatofilho@320: return FALSE; renatofilho@320: } renatofilho@320: renatofilho@320: update_backend(scheduler, record_id);// Notify the backend of the changes renatofilho@320: renatofilho@320: mysql_free_result (msql_res); renatofilho@320: g_string_free(query_str, TRUE); renatofilho@320: renatofilho@320: return TRUE; renatofilho@320: } renatofilho@320: renatofilho@320: /** Requests the Mysql database in the backend to remove an existing recorded item. renatofilho@320: * renatofilho@320: * @param scheduler the GMythScheduler instance. renatofilho@320: * @param record_id The recorded item id to be removed renatofilho@320: * @return gboolean TRUE if success, FALSE if error renatofilho@320: */ renatofilho@320: gboolean renatofilho@320: gmyth_scheduler_delete_recorded (GMythScheduler *scheduler, gint record_id) renatofilho@320: { renatofilho@320: renatofilho@320: MYSQL_RES *msql_res; renatofilho@320: renatofilho@320: GString *query_str = g_string_new (""); renatofilho@320: renatofilho@320: assert(scheduler); renatofilho@320: renatofilho@320: if (scheduler->msqlquery == NULL) { renatofilho@320: g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__); renatofilho@320: return FALSE; renatofilho@320: } renatofilho@320: renatofilho@320: //======================================== renatofilho@320: g_string_printf (query_str, renatofilho@320: "DELETE FROM recorded WHERE recordid=%d", record_id); renatofilho@320: renatofilho@320: msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str); renatofilho@320: renatofilho@320: update_backend(scheduler, record_id);// Notify the backend of the changes renatofilho@320: renatofilho@320: mysql_free_result (msql_res); renatofilho@320: g_string_free(query_str, TRUE); renatofilho@320: renatofilho@320: return TRUE; renatofilho@320: } renatofilho@320: renatofilho@320: /** Retrieves an existing recorded item information from database. The information renatofilho@320: * is used to fill the returned GMythProgramInfo. renatofilho@320: * renatofilho@320: * @param scheduler The GMythScheduler instance. renatofilho@320: * @param channel The channel associated to the record renatofilho@320: * @param starttime The record start time renatofilho@320: * @return A GMythProgramInfo struct with the requested record item renatofilho@320: * information, or NULL if error. renatofilho@320: */ renatofilho@320: GMythProgramInfo* renatofilho@320: gmyth_scheduler_get_recorded (GMythScheduler *scheduler, renatofilho@320: GString *channel, GTimeVal* starttime) renatofilho@320: { renatofilho@320: MYSQL_RES *msql_res; renatofilho@320: GMythProgramInfo *proginfo = NULL; renatofilho@320: GString *query_str = g_string_new(""); renatofilho@320: gchar *time_str = gmyth_util_time_to_string_from_time_val (starttime); renatofilho@320: renatofilho@320: assert(scheduler); renatofilho@320: renatofilho@320: if (scheduler->msqlquery == NULL) { renatofilho@320: g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__); renatofilho@320: return NULL; renatofilho@320: } renatofilho@320: renatofilho@320: g_string_printf (query_str, "SELECT recorded.chanid,starttime,endtime,title, " renatofilho@320: "subtitle,description,channel.channum, " renatofilho@320: "channel.callsign,channel.name,channel.commfree, " renatofilho@320: "channel.outputfilters,seriesid,programid,filesize, " renatofilho@320: "lastmodified,stars,previouslyshown,originalairdate, " renatofilho@320: "hostname,recordid,transcoder,playgroup, " renatofilho@320: "recorded.recpriority,progstart,progend,basename,recgroup " renatofilho@320: "FROM recorded " renatofilho@320: "LEFT JOIN channel " renatofilho@320: "ON recorded.chanid = channel.chanid " renatofilho@320: "WHERE recorded.chanid = \"%s\" " renatofilho@320: "AND starttime = \"%s\" ;", renatofilho@320: channel->str, time_str); renatofilho@320: renatofilho@320: msql_res = gmyth_query_process_statement (scheduler->msqlquery, query_str->str); renatofilho@320: renatofilho@320: if (msql_res /*&& query.size() > 0*/) { renatofilho@320: renatofilho@320: MYSQL_ROW msql_row = mysql_fetch_row (msql_res); renatofilho@320: if (msql_row) { renatofilho@320: renatofilho@320: proginfo = gmyth_program_info_new(); renatofilho@320: renatofilho@320: proginfo->chanid = g_string_new (msql_row[0]); renatofilho@320: proginfo->startts = gmyth_util_string_to_time_val (msql_row[23]); renatofilho@320: proginfo->endts = gmyth_util_string_to_time_val (msql_row[24]); renatofilho@320: proginfo->recstartts = gmyth_util_string_to_time_val (msql_row[1]); renatofilho@320: proginfo->recendts = gmyth_util_string_to_time_val (msql_row[2]); renatofilho@320: proginfo->title = g_string_new (msql_row[3]); renatofilho@320: proginfo->subtitle = g_string_new (msql_row[4]); renatofilho@320: proginfo->description = g_string_new (msql_row[5]); renatofilho@320: renatofilho@320: proginfo->chanstr = g_string_new (msql_row[6]); renatofilho@320: proginfo->chansign = g_string_new (msql_row[7]); renatofilho@320: proginfo->channame = g_string_new (msql_row[0]); renatofilho@320: proginfo->chancommfree = g_ascii_strtoull (msql_row[9], NULL, 10); renatofilho@320: proginfo->chanOutputFilters = g_string_new (msql_row[10]); renatofilho@320: proginfo->seriesid = g_string_new (msql_row[11]); renatofilho@320: proginfo->programid = g_string_new (msql_row[12]); renatofilho@320: proginfo->filesize = g_ascii_strtoull (msql_row[13], NULL, 10); renatofilho@320: renatofilho@320: proginfo->lastmodified = gmyth_util_string_to_time_val (msql_row[14]); renatofilho@320: renatofilho@320: proginfo->stars = g_ascii_strtod (msql_row[15], NULL); renatofilho@320: proginfo->repeat = g_ascii_strtoull (msql_row[16], NULL, 10); renatofilho@320: renatofilho@320: if (msql_row[17] == NULL) { renatofilho@320: proginfo->originalAirDate = 0; renatofilho@320: proginfo->hasAirDate = FALSE; renatofilho@320: } else { renatofilho@320: proginfo->originalAirDate = gmyth_util_string_to_time_val (msql_row[17]); renatofilho@320: proginfo->hasAirDate = TRUE; renatofilho@320: } renatofilho@320: renatofilho@320: proginfo->hostname = g_string_new (msql_row[18]); renatofilho@320: proginfo->recordid = g_ascii_strtoull (msql_row[19], NULL, 10); renatofilho@320: proginfo->transcoder = g_ascii_strtoull (msql_row[20], NULL, 10); renatofilho@320: renatofilho@320: //proginfo->spread = -1; renatofilho@320: //proginfo->programflags = proginfo->getProgramFlags(); renatofilho@320: renatofilho@320: proginfo->recgroup = g_string_new (msql_row[26]); renatofilho@320: proginfo->playgroup = g_string_new (msql_row[21]); renatofilho@320: proginfo->recpriority = g_ascii_strtoull (msql_row[22], NULL, 10); renatofilho@320: renatofilho@320: proginfo->pathname = g_string_new (msql_row[25]); renatofilho@320: renatofilho@320: gmyth_debug ("One program info loaded from mysql database\n"); renatofilho@320: } renatofilho@320: } renatofilho@320: renatofilho@320: mysql_free_result (msql_res); renatofilho@320: g_string_free(query_str, TRUE); renatofilho@320: g_free(time_str); renatofilho@320: renatofilho@320: return proginfo; renatofilho@320: } renatofilho@320: renatofilho@320: /** Retrieves the next record id. renatofilho@320: * renatofilho@320: * @param scheduler The GMythScheduler instance. renatofilho@320: * @return gint record_id if success, -1 otherwise renatofilho@320: */ renatofilho@320: static gint renatofilho@320: get_record_id_from_database (GMythScheduler *scheduler) renatofilho@320: { renatofilho@320: gint record_id; renatofilho@320: renatofilho@320: assert(scheduler); renatofilho@320: renatofilho@320: if (scheduler->msqlquery == NULL) { renatofilho@320: g_warning ("[%s] Scheduler db connection not initialized", __FUNCTION__); renatofilho@320: return 0; renatofilho@320: } renatofilho@320: renatofilho@320: record_id = mysql_insert_id (scheduler->msqlquery->conn); renatofilho@320: renatofilho@320: return record_id; renatofilho@320: } renatofilho@320: renatofilho@320: /** Notifies the backend of an update in the db. renatofilho@320: * renatofilho@320: * @param record_id the id of the modified recording. renatofilho@320: */ renatofilho@320: static void renatofilho@320: update_backend(GMythScheduler *scheduler, gint record_id)//fixme: put void and discovery record_id inside renatofilho@320: { renatofilho@320: GMythSocket *socket; renatofilho@320: GMythStringList *strlist = gmyth_string_list_new (); renatofilho@320: GString *datastr = g_string_new ("RESCHEDULE_RECORDINGS "); renatofilho@320: renatofilho@320: g_string_append_printf (datastr, "%d", record_id); renatofilho@320: gmyth_string_list_append_string (strlist, datastr); renatofilho@320: renatofilho@320: socket = gmyth_socket_new (); renatofilho@320: if (gmyth_socket_connect (socket, scheduler->backend_info->hostname, renatofilho@320: scheduler->backend_info->port)) { renatofilho@320: gmyth_socket_sendreceive_stringlist (socket, strlist); renatofilho@320: } else { renatofilho@320: g_warning ("[%s] Connection to backend failed!", __FUNCTION__); renatofilho@320: } renatofilho@320: renatofilho@320: g_string_free(datastr, TRUE); renatofilho@320: g_object_unref(strlist); renatofilho@320: } renatofilho@320: renatofilho@320: void renatofilho@320: gmyth_scheduler_recorded_info_get_preview (RecordedInfo *info, GByteArray* data) renatofilho@320: { renatofilho@320: } renatofilho@320: renatofilho@320: void renatofilho@320: gmyth_scheduler_recorded_info_free (RecordedInfo *info) renatofilho@320: { renatofilho@320: if (info->title != NULL) renatofilho@320: g_string_free (info->title, TRUE); renatofilho@320: renatofilho@320: if (info->subtitle != NULL) renatofilho@320: g_string_free (info->subtitle, TRUE); renatofilho@320: renatofilho@320: if (info->description != NULL) renatofilho@320: g_string_free (info->description, TRUE); renatofilho@320: renatofilho@320: if (info->category != NULL) renatofilho@320: g_string_free (info->category, TRUE); renatofilho@320: renatofilho@320: if (info->basename != NULL) renatofilho@320: g_string_free (info->basename, TRUE); renatofilho@320: renatofilho@320: g_free (info); renatofilho@320: } renatofilho@320: renatofilho@320: void renatofilho@320: gmyth_scheduler_schedule_info_free (ScheduleInfo *info) renatofilho@320: { renatofilho@320: if (info->title != NULL) renatofilho@320: g_string_free (info->title, TRUE); renatofilho@320: renatofilho@320: if (info->subtitle != NULL) renatofilho@320: g_string_free (info->subtitle, TRUE); renatofilho@320: renatofilho@320: if (info->description != NULL) renatofilho@320: g_string_free (info->description, TRUE); renatofilho@320: renatofilho@320: if (info->category != NULL) renatofilho@320: g_string_free (info->category, TRUE); renatofilho@320: renatofilho@320: g_free (info); renatofilho@320: } renatofilho@320: