Archived
Added measures to make sure the user logs into their schedule before fetching can commence
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package com.denizk0461.weserplaner.exception
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
class InvalidContentIdException : IOException()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
<string name="fetch_error_snack">Ein Fehler ist aufgetreten!</string>
|
||||
<string name="fetch_error_webpage_snack">Du musst deinen Stundenplan öffnen!</string>
|
||||
<string name="fetch_error_login_snack">Du musst dich zuerst einloggen!</string>
|
||||
<string name="canteen_fetch_error">Mensaplan konnte nicht heruntergeladen werden!</string>
|
||||
|
||||
<string name="canteen_item_difference_text_one">Ein Angebot aufgrund deiner Präferenzen versteckt.</string>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
<string name="fetch_error_snack">Something went wrong!</string>
|
||||
<string name="fetch_error_webpage_snack">You must navigate to your schedule!</string>
|
||||
<string name="fetch_error_login_snack">You must log in first!</string>
|
||||
<string name="canteen_fetch_error">Couldn\'t retrieve the canteen plan!</string>
|
||||
|
||||
<string name="canteen_item_difference_text_one">One offer hidden due to your preferences.</string>
|
||||
|
||||
Reference in New Issue
Block a user