diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/MediaReportService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/MediaReportService.kt new file mode 100644 index 00000000..14a93ba2 --- /dev/null +++ b/app/src/main/java/com/github/damontecres/wholphin/services/MediaReportService.kt @@ -0,0 +1,80 @@ +package com.github.damontecres.wholphin.services + +import android.content.Context +import android.os.Build +import com.github.damontecres.wholphin.data.ServerRepository +import com.github.damontecres.wholphin.services.hilt.IoCoroutineScope +import com.github.damontecres.wholphin.ui.launchIO +import com.github.damontecres.wholphin.ui.showToast +import com.github.damontecres.wholphin.util.ExceptionHandler +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.CoroutineScope +import kotlinx.serialization.json.Json +import org.jellyfin.sdk.api.client.ApiClient +import org.jellyfin.sdk.api.client.extensions.clientLogApi +import org.jellyfin.sdk.api.client.extensions.userLibraryApi +import org.jellyfin.sdk.model.ClientInfo +import org.jellyfin.sdk.model.DeviceInfo +import org.jellyfin.sdk.model.UUID +import org.jellyfin.sdk.model.api.BaseItemDto +import timber.log.Timber +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class MediaReportService + @Inject + constructor( + @param:ApplicationContext private val context: Context, + private val api: ApiClient, + private val serverRepository: ServerRepository, + private val userPreferencesService: UserPreferencesService, + private val clientInfo: ClientInfo, + private val deviceInfo: DeviceInfo, + private val deviceProfileService: DeviceProfileService, + @param:IoCoroutineScope private val ioScope: CoroutineScope, + ) { + val json = + Json { + encodeDefaults = false + } + + fun sendReportFor(itemId: UUID) { + ioScope.launchIO(ExceptionHandler(autoToast = true)) { + val item = api.userLibraryApi.getItem(itemId = itemId).content + sendReportFor(item) + } + } + + suspend fun sendReportFor(item: BaseItemDto) { + val sources = + item.mediaSources ?: api.userLibraryApi + .getItem(itemId = item.id) + .content.mediaSources + val sourcesJson = json.encodeToString(sources) + val playbackPrefs = userPreferencesService.getCurrent().appPreferences.playbackPreferences + val serverVersion = serverRepository.currentServer.value?.serverVersion + val deviceProfile = + deviceProfileService.getOrCreateDeviceProfile(playbackPrefs, serverVersion) + val deviceProfileJson = json.encodeToString(deviceProfile) + val body = + """ + Send media info + serverVersion=$serverVersion + clientInfo=$clientInfo + deviceInfo=$deviceInfo + manufacturer=${Build.MANUFACTURER} + model=${Build.MODEL} + apiLevel=${Build.VERSION.SDK_INT} + + playbackPrefs=${playbackPrefs.toString().replace("\n", ", ").replace("\t", " ")} + + deviceProfile=$deviceProfileJson + + mediaSources=$sourcesJson + """.trimIndent() + Timber.w(body) + val response by api.clientLogApi.logFile(body) + showToast(context, "Sent! Filename=${response.fileName}") + } + } diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderGrid.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderGrid.kt index 89cda77e..6d20211f 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderGrid.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/CollectionFolderGrid.kt @@ -58,6 +58,7 @@ import com.github.damontecres.wholphin.data.model.LibraryDisplayInfo import com.github.damontecres.wholphin.preferences.UserPreferences import com.github.damontecres.wholphin.services.BackdropService import com.github.damontecres.wholphin.services.FavoriteWatchManager +import com.github.damontecres.wholphin.services.MediaReportService import com.github.damontecres.wholphin.services.NavigationManager import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.RequestOrRestoreFocus @@ -120,6 +121,7 @@ class CollectionFolderViewModel private val favoriteWatchManager: FavoriteWatchManager, private val backdropService: BackdropService, val navigationManager: NavigationManager, + val mediaReportService: MediaReportService, @Assisted itemId: String, @Assisted initialSortAndDirection: SortAndDirection?, @Assisted("recursive") private val recursive: Boolean, @@ -664,6 +666,7 @@ fun CollectionFolderGrid( playlistViewModel.loadPlaylists(MediaType.VIDEO) showPlaylistDialog.makePresent(it) }, + onSendMediaInfo = viewModel.mediaReportService::sendReportFor, ), ), onDismissRequest = { moreDialog.makeAbsent() }, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedContent.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedContent.kt index 869a454d..24b3d502 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedContent.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedContent.kt @@ -22,6 +22,7 @@ import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.preferences.UserPreferences import com.github.damontecres.wholphin.services.BackdropService import com.github.damontecres.wholphin.services.FavoriteWatchManager +import com.github.damontecres.wholphin.services.MediaReportService import com.github.damontecres.wholphin.services.NavigationManager import com.github.damontecres.wholphin.ui.OneTimeLaunchedEffect import com.github.damontecres.wholphin.ui.data.AddPlaylistViewModel @@ -46,6 +47,7 @@ abstract class RecommendedViewModel( val context: Context, val navigationManager: NavigationManager, val favoriteWatchManager: FavoriteWatchManager, + val mediaReportService: MediaReportService, private val backdropService: BackdropService, ) : ViewModel() { abstract fun init() @@ -190,6 +192,7 @@ fun RecommendedContent( playlistViewModel.loadPlaylists(MediaType.VIDEO) showPlaylistDialog.makePresent(it) }, + onSendMediaInfo = viewModel.mediaReportService::sendReportFor, ), ), onDismissRequest = { moreDialog.makeAbsent() }, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedMovie.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedMovie.kt index 866efbf3..e44c72f7 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedMovie.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedMovie.kt @@ -14,6 +14,7 @@ import com.github.damontecres.wholphin.preferences.AppPreferences import com.github.damontecres.wholphin.preferences.UserPreferences import com.github.damontecres.wholphin.services.BackdropService import com.github.damontecres.wholphin.services.FavoriteWatchManager +import com.github.damontecres.wholphin.services.MediaReportService import com.github.damontecres.wholphin.services.NavigationManager import com.github.damontecres.wholphin.services.SuggestionService import com.github.damontecres.wholphin.services.SuggestionsResource @@ -58,8 +59,15 @@ class RecommendedMovieViewModel @Assisted val parentId: UUID, navigationManager: NavigationManager, favoriteWatchManager: FavoriteWatchManager, + mediaReportService: MediaReportService, backdropService: BackdropService, - ) : RecommendedViewModel(context, navigationManager, favoriteWatchManager, backdropService) { + ) : RecommendedViewModel( + context, + navigationManager, + favoriteWatchManager, + mediaReportService, + backdropService, + ) { @AssistedFactory interface Factory { fun create(parentId: UUID): RecommendedMovieViewModel diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedTvShow.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedTvShow.kt index 2decd21a..4e952033 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedTvShow.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/components/RecommendedTvShow.kt @@ -14,6 +14,7 @@ import com.github.damontecres.wholphin.preferences.UserPreferences import com.github.damontecres.wholphin.services.BackdropService import com.github.damontecres.wholphin.services.FavoriteWatchManager import com.github.damontecres.wholphin.services.LatestNextUpService +import com.github.damontecres.wholphin.services.MediaReportService import com.github.damontecres.wholphin.services.NavigationManager import com.github.damontecres.wholphin.services.SuggestionService import com.github.damontecres.wholphin.services.SuggestionsResource @@ -62,8 +63,15 @@ class RecommendedTvShowViewModel @Assisted val parentId: UUID, navigationManager: NavigationManager, favoriteWatchManager: FavoriteWatchManager, + mediaReportService: MediaReportService, backdropService: BackdropService, - ) : RecommendedViewModel(context, navigationManager, favoriteWatchManager, backdropService) { + ) : RecommendedViewModel( + context, + navigationManager, + favoriteWatchManager, + mediaReportService, + backdropService, + ) { @AssistedFactory interface Factory { fun create(parentId: UUID): RecommendedTvShowViewModel diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/DebugPage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/DebugPage.kt index f0ad2c0c..0abcdc07 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/DebugPage.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/DebugPage.kt @@ -49,6 +49,7 @@ import org.jellyfin.sdk.api.client.ApiClient import org.jellyfin.sdk.api.client.extensions.clientLogApi import org.jellyfin.sdk.model.ClientInfo import org.jellyfin.sdk.model.DeviceInfo +import timber.log.Timber import java.io.BufferedReader import java.io.InputStreamReader import javax.inject.Inject @@ -137,9 +138,13 @@ class DebugViewModel Send App Logs clientInfo=$clientInfo deviceInfo=$deviceInfo + manufacturer=${Build.MANUFACTURER} + model=${Build.MODEL} + apiLevel=${Build.VERSION.SDK_INT} - """.trimIndent() + logcat - val response by api.clientLogApi.logFile(body) + """.trimIndent() + Timber.w(body) + val response by api.clientLogApi.logFile(body + logcat) showToast(context, "Sent! Filename=${response.fileName}") } } @@ -253,6 +258,7 @@ fun DebugPage( "DeviceInfo: ${viewModel.deviceInfo}", "Manufacturer: ${Build.MANUFACTURER}", "Model: ${Build.MODEL}", + "API Level: ${Build.VERSION.SDK_INT}", "Display Modes:", *viewModel.refreshRateService.supportedDisplayModes, ).forEach { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/DetailUtils.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/DetailUtils.kt index 8a210c27..cebfff70 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/DetailUtils.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/DetailUtils.kt @@ -25,9 +25,10 @@ import kotlin.time.Duration.Companion.seconds data class MoreDialogActions( val navigateTo: (Destination) -> Unit, - var onClickWatch: (UUID, Boolean) -> Unit, - var onClickFavorite: (UUID, Boolean) -> Unit, - var onClickAddPlaylist: (UUID) -> Unit, + val onClickWatch: (UUID, Boolean) -> Unit, + val onClickFavorite: (UUID, Boolean) -> Unit, + val onClickAddPlaylist: (UUID) -> Unit, + val onSendMediaInfo: (UUID) -> Unit, ) enum class ClearChosenStreams { @@ -205,6 +206,14 @@ fun buildMoreDialogItems( ) }, ) + add( + DialogItem( + text = R.string.send_media_info_log_to_server, + iconStringRes = R.string.fa_file_video, + ) { + actions.onSendMediaInfo.invoke(item.id) + }, + ) } fun buildMoreDialogItemsForHome( @@ -314,6 +323,14 @@ fun buildMoreDialogItemsForHome( }, ) } + add( + DialogItem( + text = R.string.send_media_info_log_to_server, + iconStringRes = R.string.fa_file_video, + ) { + actions.onSendMediaInfo.invoke(itemId) + }, + ) } fun buildMoreDialogItemsForPerson( diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/discover/DiscoverMovieDetails.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/discover/DiscoverMovieDetails.kt index 3c22e8a9..7df86615 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/discover/DiscoverMovieDetails.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/discover/DiscoverMovieDetails.kt @@ -108,6 +108,7 @@ fun DiscoverMovieDetails( onClickWatch = { itemId, watched -> }, onClickFavorite = { itemId, favorite -> }, onClickAddPlaylist = { itemId -> }, + onSendMediaInfo = {}, ) when (val state = loading) { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/episode/EpisodeDetails.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/episode/EpisodeDetails.kt index ead6cfd4..bac9f51a 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/episode/EpisodeDetails.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/episode/EpisodeDetails.kt @@ -97,6 +97,7 @@ fun EpisodeDetails( playlistViewModel.loadPlaylists(MediaType.VIDEO) showPlaylistDialog.makePresent(itemId) }, + onSendMediaInfo = viewModel.mediaReportService::sendReportFor, ) when (val state = loading) { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/episode/EpisodeViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/episode/EpisodeViewModel.kt index ee93050e..7808141e 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/episode/EpisodeViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/episode/EpisodeViewModel.kt @@ -12,6 +12,7 @@ import com.github.damontecres.wholphin.data.model.ItemPlayback import com.github.damontecres.wholphin.preferences.ThemeSongVolume import com.github.damontecres.wholphin.services.BackdropService import com.github.damontecres.wholphin.services.FavoriteWatchManager +import com.github.damontecres.wholphin.services.MediaReportService import com.github.damontecres.wholphin.services.NavigationManager import com.github.damontecres.wholphin.services.StreamChoiceService import com.github.damontecres.wholphin.services.ThemeSongPlayer @@ -48,6 +49,7 @@ class EpisodeViewModel val serverRepository: ServerRepository, val itemPlaybackRepository: ItemPlaybackRepository, val streamChoiceService: StreamChoiceService, + val mediaReportService: MediaReportService, private val themeSongPlayer: ThemeSongPlayer, private val favoriteWatchManager: FavoriteWatchManager, private val userPreferencesService: UserPreferencesService, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/movie/MovieDetails.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/movie/MovieDetails.kt index a5d3a7c6..23ed08c3 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/movie/MovieDetails.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/movie/MovieDetails.kt @@ -125,6 +125,7 @@ fun MovieDetails( playlistViewModel.loadPlaylists(MediaType.VIDEO) showPlaylistDialog.makePresent(itemId) }, + onSendMediaInfo = viewModel.mediaReportService::sendReportFor, ) when (val state = loading) { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/movie/MovieViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/movie/MovieViewModel.kt index 8454f0a1..ed46656c 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/movie/MovieViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/movie/MovieViewModel.kt @@ -18,6 +18,7 @@ import com.github.damontecres.wholphin.preferences.ThemeSongVolume import com.github.damontecres.wholphin.services.BackdropService import com.github.damontecres.wholphin.services.ExtrasService import com.github.damontecres.wholphin.services.FavoriteWatchManager +import com.github.damontecres.wholphin.services.MediaReportService import com.github.damontecres.wholphin.services.NavigationManager import com.github.damontecres.wholphin.services.PeopleFavorites import com.github.damontecres.wholphin.services.SeerrService @@ -64,6 +65,7 @@ class MovieViewModel val serverRepository: ServerRepository, val itemPlaybackRepository: ItemPlaybackRepository, val streamChoiceService: StreamChoiceService, + val mediaReportService: MediaReportService, private val themeSongPlayer: ThemeSongPlayer, private val favoriteWatchManager: FavoriteWatchManager, private val peopleFavorites: PeopleFavorites, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesDetails.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesDetails.kt index cef5412b..55335057 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesDetails.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesDetails.kt @@ -230,6 +230,7 @@ fun SeriesDetails( playlistViewModel.loadPlaylists(MediaType.VIDEO) showPlaylistDialog.makePresent(itemId) }, + onSendMediaInfo = viewModel.mediaReportService::sendReportFor, ), ) if (showWatchConfirmation) { diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesOverview.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesOverview.kt index d95a5bbb..a8a9d83f 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesOverview.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesOverview.kt @@ -215,6 +215,7 @@ fun SeriesOverview( playlistViewModel.loadPlaylists(MediaType.VIDEO) showPlaylistDialog = it }, + onSendMediaInfo = viewModel.mediaReportService::sendReportFor, ), onChooseVersion = { chooseVersion = diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesViewModel.kt index 8ae7a579..3d80aa9d 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/detail/series/SeriesViewModel.kt @@ -16,6 +16,7 @@ import com.github.damontecres.wholphin.data.model.Trailer import com.github.damontecres.wholphin.services.BackdropService import com.github.damontecres.wholphin.services.ExtrasService import com.github.damontecres.wholphin.services.FavoriteWatchManager +import com.github.damontecres.wholphin.services.MediaReportService import com.github.damontecres.wholphin.services.NavigationManager import com.github.damontecres.wholphin.services.PeopleFavorites import com.github.damontecres.wholphin.services.SeerrService @@ -85,6 +86,7 @@ class SeriesViewModel private val trailerService: TrailerService, private val extrasService: ExtrasService, val streamChoiceService: StreamChoiceService, + val mediaReportService: MediaReportService, private val userPreferencesService: UserPreferencesService, private val backdropService: BackdropService, private val seerrService: SeerrService, diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomePage.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomePage.kt index ac946d8b..9f67dd2e 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomePage.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomePage.kt @@ -138,6 +138,7 @@ fun HomePage( playlistViewModel.loadPlaylists(MediaType.VIDEO) showPlaylistDialog = itemId }, + onSendMediaInfo = viewModel.mediaReportService::sendReportFor, ), ) dialog = diff --git a/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt b/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt index 1911e34d..8e7846b8 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/ui/main/HomeViewModel.kt @@ -13,6 +13,7 @@ import com.github.damontecres.wholphin.services.BackdropService import com.github.damontecres.wholphin.services.DatePlayedService import com.github.damontecres.wholphin.services.FavoriteWatchManager import com.github.damontecres.wholphin.services.LatestNextUpService +import com.github.damontecres.wholphin.services.MediaReportService import com.github.damontecres.wholphin.services.NavigationManager import com.github.damontecres.wholphin.services.UserPreferencesService import com.github.damontecres.wholphin.ui.launchIO @@ -44,6 +45,7 @@ class HomeViewModel val navigationManager: NavigationManager, val serverRepository: ServerRepository, val navDrawerItemRepository: NavDrawerItemRepository, + val mediaReportService: MediaReportService, private val favoriteWatchManager: FavoriteWatchManager, private val datePlayedService: DatePlayedService, private val latestNextUpService: LatestNextUpService, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c0021de1..63c7c3d2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -484,6 +484,7 @@ Zoom out Slideshow duration Play videos during slideshow + Send media info log to server Disabled