1.1 --- a/gmyth/gmyth/gmyth_livetv.c Fri Feb 29 19:03:41 2008 +0000
1.2 +++ b/gmyth/gmyth/gmyth_livetv.c Sat Mar 01 23:15:42 2008 +0000
1.3 @@ -116,7 +116,7 @@
1.4 }
1.5
1.6 if (livetv->recorder != NULL) {
1.7 - // gmyth_recorder_close(livetv->recorder);
1.8 + gmyth_recorder_close(livetv->recorder);
1.9 g_object_unref(livetv->recorder);
1.10 livetv->recorder = NULL;
1.11 }
2.1 --- a/gmyth/gmyth/gmyth_query.c Fri Feb 29 19:03:41 2008 +0000
2.2 +++ b/gmyth/gmyth/gmyth_query.c Sat Mar 01 23:15:42 2008 +0000
2.3 @@ -181,6 +181,15 @@
2.4 return TRUE;
2.5 }
2.6
2.7 +gboolean
2.8 +gmyth_query_is_alive (GMythQuery *gmyth_query)
2.9 +{
2.10 + g_return_val_if_fail (gmyth_query != NULL, FALSE);
2.11 +
2.12 + return (mysql_ping (gmyth_query->conn) == 0);
2.13 +}
2.14 +
2.15 +
2.16 /** Disconnects from the Mysql database in the backend.
2.17 *
2.18 * @param gmyth_query the GMythQuery instance to be disconnected
3.1 --- a/gmyth/gmyth/gmyth_query.h Fri Feb 29 19:03:41 2008 +0000
3.2 +++ b/gmyth/gmyth/gmyth_query.h Sat Mar 01 23:15:42 2008 +0000
3.3 @@ -38,12 +38,16 @@
3.4 #include "gmyth_backendinfo.h"
3.5
3.6 G_BEGIN_DECLS
3.7 +
3.8 +#define GMYTH_QUERY_STANDARD_TIMEOUT 10 /*seconds*/
3.9 +
3.10 #define GMYTH_QUERY_TYPE (gmyth_query_get_type ())
3.11 #define GMYTH_QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GMYTH_QUERY_TYPE, GMythQuery))
3.12 #define GMYTH_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE, GMythQueryClass))
3.13 #define IS_GMYTH_QUERY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GMYTH_QUERY_TYPE))
3.14 #define IS_GMYTH_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMYTH_QUERY_TYPE))
3.15 #define GMYTH_QUERY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMYTH_QUERY_TYPE, GMythQueryClass))
3.16 +
3.17 typedef struct _GMythQuery GMythQuery;
3.18 typedef struct _GMythQueryClass GMythQueryClass;
3.19
3.20 @@ -84,9 +88,9 @@
3.21 gboolean gmyth_query_connect(GMythQuery * gmyth_query,
3.22 GMythBackendInfo * backend_info);
3.23 gboolean gmyth_query_connect_with_timeout(GMythQuery * gmyth_query,
3.24 - GMythBackendInfo *
3.25 - backend_info,
3.26 + GMythBackendInfo *backend_info,
3.27 guint timeout);
3.28 +gboolean gmyth_query_is_alive (GMythQuery *gmyth_query);
3.29 gboolean gmyth_query_disconnect(GMythQuery * gmyth_query);
3.30
3.31 G_END_DECLS
4.1 --- a/gmyth/gmyth/gmyth_recorder.c Fri Feb 29 19:03:41 2008 +0000
4.2 +++ b/gmyth/gmyth/gmyth_recorder.c Sat Mar 01 23:15:42 2008 +0000
4.3 @@ -69,8 +69,6 @@
4.4 {
4.5 GMythRecorder *recorder = GMYTH_RECORDER(object);
4.6
4.7 - gmyth_recorder_close(recorder);
4.8 -
4.9 if (recorder->mutex != NULL) {
4.10 g_mutex_free(recorder->mutex);
4.11 recorder->mutex = NULL;
4.12 @@ -118,7 +116,7 @@
4.13 * @return a new instance of GMythRecorder.
4.14 */
4.15 GMythRecorder *
4.16 -gmyth_recorder_new(int num, GString * hostname, gshort port)
4.17 +gmyth_recorder_new(int num, GString *hostname, gshort port)
4.18 {
4.19 GMythRecorder *encoder =
4.20 GMYTH_RECORDER(g_object_new(GMYTH_RECORDER_TYPE, FALSE));
4.21 @@ -738,7 +736,7 @@
4.22 * @return The actual program info.
4.23 */
4.24 GMythProgramInfo *
4.25 -gmyth_recorder_get_current_program_info(GMythRecorder * recorder)
4.26 +gmyth_recorder_get_current_program_info(GMythRecorder *recorder)
4.27 {
4.28 GMythStringList *str_list = NULL;
4.29 GMythProgramInfo *program_info = NULL;
4.30 @@ -1135,7 +1133,7 @@
4.31 * @return <code>true</code>, if the actual remote file is bein recorded.
4.32 */
4.33 gboolean
4.34 -gmyth_recorder_is_recording(GMythRecorder * recorder)
4.35 +gmyth_recorder_is_recording (GMythRecorder* recorder)
4.36 {
4.37 gboolean ret = TRUE;
4.38
5.1 --- a/gmyth/gmyth/gmyth_recorder.h Fri Feb 29 19:03:41 2008 +0000
5.2 +++ b/gmyth/gmyth/gmyth_recorder.h Sat Mar 01 23:15:42 2008 +0000
5.3 @@ -136,15 +136,13 @@
5.4
5.5 gboolean gmyth_recorder_pause_recording(GMythRecorder * recorder);
5.6
5.7 -GMythProgramInfo *gmyth_recorder_get_current_program_info(GMythRecorder *
5.8 - recorder);
5.9 +GMythProgramInfo *gmyth_recorder_get_current_program_info(GMythRecorder *recorder);
5.10
5.11 GMythProgramInfo *gmyth_recorder_get_next_program_info(GMythRecorder *
5.12 recorder, const
5.13 GMythRecorderBrowseDirection
5.14 direction);
5.15
5.16 -GMythRecorder *gmyth_recorder_get_recorder_from_num(gint rec_id);
5.17
5.18 gint64 gmyth_recorder_get_file_position(GMythRecorder * recorder);
5.19
6.1 --- a/gmyth/gmyth/gmyth_remote_util.c Fri Feb 29 19:03:41 2008 +0000
6.2 +++ b/gmyth/gmyth/gmyth_remote_util.c Sat Mar 01 23:15:42 2008 +0000
6.3 @@ -34,6 +34,7 @@
6.4 #include "gmyth_recorder.h"
6.5 #include "gmyth_stringlist.h"
6.6 #include "gmyth_debug.h"
6.7 +#include "gmyth_query.h"
6.8
6.9 /**
6.10 * Requests the Mythtv backend for a free remote recorder.
6.11 @@ -93,7 +94,7 @@
6.12 * @return the number of remote encoders instance available, or 0 if no one is actually free..
6.13 */
6.14 gint
6.15 -gmyth_remote_util_get_free_recorder_count(GMythSocket * socket)
6.16 +gmyth_remote_util_get_free_recorder_count (GMythSocket * socket)
6.17 {
6.18 gint num_recs = 0;
6.19
6.20 @@ -124,3 +125,51 @@
6.21
6.22 return num_recs;
6.23 }
6.24 +
6.25 +/* Gets all available recorders in the backend.
6.26 + * @returns the num of recorders found, or -1 if any error happens.
6.27 + **/
6.28 +gint
6.29 +gmyth_remote_util_get_recorder_list (GMythBackendInfo* binfo, GList **list)
6.30 +{
6.31 + GMythQuery *sqlquery;
6.32 + MYSQL_RES *msql_res;
6.33 + gchar *query_str = "SELECT cardid FROM cardinput";
6.34 +
6.35 + sqlquery = gmyth_query_new ();
6.36 + if (!gmyth_query_connect_with_timeout (sqlquery, binfo, GMYTH_QUERY_STANDARD_TIMEOUT)) {
6.37 + g_warning ("[%s] Could not connect to mysql server", __FUNCTION__);
6.38 + g_object_unref (sqlquery);
6.39 + return FALSE;
6.40 + }
6.41 +
6.42 + /* Retrieves the list of recorders num */
6.43 + msql_res = gmyth_query_process_statement(sqlquery, query_str);
6.44 + if (msql_res == NULL) {
6.45 + g_warning("DB retrieval of recording list failed");
6.46 + return -1;
6.47 + } else {
6.48 + MYSQL_ROW row;
6.49 +
6.50 + *list = NULL;
6.51 +
6.52 + while ((row = mysql_fetch_row(msql_res)) != NULL) {
6.53 + GMythRecorder *recorder;
6.54 + gint recorder_num = (gint) g_ascii_strtoull (row[0], NULL, 10);
6.55 + GString *hostname = g_string_new (binfo->hostname);
6.56 +
6.57 + g_debug ("XXXXXXXXXXXX Recorded found: %d", recorder_num);
6.58 + recorder = gmyth_recorder_new (recorder_num, hostname, binfo->port);
6.59 + if (gmyth_recorder_setup (recorder)) {
6.60 + *list = g_list_append(*list, recorder);
6.61 + } else {
6.62 + g_object_unref (recorder);
6.63 + }
6.64 +
6.65 + g_string_free (hostname, TRUE);
6.66 + }
6.67 + }
6.68 +
6.69 + return g_list_length (*list);
6.70 +}
6.71 +
7.1 --- a/gmyth/gmyth/gmyth_remote_util.h Fri Feb 29 19:03:41 2008 +0000
7.2 +++ b/gmyth/gmyth/gmyth_remote_util.h Sat Mar 01 23:15:42 2008 +0000
7.3 @@ -28,14 +28,20 @@
7.4 #define __REMOTE_UTIL_H__
7.5
7.6 #include <glib.h>
7.7 +
7.8 #include "gmyth_recorder.h"
7.9 #include "gmyth_socket.h"
7.10 +#include "gmyth_backendinfo.h"
7.11
7.12 G_BEGIN_DECLS
7.13 - GMythRecorder * remote_request_next_free_recorder(GMythSocket * socket,
7.14 - gint curr);
7.15 -gint gmyth_remote_util_get_free_recorder_count(GMythSocket *
7.16 - socket);
7.17 +
7.18 +GMythRecorder * remote_request_next_free_recorder(GMythSocket *socket,
7.19 + gint curr);
7.20 +
7.21 +gint gmyth_remote_util_get_free_recorder_count(GMythSocket* socket);
7.22 +
7.23 +gint gmyth_remote_util_get_recorder_list (GMythBackendInfo* binfo, GList **list);
7.24
7.25 G_END_DECLS
7.26 +
7.27 #endif
8.1 --- a/gmyth/gmyth/gmyth_scheduler.c Fri Feb 29 19:03:41 2008 +0000
8.2 +++ b/gmyth/gmyth/gmyth_scheduler.c Sat Mar 01 23:15:42 2008 +0000
8.3 @@ -39,6 +39,7 @@
8.4 #include "gmyth_query.h"
8.5 #include "gmyth_socket.h"
8.6 #include "gmyth_debug.h"
8.7 +#include "gmyth_remote_util.h"
8.8
8.9 static void gmyth_scheduler_class_init(GMythSchedulerClass * klass);
8.10 static void gmyth_scheduler_init(GMythScheduler * object);
8.11 @@ -46,6 +47,22 @@
8.12 static void gmyth_scheduler_dispose(GObject * object);
8.13 static void gmyth_scheduler_finalize(GObject * object);
8.14
8.15 +
8.16 +static gint
8.17 +gmyth_scheduler_is_program_live_recorded (GMythScheduler * scheduler,
8.18 + ScheduleInfo *schedule_info,
8.19 + GMythProgramInfo **prog_info);
8.20 +static gboolean
8.21 +gmyth_scheduler_set_live_record (GMythScheduler * scheduler,
8.22 + ScheduleInfo * schedule_info,
8.23 + gint recorder_num, gboolean enable);
8.24 +static gboolean
8.25 +gmyth_scheduler_change_record_group (GMythScheduler* scheduler,
8.26 + GMythProgramInfo *prog_info,
8.27 + gchar *new_group);
8.28 +
8.29 +
8.30 +
8.31 static gboolean update_backend(GMythScheduler * scheduler, gint record_id);
8.32
8.33 G_DEFINE_TYPE(GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT)
8.34 @@ -491,6 +508,28 @@
8.35 return FALSE;
8.36 }
8.37
8.38 + /*
8.39 + if (!gmyth_query_is_alive (scheduler->msqlquery)) {
8.40 + g_warning ("[%s] MySql connection is not alive", __FUNCTION__);
8.41 + return FALSE;
8.42 + }
8.43 + */
8.44 +
8.45 + {
8.46 + /* Before adding the schedule, we need to check if program is been played */
8.47 + GMythProgramInfo *prog_info = NULL;
8.48 + gint recorder_num =
8.49 + gmyth_scheduler_is_program_live_recorded (scheduler, schedule_info,
8.50 + &prog_info);
8.51 + if (recorder_num > 0) {
8.52 + g_debug ("Recording already found in livetv... setting live record");
8.53 + gmyth_scheduler_change_record_group (scheduler, prog_info, "Default");
8.54 +
8.55 + return gmyth_scheduler_set_live_record (scheduler, schedule_info,
8.56 + recorder_num, TRUE);
8.57 + }
8.58 + }
8.59 +
8.60 msql_res =
8.61 gmyth_query_process_statement_with_increment(scheduler->msqlquery,
8.62 query_str, &rec_id);
8.63 @@ -609,6 +648,110 @@
8.64 GMYTH_SCHEDULE_ONE_OCCURRENCE);
8.65 }
8.66
8.67 +/** Queries if the given schedule info is currently been recorded by any
8.68 + * backend recorder.
8.69 + * @return The recorder num currently recording the scheduled item, or -1
8.70 + * if program is not been recorded.
8.71 + */
8.72 +static gint
8.73 +gmyth_scheduler_is_program_live_recorded (GMythScheduler * scheduler,
8.74 + ScheduleInfo *schedule_info,
8.75 + GMythProgramInfo **prog_info)
8.76 +{
8.77 + GList *list;
8.78 + gint recorder_num = -1;
8.79 +
8.80 + if (gmyth_remote_util_get_recorder_list (scheduler->backend_info, &list) > 0) {
8.81 + GList *iter = list;
8.82 + while (iter) {
8.83 + GMythRecorder *recorder = GMYTH_RECORDER ( iter->data );
8.84 + g_debug ("XXXX verifying the recorder %d", recorder->recorder_num);
8.85 +
8.86 + if (gmyth_recorder_is_recording (recorder)) {
8.87 + GMythProgramInfo *pinfo = gmyth_recorder_get_current_program_info (recorder);
8.88 + if (pinfo != NULL) {
8.89 + if ((schedule_info->channel_id == pinfo->channel_id)) {
8.90 + g_debug ("XXXXXX recorder %d is recording the program", recorder->recorder_num);
8.91 + recorder_num = recorder->recorder_num;
8.92 + *prog_info = pinfo;
8.93 + break;
8.94 + }
8.95 + g_object_unref (pinfo);
8.96 + }
8.97 + }
8.98 +
8.99 + iter = iter->next;
8.100 + }
8.101 +
8.102 + g_list_foreach (list, (GFunc) g_object_unref, NULL);
8.103 + g_list_free (list);
8.104 + }
8.105 +
8.106 + return recorder_num;
8.107 +
8.108 +}
8.109 +
8.110 +static gboolean
8.111 +gmyth_scheduler_set_live_record (GMythScheduler * scheduler,
8.112 + ScheduleInfo * schedule_info,
8.113 + gint recorder_num, gboolean enable)
8.114 +{
8.115 + gchar* datastr;
8.116 + GMythSocket *socket;
8.117 + gboolean ret = FALSE;
8.118 + GMythStringList *strlist = gmyth_string_list_new();
8.119 +
8.120 + datastr = g_strdup_printf ("QUERY_RECORDER %d", recorder_num);
8.121 + gmyth_string_list_append_char_array (strlist, datastr);
8.122 + gmyth_string_list_append_char_array (strlist, "SET_LIVE_RECORDING");
8.123 + gmyth_string_list_append_int (strlist, enable ? 1 : 0);
8.124 +
8.125 + socket = gmyth_backend_info_get_connected_socket (scheduler->backend_info);
8.126 + if (socket != NULL) {
8.127 + g_debug ("XXXX sending command for live recording");
8.128 + ret = (gmyth_socket_sendreceive_stringlist(socket, strlist) > 0);
8.129 + g_object_unref (socket);
8.130 + } else {
8.131 + g_warning("[%s] Connection to backend failed!", __FUNCTION__);
8.132 + }
8.133 +
8.134 + g_free(datastr);
8.135 + g_object_unref(strlist);
8.136 + return ret;
8.137 +}
8.138 +
8.139 +static gboolean
8.140 +gmyth_scheduler_change_record_group (GMythScheduler* scheduler,
8.141 + GMythProgramInfo *prog_info,
8.142 + gchar *new_group)
8.143 +
8.144 +{
8.145 + gchar *query_str = NULL;
8.146 + gchar* startts = NULL;
8.147 +
8.148 + if (prog_info == NULL) {
8.149 + g_warning ("Scheduler receiver a NULL program info to change its record group");
8.150 + return FALSE;
8.151 + }
8.152 +
8.153 + //prog_info->recstartts->tv_sec += 60*60*2;
8.154 + startts = gmyth_util_time_to_string_from_time_val (prog_info->recstartts);
8.155 +
8.156 + g_debug ("\n\n%s\n\n", startts);
8.157 + query_str = g_strdup_printf("UPDATE recorded SET recgroup = \"%s\" "
8.158 + "WHERE chanid = \"%d\" AND starttime = \"%s\"",
8.159 + new_group, prog_info->channel_id, startts);
8.160 +
8.161 + gmyth_query_process_statement(scheduler->msqlquery, query_str);
8.162 +
8.163 + g_free (query_str);
8.164 + g_free (startts);
8.165 +
8.166 + return TRUE ;
8.167 +}
8.168 +
8.169 +
8.170 +
8.171 /** Requests the Mysql database in the backend to remove an existing schedule.
8.172 *
8.173 * @param scheduler the GMythScheduler instance.
9.1 --- a/gmyth/gmyth/gmyth_util.c Fri Feb 29 19:03:41 2008 +0000
9.2 +++ b/gmyth/gmyth/gmyth_util.c Sat Mar 01 23:15:42 2008 +0000
9.3 @@ -255,10 +255,10 @@
9.4 * @param time_value the time value to be converted
9.5 * @return GString* the converted string
9.6 */
9.7 -gchar *
9.8 +gchar*
9.9 gmyth_util_time_to_string_from_time_val(const GTimeVal * time_val)
9.10 {
9.11 - gchar *result =
9.12 + gchar *result =
9.13 gmyth_util_time_to_isoformat_from_time_val_fmt("%Y-%m-%d %H:%M:%S",
9.14 time_val);
9.15
9.16 @@ -597,7 +597,7 @@
9.17 *
9.18 * @return a pointer to a GList with all the channels.
9.19 */
9.20 -GList *
9.21 +GList*
9.22 gmyth_util_get_channel_list(GMythBackendInfo * backend_info)
9.23 {
9.24 GMythRecorder *recorder;