char extdesc[5000];
char extitem[5000];
char exttext[5000];
- epg_content_type_t *ect;
event_t *e;
}
int changed = 0;
- ect = NULL;
*title = 0;
*desc = 0;
while(dllen > 0) {
case DVB_DESC_CONTENT:
if(dlen >= 2) {
/* We only support one content type per event atm. */
- ect = epg_content_type_find_by_dvbcode(*ptr);
- changed |= epg_event_set_content_type(e, ect);
+ changed |= epg_event_set_content_type(e, (*ptr) >> 4);
}
break;
case DVB_DESC_EXT_EVENT:
char *dae_title;
regex_t dae_title_preg;
- epg_content_group_t *dae_ecg;
+ uint8_t dae_content_type;
int dae_approx_time; /* Minutes from midnight */
*
*/
void dvr_autorec_add(const char *title, const char *channel,
- const char *tag, const char *contentgrp,
+ const char *tag, uint8_t content_type,
const char *creator, const char *comment);
void dvr_autorec_check_event(event_t *e);
if(dae->dae_channel == NULL &&
dae->dae_channel_tag == NULL &&
- dae->dae_ecg == NULL &&
+ dae->dae_content_type == 0 &&
dae->dae_title == NULL)
return 0; // Avoid super wildcard match
}
- if(dae->dae_ecg != NULL) {
- if(e->e_content_type == NULL ||
- dae->dae_ecg != e->e_content_type->ect_group)
- return 0;
- }
+ if(dae->dae_content_type != 0 &&
+ dae->dae_content_type != e->e_content_type)
+ return 0;
if(dae->dae_title != NULL) {
if(e->e_title == NULL ||
if(dae->dae_channel_tag != NULL)
htsmsg_add_str(e, "tag", dae->dae_channel_tag->ct_name);
- if(dae->dae_ecg != NULL)
- htsmsg_add_str(e, "contentgrp",dae->dae_ecg->ecg_name);
+ htsmsg_add_u32(e, "contenttype",dae->dae_content_type);
htsmsg_add_str(e, "title", dae->dae_title ?: "");
}
}
- if((s = htsmsg_get_str(values, "contentgrp")) != NULL)
- dae->dae_ecg = epg_content_group_find_by_name(s);
+ dae->dae_content_type = htsmsg_get_u32_or_default(values, "contenttype", 0);
if((s = htsmsg_get_str(values, "approx_time")) != NULL) {
if(strchr(s, ':') != NULL) {
*/
void
dvr_autorec_add(const char *title, const char *channel,
- const char *tag, const char *cgrp,
+ const char *tag, uint8_t content_type,
const char *creator, const char *comment)
{
dvr_autorec_entry_t *dae;
dae->dae_channel_tag = ct;
}
- dae->dae_ecg = cgrp ? epg_content_group_find_by_name(cgrp) : NULL;
dae->dae_enabled = 1;
+ dae->dae_content_type = content_type;
m = autorec_record_build(dae);
hts_settings_save(m, "%s/%s", "autorec", dae->dae_id);
{
htsbuf_queue_t *q = htsbuf_queue_alloc(0);
+ addtag(q, build_tag_string("ORIGINAL_MEDIA_TYPE", "TV", 0, NULL));
+
if(de->de_channel != NULL)
addtag(q, build_tag_string("TVCHANNEL", de->de_channel->ch_name, 0, NULL));
addtag(q, build_tag_string("SYNOPSIS",
de->de_episode.ee_onscreen, 0, NULL));
- if(de->de_title != NULL)
- addtag(q, build_tag_string("SUMMARY", de->de_title, 0, NULL));
+ if(de->de_desc != NULL)
+ addtag(q, build_tag_string("SUMMARY", de->de_desc, 0, NULL));
if(de->de_episode.ee_season)
addtag(q, build_tag_int("PART_NUMBER", de->de_episode.ee_season,
#define EPG_GLOBAL_HASH_MASK (EPG_GLOBAL_HASH_WIDTH - 1)
static struct event_list epg_hash[EPG_GLOBAL_HASH_WIDTH];
-epg_content_group_t *epg_content_groups[16];
-
static void epg_expire_event_from_channel(void *opauqe);
static void epg_ch_check_current_event(void *aux);
*
*/
int
-epg_event_set_content_type(event_t *e, epg_content_type_t *ect)
+epg_event_set_content_type(event_t *e, uint8_t type)
{
- if(e->e_content_type == ect)
+ if(e->e_content_type == type)
return 0;
- if(e->e_content_type != NULL)
- LIST_REMOVE(e, e_content_type_link);
-
- e->e_content_type = ect;
- if(ect != NULL)
- LIST_INSERT_HEAD(&ect->ect_events, e, e_content_type_link);
+ e->e_content_type = type;
return 1;
}
static void
epg_event_destroy(event_t *e)
{
- if(e->e_content_type != NULL)
- LIST_REMOVE(e, e_content_type_link);
-
free(e->e_title);
free(e->e_desc);
free(e->e_episode.ee_onscreen);
/**
+ * EPG content group
*
+ * Based on the content types defined in EN 300 468
*/
static const char *groupnames[16] = {
- [0] = "Unclassified",
[1] = "Movie / Drama",
[2] = "News / Current affairs",
[3] = "Show / Games",
[4] = "Sports",
- [5] = "Children's/Youth",
+ [5] = "Children's / Youth",
[6] = "Music",
- [7] = "Art/Culture",
- [8] = "Social/Political issues/Economics",
- [9] = "Education/Science/Factual topics",
+ [7] = "Art / Culture",
+ [8] = "Social / Political issues / Economics",
+ [9] = "Education / Science / Factual topics",
[10] = "Leisure hobbies",
[11] = "Special characteristics",
};
+
/**
*
*/
const char *
-epg_content_group_get_name(unsigned int id)
+epg_content_group_get_name(uint8_t id)
{
return id < 16 ? groupnames[id] : NULL;
}
-/**
- * Find a content type
- */
-epg_content_type_t *
-epg_content_type_find_by_dvbcode(uint8_t dvbcode)
-{
- epg_content_group_t *ecg;
- epg_content_type_t *ect;
- int group = dvbcode >> 4;
- int type = dvbcode & 0xf;
- char buf[20];
-
- ecg = epg_content_groups[group];
- if(ecg == NULL) {
- ecg = epg_content_groups[group] = calloc(1, sizeof(epg_content_group_t));
- ecg->ecg_name = groupnames[group];
- }
-
- ect = ecg->ecg_types[type];
- if(ect == NULL) {
- ect = ecg->ecg_types[type] = calloc(1, sizeof(epg_content_type_t));
- ect->ect_group = ecg;
- snprintf(buf, sizeof(buf), "type%d", type);
- ect->ect_name = strdup(buf);
- ect->ect_dvbcode = dvbcode;
- }
-
- return ect;
-}
-
/**
*
*/
-epg_content_group_t *
+uint8_t
epg_content_group_find_by_name(const char *name)
{
- epg_content_group_t *ecg;
int i;
for(i = 0; i < 16; i++) {
- ecg = epg_content_groups[i];
- if(ecg != NULL && ecg->ecg_name && !strcmp(name, ecg->ecg_name))
- return ecg;
+ if(groupnames[i] != NULL && !strcmp(name, groupnames[i]))
+ return i;
}
- return NULL;
+ return 0;
}
void
epg_init(void)
{
- int i;
-
- for(i = 0x0; i < 0x100; i+=16)
- epg_content_type_find_by_dvbcode(i);
}
*/
static void
epg_query_add_channel(epg_query_result_t *eqr, channel_t *ch,
- epg_content_group_t *ecg, regex_t *preg, time_t now)
+ uint8_t content_type, regex_t *preg, time_t now)
{
event_t *e;
- if(ecg == NULL) {
+ if(content_type == 0) {
RB_FOREACH(e, &ch->ch_epg_events, e_channel_link)
eqr_add(eqr, e, preg, now);
- return;
+ } else {
+ RB_FOREACH(e, &ch->ch_epg_events, e_channel_link)
+ if(content_type == e->e_content_type)
+ eqr_add(eqr, e, preg, now);
}
-
- RB_FOREACH(e, &ch->ch_epg_events, e_channel_link)
- if(e->e_content_type != NULL && ecg == e->e_content_type->ect_group)
- eqr_add(eqr, e, preg, now);
}
/**
*/
void
epg_query0(epg_query_result_t *eqr, channel_t *ch, channel_tag_t *ct,
- epg_content_group_t *ecg, const char *title)
+ uint8_t content_type, const char *title)
{
channel_tag_mapping_t *ctm;
time_t now;
}
if(ch != NULL && ct == NULL) {
- epg_query_add_channel(eqr, ch, ecg, preg, now);
+ epg_query_add_channel(eqr, ch, content_type, preg, now);
return;
}
if(ct != NULL) {
LIST_FOREACH(ctm, &ct->ct_ctms, ctm_tag_link)
if(ch == NULL || ctm->ctm_channel == ch)
- epg_query_add_channel(eqr, ctm->ctm_channel, ecg, preg, now);
+ epg_query_add_channel(eqr, ctm->ctm_channel, content_type, preg, now);
return;
}
RB_FOREACH(ch, &channel_name_tree, ch_name_link)
- epg_query_add_channel(eqr, ch, ecg, preg, now);
+ epg_query_add_channel(eqr, ch, content_type, preg, now);
}
/**
{
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_content_group_t *ecg = contentgroup ?
- epg_content_group_find_by_name(contentgroup) : NULL;
- epg_query0(eqr, ch, ct, ecg, title);
+ uint8_t content_type = contentgroup ?
+ epg_content_group_find_by_name(contentgroup) : 0;
+ epg_query0(eqr, ch, ct, content_type, title);
}
/**
#include "channels.h"
-/**
- * EPG content group
- *
- * Based on the content types defined in EN 300 468
- */
-
-
-typedef struct epg_content_group {
- const char *ecg_name;
- struct epg_content_type *ecg_types[16];
-} epg_content_group_t;
-
-typedef struct epg_content_type {
- const char *ect_name;
- struct event_list ect_events;
- epg_content_group_t *ect_group;
- uint8_t ect_dvbcode;
-} epg_content_type_t;
typedef struct epg_episode {
int e_refcount;
uint32_t e_id;
- LIST_ENTRY(event) e_content_type_link;
- epg_content_type_t *e_content_type;
+ uint8_t e_content_type;
time_t e_start; /* UTC time */
time_t e_stop; /* UTC time */
int epg_event_set_ext_text(event_t *e, int ext_dn, const char *text)
__attribute__ ((warn_unused_result));
-int epg_event_set_content_type(event_t *e, epg_content_type_t *ect)
+int epg_event_set_content_type(event_t *e, uint8_t type)
__attribute__ ((warn_unused_result));
int epg_event_set_episode(event_t *e, epg_episode_t *ee)
/**
*
*/
-epg_content_type_t *epg_content_type_find_by_dvbcode(uint8_t dvbcode);
-
-epg_content_group_t *epg_content_group_find_by_name(const char *name);
+uint8_t epg_content_group_find_by_name(const char *name);
-const char *epg_content_group_get_name(unsigned int id);
+const char *epg_content_group_get_name(uint8_t type);
/**
*
} epg_query_result_t;
void epg_query0(epg_query_result_t *eqr, channel_t *ch, channel_tag_t *ct,
- epg_content_group_t *ecg, const char *title);
+ uint8_t type, const char *title);
void epg_query(epg_query_result_t *eqr, const char *channel, const char *tag,
const char *contentgroup, const char *title);
void epg_query_free(epg_query_result_t *eqr);
htsmsg_t *out, *eventIds;
const char *query;
int c, i;
- uint32_t channelid, tagid, epg_content_dvbcode;
+ uint32_t channelid, tagid, epg_content_dvbcode = 0;
channel_t *ch = NULL;
channel_tag_t *ct = NULL;
- epg_content_type_t *ect = NULL;
epg_query_result_t eqr;
//only mandatory parameter is the query
if( !(htsmsg_get_u32(in, "tagId", &tagid)) )
ct = channel_tag_find_by_identifier(tagid);
- if( !(htsmsg_get_u32(in, "contentType", &epg_content_dvbcode)) )
- ect = epg_content_type_find_by_dvbcode(epg_content_dvbcode);
-
+ htsmsg_get_u32(in, "contentType", &epg_content_dvbcode);
//do the query
- epg_query0(&eqr, ch, ct, ect ? ect->ect_group : NULL, query);
+ epg_query0(&eqr, ch, ct, epg_content_dvbcode, query);
c = eqr.eqr_entries;
// create reply
if(e->e_ext_text != NULL)
htsmsg_add_str(out, "ext_text", e->e_ext_text);
- if(e->e_content_type != NULL)
- htsmsg_add_u32(out, "contentType", e->e_content_type->ect_dvbcode);
+ if(e->e_content_type)
+ htsmsg_add_u32(out, "contentType", e->e_content_type);
n = RB_NEXT(e, e_channel_link);
if(n != NULL)
end = MIN(start + limit, eqr.eqr_entries);
for(i = start; i < end; i++) {
+ const char *s;
+
e = eqr.eqr_array[i];
m = htsmsg_create_map();
htsmsg_add_u32(m, "end", e->e_stop);
htsmsg_add_u32(m, "duration", e->e_stop - e->e_start);
- if(e->e_content_type != NULL &&
- e->e_content_type->ect_group->ecg_name != NULL)
- htsmsg_add_str(m, "contentgrp", e->e_content_type->ect_group->ecg_name);
+ if((s = epg_content_group_get_name(e->e_content_type)) != NULL)
+ htsmsg_add_str(m, "contentgrp", s);
dvr_entry_t *de;
if((de = dvr_entry_find_by_event(e)) != NULL)
htsmsg_add_u32(out, "success", 1);
} else if(!strcmp(op, "createAutoRec")) {
+ const char *cgrp = http_arg_get(&hc->hc_req_args, "contentgrp");
+
+
dvr_autorec_add(http_arg_get(&hc->hc_req_args, "title"),
http_arg_get(&hc->hc_req_args, "channel"),
http_arg_get(&hc->hc_req_args, "tag"),
- http_arg_get(&hc->hc_req_args, "contentgrp"),
+ cgrp ? epg_content_group_find_by_name(cgrp) : 0,
hc->hc_representative, "Created from EPG query");
out = htsmsg_create_map();