Fix transfer of events from XML-TV to mail event database

This commit is contained in:
Andreas Öman 2008-04-19 14:52:09 +00:00
parent fcfeff193c
commit d042b9d420
9 changed files with 100 additions and 96 deletions

View file

@ -156,11 +156,11 @@ xmltv_grabber_chlist(tcp_queue_t *tq, xmltv_grabber_t *xg)
"<div>%s (%s)</div>", xc->xc_displayname, xc->xc_name);
tcp_qprintf(tq,
"<div class=\"infoprefixwide\">Best match:</div>"
"<div class=\"infoprefixwide\">Auto mapper:</div>"
"<div>%s</div>", xc->xc_bestmatch ?: "(no channel)");
tcp_qprintf(tq,
"<div class=\"infoprefixwidefat\">Mapped to:</div>"
"<div class=\"infoprefixwidefat\">Channel:</div>"
"<select class=\"textinput\" "
"onChange=\"new Ajax.Request('/ajax/xmltvgrabberchmap/%s', "
"{parameters: { xmltvch: '%s', channel: this.value }})\">",

22
epg.c
View file

@ -278,7 +278,7 @@ check_overlap(th_channel_t *ch, event_t *e)
static void
epg_event_create(th_channel_t *ch, time_t start, int duration,
const char *title, const char *desc, int source,
uint16_t id, refstr_t *icon, epg_content_type_t *ect)
uint16_t id, epg_content_type_t *ect)
{
unsigned int l;
time_t now;
@ -313,11 +313,6 @@ epg_event_create(th_channel_t *ch, time_t start, int duration,
LIST_INSERT_HEAD(&epg_hash[l], e, e_hash_link);
}
if(e->e_icon == NULL)
e->e_icon = refstr_dup(icon);
else
refstr_free(icon);
if(source > e->e_source) {
e->e_source = source;
@ -382,7 +377,7 @@ epg_update_event_by_id(th_channel_t *ch, uint16_t event_id,
} else {
epg_event_create(ch, start, duration, title, desc,
EVENT_SRC_DVB, event_id, NULL, ect);
EVENT_SRC_DVB, event_id, ect);
}
}
@ -418,11 +413,6 @@ epg_locate_current_event(th_channel_t *ch, time_t now)
{
event_t *e;
e = epg_event_find_by_time(ch, now);
if(e != NULL && e->e_icon != NULL) {
refstr_free(ch->ch_icon);
ch->ch_icon = refstr_dup(e->e_icon);
}
epg_set_current_event(ch, e);
}
@ -480,20 +470,20 @@ epg_channel_maintain(void *aux, int64_t clk)
void
epg_transfer_events(th_channel_t *ch, struct event_queue *src,
const char *srcname, refstr_t *icon)
const char *srcname, char *icon)
{
event_t *e;
int cnt = 0;
epg_lock();
if(ch->ch_icon == NULL)
ch->ch_icon = refstr_dup(icon);
free(ch->ch_icon);
ch->ch_icon = icon ? strdup(icon) : NULL;
TAILQ_FOREACH(e, src, e_link) {
epg_event_create(ch, e->e_start, e->e_duration, e->e_title,
e->e_desc, EVENT_SRC_XMLTV, 0, refstr_dup(icon),
e->e_desc, EVENT_SRC_XMLTV, 0,
e->e_content_type);
cnt++;
}

2
epg.h
View file

@ -48,7 +48,7 @@ void epg_update_event_by_id(th_channel_t *ch, uint16_t event_id,
const char *desc, epg_content_type_t *ect);
void epg_transfer_events(th_channel_t *ch, struct event_queue *src,
const char *srcname, refstr_t *icon);
const char *srcname, char *icon);
void event_time_txt(time_t start, int duration, char *out, int outlen);

View file

@ -43,6 +43,7 @@
int xmltv_status;
struct xmltv_grabber_list xmltv_grabbers;
struct xmltv_grabber_queue xmltv_grabber_workq;
static pthread_mutex_t xmltv_save_lock = PTHREAD_MUTEX_INITIALIZER;
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);
@ -138,6 +139,7 @@ xmltv_parse_programme(xmltv_grabber_t *xg, xmlNode *n,
xmltv_channel_t *xc;
xc = xc_find(xg, chid);
xc->xc_updated = 1;
start = str2time(startstr);
stop = str2time(stopstr);
@ -223,29 +225,12 @@ xmltv_flush_events(xmltv_grabber_t *xg)
}
#if 0
/*
*
*/
static int
xmltv_map(xmltv_channel_t *xc, th_channel_t *ch)
{
xmltv_map_t *xm;
LIST_FOREACH(xm, &xc->xc_maps, xm_link)
if(xm->xm_channel == ch)
return -1;
xm = calloc(1, sizeof(xmltv_map_t));
xm->xm_channel = ch;
LIST_INSERT_HEAD(&xc->xc_maps, xm, xm_link);
return 0;
}
/*
*
*/
static void
static th_channel_t *
xmltv_resolve_by_events(xmltv_channel_t *xc)
{
th_channel_t *ch;
@ -264,63 +249,78 @@ xmltv_resolve_by_events(xmltv_channel_t *xc)
LIST_FOREACH(ch, &channels, ch_global_link) {
ec = epg_event_find_by_time0(&ch->ch_epg_events, now);
cnt = 0;
while(1) {
if((cnt >= 10 && ec == NULL) || cnt >= 30) {
if(xmltv_map(xc, ch) == 0)
syslog(LOG_DEBUG,
"xmltv: Heuristically mapped \"%s\" (%s) to \"%s\" "
"(%d consequtive events matches)",
xc->xc_displayname, xc->xc_name, ch->ch_name, cnt);
break;
}
if((cnt >= 15 && ec == NULL) || cnt >= 30)
return ch;
if(ec == NULL || ex == NULL)
break;
if(ec->e_start != ex->e_start || ec->e_duration != ex->e_duration)
break;
ec = TAILQ_NEXT(ec, e_link);
ex = TAILQ_NEXT(ex, e_link);
cnt++;
}
}
}
return NULL;
}
/*
*
*/
void
xmltv_transfer(void)
static void
xmltv_transfer_events(xmltv_grabber_t *xg)
{
xmltv_channel_t *xc;
xmltv_map_t *xm;
th_channel_t *ch;
int how;
LIST_FOREACH(xc, &xmltv_channel_list, xc_link) {
ch = channel_find(xc->xc_displayname, 0, NULL);
if(ch != NULL)
xmltv_map(xc, ch);
xmltv_resolve_by_events(xc);
LIST_FOREACH(xm, &xc->xc_maps, xm_link) {
if(xm->xm_isupdated)
TAILQ_FOREACH(xc, &xg->xg_channels, xc_link) {
if(xc->xc_disabled)
continue;
if(xc->xc_channel != NULL) {
ch = channel_find(xc->xc_channel, 0, NULL);
if(ch == NULL)
continue;
epg_transfer_events(xm->xm_channel, &xc->xc_events, xc->xc_name,
xc->xc_icon);
xm->xm_isupdated = 1;
} else {
how = 0;
ch = channel_find(xc->xc_displayname, 0, NULL);
if(ch == NULL) {
epg_lock();
ch = xmltv_resolve_by_events(xc);
epg_unlock();
if(ch == NULL)
continue;
how = 1;
}
if(strcmp(xc->xc_bestmatch ?: "", ch->ch_name)) {
syslog(LOG_DEBUG,
"xmltv: mapped \"%s\" (%s) to \"%s\" by %s",
xc->xc_displayname, xc->xc_name, ch->ch_name,
how ? "consequtive-event-matching" : "name");
free(xc->xc_bestmatch);
xc->xc_bestmatch = strdup(ch->ch_name);
xmltv_config_save();
}
}
if(xc->xc_updated == 0)
continue;
xc->xc_updated = 0;
epg_transfer_events(ch, &xc->xc_events, xc->xc_name, xc->xc_icon_url);
}
}
#endif
/*
@ -493,8 +493,8 @@ xmltv_thread(void *aux)
/* Start by finding all available grabbers, we try with a few
different locations */
if(xmltv_find_grabbers("/bin/tv_find_grabbers") &&
xmltv_find_grabbers("/usr/bin/tv_find_grabbers") &&
if(xmltv_find_grabbers("/usr/bin/tv_find_grabbers") &&
xmltv_find_grabbers("/bin/tv_find_grabbers") &&
xmltv_find_grabbers("/usr/local/bin/tv_find_grabbers")) {
xmltv_status = XMLTVSTATUS_FIND_GRABBERS_NOT_FOUND;
return NULL;
@ -526,7 +526,11 @@ xmltv_thread(void *aux)
continue;
}
n = INT32_MAX;
LIST_FOREACH(xg, &xmltv_grabbers, xg_link)
xmltv_transfer_events(xg);
time(&n);
n = n + 60;
LIST_FOREACH(xg, &xmltv_grabbers, xg_link)
n = xg->xg_nextgrab ? MIN(n, xg->xg_nextgrab) : n;
@ -546,17 +550,15 @@ xmltv_thread(void *aux)
case XMLTV_GRABBER_ENQUEUED:
break;
case XMLTV_GRABBER_IDLE:
case XMLTV_GRABBER_UNCONFIGURED:
case XMLTV_GRABBER_DYSFUNCTIONAL:
case XMLTV_GRABBER_IDLE:
if(xg->xg_nextgrab <= n + 1)
TAILQ_INSERT_TAIL(&xmltv_grabber_workq, xg, xg_work_link);
break;
}
}
}
sleep(100000);
return NULL;
}
@ -667,33 +669,37 @@ xmltv_config_save(void)
xmltv_channel_t *xc;
FILE *fp;
pthread_mutex_lock(&xmltv_save_lock);
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;
if((fp = settings_open_for_write(buf)) != NULL) {
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);
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);
if(xc->xc_icon_url != NULL)
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");
TAILQ_FOREACH(xc, &xg->xg_channels, xc_link) {
fprintf(fp, "\tchannel {\n");
fprintf(fp, "\t\tdisplayname = %s\n", xc->xc_displayname);
if(xc->xc_icon_url != NULL)
fprintf(fp, "\t\ticon = %s\n", xc->xc_icon_url);
if(xc->xc_bestmatch != NULL)
fprintf(fp, "\t\tbestmatch = %s\n", xc->xc_bestmatch);
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");
}
fprintf(fp, "}\n");
fclose(fp);
}
fclose(fp);
pthread_mutex_unlock(&xmltv_save_lock);
}
/**
@ -745,6 +751,9 @@ xmltv_config_load(void)
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, "bestmatch", NULL)) != NULL)
xc->xc_bestmatch = strdup(s);
if((s = config_get_str_sub(&ce2->ce_sub, "icon", NULL)) != NULL)
xc->xc_icon_url = strdup(s);

View file

@ -70,6 +70,8 @@ typedef struct xmltv_channel {
struct event_queue xc_events;
int xc_updated;
} xmltv_channel_t;

View file

@ -164,7 +164,7 @@ cr_channel_info(client_t *c, char **argv, int argc)
"icon = %s\n"
"tag = %d\n",
ch->ch_name,
ch->ch_icon ? refstr_get(ch->ch_icon) : "",
ch->ch_icon ? ch->ch_icon : "",
ch->ch_tag);
return 0;

2
htsp.c
View file

@ -81,7 +81,7 @@ htsp_build_channel_msg(th_channel_t *ch, const char *method)
htsmsg_add_str(msg, "channelName", ch->ch_name);
htsmsg_add_u32(msg, "channelTag", ch->ch_tag);
if(ch->ch_icon != NULL)
htsmsg_add_str(msg, "channelIcon", refstr_get(ch->ch_icon));
htsmsg_add_str(msg, "channelIcon", ch->ch_icon);
if((e = epg_event_get_current(ch)) != NULL)
htsmsg_add_u32(msg, "currentEvent", e->e_tag);

2
rpc.c
View file

@ -52,7 +52,7 @@ rpc_build_channel_msg(th_channel_t *ch)
htsmsg_add_str(m, "name", ch->ch_name);
htsmsg_add_u32(m, "tag", ch->ch_tag);
if(ch->ch_icon)
htsmsg_add_str(m, "icon", refstr_get(ch->ch_icon));
htsmsg_add_str(m, "icon", ch->ch_icon);
return m;
}

View file

@ -176,7 +176,10 @@ typedef struct th_dvb_mux_instance {
uint8_t tdmi_polarisation; /* for DVB-S */
uint8_t tdmi_switchport; /* for DVB-S */
uint16_t tdmi_transport_stream_id;
char *tdmi_identifier;
const char *tdmi_network; /* Name of network, from NIT table */
struct th_transport_list tdmi_transports; /* via tht_mux_link */
@ -776,7 +779,7 @@ typedef struct th_channel {
struct event_queue ch_epg_events;
struct event *ch_epg_cur_event;
refstr_t *ch_icon;
char *ch_icon;
} th_channel_t;