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