diff --git a/README.md b/README.md index 81ec1fb..347da9a 100644 --- a/README.md +++ b/README.md @@ -18,4 +18,4 @@ ProjectLaogai is a app to access the timetable and the mensa menu of Hochschule [](https://github.com/Seil0/Seil0.github.io/blob/master/images/Project_Laogai/ProjectLaogai_Settings.png) [](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 diff --git a/app/build.gradle b/app/build.gradle index 20e235b..176bfe2 100644 --- a/app/build.gradle +++ b/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") diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt index 705b001..09ab1f6 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/MainActivity.kt +++ b/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") } diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/CacheController.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/CacheController.kt index 109e8a4..2ad9e80 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/CacheController.kt +++ b/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() - var timetables = ArrayList() - var mensaMenu = MensaMenu(MensaMeta(0, ""), MensaWeek(), MensaWeek()) + var timetables = ArrayList() + 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>() {}.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>() {}.type) - } - } \ No newline at end of file diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/TCoRAPIController.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/TCoRAPIController.kt index 8c22ec9..03a05dd 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/TCoRAPIController.kt +++ b/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) - } } \ No newline at end of file diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/HomeFragment.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/HomeFragment.kt index 68ad76f..8ab28d4 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/HomeFragment.kt +++ b/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! diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/TimeTableFragment.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/TimeTableFragment.kt index 4b55335..41de6c2 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/TimeTableFragment.kt +++ b/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 } diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/hsoparser/DataTypes.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/hsoparser/DataTypes.kt index 9c279c7..24ff111 100644 --- a/app/src/main/java/org/mosad/seil0/projectlaogai/hsoparser/DataTypes.kt +++ b/app/src/main/java/org/mosad/seil0/projectlaogai/hsoparser/DataTypes.kt @@ -122,9 +122,9 @@ data class Meals(val meals: ArrayList) data class MensaWeek(val days: Array = 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> = Array(6) { ArrayList() }) -data class TimetableWeek(val days: Array = Array(6) { TimetableDay() }) \ No newline at end of file +data class TimetableWeek(val days: Array = 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())