# HG changeset patch # User melunko # Date 1204413342 0 # Node ID 608cb47819c6c35fc2f96370f336261af5c3a041 # Parent 604f1de8ee0929c155bf45d4fa52859a29bd5dec [svn r943] Added new functions to add live recording diff -r 604f1de8ee09 -r 608cb47819c6 gmyth/gmyth/gmyth_livetv.c --- a/gmyth/gmyth/gmyth_livetv.c Fri Feb 29 19:03:41 2008 +0000 +++ b/gmyth/gmyth/gmyth_livetv.c Sat Mar 01 23:15:42 2008 +0000 @@ -116,7 +116,7 @@ } if (livetv->recorder != NULL) { - // gmyth_recorder_close(livetv->recorder); + gmyth_recorder_close(livetv->recorder); g_object_unref(livetv->recorder); livetv->recorder = NULL; } diff -r 604f1de8ee09 -r 608cb47819c6 gmyth/gmyth/gmyth_query.c --- a/gmyth/gmyth/gmyth_query.c Fri Feb 29 19:03:41 2008 +0000 +++ b/gmyth/gmyth/gmyth_query.c Sat Mar 01 23:15:42 2008 +0000 @@ -181,6 +181,15 @@ return TRUE; } +gboolean +gmyth_query_is_alive (GMythQuery *gmyth_query) +{ + g_return_val_if_fail (gmyth_query != NULL, FALSE); + + return (mysql_ping (gmyth_query->conn) == 0); +} + + /** Disconnects from the Mysql database in the backend. * * @param gmyth_query the GMythQuery instance to be disconnected diff -r 604f1de8ee09 -r 608cb47819c6 gmyth/gmyth/gmyth_query.h --- a/gmyth/gmyth/gmyth_query.h Fri Feb 29 19:03:41 2008 +0000 +++ b/gmyth/gmyth/gmyth_query.h Sat Mar 01 23:15:42 2008 +0000 @@ -38,12 +38,16 @@ #include "gmyth_backendinfo.h" G_BEGIN_DECLS + +#define GMYTH_QUERY_STANDARD_TIMEOUT 10 /*seconds*/ + #define GMYTH_QUERY_TYPE (gmyth_query_get_type ()) #define GMYTH_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE, GMythQuery)) #define GMYTH_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE, GMythQueryClass)) #define IS_GMYTH_QUERY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_QUERY_TYPE)) #define IS_GMYTH_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE)) #define GMYTH_QUERY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_QUERY_TYPE, GMythQueryClass)) + typedef struct _GMythQuery GMythQuery; typedef struct _GMythQueryClass GMythQueryClass; @@ -84,9 +88,9 @@ gboolean gmyth_query_connect(GMythQuery * gmyth_query, GMythBackendInfo * backend_info); gboolean gmyth_query_connect_with_timeout(GMythQuery * gmyth_query, - GMythBackendInfo * - backend_info, + GMythBackendInfo *backend_info, guint timeout); +gboolean gmyth_query_is_alive (GMythQuery *gmyth_query); gboolean gmyth_query_disconnect(GMythQuery * gmyth_query); G_END_DECLS diff -r 604f1de8ee09 -r 608cb47819c6 gmyth/gmyth/gmyth_recorder.c --- a/gmyth/gmyth/gmyth_recorder.c Fri Feb 29 19:03:41 2008 +0000 +++ b/gmyth/gmyth/gmyth_recorder.c Sat Mar 01 23:15:42 2008 +0000 @@ -69,8 +69,6 @@ { GMythRecorder *recorder = GMYTH_RECORDER(object); - gmyth_recorder_close(recorder); - if (recorder->mutex != NULL) { g_mutex_free(recorder->mutex); recorder->mutex = NULL; @@ -118,7 +116,7 @@ * @return a new instance of GMythRecorder. */ GMythRecorder * -gmyth_recorder_new(int num, GString * hostname, gshort port) +gmyth_recorder_new(int num, GString *hostname, gshort port) { GMythRecorder *encoder = GMYTH_RECORDER(g_object_new(GMYTH_RECORDER_TYPE, FALSE)); @@ -738,7 +736,7 @@ * @return The actual program info. */ GMythProgramInfo * -gmyth_recorder_get_current_program_info(GMythRecorder * recorder) +gmyth_recorder_get_current_program_info(GMythRecorder *recorder) { GMythStringList *str_list = NULL; GMythProgramInfo *program_info = NULL; @@ -1135,7 +1133,7 @@ * @return true, if the actual remote file is bein recorded. */ gboolean -gmyth_recorder_is_recording(GMythRecorder * recorder) +gmyth_recorder_is_recording (GMythRecorder* recorder) { gboolean ret = TRUE; diff -r 604f1de8ee09 -r 608cb47819c6 gmyth/gmyth/gmyth_recorder.h --- a/gmyth/gmyth/gmyth_recorder.h Fri Feb 29 19:03:41 2008 +0000 +++ b/gmyth/gmyth/gmyth_recorder.h Sat Mar 01 23:15:42 2008 +0000 @@ -136,15 +136,13 @@ gboolean gmyth_recorder_pause_recording(GMythRecorder * recorder); -GMythProgramInfo *gmyth_recorder_get_current_program_info(GMythRecorder * - recorder); +GMythProgramInfo *gmyth_recorder_get_current_program_info(GMythRecorder *recorder); GMythProgramInfo *gmyth_recorder_get_next_program_info(GMythRecorder * recorder, const GMythRecorderBrowseDirection direction); -GMythRecorder *gmyth_recorder_get_recorder_from_num(gint rec_id); gint64 gmyth_recorder_get_file_position(GMythRecorder * recorder); diff -r 604f1de8ee09 -r 608cb47819c6 gmyth/gmyth/gmyth_remote_util.c --- a/gmyth/gmyth/gmyth_remote_util.c Fri Feb 29 19:03:41 2008 +0000 +++ b/gmyth/gmyth/gmyth_remote_util.c Sat Mar 01 23:15:42 2008 +0000 @@ -34,6 +34,7 @@ #include "gmyth_recorder.h" #include "gmyth_stringlist.h" #include "gmyth_debug.h" +#include "gmyth_query.h" /** * Requests the Mythtv backend for a free remote recorder. @@ -93,7 +94,7 @@ * @return the number of remote encoders instance available, or 0 if no one is actually free.. */ gint -gmyth_remote_util_get_free_recorder_count(GMythSocket * socket) +gmyth_remote_util_get_free_recorder_count (GMythSocket * socket) { gint num_recs = 0; @@ -124,3 +125,51 @@ return num_recs; } + +/* Gets all available recorders in the backend. + * @returns the num of recorders found, or -1 if any error happens. + **/ +gint +gmyth_remote_util_get_recorder_list (GMythBackendInfo* binfo, GList **list) +{ + GMythQuery *sqlquery; + MYSQL_RES *msql_res; + gchar *query_str = "SELECT cardid FROM cardinput"; + + sqlquery = gmyth_query_new (); + if (!gmyth_query_connect_with_timeout (sqlquery, binfo, GMYTH_QUERY_STANDARD_TIMEOUT)) { + g_warning ("[%s] Could not connect to mysql server", __FUNCTION__); + g_object_unref (sqlquery); + return FALSE; + } + + /* Retrieves the list of recorders num */ + msql_res = gmyth_query_process_statement(sqlquery, query_str); + if (msql_res == NULL) { + g_warning("DB retrieval of recording list failed"); + return -1; + } else { + MYSQL_ROW row; + + *list = NULL; + + while ((row = mysql_fetch_row(msql_res)) != NULL) { + GMythRecorder *recorder; + gint recorder_num = (gint) g_ascii_strtoull (row[0], NULL, 10); + GString *hostname = g_string_new (binfo->hostname); + + g_debug ("XXXXXXXXXXXX Recorded found: %d", recorder_num); + recorder = gmyth_recorder_new (recorder_num, hostname, binfo->port); + if (gmyth_recorder_setup (recorder)) { + *list = g_list_append(*list, recorder); + } else { + g_object_unref (recorder); + } + + g_string_free (hostname, TRUE); + } + } + + return g_list_length (*list); +} + diff -r 604f1de8ee09 -r 608cb47819c6 gmyth/gmyth/gmyth_remote_util.h --- a/gmyth/gmyth/gmyth_remote_util.h Fri Feb 29 19:03:41 2008 +0000 +++ b/gmyth/gmyth/gmyth_remote_util.h Sat Mar 01 23:15:42 2008 +0000 @@ -28,14 +28,20 @@ #define __REMOTE_UTIL_H__ #include + #include "gmyth_recorder.h" #include "gmyth_socket.h" +#include "gmyth_backendinfo.h" G_BEGIN_DECLS - GMythRecorder * remote_request_next_free_recorder(GMythSocket * socket, - gint curr); -gint gmyth_remote_util_get_free_recorder_count(GMythSocket * - socket); + +GMythRecorder * remote_request_next_free_recorder(GMythSocket *socket, + gint curr); + +gint gmyth_remote_util_get_free_recorder_count(GMythSocket* socket); + +gint gmyth_remote_util_get_recorder_list (GMythBackendInfo* binfo, GList **list); G_END_DECLS + #endif diff -r 604f1de8ee09 -r 608cb47819c6 gmyth/gmyth/gmyth_scheduler.c --- a/gmyth/gmyth/gmyth_scheduler.c Fri Feb 29 19:03:41 2008 +0000 +++ b/gmyth/gmyth/gmyth_scheduler.c Sat Mar 01 23:15:42 2008 +0000 @@ -39,6 +39,7 @@ #include "gmyth_query.h" #include "gmyth_socket.h" #include "gmyth_debug.h" +#include "gmyth_remote_util.h" static void gmyth_scheduler_class_init(GMythSchedulerClass * klass); static void gmyth_scheduler_init(GMythScheduler * object); @@ -46,6 +47,22 @@ static void gmyth_scheduler_dispose(GObject * object); static void gmyth_scheduler_finalize(GObject * object); + +static gint +gmyth_scheduler_is_program_live_recorded (GMythScheduler * scheduler, + ScheduleInfo *schedule_info, + GMythProgramInfo **prog_info); +static gboolean +gmyth_scheduler_set_live_record (GMythScheduler * scheduler, + ScheduleInfo * schedule_info, + gint recorder_num, gboolean enable); +static gboolean +gmyth_scheduler_change_record_group (GMythScheduler* scheduler, + GMythProgramInfo *prog_info, + gchar *new_group); + + + static gboolean update_backend(GMythScheduler * scheduler, gint record_id); G_DEFINE_TYPE(GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT) @@ -491,6 +508,28 @@ return FALSE; } + /* + if (!gmyth_query_is_alive (scheduler->msqlquery)) { + g_warning ("[%s] MySql connection is not alive", __FUNCTION__); + return FALSE; + } + */ + + { + /* Before adding the schedule, we need to check if program is been played */ + GMythProgramInfo *prog_info = NULL; + gint recorder_num = + gmyth_scheduler_is_program_live_recorded (scheduler, schedule_info, + &prog_info); + if (recorder_num > 0) { + g_debug ("Recording already found in livetv... setting live record"); + gmyth_scheduler_change_record_group (scheduler, prog_info, "Default"); + + return gmyth_scheduler_set_live_record (scheduler, schedule_info, + recorder_num, TRUE); + } + } + msql_res = gmyth_query_process_statement_with_increment(scheduler->msqlquery, query_str, &rec_id); @@ -609,6 +648,110 @@ GMYTH_SCHEDULE_ONE_OCCURRENCE); } +/** Queries if the given schedule info is currently been recorded by any + * backend recorder. + * @return The recorder num currently recording the scheduled item, or -1 + * if program is not been recorded. + */ +static gint +gmyth_scheduler_is_program_live_recorded (GMythScheduler * scheduler, + ScheduleInfo *schedule_info, + GMythProgramInfo **prog_info) +{ + GList *list; + gint recorder_num = -1; + + if (gmyth_remote_util_get_recorder_list (scheduler->backend_info, &list) > 0) { + GList *iter = list; + while (iter) { + GMythRecorder *recorder = GMYTH_RECORDER ( iter->data ); + g_debug ("XXXX verifying the recorder %d", recorder->recorder_num); + + if (gmyth_recorder_is_recording (recorder)) { + GMythProgramInfo *pinfo = gmyth_recorder_get_current_program_info (recorder); + if (pinfo != NULL) { + if ((schedule_info->channel_id == pinfo->channel_id)) { + g_debug ("XXXXXX recorder %d is recording the program", recorder->recorder_num); + recorder_num = recorder->recorder_num; + *prog_info = pinfo; + break; + } + g_object_unref (pinfo); + } + } + + iter = iter->next; + } + + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); + } + + return recorder_num; + +} + +static gboolean +gmyth_scheduler_set_live_record (GMythScheduler * scheduler, + ScheduleInfo * schedule_info, + gint recorder_num, gboolean enable) +{ + gchar* datastr; + GMythSocket *socket; + gboolean ret = FALSE; + GMythStringList *strlist = gmyth_string_list_new(); + + datastr = g_strdup_printf ("QUERY_RECORDER %d", recorder_num); + gmyth_string_list_append_char_array (strlist, datastr); + gmyth_string_list_append_char_array (strlist, "SET_LIVE_RECORDING"); + gmyth_string_list_append_int (strlist, enable ? 1 : 0); + + socket = gmyth_backend_info_get_connected_socket (scheduler->backend_info); + if (socket != NULL) { + g_debug ("XXXX sending command for live recording"); + ret = (gmyth_socket_sendreceive_stringlist(socket, strlist) > 0); + g_object_unref (socket); + } else { + g_warning("[%s] Connection to backend failed!", __FUNCTION__); + } + + g_free(datastr); + g_object_unref(strlist); + return ret; +} + +static gboolean +gmyth_scheduler_change_record_group (GMythScheduler* scheduler, + GMythProgramInfo *prog_info, + gchar *new_group) + +{ + gchar *query_str = NULL; + gchar* startts = NULL; + + if (prog_info == NULL) { + g_warning ("Scheduler receiver a NULL program info to change its record group"); + return FALSE; + } + + //prog_info->recstartts->tv_sec += 60*60*2; + startts = gmyth_util_time_to_string_from_time_val (prog_info->recstartts); + + g_debug ("\n\n%s\n\n", startts); + query_str = g_strdup_printf("UPDATE recorded SET recgroup = \"%s\" " + "WHERE chanid = \"%d\" AND starttime = \"%s\"", + new_group, prog_info->channel_id, startts); + + gmyth_query_process_statement(scheduler->msqlquery, query_str); + + g_free (query_str); + g_free (startts); + + return TRUE ; +} + + + /** Requests the Mysql database in the backend to remove an existing schedule. * * @param scheduler the GMythScheduler instance. diff -r 604f1de8ee09 -r 608cb47819c6 gmyth/gmyth/gmyth_util.c --- a/gmyth/gmyth/gmyth_util.c Fri Feb 29 19:03:41 2008 +0000 +++ b/gmyth/gmyth/gmyth_util.c Sat Mar 01 23:15:42 2008 +0000 @@ -255,10 +255,10 @@ * @param time_value the time value to be converted * @return GString* the converted string */ -gchar * +gchar* gmyth_util_time_to_string_from_time_val(const GTimeVal * time_val) { - gchar *result = + gchar *result = gmyth_util_time_to_isoformat_from_time_val_fmt("%Y-%m-%d %H:%M:%S", time_val); @@ -597,7 +597,7 @@ * * @return a pointer to a GList with all the channels. */ -GList * +GList* gmyth_util_get_channel_list(GMythBackendInfo * backend_info) { GMythRecorder *recorder;