timeshift: reworked the configuration
general config stuff has now been removed and a new timeshift tab has been created
This commit is contained in:
parent
4b86d4210c
commit
fa4841b725
11 changed files with 313 additions and 109 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
@ -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", ×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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
|
|
152
src/webui/static/app/timeshift.js
Normal file
152
src/webui/static/app/timeshift.js
Normal 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;
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue