]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
add timerec support to htsp server
authorGlenn-1990 <g_christiaensen@msn.com>
Fri, 26 Dec 2014 17:39:57 +0000 (18:39 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sun, 4 Jan 2015 14:59:06 +0000 (15:59 +0100)
src/dvr/dvr.h
src/dvr/dvr_timerec.c
src/htsp_server.c
src/htsp_server.h

index 41b1b84fb8cb3cca4360e47c8f4626f22473ad47..4232060878cf98984d694e1b25884deda6dfaf4c 100644 (file)
@@ -538,6 +538,12 @@ void dvr_autorec_update(void);
 dvr_timerec_entry_t *
 dvr_timerec_create(const char *uuid, htsmsg_t *conf);
 
+dvr_timerec_entry_t*
+dvr_timerec_create_htsp(const char *dvr_config_name, const char *title,
+                            channel_t *ch, uint32_t start, uint32_t stop,
+                            uint32_t weekdays, dvr_prio_t pri, int retention,
+                            const char *owner, const char *creator, const char *comment, const char *name);
+
 static inline dvr_timerec_entry_t *
 dvr_timerec_find_by_uuid(const char *uuid)
   { return (dvr_timerec_entry_t*)idnode_find(uuid, &dvr_timerec_entry_class, NULL); }
index b8f55faf50ed94cb28078032a58dd146c535cdda..f022d35cbb62cc282a8cd87cc6afc5bb4e974a6b 100644 (file)
@@ -32,6 +32,7 @@
 #include "settings.h"
 #include "dvr.h"
 #include "epg.h"
+#include "htsp_server.h"
 
 struct dvr_timerec_entry_queue timerec_entries;
 
@@ -194,6 +195,51 @@ dvr_timerec_create(const char *uuid, htsmsg_t *conf)
 
   idnode_load(&dte->dte_id, conf);
 
+  htsp_timerec_entry_add(dte);
+
+  return dte;
+}
+
+dvr_timerec_entry_t*
+dvr_timerec_create_htsp(const char *dvr_config_name, const char *title,
+                            channel_t *ch, uint32_t start, uint32_t stop,
+                            uint32_t weekdays, dvr_prio_t pri, int retention,
+                            const char *owner, const char *creator, const char *comment, const char *name)
+{
+  dvr_timerec_entry_t *dte;
+  htsmsg_t *conf, *days;
+
+  conf = htsmsg_create_map();
+  days = htsmsg_create_list();
+
+  htsmsg_add_u32(conf, "enabled",     1);
+  htsmsg_add_u32(conf, "retention",   retention);
+  htsmsg_add_u32(conf, "pri",         pri);
+  htsmsg_add_str(conf, "title",       title);
+  htsmsg_add_str(conf, "config_name", dvr_config_name ?: "");
+  htsmsg_add_str(conf, "owner",       owner ?: "");
+  htsmsg_add_str(conf, "creator",     creator ?: "");
+  htsmsg_add_str(conf, "comment",     comment ?: "");
+  htsmsg_add_str(conf, "name",        name ?: "");
+  htsmsg_add_u32(conf, "start",       start);
+  htsmsg_add_u32(conf, "stop",        stop);
+
+  if (ch)
+    htsmsg_add_str(conf, "channel", idnode_uuid_as_str(&ch->ch_id));
+
+  int i;
+  for (i = 0; i < 7; i++)
+    if (weekdays & (1 << i))
+      htsmsg_add_u32(days, NULL, i + 1);
+
+  htsmsg_add_msg(conf, "weekdays", days);
+
+  dte = dvr_timerec_create(NULL, conf);
+  htsmsg_destroy(conf);
+
+  if (dte)
+    dvr_timerec_save(dte);
+
   return dte;
 }
 
@@ -208,6 +254,8 @@ timerec_entry_destroy(dvr_timerec_entry_t *dte, int delconf)
   if (delconf)
     hts_settings_remove("dvr/timerec/%s", idnode_uuid_as_str(&dte->dte_id));
 
+  htsp_timerec_entry_delete(dte);
+
   TAILQ_REMOVE(&timerec_entries, dte, dte_link);
   idnode_unlink(&dte->dte_id);
 
@@ -251,6 +299,7 @@ dvr_timerec_entry_class_save(idnode_t *self)
   dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)self;
   dvr_timerec_save(dte);
   dvr_timerec_check(dte);
+  htsp_timerec_entry_update(dte);
 }
 
 static void
@@ -617,8 +666,9 @@ dvr_timerec_timer_cb(void *aux)
   tvhtrace("dvr", "timerec update");
 
   /* check all entries */
-  TAILQ_FOREACH(dte, &timerec_entries, dte_link)
+  TAILQ_FOREACH(dte, &timerec_entries, dte_link) {
     dvr_timerec_check(dte);
+  }
 
   /* load the timer */
   gtimer_arm(&dvr_timerec_timer, dvr_timerec_timer_cb, NULL, 3550);
index c46d640fa74443cef980982c3a9e9345838c4145..5d3fb683d26da73171a76d65cebd6b82dfc20ac1 100644 (file)
@@ -77,6 +77,7 @@ static void *htsp_server, *htsp_server_2;
 #define HTSP_ASYNC_AUX_CHTAG   0x01
 #define HTSP_ASYNC_AUX_DVR     0x02
 #define HTSP_ASYNC_AUX_AUTOREC 0x03
+#define HTSP_ASYNC_AUX_TIMEREC 0x04
 
 #define HTSP_PRIV_MASK (ACCESS_HTSP_STREAMING)
 
@@ -676,6 +677,9 @@ htsp_build_dvrentry(dvr_entry_t *de, const char *method)
   if (de->de_autorec)
     htsmsg_add_str(out, "autorecId", idnode_uuid_as_str(&de->de_autorec->dae_id));
 
+  if (de->de_timerec)
+    htsmsg_add_str(out, "timerecId", idnode_uuid_as_str(&de->de_timerec->dte_id));
+
   htsmsg_add_s64(out, "start",       de->de_start);
   htsmsg_add_s64(out, "stop",        de->de_stop);
   htsmsg_add_s64(out, "startExtra",  dvr_entry_get_extra_time_pre(de));
@@ -768,6 +772,38 @@ htsp_build_autorecentry(dvr_autorec_entry_t *dae, const char *method)
   return out;
 }
 
+/**
+ *
+ */
+static htsmsg_t *
+htsp_build_timerecentry(dvr_timerec_entry_t *dte, const char *method)
+{
+  htsmsg_t *out = htsmsg_create_map();
+
+  htsmsg_add_str(out, "id",          idnode_uuid_as_str(&dte->dte_id));
+  htsmsg_add_u32(out, "enabled",     dte->dte_enabled);
+  htsmsg_add_u32(out, "daysOfWeek",  dte->dte_weekdays);
+  htsmsg_add_u32(out, "retention",   dte->dte_retention);
+  htsmsg_add_u32(out, "priority",    dte->dte_pri);
+  htsmsg_add_s32(out, "start",       dte->dte_start);
+  htsmsg_add_s32(out, "stop",        dte->dte_stop);
+
+  if(dte->dte_title)
+    htsmsg_add_str(out, "title",  dte->dte_title);
+  if(dte->dte_name)
+    htsmsg_add_str(out, "name",    dte->dte_name);
+  if(dte->dte_owner)
+    htsmsg_add_str(out, "owner",   dte->dte_owner);
+  if(dte->dte_creator)
+    htsmsg_add_str(out, "creator", dte->dte_creator);
+  if(dte->dte_channel)
+    htsmsg_add_u32(out, "channel", channel_get_id(dte->dte_channel));
+
+  htsmsg_add_str(out, "method", method);
+
+  return out;
+}
+
 /**
  *
  */
@@ -979,6 +1015,7 @@ htsp_method_async(htsp_connection_t *htsp, htsmsg_t *in)
   channel_tag_t *ct;
   dvr_entry_t *de;
   dvr_autorec_entry_t *dae;
+  dvr_timerec_entry_t *dte;
   htsmsg_t *m;
   uint32_t epg = 0;
   int64_t lastUpdate = 0;
@@ -1022,6 +1059,10 @@ htsp_method_async(htsp_connection_t *htsp, htsmsg_t *in)
   TAILQ_FOREACH(dae, &autorec_entries, dae_link)
     htsp_send_message(htsp, htsp_build_autorecentry(dae, "autorecEntryAdd"), NULL);
 
+  /* Send all timerecs */
+  TAILQ_FOREACH(dte, &timerec_entries, dte_link)
+    htsp_send_message(htsp, htsp_build_timerecentry(dte, "timerecEntryAdd"), NULL);
+
   /* Send all DVR entries */
   LIST_FOREACH(de, &dvrentries, de_global_link)
     if (htsp_user_access_channel(htsp,de->de_channel))
@@ -1635,6 +1676,97 @@ htsp_method_deleteAutorecEntry(htsp_connection_t *htsp, htsmsg_t *in)
   return out;
 }
 
+/**
+ * add a Dvr timerec entry
+ */
+static htsmsg_t *
+htsp_method_addTimerecEntry(htsp_connection_t *htsp, htsmsg_t *in)
+{
+  htsmsg_t *out;
+  dvr_timerec_entry_t *dte;
+  const char *dvr_config_name, *title, *creator, *comment, *owner, *name;
+  uint32_t u32, days_of_week, priority, retention, start, stop;
+  channel_t *ch = NULL;
+
+  /* Options */
+  if(!(title = htsmsg_get_str(in, "title"))
+      || htsmsg_get_u32(in, "start", &start)
+      || htsmsg_get_u32(in, "stop", &stop)
+      || htsmsg_get_u32(in, "channelId", &u32))
+    return htsp_error("Invalid arguments");
+
+  if (stop == start)
+    stop = start+1;
+
+  ch = channel_find_by_id(u32);
+  dvr_config_name = htsp_dvr_config_name(htsp, htsmsg_get_str(in, "configName"));
+
+  if(htsmsg_get_u32(in, "retention", &retention))
+    retention = 0;       // 0 = dvr config
+  if(htsmsg_get_u32(in, "daysOfWeek", &days_of_week))
+    days_of_week = 0x7f; // all days
+  if(htsmsg_get_u32(in, "priority", &priority))
+    priority = DVR_PRIO_NORMAL;
+
+  creator = htsp->htsp_username;
+  if (!(comment = htsmsg_get_str(in, "comment")))
+    comment = "";
+  if (!(owner = htsmsg_get_str(in, "owner")))
+    owner = "";
+  if (!(name = htsmsg_get_str(in, "name")))
+    name = "";
+
+  /* Check access */
+  if (ch && !htsp_user_access_channel(htsp, ch))
+    return htsp_error("User does not have access");
+
+  /* Add actual timerec */
+  dte = dvr_timerec_create_htsp(dvr_config_name, title, ch, start, stop, days_of_week,
+      priority, retention, htsp->htsp_granted_access->aa_username, creator, comment, name);
+
+  /* create response */
+  out = htsmsg_create_map();
+
+  if (dte) {
+    htsmsg_add_str(out, "id", idnode_uuid_as_str(&dte->dte_id));
+    htsmsg_add_u32(out, "success", 1);
+  }
+  else {
+    htsmsg_add_str(out, "error", "Could not add timerec entry");
+    htsmsg_add_u32(out, "success", 0);
+  }
+  return out;
+}
+
+/**
+ * delete a Dvr timerec entry
+ */
+static htsmsg_t *
+htsp_method_deleteTimerecEntry(htsp_connection_t *htsp, htsmsg_t *in)
+{
+  htsmsg_t *out;
+  const char *dteId;
+  dvr_timerec_entry_t *dte;
+
+  if (!(dteId = htsmsg_get_str(in, "id")))
+    return htsp_error("Missing argument 'id'");
+
+  if((dte = dvr_timerec_find_by_uuid(dteId)) == NULL)
+    return htsp_error("id not found");
+
+  /* Check access */
+  if (!htsp_user_access_channel(htsp, dte->dte_channel))
+    return htsp_error("User does not have access");
+
+  timerec_destroy_by_id(dteId, 1);
+
+  /* create response */
+  out = htsmsg_create_map();
+  htsmsg_add_u32(out, "success", 1);
+
+  return out;
+}
+
 /**
  * Return cutpoint data for a recording (if present). 
  *
@@ -2257,6 +2389,8 @@ struct {
   { "deleteDvrEntry",           htsp_method_deleteDvrEntry,     ACCESS_HTSP_RECORDER},
   { "addAutorecEntry",          htsp_method_addAutorecEntry,    ACCESS_HTSP_RECORDER},
   { "deleteAutorecEntry",       htsp_method_deleteAutorecEntry, ACCESS_HTSP_RECORDER},
+  { "addTimerecEntry",          htsp_method_addTimerecEntry,    ACCESS_HTSP_RECORDER},
+  { "deleteTimerecEntry",       htsp_method_deleteTimerecEntry, ACCESS_HTSP_RECORDER},
   { "getDvrCutpoints",          htsp_method_getDvrCutpoints,    ACCESS_HTSP_RECORDER},
   { "getTicket",                htsp_method_getTicket,          ACCESS_HTSP_STREAMING},
   { "subscribe",                htsp_method_subscribe,          ACCESS_HTSP_STREAMING},
@@ -2925,6 +3059,58 @@ htsp_autorec_entry_delete(dvr_autorec_entry_t *dae)
   htsp_async_send(m, HTSP_ASYNC_ON, HTSP_ASYNC_AUX_AUTOREC, dae);
 }
 
+/**
+ * Called when a timerec entry is updated/added
+ */
+static void
+_htsp_timerec_entry_update(dvr_timerec_entry_t *dte, const char *method, htsmsg_t *msg)
+{
+  htsp_connection_t *htsp;
+  LIST_FOREACH(htsp, &htsp_async_connections, htsp_async_link) {
+    if (htsp->htsp_async_mode & HTSP_ASYNC_ON) {
+      if (dte->dte_channel == NULL || htsp_user_access_channel(htsp, dte->dte_channel)) {
+        htsmsg_t *m = msg ? htsmsg_copy(msg)
+                          : htsp_build_timerecentry(dte, method);
+        htsp_send_message(htsp, m, NULL);
+      }
+    }
+  }
+  htsmsg_destroy(msg);
+}
+
+/**
+ * Called from dvr_timerec.c when a timerec entry is added
+ */
+void
+htsp_timerec_entry_add(dvr_timerec_entry_t *dte)
+{
+  _htsp_timerec_entry_update(dte, "timerecEntryAdd", NULL);
+}
+
+/**
+ * Called from dvr_timerec.c when a timerec entry is updated
+ */
+void
+htsp_timerec_entry_update(dvr_timerec_entry_t *dte)
+{
+  _htsp_timerec_entry_update(dte, "timerecEntryUpdate", NULL);
+}
+
+/**
+ * Called from dvr_timerec.c when a timerec entry is deleted
+ */
+void
+htsp_timerec_entry_delete(dvr_timerec_entry_t *dte)
+{
+  if(dte == NULL)
+    return;
+
+  htsmsg_t *m = htsmsg_create_map();
+  htsmsg_add_str(m, "id", idnode_uuid_as_str(&dte->dte_id));
+  htsmsg_add_str(m, "method", "timerecEntryDelete");
+  htsp_async_send(m, HTSP_ASYNC_ON, HTSP_ASYNC_AUX_TIMEREC, dte);
+}
+
 /**
  * Called when a event entry is updated/added
  */
index f6a0fd030093d5f1fdca06f4b239ccb6ac331ef3..9867e368e9ad91ea49235750e88b3770976d9621 100644 (file)
@@ -44,6 +44,10 @@ void htsp_autorec_entry_add(dvr_autorec_entry_t *dae);
 void htsp_autorec_entry_update(dvr_autorec_entry_t *dae);
 void htsp_autorec_entry_delete(dvr_autorec_entry_t *dae);
 
+void htsp_timerec_entry_add(dvr_timerec_entry_t *dte);
+void htsp_timerec_entry_update(dvr_timerec_entry_t *dte);
+void htsp_timerec_entry_delete(dvr_timerec_entry_t *dte);
+
 void htsp_event_add(epg_broadcast_t *ebc);
 void htsp_event_update(epg_broadcast_t *ebc);
 void htsp_event_delete(epg_broadcast_t *ebc);