🚧 first request from api

features/retrofit/1
Jordan ARTZET 2 years ago
parent 3cfc7d73b4
commit 904a5078ef

@ -66,10 +66,13 @@ dependencies {
// Moshi
implementation "com.squareup.moshi:moshi-kotlin:1.13.0"
//GSON
//implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
// Retrofit
implementation "com.squareup.retrofit2:retrofit:2.9.0"
// Retrofit with Scalar Converter
implementation "com.squareup.retrofit2:converter-scalars:2.9.0"
//implementation "com.squareup.retrofit2:converter-scalars:2.9.0"
// Retrofit with Moshi Converter
implementation "com.squareup.retrofit2:converter-moshi:2.9.0"

@ -1,18 +1,18 @@
package fr.iut.pm.movieapplication.api
import fr.iut.pm.movieapplication.network.dtos.PopularDTO
import fr.iut.pm.movieapplication.utils.Constants
import fr.iut.pm.movieapplication.utils.Constants.Companion.API_KEY
import kotlinx.coroutines.flow.Flow
import fr.iut.pm.movieapplication.api.dtos.MovieResultDTO
import fr.iut.pm.movieapplication.api.dtos.PopularDTO
import retrofit2.Call
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Path
import retrofit2.http.Query
interface MovieApplicationAPI {
@GET("movie/popular")
suspend fun getPopularMovies(@Query("api_key") apiKey : String) : Call<PopularDTO>
fun getPopularMovies(@Query("api_key") apiKey : String) : Call<PopularDTO>
@GET("movie/{movie_id")
fun getMovieDetails(@Path("movie_id") movieId : Int, @Query("api_key") apiKey: String) : Call<MovieResultDTO>
}

@ -6,22 +6,18 @@ import fr.iut.pm.movieapplication.utils.Constants.Companion.BASE_URL
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
object RetrofitInstance {
private val retrofit by lazy {
Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.baseUrl(BASE_URL)
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
}
val api : MovieApplicationAPI by lazy {
retrofit.create(MovieApplicationAPI::class.java)
}
private val retrofit = Retrofit.Builder()
.baseUrl("https://api.themoviedb.org/3/")
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
val api = retrofit.create(MovieApplicationAPI::class.java)
}

@ -0,0 +1,44 @@
package fr.iut.pm.movieapplication.api.dtos
import androidx.room.ColumnInfo
import androidx.room.Embedded
import androidx.room.PrimaryKey
import androidx.room.Relation
import com.squareup.moshi.Json
import fr.iut.pm.movieapplication.model.Genre
import fr.iut.pm.movieapplication.model.ProductionCompany
import fr.iut.pm.movieapplication.model.ProductionCountry
import fr.iut.pm.movieapplication.network.dtos.GenreDTO
class MovieDTO (
val adult: Boolean,
val budget: Int,
val genres: Array<GenreDTO>?,
val homepage: String?,
val id: Int,
@Json(name = "original_language")
val originalLanguage: String,
@Json(name = "original_title")
val originalTitle: String,
val overview: String?,
val popularity: Double,
@Json(name = "poster_path")
val posterPath: String?,
@Json(name = "production_countries")
val productionCountries: Array<ProductionCountry>,
@Json(name = "release_date")
val releaseDate: String,
val revenue: Int,
val runtime: Int?,
//var spokenLanguages : Array<SpokenLanguage>,
val status: String,
@Json(name = "tag_line")
val tagLine: String?,
val title: String,
@Json(name = "vote_average")
val voteAverage: Double,
@Json(name = "vote_count")
val voteCount: Int,
val backdropPath: String?
){
}

@ -0,0 +1,40 @@
package fr.iut.pm.movieapplication.api.dtos
import com.squareup.moshi.Json
class MovieResultDTO(
@Json(name = "poster_path")
val posterPath : String?,
@Json(name = "adult")
val adult : Boolean,
@Json(name = "overview")
val overview : String,
@Json(name = "release_date")
val releaseDate : String?,
@Json(name = "genre_ids")
val genreIds : List<Int>?,
@Json(name = "id")
val id : Int,
@Json(name = "original_title")
val originalTitle : String?,
@Json(name = "original_language")
val originalLanguage : String?,
@Json(name = "title")
val title : String?,
@Json(name = "backdrop_path")
val backdropPath : String?,
@Json(name = "popularity")
val popularity : Double?,
@Json(name = "vote_count")
val voteCount : Int?,
val video : Boolean?,
@Json(name = "vote_average")
val voteAverage : Double?
) {
}

@ -0,0 +1,18 @@
package fr.iut.pm.movieapplication.api.dtos
import com.squareup.moshi.Json
class PopularDTO(
@Json(name = "page")
val page : Int,
@Json(name = "results")
val results : List<MovieResultDTO>,
@Json(name = "total_results")
val totalResults : Int,
@Json(name = "total_pages")
val totalPages : Int
) {}

@ -1,57 +1,50 @@
package fr.iut.pm.movieapplication.model
import androidx.room.ColumnInfo
import androidx.room.Embedded
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.Relation
import java.util.Date
@Entity(tableName = "movies_table")
data class Movie(
@ColumnInfo(name = "adult")
val adult: Boolean,
@ColumnInfo(name = "budget")
val budget: Int,
val budget: Int?,
@ColumnInfo(name = "genres")
val genres: Array<Genre>,
val genres: Array<Genre>?,
@ColumnInfo(name = "homepage")
val homePage: String?,
@PrimaryKey
@ColumnInfo(name = "id")
val movieId: Int,
@ColumnInfo(name = "original_language")
val originalLanguage: String,
val originalLanguage: String?,
@ColumnInfo(name = "original_title")
val originalTitle: String,
val originalTitle: String?,
val overview: String?,
val popularity: Int,
val popularity: Double?,
@ColumnInfo(name = "poster_path")
val posterPath : String?,
@Embedded
val productionCompanies: Array<ProductionCompany>,
@Relation(
parentColumn = "movieId",
entityColumn = ""
)
val posterPath: String?,
val productionCompanies: Array<ProductionCompany>?,
@ColumnInfo(name = "production_countries")
val productionCountries: Array<ProductionCountry>,
val productionCountries: Array<ProductionCountry>?,
@ColumnInfo(name = "release_date")
val releaseDate: Date,
val revenue: Int,
val releaseDate: String?,
val revenue: Int?,
val runtime: Int?,
//var spokenLanguages : Array<SpokenLanguage>,
val status: String,
val status: String?,
@ColumnInfo(name = "tag_line")
val tagLine: String?,
val title: String,
val title: String?,
@ColumnInfo(name = "vote_average")
val voteAverage: Number,
val voteAverage: Double?,
@ColumnInfo(name = "vote_count")
val voteCount : Int
val voteCount: Int?,
val backdropPath: String?
) {
) {
override fun equals(other: Any?): Boolean {

@ -1,25 +0,0 @@
package fr.iut.pm.movieapplication.network.dtos
import com.squareup.moshi.Json
data class MovieDTO(
@Json(name = "poster_path")
val posterPath : String?,
val adult : Boolean,
val overview : String?,
@Json(name = "release_date")
val releaseDate : String,
@Json(name = "genre_ids")
val genreIds : List<Int>,
val id : Int,
@Json(name = "original_title")
val originalTitle : String,
@Json(name = "original_language")
val originalLanguage : String,
val title : String
) {
}

@ -1,12 +0,0 @@
package fr.iut.pm.movieapplication.network.dtos
import com.squareup.moshi.Json
data class PopularDTO(
val page : Int,
val results : List<MovieDTO>,
@Json(name = "total_pages")
val totalPages : Int,
@Json(name = "total_results")
val totalResults : Int
) {}

@ -1,15 +1,44 @@
package fr.iut.pm.movieapplication.repository
import fr.iut.pm.movieapplication.data.dao.MovieDAO
import android.util.Log
import fr.iut.pm.movieapplication.api.RetrofitInstance
import fr.iut.pm.movieapplication.api.dtos.PopularDTO
import fr.iut.pm.movieapplication.model.Movie
import fr.iut.pm.movieapplication.network.dtos.MovieDTO
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.transform
import fr.iut.pm.movieapplication.utils.Constants
import fr.iut.pm.movieapplication.utils.Constants.Companion.API_KEY
import fr.iut.pm.movieapplication.utils.Mapper
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class MovieRepository() {
suspend fun getPopularMovies() : List<MovieDTO>{
return PopularRepository().getPopular()!!.results
fun getPopularMovies(callback: (List<Movie>) -> Unit ) {
val listMovie : MutableList<Movie> = mutableListOf()
RetrofitInstance.api.getPopularMovies(API_KEY).enqueue(object :
Callback<PopularDTO> {
override fun onResponse(call: Call<PopularDTO>, response: Response<PopularDTO>) {
if (response.isSuccessful) {
Log.d("List :", response.body().toString())
val popularDTO = response.body()
val listMoviesDTO = popularDTO?.results
listMoviesDTO?.forEach {
val movie = Mapper.MapToMovie(it)
listMovie.add(movie)
Log.d("Movie ", movie.title!!)
}
}
callback(listMovie)
}
override fun onFailure(call: Call<PopularDTO>, t: Throwable) {
Log.d("Error failure", t.message.toString())
}
})
}
}

@ -2,9 +2,8 @@ package fr.iut.pm.movieapplication.repository
import android.util.Log
import fr.iut.pm.movieapplication.api.RetrofitInstance
import fr.iut.pm.movieapplication.network.dtos.PopularDTO
import fr.iut.pm.movieapplication.api.dtos.PopularDTO
import fr.iut.pm.movieapplication.utils.Constants.Companion.API_KEY
import kotlinx.coroutines.flow.Flow
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
@ -12,22 +11,6 @@ import retrofit2.Response
class PopularRepository() {
suspend fun getPopular(): PopularDTO? {
lateinit var popularDTO : PopularDTO
RetrofitInstance.api.getPopularMovies(API_KEY).enqueue(object : Callback<PopularDTO> {
override fun onResponse(call: Call<PopularDTO>, response: Response<PopularDTO>) {
if (response.isSuccessful) {
Log.d("RESPONSE ::", response.body()?.page.toString())
popularDTO = response.body()!!
}
}
override fun onFailure(call: Call<PopularDTO>, t: Throwable) {
TODO("Not yet implemented")
}
})
return popularDTO
throw NoSuchMethodError()
}
}

@ -3,16 +3,14 @@ package fr.iut.pm.movieapplication.ui.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import fr.iut.pm.movieapplication.R
import fr.iut.pm.movieapplication.network.dtos.MovieDTO
import fr.iut.pm.movieapplication.model.Movie
import fr.iut.pm.movieapplication.ui.activity.MainActivity
class HomeItemAdapter(
private val context : MainActivity,
private val layoutId : Int,
private val list : List<MovieDTO>
private val context: MainActivity,
private val layoutId: Int,
private val list: List<Movie>
) : RecyclerView.Adapter<HomeItemAdapter.ViewHolder>() {
class ViewHolder(view : View) : RecyclerView.ViewHolder(view) {

@ -7,8 +7,8 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import fr.iut.pm.movieapplication.R
import fr.iut.pm.movieapplication.network.dtos.MovieDTO
import fr.iut.pm.movieapplication.network.dtos.PopularDTO
import fr.iut.pm.movieapplication.api.dtos.MovieResultDTO
import fr.iut.pm.movieapplication.model.Movie
import fr.iut.pm.movieapplication.ui.activity.MainActivity
import fr.iut.pm.movieapplication.ui.adapter.HomeItemAdapter
import fr.iut.pm.movieapplication.ui.adapter.HomeItemDecoration
@ -23,12 +23,12 @@ class HomeSectionsFragment(private val context : MainActivity) : Fragment() {
//get the trends RecyclerView
val homeTrendsRecyclerView = view?.findViewById<RecyclerView>(R.id.home_trends_recycler_view)
homeTrendsRecyclerView?.adapter = HomeItemAdapter(context,R.layout.item_horizontal_home_page,ArrayList<MovieDTO>())
homeTrendsRecyclerView?.adapter = HomeItemAdapter(context,R.layout.item_horizontal_home_page,ArrayList<Movie>())
homeTrendsRecyclerView?.addItemDecoration(HomeItemDecoration())
//get the popularity RecyclerView
val homePopularityRecyclerView = view?.findViewById<RecyclerView>(R.id.home_popularity_recycler_view)
homePopularityRecyclerView?.adapter = HomeItemAdapter(context,R.layout.item_horizontal_home_page,ArrayList<MovieDTO>())
homePopularityRecyclerView?.adapter = HomeItemAdapter(context,R.layout.item_horizontal_home_page,ArrayList<Movie>())
homePopularityRecyclerView?.addItemDecoration(HomeItemDecoration())
//get the free RecyclerView

@ -6,43 +6,45 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.viewModelFactory
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import fr.iut.pm.movieapplication.R
import fr.iut.pm.movieapplication.data.dao.MovieDAO
import fr.iut.pm.movieapplication.network.dtos.MovieDTO
import fr.iut.pm.movieapplication.network.dtos.PopularDTO
import fr.iut.pm.movieapplication.api.RetrofitInstance
import fr.iut.pm.movieapplication.model.Movie
import fr.iut.pm.movieapplication.repository.MovieRepository
import fr.iut.pm.movieapplication.ui.activity.MainActivity
import fr.iut.pm.movieapplication.ui.adapter.CategoryItemDecoration
import fr.iut.pm.movieapplication.ui.adapter.HomeItemAdapter
import fr.iut.pm.movieapplication.ui.adapter.HomeItemDecoration
import fr.iut.pm.movieapplication.ui.viewmodel.MoviesVM
import fr.iut.pm.movieapplication.ui.viewmodel.MoviesVMFactory
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.runBlocking
import fr.iut.pm.movieapplication.ui.viewmodel.viewModelFactory
import kotlinx.coroutines.launch
class MoviesFragment(
private val context : MainActivity
) : Fragment() {
private val moviesVM: MoviesVM by viewModels{ MoviesVMFactory(repository = MovieRepository())}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_movies, container, false)
val viewModel by viewModels<MoviesVM> {
MoviesVMFactory(MovieRepository())
val repository = MovieRepository()
repository.getPopularMovies { listMovies ->
val moviesRecyclerView = view?.findViewById<RecyclerView>(R.id.movies_item_recycler_view)
moviesRecyclerView?.adapter = HomeItemAdapter(context, R.layout.item_vertical_fragment, listMovies)
moviesRecyclerView ?. layoutManager = GridLayoutManager (context, 2)
moviesRecyclerView?.addItemDecoration(CategoryItemDecoration())
}
val moviesRecyclerView = view?.findViewById<RecyclerView>(R.id.movies_item_recycler_view)
moviesRecyclerView?.adapter = HomeItemAdapter(context, R.layout.item_vertical_fragment,viewModel.popularMovies.value!!)
moviesRecyclerView?.layoutManager = GridLayoutManager(context, 2)
moviesRecyclerView?.addItemDecoration(CategoryItemDecoration())
return view

@ -1,46 +1,37 @@
package fr.iut.pm.movieapplication.ui.viewmodel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import fr.iut.pm.movieapplication.network.dtos.MovieDTO
import androidx.lifecycle.*
import fr.iut.pm.movieapplication.api.dtos.MovieResultDTO
import fr.iut.pm.movieapplication.model.Movie
import fr.iut.pm.movieapplication.repository.MovieRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class MoviesVM(private val repository: MovieRepository) : ViewModel() {
private val _popularMovies = MutableLiveData<List<MovieDTO>>()
val popularMovies : MutableLiveData<List<MovieDTO>> = _popularMovies
private val _popularMovies = MutableLiveData<List<Movie>>()
val popularMovies : LiveData<List<Movie>> = _popularMovies
init {
getPopularMovies()
//loadData()
}
private fun getPopularMovies() {
suspend fun loadData() {
viewModelScope.launch {
try {
_popularMovies.value = repository.getPopularMovies()}
catch (e : Exception) {
e.stackTrace
repository.getPopularMovies { movies ->
_popularMovies.value = movies
}
}.join()
}
}
}
class MoviesVMFactory(
private val repository: MovieRepository
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MoviesVM::class.java)) {
return MoviesVM(repository) as T
}
throw java.lang.IllegalArgumentException("Unknown ViewModel class")
return MoviesVM(repository) as T
}
}

@ -0,0 +1,9 @@
package fr.iut.pm.movieapplication.ui.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
inline fun <VM : ViewModel> viewModelFactory(crossinline f: () -> VM) =
object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T = f() as T
}

@ -0,0 +1,36 @@
package fr.iut.pm.movieapplication.utils
import fr.iut.pm.movieapplication.api.dtos.MovieResultDTO
import fr.iut.pm.movieapplication.model.Movie
object Mapper {
fun MapToMovie( movieDTO : MovieResultDTO) : Movie {
return Movie(
adult = movieDTO.adult,
posterPath = movieDTO.posterPath,
overview = movieDTO.overview,
releaseDate = movieDTO.releaseDate,
movieId = movieDTO.id,
originalTitle = movieDTO.originalTitle,
originalLanguage = movieDTO.originalLanguage,
title = movieDTO.title,
backdropPath = movieDTO.backdropPath,
popularity = movieDTO.popularity,
voteCount = movieDTO.voteCount,
voteAverage = movieDTO.voteAverage,
budget = null,
genres = null,
homePage = null,
productionCompanies = null,
productionCountries = null,
revenue = null,
runtime = null,
status = null,
tagLine = null
)
}
}
Loading…
Cancel
Save