Make it possible to download recorded events directly from the web ui.
This commit is contained in:
parent
74c7961651
commit
bbe35021b8
6 changed files with 103 additions and 2 deletions
|
@ -136,6 +136,8 @@ void dvr_rec_unsubscribe(dvr_entry_t *de);
|
|||
|
||||
dvr_entry_t *dvr_entry_find_by_id(int id);
|
||||
|
||||
off_t dvr_get_filesize(dvr_entry_t *de);
|
||||
|
||||
void dvr_entry_cancel(dvr_entry_t *de);
|
||||
|
||||
void dvr_entry_dec_ref(dvr_entry_t *de);
|
||||
|
|
17
dvr/dvr_db.c
17
dvr/dvr_db.c
|
@ -660,3 +660,20 @@ dvr_query_sort(dvr_query_result_t *dqr)
|
|||
qsort(dqr->dqr_array, dqr->dqr_entries, sizeof(dvr_entry_t *), sf);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
off_t
|
||||
dvr_get_filesize(dvr_entry_t *de)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if(de->de_filename == NULL)
|
||||
return 0;
|
||||
|
||||
if(stat(de->de_filename, &st) != 0)
|
||||
return 0;
|
||||
|
||||
return st.st_size;
|
||||
}
|
||||
|
|
7
http.c
7
http.c
|
@ -69,8 +69,11 @@ http_resolve(http_connection_t *hc, char **remainp, char **argsp)
|
|||
http_path_t *hp;
|
||||
char *v;
|
||||
LIST_FOREACH(hp, &http_paths, hp_link) {
|
||||
if(!strncmp(hc->hc_url, hp->hp_path, hp->hp_len))
|
||||
break;
|
||||
if(!strncmp(hc->hc_url, hp->hp_path, hp->hp_len)) {
|
||||
if(hc->hc_url[hp->hp_len] == 0 || hc->hc_url[hp->hp_len] == '/' ||
|
||||
hc->hc_url[hp->hp_len] == '?')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(hp == NULL)
|
||||
|
|
|
@ -1037,6 +1037,7 @@ extjs_dvrlist(http_connection_t *hc, const char *remain, void *opaque)
|
|||
dvr_entry_t *de;
|
||||
int start = 0, end, limit, i;
|
||||
const char *s, *t = NULL;
|
||||
off_t fsize;
|
||||
|
||||
if((s = http_arg_get(&hc->hc_req_args, "start")) != NULL)
|
||||
start = atoi(s);
|
||||
|
@ -1105,6 +1106,18 @@ extjs_dvrlist(http_connection_t *hc, const char *remain, void *opaque)
|
|||
if(t != NULL) htsmsg_add_str(m, "schedstate", t);
|
||||
|
||||
|
||||
if(de->de_sched_state == DVR_COMPLETED) {
|
||||
fsize = dvr_get_filesize(de);
|
||||
if(fsize > 0) {
|
||||
char url[100];
|
||||
htsmsg_add_u64(m, "filesize", fsize);
|
||||
|
||||
snprintf(url, sizeof(url), "/dvrfile/%d", de->de_id);
|
||||
htsmsg_add_str(m, "url", url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
htsmsg_add_msg(array, NULL, m);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ tvheadend.dvrStore = new Ext.data.JsonStore({
|
|||
{name: 'schedstate'},
|
||||
{name: 'creator'},
|
||||
{name: 'duration'},
|
||||
{name: 'filesize'},
|
||||
{name: 'url'},
|
||||
],
|
||||
url: 'dvrlist',
|
||||
autoLoad: true,
|
||||
|
@ -38,6 +40,11 @@ tvheadend.dvrDetails = function(entry) {
|
|||
content += '<hr>'
|
||||
content += '<div class="x-epg-meta">Status: ' + entry.status + '</div>';
|
||||
|
||||
if(entry.url != null && entry.filesize > 0) {
|
||||
content += '<div class="x-epg-meta">' +
|
||||
'<a href="' + entry.url + '" target="_blank">Download</a> '+
|
||||
parseInt(entry.filesize/1000000) + ' MB</div>';
|
||||
}
|
||||
|
||||
var win = new Ext.Window({
|
||||
title: entry.title,
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "access.h"
|
||||
#include "http.h"
|
||||
#include "webui.h"
|
||||
#include "dvr/dvr.h"
|
||||
|
||||
static int
|
||||
is_client_simple(http_connection_t *hc)
|
||||
|
@ -106,6 +107,63 @@ page_static(http_connection_t *hc, const char *remain, void *opaque)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Download a recorded file
|
||||
*/
|
||||
static int
|
||||
page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
|
||||
{
|
||||
int fd;
|
||||
struct stat st;
|
||||
const char *content = NULL, *postfix, *range;
|
||||
dvr_entry_t *de;
|
||||
char *fname;
|
||||
|
||||
if(remain == NULL)
|
||||
return 404;
|
||||
|
||||
pthread_mutex_lock(&global_lock);
|
||||
de = dvr_entry_find_by_id(atoi(remain));
|
||||
if(de == NULL || de->de_filename == NULL) {
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
return 404;
|
||||
}
|
||||
|
||||
fname = strdup(de->de_filename);
|
||||
pthread_mutex_unlock(&global_lock);
|
||||
|
||||
postfix = strrchr(remain, '.');
|
||||
if(postfix != NULL) {
|
||||
postfix++;
|
||||
if(!strcmp(postfix, "mkv"))
|
||||
content = "video/x-matroska";
|
||||
}
|
||||
|
||||
fd = open(fname, O_RDONLY);
|
||||
free(fname);
|
||||
if(fd < 0)
|
||||
return 404;
|
||||
|
||||
if(fstat(fd, &st) < 0) {
|
||||
close(fd);
|
||||
return 404;
|
||||
}
|
||||
|
||||
|
||||
range = http_arg_get(&hc->hc_args, "Range");
|
||||
#if 0
|
||||
if(range != NULL) {
|
||||
printf("Range req: %s\n", range);
|
||||
}
|
||||
#endif
|
||||
|
||||
http_send_header(hc, 200, content, st.st_size, NULL, NULL, 10);
|
||||
sendfile(hc->hc_fd, fd, NULL, st.st_size);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* WEB user interface
|
||||
*/
|
||||
|
@ -115,6 +173,7 @@ webui_init(void)
|
|||
http_path_add("/", NULL, page_root, ACCESS_WEB_INTERFACE);
|
||||
|
||||
http_path_add("/static", NULL, page_static, ACCESS_WEB_INTERFACE);
|
||||
http_path_add("/dvrfile", NULL, page_dvrfile, ACCESS_WEB_INTERFACE);
|
||||
|
||||
// simpleui_start();
|
||||
extjs_start();
|
||||
|
|
Loading…
Add table
Reference in a new issue