Browse Source

moved all cache checking code tho the CacheController

* added new sunday bug fix for the timetable, same as for the mensa
pull/31/head
Jannik 3 years ago
parent
commit
a7abd48726
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
  1. 2
      README.md
  2. 2
      app/build.gradle
  3. 59
      app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt
  4. 100
      app/src/main/java/org/mosad/seil0/projectlaogai/controller/CacheController.kt
  5. 47
      app/src/main/java/org/mosad/seil0/projectlaogai/controller/TCoRAPIController.kt
  6. 4
      app/src/main/java/org/mosad/seil0/projectlaogai/fragments/HomeFragment.kt
  7. 13
      app/src/main/java/org/mosad/seil0/projectlaogai/fragments/TimeTableFragment.kt
  8. 10
      app/src/main/java/org/mosad/seil0/projectlaogai/hsoparser/DataTypes.kt

2
README.md

@ -18,4 +18,4 @@ ProjectLaogai is a app to access the timetable and the mensa menu of Hochschule
[<img src="https://raw.githubusercontent.com/Seil0/Seil0.github.io/master/images/Project_Laogai/ProjectLaogai_Settings.png" width=180>](https://github.com/Seil0/Seil0.github.io/blob/master/images/Project_Laogai/ProjectLaogai_Settings.png)
[<img src="https://raw.githubusercontent.com/Seil0/Seil0.github.io/master/images/Project_Laogai/ProjectLaogai_NavDrawer.png" width=180>](https://github.com/Seil0/Seil0.github.io/blob/master/images/Project_Laogai/ProjectLaogai_NavDrawer.png)
ProjectLaogai © 2019 [@Seil0](https://git.mosad.xyz/Seil0), a mosad [mosad](http://www.mosad.xyz) Project
ProjectLaogai © 2019 [@Seil0](https://git.mosad.xyz/Seil0), a [mosad](http://www.mosad.xyz) Project

2
app/build.gradle

@ -13,7 +13,7 @@ android {
minSdkVersion 23
targetSdkVersion 28
versionCode 14
versionName "0.4.92"
versionName "0.4.93"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "build_time", buildTime()
setProperty("archivesBaseName", "projectlaogai-$versionName")

59
app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt

@ -36,17 +36,10 @@ 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.CacheController
import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.mensaMenu
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.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.TCoRAPIController
import org.mosad.seil0.projectlaogai.fragments.*
import java.util.*
import kotlin.system.measureTimeMillis
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
@ -136,56 +129,8 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
*/
private fun load() {
val startupTime = measureTimeMillis {
// load the settings
PreferencesController.load(this) // this must be finished before doing anything else
val tcor = TCoRAPIController(this)
val currentTime = System.currentTimeMillis() / 1000
val currentDay = Calendar.getInstance().get(Calendar.DAY_OF_WEEK)
val cal = Calendar.getInstance()
// TODO this will backfire if someone has to update before the server finished updating the timetable at 0001/0101
// timetable sunday workaround
cal.time = Date(timetableCacheTime * 1000)
// update blocking if a) it`s monday and the last cache was not on a monday or b) the cache is older than 6 days
if((currentDay == Calendar.MONDAY && cal.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) || currentTime - timetableCacheTime > 518400) {
println("updating timetable after sunday!")
val jobA = TCoRAPIController.getTimetable(cCourse.courseName, 0, this)
val jobB = TCoRAPIController.getTimetable(cCourse.courseName, 1, this)
jobA.get()
jobB.get()
}
// new sunday bug fix
CacheController.readMensa(this)
cal.time = Date(mensaMenu.meta.updateTime * 1000)
// if it's monday and the last cache update was on sunday or is older than 24hr, update blocking
if ((currentDay == Calendar.MONDAY && cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) || currentTime - mensaMenu.meta.updateTime > 86400) {
println("update mensa blocking")
TCoRAPIController.getMensa(this).get()
}
// get the cached files
val cache = CacheController(this)
cache.readStartCache(cCourse.courseName)
// check if an update is necessary
if(currentTime - coursesCacheTime > 86400)
tcor.getCoursesList()
if(currentTime - mensaCacheTime > 10800)
TCoRAPIController.getMensa(this)
if(currentTime - timetableCacheTime > 10800) {
TCoRAPIController.getTimetable(cCourse.courseName, 0, this)
TCoRAPIController.getTimetable(cCourse.courseName, 1, this)
}
PreferencesController.load(this) // load the settings, must be finished before doing anything else
CacheController(this) // load the cache
}
println("startup completed in $startupTime ms")
}

100
app/src/main/java/org/mosad/seil0/projectlaogai/controller/CacheController.kt

@ -26,11 +26,13 @@ import android.content.Context
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonParser
import com.google.gson.reflect.TypeToken
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cCourse
import org.mosad.seil0.projectlaogai.hsoparser.*
import java.io.BufferedReader
import java.io.File
import java.io.FileReader
import com.google.gson.reflect.TypeToken
import org.mosad.seil0.projectlaogai.hsoparser.*
import java.util.*
import kotlin.collections.ArrayList
class CacheController(cont: Context) {
@ -38,13 +40,71 @@ class CacheController(cont: Context) {
private val context = cont
init {
// TODO move cache check here
val cal = Calendar.getInstance()
val currentDay = Calendar.getInstance().get(Calendar.DAY_OF_WEEK)
val currentTime = System.currentTimeMillis() / 1000
// check if we need to update the mensa data before displaying it
readMensa(context)
cal.time = Date(mensaMenu.meta.updateTime * 1000)
// if a) it's monday and the last cache update was on sunday or b) the cache is older than 24hr, update blocking
if ((currentDay == Calendar.MONDAY && cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) || currentTime - mensaMenu.meta.updateTime > 86400) {
println("update mensa blocking")
TCoRAPIController.getMensa(context).get()
}
// check if we need to update the timetables before displaying them
readTimetable(cCourse.courseName, 0, context)
cal.time = Date(timetables[0].meta.updateTime * 1000)
// if a) it`s monday and the last cache update was not on a sunday or b) the cache is older than 5 days, update blocking
if((currentDay == Calendar.MONDAY && cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) || currentTime - timetables[0].meta.updateTime > 432000) {
println("updating timetable after sunday!")
val jobA = TCoRAPIController.getTimetable(cCourse.courseName, 0, context)
val jobB = TCoRAPIController.getTimetable(cCourse.courseName, 1, context)
jobA.get()
jobB.get()
}
// check if an update is necessary, not blocking
if(currentTime - PreferencesController.coursesCacheTime > 86400)
TCoRAPIController.getCoursesList(context)
if(currentTime - PreferencesController.mensaCacheTime > 10800)
TCoRAPIController.getMensa(context)
if(currentTime - PreferencesController.timetableCacheTime > 10800) {
TCoRAPIController.getTimetable(cCourse.courseName, 0, context)
TCoRAPIController.getTimetable(cCourse.courseName, 1, context)
}
readStartCache(cCourse.courseName)
}
companion object {
var coursesList = ArrayList<Course>()
var timetables = ArrayList<TimetableWeek>()
var mensaMenu = MensaMenu(MensaMeta(0, ""), MensaWeek(), MensaWeek())
var timetables = ArrayList<TimetableCourseWeek>()
var mensaMenu = MensaMenu()
/**
* read the courses list from the cached file
* add them to the coursesList object
*/
private fun readCoursesList(context: Context) {
val file = File(context.filesDir, "courses.json")
// make sure the file exists
if (!file.exists())
TCoRAPIController.getCoursesList(context).get()
val fileReader = FileReader(file)
val bufferedReader = BufferedReader(fileReader)
val coursesObject = JsonParser().parse(bufferedReader.readLine()).asJsonObject
coursesList = Gson().fromJson(coursesObject.getAsJsonArray("courses"), object : TypeToken<List<Course>>() {}.type)
}
/**
* get the MensaMenu object from the cached json,
@ -62,7 +122,7 @@ class CacheController(cont: Context) {
val bufferedReader = BufferedReader(fileReader)
val mensaObject = JsonParser().parse(bufferedReader.readLine()).asJsonObject
mensaMenu = GsonBuilder().create().fromJson(mensaObject, MensaMenu(MensaMeta(0, ""), MensaWeek(), MensaWeek()).javaClass)
mensaMenu = GsonBuilder().create().fromJson(mensaObject, MensaMenu().javaClass)
}
/**
@ -82,10 +142,10 @@ class CacheController(cont: Context) {
val timetableObject = JsonParser().parse(bufferedReader.readLine()).asJsonObject
// make sure you add the single weeks in the exact order!
if (timetables.size == week) {
timetables.add(Gson().fromJson(timetableObject.getAsJsonObject("timetable"), TimetableWeek().javaClass))
} else if (timetables.size >= week) {
timetables[week] = Gson().fromJson(timetableObject.getAsJsonObject("timetable"), TimetableWeek().javaClass)
if (timetables.size > week) {
timetables[week] = (Gson().fromJson(timetableObject, TimetableCourseWeek().javaClass))
} else {
timetables.add(Gson().fromJson(timetableObject, TimetableCourseWeek().javaClass))
}
}
}
@ -95,28 +155,10 @@ class CacheController(cont: Context) {
* @param courseName the course name (e.g AI1)
*/
fun readStartCache(courseName: String) {
readCoursesList()
readCoursesList(context)
readMensa(context)
readTimetable(courseName, 0, context)
readTimetable(courseName, 1, context)
}
/**
* read the courses list from the cached file
* add them to the coursesList object
*/
private fun readCoursesList() {
val file = File(context.filesDir, "courses.json")
// make sure the file exists
if (!file.exists())
TCoRAPIController(context).getCoursesList().get()
val fileReader = FileReader(file)
val bufferedReader = BufferedReader(fileReader)
val coursesObject = JsonParser().parse(bufferedReader.readLine()).asJsonObject
coursesList = Gson().fromJson(coursesObject.getAsJsonArray("courses"), object : TypeToken<List<Course>>() {}.type)
}
}

47
app/src/main/java/org/mosad/seil0/projectlaogai/controller/TCoRAPIController.kt

@ -28,13 +28,35 @@ import org.json.JSONObject
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 java.io.*
import java.io.BufferedWriter
import java.io.File
import java.io.FileWriter
import java.net.URL
class TCoRAPIController(cont: Context) {
private val context = cont
class TCoRAPIController {
companion object {
/**
* get the json object from tcor api and write it as file (cache)
*/
fun getCoursesList(context: Context) = doAsync {
val url = URL("https://tcor.mosad.xyz/courseList")
val file = File(context.filesDir, "courses.json")
// read data from the API
val coursesObject = JSONObject(url.readText()) //JSONObject(inReader.readLine())
// write the json object to a file
val writer = BufferedWriter(FileWriter(file))
writer.write(coursesObject.toString())
writer.close()
// update cache time
coursesCacheTime = System.currentTimeMillis() / 1000
PreferencesController.save(context)
}
/**
* get the json object from tcor api and write it as file (cache)
*/
@ -76,23 +98,4 @@ class TCoRAPIController(cont: Context) {
}
}
/**
* get the json object from tcor api and write it as file (cache)
*/
fun getCoursesList() = doAsync {
val url = URL("https://tcor.mosad.xyz/courseList")
val file = File(context.filesDir, "courses.json")
// read data from the API
val coursesObject = JSONObject(url.readText()) //JSONObject(inReader.readLine())
// write the json object to a file
val writer = BufferedWriter(FileWriter(file))
writer.write(coursesObject.toString())
writer.close()
// update cache time
coursesCacheTime = System.currentTimeMillis() / 1000
PreferencesController.save(context)
}
}

4
app/src/main/java/org/mosad/seil0/projectlaogai/fragments/HomeFragment.kt

@ -133,7 +133,7 @@ class HomeFragment : Fragment() {
if (timetables.isNotEmpty() && dayIndex < 6) {
// first check the current day
dayCardView = addDayTimetable(timetables[0].days[dayIndex])
dayCardView = addDayTimetable(timetables[0].timetable.days[dayIndex])
dayCardView.setDayHeading(resources.getString(R.string.today_date, formatter.format(cal.time)))
// if there are no lessons try to find the next day with a lesson
@ -202,7 +202,7 @@ class HomeFragment : Fragment() {
var weekIndexSearch = startWeekIndex
loop@ while (dayTimetable == null && weekIndexSearch <= timetables.size) {
for (i in (dayIndexSearch) ..5) {
dayTimetable = timetables[weekIndexSearch].days[i]
dayTimetable = timetables[weekIndexSearch].timetable.days[i]
cal.add(Calendar.DATE, 1)
// add the timetable to the card, if it contains at least one lesson break!

13
app/src/main/java/org/mosad/seil0/projectlaogai/fragments/TimeTableFragment.kt

@ -41,7 +41,8 @@ import org.mosad.seil0.projectlaogai.controller.TCoRAPIController
import org.mosad.seil0.projectlaogai.hsoparser.DataTypes
import org.mosad.seil0.projectlaogai.hsoparser.NotRetardedCalendar
import org.mosad.seil0.projectlaogai.hsoparser.TimetableWeek
import org.mosad.seil0.projectlaogai.uicomponents.*
import org.mosad.seil0.projectlaogai.uicomponents.DayCardView
import org.mosad.seil0.projectlaogai.uicomponents.LessonLinearLayout
import java.text.SimpleDateFormat
import java.util.*
@ -64,7 +65,7 @@ class TimeTableFragment : Fragment() {
// init actions
initActions()
if (timetables[0].days.isNotEmpty() && timetables[1].days.isNotEmpty()) {
if (timetables[0].timetable.days.isNotEmpty() && timetables[1].timetable.days.isNotEmpty()) {
addInitWeeks()
} else {
MaterialDialog(context!!)
@ -114,10 +115,10 @@ class TimeTableFragment : Fragment() {
val calendar = Calendar.getInstance()
// add current week
addWeek(dayIndex, 5, timetables[0], calendar).get()
addWeek(dayIndex, 5, timetables[0].timetable, calendar).get()
// add next week
addWeek(0, dayIndex - 1, timetables[1], calendar)
addWeek(0, dayIndex - 1, timetables[1].timetable, calendar)
}
private fun addWeek(dayStart: Int, dayEnd: Int, timetable: TimetableWeek, calendar: Calendar) = doAsync {
@ -177,10 +178,10 @@ class TimeTableFragment : Fragment() {
val calendar = Calendar.getInstance()
// add current week
addWeek(dayIndex, 5, timetables[0], calendar).get()
addWeek(dayIndex, 5, timetables[0].timetable, calendar).get()
// add next week
addWeek(0, dayIndex - 1, timetables[1], calendar)
addWeek(0, dayIndex - 1, timetables[1].timetable, calendar)
refreshLayout_Timetable.isRefreshing = false
}

10
app/src/main/java/org/mosad/seil0/projectlaogai/hsoparser/DataTypes.kt

@ -122,9 +122,9 @@ data class Meals(val meals: ArrayList<Meal>)
data class MensaWeek(val days: Array<Meals> = Array(7) { Meals(ArrayList()) })
data class MensaMeta(val updateTime: Long, val mensaName: String)
data class MensaMeta(val updateTime: Long = 0, val mensaName: String = "")
data class MensaMenu(val meta: MensaMeta, val currentWeek: MensaWeek, val nextWeek: MensaWeek)
data class MensaMenu(val meta: MensaMeta = MensaMeta(), val currentWeek: MensaWeek = MensaWeek(), val nextWeek: MensaWeek = MensaWeek())
// data classes for the timetable part
data class Lesson(
@ -136,4 +136,8 @@ data class Lesson(
data class TimetableDay(val timeslots: Array<ArrayList<Lesson>> = Array(6) { ArrayList<Lesson>() })
data class TimetableWeek(val days: Array<TimetableDay> = Array(6) { TimetableDay() })
data class TimetableWeek(val days: Array<TimetableDay> = Array(6) { TimetableDay() })
data class TimetableCourseMeta(var updateTime: Long = 0, val courseName: String = "", val week: Int = 0, val link: String = "")
data class TimetableCourseWeek(val meta: TimetableCourseMeta = TimetableCourseMeta(), var timetable: TimetableWeek = TimetableWeek())

Loading…
Cancel
Save

Du besuchst diese Seite mit einem veralteten IPv4-Internetzugang. Möglicherweise treten in Zukunft Probleme mit der Erreichbarkeit und Performance auf. Bitte frage deinen Internetanbieter oder Netzwerkadministrator nach IPv6-Unterstützung.
You are visiting this site with an outdated IPv4 internet access. You may experience problems with accessibility and performance in the future. Please ask your ISP or network administrator for IPv6 support.
Weitere Infos | More Information
Klicke zum schließen | Click to close