Finalize support for configuring xmltv grabbers
This commit is contained in:
parent
cc204b709d
commit
cc7d2c1d51
5 changed files with 312 additions and 17 deletions
|
@ -54,6 +54,16 @@ img { border: 0; }
|
|||
* Misc classes
|
||||
*/
|
||||
|
||||
.iconbackdrop {
|
||||
background: #fff;
|
||||
height: 64px;
|
||||
width: 64px;
|
||||
float: left;
|
||||
margin: 2px;
|
||||
text-align: center;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.infoprefix {
|
||||
float: left;
|
||||
width: 50px;
|
||||
|
|
|
@ -120,6 +120,78 @@ ajax_config_xmltv_tab(http_connection_t *hc, http_reply_t *hr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate displaylisting
|
||||
*/
|
||||
static void
|
||||
xmltv_grabber_chlist(tcp_queue_t *tq, xmltv_grabber_t *xg)
|
||||
{
|
||||
xmltv_channel_t *xc;
|
||||
th_channel_group_t *tcg;
|
||||
th_channel_t *ch;
|
||||
|
||||
tcp_qprintf(tq,
|
||||
"<div style=\"overflow: auto; height: 450px\">");
|
||||
|
||||
TAILQ_FOREACH(xc, &xg->xg_channels, xc_link) {
|
||||
|
||||
tcp_qprintf(tq,
|
||||
"<div style=\"overflow: auto; width: 100%%\">");
|
||||
|
||||
tcp_qprintf(tq, "<div class=\"iconbackdrop\">");
|
||||
if(xc->xc_icon_url != NULL) {
|
||||
tcp_qprintf(tq,
|
||||
"<img style=\"border: 0px;\" src=\"%s\" height=62px\">",
|
||||
xc->xc_icon_url);
|
||||
} else {
|
||||
tcp_qprintf(tq,
|
||||
"<div style=\"margin-top: 20px; text-align: center\">"
|
||||
"No icon</div>");
|
||||
}
|
||||
tcp_qprintf(tq, "</div>"); /* iconbackdrop */
|
||||
|
||||
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwide\">Name:</div>"
|
||||
"<div>%s (%s)</div>", xc->xc_displayname, xc->xc_name);
|
||||
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwide\">Best match:</div>"
|
||||
"<div>%s</div>", xc->xc_bestmatch ?: "(no channel)");
|
||||
|
||||
tcp_qprintf(tq,
|
||||
"<div class=\"infoprefixwidefat\">Mapped to:</div>"
|
||||
"<select class=\"textinput\" "
|
||||
"onChange=\"new Ajax.Request('/ajax/xmltvgrabberchmap/%s', "
|
||||
"{parameters: { xmltvch: '%s', channel: this.value }})\">",
|
||||
xg->xg_identifier, xc->xc_name);
|
||||
|
||||
tcp_qprintf(tq, "<option value=\"auto\">Automatic mapper</option>",
|
||||
!xc->xc_disabled && xc->xc_channel == NULL ? " selected" : "");
|
||||
|
||||
tcp_qprintf(tq, "<option value=\"none\"%s>No channel</option>",
|
||||
xc->xc_disabled ? " selected" : "");
|
||||
|
||||
TAILQ_FOREACH(tcg, &all_channel_groups, tcg_global_link) {
|
||||
if(tcg->tcg_hidden)
|
||||
continue;
|
||||
|
||||
TAILQ_FOREACH(ch, &tcg->tcg_channels, ch_group_link) {
|
||||
if(LIST_FIRST(&ch->ch_transports) == NULL)
|
||||
continue;
|
||||
|
||||
tcp_qprintf(tq, "<option value=\"%d\"%s>%s</option>",
|
||||
ch->ch_tag,
|
||||
!strcmp(ch->ch_name, xc->xc_channel ?: "")
|
||||
? " selected " : "", ch->ch_name);
|
||||
}
|
||||
}
|
||||
tcp_qprintf(tq, "</select>");
|
||||
tcp_qprintf(tq, "</div><hr>\r\n");
|
||||
}
|
||||
tcp_qprintf(tq, "</div>");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display detailes about a grabber
|
||||
|
@ -154,10 +226,12 @@ ajax_xmltvgrabber(http_connection_t *hc, http_reply_t *hr,
|
|||
case XMLTV_GRABBER_GRABBING:
|
||||
case XMLTV_GRABBER_UNCONFIGURED:
|
||||
case XMLTV_GRABBER_DYSFUNCTIONAL:
|
||||
case XMLTV_GRABBER_IDLE:
|
||||
tcp_qprintf(tq, "<p>%s</p>", xmltv_grabber_status_long(xg, xg->xg_status));
|
||||
break;
|
||||
|
||||
case XMLTV_GRABBER_IDLE:
|
||||
xmltv_grabber_chlist(tq, xg);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
@ -185,7 +259,7 @@ ajax_xmltvgrabbermode(http_connection_t *hc, http_reply_t *hr,
|
|||
|
||||
xmltv_grabber_enable(xg);
|
||||
|
||||
tcp_qprintf(tq,"$('details_%s').innerHTML='Ok, please wait...';",
|
||||
tcp_qprintf(tq,"$('details_%s').innerHTML='Please wait...';",
|
||||
xg->xg_identifier);
|
||||
|
||||
http_output(hc, hr, "text/javascript; charset=UTF8", NULL, 0);
|
||||
|
@ -194,13 +268,88 @@ ajax_xmltvgrabbermode(http_connection_t *hc, http_reply_t *hr,
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
tcp_queue_t *tq = &hr->hr_tq;
|
||||
|
||||
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;
|
||||
th_channel_t *ch;
|
||||
// tcp_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);
|
||||
http_path_add("/ajax/xmltvgrabbermode" , NULL, ajax_xmltvgrabbermode);
|
||||
|
||||
http_path_add("/ajax/xmltvgrabber" , NULL, ajax_xmltvgrabber);
|
||||
http_path_add("/ajax/xmltvgrabbermode" , NULL, ajax_xmltvgrabbermode);
|
||||
http_path_add("/ajax/xmltvgrabberlist" , NULL, ajax_xmltvgrabberlist);
|
||||
http_path_add("/ajax/xmltvgrabberchmap" , NULL, ajax_xmltvgrabberchmap);
|
||||
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
#define MAILBOX_EMPTY_REPLY_TIMEOUT 10
|
||||
|
||||
|
||||
//#define mbdebug(fmt...) printf(fmt);
|
||||
#define mbdebug(fmt...)
|
||||
#define mbdebug(fmt...) printf(fmt);
|
||||
//#define mbdebug(fmt...)
|
||||
|
||||
|
||||
static LIST_HEAD(, ajaxui_mailbox) mailboxes;
|
||||
|
@ -453,13 +453,23 @@ ajax_mailbox_tda_change(th_dvb_adapter_t *tda)
|
|||
void
|
||||
ajax_mailbox_xmltv_grabber_status_change(xmltv_grabber_t *xg, int status)
|
||||
{
|
||||
char buf[500];
|
||||
|
||||
ajax_mailbox_update_div("xmltvgrabbers",
|
||||
"status", xg->xg_identifier,
|
||||
xmltv_grabber_status(xg));
|
||||
|
||||
ajax_mailbox_update_div(xg->xg_identifier,
|
||||
"details", xg->xg_identifier,
|
||||
xmltv_grabber_status_long(xg, status));
|
||||
|
||||
if(status == XMLTV_GRABBER_IDLE) {
|
||||
snprintf(buf, sizeof(buf), "/ajax/xmltvgrabberlist/%s", xg->xg_identifier);
|
||||
ajax_mailbox_reload_div("xmltvgrabbers",
|
||||
"details", xg->xg_identifier,
|
||||
buf);
|
||||
} else {
|
||||
ajax_mailbox_update_div(xg->xg_identifier,
|
||||
"details", xg->xg_identifier,
|
||||
xmltv_grabber_status_long(xg, status));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
124
epg_xmltv.c
124
epg_xmltv.c
|
@ -45,6 +45,7 @@ struct xmltv_grabber_list xmltv_grabbers;
|
|||
struct xmltv_grabber_queue xmltv_grabber_workq;
|
||||
static pthread_mutex_t xmltv_work_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t xmltv_work_cond = PTHREAD_COND_INITIALIZER;
|
||||
static void xmltv_config_load(void);
|
||||
|
||||
|
||||
static xmltv_channel_t *
|
||||
|
@ -52,14 +53,14 @@ xc_find(xmltv_grabber_t *xg, const char *name)
|
|||
{
|
||||
xmltv_channel_t *xc;
|
||||
|
||||
LIST_FOREACH(xc, &xg->xg_channels, xc_link)
|
||||
TAILQ_FOREACH(xc, &xg->xg_channels, xc_link)
|
||||
if(!strcmp(xc->xc_name, name))
|
||||
return xc;
|
||||
|
||||
xc = calloc(1, sizeof(xmltv_channel_t));
|
||||
xc->xc_name = strdup(name);
|
||||
TAILQ_INIT(&xc->xc_events);
|
||||
LIST_INSERT_HEAD(&xg->xg_channels, xc, xc_link);
|
||||
TAILQ_INSERT_TAIL(&xg->xg_channels, xc, xc_link);
|
||||
return xc;
|
||||
}
|
||||
|
||||
|
@ -213,7 +214,7 @@ xmltv_flush_events(xmltv_grabber_t *xg)
|
|||
xmltv_channel_t *xc;
|
||||
event_t *e;
|
||||
|
||||
LIST_FOREACH(xc, &xg->xg_channels, xc_link) {
|
||||
TAILQ_FOREACH(xc, &xg->xg_channels, xc_link) {
|
||||
while((e = TAILQ_FIRST(&xc->xc_events)) != NULL) {
|
||||
TAILQ_REMOVE(&xc->xc_events, e, e_link);
|
||||
epg_event_free(e);
|
||||
|
@ -321,6 +322,7 @@ xmltv_transfer(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Execute grabber and parse result,
|
||||
*
|
||||
|
@ -443,6 +445,9 @@ xmltv_find_grabbers(const char *prog)
|
|||
continue;
|
||||
|
||||
xg = calloc(1, sizeof(xmltv_grabber_t));
|
||||
pthread_mutex_init(&xg->xg_mutex, NULL);
|
||||
|
||||
TAILQ_INIT(&xg->xg_channels);
|
||||
xg->xg_path = a;
|
||||
xg->xg_title = b;
|
||||
|
||||
|
@ -451,6 +456,7 @@ xmltv_find_grabbers(const char *prog)
|
|||
|
||||
LIST_INSERT_SORTED(&xmltv_grabbers, xg, xg_link, grabbercmp);
|
||||
}
|
||||
xmltv_config_load();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -559,13 +565,14 @@ xmltv_grabber_enable(xmltv_grabber_t *xg)
|
|||
{
|
||||
pthread_mutex_lock(&xmltv_work_lock);
|
||||
|
||||
if(xg->xg_status == XMLTV_GRABBER_DISABLED) {
|
||||
if(xg->xg_status != XMLTV_GRABBER_ENQUEUED) {
|
||||
xg->xg_status = XMLTV_GRABBER_ENQUEUED;
|
||||
TAILQ_INSERT_TAIL(&xmltv_grabber_workq, xg, xg_work_link);
|
||||
pthread_cond_signal(&xmltv_work_cond);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&xmltv_work_lock);
|
||||
xmltv_config_save();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -647,3 +654,112 @@ xmltv_grabber_status_long(xmltv_grabber_t *xg, int status)
|
|||
return "Unknown status";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write grabber configuration
|
||||
*/
|
||||
void
|
||||
xmltv_config_save(void)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
xmltv_grabber_t *xg;
|
||||
xmltv_channel_t *xc;
|
||||
FILE *fp;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/xmltv-settings.cfg", settings_dir);
|
||||
|
||||
if((fp = settings_open_for_write(buf)) == NULL)
|
||||
return;
|
||||
|
||||
LIST_FOREACH(xg, &xmltv_grabbers, xg_link) {
|
||||
if(xg->xg_status == XMLTV_GRABBER_DISABLED)
|
||||
continue;
|
||||
|
||||
fprintf(fp, "grabber {\n");
|
||||
fprintf(fp, "\ttitle = %s\n", xg->xg_title);
|
||||
|
||||
TAILQ_FOREACH(xc, &xg->xg_channels, xc_link) {
|
||||
fprintf(fp, "\tchannel {\n");
|
||||
fprintf(fp, "\t\tdisplayname = %s\n", xc->xc_displayname);
|
||||
fprintf(fp, "\t\ticon = %s\n", xc->xc_icon_url);
|
||||
fprintf(fp, "\t\tname = %s\n", xc->xc_name);
|
||||
if(xc->xc_disabled)
|
||||
fprintf(fp, "\t\tmapping = disabled\n");
|
||||
else
|
||||
fprintf(fp, "\t\tmapping = %s\n", xc->xc_channel ?: "auto");
|
||||
fprintf(fp, "\t}\n");
|
||||
}
|
||||
fprintf(fp, "}\n");
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void
|
||||
xmltv_config_load(void)
|
||||
{
|
||||
struct config_head cl;
|
||||
config_entry_t *ce, *ce2;
|
||||
char buf[PATH_MAX];
|
||||
const char *title, *name, *s;
|
||||
xmltv_channel_t *xc;
|
||||
xmltv_grabber_t *xg;
|
||||
|
||||
TAILQ_INIT(&cl);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/xmltv-settings.cfg", settings_dir);
|
||||
|
||||
config_read_file0(buf, &cl);
|
||||
|
||||
pthread_mutex_lock(&xmltv_work_lock);
|
||||
|
||||
TAILQ_FOREACH(ce, &cl, ce_link) {
|
||||
if(ce->ce_type != CFG_SUB || strcasecmp("grabber", ce->ce_key))
|
||||
continue;
|
||||
|
||||
if((title = config_get_str_sub(&ce->ce_sub, "title", NULL)) == NULL)
|
||||
continue;
|
||||
|
||||
LIST_FOREACH(xg, &xmltv_grabbers, xg_link)
|
||||
if(!strcmp(title, xg->xg_title))
|
||||
break;
|
||||
if(xg == NULL)
|
||||
continue;
|
||||
|
||||
xg->xg_status = XMLTV_GRABBER_ENQUEUED;
|
||||
TAILQ_INSERT_TAIL(&xmltv_grabber_workq, xg, xg_work_link);
|
||||
|
||||
TAILQ_FOREACH(ce2, &ce->ce_sub, ce_link) {
|
||||
if(ce2->ce_type != CFG_SUB || strcasecmp("channel", ce2->ce_key))
|
||||
continue;
|
||||
|
||||
if((name = config_get_str_sub(&ce2->ce_sub, "name", NULL)) == NULL)
|
||||
continue;
|
||||
|
||||
xc = xc_find(xg, name);
|
||||
|
||||
if((s = config_get_str_sub(&ce2->ce_sub, "displayname", NULL)) != NULL)
|
||||
xc->xc_displayname = strdup(s);
|
||||
|
||||
if((s = config_get_str_sub(&ce2->ce_sub, "icon", NULL)) != NULL)
|
||||
xc->xc_icon_url = strdup(s);
|
||||
|
||||
if((s = config_get_str_sub(&ce2->ce_sub, "mapping", NULL)) != NULL) {
|
||||
xc->xc_channel = NULL;
|
||||
if(!strcmp(s, "disabled")) {
|
||||
xc->xc_disabled = 1;
|
||||
} else if(!strcmp(s, "auto")) {
|
||||
} else {
|
||||
xc->xc_channel = strdup(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&xmltv_work_lock);
|
||||
|
||||
config_free0(&cl);
|
||||
}
|
||||
|
|
16
epg_xmltv.h
16
epg_xmltv.h
|
@ -23,7 +23,7 @@
|
|||
LIST_HEAD(xmltv_grabber_list, xmltv_grabber);
|
||||
TAILQ_HEAD(xmltv_grabber_queue, xmltv_grabber);
|
||||
|
||||
LIST_HEAD(xmltv_channel_list, xmltv_channel);
|
||||
TAILQ_HEAD(xmltv_channel_queue, xmltv_channel);
|
||||
|
||||
typedef struct xmltv_grabber {
|
||||
LIST_ENTRY(xmltv_grabber) xg_link;
|
||||
|
@ -44,7 +44,9 @@ typedef struct xmltv_grabber {
|
|||
|
||||
time_t xg_nextgrab;
|
||||
|
||||
struct xmltv_channel_list xg_channels;
|
||||
struct xmltv_channel_queue xg_channels;
|
||||
|
||||
pthread_mutex_t xg_mutex;
|
||||
|
||||
} xmltv_grabber_t;
|
||||
|
||||
|
@ -54,10 +56,16 @@ typedef struct xmltv_grabber {
|
|||
* A channel in the XML-TV world
|
||||
*/
|
||||
typedef struct xmltv_channel {
|
||||
LIST_ENTRY(xmltv_channel) xc_link;
|
||||
TAILQ_ENTRY(xmltv_channel) xc_link;
|
||||
char *xc_name;
|
||||
char *xc_displayname;
|
||||
|
||||
char *xc_bestmatch; /* Best matching channel */
|
||||
|
||||
char *xc_channel;
|
||||
|
||||
int xc_disabled;
|
||||
|
||||
char *xc_icon_url;
|
||||
|
||||
struct event_queue xc_events;
|
||||
|
@ -82,4 +90,6 @@ xmltv_grabber_t *xmltv_grabber_find(const char *id);
|
|||
|
||||
const char *xmltv_grabber_status_long(xmltv_grabber_t *xg, int status);
|
||||
|
||||
void xmltv_config_save(void);
|
||||
|
||||
#endif /* __XMLTV_H__ */
|
||||
|
|
Loading…
Add table
Reference in a new issue