Permalink
Browse files

Merge branch 'epg-repeats'

  • Loading branch information...
2 parents 579bbc9 + 1134b27 commit 5681bba43f0ecae5a97ef4c367f18e7165fe4af2 @sofakng committed Sep 5, 2012
Showing with 158 additions and 24 deletions.
  1. +10 −2 src/dvr/dvr.h
  2. +19 −4 src/dvr/dvr_autorec.c
  3. +17 −0 src/dvr/dvr_db.c
  4. +12 −9 src/epg.c
  5. +2 −2 src/epg.h
  6. +1 −1 src/htsp.c
  7. +19 −2 src/webui/extjs.c
  8. +1 −1 src/webui/simpleui.c
  9. +26 −1 src/webui/static/app/dvr.js
  10. +51 −2 src/webui/static/app/epg.js
View
@@ -74,6 +74,10 @@ typedef enum {
DVR_PRIO_UNIMPORTANT,
} dvr_prio_t;
+typedef enum {
+ DVR_REPEATS_ALLEPISODES,
+ DVR_REPEATS_NEWONLY
+} dvr_repeats_t;
LIST_HEAD(dvr_rec_stream_list, dvr_rec_stream);
@@ -219,6 +223,7 @@ typedef struct dvr_autorec_entry {
channel_tag_t *dae_channel_tag;
LIST_ENTRY(dvr_autorec_entry) dae_channel_tag_link;
+ dvr_repeats_t dae_repeats;
dvr_prio_t dae_pri;
struct dvr_entry_list dae_spawns;
@@ -336,7 +341,8 @@ void dvr_query_sort(dvr_query_result_t *dqr);
void dvr_autorec_add(const char *dvr_config_name,
const char *title, const char *channel,
const char *tag, epg_genre_t *content_type,
- const char *creator, const char *comment);
+ const char *creator, const char *comment,
+ dvr_repeats_t repeats);
void dvr_autorec_add_series_link(const char *dvr_config_name,
epg_broadcast_t *event,
@@ -354,8 +360,10 @@ dvr_autorec_entry_t *autorec_entry_find(const char *id, int create);
/**
*
*/
-dvr_prio_t dvr_pri2val(const char *s);
+dvr_repeats_t dvr_repeats2val(const char *s);
+const char *dvr_val2repeats(dvr_repeats_t v);
+dvr_prio_t dvr_pri2val(const char *s);
const char *dvr_val2pri(dvr_prio_t v);
#endif /* DVR_H */
View
@@ -139,6 +139,10 @@ autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e)
if(!((1 << ((tm.tm_wday ?: 7) - 1)) & dae->dae_weekdays))
return 0;
}
+
+ if ((dae->dae_repeats == DVR_REPEATS_NEWONLY) && (e->is_repeat))
+ return 0;
+
return 1;
}
@@ -280,6 +284,7 @@ autorec_record_build(dvr_autorec_entry_t *dae)
build_weekday_tags(str, sizeof(str), dae->dae_weekdays);
htsmsg_add_str(e, "weekdays", str);
+ htsmsg_add_str(e, "repeats", dvr_val2repeats(dae->dae_repeats));
htsmsg_add_str(e, "pri", dvr_val2pri(dae->dae_pri));
if (dae->dae_brand)
@@ -404,6 +409,9 @@ autorec_record_update(void *opaque, const char *id, htsmsg_t *values,
if(!htsmsg_get_u32(values, "enabled", &u32))
dae->dae_enabled = u32;
+ if((s = htsmsg_get_str(values, "repeats")) != NULL)
+ dae->dae_repeats = dvr_repeats2val(s);
+
if((s = htsmsg_get_str(values, "pri")) != NULL)
dae->dae_pri = dvr_pri2val(s);
@@ -469,7 +477,8 @@ _dvr_autorec_add(const char *config_name,
const char *tag, epg_genre_t *content_type,
epg_brand_t *brand, epg_season_t *season,
int approx_time, epg_episode_num_t *epnum,
- const char *creator, const char *comment)
+ const char *creator, const char *comment,
+ dvr_repeats_t repeats)
{
dvr_autorec_entry_t *dae;
htsmsg_t *m;
@@ -514,6 +523,8 @@ _dvr_autorec_add(const char *config_name,
dae->dae_epnum = *epnum;
}
+ dae->dae_repeats = repeats;
+
dae->dae_approx_time = approx_time;
m = autorec_record_build(dae);
@@ -533,12 +544,13 @@ void
dvr_autorec_add(const char *config_name,
const char *title, const char *channel,
const char *tag, epg_genre_t *content_type,
- const char *creator, const char *comment)
+ const char *creator, const char *comment,
+ dvr_repeats_t repeats)
{
channel_t *ch = NULL;
if(channel != NULL) ch = channel_find_by_name(channel, 0, 0);
_dvr_autorec_add(config_name, title, ch, tag, content_type,
- NULL, NULL, 0, NULL, creator, comment);
+ NULL, NULL, 0, NULL, creator, comment, repeats);
}
void dvr_autorec_add_series_link
@@ -562,13 +574,16 @@ void dvr_autorec_add_series_link
epg_episode_get_epnum(ee, &epnum);
epnump = &epnum;
}
+
+ dvr_repeats_t repeats = DVR_REPEATS_ALLEPISODES;
+
_dvr_autorec_add(dvr_config_name, NULL,/*TODO DVR lang_str event->episode->title,*/
cfg->dvr_sl_channel_lock ? event->channel : NULL,
NULL, 0, // tag/content type
cfg->dvr_sl_brand_lock ? ee->brand : NULL,
cfg->dvr_sl_season_lock || !ee->brand ? ee->season : NULL,
atime, epnump,
- creator, comment);
+ creator, comment, repeats);
}
View
@@ -1365,6 +1365,23 @@ dvr_get_filesize(dvr_entry_t *de)
/**
*
*/
+static struct strtab repeatstab[] = {
+ { "allepisodes", DVR_REPEATS_ALLEPISODES },
+ { "newonly", DVR_REPEATS_NEWONLY },
+};
+
+dvr_repeats_t
+dvr_repeats2val(const char *s)
+{
+ return str2val_def(s, repeatstab, DVR_REPEATS_ALLEPISODES);
+}
+
+const char *
+dvr_val2repeats(dvr_repeats_t v)
+{
+ return val2str(v, repeatstab) ?: "invalid";
+}
+
static struct strtab priotab[] = {
{ "important", DVR_PRIO_IMPORTANT },
{ "high", DVR_PRIO_HIGH },
View
@@ -1859,7 +1859,7 @@ htsmsg_t *epg_genres_list_all ( int major_only, int major_prefix )
static void _eqr_add
( epg_query_result_t *eqr, epg_broadcast_t *e,
- epg_genre_t *genre, regex_t *preg, time_t start, const char *lang )
+ epg_genre_t *genre, regex_t *preg, time_t start, const char *lang, int repeats )
{
const char *title;
@@ -1869,6 +1869,9 @@ static void _eqr_add
if ( genre && !epg_genre_list_contains(&e->episode->genre, genre, 1) ) return;
if ( preg && regexec(preg, title, 0, NULL, 0)) return;
+ /* Check Repeat Flag */
+ if ((repeats == 1) && (e->is_repeat)) return;
+
/* More space */
if ( eqr->eqr_entries == eqr->eqr_alloced ) {
eqr->eqr_alloced = MAX(100, eqr->eqr_alloced * 2);
@@ -1882,17 +1885,17 @@ static void _eqr_add
static void _eqr_add_channel
( epg_query_result_t *eqr, channel_t *ch, epg_genre_t *genre,
- regex_t *preg, time_t start, const char *lang )
+ regex_t *preg, time_t start, const char *lang, int repeats )
{
epg_broadcast_t *ebc;
RB_FOREACH(ebc, &ch->ch_epg_schedule, sched_link) {
- if ( ebc->episode ) _eqr_add(eqr, ebc, genre, preg, start, lang);
+ if ( ebc->episode ) _eqr_add(eqr, ebc, genre, preg, start, lang, repeats);
}
}
void epg_query0
( epg_query_result_t *eqr, channel_t *channel, channel_tag_t *tag,
- epg_genre_t *genre, const char *title, const char *lang )
+ epg_genre_t *genre, const char *title, const char *lang, int repeats )
{
time_t now;
channel_tag_mapping_t *ctm;
@@ -1913,19 +1916,19 @@ void epg_query0
/* Single channel */
if (channel && !tag) {
- _eqr_add_channel(eqr, channel, genre, preg, now, lang);
+ _eqr_add_channel(eqr, channel, genre, preg, now, lang, repeats);
/* Tag based */
} else if ( tag ) {
LIST_FOREACH(ctm, &tag->ct_ctms, ctm_tag_link) {
if(channel == NULL || ctm->ctm_channel == channel)
- _eqr_add_channel(eqr, ctm->ctm_channel, genre, preg, now, lang);
+ _eqr_add_channel(eqr, ctm->ctm_channel, genre, preg, now, lang, repeats);
}
/* All channels */
} else {
RB_FOREACH(channel, &channel_name_tree, ch_name_link) {
- _eqr_add_channel(eqr, channel, genre, preg, now, lang);
+ _eqr_add_channel(eqr, channel, genre, preg, now, lang, repeats);
}
}
if (preg) regfree(preg);
@@ -1934,11 +1937,11 @@ void epg_query0
}
void epg_query(epg_query_result_t *eqr, const char *channel, const char *tag,
- epg_genre_t *genre, const char *title, const char *lang)
+ epg_genre_t *genre, const char *title, const char *lang, int repeats)
{
channel_t *ch = channel ? channel_find_by_name(channel, 0, 0) : NULL;
channel_tag_t *ct = tag ? channel_tag_find_by_name(tag, 0) : NULL;
- epg_query0(eqr, ch, ct, genre, title, lang);
+ epg_query0(eqr, ch, ct, genre, title, lang, repeats);
}
void epg_query_free(epg_query_result_t *eqr)
View
@@ -473,9 +473,9 @@ void epg_query_sort(epg_query_result_t *eqr);
/* Query routines */
void epg_query0(epg_query_result_t *eqr, struct channel *ch,
struct channel_tag *ct, epg_genre_t *genre, const char *title,
- const char *lang);
+ const char *lang, int repeats);
void epg_query(epg_query_result_t *eqr, const char *channel, const char *tag,
- epg_genre_t *genre, const char *title, const char *lang);
+ epg_genre_t *genre, const char *title, const char *lang, int repeats);
/* ************************************************************************
View
@@ -724,7 +724,7 @@ htsp_method_epgQuery(htsp_connection_t *htsp, htsmsg_t *in)
}
//do the query
- epg_query0(&eqr, ch, ct, eg, query, NULL);
+ epg_query0(&eqr, ch, ct, eg, query, NULL, 0);
c = eqr.eqr_entries;
// create reply
View
@@ -717,6 +717,7 @@ extjs_epg(http_connection_t *hc, const char *remain, void *opaque)
epg_genre_t *eg = NULL, genre;
channel_t *ch;
int start = 0, end, limit, i;
+ int repeats;
const char *s;
char buf[100];
const char *channel = http_arg_get(&hc->hc_req_args, "channel");
@@ -740,12 +741,17 @@ extjs_epg(http_connection_t *hc, const char *remain, void *opaque)
eg = &genre;
}
+ if((s = http_arg_get(&hc->hc_req_args, "repeats")) != NULL)
+ repeats = dvr_repeats2val(s);
+ else
+ repeats = 0;
+
out = htsmsg_create_map();
array = htsmsg_create_list();
pthread_mutex_lock(&global_lock);
- epg_query(&eqr, channel, tag, eg, title, lang);
+ epg_query(&eqr, channel, tag, eg, title, lang, repeats);
epg_query_sort(&eqr);
@@ -795,6 +801,8 @@ extjs_epg(http_connection_t *hc, const char *remain, void *opaque)
if((de = dvr_entry_find_by_event(e)) != NULL)
htsmsg_add_str(m, "schedstate", dvr_entry_schedstatus(de));
+ htsmsg_add_u32(m, "repeat", e->is_repeat);
+
htsmsg_add_msg(array, NULL, m);
}
@@ -1076,12 +1084,21 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque)
eg = &genre;
}
+ const char *repeats = http_arg_get(&hc->hc_req_args, "repeats");
+ dvr_repeats_t repeats2;
+
+ if (repeats == NULL)
+ repeats2 = DVR_REPEATS_ALLEPISODES;
+ else
+ repeats2 = dvr_repeats2val(repeats);
+
dvr_autorec_add(http_arg_get(&hc->hc_req_args, "config_name"),
http_arg_get(&hc->hc_req_args, "title"),
http_arg_get(&hc->hc_req_args, "channel"),
http_arg_get(&hc->hc_req_args, "tag"),
eg,
- hc->hc_representative, "Created from EPG query");
+ hc->hc_representative, "Created from EPG query",
+ repeats2);
out = htsmsg_create_map();
htsmsg_add_u32(out, "success", 1);
@@ -87,7 +87,7 @@ page_simple(http_connection_t *hc,
if(s != NULL) {
- epg_query(&eqr, NULL, NULL, NULL, s, lang);
+ epg_query(&eqr, NULL, NULL, NULL, s, lang, 0);
epg_query_sort(&eqr);
c = eqr.eqr_entries;
@@ -13,6 +13,15 @@ tvheadend.weekdays = new Ext.data.SimpleStore({
]
});
+// Repeats
+tvheadend.dvrrepeats = new Ext.data.SimpleStore({
+ fields: ['identifier', 'name'],
+ id: 0,
+ data: [
+ ['allepisodes', 'All Episodes'],
+ ['newonly', 'New Episodes Only']
+ ]
+});
// This should be loaded from tvheadend
tvheadend.dvrprio = new Ext.data.SimpleStore({
@@ -27,6 +36,8 @@ tvheadend.dvrprio = new Ext.data.SimpleStore({
]
});
+
+
// For the container configuration
tvheadend.containers = new Ext.data.SimpleStore({
fields: ['identifier','name'],
@@ -541,6 +552,20 @@ tvheadend.autoreceditor = function() {
increment: 10,
format: 'H:i'
})
+ }, {
+ header: "Repeats",
+ dataIndex: 'repeats',
+ width: 100,
+ renderer: function(value, metadata, record, row, col, store) {
+ return tvheadend.dvrrepeats.getById(value).data.name;
+ },
+ editor: new fm.ComboBox({
+ store: tvheadend.dvrrepeats,
+ triggerAction: 'all',
+ mode: 'local',
+ valueField: 'identifier',
+ displayField: 'name'
+ })
}, {
header: "Priority",
dataIndex: 'pri',
@@ -650,7 +675,7 @@ tvheadend.dvr = function() {
tvheadend.autorecRecord = Ext.data.Record.create([
'enabled','title', 'brand', 'channel','tag','creator','contenttype','comment',
- 'weekdays', 'pri', 'approx_time', 'config_name'
+ 'weekdays', 'repeats', 'pri', 'approx_time', 'config_name'
]);
Oops, something went wrong.

0 comments on commit 5681bba

Please sign in to comment.