ref: 0630fc784bb3de6fbcb55812c9a3095ac602d4f2
app/src/main/java/xyz/apiote/bimba/czwek/repo/FeedInfo.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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
// SPDX-FileCopyrightText: Adam Evyčędo // // SPDX-License-Identifier: GPL-3.0-or-later package xyz.apiote.bimba.czwek.repo import xyz.apiote.bimba.czwek.api.structs.FeedInfoV1 import xyz.apiote.bimba.czwek.api.structs.FeedInfoV2 import xyz.apiote.bimba.czwek.api.structs.QrLocationV1 import xyz.apiote.fruchtfleisch.Reader import xyz.apiote.fruchtfleisch.Writer import java.io.InputStream import java.io.OutputStream import java.time.LocalDate import java.time.format.DateTimeFormatter import java.time.format.FormatStyle import java.util.Locale class FeedInfoPrev { companion object { fun unmarshal(@Suppress("UNUSED_PARAMETER") stream: InputStream): FeedInfo { return FeedInfo(FeedInfoPrev()) } } } data class FeedInfo( val id: String, val name: String, val attribution: String, val description: String, val lastUpdate: LocalDate, val qrHost: String, val qrIn: QrLocation, val qrSelector: String, val validSince: LocalDate?, val validTill: LocalDate?, val cached: Boolean ) { companion object { const val VERSION = 100u private fun parseDate(dateString: String) = LocalDate.parse(dateString, DateTimeFormatter.ISO_LOCAL_DATE) fun unmarshal(stream: InputStream): FeedInfo { val reader = Reader(stream) val id = reader.readString() val name = reader.readString() val attribution = reader.readString() val description = reader.readString() val lastUpdate = parseDate(reader.readString()) val qrHost = reader.readString() val qrIn = QrLocation.of(QrLocationV1.of(reader.readUInt().toULong().toUInt())) val qrSelector = reader.readString() val validSince = reader.readString() val validTill = reader.readString() return FeedInfo( id, name, attribution, description, lastUpdate, qrHost, qrIn, qrSelector, if (validSince != "") parseDate(validSince) else null, if (validTill != "") parseDate(validTill) else null, true ) } } constructor(f: FeedInfoV2, cached: Boolean = false) : this( f.id, f.name, f.attribution, f.description, f.lastUpdate, f.qrHost, QrLocation.of(f.qrIn), f.qrSelector, f.validSince, f.validTill, cached ) constructor(f: FeedInfoV1, cached: Boolean = false) : this( f.id, f.name, f.attribution, f.description, f.lastUpdate.toLocalDate(), "", QrLocation.UNKNOWN, "", null, null, cached ) constructor(@Suppress("UNUSED_PARAMETER") f: FeedInfoPrev) : this( "", "", "", "", LocalDate.MIN, "", QrLocation.UNKNOWN, "", null, null, false ) fun marshal(stream: OutputStream) { val writer = Writer(stream) writer.writeString(id) writer.writeString(name) writer.writeString(attribution) writer.writeString(description) writer.writeString(formatDateMarshal(lastUpdate)) writer.writeString(qrHost) writer.writeUInt(qrIn.value().toULong()) writer.writeString(qrSelector) writer.writeString(if (validSince == null) "" else formatDateMarshal(validSince)) writer.writeString(if (validTill == null) "" else formatDateMarshal(validTill)) } private fun formatDateMarshal(date: LocalDate): String { return date.format(DateTimeFormatter.ISO_LOCAL_DATE) } fun formatDate(): String { return lastUpdate.format( DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(Locale.getDefault()) ) } } fun FeedInfo?.join(other: FeedInfo?): FeedInfo { assert(this != null || other != null) if (this == null) return other!! if (other == null) return this return FeedInfo( id, other.name, other.attribution, other.description, if (lastUpdate.isAfter(other.lastUpdate)) lastUpdate else other.lastUpdate, other.qrHost, other.qrIn, other.qrSelector, if (other.validSince == null || (validSince ?: LocalDate.MIN).isAfter(other.validSince) ) validSince else other.validSince, if (other.validTill == null || (validTill ?: LocalDate.MIN).isAfter(other.validTill) ) validTill else other.validTill, this.cached && other.cached ) } |