mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
replaced icafe with metadata extractor (#2546)
* replaced icafe with metadata extractor * replaced icafe with metadata extractor * removed icafe from gradle * removed icafe from gradle * Revert: travis commented code * Use original content URI * merged pr * commit after merge * modified unit tests
This commit is contained in:
parent
2e23658b77
commit
6389b35b49
8 changed files with 67 additions and 29 deletions
|
|
@ -28,7 +28,7 @@ before_script:
|
|||
- emulator -avd test -no-audio -no-window -no-boot-anim &
|
||||
- android-wait-for-emulator
|
||||
script:
|
||||
#- "./gradlew clean check connectedCheck jacocoTestReport"
|
||||
- "./gradlew clean check connectedCheck jacocoTestReport"
|
||||
- if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
|
||||
mkdir -p app/src/prodRelease/play/release-notes/en-US;
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -90,7 +90,8 @@ dependencies {
|
|||
//swipe_layout
|
||||
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
|
||||
implementation 'com.nineoldandroids:library:2.4.0'
|
||||
implementation files('libs/icafe-1.1-SNAPSHOT.jar')
|
||||
//metadata extractor
|
||||
implementation 'com.drewnoakes:metadata-extractor:2.11.0'
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -50,6 +50,10 @@ public class UploadableFile implements Parcelable {
|
|||
file = (File) in.readSerializable();
|
||||
}
|
||||
|
||||
public Uri getContentUri() {
|
||||
return contentUri;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
package fr.free.nrw.commons.upload;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -20,7 +23,10 @@ import static fr.free.nrw.commons.utils.ImageUtils.IMAGE_OK;
|
|||
|
||||
/**
|
||||
* Methods for pre-processing images to be uploaded
|
||||
*/
|
||||
*//*if (dataInBytes[0] == 70 && dataInBytes[1] == 66 && dataInBytes[2] == 77 && dataInBytes[3] == 68) {
|
||||
Timber.d("Contains FBMD");
|
||||
return Single.just(ImageUtils.FILE_FBMD);
|
||||
}*/
|
||||
@Singleton
|
||||
public class ImageProcessingService {
|
||||
private final FileUtilsWrapper fileUtilsWrapper;
|
||||
|
|
@ -56,11 +62,13 @@ public class ImageProcessingService {
|
|||
}
|
||||
Timber.d("Checking the validity of image");
|
||||
String filePath = uploadItem.getMediaUri().getPath();
|
||||
Uri contentUri=uploadItem.getContentUri();
|
||||
Context context=uploadItem.getContext();
|
||||
Single<Integer> duplicateImage = checkDuplicateImage(filePath);
|
||||
Single<Integer> wrongGeoLocation = checkImageGeoLocation(uploadItem.getPlace(), filePath);
|
||||
Single<Integer> darkImage = checkDarkImage(filePath);
|
||||
Single<Integer> itemTitle = checkTitle ? validateItemTitle(uploadItem) : Single.just(ImageUtils.IMAGE_OK);
|
||||
Single<Integer> checkFBMD = checkFBMD(filePath);
|
||||
Single<Integer> checkFBMD = checkFBMD(context,contentUri);
|
||||
|
||||
Single<Integer> zipResult = Single.zip(duplicateImage, wrongGeoLocation, darkImage, itemTitle,
|
||||
(duplicate, wrongGeo, dark, title) -> {
|
||||
|
|
@ -84,9 +92,9 @@ public class ImageProcessingService {
|
|||
* Thus we successfully protect common's from Facebook's copyright violation
|
||||
*/
|
||||
|
||||
public Single<Integer> checkFBMD(String filePath) {
|
||||
public Single<Integer> checkFBMD(Context context,Uri contentUri) {
|
||||
try {
|
||||
return readFBMD.processMetadata(filePath);
|
||||
return readFBMD.processMetadata(context,contentUri);
|
||||
} catch (IOException e) {
|
||||
return Single.just(ImageUtils.FILE_FBMD);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +1,54 @@
|
|||
package fr.free.nrw.commons.upload;
|
||||
|
||||
import com.icafe4j.image.meta.Metadata;
|
||||
import com.icafe4j.image.meta.MetadataType;
|
||||
import com.icafe4j.image.meta.iptc.IPTC;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.drew.imaging.ImageMetadataReader;
|
||||
import com.drew.imaging.ImageProcessingException;
|
||||
import com.drew.metadata.Metadata;
|
||||
import com.drew.metadata.Tag;
|
||||
import com.drew.metadata.iptc.IptcDirectory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import fr.free.nrw.commons.utils.ImageUtils;
|
||||
import io.reactivex.Single;
|
||||
import timber.log.Timber;
|
||||
|
||||
@Singleton
|
||||
public class ReadFBMD {
|
||||
|
||||
@Inject
|
||||
public ReadFBMD(){
|
||||
public ReadFBMD() {
|
||||
|
||||
}
|
||||
public Single<Integer> processMetadata(String path) throws IOException {
|
||||
Map<MetadataType, Metadata> metadataMap = Metadata.readMetadata(path);
|
||||
Metadata metadata = metadataMap.get(MetadataType.IPTC);
|
||||
byte[] dataInBytes = new byte[0];
|
||||
|
||||
public Single<Integer> processMetadata(Context context, Uri contentUri) throws IOException {
|
||||
Metadata readMetadata = null;
|
||||
try {
|
||||
dataInBytes = ((IPTC) metadata).getDataSets().get("SpecialInstructions").get(0).getData();
|
||||
} catch (NullPointerException e) {
|
||||
readMetadata = ImageMetadataReader.readMetadata(context.getContentResolver().openInputStream(contentUri));
|
||||
} catch (ImageProcessingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
IptcDirectory iptcDirectory = readMetadata != null ? readMetadata.getFirstDirectoryOfType(IptcDirectory.class) : null;
|
||||
if (iptcDirectory == null) {
|
||||
return Single.just(ImageUtils.IMAGE_OK);
|
||||
}
|
||||
/**
|
||||
* The byte array so obtained is used is tested to contain FBMD data
|
||||
* Note: Any image downloaded from Facebook contains the ASCII code of the letters 'FBMD' in this bytecode extracted from it's IPTC metadata
|
||||
* */
|
||||
if (dataInBytes[0] == 70 && dataInBytes[1] == 66 && dataInBytes[2] == 77 && dataInBytes[3] == 68) {
|
||||
Timber.d("Contains FBMD");
|
||||
* We parse through all the tags in the IPTC directory if the tagname equals "Special Instructions".
|
||||
* And the description string starts with FBMD.
|
||||
* Then the source of image is facebook
|
||||
* */
|
||||
for (Tag tag : iptcDirectory.getTags()) {
|
||||
if (tag.getTagName().equals("Special Instructions") && tag.getDescription().substring(0, 4).equals("FBMD")) {
|
||||
return Single.just(ImageUtils.FILE_FBMD);
|
||||
}
|
||||
}
|
||||
return Single.just(ImageUtils.IMAGE_OK);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
package fr.free.nrw.commons.upload;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
|
|
@ -38,7 +41,7 @@ import timber.log.Timber;
|
|||
public class UploadModel {
|
||||
|
||||
private static UploadItem DUMMY = new UploadItem(
|
||||
Uri.EMPTY,
|
||||
Uri.EMPTY, Uri.EMPTY,
|
||||
"",
|
||||
"",
|
||||
GPSExtractor.DUMMY,
|
||||
|
|
@ -54,7 +57,7 @@ public class UploadModel {
|
|||
private boolean bottomCardState = true;
|
||||
private boolean rightCardState = true;
|
||||
private int currentStepIndex = 0;
|
||||
private Context context;
|
||||
public static Context context;
|
||||
private Disposable badImageSubscription;
|
||||
|
||||
private SessionManager sessionManager;
|
||||
|
|
@ -108,7 +111,7 @@ public class UploadModel {
|
|||
}
|
||||
Timber.d("File created date is %d", fileCreatedDate);
|
||||
GPSExtractor gpsExtractor = fileProcessor.processFileCoordinates(similarImageInterface);
|
||||
return new UploadItem(Uri.parse(uploadableFile.getFilePath()), uploadableFile.getMimeType(context), source, gpsExtractor, place, fileCreatedDate, createdTimestampSource);
|
||||
return new UploadItem(uploadableFile.getContentUri(), Uri.parse(uploadableFile.getFilePath()), uploadableFile.getMimeType(context), source, gpsExtractor, place, fileCreatedDate, createdTimestampSource);
|
||||
}
|
||||
|
||||
void onItemsProcessed(Place place, List<UploadItem> uploadItems) {
|
||||
|
|
@ -327,6 +330,7 @@ public class UploadModel {
|
|||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
static class UploadItem {
|
||||
private final Uri originalContentUri;
|
||||
private final Uri mediaUri;
|
||||
private final String mimeType;
|
||||
private final String source;
|
||||
|
|
@ -344,10 +348,12 @@ public class UploadModel {
|
|||
private BehaviorSubject<Integer> imageQuality;
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
UploadItem(Uri mediaUri, String mimeType, String source, GPSExtractor gpsCoords,
|
||||
UploadItem(Uri originalContentUri,
|
||||
Uri mediaUri, String mimeType, String source, GPSExtractor gpsCoords,
|
||||
@Nullable Place place,
|
||||
long createdTimestamp,
|
||||
String createdTimestampSource) {
|
||||
this.originalContentUri = originalContentUri;
|
||||
this.createdTimestampSource = createdTimestampSource;
|
||||
title = new Title();
|
||||
descriptions = new ArrayList<>();
|
||||
|
|
@ -428,6 +434,14 @@ public class UploadModel {
|
|||
public Place getPlace() {
|
||||
return place;
|
||||
}
|
||||
|
||||
public Uri getContentUri() {
|
||||
return originalContentUri;
|
||||
}
|
||||
|
||||
public Context getContext(){
|
||||
return UploadModel.context;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -82,7 +82,7 @@ class u {
|
|||
.thenReturn(false)
|
||||
`when`(mwApi!!.fileExistsWithName(ArgumentMatchers.anyString()))
|
||||
.thenReturn(false)
|
||||
`when`(readFBMD?.processMetadata(ArgumentMatchers.anyString()))
|
||||
`when`(readFBMD?.processMetadata(ArgumentMatchers.any(),ArgumentMatchers.any()))
|
||||
.thenReturn(Single.just(ImageUtils.IMAGE_OK))
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue