allow user to change channel groups in HTML ui
This commit is contained in:
parent
b7fae6d527
commit
39a4cfbe86
4 changed files with 246 additions and 58 deletions
80
channels.c
80
channels.c
|
@ -50,6 +50,78 @@ static int dontwritesettings;
|
|||
|
||||
void scanner_init(void);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
#if 0
|
||||
static int
|
||||
dictcmp(const char *s1, const char *s2)
|
||||
{
|
||||
long int da, db;
|
||||
int n1, n2;
|
||||
|
||||
while(1) {
|
||||
n1 = *s1 >= '0' && *s1 <= '9' ? 1 : 0;
|
||||
n2 = *s2 >= '0' && *s2 <= '9' ? 2 : 0;
|
||||
|
||||
switch(n1 | n2) {
|
||||
case 0:
|
||||
if(*s1 != *s2)
|
||||
return *(const unsigned char *)s1 - *(const unsigned char *)s2;
|
||||
if(*s1 == 0)
|
||||
return 0;
|
||||
s1++;
|
||||
s2++;
|
||||
break;
|
||||
case 1 ... 2:
|
||||
return *(const unsigned char *)s1 - *(const unsigned char *)s2;
|
||||
case 3:
|
||||
da = strtol(s1, (char **)&s1, 10);
|
||||
db = strtol(s2, (char **)&s2, 10);
|
||||
if(da != db)
|
||||
return da - db;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ch_number(const char *s1)
|
||||
{
|
||||
while(*s1) {
|
||||
if(*s1 >= '0' && *s1 <= '9') {
|
||||
return strtol(s1, NULL, 10);
|
||||
}
|
||||
s1++;
|
||||
}
|
||||
return INT32_MAX;
|
||||
}
|
||||
|
||||
static int
|
||||
chcmp(const char *s1, const char *s2)
|
||||
{
|
||||
int n1, n2;
|
||||
|
||||
n1 = ch_number(s1);
|
||||
n2 = ch_number(s2);
|
||||
|
||||
if(n1 != n2) {
|
||||
return n1 - n2;
|
||||
}
|
||||
return strcmp(s1, s2);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static int
|
||||
channelcmp(th_channel_t *a, th_channel_t *b)
|
||||
{
|
||||
return chcmp(a->ch_name, b->ch_name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -92,7 +164,7 @@ channel_set_group(th_channel_t *ch, th_channel_group_t *tcg)
|
|||
TAILQ_REMOVE(&ch->ch_group->tcg_channels, ch, ch_group_link);
|
||||
|
||||
ch->ch_group = tcg;
|
||||
TAILQ_INSERT_TAIL(&tcg->tcg_channels, ch, ch_group_link);
|
||||
TAILQ_INSERT_SORTED(&tcg->tcg_channels, ch, ch_group_link, channelcmp);
|
||||
if(!dontwritesettings)
|
||||
channel_settings_write();
|
||||
}
|
||||
|
@ -157,7 +229,7 @@ channel_find(const char *name, int create, th_channel_group_t *tcg)
|
|||
ch->ch_index = nchannels;
|
||||
TAILQ_INIT(&ch->ch_epg_events);
|
||||
|
||||
LIST_INSERT_HEAD(&channels, ch, ch_global_link);
|
||||
LIST_INSERT_SORTED(&channels, ch, ch_global_link, channelcmp);
|
||||
|
||||
channel_set_group(ch, tcg ?: defgroup);
|
||||
|
||||
|
@ -309,6 +381,10 @@ channels_load(void)
|
|||
}
|
||||
}
|
||||
|
||||
tcg = channel_group_find("-disabled-", 1);
|
||||
tcg->tcg_cant_delete_me = 1;
|
||||
tcg->tcg_hidden = 1;
|
||||
|
||||
defgroup = channel_group_find("Uncategorized", 1);
|
||||
defgroup->tcg_cant_delete_me = 1;
|
||||
|
||||
|
|
|
@ -46,4 +46,6 @@ void channel_group_move_next(th_channel_group_t *tcg);
|
|||
|
||||
void channel_settings_write(void);
|
||||
|
||||
void channel_set_group(th_channel_t *ch, th_channel_group_t *tcg);
|
||||
|
||||
#endif /* CHANNELS_H */
|
||||
|
|
221
htmlui.c
221
htmlui.c
|
@ -94,37 +94,16 @@ pvrstatus_to_html(tv_pvr_status_t pvrstatus, const char **text,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
html_header(tcp_queue_t *tq, const char *title, int javascript, int width,
|
||||
int autorefresh)
|
||||
/*
|
||||
* Root page
|
||||
*/
|
||||
static int
|
||||
page_css(http_connection_t *hc, const char *remain, void *opaque)
|
||||
{
|
||||
char w[30];
|
||||
tcp_queue_t tq;
|
||||
tcp_init_queue(&tq, -1);
|
||||
|
||||
if(width > 0)
|
||||
snprintf(w, sizeof(w), "width: %dpx; ", width);
|
||||
else
|
||||
w[0] = 0;
|
||||
|
||||
tcp_qprintf(tq,
|
||||
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" "
|
||||
"http://www.w3.org/TR/html4/strict.dtd\">\r\n"
|
||||
"<html><head>\r\n"
|
||||
"<title>%s</title>\r\n"
|
||||
"<meta http-equiv=\"Content-Type\" "
|
||||
"content=\"text/html; charset=utf-8\">\r\n", title);
|
||||
|
||||
if(autorefresh)
|
||||
tcp_qprintf(tq,
|
||||
"<meta http-equiv=\"refresh\" content=\"%d\">\r\n",
|
||||
autorefresh);
|
||||
|
||||
tcp_qprintf(tq,
|
||||
"<style type=\"text/css\">\r\n"
|
||||
"<!--\r\n"
|
||||
tcp_qprintf(&tq,
|
||||
"img { border: 0px; }\r\n"
|
||||
"a:link { text-decoration: none}\r\n"
|
||||
"a:visited { text-decoration: none}\r\n"
|
||||
|
@ -134,10 +113,6 @@ html_header(tcp_queue_t *tq, const char *title, int javascript, int width,
|
|||
"a:active { text-decoration: none; color: #000000}\r\n"
|
||||
"a:hover { text-decoration: underline; color: CC3333}\r\n"
|
||||
""
|
||||
"body {margin: 4px 4px; "
|
||||
"font: 75% Verdana, Arial, Helvetica, sans-serif; "
|
||||
"%s margin-right: auto; margin-left: auto;}\r\n"
|
||||
""
|
||||
"#box {background: #cccc99;}\r\n"
|
||||
".roundtop {background: #ffffff;}\r\n"
|
||||
".roundbottom {background: #ffffff;}\r\n"
|
||||
|
@ -178,31 +153,67 @@ html_header(tcp_queue_t *tq, const char *title, int javascript, int width,
|
|||
".toptxt {float: left; width: 165px; text-align: center}\r\n"
|
||||
""
|
||||
".knapp {border: 1px dotted #000000; background: #ddddaa} "
|
||||
".knapp:hover {border: 1px dotted #000000; background: #aaaa66} "
|
||||
".knapp:hover {border: 1px dotted #000000; background: #aaaa66}"
|
||||
""
|
||||
".drop {border: 1px dotted #000000; background: #ddddaa} "
|
||||
""
|
||||
"#meny {margin: 0; padding: 0}\r\n"
|
||||
"#meny li{display: inline; list-style-type: none;}\r\n"
|
||||
"#meny a{padding: 1.15em 0.8em; text-decoration: none;}\r\n"
|
||||
);
|
||||
|
||||
http_output_queue(hc, &tq, "text/css", 60);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
html_header(tcp_queue_t *tq, const char *title, int javascript, int width,
|
||||
int autorefresh)
|
||||
{
|
||||
char w[30];
|
||||
|
||||
if(width > 0)
|
||||
snprintf(w, sizeof(w), "width: %dpx; ", width);
|
||||
else
|
||||
w[0] = 0;
|
||||
|
||||
tcp_qprintf(tq,
|
||||
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" "
|
||||
"http://www.w3.org/TR/html4/strict.dtd\">\r\n"
|
||||
"<html><head>\r\n"
|
||||
"<title>%s</title>\r\n"
|
||||
"<meta http-equiv=\"Content-Type\" "
|
||||
"content=\"text/html; charset=utf-8\">\r\n", title);
|
||||
|
||||
if(autorefresh)
|
||||
tcp_qprintf(tq,
|
||||
"<meta http-equiv=\"refresh\" content=\"%d\">\r\n",
|
||||
autorefresh);
|
||||
|
||||
tcp_qprintf(tq,
|
||||
"<link href=\"/css.css\" rel=\"stylesheet\" type=\"text/css\">"
|
||||
);
|
||||
|
||||
tcp_qprintf(tq,
|
||||
"<style type=\"text/css\">\r\n"
|
||||
"<!--\r\n"
|
||||
"body {margin: 4px 4px; "
|
||||
"font: 75% Verdana, Arial, Helvetica, sans-serif; "
|
||||
"%s margin-right: auto; margin-left: auto;}\r\n"
|
||||
"-->\r\n"
|
||||
"</style>", w);
|
||||
|
||||
|
||||
if(javascript) {
|
||||
tcp_qprintf(tq,
|
||||
"<script type=\"text/javascript\" "
|
||||
"src=\"http://www.olebyn.nu/hts/overlib.js\"></script>\r\n");
|
||||
|
||||
|
||||
|
||||
tcp_qprintf(tq,
|
||||
"<script language=\"javascript\">\r\n"
|
||||
"<!-- Begin\r\n"
|
||||
"function epop() {\r\n"
|
||||
" props=window.open(epop.arguments[0],"
|
||||
"'poppage', 'toolbars=0, scrollbars=0, location=0, "
|
||||
"statusbars=0, menubars=0, resizable=0, "
|
||||
"width=600, height=300 left = 100, top = 100');\r\n}\r\n"
|
||||
"// End -->\r\n"
|
||||
"</script>\r\n");
|
||||
}
|
||||
/* BODY start */
|
||||
|
||||
|
@ -434,6 +445,8 @@ page_root(http_connection_t *hc, const char *remain, void *opaque)
|
|||
top_menu(hc, &tq);
|
||||
|
||||
TAILQ_FOREACH(tcg, &all_channel_groups, tcg_global_link) {
|
||||
if(tcg->tcg_hidden)
|
||||
continue;
|
||||
|
||||
box_top(&tq, "box");
|
||||
|
||||
|
@ -490,7 +503,7 @@ page_root(http_connection_t *hc, const char *remain, void *opaque)
|
|||
epg_unlock();
|
||||
|
||||
html_footer(&tq);
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8");
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -584,7 +597,7 @@ page_channel(http_connection_t *hc, const char *remain, void *opaque)
|
|||
epg_unlock();
|
||||
|
||||
html_footer(&tq);
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8");
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -714,7 +727,7 @@ page_event(http_connection_t *hc, const char *remain, void *opaque)
|
|||
box_bottom(&tq);
|
||||
tcp_qprintf(&tq, "</form>\r\n");
|
||||
html_footer(&tq);
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8");
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
|
||||
epg_unlock();
|
||||
|
||||
|
@ -852,7 +865,7 @@ page_pvrlog(http_connection_t *hc, const char *remain, void *opaque)
|
|||
box_bottom(&tq);
|
||||
tcp_qprintf(&tq, "</form>\r\n");
|
||||
html_footer(&tq);
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8");
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1215,7 +1228,7 @@ page_status(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
tcp_qprintf(&tq, "</div>");
|
||||
html_footer(&tq);
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8");
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1270,6 +1283,8 @@ page_chgroups(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
|
||||
TAILQ_FOREACH(tcg, &all_channel_groups, tcg_global_link) {
|
||||
if(tcg->tcg_hidden)
|
||||
continue;
|
||||
|
||||
tcp_qprintf(&tq, "<form method=\"get\" action=\"/chgrp\">");
|
||||
|
||||
|
@ -1298,15 +1313,16 @@ page_chgroups(http_connection_t *hc, const char *remain, void *opaque)
|
|||
|
||||
tcp_qprintf(&tq, "</div>");
|
||||
box_bottom(&tq);
|
||||
tcp_qprintf(&tq, "</form><br>\r\n");
|
||||
tcp_qprintf(&tq, "</form>\r\n");
|
||||
}
|
||||
|
||||
|
||||
tcp_qprintf(&tq, "<form method=\"get\" action=\"/chgrp\">");
|
||||
|
||||
box_top(&tq, "box");
|
||||
tcp_qprintf(&tq, "<div class=\"content3\">"
|
||||
"<input type=\"text\" name=\"newgrpname\"> "
|
||||
tcp_qprintf(&tq, "<div class=\"content\">"
|
||||
"<input type=\"text\" name=\"newgrpname\""
|
||||
" style=\"border: 1px dotted #000000\"> "
|
||||
"<input type=\"submit\" class=\"knapp\" name=\"newgrp\""
|
||||
" value=\"Add new group\">"
|
||||
"</div>");
|
||||
|
@ -1314,11 +1330,101 @@ page_chgroups(http_connection_t *hc, const char *remain, void *opaque)
|
|||
box_bottom(&tq);
|
||||
tcp_qprintf(&tq, "</form><br>\r\n");
|
||||
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8");
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Manage channels
|
||||
*/
|
||||
static int
|
||||
page_chadm(http_connection_t *hc, const char *remain, void *opaque)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
th_channel_t *ch;
|
||||
int simple = is_client_simple(hc);
|
||||
|
||||
if(!html_verify_access(hc, "admin"))
|
||||
return HTTP_STATUS_UNAUTHORIZED;
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
html_header(&tq, "HTS/tvheadend", !simple, 700, 0);
|
||||
top_menu(hc, &tq);
|
||||
|
||||
LIST_FOREACH(ch, &channels, ch_global_link) {
|
||||
tcp_qprintf(&tq,
|
||||
"<iframe src=\"/editchannel/%d\" "
|
||||
"height=\"50\" width=\"700\" frameborder=\"0\"></iframe>\r\n",
|
||||
ch->ch_tag);
|
||||
}
|
||||
|
||||
html_footer(&tq);
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a single channel
|
||||
*/
|
||||
static int
|
||||
page_editchannel(http_connection_t *hc, const char *remain, void *opaque)
|
||||
{
|
||||
tcp_queue_t tq;
|
||||
th_channel_t *ch;
|
||||
th_channel_group_t *tcg, *dis;
|
||||
const char *grp;
|
||||
if(!html_verify_access(hc, "admin"))
|
||||
return HTTP_STATUS_UNAUTHORIZED;
|
||||
|
||||
if(remain == NULL || (ch = channel_by_tag(atoi(remain))) == NULL)
|
||||
return 404;
|
||||
|
||||
if((grp = http_arg_get(&hc->hc_url_args, "grp")) != NULL) {
|
||||
tcg = channel_group_find(grp, 1);
|
||||
channel_set_group(ch, tcg);
|
||||
}
|
||||
dis = channel_group_find("-disabled-", 1);
|
||||
|
||||
tcp_init_queue(&tq, -1);
|
||||
html_header(&tq, "HTS/tvheadend", 0, 700, 0);
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
"<form method=\"get\" action=\"/editchannel/%d\">",
|
||||
ch->ch_tag);
|
||||
|
||||
box_top(&tq, "box");
|
||||
|
||||
tcp_qprintf(&tq,
|
||||
"<div class=\"content\">"
|
||||
"<span style=\"overflow: hidden; width: 200px; float: left\">"
|
||||
"%s</span>"
|
||||
"<span style=\"width: 250px\">"
|
||||
"<select name=\"grp\" class=\"drop\" "
|
||||
"onChange=\"this.form.submit()\">",
|
||||
ch->ch_name);
|
||||
|
||||
TAILQ_FOREACH(tcg, &all_channel_groups, tcg_global_link) {
|
||||
if(tcg->tcg_hidden)
|
||||
continue;
|
||||
tcp_qprintf(&tq, "<option%s>%s</option>",
|
||||
ch->ch_group == tcg ? " selected" : "",
|
||||
tcg->tcg_name);
|
||||
}
|
||||
|
||||
tcp_qprintf(&tq, "<option%s>%s</option></select></span>",
|
||||
ch->ch_group == dis ? " selected" : "",
|
||||
dis->tcg_name);
|
||||
|
||||
tcp_qprintf(&tq, "<br></div>");
|
||||
box_bottom(&tq);
|
||||
tcp_qprintf(&tq, "</form>");
|
||||
|
||||
html_footer(&tq);
|
||||
http_output_queue(hc, &tq, "text/html; charset=UTF-8", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1333,4 +1439,7 @@ htmlui_start(void)
|
|||
http_path_add("/pvrlog", NULL, page_pvrlog);
|
||||
http_path_add("/status", NULL, page_status);
|
||||
http_path_add("/chgrp", NULL, page_chgroups);
|
||||
http_path_add("/chadm", NULL, page_chadm);
|
||||
http_path_add("/editchannel", NULL, page_editchannel);
|
||||
http_path_add("/css.css", NULL, page_css);
|
||||
}
|
||||
|
|
1
tvhead.h
1
tvhead.h
|
@ -628,6 +628,7 @@ typedef struct th_channel_group {
|
|||
struct th_channel_queue tcg_channels;
|
||||
int tcg_tag;
|
||||
int tcg_cant_delete_me;
|
||||
int tcg_hidden;
|
||||
|
||||
} th_channel_group_t;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue