Basically hack out all code that currently does not work due to partial epg rewrite.

This commit is contained in:
Adam Sutton 2012-05-17 12:52:21 +01:00
parent 8ca64083f1
commit d1dcaf4e69
9 changed files with 78 additions and 890 deletions

View file

@ -405,7 +405,7 @@ channel_delete(channel_t *ch)
s->ths_channel = NULL;
}
epg_unlink_from_channel(ch);
//epg_unlink_from_channel(ch);
hts_settings_remove("channels/%d", ch->ch_id);

View file

@ -325,6 +325,7 @@ tdt_add(th_dvb_mux_instance_t *tdmi, struct dmx_sct_filter_params *fparams,
/**
* DVB Descriptor; Short Event
*/
#if TODO
static int
dvb_desc_short_event(uint8_t *ptr, int len,
char *title, size_t titlelen,
@ -408,6 +409,7 @@ dvb_desc_extended_event(uint8_t *ptr, int len,
return 0;
}
#endif
/**
@ -446,6 +448,7 @@ static int
dvb_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
uint8_t tableid, void *opaque)
{
#if TODO
service_t *t;
channel_t *ch;
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
@ -596,6 +599,7 @@ dvb_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
if(changed)
epg_event_updated(e);
}
#endif
return 0;
}

View file

@ -30,7 +30,7 @@
#include "htsp.h"
#include "streaming.h"
static int de_tally;
//static int de_tally;
int dvr_iov_max;
@ -40,7 +40,9 @@ struct dvr_entry_list dvrentries;
static void dvr_entry_save(dvr_entry_t *de);
static void dvr_timer_expire(void *aux);
#if 0
static void dvr_timer_start_recording(void *aux);
#endif
/**
* Return printable status for a dvr entry
@ -153,6 +155,7 @@ dvr_entry_notify(dvr_entry_t *de)
/**
*
*/
#if TODO
static void
dvr_make_title(char *output, size_t outlen, dvr_entry_t *de)
{
@ -207,11 +210,13 @@ dvr_make_title(char *output, size_t outlen, dvr_entry_t *de)
}
}
}
#endif
/**
*
*/
#if TODO
static void
dvr_entry_link(dvr_entry_t *de)
{
@ -246,6 +251,7 @@ dvr_entry_link(dvr_entry_t *de)
}
htsp_dvr_entry_add(de);
}
#endif
/**
@ -258,6 +264,7 @@ dvr_entry_create(const char *config_name,
const char *creator, dvr_autorec_entry_t *dae,
epg_episode_t *ee, uint8_t content_type, dvr_prio_t pri)
{
#if TODO
dvr_entry_t *de;
char tbuf[30];
struct tm tm;
@ -317,12 +324,15 @@ dvr_entry_create(const char *config_name,
dvrdb_changed();
dvr_entry_save(de);
return de;
#endif
return NULL;
}
/**
*
*/
#if TODO
static const char *
longest_string(const char *a, const char *b)
{
@ -332,6 +342,7 @@ longest_string(const char *a, const char *b)
return b;
return strlen(a) > strlen(b) ? a : b;
}
#endif
/**
@ -342,6 +353,7 @@ dvr_entry_create_by_event(const char *config_name,
event_t *e, const char *creator,
dvr_autorec_entry_t *dae, dvr_prio_t pri)
{
#if TODO
const char *desc = NULL;
if(e->e_channel == NULL || e->e_title == NULL)
return NULL;
@ -356,6 +368,8 @@ dvr_entry_create_by_event(const char *config_name,
e->e_channel, e->e_start, e->e_stop,
e->e_title, desc, creator, dae, &e->e_episode,
e->e_content_type, pri);
#endif
return NULL;
}
@ -382,6 +396,7 @@ dvr_entry_create_by_autorec(event_t *e, dvr_autorec_entry_t *dae)
void
dvr_entry_dec_ref(dvr_entry_t *de)
{
#if TODO
lock_assert(&global_lock);
if(de->de_refcnt > 1) {
@ -401,6 +416,7 @@ dvr_entry_dec_ref(dvr_entry_t *de)
free(de->de_episode.ee_onscreen);
free(de);
#endif
}
@ -434,6 +450,7 @@ dvr_entry_remove(dvr_entry_t *de)
static void
dvr_db_load_one(htsmsg_t *c, int id)
{
#if TODO
dvr_entry_t *de;
const char *s, *title, *creator;
channel_t *ch;
@ -516,6 +533,7 @@ dvr_db_load_one(htsmsg_t *c, int id)
tvh_str_set(&de->de_episode.ee_onscreen, htsmsg_get_str(c, "episodename"));
dvr_entry_link(de);
#endif
}
@ -546,6 +564,7 @@ dvr_db_load(void)
static void
dvr_entry_save(dvr_entry_t *de)
{
#if TODO
htsmsg_t *m = htsmsg_create_map();
lock_assert(&global_lock);
@ -596,6 +615,7 @@ dvr_entry_save(dvr_entry_t *de)
hts_settings_save(m, "dvr/log/%d", de->de_id);
htsmsg_destroy(m);
#endif
}
@ -681,17 +701,20 @@ dvr_stop_recording(dvr_entry_t *de, int stopcode)
/**
*
*/
#if TODO
static void
dvr_timer_stop_recording(void *aux)
{
dvr_stop_recording(aux, 0);
}
#endif
/**
*
*/
#if 0
static void
dvr_timer_start_recording(void *aux)
{
@ -710,6 +733,7 @@ dvr_timer_start_recording(void *aux)
gtimer_arm_abs(&de->de_timer, dvr_timer_stop_recording, de,
de->de_stop + (60 * de->de_stop_extra));
}
#endif
/**

View file

@ -470,7 +470,9 @@ mk_build_metadata(const dvr_entry_t *de)
htsbuf_queue_t *q = htsbuf_queue_alloc(0);
char datestr[64];
struct tm tm;
#if TODO
const char *ctype;
#endif
localtime_r(&de->de_start, &tm);
snprintf(datestr, sizeof(datestr),
@ -487,22 +489,27 @@ mk_build_metadata(const dvr_entry_t *de)
addtag(q, build_tag_string("ORIGINAL_MEDIA_TYPE", "TV", 0, NULL));
#if TODO
if(de->de_content_type) {
ctype = epg_content_group_get_name(de->de_content_type);
if(ctype != NULL)
addtag(q, build_tag_string("CONTENT_TYPE", ctype, 0, NULL));
}
#endif
if(de->de_channel != NULL)
addtag(q, build_tag_string("TVCHANNEL", de->de_channel->ch_name, 0, NULL));
#if TODO
if(de->de_episode.ee_onscreen)
addtag(q, build_tag_string("SYNOPSIS",
de->de_episode.ee_onscreen, 0, NULL));
#endif
if(de->de_desc != NULL)
addtag(q, build_tag_string("SUMMARY", de->de_desc, 0, NULL));
#if TODO
if(de->de_episode.ee_season)
addtag(q, build_tag_int("PART_NUMBER", de->de_episode.ee_season,
60, "SEASON"));
@ -514,6 +521,7 @@ mk_build_metadata(const dvr_entry_t *de)
if(de->de_episode.ee_part)
addtag(q, build_tag_int("PART_NUMBER", de->de_episode.ee_part,
40, "PART"));
#endif
return q;
}
@ -525,7 +533,9 @@ mk_build_metadata2(const event_t *e)
htsbuf_queue_t *q = htsbuf_queue_alloc(0);
char datestr[64];
struct tm tm;
#if TODO
const char *ctype;
#endif
localtime_r(&e->e_start, &tm);
snprintf(datestr, sizeof(datestr),
@ -542,11 +552,13 @@ mk_build_metadata2(const event_t *e)
addtag(q, build_tag_string("ORIGINAL_MEDIA_TYPE", "TV", 0, NULL));
#if TODO
if(e->e_content_type) {
ctype = epg_content_group_get_name(e->e_content_type);
if(ctype != NULL)
addtag(q, build_tag_string("CONTENT_TYPE", ctype, 0, NULL));
}
#endif
if(e->e_channel != NULL)
addtag(q, build_tag_string("TVCHANNEL", e->e_channel->ch_name, 0, NULL));

884
src/epg.c
View file

@ -33,887 +33,3 @@
#include "htsp.h"
#include "htsmsg_binary.h"
#define EPG_MAX_AGE 86400
#define EPG_GLOBAL_HASH_WIDTH 1024
#define EPG_GLOBAL_HASH_MASK (EPG_GLOBAL_HASH_WIDTH - 1)
static struct event_list epg_hash[EPG_GLOBAL_HASH_WIDTH];
static void epg_expire_event_from_channel(void *opauqe);
static void epg_ch_check_current_event(void *aux);
/* helper function to fuzzy compare two events */
static int epg_event_cmp_overlap(event_t *e1, event_t *e2);
static void epg_erase_duplicates(event_t *e, channel_t *ch);
static int
e_ch_cmp(const event_t *a, const event_t *b)
{
return a->e_start - b->e_start;
}
/**
*
*/
static void
epg_set_current(channel_t *ch, event_t *e, event_t *next)
{
if(next == NULL && e != NULL)
next = RB_NEXT(e, e_channel_link);
if(ch->ch_epg_current == e && ch->ch_epg_next == next)
return;
ch->ch_epg_current = e;
ch->ch_epg_next = next;
if(e != NULL)
gtimer_arm_abs(&ch->ch_epg_timer_current, epg_ch_check_current_event,
ch, MAX(e->e_stop, dispatch_clock + 1));
htsp_channel_update_current(ch);
}
/**
*
*/
static void
epg_ch_check_current_event(void *aux)
{
channel_t *ch = aux;
event_t skel, *e = ch->ch_epg_current;
if(e != NULL) {
if(e->e_start <= dispatch_clock && e->e_stop > dispatch_clock) {
epg_set_current(ch, e, NULL);
return;
}
if((e = RB_NEXT(e, e_channel_link)) != NULL) {
if(e->e_start <= dispatch_clock && e->e_stop > dispatch_clock) {
epg_set_current(ch, e, NULL);
return;
}
}
}
e = epg_event_find_by_time(ch, dispatch_clock);
if(e != NULL) {
epg_set_current(ch, e, NULL);
return;
}
skel.e_start = dispatch_clock;
e = RB_FIND_GT(&ch->ch_epg_events, &skel, e_channel_link, e_ch_cmp);
if(e != NULL) {
gtimer_arm_abs(&ch->ch_epg_timer_current, epg_ch_check_current_event,
ch, MAX(e->e_start, dispatch_clock + 1));
epg_set_current(ch, NULL, e);
} else {
epg_set_current(ch, NULL, NULL);
}
}
/**
*
*/
void
epg_event_updated(event_t *e)
{
dvr_autorec_check_event(e);
}
/**
*
*/
int
epg_event_set_title(event_t *e, const char *title)
{
if(e->e_title != NULL && !strcmp(e->e_title, title))
return 0;
free(e->e_title);
e->e_title = strdup(title);
return 1;
}
/**
*
*/
int
epg_event_set_desc(event_t *e, const char *desc)
{
if(e->e_desc != NULL && strlen(e->e_desc) >= strlen(desc)) {
/* The current description is longer than the one we try to set.
* We assume that a longer description is better than a shorter
* so we just bail out.
* Typically happens when the XMLTV and DVB EPG feed differs.
*/
return 0;
}
free(e->e_desc);
e->e_desc = strdup(desc);
return 1;
}
/**
*
*/
int
epg_event_set_ext_desc(event_t *e, int ext_dn, const char *desc)
{
if(e->e_ext_desc == NULL && ext_dn != 0)
return 0;
if(e->e_ext_desc != NULL && strstr(e->e_ext_desc, desc))
return 0;
int len = strlen(desc) + ( e->e_ext_desc ? strlen(e->e_ext_desc) : 0) + 1;
char *tmp = (char*)malloc(len);
if(e->e_ext_desc) {
strcpy(tmp, e->e_ext_desc);
strcat(tmp, desc);
free(e->e_ext_desc);
} else
strcpy(tmp, desc);
e->e_ext_desc = tmp;
return 1;
}
/**
*
*/
int
epg_event_set_ext_item(event_t *e, int ext_dn, const char *item)
{
if(e->e_ext_item == NULL && ext_dn != 0)
return 0;
if(e->e_ext_item != NULL && strstr(e->e_ext_item, item))
return 0;
int len = strlen(item) + ( e->e_ext_item ? strlen(e->e_ext_item) : 0) + 1;
char *tmp = (char*)malloc(len);
if(e->e_ext_item) {
strcpy(tmp, e->e_ext_item);
strcat(tmp, item);
free(e->e_ext_item);
} else
strcpy(tmp, item);
e->e_ext_item = tmp;
return 1;
}
/**
*
*/
int
epg_event_set_ext_text(event_t *e, int ext_dn, const char *text)
{
if(e->e_ext_text == NULL && ext_dn != 0)
return 0;
if(e->e_ext_text != NULL && strstr(e->e_ext_text, text))
return 0;
int len = strlen(text) + ( e->e_ext_text ? strlen(e->e_ext_text) : 0) + 1;
char *tmp = (char*)malloc(len);
if(e->e_ext_text) {
strcpy(tmp, e->e_ext_text);
strcat(tmp, text);
free(e->e_ext_text);
} else
strcpy(tmp, text);
e->e_ext_text = tmp;
return 1;
}
/**
*
*/
int
epg_event_set_content_type(event_t *e, uint8_t type)
{
if(e->e_content_type == type)
return 0;
e->e_content_type = type;
return 1;
}
/**
*
*/
int
epg_event_set_episode(event_t *e, epg_episode_t *ee)
{
if(e->e_episode.ee_season == ee->ee_season &&
e->e_episode.ee_episode == ee->ee_episode &&
e->e_episode.ee_part == ee->ee_part &&
!strcmp(e->e_episode.ee_onscreen ?: "", ee->ee_onscreen ?: ""))
return 0;
e->e_episode.ee_season = ee->ee_season;
e->e_episode.ee_episode = ee->ee_episode;
e->e_episode.ee_part = ee->ee_part;
tvh_str_set(&e->e_episode.ee_onscreen, ee->ee_onscreen);
return 1;
}
/**
*
*/
static void
epg_event_destroy(event_t *e)
{
free(e->e_title);
free(e->e_desc);
free(e->e_ext_desc);
free(e->e_ext_item);
free(e->e_ext_text);
free(e->e_episode.ee_onscreen);
LIST_REMOVE(e, e_global_link);
free(e);
}
/**
*
*/
static void
epg_event_unref(event_t *e)
{
if(e->e_refcount > 1) {
e->e_refcount--;
return;
}
assert(e->e_refcount == 1);
epg_event_destroy(e);
}
/**
*
*/
static void
epg_remove_event_from_channel(channel_t *ch, event_t *e)
{
int wasfirst = e == RB_FIRST(&ch->ch_epg_events);
event_t *n = RB_NEXT(e, e_channel_link);
assert(e->e_channel == ch);
RB_REMOVE(&ch->ch_epg_events, e, e_channel_link);
e->e_channel = NULL;
epg_event_unref(e);
if(ch->ch_epg_current == e) {
epg_set_current(ch, NULL, n);
if(n != NULL)
gtimer_arm_abs(&ch->ch_epg_timer_current, epg_ch_check_current_event,
ch, n->e_start);
} else if(ch->ch_epg_next == e) {
epg_set_current(ch, ch->ch_epg_current, NULL);
}
if(wasfirst && (e = RB_FIRST(&ch->ch_epg_events)) != NULL) {
gtimer_arm_abs(&ch->ch_epg_timer_head, epg_expire_event_from_channel,
ch, e->e_stop);
}
}
/**
*
*/
event_t *
epg_event_create(channel_t *ch, time_t start, time_t stop, int dvb_id,
int *created)
{
static event_t *skel;
event_t *e;
static int tally;
if(created != NULL)
*created = 0;
if((stop - start) > 11 * 3600)
return NULL;
if(stop <= start)
return NULL;
lock_assert(&global_lock);
if(skel == NULL)
skel = calloc(1, sizeof(event_t));
skel->e_start = start;
e = RB_INSERT_SORTED(&ch->ch_epg_events, skel, e_channel_link, e_ch_cmp);
if(e == NULL) {
/* New entry was inserted */
if(created != NULL)
*created = 1;
e = skel;
skel = NULL;
e->e_id = ++tally;
e->e_stop = stop;
e->e_dvb_id = dvb_id;
LIST_INSERT_HEAD(&epg_hash[e->e_id & EPG_GLOBAL_HASH_MASK], e,
e_global_link);
e->e_refcount = 1;
e->e_channel = ch;
if(e == RB_FIRST(&ch->ch_epg_events)) {
/* First in temporal order, arm expiration timer */
gtimer_arm_abs(&ch->ch_epg_timer_head, epg_expire_event_from_channel,
ch, e->e_stop);
}
if(ch->ch_epg_timer_current.gti_callback == NULL ||
start < ch->ch_epg_timer_current.gti_expire) {
gtimer_arm_abs(&ch->ch_epg_timer_current, epg_ch_check_current_event,
ch, e->e_start);
}
} else {
/* Already exist */
if(stop > e->e_stop) {
/* We allow the event to extend in time */
#if 0
printf("Event %s on %s extended stop time\n", e->e_title,
e->e_channel->ch_name);
printf("Previous %s", ctime(&e->e_stop));
printf(" New %s", ctime(&stop));
#endif
e->e_stop = stop;
if(e == ch->ch_epg_current) {
gtimer_arm_abs(&ch->ch_epg_timer_current, epg_ch_check_current_event,
ch, e->e_start);
}
}
}
epg_erase_duplicates(e, ch);
return e;
}
static void
epg_erase_duplicates(event_t *e, channel_t *ch) {
event_t *p, *n;
int dvb_id = e->e_dvb_id;
if(dvb_id != -1) {
/* Erase any close events with the same DVB event id or are very similar*/
if((p = RB_PREV(e, e_channel_link)) != NULL) {
if(p->e_dvb_id == dvb_id || epg_event_cmp_overlap(p, e)) {
tvhlog(LOG_DEBUG, "epg",
"Removing overlapping event instance %s from EPG", p->e_title);
dvr_event_replaced(p, e);
epg_remove_event_from_channel(ch, p);
} else if((p = RB_PREV(p, e_channel_link)) != NULL) {
if(p->e_dvb_id == dvb_id || epg_event_cmp_overlap(p, e)) {
tvhlog(LOG_DEBUG, "epg",
"Removing overlapping event instance %s from EPG", p->e_title);
dvr_event_replaced(p, e);
epg_remove_event_from_channel(ch, p);
}
}
}
if((n = RB_NEXT(e, e_channel_link)) != NULL) {
if(n->e_dvb_id == dvb_id || epg_event_cmp_overlap(n, e)) {
tvhlog(LOG_DEBUG, "epg",
"Removing overlapping event instance %s from EPG", n->e_title);
dvr_event_replaced(n, e);
epg_remove_event_from_channel(ch, n);
} else if((n = RB_NEXT(n, e_channel_link)) != NULL) {
if(n->e_dvb_id == dvb_id || epg_event_cmp_overlap(n, e)) {
tvhlog(LOG_DEBUG, "epg",
"Removing overlapping event instance %s from EPG", n->e_title);
dvr_event_replaced(n, e);
epg_remove_event_from_channel(ch, n);
}
}
}
}
}
static int
epg_event_cmp_overlap(event_t *e1, event_t *e2)
{
int dur_a, dur_b, mindur;
if ((e1->e_title == NULL) || (e2->e_title == NULL))
return 0;
dur_a = e1->e_stop - e1->e_start;
dur_b = e2->e_stop - e2->e_start;
mindur = dur_a < dur_b ? dur_a : dur_b;
if ((abs(e1->e_start - e2->e_start) < mindur) && (abs(e1->e_stop - e2->e_stop) < mindur)) {
return 1;
}
return 0;
}
/**
*
*/
event_t *
epg_event_find_by_time(channel_t *ch, time_t t)
{
event_t skel, *e;
skel.e_start = t;
e = RB_FIND_LE(&ch->ch_epg_events, &skel, e_channel_link, e_ch_cmp);
if(e == NULL || e->e_stop < t)
return NULL;
return e;
}
/**
*
*/
event_t *
epg_event_find_by_id(int eventid)
{
event_t *e;
LIST_FOREACH(e, &epg_hash[eventid & EPG_GLOBAL_HASH_MASK], e_global_link)
if(e->e_id == eventid)
break;
return e;
}
/**
*
*/
static void
epg_expire_event_from_channel(void *opaque)
{
channel_t *ch = opaque;
event_t *e = RB_FIRST(&ch->ch_epg_events);
epg_remove_event_from_channel(ch, e);
}
/**
*
*/
void
epg_unlink_from_channel(channel_t *ch)
{
event_t *e;
while((e = ch->ch_epg_events.root) != NULL)
epg_remove_event_from_channel(ch, e);
gtimer_disarm(&ch->ch_epg_timer_head);
gtimer_disarm(&ch->ch_epg_timer_current);
}
/**
* EPG content group
*
* Based on the content types defined in EN 300 468
*/
static const char *groupnames[16] = {
[1] = "Movie / Drama",
[2] = "News / Current affairs",
[3] = "Show / Games",
[4] = "Sports",
[5] = "Children's / Youth",
[6] = "Music",
[7] = "Art / Culture",
[8] = "Social / Political issues / Economics",
[9] = "Education / Science / Factual topics",
[10] = "Leisure hobbies",
[11] = "Special characteristics",
};
/**
*
*/
const char *
epg_content_group_get_name(uint8_t id)
{
return id < 16 ? groupnames[id] : NULL;
}
/**
*
*/
uint8_t
epg_content_group_find_by_name(const char *name)
{
int i;
for(i = 0; i < 16; i++) {
if(groupnames[i] != NULL && !strcmp(name, groupnames[i]))
return i;
}
return 0;
}
/**
*
*/
static int
epg_event_create_by_msg(htsmsg_t *c, time_t now)
{
channel_t *ch;
event_t *e = NULL;
uint32_t ch_id = 0;
uint32_t e_start = 0;
uint32_t e_stop = 0;
int e_dvb_id = 0, v;
const char *s;
// Now create the event
if(htsmsg_get_u32(c, "ch_id", &ch_id))
return 0;
if((ch = channel_find_by_identifier(ch_id)) == NULL)
return 0;
if(htsmsg_get_u32(c, "start", &e_start))
return 0;
if(htsmsg_get_u32(c, "stop", &e_stop))
return 0;
if(e_stop < now)
return 0;
if(htsmsg_get_s32(c, "dvb_id", &e_dvb_id))
e_dvb_id = -1;
e = epg_event_create(ch, e_start, e_stop, e_dvb_id, NULL);
if((s = htsmsg_get_str(c, "title")) != NULL)
epg_event_set_title(e, s);
if((s = htsmsg_get_str(c, "desc")) != NULL)
epg_event_set_desc(e, s);
if(!htsmsg_get_s32(c, "season", &v))
e->e_episode.ee_season = v;
if(!htsmsg_get_s32(c, "episode", &v))
e->e_episode.ee_episode = v;
if(!htsmsg_get_s32(c, "part", &v))
e->e_episode.ee_part = v;
if((s = htsmsg_get_str(c, "epname")) != NULL)
tvh_str_set(&e->e_episode.ee_onscreen, s);
return 1;
}
/**
*
*/
static void
epg_load(void)
{
struct stat st;
int fd = hts_settings_open_file(0, "epgdb");
time_t now;
int created = 0;
time(&now);
if(fd == -1)
return;
if(fstat(fd, &st)) {
close(fd);
return;
}
uint8_t *mem = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
if(mem == MAP_FAILED) {
close(fd);
return;
}
const uint8_t *rp = mem;
size_t remain = st.st_size;
while(remain > 4) {
int msglen = (rp[0] << 24) | (rp[1] << 16) | (rp[2] << 8) | rp[3];
remain -= 4;
rp += 4;
if(msglen > remain) {
tvhlog(LOG_ERR, "EPG", "Malformed EPG database, skipping some data");
break;
}
htsmsg_t *m = htsmsg_binary_deserialize(rp, msglen, NULL);
created += epg_event_create_by_msg(m, now);
htsmsg_destroy(m);
rp += msglen;
remain -= msglen;
}
munmap(mem, st.st_size);
close(fd);
tvhlog(LOG_NOTICE, "EPG", "Injected %d event from disk database", created);
}
/**
*
*/
void
epg_init(void)
{
channel_t *ch;
epg_load();
RB_FOREACH(ch, &channel_name_tree, ch_name_link)
epg_ch_check_current_event(ch);
}
/**
* Save the epg on disk
*/
void
epg_save(void)
{
event_t *e;
int num_saved = 0;
size_t msglen;
void *msgdata;
channel_t *ch;
int fd = hts_settings_open_file(1, "epgdb");
RB_FOREACH(ch, &channel_name_tree, ch_name_link) {
RB_FOREACH(e, &ch->ch_epg_events, e_channel_link) {
if(!e->e_start || !e->e_stop)
continue;
htsmsg_t *m = htsmsg_create_map();
htsmsg_add_u32(m, "ch_id", ch->ch_id);
htsmsg_add_u32(m, "start", e->e_start);
htsmsg_add_u32(m, "stop", e->e_stop);
if(e->e_title != NULL)
htsmsg_add_str(m, "title", e->e_title);
if(e->e_desc != NULL)
htsmsg_add_str(m, "desc", e->e_desc);
if(e->e_dvb_id)
htsmsg_add_u32(m, "dvb_id", e->e_dvb_id);
if(e->e_episode.ee_season)
htsmsg_add_u32(m, "season", e->e_episode.ee_season);
if(e->e_episode.ee_episode)
htsmsg_add_u32(m, "episode", e->e_episode.ee_episode);
if(e->e_episode.ee_part)
htsmsg_add_u32(m, "part", e->e_episode.ee_part);
if(e->e_episode.ee_onscreen)
htsmsg_add_str(m, "epname", e->e_episode.ee_onscreen);
int r = htsmsg_binary_serialize(m, &msgdata, &msglen, 0x10000);
htsmsg_destroy(m);
if(!r) {
ssize_t written = write(fd, msgdata, msglen);
int err = errno;
free(msgdata);
if(written != msglen) {
tvhlog(LOG_DEBUG, "epg", "Failed to store EPG on disk -- %s",
strerror(err));
close(fd);
hts_settings_remove("epgdb");
return;
}
}
num_saved++;
}
}
close(fd);
tvhlog(LOG_DEBUG, "EPG", "Stored EPG data for %d events on disk", num_saved);
}
/**
*
*/
static void
eqr_add(epg_query_result_t *eqr, event_t *e, regex_t *preg, time_t now)
{
if(e->e_title == NULL)
return;
if(preg != NULL && regexec(preg, e->e_title, 0, NULL, 0))
return;
if(e->e_stop < now)
return; /* Already passed */
if(eqr->eqr_entries == eqr->eqr_alloced) {
/* Need to alloc more space */
eqr->eqr_alloced = MAX(100, eqr->eqr_alloced * 2);
eqr->eqr_array = realloc(eqr->eqr_array,
eqr->eqr_alloced * sizeof(event_t *));
}
eqr->eqr_array[eqr->eqr_entries++] = e;
e->e_refcount++;
}
/**
*
*/
static void
epg_query_add_channel(epg_query_result_t *eqr, channel_t *ch,
uint8_t content_type, regex_t *preg, time_t now)
{
event_t *e;
if(content_type == 0) {
RB_FOREACH(e, &ch->ch_epg_events, e_channel_link)
eqr_add(eqr, e, preg, now);
} else {
RB_FOREACH(e, &ch->ch_epg_events, e_channel_link)
if(content_type == e->e_content_type)
eqr_add(eqr, e, preg, now);
}
}
/**
*
*/
void
epg_query0(epg_query_result_t *eqr, channel_t *ch, channel_tag_t *ct,
uint8_t content_type, const char *title)
{
channel_tag_mapping_t *ctm;
time_t now;
regex_t preg0, *preg;
lock_assert(&global_lock);
memset(eqr, 0, sizeof(epg_query_result_t));
time(&now);
if(title != NULL) {
if(regcomp(&preg0, title, REG_ICASE | REG_EXTENDED | REG_NOSUB))
return;
preg = &preg0;
} else {
preg = NULL;
}
if(ch != NULL && ct == NULL) {
epg_query_add_channel(eqr, ch, content_type, preg, now);
return;
}
if(ct != NULL) {
LIST_FOREACH(ctm, &ct->ct_ctms, ctm_tag_link)
if(ch == NULL || ctm->ctm_channel == ch)
epg_query_add_channel(eqr, ctm->ctm_channel, content_type, preg, now);
return;
}
RB_FOREACH(ch, &channel_name_tree, ch_name_link)
epg_query_add_channel(eqr, ch, content_type, preg, now);
}
/**
*
*/
void
epg_query(epg_query_result_t *eqr, const char *channel, const char *tag,
const char *contentgroup, const char *title)
{
channel_t *ch = channel ? channel_find_by_name(channel, 0, 0) : NULL;
channel_tag_t *ct = tag ? channel_tag_find_by_name(tag, 0) : NULL;
uint8_t content_type = contentgroup ?
epg_content_group_find_by_name(contentgroup) : 0;
epg_query0(eqr, ch, ct, content_type, title);
}
/**
*
*/
void
epg_query_free(epg_query_result_t *eqr)
{
int i;
for(i = 0; i < eqr->eqr_entries; i++)
epg_event_unref(eqr->eqr_array[i]);
free(eqr->eqr_array);
}
/**
* Sorting functions
*/
static int
epg_sort_start_ascending(const void *A, const void *B)
{
event_t *a = *(event_t **)A;
event_t *b = *(event_t **)B;
return a->e_start - b->e_start;
}
/**
*
*/
void
epg_query_sort(epg_query_result_t *eqr)
{
int (*sf)(const void *a, const void *b);
sf = epg_sort_start_ascending;
qsort(eqr->eqr_array, eqr->eqr_entries, sizeof(event_t *), sf);
}

View file

@ -309,10 +309,12 @@ htsp_build_channel(channel_t *ch, const char *method)
if(ch->ch_icon != NULL)
htsmsg_add_str(out, "channelIcon", ch->ch_icon);
#if TODO
htsmsg_add_u32(out, "eventId",
ch->ch_epg_current != NULL ? ch->ch_epg_current->e_id : 0);
htsmsg_add_u32(out, "nextEventId",
ch->ch_epg_next ? ch->ch_epg_next->e_id : 0);
#endif
LIST_FOREACH(ctm, &ch->ch_ctms, ctm_channel_link) {
ct = ctm->ctm_tag;
@ -525,6 +527,7 @@ htsp_method_getTicket(htsp_connection_t *htsp, htsmsg_t *in)
static htsmsg_t *
htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
{
#if TODO
htsmsg_t *out;
uint32_t eventid;
event_t *e;
@ -600,6 +603,8 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
break;
}
return out;
#endif
return NULL;
}
/**
@ -697,6 +702,7 @@ htsp_method_deleteDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
static htsmsg_t *
htsp_method_epgQuery(htsp_connection_t *htsp, htsmsg_t *in)
{
#if TODO
htsmsg_t *out, *eventIds;
const char *query;
int c, i;
@ -734,11 +740,14 @@ htsp_method_epgQuery(htsp_connection_t *htsp, htsmsg_t *in)
epg_query_free(&eqr);
return out;
#endif
return NULL;
}
/**
*
*/
#if 0
static htsmsg_t *
htsp_build_event(event_t *e)
{
@ -776,6 +785,7 @@ htsp_build_event(event_t *e)
return out;
}
#endif
/**
* Get information about the given event +
@ -784,6 +794,7 @@ htsp_build_event(event_t *e)
static htsmsg_t *
htsp_method_getEvents(htsp_connection_t *htsp, htsmsg_t *in)
{
#if TODO
uint32_t eventid, numFollowing;
htsmsg_t *out, *events;
event_t *e;
@ -811,6 +822,8 @@ htsp_method_getEvents(htsp_connection_t *htsp, htsmsg_t *in)
htsmsg_add_msg(out, "events", events);
return out;
#endif
return NULL;
}
@ -820,6 +833,7 @@ htsp_method_getEvents(htsp_connection_t *htsp, htsmsg_t *in)
static htsmsg_t *
htsp_method_getEvent(htsp_connection_t *htsp, htsmsg_t *in)
{
#if TODO
uint32_t eventid;
event_t *e;
htsmsg_t *out;
@ -832,6 +846,8 @@ htsp_method_getEvent(htsp_connection_t *htsp, htsmsg_t *in)
out = htsp_build_event(e);
return out;
#endif
return NULL;
}
/**

View file

@ -148,7 +148,7 @@ spawn_and_store_stdout(const char *prog, char *const argv[], char **outp)
if(p == 0) {
close(0);
close(2);
//close(2);
close(fd[0]);
dup2(fd[1], 1);
close(fd[1]);
@ -162,7 +162,7 @@ spawn_and_store_stdout(const char *prog, char *const argv[], char **outp)
}
dup2(f, 0);
dup2(f, 2);
//dup2(f, 2);
close(f);
execve(prog, argv, environ);

View file

@ -424,13 +424,16 @@ static int
extjs_ecglist(http_connection_t *hc, const char *remain, void *opaque)
{
htsbuf_queue_t *hq = &hc->hc_reply;
htsmsg_t *out, *array, *c;
htsmsg_t *out, *array;//TODO:, *c;
#if TODO
const char *s;
int i;
#endif
out = htsmsg_create_map();
array = htsmsg_create_list();
#if TODO
for(i = 0; i < 16; i++) {
if((s = epg_content_group_get_name(i)) == NULL)
continue;
@ -439,6 +442,7 @@ extjs_ecglist(http_connection_t *hc, const char *remain, void *opaque)
htsmsg_add_str(c, "name", s);
htsmsg_add_msg(array, NULL, c);
}
#endif
htsmsg_add_msg(out, "entries", array);
@ -663,6 +667,7 @@ skip:
static int
extjs_epg(http_connection_t *hc, const char *remain, void *opaque)
{
#if TODO
htsbuf_queue_t *hq = &hc->hc_reply;
htsmsg_t *out, *array, *m;
epg_query_result_t eqr;
@ -756,6 +761,7 @@ extjs_epg(http_connection_t *hc, const char *remain, void *opaque)
htsmsg_json_serialize(out, hq, 0);
htsmsg_destroy(out);
http_output_content(hc, "text/x-json; charset=UTF-8");
#endif
return 0;
}
@ -768,7 +774,7 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
htsbuf_queue_t *hq = &hc->hc_reply;
const char *op = http_arg_get(&hc->hc_req_args, "op");
htsmsg_t *out, *r;
event_t *e;
//TODO:event_t *e;
dvr_entry_t *de;
const char *s;
int flags = 0;
@ -786,6 +792,7 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
if(!strcmp(op, "recordEvent")) {
#if TODO
const char *config_name = http_arg_get(&hc->hc_req_args, "config_name");
s = http_arg_get(&hc->hc_req_args, "eventId");
@ -809,6 +816,7 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
dvr_entry_create_by_event(config_name,
e, hc->hc_representative, NULL, DVR_PRIO_NORMAL);
#endif
out = htsmsg_create_map();
htsmsg_add_u32(out, "success", 1);
@ -898,6 +906,7 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
htsmsg_add_u32(out, "success", 1);
} else if(!strcmp(op, "createAutoRec")) {
#if TODO
const char *cgrp = http_arg_get(&hc->hc_req_args, "contentgrp");
@ -908,6 +917,7 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
http_arg_get(&hc->hc_req_args, "tag"),
cgrp ? epg_content_group_find_by_name(cgrp) : 0,
hc->hc_representative, "Created from EPG query");
#endif
out = htsmsg_create_map();
htsmsg_add_u32(out, "success", 1);
@ -1074,8 +1084,10 @@ extjs_dvrlist(http_connection_t *hc, const char *remain, void *opaque)
if(de->de_desc != NULL)
htsmsg_add_str(m, "description", de->de_desc);
#if TODO
if(de->de_episode.ee_onscreen)
htsmsg_add_str(m, "episode", de->de_episode.ee_onscreen);
#endif
htsmsg_add_u32(m, "id", de->de_id);
htsmsg_add_u32(m, "start", de->de_start);

View file

@ -58,6 +58,7 @@ static int
page_simple(http_connection_t *hc,
const char *remain, void *opaque)
{
#if TODO
htsbuf_queue_t *hq = &hc->hc_reply;
const char *s = http_arg_get(&hc->hc_req_args, "s");
event_t *e;
@ -184,6 +185,7 @@ page_simple(http_connection_t *hc,
htsbuf_qprintf(hq, "</body></html>");
http_output_html(hc);
#endif
return 0;
}
@ -193,6 +195,7 @@ page_simple(http_connection_t *hc,
static int
page_einfo(http_connection_t *hc, const char *remain, void *opaque)
{
#if TODO
htsbuf_queue_t *hq = &hc->hc_reply;
event_t *e;
struct tm a, b;
@ -267,6 +270,7 @@ page_einfo(http_connection_t *hc, const char *remain, void *opaque)
htsbuf_qprintf(hq, "<hr><a href=\"/simple.html\">To main page</a><br>");
htsbuf_qprintf(hq, "</body></html>");
http_output_html(hc);
#endif
return 0;
}