Skip to content

Commit e063dd5

Browse files
committed
remove scrapers
1 parent 28cc603 commit e063dd5

File tree

3 files changed

+61
-123
lines changed

3 files changed

+61
-123
lines changed

app/src/main/java/com/addev/listaspam/util/SharedPreferencesUtils.kt

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,7 @@ fun getTruecallerApiCountry(context: Context): String? =
5656
fun setTruecallerApiCountry(context: Context, countryCode: String) =
5757
setStringPref(context, "pref_truecaller_country", countryCode.uppercase())
5858

59-
fun shouldFilterWithListaSpamScraper(context: Context): Boolean =
60-
getBooleanPref(context, "pref_filter_lista_spam_scraper", false)
61-
62-
fun shouldFilterWithResponderONo(context: Context): Boolean =
63-
getBooleanPref(context, "pref_filter_responder_o_no", false)
64-
65-
fun shouldFilterWithCleverdialer(context: Context): Boolean =
66-
getBooleanPref(context, "pref_filter_cleverdialer", false)
59+
// ...scraper-related preferences removed...
6760

6861
fun shouldBlockNonContacts(context: Context): Boolean =
6962
getBooleanPref(context, "pref_block_non_contacts", false)
@@ -178,11 +171,65 @@ fun getWhitelistNumbers(context: Context): Set<String> {
178171
* @param number The phone number to check.
179172
* @return True if the number is blocked locally, false otherwise.
180173
*/
174+
175+
/**
176+
* Checks if a number is blocked locally in shared preferences, supporting wildcards.
177+
*
178+
* Wildcard rules:
179+
* - '*' at the end: matches prefix (e.g., +33162*)
180+
* - '*' at the start: matches suffix (e.g., *98)
181+
* - '*' in the middle: matches infix (e.g., 213*134)
182+
* - No '*': exact match
183+
* - If pattern does not start with '+', also check with user's country prefix
184+
*
185+
* @param context The application context.
186+
* @param number The phone number to check.
187+
* @return True if the number is blocked locally, false otherwise.
188+
*/
181189
fun isNumberBlocked(context: Context, number: String): Boolean {
182190
val sharedPreferences = context.getSharedPreferences(SPAM_PREFS, Context.MODE_PRIVATE)
183-
val blockedNumbers = sharedPreferences.getStringSet(BLOCK_NUMBERS_KEY, emptySet())
184-
if (blockedNumbers != null) {
185-
return blockedNumbers.contains(number)
191+
val blockedNumbers = sharedPreferences.getStringSet(BLOCK_NUMBERS_KEY, emptySet()) ?: emptySet()
192+
val normalizedNumber = number.replace("\\D".toRegex(), "")
193+
194+
// Helper to get user's country prefix (e.g., "+33")
195+
fun getUserCountryPrefix(): String? {
196+
return try {
197+
val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as? android.telephony.TelephonyManager
198+
val countryIso = telephonyManager?.networkCountryIso?.uppercase()
199+
if (countryIso != null) {
200+
val phoneUtil = com.google.i18n.phonenumbers.PhoneNumberUtil.getInstance()
201+
val code = phoneUtil.getCountryCodeForRegion(countryIso)
202+
if (code > 0) "+$code" else null
203+
} else null
204+
} catch (e: Exception) { null }
205+
}
206+
val userPrefix = getUserCountryPrefix()
207+
208+
fun matchesPattern(pattern: String, num: String): Boolean {
209+
return when {
210+
pattern == "*" -> true
211+
pattern.startsWith("*") && pattern.endsWith("*") && pattern.length > 2 -> num.contains(pattern.substring(1, pattern.length-1))
212+
pattern.startsWith("*") -> num.endsWith(pattern.substring(1))
213+
pattern.endsWith("*") -> num.startsWith(pattern.substring(0, pattern.length-1))
214+
pattern.contains("*") -> {
215+
val parts = pattern.split("*")
216+
if (parts.size == 2) num.startsWith(parts[0]) && num.endsWith(parts[1])
217+
else false
218+
}
219+
else -> num == pattern
220+
}
221+
}
222+
223+
for (pattern in blockedNumbers) {
224+
if (pattern.isNullOrBlank()) continue
225+
val normalizedPattern = pattern.replace("\\D".toRegex(), "")
226+
// Try direct match
227+
if (matchesPattern(normalizedPattern, normalizedNumber)) return true
228+
// If pattern does not start with '+', try with user prefix
229+
if (!pattern.startsWith("+") && userPrefix != null) {
230+
val withPrefix = (userPrefix + normalizedPattern).replace("\\D".toRegex(), "")
231+
if (matchesPattern(withPrefix, normalizedNumber)) return true
232+
}
186233
}
187234
return false
188235
}

app/src/main/java/com/addev/listaspam/util/SpamUtils.kt

Lines changed: 3 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,7 @@ import java.util.logging.Logger
3838
class SpamUtils {
3939

4040
companion object {
41-
// URLs
42-
const val LISTA_SPAM_URL_TEMPLATE = "https://www.listaspam.com/busca.php?Telefono=%s"
43-
const val LISTA_SPAM_CSS_SELECTOR =
44-
".rate-and-owner .phone_rating:not(.result-4):not(.result-5)"
45-
private const val RESPONDERONO_URL_TEMPLATE =
46-
"https://www.responderono.es/numero-de-telefono/%s"
47-
private const val RESPONDERONO_CSS_SELECTOR = ".scoreContainer .score.negative"
48-
private const val CLEVER_DIALER_URL_TEMPLATE = "https://www.cleverdialer.es/numero/%s"
49-
private const val CLEVER_DIALER_CSS_SELECTOR =
50-
"body:has(#comments):has(.front-stars:not(.star-rating .stars-4, .star-rating .stars-5)), .circle-spam"
41+
// ...existing code...
5142

5243
private const val SPAM_PREFS = "SPAM_PREFS"
5344
private const val BLOCK_NUMBERS_KEY = "BLOCK_NUMBERS"
@@ -240,35 +231,25 @@ class SpamUtils {
240231

241232
private fun buildSpamCheckers(context: Context): List<suspend (String) -> Boolean> {
242233
val spamCheckers = mutableListOf<suspend (String) -> Boolean>()
243-
244-
// ListaSpam
234+
// ...existing code for API-based checkers only...
245235
val listaSpamApi = shouldFilterWithListaSpamApi(context)
246236
if (listaSpamApi) {
247237
spamCheckers.add { number ->
248238
ApiUtils.checkListaSpamApi(number, getListaSpamApiLang(context) ?: "EN")
249239
}
250240
}
251-
252-
// Tellows
253241
val tellowsApi = shouldFilterWithTellowsApi(context)
254242
if (tellowsApi) {
255243
spamCheckers.add { number ->
256244
ApiUtils.checkTellowsSpamApi(number, getTellowsApiCountry(context) ?: "us")
257245
}
258246
}
259-
260-
// Truecaller
261247
val truecallerApi = shouldFilterWithTruecallerApi(context)
262248
if (truecallerApi) {
263249
spamCheckers.add { number ->
264250
ApiUtils.checkTruecallerSpamApi(number, getTruecallerApiCountry(context) ?: "US")
265251
}
266252
}
267-
268-
if (shouldFilterWithListaSpamScraper(context) && !listaSpamApi) spamCheckers.add(::checkListaSpam)
269-
270-
if (shouldFilterWithResponderONo(context)) spamCheckers.add(::checkResponderono)
271-
if (shouldFilterWithCleverdialer(context)) spamCheckers.add(::checkCleverdialer)
272253
return spamCheckers
273254
}
274255

@@ -356,69 +337,7 @@ class SpamUtils {
356337
}
357338
}
358339

359-
/**
360-
* Checks if a number is marked as spam on ListaSpam.
361-
*
362-
* @param number The phone number to check.
363-
* @return True if the number is marked as spam, false otherwise.
364-
*/
365-
private suspend fun checkListaSpam(number: String): Boolean {
366-
val url = LISTA_SPAM_URL_TEMPLATE.format(number)
367-
return checkUrlForSpam(
368-
url,
369-
LISTA_SPAM_CSS_SELECTOR
370-
)
371-
}
372-
373-
/**
374-
* Checks if a number is marked as spam on Responderono.
375-
*
376-
* @param number The phone number to check.
377-
* @return True if the number is marked as spam, false otherwise.
378-
*/
379-
private suspend fun checkResponderono(number: String): Boolean {
380-
val url = RESPONDERONO_URL_TEMPLATE.format(number)
381-
return checkUrlForSpam(url, RESPONDERONO_CSS_SELECTOR)
382-
}
383-
384-
/**
385-
* Checks if a number is marked as spam on Cleverdialer.
386-
*
387-
* @param number The phone number to check.
388-
* @return True if the number is marked as spam, false otherwise.
389-
*/
390-
private suspend fun checkCleverdialer(number: String): Boolean {
391-
val url = CLEVER_DIALER_URL_TEMPLATE.format(number)
392-
return checkUrlForSpam(url, CLEVER_DIALER_CSS_SELECTOR)
393-
}
394-
395-
/**
396-
* Checks a URL for spam indicators using a CSS selector.
397-
*
398-
* @param url The URL to check.
399-
* @param cssSelector The CSS selector to use for finding spam indicators.
400-
* @return True if spam indicators are found, false otherwise.
401-
*/
402-
private suspend fun checkUrlForSpam(url: String, cssSelector: String): Boolean {
403-
val request = Request.Builder()
404-
.header("User-Agent", USER_AGENT)
405-
.url(url)
406-
.build()
407-
408-
return withContext(Dispatchers.IO) {
409-
try {
410-
client.newCall(request).execute().use { response ->
411-
val body = response.body?.string() ?: return@withContext false
412-
val doc = Jsoup.parse(body)
413-
doc.select(cssSelector).isNotEmpty()
414-
}
415-
} catch (e: IOException) {
416-
Logger.getLogger("checkUrlForSpam")
417-
.warning("Error checking URL: $url with error ${e.message}")
418-
false
419-
}
420-
}
421-
}
340+
// ...scraper logic removed...
422341

423342
/**
424343
* Handles the scenario when a phone number is identified as spam.

app/src/main/res/xml/preferences.xml

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -80,34 +80,6 @@
8080

8181
</PreferenceCategory>
8282

83-
<!-- Spam Number Filters -->
84-
<PreferenceCategory
85-
android:title="@string/pref_category_scrapers_es"
86-
app:iconSpaceReserved="false">
87-
88-
<CheckBoxPreference
89-
android:defaultValue="false"
90-
android:key="pref_filter_lista_spam_scraper"
91-
android:summary="@string/pref_filter_lista_spam_scraper_summary"
92-
android:title="@string/pref_filter_lista_spam_scraper_title"
93-
app:iconSpaceReserved="false" />
94-
95-
<CheckBoxPreference
96-
android:defaultValue="false"
97-
android:key="pref_filter_responder_o_no"
98-
android:summary="@string/pref_filter_responder_o_no_summary"
99-
android:title="@string/pref_filter_responder_o_no_title"
100-
app:iconSpaceReserved="false" />
101-
102-
<CheckBoxPreference
103-
android:defaultValue="false"
104-
android:key="pref_filter_cleverdialer"
105-
android:summary="@string/pref_filter_cleverdialer_summary"
106-
android:title="@string/pref_filter_cleverdialer_title"
107-
app:iconSpaceReserved="false" />
108-
109-
</PreferenceCategory>
110-
11183
<!-- Other Blocking Options -->
11284
<PreferenceCategory
11385
android:title="@string/pref_category_other_options"

0 commit comments

Comments
 (0)