2023-04-16 18:19:06 +02:00
|
|
|
package com.denizk0461.studip.data
|
|
|
|
|
|
2023-04-17 14:19:06 +02:00
|
|
|
import com.denizk0461.studip.db.EventRepository
|
|
|
|
|
import com.denizk0461.studip.model.*
|
2023-04-16 18:19:06 +02:00
|
|
|
import org.jsoup.Jsoup
|
|
|
|
|
import org.jsoup.nodes.Element
|
|
|
|
|
import org.jsoup.select.Elements
|
|
|
|
|
|
|
|
|
|
// Parser class for the Studierendenwerk cafeteria plans
|
|
|
|
|
class StwParser {
|
|
|
|
|
|
2023-04-17 14:19:06 +02:00
|
|
|
private var dateId = 0
|
|
|
|
|
private var canteenId = 0
|
|
|
|
|
private var categoryId = 0
|
|
|
|
|
private var itemId = 0
|
2023-04-16 18:19:06 +02:00
|
|
|
|
|
|
|
|
fun parse(onFinish: () -> Unit) {
|
2023-04-17 14:19:06 +02:00
|
|
|
dateId = 0
|
|
|
|
|
canteenId = 0
|
|
|
|
|
categoryId = 0
|
|
|
|
|
itemId = 0
|
2023-04-16 18:19:06 +02:00
|
|
|
val links = mutableListOf<String>()
|
|
|
|
|
if (true) { links.add(urlUniMensa) }
|
|
|
|
|
// if (true) { links.add(urlCafeCentral) }
|
|
|
|
|
// if (true) { links.add(urlNW1) }
|
|
|
|
|
// if (true) { links.add(urlGW2) }
|
|
|
|
|
// if (true) { links.add(urlHSBNeustadt) }
|
|
|
|
|
// if (true) { links.add(urlHSBAirport) }
|
|
|
|
|
// if (true) { links.add(urlHSBWerder) }
|
|
|
|
|
// if (true) { links.add(urlHfK) }
|
|
|
|
|
// if (true) { links.add(urlMensaBHV) }
|
|
|
|
|
// if (true) { links.add(urlCafeBHV) }
|
|
|
|
|
|
|
|
|
|
Dependencies.repo.nukeOffers()
|
|
|
|
|
|
2023-04-17 14:19:06 +02:00
|
|
|
// STEP: fetch every canteen
|
2023-04-16 18:19:06 +02:00
|
|
|
links.forEach { link ->
|
2023-04-17 14:19:06 +02:00
|
|
|
parseFromPage(link, Dependencies.repo)
|
2023-04-16 18:19:06 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-17 14:19:06 +02:00
|
|
|
private fun parseFromPage(url: String, repo: EventRepository): List<CanteenOffer> {
|
2023-04-16 18:19:06 +02:00
|
|
|
val items = mutableListOf<CanteenOffer>()
|
2023-04-16 21:41:46 +02:00
|
|
|
var date: String
|
2023-04-17 14:19:06 +02:00
|
|
|
|
|
|
|
|
dateId = 0
|
2023-04-16 18:19:06 +02:00
|
|
|
|
|
|
|
|
val doc = Jsoup.connect(url).get()
|
2023-04-17 14:19:06 +02:00
|
|
|
|
|
|
|
|
repo.insert(OfferCanteen(canteenId, "TEMP")) // TODO canteen name
|
|
|
|
|
|
|
|
|
|
// STEP: get each day
|
2023-04-16 18:19:06 +02:00
|
|
|
doc.getElementsByClass("food-plan").forEach { dayPlan ->
|
|
|
|
|
|
|
|
|
|
val rawDate = doc.getElementsByClass("tabs")[0]
|
2023-04-17 14:19:06 +02:00
|
|
|
.getElementsByClass("tab-date")[dateId].text().split(" ")
|
2023-04-16 18:19:06 +02:00
|
|
|
|
|
|
|
|
date = "${rawDate[0]}${rawDate[1].monthToNumber()}."
|
|
|
|
|
|
2023-04-17 14:19:06 +02:00
|
|
|
repo.insert(OfferDate(dateId, date))
|
|
|
|
|
|
|
|
|
|
// STEP: get each category in a day
|
2023-04-16 18:19:06 +02:00
|
|
|
dayPlan.getElementsByClass("food-category").forEach { category ->
|
|
|
|
|
val categoryTitle = category.getElementsByClass("category-name")[0].text()
|
2023-04-17 14:19:06 +02:00
|
|
|
|
|
|
|
|
repo.insert(OfferCategory(categoryId, dateId, canteenId, categoryTitle))
|
|
|
|
|
|
|
|
|
|
// STEP: get each item in a category
|
2023-04-16 18:19:06 +02:00
|
|
|
category
|
|
|
|
|
.getElementsByTag("tbody")[0]
|
|
|
|
|
.getElementsByTag("tr").forEach { element ->
|
|
|
|
|
val tableRows = element.getElementsByTag("td")
|
|
|
|
|
|
|
|
|
|
val prefs =
|
|
|
|
|
element.getElementsByClass("field field-name-field-food-types")[0]
|
|
|
|
|
|
2023-04-17 14:19:06 +02:00
|
|
|
repo.insert(
|
|
|
|
|
OfferItem(
|
|
|
|
|
itemId,
|
|
|
|
|
categoryId,
|
|
|
|
|
title = tableRows[1].getFilteredText(),
|
|
|
|
|
price = tableRows.getTextOrEmpty(2),
|
|
|
|
|
isFair = prefs.isDietaryPreferenceMet(PREFERENCE_FAIR),
|
|
|
|
|
isFish = prefs.isDietaryPreferenceMet(PREFERENCE_FISH),
|
|
|
|
|
isPoultry = prefs.isDietaryPreferenceMet(PREFERENCE_POULTRY),
|
|
|
|
|
isLamb = prefs.isDietaryPreferenceMet(PREFERENCE_LAMB),
|
|
|
|
|
isVital = prefs.isDietaryPreferenceMet(PREFERENCE_VITAL),
|
|
|
|
|
isBeef = prefs.isDietaryPreferenceMet(PREFERENCE_BEEF),
|
|
|
|
|
isPork = prefs.isDietaryPreferenceMet(PREFERENCE_PORK),
|
|
|
|
|
isVegan = prefs.isDietaryPreferenceMet(PREFERENCE_VEGAN),
|
|
|
|
|
isVegetarian = prefs.isDietaryPreferenceMet(PREFERENCE_VEGETARIAN),
|
|
|
|
|
isGame = prefs.isDietaryPreferenceMet(PREFERENCE_GAME),
|
|
|
|
|
)
|
2023-04-16 18:19:06 +02:00
|
|
|
)
|
2023-04-17 14:19:06 +02:00
|
|
|
itemId += 1
|
|
|
|
|
|
|
|
|
|
// val newItem = CanteenOffer(
|
|
|
|
|
// id = id,
|
|
|
|
|
// date = date,
|
|
|
|
|
// dateId = day,
|
|
|
|
|
// category = categoryTitle,
|
|
|
|
|
// title = tableRows[1].getFilteredText(),
|
|
|
|
|
//// price = tableRows.getTextOrEmpty(2),
|
|
|
|
|
// isFair = prefs.isDietaryPreferenceMet(PREFERENCE_FAIR),
|
|
|
|
|
// isFish = prefs.isDietaryPreferenceMet(PREFERENCE_FISH),
|
|
|
|
|
// isPoultry = prefs.isDietaryPreferenceMet(PREFERENCE_POULTRY),
|
|
|
|
|
// isLamb = prefs.isDietaryPreferenceMet(PREFERENCE_LAMB),
|
|
|
|
|
// isVital = prefs.isDietaryPreferenceMet(PREFERENCE_VITAL),
|
|
|
|
|
// isBeef = prefs.isDietaryPreferenceMet(PREFERENCE_BEEF),
|
|
|
|
|
// isPork = prefs.isDietaryPreferenceMet(PREFERENCE_PORK),
|
|
|
|
|
// isVegan = prefs.isDietaryPreferenceMet(PREFERENCE_VEGAN),
|
|
|
|
|
// isVegetarian = prefs.isDietaryPreferenceMet(PREFERENCE_VEGETARIAN),
|
|
|
|
|
// isGame = prefs.isDietaryPreferenceMet(PREFERENCE_GAME),
|
|
|
|
|
// )
|
2023-04-16 18:19:06 +02:00
|
|
|
}
|
2023-04-17 14:19:06 +02:00
|
|
|
categoryId += 1
|
2023-04-16 18:19:06 +02:00
|
|
|
}
|
2023-04-17 14:19:06 +02:00
|
|
|
dateId += 1
|
2023-04-16 18:19:06 +02:00
|
|
|
}
|
2023-04-17 14:19:06 +02:00
|
|
|
canteenId += 1
|
2023-04-16 18:19:06 +02:00
|
|
|
|
|
|
|
|
return items
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun Element.isDietaryPreferenceMet(preference: String): Boolean =
|
|
|
|
|
getElementsByAttributeValue("src", preference).isNotEmpty()
|
|
|
|
|
|
|
|
|
|
private fun Element.getFilteredText(): String {
|
2023-04-16 21:41:46 +02:00
|
|
|
var text = html().replace("&", "&")
|
2023-04-16 18:19:06 +02:00
|
|
|
|
|
|
|
|
while (text.contains("<sup>")) {
|
|
|
|
|
text = text.substring(0 until text.indexOf("<sup>")) + text.substring(text.indexOf("</sup>")+6 until text.length)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return text
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun Elements.getTextOrEmpty(index: Int): String = try {
|
|
|
|
|
get(index).text()
|
|
|
|
|
} catch (e: java.lang.IndexOutOfBoundsException) {
|
|
|
|
|
""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun String.monthToNumber(): String = when (this) {
|
|
|
|
|
"Jan" -> "01"
|
|
|
|
|
"Feb" -> "02"
|
|
|
|
|
"Mar" -> "03"
|
|
|
|
|
"Apr" -> "04"
|
|
|
|
|
"Mai" -> "05"
|
|
|
|
|
"Jun" -> "06"
|
|
|
|
|
"Jul" -> "07"
|
|
|
|
|
"Aug" -> "08"
|
|
|
|
|
"Sep" -> "09"
|
|
|
|
|
"Okt" -> "10"
|
|
|
|
|
"Nov" -> "11"
|
|
|
|
|
"Dez" -> "12"
|
|
|
|
|
else -> "00" // shouldn't occur
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private val PREFERENCE_FAIR = "https://www.stw-bremen.de/sites/default/files/images/pictograms/at_small.png"
|
|
|
|
|
private val PREFERENCE_FISH = "https://www.stw-bremen.de/sites/default/files/images/pictograms/fisch.png"
|
|
|
|
|
private val PREFERENCE_POULTRY = "https://www.stw-bremen.de/sites/default/files/images/pictograms/geflugel.png"
|
|
|
|
|
private val PREFERENCE_LAMB = "https://www.stw-bremen.de/sites/default/files/images/pictograms/lamm.png"
|
|
|
|
|
private val PREFERENCE_VITAL = "https://www.stw-bremen.de/sites/default/files/images/pictograms/mensa_vital.png"
|
|
|
|
|
private val PREFERENCE_BEEF = "https://www.stw-bremen.de/sites/default/files/images/pictograms/rindfleisch.png"
|
|
|
|
|
private val PREFERENCE_PORK = "https://www.stw-bremen.de/sites/default/files/images/pictograms/schwein.png"
|
|
|
|
|
private val PREFERENCE_VEGAN = "https://www.stw-bremen.de/sites/default/files/images/pictograms/mensa_vegan.png"
|
|
|
|
|
private val PREFERENCE_VEGETARIAN = "https://www.stw-bremen.de/sites/default/files/images/pictograms/vegetarisch.png"
|
|
|
|
|
private val PREFERENCE_GAME = "https://www.stw-bremen.de/sites/default/files/images/pictograms/wild.png"
|
|
|
|
|
|
|
|
|
|
private val urlUniMensa = "https://www.stw-bremen.de/de/mensa/uni-mensa"
|
|
|
|
|
private val urlCafeCentral = "https://www.stw-bremen.de/de/mensa/cafe-central"
|
|
|
|
|
private val urlNW1 = "https://www.stw-bremen.de/de/mensa/nw-1"
|
|
|
|
|
private val urlGW2 = "https://www.stw-bremen.de/de/cafeteria/gw2"
|
|
|
|
|
// private val urlGraz = ""
|
|
|
|
|
private val urlHSBNeustadt = "https://www.stw-bremen.de/de/mensa/neustadtswall"
|
|
|
|
|
private val urlHSBWerder = "https://www.stw-bremen.de/de/mensa/werderstra%C3%9Fe"
|
|
|
|
|
private val urlHSBAirport = "https://www.stw-bremen.de/de/mensa/airport"
|
|
|
|
|
private val urlHfK = "https://www.stw-bremen.de/de/mensa/interimsmensa-hfk"
|
|
|
|
|
private val urlMensaBHV = "https://www.stw-bremen.de/de/mensa/bremerhaven"
|
|
|
|
|
private val urlCafeBHV = "https://www.stw-bremen.de/de/cafeteria/bremerhaven"
|
|
|
|
|
}
|