diff --git a/app/src/main/java/net/underdesk/circolapp/data/Circular.kt b/app/src/main/java/net/underdesk/circolapp/data/Circular.kt index 511c633..44cce8e 100644 --- a/app/src/main/java/net/underdesk/circolapp/data/Circular.kt +++ b/app/src/main/java/net/underdesk/circolapp/data/Circular.kt @@ -22,7 +22,6 @@ import android.os.Parcelable import androidx.room.Entity import androidx.room.PrimaryKey import kotlinx.android.parcel.Parcelize -import java.util.regex.Pattern @Parcelize @Entity(tableName = "circulars") @@ -35,31 +34,4 @@ data class Circular( var reminder: Boolean = false, val attachmentsNames: MutableList = mutableListOf(), val attachmentsUrls: MutableList = mutableListOf() -) : Parcelable { - companion object { - fun generateFromString(string: String, url: String): Circular { - val idRegex = - """(\d+)""" - val matcherId = Pattern.compile(idRegex).matcher(string) - matcherId.find() - val id = matcherId.group(1) - - val dateRegex = - """(\d{2}/\d{2}/\d{4})""" - val matcherDate = Pattern.compile(dateRegex).matcher(string) - - var title = string.removeSuffix("-signed") - - return if (matcherDate.find()) { - title = title.removeRange(0, matcherDate.end()) - .removePrefix(" ") - .removePrefix("_") - .removePrefix(" ") - - Circular(id.toLong(), title, url, matcherDate.group(1) ?: "") - } else { - Circular(id.toLong(), title, url, "") - } - } - } -} +) : Parcelable diff --git a/app/src/main/java/net/underdesk/circolapp/server/ServerAPI.kt b/app/src/main/java/net/underdesk/circolapp/server/ServerAPI.kt index eb1e683..8de7159 100644 --- a/app/src/main/java/net/underdesk/circolapp/server/ServerAPI.kt +++ b/app/src/main/java/net/underdesk/circolapp/server/ServerAPI.kt @@ -20,6 +20,7 @@ package net.underdesk.circolapp.server import net.underdesk.circolapp.data.Circular import net.underdesk.circolapp.server.curie.CurieServer +import net.underdesk.circolapp.server.porporato.PorporatoServer class ServerAPI( private val server: Server @@ -57,7 +58,7 @@ class ServerAPI( private fun createServerAPI(server: Servers): ServerAPI { return when (server) { Servers.CURIE -> ServerAPI(CurieServer()) - Servers.PORPORATO -> TODO() + Servers.PORPORATO -> ServerAPI(PorporatoServer()) } } } diff --git a/app/src/main/java/net/underdesk/circolapp/server/curie/CurieServer.kt b/app/src/main/java/net/underdesk/circolapp/server/curie/CurieServer.kt index 9f9b407..628293c 100644 --- a/app/src/main/java/net/underdesk/circolapp/server/curie/CurieServer.kt +++ b/app/src/main/java/net/underdesk/circolapp/server/curie/CurieServer.kt @@ -11,6 +11,7 @@ import okhttp3.OkHttpClient import okhttp3.Request import org.jsoup.Jsoup import java.io.IOException +import java.util.regex.Pattern class CurieServer : Server() { private val moshi = Moshi.Builder().build() @@ -32,7 +33,7 @@ class CurieServer : Server() { 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.add(generateFromString(element.text(), element.attr("href"))) } } Pair(list, ServerAPI.Companion.Result.SUCCESS) @@ -65,6 +66,31 @@ class CurieServer : Server() { } } + private fun generateFromString(string: String, url: String): Circular { + val idRegex = + """(\d+)""" + val matcherId = Pattern.compile(idRegex).matcher(string) + matcherId.find() + val id = matcherId.group(1) + + val dateRegex = + """(\d{2}/\d{2}/\d{4})""" + val matcherDate = Pattern.compile(dateRegex).matcher(string) + + var title = string.removeSuffix("-signed") + + return if (matcherDate.find()) { + title = title.removeRange(0, matcherDate.end()) + .removePrefix(" ") + .removePrefix("_") + .removePrefix(" ") + + Circular(id.toLong(), title, url, matcherDate.group(1) ?: "") + } else { + Circular(id.toLong(), title, url, "") + } + } + companion object { const val ENDPOINT_URL = "https://www.curiepinerolo.edu.it/wp-json/wp/v2/pages/5958" } diff --git a/app/src/main/java/net/underdesk/circolapp/server/porporato/PorporatoServer.kt b/app/src/main/java/net/underdesk/circolapp/server/porporato/PorporatoServer.kt new file mode 100644 index 0000000..2e7d93b --- /dev/null +++ b/app/src/main/java/net/underdesk/circolapp/server/porporato/PorporatoServer.kt @@ -0,0 +1,158 @@ +package net.underdesk.circolapp.server.porporato + +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 okhttp3.OkHttpClient +import okhttp3.Request +import org.jsoup.Jsoup +import java.io.IOException +import java.util.regex.Pattern + +class PorporatoServer : Server() { + private val client = OkHttpClient() + + private val baseUrl = "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/" + private val endpointUrls = listOf( + "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-01-Settembre/", + "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-02-Ottobre/", + "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-03-Novembre/", + "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-04-Dicembre/", + "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-05-Gennaio/", + "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-06-Febbraio/", + "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-07-Marzo/", + "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-08-Aprile/", + "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-09-Maggio/", + "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-10-Giugno/", + "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-11-Luglio/", + "https://www.liceoporporato.edu.it/ARCHIVIO/PR/VP/circolari.php?dirname=CIRCOLARIP/- CIRCOLARI 2020-21/-12-Agosto/" + ) + + override suspend fun getCircularsFromServer(): Pair, ServerAPI.Companion.Result> { + return try { + val list = arrayListOf() + + for (url in endpointUrls) { + list.addAll(parsePage(url)) + } + + list.sortByDescending { it.id } + + Pair(list, ServerAPI.Companion.Result.SUCCESS) + } catch (exception: IOException) { + Pair(emptyList(), ServerAPI.Companion.Result.ERROR) + } + } + + override suspend fun newCircularsAvailable(): Pair { + return Pair(true, ServerAPI.Companion.Result.SUCCESS) + } + + @Throws(IOException::class) + private suspend fun parsePage(url: String): List { + val response = retrieveDataFromServer(url) + + return withContext(Dispatchers.Default) { + val document = Jsoup.parseBodyFragment(response) + val htmlList = document.getElementsByTag("table")[2] + .getElementsByTag("td")[2] + .getElementsByTag("a") + + val list = ArrayList() + + for (i in 0 until htmlList.size) { + list.add( + generateFromString( + htmlList[i].text(), + htmlList[i].attr("href"), + i.toLong() + ) + ) + } + + // Identify and group all attachments + list.removeAll { attachment -> + if (attachment.name.startsWith("All", true)) { + val parent = list.find { it.id == attachment.id && !it.name.startsWith("All") } + parent?.attachmentsNames?.add(attachment.name) + parent?.attachmentsUrls?.add(attachment.url) + + return@removeAll true + } + + false + } + + // Identify and group attachments not marked with "All" + var lastIndex = -1 + var lastId = -1L + + list.removeAll { attachment -> + if (lastId == attachment.id) { + val parent = list[lastIndex] + parent.attachmentsNames.add(attachment.name) + parent.attachmentsUrls.add(attachment.url) + + return@removeAll true + } + lastId = attachment.id + lastIndex = list.indexOf(attachment) + + false + } + + list + } + } + + @Throws(IOException::class) + private suspend fun retrieveDataFromServer(url: String): String { + val request = Request.Builder() + .url(url) + .build() + + return withContext(Dispatchers.IO) { + val response = client.newCall(request).execute() + + if (!response.isSuccessful) { + throw IOException("HTTP error code: ${response.code})") + } + + response.body!!.string() + } + } + + private fun generateFromString(string: String, path: String, index: Long): Circular { + val fullUrl = baseUrl + path + var title = string + + val idRegex = + """(\d+)""" + val matcherId = Pattern.compile(idRegex).matcher(string) + val id = if (!string.startsWith("Avviso") && matcherId.find()) { + title = title.removeRange(matcherId.start(), matcherId.end()) + .removePrefix(" ") + .removePrefix("-") + .removePrefix(" ") + + matcherId.group(1)?.toLong() ?: -index + } else { + -index + } + + val dateRegex = + """(\d{2}-\d{2}-\d{4})""" + val matcherDate = Pattern.compile(dateRegex).matcher(title) + + return if (matcherDate.find()) { + title = title.removeRange(matcherDate.start(), matcherDate.end()) + .removeSuffix(" (pubb.: )") + + Circular(id, title, fullUrl, matcherDate.group(1)?.replace("-", "/") ?: "") + } else { + Circular(id, title, fullUrl, "") + } + } +}