mirror of
https://github.com/NiciDieNase/chaosflix
synced 2024-11-26 06:00:25 +00:00
add API for VOC-Eventcalender
This commit is contained in:
parent
bd77a7bc22
commit
66c1221005
11 changed files with 133 additions and 6 deletions
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
)
|
|
@ -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
|
||||
)
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue