Skip to content

Commit

Permalink
move lib rxunfurl to sdk core
Browse files Browse the repository at this point in the history
  • Loading branch information
Arief Nur Putranto committed Jul 18, 2023
1 parent 7abfea7 commit 4eb5c82
Show file tree
Hide file tree
Showing 15 changed files with 600 additions and 15 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Second, you need to add SDK dependencies inside your app .gradle. Then, you need
```
dependencies {
...
implementation 'com.qiscus.sdk:chat-core:1.6.8'
implementation 'com.qiscus.sdk:chat-core:1.6.9'
}
```

Expand Down
5 changes: 5 additions & 0 deletions chat-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ android {
minSdkVersion minSDKVersion
targetSdkVersion targetSDKVersion
versionCode 1
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
versionName "${chatCoreVersionMajor}.${chatCoreVersionMinor}.${chatCoreVersionPatch}"
}
buildTypes {
Expand Down Expand Up @@ -105,4 +106,8 @@ dependencies {
androidTestImplementation 'androidx.test:runner:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
//androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'

// test
testImplementation unitTestLibs
androidTestImplementation androidUnitTestLibs
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package com.qiscus.sdk.chat.core.util;

import static org.junit.Assert.*;

import android.util.Log;

import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner;

import com.qiscus.sdk.chat.core.data.model.urlsextractor.PreviewData;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import rx.Observable;
import rx.schedulers.Schedulers;

@RunWith(AndroidJUnit4ClassRunner.class)
public class UrlsExtractorUtilsTest {

private UrlsExtractorUtils extractor;

@Before
public void setUp() throws Exception {
extractor = new UrlsExtractorUtils.Builder()
.scheduler(Schedulers.io())
.build();
}

@After
public void tearDown() throws Exception {
extractor = null;
}

private void generatePreview(String url, Type type) {
final Observable<PreviewData> observable = extractor.generatePreview(url);

if (type == Type.SUCCESS) {
assertNotNull(
observable.toBlocking().single()
);
} else if (type == Type.EMPTY) {
assertTrue(
observable.isEmpty().toBlocking().single()
);
} else {
assertNull(
observable.onErrorReturn(null).toBlocking().single()
);
}

observable.subscribe(
previewData -> print(previewData.toString()),
throwable -> print(throwable.getMessage()),
() -> print(type.toString())
);
}

@Test
public void generatePreviewEmptyTest() {
String url = "";
Type type = Type.ERROR;

generatePreview(url, type);
}

@Test
public void generatePreviewHtmlTest() {
String url = "https://www.multichannel.com";
Type type = Type.SUCCESS;

generatePreview(url, type);
}

@Test
public void generatePreviewHtmlEmptyTest() {
String url = "https://www.tidakpernahada-harusnya.com";
Type type = Type.ERROR;

generatePreview(url, type);
}

@Test
public void generatePreviewImageTest() {
String url = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSlB6dfZVkKvk3HXFAo9zGp2rMFh7gmQL8m6JRdl03W_76v4AkyLy4P4xxFbLDC6p4XUko&usqp=CAU";
Type type = Type.SUCCESS;

generatePreview(url, type);
}

@Test
public void generatePreviewDocTest() {
String url = "https://filesamples.com/samples/document/txt/sample3.txt";
Type type = Type.EMPTY;

generatePreview(url, type);
}

@Test
public void generatePreviewVideoTest() {
String url = "https://dnlbo7fgjcc7f.cloudfront.net/weapr-01wjzygbxjmeosf/video/upload/683YWsiYHR/A297_Nuraniah_QP901-b(1).mp4";
Type type = Type.EMPTY;

generatePreview(url, type);
}

void print(String message) {
Log.d("testResult", message);
}

enum Type {
SUCCESS, ERROR, EMPTY
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@
import android.text.TextUtils;
import android.webkit.MimeTypeMap;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.qiscus.sdk.chat.core.QiscusCore;
import com.qiscus.sdk.chat.core.data.model.urlsextractor.PreviewData;
import com.qiscus.sdk.chat.core.data.remote.QiscusUrlScraper;
import com.qiscus.sdk.chat.core.util.QiscusAndroidUtil;
import com.qiscus.sdk.chat.core.util.QiscusFileUtil;
import com.qiscus.sdk.chat.core.util.QiscusRawDataExtractor;
import com.qiscus.sdk.chat.core.util.QiscusTextUtil;
import com.schinizer.rxunfurl.model.PreviewData;

import org.json.JSONException;
import org.json.JSONObject;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.qiscus.sdk.chat.core.data.model.urlsextractor;

public class Dimension {

private Integer width = 0;
private Integer height = 0;

public Dimension(Integer width, Integer height)
{
this.width = width;
this.height = height;
}

public int getWidth()
{
return width;
}

public int getHeight()
{
return height;
}

@Override
public String toString() {
return "Dimension{" +
"width=" + width +
", height=" + height +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.qiscus.sdk.chat.core.data.model.urlsextractor;


public class ImageInfo {

private String source;
private Dimension dimension;

public ImageInfo(String source, Dimension dimension)
{
this.source = source;
this.dimension = dimension;
}

public String getSource()
{
return source;
}

public Dimension getDimension()
{
return dimension;
}

@Override
public String toString() {
return "ImageInfo{" +
"source='" + source + '\'' +
", dimension=" + dimension +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.qiscus.sdk.chat.core.data.model.urlsextractor;

import java.util.List;

public class PreviewData {

private String url = "";
private String title = "";
private String description = "";
private List<ImageInfo> images;

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public List<ImageInfo> getImages() {
return images;
}

public void setImages(List<ImageInfo> images) {
this.images = images;
}

@Override
public String toString() {
return "PreviewData{" +
"url='" + url + '\'' +
", title='" + title + '\'' +
", description='" + description + '\'' +
", images=" + images +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

package com.qiscus.sdk.chat.core.data.remote;

import com.schinizer.rxunfurl.RxUnfurl;
import com.schinizer.rxunfurl.model.PreviewData;
import com.qiscus.sdk.chat.core.data.model.urlsextractor.PreviewData;
import com.qiscus.sdk.chat.core.util.UrlsExtractorUtils;

import rx.Observable;
import rx.schedulers.Schedulers;
Expand All @@ -31,10 +31,10 @@
public enum QiscusUrlScraper {
INSTANCE;

private final RxUnfurl rxUnfurl;
private final UrlsExtractorUtils rxUnfurl;

QiscusUrlScraper() {
rxUnfurl = new RxUnfurl.Builder()
rxUnfurl = new UrlsExtractorUtils.Builder()
.scheduler(Schedulers.io())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.qiscus.sdk.chat.core.util;


import com.qiscus.sdk.chat.core.data.model.urlsextractor.Dimension;

import java.io.IOException;
import java.io.InputStream;
import java.util.InvalidPropertiesFormatException;

import okio.BufferedSource;
import okio.ByteString;
import okio.Okio;

public class ImageDecoder {

private static final ByteString JPEG_START_MARKER = ByteString.decodeHex("FF");
private static final ByteString JPEG_BASELINE_MARKER = ByteString.decodeHex("C0");
private static final ByteString JPEG_PROGRESSIVE_MARKER = ByteString.decodeHex("C2");

public Dimension decodeJpegDimension(InputStream in) throws IOException {
// Jpeg stores in big endian
BufferedSource jpegSource = Okio.buffer(Okio.source(in));
Dimension dimension;

while (true) {
ByteString marker = jpegSource.readByteString(JPEG_START_MARKER.size());

if (!marker.equals(JPEG_START_MARKER))
continue;

marker = jpegSource.readByteString(JPEG_START_MARKER.size());

if (marker.equals(JPEG_BASELINE_MARKER) || marker.equals(JPEG_PROGRESSIVE_MARKER)) {
jpegSource.skip(3);
Short h = jpegSource.readShort();
Short w = jpegSource.readShort();

if(h < 0 || w < 0) {
throw new InvalidPropertiesFormatException("Invalid width and height");
}

dimension = new Dimension(Integer.valueOf(w), Integer.valueOf(h));
break;
}

}

return dimension;
}

public Dimension decodePngDimension(InputStream in) throws IOException {
// Png stores in big endian
BufferedSource pngSource = Okio.buffer(Okio.source(in));

pngSource.skip(16);
int w = pngSource.readInt();
int h = pngSource.readInt();

return new Dimension(w, h);
}

public Dimension decodeBmpDimension(InputStream in) throws IOException {
// Bmp stores in little endian
BufferedSource bmpSource = Okio.buffer(Okio.source(in));

bmpSource.skip(18);
int w = bmpSource.readIntLe();
int h = bmpSource.readIntLe();

return new Dimension(w, h);
}

public Dimension decodeGifDimension(InputStream in) throws IOException {
// Gif stores in little endian
BufferedSource gifSource = Okio.buffer(Okio.source(in));

gifSource.skip(6);
Short w = gifSource.readShortLe();
Short h = gifSource.readShortLe();

return new Dimension(Integer.valueOf(w), Integer.valueOf(h));
}
}
Loading

0 comments on commit 4eb5c82

Please sign in to comment.