implemented locale-specific formatting of view, like and dislike counts, and video published date

This commit is contained in:
Adam Howard 2015-11-11 16:23:22 +00:00
parent c5084901b5
commit 67ba126602
5 changed files with 86 additions and 39 deletions

View File

@ -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;
}
}

View File

@ -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++) {

View File

@ -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);

View File

@ -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");
//-----------------------------------------------------------------------------

View File

@ -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()