|
|
|
@ -6,8 +6,10 @@ import kotlinx.coroutines.Dispatchers
|
|
|
|
|
import kotlinx.coroutines.runBlocking
|
|
|
|
|
import kotlinx.coroutines.withContext
|
|
|
|
|
import org.jsoup.Jsoup
|
|
|
|
|
import org.jsoup.nodes.Element
|
|
|
|
|
import org.mosad.seil0.projectlaogai.R
|
|
|
|
|
import org.mosad.seil0.projectlaogai.controller.preferences.EncryptedPreferences
|
|
|
|
|
import org.mosad.seil0.projectlaogai.util.gradeSubject
|
|
|
|
|
import java.security.KeyStore
|
|
|
|
|
import java.security.cert.CertificateFactory
|
|
|
|
|
import java.security.cert.X509Certificate
|
|
|
|
@ -15,20 +17,75 @@ import javax.net.ssl.SSLContext
|
|
|
|
|
import javax.net.ssl.SSLSocketFactory
|
|
|
|
|
import javax.net.ssl.TrustManagerFactory
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* TODO context in constructor?
|
|
|
|
|
*/
|
|
|
|
|
class QISPOSParser {
|
|
|
|
|
|
|
|
|
|
private val className = this.javaClass.name
|
|
|
|
|
private val baseURL = "https://notenverwaltung.hs-offenburg.de"
|
|
|
|
|
private val loginPath = "/qispos/rds?state=user&type=1&category=auth.login&startpage=portal.vm&breadCrumbSource=portal"
|
|
|
|
|
private val rootPath = "/qispos/rds?state=change&type=1&moduleParameter=studyPOSMenu&nextdir=change&next=menu.vm&subdir=applications&xml=menu&purge=y&navigationPosition=functions%2CstudyPOSMenu&breadcrumb=studyPOSMenu&topitem=functions&subitem=studyPOSMenu"
|
|
|
|
|
//private val rootPath = "/qispos/rds?state=change&type=1&moduleParameter=studyPOSMenu&nextdir=change&next=menu.vm&subdir=applications&xml=menu&purge=y&navigationPosition=functions%2CstudyPOSMenu&breadcrumb=studyPOSMenu&topitem=functions&subitem=studyPOSMenu"
|
|
|
|
|
|
|
|
|
|
fun test(context: Context) {
|
|
|
|
|
|
|
|
|
|
fun parseGrades(context: Context) {
|
|
|
|
|
val gradesMap = HashMap<String, ArrayList<gradeSubject>>()
|
|
|
|
|
val gradesListHtml = readGrades(context)
|
|
|
|
|
|
|
|
|
|
gradesListHtml?.select("table > tbody > tr")?.forEach {
|
|
|
|
|
val row = it.select("td.qis_konto")
|
|
|
|
|
|
|
|
|
|
//println("-----------------------------------------------------------")
|
|
|
|
|
//println(it.select("td.qis_konto"))
|
|
|
|
|
|
|
|
|
|
if(row.size >= 6) {
|
|
|
|
|
val subject = gradeSubject(
|
|
|
|
|
id = row[0].text(),
|
|
|
|
|
name = row[1].text(),
|
|
|
|
|
semester = row[2].text(),
|
|
|
|
|
grade = row[3].text(),
|
|
|
|
|
credits = row[5].text()
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if (gradesMap.containsKey(subject.semester)) {
|
|
|
|
|
gradesMap[subject.semester]!!.add(subject)
|
|
|
|
|
println(subject.name)
|
|
|
|
|
} else {
|
|
|
|
|
gradesMap[subject.semester] = arrayListOf(subject)
|
|
|
|
|
println(subject.name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
println("ID: ${row[0].text()}")
|
|
|
|
|
println("Subject Name: ${row[1].text()}")
|
|
|
|
|
println("Semester: ${row[2].text()}")
|
|
|
|
|
println("Grade: ${row[3].text()}")
|
|
|
|
|
println("Credits: ${row[5].text()}")
|
|
|
|
|
println("------------------------------------------------------")
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
println(gradesMap)
|
|
|
|
|
gradesMap.forEach {
|
|
|
|
|
println("${it.key}: ${it.value}")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO sort
|
|
|
|
|
|
|
|
|
|
println("finished parsing!")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* read the grades html from qispos
|
|
|
|
|
* @return the grades list as html element or null
|
|
|
|
|
*/
|
|
|
|
|
private fun readGrades(context: Context): Element?{
|
|
|
|
|
|
|
|
|
|
val credentials = EncryptedPreferences.readCredentials(context)
|
|
|
|
|
val username = credentials.first.substringBefore("@")
|
|
|
|
|
val password = credentials.second
|
|
|
|
|
|
|
|
|
|
runBlocking {
|
|
|
|
|
return runBlocking {
|
|
|
|
|
withContext(Dispatchers.IO) {
|
|
|
|
|
try {
|
|
|
|
|
println("querying qispos ...")
|
|
|
|
@ -56,14 +113,46 @@ class QISPOSParser {
|
|
|
|
|
|
|
|
|
|
println("cookies: $loginCookies")
|
|
|
|
|
println("status is: ${res.statusMessage()}: ${res.statusCode()}")
|
|
|
|
|
println(res.body())
|
|
|
|
|
|
|
|
|
|
// grades url
|
|
|
|
|
val test = Jsoup.parse(res.body()).select("li.menueListStyle").select("a.auflistung").last()
|
|
|
|
|
println(test)
|
|
|
|
|
// grades root document and url
|
|
|
|
|
val rootHtml =Jsoup.parse(res.body())
|
|
|
|
|
val gradesRootLink = rootHtml.select("li.menueListStyle > a.auflistung").last().attr("abs:href")
|
|
|
|
|
println(gradesRootLink)
|
|
|
|
|
|
|
|
|
|
// parse grades url
|
|
|
|
|
val gradesHtml = Jsoup.connect(gradesRootLink)
|
|
|
|
|
.sslSocketFactory(socketFactory)
|
|
|
|
|
.followRedirects(true)
|
|
|
|
|
.cookies(loginCookies)
|
|
|
|
|
.referrer("https://notenverwaltung.hs-offenburg.de/qispos/rds?state=user&type=0")
|
|
|
|
|
.get()
|
|
|
|
|
|
|
|
|
|
val gradesNextLink = gradesHtml.select("li.treelist > a.regular").attr("abs:href")
|
|
|
|
|
println(gradesNextLink)
|
|
|
|
|
|
|
|
|
|
val gradesNextHtml = Jsoup.connect(gradesNextLink)
|
|
|
|
|
.sslSocketFactory(socketFactory)
|
|
|
|
|
.followRedirects(true)
|
|
|
|
|
.cookies(loginCookies)
|
|
|
|
|
.referrer("https://notenverwaltung.hs-offenburg.de/qispos/rds?state=user&type=0")
|
|
|
|
|
.get()
|
|
|
|
|
|
|
|
|
|
val gradesListLink = gradesNextHtml.selectFirst("li.treelist > ul > li").selectFirst("a").attr("abs:href")
|
|
|
|
|
println(gradesListLink)
|
|
|
|
|
|
|
|
|
|
// get the grades list
|
|
|
|
|
val gradesListHtml = Jsoup.connect(gradesListLink)
|
|
|
|
|
.sslSocketFactory(socketFactory)
|
|
|
|
|
.followRedirects(true)
|
|
|
|
|
.cookies(loginCookies)
|
|
|
|
|
.referrer("https://notenverwaltung.hs-offenburg.de/qispos/rds?state=user&type=0")
|
|
|
|
|
.get()
|
|
|
|
|
|
|
|
|
|
//println(gradesListHtml.body())
|
|
|
|
|
gradesListHtml.body()
|
|
|
|
|
} catch (ex: Exception) {
|
|
|
|
|
Log.e(className, "could not load qispos", ex)
|
|
|
|
|
null
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|