/* * tvheadend, AJAX / HTML user interface * Copyright (C) 2008 Andreas Öman * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define _GNU_SOURCE #include #include #include #include #include #include #include "tvhead.h" #include "http.h" #include "ajaxui.h" #include "channels.h" #include "epg_xmltv.h" #include "psi.h" #include "transports.h" #include "ajaxui_mailbox.h" /** * XMLTV configuration */ int ajax_config_xmltv_tab(http_connection_t *hc, http_reply_t *hr) { htsbuf_queue_t *tq = &hr->hr_q; xmltv_grabber_t *xg; int ngrabbers = 0; ajax_table_t ta; htsbuf_qprintf(tq, "
"); switch(xmltv_globalstatus) { default: htsbuf_qprintf(tq, "

" "XMLTV subsystem is not yet fully initialized, please retry " "in a few seconds

"); http_output_html(hc, hr); return 0; case XMLTVSTATUS_FIND_GRABBERS_NOT_FOUND: htsbuf_qprintf(tq, "

" "XMLTV subsystem can not initialize

" "

" "Make sure that the 'tv_find_grabbers' executable is in " "the system path

"); http_output_html(hc, hr); return 0; case XMLTVSTATUS_RUNNING: break; } htsbuf_qprintf(tq, "
"); ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, "XMLTV grabbers"); LIST_FOREACH(xg, &xmltv_grabbers, xg_link) ngrabbers++; ajax_table_top(&ta, hc, tq, (const char *[]){"Grabber", "Status", NULL}, (int[]){4,2}); LIST_FOREACH(xg, &xmltv_grabbers, xg_link) { ajax_table_row_start(&ta, xg->xg_identifier); ajax_table_cell(&ta, NULL, "%s", xg->xg_identifier, xg->xg_title); ajax_table_cell(&ta, "status", xmltv_grabber_status(xg)); } ajax_table_bottom(&ta); ajax_box_end(tq, AJAX_BOX_SIDEBOX); htsbuf_qprintf(tq, "
" "
" "
"); htsbuf_qprintf(tq, ""); http_output_html(hc, hr); return 0; } /** * Generate displaylisting */ static void xmltv_grabber_chlist(htsbuf_queue_t *tq, xmltv_grabber_t *xg) { xmltv_channel_t *xc; channel_group_t *tcg; channel_t *ch; htsbuf_qprintf(tq, "
"); TAILQ_FOREACH(xc, &xg->xg_channels, xc_link) { htsbuf_qprintf(tq, "
"); htsbuf_qprintf(tq, "
"); if(xc->xc_icon_url != NULL) { htsbuf_qprintf(tq, "", xc->xc_icon_url); } else { htsbuf_qprintf(tq, "
" "No icon
"); } htsbuf_qprintf(tq, "
"); /* iconbackdrop */ htsbuf_qprintf(tq, "
Name:
" "
%s (%s)
", xc->xc_displayname, xc->xc_name); htsbuf_qprintf(tq, "
Auto mapper:
" "
%s
", xc->xc_bestmatch ?: "(no channel)"); htsbuf_qprintf(tq, "
Channel:
" ""); htsbuf_qprintf(tq, "

\r\n"); } htsbuf_qprintf(tq, "
"); } /** * Display detailes about a grabber */ static int ajax_xmltvgrabber(http_connection_t *hc, http_reply_t *hr, const char *remain, void *opaque) { xmltv_grabber_t *xg; htsbuf_queue_t *tq = &hr->hr_q; if(remain == NULL || (xg = xmltv_grabber_find(remain)) == NULL) return HTTP_STATUS_NOT_FOUND; ajax_box_begin(tq, AJAX_BOX_SIDEBOX, NULL, NULL, xg->xg_title); htsbuf_qprintf(tq,"
", xg->xg_identifier); if(xg->xg_enabled == 0) { htsbuf_qprintf(tq, "

This grabber is currently not enabled, click " "here " "to enable it

"); } else if(xg->xg_status == XMLTV_GRAB_OK) { xmltv_grabber_chlist(tq, xg); } else { htsbuf_qprintf(tq, "

%s

", xmltv_grabber_status_long(xg)); } htsbuf_qprintf(tq,"
"); ajax_box_end(tq, AJAX_BOX_SIDEBOX); http_output_html(hc, hr); return 0; } /** * Enable / Disable a grabber */ static int ajax_xmltvgrabbermode(http_connection_t *hc, http_reply_t *hr, const char *remain, void *opaque) { xmltv_grabber_t *xg; htsbuf_queue_t *tq = &hr->hr_q; if(remain == NULL || (xg = xmltv_grabber_find(remain)) == NULL) return HTTP_STATUS_NOT_FOUND; xmltv_grabber_enable(xg); htsbuf_qprintf(tq,"$('details_%s').innerHTML='Please wait...';", xg->xg_identifier); http_output(hc, hr, "text/javascript; charset=UTF8", NULL, 0); return 0; } /** * Enable / Disable a grabber */ static int ajax_xmltvgrabberlist(http_connection_t *hc, http_reply_t *hr, const char *remain, void *opaque) { xmltv_grabber_t *xg; htsbuf_queue_t *tq = &hr->hr_q; if(remain == NULL || (xg = xmltv_grabber_find(remain)) == NULL) return HTTP_STATUS_NOT_FOUND; xmltv_grabber_chlist(tq, xg); http_output_html(hc, hr); return 0; } /** * Change mapping of a channel for a grabber */ static int ajax_xmltvgrabberchmap(http_connection_t *hc, http_reply_t *hr, const char *remain, void *opaque) { xmltv_grabber_t *xg; xmltv_channel_t *xc; const char *xmltvname; const char *chname; channel_t *ch; // htsbuf_queue_t *tq = &hr->hr_tq; if(remain == NULL || (xg = xmltv_grabber_find(remain)) == NULL) return HTTP_STATUS_NOT_FOUND; if((xmltvname = http_arg_get(&hc->hc_req_args, "xmltvch")) == NULL) return HTTP_STATUS_BAD_REQUEST; if((chname = http_arg_get(&hc->hc_req_args, "channel")) == NULL) return HTTP_STATUS_BAD_REQUEST; TAILQ_FOREACH(xc, &xg->xg_channels, xc_link) if(!strcmp(xc->xc_name, xmltvname)) break; if(xc == NULL) return HTTP_STATUS_BAD_REQUEST; pthread_mutex_lock(&xg->xg_mutex); free(xc->xc_channel); xc->xc_channel = NULL; xc->xc_disabled = 0; if(!strcmp(chname, "none")) { xc->xc_disabled = 1; } else if(!strcmp(chname, "auto")) { } else if((ch = channel_by_tag(atoi(chname))) != NULL) { xc->xc_disabled = 0; xc->xc_channel = strdup(ch->ch_name); } pthread_mutex_unlock(&xg->xg_mutex); xmltv_config_save(); http_output(hc, hr, "text/javascript; charset=UTF8", NULL, 0); return 0; } /** * */ void ajax_config_xmltv_init(void) { http_path_add("/ajax/xmltvgrabber" , NULL, ajax_xmltvgrabber, AJAX_ACCESS_CONFIG); http_path_add("/ajax/xmltvgrabbermode" , NULL, ajax_xmltvgrabbermode, AJAX_ACCESS_CONFIG); http_path_add("/ajax/xmltvgrabberlist" , NULL, ajax_xmltvgrabberlist, AJAX_ACCESS_CONFIG); http_path_add("/ajax/xmltvgrabberchmap" , NULL, ajax_xmltvgrabberchmap, AJAX_ACCESS_CONFIG); }