From ff0c4ad1a71ae3582cc67738a7e8dc89aa4ebfe5 Mon Sep 17 00:00:00 2001 From: Jannik Seiler Date: Thu, 13 Aug 2020 21:01:21 +0200 Subject: [PATCH] QISPOSParser [Part 1] * get the grades url from qispos --- app/build.gradle | 1 + .../mosad/seil0/projectlaogai/MainActivity.kt | 19 +- .../projectlaogai/controller/NFCMensaCard.kt | 5 +- .../controller/PreferencesController.kt | 189 ------------------ .../projectlaogai/controller/QISPOSParser.kt | 107 ++++++++++ .../controller/cache/CacheController.kt | 16 +- .../controller/cache/TimetableController.kt | 2 +- .../EncryptedPreferences.kt} | 29 +-- .../controller/preferences/Preferences.kt | 188 +++++++++++++++++ .../projectlaogai/fragments/MensaFragment.kt | 2 +- .../fragments/SettingsFragment.kt | 29 ++- .../uicomponents/dialogs/AddSubjectDialog.kt | 6 +- .../uicomponents/dialogs/LoginDialog.kt | 6 +- .../raw/notenverwaltung_hs_offenburg_de.crt | Bin 0 -> 2747 bytes 14 files changed, 356 insertions(+), 243 deletions(-) delete mode 100644 app/src/main/java/org/mosad/seil0/projectlaogai/controller/PreferencesController.kt create mode 100644 app/src/main/java/org/mosad/seil0/projectlaogai/controller/QISPOSParser.kt rename app/src/main/java/org/mosad/seil0/projectlaogai/controller/{login/LoginController.kt => preferences/EncryptedPreferences.kt} (95%) create mode 100644 app/src/main/java/org/mosad/seil0/projectlaogai/controller/preferences/Preferences.kt create mode 100644 app/src/main/res/raw/notenverwaltung_hs_offenburg_de.crt diff --git a/app/build.gradle b/app/build.gradle index c614135..39f46d0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -63,6 +63,7 @@ dependencies { implementation 'de.psdev.licensesdialog:licensesdialog:2.1.0' implementation 'org.apache.commons:commons-lang3:3.10' + implementation 'org.jsoup:jsoup:1.13.1' testImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test:core:1.2.0' diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt index 621de15..54f0afe 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt @@ -43,12 +43,13 @@ import com.afollestad.aesthetic.NavigationViewMode import com.google.android.material.navigation.NavigationView import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.app_bar_main.* -import org.mosad.seil0.projectlaogai.controller.cache.CacheController import org.mosad.seil0.projectlaogai.controller.NFCMensaCard -import org.mosad.seil0.projectlaogai.controller.PreferencesController -import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cColorAccent -import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cColorPrimary -import org.mosad.seil0.projectlaogai.controller.login.LoginController +import org.mosad.seil0.projectlaogai.controller.QISPOSParser +import org.mosad.seil0.projectlaogai.controller.cache.CacheController +import org.mosad.seil0.projectlaogai.controller.preferences.EncryptedPreferences +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cColorAccent +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cColorPrimary import org.mosad.seil0.projectlaogai.fragments.* import kotlin.system.measureTimeMillis @@ -173,9 +174,13 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte */ private fun load() { val startupTime = measureTimeMillis { - PreferencesController.load(this) // load the settings, must be finished before doing anything else + Preferences.load(this) // load the settings, must be finished before doing anything else CacheController(this) // load the cache - LoginController.load(this) + EncryptedPreferences.load(this) + + val parser = QISPOSParser() + parser.test(applicationContext) + } Log.i(className, "startup completed in $startupTime ms") } diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/NFCMensaCard.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/NFCMensaCard.kt index c19db0a..af4b310 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/NFCMensaCard.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/NFCMensaCard.kt @@ -35,6 +35,7 @@ import com.codebutler.farebot.card.desfire.DesfireFileSettings import com.codebutler.farebot.card.desfire.DesfireProtocol import kotlinx.android.synthetic.main.dialog_mensa_credit.* import org.mosad.seil0.projectlaogai.R +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences import java.lang.Exception class NFCMensaCard { @@ -84,13 +85,13 @@ class NFCMensaCard { val dialog = MaterialDialog(context) .customView(R.layout.dialog_mensa_credit) - val current = if (!PreferencesController.oGiants) { + val current = if (!Preferences.oGiants) { String.format("%.2f €", (currentRaw.toFloat() / 1000)) } else { String.format("%.4f shm", (currentRaw.toFloat() * 0.0000075)) } - val last = if (!PreferencesController.oGiants) { + val last = if (!Preferences.oGiants) { String.format("%.2f €", (lastRaw.toFloat() / 1000)) } else { String.format("%.4f shm", (lastRaw.toFloat() * 0.0000075)) diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/PreferencesController.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/PreferencesController.kt deleted file mode 100644 index ead7a16..0000000 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/PreferencesController.kt +++ /dev/null @@ -1,189 +0,0 @@ -/** - * ProjectLaogai - * - * Copyright 2019-2020 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - * - */ - -package org.mosad.seil0.projectlaogai.controller - -import android.content.Context -import android.graphics.Color -import org.mosad.seil0.projectlaogai.R -import org.mosad.seil0.projectlaogai.util.Course - -/** - * The PreferencesController class - * contains all preferences and global variables that exist in this app - */ -class PreferencesController { - - companion object { - var coursesCacheTime: Long = 0 - var mensaCacheTime: Long = 0 - var timetableCacheTime: Long = 0 - var cColorPrimary: Int = Color.parseColor("#009688") - var cColorAccent: Int = Color.parseColor("#0096ff") - var cCourse = Course( - "https://www.hs-offenburg.de/index.php?id=6627&class=class&iddV=DA64F6FE-9DDB-429E-A677-05D0D40CB636&week=0", - "AI3" - ) - var cShowBuffet = true - var oGiants = false - - // the save function - fun save(context: Context) { - val sharedPref = context.getSharedPreferences( - context.getString(R.string.preference_file_key), - Context.MODE_PRIVATE - ) - - // save the update times (cache) - with (sharedPref.edit()) { - putLong(context.getString(R.string.save_key_coursesCacheTime), - coursesCacheTime - ) - putLong(context.getString(R.string.save_key_mensaCacheTime), - mensaCacheTime - ) - putLong(context.getString(R.string.save_key_timetableCacheTime), - timetableCacheTime - ) - apply() - } - - } - - /** - * save the course locally - */ - fun saveCourse(context: Context, course: Course) { - val sharedPref = context.getSharedPreferences( - context.getString(R.string.preference_file_key), - Context.MODE_PRIVATE - ) - - with (sharedPref.edit()) { - putString(context.getString(R.string.save_key_course), course.courseName) - putString(context.getString(R.string.save_key_courseTTLink), course.courseLink) - apply() - } - - cCourse = course - } - - /** - * save the primary color - */ - fun saveColorPrimary(context: Context, colorPrimary: Int) { - val sharedPref = context.getSharedPreferences( - context.getString(R.string.preference_file_key), - Context.MODE_PRIVATE - ) - - with (sharedPref.edit()) { - putInt(context.getString(R.string.save_key_colorPrimary), - colorPrimary - ) - apply() - } - - cColorPrimary = colorPrimary - } - - /** - * save the accent color - */ - fun saveColorAccent(context: Context, colorAccent: Int) { - val sharedPref = context.getSharedPreferences( - context.getString(R.string.preference_file_key), - Context.MODE_PRIVATE - ) - - with (sharedPref.edit()) { - putInt(context.getString(R.string.save_key_colorAccent), - colorAccent - ) - apply() - } - - cColorAccent = colorAccent - } - - /** - * save showBuffet - */ - fun saveShowBuffet(context: Context, showBuffet: Boolean) { - val sharedPref = context.getSharedPreferences( - context.getString(R.string.preference_file_key), - Context.MODE_PRIVATE - ) - - with (sharedPref.edit()) { - putBoolean(context.getString(R.string.save_key_showBuffet), - showBuffet - ) - apply() - } - - cShowBuffet = showBuffet - } - - // the load function - fun load(context: Context) { - val sharedPref = context.getSharedPreferences( - context.getString(R.string.preference_file_key), - Context.MODE_PRIVATE - ) - - // load the update times (cache) - coursesCacheTime = sharedPref.getLong(context.getString( - R.string.save_key_coursesCacheTime - ), 0) - mensaCacheTime = sharedPref.getLong(context.getString( - R.string.save_key_mensaCacheTime - ), 0) - timetableCacheTime = sharedPref.getLong(context.getString( - R.string.save_key_timetableCacheTime - ), 0) - - // load saved course - cCourse = Course( - sharedPref.getString( - context.getString(R.string.save_key_courseTTLink), - "https://www.hs-offenburg.de/index.php?id=6627&class=class&iddV=DA64F6FE-9DDB-429E-A677-05D0D40CB636&week=0" - )!!, - sharedPref.getString(context.getString(R.string.save_key_course), "AI3")!! - ) - - // load saved colors - cColorPrimary = sharedPref.getInt(context.getString( - R.string.save_key_colorPrimary - ), cColorPrimary) - cColorAccent = sharedPref.getInt(context.getString( - R.string.save_key_colorAccent - ), cColorAccent) - - // load showBuffet - cShowBuffet = sharedPref.getBoolean(context.getString( - R.string.save_key_showBuffet - ), true) - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/QISPOSParser.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/QISPOSParser.kt new file mode 100644 index 0000000..28b7d1a --- /dev/null +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/QISPOSParser.kt @@ -0,0 +1,107 @@ +package org.mosad.seil0.projectlaogai.controller + +import android.content.Context +import android.util.Log +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import org.jsoup.Jsoup +import org.mosad.seil0.projectlaogai.R +import org.mosad.seil0.projectlaogai.controller.preferences.EncryptedPreferences +import java.security.KeyStore +import java.security.cert.CertificateFactory +import java.security.cert.X509Certificate +import javax.net.ssl.SSLContext +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.TrustManagerFactory + +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" + + fun test(context: Context) { + + val credentials = EncryptedPreferences.readCredentials(context) + val username = credentials.first.substringBefore("@") + val password = credentials.second + + runBlocking { + withContext(Dispatchers.IO) { + try { + println("querying qispos ...") + println("using $username with ********") + + val socketFactory = createSSLSocketFactory(context) + + // login, asdf = username, fdsa = password, wtf + val list = mapOf( + Pair("asdf", username), + Pair("fdsa", password), + Pair("submit", "Anmelden") + ) + + // login and get session cookies + val res = Jsoup.connect(baseURL + loginPath) + .sslSocketFactory(socketFactory) + .followRedirects(true) + .referrer("https://notenverwaltung.hs-offenburg.de/qispos/rds?state=user&type=0") + .data(list) + .postDataCharset("UTF-8") + .execute() + + val loginCookies = res.cookies() + + 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) + + } catch (ex: Exception) { + Log.e(className, "could not load qispos", ex) + } + } + } + + } + + private fun createSSLSocketFactory(context: Context): SSLSocketFactory { + // Load CAs from an InputStream + // (could be from a resource or ByteArrayInputStream or ...) + val cf: CertificateFactory = CertificateFactory.getInstance("X.509") + val caInput = context.resources.openRawResource(R.raw.notenverwaltung_hs_offenburg_de) + val ca = caInput.use { + cf.generateCertificate(it) as X509Certificate + } + println("ca=" + ca.subjectDN) + + // Create a KeyStore containing our trusted CAs + val keyStoreType = KeyStore.getDefaultType() + val keyStore = KeyStore.getInstance(keyStoreType).apply { + load(null, null) + setCertificateEntry("ca", ca) + } + + // Create a TrustManager that trusts the CAs inputStream our KeyStore + val tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm() + val tmf = TrustManagerFactory.getInstance(tmfAlgorithm).apply { + init(keyStore) + } + + // Create an SSLContext that uses our TrustManager + val sslContext = SSLContext.getInstance("TLS").apply { + init(null, tmf.trustManagers, null) + } + + return sslContext.socketFactory + } + + + + +} \ No newline at end of file diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/cache/CacheController.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/cache/CacheController.kt index 2947216..3fc2581 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/cache/CacheController.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/cache/CacheController.kt @@ -29,12 +29,12 @@ import com.google.gson.GsonBuilder import com.google.gson.JsonParser import com.google.gson.reflect.TypeToken import kotlinx.coroutines.* -import org.mosad.seil0.projectlaogai.controller.PreferencesController -import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cCourse -import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.coursesCacheTime -import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.mensaCacheTime -import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.timetableCacheTime +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences import org.mosad.seil0.projectlaogai.controller.TCoRAPIController +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cCourse +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.coursesCacheTime +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.mensaCacheTime +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.timetableCacheTime import org.mosad.seil0.projectlaogai.util.* import java.io.* import java.util.* @@ -122,7 +122,7 @@ class CacheController(cont: Context) { // save cache file and update time save(file, Gson().toJson(courseListUp)) coursesCacheTime = System.currentTimeMillis() / 1000 - PreferencesController.save(context) + Preferences.save(context) } } @@ -142,7 +142,7 @@ class CacheController(cont: Context) { // save cache file and update time save(file, Gson().toJson(mensaMenu)) mensaCacheTime = System.currentTimeMillis() / 1000 - PreferencesController.save(context) + Preferences.save(context) } } @@ -173,7 +173,7 @@ class CacheController(cont: Context) { // save cache file and update time save(file, Gson().toJson(timetable)) timetableCacheTime = System.currentTimeMillis() / 1000 - PreferencesController.save(context) + Preferences.save(context) } } diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/cache/TimetableController.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/cache/TimetableController.kt index b76b830..2e562f7 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/cache/TimetableController.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/cache/TimetableController.kt @@ -24,8 +24,8 @@ package org.mosad.seil0.projectlaogai.controller.cache import android.content.Context import kotlinx.coroutines.Job -import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cCourse import org.mosad.seil0.projectlaogai.controller.TCoRAPIController +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cCourse import org.mosad.seil0.projectlaogai.util.Lesson import org.mosad.seil0.projectlaogai.util.TimetableWeek diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/login/LoginController.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/preferences/EncryptedPreferences.kt similarity index 95% rename from app/src/main/java/org/mosad/seil0/projectlaogai/controller/login/LoginController.kt rename to app/src/main/java/org/mosad/seil0/projectlaogai/controller/preferences/EncryptedPreferences.kt index df51706..0925dbc 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/login/LoginController.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/preferences/EncryptedPreferences.kt @@ -20,7 +20,7 @@ * */ -package org.mosad.seil0.projectlaogai.controller.login +package org.mosad.seil0.projectlaogai.controller.preferences import android.content.Context import android.content.SharedPreferences @@ -31,23 +31,11 @@ import androidx.security.crypto.EncryptedSharedPreferences import androidx.security.crypto.MasterKey import org.mosad.seil0.projectlaogai.R -object LoginController { +object EncryptedPreferences { var email = "" internal set - /** - * initially load the users email - */ - fun load(context: Context) { - with(getEncryptedPreferences(context)) { - email = this?.getString( - context.getString(R.string.save_key_user_email), - context.getString(R.string.sample_user) - ).toString() - } - } - /** * save user email and password to encrypted preference */ @@ -64,6 +52,7 @@ object LoginController { /** * read user email and password from encrypted preference + * @return Pair(email, password) */ fun readCredentials(context: Context): Pair { return with (getEncryptedPreferences(context)) { @@ -76,6 +65,18 @@ object LoginController { } } + /** + * initially load the stored values + */ + fun load(context: Context) { + with(getEncryptedPreferences(context)) { + email = this?.getString( + context.getString(R.string.save_key_user_email), + context.getString(R.string.sample_user) + ).toString() + } + } + /** * create a encrypted shared preference */ diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/preferences/Preferences.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/preferences/Preferences.kt new file mode 100644 index 0000000..308e85c --- /dev/null +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/preferences/Preferences.kt @@ -0,0 +1,188 @@ +/** + * ProjectLaogai + * + * Copyright 2019-2020 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +package org.mosad.seil0.projectlaogai.controller.preferences + +import android.content.Context +import android.graphics.Color +import org.mosad.seil0.projectlaogai.R +import org.mosad.seil0.projectlaogai.util.Course + +/** + * The PreferencesController class + * contains all preferences and global variables that exist in this app + */ +object Preferences { + + var coursesCacheTime: Long = 0 + var mensaCacheTime: Long = 0 + var timetableCacheTime: Long = 0 + var cColorPrimary: Int = Color.parseColor("#009688") + var cColorAccent: Int = Color.parseColor("#0096ff") + var cCourse = Course( + "https://www.hs-offenburg.de/index.php?id=6627&class=class&iddV=DA64F6FE-9DDB-429E-A677-05D0D40CB636&week=0", + "AI3" + ) + var cShowBuffet = true + var oGiants = false + + // the save function + fun save(context: Context) { + val sharedPref = context.getSharedPreferences( + context.getString(R.string.preference_file_key), + Context.MODE_PRIVATE + ) + + // save the update times (cache) + with (sharedPref.edit()) { + putLong(context.getString(R.string.save_key_coursesCacheTime), + coursesCacheTime + ) + putLong(context.getString(R.string.save_key_mensaCacheTime), + mensaCacheTime + ) + putLong(context.getString(R.string.save_key_timetableCacheTime), + timetableCacheTime + ) + apply() + } + + } + + /** + * save the course locally + */ + fun saveCourse(context: Context, course: Course) { + val sharedPref = context.getSharedPreferences( + context.getString(R.string.preference_file_key), + Context.MODE_PRIVATE + ) + + with (sharedPref.edit()) { + putString(context.getString(R.string.save_key_course), course.courseName) + putString(context.getString(R.string.save_key_courseTTLink), course.courseLink) + apply() + } + + cCourse = course + } + + /** + * save the primary color + */ + fun saveColorPrimary(context: Context, colorPrimary: Int) { + val sharedPref = context.getSharedPreferences( + context.getString(R.string.preference_file_key), + Context.MODE_PRIVATE + ) + + with (sharedPref.edit()) { + putInt(context.getString(R.string.save_key_colorPrimary), + colorPrimary + ) + apply() + } + + cColorPrimary = colorPrimary + } + + /** + * save the accent color + */ + fun saveColorAccent(context: Context, colorAccent: Int) { + val sharedPref = context.getSharedPreferences( + context.getString(R.string.preference_file_key), + Context.MODE_PRIVATE + ) + + with (sharedPref.edit()) { + putInt(context.getString(R.string.save_key_colorAccent), + colorAccent + ) + apply() + } + + cColorAccent = colorAccent + } + + /** + * save showBuffet + */ + fun saveShowBuffet(context: Context, showBuffet: Boolean) { + val sharedPref = context.getSharedPreferences( + context.getString(R.string.preference_file_key), + Context.MODE_PRIVATE + ) + + with (sharedPref.edit()) { + putBoolean(context.getString(R.string.save_key_showBuffet), + showBuffet + ) + apply() + } + + cShowBuffet = showBuffet + } + + /** + * initially load the stored values + */ + fun load(context: Context) { + val sharedPref = context.getSharedPreferences( + context.getString(R.string.preference_file_key), + Context.MODE_PRIVATE + ) + + // load the update times (cache) + coursesCacheTime = sharedPref.getLong(context.getString( + R.string.save_key_coursesCacheTime + ), 0) + mensaCacheTime = sharedPref.getLong(context.getString( + R.string.save_key_mensaCacheTime + ), 0) + timetableCacheTime = sharedPref.getLong(context.getString( + R.string.save_key_timetableCacheTime + ), 0) + + // load saved course + cCourse = Course( + sharedPref.getString(context.getString(R.string.save_key_courseTTLink), + "https://www.hs-offenburg.de/index.php?id=6627&class=class&iddV=DA64F6FE-9DDB-429E-A677-05D0D40CB636&week=0" + )!!, + sharedPref.getString(context.getString(R.string.save_key_course), "AI3")!! + ) + + // load saved colors + cColorPrimary = sharedPref.getInt(context.getString( + R.string.save_key_colorPrimary + ), cColorPrimary) + cColorAccent = sharedPref.getInt(context.getString( + R.string.save_key_colorAccent + ), cColorAccent) + + // load showBuffet + cShowBuffet = sharedPref.getBoolean(context.getString( + R.string.save_key_showBuffet + ), true) + } + +} \ No newline at end of file diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MensaFragment.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MensaFragment.kt index 0ec7d23..48e25da 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MensaFragment.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MensaFragment.kt @@ -35,7 +35,7 @@ import kotlinx.coroutines.withContext import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.controller.cache.CacheController import org.mosad.seil0.projectlaogai.controller.cache.CacheController.Companion.mensaMenu -import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cShowBuffet +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cShowBuffet import org.mosad.seil0.projectlaogai.util.MensaWeek import org.mosad.seil0.projectlaogai.uicomponents.DayCardView import org.mosad.seil0.projectlaogai.uicomponents.MealLinearLayout diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt index 50f2dc3..ecd7c23 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt @@ -49,13 +49,13 @@ import org.mosad.seil0.projectlaogai.BuildConfig import org.mosad.seil0.projectlaogai.R import org.mosad.seil0.projectlaogai.controller.cache.CacheController import org.mosad.seil0.projectlaogai.controller.cache.CacheController.Companion.coursesList -import org.mosad.seil0.projectlaogai.controller.PreferencesController -import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cColorAccent -import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cColorPrimary -import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cCourse -import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cShowBuffet +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences import org.mosad.seil0.projectlaogai.controller.cache.TimetableController -import org.mosad.seil0.projectlaogai.controller.login.LoginController +import org.mosad.seil0.projectlaogai.controller.preferences.EncryptedPreferences +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cColorAccent +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cColorPrimary +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cCourse +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cShowBuffet import org.mosad.seil0.projectlaogai.uicomponents.dialogs.LoginDialog import org.mosad.seil0.projectlaogai.util.DataTypes import java.util.* @@ -105,7 +105,7 @@ class SettingsFragment : Fragment() { super.onViewCreated(view, savedInstanceState) // initialize the settings gui - txtView_User.text = LoginController.email + txtView_User.text = EncryptedPreferences.email txtView_Course.text = cCourse.courseName txtView_AboutDesc.text = resources.getString(R.string.about_version, BuildConfig.VERSION_NAME, getString(R.string.build_time)) switch_buffet.isChecked = cShowBuffet // init switch @@ -141,16 +141,16 @@ class SettingsFragment : Fragment() { LoginDialog(context!!) .positiveButton { println("Test: $password") - LoginController.saveCredentials(email, password, context) + EncryptedPreferences.saveCredentials(email, password, context) } .show { - email = LoginController.email + email = EncryptedPreferences.email password = "" } } linLayoutUser.setOnLongClickListener { - PreferencesController.oGiants = true // enable easter egg + Preferences.oGiants = true // enable easter egg return@setOnLongClickListener true } @@ -181,7 +181,6 @@ class SettingsFragment : Fragment() { items.forEach { val list = it.split(" - ") TimetableController.removeSubject(list[0], list[1], context) - // TODO save } } } @@ -254,7 +253,7 @@ class SettingsFragment : Fragment() { colorPrimaryDark(color) apply() } - PreferencesController.saveColorPrimary(context!!, color) + Preferences.saveColorPrimary(context!!, color) } .show { title(R.string.primary_color) @@ -274,7 +273,7 @@ class SettingsFragment : Fragment() { apply() } - PreferencesController.saveColorAccent(context!!, color) + Preferences.saveColorAccent(context!!, color) } .show{ title(R.string.accent_color) @@ -284,7 +283,7 @@ class SettingsFragment : Fragment() { } switchBuffet.setOnClickListener { - PreferencesController.saveShowBuffet(context!!, switchBuffet.isChecked) + Preferences.saveShowBuffet(context!!, switchBuffet.isChecked) } } @@ -306,7 +305,7 @@ class SettingsFragment : Fragment() { loadingDialog.show() GlobalScope.launch(Dispatchers.Default) { - PreferencesController.saveCourse(context, coursesList[index]) // save the course + Preferences.saveCourse(context, coursesList[index]) // save the course // update current & next weeks timetable val threads = listOf( diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/dialogs/AddSubjectDialog.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/dialogs/AddSubjectDialog.kt index 7ca4aab..e43ebb1 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/dialogs/AddSubjectDialog.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/dialogs/AddSubjectDialog.kt @@ -37,7 +37,7 @@ import com.afollestad.materialdialogs.customview.customView import com.afollestad.materialdialogs.customview.getCustomView import kotlinx.coroutines.runBlocking import org.mosad.seil0.projectlaogai.R -import org.mosad.seil0.projectlaogai.controller.PreferencesController +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences import org.mosad.seil0.projectlaogai.controller.cache.CacheController import org.mosad.seil0.projectlaogai.controller.TCoRAPIController import org.mosad.seil0.projectlaogai.util.Course @@ -71,8 +71,8 @@ class AddSubjectDialog(val context: Context) { spinnerSubjects = dialog.getCustomView().findViewById(R.id.spinner_Lessons) // fix not working accent color - dialog.getActionButton(WhichButton.POSITIVE).updateTextColor(PreferencesController.cColorAccent) - dialog.getActionButton(WhichButton.NEGATIVE).updateTextColor(PreferencesController.cColorAccent) + dialog.getActionButton(WhichButton.POSITIVE).updateTextColor(Preferences.cColorAccent) + dialog.getActionButton(WhichButton.NEGATIVE).updateTextColor(Preferences.cColorAccent) initSpinners() } diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/dialogs/LoginDialog.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/dialogs/LoginDialog.kt index fb17159..caef238 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/dialogs/LoginDialog.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/dialogs/LoginDialog.kt @@ -32,7 +32,7 @@ import com.afollestad.materialdialogs.bottomsheets.setPeekHeight import com.afollestad.materialdialogs.customview.customView import com.afollestad.materialdialogs.customview.getCustomView import org.mosad.seil0.projectlaogai.R -import org.mosad.seil0.projectlaogai.controller.PreferencesController +import org.mosad.seil0.projectlaogai.controller.preferences.Preferences class LoginDialog(val context: Context) { @@ -56,8 +56,8 @@ class LoginDialog(val context: Context) { editTextPassword = dialog.getCustomView().findViewById(R.id.editText_password) // fix not working accent color - dialog.getActionButton(WhichButton.POSITIVE).updateTextColor(PreferencesController.cColorAccent) - dialog.getActionButton(WhichButton.NEGATIVE).updateTextColor(PreferencesController.cColorAccent) + dialog.getActionButton(WhichButton.POSITIVE).updateTextColor(Preferences.cColorAccent) + dialog.getActionButton(WhichButton.NEGATIVE).updateTextColor(Preferences.cColorAccent) } fun positiveButton(func: LoginDialog.() -> Unit): LoginDialog = apply { diff --git a/app/src/main/res/raw/notenverwaltung_hs_offenburg_de.crt b/app/src/main/res/raw/notenverwaltung_hs_offenburg_de.crt new file mode 100644 index 0000000000000000000000000000000000000000..a0b949e77e09cc3a01005ac7a15789d2eb321b3a GIT binary patch literal 2747 zcmb7Gc~}!k9_{Wlfk3zsgm5$|M@Wc}s zSOwITLmWX=5KvIO76cDuf()pP*E;He4lsCb2hq{R{dVV%KI;9d-m6#js=r1Rnx{|& zX@4;R0wIWuWPrPxBF8R;Zmf4hwTUFB?7-|%Z4lH_15o)^h89X95+Y!tA;g-`n2-9Y z8k%HgBqqiLLL^frM*KyXn2U*JLOy~+m;_;AGO2`~ zP#qPG7FnI;zla*LFobV}O0nd4Ow4B(pn9sJI++yA z<6**h8IH|HnJP?^JR?xVNl?u_2}3@W5h}76<0J?Li7rT#K&&#!=1CEmkc)hSaRr$0 zBc~Rbi=2m9Q=KWxJs%|;0}jz-cwITrNb`nk$w=bb(7Zm^*qV5a86PR&;s z+dZ`G$j)lFV)NfYa~C(brsn*L^5Z-Ghr{OEWH9u4x4eGD$!F#2r8oLE7UhJ# zE_*<#DP57b;MdcQa)i4M8=CM82Gi=NVrpPnD2NJBs!wS$7Z@4S|cUTmr@mLxrj>nJJf96PGB@{_9p(tY_6-e+0WPm6<^$25-VX7uVUw_0MDpBnw4RX&2sm0J+@h1&zkVd`AoMnVervC`*f<{@QdNi-f8Am zr&}Z6Q?3k^*7~iOiu`;5LZa(?-oA)!>uTSjbZ=OmJD(Pz-`AlR=jn9zXwJrWYs_(7 z)^3b;?0LtJt#j0sW$&gp-+rh#qikcG@V)7__rytg*$3V3-#_Uh9z~_r7d=?)XpU0f zw`T6<_LAjLte+zzsyRL=D6PaD--%*}%GM{%Gb!6nEuC5LY!2E&C=Ussakb+*^DkX{ zwK@uq)$@f-r(_**r|-=ZSXJKJ$2*|=UF-1c4x;1MrK2Z&eP1_l;8K6h1NQ-faB4<7s3XD1Cj@b z14RA{%H`%Qq+xguQLmW!jEL66~U}i(V<95;OVG`kvlRf(EB13<*AglVHZ!IqNq}W%VDX;U4 z(WG~DPH!cddmisRF@;`{p{rwDcV*cliuJ+5XxrO2cw>c$#NDi3tDkZU>aBn3w4&2b Z>W44sXkD1MnrghyA(VD7