Introduce class that indicates when the time ago is an approximation

This commit is contained in:
Mauricio Colli 2019-11-03 15:45:25 -03:00
parent 6ca4c8986a
commit 3d21ef5dba
No known key found for this signature in database
GPG Key ID: F200BFD6F29DDD85
22 changed files with 139 additions and 92 deletions

View File

@ -1,8 +1,9 @@
package org.schabi.newpipe.extractor.comments; package org.schabi.newpipe.extractor.comments;
import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import java.util.Calendar; import javax.annotation.Nullable;
public class CommentsInfoItem extends InfoItem { public class CommentsInfoItem extends InfoItem {
@ -12,7 +13,7 @@ public class CommentsInfoItem extends InfoItem {
private String authorThumbnail; private String authorThumbnail;
private String authorEndpoint; private String authorEndpoint;
private String textualPublishedTime; private String textualPublishedTime;
private Calendar publishedTime; @Nullable private DateWrapper publishedTime;
private int likeCount; private int likeCount;
public CommentsInfoItem(int serviceId, String url, String name) { public CommentsInfoItem(int serviceId, String url, String name) {
@ -67,11 +68,12 @@ public class CommentsInfoItem extends InfoItem {
this.textualPublishedTime = textualPublishedTime; this.textualPublishedTime = textualPublishedTime;
} }
public Calendar getPublishedTime() { @Nullable
public DateWrapper getPublishedTime() {
return publishedTime; return publishedTime;
} }
public void setPublishedTime(Calendar publishedTime) { public void setPublishedTime(@Nullable DateWrapper publishedTime) {
this.publishedTime = publishedTime; this.publishedTime = publishedTime;
} }

View File

@ -2,8 +2,9 @@ package org.schabi.newpipe.extractor.comments;
import org.schabi.newpipe.extractor.InfoItemExtractor; import org.schabi.newpipe.extractor.InfoItemExtractor;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import java.util.Calendar; import javax.annotation.Nullable;
public interface CommentsInfoItemExtractor extends InfoItemExtractor { public interface CommentsInfoItemExtractor extends InfoItemExtractor {
String getCommentId() throws ParsingException; String getCommentId() throws ParsingException;
@ -12,6 +13,7 @@ public interface CommentsInfoItemExtractor extends InfoItemExtractor {
String getAuthorThumbnail() throws ParsingException; String getAuthorThumbnail() throws ParsingException;
String getAuthorEndpoint() throws ParsingException; String getAuthorEndpoint() throws ParsingException;
String getTextualPublishedTime() throws ParsingException; String getTextualPublishedTime() throws ParsingException;
Calendar getPublishedTime() throws ParsingException; @Nullable
DateWrapper getPublishedTime() throws ParsingException;
int getLikeCount() throws ParsingException; int getLikeCount() throws ParsingException;
} }

View File

@ -0,0 +1,39 @@
package org.schabi.newpipe.extractor.localization;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.io.Serializable;
import java.util.Calendar;
/**
* A wrapper class that provides a field to describe if the date is precise or just an approximation.
*/
public class DateWrapper implements Serializable {
@NonNull private final Calendar date;
private final boolean isApproximation;
public DateWrapper(@NonNull Calendar date) {
this(date, false);
}
public DateWrapper(@NonNull Calendar date, boolean isApproximation) {
this.date = date;
this.isApproximation = isApproximation;
}
/**
* @return the wrapped date.
*/
@NonNull
public Calendar date() {
return date;
}
/**
* @return if the date is considered is precise or just an approximation (e.g. service only returns an approximation
* like 2 weeks ago instead of a precise date).
*/
public boolean isApproximation() {
return isApproximation;
}
}

View File

@ -31,15 +31,16 @@ public class TimeAgoParser {
} }
/** /**
* Parses a textual date in the format '2 days ago' into a Calendar representation. * Parses a textual date in the format '2 days ago' into a Calendar representation which is then wrapped in a
* Beginning with weeks ago, marks the date as approximated by setting minutes, seconds * {@link DateWrapper} object.
* and milliseconds to 0. * <p>
* Beginning with days ago, the date is considered as an approximation.
* *
* @param textualDate The original date as provided by the streaming service * @param textualDate The original date as provided by the streaming service
* @return The parsed (approximated) time * @return The parsed time (can be approximated)
* @throws ParsingException if the time unit could not be recognized * @throws ParsingException if the time unit could not be recognized
*/ */
public Calendar parse(String textualDate) throws ParsingException { public DateWrapper parse(String textualDate) throws ParsingException {
for (Map.Entry<TimeAgoUnit, Map<String, Integer>> caseUnitEntry : patternsHolder.specialCases().entrySet()) { for (Map.Entry<TimeAgoUnit, Map<String, Integer>> caseUnitEntry : patternsHolder.specialCases().entrySet()) {
final TimeAgoUnit timeAgoUnit = caseUnitEntry.getKey(); final TimeAgoUnit timeAgoUnit = caseUnitEntry.getKey();
for (Map.Entry<String, Integer> caseMapToAmountEntry : caseUnitEntry.getValue().entrySet()) { for (Map.Entry<String, Integer> caseMapToAmountEntry : caseUnitEntry.getValue().entrySet()) {
@ -47,7 +48,7 @@ public class TimeAgoParser {
final Integer caseAmount = caseMapToAmountEntry.getValue(); final Integer caseAmount = caseMapToAmountEntry.getValue();
if (textualDateMatches(textualDate, caseText)) { if (textualDateMatches(textualDate, caseText)) {
return getCalendar(caseAmount, timeAgoUnit); return getResultFor(caseAmount, timeAgoUnit);
} }
} }
} }
@ -61,8 +62,8 @@ public class TimeAgoParser {
timeAgoAmount = 1; timeAgoAmount = 1;
} }
TimeAgoUnit timeAgoUnit = parseTimeAgoUnit(textualDate); final TimeAgoUnit timeAgoUnit = parseTimeAgoUnit(textualDate);
return getCalendar(timeAgoAmount, timeAgoUnit); return getResultFor(timeAgoAmount, timeAgoUnit);
} }
private int parseTimeAgoAmount(String textualDate) throws NumberFormatException { private int parseTimeAgoAmount(String textualDate) throws NumberFormatException {
@ -110,8 +111,9 @@ public class TimeAgoParser {
} }
} }
private Calendar getCalendar(int timeAgoAmount, TimeAgoUnit timeAgoUnit) { private DateWrapper getResultFor(int timeAgoAmount, TimeAgoUnit timeAgoUnit) {
Calendar calendarTime = getNow(); final Calendar calendarTime = getNow();
boolean isApproximation = false;
switch (timeAgoUnit) { switch (timeAgoUnit) {
case SECONDS: case SECONDS:
@ -128,28 +130,32 @@ public class TimeAgoParser {
case DAYS: case DAYS:
calendarTime.add(Calendar.DAY_OF_MONTH, -timeAgoAmount); calendarTime.add(Calendar.DAY_OF_MONTH, -timeAgoAmount);
markApproximatedTime(calendarTime); isApproximation = true;
break; break;
case WEEKS: case WEEKS:
calendarTime.add(Calendar.WEEK_OF_YEAR, -timeAgoAmount); calendarTime.add(Calendar.WEEK_OF_YEAR, -timeAgoAmount);
markApproximatedTime(calendarTime); isApproximation = true;
break; break;
case MONTHS: case MONTHS:
calendarTime.add(Calendar.MONTH, -timeAgoAmount); calendarTime.add(Calendar.MONTH, -timeAgoAmount);
markApproximatedTime(calendarTime); isApproximation = true;
break; break;
case YEARS: case YEARS:
calendarTime.add(Calendar.YEAR, -timeAgoAmount); calendarTime.add(Calendar.YEAR, -timeAgoAmount);
// Prevent `PrettyTime` from showing '12 months ago'. // Prevent `PrettyTime` from showing '12 months ago'.
calendarTime.add(Calendar.DAY_OF_MONTH, -1); calendarTime.add(Calendar.DAY_OF_MONTH, -1);
markApproximatedTime(calendarTime); isApproximation = true;
break; break;
} }
return calendarTime; if (isApproximation) {
markApproximatedTime(calendarTime);
}
return new DateWrapper(calendarTime, isApproximation);
} }
private Calendar getNow() { private Calendar getNow() {

View File

@ -10,15 +10,12 @@ import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.stream.*; import org.schabi.newpipe.extractor.stream.*;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List; import java.util.List;
public class MediaCCCStreamExtractor extends StreamExtractor { public class MediaCCCStreamExtractor extends StreamExtractor {
@ -38,8 +35,8 @@ public class MediaCCCStreamExtractor extends StreamExtractor {
@Nonnull @Nonnull
@Override @Override
public Calendar getUploadDate() throws ParsingException { public DateWrapper getUploadDate() throws ParsingException {
return MediaCCCParsingHelper.parseDateFrom(getTextualUploadDate()); return new DateWrapper(MediaCCCParsingHelper.parseDateFrom(getTextualUploadDate()));
} }
@Nonnull @Nonnull

View File

@ -2,11 +2,12 @@ package org.schabi.newpipe.extractor.services.media_ccc.extractors.infoItems;
import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCParsingHelper; import org.schabi.newpipe.extractor.services.media_ccc.extractors.MediaCCCParsingHelper;
import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor; import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor;
import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.StreamType;
import java.util.Calendar; import javax.annotation.Nullable;
public class MediaCCCStreamInfoItemExtractor implements StreamInfoItemExtractor { public class MediaCCCStreamInfoItemExtractor implements StreamInfoItemExtractor {
@ -47,14 +48,16 @@ public class MediaCCCStreamInfoItemExtractor implements StreamInfoItemExtractor
return event.getString("conference_url"); return event.getString("conference_url");
} }
@Nullable
@Override @Override
public String getTextualUploadDate() throws ParsingException { public String getTextualUploadDate() throws ParsingException {
return event.getString("release_date"); return event.getString("release_date");
} }
@Nullable
@Override @Override
public Calendar getUploadDate() throws ParsingException { public DateWrapper getUploadDate() throws ParsingException {
return MediaCCCParsingHelper.parseDateFrom(getTextualUploadDate()); return new DateWrapper(MediaCCCParsingHelper.parseDateFrom(getTextualUploadDate()));
} }
@Override @Override

View File

@ -9,15 +9,14 @@ import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.stream.*; import org.schabi.newpipe.extractor.stream.*;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -58,8 +57,8 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
@Nonnull @Nonnull
@Override @Override
public Calendar getUploadDate() throws ParsingException { public DateWrapper getUploadDate() throws ParsingException {
return SoundcloudParsingHelper.parseDate(getTextualUploadDate()); return new DateWrapper(SoundcloudParsingHelper.parseDate(getTextualUploadDate()));
} }
@Nonnull @Nonnull

View File

@ -2,11 +2,10 @@ package org.schabi.newpipe.extractor.services.soundcloud;
import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor; import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor;
import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.StreamType;
import java.util.Calendar;
import static org.schabi.newpipe.extractor.utils.Utils.replaceHttpWithHttps; import static org.schabi.newpipe.extractor.utils.Utils.replaceHttpWithHttps;
public class SoundcloudStreamInfoItemExtractor implements StreamInfoItemExtractor { public class SoundcloudStreamInfoItemExtractor implements StreamInfoItemExtractor {
@ -48,8 +47,8 @@ public class SoundcloudStreamInfoItemExtractor implements StreamInfoItemExtracto
} }
@Override @Override
public Calendar getUploadDate() throws ParsingException { public DateWrapper getUploadDate() throws ParsingException {
return SoundcloudParsingHelper.parseDate(getTextualUploadDate()); return new DateWrapper(SoundcloudParsingHelper.parseDate(getTextualUploadDate()));
} }
private String getCreatedAt() { private String getCreatedAt() {

View File

@ -5,10 +5,11 @@ import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.comments.CommentsInfoItemExtractor; import org.schabi.newpipe.extractor.comments.CommentsInfoItemExtractor;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.localization.TimeAgoParser;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.utils.JsonUtils; import org.schabi.newpipe.extractor.utils.JsonUtils;
import org.schabi.newpipe.extractor.utils.Utils; import org.schabi.newpipe.extractor.utils.Utils;
import java.util.Calendar; import javax.annotation.Nullable;
public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtractor { public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtractor {
@ -55,8 +56,9 @@ public class YoutubeCommentsInfoItemExtractor implements CommentsInfoItemExtract
} }
} }
@Nullable
@Override @Override
public Calendar getPublishedTime() throws ParsingException { public DateWrapper getPublishedTime() throws ParsingException {
String textualPublishedTime = getTextualPublishedTime(); String textualPublishedTime = getTextualPublishedTime();
if (timeAgoParser != null && textualPublishedTime != null && !textualPublishedTime.isEmpty()) { if (timeAgoParser != null && textualPublishedTime != null && !textualPublishedTime.isEmpty()) {
return timeAgoParser.parse(textualPublishedTime); return timeAgoParser.parse(textualPublishedTime);

View File

@ -23,6 +23,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.localization.TimeAgoParser;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.services.youtube.ItagItem; import org.schabi.newpipe.extractor.services.youtube.ItagItem;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeParsingHelper; import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeParsingHelper;
import org.schabi.newpipe.extractor.stream.*; import org.schabi.newpipe.extractor.stream.*;
@ -134,14 +135,14 @@ public class YoutubeStreamExtractor extends StreamExtractor {
} }
@Override @Override
public Calendar getUploadDate() throws ParsingException { public DateWrapper getUploadDate() throws ParsingException {
final String textualUploadDate = getTextualUploadDate(); final String textualUploadDate = getTextualUploadDate();
if (textualUploadDate == null) { if (textualUploadDate == null) {
return null; return null;
} }
return YoutubeParsingHelper.parseDateFrom(textualUploadDate); return new DateWrapper(YoutubeParsingHelper.parseDateFrom(textualUploadDate));
} }
@Nonnull @Nonnull

View File

@ -4,6 +4,7 @@ import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.localization.TimeAgoParser;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeParsingHelper; import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeParsingHelper;
import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor; import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor;
import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.StreamType;
@ -141,6 +142,7 @@ public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
} }
} }
@Nullable
@Override @Override
public String getTextualUploadDate() throws ParsingException { public String getTextualUploadDate() throws ParsingException {
if (getStreamType().equals(StreamType.LIVE_STREAM)) { if (getStreamType().equals(StreamType.LIVE_STREAM)) {
@ -173,17 +175,15 @@ public class YoutubeStreamInfoItemExtractor implements StreamInfoItemExtractor {
} }
} }
@Nullable
@Override @Override
public Calendar getUploadDate() throws ParsingException { public DateWrapper getUploadDate() throws ParsingException {
if (getStreamType().equals(StreamType.LIVE_STREAM)) { if (getStreamType().equals(StreamType.LIVE_STREAM)) {
return null; return null;
} }
if (isVideoReminder()) { if (isVideoReminder()) {
final Calendar calendar = getDateFromReminder(); return new DateWrapper(getDateFromReminder());
if (calendar != null) {
return calendar;
}
} }
String textualUploadDate = getTextualUploadDate(); String textualUploadDate = getTextualUploadDate();

View File

@ -26,13 +26,12 @@ import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.utils.Parser; import org.schabi.newpipe.extractor.utils.Parser;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -72,7 +71,7 @@ public abstract class StreamExtractor extends Extractor {
* @see #getTextualUploadDate() * @see #getTextualUploadDate()
*/ */
@Nullable @Nullable
public abstract Calendar getUploadDate() throws ParsingException; public abstract DateWrapper getUploadDate() throws ParsingException;
/** /**
* This will return the url to the thumbnail of the stream. Try to return the medium resolution here. * This will return the url to the thumbnail of the stream. Try to return the medium resolution here.

View File

@ -1,19 +1,19 @@
package org.schabi.newpipe.extractor.stream; package org.schabi.newpipe.extractor.stream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import org.schabi.newpipe.extractor.Info; import org.schabi.newpipe.extractor.Info;
import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.InfoItem;
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.exceptions.ContentNotAvailableException; import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.utils.DashMpdParser; import org.schabi.newpipe.extractor.utils.DashMpdParser;
import org.schabi.newpipe.extractor.utils.ExtractorHelper; import org.schabi.newpipe.extractor.utils.ExtractorHelper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/* /*
* Created by Christian Schabesberger on 26.08.15. * Created by Christian Schabesberger on 26.08.15.
* *
@ -278,7 +278,7 @@ public class StreamInfo extends Info {
private StreamType streamType; private StreamType streamType;
private String thumbnailUrl = ""; private String thumbnailUrl = "";
private String textualUploadDate; private String textualUploadDate;
private Calendar uploadDate; private DateWrapper uploadDate;
private long duration = -1; private long duration = -1;
private int ageLimit = -1; private int ageLimit = -1;
private String description; private String description;
@ -342,11 +342,11 @@ public class StreamInfo extends Info {
this.textualUploadDate = textualUploadDate; this.textualUploadDate = textualUploadDate;
} }
public Calendar getUploadDate() { public DateWrapper getUploadDate() {
return uploadDate; return uploadDate;
} }
public void setUploadDate(Calendar uploadDate) { public void setUploadDate(DateWrapper uploadDate) {
this.uploadDate = uploadDate; this.uploadDate = uploadDate;
} }

View File

@ -21,9 +21,9 @@ package org.schabi.newpipe.extractor.stream;
*/ */
import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Calendar;
/** /**
* Info object for previews of unopened videos, eg search results, related videos * Info object for previews of unopened videos, eg search results, related videos
@ -33,7 +33,7 @@ public class StreamInfoItem extends InfoItem {
private String uploaderName; private String uploaderName;
private String textualUploadDate; private String textualUploadDate;
private Calendar uploadDate; @Nullable private DateWrapper uploadDate;
private long viewCount = -1; private long viewCount = -1;
private long duration = -1; private long duration = -1;
@ -80,10 +80,6 @@ public class StreamInfoItem extends InfoItem {
this.uploaderUrl = uploaderUrl; this.uploaderUrl = uploaderUrl;
} }
/**
* @return The original textual upload date as returned by the streaming service.
* @see #getUploadDate()
*/
@Nullable @Nullable
public String getTextualUploadDate() { public String getTextualUploadDate() {
return textualUploadDate; return textualUploadDate;
@ -93,16 +89,12 @@ public class StreamInfoItem extends InfoItem {
this.textualUploadDate = uploadDate; this.textualUploadDate = uploadDate;
} }
/**
* @return The (approximated) date and time this item was uploaded or {@code null}.
* @see #getTextualUploadDate()
*/
@Nullable @Nullable
public Calendar getUploadDate() { public DateWrapper getUploadDate() {
return uploadDate; return uploadDate;
} }
public void setUploadDate(Calendar uploadDate) { public void setUploadDate(@Nullable DateWrapper uploadDate) {
this.uploadDate = uploadDate; this.uploadDate = uploadDate;
} }

View File

@ -2,8 +2,9 @@ package org.schabi.newpipe.extractor.stream;
import org.schabi.newpipe.extractor.InfoItemExtractor; import org.schabi.newpipe.extractor.InfoItemExtractor;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import java.util.Calendar; import javax.annotation.Nullable;
/* /*
* Created by Christian Schabesberger on 28.02.16. * Created by Christian Schabesberger on 28.02.16.
@ -69,26 +70,27 @@ public interface StreamInfoItemExtractor extends InfoItemExtractor {
* The original textual date provided by the service. Should be used as a fallback if * The original textual date provided by the service. Should be used as a fallback if
* {@link #getUploadDate()} isn't provided by the service, or it fails for some reason. * {@link #getUploadDate()} isn't provided by the service, or it fails for some reason.
* *
* @return The original textual date provided by the service. * @return The original textual date provided by the service or {@code null} if not provided.
* @throws ParsingException if there is an error in the extraction * @throws ParsingException if there is an error in the extraction
* @see #getUploadDate() * @see #getUploadDate()
*/ */
@Nullable
String getTextualUploadDate() throws ParsingException; String getTextualUploadDate() throws ParsingException;
/** /**
* Extracts the upload date and time of this item and parses it. * Extracts the upload date and time of this item and parses it.
* <p> * <p>
* If the service doesn't provide an exact time, an approximation can be returned. * If the service doesn't provide an exact time, an approximation can be returned.
* The approximation should be marked by setting seconds and milliseconds to zero.
* <br> * <br>
* If the service doesn't provide any date at all, then {@code null} should be returned. * If the service doesn't provide any date at all, then {@code null} should be returned.
* </p> * </p>
* *
* @return The (approximated) date and time this item was uploaded or {@code null}. * @return The date and time (can be approximated) this item was uploaded or {@code null}.
* @throws ParsingException if there is an error in the extraction * @throws ParsingException if there is an error in the extraction
* or the extracted date couldn't be parsed. * or the extracted date couldn't be parsed.
* @see #getTextualUploadDate() * @see #getTextualUploadDate()
*/ */
Calendar getUploadDate() throws ParsingException; @Nullable
DateWrapper getUploadDate() throws ParsingException;
} }

View File

@ -2,6 +2,7 @@ package org.schabi.newpipe.extractor.services;
import org.schabi.newpipe.extractor.InfoItem; import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import java.util.Calendar; import java.util.Calendar;
@ -31,9 +32,9 @@ public final class DefaultTests {
final String textualUploadDate = streamInfoItem.getTextualUploadDate(); final String textualUploadDate = streamInfoItem.getTextualUploadDate();
if (textualUploadDate != null && !textualUploadDate.isEmpty()) { if (textualUploadDate != null && !textualUploadDate.isEmpty()) {
final Calendar uploadDate = streamInfoItem.getUploadDate(); final DateWrapper uploadDate = streamInfoItem.getUploadDate();
assertNotNull("No parsed upload date", uploadDate); assertNotNull("No parsed upload date", uploadDate);
assertTrue("Upload date not in the past", uploadDate.before(Calendar.getInstance())); assertTrue("Upload date not in the past", uploadDate.date().before(Calendar.getInstance()));
} }
} }

View File

@ -14,6 +14,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import static java.util.Objects.requireNonNull;
import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertEquals;
import static org.schabi.newpipe.extractor.ServiceList.MediaCCC; import static org.schabi.newpipe.extractor.ServiceList.MediaCCC;
@ -95,6 +96,6 @@ public class MediaCCCStreamExtractorTest implements BaseExtractorTest {
public void testGetUploadDate() throws ParsingException, ParseException { public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance(); final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2018-05-11")); instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2018-05-11"));
Assert.assertEquals(instance, extractor.getUploadDate()); assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
} }
} }

View File

@ -16,6 +16,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import static java.util.Objects.requireNonNull;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl; import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ServiceList.SoundCloud; import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
@ -80,7 +81,7 @@ public class SoundcloudStreamExtractorDefaultTest {
public void testGetUploadDate() throws ParsingException, ParseException { public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance(); final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss +0000").parse("2016/07/31 18:18:07 +0000")); instance.setTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss +0000").parse("2016/07/31 18:18:07 +0000"));
Assert.assertEquals(instance, extractor.getUploadDate()); assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
} }
@Test @Test

View File

@ -7,6 +7,7 @@ import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.channel.ChannelExtractor; import org.schabi.newpipe.extractor.channel.ChannelExtractor;
import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.Localization;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -61,9 +62,9 @@ public class YoutubeChannelLocalizationTest {
String debugMessage = "[" + String.format("%02d", i) + "] " String debugMessage = "[" + String.format("%02d", i) + "] "
+ currentLocalization.getLocalizationCode() + "" + item.getName() + currentLocalization.getLocalizationCode() + "" + item.getName()
+ "\n:::: " + item.getStreamType() + ", views = " + item.getViewCount(); + "\n:::: " + item.getStreamType() + ", views = " + item.getViewCount();
final Calendar uploadDate = item.getUploadDate(); final DateWrapper uploadDate = item.getUploadDate();
if (uploadDate != null) { if (uploadDate != null) {
String dateAsText = dateFormat.format(uploadDate.getTime()); String dateAsText = dateFormat.format(uploadDate.date().getTime());
debugMessage += "\n:::: " + item.getTextualUploadDate() + debugMessage += "\n:::: " + item.getTextualUploadDate() +
"\n:::: " + dateAsText; "\n:::: " + dateAsText;
} }
@ -102,17 +103,17 @@ public class YoutubeChannelLocalizationTest {
final StreamInfoItem referenceItem = referenceList.get(i); final StreamInfoItem referenceItem = referenceList.get(i);
final StreamInfoItem currentItem = currentList.get(i); final StreamInfoItem currentItem = currentList.get(i);
final Calendar referenceUploadDate = referenceItem.getUploadDate(); final DateWrapper referenceUploadDate = referenceItem.getUploadDate();
final Calendar currentUploadDate = currentItem.getUploadDate(); final DateWrapper currentUploadDate = currentItem.getUploadDate();
final String referenceDateString = referenceUploadDate == null ? "null" : final String referenceDateString = referenceUploadDate == null ? "null" :
dateFormat.format(referenceUploadDate.getTime()); dateFormat.format(referenceUploadDate.date().getTime());
final String currentDateString = currentUploadDate == null ? "null" : final String currentDateString = currentUploadDate == null ? "null" :
dateFormat.format(currentUploadDate.getTime()); dateFormat.format(currentUploadDate.date().getTime());
long difference = -1; long difference = -1;
if (referenceUploadDate != null && currentUploadDate != null) { if (referenceUploadDate != null && currentUploadDate != null) {
difference = Math.abs(referenceUploadDate.getTimeInMillis() - currentUploadDate.getTimeInMillis()); difference = Math.abs(referenceUploadDate.date().getTimeInMillis() - currentUploadDate.date().getTimeInMillis());
} }
final boolean areTimeEquals = difference < 5 * 60 * 1000L; final boolean areTimeEquals = difference < 5 * 60 * 1000L;

View File

@ -1,7 +1,6 @@
package org.schabi.newpipe.extractor.services.youtube.stream; package org.schabi.newpipe.extractor.services.youtube.stream;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl; import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.MediaFormat; import org.schabi.newpipe.extractor.MediaFormat;
@ -18,9 +17,9 @@ import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date;
import java.util.List; import java.util.List;
import static java.util.Objects.requireNonNull;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl; import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ServiceList.YouTube; import static org.schabi.newpipe.extractor.ServiceList.YouTube;
@ -93,7 +92,7 @@ public class YoutubeStreamExtractorAgeRestrictedTest {
public void testGetUploadDate() throws ParsingException, ParseException { public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance(); final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2017-01-25")); instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2017-01-25"));
assertEquals(instance, extractor.getUploadDate()); assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
} }
@Test @Test

View File

@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
import static java.util.Objects.requireNonNull;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl; import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ServiceList.YouTube; import static org.schabi.newpipe.extractor.ServiceList.YouTube;
@ -92,7 +93,7 @@ public class YoutubeStreamExtractorControversialTest {
public void testGetUploadDate() throws ParsingException, ParseException { public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance(); final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2010-09-09")); instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2010-09-09"));
assertEquals(instance, extractor.getUploadDate()); assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
} }
@Test @Test

View File

@ -17,9 +17,9 @@ import java.io.IOException;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date;
import java.util.List; import java.util.List;
import static java.util.Objects.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl; import static org.schabi.newpipe.extractor.ExtractorAsserts.assertIsSecureUrl;
import static org.schabi.newpipe.extractor.ServiceList.YouTube; import static org.schabi.newpipe.extractor.ServiceList.YouTube;
@ -119,7 +119,7 @@ public class YoutubeStreamExtractorDefaultTest {
public void testGetUploadDate() throws ParsingException, ParseException { public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance(); final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2015-10-22")); instance.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("2015-10-22"));
Assert.assertEquals(instance, extractor.getUploadDate()); assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
} }
@Test @Test