Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement playcount and playposition
  • Loading branch information
Glenn-1990 authored and perexg committed Nov 24, 2016
1 parent c6aa155 commit 790b38c
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 19 deletions.
7 changes: 6 additions & 1 deletion src/dvr/dvr.h
Expand Up @@ -209,6 +209,8 @@ typedef struct dvr_entry {
uint32_t de_file_removed;
uint32_t de_retention;
uint32_t de_removal;
uint32_t de_playcount; /* Recording play count */
uint32_t de_playposition; /* Recording last played position in seconds */

/**
* EPG information / links
Expand Down Expand Up @@ -542,7 +544,8 @@ dvr_entry_update( dvr_entry_t *de, int enabled,
const char *desc, const char *lang,
time_t start, time_t stop,
time_t start_extra, time_t stop_extra,
dvr_prio_t pri, int retention, int removal );
dvr_prio_t pri, int retention, int removal,
int playcount, int playposition);

void dvr_destroy_by_channel(channel_t *ch, int delconf);

Expand Down Expand Up @@ -604,6 +607,8 @@ htsmsg_t *dvr_entry_class_removal_list ( void *o, const char *lang );

int dvr_entry_verify(dvr_entry_t *de, access_t *a, int readonly);

void dvr_entry_changed_notify(dvr_entry_t *de);

void dvr_spawn_cmd(dvr_entry_t *de, const char *cmd, const char *filename, int pre);

void dvr_vfs_refresh_entry(dvr_entry_t *de);
Expand Down
60 changes: 49 additions & 11 deletions src/dvr/dvr_db.c
Expand Up @@ -146,6 +146,16 @@ dvr_entry_verify(dvr_entry_t *de, access_t *a, int readonly)
return 0;
}

/*
*
*/
void
dvr_entry_changed_notify(dvr_entry_t *de)
{
idnode_changed(&de->de_id);
htsp_dvr_entry_update(de);
}

/*
*
*/
Expand Down Expand Up @@ -213,9 +223,7 @@ dvr_entry_dont_rerecord(dvr_entry_t *de, int dont_rerecord)
if (de->de_dont_rerecord ? 1 : 0 != dont_rerecord) {
dvr_entry_trace(de, "don't rerecord change %d", dont_rerecord);
de->de_dont_rerecord = dont_rerecord;
idnode_changed(&de->de_id);
idnode_notify_changed(&de->de_id);
htsp_dvr_entry_update(de);
dvr_entry_changed_notify(de);
}
}

Expand Down Expand Up @@ -1550,6 +1558,8 @@ dvr_timer_remove_files(void *aux)
#define DVR_UPDATED_BROADCAST (1<<15)
#define DVR_UPDATED_EPISODE (1<<16)
#define DVR_UPDATED_CONFIG (1<<17)
#define DVR_UPDATED_PLAYPOS (1<<18)
#define DVR_UPDATED_PLAYCOUNT (1<<19)

static char *dvr_updated_str(char *buf, size_t buflen, int flags)
{
Expand All @@ -1576,7 +1586,8 @@ static dvr_entry_t *_dvr_entry_update
const char *title, const char *subtitle, const char *desc,
const char *lang, time_t start, time_t stop,
time_t start_extra, time_t stop_extra,
dvr_prio_t pri, int retention, int removal )
dvr_prio_t pri, int retention, int removal,
int playcount, int playposition)
{
char buf[40];
int save = 0, updated = 0;
Expand Down Expand Up @@ -1608,6 +1619,16 @@ static dvr_entry_t *_dvr_entry_update
updated = 1;
dvr_entry_set_timer(de);
}
if (de->de_sched_state == DVR_RECORDING || de->de_sched_state == DVR_COMPLETED) {
if (playcount >= 0 && playcount != de->de_playcount) {
de->de_playcount = playcount;
save |= DVR_UPDATED_PLAYCOUNT;
}
if (playposition >= 0 && playposition != de->de_playposition) {
de->de_playposition = playposition;
save |= DVR_UPDATED_PLAYPOS;
}
}
goto dosave;
}

Expand Down Expand Up @@ -1721,8 +1742,7 @@ static dvr_entry_t *_dvr_entry_update
/* Save changes */
dosave:
if (save) {
idnode_changed(&de->de_id);
htsp_dvr_entry_update(de);
dvr_entry_changed_notify(de);
if (tvhlog_limit(&de->de_update_limit, 60)) {
tvhinfo(LS_DVR, "\"%s\" on \"%s\": Updated%s (%s)",
lang_str_get(de->de_title, NULL), DVR_CH_NAME(de),
Expand Down Expand Up @@ -1750,12 +1770,12 @@ dvr_entry_update
const char *desc, const char *lang,
time_t start, time_t stop,
time_t start_extra, time_t stop_extra,
dvr_prio_t pri, int retention, int removal )
dvr_prio_t pri, int retention, int removal, int playcount, int playposition )
{
return _dvr_entry_update(de, enabled, dvr_config_uuid,
NULL, ch, title, subtitle, desc, lang,
start, stop, start_extra, stop_extra,
pri, retention, removal);
pri, retention, removal, playcount, playposition);
}

/**
Expand Down Expand Up @@ -1809,7 +1829,7 @@ dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e)
gmtime2local(e2->start, t1buf, sizeof(t1buf)),
gmtime2local(e2->stop, t2buf, sizeof(t2buf)));
_dvr_entry_update(de, -1, NULL, e2, NULL, NULL, NULL, NULL, NULL,
0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0);
0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0, -1, -1);
return;
}
}
Expand Down Expand Up @@ -1851,7 +1871,7 @@ void dvr_event_updated(epg_broadcast_t *e)
if (de->de_bcast != e)
continue;
_dvr_entry_update(de, -1, NULL, e, NULL, NULL, NULL, NULL,
NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0);
NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0, -1, -1);
found++;
}
if (found == 0) {
Expand All @@ -1865,7 +1885,7 @@ void dvr_event_updated(epg_broadcast_t *e)
epg_broadcast_get_title(e, NULL),
channel_get_name(e->channel));
_dvr_entry_update(de, -1, NULL, e, NULL, NULL, NULL, NULL,
NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0);
NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0, -1, -1);
break;
}
}
Expand Down Expand Up @@ -3112,6 +3132,24 @@ const idclass_t dvr_entry_class = {
.list = dvr_entry_class_removal_list,
.opts = PO_HIDDEN | PO_ADVANCED | PO_DOC_NLIST,
},
{
.type = PT_U32,
.id = "playposition",
.name = N_("Last played position"),
.desc = N_("Last played position when the recording isn't fully watched yet."),
.off = offsetof(dvr_entry_t, de_playposition),
.def.i = 0,
.opts = PO_HIDDEN | PO_NOUI | PO_DOC_NLIST,
},
{
.type = PT_U32,
.id = "playcount",
.name = N_("Recording play count"),
.desc = N_("Number of times this recording was played."),
.off = offsetof(dvr_entry_t, de_playcount),
.def.i = 0,
.opts = PO_HIDDEN | PO_EXPERT | PO_DOC_NLIST,
},
{
.type = PT_STR,
.id = "config_name",
Expand Down
16 changes: 13 additions & 3 deletions src/htsp_server.c
Expand Up @@ -933,6 +933,11 @@ htsp_build_dvrentry(htsp_connection_t *htsp, dvr_entry_t *de, const char *method
htsmsg_add_u32(out, "priority", de->de_pri);
htsmsg_add_u32(out, "contentType", de->de_content_type);

if (de->de_sched_state == DVR_RECORDING || de->de_sched_state == DVR_COMPLETED) {
htsmsg_add_u32(out, "playcount", de->de_playcount);
htsmsg_add_u32(out, "playposition", de->de_playposition);
}

if(de->de_title && (s = lang_str_get(de->de_title, lang)))
htsmsg_add_str(out, "title", s);
if(de->de_subtitle && (s = lang_str_get(de->de_subtitle, lang)))
Expand Down Expand Up @@ -1915,10 +1920,10 @@ htsp_method_updateDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
htsmsg_t *out = NULL;
uint32_t u32;
dvr_entry_t *de;
time_t start, stop, start_extra, stop_extra, priority, retention, removal;
time_t start, stop, start_extra, stop_extra, priority;
const char *dvr_config_name, *title, *subtitle, *desc, *lang;
channel_t *channel = NULL;
int enabled;
int enabled, retention, removal, playcount = -1, playposition = -1;

de = htsp_findDvrEntry(htsp, in, &out, 0);
if (de == NULL)
Expand Down Expand Up @@ -1947,9 +1952,14 @@ htsp_method_updateDvrEntry(htsp_connection_t *htsp, htsmsg_t *in)
desc = htsmsg_get_str(in, "description");
lang = htsmsg_get_str(in, "language") ?: htsp->htsp_language;

if(!htsmsg_get_u32(in, "playcount", &u32))
playcount = u32 > INT_MAX ? INT_MAX : u32;
if(!htsmsg_get_u32(in, "playposition", &u32))
playposition = u32 > INT_MAX ? INT_MAX : u32;

de = dvr_entry_update(de, enabled, dvr_config_name, channel, title, subtitle,
desc, lang, start, stop, start_extra, stop_extra,
priority, retention, removal);
priority, retention, removal, playcount, playposition);

return htsp_success();
}
Expand Down
8 changes: 4 additions & 4 deletions src/webui/static/app/dvr.js
Expand Up @@ -454,11 +454,11 @@ tvheadend.dvr_finished = function(panel, index) {
titleP: _('Finished Recordings'),
iconCls: 'finishedRec',
tabIndex: index,
edit: { params: { list: tvheadend.admin ? "retention,removal,owner,comment" : "retention,removal,comment" } },
edit: { params: { list: tvheadend.admin ? "playcount,retention,removal,owner,comment" : "retention,removal,comment" } },
del: false,
list: 'disp_title,disp_subtitle,episode,channelname,' +
'start_real,stop_real,duration,filesize,' +
'sched_status,errors,data_errors,url,config_name,owner,creator,comment',
'sched_status,errors,data_errors,playcount,url,config_name,owner,creator,comment',
columns: {
filesize: {
renderer: tvheadend.filesizeRenderer()
Expand Down Expand Up @@ -589,13 +589,13 @@ tvheadend.dvr_failed = function(panel, index) {
titleP: _('Failed Recordings'),
iconCls: 'exclamation',
tabIndex: index,
edit: { params: { list: tvheadend.admin ? "retention,removal,owner,comment" : "retention,removal,comment" } },
edit: { params: { list: tvheadend.admin ? "playcount,retention,removal,owner,comment" : "retention,removal,comment" } },
del: true,
delquestion: _('Do you really want to delete the selected recordings?') + '<br/><br/>' +
_('The associated file will be removed from storage.'),
list: 'disp_title,disp_subtitle,episode,channelname,' +
'start_real,stop_real,duration,filesize,status,' +
'sched_status,errors,data_errors,url,config_name,owner,creator,comment',
'sched_status,errors,data_errors,playcount,url,config_name,owner,creator,comment',
columns: {
filesize: {
renderer: tvheadend.filesizeRenderer()
Expand Down
6 changes: 6 additions & 0 deletions src/webui/webui.c
Expand Up @@ -1523,6 +1523,12 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
return HTTP_STATUS_UNAUTHORIZED;
}

/* Play count + 1 when write access */
if (!dvr_entry_verify(de, hc->hc_access, 0)) {
de->de_playcount = de->de_playcount + 1;
dvr_entry_changed_notify(de);
}

fname = tvh_strdupa(filename);
content = muxer_container_filename2mime(fname, 1);
charset = de->de_config ? de->de_config->dvr_charset_id : NULL;
Expand Down

0 comments on commit 790b38c

Please sign in to comment.