/* * 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 #include "tvhead.h" #include "http.h" #include "ajaxui.h" #include "channels.h" #include "psi.h" #include "transports.h" /** * */ int ajax_transport_build_list(http_connection_t *hc, tcp_queue_t *tq, struct th_transport_list *tlist, int numtransports) { char buf[1000]; th_transport_t *t; const char *v; int o = 1; th_stream_t *st; const char *extra; int displines = 21; int csize[10]; tcp_qprintf(tq, "\r\n"); /* Top */ tcp_qprintf(tq, "
"); ajax_table_header(hc, tq, (const char *[]) {"", "ServiceID", "Crypto", "Type", "Source service", "", "Target channel", "", NULL}, (int[]){3,5,4,4,12,3,12,1}, numtransports > displines, csize); tcp_qprintf(tq, "
"); LIST_FOREACH(t, tlist, tht_tmp_link) { tcp_qprintf(tq, "", o ? " style=\"background: #fff\"" : ""); o = !o; tcp_qprintf(tq, "
"); tcp_qprintf(tq, "", csize[0], t->tht_identifier, t->tht_identifier); tcp_qprintf(tq, "
%d
", csize[1], t->tht_dvb_service_id); tcp_qprintf(tq, "
%s
", csize[2], t->tht_scrambled ? "CSA" : "Free"); tcp_qprintf(tq, "
%s
", csize[3], transport_servicetype_txt(t)); tcp_qprintf(tq, "
%s
", csize[4], t->tht_servicename ?: ""); tcp_qprintf(tq, "
" "" "
", csize[5], t->tht_identifier, t->tht_identifier, t->tht_channel ? "" : "un"); tcp_qprintf(tq, "
", t->tht_identifier, csize[6]); if(t->tht_channel == NULL) { /* Unmapped */ v = t->tht_channelname; snprintf(buf, sizeof(buf), "tentative_chname('chname%s', " "'/ajax/transport_rename_channel/%s', '%s')", t->tht_identifier, t->tht_identifier, v); ajax_a_jsfunc(tq, v, buf, ""); } else { /* Mapped */ tcp_qprintf(tq, "%s", t->tht_channel->ch_name); } tcp_qprintf(tq, "
"); tcp_qprintf(tq, "
" "" "
", csize[7], t->tht_identifier); tcp_qprintf(tq, "
"); /* Extra info */ tcp_qprintf(tq, "
", t->tht_identifier); tcp_qprintf(tq, "

"); tcp_qprintf(tq, "

"); tcp_qprintf(tq, "
" " 
", csize[0]); tcp_qprintf(tq, "
" "PID
", csize[1]); tcp_qprintf(tq, "
" "Payload
", csize[2] + csize[3]); tcp_qprintf(tq, "
Details" "
", csize[4] + csize[5] + csize[6] + csize[7]); tcp_qprintf(tq, "
"); LIST_FOREACH(st, &t->tht_streams, st_link) { tcp_qprintf(tq, "
"); tcp_qprintf(tq, "
 
", csize[0]); tcp_qprintf(tq, "
%d
", csize[1], st->st_pid); tcp_qprintf(tq, "
%s
", csize[2] + csize[3], htstvstreamtype2txt(st->st_type)); switch(st->st_type) { case HTSTV_MPEG2AUDIO: case HTSTV_AC3: extra = st->st_lang; break; case HTSTV_CA: extra = psi_caid2name(st->st_caid); break; default: extra = NULL; break; } if(extra != NULL) tcp_qprintf(tq, "
%s
", csize[4] + csize[5] + csize[6] + csize[7], extra); tcp_qprintf(tq, "
"); } tcp_qprintf(tq, "

"); tcp_qprintf(tq, "\r\n"); } tcp_qprintf(tq, "
\r\n"); tcp_qprintf(tq, "
"); tcp_qprintf(tq, "
Select:
"); ajax_a_jsfunc(tq, "All", "select_all();", " / "); ajax_a_jsfunc(tq, "None", "select_none();", " / "); ajax_a_jsfunc(tq, "Invert", "select_invert();", " / "); ajax_a_jsfunc(tq, "All TV-services", "select_tv();", " / "); ajax_a_jsfunc(tq, "All uncrypted TV-services", "select_tv_nocrypt();", ""); tcp_qprintf(tq, "
\r\n"); tcp_qprintf(tq, "
"); tcp_qprintf(tq, "
 
"); ajax_a_jsfunc(tq, "Map selected", "selected_do('map');", " / "); ajax_a_jsfunc(tq, "Unmap selected", "selected_do('unmap');", ""); tcp_qprintf(tq, "
"); tcp_qprintf(tq, ""); return 0; } /** * Rename of unmapped channel */ static int ajax_transport_rename_channel(http_connection_t *hc, const char *remain, void *opaque) { th_transport_t *t; const char *newname, *v; tcp_queue_t tq; char buf[1000]; if(remain == NULL || (t = transport_find_by_identifier(remain)) == NULL) return HTTP_STATUS_NOT_FOUND; if((newname = http_arg_get(&hc->hc_req_args, "newname")) == NULL) return HTTP_STATUS_BAD_REQUEST; free((void *)t->tht_channelname); t->tht_channelname = strdup(newname); tcp_init_queue(&tq, -1); v = newname; snprintf(buf, sizeof(buf), "tentative_chname('chname%s', " "'/ajax/transport_rename_channel/%s', '%s')", t->tht_identifier, t->tht_identifier, v); ajax_a_jsfunc(&tq, v, buf, ""); http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0); t->tht_config_change(t); return 0; } /** * */ static void dvb_map_channel(th_transport_t *t, tcp_queue_t *tq) { transport_set_channel(t, t->tht_channelname); printf("Mapped transport %s to channel %s\n", t->tht_servicename, t->tht_channel->ch_name); tcp_qprintf(tq, "document.getElementById('chname%s').innerHTML='%s';\n\r" "document.getElementById('map%s').src='/gfx/mapped.png';\n\r", t->tht_identifier, t->tht_channel->ch_name, t->tht_identifier); } /** * */ static void dvb_unmap_channel(th_transport_t *t, tcp_queue_t *tq) { transport_unset_channel(t); printf("Unmapped transport %s\n", t->tht_servicename); tcp_qprintf(tq, "document.getElementById('chname%s').innerHTML='" "%s" "';\n\r" "document.getElementById('map%s').src='/gfx/unmapped.png';\n\r", t->tht_identifier, t->tht_identifier, t->tht_identifier, t->tht_channelname, t->tht_channelname, t->tht_identifier); } /** * */ int ajax_transport_op(http_connection_t *hc, const char *remain, void *opaque) { th_transport_t *t; tcp_queue_t tq; const char *op; if(remain == NULL || (t = transport_find_by_identifier(remain)) == NULL) return HTTP_STATUS_NOT_FOUND; if((op = http_arg_get(&hc->hc_req_args, "action")) == NULL) return HTTP_STATUS_BAD_REQUEST; tcp_init_queue(&tq, -1); if(!strcmp(op, "toggle")) { if(t->tht_channel) dvb_unmap_channel(t, &tq); else dvb_map_channel(t, &tq); } else if(!strcmp(op, "map") && t->tht_channel == NULL) { dvb_map_channel(t, &tq); } else if(!strcmp(op, "unmap") && t->tht_channel != NULL) { dvb_unmap_channel(t, &tq); } http_output_queue(hc, &tq, "text/javascript; charset=UTF-8", 0); t->tht_config_change(t); return 0; } /** * */ void ajax_config_transport_init(void) { http_path_add("/ajax/transport_rename_channel", NULL, ajax_transport_rename_channel); http_path_add("/ajax/transport_op", NULL, ajax_transport_op); }