Bimba.git

ref: 9f963267072cef9fd3a2ab10a7ec4d6292e259e1

app/src/main/java/ml/adamsprogs/bimba/ui/home/HomeViewModel.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
package ml.adamsprogs.bimba.ui.home

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ml.adamsprogs.bimba.api.Line
import ml.adamsprogs.bimba.api.Stop
import xyz.apiote.fruchtfleisch.Reader
import java.io.InputStream
import java.net.HttpURLConnection
import java.net.URL

class HomeViewModel : ViewModel() {

	private val _text = MutableLiveData<List<String>>()
	val text: LiveData<List<String>> = _text

	fun getItems(query: String) {
		viewModelScope.launch {
			val itemsStream = queryItems(query)
			_text.value = unmarshallItemResponse(itemsStream)
		}
	}

	@Suppress("BlockingMethodInNonBlockingContext")
	private suspend fun queryItems(query: String): InputStream {
		return withContext(Dispatchers.IO) {
			val url = URL("https://bimba.apiote.xyz/api/poznan_ztm/items?q=${query}")
			val c = (url.openConnection() as HttpURLConnection).apply {
				setRequestProperty("X-Bimba-Token", "ef0179272e7270e1a2da1710a8ba24e1")
			}
			c.inputStream
		}
	}

	private suspend fun unmarshallItemResponse(r: InputStream): List<String> {
		val items = mutableListOf<String>()
		val reader = Reader(r)
		withContext(Dispatchers.IO) {
			// todo ItemResponse from .api.unmarshallItemResponse(stream)
			when (reader.readUInt()) {
				0UL -> {
					TODO("error response")
				}
				1UL -> {
					val itemsNum = reader.readUInt()
					for (i in 0UL until itemsNum) {
						when (reader.readUInt()) {
							0UL -> {
								val stop = Stop.unmarshall(r)
								items.add(stop.toString())
							}
							1UL -> {
								val line = Line.unmarshall(r)
								items.add(line.toString())
							}
							else -> {
								TODO("throw unknown tag")
							}
						}
					}
				}
				else -> {
					TODO("throw unknown tag")
				}
			}
		}
		return items
	}

	private fun String.printable() = map {
		when (Character.getType(it).toByte()) {
			Character.CONTROL, Character.FORMAT, Character.PRIVATE_USE,
			Character.SURROGATE, Character.UNASSIGNED, Character.OTHER_SYMBOL
			-> "\\u%04x".format(it.code)
			else -> it.toString()
		}
	}.joinToString("")
}