static htsmsg_t * xmlrpc_convert_response(htsmsg_t *xml, char *errbuf, size_t errlen) { htsmsg_t *dst, *params; htsmsg_field_t *f, *g; htsmsg_t *c; if((params = htsmsg_get_map_multi(xml, "methodResponse", "params", NULL)) == NULL) { snprintf(errbuf, errlen, "No params in reply found"); return NULL; } dst = htsmsg_create_list(); HTSMSG_FOREACH(f, params) { if(strcmp(f->hmf_name, "param") || (c = htsmsg_get_map_by_field(f)) == NULL) continue; if((c = htsmsg_get_map(c, "value")) == NULL) continue; g = TAILQ_FIRST(&c->hm_fields); if(g == NULL || g->hmf_type != HMF_MAP) continue; if(xmlrpc_parse_value(dst, g, NULL, errbuf, errlen)) { htsmsg_release(dst); return NULL; } } return dst; }
/** * TTML docs here: http://www.w3.org/TR/ttaf1-dfxp/ */ static ext_subtitles_t * load_ttml(const char *url, buf_t *buf) { char errbuf[256]; htsmsg_t *subs; htsmsg_field_t *f; htsmsg_t *xml = htsmsg_xml_deserialize_buf(buf, errbuf, sizeof(errbuf)); if(xml == NULL) { TRACE(TRACE_INFO, "Subtitles", "Unable to load TTML: %s", errbuf); return NULL; } subs = htsmsg_get_map_multi(xml, "tt", "body", "div", NULL); if(subs == NULL) { htsmsg_release(xml); return NULL; } ext_subtitles_t *es = calloc(1, sizeof(ext_subtitles_t)); TAILQ_INIT(&es->es_entries); HTSMSG_FOREACH(f, subs) { if(f->hmf_type == HMF_STR && f->hmf_childs != NULL) { htsmsg_t *n = f->hmf_childs; const char *str, *txt; int64_t start, end; txt = f->hmf_str; if((str = htsmsg_get_str(n, "begin")) == NULL) continue; if((start = ttml_time_expression(str)) == -1) continue; if((str = htsmsg_get_str(n, "end")) == NULL) continue; if((end = ttml_time_expression(str)) == -1) continue; es_insert_text(es, txt, start, end, 0); } } return es; }
static ext_subtitles_t * load_timedtext(const char *url, buf_t *buf) { char errbuf[256]; htsmsg_field_t *f; htsmsg_t *xml = htsmsg_xml_deserialize_buf(buf, errbuf, sizeof(errbuf)); if(xml == NULL) { TRACE(TRACE_INFO, "Subtitles", "Unable to load timed text: %s", errbuf); return NULL; } htsmsg_t *transcript = htsmsg_get_map_multi(xml, "transcript", NULL); if(transcript == NULL) { htsmsg_release(xml); return NULL; } ext_subtitles_t *es = calloc(1, sizeof(ext_subtitles_t)); TAILQ_INIT(&es->es_entries); HTSMSG_FOREACH(f, transcript) { if(f->hmf_type == HMF_STR && f->hmf_childs != NULL) { htsmsg_t *n = f->hmf_childs; const char *str; int64_t start, end; if((str = htsmsg_get_str(n, "start")) == NULL) continue; start = my_str2double(str, NULL) * 1000000.0; if((str = htsmsg_get_str(n, "dur")) == NULL) continue; end = start + my_str2double(str, NULL) * 1000000.0; char *txt = strdup(f->hmf_str); html_entities_decode(txt); es_insert_text(es, txt, start, end, 0); free(txt); } } return es; }
int soap_exec(const char *uri, const char *service, int version, const char *method, htsmsg_t *in, htsmsg_t **outp, char *errbuf, size_t errlen) { int r; htsmsg_t *out; htsbuf_queue_t post; buf_t *result; struct http_header_list hdrs = {0}; char tmp[100]; htsbuf_queue_init(&post, 0); htsbuf_qprintf(&post, "<?xml version=\"1.0\" encoding=\"utf-8\"?>" "<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">" "<s:Body><ns0:%s xmlns:ns0=\"urn:schemas-upnp-org:service:%s:%d\">", method, service, version); soap_encode_args(&post, in); htsbuf_qprintf(&post, "</ns0:%s></s:Body></s:Envelope>", method); snprintf(tmp, sizeof(tmp),"\"urn:schemas-upnp-org:service:%s:%d#%s\"", service, version, method); http_header_add(&hdrs, "SOAPACTION", tmp, 0); r = http_request(uri, NULL, &result, errbuf, errlen, &post, "text/xml; charset=\"utf-8\"", 0, NULL, &hdrs, NULL, NULL, NULL); http_headers_free(&hdrs); htsbuf_queue_flush(&post); if(r) return -1; out = htsmsg_xml_deserialize_buf2(result, errbuf, errlen); if(out == NULL) return -1; snprintf(tmp, sizeof(tmp), "urn:schemas-upnp-org:service:%s:%d%sResponse", service, version, method); htsmsg_t *outargs = htsmsg_get_map_multi(out, "tags", "http://schemas.xmlsoap.org/soap/envelope/Envelope", "tags", "http://schemas.xmlsoap.org/soap/envelope/Body", "tags", tmp, "tags", NULL); if(outargs != NULL) { htsmsg_field_t *f; htsmsg_t *out = htsmsg_create_map(); // Convert args from XML style to more compact style HTSMSG_FOREACH(f, outargs) { htsmsg_t *a; const char *s; if((a = htsmsg_get_map_by_field(f)) == NULL) continue; if((s = htsmsg_get_str(a, "cdata")) != NULL) htsmsg_add_str(out, f->hmf_name, s); }