Revert "Wmhack2018 (#1536)" (#1539)

This reverts commit 01cb9ccd70.
This commit is contained in:
neslihanturan 2018-05-19 23:02:29 +03:00 committed by GitHub
parent 01cb9ccd70
commit 32d36944fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 45 additions and 1086 deletions

View file

@ -96,10 +96,6 @@
android:label="@string/title_activity_featured_images"
android:parentActivityName=".contributions.ContributionsActivity" />
<activity
android:name=".review.ReviewActivity"
android:label="@string/title_activity_review" />
<service android:name=".upload.UploadService" />
<service

View file

@ -24,7 +24,6 @@ import javax.xml.parsers.ParserConfigurationException;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.mwapi.MediaResult;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.utils.MediaDataExtractorUtil;
import timber.log.Timber;
/**
@ -72,13 +71,28 @@ public class MediaDataExtractor {
MediaResult result = mediaWikiApi.fetchMediaByFilename(filename);
// In-page category links are extracted from source, as XML doesn't cover [[links]]
categories = MediaDataExtractorUtil.extractCategories(result.getWikiSource());
extractCategories(result.getWikiSource());
// Description template info is extracted from preprocessor XML
processWikiParseTree(result.getParseTreeXmlSource(), licenseList);
fetched = true;
}
/**
* We could fetch all category links from API, but we actually only want the ones
* directly in the page source so they're editable. In the future this may change.
*
* @param source wikitext source code
*/
private void extractCategories(String source) {
Pattern regex = Pattern.compile("\\[\\[\\s*Category\\s*:([^]]*)\\s*\\]\\]", Pattern.CASE_INSENSITIVE);
Matcher matcher = regex.matcher(source);
while (matcher.find()) {
String cat = matcher.group(1).trim();
categories.add(cat);
}
}
private void processWikiParseTree(String source, LicenseList licenseList) throws IOException {
Document doc;
try {

View file

@ -54,7 +54,7 @@ public class DeleteTask extends AsyncTask<Void, Integer, Boolean> {
notificationBuilder = new NotificationCompat.Builder(context);
Toast toast = new Toast(context);
toast.setGravity(Gravity.CENTER,0,0);
toast = Toast.makeText(context,"Trying to nominate "+media.getDisplayTitle()+ " for deletion", Toast.LENGTH_SHORT);
toast = Toast.makeText(context,"Trying to nominate "+media.getDisplayTitle()+ " for deletion",Toast.LENGTH_SHORT);
toast.show();
}
@ -64,7 +64,7 @@ public class DeleteTask extends AsyncTask<Void, Integer, Boolean> {
String editToken;
String authCookie;
String summary = context.getString(R.string.nominating_file_for_deletion, media.getFilename());
String summary = "Nominating " + media.getFilename() +" for deletion.";
authCookie = sessionManager.getAuthCookie();
mwApi.setAuthCookie(authCookie);
@ -97,19 +97,19 @@ public class DeleteTask extends AsyncTask<Void, Integer, Boolean> {
publishProgress(1);
mwApi.prependEdit(editToken,fileDeleteString+"\n",
media.getFilename(), summary);
media.getFilename(),summary);
publishProgress(2);
mwApi.edit(editToken,subpageString+"\n",
"Commons:Deletion_requests/"+media.getFilename(), summary);
"Commons:Deletion_requests/"+media.getFilename(),summary);
publishProgress(3);
mwApi.appendEdit(editToken,logPageString+"\n",
"Commons:Deletion_requests/"+date, summary);
"Commons:Deletion_requests/"+date,summary);
publishProgress(4);
mwApi.appendEdit(editToken,userPageString+"\n",
"User_Talk:"+sessionManager.getCurrentAccount().name, summary);
"User_Talk:"+sessionManager.getCurrentAccount().name,summary);
publishProgress(5);
}
catch (Exception e) {
@ -123,21 +123,29 @@ public class DeleteTask extends AsyncTask<Void, Integer, Boolean> {
protected void onProgressUpdate (Integer... values){
super.onProgressUpdate(values);
int[] messages = new int[]{
R.string.getting_edit_token,
R.string.nominate_for_deletion_edit_file_page,
R.string.nominate_for_deletion_create_deletion_request,
R.string.nominate_for_deletion_edit_deletion_request_log,
R.string.nominate_for_deletion_notify_user,
R.string.nominate_for_deletion_done
};
String message = "";
if (0 < values[0] && values[0] < messages.length) {
message = context.getString(messages[values[0]]);
switch (values[0]){
case 0:
message = "Getting token";
break;
case 1:
message = "Adding delete message to file";
break;
case 2:
message = "Creating Delete requests sub-page";
break;
case 3:
message = "Adding file to Delete requests log";
break;
case 4:
message = "Notifying User on Talk page";
break;
case 5:
message = "Done";
break;
}
notificationBuilder.setContentTitle(context.getString(R.string.nominating_file_for_deletion, media.getFilename()))
notificationBuilder.setContentTitle("Nominating "+media.getDisplayTitle()+" for deletion")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(message))
.setSmallIcon(R.drawable.ic_launcher)

View file

@ -10,7 +10,6 @@ import fr.free.nrw.commons.contributions.ContributionsActivity;
import fr.free.nrw.commons.category.CategoryImagesActivity;
import fr.free.nrw.commons.nearby.NearbyActivity;
import fr.free.nrw.commons.notification.NotificationActivity;
import fr.free.nrw.commons.review.ReviewActivity;
import fr.free.nrw.commons.settings.SettingsActivity;
import fr.free.nrw.commons.upload.MultipleShareActivity;
import fr.free.nrw.commons.upload.ShareActivity;
@ -51,7 +50,4 @@ public abstract class ActivityBuilderModule {
@ContributesAndroidInjector
abstract CategoryImagesActivity bindFeaturedImagesActivity();
@ContributesAndroidInjector
abstract ReviewActivity bindReviewActivity();
}

View file

@ -9,11 +9,11 @@ import dagger.android.support.AndroidSupportInjectionModule;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.MediaWikiImageView;
import fr.free.nrw.commons.auth.LoginActivity;
import fr.free.nrw.commons.contributions.Contribution;
import fr.free.nrw.commons.contributions.ContributionsActivity;
import fr.free.nrw.commons.contributions.ContributionsSyncAdapter;
import fr.free.nrw.commons.delete.DeleteTask;
import fr.free.nrw.commons.modifications.ModificationsSyncAdapter;
import fr.free.nrw.commons.review.CheckCategoryTask;
import fr.free.nrw.commons.review.SendThankTask;
import fr.free.nrw.commons.settings.SettingsFragment;
import fr.free.nrw.commons.nearby.PlaceRenderer;
@ -40,10 +40,6 @@ public interface CommonsApplicationComponent extends AndroidInjector<Application
void inject(DeleteTask deleteTask);
void inject(CheckCategoryTask checkCategoryTask);
void inject(SendThankTask sendThankTask);
void inject(SettingsFragment fragment);
@Override

View file

@ -10,7 +10,6 @@ import fr.free.nrw.commons.media.MediaDetailPagerFragment;
import fr.free.nrw.commons.nearby.NearbyListFragment;
import fr.free.nrw.commons.nearby.NearbyMapFragment;
import fr.free.nrw.commons.nearby.NoPermissionsFragment;
import fr.free.nrw.commons.review.ReviewImageFragment;
import fr.free.nrw.commons.settings.SettingsFragment;
import fr.free.nrw.commons.upload.MultipleUploadListFragment;
import fr.free.nrw.commons.upload.SingleUploadFragment;
@ -52,7 +51,4 @@ public abstract class FragmentBuilderModule {
@ContributesAndroidInjector
abstract CategoryImagesListFragment bindFeaturedImagesListFragment();
@ContributesAndroidInjector
abstract ReviewImageFragment bindReviewOutOfContextFragment();
}

View file

@ -46,12 +46,7 @@ import fr.free.nrw.commons.delete.DeleteTask;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.review.CheckCategoryTask;
import fr.free.nrw.commons.review.SendThankTask;
import fr.free.nrw.commons.ui.widget.CompatTextView;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;
import static android.view.View.GONE;
@ -362,7 +357,6 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String reason = input.getText().toString();
DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
deleteTask.execute();
enableDeleteButton(false);

View file

@ -1,32 +0,0 @@
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

@ -38,14 +38,12 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.Callable;
import java.util.Random;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.PageTitle;
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 in.yuvi.http.fluent.Http;
@ -62,14 +60,6 @@ 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 MWApi api;
private Context context;
@ -233,19 +223,6 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
.getString("/api/query/pages/page/@_idx")) != -1;
}
@Override
public boolean thank(String editToken, String revision) throws IOException {
ApiResult res = api.action("thank")
.param("rev", revision)
.param("token", editToken)
.param("source", getUserAgent())
.post();
String r = res.getString("/api/result/@success");
// Does this correctly check the success/failure?
// The docs https://www.mediawiki.org/wiki/Extension:Thanks seems unclear about that.
return r.equals("success");
}
@Override
@Nullable
public String edit(String editToken, String processedPageContent, String filename, String summary) throws IOException {
@ -458,20 +435,6 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
.getString("/api/query/pages/page/revisions/rev");
}
@Override
@Nullable
public String firstRevisionOfFile(String filename) throws IOException {
String res = api.action("query")
.param("prop", "revisions")
.param("rvprop", "timestamp|ids")
.param("titles", filename)
.param("rvdir", "newer")
.param("rvlimit", "1")
.get()
.getString("/api/query/pages/page/revisions/rev/@revid");
return res;
}
@Override
@NonNull
public List<Notification> getNotifications() {
@ -653,59 +616,11 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
}
private Date parseMWDate(String mwDate) {
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC
try {
return isoFormat.parse(mwDate);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
private String formatMWDate(Date date) {
return isoFormat.format(date);
}
public Media getRecentRandomImage() throws IOException {
Media 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) {
boolean deletionStatus = pageExists("Commons:Deletion_requests/" + imageTitle);
if (!deletionStatus) {
// strip File: prefix
imageTitle = imageTitle.replace("File:", "");
media = new Media(imageTitle);
}
}
}
}
tries++;
}
return media;
}
}

View file

@ -75,14 +75,7 @@ public interface MediaWikiApi {
@NonNull
Single<Integer> getUploadCount(String userName);
boolean thank(String editToken, String revision) throws IOException;
String firstRevisionOfFile(String filename) throws IOException;
interface ProgressListener {
void onProgress(long transferred, long total);
}
@Nullable
Media getRecentRandomImage() throws IOException;
}

View file

@ -1,130 +0,0 @@
package fr.free.nrw.commons.review;
import android.app.NotificationManager;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.app.NotificationCompat;
import android.view.Gravity;
import android.widget.Toast;
import javax.inject.Inject;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.di.ApplicationlessInjection;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import timber.log.Timber;
import static android.support.v4.app.NotificationCompat.DEFAULT_ALL;
import static android.support.v4.app.NotificationCompat.PRIORITY_HIGH;
// Example code:
// CheckCategoryTask deleteTask = new CheckCategoryTask(getActivity(), media);
public class CheckCategoryTask extends AsyncTask<Void, Integer, Boolean> {
@Inject
MediaWikiApi mwApi;
@Inject
SessionManager sessionManager;
public static final int NOTIFICATION_CHECK_CATEGORY = 0x101;
private NotificationManager notificationManager;
private NotificationCompat.Builder notificationBuilder;
private Context context;
private Media media;
public CheckCategoryTask(Context context, Media media){
this.context = context;
this.media = media;
}
@Override
protected void onPreExecute(){
ApplicationlessInjection
.getInstance(context.getApplicationContext())
.getCommonsApplicationComponent()
.inject(this);
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder = new NotificationCompat.Builder(context);
Toast toast = new Toast(context);
toast.setGravity(Gravity.CENTER,0,0);
toast = Toast.makeText(context, context.getString(R.string.check_category_toast, media.getDisplayTitle()), Toast.LENGTH_SHORT);
toast.show();
}
@Override
protected Boolean doInBackground(Void ...voids) {
publishProgress(0);
String editToken;
String authCookie;
String summary = context.getString(R.string.check_category_edit_summary);
authCookie = sessionManager.getAuthCookie();
mwApi.setAuthCookie(authCookie);
try {
editToken = mwApi.getEditToken();
if (editToken.equals("+\\")) {
return false;
}
publishProgress(1);
mwApi.appendEdit(editToken, "\n{{subst:chc}}\n", media.getFilename(), summary);
publishProgress(2);
}
catch (Exception e) {
Timber.d(e.getMessage());
return false;
}
return true;
}
@Override
protected void onProgressUpdate (Integer... values){
super.onProgressUpdate(values);
int[] messages = new int[]{R.string.getting_edit_token, R.string.check_category_adding_template};
String message = "";
if (0 < values[0] && values[0] < messages.length) {
message = context.getString(messages[values[0]]);
}
notificationBuilder.setContentTitle(context.getString(R.string.check_category_notification_title, media.getDisplayTitle()))
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(message))
.setSmallIcon(R.drawable.ic_launcher)
.setProgress(messages.length, values[0], false)
.setOngoing(true);
notificationManager.notify(NOTIFICATION_CHECK_CATEGORY, notificationBuilder.build());
}
@Override
protected void onPostExecute(Boolean result) {
String message = "";
String title = "";
if (result){
title = context.getString(R.string.check_category_success_title);
message = context.getString(R.string.check_category_success_message, media.getDisplayTitle());
}
else {
title = context.getString(R.string.check_category_failure_title);
message = context.getString(R.string.check_category_failure_message, media.getDisplayTitle());
}
notificationBuilder.setDefaults(DEFAULT_ALL)
.setContentTitle(title)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(message))
.setSmallIcon(R.drawable.ic_launcher)
.setProgress(0,0,false)
.setOngoing(false)
.setPriority(PRIORITY_HIGH);
notificationManager.notify(NOTIFICATION_CHECK_CATEGORY, notificationBuilder.build());
}
}

View file

@ -1,173 +0,0 @@
package fr.free.nrw.commons.review;
import android.app.AlertDialog;
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 android.widget.EditText;
import com.viewpagerindicator.CirclePageIndicator;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.auth.AuthenticatedActivity;
import fr.free.nrw.commons.mwapi.MediaResult;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.utils.MediaDataExtractorUtil;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* Created by root on 18.05.2018.
*/
public class ReviewActivity extends AuthenticatedActivity {
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.navigation_view)
NavigationView navigationView;
@BindView(R.id.drawer_layout)
DrawerLayout drawerLayout;
@BindView(R.id.reviewPager)
ViewPager pager;
@Inject MediaWikiApi mwApi;
private ReviewPagerAdapter reviewPagerAdapter;
//private ReviewCallback reviewCallback;
private ReviewController reviewController;
@BindView(R.id.reviewPagerIndicator)
public CirclePageIndicator pagerIndicator;
@Override
protected void onAuthCookieAcquired(String authCookie) {
}
@Override
protected void onAuthFailure() {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_review);
ButterKnife.bind(this);
initDrawer();
reviewController = new ReviewController();
reviewPagerAdapter = new ReviewPagerAdapter(getSupportFragmentManager());
pager.setAdapter(reviewPagerAdapter);
reviewPagerAdapter.getItem(0);
pagerIndicator.setViewPager(pager);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.review_randomizer_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_review_randomizer) {
Observable.fromCallable(() -> {
Media result = null;
try {
result = mwApi.getRecentRandomImage();
//String thumBaseUrl = Utils.makeThumbBaseUrl(result.getFilename());
//reviewPagerAdapter.currentThumbBasedUrl = thumBaseUrl;
//Log.d("review", result.getWikiSource());
} catch (IOException e) {
Log.d("review", e.toString());
}
return result;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::updateImage);
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateImage(Media result) {
reviewController.onImageRefreshed(result.getFilename()); //file name is updated
reviewPagerAdapter.updateFilename();
pager.setCurrentItem(0);
Observable.fromCallable(() -> {
MediaResult media = mwApi.fetchMediaByFilename("File:" + result.getFilename());
return MediaDataExtractorUtil.extractCategories(media.getWikiSource());
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::updateCategories);
}
private void updateCategories(ArrayList<String> categories) {
reviewController.onCategoriesRefreshed(categories);
reviewPagerAdapter.updateCategories();
}
/**
* References ReviewPagerAdapter to null before the activity is destroyed
*/
@Override
public void onDestroy() {
//adapter.setCallback(null);
super.onDestroy();
}
/**
* Consumers should be simply using this method to use this activity.
* @param context
* @param title Page title
*/
public static void startYourself(Context context, String title) {
Intent reviewActivity = new Intent(context, ReviewActivity.class);
context.startActivity(reviewActivity);
}
interface ReviewCallback {
void onImageRefreshed(String itemTitle);
void onQuestionChanged();
void onSurveyFinished();
void onImproperImageReported();
void onLicenceViolationReported();
void onWrongCategoryReported();
void onThankSent();
}
}

View file

@ -1,52 +0,0 @@
package fr.free.nrw.commons.review;
import java.util.ArrayList;
/**
* Created by root on 19.05.2018.
*/
public class ReviewController implements ReviewActivity.ReviewCallback {
public static String fileName;
protected static ArrayList<String> categories;
@Override
public void onImageRefreshed(String fileName) {
ReviewController.fileName = fileName;
ReviewController.categories = new ArrayList<>();
}
public void onCategoriesRefreshed(ArrayList<String> categories) {
ReviewController.categories = categories;
}
@Override
public void onQuestionChanged() {
}
@Override
public void onSurveyFinished() {
}
@Override
public void onImproperImageReported() {
}
@Override
public void onLicenceViolationReported() {
}
@Override
public void onWrongCategoryReported() {
}
@Override
public void onThankSent() {
}
}

View file

@ -1,92 +0,0 @@
package fr.free.nrw.commons.review;
import android.app.AlertDialog;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import com.facebook.drawee.view.SimpleDraweeView;
import java.util.ArrayList;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
/**
* Created by root on 19.05.2018.
*/
public class ReviewImageFragment extends CommonsDaggerSupportFragment {
public static final int SPAM = 0;
public static final int COPYRIGHT = 1;
public static final int CATEGORY = 2;
private int position;
private String fileName;
private String catString;
private View catsView;
private SimpleDraweeView simpleDraweeView;
public void update(int position, String fileName) {
this.position = position;
this.fileName = fileName;
if (simpleDraweeView!=null) {
simpleDraweeView.setImageURI(Utils.makeThumbBaseUrl(fileName));
}
}
public void updateCategories(Iterable<String> categories) {
catString = TextUtils.join(", ", categories);
if (catsView != null) {
((TextView) catsView).setText(catString);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
position = getArguments().getInt("position");
View layoutView = inflater.inflate(R.layout.fragment_review_image, container,
false);
View textView = layoutView.findViewById(R.id.reviewQuestion);
catsView = layoutView.findViewById(R.id.reviewCategories);
String question;
switch(position) {
case COPYRIGHT:
question = getString(R.string.review_copyright);
break;
case CATEGORY:
question = getString(R.string.review_category);
catsView.setVisibility(View.VISIBLE);
break;
case SPAM:
question = getString(R.string.review_spam);
break;
default:
question = "How did we get here?";
}
((TextView) textView).setText(question);
simpleDraweeView = layoutView.findViewById(R.id.imageView);
if (fileName != null) {
simpleDraweeView.setImageURI(Utils.makeThumbBaseUrl(fileName));
}
if (catString != null) {
((TextView) catsView).setText(catString);
}
return layoutView;
}
}

View file

@ -1,51 +0,0 @@
package fr.free.nrw.commons.review;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
/**
* Created by nes on 19.05.2018.
*/
public class ReviewPagerAdapter extends FragmentStatePagerAdapter {
private int currentPosition;
ReviewImageFragment[] reviewImageFragments;
public ReviewPagerAdapter(FragmentManager fm) {
super(fm);
reviewImageFragments = new ReviewImageFragment[] {
new ReviewImageFragment(),
new ReviewImageFragment(),
new ReviewImageFragment()
};
}
@Override
public int getCount() {
return 3;
}
public void updateFilename() {
for (int i = 0; i < getCount(); i++) {
ReviewImageFragment fragment = reviewImageFragments[i];
fragment.update(i, ReviewController.fileName);
}
}
public void updateCategories() {
ReviewImageFragment categoryFragment = reviewImageFragments[ReviewImageFragment.CATEGORY];
categoryFragment.updateCategories(ReviewController.categories);
}
@Override
public Fragment getItem(int position) {
Bundle bundle = new Bundle();
bundle.putInt("position", position);
reviewImageFragments[position].setArguments(bundle);
return reviewImageFragments[position];
}
}

View file

@ -1,140 +0,0 @@
package fr.free.nrw.commons.review;
import android.app.NotificationManager;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.app.NotificationCompat;
import android.view.Gravity;
import android.widget.Toast;
import javax.inject.Inject;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.di.ApplicationlessInjection;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import timber.log.Timber;
import static android.support.v4.app.NotificationCompat.DEFAULT_ALL;
import static android.support.v4.app.NotificationCompat.PRIORITY_HIGH;
// example code:
//
// media = new Media("File:Iru.png");
// Observable.fromCallable(() -> mwApi.firstRevisionOfFile(media.getFilename()))
// .subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
// .subscribe(revision -> {
// SendThankTask task = new SendThankTask(getActivity(), media, revision);
// task.execute();
// });
public class SendThankTask extends AsyncTask<Void, Integer, Boolean> {
@Inject
MediaWikiApi mwApi;
@Inject
SessionManager sessionManager;
public static final int NOTIFICATION_SEND_THANK = 0x102;
private NotificationManager notificationManager;
private NotificationCompat.Builder notificationBuilder;
private Context context;
private Media media;
private String revision;
public SendThankTask(Context context, Media media, String revision){
this.context = context;
this.media = media;
this.revision = revision;
}
@Override
protected void onPreExecute(){
ApplicationlessInjection
.getInstance(context.getApplicationContext())
.getCommonsApplicationComponent()
.inject(this);
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder = new NotificationCompat.Builder(context);
Toast toast = new Toast(context);
toast.setGravity(Gravity.CENTER,0,0);
toast = Toast.makeText(context, context.getString(R.string.send_thank_toast, media.getDisplayTitle()), Toast.LENGTH_SHORT);
toast.show();
}
@Override
protected Boolean doInBackground(Void ...voids) {
publishProgress(0);
String editToken;
String authCookie;
authCookie = sessionManager.getAuthCookie();
mwApi.setAuthCookie(authCookie);
try {
editToken = mwApi.getEditToken();
if (editToken.equals("+\\")) {
return false;
}
publishProgress(1);
mwApi.thank(editToken, revision);
publishProgress(2);
}
catch (Exception e) {
Timber.d(e.getMessage());
return false;
}
return true;
}
@Override
protected void onProgressUpdate (Integer... values){
super.onProgressUpdate(values);
int[] messages = new int[]{R.string.getting_edit_token, R.string.send_thank_send};
String message = "";
if (0 < values[0] && values[0] < messages.length) {
message = context.getString(messages[values[0]]);
}
notificationBuilder.setContentTitle(context.getString(R.string.send_thank_notification_title))
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(message))
.setSmallIcon(R.drawable.ic_launcher)
.setProgress(messages.length, values[0], false)
.setOngoing(true);
notificationManager.notify(NOTIFICATION_SEND_THANK, notificationBuilder.build());
}
@Override
protected void onPostExecute(Boolean result) {
String message = "";
String title = "";
if (result){
title = context.getString(R.string.send_thank_success_title);
message = context.getString(R.string.send_thank_success_message, media.getDisplayTitle());
}
else {
title = context.getString(R.string.send_thank_failure_title);
message = context.getString(R.string.send_thank_failure_message, media.getDisplayTitle());
}
notificationBuilder.setDefaults(DEFAULT_ALL)
.setContentTitle(title)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(message))
.setSmallIcon(R.drawable.ic_launcher)
.setProgress(0,0,false)
.setOngoing(false)
.setPriority(PRIORITY_HIGH);
notificationManager.notify(NOTIFICATION_SEND_THANK, notificationBuilder.build());
}
}

View file

@ -30,7 +30,6 @@ import fr.free.nrw.commons.contributions.ContributionsActivity;
import fr.free.nrw.commons.category.CategoryImagesActivity;
import fr.free.nrw.commons.nearby.NearbyActivity;
import fr.free.nrw.commons.notification.NotificationActivity;
import fr.free.nrw.commons.review.ReviewActivity;
import fr.free.nrw.commons.settings.SettingsActivity;
import timber.log.Timber;
@ -161,11 +160,6 @@ public abstract class NavigationBaseActivity extends BaseActivity
drawerLayout.closeDrawer(navigationView);
CategoryImagesActivity.startYourself(this, getString(R.string.title_activity_featured_images), FEATURED_IMAGES_CATEGORY);
return true;
case R.id.action_review:
drawerLayout.closeDrawer(navigationView);
ReviewActivity.startYourself(this, getString(R.string.title_activity_review));
return true;
default:
Timber.e("Unknown option [%s] selected from the navigation menu", itemId);
return false;

View file

@ -1,28 +0,0 @@
package fr.free.nrw.commons.utils;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MediaDataExtractorUtil {
/**
* We could fetch all category links from API, but we actually only want the ones
* directly in the page source so they're editable. In the future this may change.
*
* @param source wikitext source code
*/
public static ArrayList<String> extractCategories(String source) {
ArrayList<String> categories = new ArrayList<>();
Pattern regex = Pattern.compile("\\[\\[\\s*Category\\s*:([^]]*)\\s*\\]\\]", Pattern.CASE_INSENSITIVE);
Matcher matcher = regex.matcher(source);
while (matcher.find()) {
String cat = matcher.group(1).trim();
categories.add(cat);
}
return categories;
}
}

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/>
</vector>

View file

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="2dp"
android:useLevel="false">
<solid android:color="@android:color/darker_gray"/>
</shape>
</item>
</layer-list>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape android:innerRadius="0dp"
android:shape="ring"
android:thickness="4dp"
android:useLevel="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/commons_app_blue_dark"/>
</shape>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/tab_indicator_selected"
android:state_selected="true"/>
<item android:drawable="@drawable/tab_indicator_default"/>
</selector>

View file

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</include>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar">
<android.support.v4.view.ViewPager
android:id="@+id/reviewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fadingEdge="none" />
<com.viewpagerindicator.CirclePageIndicator
android:id="@+id/reviewPagerIndicator"
android:layout_height="@dimen/half_standard_height"
android:layout_width="match_parent"
android:layout_below="@id/reviewPager"
android:layout_gravity="bottom"
android:elevation="3dp"
android:background="?attr/colorPrimaryDark"
/>
</FrameLayout>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer" />
</android.support.v4.widget.DrawerLayout>

View file

@ -1,89 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="6"
android:orientation="vertical"
android:gravity="center_horizontal"
>
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:src="@drawable/commons_logo_large"
/>
<TextView
android:id="@+id/reviewQuestion"
android:layout_width="match_parent"
android:textColor="@android:color/black"
android:layout_height="0dp"
android:layout_weight="1.1"
android:textAlignment="center"
android:textSize="32sp"
android:gravity="center_vertical"
android:text="testing1"
/>
<TextView
android:id="@+id/reviewQuestionContext"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.7"
android:textAlignment="center"
android:textSize="24sp"
android:layout_marginBottom="15dp"
android:gravity="center_vertical"
android:text="testing2"
/>
<TextView
android:id="@+id/reviewCategories"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.7"
android:textSize="24sp"
android:textAlignment="center"
android:text="testing2"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.6"
android:weightSum="2"
android:orientation="horizontal">
<Button
android:id="@+id/yesButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/transparent"
android:text="@string/yes"
android:textSize="20sp"
android:textColor="?attr/colorPrimaryDark"
/>
<Button
android:id="@+id/noButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:layout_weight="1"
android:text="@string/no"
android:textSize="20sp"
android:textColor="?attr/colorPrimaryDark"
/>
</LinearLayout>
<View
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="0.6"
android:background="?attr/colorPrimaryDark"
></View>
</LinearLayout>

View file

@ -15,11 +15,6 @@
android:icon="@drawable/ic_star_black_24dp"
android:title="@string/navigation_item_featured_images"/>
<item
android:id="@+id/action_review"
android:icon="@drawable/ic_check_black_24dp"
android:title="@string/navigation_item_review"/>
</group>
<group android:id="@+id/drawer_account">
<item

View file

@ -1,10 +0,0 @@
<?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/action_review_randomizer"
android:title="@string/menu_from_gallery"
app:showAsAction="ifRoom|withText"
android:icon="@drawable/ic_refresh_white_24dp"
/>
</menu>

View file

@ -83,7 +83,6 @@
<string name="title_activity_settings">Settings</string>
<string name="title_activity_signup">Sign Up</string>
<string name="title_activity_featured_images">Featured Images</string>
<string name="title_activity_review">Peer Review</string>
<string name="menu_about">About</string>
<string name="about_license">The Wikimedia Commons app is an open-source app created and maintained by grantees and volunteers of the Wikimedia community. The Wikimedia Foundation is not involved in the creation, development, or maintenance of the app. </string>
<string name="trademarked_name" translatable="false">Wikimedia Commons</string>
@ -220,7 +219,6 @@
<string name="navigation_item_info">Tutorial</string>
<string name="navigation_item_notification">Notifications</string>
<string name="navigation_item_featured_images">Featured</string>
<string name="navigation_item_review">Review</string>
<string name="nearby_needs_permissions">Nearby places cannot be displayed without location permissions</string>
<string name="no_description_found">no description found</string>
<string name="nearby_info_menu_commons_article">Commons file page</string>
@ -241,8 +239,6 @@
<string name="null_url">Error! URL not found</string>
<string name="nominate_deletion">Nominate for Deletion</string>
<string name="nominated_for_deletion">This image has been nominated for deletion.</string>
<string name="nominating_file_for_deletion">Nominating %1$s for deletion.</string>
<string name="nominating_for_deletion_status">Nominating file for deletion: %1$s</string>
<string name="nominated_see_more"><u>See webpage for details</u></string>
<string name="view_browser">View in Browser</string>
@ -287,31 +283,5 @@
<string name="share_app_title">Share App</string>
<string name="share_coordinates_not_present">Coordinates were not specified during image selection</string>
<string name="error_fetching_nearby_places">Error fetching nearby places.</string>
<string name="getting_edit_token">Getting token for editing</string>
<string name="check_category_adding_template">Adding template for category check</string>
<string name="check_category_notification_title">Requesting category check for %1$s</string>
<string name="check_category_edit_summary">Requesting category check</string>
<string name="check_category_success_title">Requesting category check: Success</string>
<string name="check_category_failure_title">Requesting category check: Failed</string>
<string name="check_category_success_message">Successfully requested category check for %1$s</string>
<string name="check_category_failure_message">Could not request category check for %1$s</string>
<string name="check_category_toast">Requesting category check for %1$s</string>
<string name="nominate_for_deletion_edit_file_page">Adding delete message to file</string>
<string name="nominate_for_deletion_done">Done</string>
<string name="nominate_for_deletion_notify_user">Notifying User on Talk page</string>
<string name="nominate_for_deletion_edit_deletion_request_log">Adding file to Delete requests log</string>
<string name="nominate_for_deletion_create_deletion_request">Creating Delete requests subpage</string>
<string name="notsure">Not sure</string>
<string name="send_thank_success_title">Sending Thanks: Success</string>
<string name="send_thank_success_message">Successfully sent thanks to %1$s</string>
<string name="send_thank_failure_message">Failed to send thanks %1$s</string>
<string name="send_thank_failure_title">Sending Thanks: Failure</string>
<string name="send_thank_send">Sending thanks</string>
<string name="send_thank_notification_title">Sending thanks</string>
<string name="send_thank_toast">Sending Thanks for %1$s</string>
<string name="review_copyright">Is this a copyright violation?</string>
<string name="review_category">Is this mis-categorized?</string>
<string name="review_spam">Is this spam?</string>
</resources>