add API for VOC-Eventcalender

This commit is contained in:
Felix 2020-06-11 23:08:14 +02:00
parent bd77a7bc22
commit 66c1221005
11 changed files with 133 additions and 6 deletions

View file

@ -26,6 +26,7 @@ android {
buildConfigField "String", "STREAMING_API_BASE_URL", "\"https://streaming.media.ccc.de\""
buildConfigField "String", "STREAMING_API_OFFERS_PATH", "\"/streams/v2.json\""
}
compileOptions {

View file

@ -47,3 +47,27 @@ open class SingletonHolder2<out T, in A, in B>(creator: (A, B) -> T) {
}
}
}
open class SingletonHolder3<out T, in A, in B, in C>(creator: (A, B, C) -> T) {
private var creator: ((A, B, C) -> T)? = creator
@Volatile private var instance: T? = null
fun getInstance(arg1: A, arg2: B, arg3: C): T {
val i = instance
if (i != null) {
return i
}
return synchronized(this) {
val i2 = instance
if (i2 != null) {
i2
} else {
val created = creator!!(arg1, arg2, arg3)
instance = created
creator = null
created
}
}
}
}

View file

@ -0,0 +1,34 @@
package de.nicidienase.chaosflix.common.mediadata.entities.eventinfo
import androidx.room.Entity
import de.nicidienase.chaosflix.common.mediadata.entities.eventinfo.dto.VocEventDto
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@Entity
data class EventInfo(
val name: String,
val location: String,
val streaming: Boolean?,
val startDate: Date,
val endDate: Date
) {
companion object {
fun fromVocEventDto(dto: VocEventDto): EventInfo? {
return if(dto.name == null
|| dto.location == null
|| dto.startDate == null
|| dto.endDate == null
) {
null
} else {
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val startDate = dateFormat.parse(dto.startDate)
val endDate = dateFormat.parse(dto.endDate)
EventInfo(dto.name, dto.location, dto.streaming, startDate, endDate)
}
}
}
}

View file

@ -0,0 +1,17 @@
package de.nicidienase.chaosflix.common.mediadata.entities.eventinfo.dto
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
@Keep
data class EventInfoWrapperDto(
@SerializedName("voc_events") val events: Map<String, VocEventDto>,
@SerializedName("voc_events_count") val eventsCount: CountInfo
)
data class CountInfo(
val all: Int,
val with_streaming: Int,
val without_streaming: Int,
val undefined_streaming: Int
)

View file

@ -0,0 +1,25 @@
package de.nicidienase.chaosflix.common.mediadata.entities.eventinfo.dto
import androidx.annotation.Keep
import com.google.gson.annotations.SerializedName
@Keep
data class VocEventDto(
val name: String?,
@SerializedName("short_name")
val shortName: String?,
val location: String?,
@SerializedName("start_date")
val startDate: String?, // Date: YYYY-MM-DD
@SerializedName("end_date")
val endDate: String?, // Date: YYYY-MM-DD
val description: String?,
@SerializedName("voc_wiki_path")
val vocWikiPath: String?,
val streaming: Boolean?,
@SerializedName("planing_status")
val planingStatus: String?,
val cases: List<String>?,
val buildup: String?, // Date: YYYY-MM-DD
val teardown: String? // Date: YYYY-MM-DD
)

View file

@ -4,6 +4,7 @@ import android.os.Build
import com.google.gson.Gson
import de.nicidienase.chaosflix.BuildConfig
import de.nicidienase.chaosflix.common.SingletonHolder2
import de.nicidienase.chaosflix.common.SingletonHolder3
import java.io.File
import java.util.concurrent.TimeUnit
import okhttp3.Cache
@ -12,7 +13,7 @@ import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class ApiFactory private constructor(apiUrl: String, cache: File? = null) {
class ApiFactory private constructor(apiUrl: String, eventInfoUrl: String, cache: File? = null) {
private val chaosflixUserAgent: String by lazy { buildUserAgent() }
private val gsonConverterFactory: GsonConverterFactory by lazy { GsonConverterFactory.create(Gson()) }
@ -39,13 +40,23 @@ class ApiFactory private constructor(apiUrl: String, cache: File? = null) {
.create(RecordingApi::class.java)
}
val streamingApi: StreamingApi by lazy { Retrofit.Builder()
val streamingApi: StreamingApi by lazy {
Retrofit.Builder()
.baseUrl(BuildConfig.STREAMING_API_BASE_URL)
.client(client)
.addConverterFactory(gsonConverterFactory)
.build()
.create(StreamingApi::class.java) }
val eventInfoApi: EventInfoApi by lazy {
Retrofit.Builder()
.baseUrl(eventInfoUrl)
.client(client)
.addConverterFactory(gsonConverterFactory)
.build()
.create(EventInfoApi::class.java)
}
private val useragentInterceptor: Interceptor = Interceptor { chain ->
val requestWithUseragent = chain.request().newBuilder()
.header("User-Agent", chaosflixUserAgent)
@ -53,7 +64,7 @@ class ApiFactory private constructor(apiUrl: String, cache: File? = null) {
return@Interceptor chain.proceed(requestWithUseragent)
}
companion object : SingletonHolder2<ApiFactory, String, File?>(::ApiFactory) {
companion object : SingletonHolder3<ApiFactory, String, String, File?>(::ApiFactory) {
private const val DEFAULT_TIMEOUT = 30L
private const val CACHE_SIZE = 1024L * 5 // 5MB

View file

@ -0,0 +1,11 @@
package de.nicidienase.chaosflix.common.mediadata.network
import de.nicidienase.chaosflix.common.mediadata.entities.eventinfo.dto.EventInfoWrapperDto
import retrofit2.http.GET
interface EventInfoApi {
@GET("/eventkalender/events.json")
suspend fun getVocEvents(): EventInfoWrapperDto
}

View file

@ -23,7 +23,10 @@ import kotlinx.coroutines.SupervisorJob
class ViewModelFactory private constructor(context: Context) : ViewModelProvider.Factory {
val apiFactory = ApiFactory.getInstance(context.resources.getString(R.string.recording_url), context.cacheDir)
val apiFactory = ApiFactory.getInstance(
context.resources.getString(R.string.recording_url),
context.resources.getString(R.string.event_info_url),
context.cacheDir)
private val supervisorJob = SupervisorJob()
private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO + supervisorJob)

View file

@ -2,6 +2,7 @@
<resources>
<string name="recording_url" translatable="false">https://api.media.ccc.de</string>
<string name="streaming_url" translatable="false">https://streaming.media.ccc.de</string>
<string name="event_info_url" translatable="false">https://c3voc.de</string>
<string name="about_beta_url" translatable="false">https://play.google.com/apps/testing/de.nicidienase.chaosflix</string>
<string name="about_voctocat_url" translatable="false">https://morr.cc/voctocat/</string>

View file

@ -8,7 +8,7 @@ import org.junit.jupiter.api.Test
class ChaosflixUtilTest {
val api = ApiFactory.getInstance("https://api.media.ccc.de", null).recordingApi
val api = ApiFactory.getInstance("https://api.media.ccc.de","https://c3voc.de", null).recordingApi
@Test
fun testGPN19() = genericTest("gpn19", false)

View file

@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test
class RecordingServiceTest {
private val apiFactory = ApiFactory.getInstance("https://api.media.ccc.de", null)
private val apiFactory = ApiFactory.getInstance("https://api.media.ccc.de","https://c3voc.de", null)
private val api = apiFactory.recordingApi
@BeforeEach