From 39a4cfbe865e41142c312a6851194d4b2b896b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Thu, 6 Dec 2007 15:08:34 +0000 Subject: [PATCH] allow user to change channel groups in HTML ui --- channels.c | 80 ++++++++++++++++++- channels.h | 2 + htmlui.c | 221 +++++++++++++++++++++++++++++++++++++++-------------- tvhead.h | 1 + 4 files changed, 246 insertions(+), 58 deletions(-) diff --git a/channels.c b/channels.c index 1023fc89..9e07f99d 100644 --- a/channels.c +++ b/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; diff --git a/channels.h b/channels.h index 2ec3bc56..fbb1b77d 100644 --- a/channels.h +++ b/channels.h @@ -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 */ diff --git a/htmlui.c b/htmlui.c index a58cc3bb..b5580b6d 100644 --- a/htmlui.c +++ b/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, - "\r\n" - "\r\n" - "%s\r\n" - "\r\n", title); - - if(autorefresh) - tcp_qprintf(tq, - "\r\n", - autorefresh); - - tcp_qprintf(tq, - "", w); + if(javascript) { tcp_qprintf(tq, "\r\n"); - - - - tcp_qprintf(tq, - "\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, "\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, "\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, ""); 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, "
"); @@ -1298,15 +1313,16 @@ page_chgroups(http_connection_t *hc, const char *remain, void *opaque) tcp_qprintf(&tq, ""); box_bottom(&tq); - tcp_qprintf(&tq, "

\r\n"); + tcp_qprintf(&tq, "\r\n"); } tcp_qprintf(&tq, "
"); box_top(&tq, "box"); - tcp_qprintf(&tq, "
" - " " + tcp_qprintf(&tq, "
" + " " "" "
"); @@ -1314,11 +1330,101 @@ page_chgroups(http_connection_t *hc, const char *remain, void *opaque) box_bottom(&tq); tcp_qprintf(&tq, "
\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, + "\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, + "
", + ch->ch_tag); + + box_top(&tq, "box"); + + tcp_qprintf(&tq, + "
" + "" + "%s" + "" + "", + ch->ch_group == dis ? " selected" : "", + dis->tcg_name); + + tcp_qprintf(&tq, "
"); + box_bottom(&tq); + tcp_qprintf(&tq, "
"); + + 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); } diff --git a/tvhead.h b/tvhead.h index 0f4759c1..50e6e32e 100644 --- a/tvhead.h +++ b/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;