* parse grades and store them in a HashMap per semester
This commit is contained in:
		@ -179,7 +179,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
 | 
			
		||||
            EncryptedPreferences.load(this)
 | 
			
		||||
 | 
			
		||||
            val parser = QISPOSParser()
 | 
			
		||||
            parser.test(applicationContext)
 | 
			
		||||
            parser.parseGrades(applicationContext)
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        Log.i(className, "startup completed in $startupTime ms")
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -108,6 +108,9 @@ data class TimetableDay(val timeslots: Array<ArrayList<Lesson>> = Array(6) { Arr
 | 
			
		||||
 | 
			
		||||
data class TimetableWeek(val weekIndex: Int = 0, val weekNumberYear: Int = 0, val days: Array<TimetableDay> = Array(6) { TimetableDay() })
 | 
			
		||||
 | 
			
		||||
// data classes for the qispos part
 | 
			
		||||
data class gradeSubject(val id: String = "", val name: String = "", val semester: String = "", val grade: String = "", val credits: String = "")
 | 
			
		||||
 | 
			
		||||
// TCoR
 | 
			
		||||
data class TimetableWeekTCoR(val days: Array<TimetableDay> = Array(6) { TimetableDay() })
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user