[svn r951] gmyth now is 0.8.1. Added methods epg_is_connected() and scheduler_is_connected()
4 * @file gmyth/gmyth_scheduler.c
6 * @brief <p> The scheduler encapsulates all functions for browsing, scheduling
7 * and modifying the recorded content.
9 * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
10 * @author Alexsandro Jose Virginio dos Santos <alexsandro.santos@indt.org.br>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 #include <glib/gprintf.h>
37 #include "gmyth_scheduler.h"
38 #include "gmyth_util.h"
39 #include "gmyth_query.h"
40 #include "gmyth_socket.h"
41 #include "gmyth_debug.h"
42 #include "gmyth_remote_util.h"
44 static void gmyth_scheduler_class_init(GMythSchedulerClass * klass);
45 static void gmyth_scheduler_init(GMythScheduler * object);
47 static void gmyth_scheduler_dispose(GObject * object);
48 static void gmyth_scheduler_finalize(GObject * object);
52 gmyth_scheduler_is_program_live_recorded (GMythScheduler * scheduler,
53 ScheduleInfo *schedule_info,
54 GMythProgramInfo **prog_info);
56 gmyth_scheduler_set_live_record (GMythScheduler * scheduler,
57 ScheduleInfo * schedule_info,
58 gint recorder_num, gboolean enable);
60 gmyth_scheduler_change_record_group (GMythScheduler* scheduler,
61 GMythProgramInfo *prog_info,
65 gmyth_scheduler_query_schedule_list (GMythScheduler * scheduler,
66 GList ** schedule_list,
69 gmyth_scheduler_query_schedule_id (GMythScheduler *scheduler,
70 GMythProgramInfo *prog_info);
71 static gint gmyth_scheduler_query_old_schedule (GMythScheduler *scheduler,
72 gint channel_id, GTimeVal *startts,
75 static gboolean update_backend(GMythScheduler * scheduler, gint record_id);
77 G_DEFINE_TYPE(GMythScheduler, gmyth_scheduler, G_TYPE_OBJECT)
78 static void gmyth_scheduler_class_init(GMythSchedulerClass * klass)
80 GObjectClass *gobject_class;
82 gobject_class = (GObjectClass *) klass;
84 gobject_class->dispose = gmyth_scheduler_dispose;
85 gobject_class->finalize = gmyth_scheduler_finalize;
89 gmyth_scheduler_init(GMythScheduler * sched)
94 sched->profile = g_string_new("");
98 sched->autoexpire = 0;
99 sched->autotranscode = 0;
100 sched->transcoder = 0;
102 sched->autocommflag = 0;
103 sched->autouserjob1 = 0;
104 sched->autouserjob2 = 0;
105 sched->autouserjob3 = 0;
106 sched->autouserjob4 = 0;
108 sched->startoffset = 0;
109 sched->endoffset = 0;
110 sched->maxepisodes = 0;
111 sched->maxnewest = 0;
113 sched->recpriority = 0;
114 sched->recgroup = g_string_new("");
115 sched->playgroup = g_string_new("");
117 sched->prefinput = 0;
120 sched->search_type = g_string_new("");
121 sched->search_what = g_string_new("");
123 sched->msqlquery = gmyth_query_new();
127 gmyth_scheduler_dispose(GObject * object)
129 GMythScheduler *scheduler = GMYTH_SCHEDULER(object);
131 if (scheduler->backend_info) {
132 g_object_unref(scheduler->backend_info);
133 scheduler->backend_info = NULL;
136 if (scheduler->msqlquery) {
137 g_object_unref(scheduler->msqlquery);
138 scheduler->msqlquery = NULL;
141 g_string_free(scheduler->profile, TRUE);
142 g_string_free(scheduler->recgroup, TRUE);
143 g_string_free(scheduler->playgroup, TRUE);
144 g_string_free(scheduler->search_type, TRUE);
145 g_string_free(scheduler->search_what, TRUE);
147 G_OBJECT_CLASS(gmyth_scheduler_parent_class)->dispose(object);
151 gmyth_scheduler_finalize(GObject * object)
153 g_signal_handlers_destroy(object);
155 G_OBJECT_CLASS(gmyth_scheduler_parent_class)->finalize(object);
158 /** Creates a new instance of GMythScheduler.
160 * @return a new instance of GMythScheduler.
163 gmyth_scheduler_new()
165 GMythScheduler *scheduler =
166 GMYTH_SCHEDULER(g_object_new(GMYTH_SCHEDULER_TYPE, NULL));
172 gmyth_scheduler_connect(GMythScheduler * scheduler,
173 GMythBackendInfo * backend_info)
175 return gmyth_scheduler_connect_with_timeout(scheduler, backend_info,
179 /** Connects to the Mysql database in the backend. The backend address
180 * is loaded from the GMythSettings instance.
182 * @param scheduler the GMythScheduler instance to be connected.
183 * @return true if connection was success, false if failed.
186 gmyth_scheduler_connect_with_timeout(GMythScheduler * scheduler,
187 GMythBackendInfo * backend_info,
191 g_return_val_if_fail(backend_info != NULL, FALSE);
193 if (scheduler->backend_info)
194 g_object_unref(scheduler->backend_info);
196 scheduler->backend_info = g_object_ref(backend_info);
198 if (scheduler->msqlquery == NULL) {
199 g_warning("[%s] GMythScheduler db initializing", __FUNCTION__);
200 scheduler->msqlquery = gmyth_query_new();
203 if (!gmyth_query_connect_with_timeout(scheduler->msqlquery,
204 scheduler->backend_info,
206 g_warning("[%s] Error while connecting to db", __FUNCTION__);
214 gmyth_scheduler_is_connected (GMythScheduler *scheduler)
216 g_return_val_if_fail (scheduler != NULL, FALSE);
218 return gmyth_query_is_alive (scheduler->msqlquery);
221 /** Disconnects from the Mysql database in the backend.
223 * @param scheduler the GMythScheduler instance to be disconnected
224 * @return true if disconnection was success, false if failed.
227 gmyth_scheduler_disconnect(GMythScheduler * scheduler)
231 if (scheduler->msqlquery != NULL) {
232 gmyth_query_disconnect(scheduler->msqlquery);
238 /** Retrieves from the backend Mysql database the list of recording schedules.
240 * @param scheduler The GMythScheduler instance.
241 * @param schedule_list the GList pointer to be filled with the loaded list of ScheduleInfo items.
242 * @return The amount of schedules retrieved from database, or -1 if error.
245 gmyth_scheduler_get_schedule_list (GMythScheduler * scheduler,
246 GList ** schedule_list)
248 return gmyth_scheduler_query_schedule_list (scheduler, schedule_list, NULL);
252 gmyth_scheduler_get_schedule (GMythScheduler * scheduler, gint sched_id)
254 GList *sched_list = NULL;
255 ScheduleInfo *schedule = NULL;
259 filter = g_strdup_printf ("WHERE recordid=%d", sched_id);
261 count = gmyth_scheduler_query_schedule_list (scheduler, &sched_list, filter);
262 if ((count > 0) && (sched_list != NULL)) {
263 schedule = (ScheduleInfo*) sched_list->data;
264 g_list_free (sched_list);
272 gmyth_scheduler_query_schedule_list (GMythScheduler * scheduler,
273 GList ** schedule_list,
277 ScheduleInfo *schedule;
279 GString *query_str = g_string_new("");
280 gchar *date_time = NULL;
283 if (scheduler->msqlquery == NULL) {
284 g_warning("[%s] Scheduler db connection not initialized",
289 if (filter == NULL) {
290 g_string_printf(query_str,
291 "SELECT recordid,programid,chanid,starttime,startdate,"
292 "endtime,enddate,title,subtitle,description,category,type,parentid,seriesid FROM record;");
294 g_string_printf(query_str,
295 "SELECT recordid,programid,chanid,starttime,startdate,"
296 "endtime,enddate,title,subtitle,description,category,type,parentid,seriesid FROM record "
302 gmyth_query_process_statement(scheduler->msqlquery,
305 if (msql_res == NULL) {
306 g_warning("DB retrieval of schedule list failed");
311 *schedule_list = NULL;
313 while ((row = mysql_fetch_row(msql_res)) != NULL) {
314 schedule = g_new0(ScheduleInfo, 1);
317 schedule->schedule_id =
318 (guint) g_ascii_strtoull(row[0], NULL, 10);
319 schedule->program_id = g_string_new (row[1]);
320 schedule->channel_id = (gint) g_ascii_strtoull (row[2], NULL, 10);
323 * generate a time_t from a time and a date db field
325 date_time = g_strdup_printf("%sT%s", row[4], row[3]);
326 schedule->start_time =
327 gmyth_util_string_to_time_val(date_time);
331 * generate a time_t from a time and a date db field
333 date_time = g_strdup_printf("%sT%s", row[6], row[5]);
334 schedule->end_time = gmyth_util_string_to_time_val(date_time);
337 schedule->title = g_string_new(row[7]);
338 schedule->subtitle = g_string_new(row[8]);
339 schedule->description = g_string_new(row[9]);
340 schedule->category = g_string_new(row[10]);
341 type = g_ascii_strtoull (row[11], NULL, 10);
343 schedule->type = GMYTH_SCHEDULE_ALL_OCCURRENCES;
344 } else if (type == 1) {
345 schedule->type = GMYTH_SCHEDULE_ONE_OCCURRENCE;
346 } else if (type == 8) {
347 schedule->type = GMYTH_SCHEDULE_EXCEPTION;
348 schedule->parentid = (gint) g_ascii_strtoull (row[12], NULL, 10);
351 schedule->seriesid = g_string_new (row[13]);
353 (*schedule_list) = g_list_append(*(schedule_list), schedule);
357 mysql_free_result(msql_res);
358 g_string_free(query_str, TRUE);
360 return (*schedule_list == NULL) ? 0 : g_list_length(*schedule_list);
363 /** Retrieves from the backend Mysql database the list of recorded programs.
365 * @param scheduler The GMythScheduler instance.
366 * @param recorded_list the GList pointer to be filled with the loaded RecordInfo items.
367 * @return The amount of recorded retrieved from database, or -1 if error.
370 gmyth_scheduler_get_recorded_list(GMythScheduler * scheduler,
371 GList ** recorded_list)
373 RecordedInfo *record;
375 GString *query_str = g_string_new("");
379 g_string_printf(query_str,
380 "SELECT recordid,programid,chanid,starttime,progstart,"
381 "endtime,progend,title,subtitle,description,category,"
382 "filesize,basename,seriesid FROM recorded WHERE recgroup != 'LiveTV'");
384 if (scheduler->msqlquery == NULL) {
385 g_warning("[%s] Scheduler db connection not initialized",
391 gmyth_query_process_statement(scheduler->msqlquery,
394 if (msql_res == NULL) {
395 g_warning("DB retrieval of recording list failed");
400 (*recorded_list) = NULL;
402 while ((row = mysql_fetch_row(msql_res)) != NULL) {
403 record = g_new0(RecordedInfo, 1);
405 record->record_id = (guint) g_ascii_strtoull(row[0], NULL, 10);
406 record->program_id = g_string_new (row[1]);
407 record->channel_id = (gint) g_ascii_strtoull(row[2], NULL, 10);
408 record->start_time = gmyth_util_string_to_time_val(row[3]);
409 record->end_time = gmyth_util_string_to_time_val(row[5]);
411 record->title = g_string_new(row[7]);
412 record->subtitle = g_string_new(row[8]);
413 record->description = g_string_new(row[9]);
414 record->category = g_string_new(row[10]);
415 record->filesize = g_ascii_strtoull(row[11], NULL, 10);
416 record->basename = g_string_new(row[12]);
417 record->seriesid = g_string_new(row[13]);
419 (*recorded_list) = g_list_append((*recorded_list), record);
423 mysql_free_result(msql_res);
424 g_string_free(query_str, TRUE);
426 return (*recorded_list == NULL) ? 0 : g_list_length(*recorded_list);
430 gmyth_scheduler_get_recorded_info (GMythScheduler *scheduler,
431 const gchar* basename)
433 RecordedInfo *record = NULL;
435 GString *query_str = g_string_new("");
439 g_string_printf(query_str,
440 "SELECT recordid,programid,chanid,starttime,progstart,"
441 "endtime,progend,title,subtitle,description,category,"
442 "filesize,basename,seriesid FROM recorded "
443 "WHERE recgroup != 'LiveTV' AND basename = '%s'", basename);
445 if (scheduler->msqlquery == NULL) {
446 g_warning("[%s] Scheduler db connection not initialized",
452 gmyth_query_process_statement(scheduler->msqlquery,
455 if (msql_res == NULL) {
456 g_warning("DB retrieval of recording list failed");
460 row = mysql_fetch_row(msql_res);
462 record = g_new0(RecordedInfo, 1);
463 record->record_id = (guint) g_ascii_strtoull(row[0], NULL, 10);
464 record->program_id = g_string_new (row[1]);
465 record->channel_id = (gint) g_ascii_strtoull(row[2], NULL, 10);
466 record->start_time = gmyth_util_string_to_time_val(row[3]);
467 record->end_time = gmyth_util_string_to_time_val(row[5]);
468 record->title = g_string_new(row[7]);
469 record->subtitle = g_string_new(row[8]);
470 record->description = g_string_new(row[9]);
471 record->category = g_string_new(row[10]);
472 record->filesize = g_ascii_strtoull(row[11], NULL, 10);
473 record->basename = g_string_new(row[12]);
474 record->seriesid = g_string_new(row[13]);
478 mysql_free_result(msql_res);
479 g_string_free(query_str, TRUE);
486 _set_value(GMythQuery * myth_query, char *field, gchar * value,
491 ("UPDATE record SET recordid = %d, %s = \"%s\" WHERE recordid = %d;",
492 rec_id, field, value, rec_id);
494 gmyth_query_process_statement(myth_query, query);
499 _set_int_value(GMythQuery * myth_query, char *field, gint value,
502 gchar *str_value = g_strdup_printf("%d", value);
504 _set_value(myth_query, field, str_value, rec_id);
509 gmyth_scheduler_add_schedule_program (GMythScheduler * scheduler,
510 GMythProgramInfo *program,
511 GMythScheduleType type)
515 info = g_new0 (ScheduleInfo, 1);
516 info->program_id = g_string_new (program->program_id->str);
517 info->channel_id = program->channel_id;
518 info->start_time = g_new0 (GTimeVal, 1);
519 *info->start_time = *program->startts;
520 info->end_time = g_new0 (GTimeVal, 1);
521 *info->end_time = *program->endts;
522 info->seriesid = g_string_new (program->seriesid->str);
523 info->title = g_string_new (program->title->str);
524 info->subtitle = g_string_new (program->subtitle->str);
525 info->description = g_string_new (program->description->str);
526 info->category = g_string_new (program->category->str);
529 if (gmyth_scheduler_add_schedule_full (scheduler, info, type))
531 if (!program->recstartts)
532 program->recstartts = g_new0 (GTimeVal, 1);
533 *program->recstartts = *info->start_time;
535 if (!program->recendts)
536 program->recendts = g_new0 (GTimeVal, 1);
537 *program->recendts = *info->end_time;
539 program->recordid = info->schedule_id;
543 gmyth_schedule_info_free (info);
549 gmyth_scheduler_add_schedule_full (GMythScheduler * scheduler,
550 ScheduleInfo *schedule_info, GMythScheduleType type)
553 gchar *query_str = NULL;
554 gchar *station = NULL;
557 g_return_val_if_fail (IS_GMYTH_SCHEDULER (scheduler), FALSE);
559 if (scheduler->msqlquery == NULL) {
560 g_warning("[%s] Scheduler db connection not initialized",
566 if (!gmyth_query_is_alive (scheduler->msqlquery)) {
567 g_warning ("[%s] MySql connection is not alive", __FUNCTION__);
573 /* Before adding the schedule, we need to check if program is been played */
574 GMythProgramInfo *prog_info = NULL;
576 gmyth_scheduler_is_program_live_recorded (scheduler, schedule_info,
578 if ((recorder_num > 0) && (prog_info != NULL)) {
580 gmyth_scheduler_change_record_group (scheduler, prog_info, "Default");
582 res = gmyth_scheduler_set_live_record (scheduler, schedule_info,
584 schedule_info->schedule_id = gmyth_scheduler_query_schedule_id (scheduler, prog_info);
589 /* Now, verifies if there is an old schedule for this program */
590 /* If threre is one, we reactivate it */
593 time_t now = time (NULL);
595 if (schedule_info->start_time->tv_sec < now) {
596 sched_id = gmyth_scheduler_query_old_schedule (scheduler, schedule_info->channel_id,
597 schedule_info->start_time, TRUE);
599 schedule_info->schedule_id = sched_id;
606 gmyth_query_process_statement_with_increment(scheduler->msqlquery,
607 "INSERT record (recordid) VALUE (0);",
609 mysql_free_result(msql_res);
611 // Retrieves the station info
614 ("SELECT callsign FROM channel WHERE chanid = %d;",
615 schedule_info->channel_id);
617 gmyth_query_process_statement(scheduler->msqlquery, query_str);
618 if (msql_res == NULL) {
619 g_warning("[%s] msql query returned NULL MYSQL_RES", __FUNCTION__);
624 if ((row = mysql_fetch_row(msql_res)) != NULL) {
625 station = g_strdup(row[0]);
628 mysql_free_result(msql_res);
631 // _set_value (field, value, id);
632 _set_int_value(scheduler->msqlquery, "chanid",
633 schedule_info->channel_id, rec_id);
634 _set_value(scheduler->msqlquery, "station", station, rec_id);
635 _set_value(scheduler->msqlquery, "title", schedule_info->title->str,
637 // / subtitle, description
638 _set_value(scheduler->msqlquery, "starttime",
639 gmyth_util_time_to_string_only_time(schedule_info->
640 start_time), rec_id);
641 _set_value(scheduler->msqlquery, "startdate",
642 gmyth_util_time_to_string_only_date(schedule_info->
643 start_time), rec_id);
644 _set_value(scheduler->msqlquery, "endtime",
645 gmyth_util_time_to_string_only_time(schedule_info->
647 _set_value(scheduler->msqlquery, "enddate",
648 gmyth_util_time_to_string_only_date(schedule_info->
650 // / category, series id, program id
651 // _set_value (scheduler->msqlquery, "findday",
652 // (gmyth_util_time_val_to_date( schedule_info->start_time
653 // ))->tm_wday, rec_id);
654 // _set_value (scheduler->msqlquery, "findtime",
655 // gmyth_util_time_to_string_only_time( schedule_info->start_time),
657 // _set_int_value (scheduler->msqlquery, "findid",
658 // (gint)(schedule_info->start_time->tv_sec/60/60/24 + 719528),
661 if (schedule_info->seriesid)
662 _set_value(scheduler->msqlquery, "seriesid",
663 schedule_info->seriesid->str, rec_id);
665 _set_value(scheduler->msqlquery, "parentid", "0", rec_id);
666 _set_value(scheduler->msqlquery, "search", "0", rec_id);
668 if (type == GMYTH_SCHEDULE_ALL_OCCURRENCES) {
669 _set_int_value(scheduler->msqlquery, "type", 3, rec_id);
670 } else if (type == GMYTH_SCHEDULE_ONE_OCCURRENCE) {
671 _set_int_value(scheduler->msqlquery, "type", 1, rec_id);
672 } else if (type == GMYTH_SCHEDULE_EXCEPTION) {
673 _set_int_value(scheduler->msqlquery, "type", 8, rec_id);
674 _set_int_value(scheduler->msqlquery, "parentid", schedule_info->parentid,
678 _set_value(scheduler->msqlquery, "recpriority", "0", rec_id);
679 _set_value(scheduler->msqlquery, "startoffset", "0", rec_id);
680 _set_value(scheduler->msqlquery, "endoffset", "0", rec_id);
681 _set_value(scheduler->msqlquery, "dupmethod", "6", rec_id); // ?
682 _set_value(scheduler->msqlquery, "dupin", "15", rec_id); // ?
684 _set_value(scheduler->msqlquery, "prefinput", "0", rec_id);
685 _set_value(scheduler->msqlquery, "inactive", "0", rec_id);
686 _set_value(scheduler->msqlquery, "profile", "Default", rec_id);
687 _set_value(scheduler->msqlquery, "recgroup", "Default", rec_id);
688 _set_value(scheduler->msqlquery, "storagegroup", "Default", rec_id);
689 _set_value(scheduler->msqlquery, "playgroup", "Default", rec_id);
690 _set_value(scheduler->msqlquery, "autoexpire", "1", rec_id);
691 _set_value(scheduler->msqlquery, "maxepisodes", "0", rec_id);
692 _set_value(scheduler->msqlquery, "maxnewest", "0", rec_id);
693 _set_value(scheduler->msqlquery, "autocommflag", "1", rec_id);
694 _set_value(scheduler->msqlquery, "autotranscode", "0", rec_id);
695 _set_value(scheduler->msqlquery, "transcoder", "0", rec_id);
697 _set_value(scheduler->msqlquery, "autouserjob1", "0", rec_id);
698 _set_value(scheduler->msqlquery, "autouserjob2", "0", rec_id);
699 _set_value(scheduler->msqlquery, "autouserjob3", "0", rec_id);
700 _set_value(scheduler->msqlquery, "autouserjob4", "0", rec_id);
702 schedule_info->schedule_id = rec_id;
704 /* Notify the backend of changes */
705 return update_backend(scheduler, rec_id);
708 /** Requests the Mysql database in the backend to add a new schedule.
710 * @param scheduler the GMythScheduler instance.
711 * @param schedule_info the ScheduleInfo with recording schedule information
712 * to be added. record_id = -1 to add a new schedule, otherwise this
713 * function will update the schedule in the db
714 * @return gboolean returns FALSE if some error occurs, TRUE otherwise
717 gmyth_scheduler_add_schedule (GMythScheduler * scheduler,
718 ScheduleInfo * schedule_info)
720 return gmyth_scheduler_add_schedule_full (scheduler, schedule_info,
721 GMYTH_SCHEDULE_ONE_OCCURRENCE);
725 gmyth_scheduler_query_schedule_id (GMythScheduler *scheduler,
726 GMythProgramInfo *prog_info)
728 MYSQL_RES *mysql_res;
730 gchar *query_str, *startts;
732 startts = gmyth_util_time_to_string_from_time_val (prog_info->recstartts);
733 query_str = g_strdup_printf ("SELECT recordid from recorded "
734 "WHERE chanid= \"%d\" AND starttime = \"%s\";",
735 prog_info->channel_id, startts);
737 mysql_res = gmyth_query_process_statement(scheduler->msqlquery, query_str);
740 MYSQL_ROW msql_row = mysql_fetch_row(mysql_res);
742 sched_id = g_ascii_strtoull (msql_row[0], NULL, 10);
749 /* Queries if there is an old schedule previously set to this program.
750 * If reactivate flag is set, the recording will be reactivated.
751 * @returns the schedule id.
754 gmyth_scheduler_query_old_schedule (GMythScheduler *scheduler,
755 gint channel_id, GTimeVal *startts,
758 MYSQL_RES *mysql_res;
760 gchar *query_str, *startts_str;
762 startts_str = gmyth_util_time_to_string_from_time_val (startts);
763 query_str = g_strdup_printf ("SELECT recordid from oldrecorded "
764 "WHERE chanid= \"%d\" AND starttime=\"%s\";",
765 channel_id, startts_str);
767 mysql_res = gmyth_query_process_statement(scheduler->msqlquery, query_str);
771 MYSQL_ROW msql_row = mysql_fetch_row(mysql_res);
773 sched_id = g_ascii_strtoull (msql_row[0], NULL, 10);
774 if ((sched_id > 0) && (reactivate)) {
775 query_str = g_strdup_printf ("UPDATE oldrecorded SET reactivate = 1 "
776 "WHERE chanid= \"%d\" AND starttime=\"%s\";",
777 channel_id, startts_str);
778 update_backend (scheduler, 0);
786 /** Queries if the given schedule info is currently been recorded by any
788 * @return The recorder num currently recording the scheduled item, or -1
789 * if program is not been recorded.
792 gmyth_scheduler_is_program_live_recorded (GMythScheduler * scheduler,
793 ScheduleInfo *schedule_info,
794 GMythProgramInfo **prog_info)
797 gint recorder_num = -1;
799 if (gmyth_remote_util_get_recorder_list (scheduler->backend_info, &list) > 0) {
802 GMythRecorder *recorder = GMYTH_RECORDER ( iter->data );
804 if (gmyth_recorder_is_recording (recorder)) {
805 GMythProgramInfo *pinfo = gmyth_recorder_get_current_program_info (recorder);
807 if ((schedule_info->channel_id == pinfo->channel_id) &&
808 (schedule_info->start_time->tv_sec == pinfo->startts->tv_sec)) {
809 recorder_num = recorder->recorder_num;
813 g_object_unref (pinfo);
820 g_list_foreach (list, (GFunc) g_object_unref, NULL);
829 gmyth_scheduler_set_live_record (GMythScheduler * scheduler,
830 ScheduleInfo * schedule_info,
831 gint recorder_num, gboolean enable)
835 gboolean ret = FALSE;
836 GMythStringList *strlist = gmyth_string_list_new();
838 datastr = g_strdup_printf ("QUERY_RECORDER %d", recorder_num);
839 gmyth_string_list_append_char_array (strlist, datastr);
840 gmyth_string_list_append_char_array (strlist, "SET_LIVE_RECORDING");
841 gmyth_string_list_append_int (strlist, enable ? 1 : 0);
843 socket = gmyth_backend_info_get_connected_socket (scheduler->backend_info);
844 if (socket != NULL) {
845 ret = (gmyth_socket_sendreceive_stringlist(socket, strlist) > 0);
846 g_object_unref (socket);
848 g_warning("[%s] Connection to backend failed!", __FUNCTION__);
852 g_object_unref(strlist);
857 gmyth_scheduler_change_record_group (GMythScheduler* scheduler,
858 GMythProgramInfo *prog_info,
862 gchar *query_str = NULL;
863 gchar* startts = NULL;
865 if (prog_info == NULL) {
866 g_warning ("Scheduler receiver a NULL program info to change its record group");
870 startts = gmyth_util_time_to_string_from_time_val (prog_info->recstartts);
872 query_str = g_strdup_printf("UPDATE recorded SET recgroup = \"%s\" "
873 "WHERE chanid = \"%d\" AND starttime = \"%s\";",
874 new_group, prog_info->channel_id, startts);
876 gmyth_query_process_statement(scheduler->msqlquery, query_str);
886 /** Requests the Mysql database in the backend to remove an existing schedule.
888 * @param scheduler the GMythScheduler instance.
889 * @param schedule_id The schedule's record id to be removed
890 * @return gboolean TRUE if success, FALSE if error
893 gmyth_scheduler_delete_schedule (GMythScheduler * scheduler, gint schedule_id)
896 GString *query_str = NULL;
898 g_return_val_if_fail (scheduler != NULL, FALSE);
900 if (scheduler->msqlquery == NULL) {
901 g_warning("[%s] Scheduler db connection not initialized",
907 /* Before adding the schedule, we need to check if program is been played */
908 GMythProgramInfo *prog_info = NULL;
909 ScheduleInfo *sched_info = NULL;
911 sched_info = gmyth_scheduler_get_schedule (scheduler, schedule_id);
912 if (sched_info != NULL) {
914 gmyth_scheduler_is_program_live_recorded (scheduler, sched_info,
916 if ((recorder_num > 0) && (prog_info != NULL)) {
918 gmyth_scheduler_change_record_group (scheduler, prog_info, "LiveTV");
920 ret = gmyth_scheduler_set_live_record (scheduler, sched_info,
921 recorder_num, FALSE);
922 gmyth_schedule_info_free (sched_info);
929 query_str = g_string_new("");
930 g_string_printf(query_str,
931 "DELETE FROM record WHERE recordid=%d", schedule_id);
934 gmyth_query_process_statement(scheduler->msqlquery,
938 mysql_free_result(msql_res);
939 g_string_free(query_str, TRUE);
941 // Notify the backend of the changes
942 return update_backend(scheduler, schedule_id);
946 * Add an exception program to be removed from the schedule list, when programs
947 * where scheduled with the GMYTH_SCHEDULE_ALL_OCCURRENCES option.
948 * @param scheduler the GMythScheduler instance.
949 * @param schedule_id the schedule id of the all occurrence schedule to be changed
950 * @param exception_info the ScheduleInfo to be removed from all schedule occurrences
951 * @return TRUE if success, FALSE if any error happens
954 gmyth_scheduler_add_exception (GMythScheduler *scheduler, gint schedule_id,
955 ScheduleInfo *exception_info)
959 g_return_val_if_fail (scheduler != NULL, FALSE);
960 g_return_val_if_fail (exception_info != NULL, FALSE);
962 exception_info->parentid = schedule_id;
963 res = gmyth_scheduler_add_schedule_full (scheduler, exception_info, GMYTH_SCHEDULE_EXCEPTION);
968 /** Requests the Mysql database in the backend to remove an existing recorded item.
970 * @param scheduler the GMythScheduler instance.
971 * @param record_id The recorded item id to be removed
972 * @return gboolean TRUE if success, FALSE if error
975 gmyth_scheduler_delete_recorded(GMythScheduler * scheduler, gint record_id)
980 GString *query_str = g_string_new("");
984 if (scheduler->msqlquery == NULL) {
985 g_warning("[%s] Scheduler db connection not initialized",
989 // ========================================
990 g_string_printf(query_str,
991 "DELETE FROM recorded WHERE recordid=%d", record_id);
993 // FIXME: Mythtv implementation runs also: DELETE FROM oldfind WHERE
997 gmyth_query_process_statement(scheduler->msqlquery,
1000 mysql_free_result(msql_res);
1001 g_string_free(query_str, TRUE);
1003 // Notify the backend of the changes
1004 return update_backend(scheduler, record_id);
1007 /** Retrieves an existing recorded item information from database. The information
1008 * is used to fill the returned GMythProgramInfo.
1010 * @param scheduler The GMythScheduler instance.
1011 * @param channel The channel associated to the record
1012 * @param starttime The record start time
1013 * @return A GMythProgramInfo struct with the requested record item
1014 * information, or NULL if error.
1017 gmyth_scheduler_get_recorded(GMythScheduler * scheduler,
1018 GString * channel, GTimeVal * starttime)
1020 MYSQL_RES *msql_res;
1021 GMythProgramInfo *proginfo = NULL;
1022 GString *query_str = g_string_new("");
1024 gmyth_util_time_to_string_from_time_val(starttime);
1028 gmyth_debug("[%s] channel: %s", __FUNCTION__, channel->str);
1030 if (scheduler->msqlquery == NULL) {
1031 g_warning("[%s] Scheduler db connection not initialized",
1036 g_string_printf(query_str,
1037 "SELECT recorded.chanid,starttime,endtime,title, "
1038 "subtitle,description,channel.channum, "
1039 "channel.callsign,channel.name,channel.commfree, "
1040 "channel.outputfilters,seriesid,programid,filesize, "
1041 "lastmodified,stars,previouslyshown,originalairdate, "
1042 "hostname,recordid,transcoder,playgroup, "
1043 "recorded.recpriority,progstart,progend,basename,recgroup "
1044 "FROM recorded " "LEFT JOIN channel "
1045 "ON recorded.chanid = channel.chanid "
1046 "WHERE recorded.chanid = \"%s\" "
1047 "AND starttime = \"%s\" ;", channel->str, time_str);
1050 gmyth_query_process_statement(scheduler->msqlquery,
1053 if (msql_res /* && query.size() > 0 */ ) {
1054 MYSQL_ROW msql_row = mysql_fetch_row(msql_res);
1057 proginfo = gmyth_program_info_new();
1059 proginfo->channel_id = (gint) g_ascii_strtoull (msql_row[0], NULL, 10);
1061 gmyth_util_string_to_time_val(msql_row[23]);
1062 proginfo->endts = gmyth_util_string_to_time_val(msql_row[24]);
1063 proginfo->recstartts =
1064 gmyth_util_string_to_time_val(msql_row[1]);
1065 proginfo->recendts =
1066 gmyth_util_string_to_time_val(msql_row[2]);
1067 proginfo->title = g_string_new(msql_row[3]);
1068 proginfo->subtitle = g_string_new(msql_row[4]);
1069 proginfo->description = g_string_new(msql_row[5]);
1071 proginfo->chanstr = g_string_new(msql_row[6]);
1072 proginfo->chansign = g_string_new(msql_row[7]);
1073 proginfo->channame = g_string_new(msql_row[0]);
1074 proginfo->chancommfree =
1075 (gint) g_ascii_strtoull(msql_row[9], NULL, 10);
1076 proginfo->chanOutputFilters = g_string_new(msql_row[10]);
1077 proginfo->seriesid = g_string_new(msql_row[11]);
1078 proginfo->program_id = g_string_new(msql_row[12]);
1079 proginfo->filesize = g_ascii_strtoull(msql_row[13], NULL, 10);
1081 proginfo->lastmodified =
1082 gmyth_util_string_to_time_val(msql_row[14]);
1083 proginfo->stars = g_ascii_strtod(msql_row[15], NULL);
1085 (gint) g_ascii_strtoull(msql_row[16], NULL, 10);
1087 if (msql_row[17] == NULL) {
1088 proginfo->originalAirDate = 0;
1089 proginfo->hasAirDate = FALSE;
1091 proginfo->originalAirDate =
1092 gmyth_util_string_to_time_val(msql_row[17]);
1093 proginfo->hasAirDate = TRUE;
1096 proginfo->hostname = g_string_new(msql_row[18]);
1097 proginfo->recordid =
1098 (gint) g_ascii_strtoull(msql_row[19], NULL, 10);
1099 proginfo->transcoder =
1100 (gint) g_ascii_strtoull(msql_row[20], NULL, 10);
1101 // proginfo->spread = -1;
1102 // proginfo->programflags = proginfo->getProgramFlags();
1104 proginfo->recgroup = g_string_new(msql_row[26]);
1105 proginfo->playgroup = g_string_new(msql_row[21]);
1106 proginfo->recpriority =
1107 (gint) g_ascii_strtoull(msql_row[22], NULL, 10);
1109 proginfo->pathname = g_string_new(g_strdup(msql_row[25]));
1111 gmyth_debug("One program info loaded from mysql database\n");
1115 mysql_free_result(msql_res);
1116 g_string_free(query_str, TRUE);
1123 /** Notifies the backend of an update in the db.
1125 * @param record_id the id of the modified recording.
1127 // fixme: put void and discovery record_id inside
1129 update_backend (GMythScheduler * scheduler,
1132 GMythSocket *socket;
1133 GMythStringList *strlist = gmyth_string_list_new();
1134 GString *datastr = g_string_new("RESCHEDULE_RECORDINGS ");
1135 gboolean ret = FALSE;
1137 g_string_append_printf(datastr, "%d", record_id);
1138 gmyth_string_list_append_string(strlist, datastr);
1140 socket = gmyth_backend_info_get_connected_socket (scheduler->backend_info);
1141 if (socket != NULL) {
1142 ret = (gmyth_socket_sendreceive_stringlist(socket, strlist) > 0);
1143 g_object_unref (socket);
1145 g_warning("[%s] Connection to backend failed!", __FUNCTION__);
1148 g_string_free(datastr, TRUE);
1149 g_object_unref(strlist);
1154 gmyth_scheduler_recorded_info_get_preview(RecordedInfo * info,
1160 gmyth_recorded_info_free(RecordedInfo * info)
1162 g_return_if_fail (info != NULL);
1164 if (info->program_id)
1165 g_string_free (info->program_id, TRUE);
1167 if (info->title != NULL)
1168 g_string_free(info->title, TRUE);
1170 if (info->subtitle != NULL)
1171 g_string_free(info->subtitle, TRUE);
1173 if (info->description != NULL)
1174 g_string_free(info->description, TRUE);
1176 if (info->category != NULL)
1177 g_string_free(info->category, TRUE);
1179 if (info->basename != NULL)
1180 g_string_free(info->basename, TRUE);
1183 g_free(info->start_time);
1186 g_free(info->end_time);
1192 free_recorded_info_item(gpointer data, gpointer user_data)
1194 RecordedInfo *info = (RecordedInfo *) data;
1196 gmyth_recorded_info_free(info);
1200 gmyth_recorded_info_list_free(GList * list)
1202 g_return_if_fail(list != NULL);
1204 g_list_foreach(list, free_recorded_info_item, NULL);
1209 gmyth_schedule_info_free(ScheduleInfo * info)
1212 g_return_if_fail(info != NULL);
1214 if (info->program_id)
1215 g_string_free (info->program_id, TRUE);
1217 if (info->title != NULL)
1218 g_string_free(info->title, TRUE);
1220 if (info->subtitle != NULL)
1221 g_string_free(info->subtitle, TRUE);
1223 if (info->description != NULL)
1224 g_string_free(info->description, TRUE);
1226 if (info->category != NULL)
1227 g_string_free(info->category, TRUE);
1230 g_free(info->start_time);
1233 g_free(info->end_time);
1239 free_schedule_info_item(gpointer data, gpointer user_data)
1241 ScheduleInfo *info = (ScheduleInfo *) data;
1243 gmyth_schedule_info_free(info);
1247 gmyth_schedule_info_list_free(GList * list)
1249 g_return_if_fail(list != NULL);
1251 g_list_foreach(list, free_schedule_info_item, NULL);