mirror of
https://github.com/Matte23/circolapp.git
synced 2025-12-06 07:29:10 +00:00
Add base code for multiple server (schools) support
This commit is contained in:
@@ -2,20 +2,23 @@ package net.underdesk.circolapp.data
|
|||||||
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import net.underdesk.circolapp.server.DataFetcher
|
import net.underdesk.circolapp.server.ServerAPI
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
class CircularRepository(
|
class CircularRepository(
|
||||||
val circularDao: CircularDao,
|
val circularDao: CircularDao,
|
||||||
private val fetcher: DataFetcher = DataFetcher()
|
private val serverAPI: ServerAPI
|
||||||
) {
|
) {
|
||||||
suspend fun updateCirculars(returnNewCirculars: Boolean = true): Pair<List<Circular>, Boolean> {
|
suspend fun updateCirculars(returnNewCirculars: Boolean = true): Pair<List<Circular>, Boolean> {
|
||||||
var onlyNewCirculars = listOf<Circular>()
|
var onlyNewCirculars = listOf<Circular>()
|
||||||
|
|
||||||
try {
|
return withContext(Dispatchers.IO) {
|
||||||
withContext(Dispatchers.IO) {
|
val result = serverAPI.getCircularsFromServer()
|
||||||
|
if (result.second == ServerAPI.Companion.Result.ERROR)
|
||||||
|
return@withContext Pair(emptyList(), false)
|
||||||
|
|
||||||
val oldCirculars = circularDao.getCirculars()
|
val oldCirculars = circularDao.getCirculars()
|
||||||
val newCirculars = fetcher.getCircularsFromServer()
|
val newCirculars = result.first
|
||||||
|
|
||||||
if (newCirculars.size != oldCirculars.size) {
|
if (newCirculars.size != oldCirculars.size) {
|
||||||
if (newCirculars.size < oldCirculars.size) {
|
if (newCirculars.size < oldCirculars.size) {
|
||||||
circularDao.deleteAll()
|
circularDao.deleteAll()
|
||||||
@@ -31,21 +34,17 @@ class CircularRepository(
|
|||||||
|
|
||||||
circularDao.insertAll(newCirculars)
|
circularDao.insertAll(newCirculars)
|
||||||
}
|
}
|
||||||
|
Pair(onlyNewCirculars, true)
|
||||||
}
|
}
|
||||||
} catch (exception: IOException) {
|
|
||||||
return Pair(onlyNewCirculars, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
return Pair(onlyNewCirculars, true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Volatile
|
@Volatile
|
||||||
private var instance: CircularRepository? = null
|
private var instance: CircularRepository? = null
|
||||||
|
|
||||||
fun getInstance(circularDao: CircularDao) =
|
fun getInstance(circularDao: CircularDao, serverAPI: ServerAPI) =
|
||||||
instance ?: synchronized(this) {
|
instance ?: synchronized(this) {
|
||||||
instance ?: CircularRepository(circularDao).also { instance = it }
|
instance ?: CircularRepository(circularDao, serverAPI).also { instance = it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import net.underdesk.circolapp.R
|
|||||||
import net.underdesk.circolapp.adapters.CircularLetterAdapter
|
import net.underdesk.circolapp.adapters.CircularLetterAdapter
|
||||||
import net.underdesk.circolapp.data.AppDatabase
|
import net.underdesk.circolapp.data.AppDatabase
|
||||||
import net.underdesk.circolapp.data.CircularRepository
|
import net.underdesk.circolapp.data.CircularRepository
|
||||||
|
import net.underdesk.circolapp.server.ServerAPI
|
||||||
import net.underdesk.circolapp.viewmodels.CircularLetterViewModel
|
import net.underdesk.circolapp.viewmodels.CircularLetterViewModel
|
||||||
import net.underdesk.circolapp.viewmodels.CircularLetterViewModelFactory
|
import net.underdesk.circolapp.viewmodels.CircularLetterViewModelFactory
|
||||||
|
|
||||||
@@ -45,7 +46,8 @@ class CircularLetterFragment :
|
|||||||
private val circularLetterViewModel: CircularLetterViewModel by viewModels {
|
private val circularLetterViewModel: CircularLetterViewModel by viewModels {
|
||||||
CircularLetterViewModelFactory(
|
CircularLetterViewModelFactory(
|
||||||
CircularRepository.getInstance(
|
CircularRepository.getInstance(
|
||||||
AppDatabase.getInstance(requireContext()).circularDao()
|
AppDatabase.getInstance(requireContext()).circularDao(),
|
||||||
|
ServerAPI.getInstance(ServerAPI.Companion.Servers.CURIE)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import net.underdesk.circolapp.R
|
|||||||
import net.underdesk.circolapp.adapters.CircularLetterAdapter
|
import net.underdesk.circolapp.adapters.CircularLetterAdapter
|
||||||
import net.underdesk.circolapp.data.AppDatabase
|
import net.underdesk.circolapp.data.AppDatabase
|
||||||
import net.underdesk.circolapp.data.CircularRepository
|
import net.underdesk.circolapp.data.CircularRepository
|
||||||
|
import net.underdesk.circolapp.server.ServerAPI
|
||||||
import net.underdesk.circolapp.viewmodels.FavouritesViewModel
|
import net.underdesk.circolapp.viewmodels.FavouritesViewModel
|
||||||
import net.underdesk.circolapp.viewmodels.FavouritesViewModelFactory
|
import net.underdesk.circolapp.viewmodels.FavouritesViewModelFactory
|
||||||
|
|
||||||
@@ -39,7 +40,8 @@ class FavouritesFragment : Fragment(), MainActivity.SearchCallback {
|
|||||||
private val favouritesViewModel: FavouritesViewModel by viewModels {
|
private val favouritesViewModel: FavouritesViewModel by viewModels {
|
||||||
FavouritesViewModelFactory(
|
FavouritesViewModelFactory(
|
||||||
CircularRepository.getInstance(
|
CircularRepository.getInstance(
|
||||||
AppDatabase.getInstance(requireContext()).circularDao()
|
AppDatabase.getInstance(requireContext()).circularDao(),
|
||||||
|
ServerAPI.getInstance(ServerAPI.Companion.Servers.CURIE)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import net.underdesk.circolapp.R
|
|||||||
import net.underdesk.circolapp.adapters.CircularLetterAdapter
|
import net.underdesk.circolapp.adapters.CircularLetterAdapter
|
||||||
import net.underdesk.circolapp.data.AppDatabase
|
import net.underdesk.circolapp.data.AppDatabase
|
||||||
import net.underdesk.circolapp.data.CircularRepository
|
import net.underdesk.circolapp.data.CircularRepository
|
||||||
|
import net.underdesk.circolapp.server.ServerAPI
|
||||||
import net.underdesk.circolapp.viewmodels.RemindersViewModel
|
import net.underdesk.circolapp.viewmodels.RemindersViewModel
|
||||||
import net.underdesk.circolapp.viewmodels.RemindersViewModelFactory
|
import net.underdesk.circolapp.viewmodels.RemindersViewModelFactory
|
||||||
|
|
||||||
@@ -39,7 +40,8 @@ class RemindersFragment : Fragment(), MainActivity.SearchCallback {
|
|||||||
private val remindersViewModel: RemindersViewModel by viewModels {
|
private val remindersViewModel: RemindersViewModel by viewModels {
|
||||||
RemindersViewModelFactory(
|
RemindersViewModelFactory(
|
||||||
CircularRepository.getInstance(
|
CircularRepository.getInstance(
|
||||||
AppDatabase.getInstance(requireContext()).circularDao()
|
AppDatabase.getInstance(requireContext()).circularDao(),
|
||||||
|
ServerAPI.getInstance(ServerAPI.Companion.Servers.CURIE)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* Circolapp
|
|
||||||
* Copyright (C) 2019-2020 Matteo Schiff
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.underdesk.circolapp.server
|
|
||||||
|
|
||||||
import com.squareup.moshi.Moshi
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import net.underdesk.circolapp.data.Circular
|
|
||||||
import net.underdesk.circolapp.server.pojo.Response
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.Request
|
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
class DataFetcher {
|
|
||||||
companion object {
|
|
||||||
const val ENDPOINT_URL = "https://www.curiepinerolo.edu.it/wp-json/wp/v2/pages/5958"
|
|
||||||
|
|
||||||
private val moshi = Moshi.Builder().build()
|
|
||||||
private val responseAdapter = moshi.adapter(Response::class.java)
|
|
||||||
private val client = OkHttpClient()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(IOException::class)
|
|
||||||
suspend fun getCircularsFromServer(): List<Circular> {
|
|
||||||
return withContext(Dispatchers.Default) {
|
|
||||||
val json = retrieveDataFromServer()
|
|
||||||
|
|
||||||
val document = Jsoup.parseBodyFragment(json.content.rendered)
|
|
||||||
val htmlList = document.getElementsByTag("ul")[0].getElementsByTag("a")
|
|
||||||
|
|
||||||
val list = ArrayList<Circular>()
|
|
||||||
|
|
||||||
htmlList.forEach { element ->
|
|
||||||
if (element.parents().size == 6) {
|
|
||||||
list.last().attachmentsNames.add(element.text())
|
|
||||||
list.last().attachmentsUrls.add(element.attr("href"))
|
|
||||||
} else if (element.parents().size == 4) {
|
|
||||||
list.add(Circular.generateFromString(element.text(), element.attr("href")))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
list
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(IOException::class)
|
|
||||||
private suspend fun retrieveDataFromServer(): Response {
|
|
||||||
val request = Request.Builder()
|
|
||||||
.url(ENDPOINT_URL)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
return withContext(Dispatchers.IO) {
|
|
||||||
val response = client.newCall(request).execute()
|
|
||||||
|
|
||||||
if (!response.isSuccessful) {
|
|
||||||
throw IOException("HTTP error code: ${response.code})")
|
|
||||||
}
|
|
||||||
|
|
||||||
responseAdapter.fromJson(
|
|
||||||
response.body!!.string()
|
|
||||||
)!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
26
app/src/main/java/net/underdesk/circolapp/server/Server.kt
Normal file
26
app/src/main/java/net/underdesk/circolapp/server/Server.kt
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Circolapp
|
||||||
|
* Copyright (C) 2019-2020 Matteo Schiff
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.underdesk.circolapp.server
|
||||||
|
|
||||||
|
import net.underdesk.circolapp.data.Circular
|
||||||
|
|
||||||
|
abstract class Server {
|
||||||
|
abstract suspend fun getCircularsFromServer(): Pair<List<Circular>, ServerAPI.Companion.Result>
|
||||||
|
abstract suspend fun newCircularsAvailable(): Pair<Boolean, ServerAPI.Companion.Result>
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Circolapp
|
||||||
|
* Copyright (C) 2019-2020 Matteo Schiff
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.underdesk.circolapp.server
|
||||||
|
|
||||||
|
import net.underdesk.circolapp.data.Circular
|
||||||
|
import net.underdesk.circolapp.server.curie.CurieServer
|
||||||
|
|
||||||
|
class ServerAPI(
|
||||||
|
private val server: Server
|
||||||
|
) {
|
||||||
|
suspend fun getCircularsFromServer(): Pair<List<Circular>, Result> {
|
||||||
|
val newCircularsAvailable = server.newCircularsAvailable()
|
||||||
|
|
||||||
|
if (newCircularsAvailable.second == Result.ERROR)
|
||||||
|
return Pair(emptyList(), Result.ERROR)
|
||||||
|
|
||||||
|
if (!newCircularsAvailable.first)
|
||||||
|
return Pair(emptyList(), Result.SUCCESS)
|
||||||
|
|
||||||
|
return server.getCircularsFromServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
enum class Servers {
|
||||||
|
CURIE, PORPORATO
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class Result {
|
||||||
|
SUCCESS, ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var instance: ServerAPI? = null
|
||||||
|
|
||||||
|
fun getInstance(server: Servers): ServerAPI {
|
||||||
|
return instance ?: synchronized(this) {
|
||||||
|
instance ?: createServerAPI(server).also { instance = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createServerAPI(server: Servers): ServerAPI {
|
||||||
|
return when (server) {
|
||||||
|
Servers.CURIE -> ServerAPI(CurieServer())
|
||||||
|
Servers.PORPORATO -> TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package net.underdesk.circolapp.server.curie
|
||||||
|
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import net.underdesk.circolapp.data.Circular
|
||||||
|
import net.underdesk.circolapp.server.Server
|
||||||
|
import net.underdesk.circolapp.server.ServerAPI
|
||||||
|
import net.underdesk.circolapp.server.curie.pojo.Response
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
class CurieServer : Server() {
|
||||||
|
private val moshi = Moshi.Builder().build()
|
||||||
|
private val responseAdapter = moshi.adapter(Response::class.java)
|
||||||
|
private val client = OkHttpClient()
|
||||||
|
|
||||||
|
override suspend fun getCircularsFromServer(): Pair<List<Circular>, ServerAPI.Companion.Result> {
|
||||||
|
return try {
|
||||||
|
withContext(Dispatchers.Default) {
|
||||||
|
val json = retrieveDataFromServer()
|
||||||
|
|
||||||
|
val document = Jsoup.parseBodyFragment(json.content.rendered)
|
||||||
|
val htmlList = document.getElementsByTag("ul")[0].getElementsByTag("a")
|
||||||
|
|
||||||
|
val list = ArrayList<Circular>()
|
||||||
|
|
||||||
|
htmlList.forEach { element ->
|
||||||
|
if (element.parents().size == 6) {
|
||||||
|
list.last().attachmentsNames.add(element.text())
|
||||||
|
list.last().attachmentsUrls.add(element.attr("href"))
|
||||||
|
} else if (element.parents().size == 4) {
|
||||||
|
list.add(Circular.generateFromString(element.text(), element.attr("href")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Pair(list, ServerAPI.Companion.Result.SUCCESS)
|
||||||
|
}
|
||||||
|
} catch (exception: IOException) {
|
||||||
|
Pair(emptyList(), ServerAPI.Companion.Result.ERROR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun newCircularsAvailable(): Pair<Boolean, ServerAPI.Companion.Result> {
|
||||||
|
return Pair(true, ServerAPI.Companion.Result.SUCCESS)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
private suspend fun retrieveDataFromServer(): Response {
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url(ENDPOINT_URL)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
return withContext(Dispatchers.IO) {
|
||||||
|
val response = client.newCall(request).execute()
|
||||||
|
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
throw IOException("HTTP error code: ${response.code})")
|
||||||
|
}
|
||||||
|
|
||||||
|
responseAdapter.fromJson(
|
||||||
|
response.body!!.string()
|
||||||
|
)!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val ENDPOINT_URL = "https://www.curiepinerolo.edu.it/wp-json/wp/v2/pages/5958"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.underdesk.circolapp.server.pojo
|
package net.underdesk.circolapp.server.curie.pojo
|
||||||
|
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.underdesk.circolapp.server.pojo
|
package net.underdesk.circolapp.server.curie.pojo
|
||||||
|
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
@@ -36,6 +36,7 @@ import net.underdesk.circolapp.R
|
|||||||
import net.underdesk.circolapp.data.AppDatabase
|
import net.underdesk.circolapp.data.AppDatabase
|
||||||
import net.underdesk.circolapp.data.Circular
|
import net.underdesk.circolapp.data.Circular
|
||||||
import net.underdesk.circolapp.data.CircularRepository
|
import net.underdesk.circolapp.data.CircularRepository
|
||||||
|
import net.underdesk.circolapp.server.ServerAPI
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class PollWork(appContext: Context, workerParams: WorkerParameters) :
|
class PollWork(appContext: Context, workerParams: WorkerParameters) :
|
||||||
@@ -85,7 +86,8 @@ class PollWork(appContext: Context, workerParams: WorkerParameters) :
|
|||||||
|
|
||||||
override suspend fun doWork(): Result = coroutineScope {
|
override suspend fun doWork(): Result = coroutineScope {
|
||||||
val circularRepository = CircularRepository.getInstance(
|
val circularRepository = CircularRepository.getInstance(
|
||||||
AppDatabase.getInstance(applicationContext).circularDao()
|
AppDatabase.getInstance(applicationContext).circularDao(),
|
||||||
|
ServerAPI.getInstance(ServerAPI.Companion.Servers.CURIE)
|
||||||
)
|
)
|
||||||
|
|
||||||
val result = circularRepository.updateCirculars()
|
val result = circularRepository.updateCirculars()
|
||||||
|
|||||||
Reference in New Issue
Block a user