Wikimedia hackathon 2018 (#1533)

* First draft of fn to get random recent image

* Use log entries for requests to beta, try to connect refresh button

FIXME: runs http request on main thread, breaks

* Tweak button connection
This commit is contained in:
Elliott Eggleston 2018-05-19 08:49:41 -05:00 committed by maskara
parent 8087d0872f
commit 67310be7b5
5 changed files with 116 additions and 2 deletions

View file

@ -0,0 +1,32 @@
package fr.free.nrw.commons.media;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.annotation.Nullable;
public class RecentChangesImageUtils {
private static final String[] imageExtensions = new String[]
{".jpg", ".jpeg", ".png"};
@Nullable
public static String findImageInRecentChanges(NodeList childNodes) {
String imageTitle;
for (int i = 0; i < childNodes.getLength(); i++) {
Element e = (Element)childNodes.item(i);
if (e.getAttribute("type").equals("log") && !e.getAttribute("old_revid").equals("0")) {
// For log entries, we only want ones where old_revid is zero, indicating a new file
continue;
}
imageTitle = e.getAttribute("title");
for (String imageExtension : imageExtensions) {
if (imageTitle.toLowerCase().endsWith(imageExtension)) {
return imageTitle;
}
}
}
return null;
}
}

View file

@ -41,6 +41,7 @@ import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.Callable;
import java.util.Random;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.Media;
@ -50,6 +51,7 @@ import fr.free.nrw.commons.achievements.FeedbackResponse;
import fr.free.nrw.commons.auth.AccountUtil;
import fr.free.nrw.commons.category.CategoryImageUtils;
import fr.free.nrw.commons.category.QueryContinue;
import fr.free.nrw.commons.media.RecentChangesImageUtils;
import fr.free.nrw.commons.notification.Notification;
import fr.free.nrw.commons.notification.NotificationUtils;
import fr.free.nrw.commons.utils.ContributionUtils;
@ -73,6 +75,14 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
private String wikiMediaToolforgeUrl = "https://tools.wmflabs.org/";
private static final String THUMB_SIZE = "640";
// Give up if no random recent image found after 5 tries
private static final int MAX_RANDOM_TRIES = 5;
// Random image request is for some time in the past 30 days
private static final int RANDOM_SECONDS = 60 * 60 * 24 * 30;
// Assuming MW always gives me UTC
private static final SimpleDateFormat isoFormat =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH);
private static final String FILE_NAMESPACE = "6";
private AbstractHttpClient httpClient;
private CustomMwApi api;
private CustomMwApi wikidataApi;
@ -1082,4 +1092,48 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
return null;
});
}
private String formatMWDate(Date date) {
return isoFormat.format(date);
}
public MediaResult getRecentRandomImage() throws IOException {
MediaResult media = null;
int tries = 0;
Random r = new Random();
while (media == null && tries < MAX_RANDOM_TRIES) {
Date now = new Date();
Date startDate = new Date(now.getTime() - r.nextInt(RANDOM_SECONDS) * 1000L);
ApiResult apiResult = null;
try {
MWApi.RequestBuilder requestBuilder = api.action("query")
.param("list", "recentchanges")
.param("rcstart", formatMWDate(startDate))
.param("rcnamespace", FILE_NAMESPACE)
.param("rcprop", "title|ids")
.param("rctype", "new|log")
.param("rctoponly", "1");
apiResult = requestBuilder.get();
} catch (IOException e) {
Timber.e("Failed to obtain recent random", e);
}
if (apiResult != null) {
ApiResult recentChangesNode = apiResult.getNode("/api/query/recentchanges");
if (recentChangesNode != null
&& recentChangesNode.getDocument() != null
&& recentChangesNode.getDocument().getChildNodes() != null
&& recentChangesNode.getDocument().getChildNodes().getLength() > 0) {
NodeList childNodes = recentChangesNode.getDocument().getChildNodes();
String imageTitle = RecentChangesImageUtils.findImageInRecentChanges(childNodes);
if (imageTitle != null) {
media = fetchMediaByFilename(imageTitle);
}
}
}
tries++;
}
return media;
}
}

View file

@ -111,4 +111,7 @@ public interface MediaWikiApi {
interface ProgressListener {
void onProgress(long transferred, long total);
}
@Nullable
MediaResult getRecentRandomImage() throws IOException;
}

View file

@ -4,18 +4,28 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.NavigationView;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import java.io.IOException;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.auth.AuthenticatedActivity;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
/**
* Created by root on 18.05.2018.
@ -33,6 +43,9 @@ public class ReviewActivity extends AuthenticatedActivity {
@BindView(R.id.reviewPager)
ViewPager pager;
@Inject
MediaWikiApi mwApi;
public static final int MAX_NUM = 4;
private ReviewPagerAdapter reviewPagerAdapter;
@ -69,7 +82,19 @@ public class ReviewActivity extends AuthenticatedActivity {
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_review) {
if (id == R.id.action_review_randomizer) {
Observable.fromCallable(() -> {
try {
Log.d("review", mwApi.getRecentRandomImage().getWikiSource());
} catch (IOException e) {
Log.d("review", e.toString());
}
return "Booga!";
})
.subscribeOn(Schedulers.io())
.subscribe();
return true;
}

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_from_gallery"
<item android:id="@+id/action_review_randomizer"
android:title="@string/menu_from_gallery"
app:showAsAction="ifRoom|withText"
android:icon="@drawable/ic_refresh_white_24dp"