static int _pyepg_parse_channel ( epggrab_module_t *mod, htsmsg_t *data, epggrab_stats_t *stats ) { int save = 0; epggrab_channel_t *ch; htsmsg_t *attr, *tags; const char *str; uint32_t u32; if ( data == NULL ) return 0; if ((attr = htsmsg_get_map(data, "attrib")) == NULL) return 0; if ((str = htsmsg_get_str(attr, "id")) == NULL) return 0; if ((tags = htsmsg_get_map(data, "tags")) == NULL) return 0; if (!(ch = _pyepg_channel_find(str, 1, &save))) return 0; stats->channels.total++; if (save) stats->channels.created++; /* Update data */ if ((str = htsmsg_xml_get_cdata_str(tags, "name"))) save |= epggrab_channel_set_name(ch, str); if ((str = htsmsg_xml_get_cdata_str(tags, "image"))) save |= epggrab_channel_set_icon(ch, str); if ((!htsmsg_xml_get_cdata_u32(tags, "number", &u32))) save |= epggrab_channel_set_number(ch, u32, 0); /* Update */ if (save) { epggrab_channel_updated(ch); stats->channels.modified++; } return save; }
static int _pyepg_parse_season ( epggrab_module_t *mod, htsmsg_t *data, epggrab_stats_t *stats ) { int save = 0; htsmsg_t *attr, *tags; epg_season_t *season; epg_brand_t *brand; const char *str; uint32_t u32; if ( data == NULL ) return 0; if ((attr = htsmsg_get_map(data, "attrib")) == NULL) return 0; if ((str = htsmsg_get_str(attr, "id")) == NULL) return 0; if ((tags = htsmsg_get_map(data, "tags")) == NULL) return 0; /* Find series */ if ((season = epg_season_find_by_uri(str, 1, &save)) == NULL) return 0; stats->seasons.total++; if (save) stats->seasons.created++; /* Set brand */ if ((str = htsmsg_get_str(attr, "brand"))) { if ((brand = epg_brand_find_by_uri(str, 0, NULL))) { save |= epg_season_set_brand(season, brand, mod); } } /* Set summary */ if ((str = htsmsg_xml_get_cdata_str(tags, "summary"))) { save |= epg_season_set_summary(season, str, NULL, mod); } /* Set image */ if ((str = htsmsg_xml_get_cdata_str(tags, "image"))) { save |= epg_season_set_image(season, str, mod); } else if ((str = htsmsg_xml_get_cdata_str(tags, "thumb"))) { save |= epg_season_set_image(season, str, mod); } /* Set season number */ if (htsmsg_xml_get_cdata_u32(tags, "number", &u32) == 0) { save |= epg_season_set_number(season, u32, mod); } /* Set episode count */ if (htsmsg_xml_get_cdata_u32(tags, "episode-count", &u32) == 0) { save |= epg_season_set_episode_count(season, u32, mod); } if(save) stats->seasons.modified++; return save; }
/** * Parse a <channel> tag from xmltv */ static int _xmltv_parse_channel (epggrab_module_t *mod, htsmsg_t *body, epggrab_stats_t *stats) { int save =0; htsmsg_t *attribs, *tags, *subtag; const char *id, *name, *icon; epggrab_channel_t *ch; if(body == NULL) return 0; if((attribs = htsmsg_get_map(body, "attrib")) == NULL) return 0; if((id = htsmsg_get_str(attribs, "id")) == NULL) return 0; if((tags = htsmsg_get_map(body, "tags")) == NULL) return 0; if((ch = _xmltv_channel_find(id, 1, &save)) == NULL) return 0; stats->channels.total++; if (save) stats->channels.created++; if((name = htsmsg_xml_get_cdata_str(tags, "display-name")) != NULL) { save |= epggrab_channel_set_name(ch, name); } if((subtag = htsmsg_get_map(tags, "icon")) != NULL && (attribs = htsmsg_get_map(subtag, "attrib")) != NULL && (icon = htsmsg_get_str(attribs, "src")) != NULL) { save |= epggrab_channel_set_icon(ch, icon); } if (save) { epggrab_channel_updated(ch); stats->channels.modified++; } return save; }
/* * Process video quality flags * * Note: this is very rough/approx someone might be able to do a much better * job */ static int xmltv_parse_vid_quality ( epggrab_module_t *mod, epg_broadcast_t *ebc, htsmsg_t *m, int8_t *bw ) { int save = 0; int hd = 0, lines = 0, aspect = 0; const char *str; if (!ebc || !m) return 0; if ((str = htsmsg_xml_get_cdata_str(m, "colour"))) *bw = strcmp(str, "no") ? 0 : 1; if ((str = htsmsg_xml_get_cdata_str(m, "quality"))) { if (strstr(str, "HD")) { hd = 1; } else if (strstr(str, "480")) { lines = 480; aspect = 150; } else if (strstr(str, "576")) { lines = 576; aspect = 133; } else if (strstr(str, "720")) { lines = 720; hd = 1; aspect = 178; } else if (strstr(str, "1080")) { lines = 1080; hd = 1; aspect = 178; } } if ((str = htsmsg_xml_get_cdata_str(m, "aspect"))) { int w, h; if (sscanf(str, "%d:%d", &w, &h) == 2) { aspect = (100 * w) / h; } } save |= epg_broadcast_set_is_hd(ebc, hd, mod); if (aspect) { save |= epg_broadcast_set_is_widescreen(ebc, hd || aspect > 137, mod); save |= epg_broadcast_set_aspect(ebc, aspect, mod); } if (lines) save |= epg_broadcast_set_lines(ebc, lines, mod); return save; }
static int _pyepg_parse_brand ( epggrab_module_t *mod, htsmsg_t *data, epggrab_stats_t *stats ) { int save = 0; htsmsg_t *attr, *tags; epg_brand_t *brand; const char *str; uint32_t u32; if ( data == NULL ) return 0; if ((attr = htsmsg_get_map(data, "attrib")) == NULL) return 0; if ((str = htsmsg_get_str(attr, "id")) == NULL) return 0; if ((tags = htsmsg_get_map(data, "tags")) == NULL) return 0; /* Find brand */ if ((brand = epg_brand_find_by_uri(str, 1, &save)) == NULL) return 0; stats->brands.total++; if (save) stats->brands.created++; /* Set title */ if ((str = htsmsg_xml_get_cdata_str(tags, "title"))) { save |= epg_brand_set_title(brand, str, NULL, mod); } /* Set summary */ if ((str = htsmsg_xml_get_cdata_str(tags, "summary"))) { save |= epg_brand_set_summary(brand, str, NULL, mod); } /* Set image */ if ((str = htsmsg_xml_get_cdata_str(tags, "image"))) { save |= epg_brand_set_image(brand, str, mod); } else if ((str = htsmsg_xml_get_cdata_str(tags, "thumb"))) { save |= epg_brand_set_image(brand, str, mod); } /* Set season count */ if (htsmsg_xml_get_cdata_u32(tags, "series-count", &u32) == 0) { save |= epg_brand_set_season_count(brand, u32, mod); } if (save) stats->brands.modified++; return save; }
/* * Star rating */ static int _xmltv_parse_star_rating ( epggrab_module_t *mod, epg_episode_t *ee, htsmsg_t *tags ) { int a, b; const char *stars; if (!mod || !ee || !tags) return 0; if (!(stars = htsmsg_xml_get_cdata_str(tags, "star-rating"))) return 0; if (sscanf(stars, "%d/%d", &a, &b) != 2) return 0; return epg_episode_set_star_rating(ee, (5 * a) / b, mod); }
/* * Tries to get age ratingform <rating> element. * Expects integer representing minimal age of watcher. * Other rating types (non-integer, for example MPAA or VCHIP) are ignored. * * Attribute system is ignored. * * Working example: * <rating system="pl"><value>16</value></rating> * * Currently non-working example: * <rating system="MPAA"> * <value>PG</value> * <icon src="pg_symbol.png" /> * </rating> * * TODO - support for other rating systems: * [rating system=VCHIP] values TV-PG, TV-G, etc * [rating system=MPAA] values R, PG, G, PG-13 etc * [rating system=advisory] values "strong sexual content","Language", etc */ static int _xmltv_parse_age_rating ( epggrab_module_t *mod, epg_episode_t *ee, htsmsg_t *body ) { uint8_t age; htsmsg_t *rating, *tags; const char *s1; if (!mod || !ee || !body) return 0; if (!(rating = htsmsg_get_map(body, "rating"))) return 0; if (!(tags = htsmsg_get_map(rating, "tags"))) return 0; if (!(s1 = htsmsg_xml_get_cdata_str(tags, "value"))) return 0; age = atoi(s1); return epg_episode_set_age_rating(ee, age, mod); }
/* * Star rating */ static int _xmltv_parse_star_rating ( epggrab_module_t *mod, epg_episode_t *ee, htsmsg_t *body ) { double a, b; htsmsg_t *stars, *tags; const char *s1, *s2; if (!mod || !ee || !body) return 0; if (!(stars = htsmsg_get_map(body, "star-rating"))) return 0; if (!(tags = htsmsg_get_map(stars, "tags"))) return 0; if (!(s1 = htsmsg_xml_get_cdata_str(tags, "value"))) return 0; if (!(s2 = strstr(s1, "/"))) return 0; a = atof(s1); b = atof(s2 + 1); return epg_episode_set_star_rating(ee, (100 * a) / b, mod); }
static int _pyepg_parse_episode ( epggrab_module_t *mod, htsmsg_t *data, epggrab_stats_t *stats ) { int save = 0; htsmsg_t *attr, *tags; epg_episode_t *episode; epg_season_t *season; epg_brand_t *brand; const char *str; uint32_t u32, pc, pn; epg_genre_list_t *egl; if ( data == NULL ) return 0; if ((attr = htsmsg_get_map(data, "attrib")) == NULL) return 0; if ((str = htsmsg_get_str(attr, "id")) == NULL) return 0; if ((tags = htsmsg_get_map(data, "tags")) == NULL) return 0; /* Find episode */ if ((episode = epg_episode_find_by_uri(str, 1, &save)) == NULL) return 0; stats->episodes.total++; if (save) stats->episodes.created++; /* Set season */ if ((str = htsmsg_get_str(attr, "series"))) { if ((season = epg_season_find_by_uri(str, 0, NULL))) { save |= epg_episode_set_season(episode, season, mod); } } /* Set brand */ if ((str = htsmsg_get_str(attr, "brand"))) { if ((brand = epg_brand_find_by_uri(str, 0, NULL))) { save |= epg_episode_set_brand(episode, brand, mod); } } /* Set title/subtitle */ if ((str = htsmsg_xml_get_cdata_str(tags, "title"))) { save |= epg_episode_set_title(episode, str, NULL, mod); } if ((str = htsmsg_xml_get_cdata_str(tags, "subtitle"))) { save |= epg_episode_set_subtitle(episode, str, NULL, mod); } /* Set summary */ if ((str = htsmsg_xml_get_cdata_str(tags, "summary"))) { save |= epg_episode_set_summary(episode, str, NULL, mod); } /* Number */ if (htsmsg_xml_get_cdata_u32(tags, "number", &u32) == 0) { save |= epg_episode_set_number(episode, u32, mod); } if (!htsmsg_xml_get_cdata_u32(tags, "part-number", &pn)) { pc = 0; htsmsg_xml_get_cdata_u32(tags, "part-count", &pc); save |= epg_episode_set_part(episode, pn, pc, mod); } /* Set image */ if ((str = htsmsg_xml_get_cdata_str(tags, "image"))) { save |= epg_episode_set_image(episode, str, mod); } else if ((str = htsmsg_xml_get_cdata_str(tags, "thumb"))) { save |= epg_episode_set_image(episode, str, mod); } /* Genre */ if ((egl = _pyepg_parse_genre(tags))) { save |= epg_episode_set_genre(episode, egl, mod); epg_genre_list_destroy(egl); } /* Content */ if ((htsmsg_get_map(tags, "blackandwhite"))) save |= epg_episode_set_is_bw(episode, 1, mod); if (save) stats->episodes.modified++; return save; }
static void satip_discovery_http_closed(http_client_t *hc, int errn) { satip_discovery_t *d = hc->hc_aux; char *s; htsmsg_t *xml = NULL, *tags, *root, *device; const char *friendlyname, *manufacturer, *manufacturerURL, *modeldesc; const char *modelname, *modelnum, *serialnum; const char *presentation, *tunercfg, *udn, *uuid; const char *cs, *arg; satip_device_info_t info; char errbuf[100]; char *argv[10]; int i, n; s = http_arg_get(&hc->hc_args, "Content-Type"); if (s) { n = http_tokenize(s, argv, ARRAY_SIZE(argv), ';'); if (n <= 0 || strcasecmp(s, "text/xml")) { errn = ENOENT; s = NULL; } } if (errn != 0 || s == NULL || hc->hc_code != 200 || hc->hc_data_size == 0 || hc->hc_data == NULL) { tvhlog(LOG_ERR, "satip", "Cannot get %s: %s", d->location, strerror(errn)); return; } if (tvhtrace_enabled()) { tvhtrace("satip", "received XML description from %s", hc->hc_host); tvhlog_hexdump("satip", hc->hc_data, hc->hc_data_size); } if (d->myaddr == NULL || d->myaddr[0] == '\0') { struct sockaddr_storage ip; socklen_t addrlen = sizeof(ip); errbuf[0] = '\0'; getsockname(hc->hc_fd, (struct sockaddr *)&ip, &addrlen); inet_ntop(ip.ss_family, IP_IN_ADDR(ip), errbuf, sizeof(errbuf)); free(d->myaddr); d->myaddr = strdup(errbuf); } s = hc->hc_data + hc->hc_data_size - 1; while (s != hc->hc_data && *s != '/') s--; if (s != hc->hc_data) s--; if (strncmp(s, "</root>", 7)) return; /* Parse */ xml = htsmsg_xml_deserialize(hc->hc_data, errbuf, sizeof(errbuf)); hc->hc_data = NULL; if (!xml) { tvhlog(LOG_ERR, "satip_discovery_desc", "htsmsg_xml_deserialize error %s", errbuf); goto finish; } if ((tags = htsmsg_get_map(xml, "tags")) == NULL) goto finish; if ((root = htsmsg_get_map(tags, "root")) == NULL) goto finish; if ((device = htsmsg_get_map(root, "tags")) == NULL) goto finish; if ((device = htsmsg_get_map(device, "device")) == NULL) goto finish; if ((device = htsmsg_get_map(device, "tags")) == NULL) goto finish; if ((cs = htsmsg_xml_get_cdata_str(device, "deviceType")) == NULL) goto finish; if (strcmp(cs, "urn:ses-com:device:SatIPServer:1")) goto finish; if ((friendlyname = htsmsg_xml_get_cdata_str(device, "friendlyName")) == NULL) goto finish; if ((manufacturer = htsmsg_xml_get_cdata_str(device, "manufacturer")) == NULL) goto finish; if ((manufacturerURL = htsmsg_xml_get_cdata_str(device, "manufacturerURL")) == NULL) manufacturerURL = ""; if ((modeldesc = htsmsg_xml_get_cdata_str(device, "modelDescription")) == NULL) modeldesc = ""; if ((modelname = htsmsg_xml_get_cdata_str(device, "modelName")) == NULL) goto finish; if ((modelnum = htsmsg_xml_get_cdata_str(device, "modelNumber")) == NULL) modelnum = ""; if ((serialnum = htsmsg_xml_get_cdata_str(device, "serialNumber")) == NULL) serialnum = ""; if ((presentation = htsmsg_xml_get_cdata_str(device, "presentationURL")) == NULL) presentation = ""; if ((udn = htsmsg_xml_get_cdata_str(device, "UDN")) == NULL) goto finish; if ((tunercfg = htsmsg_xml_get_cdata_str(device, "urn:ses-com:satipX_SATIPCAP")) == NULL) tunercfg = ""; uuid = NULL; n = http_tokenize((char *)udn, argv, ARRAY_SIZE(argv), ':'); for (i = 0; i < n+1; i++) if (argv[i] && strcmp(argv[i], "uuid") == 0) { uuid = argv[++i]; break; } if (uuid == NULL || (d->uuid[0] && strcmp(uuid, d->uuid))) goto finish; info.rtsp_port = 554; info.srcs = 4; arg = http_arg_get(&hc->hc_args, "X-SATIP-RTSP-Port"); if (arg) { i = atoi(arg); if (i > 0 && i < 65535) info.rtsp_port = i; } arg = http_arg_get(&hc->hc_args, "X-SATIP-Sources"); if (arg) { i = atoi(arg); if (i > 0 && i < 128) info.srcs = i; } info.myaddr = strdup(d->myaddr); info.addr = strdup(d->url.host); info.uuid = strdup(uuid); info.bootid = strdup(d->bootid); info.configid = strdup(d->configid); info.deviceid = strdup(d->deviceid); info.location = strdup(d->location); info.server = strdup(d->server); info.friendlyname = strdup(friendlyname); info.manufacturer = strdup(manufacturer); info.manufacturerURL = strdup(manufacturerURL); info.modeldesc = strdup(modeldesc); info.modelname = strdup(modelname); info.modelnum = strdup(modelnum); info.serialnum = strdup(serialnum); info.presentation = strdup(presentation); info.tunercfg = strdup(tunercfg); htsmsg_destroy(xml); xml = NULL; pthread_mutex_lock(&global_lock); if (!satip_device_find(info.uuid)) satip_device_create(&info); pthread_mutex_unlock(&global_lock); free(info.myaddr); free(info.location); free(info.server); free(info.addr); free(info.uuid); free(info.bootid); free(info.configid); free(info.deviceid); free(info.friendlyname); free(info.manufacturer); free(info.manufacturerURL); free(info.modeldesc); free(info.modelname); free(info.modelnum); free(info.serialnum); free(info.presentation); free(info.tunercfg); finish: htsmsg_destroy(xml); }