/* * 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 "psi.h" #include "transports.h" #include "serviceprobe.h" /** * */ int ajax_transport_build_list(http_connection_t *hc, htsbuf_queue_t *tq, struct th_transport_tree *tlist, int numtransports) { th_transport_t *t; ajax_table_t ta; htsbuf_qprintf(tq, "\r\n"); /* Top */ htsbuf_qprintf(tq, "
"); ajax_table_top(&ta, hc, tq, (const char *[]){"Last status", "Crypto", "Type", "Source service", "", "Target channel", "", NULL}, (int[]){8,4,4,12,3,12,1}); RB_FOREACH(t, tlist, tht_tmp_link) { ajax_table_row_start(&ta, t->tht_identifier); ajax_table_cell(&ta, "status", transport_status_to_text(t->tht_last_status)); ajax_table_cell(&ta, NULL, "%s", t->tht_scrambled ? "Yes" : "No"); ajax_table_cell(&ta, NULL, "%s", transport_servicetype_txt(t)); ajax_table_cell(&ta, NULL, "%s", t->tht_svcname ?: ""); ajax_table_cell(&ta, NULL, "" "", t->tht_identifier, t->tht_identifier, t->tht_ch ? "" : "un"); if(t->tht_ch == NULL) { /* Unmapped */ ajax_table_cell(&ta, "chname", "" "%s", t->tht_identifier, t->tht_identifier, t->tht_chname, t->tht_chname); } else { ajax_table_cell(&ta, "chname", "%s", t->tht_ch->ch_name); } ajax_table_cell_checkbox(&ta); } ajax_table_bottom(&ta); htsbuf_qprintf(tq, "
\r\n"); htsbuf_qprintf(tq, "
"); ajax_button(tq, "Select all", "select_all()"); ajax_button(tq, "Select none", "select_none()"); // htsbuf_qprintf(tq, "
\r\n"); //htsbuf_qprintf(tq, "
"); ajax_button(tq, "Map selected", "selected_do('map');"); ajax_button(tq, "Unmap selected", "selected_do('unmap');"); ajax_button(tq, "Test and map selected", "selected_do('probe');"); htsbuf_qprintf(tq, "
"); htsbuf_qprintf(tq, "
"); return 0; } /** * Rename of unmapped channel */ static int ajax_transport_rename_channel(http_connection_t *hc, http_reply_t *hr, const char *remain, void *opaque) { th_transport_t *t; const char *newname; htsbuf_queue_t *tq = &hr->hr_q; 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_chname); t->tht_chname = strdup(newname); ajax_a_jsfuncf(tq, newname, "tentative_chname('chname_%s', " "'/ajax/transport_rename_channel/%s', '%s')", t->tht_identifier, t->tht_identifier, newname); http_output_html(hc, hr); t->tht_config_change(t); return 0; } /** * */ void ajax_transport_build_mapper_state(char *buf, size_t siz, th_transport_t *t, int mapped) { if(mapped) { snprintf(buf, siz, "$('chname_%s').innerHTML='%s';\n\r" "$('map_%s').src='/gfx/mapped.png';\n\r", t->tht_identifier, t->tht_ch->ch_name, t->tht_identifier); } else { snprintf(buf, siz, "$('chname_%s').innerHTML='" "%s" "';\n\r" "$('map_%s').src='/gfx/unmapped.png';\n\r", t->tht_identifier, t->tht_identifier, t->tht_identifier, t->tht_chname, t->tht_chname, t->tht_identifier); } } /** * */ static void ajax_map_unmap_channel(th_transport_t *t, htsbuf_queue_t *tq, int map) { char buf[1000]; if(map) transport_map_channel(t, NULL); else transport_unmap_channel(t); ajax_transport_build_mapper_state(buf, sizeof(buf), t, map); htsbuf_qprintf(tq, "%s", buf); } /** * */ static int ajax_transport_op(http_connection_t *hc, http_reply_t *hr, const char *remain, void *opaque) { th_transport_t *t; htsbuf_queue_t *tq = &hr->hr_q; const char *op = remain; http_arg_t *ra; if(op == NULL) return HTTP_STATUS_NOT_FOUND; TAILQ_FOREACH(ra, &hc->hc_req_args, link) { if(strcmp(ra->val, "selected")) continue; if((t = transport_find_by_identifier(ra->key)) == NULL) continue; if(!strcmp(op, "toggle")) { ajax_map_unmap_channel(t, tq, t->tht_ch ? 0 : 1); } else if(!strcmp(op, "map") && t->tht_ch == NULL) { ajax_map_unmap_channel(t, tq, 1); } else if(!strcmp(op, "unmap") && t->tht_ch != NULL) { ajax_map_unmap_channel(t, tq, 0); } else if(!strcmp(op, "probe")) { serviceprobe_add(t); continue; } t->tht_config_change(t); } http_output(hc, hr, "text/javascript; charset=UTF8", NULL, 0); return 0; } /** * */ static int ajax_transport_chdisable(http_connection_t *hc, http_reply_t *hr, const char *remain, void *opaque) { th_transport_t *t; const char *s; if(remain == NULL || (t = transport_find_by_identifier(remain)) == NULL) return HTTP_STATUS_NOT_FOUND; if((s = http_arg_get(&hc->hc_req_args, "enabled")) == NULL) return HTTP_STATUS_BAD_REQUEST; t->tht_disabled = !strcasecmp(s, "false"); http_output(hc, hr, "text/javascript; charset=UTF8", NULL, 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, AJAX_ACCESS_CONFIG); http_path_add("/ajax/transport_op", NULL, ajax_transport_op, AJAX_ACCESS_CONFIG); http_path_add("/ajax/transport_chdisable", NULL, ajax_transport_chdisable, AJAX_ACCESS_CONFIG); }