Make it possible to download recorded events directly from the web ui.

This commit is contained in:
Andreas Öman 2008-09-24 21:30:08 +00:00
parent 74c7961651
commit bbe35021b8
6 changed files with 103 additions and 2 deletions

View file

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

View file

@ -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
View file

@ -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)

View file

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

View file

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

View file

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