From: Jaroslav Kysela Date: Tue, 19 Jan 2016 10:33:51 +0000 (+0100) Subject: wizard predefined muxes dialog X-Git-Tag: v4.2.1~1155 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a28d4996887b9c633e9e68a298a769cc4225e020;p=thirdparty%2Ftvheadend.git wizard predefined muxes dialog --- diff --git a/src/api/api_wizard.c b/src/api/api_wizard.c index 785fd3dae..e68fbfebd 100644 --- a/src/api/api_wizard.c +++ b/src/api/api_wizard.c @@ -86,8 +86,8 @@ api_wizard_init ( void ) { "wizard/login/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_login }, { "wizard/network/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_network }, { "wizard/network/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_network }, - { "wizard/input/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_input }, - { "wizard/input/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_input }, + { "wizard/muxes/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_muxes }, + { "wizard/muxes/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_muxes }, { "wizard/status/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_status }, { "wizard/status/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_status }, { "wizard/mapping/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_mapping }, diff --git a/src/input/mpegts/mpegts_dvb.h b/src/input/mpegts/mpegts_dvb.h index a2f2ae304..0258e7cf2 100644 --- a/src/input/mpegts/mpegts_dvb.h +++ b/src/input/mpegts/mpegts_dvb.h @@ -75,6 +75,10 @@ dvb_mux_t *dvb_network_find_mux const idclass_t *dvb_network_mux_class(mpegts_network_t *mn); int dvb_network_get_orbital_pos(mpegts_network_t *mn); +void dvb_network_scanfile_set ( dvb_network_t *ln, const char *id ); + +htsmsg_t * dvb_network_class_scanfile_list ( void *o, const char *lang ); + /* * */ diff --git a/src/input/mpegts/mpegts_network_dvb.c b/src/input/mpegts/mpegts_network_dvb.c index cbec7c802..53104da3b 100644 --- a/src/input/mpegts/mpegts_network_dvb.c +++ b/src/input/mpegts/mpegts_network_dvb.c @@ -59,19 +59,19 @@ dvb_network_class_scanfile_get ( void *o ) static const char *s = NULL; return &s; } -static int -dvb_network_class_scanfile_set ( void *o, const void *s ) + +void +dvb_network_scanfile_set ( dvb_network_t *ln, const char *id ) { - dvb_network_t *ln = o; dvb_mux_conf_t *dmc; scanfile_network_t *sfn; dvb_mux_t *mm; /* Find */ - if (!s) - return 0; - if (!(sfn = scanfile_find(s))) - return 0; + if (!id) + return; + if (!(sfn = scanfile_find(id))) + return; /* Set satellite position */ if (sfn->sfn_satpos != INT_MAX && ln->mn_satpos == INT_MAX) @@ -80,7 +80,7 @@ dvb_network_class_scanfile_set ( void *o, const void *s ) /* Create */ LIST_FOREACH(dmc, &sfn->sfn_muxes, dmc_link) { if (!(mm = dvb_network_find_mux(ln, dmc, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE))) { - mm = dvb_mux_create0(o, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, + mm = dvb_mux_create0(ln, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, dmc, NULL, NULL); if (mm) mm->mm_config_save((mpegts_mux_t *)mm); @@ -99,17 +99,51 @@ dvb_network_class_scanfile_set ( void *o, const void *s ) } } } + return; +} + +static int +dvb_network_class_scanfile_set ( void *o, const void *s ) +{ + dvb_network_scanfile_set(o, s); return 0; } -static htsmsg_t * -dvb_network_class_scanfile_list ( void *o, const char *lang, const char *type ) + +htsmsg_t * +dvb_network_class_scanfile_list ( void *o, const char *lang ) { dvb_network_t *ln = o; + const char *type; + const idclass_t *clazz; + + if (ln == NULL) + return NULL; htsmsg_t *e, *m = htsmsg_create_map(); htsmsg_add_str(m, "type", "api"); htsmsg_add_str(m, "uri", "dvb/scanfile/list"); htsmsg_add_str(m, "stype", "none"); e = htsmsg_create_map(); + clazz = ln->mn_id.in_class; + if (clazz == &dvb_network_dvbt_class) + type = "dvbt"; + else if (clazz == &dvb_network_dvbc_class) + type = "dvbc"; + else if (clazz == &dvb_network_dvbs_class) + type = "dvbs"; + else if (clazz == &dvb_network_atsc_t_class) + type = "atsc-t"; + else if (clazz == &dvb_network_atsc_c_class) + type = "atsc-c"; + else if (clazz == &dvb_network_isdb_t_class) + type = "isdb-t"; + else if (clazz == &dvb_network_isdb_c_class) + type = "isdb-c"; + else if (clazz == &dvb_network_isdb_s_class) + type = "isdb-s"; + else if (clazz == &dvb_network_dab_class) + type = "dab"; + else + type = "unk"; htsmsg_add_str(e, "type", type); if (ln && ln->mn_satpos != INT_MAX) htsmsg_add_s32(e, "satpos", ln->mn_satpos); @@ -117,52 +151,6 @@ dvb_network_class_scanfile_list ( void *o, const char *lang, const char *type ) return m; } -static htsmsg_t * -dvb_network_dvbt_class_scanfile_list ( void *o, const char *lang ) -{ - return dvb_network_class_scanfile_list(o, lang, "dvbt"); -} -static htsmsg_t * -dvb_network_dvbc_class_scanfile_list ( void *o, const char *lang ) -{ - return dvb_network_class_scanfile_list(o, lang, "dvbc"); -} -static htsmsg_t * -dvb_network_dvbs_class_scanfile_list ( void *o, const char *lang ) -{ - return dvb_network_class_scanfile_list(o, lang, "dvbs"); -} -static htsmsg_t * -dvb_network_atsc_t_class_scanfile_list ( void *o, const char *lang ) -{ - return dvb_network_class_scanfile_list(o, lang, "atsc-t"); -} -static htsmsg_t * -dvb_network_atsc_c_class_scanfile_list ( void *o, const char *lang ) -{ - return dvb_network_class_scanfile_list(o, lang, "atsc-c"); -} -static htsmsg_t * -dvb_network_isdb_t_class_scanfile_list ( void *o, const char *lang ) -{ - return dvb_network_class_scanfile_list(o, lang, "isdb-t"); -} -static htsmsg_t * -dvb_network_isdb_c_class_scanfile_list ( void *o, const char *lang ) -{ - return dvb_network_class_scanfile_list(o, lang, "isdb-c"); -} -static htsmsg_t * -dvb_network_isdb_s_class_scanfile_list ( void *o, const char *lang ) -{ - return dvb_network_class_scanfile_list(o, lang, "isdb-s"); -} -static htsmsg_t * -dvb_network_dab_class_scanfile_list ( void *o, const char *lang ) -{ - return dvb_network_class_scanfile_list(o, lang, "dab"); -} - static const void * dvb_network_class_orbital_pos_get ( void *o ) { @@ -235,7 +223,7 @@ const idclass_t dvb_network_dvbt_class = "may cause scanning to take longer than usual."), .set = dvb_network_class_scanfile_set, .get = dvb_network_class_scanfile_get, - .list = dvb_network_dvbt_class_scanfile_list, + .list = dvb_network_class_scanfile_list, .opts = PO_NOSAVE, }, {} @@ -257,7 +245,7 @@ const idclass_t dvb_network_dvbc_class = "may cause scanning to take longer than usual."), .set = dvb_network_class_scanfile_set, .get = dvb_network_class_scanfile_get, - .list = dvb_network_dvbc_class_scanfile_list, + .list = dvb_network_class_scanfile_list, .opts = PO_NOSAVE, }, {} @@ -279,7 +267,7 @@ const idclass_t dvb_network_dvbs_class = "may cause scanning to take longer than usual."), .set = dvb_network_class_scanfile_set, .get = dvb_network_class_scanfile_get, - .list = dvb_network_dvbs_class_scanfile_list, + .list = dvb_network_class_scanfile_list, .opts = PO_NOSAVE, }, { @@ -311,7 +299,7 @@ const idclass_t dvb_network_atsc_t_class = "may cause scanning to take longer than usual."), .set = dvb_network_class_scanfile_set, .get = dvb_network_class_scanfile_get, - .list = dvb_network_atsc_t_class_scanfile_list, + .list = dvb_network_class_scanfile_list, .opts = PO_NOSAVE, }, {} @@ -333,7 +321,7 @@ const idclass_t dvb_network_atsc_c_class = "may cause scanning to take longer than usual."), .set = dvb_network_class_scanfile_set, .get = dvb_network_class_scanfile_get, - .list = dvb_network_atsc_c_class_scanfile_list, + .list = dvb_network_class_scanfile_list, .opts = PO_NOSAVE, }, {} @@ -355,7 +343,7 @@ const idclass_t dvb_network_isdb_t_class = "may cause scanning to take longer than usual."), .set = dvb_network_class_scanfile_set, .get = dvb_network_class_scanfile_get, - .list = dvb_network_isdb_t_class_scanfile_list, + .list = dvb_network_class_scanfile_list, .opts = PO_NOSAVE, }, {} @@ -377,7 +365,7 @@ const idclass_t dvb_network_isdb_c_class = "may cause scanning to take longer than usual."), .set = dvb_network_class_scanfile_set, .get = dvb_network_class_scanfile_get, - .list = dvb_network_isdb_c_class_scanfile_list, + .list = dvb_network_class_scanfile_list, .opts = PO_NOSAVE, }, {} @@ -399,7 +387,7 @@ const idclass_t dvb_network_isdb_s_class = "may cause scanning to take longer than usual."), .set = dvb_network_class_scanfile_set, .get = dvb_network_class_scanfile_get, - .list = dvb_network_isdb_s_class_scanfile_list, + .list = dvb_network_class_scanfile_list, .opts = PO_NOSAVE, }, {} @@ -421,7 +409,7 @@ const idclass_t dvb_network_dab_class = "may cause scanning to take longer than usual."), .set = dvb_network_class_scanfile_set, .get = dvb_network_class_scanfile_get, - .list = dvb_network_dab_class_scanfile_list, + .list = dvb_network_class_scanfile_list, .opts = PO_NOSAVE, }, {} diff --git a/src/webui/static/app/wizard.js b/src/webui/static/app/wizard.js index fcd2b9756..49077e0b9 100644 --- a/src/webui/static/app/wizard.js +++ b/src/webui/static/app/wizard.js @@ -10,8 +10,8 @@ tvheadend.wizard_start = function(page) { var tabMapping = { hello: 'base_config', login: 'access_entry', - network: 'mpegts_network', - input: 'tvadapters', + network: 'tvadapters', + muxes: 'mpegts_network', status: 'status_streams', mapping: 'channels', } diff --git a/src/wizard.c b/src/wizard.c index 4529aced3..89ce8b458 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -21,6 +21,7 @@ #include "access.h" #include "settings.h" #include "input.h" +#include "input/mpegts/iptv/iptv_private.h" #include "wizard.h" /* @@ -547,7 +548,8 @@ static void network_save(idnode_t *in) .id = "tunerid" STRINGIFY(num), \ .name = "Tuner", \ .get = network_get_tidvalue##num, \ - .opts = PO_RDONLY | PO_PERSIST | PO_NOUI, \ + .set = network_set_tidvalue##num, \ + .opts = PO_PERSIST | PO_NOUI, \ }, { \ .type = PT_STR, \ .id = "network" STRINGIFY(num), \ @@ -573,6 +575,13 @@ static const void *network_get_tidvalue##num(void *o) \ snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", w->tunerid[num-1]); \ return &prop_sbuf_ptr; \ } \ +static int network_set_tidvalue##num(void *o, const void *v) \ +{ \ + wizard_page_t *p = o; \ + wizard_network_t *w = p->aux; \ + snprintf(w->tunerid[num-1], sizeof(w->tunerid[num-1]), "%s", (const char *)v); \ + return 1; \ +} \ static const void *network_get_value##num(void *o) \ { \ wizard_page_t *p = o; \ @@ -631,7 +640,7 @@ wizard_page_t *wizard_network(const char *lang) ICON(), DESCRIPTION(network), PREV_BUTTON(login), - NEXT_BUTTON(input), + NEXT_BUTTON(muxes), }; wizard_page_t *page = page_init("network", "wizard_network", N_("Network settings")); idclass_t *ic = (idclass_t *)page->idnode.in_class; @@ -685,47 +694,233 @@ wizard_page_t *wizard_network(const char *lang) } /* - * Input settings + * Muxes settings */ -DESCRIPTION_FCN(input, N_("\ -Assign inputs to networks.\ -")) +typedef struct wizard_muxes { + property_t props [WIZARD_NETWORKS * 3 + 10]; + char network [WIZARD_NETWORKS][64]; + char networkid [WIZARD_NETWORKS][UUID_HEX_SIZE]; + char muxes [WIZARD_NETWORKS][64]; + char iptv_url [WIZARD_NETWORKS][512]; +} wizard_muxes_t; +static void muxes_free(wizard_page_t *page) +{ + page_free(page); +} -wizard_page_t *wizard_input(const char *lang) +static void muxes_save(idnode_t *in) { + wizard_page_t *p = (wizard_page_t *)in; + wizard_muxes_t *w = p->aux; + mpegts_network_t *mn; + htsmsg_t *m; + int idx; + + for (idx = 0; idx < WIZARD_NETWORKS; idx++) { + if (w->networkid[idx][0] == '\0') + continue; + mn = mpegts_network_find(w->networkid[idx]); + if (mn == NULL || !mn->mn_wizard) + continue; + if (idnode_is_instance(&mn->mn_id, &dvb_network_class) && w->muxes[idx][0]) { + dvb_network_scanfile_set((dvb_network_t *)mn, w->muxes[idx]); + } else if (idnode_is_instance(&mn->mn_id, &iptv_auto_network_class) && + w->iptv_url[0]) { + m = htsmsg_create_map(); + htsmsg_add_str(m, "url", w->iptv_url[idx]); + idnode_load(&mn->mn_id, m); + htsmsg_destroy(m); + } + } +} + +#define MUXES(num) { \ + .type = PT_STR, \ + .id = "network" STRINGIFY(num), \ + .name = N_("Network"), \ + .get = muxes_get_nvalue##num, \ + .opts = PO_RDONLY, \ + .group = num, \ +}, { \ + .type = PT_STR, \ + .id = "networkid" STRINGIFY(num), \ + .name = "Network", \ + .get = muxes_get_idvalue##num, \ + .set = muxes_set_idvalue##num, \ + .opts = PO_PERSIST | PO_NOUI, \ +}, { \ + .type = PT_STR, \ + .id = "muxes" STRINGIFY(num), \ + .name = N_("Pre-defined muxes"), \ + .get = muxes_get_value##num, \ + .set = muxes_set_value##num, \ + .list = muxes_get_list##num, \ + .group = num, \ +} + +#define MUXES_IPTV(num) { \ + .type = PT_STR, \ + .id = "network" STRINGIFY(num), \ + .name = N_("Network"), \ + .get = muxes_get_nvalue##num, \ + .opts = PO_RDONLY, \ + .group = num, \ +}, { \ + .type = PT_STR, \ + .id = "networkid" STRINGIFY(num), \ + .name = "Network", \ + .get = muxes_get_idvalue##num, \ + .set = muxes_set_idvalue##num, \ + .opts = PO_PERSIST | PO_NOUI, \ +}, { \ + .type = PT_STR, \ + .id = "muxes" STRINGIFY(num), \ + .name = N_("URL"), \ + .desc = N_("URL of the M3U playlist."), \ + .get = muxes_get_iptv_value##num, \ + .set = muxes_set_iptv_value##num, \ + .group = num, \ +} + +#define MUXES_FCN(num) \ +static const void *muxes_get_nvalue##num(void *o) \ +{ \ + wizard_page_t *p = o; \ + wizard_muxes_t *w = p->aux; \ + snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", w->network[num-1]); \ + return &prop_sbuf_ptr; \ +} \ +static const void *muxes_get_idvalue##num(void *o) \ +{ \ + wizard_page_t *p = o; \ + wizard_muxes_t *w = p->aux; \ + snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", w->networkid[num-1]); \ + return &prop_sbuf_ptr; \ +} \ +static int muxes_set_idvalue##num(void *o, const void *v) \ +{ \ + wizard_page_t *p = o; \ + wizard_muxes_t *w = p->aux; \ + snprintf(w->networkid[num-1], sizeof(w->networkid[num-1]), "%s", (const char *)v); \ + return 1; \ +} \ +static const void *muxes_get_value##num(void *o) \ +{ \ + wizard_page_t *p = o; \ + wizard_muxes_t *w = p->aux; \ + snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", w->muxes[num-1]); \ + return &prop_sbuf_ptr; \ +} \ +static int muxes_set_value##num(void *o, const void *v) \ +{ \ + wizard_page_t *p = o; \ + wizard_muxes_t *w = p->aux; \ + snprintf(w->muxes[num-1], sizeof(w->muxes[num-1]), "%s", (const char *)v); \ + return 1; \ +} \ +static htsmsg_t *muxes_get_list##num(void *o, const char *lang) \ +{ \ + if (o == NULL) return NULL; \ + wizard_page_t *p = o; \ + wizard_muxes_t *w = p->aux; \ + mpegts_network_t *mn = mpegts_network_find(w->networkid[num-1]); \ + return mn ? dvb_network_class_scanfile_list(mn, lang) : NULL; \ +} \ +static const void *muxes_get_iptv_value##num(void *o) \ +{ \ + wizard_page_t *p = o; \ + wizard_muxes_t *w = p->aux; \ + snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", w->iptv_url[num-1]); \ + return &prop_sbuf_ptr; \ +} \ +static int muxes_set_iptv_value##num(void *o, const void *v) \ +{ \ + wizard_page_t *p = o; \ + wizard_muxes_t *w = p->aux; \ + snprintf(w->iptv_url[num-1], sizeof(w->iptv_url[num-1]), "%s", (const char *)v); \ + return 1; \ +} + +MUXES_FCN(1) +MUXES_FCN(2) +MUXES_FCN(3) +MUXES_FCN(4) +MUXES_FCN(5) +MUXES_FCN(6) + +DESCRIPTION_FCN(muxes, N_("\ +Assign predefined mxues to networks.\ +")) + +wizard_page_t *wizard_muxes(const char *lang) +{ + static const property_group_t groups[] = { + NETWORK_GROUP(1), + NETWORK_GROUP(2), + NETWORK_GROUP(3), + NETWORK_GROUP(4), + NETWORK_GROUP(5), + NETWORK_GROUP(6), + {} + }; + static const property_t nprops[] = { + MUXES(1), + MUXES(2), + MUXES(3), + MUXES(4), + MUXES(5), + MUXES(6), + }; + static const property_t iptvprops[] = { + MUXES_IPTV(1), + MUXES_IPTV(2), + MUXES_IPTV(3), + MUXES_IPTV(4), + MUXES_IPTV(5), + MUXES_IPTV(6), + }; static const property_t props[] = { - { - .type = PT_STR, - .id = "input1", - .name = N_("Input 1 network"), - .get = hello_get_network, - .set = hello_set_network, - }, - { - .type = PT_STR, - .id = "input2", - .name = N_("Input 2 network"), - .get = hello_get_network, - .set = hello_set_network, - }, - { - .type = PT_STR, - .id = "input3", - .name = N_("Input 3 network"), - .get = hello_get_network, - .set = hello_set_network, - }, ICON(), - DESCRIPTION(input), + DESCRIPTION(muxes), PREV_BUTTON(network), NEXT_BUTTON(status), - {} }; - wizard_page_t *page = page_init("input", "wizard_input", N_("Input / tuner settings")); + wizard_page_t *page = page_init("muxes", "wizard_muxes", N_("Assign predefined muxes to networks")); idclass_t *ic = (idclass_t *)page->idnode.in_class; - ic->ic_properties = props; + wizard_muxes_t *w; + mpegts_network_t *mn; + int idx, midx = 0; + + page->aux = w = calloc(1, sizeof(wizard_network_t)); + ic->ic_groups = groups; + ic->ic_properties = w->props; + ic->ic_save = muxes_save; + page->free = muxes_free; + + for (idx = 0; idx < ARRAY_SIZE(props); idx++) + w->props[idx] = props[idx]; + + LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) + if (mn->mn_wizard) { + mn->mn_display_name(mn, w->network[midx], sizeof(w->network[midx])); + idnode_uuid_as_str(&mn->mn_id, w->networkid[midx]); + if (idnode_is_instance(&mn->mn_id, &dvb_network_class)) { + w->props[idx++] = nprops[midx * 3 + 0]; + w->props[idx++] = nprops[midx * 3 + 1]; + w->props[idx++] = nprops[midx * 3 + 2]; + midx++; + } else if (idnode_is_instance(&mn->mn_id, &iptv_auto_network_class)) { + w->props[idx++] = iptvprops[midx * 3 + 0]; + w->props[idx++] = iptvprops[midx * 3 + 1]; + w->props[idx++] = iptvprops[midx * 3 + 2]; + midx++; + } + } + + assert(idx < ARRAY_SIZE(w->props)); + return page; } diff --git a/src/wizard.h b/src/wizard.h index 71768b9eb..04096a3f1 100644 --- a/src/wizard.h +++ b/src/wizard.h @@ -34,7 +34,7 @@ typedef wizard_page_t *(*wizard_build_fcn_t)(const char *lang); wizard_page_t *wizard_hello(const char *lang); wizard_page_t *wizard_login(const char *lang); wizard_page_t *wizard_network(const char *lang); -wizard_page_t *wizard_input(const char *lang); +wizard_page_t *wizard_muxes(const char *lang); wizard_page_t *wizard_status(const char *lang); wizard_page_t *wizard_mapping(const char *lang);