general config stuff has now been removed and a new timeshift tab has been created
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 )
return 0;
}
+#if 0
static int _config_set_u32 ( const char *fld, uint32_t val )
{
uint32_t u32;
}
return 0;
}
+#endif
const char *config_get_language ( void )
{
{
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);
-}
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__ */
#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
/*
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", ×hift_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);
+ }
}
/*
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
*/
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);
#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);
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,
/*
* 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);
}
/*
#include "lang_codes.h"
#include "subscriptions.h"
#include "imagecache.h"
+#include "timeshift.h"
/**
*
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");
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
*/
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();
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
* ***************************************************************/
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();
}
});
--- /dev/null
+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;
+}
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();
}