timeshift: reworked the configuration

general config stuff has now been removed and a new timeshift tab has been created
This commit is contained in:
Adam Sutton 2012-12-21 21:43:29 +00:00
parent 4b86d4210c
commit fa4841b725
11 changed files with 313 additions and 109 deletions

View 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);
}

View 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__ */

View 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
/*

View file

@ -34,12 +34,51 @@
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);

View file

@ -19,8 +19,17 @@
#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);

View 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,

View 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);
}
/*

View 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();

View 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();
}
});

View file

@ -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;
}

View 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();
}