|
25 | 25 | import static org.schabi.newpipe.extractor.utils.Utils.HTTPS; |
26 | 26 | import static org.schabi.newpipe.extractor.utils.Utils.getStringResultFromRegexArray; |
27 | 27 | import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; |
| 28 | +import static org.schabi.newpipe.extractor.utils.Utils.replaceHttpWithHttps; |
28 | 29 |
|
29 | 30 | import com.grack.nanojson.JsonArray; |
30 | 31 | import com.grack.nanojson.JsonBuilder; |
31 | 32 | import com.grack.nanojson.JsonObject; |
32 | 33 | import com.grack.nanojson.JsonParser; |
33 | 34 | import com.grack.nanojson.JsonParserException; |
34 | 35 | import com.grack.nanojson.JsonWriter; |
35 | | -import org.jsoup.nodes.Entities; |
36 | 36 |
|
| 37 | +import org.jsoup.nodes.Entities; |
37 | 38 | import org.schabi.newpipe.extractor.Image; |
38 | 39 | import org.schabi.newpipe.extractor.Image.ResolutionLevel; |
39 | 40 | import org.schabi.newpipe.extractor.MetaInfo; |
|
71 | 72 | import java.util.Optional; |
72 | 73 | import java.util.Random; |
73 | 74 | import java.util.Set; |
| 75 | +import java.util.function.Consumer; |
74 | 76 | import java.util.regex.Pattern; |
75 | 77 | import java.util.stream.Collectors; |
76 | 78 | import java.util.stream.Stream; |
@@ -1080,6 +1082,16 @@ public static String getAttributedDescription( |
1080 | 1082 | .replaceAll(" {2}", " "); |
1081 | 1083 | } |
1082 | 1084 |
|
| 1085 | + @Nonnull |
| 1086 | + public static String getTextFromObjectOrThrow(final JsonObject textObject, final String error) |
| 1087 | + throws ParsingException { |
| 1088 | + final String result = getTextFromObject(textObject); |
| 1089 | + if (result == null) { |
| 1090 | + throw new ParsingException("Could not extract text: " + error); |
| 1091 | + } |
| 1092 | + return result; |
| 1093 | + } |
| 1094 | + |
1083 | 1095 | @Nullable |
1084 | 1096 | public static String getTextFromObject(final JsonObject textObject) { |
1085 | 1097 | return getTextFromObject(textObject, false); |
@@ -1664,11 +1676,16 @@ public static List<MetaInfo> getMetaInfo(@Nonnull final JsonArray contents) |
1664 | 1676 | .getObject("infoPanelContentRenderer"))); |
1665 | 1677 | } |
1666 | 1678 | if (sectionContent.has("clarificationRenderer")) { |
1667 | | - metaInfo.add(getClarificationRendererContent(sectionContent |
| 1679 | + metaInfo.add(getClarificationRenderer(sectionContent |
1668 | 1680 | .getObject("clarificationRenderer") |
1669 | 1681 | )); |
1670 | 1682 | } |
1671 | | - |
| 1683 | + if (sectionContent.has("emergencyOneboxRenderer")) { |
| 1684 | + getEmergencyOneboxRenderer( |
| 1685 | + sectionContent.getObject("emergencyOneboxRenderer"), |
| 1686 | + metaInfo::add |
| 1687 | + ); |
| 1688 | + } |
1672 | 1689 | } |
1673 | 1690 | } |
1674 | 1691 | } |
@@ -1709,7 +1726,7 @@ private static MetaInfo getInfoPanelContent(@Nonnull final JsonObject infoPanelC |
1709 | 1726 | } |
1710 | 1727 |
|
1711 | 1728 | @Nonnull |
1712 | | - private static MetaInfo getClarificationRendererContent( |
| 1729 | + private static MetaInfo getClarificationRenderer( |
1713 | 1730 | @Nonnull final JsonObject clarificationRenderer) throws ParsingException { |
1714 | 1731 | final MetaInfo metaInfo = new MetaInfo(); |
1715 | 1732 |
|
@@ -1762,6 +1779,55 @@ private static MetaInfo getClarificationRendererContent( |
1762 | 1779 | return metaInfo; |
1763 | 1780 | } |
1764 | 1781 |
|
| 1782 | + @Nonnull |
| 1783 | + private static void getEmergencyOneboxRenderer( |
| 1784 | + @Nonnull final JsonObject emergencyOneboxRenderer, |
| 1785 | + final Consumer<MetaInfo> addMetaInfo |
| 1786 | + ) throws ParsingException { |
| 1787 | + final List<JsonObject> supportRenderers = emergencyOneboxRenderer.entrySet().stream() |
| 1788 | + .filter((a) -> a.getValue() instanceof JsonObject |
| 1789 | + && ((JsonObject) a.getValue()).has("singleActionEmergencySupportRenderer")) |
| 1790 | + .map((a) -> ((JsonObject) a.getValue()) |
| 1791 | + .getObject("singleActionEmergencySupportRenderer")) |
| 1792 | + .collect(Collectors.toList()); |
| 1793 | + |
| 1794 | + if (supportRenderers.isEmpty()) { |
| 1795 | + throw new ParsingException("Could not extract any meta info from emergency renderer"); |
| 1796 | + } |
| 1797 | + |
| 1798 | + for (final JsonObject r : supportRenderers) { |
| 1799 | + final MetaInfo metaInfo = new MetaInfo(); |
| 1800 | + |
| 1801 | + // usually an encouragement like "We are with you" |
| 1802 | + final String title = getTextFromObjectOrThrow(r.getObject("title"), "title"); |
| 1803 | + // usually a phone number |
| 1804 | + final String action = getTextFromObjectOrThrow(r.getObject("actionText"), "action"); |
| 1805 | + // usually details about the phone number |
| 1806 | + final String details = getTextFromObjectOrThrow(r.getObject("detailsText"), "details"); |
| 1807 | + // usually the name of an association |
| 1808 | + final String urlText = getTextFromObjectOrThrow(r.getObject("navigationText"), |
| 1809 | + "urlText"); |
| 1810 | + |
| 1811 | + metaInfo.setTitle(title); |
| 1812 | + metaInfo.setContent(new Description(details + "\n" + action, Description.PLAIN_TEXT)); |
| 1813 | + metaInfo.addUrlText(urlText); |
| 1814 | + |
| 1815 | + // usually the webpage of the association |
| 1816 | + final String url = getUrlFromNavigationEndpoint(r.getObject("navigationEndpoint")); |
| 1817 | + if (url == null) { |
| 1818 | + throw new ParsingException("Could not extract emergency renderer url"); |
| 1819 | + } |
| 1820 | + |
| 1821 | + try { |
| 1822 | + metaInfo.addUrl(new URL(replaceHttpWithHttps(url))); |
| 1823 | + } catch (final MalformedURLException e) { |
| 1824 | + throw new ParsingException("Could not parse emergency renderer url", e); |
| 1825 | + } |
| 1826 | + |
| 1827 | + addMetaInfo.accept(metaInfo); |
| 1828 | + } |
| 1829 | + } |
| 1830 | + |
1765 | 1831 | /** |
1766 | 1832 | * Sometimes, YouTube provides URLs which use Google's cache. They look like |
1767 | 1833 | * {@code https://webcache.googleusercontent.com/search?q=cache:CACHED_URL} |
|
0 commit comments