Bimba.git

ref: 076a9923c8d5f588489aae6a667e82a5763a3475

app/src/main/java/ml/adamsprogs/bimba/VmClient.kt


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package ml.adamsprogs.bimba

import android.app.IntentService
import android.content.Intent
import android.util.Log
import ml.adamsprogs.bimba.models.*
import okhttp3.*
import com.google.gson.Gson
import org.onebusaway.gtfs.model.AgencyAndId
import java.io.IOException
import java.util.*


class VmClient : IntentService("VmClient") {
    companion object {
        const val ACTION_DEPARTURES_CREATED = "ml.adamsprogs.bimba.departuresCreated"
        const val ACTION_NO_DEPARTURES = "ml.adamsprogs.bimba.noVM"
        const val EXTRA_STOP_SYMBOL = "stopSymbol"
        const val EXTRA_LINE_NUMBER = "lineNumber"
        const val EXTRA_REQUESTER = "requester"
        const val EXTRA_DEPARTURES = "departures"
        const val EXTRA_SIZE = "size"
        const val EXTRA_ID = "id"
    }

    override fun onHandleIntent(intent: Intent?) {
        if (intent != null) {
            val requester = intent.getStringExtra(EXTRA_REQUESTER)
            Log.i("VM", "Request for $requester received")
            val id = intent.getStringExtra(EXTRA_ID)
            val size = intent.getIntExtra(EXTRA_SIZE, -1)

            if (!NetworkStateReceiver.isNetworkAvailable(this)) {
                sendNullResult(requester, id, size)
                return
            }

            val stopSymbol = intent.getStringExtra(EXTRA_STOP_SYMBOL)
            if (stopSymbol == null) {
                sendNullResult(requester, id, size)
                return
            }
            val lineId = intent.getSerializableExtra(EXTRA_LINE_NUMBER) as AgencyAndId?

            val client = OkHttpClient()
            val url = "http://www.peka.poznan.pl/vm/method.vm?ts=${Calendar.getInstance().timeInMillis}"
            val formBody = FormBody.Builder()
                    .add("method", "getTimes")
                    .add("p0", "{\"symbol\": \"$stopSymbol\"}")
                    .build()
            val request = Request.Builder()
                    .url(url)
                    .post(formBody)
                    .build()

            Log.i("VM", "created http request")

            val responseBody: String?
            try {
                responseBody = client.newCall(request).execute().body()?.string()
            } catch (e: IOException) {
                sendNullResult(requester, id, size)
                return
            }

            Log.i("VM", "received http response")

            if (responseBody?.get(0) == '<') {
                sendNullResult(requester, id, size)
                return
            }

            val javaRootMapObject = Gson().fromJson(responseBody, HashMap::class.java)
            val times = (javaRootMapObject["success"] as Map<*, *>)["times"] as List<*>
            val date = Calendar.getInstance()
            val todayDay = "${date.get(Calendar.DATE)}".padStart(2, '0')
            val timetable = Timetable.getTimetable()
            val todayMode = timetable.calendarToMode(timetable.getServiceForToday().id.toInt())
            val departuresToday = ArrayList<Departure>()
            val lineNumber = if (lineId != null) timetable.getLineNumber(lineId) else null
            for (time in times) {
                val t = time as Map<*, *>
                if (lineId == null || t["line"] == lineNumber) {
                    val departureDay = (t["departure"] as String).split("T")[0].split("-")[2]
                    val departureTime = calendarFromIso(t["departure"] as String).secondsAfterMidnight()
                    val departure = Departure(lineId?: timetable.getLineForNumber(t["line"] as String)!!
                            , todayMode, departureTime, false,
                            ArrayList(), t["direction"] as String, t["realTime"] as Boolean,
                            departureDay != todayDay, t["onStopPoint"] as Boolean)
                    departuresToday.add(departure)
                }
            }

            Log.i("VM", "parsed http response")
            if (departuresToday.isEmpty())
                sendNullResult(requester, id, size)
            else
                sendResult(departuresToday, requester, id, size)
        }
    }

    private fun sendNullResult(requester: String, id: String, size: Int) {
        val broadcastIntent = Intent()
        broadcastIntent.action = ACTION_NO_DEPARTURES
        broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT)
        broadcastIntent.putExtra(EXTRA_REQUESTER, requester)
        broadcastIntent.putExtra(EXTRA_ID, id)
        broadcastIntent.putExtra(EXTRA_SIZE, size)
        sendBroadcast(broadcastIntent)
    }

    private fun sendResult(departures: ArrayList<Departure>, requester: String, id: String, size: Int) {
        val broadcastIntent = Intent()
        broadcastIntent.action = ACTION_DEPARTURES_CREATED
        broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT)
        broadcastIntent.putStringArrayListExtra(EXTRA_DEPARTURES, departures.map { it.toString() } as java.util.ArrayList<String>)
        broadcastIntent.putExtra(EXTRA_REQUESTER, requester)
        broadcastIntent.putExtra(EXTRA_ID, id)
        broadcastIntent.putExtra(EXTRA_SIZE, size)
        sendBroadcast(broadcastIntent)
        Log.i("VM", "sent response")
    }
}