implemented locale-specific formatting of view, like and dislike counts, and video published date
This commit is contained in:
parent
c5084901b5
commit
67ba126602
|
@ -2,6 +2,8 @@ package org.schabi.newpipe;
|
|||
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
|
@ -33,15 +35,15 @@ public class VideoInfo {
|
|||
public Bitmap thumbnail = null;
|
||||
public String webpage_url = "";
|
||||
public String upload_date = "";
|
||||
public String view_count = "";
|
||||
public long view_count = 0;
|
||||
|
||||
public String uploader_thumbnail_url = "";
|
||||
public Bitmap uploader_thumbnail = null;
|
||||
public String description = "";
|
||||
public int duration = -1;
|
||||
public int age_limit = 0;
|
||||
public String like_count = "";
|
||||
public String dislike_count = "";
|
||||
public int like_count = 0;
|
||||
public int dislike_count = 0;
|
||||
public String average_rating = "";
|
||||
public VideoStream[] videoStreams = null;
|
||||
public AudioStream[] audioStreams = null;
|
||||
|
@ -64,11 +66,6 @@ public class VideoInfo {
|
|||
public String resolution = "";
|
||||
}
|
||||
|
||||
protected static void formatNotKnown(int id) {
|
||||
Log.e(TAG, "format not known: \"" +
|
||||
Integer.toString(id) + "\". Call the programmers, they messed it up!");
|
||||
}
|
||||
|
||||
public static class AudioStream {
|
||||
public AudioStream(String url, int format, int bandwidth, int samplingRate) {
|
||||
this.url = url; this.format = format;
|
||||
|
@ -78,7 +75,5 @@ public class VideoInfo {
|
|||
public int format = -1;
|
||||
public int bandwidth = -1;
|
||||
public int samplingRate = -1;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -5,6 +5,7 @@ import android.os.Bundle;
|
|||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
@ -60,6 +61,7 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
|||
// this means the video was called though another app
|
||||
if (getIntent().getData() != null) {
|
||||
videoUrl = getIntent().getData().toString();
|
||||
Log.i(TAG, "video URL passed:\"" + videoUrl + "\"");
|
||||
StreamingService[] serviceList = ServiceList.getServices();
|
||||
Extractor extractor = null;
|
||||
for (int i = 0; i < serviceList.length; i++) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.schabi.newpipe;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Bundle;
|
||||
|
@ -29,6 +30,11 @@ import android.widget.TextView;
|
|||
import android.view.MenuItem;
|
||||
|
||||
import java.net.URL;
|
||||
import java.text.DateFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
|
@ -216,12 +222,31 @@ public class VideoItemDetailFragment extends Fragment {
|
|||
case VideoInfo.VIDEO_AVAILABLE: {
|
||||
videoTitleView.setText(info.title);
|
||||
uploaderView.setText(info.uploader);
|
||||
viewCountView.setText(info.view_count
|
||||
|
||||
Locale locale = getPreferredLocale();
|
||||
NumberFormat nf = NumberFormat.getInstance(locale);
|
||||
String localisedViewCount = nf.format(info.view_count);
|
||||
viewCountView.setText(localisedViewCount
|
||||
+ " " + activity.getString(R.string.viewSufix));
|
||||
thumbsUpView.setText(info.like_count);
|
||||
thumbsDownView.setText(info.dislike_count);
|
||||
|
||||
|
||||
thumbsUpView.setText(nf.format(info.like_count));
|
||||
thumbsDownView.setText(nf.format(info.dislike_count));
|
||||
|
||||
//this is horribly convoluted
|
||||
//TODO: find a better way to convert YYYY-MM-DD to a locale-specific date
|
||||
//suggestions welcome
|
||||
int year = Integer.parseInt(info.upload_date.substring(0, 4));
|
||||
int month = Integer.parseInt(info.upload_date.substring(5, 7));
|
||||
int date = Integer.parseInt(info.upload_date.substring(8, 10));
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(year, month, date);
|
||||
Date datum = cal.getTime();
|
||||
DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
|
||||
|
||||
String localisedDate = df.format(datum);
|
||||
uploadDateView.setText(
|
||||
activity.getString(R.string.uploadDatePrefix) + " " + info.upload_date);
|
||||
activity.getString(R.string.uploadDatePrefix) + " " + localisedDate);
|
||||
descriptionView.setText(Html.fromHtml(info.description));
|
||||
descriptionView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
|
||||
|
@ -369,6 +394,23 @@ public class VideoItemDetailFragment extends Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
public Locale getPreferredLocale() {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||
String languageKey = getContext().getString(R.string.searchLanguage);
|
||||
String languageCode = "en";//i know the following lines defaults languageCode to "en", but java is picky about uninitialised values
|
||||
languageCode = sp.getString(languageKey, "en");
|
||||
|
||||
if(languageCode.length() == 2) {
|
||||
return new Locale(languageCode);
|
||||
}
|
||||
else if(languageCode.contains("_")) {
|
||||
String country = languageCode
|
||||
.substring(languageCode.indexOf("_"), languageCode.length());
|
||||
return new Locale(languageCode.substring(0, 2), country);
|
||||
}
|
||||
return Locale.getDefault();
|
||||
}
|
||||
|
||||
public boolean checkIfLandscape() {
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||
|
|
|
@ -103,7 +103,7 @@ public class VideoItemListActivity extends AppCompatActivity
|
|||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_videoitem_list);
|
||||
|
||||
//-------- remove this line when multiservice support is implemented ----------
|
||||
//------ todo: remove this line when multiservice support is implemented ------
|
||||
currentStreamingServiceId = ServiceList.getIdOfService("Youtube");
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -133,22 +133,27 @@ public class YoutubeExtractor implements Extractor {
|
|||
|
||||
@Override
|
||||
public String getVideoId(String videoUrl) {
|
||||
//https://www.youtube.com/watch?v=laF2D3QyAFQ
|
||||
String id;
|
||||
String id = "";
|
||||
Pattern pat;
|
||||
|
||||
if(videoUrl.contains("youtube")) {
|
||||
pat = Pattern.compile("youtube\\.com/watch\\?v=([a-zA-Z0-9_]{11})");
|
||||
pat = Pattern.compile("youtube\\.com/watch\\?v=([\\-a-zA-Z0-9_]{11})");
|
||||
}
|
||||
else if(videoUrl.contains("youtu.be")) {
|
||||
pat = Pattern.compile("youtu\\.be/([a-zA-Z0-9_]{11})");
|
||||
pat = Pattern.compile("youtu\\.be/([a-zA-Z0-9_-]{11})");
|
||||
}
|
||||
else {
|
||||
Log.e(TAG, "Error could not parse url: " + videoUrl);
|
||||
return "";
|
||||
}
|
||||
Matcher mat = pat.matcher(videoUrl);
|
||||
id = mat.group(1);
|
||||
return (id == null ? "" : id);
|
||||
boolean foundMatch = mat.find();
|
||||
if(foundMatch){
|
||||
id = mat.group(1);
|
||||
Log.i(TAG, "string \""+videoUrl+"\" matches!");
|
||||
}
|
||||
Log.i(TAG, "string \""+videoUrl+"\" does not match.");
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -163,7 +168,7 @@ public class YoutubeExtractor implements Extractor {
|
|||
|
||||
Document doc = Jsoup.parse(site, siteUrl);
|
||||
|
||||
videoInfo.id = matchGroup1("v=([0-9a-zA-Z]{10,})", siteUrl);
|
||||
videoInfo.id = matchGroup1("v=([0-9a-zA-Z_-]{11})", siteUrl);
|
||||
|
||||
videoInfo.age_limit = 0;
|
||||
videoInfo.webpage_url = siteUrl;
|
||||
|
@ -173,7 +178,7 @@ public class YoutubeExtractor implements Extractor {
|
|||
//-------------------------------------
|
||||
// extracting form player args
|
||||
//-------------------------------------
|
||||
JSONObject playerArgs;
|
||||
JSONObject playerArgs = null;
|
||||
{
|
||||
try {
|
||||
String jsonString = matchGroup1("ytplayer.config\\s*=\\s*(\\{.*?\\});", site);
|
||||
|
@ -185,8 +190,6 @@ public class YoutubeExtractor implements Extractor {
|
|||
// If we fail in this part the video is most likely not available.
|
||||
// Determining why is done later.
|
||||
videoInfo.videoAvailableStatus = VideoInfo.VIDEO_UNAVAILABLE;
|
||||
//exit early, since we can't extract other args
|
||||
return videoInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,23 +280,27 @@ public class YoutubeExtractor implements Extractor {
|
|||
|
||||
|
||||
// description
|
||||
videoInfo.description = doc.select("p[id=\"eow-description\"]").first()
|
||||
.html();
|
||||
|
||||
videoInfo.description = doc.select("p[id=\"eow-description\"]").first().html();
|
||||
String likesString = "";
|
||||
String dislikesString = "";
|
||||
try {
|
||||
// likes
|
||||
videoInfo.like_count = doc.select("span[class=\"like-button-renderer \"]").first()
|
||||
.getAllElements().select("button")
|
||||
.select("span").get(0).text();
|
||||
|
||||
likesString = doc.select("button.like-button-renderer-like-button").first()
|
||||
.select("span.yt-uix-button-content").first().text();
|
||||
videoInfo.like_count = Integer.parseInt(likesString.replace(",", ""));
|
||||
// dislikes
|
||||
videoInfo.dislike_count = doc.select("span[class=\"like-button-renderer \"]").first()
|
||||
.getAllElements().select("button")
|
||||
.select("span").get(2).text();
|
||||
dislikesString = doc.select("button.like-button-renderer-dislike-button").first()
|
||||
.select("span.yt-uix-button-content").first().text();
|
||||
|
||||
videoInfo.dislike_count = Integer.parseInt(dislikesString.replace(",", ""));
|
||||
} catch(NumberFormatException nfe) {
|
||||
Log.e(TAG, "failed to parse likesString \""+likesString+"\" and dislikesString \""+
|
||||
dislikesString+"\" as integers");
|
||||
} catch(Exception e) {
|
||||
// if it fails we know that the video does not offer dislikes.
|
||||
videoInfo.like_count = "0";
|
||||
videoInfo.dislike_count = "0";
|
||||
e.printStackTrace();
|
||||
videoInfo.like_count = 0;
|
||||
videoInfo.dislike_count = 0;
|
||||
}
|
||||
|
||||
// uploader thumbnail
|
||||
|
@ -301,8 +308,9 @@ public class YoutubeExtractor implements Extractor {
|
|||
.select("img").first()
|
||||
.attr("abs:data-thumb");
|
||||
|
||||
// view count TODO: format locale-specifically
|
||||
videoInfo.view_count = doc.select("meta[itemprop=interactionCount]").attr("content");
|
||||
// view count TODO: locale-specific formatting
|
||||
String viewCountString = doc.select("meta[itemprop=interactionCount]").attr("content");
|
||||
videoInfo.view_count = Integer.parseInt(viewCountString);
|
||||
|
||||
// next video
|
||||
videoInfo.nextVideo = extractVideoInfoItem(doc.select("div[class=\"watch-sidebar-section\"]").first()
|
||||
|
|
Loading…
Reference in New Issue