From 66c122100545a682d2fbd20964d55a62fc5ab8fa Mon Sep 17 00:00:00 2001 From: Felix Date: Thu, 11 Jun 2020 23:08:14 +0200 Subject: [PATCH] add API for VOC-Eventcalender --- common/build.gradle | 1 + .../chaosflix/common/SingletonHolder.kt | 24 +++++++++++++ .../mediadata/entities/eventinfo/EventInfo.kt | 34 +++++++++++++++++++ .../eventinfo/dto/EventInfoWrapperDto.kt | 17 ++++++++++ .../entities/eventinfo/dto/VocEventDto.kt | 25 ++++++++++++++ .../common/mediadata/network/ApiFactory.kt | 17 ++++++++-- .../common/mediadata/network/EventInfoApi.kt | 11 ++++++ .../common/viewmodel/ViewModelFactory.kt | 5 ++- common/src/main/res/values/urlstrings.xml | 1 + .../chaosflix/common/ChaosflixUtilTest.kt | 2 +- .../mediadata/network/RecordingServiceTest.kt | 2 +- 11 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 common/src/main/java/de/nicidienase/chaosflix/common/mediadata/entities/eventinfo/EventInfo.kt create mode 100644 common/src/main/java/de/nicidienase/chaosflix/common/mediadata/entities/eventinfo/dto/EventInfoWrapperDto.kt create mode 100644 common/src/main/java/de/nicidienase/chaosflix/common/mediadata/entities/eventinfo/dto/VocEventDto.kt create mode 100644 common/src/main/java/de/nicidienase/chaosflix/common/mediadata/network/EventInfoApi.kt diff --git a/common/build.gradle b/common/build.gradle index 199d4806..b93a5010 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -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 { diff --git a/common/src/main/java/de/nicidienase/chaosflix/common/SingletonHolder.kt b/common/src/main/java/de/nicidienase/chaosflix/common/SingletonHolder.kt index b9258438..d29369ef 100644 --- a/common/src/main/java/de/nicidienase/chaosflix/common/SingletonHolder.kt +++ b/common/src/main/java/de/nicidienase/chaosflix/common/SingletonHolder.kt @@ -47,3 +47,27 @@ open class SingletonHolder2(creator: (A, B) -> T) { } } } + +open class SingletonHolder3(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 + } + } + } +} diff --git a/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/entities/eventinfo/EventInfo.kt b/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/entities/eventinfo/EventInfo.kt new file mode 100644 index 00000000..ec459d00 --- /dev/null +++ b/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/entities/eventinfo/EventInfo.kt @@ -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) + } + } + } +} + diff --git a/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/entities/eventinfo/dto/EventInfoWrapperDto.kt b/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/entities/eventinfo/dto/EventInfoWrapperDto.kt new file mode 100644 index 00000000..550c95f3 --- /dev/null +++ b/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/entities/eventinfo/dto/EventInfoWrapperDto.kt @@ -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, + @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 +) diff --git a/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/entities/eventinfo/dto/VocEventDto.kt b/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/entities/eventinfo/dto/VocEventDto.kt new file mode 100644 index 00000000..6667fa56 --- /dev/null +++ b/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/entities/eventinfo/dto/VocEventDto.kt @@ -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?, + val buildup: String?, // Date: YYYY-MM-DD + val teardown: String? // Date: YYYY-MM-DD +) \ No newline at end of file diff --git a/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/network/ApiFactory.kt b/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/network/ApiFactory.kt index 1ac18ce5..7ba91da3 100644 --- a/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/network/ApiFactory.kt +++ b/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/network/ApiFactory.kt @@ -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) { + companion object : SingletonHolder3(::ApiFactory) { private const val DEFAULT_TIMEOUT = 30L private const val CACHE_SIZE = 1024L * 5 // 5MB diff --git a/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/network/EventInfoApi.kt b/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/network/EventInfoApi.kt new file mode 100644 index 00000000..848d0aef --- /dev/null +++ b/common/src/main/java/de/nicidienase/chaosflix/common/mediadata/network/EventInfoApi.kt @@ -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 +} + diff --git a/common/src/main/java/de/nicidienase/chaosflix/common/viewmodel/ViewModelFactory.kt b/common/src/main/java/de/nicidienase/chaosflix/common/viewmodel/ViewModelFactory.kt index 03ab2fc8..251195a6 100644 --- a/common/src/main/java/de/nicidienase/chaosflix/common/viewmodel/ViewModelFactory.kt +++ b/common/src/main/java/de/nicidienase/chaosflix/common/viewmodel/ViewModelFactory.kt @@ -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) diff --git a/common/src/main/res/values/urlstrings.xml b/common/src/main/res/values/urlstrings.xml index d95b04d6..0afb5639 100644 --- a/common/src/main/res/values/urlstrings.xml +++ b/common/src/main/res/values/urlstrings.xml @@ -2,6 +2,7 @@ https://api.media.ccc.de https://streaming.media.ccc.de + https://c3voc.de https://play.google.com/apps/testing/de.nicidienase.chaosflix https://morr.cc/voctocat/ diff --git a/common/src/test/java/de/nicidienase/chaosflix/common/ChaosflixUtilTest.kt b/common/src/test/java/de/nicidienase/chaosflix/common/ChaosflixUtilTest.kt index 4c08efe4..f7158351 100644 --- a/common/src/test/java/de/nicidienase/chaosflix/common/ChaosflixUtilTest.kt +++ b/common/src/test/java/de/nicidienase/chaosflix/common/ChaosflixUtilTest.kt @@ -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) diff --git a/common/src/test/java/de/nicidienase/chaosflix/common/mediadata/network/RecordingServiceTest.kt b/common/src/test/java/de/nicidienase/chaosflix/common/mediadata/network/RecordingServiceTest.kt index 9c0de7ff..756eddb3 100644 --- a/common/src/test/java/de/nicidienase/chaosflix/common/mediadata/network/RecordingServiceTest.kt +++ b/common/src/test/java/de/nicidienase/chaosflix/common/mediadata/network/RecordingServiceTest.kt @@ -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