Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 4 commits
  • 13 files changed
  • 0 commit comments
  • 1 contributor
Showing with 181 additions and 32 deletions.
  1. +1 −0 src/dvb/dvb.h
  2. +17 −8 src/dvb/dvb_fe.c
  3. +5 −0 src/dvb/dvb_satconf.c
  4. +10 −2 src/dvr/dvr.h
  5. +19 −4 src/dvr/dvr_autorec.c
  6. +17 −0 src/dvr/dvr_db.c
  7. +12 −9 src/epg.c
  8. +2 −2 src/epg.h
  9. +1 −1 src/htsp.c
  10. +19 −2 src/webui/extjs.c
  11. +1 −1 src/webui/simpleui.c
  12. +26 −1 src/webui/static/app/dvr.js
  13. +51 −2 src/webui/static/app/epg.js
View
1 src/dvb/dvb.h
@@ -24,6 +24,7 @@
#include <pthread.h>
#include "htsmsg.h"
+#define BANDSTACKED_NA_LNB 1
#define DVB_VER_INT(maj,min) (((maj) << 16) + (min))
View
25 src/dvb/dvb_fe.c
@@ -466,20 +466,29 @@ dvb_fe_tune(th_dvb_mux_instance_t *tdmi, const char *reason)
dvb_lnb_get_frequencies(sc->sc_lnb, &lowfreq, &hifreq, &switchfreq);
}
- hiband = switchfreq && p->frequency > switchfreq;
-
- pol = tdmi->tdmi_conf.dmc_polarisation;
+ if (switchfreq == BANDSTACKED_NA_LNB) {
+ hiband = 0;
+ if(tdmi->tdmi_conf.dmc_polarisation == POLARISATION_HORIZONTAL ||
+ tdmi->tdmi_conf.dmc_polarisation == POLARISATION_CIRCULAR_LEFT)
+ p->frequency = abs(p->frequency - hifreq);
+ else
+ p->frequency = abs(p->frequency - lowfreq);
+ pol = POLARISATION_CIRCULAR_LEFT;
+ } else {
+ hiband = switchfreq && p->frequency > switchfreq;
+ pol = tdmi->tdmi_conf.dmc_polarisation;
+ if(hiband)
+ p->frequency = abs(p->frequency - hifreq);
+ else
+ p->frequency = abs(p->frequency - lowfreq);
+ }
+
if ((r = diseqc_setup(tda->tda_fe_fd,
port,
pol == POLARISATION_HORIZONTAL ||
pol == POLARISATION_CIRCULAR_LEFT,
hiband, tda->tda_diseqc_version)) != 0)
tvhlog(LOG_ERR, "dvb", "diseqc setup failed %d\n", r);
-
- if(hiband)
- p->frequency = abs(p->frequency - hifreq);
- else
- p->frequency = abs(p->frequency - lowfreq);
}
dvb_mux_nicename(buf, sizeof(buf), tdmi);
View
5 src/dvb/dvb_satconf.c
@@ -290,6 +290,7 @@ dvb_lnblist_get(void)
add_to_lnblist(array, "Universal");
add_to_lnblist(array, "DBS");
+ add_to_lnblist(array, "DBS Bandstacked");
add_to_lnblist(array, "Standard");
add_to_lnblist(array, "Enhanced");
add_to_lnblist(array, "C-Band");
@@ -313,6 +314,10 @@ dvb_lnb_get_frequencies(const char *id, int *f_low, int *f_hi, int *f_switch)
*f_low = 11250000;
*f_hi = 0;
*f_switch = 0;
+ } else if(!strcmp(id, "DBS Bandstacked")) {
+ *f_low = 11250000;
+ *f_hi = 14350000;
+ *f_switch = BANDSTACKED_NA_LNB; /* special case for Bandstacked LNB */
} else if(!strcmp(id, "Standard")) {
*f_low = 10000000;
*f_hi = 0;
View
12 src/dvr/dvr.h
@@ -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
23 src/dvr/dvr_autorec.c
@@ -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
17 src/dvr/dvr_db.c
@@ -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
21 src/epg.c
@@ -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
4 src/epg.h
@@ -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
2 src/htsp.c
@@ -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
21 src/webui/extjs.c
@@ -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);
View
2 src/webui/simpleui.c
@@ -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;
View
27 src/webui/static/app/dvr.js
@@ -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'
]);
View
53 src/webui/static/app/epg.js
@@ -14,6 +14,16 @@ tvheadend.ContentGroupStore = new Ext.data.JsonStore({
url:'ecglist'
});
+// Repeats
+tvheadend.dvrrepeats = new Ext.data.SimpleStore({
+ fields: ['identifier', 'name'],
+ id: 0,
+ data: [
+ ['allepisodes', 'All Episodes'],
+ ['newonly', 'New Episodes Only']
+ ]
+});
+
tvheadend.contentGroupLookupName = function(code)
{
ret = "";
@@ -219,7 +229,8 @@ tvheadend.epg = function() {
{name: 'end', type: 'date', dateFormat: 'U' /* unix time */},
{name: 'duration'},
{name: 'contenttype'},
- {name: 'schedstate'}
+ {name: 'schedstate'},
+ {name: 'repeat'},
])
});
@@ -263,6 +274,12 @@ tvheadend.epg = function() {
return value;
}
+ function renderRepeat(value, meta, record, rowIndex, colIndex, store){
+ setMetaAttr(meta, record);
+
+ return value ? 'Repeat' : 'New';
+ }
+
var epgCm = new Ext.grid.ColumnModel([
actions,
{
@@ -316,6 +333,12 @@ tvheadend.epg = function() {
renderer: function(v) {
return tvheadend.contentGroupLookupName(v);
}
+ },{
+ width: 50,
+ id:'repeat',
+ header: "Repeat",
+ dataIndex: 'repeat',
+ renderer: renderRepeat
}
]);
@@ -355,7 +378,6 @@ tvheadend.epg = function() {
// Content groups
-
var epgFilterContentGroup = new Ext.form.ComboBox({
loadingText: 'Loading...',
width: 200,
@@ -367,17 +389,31 @@ tvheadend.epg = function() {
emptyText: 'Only include content...'
});
+ // Repeat status
+
+ var epgFilterRepeats = new Ext.form.ComboBox({
+ loadingText: 'Loading...',
+ width: 150,
+ displayField:'name',
+ store: tvheadend.dvrrepeats,
+ mode: 'local',
+ editable: false,
+ triggerAction: 'all',
+ emptyText: 'Only include episodes...'
+ });
function epgQueryClear() {
epgStore.baseParams.channel = null;
epgStore.baseParams.tag = null;
epgStore.baseParams.contenttype = null;
epgStore.baseParams.title = null;
+ epgStore.baseParams.repeats = null;
epgFilterChannels.setValue("");
epgFilterChannelTags.setValue("");
epgFilterContentGroup.setValue("");
epgFilterTitle.setValue("");
+ epgFilterRepeats.setValue("");
epgStore.reload();
}
@@ -415,6 +451,13 @@ tvheadend.epg = function() {
}
});
+ epgFilterRepeats.on('select', function(c, r) {
+ if(epgStore.baseParams.repeats != r.data.identifier) {
+ epgStore.baseParams.repeats = r.data.identifier;
+ epgStore.reload();
+ }
+ });
+
var epgView = new Ext.ux.grid.livegrid.GridView({
nearLimit : 100,
loadMask : {
@@ -440,6 +483,8 @@ tvheadend.epg = function() {
'-',
epgFilterContentGroup,
'-',
+ epgFilterRepeats,
+ '-',
{
text: 'Reset',
handler: epgQueryClear
@@ -493,6 +538,9 @@ tvheadend.epg = function() {
epgStore.baseParams.tag : "<i>Don't care</i>";
var contenttype = epgStore.baseParams.contenttype ?
epgStore.baseParams.contenttype : "<i>Don't care</i>";
+ var repeats = epgStore.baseParams.repeats ?
+ tvheadend.dvrrepeats.getById(epgStore.baseParams.repeats).data.name : "<i>Don't care</i>";
+
Ext.MessageBox.confirm('Auto Recorder',
'This will create an automatic rule that ' +
@@ -503,6 +551,7 @@ tvheadend.epg = function() {
'<div class="x-smallhdr">Channel:</div>' + channel + '<br>' +
'<div class="x-smallhdr">Tag:</div>' + tag + '<br>' +
'<div class="x-smallhdr">Genre:</div>' + contenttype + '<br>' +
+ '<div class="x-smallhdr">Repeat:</div>' + repeats + '<br>' +
'<br>' +
'Currently this will match (and record) ' +
epgStore.getTotalCount() + ' events. ' +

No commit comments for this range

Something went wrong with that request. Please try again.