]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
DVR: fix the broken dvb_eid handling, multiple DVR records can be matched
authorJaroslav Kysela <perex@perex.cz>
Tue, 3 Nov 2015 08:54:37 +0000 (09:54 +0100)
committerJaroslav Kysela <perex@perex.cz>
Tue, 3 Nov 2015 08:54:37 +0000 (09:54 +0100)
src/api/api_epg.c
src/dvr/dvr.h
src/dvr/dvr_db.c
src/htsp_server.c
src/webui/simpleui.c

index a5952af66e021c0e19553298879177e868c7c4f2..7ac6a6bbfb5867ea9c513d42077450703c0743f0 100644 (file)
@@ -164,12 +164,18 @@ api_epg_entry ( epg_broadcast_t *eb, const char *lang, access_t *perm )
   }
 
   /* Recording */
-  if (!access_verify2(perm, ACCESS_RECORDER) &&
-      (de = dvr_entry_find_by_event(eb)) &&
-      !access_verify_list(perm->aa_dvrcfgs,
-                          idnode_uuid_as_sstr(&de->de_config->dvr_id))) {
-    htsmsg_add_str(m, "dvrUuid", idnode_uuid_as_sstr(&de->de_id));
-    htsmsg_add_str(m, "dvrState", dvr_entry_schedstatus(de));
+  if (eb->channel && !access_verify2(perm, ACCESS_RECORDER)) {
+    /* Note: only first hit is matched */
+    LIST_FOREACH(de, &eb->channel->ch_dvrs, de_channel_link) {
+      if (de->de_bcast != eb)
+        continue;
+      if (access_verify_list(perm->aa_dvrcfgs,
+                             idnode_uuid_as_sstr(&de->de_config->dvr_id)))
+        continue;
+      htsmsg_add_str(m, "dvrUuid", idnode_uuid_as_sstr(&de->de_id));
+      htsmsg_add_str(m, "dvrState", dvr_entry_schedstatus(de));
+      break;
+    }
   }
 
   /* Next event */
index 56a0c4344950dab2c021f2ee75c6c7d704340933..ec283944d4b414c8f5121be2b9031a804c94db50 100644 (file)
@@ -513,12 +513,8 @@ dvr_entry_t *dvr_entry_find_by_id(int id);
 static inline dvr_entry_t *dvr_entry_find_by_uuid(const char *uuid)
   { return (dvr_entry_t*)idnode_find(uuid, &dvr_entry_class, NULL); }
 
-dvr_entry_t *dvr_entry_find_by_event(epg_broadcast_t *e);
-
 dvr_entry_t *dvr_entry_find_by_event_fuzzy(epg_broadcast_t *e);
 
-dvr_entry_t *dvr_entry_find_by_episode(epg_broadcast_t *e);
-
 const char *dvr_get_filename(dvr_entry_t *de);
 
 int64_t dvr_get_filesize(dvr_entry_t *de);
index cc27854d918744be07dd8de59f1988e81d73b7d0..ffe4e8f6587280c993717b93cc66c921544f2d5a 100644 (file)
@@ -1458,10 +1458,14 @@ dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e)
   assert(new_e != NULL);
 
   /* Ignore */
-  if (e == new_e) return;
+  if (e->channel == NULL || e == new_e) return;
 
   /* Existing entry */
-  if ((de = dvr_entry_find_by_event(e))) {
+  LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link) {
+
+    if (de->de_bcast != e)
+      continue;
+
     tvhtrace("dvr",
              "dvr entry %s event replaced %s on %s @ %"PRItime_t
              " to %"PRItime_t,
@@ -1509,8 +1513,13 @@ dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e)
 void
 dvr_event_removed(epg_broadcast_t *e)
 {
-  dvr_entry_t *de = dvr_entry_find_by_event(e);
-  if (de) {
+  dvr_entry_t *de;
+
+  if (e->channel == NULL)
+    return;
+  LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link) {
+    if (de->de_bcast != e)
+      continue;
     dvr_entry_assign_broadcast(de, NULL);
     dvr_entry_save(de);
   }
@@ -1522,14 +1531,21 @@ dvr_event_removed(epg_broadcast_t *e)
 void dvr_event_updated(epg_broadcast_t *e)
 {
   dvr_entry_t *de;
-  de = dvr_entry_find_by_event(e);
-  if (de)
-    _dvr_entry_update(de, -1, e, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0);
-  else {
-    LIST_FOREACH(de, &dvrentries, de_global_link) {
+  int found = 0;
+
+  if (e->channel == NULL)
+    return;
+  LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link) {
+    if (de->de_bcast != e)
+      continue;
+    _dvr_entry_update(de, -1, e, NULL, NULL, NULL, NULL,
+                      NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0);
+    found++;
+  }
+  if (found == 0) {
+    LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link) {
       if (de->de_sched_state != DVR_SCHEDULED) continue;
       if (de->de_bcast) continue;
-      if (de->de_channel != e->channel) continue;
       if (dvr_entry_fuzzy_match(de, e, e->dvb_eid,
                                 de->de_config->dvr_update_window)) {
         tvhtrace("dvr",
@@ -1539,83 +1555,66 @@ void dvr_event_updated(epg_broadcast_t *e)
                  epg_broadcast_get_title(e, NULL),
                  channel_get_name(e->channel),
                  e->start, e->stop);
-        _dvr_entry_update(de, -1, e, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0);
+        _dvr_entry_update(de, -1, e, NULL, NULL, NULL, NULL,
+                          NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0);
         break;
       }
     }
   }
 }
 
-/**
- * Event running status is updated
- */
-static void dvr_entry_not_running(dvr_entry_t *de,
-                                  const char *srcname,
-                                  const char *srctitle)
-{
-  if (!de->de_running_stop ||
-      de->de_running_start > de->de_running_stop)
-    tvhdebug("dvr", "dvr entry %s %s %s on %s - EPG marking stop",
-             idnode_uuid_as_sstr(&de->de_id), srcname, srctitle,
-             channel_get_name(de->de_channel));
-  de->de_running_stop = dispatch_clock;
-  if (de->de_sched_state == DVR_RECORDING && de->de_running_start) {
-    if (dvr_entry_get_stop_time(de) > dispatch_clock) {
-      de->de_dont_reschedule = 1;
-      dvr_stop_recording(de, SM_CODE_OK, 0, 0);
-      tvhdebug("dvr", "dvr entry %s %s %s on %s - EPG stop",
-             idnode_uuid_as_sstr(&de->de_id), srcname, srctitle,
-             channel_get_name(de->de_channel));
-    }
-  }
-}
-
 /**
  * Event running status is updated
  */
 void dvr_event_running(epg_broadcast_t *e, epg_source_t esrc, int running)
 {
-  dvr_entry_t *de, *de2;
+  dvr_entry_t *de;
+  const char *srcname;
 
-  if (esrc != EPG_SOURCE_EIT || e->dvb_eid == 0)
-    return;
-  de = dvr_entry_find_by_event(e);
-  if (de == NULL)
-    return;
-  if (!de->de_channel->ch_epg_running || !de->de_config->dvr_running) {
-    de->de_running_start = de->de_running_stop = 0;
-    return;
-  }
-  if (!running) {
-    dvr_entry_not_running(de, "event", epg_broadcast_get_title(e, NULL));
+  if (esrc != EPG_SOURCE_EIT || e->dvb_eid == 0 || e->channel == NULL)
     return;
-  }
-  de2 = de;
-  assert(e->channel == de->de_channel);
-  LIST_FOREACH(de, &de->de_channel->ch_dvrs, de_channel_link) {
-    if (de != de2) {
-      if (de->de_dvb_eid == 0)
-        continue;
-      if (de->de_dvb_eid == e->dvb_eid)
-        goto running;
-      dvr_entry_not_running(de, "other running event",
-                            epg_broadcast_get_title(e, NULL));
+  LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link) {
+    if (de->de_dvb_eid == 0 ||
+        !de->de_channel->ch_epg_running ||
+        !de->de_config->dvr_running) {
+      de->de_running_start = de->de_running_stop = 0;
       continue;
     }
-running:
-    if (!de->de_running_start)
-      tvhdebug("dvr", "dvr entry %s event %s on %s - EPG marking start",
-               idnode_uuid_as_sstr(&de->de_id),
-               epg_broadcast_get_title(e, NULL),
-               channel_get_name(e->channel));
-    de->de_running_start = dispatch_clock;
-    if (dvr_entry_get_start_time(de) > dispatch_clock) {
-      de->de_start = dispatch_clock;
-      dvr_entry_set_timer(de);
-      tvhdebug("dvr", "dvr entry %s event %s on %s - EPG start",
-               idnode_uuid_as_sstr(&de->de_id),
-               epg_broadcast_get_title(e, NULL),
-               channel_get_name(e->channel));
+    if (running && de->de_dvb_eid == e->dvb_eid) {
+      if (!de->de_running_start)
+        tvhdebug("dvr", "dvr entry %s event %s on %s - EPG marking start",
+                 idnode_uuid_as_sstr(&de->de_id),
+                 epg_broadcast_get_title(e, NULL),
+                 channel_get_name(e->channel));
+      de->de_running_start = dispatch_clock;
+      if (dvr_entry_get_start_time(de) > dispatch_clock) {
+        de->de_start = dispatch_clock;
+        dvr_entry_set_timer(de);
+        tvhdebug("dvr", "dvr entry %s event %s on %s - EPG start",
+                 idnode_uuid_as_sstr(&de->de_id),
+                 epg_broadcast_get_title(e, NULL),
+                 channel_get_name(e->channel));
+      }
+    } else {
+      srcname = de->de_dvb_eid == e->dvb_eid ? "event" : "other running event";
+      if (!de->de_running_stop ||
+          de->de_running_start > de->de_running_stop) {
+        tvhdebug("dvr", "dvr entry %s %s %s on %s - EPG marking stop",
+                 idnode_uuid_as_sstr(&de->de_id), srcname,
+                 epg_broadcast_get_title(e, NULL),
+                 channel_get_name(de->de_channel));
+      }
+      de->de_running_stop = dispatch_clock;
+      if (de->de_sched_state == DVR_RECORDING && de->de_running_start) {
+        if (dvr_entry_get_stop_time(de) > dispatch_clock) {
+          de->de_dont_reschedule = 1;
+          dvr_stop_recording(de, SM_CODE_OK, 0, 0);
+          tvhdebug("dvr", "dvr entry %s %s %s on %s - EPG stop",
+                 idnode_uuid_as_sstr(&de->de_id), srcname,
+                 epg_broadcast_get_title(e, NULL),
+                 channel_get_name(de->de_channel));
+        }
+      }
     }
   }
 }
@@ -1743,40 +1742,6 @@ dvr_entry_find_by_id(int id)
 }
 
 
-/**
- *
- */
-dvr_entry_t *
-dvr_entry_find_by_event(epg_broadcast_t *e)
-{
-  dvr_entry_t *de;
-
-  if(!e->channel) return NULL;
-
-  LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link)
-    if(de->de_bcast == e) return de;
-  return NULL;
-}
-
-/*
- * Find DVR entry based on an episode
- */
-dvr_entry_t *
-dvr_entry_find_by_episode(epg_broadcast_t *e)
-{
-  if (e->episode) {
-    dvr_entry_t *de;
-    epg_broadcast_t *ebc;
-    LIST_FOREACH(ebc, &e->episode->broadcasts, ep_link) {
-      de = dvr_entry_find_by_event(ebc);
-      if (de) return de;
-    }
-    return NULL;
-  } else {
-    return dvr_entry_find_by_event(e);
-  }
-}
-
 /**
  * Unconditionally remove an entry
  */
index cc474558198b48067c696cc1efec8176ff8356dc..a88101be9a6ff9570c556d513b7e0bf173282012 100644 (file)
@@ -992,9 +992,15 @@ htsp_build_event
       htsmsg_add_str(out, "image", ee->image);
   }
 
-  if((de = dvr_entry_find_by_event(e)) != NULL &&
-     !dvr_entry_verify(de, htsp->htsp_granted_access, 1)) {
-    htsmsg_add_u32(out, "dvrId", idnode_get_short_uuid(&de->de_id));
+  if (e->channel) {
+    LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link) {
+      if (de->de_bcast != e)
+        continue;
+      if (dvr_entry_verify(de, htsp->htsp_granted_access, 1))
+        continue;
+      htsmsg_add_u32(out, "dvrId", idnode_get_short_uuid(&de->de_id));
+      break;
+    }
   }
 
   if ((n = epg_broadcast_get_next(e)))
index f7fd54dd23cae2028279ed3042b835d95ff17603..14ad9e605a5a6e2a7a4febefdd8ffd8294de1209 100644 (file)
@@ -111,6 +111,23 @@ dvr_query_free(dvr_query_result_t *dqr)
   free(dqr->dqr_array);
 }
 
+/**
+ *
+ */
+static dvr_entry_t *
+dvr_find_by_event(epg_broadcast_t *e)
+{
+  dvr_entry_t *de;
+
+  if (e->channel == NULL)
+    return NULL;
+
+  LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link)
+    if (de->de_bcast == e)
+      return de;
+  return NULL;
+}
+
 /**
  * Sorting functions
  */
@@ -223,7 +240,7 @@ page_simple(http_connection_t *hc,
                      days[day.tm_wday], day.tm_mday, day.tm_mon + 1);
        }
 
-       de = dvr_entry_find_by_event(e);
+       de = dvr_find_by_event(e);
        rstatus = de != NULL ? val2str(de->de_sched_state,
                                       recstatustxt) : NULL;
 
@@ -314,7 +331,7 @@ page_einfo(http_connection_t *hc, const char *remain, void *opaque)
     return 404;
   }
 
-  de = dvr_entry_find_by_event(e);
+  de = dvr_find_by_event(e);
 
   if((http_arg_get(&hc->hc_req_args, "rec")) != NULL) {
     de = dvr_entry_create_by_event(1, NULL, e, 0, 0, hc->hc_username ?: NULL,