VmClient.kt 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package ml.adamsprogs.bimba.datasources
  2. import com.google.gson.Gson
  3. import com.google.gson.JsonObject
  4. import com.google.gson.JsonSyntaxException
  5. import kotlinx.coroutines.Dispatchers
  6. import kotlinx.coroutines.withContext
  7. import ml.adamsprogs.bimba.NetworkStateReceiver
  8. import ml.adamsprogs.bimba.models.Plate
  9. import ml.adamsprogs.bimba.models.StopSegment
  10. import ml.adamsprogs.bimba.models.suggestions.StopSuggestion
  11. import okhttp3.MediaType
  12. import okhttp3.OkHttpClient
  13. import okhttp3.RequestBody
  14. import java.io.IOException
  15. import java.util.*
  16. import kotlin.collections.HashMap
  17. import kotlin.collections.HashSet
  18. class VmClient {
  19. companion object {
  20. private var vmClient: VmClient? = null
  21. fun getVmClient(): VmClient {
  22. if (vmClient == null)
  23. vmClient = VmClient()
  24. return vmClient!!
  25. }
  26. }
  27. suspend fun getSheds(name: String): Map<String, Set<String>> {
  28. val (_, response) = makeRequest("getBollardsByStopPoint", """{"name": "$name"}""")
  29. if (!response.has("success"))
  30. return emptyMap()
  31. val rootObject = response["success"].asJsonObject["bollards"].asJsonArray
  32. val result = HashMap<String, Set<String>>()
  33. rootObject.forEach { element ->
  34. val code = element.asJsonObject["bollard"].asJsonObject["tag"].asString
  35. result[code] = element.asJsonObject["directions"].asJsonArray.map {
  36. """${it.asJsonObject["lineName"].asString} → ${it.asJsonObject["direction"].asString}"""
  37. }.toSet()
  38. }
  39. return result
  40. }
  41. /*
  42. suspend fun getPlatesByStopPoint(code: String): Set<Plate.ID>? {
  43. val getTimesResponse = makeRequest("getTimes", """{"symbol": "$code"}""")
  44. val name = getTimesResponse["success"].asJsonObject["bollard"].asJsonObject["name"].asString
  45. val bollards = getBollardsByStopPoint(name)
  46. return bollards.filter {
  47. it.key == code
  48. }.values.flatMap {
  49. it.map {
  50. val (line, headsign) = it.split(" → ")
  51. Plate.ID(AgencyAndId(line), AgencyAndId(code), headsign)
  52. }
  53. }.toSet()
  54. }*/
  55. suspend fun getStops(pattern: String): List<StopSuggestion> {
  56. val (_, response) = withContext(Dispatchers.Default) {
  57. makeRequest("getStopPoints", """{"pattern": "$pattern"}""")
  58. }
  59. if (!response.has("success"))
  60. return emptyList()
  61. val points = response["success"].asJsonArray.map { it.asJsonObject }
  62. val names = HashSet<String>()
  63. points.forEach {
  64. val name = it["name"].asString
  65. names.add(name)
  66. }
  67. return names.map { StopSuggestion(it, "") }
  68. }
  69. suspend fun makeRequest(method: String, data: String): Pair<Int, JsonObject> {
  70. if (!NetworkStateReceiver.isNetworkAvailable())
  71. return Pair(0, JsonObject())
  72. val client = OkHttpClient()
  73. val url = "http://www.peka.poznan.pl/vm/method.vm?ts=${Calendar.getInstance().timeInMillis}"
  74. val body = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded; charset=UTF-8"),
  75. "method=$method&p0=$data")
  76. val request = okhttp3.Request.Builder()
  77. .url(url)
  78. .post(body)
  79. .build()
  80. var responseBody: String? = null
  81. var responseCode = 0
  82. try {
  83. withContext(Dispatchers.Default) {
  84. client.newCall(request).execute().let {
  85. responseCode = it.code()
  86. responseBody = it.body()?.string()
  87. }
  88. }
  89. } catch (e: IOException) {
  90. return Pair(0, JsonObject())
  91. }
  92. return try {
  93. Pair(responseCode, Gson().fromJson(responseBody, JsonObject::class.java))
  94. } catch (e: JsonSyntaxException) {
  95. Pair(responseCode, JsonObject())
  96. }
  97. }
  98. suspend fun getName(symbol: String): String? {
  99. val (_, timesResponse) = withContext(Dispatchers.Default) {
  100. makeRequest("getTimes", """{"symbol": "$symbol"}""")
  101. }
  102. if (!timesResponse.has("success"))
  103. return null
  104. return timesResponse["success"].asJsonObject["bollard"].asJsonObject["name"].asString
  105. }
  106. suspend fun getDirections(symbol: String): StopSegment? {
  107. val name = getName(symbol)
  108. val (_, directionsResponse) = makeRequest("getBollardsByStopPoint", """{"name": "$name"}""")
  109. if (!directionsResponse.has("success"))
  110. return null
  111. return StopSegment(symbol,
  112. directionsResponse["success"].asJsonObject["bollards"].asJsonArray.filter {
  113. it.asJsonObject["bollard"].asJsonObject["tag"].asString == symbol
  114. }[0].asJsonObject["directions"].asJsonArray.map {
  115. it.asJsonObject.let { direction ->
  116. Plate.ID(direction["lineName"].asString, symbol, direction["direction"].asString)
  117. }
  118. }.toSet())
  119. }
  120. suspend fun getMessage(shed: String): String? {
  121. val (_, response) = makeRequest("findMessagesForBollard", """{"symbol": "$shed"}""")
  122. if (!response.has("success"))
  123. return null
  124. if (response["success"].asJsonArray.size() == 0)
  125. return null
  126. return response["success"].asJsonArray[0].asJsonObject["content"].asString
  127. }
  128. }