diff --git a/app/src/main/java/com/denizk0461/weserplaner/activity/FetcherActivity.kt b/app/src/main/java/com/denizk0461/weserplaner/activity/FetcherActivity.kt index 9f97ff4..38ee099 100644 --- a/app/src/main/java/com/denizk0461/weserplaner/activity/FetcherActivity.kt +++ b/app/src/main/java/com/denizk0461/weserplaner/activity/FetcherActivity.kt @@ -13,6 +13,7 @@ import com.denizk0461.weserplaner.data.showErrorSnackBar import com.denizk0461.weserplaner.data.showSnackBar import com.denizk0461.weserplaner.data.showToast import com.denizk0461.weserplaner.databinding.ActivityFetcherBinding +import com.denizk0461.weserplaner.exception.NotLoggedInException import com.denizk0461.weserplaner.model.TextSheetContentId import com.denizk0461.weserplaner.sheet.TextSheet import com.denizk0461.weserplaner.viewmodel.FetcherViewModel @@ -58,9 +59,7 @@ class FetcherActivity : FragmentActivity() { ) // Enabling JavaScript. See comment above lint suppression for reason why this is done. - binding.webview.settings.apply { - javaScriptEnabled = true - } + binding.webview.settings.javaScriptEnabled = true binding.webview.webViewClient = object : WebViewClient() { // Disallow redirecting to prevent the app from launching Chrome after the user logs in @@ -125,9 +124,7 @@ class FetcherActivity : FragmentActivity() { binding.fab.setOnClickListener { - if (binding.webview.url?.contains( - scheduleUrl - ) == true) { + if (binding.webview.url?.contains(scheduleUrl) == true) { /* * Retrieve encoded HTML via JavaScript function. Encoding is done as otherwise not all * symbols will be accurately fetched. @@ -143,15 +140,27 @@ class FetcherActivity : FragmentActivity() { * Notify the user that the fetch was successful, and tell the user how many * items could not be fetched. */ - showToast(this, when (elementsNotFetched) { - 0 -> getString(R.string.toast_fetch_finished_zero) - 1 -> getString(R.string.toast_fetch_finished_one) - else -> getString(R.string.toast_fetch_finished_other, elementsNotFetched) - }) + showToast( + this, when (elementsNotFetched) { + 0 -> getString(R.string.toast_fetch_finished_zero) + 1 -> getString(R.string.toast_fetch_finished_one) + else -> getString( + R.string.toast_fetch_finished_other, + elementsNotFetched + ) + } + ) // Close the activity finish() + } catch (e: NotLoggedInException) { + // Let the user know that they need to log in + theme.showErrorSnackBar( + binding.coordinatorLayout, + getString(R.string.fetch_error_login_snack), + binding.bottomAppBar, + ) } catch (e: IOException) { // Let the user know that an error occurred theme.showErrorSnackBar( diff --git a/app/src/main/java/com/denizk0461/weserplaner/data/StudIPParser.kt b/app/src/main/java/com/denizk0461/weserplaner/data/StudIPParser.kt index 4e22b6d..00c1fef 100644 --- a/app/src/main/java/com/denizk0461/weserplaner/data/StudIPParser.kt +++ b/app/src/main/java/com/denizk0461/weserplaner/data/StudIPParser.kt @@ -2,6 +2,7 @@ package com.denizk0461.weserplaner.data import android.app.Application import com.denizk0461.weserplaner.db.AppRepository +import com.denizk0461.weserplaner.exception.NotLoggedInException import com.denizk0461.weserplaner.model.StudIPEvent import org.jsoup.Jsoup import org.jsoup.nodes.Document @@ -20,10 +21,11 @@ class StudIPParser(application: Application) { * Parse a given HTML string. HTML must be of a Stud.IP timetable. May skip elements that don't * provide full information on an event (title, timeslot, lecturers, room). * - * @param html website content of the Stud.IP timetable - * @throws IOException when an error in fetching or the database transaction occurs + * @param html website content of the Stud.IP timetable + * @throws NotLoggedInException if the user has not logged in before starting the fetch + * @throws IOException when an error in fetching or the database transaction occurs */ - @Throws(IOException::class) + @Throws(NotLoggedInException::class, IOException::class) fun parse(html: String): Int { // Counts how many elements could not be successfully fetched var elementsNotFetched = 0 @@ -31,6 +33,11 @@ class StudIPParser(application: Application) { // Parse the HTML using Jsoup to traverse the document val doc = Jsoup.parse(html) + // Check if the user has logged in by checking the ID of the body tag + if (doc.body().id() != "calendar-schedule-index") { + throw NotLoggedInException() + } + /* * Create the list that all events will be added to temporarily before saving them to * persistent storage. diff --git a/app/src/main/java/com/denizk0461/weserplaner/exception/InvalidContentIdException.kt b/app/src/main/java/com/denizk0461/weserplaner/exception/InvalidContentIdException.kt deleted file mode 100644 index e055ee8..0000000 --- a/app/src/main/java/com/denizk0461/weserplaner/exception/InvalidContentIdException.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.denizk0461.weserplaner.exception - -import java.io.IOException - -class InvalidContentIdException : IOException() \ No newline at end of file diff --git a/app/src/main/java/com/denizk0461/weserplaner/exception/NotLoggedInException.kt b/app/src/main/java/com/denizk0461/weserplaner/exception/NotLoggedInException.kt new file mode 100644 index 0000000..b8d2c19 --- /dev/null +++ b/app/src/main/java/com/denizk0461/weserplaner/exception/NotLoggedInException.kt @@ -0,0 +1,8 @@ +package com.denizk0461.weserplaner.exception + +import java.io.IOException + +/** + * Exception used to let the user know that they need to log in in order to download their schedule. + */ +class NotLoggedInException : IOException() \ No newline at end of file diff --git a/app/src/main/java/com/denizk0461/weserplaner/exception/ParcelNotFoundException.kt b/app/src/main/java/com/denizk0461/weserplaner/exception/ParcelNotFoundException.kt index 612fd1a..4fb1f9c 100644 --- a/app/src/main/java/com/denizk0461/weserplaner/exception/ParcelNotFoundException.kt +++ b/app/src/main/java/com/denizk0461/weserplaner/exception/ParcelNotFoundException.kt @@ -2,4 +2,7 @@ package com.denizk0461.weserplaner.exception import java.io.IOException +/** + * This exception is fired whenever a parcel is not transmitted properly. + */ class ParcelNotFoundException : IOException() \ No newline at end of file diff --git a/app/src/main/java/com/denizk0461/weserplaner/viewmodel/FetcherViewModel.kt b/app/src/main/java/com/denizk0461/weserplaner/viewmodel/FetcherViewModel.kt index d69ade7..a04de18 100644 --- a/app/src/main/java/com/denizk0461/weserplaner/viewmodel/FetcherViewModel.kt +++ b/app/src/main/java/com/denizk0461/weserplaner/viewmodel/FetcherViewModel.kt @@ -2,6 +2,7 @@ package com.denizk0461.weserplaner.viewmodel import android.app.Application import com.denizk0461.weserplaner.data.StudIPParser +import com.denizk0461.weserplaner.exception.NotLoggedInException import java.io.IOException import kotlin.jvm.Throws @@ -20,9 +21,11 @@ class FetcherViewModel(app: Application) : AppViewModel(app) { /** * Fetches and parses the user's Stud.IP schedule. * - * @param html source code of the schedule website + * @param html source code of the schedule website + * @throws NotLoggedInException if the user has not logged in before starting the fetch + * @throws IOException when an error in fetching or the database transaction occurs */ - @Throws(IOException::class) + @Throws(NotLoggedInException::class, IOException::class) fun parse(html: String): Int = returnBlocking { parser.parse(html) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 3a22f6f..039aeb5 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -22,6 +22,7 @@ Ein Fehler ist aufgetreten! Du musst deinen Stundenplan öffnen! + Du musst dich zuerst einloggen! Mensaplan konnte nicht heruntergeladen werden! Ein Angebot aufgrund deiner Präferenzen versteckt. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8bffcc9..11e22c1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -23,6 +23,7 @@ Something went wrong! You must navigate to your schedule! + You must log in first! Couldn\'t retrieve the canteen plan! One offer hidden due to your preferences. diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 41dfb87..8bad7d9 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Sun May 21 09:09:07 CEST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists