Skip to content

Commit 7875da1

Browse files
authored
Merge pull request #21 from Mek101/reentrant
Make the library reentrant and thread-safe
2 parents 1ccc5eb + a906d1b commit 7875da1

4 files changed

Lines changed: 89 additions & 89 deletions

File tree

OGParser/src/main/java/com/kedia/ogparser/JsoupNetworkCall.kt

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,8 @@ import org.jsoup.Jsoup
44

55
class JsoupNetworkCall {
66

7-
private val REFERRER = "http://www.google.com"
8-
private val TIMEOUT = 100000
9-
private val DOC_SELECT_QUERY = "meta[property^=og:]"
10-
private val OPEN_GRAPH_KEY = "content"
11-
private val PROPERTY = "property"
12-
private val OG_IMAGE = "og:image"
13-
private val OG_DESCRIPTION = "og:description"
14-
private val OG_URL = "og:url"
15-
private val OG_TITLE = "og:title"
16-
private val OG_SITE_NAME = "og:site_name"
17-
private val OG_TYPE = "og:type"
18-
19-
private var openGraphResult: OpenGraphResult? = null
20-
217
fun callUrl(url: String, agent: String): OpenGraphResult? {
22-
openGraphResult = OpenGraphResult()
8+
val openGraphResult = OpenGraphResult()
239
try {
2410
val response = Jsoup.connect(url)
2511
.ignoreContentType(true)
@@ -30,48 +16,63 @@ class JsoupNetworkCall {
3016
.execute()
3117

3218
val doc = response.parse()
33-
val ogTags = doc.select(DOC_SELECT_QUERY)
34-
when {
35-
ogTags.size > 0 ->
36-
ogTags.forEachIndexed { index, _ ->
37-
val tag = ogTags[index]
38-
val text = tag.attr(PROPERTY)
19+
val ogTags = doc.select(DOC_SELECT_OGTAGS)
3920

40-
when (text) {
41-
OG_IMAGE -> {
42-
openGraphResult!!.image = (tag.attr(OPEN_GRAPH_KEY))
43-
}
44-
OG_DESCRIPTION -> {
45-
openGraphResult!!.description = (tag.attr(OPEN_GRAPH_KEY))
46-
}
47-
OG_URL -> {
48-
openGraphResult!!.url = (tag.attr(OPEN_GRAPH_KEY))
49-
}
50-
OG_TITLE -> {
51-
openGraphResult!!.title = (tag.attr(OPEN_GRAPH_KEY))
52-
}
53-
OG_SITE_NAME -> {
54-
openGraphResult!!.siteName = (tag.attr(OPEN_GRAPH_KEY))
55-
}
56-
OG_TYPE -> {
57-
openGraphResult!!.type = (tag.attr(OPEN_GRAPH_KEY))
58-
}
59-
}
21+
ogTags.forEach { tag ->
22+
val text = tag.attr(PROPERTY)
23+
24+
when (text) {
25+
OG_IMAGE -> {
26+
openGraphResult.image = tag.attr(OPEN_GRAPH_KEY)
27+
}
28+
OG_DESCRIPTION -> {
29+
openGraphResult.description = tag.attr(OPEN_GRAPH_KEY)
30+
}
31+
OG_URL -> {
32+
openGraphResult.url = tag.attr(OPEN_GRAPH_KEY)
33+
}
34+
OG_TITLE -> {
35+
openGraphResult.title = tag.attr(OPEN_GRAPH_KEY)
36+
}
37+
OG_SITE_NAME -> {
38+
openGraphResult.siteName = tag.attr(OPEN_GRAPH_KEY)
6039
}
40+
OG_TYPE -> {
41+
openGraphResult.type = tag.attr(OPEN_GRAPH_KEY)
42+
}
43+
}
6144
}
6245

63-
if (openGraphResult!!.title.isNullOrEmpty())
64-
openGraphResult!!.title = doc.title()
65-
if (openGraphResult!!.description.isNullOrEmpty())
66-
openGraphResult!!.description = if (doc.select("meta[name=description]").size != 0) doc.select("meta[name=description]")
67-
.first().attr("content") else ""
68-
if (openGraphResult!!.url.isNullOrEmpty())
69-
openGraphResult!!.url = getBaseUrl(url)
46+
if (openGraphResult.title.isNullOrEmpty()) {
47+
openGraphResult.title = doc.title()
48+
}
49+
if (openGraphResult.description.isNullOrEmpty()) {
50+
val docSelection = doc.select(DOC_SELECT_DESCRIPTION)
51+
openGraphResult.description = docSelection.firstOrNull()?.attr("content") ?: ""
52+
}
53+
if (openGraphResult.url.isNullOrEmpty()) {
54+
openGraphResult.url = getBaseUrl(url)
55+
}
7056
} catch (e: Exception) {
7157
e.printStackTrace()
7258
return null
7359
}
7460

7561
return openGraphResult
7662
}
77-
}
63+
64+
companion object {
65+
private const val REFERRER = "http://www.google.com"
66+
private const val TIMEOUT = 100000
67+
private const val DOC_SELECT_OGTAGS = "meta[property^=og:]"
68+
private const val DOC_SELECT_DESCRIPTION = "meta[name=description]"
69+
private const val OPEN_GRAPH_KEY = "content"
70+
private const val PROPERTY = "property"
71+
private const val OG_IMAGE = "og:image"
72+
private const val OG_DESCRIPTION = "og:description"
73+
private const val OG_URL = "og:url"
74+
private const val OG_TITLE = "og:title"
75+
private const val OG_SITE_NAME = "og:site_name"
76+
private const val OG_TYPE = "og:type"
77+
}
78+
}

OGParser/src/main/java/com/kedia/ogparser/OpenGraphCacheProvider.kt

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,6 @@ class OpenGraphCacheProvider(context: Context) : CacheProvider {
99

1010
private val pm: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
1111

12-
private val OG_PARSER = "Og_Parser"
13-
private val TITLE = OG_PARSER + "_title"
14-
private val DESCRIPTION = OG_PARSER + "_description"
15-
private val URL = OG_PARSER + "_url"
16-
private val IMAGE = OG_PARSER + "_image"
17-
private val SITE_NAME = OG_PARSER + "_site_name"
18-
private val TYPE = OG_PARSER + "_type"
1912

2013
private fun setTitle(link: String, title: String) {
2114
pm.edit().putString(TITLE + "_$link", title).apply()
@@ -67,11 +60,11 @@ class OpenGraphCacheProvider(context: Context) : CacheProvider {
6760

6861
private fun urlExists(title: String, description: String, image: String): Boolean {
6962
return title.isNotEmpty() &&
70-
title.equals("null").not() &&
63+
title != "null" &&
7164
description.isNotEmpty() &&
72-
description.equals("null").not() &&
65+
title != "null" &&
7366
image.isNotEmpty() &&
74-
image.equals("null").not()
67+
title != "null"
7568
}
7669

7770
override suspend fun setOpenGraphResult(openGraphResult: OpenGraphResult, url: String) {
@@ -97,4 +90,14 @@ class OpenGraphCacheProvider(context: Context) : CacheProvider {
9790
val url = getUrl(url)
9891
return OpenGraphResult(title, description, url, image, siteName, type)
9992
}
93+
94+
companion object {
95+
private const val OG_PARSER = "Og_Parser"
96+
private const val TITLE = OG_PARSER + "_title"
97+
private const val DESCRIPTION = OG_PARSER + "_description"
98+
private const val URL = OG_PARSER + "_url"
99+
private const val IMAGE = OG_PARSER + "_image"
100+
private const val SITE_NAME = OG_PARSER + "_site_name"
101+
private const val TYPE = OG_PARSER + "_type"
102+
}
100103
}
Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.kedia.ogparser
22

3-
import android.content.Context
4-
import android.util.Log
53
import kotlinx.coroutines.*
64
import kotlin.coroutines.CoroutineContext
75

@@ -10,52 +8,40 @@ class OpenGraphParser(
108
private var showNullOnEmpty: Boolean = false,
119
private val cacheProvider: CacheProvider? = null
1210
) {
13-
private var url: String = ""
1411

15-
private val AGENTS = mutableListOf(
16-
"facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)",
17-
"Mozilla",
18-
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36",
19-
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36",
20-
"WhatsApp/2.19.81 A",
21-
"facebookexternalhit/1.1",
22-
"facebookcatalog/1.0"
23-
)
2412
private val jsoupNetworkCall = JsoupNetworkCall()
2513

26-
private var openGraphResult: OpenGraphResult? = null
2714

2815
fun parse(url: String) {
29-
this.url = url
30-
parseLink().parse()
16+
ParseLink(url).parse()
3117
}
3218

33-
inner class parseLink : CoroutineScope {
34-
19+
inner class ParseLink(private val url: String) : CoroutineScope {
3520
private val job: Job = Job()
3621
override val coroutineContext: CoroutineContext
3722
get() = Dispatchers.Main + job
3823

39-
4024
fun parse() = launch {
41-
val result = fetchContent()
25+
val result = fetchContent(url)
4226
result?.let {
4327
listener.onPostResponse(it)
4428
}
4529
}
4630
}
4731

48-
private suspend fun fetchContent() = withContext(Dispatchers.IO) {
49-
if (!url.contains("http")) {
50-
url = "http://$url"
32+
private suspend fun fetchContent(url: String) = withContext(Dispatchers.IO) {
33+
var validatedUrl = url
34+
if (!validatedUrl.contains("http")) {
35+
validatedUrl = "http://$validatedUrl"
5136
}
5237

5338
cacheProvider?.getOpenGraphResult(url)?.let {
5439
return@withContext it
5540
}
5641

42+
var openGraphResult: OpenGraphResult? = null
5743
AGENTS.forEach {
58-
openGraphResult = jsoupNetworkCall.callUrl(url, it)
44+
openGraphResult = jsoupNetworkCall.callUrl(validatedUrl, it)
5945
val isResultNull = checkNullParserResult(openGraphResult)
6046
if (!isResultNull) {
6147
openGraphResult?.let { cacheProvider?.setOpenGraphResult(it, url) }
@@ -69,7 +55,21 @@ class OpenGraphParser(
6955
}
7056
return@withContext null
7157
}
58+
7259
openGraphResult?.let { cacheProvider?.setOpenGraphResult(it, url) }
60+
7361
return@withContext openGraphResult
7462
}
63+
64+
companion object {
65+
private val AGENTS = arrayOf(
66+
"facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)",
67+
"Mozilla",
68+
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36",
69+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36",
70+
"WhatsApp/2.19.81 A",
71+
"facebookexternalhit/1.1",
72+
"facebookcatalog/1.0"
73+
)
74+
}
7575
}

OGParser/src/main/java/com/kedia/ogparser/UtilityFunctions.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,11 @@ import java.net.URI
44
import java.net.URL
55

66
fun checkNullParserResult(openGraphResult: OpenGraphResult?): Boolean {
7-
return (openGraphResult?.title.isNullOrEmpty() ||
8-
openGraphResult?.title.equals("null")) &&
9-
(openGraphResult?.description.isNullOrEmpty() ||
10-
openGraphResult?.description.equals(
11-
"null"
12-
))
7+
return (openGraphResult?.title.isNullOrEmpty() || openGraphResult?.title == "null") &&
8+
(openGraphResult?.description.isNullOrEmpty() || openGraphResult?.description == "null")
139
}
1410

1511
fun getBaseUrl(urlString: String): String {
1612
val url: URL = URI.create(urlString).toURL()
1713
return url.protocol.toString() + "://" + url.authority + "/"
18-
}
14+
}

0 commit comments

Comments
 (0)