Adding Captcha support and call the login page when auth failed
This commit is contained in:
parent
c29abee329
commit
370c0a83a2
2 changed files with 66 additions and 30 deletions
|
@ -22,6 +22,7 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.util.*
|
||||
|
||||
|
||||
|
@ -162,7 +163,7 @@ class MainActivity : AppCompatActivity() {
|
|||
button?.setOnClickListener {
|
||||
val password = Credentials().get(1)
|
||||
if (password != null) { // call script
|
||||
callScript(user, password.toString(), button?.text.toString())
|
||||
callScrapper(user, password.toString(), button?.text.toString())
|
||||
} else {
|
||||
Toast.makeText(applicationContext, R.string.notConnected, Toast.LENGTH_LONG)
|
||||
.show()
|
||||
|
@ -222,6 +223,36 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun callScrapper(user: String, password: String, app: String, captchaID: String? = null, captchaResponse: String? = null) {
|
||||
if (ContextCompat.checkSelfPermission(this@MainActivity, Manifest.permission.INTERNET)
|
||||
!= PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
Toast.makeText(this@MainActivity, R.string.internetPermission, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
this.finishAffinity()
|
||||
} else {
|
||||
runBlocking {
|
||||
val returns: MutableList<String>? = Scraper(user, password, app, captchaID = captchaID, captchaResponse = captchaResponse, debug = true).search()
|
||||
if (returns != null) { // if job is needed
|
||||
if (returns[0] == "errorNotConnected") loginPage()
|
||||
if (returns[0] == "loginAttemptsExceeded") {
|
||||
val builder: android.app.AlertDialog.Builder = android.app.AlertDialog.Builder(
|
||||
instance)
|
||||
builder.setTitle("Captcha")
|
||||
builder.setMessage(returns[1])
|
||||
val input = EditText(instance)
|
||||
input.inputType = InputType.TYPE_CLASS_TEXT
|
||||
builder.setView(input)
|
||||
builder.setPositiveButton(R.string.validate) { _, _ -> callScrapper(user, password, app, returns[2], input.text.toString()) }
|
||||
builder.setNeutralButton(R.string.cancel) { dialog, _ -> dialog.cancel() }
|
||||
|
||||
builder.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun settingsPage() {
|
||||
setContentView(R.layout.activity_settings)
|
||||
|
@ -252,18 +283,6 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun callScript(user: String, password: String, app: String) {
|
||||
if (ContextCompat.checkSelfPermission(this@MainActivity, Manifest.permission.INTERNET)
|
||||
!= PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
Toast.makeText(this@MainActivity, R.string.internetPermission, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
this.finishAffinity()
|
||||
} else {
|
||||
Scraper(user, password, app = app, debug = true).search()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (prefs!!.getBoolean("firstrun", true)) {
|
||||
|
|
|
@ -14,6 +14,8 @@ class Scraper(
|
|||
private var password: String,
|
||||
private var app: String,
|
||||
private var debug: Boolean = false,
|
||||
private var captchaID: String? = null,
|
||||
private var captchaResponse: String? = null
|
||||
) {
|
||||
|
||||
private var url: String = "https://forum.mobilism.org"
|
||||
|
@ -31,13 +33,18 @@ class Scraper(
|
|||
return "${if (code != null) "[$code]" else ""}${if ((message.isNotEmpty()) and (code is Int)) " " else ""}$message."
|
||||
}
|
||||
|
||||
private fun connect() {
|
||||
private fun connect(): MutableList<String>? {
|
||||
if (debug) println("Connection attempt...")
|
||||
retry++
|
||||
FuelManager.instance.basePath = url
|
||||
FuelManager.instance.baseParams = listOf("mode" to "login")
|
||||
val params = mutableListOf("username" to pseudo, "password" to password, "login" to "Login")
|
||||
if (captchaID != null) {
|
||||
params.add("qa_answer" to captchaResponse.toString())
|
||||
params.add("qa_confirm_id" to captchaID.toString())
|
||||
}
|
||||
val session = "/ucp.php"
|
||||
.httpPost(listOf("username" to pseudo, "password" to password, "login" to "Login"))
|
||||
.httpPost(params)
|
||||
.responseString { _, response, result ->
|
||||
when (result) {
|
||||
is FuelFailure -> {
|
||||
|
@ -51,36 +58,45 @@ class Scraper(
|
|||
}
|
||||
val data = session.join().data.decodeToString()
|
||||
sid = "(?<=sid=)(.{32})".toRegex().find(data)?.value
|
||||
if (errorNotConnected in data) return if (loginAttemptsExceeded in data) error(loginAttemptsExceeded) else error(data)
|
||||
if (errorNotConnected in data) return error(data)
|
||||
Credentials().storeSID(sid.toString())
|
||||
return search()
|
||||
}
|
||||
|
||||
private fun error(htmlPage: String) {
|
||||
private fun error(htmlPage: String): MutableList<String>? {
|
||||
var message = ""
|
||||
var array: MutableList<String>? = null
|
||||
if (errorNotConnected in htmlPage) {
|
||||
message = "${applicationContext().getString(R.string.connectionFailed)}\n${applicationContext().getString(R.string.credentialsDeleted)}."
|
||||
Credentials().delete()
|
||||
} else if (loginAttemptsExceeded in htmlPage) {
|
||||
message = applicationContext().getString(R.string.loginAttemptsExceeded)
|
||||
if (loginAttemptsExceeded in htmlPage) {
|
||||
message = applicationContext().getString(R.string.loginAttemptsExceeded)
|
||||
val qaConfirmID = "(?<=qa_confirm_id\" value=\")(.{32})".toRegex().find(htmlPage)?.value
|
||||
var answer = "(?<=answer\">)(.*)</l".toRegex().find(htmlPage)?.value
|
||||
answer = answer?.dropLast(3)
|
||||
array = mutableListOf("loginAttemptsExceeded", answer.toString(), qaConfirmID.toString())
|
||||
} else {
|
||||
message = "${applicationContext().getString(R.string.connectionFailed)}\n${applicationContext().getString(R.string.credentialsDeleted)}."
|
||||
Credentials().delete()
|
||||
array = mutableListOf("errorNotConnected")
|
||||
}
|
||||
}
|
||||
println(errorFormat(message = message))
|
||||
Toast.makeText(applicationContext(), message, Toast.LENGTH_LONG)
|
||||
.show()
|
||||
|
||||
return array
|
||||
}
|
||||
|
||||
fun search() { // Do the research.
|
||||
fun search(): MutableList<String>? { // Do the research.
|
||||
if (sid == null) {
|
||||
println(errorFormat(message = "No SID found"))
|
||||
if (retry < 3) return connect() else return
|
||||
println(errorFormat(message = "SID not found"))
|
||||
return if (retry < 3) connect() else null
|
||||
} else {
|
||||
if (debug) println("SID recovered")
|
||||
retry = 0
|
||||
}
|
||||
if (debug) println("Going to search page...")
|
||||
FuelManager.instance.basePath = url
|
||||
FuelManager.instance.baseParams =
|
||||
listOf("sid" to sid, "sr" to "topics", "sf" to "titleonly")
|
||||
FuelManager.instance.baseParams = listOf("sid" to sid, "sr" to "topics", "sf" to "titleonly")
|
||||
val session = "/search.php"
|
||||
.httpGet(listOf("keywords" to app))
|
||||
.responseString { _, response, result ->
|
||||
|
@ -95,15 +111,16 @@ class Scraper(
|
|||
}
|
||||
}
|
||||
val data = session.join().data.decodeToString()
|
||||
if (searchNotLogged in data) {
|
||||
return if (searchNotLogged in data) {
|
||||
println(errorFormat(message = "The SID doesn't work, new attempt..."))
|
||||
if (retry < 3) return connect() else return
|
||||
} else return parse(data)
|
||||
if (retry < 3) connect() else null
|
||||
} else parse(data)
|
||||
}
|
||||
|
||||
private fun parse(htmlPage: String) {
|
||||
private fun parse(htmlPage: String): MutableList<String>? {
|
||||
if (debug) println("Fetching results for $app...")
|
||||
// println(htmlPage)
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Reference in a new issue