From 58d206df66284ebd2d6e5bc720e5028a670b720b Mon Sep 17 00:00:00 2001 From: Dhruv Nagarajan Date: Wed, 30 Oct 2019 23:29:52 +0530 Subject: [PATCH 1/6] Update gradle version --- build.gradle | 3 ++- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 37b7497..03fa023 100644 --- a/build.gradle +++ b/build.gradle @@ -8,9 +8,10 @@ buildscript { url 'https://maven.google.com/' name 'Google' } + google() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.4' + classpath 'com.android.tools.build:gradle:3.5.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index caa78d2..b55d6f4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Aug 17 11:21:22 CEST 2017 +#Wed Oct 30 23:21:36 IST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip From c71dfe50de3fe0eee52d291bc9c14fe5308f9e4e Mon Sep 17 00:00:00 2001 From: Dhruv Nagarajan Date: Thu, 31 Oct 2019 18:35:23 +0530 Subject: [PATCH 2/6] Add RxJava variant of TextCrawler.makePreview() - Move Textcrawler.getSourceCode to a new abstraction - Add RxJava to :library and :app - Add kotlin to :library - Update getSourceCode AsyncTask return type --- README.md | 61 ++- app/build.gradle | 4 + .../java/com/leocardz/link/preview/Main.java | 73 ++- build.gradle | 7 +- library/build.gradle | 15 +- .../library/ProvidedDocumentTextCrawler.java | 4 +- .../link/preview/library/TextCrawlerTest.java | 4 +- .../library/BaseImagePickingStrategy.java | 53 --- .../library/BaseImagePickingStrategy.kt | 40 ++ .../library/DefaultImagePickingStrategy.java | 27 +- .../link/preview/library/GetSource.kt | 15 + .../preview/library/GetSourceAynscTask.kt | 30 ++ .../preview/library/GetSourceObservable.kt | 27 ++ .../link/preview/library/GetSourceSync.kt | 347 ++++++++++++++ .../preview/library/ImagePickingStrategy.java | 20 - .../preview/library/ImagePickingStrategy.kt | 14 + .../leocardz/link/preview/library/Regex.java | 8 +- .../link/preview/library/SourceContent.java | 350 +++++++------- .../link/preview/library/TextCrawler.java | 432 ------------------ .../link/preview/library/TextCrawler.kt | 35 ++ .../com/leocardz/link/preview/library/Util.kt | 15 + .../url/DefaultUrlExtractionStrategy.java | 2 +- .../library/url/UrlExtractionStrategy.java | 1 + 23 files changed, 852 insertions(+), 732 deletions(-) delete mode 100644 library/src/main/java/com/leocardz/link/preview/library/BaseImagePickingStrategy.java create mode 100644 library/src/main/java/com/leocardz/link/preview/library/BaseImagePickingStrategy.kt create mode 100644 library/src/main/java/com/leocardz/link/preview/library/GetSource.kt create mode 100644 library/src/main/java/com/leocardz/link/preview/library/GetSourceAynscTask.kt create mode 100644 library/src/main/java/com/leocardz/link/preview/library/GetSourceObservable.kt create mode 100644 library/src/main/java/com/leocardz/link/preview/library/GetSourceSync.kt delete mode 100644 library/src/main/java/com/leocardz/link/preview/library/ImagePickingStrategy.java create mode 100644 library/src/main/java/com/leocardz/link/preview/library/ImagePickingStrategy.kt delete mode 100644 library/src/main/java/com/leocardz/link/preview/library/TextCrawler.java create mode 100644 library/src/main/java/com/leocardz/link/preview/library/TextCrawler.kt create mode 100644 library/src/main/java/com/leocardz/link/preview/library/Util.kt diff --git a/README.md b/README.md index 7df6c3c..fc9a57b 100644 --- a/README.md +++ b/README.md @@ -71,17 +71,66 @@ LinkPreviewCallback linkPreviewCallback = new LinkPreviewCallback() { #### Generate Preview ```java -textCrawler.makePreview( linkPreviewCallback, url); +// using AsyncTask + +textCrawler.makePreview(linkPreviewCallback, url); +``` +```java +// using RxJava2 +// no need to implement LinkPreviewCallback + +textCrawler.makePreview(editText.getText().toString()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + linkPreviewDisposable = d; + linkPreviewCallback.onPre(); + } + + @Override + public void onNext(SourceContent sourceContent) { + try { + linkPreviewCallback.onPos(sourceContent, !sourceContent.isSuccess()); + } catch (Exception e) { + onError(e); + } + } + + @Override + public void onError(Throwable e) { + Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onComplete() { + } + }); +} ``` + #### Cancel unfinished tasks when views are destroied. If you are using Android Link Preview inside of an Activity, it is important to cancel unfinished Preview activites at the end of the Activity's lifecycle. ```java - @Override - protected void onDestroy() { - super.onDestroy(); - textCrawler.cancel(); - } +// using AsyncTask + +@Override +protected void onDestroy() { + super.onDestroy(); + textCrawler.cancel(); +} +``` + +```java +// using RxJava2 + +@Override +protected void onStop() { + if (!linkPreviewDisposable.isDisposed()) linkPreviewDisposable.dispose(); + super.onStop(); +} ``` Apps using Android Link Preview diff --git a/app/build.gradle b/app/build.gradle index b262f4f..821de2a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,6 +25,10 @@ android { dependencies { implementation project(":library") implementation 'com.android.support:appcompat-v7:23.1.1' + implementation 'com.koushikdutta.urlimageviewhelper:urlimageviewhelper:1.0.4' implementation 'org.jsoup:jsoup:1.11.3' + + implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' + implementation 'io.reactivex.rxjava2:rxjava:2.2.12' } diff --git a/app/src/main/java/com/leocardz/link/preview/Main.java b/app/src/main/java/com/leocardz/link/preview/Main.java index f063313..3101270 100644 --- a/app/src/main/java/com/leocardz/link/preview/Main.java +++ b/app/src/main/java/com/leocardz/link/preview/Main.java @@ -22,6 +22,7 @@ import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; +import android.widget.Toast; import com.koushikdutta.urlimageviewhelper.UrlImageViewCallback; import com.koushikdutta.urlimageviewhelper.UrlImageViewHelper; @@ -32,6 +33,11 @@ import java.util.List; import java.util.Random; +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; + @SuppressWarnings("unused") public class Main extends ActionBarActivity { @@ -46,8 +52,7 @@ public class Main extends ActionBarActivity { private TextView previewAreaTitle, postAreaTitle; - private String currentTitle, currentUrl, currentCannonicalUrl, - currentDescription; + private String currentTitle, currentUrl, currentCannonicalUrl, currentDescription; private Bitmap[] currentImageSet; private Bitmap currentImage; @@ -55,6 +60,8 @@ public class Main extends ActionBarActivity { private int countBigImages = 0; private boolean noThumb; + private Disposable linkPreviewDisposable; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -137,7 +144,6 @@ public void onClick(View arg0) { */ private void initPostButton() { postButton.setOnClickListener(new View.OnClickListener() { - @Override public void onClick(View v) { postAreaTitle.setVisibility(View.VISIBLE); @@ -174,8 +180,7 @@ public void onClick(View v) { final TextView descriptionTextView = (TextView) content .findViewById(R.id.description); - contentTextView.setText(TextCrawler.extendedTrim(editText - .getText().toString())); + contentTextView.setText(TextCrawler.Companion.extendedTrim(editText.getText().toString())); if (currentImage != null && !noThumb) { imageView.setImageBitmap(currentImage); @@ -194,7 +199,7 @@ public void onClick(View v) { descriptionTextView.setVisibility(View.GONE); urlTextView.setText(currentCannonicalUrl); - + final String currentUrlLocal = currentUrl; mainView.setOnClickListener(new OnClickListener() { @@ -219,24 +224,48 @@ public void onClick(View arg0) { */ public void initSubmitButton() { submitButton.setOnClickListener(new View.OnClickListener() { - @Override public void onClick(View arg0) { + textCrawler.makePreview(editText.getText().toString()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + linkPreviewDisposable = d; + callback.onPre(); + } + + @Override + public void onNext(SourceContent sourceContent) { + try { + callback.onPos(sourceContent, !sourceContent.isSuccess()); + } catch (Exception e) { + onError(e); + } + } - textCrawler - .makePreview(callback, editText.getText().toString()); - // , TextCrawler.NONE); + @Override + public void onError(Throwable e) { + Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show(); + } + + @Override + public void onComplete() { + } + }); } }); } - /** Callback to update your view. Totally customizable. */ - /** onPre() will be called before the crawling. onPos() after. */ /** + * Callback to update your view. Totally customizable. + * onPre() will be called before the crawling. onPos() after. * You can customize this to update your view */ private LinkPreviewCallback callback = new LinkPreviewCallback() { - /** + + /* * This view is used to be updated or added in the layout after getting * the result */ @@ -356,7 +385,7 @@ public void onClick(View arg0) { titleTextView.setVisibility(View.GONE); titleEditText.setText(TextCrawler - .extendedTrim(titleTextView.getText() + .Companion.extendedTrim(titleTextView.getText() .toString())); titleEditText.setVisibility(View.VISIBLE); } @@ -372,7 +401,7 @@ public boolean onEditorAction(TextView arg0, titleEditText.setVisibility(View.GONE); currentTitle = TextCrawler - .extendedTrim(titleEditText + .Companion.extendedTrim(titleEditText .getText().toString()); titleTextView.setText(currentTitle); @@ -391,7 +420,7 @@ public void onClick(View arg0) { descriptionTextView.setVisibility(View.GONE); descriptionEditText.setText(TextCrawler - .extendedTrim(descriptionTextView.getText() + .Companion.extendedTrim(descriptionTextView.getText() .toString())); descriptionEditText.setVisibility(View.VISIBLE); } @@ -408,7 +437,7 @@ public boolean onEditorAction(TextView arg0, .setVisibility(View.GONE); currentDescription = TextCrawler - .extendedTrim(descriptionEditText + .Companion.extendedTrim(descriptionEditText .getText().toString()); descriptionTextView @@ -512,7 +541,7 @@ public void onLoaded(ImageView imageView, .setDescription(getString(R.string.enter_description)); titleTextView.setText(sourceContent.getTitle()); - urlTextView.setText(sourceContent.getCannonicalUrl()); + urlTextView.setText(sourceContent.getCanonicalUrl()); descriptionTextView.setText(sourceContent.getDescription()); postButton.setVisibility(View.VISIBLE); @@ -521,7 +550,7 @@ public void onLoaded(ImageView imageView, currentTitle = sourceContent.getTitle(); currentDescription = sourceContent.getDescription(); currentUrl = sourceContent.getUrl(); - currentCannonicalUrl = sourceContent.getCannonicalUrl(); + currentCannonicalUrl = sourceContent.getCanonicalUrl(); } }; @@ -634,4 +663,10 @@ private void releasePreviewArea() { previewAreaTitle.setVisibility(View.GONE); dropPreview.removeAllViews(); } + + @Override + protected void onStop() { + if (!linkPreviewDisposable.isDisposed()) linkPreviewDisposable.dispose(); + super.onStop(); + } } diff --git a/build.gradle b/build.gradle index 03fa023..5a87b5c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,5 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - buildscript { + ext.kotlin_version = '1.3.50' repositories { maven { url 'https://github.com/leonardocardoso/mvn-repo/raw/master/maven-deploy' } jcenter() @@ -12,9 +11,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:3.5.1' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/library/build.gradle b/library/build.gradle index c065572..0ebc24c 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,13 +1,15 @@ apply plugin: 'com.android.library' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-android' android { - compileSdkVersion 23 + compileSdkVersion 29 defaultConfig { minSdkVersion 9 - targetSdkVersion 23 + targetSdkVersion 29 versionCode 1 - versionName "1.2.2" + versionName "1.3.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } @@ -22,8 +24,15 @@ android { dependencies { implementation 'org.jsoup:jsoup:1.11.3' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + + implementation 'io.reactivex.rxjava2:rxjava:2.2.12' androidTestImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'org.mockito:mockito-android:2.22.0' } + +repositories { + mavenCentral() +} diff --git a/library/src/androidTest/java/com/leocardz/link/preview/library/ProvidedDocumentTextCrawler.java b/library/src/androidTest/java/com/leocardz/link/preview/library/ProvidedDocumentTextCrawler.java index 7b13c39..a76c3bf 100644 --- a/library/src/androidTest/java/com/leocardz/link/preview/library/ProvidedDocumentTextCrawler.java +++ b/library/src/androidTest/java/com/leocardz/link/preview/library/ProvidedDocumentTextCrawler.java @@ -16,8 +16,8 @@ public ProvidedDocumentTextCrawler(final String html) { } @Override - protected GetCode createPreviewGenerator(ImagePickingStrategy imagePickingStrategy) { - return new GetCode(imagePickingStrategy, null) { + protected AsyncTaskImpl createPreviewGenerator(ImagePickingStrategy imagePickingStrategy) { + return new AsyncTaskImpl(imagePickingStrategy, null) { @Override protected Document getDocument() throws IOException { diff --git a/library/src/androidTest/java/com/leocardz/link/preview/library/TextCrawlerTest.java b/library/src/androidTest/java/com/leocardz/link/preview/library/TextCrawlerTest.java index 2714b60..9745233 100644 --- a/library/src/androidTest/java/com/leocardz/link/preview/library/TextCrawlerTest.java +++ b/library/src/androidTest/java/com/leocardz/link/preview/library/TextCrawlerTest.java @@ -74,8 +74,8 @@ public void urlExhibitingInfiniteRedirectIssueCanBeProcessed() throws Throwable private class JSoupFailingTextCrawler extends TextCrawler { @Override - protected GetCode createPreviewGenerator(ImagePickingStrategy imagePickingStrategy) { - return new GetCode(imagePickingStrategy, null) { + protected AsyncTaskImpl createPreviewGenerator(ImagePickingStrategy imagePickingStrategy) { + return new AsyncTaskImpl(imagePickingStrategy, null) { @Override protected Document getDocument() throws IOException { diff --git a/library/src/main/java/com/leocardz/link/preview/library/BaseImagePickingStrategy.java b/library/src/main/java/com/leocardz/link/preview/library/BaseImagePickingStrategy.java deleted file mode 100644 index 790fec8..0000000 --- a/library/src/main/java/com/leocardz/link/preview/library/BaseImagePickingStrategy.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.leocardz.link.preview.library; - -import android.os.AsyncTask; - -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.select.Elements; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public abstract class BaseImagePickingStrategy implements ImagePickingStrategy { - private int imageQuantity = TextCrawler.ALL; - - @Override - public void setImageQuantity(int imageQuantity) { - this.imageQuantity = imageQuantity; - } - - @Override - public int getImageQuantity() { - return imageQuantity; - } - - protected List getMetaImage(HashMap metaTags) { - List images = new ArrayList<>(); - final String metaImage = metaTags.get("image"); - - if (!metaImage.equals("")) { - images.add(metaImage); - } - return images; - } - - protected List getImagesFromImgTags(AsyncTask asyncTask, Document document) { - List images = new ArrayList<>(); - Elements media = document.select("[src]"); - - for (Element srcElement : media) { - if (asyncTask.isCancelled()) { - break; - } - if (srcElement.tagName().equals("img")) { - images.add(srcElement.attr("abs:src")); - if (getImageQuantity() != TextCrawler.ALL && images.size() == getImageQuantity()) { - break; - } - } - } - return images; - } -} diff --git a/library/src/main/java/com/leocardz/link/preview/library/BaseImagePickingStrategy.kt b/library/src/main/java/com/leocardz/link/preview/library/BaseImagePickingStrategy.kt new file mode 100644 index 0000000..fb4893b --- /dev/null +++ b/library/src/main/java/com/leocardz/link/preview/library/BaseImagePickingStrategy.kt @@ -0,0 +1,40 @@ +package com.leocardz.link.preview.library + +import org.jsoup.nodes.Document +import java.util.* + +abstract class BaseImagePickingStrategy : ImagePickingStrategy { + + protected fun getMetaImage(metaTags: HashMap): List { + val images = ArrayList() + val metaImage = metaTags["image"]!! + if (metaImage != "") { + images.add(metaImage) + } + return images + } + + protected fun getImagesFromImgTags(getSource: GetSource, document: Document): List { + val images = ArrayList() + val media = document.select("[src]") + + for (srcElement in media) { + if (getSource.isCallCancelled()) { + break + } + if (srcElement.tagName() == "img") { + images.add(srcElement.attr("abs:src")) + if (imageQuantity != QUANTITY_ALL && images.size == imageQuantity) { + break + } + } + } + return images + } + + companion object { + + var QUANTITY_ALL = -1 + var QUANTITY_NONE = -2 + } +} diff --git a/library/src/main/java/com/leocardz/link/preview/library/DefaultImagePickingStrategy.java b/library/src/main/java/com/leocardz/link/preview/library/DefaultImagePickingStrategy.java index bfe788e..30f7640 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/DefaultImagePickingStrategy.java +++ b/library/src/main/java/com/leocardz/link/preview/library/DefaultImagePickingStrategy.java @@ -1,7 +1,5 @@ package com.leocardz.link.preview.library; -import android.os.AsyncTask; - import org.jsoup.nodes.Document; import java.util.HashMap; @@ -13,16 +11,35 @@ */ class DefaultImagePickingStrategy extends BaseImagePickingStrategy { + private int imageQuantity; + + public DefaultImagePickingStrategy() { + this(Companion.getQUANTITY_ALL()); + } + + public DefaultImagePickingStrategy(int imageQuantity) { + setImageQuantity(imageQuantity); + } + /** * Gets images from the html code */ @Override - public List getImages(AsyncTask asyncTask, Document document, HashMap metaTags) { + public List getImages(GetSource getSource, Document document, HashMap metaTags) { List images = getMetaImage(metaTags); - if (images.isEmpty()) { - images.addAll(getImagesFromImgTags(asyncTask, document)); + images.addAll(getImagesFromImgTags(getSource, document)); } return images; } + + @Override + public int getImageQuantity() { + return imageQuantity; + } + + @Override + public void setImageQuantity(int i) { + imageQuantity = i; + } } diff --git a/library/src/main/java/com/leocardz/link/preview/library/GetSource.kt b/library/src/main/java/com/leocardz/link/preview/library/GetSource.kt new file mode 100644 index 0000000..64ebabb --- /dev/null +++ b/library/src/main/java/com/leocardz/link/preview/library/GetSource.kt @@ -0,0 +1,15 @@ +package com.leocardz.link.preview.library + +/** + * @author dhruvaraj nagarajan + */ +interface GetSource { + + fun getSourceCode(url: String): SourceContent + + fun isNull(sourceContent: SourceContent): Boolean + + fun cancel() + + fun isCallCancelled(): Boolean +} diff --git a/library/src/main/java/com/leocardz/link/preview/library/GetSourceAynscTask.kt b/library/src/main/java/com/leocardz/link/preview/library/GetSourceAynscTask.kt new file mode 100644 index 0000000..82ad6af --- /dev/null +++ b/library/src/main/java/com/leocardz/link/preview/library/GetSourceAynscTask.kt @@ -0,0 +1,30 @@ +package com.leocardz.link.preview.library + +import android.os.AsyncTask +import com.leocardz.link.preview.library.url.DefaultUrlExtractionStrategy +import com.leocardz.link.preview.library.url.UrlExtractionStrategy + +/** + * @author dhruvaraj nagarajan + */ +class GetSourceAynscTask( + private val callback: LinkPreviewCallback, + private val imagePickingStrategy: ImagePickingStrategy = DefaultImagePickingStrategy(), + private val urlExtractionStrategy: UrlExtractionStrategy = DefaultUrlExtractionStrategy() +) : AsyncTask(), GetSource by GetSourceSync(imagePickingStrategy, urlExtractionStrategy) { + + override fun onPreExecute() { + callback.onPre() + super.onPreExecute() + } + + override fun onPostExecute(result: SourceContent) { + callback.onPos(result, isNull(result)) + super.onPostExecute(result) + } + + override fun doInBackground(vararg params: String): SourceContent { + val url = params[0] + return getSourceCode(url) + } +} \ No newline at end of file diff --git a/library/src/main/java/com/leocardz/link/preview/library/GetSourceObservable.kt b/library/src/main/java/com/leocardz/link/preview/library/GetSourceObservable.kt new file mode 100644 index 0000000..95b0ce4 --- /dev/null +++ b/library/src/main/java/com/leocardz/link/preview/library/GetSourceObservable.kt @@ -0,0 +1,27 @@ +package com.leocardz.link.preview.library + +import com.leocardz.link.preview.library.url.DefaultUrlExtractionStrategy +import com.leocardz.link.preview.library.url.UrlExtractionStrategy +import io.reactivex.Observable + +/** + * @author dhruvaraj nagarajan + */ +class GetSourceObservable( + private val url: String, + private val imagePickingStrategy: ImagePickingStrategy = DefaultImagePickingStrategy(), + private val urlExtractionStrategy: UrlExtractionStrategy = DefaultUrlExtractionStrategy() +) : GetSource by GetSourceSync(imagePickingStrategy, urlExtractionStrategy) { + + fun getObservable() = Observable.create { emitter -> + val sourceContent = getSourceCode(url) + + if (!sourceContent.isSuccess) { + emitter.onError(Exception("Content is null.")) + return@create + } + + emitter.onNext(sourceContent) + emitter.onComplete() + } +} \ No newline at end of file diff --git a/library/src/main/java/com/leocardz/link/preview/library/GetSourceSync.kt b/library/src/main/java/com/leocardz/link/preview/library/GetSourceSync.kt new file mode 100644 index 0000000..955657c --- /dev/null +++ b/library/src/main/java/com/leocardz/link/preview/library/GetSourceSync.kt @@ -0,0 +1,347 @@ +package com.leocardz.link.preview.library + +import com.leocardz.link.preview.library.Util.extendedTrim +import com.leocardz.link.preview.library.url.UrlExtractionStrategy +import org.jsoup.Jsoup +import org.jsoup.UnsupportedMimeTypeException +import org.jsoup.nodes.Document +import java.io.IOException +import java.net.MalformedURLException +import java.net.URL +import java.net.URLConnection +import java.util.* + +/** + * Reads url result synchronously. + * + * Wrap this in your choice of async wrapper, like Rx or Coroutine. + */ +class GetSourceSync( + private val imagePickingStrategy: ImagePickingStrategy, + private val urlExtractionStrategy: UrlExtractionStrategy +) : GetSource { + + private val HTTP_PROTOCOL = "http://" + private val HTTPS_PROTOCOL = "https://" + + private var _isCancelled = false + + override fun getSourceCode(url: String): SourceContent { + var url = url + val sourceContent = SourceContent() + + url = unshortenUrl(url) + + sourceContent.finalUrl = url + var wasPreviewGenerationSuccessful = false + if (url != "") { + if (isImage(url) && !url.contains("dropbox")) { + sourceContent.images.add(sourceContent.finalUrl) + sourceContent.title = "" + sourceContent.description = "" + wasPreviewGenerationSuccessful = true + } else { + try { + val doc = getDocument(sourceContent) + + sourceContent.htmlCode = extendedTrim(doc.toString()) + + val metaTags = getMetaTags(sourceContent.htmlCode) + + sourceContent.metaTags = metaTags + + sourceContent.title = metaTags["title"] + sourceContent.description = metaTags["description"] + + if (sourceContent.title == "") { + val matchTitle = Regex.pregMatch( + sourceContent.htmlCode, + Regex.TITLE_PATTERN, 2) + + if (matchTitle != "") + sourceContent.title = htmlDecode(matchTitle) + } + + if (sourceContent.description == "") + sourceContent.description = crawlCode(sourceContent.htmlCode) + + sourceContent.description = sourceContent.description.replace(Regex.SCRIPT_PATTERN.toRegex(), "") + + if (imagePickingStrategy.imageQuantity != BaseImagePickingStrategy.QUANTITY_NONE) { + val images: List = imagePickingStrategy.getImages(this, doc, metaTags) + sourceContent.images = images + } + + wasPreviewGenerationSuccessful = true + } catch (t: Throwable) { + if (t is UnsupportedMimeTypeException) { + val mimeType = t.mimeType + if (mimeType != null && mimeType.startsWith("image")) { + sourceContent.images.add(sourceContent.finalUrl) + sourceContent.title = "" + sourceContent.description = "" + wasPreviewGenerationSuccessful = true + } + } + } + } + + sourceContent.isSuccess = wasPreviewGenerationSuccessful + } + + val finalLinkSet = sourceContent.finalUrl.split("&".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + sourceContent.url = finalLinkSet[0] + sourceContent.canonicalUrl = cannonicalPage(sourceContent.finalUrl) + sourceContent.description = stripTags(sourceContent.description) + + return sourceContent + } + + /** + * Verifies if the content could not be retrieved + */ + override fun isNull(sourceContent: SourceContent): Boolean { + return !sourceContent.isSuccess && + extendedTrim(sourceContent.htmlCode) == "" && + !isImage(sourceContent.finalUrl) + } + + override fun cancel() { + _isCancelled = true + } + + override fun isCallCancelled(): Boolean = _isCancelled + + /** + * Verifies if the url is an image + */ + fun isImage(url: String): Boolean { + return url.matches(Regex.IMAGE_PATTERN.toRegex()) + } + + @Throws(IOException::class) + private fun getDocument(sourceContent: SourceContent): Document { + return Jsoup.connect(sourceContent.finalUrl).userAgent("Mozilla").get() + } + + /** + * Gets content from a html tag + */ + private fun getTagContent(tag: String, content: String): String { + + val pattern = "<$tag(.*?)>(.*?)" + var result = "" + var currentMatch = "" + + val matches = Regex.pregMatchAll(content, pattern, 2) + + val matchesSize = matches.size + for (i in 0 until matchesSize) { + if (isCallCancelled()) { + break + } + currentMatch = stripTags(matches[i]) + if (currentMatch.length >= 120) { + result = extendedTrim(currentMatch) + break + } + } + + if (result == "") { + val matchFinal = Regex.pregMatch(content, pattern, 2) + result = extendedTrim(matchFinal) + } + + result = result.replace(" ".toRegex(), "") + + return htmlDecode(result) + } + + /** + * Transforms from html to normal string + */ + private fun htmlDecode(content: String): String { + return Jsoup.parse(content).text() + } + + /** + * Crawls the code looking for relevant information + */ + private fun crawlCode(content: String): String { + val resultSpan = getTagContent("span", content) + val resultParagraph = getTagContent("p", content) + val resultDiv = getTagContent("div", content) + + val result: String + + if (resultParagraph.length > resultSpan.length && resultParagraph.length >= resultDiv.length) + result = resultParagraph + else if (resultParagraph.length > resultSpan.length && resultParagraph.length < resultDiv.length) + result = resultDiv + else + result = resultParagraph + + return htmlDecode(result) + } + + /** + * Returns the cannoncial url + */ + private fun cannonicalPage(url: String): String { + var url = url + + var cannonical = "" + if (url.startsWith(HTTP_PROTOCOL)) { + url = url.substring(HTTP_PROTOCOL.length) + } else if (url.startsWith(HTTPS_PROTOCOL)) { + url = url.substring(HTTPS_PROTOCOL.length) + } + + val urlLength = url.length + for (i in 0 until urlLength) { + if (isCallCancelled()) { + break + } + if (url[i] != '/') + cannonical += url[i] + else + break + } + + return cannonical + + } + + /** + * Strips the tags from an element + */ + private fun stripTags(content: String): String { + return Jsoup.parse(content).text() + } + + /** + * Returns meta tags from html code + */ + private fun getMetaTags(content: String): HashMap { + + val metaTags = HashMap() + metaTags["url"] = "" + metaTags["title"] = "" + metaTags["description"] = "" + metaTags["image"] = "" + + val matches = Regex.pregMatchAll(content, + Regex.METATAG_PATTERN, 1) + + for (match in matches) { + if (isCallCancelled()) { + break + } + val lowerCase = match.toLowerCase() + if (lowerCase.contains("property=\"og:url\"") + || lowerCase.contains("property='og:url'") + || lowerCase.contains("name=\"url\"") + || lowerCase.contains("name='url'")) + updateMetaTag(metaTags, "url", separeMetaTagsContent(match)) + else if (lowerCase.contains("property=\"og:title\"") + || lowerCase.contains("property='og:title'") + || lowerCase.contains("name=\"title\"") + || lowerCase.contains("name='title'")) + updateMetaTag(metaTags, "title", separeMetaTagsContent(match)) + else if (lowerCase + .contains("property=\"og:description\"") + || lowerCase + .contains("property='og:description'") + || lowerCase.contains("name=\"description\"") + || lowerCase.contains("name='description'")) + updateMetaTag(metaTags, "description", separeMetaTagsContent(match)) + else if (lowerCase.contains("property=\"og:image\"") + || lowerCase.contains("property='og:image'") + || lowerCase.contains("name=\"image\"") + || lowerCase.contains("name='image'")) + updateMetaTag(metaTags, "image", separeMetaTagsContent(match)) + } + + return metaTags + } + + private fun updateMetaTag(metaTags: HashMap, url: String, value: String?) { + if (value != null && value.length > 0) { + metaTags[url] = value + } + } + + /** + * Gets content from metatag + */ + private fun separeMetaTagsContent(content: String): String { + val result = Regex.pregMatch(content, Regex.METATAG_CONTENT_PATTERN, + 1) + return htmlDecode(result) + } + + /** + * Unshortens a short url + */ + private fun unshortenUrl(originURL: String): String { + if (!originURL.startsWith(HTTP_PROTOCOL) && !originURL.startsWith(HTTPS_PROTOCOL)) + return "" + + var urlConn = connectURL(originURL) + urlConn!!.headerFields + + val finalUrl = urlConn.url + + urlConn = connectURL(finalUrl) + urlConn!!.headerFields + + val shortURL = urlConn.url + + var finalResult = shortURL.toString() + + while (!shortURL.sameFile(finalUrl)) { + var isEndlesslyRedirecting = false + if (shortURL.host == finalUrl.host) { + if (shortURL.path == finalUrl.path) { + isEndlesslyRedirecting = true + } + } + if (isEndlesslyRedirecting) { + break + } else { + finalResult = unshortenUrl(shortURL.toString()) + } + } + + return finalResult + } + + /** + * Takes a valid url string and returns a URLConnection object for the url. + */ + private fun connectURL(strURL: String): URLConnection? { + var conn: URLConnection? = null + try { + val inputURL = URL(strURL) + conn = connectURL(inputURL) + } catch (e: MalformedURLException) { + println("Please input a valid URL") + } + + return conn + } + + /** + * Takes a valid url and returns a URLConnection object for the url. + */ + private fun connectURL(inputURL: URL): URLConnection? { + var conn: URLConnection? = null + try { + conn = inputURL.openConnection() + } catch (ioe: IOException) { + println("Can not connect to the URL") + } + + return conn + } +} diff --git a/library/src/main/java/com/leocardz/link/preview/library/ImagePickingStrategy.java b/library/src/main/java/com/leocardz/link/preview/library/ImagePickingStrategy.java deleted file mode 100644 index a38f86b..0000000 --- a/library/src/main/java/com/leocardz/link/preview/library/ImagePickingStrategy.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.leocardz.link.preview.library; - -import android.os.AsyncTask; - -import org.jsoup.nodes.Document; - -import java.util.HashMap; -import java.util.List; - -/** - * A strategy for how to select the images to return. - */ -public interface ImagePickingStrategy { - - void setImageQuantity(int imageQuantity); - - int getImageQuantity(); - - List getImages(AsyncTask asyncTask, Document doc, HashMap metaTags); -} diff --git a/library/src/main/java/com/leocardz/link/preview/library/ImagePickingStrategy.kt b/library/src/main/java/com/leocardz/link/preview/library/ImagePickingStrategy.kt new file mode 100644 index 0000000..7baa5c7 --- /dev/null +++ b/library/src/main/java/com/leocardz/link/preview/library/ImagePickingStrategy.kt @@ -0,0 +1,14 @@ +package com.leocardz.link.preview.library + +import org.jsoup.nodes.Document +import java.util.* + +/** + * A strategy for how to select the images to return. + */ +interface ImagePickingStrategy { + + var imageQuantity: Int + + fun getImages(getSource: GetSource, doc: Document, metaTags: HashMap): List +} diff --git a/library/src/main/java/com/leocardz/link/preview/library/Regex.java b/library/src/main/java/com/leocardz/link/preview/library/Regex.java index 7181713..fcdbb6d 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/Regex.java +++ b/library/src/main/java/com/leocardz/link/preview/library/Regex.java @@ -28,7 +28,7 @@ public static String pregMatch(String content, String pattern, int index) { break; } - return TextCrawler.extendedTrim(match); + return TextCrawler.Companion.extendedTrim(match); } public static List pregMatchAll(String content, String pattern, @@ -38,7 +38,7 @@ public static List pregMatchAll(String content, String pattern, Matcher matcher = Pattern.compile(pattern).matcher(content); while (matcher.find()) { - matches.add(TextCrawler.extendedTrim(matcher.group(index))); + matches.add(TextCrawler.Companion.extendedTrim(matcher.group(index))); } return matches; @@ -50,7 +50,7 @@ public static List pregMatchAllImages(String content, String pattern) { Matcher matcher = Pattern.compile(pattern).matcher(content); while (matcher.find()) { - matches.add(TextCrawler.extendedTrim(matcher.group(3)) + matches.add(TextCrawler.Companion.extendedTrim(matcher.group(3)) + matcher.group(4)); } @@ -64,7 +64,7 @@ public static List pregMatchAllExtraImages(String content, Matcher matcher = Pattern.compile(pattern).matcher(content); while (matcher.find()) { - matches.add(TextCrawler.extendedTrim(matcher.group(3)) + matches.add(TextCrawler.Companion.extendedTrim(matcher.group(3)) + matcher.group(4)); } diff --git a/library/src/main/java/com/leocardz/link/preview/library/SourceContent.java b/library/src/main/java/com/leocardz/link/preview/library/SourceContent.java index a922ef6..c0b13a3 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/SourceContent.java +++ b/library/src/main/java/com/leocardz/link/preview/library/SourceContent.java @@ -6,185 +6,175 @@ public class SourceContent { - private boolean success = false; - private String htmlCode = ""; - private String raw = ""; - private String title = ""; - private String description = ""; - private String url = ""; - private String finalUrl = ""; - private String cannonicalUrl = ""; - private HashMap metaTags = new HashMap(); - - private List images = new ArrayList(); - private String[] urlData = new String[2]; - - public SourceContent() { - } - - /** - * @return the success - */ - public boolean isSuccess() { - return success; - } - - /** - * @param success - * the success to set - */ - public void setSuccess(boolean success) { - this.success = success; - } - - /** - * @return the htmlCode - */ - public String getHtmlCode() { - return htmlCode; - } - - /** - * @param htmlCode - * the htmlCode to set - */ - public void setHtmlCode(String htmlCode) { - this.htmlCode = htmlCode; - } - - /** - * @return the raw - */ - public String getRaw() { - return raw; - } - - /** - * @param raw - * the raw to set - */ - public void setRaw(String raw) { - this.raw = raw; - } - - /** - * @return the title - */ - public String getTitle() { - return title; - } - - /** - * @param title - * the title to set - */ - public void setTitle(String title) { - this.title = title; - } - - /** - * @return the description - */ - public String getDescription() { - return description; - } - - /** - * @param description - * the description to set - */ - public void setDescription(String description) { - this.description = description; - } - - /** - * @return the url - */ - public String getUrl() { - return url; - } - - /** - * @param url - * the url to set - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * @return the finalUrl - */ - public String getFinalUrl() { - return finalUrl; - } - - /** - * @param finalUrl - * the finalUrl to set - */ - public void setFinalUrl(String finalUrl) { - this.finalUrl = finalUrl; - } - - /** - * @return the cannonicalUrl - */ - public String getCannonicalUrl() { - return cannonicalUrl; - } - - /** - * @param cannonicalUrl - * the cannonicalUrl to set - */ - public void setCannonicalUrl(String cannonicalUrl) { - this.cannonicalUrl = cannonicalUrl; - } - - /** - * @return the metaTags - */ - public HashMap getMetaTags() { - return metaTags; - } - - /** - * @param metaTags - * the metaTags to set - */ - public void setMetaTags(HashMap metaTags) { - this.metaTags = metaTags; - } - - /** - * @return the images - */ - public List getImages() { - return images; - } - - /** - * @param images - * the images to set - */ - public void setImages(List images) { - this.images = images; - } - - /** - * @return the urlData - */ - public String[] getUrlData() { - return urlData; - } - - /** - * @param urlData - * the urlData to set - */ - public void setUrlData(String[] urlData) { - this.urlData = urlData; - } + private boolean success = false; + + private String htmlCode = ""; + private String raw = ""; + private String title = ""; + private String description = ""; + private String url = ""; + private String finalUrl = ""; + private String canonicalUrl = ""; + private HashMap metaTags = new HashMap<>(); + + private List images = new ArrayList<>(); + private String[] urlData = new String[2]; + + public SourceContent() { + } + + /** + * @return the success + */ + public boolean isSuccess() { + return success; + } + + /** + * @param success the success to set + */ + public void setSuccess(boolean success) { + this.success = success; + } + + /** + * @return the htmlCode + */ + public String getHtmlCode() { + return htmlCode; + } + + /** + * @param htmlCode the htmlCode to set + */ + public void setHtmlCode(String htmlCode) { + this.htmlCode = htmlCode; + } + + /** + * @return the raw + */ + public String getRaw() { + return raw; + } + + /** + * @param raw the raw to set + */ + public void setRaw(String raw) { + this.raw = raw; + } + + /** + * @return the title + */ + public String getTitle() { + return title; + } + + /** + * @param title the title to set + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * @param description the description to set + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * @return the url + */ + public String getUrl() { + return url; + } + + /** + * @param url the url to set + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * @return the finalUrl + */ + public String getFinalUrl() { + return finalUrl; + } + + /** + * @param finalUrl the finalUrl to set + */ + public void setFinalUrl(String finalUrl) { + this.finalUrl = finalUrl; + } + + /** + * @return the canonicalUrl + */ + public String getCanonicalUrl() { + return canonicalUrl; + } + + /** + * @param canonicalUrl the canonicalUrl to set + */ + public void setCanonicalUrl(String canonicalUrl) { + this.canonicalUrl = canonicalUrl; + } + + /** + * @return the metaTags + */ + public HashMap getMetaTags() { + return metaTags; + } + + /** + * @param metaTags the metaTags to set + */ + public void setMetaTags(HashMap metaTags) { + this.metaTags = metaTags; + } + + /** + * @return the images + */ + public List getImages() { + return images; + } + + /** + * @param images the images to set + */ + public void setImages(List images) { + this.images = images; + } + + /** + * @return the urlData + */ + public String[] getUrlData() { + return urlData; + } + + /** + * @param urlData the urlData to set + */ + public void setUrlData(String[] urlData) { + this.urlData = urlData; + } } diff --git a/library/src/main/java/com/leocardz/link/preview/library/TextCrawler.java b/library/src/main/java/com/leocardz/link/preview/library/TextCrawler.java deleted file mode 100644 index 19ccc12..0000000 --- a/library/src/main/java/com/leocardz/link/preview/library/TextCrawler.java +++ /dev/null @@ -1,432 +0,0 @@ -package com.leocardz.link.preview.library; - -import android.os.AsyncTask; - -import com.leocardz.link.preview.library.url.DefaultUrlExtractionStrategy; -import com.leocardz.link.preview.library.url.UrlExtractionStrategy; - -import org.jsoup.Jsoup; -import org.jsoup.UnsupportedMimeTypeException; -import org.jsoup.nodes.Document; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.util.HashMap; -import java.util.List; - -public class TextCrawler { - - public static final int ALL = -1; - public static final int NONE = -2; - - private final String HTTP_PROTOCOL = "http://"; - private final String HTTPS_PROTOCOL = "https://"; - - private LinkPreviewCallback callback; - - private AsyncTask getCodeTask; - - private UrlExtractionStrategy urlExtractionStrategy; - - public TextCrawler() { - } - - public void makePreview(LinkPreviewCallback callback, String url) { - ImagePickingStrategy imagePickingStrategy = new DefaultImagePickingStrategy(); - - makePreview(callback, url, imagePickingStrategy); - } - - public void makePreview(LinkPreviewCallback callback, String url, - int imageQuantity) { - ImagePickingStrategy imagePickingStrategy = new DefaultImagePickingStrategy(); - imagePickingStrategy.setImageQuantity(imageQuantity); - makePreview(callback, url, imagePickingStrategy); - } - - public void makePreview(LinkPreviewCallback callback, String url, ImagePickingStrategy imagePickingStrategy) { - this.callback = callback; - cancel(); - getCodeTask = createPreviewGenerator(imagePickingStrategy).execute(url); - } - - protected GetCode createPreviewGenerator(ImagePickingStrategy imagePickingStrategy) { - return new GetCode(imagePickingStrategy, urlExtractionStrategy); - } - - public void cancel(){ - if(getCodeTask != null){ - getCodeTask.cancel(true); - } - } - - public void setUrlExtractionStrategy(UrlExtractionStrategy urlExtractionStrategy) { - this.urlExtractionStrategy = urlExtractionStrategy; - } - - - /** - * Get html code - */ - class GetCode extends AsyncTask { - - private SourceContent sourceContent = new SourceContent(); - private final ImagePickingStrategy imagePickingStrategy; - private final UrlExtractionStrategy urlExtractionStrategy; - - GetCode(ImagePickingStrategy imagePickingStrategy, UrlExtractionStrategy urlExtractionStrategy) { - this.imagePickingStrategy = imagePickingStrategy; - if (urlExtractionStrategy == null) { - urlExtractionStrategy = new DefaultUrlExtractionStrategy(); - } - this.urlExtractionStrategy = urlExtractionStrategy; - } - - @Override - protected void onPreExecute() { - if (callback != null) { - callback.onPre(); - } - super.onPreExecute(); - } - - @Override - protected void onPostExecute(Void result) { - if (callback != null) { - callback.onPos(sourceContent, isNull()); - } - super.onPostExecute(result); - } - - @Override - protected void onCancelled() { - super.onCancelled(); - } - - @Override - protected Void doInBackground(String... params) { - final List urlStrings = urlExtractionStrategy.extractUrls(params[0]); - String url; - if (urlStrings != null && !urlStrings.isEmpty()) { - url = unshortenUrl(urlStrings.get(0)); - } else { - url = ""; - } - - sourceContent.setFinalUrl(url); - boolean wasPreviewGenerationSuccessful = false; - if (!url.equals("")) { - if (isImage(url) && !url.contains("dropbox")) { - setSourceContentForImage(); - wasPreviewGenerationSuccessful = true; - } else { - try { - Document doc = getDocument(); - - sourceContent.setHtmlCode(extendedTrim(doc.toString())); - - HashMap metaTags = getMetaTags(sourceContent - .getHtmlCode()); - - sourceContent.setMetaTags(metaTags); - - sourceContent.setTitle(metaTags.get("title")); - sourceContent.setDescription(metaTags - .get("description")); - - if (sourceContent.getTitle().equals("")) { - String matchTitle = Regex.pregMatch( - sourceContent.getHtmlCode(), - Regex.TITLE_PATTERN, 2); - - if (!matchTitle.equals("")) - sourceContent.setTitle(htmlDecode(matchTitle)); - } - - if (sourceContent.getDescription().equals("")) - sourceContent - .setDescription(crawlCode(sourceContent - .getHtmlCode())); - - sourceContent.setDescription(sourceContent - .getDescription().replaceAll( - Regex.SCRIPT_PATTERN, "")); - - if (imagePickingStrategy.getImageQuantity() != NONE) { - List images; - images = imagePickingStrategy.getImages(getCodeTask, doc, metaTags); - sourceContent.setImages(images); - } - - wasPreviewGenerationSuccessful = true; - } catch (Throwable t) { - if (t instanceof UnsupportedMimeTypeException) { - final String mimeType = ((UnsupportedMimeTypeException) t).getMimeType(); - if (mimeType != null && mimeType.startsWith("image")) { - setSourceContentForImage(); - wasPreviewGenerationSuccessful = true; - } - } - } - } - sourceContent.setSuccess(wasPreviewGenerationSuccessful); - } - - String[] finalLinkSet = sourceContent.getFinalUrl().split("&"); - sourceContent.setUrl(finalLinkSet[0]); - - sourceContent.setCannonicalUrl(cannonicalPage(sourceContent - .getFinalUrl())); - sourceContent.setDescription(stripTags(sourceContent - .getDescription())); - - return null; - } - - /** - * Configures the sourceContent for an Image. - */ - private void setSourceContentForImage() { - sourceContent.getImages().add(sourceContent.getFinalUrl()); - - sourceContent.setTitle(""); - sourceContent.setDescription(""); - } - - protected Document getDocument() throws IOException { - return Jsoup.connect(sourceContent.getFinalUrl()).userAgent("Mozilla").get(); - } - - /** Verifies if the content could not be retrieved */ - public boolean isNull() { - return !sourceContent.isSuccess() && - extendedTrim(sourceContent.getHtmlCode()).equals("") && - !isImage(sourceContent.getFinalUrl()); - } - - } - - /** Gets content from a html tag */ - private String getTagContent(String tag, String content) { - - String pattern = "<" + tag + "(.*?)>(.*?)"; - String result = "", currentMatch = ""; - - List matches = Regex.pregMatchAll(content, pattern, 2); - - int matchesSize = matches.size(); - for (int i = 0; i < matchesSize; i++) { - if(getCodeTask.isCancelled()){ - break; - } - currentMatch = stripTags(matches.get(i)); - if (currentMatch.length() >= 120) { - result = extendedTrim(currentMatch); - break; - } - } - - if (result.equals("")) { - String matchFinal = Regex.pregMatch(content, pattern, 2); - result = extendedTrim(matchFinal); - } - - result = result.replaceAll(" ", ""); - - return htmlDecode(result); - } - - /** Transforms from html to normal string */ - private String htmlDecode(String content) { - return Jsoup.parse(content).text(); - } - - /** - * Crawls the code looking for relevant information - */ - private String crawlCode(String content) { - String resultSpan = getTagContent("span", content); - String resultParagraph = getTagContent("p", content); - String resultDiv = getTagContent("div", content); - - String result; - - if (resultParagraph.length() > resultSpan.length() - && resultParagraph.length() >= resultDiv.length()) - result = resultParagraph; - else if (resultParagraph.length() > resultSpan.length() - && resultParagraph.length() < resultDiv.length()) - result = resultDiv; - else - result = resultParagraph; - - return htmlDecode(result); - } - - /** Returns the cannoncial url */ - private String cannonicalPage(String url) { - - String cannonical = ""; - if (url.startsWith(HTTP_PROTOCOL)) { - url = url.substring(HTTP_PROTOCOL.length()); - } else if (url.startsWith(HTTPS_PROTOCOL)) { - url = url.substring(HTTPS_PROTOCOL.length()); - } - - int urlLength = url.length(); - for (int i = 0; i < urlLength; i++) { - if(getCodeTask.isCancelled()){ - break; - } - if (url.charAt(i) != '/') - cannonical += url.charAt(i); - else - break; - } - - return cannonical; - - } - - /** Strips the tags from an element */ - private String stripTags(String content) { - return Jsoup.parse(content).text(); - } - - /** Verifies if the url is an image */ - private boolean isImage(String url) { - return url.matches(Regex.IMAGE_PATTERN); - } - - /** - * Returns meta tags from html code - */ - private HashMap getMetaTags(String content) { - - HashMap metaTags = new HashMap(); - metaTags.put("url", ""); - metaTags.put("title", ""); - metaTags.put("description", ""); - metaTags.put("image", ""); - - List matches = Regex.pregMatchAll(content, - Regex.METATAG_PATTERN, 1); - - for (String match : matches) { - if(getCodeTask.isCancelled()){ - break; - } - final String lowerCase = match.toLowerCase(); - if (lowerCase.contains("property=\"og:url\"") - || lowerCase.contains("property='og:url'") - || lowerCase.contains("name=\"url\"") - || lowerCase.contains("name='url'")) - updateMetaTag(metaTags, "url", separeMetaTagsContent(match)); - else if (lowerCase.contains("property=\"og:title\"") - || lowerCase.contains("property='og:title'") - || lowerCase.contains("name=\"title\"") - || lowerCase.contains("name='title'")) - updateMetaTag(metaTags, "title", separeMetaTagsContent(match)); - else if (lowerCase - .contains("property=\"og:description\"") - || lowerCase - .contains("property='og:description'") - || lowerCase.contains("name=\"description\"") - || lowerCase.contains("name='description'")) - updateMetaTag(metaTags, "description", separeMetaTagsContent(match)); - else if (lowerCase.contains("property=\"og:image\"") - || lowerCase.contains("property='og:image'") - || lowerCase.contains("name=\"image\"") - || lowerCase.contains("name='image'")) - updateMetaTag(metaTags, "image", separeMetaTagsContent(match)); - } - - return metaTags; - } - - private void updateMetaTag(HashMap metaTags, String url, String value) { - if (value != null && (value.length() > 0)) { - metaTags.put(url, value); - } - } - - /** Gets content from metatag */ - private String separeMetaTagsContent(String content) { - String result = Regex.pregMatch(content, Regex.METATAG_CONTENT_PATTERN, - 1); - return htmlDecode(result); - } - - /** - * Unshortens a short url - */ - private String unshortenUrl(final String originURL) { - if (!originURL.startsWith(HTTP_PROTOCOL) - && !originURL.startsWith(HTTPS_PROTOCOL)) - return ""; - - URLConnection urlConn = connectURL(originURL); - urlConn.getHeaderFields(); - - final URL finalUrl = urlConn.getURL(); - - urlConn = connectURL(finalUrl); - urlConn.getHeaderFields(); - - final URL shortURL = urlConn.getURL(); - - String finalResult = shortURL.toString(); - - while (!shortURL.sameFile(finalUrl)) { - boolean isEndlesslyRedirecting = false; - if (shortURL.getHost().equals(finalUrl.getHost())) { - if (shortURL.getPath().equals(finalUrl.getPath())) { - isEndlesslyRedirecting = true; - } - } - if (isEndlesslyRedirecting) { - break; - } else { - finalResult = unshortenUrl(shortURL.toString()); - } - } - - return finalResult; - } - - /** - * Takes a valid url string and returns a URLConnection object for the url. - */ - private URLConnection connectURL(String strURL) { - URLConnection conn = null; - try { - URL inputURL = new URL(strURL); - conn = connectURL(inputURL); - } catch (MalformedURLException e) { - System.out.println("Please input a valid URL"); - } - return conn; - } - - /** - * Takes a valid url and returns a URLConnection object for the url. - */ - private URLConnection connectURL(URL inputURL) { - URLConnection conn = null; - try { - conn = inputURL.openConnection(); - } catch (IOException ioe) { - System.out.println("Can not connect to the URL"); - } - return conn; - } - - /** Removes extra spaces and trim the string */ - public static String extendedTrim(String content) { - return content.replaceAll("\\s+", " ").replace("\n", " ") - .replace("\r", " ").trim(); - } - -} diff --git a/library/src/main/java/com/leocardz/link/preview/library/TextCrawler.kt b/library/src/main/java/com/leocardz/link/preview/library/TextCrawler.kt new file mode 100644 index 0000000..5221e6d --- /dev/null +++ b/library/src/main/java/com/leocardz/link/preview/library/TextCrawler.kt @@ -0,0 +1,35 @@ +package com.leocardz.link.preview.library + +import io.reactivex.Observable + +class TextCrawler { + + fun makePreview(callback: LinkPreviewCallback, url: String) { + val imagePickingStrategy = DefaultImagePickingStrategy() + makePreview(callback, url, imagePickingStrategy) + } + + fun makePreview(callback: LinkPreviewCallback, + url: String, + imageQuantity: Int) { + val imagePickingStrategy = DefaultImagePickingStrategy() + imagePickingStrategy.imageQuantity = imageQuantity + makePreview(callback, url, imagePickingStrategy) + } + + fun makePreview(callback: LinkPreviewCallback, + url: String, + imagePickingStrategy: ImagePickingStrategy) { + GetSourceAynscTask(callback, imagePickingStrategy) + .getSourceCode(url) + } + + fun makePreview(url: String): Observable = GetSourceObservable(url).getObservable() + + companion object { + /** + * Removes extra spaces and trim the string + */ + fun extendedTrim(content: String): String = Util.extendedTrim(content) + } +} \ No newline at end of file diff --git a/library/src/main/java/com/leocardz/link/preview/library/Util.kt b/library/src/main/java/com/leocardz/link/preview/library/Util.kt new file mode 100644 index 0000000..b3047e8 --- /dev/null +++ b/library/src/main/java/com/leocardz/link/preview/library/Util.kt @@ -0,0 +1,15 @@ +package com.leocardz.link.preview.library + +/** + * @author dhruvaraj nagarajan + */ +object Util { + + /** + * Removes extra spaces and trim the string + */ + fun extendedTrim(content: String): String { + return content.replace("\\s+".toRegex(), " ").replace("\n", " ") + .replace("\r", " ").trim { it <= ' ' } + } +} \ No newline at end of file diff --git a/library/src/main/java/com/leocardz/link/preview/library/url/DefaultUrlExtractionStrategy.java b/library/src/main/java/com/leocardz/link/preview/library/url/DefaultUrlExtractionStrategy.java index 7b25c52..efe16e7 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/url/DefaultUrlExtractionStrategy.java +++ b/library/src/main/java/com/leocardz/link/preview/library/url/DefaultUrlExtractionStrategy.java @@ -13,7 +13,7 @@ public List extractUrls(String textPassedToTextCrawler) { List urls = SearchUrls.matches(textPassedToTextCrawler); if (urls.size() > 0) { - String url = TextCrawler.extendedTrim(urls.get(0)); + String url = TextCrawler.Companion.extendedTrim(urls.get(0)); urls.set(0, url); } return urls; diff --git a/library/src/main/java/com/leocardz/link/preview/library/url/UrlExtractionStrategy.java b/library/src/main/java/com/leocardz/link/preview/library/url/UrlExtractionStrategy.java index 1738499..11cb164 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/url/UrlExtractionStrategy.java +++ b/library/src/main/java/com/leocardz/link/preview/library/url/UrlExtractionStrategy.java @@ -6,5 +6,6 @@ * Provides the means for extracting URL(s) from text. */ public interface UrlExtractionStrategy { + List extractUrls(String textPassedToTextCrawler); } From a9a6f197ce93f1dc2d637c0ecf6e0e4bfab517af Mon Sep 17 00:00:00 2001 From: Dhruv Nagarajan Date: Mon, 4 Nov 2019 02:18:14 +0530 Subject: [PATCH 3/6] Migrate to Android X --- README.md | 2 +- app/build.gradle | 10 +-- app/src/main/AndroidManifest.xml | 4 +- .../preview => linkpreview/sample}/Main.java | 11 ++- gradle.properties | 4 +- library/LinkPreview.iml | 69 ------------------- {library => linkpreview}/.gitignore | 0 {library => linkpreview}/build.gradle | 6 +- {library => linkpreview}/proguard-rules.pro | 0 .../library/ProvidedDocumentTextCrawler.java | 2 +- .../library/TestLinkPreviewCallback.java | 2 +- .../sample}/library/TextCrawlerImageTest.java | 4 +- .../sample}/library/TextCrawlerTest.java | 6 +- .../src/main/AndroidManifest.xml | 2 +- .../library/BaseImagePickingStrategy.kt | 2 +- .../library/DefaultImagePickingStrategy.java | 2 +- .../sample}/library/DowloadImageCallback.java | 2 +- .../linkpreview/sample}/library/GetSource.kt | 2 +- .../sample}/library/GetSourceAynscTask.kt | 6 +- .../sample}/library/GetSourceObservable.kt | 6 +- .../sample}/library/GetSourceSync.kt | 6 +- .../sample}/library/ImagePickingStrategy.kt | 2 +- .../sample}/library/LinkPreviewCallback.java | 2 +- .../linkpreview/sample}/library/Regex.java | 2 +- .../sample}/library/SearchUrls.java | 2 +- .../sample}/library/SourceContent.java | 2 +- .../sample}/library/TextCrawler.kt | 2 +- .../linkpreview/sample}/library/Util.kt | 2 +- .../url/DefaultUrlExtractionStrategy.java | 6 +- .../library/url/UrlExtractionStrategy.java | 2 +- settings.gradle | 2 +- 31 files changed, 52 insertions(+), 120 deletions(-) rename app/src/main/java/com/leocardz/{link/preview => linkpreview/sample}/Main.java (98%) delete mode 100644 library/LinkPreview.iml rename {library => linkpreview}/.gitignore (100%) rename {library => linkpreview}/build.gradle (81%) rename {library => linkpreview}/proguard-rules.pro (100%) rename {library/src/androidTest/java/com/leocardz/link/preview => linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample}/library/ProvidedDocumentTextCrawler.java (93%) rename {library/src/androidTest/java/com/leocardz/link/preview => linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample}/library/TestLinkPreviewCallback.java (93%) rename {library/src/androidTest/java/com/leocardz/link/preview => linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample}/library/TextCrawlerImageTest.java (99%) rename {library/src/androidTest/java/com/leocardz/link/preview => linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample}/library/TextCrawlerTest.java (94%) rename {library => linkpreview}/src/main/AndroidManifest.xml (73%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/BaseImagePickingStrategy.kt (95%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/DefaultImagePickingStrategy.java (95%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/DowloadImageCallback.java (88%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/GetSource.kt (82%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/GetSourceAynscTask.kt (80%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/GetSourceObservable.kt (78%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/GetSourceSync.kt (98%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/ImagePickingStrategy.kt (85%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/LinkPreviewCallback.java (88%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/Regex.java (98%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/SearchUrls.java (93%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/SourceContent.java (98%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/TextCrawler.kt (95%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/Util.kt (86%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/url/DefaultUrlExtractionStrategy.java (73%) rename {library/src/main/java/com/leocardz/link/preview => linkpreview/src/main/java/com/leocardz/linkpreview/sample}/library/url/UrlExtractionStrategy.java (78%) diff --git a/README.md b/README.md index fc9a57b..3751ad3 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ to your ProGuard rules file. ## Usage #### Instantiating ```java -import com.leocardz.link.preview.library.TextCrawler; +import com.leocardz.linkpreview.sample.library.TextCrawler; // ... // Create an instance of the TextCrawler to parse your url into a preview. TextCrawler textCrawler = new TextCrawler(); diff --git a/app/build.gradle b/app/build.gradle index 821de2a..0ad3084 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 23 + compileSdkVersion 29 dexOptions { jumboMode = true @@ -9,8 +9,8 @@ android { defaultConfig { applicationId "com.leocardz.link.preview" - minSdkVersion 11 - targetSdkVersion 23 + minSdkVersion 14 + targetSdkVersion 29 versionCode 1 versionName "1.1" } @@ -23,8 +23,8 @@ android { } dependencies { - implementation project(":library") - implementation 'com.android.support:appcompat-v7:23.1.1' + implementation project(':linkpreview') + implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'com.koushikdutta.urlimageviewhelper:urlimageviewhelper:1.0.4' implementation 'org.jsoup:jsoup:1.11.3' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 831043e..7d36552 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ @@ -12,7 +12,7 @@ android:screenOrientation="portrait" android:theme="@style/App.Theme"> diff --git a/app/src/main/java/com/leocardz/link/preview/Main.java b/app/src/main/java/com/leocardz/linkpreview/sample/Main.java similarity index 98% rename from app/src/main/java/com/leocardz/link/preview/Main.java rename to app/src/main/java/com/leocardz/linkpreview/sample/Main.java index 3101270..be200bc 100644 --- a/app/src/main/java/com/leocardz/link/preview/Main.java +++ b/app/src/main/java/com/leocardz/linkpreview/sample/Main.java @@ -1,4 +1,4 @@ -package com.leocardz.link.preview; +package com.leocardz.linkpreview.sample; import android.app.Activity; import android.content.Context; @@ -6,7 +6,6 @@ import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; -import android.support.v7.app.ActionBarActivity; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; @@ -26,9 +25,9 @@ import com.koushikdutta.urlimageviewhelper.UrlImageViewCallback; import com.koushikdutta.urlimageviewhelper.UrlImageViewHelper; -import com.leocardz.link.preview.library.LinkPreviewCallback; -import com.leocardz.link.preview.library.SourceContent; -import com.leocardz.link.preview.library.TextCrawler; +import com.leocardz.linkpreview.sample.library.LinkPreviewCallback; +import com.leocardz.linkpreview.sample.library.SourceContent; +import com.leocardz.linkpreview.sample.library.TextCrawler; import java.util.List; import java.util.Random; @@ -40,7 +39,7 @@ @SuppressWarnings("unused") -public class Main extends ActionBarActivity { +public class Main extends Activity { private EditText editText, editTextTitlePost, editTextDescriptionPost; private Button submitButton, postButton, randomButton; diff --git a/gradle.properties b/gradle.properties index 5d08ba7..21ee4a5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,4 +15,6 @@ # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file +# org.gradle.parallel=true +android.enableJetifier=true +android.useAndroidX=true \ No newline at end of file diff --git a/library/LinkPreview.iml b/library/LinkPreview.iml deleted file mode 100644 index c717258..0000000 --- a/library/LinkPreview.iml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/library/.gitignore b/linkpreview/.gitignore similarity index 100% rename from library/.gitignore rename to linkpreview/.gitignore diff --git a/library/build.gradle b/linkpreview/build.gradle similarity index 81% rename from library/build.gradle rename to linkpreview/build.gradle index 0ebc24c..1c20f8b 100644 --- a/library/build.gradle +++ b/linkpreview/build.gradle @@ -6,12 +6,12 @@ android { compileSdkVersion 29 defaultConfig { - minSdkVersion 9 + minSdkVersion 14 targetSdkVersion 29 versionCode 1 versionName "1.3.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -29,7 +29,7 @@ dependencies { implementation 'io.reactivex.rxjava2:rxjava:2.2.12' androidTestImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'org.mockito:mockito-android:2.22.0' } diff --git a/library/proguard-rules.pro b/linkpreview/proguard-rules.pro similarity index 100% rename from library/proguard-rules.pro rename to linkpreview/proguard-rules.pro diff --git a/library/src/androidTest/java/com/leocardz/link/preview/library/ProvidedDocumentTextCrawler.java b/linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample/library/ProvidedDocumentTextCrawler.java similarity index 93% rename from library/src/androidTest/java/com/leocardz/link/preview/library/ProvidedDocumentTextCrawler.java rename to linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample/library/ProvidedDocumentTextCrawler.java index a76c3bf..51199e2 100644 --- a/library/src/androidTest/java/com/leocardz/link/preview/library/ProvidedDocumentTextCrawler.java +++ b/linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample/library/ProvidedDocumentTextCrawler.java @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library; +package com.leocardz.linkpreview.sample.library; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; diff --git a/library/src/androidTest/java/com/leocardz/link/preview/library/TestLinkPreviewCallback.java b/linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample/library/TestLinkPreviewCallback.java similarity index 93% rename from library/src/androidTest/java/com/leocardz/link/preview/library/TestLinkPreviewCallback.java rename to linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample/library/TestLinkPreviewCallback.java index d19e9d0..3398832 100644 --- a/library/src/androidTest/java/com/leocardz/link/preview/library/TestLinkPreviewCallback.java +++ b/linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample/library/TestLinkPreviewCallback.java @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library; +package com.leocardz.linkpreview.sample.library; import java.util.concurrent.CountDownLatch; diff --git a/library/src/androidTest/java/com/leocardz/link/preview/library/TextCrawlerImageTest.java b/linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample/library/TextCrawlerImageTest.java similarity index 99% rename from library/src/androidTest/java/com/leocardz/link/preview/library/TextCrawlerImageTest.java rename to linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample/library/TextCrawlerImageTest.java index 7a3f256..75045c5 100644 --- a/library/src/androidTest/java/com/leocardz/link/preview/library/TextCrawlerImageTest.java +++ b/linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample/library/TextCrawlerImageTest.java @@ -1,7 +1,7 @@ -package com.leocardz.link.preview.library; +package com.leocardz.linkpreview.sample.library; import android.os.AsyncTask; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.ext.junit.runners.AndroidJUnit4; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; diff --git a/library/src/androidTest/java/com/leocardz/link/preview/library/TextCrawlerTest.java b/linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample/library/TextCrawlerTest.java similarity index 94% rename from library/src/androidTest/java/com/leocardz/link/preview/library/TextCrawlerTest.java rename to linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample/library/TextCrawlerTest.java index 9745233..a042bd8 100644 --- a/library/src/androidTest/java/com/leocardz/link/preview/library/TextCrawlerTest.java +++ b/linkpreview/src/androidTest/java/com/leocardz/linkpreview/sample/library/TextCrawlerTest.java @@ -1,8 +1,8 @@ -package com.leocardz.link.preview.library; +package com.leocardz.linkpreview.sample.library; -import android.support.test.runner.AndroidJUnit4; +import androidx.test.ext.junit.runners.AndroidJUnit4; -import com.leocardz.link.preview.library.url.UrlExtractionStrategy; +import com.leocardz.linkpreview.sample.library.url.UrlExtractionStrategy; import org.jsoup.nodes.Document; import org.junit.Test; diff --git a/library/src/main/AndroidManifest.xml b/linkpreview/src/main/AndroidManifest.xml similarity index 73% rename from library/src/main/AndroidManifest.xml rename to linkpreview/src/main/AndroidManifest.xml index 0701afe..5acd7de 100644 --- a/library/src/main/AndroidManifest.xml +++ b/linkpreview/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="com.leocardz.linkpreview.sample.library"> diff --git a/library/src/main/java/com/leocardz/link/preview/library/BaseImagePickingStrategy.kt b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/BaseImagePickingStrategy.kt similarity index 95% rename from library/src/main/java/com/leocardz/link/preview/library/BaseImagePickingStrategy.kt rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/BaseImagePickingStrategy.kt index fb4893b..8884a78 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/BaseImagePickingStrategy.kt +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/BaseImagePickingStrategy.kt @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library +package com.leocardz.linkpreview.sample.library import org.jsoup.nodes.Document import java.util.* diff --git a/library/src/main/java/com/leocardz/link/preview/library/DefaultImagePickingStrategy.java b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/DefaultImagePickingStrategy.java similarity index 95% rename from library/src/main/java/com/leocardz/link/preview/library/DefaultImagePickingStrategy.java rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/DefaultImagePickingStrategy.java index 30f7640..b6ee5e0 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/DefaultImagePickingStrategy.java +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/DefaultImagePickingStrategy.java @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library; +package com.leocardz.linkpreview.sample.library; import org.jsoup.nodes.Document; diff --git a/library/src/main/java/com/leocardz/link/preview/library/DowloadImageCallback.java b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/DowloadImageCallback.java similarity index 88% rename from library/src/main/java/com/leocardz/link/preview/library/DowloadImageCallback.java rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/DowloadImageCallback.java index 7d507a4..fa5fff8 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/DowloadImageCallback.java +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/DowloadImageCallback.java @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library; +package com.leocardz.linkpreview.sample.library; import android.graphics.Bitmap; import android.widget.ImageView; diff --git a/library/src/main/java/com/leocardz/link/preview/library/GetSource.kt b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/GetSource.kt similarity index 82% rename from library/src/main/java/com/leocardz/link/preview/library/GetSource.kt rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/GetSource.kt index 64ebabb..b32bb1b 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/GetSource.kt +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/GetSource.kt @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library +package com.leocardz.linkpreview.sample.library /** * @author dhruvaraj nagarajan diff --git a/library/src/main/java/com/leocardz/link/preview/library/GetSourceAynscTask.kt b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/GetSourceAynscTask.kt similarity index 80% rename from library/src/main/java/com/leocardz/link/preview/library/GetSourceAynscTask.kt rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/GetSourceAynscTask.kt index 82ad6af..d0b6e56 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/GetSourceAynscTask.kt +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/GetSourceAynscTask.kt @@ -1,8 +1,8 @@ -package com.leocardz.link.preview.library +package com.leocardz.linkpreview.sample.library import android.os.AsyncTask -import com.leocardz.link.preview.library.url.DefaultUrlExtractionStrategy -import com.leocardz.link.preview.library.url.UrlExtractionStrategy +import com.leocardz.linkpreview.sample.library.url.DefaultUrlExtractionStrategy +import com.leocardz.linkpreview.sample.library.url.UrlExtractionStrategy /** * @author dhruvaraj nagarajan diff --git a/library/src/main/java/com/leocardz/link/preview/library/GetSourceObservable.kt b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/GetSourceObservable.kt similarity index 78% rename from library/src/main/java/com/leocardz/link/preview/library/GetSourceObservable.kt rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/GetSourceObservable.kt index 95b0ce4..705c5a7 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/GetSourceObservable.kt +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/GetSourceObservable.kt @@ -1,7 +1,7 @@ -package com.leocardz.link.preview.library +package com.leocardz.linkpreview.sample.library -import com.leocardz.link.preview.library.url.DefaultUrlExtractionStrategy -import com.leocardz.link.preview.library.url.UrlExtractionStrategy +import com.leocardz.linkpreview.sample.library.url.DefaultUrlExtractionStrategy +import com.leocardz.linkpreview.sample.library.url.UrlExtractionStrategy import io.reactivex.Observable /** diff --git a/library/src/main/java/com/leocardz/link/preview/library/GetSourceSync.kt b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/GetSourceSync.kt similarity index 98% rename from library/src/main/java/com/leocardz/link/preview/library/GetSourceSync.kt rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/GetSourceSync.kt index 955657c..fd7353b 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/GetSourceSync.kt +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/GetSourceSync.kt @@ -1,7 +1,7 @@ -package com.leocardz.link.preview.library +package com.leocardz.linkpreview.sample.library -import com.leocardz.link.preview.library.Util.extendedTrim -import com.leocardz.link.preview.library.url.UrlExtractionStrategy +import com.leocardz.linkpreview.sample.library.Util.extendedTrim +import com.leocardz.linkpreview.sample.library.url.UrlExtractionStrategy import org.jsoup.Jsoup import org.jsoup.UnsupportedMimeTypeException import org.jsoup.nodes.Document diff --git a/library/src/main/java/com/leocardz/link/preview/library/ImagePickingStrategy.kt b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/ImagePickingStrategy.kt similarity index 85% rename from library/src/main/java/com/leocardz/link/preview/library/ImagePickingStrategy.kt rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/ImagePickingStrategy.kt index 7baa5c7..8865e87 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/ImagePickingStrategy.kt +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/ImagePickingStrategy.kt @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library +package com.leocardz.linkpreview.sample.library import org.jsoup.nodes.Document import java.util.* diff --git a/library/src/main/java/com/leocardz/link/preview/library/LinkPreviewCallback.java b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/LinkPreviewCallback.java similarity index 88% rename from library/src/main/java/com/leocardz/link/preview/library/LinkPreviewCallback.java rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/LinkPreviewCallback.java index c7652e9..1b77854 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/LinkPreviewCallback.java +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/LinkPreviewCallback.java @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library; +package com.leocardz.linkpreview.sample.library; /** * Callback that is invoked with before and after the loading of a link preview diff --git a/library/src/main/java/com/leocardz/link/preview/library/Regex.java b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/Regex.java similarity index 98% rename from library/src/main/java/com/leocardz/link/preview/library/Regex.java rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/Regex.java index fcdbb6d..9107c21 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/Regex.java +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/Regex.java @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library; +package com.leocardz.linkpreview.sample.library; import java.util.ArrayList; import java.util.List; diff --git a/library/src/main/java/com/leocardz/link/preview/library/SearchUrls.java b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/SearchUrls.java similarity index 93% rename from library/src/main/java/com/leocardz/link/preview/library/SearchUrls.java rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/SearchUrls.java index 0407cce..f60c5b0 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/SearchUrls.java +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/SearchUrls.java @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library; +package com.leocardz.linkpreview.sample.library; import java.net.URL; import java.util.ArrayList; diff --git a/library/src/main/java/com/leocardz/link/preview/library/SourceContent.java b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/SourceContent.java similarity index 98% rename from library/src/main/java/com/leocardz/link/preview/library/SourceContent.java rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/SourceContent.java index c0b13a3..68fa705 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/SourceContent.java +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/SourceContent.java @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library; +package com.leocardz.linkpreview.sample.library; import java.util.ArrayList; import java.util.HashMap; diff --git a/library/src/main/java/com/leocardz/link/preview/library/TextCrawler.kt b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/TextCrawler.kt similarity index 95% rename from library/src/main/java/com/leocardz/link/preview/library/TextCrawler.kt rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/TextCrawler.kt index 5221e6d..bbb5443 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/TextCrawler.kt +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/TextCrawler.kt @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library +package com.leocardz.linkpreview.sample.library import io.reactivex.Observable diff --git a/library/src/main/java/com/leocardz/link/preview/library/Util.kt b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/Util.kt similarity index 86% rename from library/src/main/java/com/leocardz/link/preview/library/Util.kt rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/Util.kt index b3047e8..ed45981 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/Util.kt +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/Util.kt @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library +package com.leocardz.linkpreview.sample.library /** * @author dhruvaraj nagarajan diff --git a/library/src/main/java/com/leocardz/link/preview/library/url/DefaultUrlExtractionStrategy.java b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/url/DefaultUrlExtractionStrategy.java similarity index 73% rename from library/src/main/java/com/leocardz/link/preview/library/url/DefaultUrlExtractionStrategy.java rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/url/DefaultUrlExtractionStrategy.java index efe16e7..08fce8e 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/url/DefaultUrlExtractionStrategy.java +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/url/DefaultUrlExtractionStrategy.java @@ -1,7 +1,7 @@ -package com.leocardz.link.preview.library.url; +package com.leocardz.linkpreview.sample.library.url; -import com.leocardz.link.preview.library.SearchUrls; -import com.leocardz.link.preview.library.TextCrawler; +import com.leocardz.linkpreview.sample.library.SearchUrls; +import com.leocardz.linkpreview.sample.library.TextCrawler; import java.util.List; diff --git a/library/src/main/java/com/leocardz/link/preview/library/url/UrlExtractionStrategy.java b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/url/UrlExtractionStrategy.java similarity index 78% rename from library/src/main/java/com/leocardz/link/preview/library/url/UrlExtractionStrategy.java rename to linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/url/UrlExtractionStrategy.java index 11cb164..2568b33 100644 --- a/library/src/main/java/com/leocardz/link/preview/library/url/UrlExtractionStrategy.java +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/url/UrlExtractionStrategy.java @@ -1,4 +1,4 @@ -package com.leocardz.link.preview.library.url; +package com.leocardz.linkpreview.sample.library.url; import java.util.List; diff --git a/settings.gradle b/settings.gradle index 3306997..7548f94 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':library' +include ':app', ':linkpreview' From dd46df916be659f36334e9021385323e726bc2dd Mon Sep 17 00:00:00 2001 From: Dhruv Nagarajan Date: Sun, 10 Nov 2019 11:47:40 +0530 Subject: [PATCH 4/6] Deprecate usage of AsyncTask --- .../com/leocardz/linkpreview/sample/Main.java | 11 +++++ build.gradle | 3 +- linkpreview/build.gradle | 5 ++- .../linkpreview/sample/library/TextCrawler.kt | 45 +++++++++++++++---- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/leocardz/linkpreview/sample/Main.java b/app/src/main/java/com/leocardz/linkpreview/sample/Main.java index be200bc..09b2f55 100644 --- a/app/src/main/java/com/leocardz/linkpreview/sample/Main.java +++ b/app/src/main/java/com/leocardz/linkpreview/sample/Main.java @@ -225,6 +225,17 @@ public void initSubmitButton() { submitButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { + textCrawler.makePreview(new LinkPreviewCallback() { + @Override + public void onPre() { + + } + + @Override + public void onPos(SourceContent sourceContent, boolean isNull) { + + } + }, ""); textCrawler.makePreview(editText.getText().toString()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) diff --git a/build.gradle b/build.gradle index 5a87b5c..8372952 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ buildscript { ext.kotlin_version = '1.3.50' + ext.rxjava_version = "2.2.12" repositories { maven { url 'https://github.com/leonardocardoso/mvn-repo/raw/master/maven-deploy' } jcenter() @@ -10,7 +11,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.1' + classpath 'com.android.tools.build:gradle:3.5.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/linkpreview/build.gradle b/linkpreview/build.gradle index 1c20f8b..cf21305 100644 --- a/linkpreview/build.gradle +++ b/linkpreview/build.gradle @@ -23,10 +23,11 @@ android { } dependencies { - implementation 'org.jsoup:jsoup:1.11.3' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'io.reactivex.rxjava2:rxjava:2.2.12' + implementation "io.reactivex.rxjava2:rxjava:$rxjava_version" + + implementation 'org.jsoup:jsoup:1.12.1' androidTestImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' diff --git a/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/TextCrawler.kt b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/TextCrawler.kt index bbb5443..00d5100 100644 --- a/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/TextCrawler.kt +++ b/linkpreview/src/main/java/com/leocardz/linkpreview/sample/library/TextCrawler.kt @@ -4,27 +4,56 @@ import io.reactivex.Observable class TextCrawler { + @Deprecated( + level = DeprecationLevel.WARNING, + message = """ + AsyncTask has been deprecated since Android 11. + Use RxJava variant, makePreview(url) instead. + """, + replaceWith = ReplaceWith("makePreview(url)") + ) fun makePreview(callback: LinkPreviewCallback, url: String) { val imagePickingStrategy = DefaultImagePickingStrategy() makePreview(callback, url, imagePickingStrategy) } - fun makePreview(callback: LinkPreviewCallback, - url: String, - imageQuantity: Int) { + @Deprecated( + level = DeprecationLevel.WARNING, + message = """ + AsyncTask has been deprecated since Android 11. + Use RxJava variant, makePreview(url) instead. + """, + replaceWith = ReplaceWith("makePreview(url)") + ) + fun makePreview( + callback: LinkPreviewCallback, + url: String, + imageQuantity: Int + ) { val imagePickingStrategy = DefaultImagePickingStrategy() imagePickingStrategy.imageQuantity = imageQuantity makePreview(callback, url, imagePickingStrategy) } - fun makePreview(callback: LinkPreviewCallback, - url: String, - imagePickingStrategy: ImagePickingStrategy) { + @Deprecated( + level = DeprecationLevel.WARNING, + message = """ + AsyncTask has been deprecated since Android 11. + Use RxJava variant, makePreview(url) instead. + """, + replaceWith = ReplaceWith("makePreview(url)") + ) + fun makePreview( + callback: LinkPreviewCallback, + url: String, + imagePickingStrategy: ImagePickingStrategy + ) { GetSourceAynscTask(callback, imagePickingStrategy) - .getSourceCode(url) + .getSourceCode(url) } - fun makePreview(url: String): Observable = GetSourceObservable(url).getObservable() + fun makePreview(url: String): Observable = + GetSourceObservable(url).getObservable() companion object { /** From 4a33a8fa70a6eb401047d4d79d6a7904a2fc8850 Mon Sep 17 00:00:00 2001 From: Dhruv Nagarajan Date: Mon, 11 Nov 2019 00:49:30 +0530 Subject: [PATCH 5/6] Change kotlin plugin order --- linkpreview/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linkpreview/build.gradle b/linkpreview/build.gradle index cf21305..7f19e25 100644 --- a/linkpreview/build.gradle +++ b/linkpreview/build.gradle @@ -1,6 +1,6 @@ apply plugin: 'com.android.library' -apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 29 From af6404d09b4ffd836b12d5aa8efcfebb469c1449 Mon Sep 17 00:00:00 2001 From: N Dhruvaraj Date: Wed, 12 Feb 2020 19:38:46 +0530 Subject: [PATCH 6/6] Update dependencies --- LinkPreview.iml | 19 ------------------- linkpreview/build.gradle | 4 ++-- 2 files changed, 2 insertions(+), 21 deletions(-) delete mode 100644 LinkPreview.iml diff --git a/LinkPreview.iml b/LinkPreview.iml deleted file mode 100644 index 33e0718..0000000 --- a/LinkPreview.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/linkpreview/build.gradle b/linkpreview/build.gradle index 7f19e25..2c1e7f5 100644 --- a/linkpreview/build.gradle +++ b/linkpreview/build.gradle @@ -23,9 +23,9 @@ android { } dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.61" - implementation "io.reactivex.rxjava2:rxjava:$rxjava_version" + implementation "io.reactivex.rxjava2:rxjava:2.2.17" implementation 'org.jsoup:jsoup:1.12.1'