htsp_dvr_entry_add(de);
}
+/**
+ * Find dvr entry using 'fuzzy' search
+ */
+static int
+dvr_entry_fuzzy_match(dvr_entry_t *de, epg_broadcast_t *e)
+{
+ time_t t1, t2;
+ const char *title1, *title2;
+
+ /* Matching ID */
+ if (de->de_dvb_eid && de->de_dvb_eid == e->dvb_eid)
+ return 1;
+
+ /* No title */
+ if (!(title1 = epg_broadcast_get_title(e, NULL)))
+ return 0;
+ if (!(title2 = lang_str_get(de->de_title, NULL)))
+ return 0;
+
+ /* Wrong length (+/-20%) */
+ t1 = de->de_stop - de->de_start;
+ t2 = e->stop - e->start;
+ if ( abs(t2 - t1) > (t1 / 5) )
+ return 0;
+
+ /* Outside of window (should it be configurable)? */
+ if ( abs(e->start - de->de_start) > 86400 )
+ return 0;
+
+ /* Title match (or contains?) */
+ return strcmp(title1, title2) == 0;
+}
+
/**
* Create the event
*/
de->de_desc = NULL;
// TODO: this really needs updating
if (e) {
+ de->de_dvb_eid = e->dvb_eid;
if (e->episode && e->episode->title)
de->de_title = lang_str_copy(e->episode->title);
if (e->description)
dvr_entry_t *de;
const char *chname, *s, *creator;
channel_t *ch;
- uint32_t start, stop, bcid;
+ uint32_t start, stop, bcid, u32;
int d;
dvr_config_t *cfg;
lang_str_t *title, *ls;
de->de_creator = strdup(creator);
de->de_title = title;
de->de_pri = dvr_pri2val(htsmsg_get_str(c, "pri"));
+ if (!htsmsg_get_u32(c, "dvb_eid", &u32))
+ de->de_dvb_eid = (uint16_t)u32;
if(htsmsg_get_s32(c, "start_extra", &d))
if (ch && ch->ch_dvr_extra_time_pre)
lang_str_serialize(de->de_title, m, "title");
+ if(de->de_dvb_eid)
+ htsmsg_add_u32(m, "dvb_eid", de->de_dvb_eid);
+
if(de->de_desc != NULL)
lang_str_serialize(de->de_desc, m, "description");
if (!de->de_title) de->de_title = lang_str_create();
save = lang_str_add(de->de_title, title, lang, 1);
}
+
+ /* EID */
+ if (e && e->dvb_eid != de->de_dvb_eid) {
+ de->de_dvb_eid = e->dvb_eid;
+ save = 1;
+ }
// TODO: description
/* Broadcast */
if (e && (de->de_bcast != e)) {
- de->de_bcast->putref(de->de_bcast);
+ if (de->de_bcast)
+ de->de_bcast->putref(de->de_bcast);
de->de_bcast = e;
e->getref(e);
save = 1;
/**
* Used to notify the DVR that an event has been replaced in the EPG
- *
- * TODO: I think this will record the title slot event if its now a
- * completely different episode etc...
*/
void
dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e)
{
- dvr_entry_t *de, *ude;
+ dvr_entry_t *de;
+ assert(e != NULL);
+ assert(new_e != NULL);
+
+ /* Ignore */
if ( e == new_e ) return;
- de = dvr_entry_find_by_event(e);
- if (de != NULL) {
- ude = dvr_entry_find_by_event_fuzzy(new_e);
- if (ude == NULL && de->de_sched_state == DVR_SCHEDULED)
- dvr_entry_cancel(de);
- else if(new_e->episode && new_e->episode->title)
- _dvr_entry_update(de, new_e, NULL, NULL, NULL, 0, 0, 0, 0);
+ /* Existing entry */
+ if ((de = dvr_entry_find_by_event(e))) {
+
+ /* Unlink the broadcast */
+ e->putref(e);
+ de->de_bcast = NULL;
+
+ /* Find match */
+ RB_FOREACH(e, &e->channel->ch_epg_schedule, sched_link) {
+ if (dvr_entry_fuzzy_match(de, e)) {
+ e->getref(e);
+ de->de_bcast = e;
+ _dvr_entry_update(de, e, NULL, NULL, NULL, 0, 0, 0, 0);
+ break;
+ }
+ }
}
}
{
dvr_entry_t *de;
de = dvr_entry_find_by_event(e);
- if (de) _dvr_entry_update(de, e, NULL, NULL, NULL, 0, 0, 0, 0);
+ if (de)
+ _dvr_entry_update(de, e, NULL, NULL, NULL, 0, 0, 0, 0);
+ else {
+ LIST_FOREACH(de, &dvrentries, de_global_link) {
+ if (dvr_entry_fuzzy_match(de, e)) {
+ e->getref(e);
+ de->de_bcast = e;
+ _dvr_entry_update(de, e, NULL, NULL, NULL, 0, 0, 0, 0);
+ break;
+ }
+ }
+ }
}
/**
return NULL;
}
-/**
- * Find dvr entry using 'fuzzy' search
- */
-dvr_entry_t *
-dvr_entry_find_by_event_fuzzy(epg_broadcast_t *e)
-{
- dvr_entry_t *de;
-
- if (!e->episode || !e->episode->title)
- return NULL;
-
- LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link)
- if ((abs(de->de_start - e->start) < 600) && (abs(de->de_stop - e->stop) < 600)) {
- return de;
- }
- return NULL;
-}
-
/*
* Find DVR entry based on an episode
*/