Skip to content

Commit 6389b35

Browse files
vanshikaaroramaskaravivek
authored andcommitted
replaced icafe with metadata extractor (commons-app#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
1 parent 2e23658 commit 6389b35

File tree

8 files changed

+67
-29
lines changed

8 files changed

+67
-29
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ before_script:
2828
- emulator -avd test -no-audio -no-window -no-boot-anim &
2929
- android-wait-for-emulator
3030
script:
31-
#- "./gradlew clean check connectedCheck jacocoTestReport"
31+
- "./gradlew clean check connectedCheck jacocoTestReport"
3232
- if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
3333
mkdir -p app/src/prodRelease/play/release-notes/en-US;
3434
fi

app/build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ dependencies {
9090
//swipe_layout
9191
implementation 'com.daimajia.swipelayout:library:1.2.0@aar'
9292
implementation 'com.nineoldandroids:library:2.4.0'
93-
implementation files('libs/icafe-1.1-SNAPSHOT.jar')
93+
//metadata extractor
94+
implementation 'com.drewnoakes:metadata-extractor:2.11.0'
9495
}
9596

9697
android {

app/libs/icafe-1.1-SNAPSHOT.jar

-988 KB
Binary file not shown.

app/src/main/java/fr/free/nrw/commons/filepicker/UploadableFile.java

+4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ public UploadableFile(Parcel in) {
5050
file = (File) in.readSerializable();
5151
}
5252

53+
public Uri getContentUri() {
54+
return contentUri;
55+
}
56+
5357
public File getFile() {
5458
return file;
5559
}

app/src/main/java/fr/free/nrw/commons/upload/ImageProcessingService.java

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package fr.free.nrw.commons.upload;
22

3+
import android.content.Context;
4+
import android.net.Uri;
5+
36
import java.io.IOException;
47

58
import javax.inject.Inject;
@@ -20,7 +23,10 @@
2023

2124
/**
2225
* Methods for pre-processing images to be uploaded
23-
*/
26+
*//*if (dataInBytes[0] == 70 && dataInBytes[1] == 66 && dataInBytes[2] == 77 && dataInBytes[3] == 68) {
27+
Timber.d("Contains FBMD");
28+
return Single.just(ImageUtils.FILE_FBMD);
29+
}*/
2430
@Singleton
2531
public class ImageProcessingService {
2632
private final FileUtilsWrapper fileUtilsWrapper;
@@ -56,11 +62,13 @@ Single<Integer> validateImage(UploadModel.UploadItem uploadItem, boolean checkTi
5662
}
5763
Timber.d("Checking the validity of image");
5864
String filePath = uploadItem.getMediaUri().getPath();
65+
Uri contentUri=uploadItem.getContentUri();
66+
Context context=uploadItem.getContext();
5967
Single<Integer> duplicateImage = checkDuplicateImage(filePath);
6068
Single<Integer> wrongGeoLocation = checkImageGeoLocation(uploadItem.getPlace(), filePath);
6169
Single<Integer> darkImage = checkDarkImage(filePath);
6270
Single<Integer> itemTitle = checkTitle ? validateItemTitle(uploadItem) : Single.just(ImageUtils.IMAGE_OK);
63-
Single<Integer> checkFBMD = checkFBMD(filePath);
71+
Single<Integer> checkFBMD = checkFBMD(context,contentUri);
6472

6573
Single<Integer> zipResult = Single.zip(duplicateImage, wrongGeoLocation, darkImage, itemTitle,
6674
(duplicate, wrongGeo, dark, title) -> {
@@ -84,9 +92,9 @@ Single<Integer> validateImage(UploadModel.UploadItem uploadItem, boolean checkTi
8492
* Thus we successfully protect common's from Facebook's copyright violation
8593
*/
8694

87-
public Single<Integer> checkFBMD(String filePath) {
95+
public Single<Integer> checkFBMD(Context context,Uri contentUri) {
8896
try {
89-
return readFBMD.processMetadata(filePath);
97+
return readFBMD.processMetadata(context,contentUri);
9098
} catch (IOException e) {
9199
return Single.just(ImageUtils.FILE_FBMD);
92100
}

app/src/main/java/fr/free/nrw/commons/upload/ReadFBMD.java

+28-17
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,54 @@
11
package fr.free.nrw.commons.upload;
22

3-
import com.icafe4j.image.meta.Metadata;
4-
import com.icafe4j.image.meta.MetadataType;
5-
import com.icafe4j.image.meta.iptc.IPTC;
3+
import android.content.Context;
4+
import android.net.Uri;
5+
6+
import com.drew.imaging.ImageMetadataReader;
7+
import com.drew.imaging.ImageProcessingException;
8+
import com.drew.metadata.Metadata;
9+
import com.drew.metadata.Tag;
10+
import com.drew.metadata.iptc.IptcDirectory;
611

712
import java.io.IOException;
8-
import java.util.Map;
913

1014
import javax.inject.Inject;
1115
import javax.inject.Singleton;
1216

1317
import fr.free.nrw.commons.utils.ImageUtils;
1418
import io.reactivex.Single;
15-
import timber.log.Timber;
1619

1720
@Singleton
1821
public class ReadFBMD {
1922

2023
@Inject
21-
public ReadFBMD(){
24+
public ReadFBMD() {
2225

2326
}
24-
public Single<Integer> processMetadata(String path) throws IOException {
25-
Map<MetadataType, Metadata> metadataMap = Metadata.readMetadata(path);
26-
Metadata metadata = metadataMap.get(MetadataType.IPTC);
27-
byte[] dataInBytes = new byte[0];
27+
28+
public Single<Integer> processMetadata(Context context, Uri contentUri) throws IOException {
29+
Metadata readMetadata = null;
2830
try {
29-
dataInBytes = ((IPTC) metadata).getDataSets().get("SpecialInstructions").get(0).getData();
30-
} catch (NullPointerException e) {
31+
readMetadata = ImageMetadataReader.readMetadata(context.getContentResolver().openInputStream(contentUri));
32+
} catch (ImageProcessingException e) {
33+
e.printStackTrace();
34+
} catch (IOException e) {
35+
e.printStackTrace();
36+
}
37+
38+
IptcDirectory iptcDirectory = readMetadata != null ? readMetadata.getFirstDirectoryOfType(IptcDirectory.class) : null;
39+
if (iptcDirectory == null) {
3140
return Single.just(ImageUtils.IMAGE_OK);
3241
}
3342
/**
34-
* The byte array so obtained is used is tested to contain FBMD data
35-
* Note: Any image downloaded from Facebook contains the ASCII code of the letters 'FBMD' in this bytecode extracted from it's IPTC metadata
36-
* */
37-
if (dataInBytes[0] == 70 && dataInBytes[1] == 66 && dataInBytes[2] == 77 && dataInBytes[3] == 68) {
38-
Timber.d("Contains FBMD");
43+
* We parse through all the tags in the IPTC directory if the tagname equals "Special Instructions".
44+
* And the description string starts with FBMD.
45+
* Then the source of image is facebook
46+
* */
47+
for (Tag tag : iptcDirectory.getTags()) {
48+
if (tag.getTagName().equals("Special Instructions") && tag.getDescription().substring(0, 4).equals("FBMD")) {
3949
return Single.just(ImageUtils.FILE_FBMD);
4050
}
51+
}
4152
return Single.just(ImageUtils.IMAGE_OK);
4253
}
4354
}

app/src/main/java/fr/free/nrw/commons/upload/UploadModel.java

+19-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package fr.free.nrw.commons.upload;
22

33
import android.annotation.SuppressLint;
4+
import android.content.ContentValues;
45
import android.content.Context;
6+
import android.database.Cursor;
57
import android.net.Uri;
8+
import android.provider.MediaStore;
69
import android.support.annotation.NonNull;
710
import android.support.annotation.Nullable;
811

@@ -38,7 +41,7 @@
3841
public class UploadModel {
3942

4043
private static UploadItem DUMMY = new UploadItem(
41-
Uri.EMPTY,
44+
Uri.EMPTY, Uri.EMPTY,
4245
"",
4346
"",
4447
GPSExtractor.DUMMY,
@@ -54,7 +57,7 @@ public class UploadModel {
5457
private boolean bottomCardState = true;
5558
private boolean rightCardState = true;
5659
private int currentStepIndex = 0;
57-
private Context context;
60+
public static Context context;
5861
private Disposable badImageSubscription;
5962

6063
private SessionManager sessionManager;
@@ -108,7 +111,7 @@ private UploadItem getUploadItem(UploadableFile uploadableFile,
108111
}
109112
Timber.d("File created date is %d", fileCreatedDate);
110113
GPSExtractor gpsExtractor = fileProcessor.processFileCoordinates(similarImageInterface);
111-
return new UploadItem(Uri.parse(uploadableFile.getFilePath()), uploadableFile.getMimeType(context), source, gpsExtractor, place, fileCreatedDate, createdTimestampSource);
114+
return new UploadItem(uploadableFile.getContentUri(), Uri.parse(uploadableFile.getFilePath()), uploadableFile.getMimeType(context), source, gpsExtractor, place, fileCreatedDate, createdTimestampSource);
112115
}
113116

114117
void onItemsProcessed(Place place, List<UploadItem> uploadItems) {
@@ -327,6 +330,7 @@ public List<UploadItem> getItems() {
327330

328331
@SuppressWarnings("WeakerAccess")
329332
static class UploadItem {
333+
private final Uri originalContentUri;
330334
private final Uri mediaUri;
331335
private final String mimeType;
332336
private final String source;
@@ -344,10 +348,12 @@ static class UploadItem {
344348
private BehaviorSubject<Integer> imageQuality;
345349

346350
@SuppressLint("CheckResult")
347-
UploadItem(Uri mediaUri, String mimeType, String source, GPSExtractor gpsCoords,
351+
UploadItem(Uri originalContentUri,
352+
Uri mediaUri, String mimeType, String source, GPSExtractor gpsCoords,
348353
@Nullable Place place,
349354
long createdTimestamp,
350355
String createdTimestampSource) {
356+
this.originalContentUri = originalContentUri;
351357
this.createdTimestampSource = createdTimestampSource;
352358
title = new Title();
353359
descriptions = new ArrayList<>();
@@ -428,6 +434,14 @@ public String getFileName() {
428434
public Place getPlace() {
429435
return place;
430436
}
437+
438+
public Uri getContentUri() {
439+
return originalContentUri;
440+
}
441+
442+
public Context getContext(){
443+
return UploadModel.context;
444+
}
431445
}
432446

433-
}
447+
}

app/src/test/kotlin/fr/free/nrw/commons/upload/ImageProcessingServiceTest.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class u {
8282
.thenReturn(false)
8383
`when`(mwApi!!.fileExistsWithName(ArgumentMatchers.anyString()))
8484
.thenReturn(false)
85-
`when`(readFBMD?.processMetadata(ArgumentMatchers.anyString()))
85+
`when`(readFBMD?.processMetadata(ArgumentMatchers.any(),ArgumentMatchers.any()))
8686
.thenReturn(Single.just(ImageUtils.IMAGE_OK))
8787
}
8888

0 commit comments

Comments
 (0)