Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import android.content.Context.MODE_PRIVATE
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase

const val DATABASE_VERSION = 41
const val DATABASE_VERSION = 42
const val DATABASE_NAME = "SHOWLY2_DB_2"

class Migrations(
Expand Down Expand Up @@ -778,47 +778,56 @@ class Migrations(
}
}

fun getAll() =
listOf(
migration2,
migration3,
migration4,
migration5,
migration6,
migration7,
migration8,
migration9,
migration10,
migration11,
migration12,
migration13,
migration14,
migration15,
migration16,
migration17,
migration18,
migration19,
migration20,
migration21,
migration22,
migration23,
migration24,
migration25,
migration26,
migration27,
migration28,
migration29,
migration30,
migration31,
migration32,
migration33,
migration34,
migration35,
migration36,
migration37,
migration38,
migration39,
migration40,
migration41,
)
private val migration42 = object : Migration(41, 42) {
override fun migrate(database: SupportSQLiteDatabase) {
with(database) {
execSQL("ALTER TABLE movies ADD COLUMN original_release TEXT NOT NULL DEFAULT ''")
execSQL("ALTER TABLE movies ADD COLUMN current_country TEXT NOT NULL DEFAULT ''")
}
}
}

fun getAll() = listOf(
migration2,
migration3,
migration4,
migration5,
migration6,
migration7,
migration8,
migration9,
migration10,
migration11,
migration12,
migration13,
migration14,
migration15,
migration16,
migration17,
migration18,
migration19,
migration20,
migration21,
migration22,
migration23,
migration24,
migration25,
migration26,
migration27,
migration28,
migration29,
migration30,
migration31,
migration32,
migration33,
migration34,
migration35,
migration36,
migration37,
migration38,
migration39,
migration40,
migration41,
migration42
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ data class Movie(
@ColumnInfo(name = "title", defaultValue = "") val title: String,
@ColumnInfo(name = "year", defaultValue = "-1") val year: Int,
@ColumnInfo(name = "overview", defaultValue = "") val overview: String,
@ColumnInfo(name = "released", defaultValue = "") val released: String,
@ColumnInfo(name = "released", defaultValue = "") var released: String,
@ColumnInfo(name = "original_release", defaultValue = "") val originalRelease: String,
@ColumnInfo(name = "runtime", defaultValue = "-1") val runtime: Int,
@ColumnInfo(name = "country", defaultValue = "") val country: String,
@ColumnInfo(name = "current_country", defaultValue = "") val currentCountry: String,
@ColumnInfo(name = "trailer", defaultValue = "") val trailer: String,
@ColumnInfo(name = "language", defaultValue = "") val language: String,
@ColumnInfo(name = "homepage", defaultValue = "") val homepage: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.michaldrabik.data_remote.tmdb

import com.michaldrabik.data_remote.tmdb.model.Releases
import com.michaldrabik.data_remote.tmdb.model.TmdbImage
import com.michaldrabik.data_remote.tmdb.model.TmdbImages
import com.michaldrabik.data_remote.tmdb.model.TmdbPerson
Expand Down Expand Up @@ -40,4 +41,6 @@ interface TmdbRemoteDataSource {
suspend fun fetchPersonTranslations(id: Long): Map<String, TmdbTranslation.Data>

suspend fun fetchPersonImages(tmdbId: Long): TmdbImages

suspend fun fetchMovieRelease(tmdbId: Long): Releases
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,7 @@ internal class TmdbApi(
} catch (error: Throwable) {
TmdbImages.EMPTY
}

override suspend fun fetchMovieRelease(imdbId: Long) =
service.fetchMovieRelease(imdbId)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.michaldrabik.data_remote.tmdb.api

import com.michaldrabik.data_remote.tmdb.model.Releases
import com.michaldrabik.data_remote.tmdb.model.TmdbImages
import com.michaldrabik.data_remote.tmdb.model.TmdbPeople
import com.michaldrabik.data_remote.tmdb.model.TmdbPerson
Expand Down Expand Up @@ -58,7 +59,8 @@ interface TmdbService {
): TmdbStreamings

@GET("tv/{tmdbId}/watch/providers")
suspend fun fetchShowWatchProviders(
@Path("tmdbId") tmdbId: Long,
): TmdbStreamings
suspend fun fetchShowWatchProviders(@Path("tmdbId") tmdbId: Long): TmdbStreamings

@GET("movie/{tmdbId}/release_dates")
suspend fun fetchMovieRelease(@Path("tmdbId") tmdbId: Long): Releases
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.michaldrabik.data_remote.tmdb.model

data class ReleaseDate(
val note: String,
val release_date: Any,
val type: Int
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.michaldrabik.data_remote.tmdb.model

data class ReleaseInfo(
val iso_3166_1: String,
val release_dates: List<ReleaseDate>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.michaldrabik.data_remote.tmdb.model

data class Releases(
val id: Long,
val results: List<ReleaseInfo>
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ class MovieMapper @Inject constructor(
private val idsMapper: IdsMapper,
) {

fun fromNetwork(movie: MovieNetwork) =
Movie(
fun fromNetwork(movie: MovieNetwork): Movie {
val released: LocalDate? = movie.released?.let { if (it.isNotBlank()) LocalDate.parse(it) else null }

return Movie(
idsMapper.fromNetwork(movie.ids),
movie.title ?: "",
movie.year ?: -1,
movie.overview ?: "",
movie.released?.let { if (it.isNotBlank()) LocalDate.parse(it) else null },
released,
released,
movie.runtime ?: -1,
movie.country ?: "",
movie.country,
movie.trailer ?: "",
movie.homepage ?: "",
movie.language ?: "",
Expand All @@ -30,8 +34,9 @@ class MovieMapper @Inject constructor(
movie.comment_count ?: -1,
movie.genres ?: emptyList(),
nowUtcMillis(),
nowUtcMillis(),
nowUtcMillis()
)
}

fun toNetwork(movie: Movie) =
MovieNetwork(
Expand All @@ -52,48 +57,50 @@ class MovieMapper @Inject constructor(
movie.language,
)

fun fromDatabase(movie: MovieDb) =
Movie(
idsMapper.fromDatabase(movie),
movie.title,
movie.year,
movie.overview,
if (movie.released.isBlank()) null else LocalDate.parse(movie.released),
movie.runtime,
movie.country,
movie.trailer,
movie.homepage,
movie.language,
MovieStatus.fromKey(movie.status),
movie.rating,
movie.votes,
movie.commentCount,
movie.genres.split(","),
movie.updatedAt,
movie.createdAt,
)
fun fromDatabase(movie: MovieDb) = Movie(
idsMapper.fromDatabase(movie),
movie.title,
movie.year,
movie.overview,
movie.released.let { if (it.isNotBlank()) LocalDate.parse(it) else null },
movie.originalRelease.let { if (it.isNotBlank()) LocalDate.parse(it) else null },
movie.runtime,
movie.country,
movie.currentCountry.let { it.ifBlank { null } },
movie.trailer,
movie.homepage,
movie.language,
MovieStatus.fromKey(movie.status),
movie.rating,
movie.votes,
movie.commentCount,
movie.genres.split(","),
movie.updatedAt,
movie.createdAt
)

fun toDatabase(movie: Movie) =
MovieDb(
movie.ids.trakt.id,
movie.ids.tmdb.id,
movie.ids.imdb.id,
movie.ids.slug.id,
movie.title,
movie.year,
movie.overview,
movie.released?.toString() ?: "",
movie.runtime,
movie.country,
movie.trailer,
movie.language,
movie.homepage,
movie.status.key,
movie.rating,
movie.votes,
movie.commentCount,
movie.genres.joinToString(","),
nowUtcMillis(),
movie.createdAt,
)
}
fun toDatabase(movie: Movie) = MovieDb(
movie.ids.trakt.id,
movie.ids.tmdb.id,
movie.ids.imdb.id,
movie.ids.slug.id,
movie.title,
movie.year,
movie.overview,
movie.released?.toString() ?: "",
movie.originalRelease?.toString() ?: "",
movie.runtime,
movie.country,
movie.currentCountry ?: "",
movie.trailer,
movie.language,
movie.homepage,
movie.status.key,
movie.rating,
movie.votes,
movie.commentCount,
movie.genres.joinToString(","),
nowUtcMillis(),
movie.createdAt
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,58 @@ import com.michaldrabik.common.extensions.nowUtcMillis
import com.michaldrabik.data_local.LocalDataSource
import com.michaldrabik.data_local.database.model.MoviesSyncLog
import com.michaldrabik.data_remote.RemoteDataSource
import com.michaldrabik.data_remote.tmdb.model.Releases
import com.michaldrabik.repository.mappers.Mappers
import com.michaldrabik.repository.settings.SettingsRepository
import com.michaldrabik.ui_model.IdImdb
import com.michaldrabik.ui_model.IdSlug
import com.michaldrabik.ui_model.IdTmdb
import com.michaldrabik.ui_model.IdTrakt
import com.michaldrabik.ui_model.Movie
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import javax.inject.Inject

class MovieDetailsRepository @Inject constructor(
private val remoteSource: RemoteDataSource,
private val localSource: LocalDataSource,
private val mappers: Mappers,
private val settingsRepository: SettingsRepository
) {

suspend fun load(
idTrakt: IdTrakt,
force: Boolean = false,
): Movie {
val local = localSource.movies.getById(idTrakt.id)
if (force || local == null || nowUtcMillis() - local.updatedAt > Config.MOVIE_DETAILS_CACHE_DURATION) {
if (force
|| local == null
|| (local.currentCountry != settingsRepository.country)
|| nowUtcMillis() - local.updatedAt > Config.MOVIE_DETAILS_CACHE_DURATION) {
val remote = remoteSource.trakt.fetchMovie(idTrakt.id)
val movie = mappers.movie.fromNetwork(remote)
val releases: Releases = remoteSource.tmdb.fetchMovieRelease(movie.ids.tmdb.id)
val localRelease = getLocalReleaseDate(releases)
if (localRelease != null) {
movie.released = localRelease
movie.year = localRelease.year
movie.currentCountry = settingsRepository.country
} else { movie.currentCountry = null }
localSource.movies.upsert(listOf(mappers.movie.toDatabase(movie)))
localSource.moviesSyncLog.upsert(MoviesSyncLog(movie.traktId, nowUtcMillis()))
return movie
}
return mappers.movie.fromDatabase(local)
}

private fun getLocalReleaseDate(releaseInfos: Releases): LocalDate? {
val countryCode = settingsRepository.country.uppercase()
val localReleases = releaseInfos.results.find { it.iso_3166_1 == countryCode }
val localRelease = localReleases?.release_dates?.find { it.type > 2 }
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
return localRelease?.release_date?.let { LocalDate.parse(it.toString(), formatter) }
}

suspend fun find(idImdb: IdImdb): Movie? {
val localMovie = localSource.movies.getById(idImdb.id)
if (localMovie != null) {
Expand Down
Loading