Remove useless code
This commit is contained in:
parent
dd4dd849dc
commit
02b59903fa
|
@ -34,7 +34,6 @@ public class YoutubePlaylistExtractor extends PlaylistExtractor {
|
||||||
private JsonObject initialData;
|
private JsonObject initialData;
|
||||||
private JsonObject uploaderInfo;
|
private JsonObject uploaderInfo;
|
||||||
private JsonObject playlistInfo;
|
private JsonObject playlistInfo;
|
||||||
private JsonObject playlistVideos;
|
|
||||||
|
|
||||||
public YoutubePlaylistExtractor(StreamingService service, ListLinkHandler linkHandler) {
|
public YoutubePlaylistExtractor(StreamingService service, ListLinkHandler linkHandler) {
|
||||||
super(service, linkHandler);
|
super(service, linkHandler);
|
||||||
|
@ -48,7 +47,6 @@ public class YoutubePlaylistExtractor extends PlaylistExtractor {
|
||||||
initialData = YoutubeParsingHelper.getInitialData(response.responseBody());
|
initialData = YoutubeParsingHelper.getInitialData(response.responseBody());
|
||||||
uploaderInfo = getUploaderInfo();
|
uploaderInfo = getUploaderInfo();
|
||||||
playlistInfo = getPlaylistInfo();
|
playlistInfo = getPlaylistInfo();
|
||||||
playlistVideos = getPlaylistVideos();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonObject getUploaderInfo() throws ParsingException {
|
private JsonObject getUploaderInfo() throws ParsingException {
|
||||||
|
@ -83,19 +81,8 @@ public class YoutubePlaylistExtractor extends PlaylistExtractor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonObject getPlaylistVideos() throws ParsingException {
|
|
||||||
try {
|
|
||||||
return initialData.getObject("contents").getObject("twoColumnBrowseResultsRenderer")
|
|
||||||
.getArray("tabs").getObject(0).getObject("tabRenderer").getObject("content").getObject("sectionListRenderer")
|
|
||||||
.getArray("contents").getObject(0).getObject("itemSectionRenderer").getArray("contents")
|
|
||||||
.getObject(0).getObject("playlistVideoListRenderer");
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ParsingException("Could not get playlist info", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNextPageUrl() throws ExtractionException {
|
public String getNextPageUrl() {
|
||||||
return getNextPageUrlFrom(initialData.getObject("contents").getObject("twoColumnBrowseResultsRenderer")
|
return getNextPageUrlFrom(initialData.getObject("contents").getObject("twoColumnBrowseResultsRenderer")
|
||||||
.getArray("tabs").getObject(0).getObject("tabRenderer").getObject("content")
|
.getArray("tabs").getObject(0).getObject("tabRenderer").getObject("content")
|
||||||
.getObject("sectionListRenderer").getArray("contents").getObject(0)
|
.getObject("sectionListRenderer").getArray("contents").getObject(0)
|
||||||
|
@ -177,7 +164,7 @@ public class YoutubePlaylistExtractor extends PlaylistExtractor {
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public InfoItemsPage<StreamInfoItem> getInitialPage() throws ExtractionException {
|
public InfoItemsPage<StreamInfoItem> getInitialPage() {
|
||||||
StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
||||||
|
|
||||||
JsonArray videos = initialData.getObject("contents").getObject("twoColumnBrowseResultsRenderer")
|
JsonArray videos = initialData.getObject("contents").getObject("twoColumnBrowseResultsRenderer")
|
||||||
|
|
|
@ -17,7 +17,6 @@ import org.schabi.newpipe.extractor.localization.TimeAgoParser;
|
||||||
import org.schabi.newpipe.extractor.search.InfoItemsSearchCollector;
|
import org.schabi.newpipe.extractor.search.InfoItemsSearchCollector;
|
||||||
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
||||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeParsingHelper;
|
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeParsingHelper;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -147,7 +146,7 @@ public class YoutubeSearchExtractor extends SearchExtractor {
|
||||||
return new InfoItemsPage<>(collector, getNextPageUrlFrom(itemSectionRenderer.getArray("continuations")));
|
return new InfoItemsPage<>(collector, getNextPageUrlFrom(itemSectionRenderer.getArray("continuations")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectStreamsFrom(InfoItemsSearchCollector collector, JsonArray videos) throws NothingFoundException, ParsingException {
|
private void collectStreamsFrom(InfoItemsSearchCollector collector, JsonArray videos) throws NothingFoundException {
|
||||||
collector.reset();
|
collector.reset();
|
||||||
|
|
||||||
final TimeAgoParser timeAgoParser = getTimeAgoParser();
|
final TimeAgoParser timeAgoParser = getTimeAgoParser();
|
||||||
|
|
|
@ -3,7 +3,6 @@ package org.schabi.newpipe.extractor.services.youtube.extractors;
|
||||||
import com.grack.nanojson.JsonArray;
|
import com.grack.nanojson.JsonArray;
|
||||||
import com.grack.nanojson.JsonObject;
|
import com.grack.nanojson.JsonObject;
|
||||||
import com.grack.nanojson.JsonParser;
|
import com.grack.nanojson.JsonParser;
|
||||||
import com.grack.nanojson.JsonParserException;
|
|
||||||
|
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.jsoup.nodes.Document;
|
import org.jsoup.nodes.Document;
|
||||||
|
@ -15,7 +14,6 @@ import org.schabi.newpipe.extractor.MediaFormat;
|
||||||
import org.schabi.newpipe.extractor.NewPipe;
|
import org.schabi.newpipe.extractor.NewPipe;
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
import org.schabi.newpipe.extractor.downloader.Downloader;
|
import org.schabi.newpipe.extractor.downloader.Downloader;
|
||||||
import org.schabi.newpipe.extractor.downloader.Request;
|
|
||||||
import org.schabi.newpipe.extractor.downloader.Response;
|
import org.schabi.newpipe.extractor.downloader.Response;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
|
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
|
||||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||||
|
@ -36,7 +34,6 @@ import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||||
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
|
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
|
||||||
import org.schabi.newpipe.extractor.stream.VideoStream;
|
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||||
import org.schabi.newpipe.extractor.utils.JsonUtils;
|
|
||||||
import org.schabi.newpipe.extractor.utils.Parser;
|
import org.schabi.newpipe.extractor.utils.Parser;
|
||||||
import org.schabi.newpipe.extractor.utils.Utils;
|
import org.schabi.newpipe.extractor.utils.Utils;
|
||||||
|
|
||||||
|
@ -366,55 +363,6 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getLiveStreamWatchingCount() throws ExtractionException, IOException, JsonParserException {
|
|
||||||
// https://www.youtube.com/youtubei/v1/updated_metadata?alt=json&key=
|
|
||||||
String innerTubeKey = null, clientVersion = null;
|
|
||||||
if (playerArgs != null && !playerArgs.isEmpty()) {
|
|
||||||
innerTubeKey = playerArgs.getString("innertube_api_key");
|
|
||||||
clientVersion = playerArgs.getString("innertube_context_client_version");
|
|
||||||
} else if (!videoInfoPage.isEmpty()) {
|
|
||||||
innerTubeKey = videoInfoPage.get("innertube_api_key");
|
|
||||||
clientVersion = videoInfoPage.get("innertube_context_client_version");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (innerTubeKey == null || innerTubeKey.isEmpty()) {
|
|
||||||
throw new ExtractionException("Couldn't get innerTube key");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clientVersion == null || clientVersion.isEmpty()) {
|
|
||||||
throw new ExtractionException("Couldn't get innerTube client version");
|
|
||||||
}
|
|
||||||
|
|
||||||
final String metadataUrl = "https://www.youtube.com/youtubei/v1/updated_metadata?alt=json&key=" + innerTubeKey;
|
|
||||||
final byte[] dataBody = ("{\"context\":{\"client\":{\"clientName\":1,\"clientVersion\":\"" + clientVersion + "\"}}" +
|
|
||||||
",\"videoId\":\"" + getId() + "\"}").getBytes("UTF-8");
|
|
||||||
final Response response = getDownloader().execute(Request.newBuilder()
|
|
||||||
.post(metadataUrl, dataBody)
|
|
||||||
.addHeader("Content-Type", "application/json")
|
|
||||||
.build());
|
|
||||||
final JsonObject jsonObject = JsonParser.object().from(response.responseBody());
|
|
||||||
|
|
||||||
for (Object actionEntry : jsonObject.getArray("actions")) {
|
|
||||||
if (!(actionEntry instanceof JsonObject)) continue;
|
|
||||||
final JsonObject entry = (JsonObject) actionEntry;
|
|
||||||
|
|
||||||
final JsonObject updateViewershipAction = entry.getObject("updateViewershipAction", null);
|
|
||||||
if (updateViewershipAction == null) continue;
|
|
||||||
|
|
||||||
final JsonArray viewCountRuns = JsonUtils.getArray(updateViewershipAction, "viewership.videoViewCountRenderer.viewCount.runs");
|
|
||||||
if (viewCountRuns.isEmpty()) continue;
|
|
||||||
|
|
||||||
final JsonObject textObject = viewCountRuns.getObject(0);
|
|
||||||
if (!textObject.has("text")) {
|
|
||||||
throw new ExtractionException("Response don't have \"text\" element");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Long.parseLong(Utils.removeNonDigitCharacters(textObject.getString("text")));
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new ExtractionException("Could not find correct results in response");
|
|
||||||
}
|
|
||||||
|
|
||||||
private JsonObject getVideoPrimaryInfoRenderer() throws ParsingException {
|
private JsonObject getVideoPrimaryInfoRenderer() throws ParsingException {
|
||||||
JsonArray contents = initialData.getObject("contents").getObject("twoColumnWatchNextResults")
|
JsonArray contents = initialData.getObject("contents").getObject("twoColumnWatchNextResults")
|
||||||
.getObject("results").getObject("results").getArray("contents");
|
.getObject("results").getObject("results").getArray("contents");
|
||||||
|
@ -525,7 +473,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
public String getUploaderAvatarUrl() throws ParsingException {
|
public String getUploaderAvatarUrl() throws ParsingException {
|
||||||
assertPageFetched();
|
assertPageFetched();
|
||||||
|
|
||||||
String uploaderAvatarUrl = null;
|
String uploaderAvatarUrl;
|
||||||
try {
|
try {
|
||||||
uploaderAvatarUrl = initialData.getObject("contents").getObject("twoColumnWatchNextResults").getObject("secondaryResults")
|
uploaderAvatarUrl = initialData.getObject("contents").getObject("twoColumnWatchNextResults").getObject("secondaryResults")
|
||||||
.getObject("secondaryResults").getArray("results").getObject(0).getObject("compactAutoplayRenderer")
|
.getObject("secondaryResults").getArray("results").getObject(0).getObject("compactAutoplayRenderer")
|
||||||
|
@ -657,13 +605,13 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public List<SubtitlesStream> getSubtitlesDefault() throws IOException, ExtractionException {
|
public List<SubtitlesStream> getSubtitlesDefault() {
|
||||||
return getSubtitles(MediaFormat.TTML);
|
return getSubtitles(MediaFormat.TTML);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public List<SubtitlesStream> getSubtitles(final MediaFormat format) throws IOException, ExtractionException {
|
public List<SubtitlesStream> getSubtitles(final MediaFormat format) {
|
||||||
assertPageFetched();
|
assertPageFetched();
|
||||||
List<SubtitlesStream> subtitles = new ArrayList<>();
|
List<SubtitlesStream> subtitles = new ArrayList<>();
|
||||||
for (final SubtitlesInfo subtitlesInfo : subtitlesInfos) {
|
for (final SubtitlesInfo subtitlesInfo : subtitlesInfos) {
|
||||||
|
@ -687,7 +635,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StreamInfoItem getNextStream() throws IOException, ExtractionException {
|
public StreamInfoItem getNextStream() throws ExtractionException {
|
||||||
assertPageFetched();
|
assertPageFetched();
|
||||||
try {
|
try {
|
||||||
final JsonObject videoInfo = initialData.getObject("contents").getObject("twoColumnWatchNextResults")
|
final JsonObject videoInfo = initialData.getObject("contents").getObject("twoColumnWatchNextResults")
|
||||||
|
@ -815,12 +763,10 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
return JsonParser.object().from(ytPlayerConfigRaw);
|
return JsonParser.object().from(ytPlayerConfigRaw);
|
||||||
} catch (Parser.RegexException e) {
|
} catch (Parser.RegexException e) {
|
||||||
String errorReason = getErrorMessage();
|
String errorReason = getErrorMessage();
|
||||||
switch (errorReason) {
|
if (errorReason.isEmpty()) {
|
||||||
case "":
|
throw new ContentNotAvailableException("Content not available: player config empty", e);
|
||||||
throw new ContentNotAvailableException("Content not available: player config empty", e);
|
|
||||||
default:
|
|
||||||
throw new ContentNotAvailableException("Content not available", e);
|
|
||||||
}
|
}
|
||||||
|
throw new ContentNotAvailableException("Content not available", e);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ParsingException("Could not parse yt player config", e);
|
throw new ParsingException("Could not parse yt player config", e);
|
||||||
}
|
}
|
||||||
|
@ -976,7 +922,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private List<SubtitlesInfo> getAvailableSubtitlesInfo() throws SubtitlesException {
|
private List<SubtitlesInfo> getAvailableSubtitlesInfo() {
|
||||||
// If the video is age restricted getPlayerConfig will fail
|
// If the video is age restricted getPlayerConfig will fail
|
||||||
if (isAgeRestricted) return Collections.emptyList();
|
if (isAgeRestricted) return Collections.emptyList();
|
||||||
|
|
||||||
|
@ -990,7 +936,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
final JsonObject renderer = captions.getObject("playerCaptionsTracklistRenderer", new JsonObject());
|
final JsonObject renderer = captions.getObject("playerCaptionsTracklistRenderer", new JsonObject());
|
||||||
final JsonArray captionsArray = renderer.getArray("captionTracks", new JsonArray());
|
final JsonArray captionsArray = renderer.getArray("captionTracks", new JsonArray());
|
||||||
// todo: use this to apply auto translation to different language from a source language
|
// todo: use this to apply auto translation to different language from a source language
|
||||||
final JsonArray autoCaptionsArray = renderer.getArray("translationLanguages", new JsonArray());
|
// final JsonArray autoCaptionsArray = renderer.getArray("translationLanguages", new JsonArray());
|
||||||
|
|
||||||
// This check is necessary since there may be cases where subtitles metadata do not contain caption track info
|
// This check is necessary since there may be cases where subtitles metadata do not contain caption track info
|
||||||
// e.g. https://www.youtube.com/watch?v=-Vpwatutnko
|
// e.g. https://www.youtube.com/watch?v=-Vpwatutnko
|
||||||
|
@ -1147,40 +1093,44 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getHost() throws ParsingException {
|
public String getHost() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getPrivacy() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getLicence() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPrivacy() throws ParsingException {
|
public Locale getLanguageInfo() {
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCategory() throws ParsingException {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLicence() throws ParsingException {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Locale getLanguageInfo() throws ParsingException {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public List<String> getTags() throws ParsingException {
|
public List<String> getTags() {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public String getSupportInfo() throws ParsingException {
|
public String getSupportInfo() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,7 @@ package org.schabi.newpipe.extractor.services.youtube.extractors;
|
||||||
|
|
||||||
import com.grack.nanojson.JsonArray;
|
import com.grack.nanojson.JsonArray;
|
||||||
import com.grack.nanojson.JsonObject;
|
import com.grack.nanojson.JsonObject;
|
||||||
import com.grack.nanojson.JsonParser;
|
|
||||||
import com.grack.nanojson.JsonParserException;
|
|
||||||
|
|
||||||
import org.jsoup.nodes.Document;
|
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
import org.schabi.newpipe.extractor.downloader.Downloader;
|
import org.schabi.newpipe.extractor.downloader.Downloader;
|
||||||
import org.schabi.newpipe.extractor.downloader.Response;
|
import org.schabi.newpipe.extractor.downloader.Response;
|
||||||
|
@ -37,15 +34,12 @@ import org.schabi.newpipe.extractor.localization.TimeAgoParser;
|
||||||
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeParsingHelper;
|
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeParsingHelper;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||||
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
|
||||||
import org.schabi.newpipe.extractor.utils.Parser;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class YoutubeTrendingExtractor extends KioskExtractor<StreamInfoItem> {
|
public class YoutubeTrendingExtractor extends KioskExtractor<StreamInfoItem> {
|
||||||
|
|
||||||
private Document doc;
|
|
||||||
private JsonObject initialData;
|
private JsonObject initialData;
|
||||||
|
|
||||||
public YoutubeTrendingExtractor(StreamingService service,
|
public YoutubeTrendingExtractor(StreamingService service,
|
||||||
|
@ -60,7 +54,6 @@ public class YoutubeTrendingExtractor extends KioskExtractor<StreamInfoItem> {
|
||||||
"?gl=" + getExtractorContentCountry().getCountryCode();
|
"?gl=" + getExtractorContentCountry().getCountryCode();
|
||||||
|
|
||||||
final Response response = downloader.get(url, getExtractorLocalization());
|
final Response response = downloader.get(url, getExtractorLocalization());
|
||||||
doc = YoutubeParsingHelper.parseAndCheckPage(url, response);
|
|
||||||
initialData = YoutubeParsingHelper.getInitialData(response.responseBody());
|
initialData = YoutubeParsingHelper.getInitialData(response.responseBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +85,7 @@ public class YoutubeTrendingExtractor extends KioskExtractor<StreamInfoItem> {
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public InfoItemsPage<StreamInfoItem> getInitialPage() throws ParsingException {
|
public InfoItemsPage<StreamInfoItem> getInitialPage() {
|
||||||
StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId());
|
||||||
JsonArray firstPageElements = initialData.getObject("contents").getObject("twoColumnBrowseResultsRenderer")
|
JsonArray firstPageElements = initialData.getObject("contents").getObject("twoColumnBrowseResultsRenderer")
|
||||||
.getArray("tabs").getObject(0).getObject("tabRenderer").getObject("content")
|
.getArray("tabs").getObject(0).getObject("tabRenderer").getObject("content")
|
||||||
|
|
Loading…
Reference in New Issue