]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
timeshift: reworked the configuration
authorAdam Sutton <dev@adamsutton.me.uk>
Fri, 21 Dec 2012 21:43:29 +0000 (21:43 +0000)
committerAdam Sutton <dev@adamsutton.me.uk>
Wed, 9 Jan 2013 21:26:52 +0000 (21:26 +0000)
general config stuff has now been removed and a new timeshift tab has been created

src/config2.c
src/config2.h
src/htsp_server.c
src/timeshift.c
src/timeshift.h
src/timeshift/private.h
src/timeshift/timeshift_filemgr.c
src/webui/extjs.c
src/webui/static/app/config.js
src/webui/static/app/timeshift.js [new file with mode: 0644]
src/webui/static/app/tvheadend.js

index 05bb7a3407403cfc22da8d069a8ef11c81e86d87..cfeeb12706a115cbc9e7b4b0d1e63f7e97c9cf68 100644 (file)
@@ -26,24 +26,11 @@ static htsmsg_t *config;
 
 void config_init ( void )
 {
-  int save = 0;
-  uint32_t u32;
-
   config = hts_settings_load("config");
   if (!config) {
     tvhlog(LOG_DEBUG, "config", "no configuration, loading defaults");
     config = htsmsg_create_map();
   }
-
-  /* Defaults */
-  if (htsmsg_get_u32(config, "timeshiftperiod", &u32))
-    save |= config_set_timeshift_period(0);
-  if (htsmsg_get_u32(config, "timeshiftsize", &u32))
-    save |= config_set_timeshift_size(0);
-
-  /* Save defaults */
-  if (save)
-    config_save();
 }
 
 void config_save ( void )
@@ -67,6 +54,7 @@ static int _config_set_str ( const char *fld, const char *val )
   return 0;
 }
 
+#if 0
 static int _config_set_u32 ( const char *fld, uint32_t val )
 {
   uint32_t u32;
@@ -78,6 +66,7 @@ static int _config_set_u32 ( const char *fld, uint32_t val )
   }
   return 0;
 }
+#endif
 
 const char *config_get_language ( void )
 {
@@ -98,33 +87,3 @@ int config_set_muxconfpath ( const char *path )
 {
   return _config_set_str("muxconfpath", path);
 }
-
-const char *config_get_timeshift_path ( void )
-{
-  return htsmsg_get_str(config, "timeshiftpath");
-}
-
-int config_set_timeshift_path ( const char *path )
-{
-  return _config_set_str("timeshiftpath", path);
-}
-
-uint32_t config_get_timeshift_period ( void )
-{
-  return htsmsg_get_u32_or_default(config, "timeshiftperiod", 0);
-}
-
-int config_set_timeshift_period ( uint32_t period )
-{
-  return _config_set_u32("timeshiftperiod", period);
-}
-
-uint32_t config_get_timeshift_size ( void )
-{
-  return htsmsg_get_u32_or_default(config, "timeshiftsize", 0);
-}
-
-int config_set_timeshift_size ( uint32_t size )
-{
-  return _config_set_u32("timeshiftsize", size);
-}
index 7ba28e0a30d9c5dcee0b13c0604dec90aec5c13b..cd68e30621de19e679970fe49ed61f49708c6e60 100644 (file)
@@ -36,16 +36,4 @@ const char *config_get_language    ( void );
 int         config_set_language    ( const char *str )
   __attribute__((warn_unused_result));
 
-const char *config_get_timeshift_path ( void );
-int         config_set_timeshift_path ( const char *str )
-  __attribute__((warn_unused_result));
-
-uint32_t    config_get_timeshift_period ( void );
-int         config_set_timeshift_period ( uint32_t val )
-  __attribute__((warn_unused_result));
-
-uint32_t    config_get_timeshift_size ( void );
-int         config_set_timeshift_size ( uint32_t val )
-  __attribute__((warn_unused_result));
-
 #endif /* __TVH_CONFIG__H__ */
index 0c1db9b1fce1505f81b45090c2f7d52189ad5fa6..77556d6eea4bde08f419c237fb7333c14bd5e256 100644 (file)
@@ -1264,7 +1264,8 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in)
 
 #if ENABLE_TIMESHIFT
   timeshiftPeriod = htsmsg_get_u32_or_default(in, "timeshiftPeriod", 0);
-  timeshiftPeriod = MIN(timeshiftPeriod, config_get_timeshift_period());
+  if (!timeshift_unlimited_period)
+    timeshiftPeriod = MIN(timeshiftPeriod, timeshift_max_period);
 #endif
 
   /*
index 2114442e8a3c8c0e037030abb5649b8d0e1ee580..14cee0d1d6c391e6f337e83307fcb67f6a4076a2 100644 (file)
 
 static int timeshift_index = 0;
 
+int       timeshift_enabled;
+int       timeshift_ondemand;
+char     *timeshift_path;
+int       timeshift_unlimited_period;
+uint32_t  timeshift_max_period;
+int       timeshift_unlimited_size;
+size_t    timeshift_max_size;
+
 /*
  * Intialise global file manager
  */
 void timeshift_init ( void )
 {
+  htsmsg_t *m;
+  const char *str;
+  uint32_t u32;
+
   timeshift_filemgr_init();
+
+  /* Defaults */
+  timeshift_enabled          = 0;                       // Disabled
+  timeshift_ondemand         = 0;                       // Permanent
+  timeshift_path             = NULL;                    // setting dir
+  timeshift_unlimited_period = 0;
+  timeshift_max_period       = 3600;                    // 1Hr
+  timeshift_unlimited_size   = 0;
+  timeshift_max_size         = 10000 * (size_t)1048576; // 10G
+
+  /* Load settings */
+  if ((m = hts_settings_load("timeshift/config"))) {
+    if (!htsmsg_get_u32(m, "enabled", &u32))
+      timeshift_enabled = u32 ? 1 : 0;
+    if (!htsmsg_get_u32(m, "ondemand", &u32))
+      timeshift_ondemand = u32 ? 1 : 0;
+    if ((str = htsmsg_get_str(m, "path")))
+      timeshift_path = strdup(str);
+    if (!htsmsg_get_u32(m, "unlimited_period", &u32))
+      timeshift_unlimited_period = u32 ? 1 : 0;
+    htsmsg_get_u32(m, "max_period", &timeshift_max_period);
+    if (!htsmsg_get_u32(m, "unlimited_size", &u32))
+      timeshift_unlimited_size = u32 ? 1 : 0;
+    if (!htsmsg_get_u32(m, "max_size", &u32))
+      timeshift_max_size = 1048576LL * u32;
+    htsmsg_destroy(m);
+  }
 }
 
 /*
@@ -50,6 +89,26 @@ void timeshift_term ( void )
   timeshift_filemgr_term();
 }
 
+/*
+ * Save settings
+ */
+void timeshift_save ( void )
+{
+  htsmsg_t *m;
+
+  m = htsmsg_create_map();
+  htsmsg_add_u32(m, "enabled", timeshift_enabled);
+  htsmsg_add_u32(m, "ondemand", timeshift_ondemand);
+  if (timeshift_path)
+    htsmsg_add_str(m, "path", timeshift_path);
+  htsmsg_add_u32(m, "unlimited_period", timeshift_unlimited_period);
+  htsmsg_add_u32(m, "max_period", timeshift_max_period);
+  htsmsg_add_u32(m, "unlimited_size", timeshift_unlimited_size);
+  htsmsg_add_u32(m, "max_size", timeshift_max_size / 1048576);
+
+  hts_settings_save(m, "timeshift/config");
+}
+
 /*
  * Receive data
  */
@@ -169,6 +228,7 @@ streaming_target_t *timeshift_create
   ts->full       = 0;
   ts->vididx     = -1;
   ts->id         = timeshift_index;
+  ts->ondemand   = timeshift_ondemand;
   pthread_mutex_init(&ts->rdwr_mutex, NULL);
   pthread_mutex_init(&ts->state_mutex, NULL);
 
index 69574bc5c4e579e6d898a35262e060ea2524304e..eeb6baadc56878526a26921d43e8e11f7b4ee553 100644 (file)
 #ifndef __TVH_TIMESHIFT_H__
 #define __TVH_TIMESHIFT_H__
 
+extern int       timeshift_enabled;
+extern int       timeshift_ondemand;
+extern char     *timeshift_path;
+extern int       timeshift_unlimited_period;
+extern uint32_t  timeshift_max_period;
+extern int       timeshift_unlimited_size;
+extern size_t    timeshift_max_size;
+
 void timeshift_init ( void );
 void timeshift_term ( void );
+void timeshift_save ( void );
 
 streaming_target_t *timeshift_create
   (streaming_target_t *out, time_t max_period);
index 11b53bac82a05c9a49b6079d20797c6b81d745d6..133eb6954c90b4ecbe3118ede8159c59acfbd89c 100644 (file)
@@ -80,6 +80,7 @@ typedef struct timeshift {
   int                         id;         ///< Reference number
   char                        *path;      ///< Directory containing buffer
   time_t                      max_time;   ///< Maximum period to shift
+  int                         ondemand;   ///< Whether this is an on-demand timeshift
 
   enum {
     TS_INIT,
index 01c2dd1501c59c32a6ffea49473c6af07f5ff346..3562393f4c61ac3283f179e7f10e54a1770c840d 100644 (file)
@@ -111,13 +111,15 @@ static void timeshift_reaper_remove ( timeshift_file_t *tsf )
 
 /*
  * Get root directory
+ *
+ * TODO: should this be fixed on startup?
  */
 static void timeshift_filemgr_get_root ( char *buf, size_t len )
 {
-  const char *path = config_get_timeshift_path();
+  const char *path = timeshift_path;
   if (!path || !*path)
     path = hts_settings_get_root();
-  snprintf(buf, len, "%s/timeshift", path);
+  snprintf(buf, len, "%s/timeshift/temp", path);
 }
 
 /*
index f68dff875977dc3e330e2225dc3c86f582eb5aab..2b6fff4555ba4d18681ef26bcf6a7f90ec01c402 100644 (file)
@@ -48,6 +48,7 @@
 #include "lang_codes.h"
 #include "subscriptions.h"
 #include "imagecache.h"
+#include "timeshift.h"
 
 /**
  *
@@ -130,6 +131,9 @@ extjs_root(http_connection_t *hc, const char *remain, void *opaque)
   extjs_load(hq, "static/app/iptv.js");
 #if ENABLE_V4L
   extjs_load(hq, "static/app/v4l.js");
+#endif
+#if ENABLE_TIMESHIFT
+  extjs_load(hq, "static/app/timeshift.js");
 #endif
   extjs_load(hq, "static/app/chconf.js");
   extjs_load(hq, "static/app/epg.js");
@@ -2034,6 +2038,79 @@ extjs_capabilities(http_connection_t *hc, const char *remain, void *opaque)
   return 0;
 }
 
+/**
+ *
+ */
+#if ENABLE_TIMESHIFT
+static int
+extjs_timeshift(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, *m;
+  const char *str;
+
+  if(op == NULL)
+    return 400;
+
+  pthread_mutex_lock(&global_lock);
+
+  if(http_access_verify(hc, ACCESS_ADMIN)) {
+    pthread_mutex_unlock(&global_lock);
+    return HTTP_STATUS_UNAUTHORIZED;
+  }
+
+  pthread_mutex_unlock(&global_lock);
+
+  /* Basic settings (not the advanced schedule) */
+  if(!strcmp(op, "loadSettings")) {
+    pthread_mutex_lock(&global_lock);
+    m = htsmsg_create_map();
+    htsmsg_add_u32(m, "timeshift_enabled",  timeshift_enabled);
+    htsmsg_add_u32(m, "timeshift_ondemand", timeshift_ondemand);
+    if (timeshift_path)
+      htsmsg_add_str(m, "timeshift_path", timeshift_path);
+    htsmsg_add_u32(m, "timeshift_unlimited_period", timeshift_unlimited_period);
+    htsmsg_add_u32(m, "timeshift_max_period", timeshift_max_period);
+    htsmsg_add_u32(m, "timeshift_unlimited_size", timeshift_unlimited_size);
+    htsmsg_add_u32(m, "timeshift_max_size", timeshift_max_size / 1048576);
+    pthread_mutex_unlock(&global_lock);
+    out = json_single_record(m, "config");
+
+  /* Save settings */
+  } else if (!strcmp(op, "saveSettings") ) {
+    pthread_mutex_lock(&global_lock);
+    timeshift_enabled  = http_arg_get(&hc->hc_req_args, "timeshift_enabled")  ? 1 : 0;
+    timeshift_ondemand = http_arg_get(&hc->hc_req_args, "timeshift_ondemand") ? 1 : 0;
+    if ((str = http_arg_get(&hc->hc_req_args, "timeshift_path"))) {
+      if (timeshift_path)
+        free(timeshift_path);
+      timeshift_path = strdup(str);
+    }
+    timeshift_unlimited_period = http_arg_get(&hc->hc_req_args, "timeshift_unlimited_period") ? 1 : 0;
+    if ((str = http_arg_get(&hc->hc_req_args, "timeshift_max_period")))
+      timeshift_max_period = (uint32_t)atol(str);
+    timeshift_unlimited_size = http_arg_get(&hc->hc_req_args, "timeshift_unlimited_size") ? 1 : 0;
+    if ((str = http_arg_get(&hc->hc_req_args, "timeshift_max_size")))
+      timeshift_max_size   = atol(str) * 1048576LL;
+    timeshift_save();
+    pthread_mutex_unlock(&global_lock);
+
+    out = htsmsg_create_map();
+    htsmsg_add_u32(out, "success", 1);
+
+  } else {
+    return HTTP_STATUS_BAD_REQUEST;
+  }
+
+  htsmsg_json_serialize(out, hq, 0);
+  htsmsg_destroy(out);
+  http_output_content(hc, "text/x-json; charset=UTF-8");
+
+  return 0;
+}
+#endif
+
 /**
  * WEB user interface
  */
@@ -2064,6 +2141,9 @@ extjs_start(void)
   http_path_add("/iptv/services",    NULL, extjs_iptvservices,     ACCESS_ADMIN);
   http_path_add("/servicedetails",   NULL, extjs_servicedetails,   ACCESS_ADMIN);
   http_path_add("/tv/adapter",       NULL, extjs_tvadapter,        ACCESS_ADMIN);
+#if ENABLE_TIMESHIFT
+  http_path_add("/timeshift",        NULL, extjs_timeshift,        ACCESS_ADMIN);
+#endif
 
 #if ENABLE_LINUXDVB
   extjs_start_dvb();
index a7e4d968e5d772f7b51bd8a4cba2d72c3fe637d3..b71a4a5d4232de21c19a6582328cb77995e98103 100644 (file)
@@ -103,49 +103,6 @@ tvheadend.miscconf = function() {
   if (tvheadend.capabilities.indexOf('imagecache') == -1)
     imagecachePanel.hide();
 
-       /* ****************************************************************
-        * Timeshift
-        * ***************************************************************/
-
-       var timeshiftPath = new Ext.form.TextField({
-               fieldLabel  : 'Temp. storage path',
-               name        : 'timeshiftpath',
-               allowBlank  : true,
-               width       : 400
-       });
-
-       var timeshiftPeriod = new Ext.form.NumberField({
-               fieldLabel  : 'Max period (minutes, per stream)',
-               name        : 'timeshiftperiod',
-               allowBlank  : false,
-               width       : 400
-       });
-
-       var timeshiftPeriodU = new Ext.form.Checkbox({
-               fieldLabel  : '(unlimited)',
-               name        : 'timeshiftperiod_unlimited',
-               allowBlank  : false,
-               width       : 400
-       });
-       timeshiftPeriodU.on('check', function(e, c) {
-               timeshiftPeriod.setDisabled(c);
-       });
-
-       var timeshiftSize = new Ext.form.NumberField({
-               fieldLabel  : 'Max size (MB, global)',
-               name        : 'timeshiftsize',
-               allowBlank  : false,
-               width       : 400
-       });
-
-       var timeshiftFields = new Ext.form.FieldSet({
-               title       : 'Timeshift',
-               width       : 700,
-               autoHeight  : true,
-               collapsible : true,
-               items       : [ timeshiftPath, timeshiftPeriod, timeshiftPeriodU ]//, timeshiftSize ]
-       });
-
        /* ****************************************************************
         * Form
         * ***************************************************************/
@@ -192,14 +149,6 @@ tvheadend.miscconf = function() {
                                op : 'loadSettings'
                        },
                        success : function(form, action) {
-                               v = parseInt(timeshiftPeriod.getValue());
-                               if (v == 4294967295) {
-                                       timeshiftPeriodU.setValue(true);
-                                       timeshiftPeriod.setValue("");
-                                       timeshiftPeriod.setDisabled(true); // TODO: this isn't working
-                               } else {
-                                       timeshiftPeriod.setValue(v / 60);
-                               }
                                confpanel.enable();
                        }
                });
diff --git a/src/webui/static/app/timeshift.js b/src/webui/static/app/timeshift.js
new file mode 100644 (file)
index 0000000..7f27ba4
--- /dev/null
@@ -0,0 +1,152 @@
+tvheadend.timeshift = function() {
+
+  /* ****************************************************************
+   * Data
+   * ***************************************************************/
+
+  var confreader = new Ext.data.JsonReader(
+    {
+      root: 'config'
+    },
+    [
+      'timeshift_enabled', 'timeshift_ondemand',
+      'timeshift_path',
+      'timeshift_unlimited_period', 'timeshift_max_period',
+      'timeshift_unlimited_size', 'timeshift_max_size'
+    ]
+  );
+  
+  /* ****************************************************************
+   * Fields
+   * ***************************************************************/
+
+  var timeshiftEnabled = new Ext.form.Checkbox({
+    fieldLabel: 'Enabled',
+    name: 'timeshift_enabled',
+    width: 300
+  });
+
+  var timeshiftOndemand = new Ext.form.Checkbox({
+    fieldLabel: 'On-Demand',
+    name: 'timeshift_ondemand',
+    width: 300
+  });
+
+  var timeshiftPath = new Ext.form.TextField({
+    fieldLabel: 'Storage Path',
+    name: 'timeshift_path',
+    allowBlank: true,
+    width: 300
+  });
+
+  var timeshiftMaxPeriod = new Ext.form.NumberField({
+    fieldLabel: 'Max. Period (mins)',
+    name: 'timeshift_max_period',
+    allowBlank: false,
+    width: 300
+  });
+
+  var timeshiftUnlPeriod = new Ext.form.Checkbox({
+    fieldLabel: '  unlimited',
+    name: 'timeshift_unlimited_period',
+    Width: 300
+  });
+
+  var timeshiftMaxSize = new Ext.form.NumberField({
+    fieldLabel: 'Max. Size (MB)',
+    name: 'timeshift_max_size',
+    allowBlank: false,
+    width: 300
+  });
+
+  var timeshiftUnlSize = new Ext.form.Checkbox({
+    fieldLabel: '  unlimited',
+    name: 'timeshift_unlimited_size',
+    Width: 300
+  });
+
+  /* ****************************************************************
+   * Events
+   * ***************************************************************/
+
+  timeshiftUnlPeriod.on('check', function(e, c){
+    timeshiftMaxPeriod.setDisabled(c);
+  });
+  timeshiftUnlSize.on('check', function(e, c){
+    timeshiftMaxSize.setDisabled(c);
+  });
+
+  /* ****************************************************************
+   * Form
+   * ***************************************************************/
+
+  var saveButton = new Ext.Button({
+    text : "Save configuration",
+    tooltip : 'Save changes made to configuration below',
+    iconCls : 'save',
+    handler : saveChanges
+  });
+
+  var helpButton = new Ext.Button({
+    text : 'Help',
+    handler : function() {
+      new tvheadend.help('Timeshift Configuration', 'config_timeshift.html');
+    }
+  });
+
+  var confpanel = new Ext.FormPanel({
+    title : 'Timeshift',
+    iconCls : 'clock',
+    border : false,
+    bodyStyle : 'padding:15px',
+    labelAlign : 'left',
+    labelWidth : 150,
+    waitMsgTarget : true,
+    reader : confreader,
+    layout : 'form',
+    defaultType : 'textfield',
+    autoHeight : true,
+    items : [
+      timeshiftEnabled, timeshiftOndemand,
+      timeshiftPath,
+      timeshiftMaxPeriod, timeshiftUnlPeriod,
+      timeshiftMaxSize, timeshiftUnlSize
+    ],
+    tbar : [ saveButton, '->', helpButton ]
+  });
+
+  /* ****************************************************************
+   * Load/Save
+   * ***************************************************************/
+
+  confpanel.on('render', function() {
+    confpanel.getForm().load({
+      url: 'timeshift',
+      params: {
+        'op': 'loadSettings'
+      },
+      success: function() {
+        confpanel.enable();
+        timeshiftMaxPeriod.setDisabled(timeshiftUnlPeriod.getValue());
+        timeshiftMaxSize.setDisabled(timeshiftUnlSize.getValue());
+      }
+    });
+  });
+
+  function saveChanges() {
+    confpanel.getForm().submit({
+      url : 'timeshift',
+      params : {
+        op : 'saveSettings',
+      },
+      waitMsg : 'Saving Data...',
+      success : function(form, action) {
+      },
+      failure : function(form, action) {
+        Ext.Msg.alert('Save failed', action.result.errormsg);
+      }
+    });
+  }
+
+  return confpanel;
+}
index d1754f498f73b645e59e8ef85c2457c678e7ef45..96bb66a3ff07002be38327d335b3f94cda865b18 100644 (file)
@@ -270,6 +270,9 @@ function accessUpdate(o) {
       tvheadend.confpanel.add(new tvheadend.cwceditor);
       tvheadend.confpanel.add(new tvheadend.capmteditor);
     }
+    if (tvheadend.capabilities.indexOf('timeshift') != -1) {
+      tvheadend.confpanel.add(new tvheadend.timeshift);
+    }
     tvheadend.confpanel.doLayout();
   }