mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-28 05:13:53 +01:00
Merge pull request #248 from whym/fixextension2
Further attempts to reduce overwrites
This commit is contained in:
commit
03c5896937
3 changed files with 72 additions and 45 deletions
|
|
@ -25,6 +25,7 @@ import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.xml.transform.TransformerConfigurationException;
|
import javax.xml.transform.TransformerConfigurationException;
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
|
|
@ -242,13 +243,13 @@ public class Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String fixExtension(String title, String extension) {
|
public static String fixExtension(String title, String extension) {
|
||||||
|
Pattern jpegPattern = Pattern.compile("\\.jpeg$", Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
// People are used to ".jpg" more than ".jpeg" which the system gives us.
|
// People are used to ".jpg" more than ".jpeg" which the system gives us.
|
||||||
if (extension != null && extension.toLowerCase().equals("jpeg")) {
|
if (extension != null && extension.toLowerCase().equals("jpeg")) {
|
||||||
extension = "jpg";
|
extension = "jpg";
|
||||||
}
|
}
|
||||||
if (title.toLowerCase().endsWith(".jpeg")) {
|
title = jpegPattern.matcher(title).replaceFirst(".jpg");
|
||||||
title = title.replaceFirst("\\.jpeg$", ".jpg");
|
|
||||||
}
|
|
||||||
if (extension != null && !title.toLowerCase().endsWith("." + extension.toLowerCase())) {
|
if (extension != null && !title.toLowerCase().endsWith("." + extension.toLowerCase())) {
|
||||||
title += "." + extension;
|
title += "." + extension;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
package fr.free.nrw.commons.upload;
|
package fr.free.nrw.commons.upload;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
@ -43,6 +44,9 @@ public class UploadService extends HandlerService<Contribution> {
|
||||||
|
|
||||||
private int toUpload;
|
private int toUpload;
|
||||||
|
|
||||||
|
// The file names of unfinished uploads, used to prevent overwriting
|
||||||
|
private Set<String> unfinishedUploads = new HashSet<>();
|
||||||
|
|
||||||
// DO NOT HAVE NOTIFICATION ID OF 0 FOR ANYTHING
|
// DO NOT HAVE NOTIFICATION ID OF 0 FOR ANYTHING
|
||||||
// See http://stackoverflow.com/questions/8725909/startforeground-does-not-show-my-notification
|
// See http://stackoverflow.com/questions/8725909/startforeground-does-not-show-my-notification
|
||||||
// Seriously, Android?
|
// Seriously, Android?
|
||||||
|
|
@ -96,7 +100,7 @@ public class UploadService extends HandlerService<Contribution> {
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
contributionsProviderClient.release();
|
contributionsProviderClient.release();
|
||||||
Log.d("Commons", "ZOMG I AM BEING KILLED HALP!");
|
Log.d("Commons", "UploadService.onDestroy; " + unfinishedUploads + " are yet to be uploaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -165,7 +169,6 @@ public class UploadService extends HandlerService<Contribution> {
|
||||||
return START_REDELIVER_INTENT;
|
return START_REDELIVER_INTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void uploadContribution(Contribution contribution) {
|
private void uploadContribution(Contribution contribution) {
|
||||||
MWApi api = app.getApi();
|
MWApi api = app.getApi();
|
||||||
|
|
||||||
|
|
@ -197,12 +200,17 @@ public class UploadService extends HandlerService<Contribution> {
|
||||||
|
|
||||||
this.startForeground(NOTIFICATION_UPLOAD_IN_PROGRESS, curProgressNotification.build());
|
this.startForeground(NOTIFICATION_UPLOAD_IN_PROGRESS, curProgressNotification.build());
|
||||||
|
|
||||||
|
String filename = null;
|
||||||
try {
|
try {
|
||||||
|
filename = Utils.fixExtension(
|
||||||
String filename = Utils.fixExtension(
|
|
||||||
contribution.getFilename(),
|
contribution.getFilename(),
|
||||||
MimeTypeMap.getSingleton().getExtensionFromMimeType((String)contribution.getTag("mimeType")));
|
MimeTypeMap.getSingleton().getExtensionFromMimeType((String)contribution.getTag("mimeType")));
|
||||||
filename = findUniqueFilename(filename);
|
|
||||||
|
synchronized (unfinishedUploads) {
|
||||||
|
Log.d("Commons", "making sure of uniqueness of name: " + filename);
|
||||||
|
filename = findUniqueFilename(filename);
|
||||||
|
unfinishedUploads.add(filename);
|
||||||
|
}
|
||||||
if(!api.validateLogin()) {
|
if(!api.validateLogin()) {
|
||||||
// Need to revalidate!
|
// Need to revalidate!
|
||||||
if(app.revalidateAuthToken()) {
|
if(app.revalidateAuthToken()) {
|
||||||
|
|
@ -223,7 +231,6 @@ public class UploadService extends HandlerService<Contribution> {
|
||||||
);
|
);
|
||||||
result = api.upload(filename, file, contribution.getDataLength(), contribution.getPageContents(), contribution.getEditSummary(), notificationUpdater);
|
result = api.upload(filename, file, contribution.getDataLength(), contribution.getPageContents(), contribution.getEditSummary(), notificationUpdater);
|
||||||
|
|
||||||
|
|
||||||
Log.d("Commons", "Response is" + Utils.getStringFromDOM(result.getDocument()));
|
Log.d("Commons", "Response is" + Utils.getStringFromDOM(result.getDocument()));
|
||||||
|
|
||||||
curProgressNotification = null;
|
curProgressNotification = null;
|
||||||
|
|
@ -233,7 +240,7 @@ public class UploadService extends HandlerService<Contribution> {
|
||||||
if(!resultStatus.equals("Success")) {
|
if(!resultStatus.equals("Success")) {
|
||||||
String errorCode = result.getString("/api/error/@code");
|
String errorCode = result.getString("/api/error/@code");
|
||||||
showFailedNotification(contribution);
|
showFailedNotification(contribution);
|
||||||
fr.free.nrw.commons.EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT)
|
EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT)
|
||||||
.param("username", app.getCurrentAccount().name)
|
.param("username", app.getCurrentAccount().name)
|
||||||
.param("source", contribution.getSource())
|
.param("source", contribution.getSource())
|
||||||
.param("multiple", contribution.getMultiple())
|
.param("multiple", contribution.getMultiple())
|
||||||
|
|
@ -264,6 +271,9 @@ public class UploadService extends HandlerService<Contribution> {
|
||||||
showFailedNotification(contribution);
|
showFailedNotification(contribution);
|
||||||
return;
|
return;
|
||||||
} finally {
|
} finally {
|
||||||
|
if ( filename != null ) {
|
||||||
|
unfinishedUploads.remove(filename);
|
||||||
|
}
|
||||||
toUpload--;
|
toUpload--;
|
||||||
if(toUpload == 0) {
|
if(toUpload == 0) {
|
||||||
// Sync modifications right after all uplaods are processed
|
// Sync modifications right after all uplaods are processed
|
||||||
|
|
@ -289,36 +299,33 @@ public class UploadService extends HandlerService<Contribution> {
|
||||||
contribution.save();
|
contribution.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized private String findUniqueFilename(String fileName) throws IOException {
|
private String findUniqueFilename(String fileName) throws IOException {
|
||||||
return findUniqueFilename(fileName, 1);
|
MWApi api = app.getApi();
|
||||||
}
|
|
||||||
|
|
||||||
private String findUniqueFilename(String fileName, int sequenceNumber) throws IOException {
|
|
||||||
String sequenceFileName;
|
String sequenceFileName;
|
||||||
if (sequenceNumber == 1) {
|
for ( int sequenceNumber = 1; true; sequenceNumber++ ) {
|
||||||
sequenceFileName = fileName;
|
if (sequenceNumber == 1) {
|
||||||
} else {
|
sequenceFileName = fileName;
|
||||||
if (fileName.indexOf('.') == -1) {
|
|
||||||
// We really should have appended a file type suffix already.
|
|
||||||
// But... we might not.
|
|
||||||
sequenceFileName = fileName + " " + sequenceNumber;
|
|
||||||
} else {
|
} else {
|
||||||
Pattern regex = Pattern.compile("^(.*)(\\..+?)$");
|
if (fileName.indexOf('.') == -1) {
|
||||||
Matcher regexMatcher = regex.matcher(fileName);
|
// We really should have appended a file type suffix already.
|
||||||
sequenceFileName = regexMatcher.replaceAll("$1 " + sequenceNumber + "$2");
|
// But... we might not.
|
||||||
|
sequenceFileName = fileName + " " + sequenceNumber;
|
||||||
|
} else {
|
||||||
|
Pattern regex = Pattern.compile("^(.*)(\\..+?)$");
|
||||||
|
Matcher regexMatcher = regex.matcher(fileName);
|
||||||
|
sequenceFileName = regexMatcher.replaceAll("$1 " + sequenceNumber + "$2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( fileExistsWithName(api, sequenceFileName) || unfinishedUploads.contains(sequenceFileName) ) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.d("Commons", "checking for uniqueness of name " + sequenceFileName);
|
return sequenceFileName;
|
||||||
|
|
||||||
if (fileExistsWithName(sequenceFileName)) {
|
|
||||||
return findUniqueFilename(fileName, sequenceNumber + 1);
|
|
||||||
} else {
|
|
||||||
return sequenceFileName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean fileExistsWithName(String fileName) throws IOException {
|
private static boolean fileExistsWithName(MWApi api, String fileName) throws IOException {
|
||||||
MWApi api = app.getApi();
|
|
||||||
ApiResult result;
|
ApiResult result;
|
||||||
|
|
||||||
result = api.action("query")
|
result = api.action("query")
|
||||||
|
|
@ -326,7 +333,6 @@ public class UploadService extends HandlerService<Contribution> {
|
||||||
.param("titles", "File:" + fileName)
|
.param("titles", "File:" + fileName)
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
ArrayList<ApiResult> nodes = result.getNodes("/api/query/pages/page/imageinfo");
|
return result.getNodes("/api/query/pages/page/imageinfo").size() > 0;
|
||||||
return nodes.size() > 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,49 @@
|
||||||
package fr.free.nrw.commons;
|
package fr.free.nrw.commons;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import fr.free.nrw.commons.upload.UploadController;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
|
||||||
|
|
||||||
public class UtilsTest {
|
public class UtilsTest {
|
||||||
|
|
||||||
@Test public void fixExtensionJpegToJpg() {
|
@Test public void fixExtensionJpegToJpeg() {
|
||||||
assertEquals("SampleFile.jpg", Utils.fixExtension("SampleFile.jpeg", "jpeg"));
|
assertThat(Utils.fixExtension("SampleFile.jpeg", "jpeg"), is("SampleFile.jpg"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void fixExtensionJPEGToJpg() {
|
||||||
|
assertThat(Utils.fixExtension("SampleFile.JPEG", null), is("SampleFile.jpg"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void fixExtensionNull() {
|
||||||
|
assertThat(Utils.fixExtension("SampleFile.jpeg", "JPEG"), is("SampleFile.jpg"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void fixExtensionJpgToJpeg() {
|
||||||
|
assertThat(Utils.fixExtension("SampleFile.jpg", "jpeg"), is("SampleFile.jpg"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void fixExtensionJpgToJpg() {
|
@Test public void fixExtensionJpgToJpg() {
|
||||||
assertEquals("SampleFile.jpg", Utils.fixExtension("SampleFile.jpg", "jpg"));
|
assertThat(Utils.fixExtension("SampleFile.jpg", "jpg"), is("SampleFile.jpg"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void fixExtensionPngToPng() {
|
@Test public void fixExtensionPngToPng() {
|
||||||
assertEquals("SampleFile.png", Utils.fixExtension("SampleFile.png", "png"));
|
assertThat(Utils.fixExtension("SampleFile.png", "png"), is("SampleFile.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void fixExtensionEmptyToJpg() {
|
@Test public void fixExtensionEmptyToJpg() {
|
||||||
assertEquals("SampleFile.jpg", Utils.fixExtension("SampleFile", "jpg"));
|
assertThat(Utils.fixExtension("SampleFile", "jpg"), is("SampleFile.jpg"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void fixExtensionEmptyToJpeg() {
|
||||||
|
assertThat(Utils.fixExtension("SampleFile", "jpeg"), is("SampleFile.jpg"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void fixExtensionJpgNotExtension() {
|
@Test public void fixExtensionJpgNotExtension() {
|
||||||
assertEquals("SampleFileJpg.jpg", Utils.fixExtension("SampleFileJpg", "jpg"));
|
assertThat(Utils.fixExtension("SAMPLEjpg", "jpg"), is("SAMPLEjpg.jpg"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void fixExtensionJpegNotExtension() {
|
||||||
|
assertThat(Utils.fixExtension("SAMPLE.jpeg.SAMPLE", "jpg"), is("SAMPLE.jpeg.SAMPLE.jpg"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue