mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-25 02:14:32 +01:00
Gaana Implementation Done
This commit is contained in:
parent
180a284a54
commit
d97536ee50
@ -17,8 +17,11 @@
|
|||||||
|
|
||||||
package com.shabinder.spotiflyer.models.gaana
|
package com.shabinder.spotiflyer.models.gaana
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
|
||||||
data class Artist (
|
data class Artist (
|
||||||
val popularity : Int,
|
val popularity : Int,
|
||||||
val seokey : String,
|
val seokey : String,
|
||||||
val name : String,
|
val name : String,
|
||||||
|
@Json(name = "artwork_175x175")var artworkLink :String?
|
||||||
)
|
)
|
@ -18,8 +18,7 @@
|
|||||||
package com.shabinder.spotiflyer.models.gaana
|
package com.shabinder.spotiflyer.models.gaana
|
||||||
|
|
||||||
data class GaanaPlaylist (
|
data class GaanaPlaylist (
|
||||||
val tags : String,
|
val tags : String?,
|
||||||
val fromCache : Int,
|
|
||||||
val modified_on : String,
|
val modified_on : String,
|
||||||
val count : Int,
|
val count : Int,
|
||||||
val created_on : String,
|
val created_on : String,
|
||||||
|
@ -21,12 +21,13 @@ import com.shabinder.spotiflyer.models.DownloadStatus
|
|||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
|
|
||||||
data class GaanaTrack (
|
data class GaanaTrack (
|
||||||
val tags : List<Tags>,
|
val tags : List<Tags?>?,
|
||||||
val seokey : String,
|
val seokey : String,
|
||||||
val albumseokey : String,
|
val albumseokey : String,
|
||||||
val track_title : String,
|
val track_title : String,
|
||||||
val album_title : String,
|
val album_title : String,
|
||||||
val language : String,
|
val language : String,
|
||||||
|
val duration: Int,
|
||||||
@Json(name = "artwork_large") val artworkLink : String,
|
@Json(name = "artwork_large") val artworkLink : String,
|
||||||
val artist : List<Artist>,
|
val artist : List<Artist>,
|
||||||
@Json(name = "gener") val genre : List<Genre>,
|
@Json(name = "gener") val genre : List<Genre>,
|
||||||
@ -35,6 +36,6 @@ data class GaanaTrack (
|
|||||||
val total_favourite_count : Int,
|
val total_favourite_count : Int,
|
||||||
val release_date : String,
|
val release_date : String,
|
||||||
val play_ct : String,
|
val play_ct : String,
|
||||||
val secondary_language : String,
|
val secondary_language : String?,
|
||||||
var downloaded: DownloadStatus? = DownloadStatus.NotDownloaded
|
var downloaded: DownloadStatus? = DownloadStatus.NotDownloaded
|
||||||
)
|
)
|
@ -20,4 +20,5 @@ package com.shabinder.spotiflyer.models.spotify
|
|||||||
enum class Source {
|
enum class Source {
|
||||||
Spotify,
|
Spotify,
|
||||||
YouTube,
|
YouTube,
|
||||||
|
Gaana,
|
||||||
}
|
}
|
@ -31,7 +31,7 @@ interface GaanaInterface {
|
|||||||
*
|
*
|
||||||
* subtype : ["most_popular_playlist" , "playlist_home_featured" ,"playlist_detail" ,"user_playlist" ,"topCharts"]
|
* subtype : ["most_popular_playlist" , "playlist_home_featured" ,"playlist_detail" ,"user_playlist" ,"topCharts"]
|
||||||
**/
|
**/
|
||||||
@GET
|
@GET(".")
|
||||||
suspend fun getGaanaPlaylist(
|
suspend fun getGaanaPlaylist(
|
||||||
@Query("type") type: String = "playlist",
|
@Query("type") type: String = "playlist",
|
||||||
@Query("subtype") subtype: String = "playlist_detail",
|
@Query("subtype") subtype: String = "playlist_detail",
|
||||||
@ -46,7 +46,7 @@ interface GaanaInterface {
|
|||||||
*
|
*
|
||||||
* subtype : ["most_popular" , "new_release" ,"featured_album" ,"similar_album" ,"all_albums", "album" ,"album_detail" ,"album_detail_info"]
|
* subtype : ["most_popular" , "new_release" ,"featured_album" ,"similar_album" ,"all_albums", "album" ,"album_detail" ,"album_detail_info"]
|
||||||
**/
|
**/
|
||||||
@GET
|
@GET(".")
|
||||||
suspend fun getGaanaAlbum(
|
suspend fun getGaanaAlbum(
|
||||||
@Query("type") type: String = "album",
|
@Query("type") type: String = "album",
|
||||||
@Query("subtype") subtype: String = "album_detail",
|
@Query("subtype") subtype: String = "album_detail",
|
||||||
@ -61,7 +61,7 @@ interface GaanaInterface {
|
|||||||
*
|
*
|
||||||
* subtype : ["most_popular" , "hot_songs" ,"recommendation" ,"song_detail"]
|
* subtype : ["most_popular" , "hot_songs" ,"recommendation" ,"song_detail"]
|
||||||
**/
|
**/
|
||||||
@GET
|
@GET(".")
|
||||||
suspend fun getGaanaSong(
|
suspend fun getGaanaSong(
|
||||||
@Query("type") type: String = "song",
|
@Query("type") type: String = "song",
|
||||||
@Query("subtype") subtype: String = "song_detail",
|
@Query("subtype") subtype: String = "song_detail",
|
||||||
@ -75,7 +75,7 @@ interface GaanaInterface {
|
|||||||
*
|
*
|
||||||
* subtype : ["most_popular" , "artist_list" ,"artist_track_listing" ,"artist_album" ,"similar_artist","artist_details" ,"artist_details_info"]
|
* subtype : ["most_popular" , "artist_list" ,"artist_track_listing" ,"artist_album" ,"similar_artist","artist_details" ,"artist_details_info"]
|
||||||
**/
|
**/
|
||||||
@GET
|
@GET(".")
|
||||||
suspend fun getGaanaArtistDetails(
|
suspend fun getGaanaArtistDetails(
|
||||||
@Query("type") type: String = "artist",
|
@Query("type") type: String = "artist",
|
||||||
@Query("subtype") subtype: String = "artist_details_info",
|
@Query("subtype") subtype: String = "artist_details_info",
|
||||||
@ -88,7 +88,7 @@ interface GaanaInterface {
|
|||||||
*
|
*
|
||||||
* subtype : ["most_popular" , "artist_list" ,"artist_track_listing" ,"artist_album" ,"similar_artist","artist_details" ,"artist_details_info"]
|
* subtype : ["most_popular" , "artist_list" ,"artist_track_listing" ,"artist_album" ,"similar_artist","artist_details" ,"artist_details_info"]
|
||||||
**/
|
**/
|
||||||
@GET
|
@GET(".")
|
||||||
suspend fun getGaanaArtistTracks(
|
suspend fun getGaanaArtistTracks(
|
||||||
@Query("type") type: String = "artist",
|
@Query("type") type: String = "artist",
|
||||||
@Query("subtype") subtype: String = "artist_track_listing",
|
@Query("subtype") subtype: String = "artist_track_listing",
|
||||||
|
@ -76,18 +76,18 @@ class TrackListAdapter(private val viewModel :BaseViewModel): ListAdapter<TrackD
|
|||||||
rotateAnim(it)
|
rotateAnim(it)
|
||||||
item.downloaded = DownloadStatus.Downloading
|
item.downloaded = DownloadStatus.Downloading
|
||||||
when(source){
|
when(source){
|
||||||
Source.Spotify -> {
|
Source.YouTube -> {
|
||||||
viewModel.uiScope.launch {
|
viewModel.uiScope.launch {
|
||||||
DownloadHelper.downloadAllTracks(
|
YTDownloadHelper.downloadYTTracks(
|
||||||
viewModel.folderType,
|
viewModel.folderType,
|
||||||
viewModel.subFolder,
|
viewModel.subFolder,
|
||||||
listOf(item)
|
listOf(item)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Source.YouTube -> {
|
else -> {
|
||||||
viewModel.uiScope.launch {
|
viewModel.uiScope.launch {
|
||||||
YTDownloadHelper.downloadYTTracks(
|
DownloadHelper.downloadAllTracks(
|
||||||
viewModel.folderType,
|
viewModel.folderType,
|
||||||
viewModel.subFolder,
|
viewModel.subFolder,
|
||||||
listOf(item)
|
listOf(item)
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
package com.shabinder.spotiflyer.ui.gaana
|
package com.shabinder.spotiflyer.ui.gaana
|
||||||
|
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -27,19 +29,24 @@ import android.view.ViewGroup
|
|||||||
import androidx.databinding.DataBindingUtil
|
import androidx.databinding.DataBindingUtil
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||||
import com.shabinder.spotiflyer.R
|
import com.shabinder.spotiflyer.R
|
||||||
import com.shabinder.spotiflyer.SharedViewModel
|
import com.shabinder.spotiflyer.SharedViewModel
|
||||||
import com.shabinder.spotiflyer.databinding.TrackListFragmentBinding
|
import com.shabinder.spotiflyer.databinding.TrackListFragmentBinding
|
||||||
import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
|
import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
|
||||||
import com.shabinder.spotiflyer.models.DownloadStatus
|
import com.shabinder.spotiflyer.models.DownloadStatus
|
||||||
|
import com.shabinder.spotiflyer.models.TrackDetails
|
||||||
|
import com.shabinder.spotiflyer.models.spotify.Source
|
||||||
import com.shabinder.spotiflyer.networking.GaanaInterface
|
import com.shabinder.spotiflyer.networking.GaanaInterface
|
||||||
import com.shabinder.spotiflyer.networking.YoutubeMusicApi
|
import com.shabinder.spotiflyer.networking.YoutubeMusicApi
|
||||||
import com.shabinder.spotiflyer.recyclerView.TrackListAdapter
|
import com.shabinder.spotiflyer.recyclerView.TrackListAdapter
|
||||||
import com.shabinder.spotiflyer.utils.*
|
import com.shabinder.spotiflyer.utils.*
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
class GaanaFragment : Fragment() {
|
class GaanaFragment : Fragment() {
|
||||||
|
|
||||||
private lateinit var binding: TrackListFragmentBinding
|
private lateinit var binding: TrackListFragmentBinding
|
||||||
@ -56,8 +63,9 @@ class GaanaFragment : Fragment() {
|
|||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
binding = DataBindingUtil.inflate(inflater,R.layout.track_list_fragment, container, false)
|
binding = DataBindingUtil.inflate(inflater,R.layout.track_list_fragment, container, false)
|
||||||
viewModel = ViewModelProvider(this).get(GaanaViewModel::class.java)
|
initializeAll()
|
||||||
adapter = TrackListAdapter(viewModel)
|
initializeLiveDataObservers()
|
||||||
|
initializeBroadcast()
|
||||||
|
|
||||||
val gaanaLink = GaanaFragmentArgs.fromBundle(requireArguments()).link.substringAfter("gaana.com/")
|
val gaanaLink = GaanaFragmentArgs.fromBundle(requireArguments()).link.substringAfter("gaana.com/")
|
||||||
//Link Schema: https://gaana.com/type/link
|
//Link Schema: https://gaana.com/type/link
|
||||||
@ -95,7 +103,7 @@ class GaanaFragment : Fragment() {
|
|||||||
val urlList = arrayListOf<String>()
|
val urlList = arrayListOf<String>()
|
||||||
viewModel.trackList.value?.forEach { urlList.add(it.albumArtURL) }
|
viewModel.trackList.value?.forEach { urlList.add(it.albumArtURL) }
|
||||||
//Appending Source
|
//Appending Source
|
||||||
urlList.add("spotify")
|
urlList.add("gaana")
|
||||||
loadAllImages(
|
loadAllImages(
|
||||||
requireActivity(),
|
requireActivity(),
|
||||||
urlList
|
urlList
|
||||||
@ -116,4 +124,89 @@ class GaanaFragment : Fragment() {
|
|||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic Initialization
|
||||||
|
**/
|
||||||
|
private fun initializeAll() {
|
||||||
|
sharedViewModel = ViewModelProvider(this.requireActivity()).get(SharedViewModel::class.java)
|
||||||
|
viewModel = ViewModelProvider(this).get(GaanaViewModel::class.java)
|
||||||
|
viewModel.gaanaInterface = gaanaInterface
|
||||||
|
adapter = TrackListAdapter(viewModel)
|
||||||
|
DownloadHelper.youtubeMusicApi = youtubeMusicApi
|
||||||
|
DownloadHelper.sharedViewModel = sharedViewModel
|
||||||
|
DownloadHelper.statusBar = binding.statusBar
|
||||||
|
binding.trackList.adapter = adapter
|
||||||
|
(binding.trackList.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Live Data Observers
|
||||||
|
**/
|
||||||
|
private fun initializeLiveDataObservers() {
|
||||||
|
viewModel.trackList.observe(viewLifecycleOwner, {
|
||||||
|
if (it.isNotEmpty()){
|
||||||
|
Log.i("GaanaFragment","TrackList Updated")
|
||||||
|
adapter.submitList(it,Source.Gaana)
|
||||||
|
checkIfAllDownloaded()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
viewModel.coverUrl.observe(viewLifecycleOwner, {
|
||||||
|
if(it!="Loading") bindImage(binding.coverImage,it, Source.Gaana)
|
||||||
|
})
|
||||||
|
|
||||||
|
viewModel.title.observe(viewLifecycleOwner, {
|
||||||
|
binding.titleView.text = it
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkIfAllDownloaded() {
|
||||||
|
if(!viewModel.trackList.value!!.any { it.downloaded != DownloadStatus.Downloaded }){
|
||||||
|
//All Tracks Downloaded
|
||||||
|
binding.btnDownloadAll.visibility = View.GONE
|
||||||
|
binding.downloadingFab.apply{
|
||||||
|
setImageResource(R.drawable.ic_tick)
|
||||||
|
visibility = View.VISIBLE
|
||||||
|
clearAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private fun initializeBroadcast() {
|
||||||
|
intentFilter = IntentFilter()
|
||||||
|
intentFilter?.addAction("track_download_completed")
|
||||||
|
|
||||||
|
updateUIReceiver = object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
//UI update here
|
||||||
|
if (intent != null){
|
||||||
|
val trackDetails = intent.getParcelableExtra<TrackDetails?>("track")
|
||||||
|
trackDetails?.let {
|
||||||
|
val position: Int = viewModel.trackList.value?.map { it.title }?.indexOf(trackDetails.title) ?: -1
|
||||||
|
Log.i("Track","Download Completed Intent :$position")
|
||||||
|
if(position != -1) {
|
||||||
|
val track = viewModel.trackList.value?.get(position)
|
||||||
|
track?.let{
|
||||||
|
it.downloaded = DownloadStatus.Downloaded
|
||||||
|
viewModel.trackList.value?.set(position, it)
|
||||||
|
adapter.notifyItemChanged(position)
|
||||||
|
checkIfAllDownloaded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requireActivity().registerReceiver(updateUIReceiver, intentFilter)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
initializeBroadcast()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
requireActivity().unregisterReceiver(updateUIReceiver)
|
||||||
|
}
|
||||||
}
|
}
|
@ -17,10 +17,23 @@
|
|||||||
|
|
||||||
package com.shabinder.spotiflyer.ui.gaana
|
package com.shabinder.spotiflyer.ui.gaana
|
||||||
|
|
||||||
|
import android.os.Environment
|
||||||
|
import android.util.Log
|
||||||
import androidx.hilt.lifecycle.ViewModelInject
|
import androidx.hilt.lifecycle.ViewModelInject
|
||||||
import com.shabinder.spotiflyer.database.DatabaseDAO
|
import com.shabinder.spotiflyer.database.DatabaseDAO
|
||||||
|
import com.shabinder.spotiflyer.database.DownloadRecord
|
||||||
|
import com.shabinder.spotiflyer.models.DownloadStatus
|
||||||
|
import com.shabinder.spotiflyer.models.TrackDetails
|
||||||
|
import com.shabinder.spotiflyer.models.gaana.*
|
||||||
|
import com.shabinder.spotiflyer.models.spotify.Source
|
||||||
import com.shabinder.spotiflyer.networking.GaanaInterface
|
import com.shabinder.spotiflyer.networking.GaanaInterface
|
||||||
import com.shabinder.spotiflyer.utils.BaseViewModel
|
import com.shabinder.spotiflyer.utils.BaseViewModel
|
||||||
|
import com.shabinder.spotiflyer.utils.Provider
|
||||||
|
import com.shabinder.spotiflyer.utils.finalOutputDir
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class GaanaViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO) : BaseViewModel(){
|
class GaanaViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO) : BaseViewModel(){
|
||||||
|
|
||||||
@ -29,7 +42,156 @@ class GaanaViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO)
|
|||||||
var gaanaInterface : GaanaInterface? = null
|
var gaanaInterface : GaanaInterface? = null
|
||||||
|
|
||||||
fun gaanaSearch(type:String,link:String){
|
fun gaanaSearch(type:String,link:String){
|
||||||
|
when(type){
|
||||||
|
"song" -> {
|
||||||
|
uiScope.launch {
|
||||||
|
getGaanaSong(link)?.tracks?.firstOrNull()?.also {
|
||||||
|
folderType = "Tracks"
|
||||||
|
if(File(finalOutputDir(it.track_title,folderType,subFolder)).exists()){//Download Already Present!!
|
||||||
|
it.downloaded = DownloadStatus.Downloaded
|
||||||
|
}
|
||||||
|
trackList.value = listOf(it).toTrackDetailsList()
|
||||||
|
title.value = it.track_title
|
||||||
|
coverUrl.value = it.artworkLink
|
||||||
|
withContext(Dispatchers.IO){
|
||||||
|
databaseDAO.insert(
|
||||||
|
DownloadRecord(
|
||||||
|
type = "Track",
|
||||||
|
name = title.value!!,
|
||||||
|
link = "https://gaana.com/$type/$link",
|
||||||
|
coverUrl = coverUrl.value!!,
|
||||||
|
totalFiles = 1,
|
||||||
|
downloaded = it.downloaded == DownloadStatus.Downloaded,
|
||||||
|
directory = finalOutputDir(it.track_title,folderType,subFolder)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"album" -> {
|
||||||
|
uiScope.launch {
|
||||||
|
getGaanaAlbum(link)?.also {
|
||||||
|
folderType = "Albums"
|
||||||
|
subFolder = link
|
||||||
|
it.tracks.forEach { track ->
|
||||||
|
if(File(finalOutputDir(track.track_title,folderType,subFolder)).exists()){//Download Already Present!!
|
||||||
|
track.downloaded = DownloadStatus.Downloaded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trackList.value = it.tracks.toTrackDetailsList()
|
||||||
|
title.value = link
|
||||||
|
coverUrl.value = it.custom_artworks.size_480p
|
||||||
|
withContext(Dispatchers.IO){
|
||||||
|
databaseDAO.insert(DownloadRecord(
|
||||||
|
type = "Album",
|
||||||
|
name = title.value!!,
|
||||||
|
link = "https://gaana.com/$type/$link",
|
||||||
|
coverUrl = coverUrl.value.toString(),
|
||||||
|
totalFiles = trackList.value?.size ?: 0,
|
||||||
|
downloaded = File(finalOutputDir(type = folderType,subFolder = subFolder)).listFiles()?.size == trackList.value?.size,
|
||||||
|
directory = finalOutputDir(type = folderType,subFolder = subFolder)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"playlist" -> {
|
||||||
|
uiScope.launch {
|
||||||
|
getGaanaPlaylist(link)?.also {
|
||||||
|
folderType = "Playlists"
|
||||||
|
subFolder = link
|
||||||
|
it.tracks.forEach {track ->
|
||||||
|
if(File(finalOutputDir(track.track_title,folderType,subFolder)).exists()){//Download Already Present!!
|
||||||
|
track.downloaded = DownloadStatus.Downloaded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trackList.value = it.tracks.toTrackDetailsList()
|
||||||
|
title.value = link
|
||||||
|
//coverUrl.value = "TODO"
|
||||||
|
withContext(Dispatchers.IO){
|
||||||
|
databaseDAO.insert(DownloadRecord(
|
||||||
|
type = "Playlist",
|
||||||
|
name = title.value.toString(),
|
||||||
|
link = "https://gaana.com/$type/$link",
|
||||||
|
coverUrl = coverUrl.value.toString(),
|
||||||
|
totalFiles = it.tracks.size,
|
||||||
|
downloaded = File(finalOutputDir(type = folderType,subFolder = subFolder)).listFiles()?.size == trackList.value?.size,
|
||||||
|
directory = finalOutputDir(type = folderType,subFolder = subFolder)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"artist" -> {
|
||||||
|
uiScope.launch {
|
||||||
|
folderType = "Artist"
|
||||||
|
subFolder = link
|
||||||
|
val artistDetails = getGaanaArtistDetails(link)?.artist?.firstOrNull()?.also {
|
||||||
|
title.value = it.name
|
||||||
|
coverUrl.value = it.artworkLink
|
||||||
|
}
|
||||||
|
getGaanaArtistTracks(link)?.also {
|
||||||
|
it.tracks.forEach {track ->
|
||||||
|
if(File(finalOutputDir(track.track_title,folderType,subFolder)).exists()){//Download Already Present!!
|
||||||
|
track.downloaded = DownloadStatus.Downloaded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trackList.value = it.tracks.toTrackDetailsList()
|
||||||
|
withContext(Dispatchers.IO){
|
||||||
|
databaseDAO.insert(DownloadRecord(
|
||||||
|
type = "Artist",
|
||||||
|
name = artistDetails?.name ?: link,
|
||||||
|
link = "https://gaana.com/$type/$link",
|
||||||
|
coverUrl = coverUrl.value.toString(),
|
||||||
|
totalFiles = trackList.value?.size ?: 0,
|
||||||
|
downloaded = File(finalOutputDir(type = folderType,subFolder = subFolder)).listFiles()?.size == trackList.value?.size,
|
||||||
|
directory = finalOutputDir(type = folderType,subFolder = subFolder)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun List<GaanaTrack>.toTrackDetailsList() = this.map {
|
||||||
|
TrackDetails(
|
||||||
|
title = it.track_title,
|
||||||
|
artists = it.artist.map { artist -> artist.name },
|
||||||
|
durationSec = it.duration,
|
||||||
|
albumArt = File(
|
||||||
|
Environment.getExternalStorageDirectory(),
|
||||||
|
Provider.defaultDir +".Images/" + (it.artworkLink.substringBeforeLast('/').substringAfterLast('/')) + ".jpeg"),
|
||||||
|
albumName = it.album_title,
|
||||||
|
year = it.release_date,
|
||||||
|
comment = "Genres:${it.genre.map { genre -> genre.name }.reduceOrNull { acc, s -> acc + s }}",
|
||||||
|
trackUrl = it.lyrics_url,
|
||||||
|
downloaded = it.downloaded ?: DownloadStatus.NotDownloaded,
|
||||||
|
source = Source.Gaana,
|
||||||
|
albumArtURL = it.artworkLink
|
||||||
|
)
|
||||||
|
}.toMutableList()
|
||||||
|
|
||||||
|
private suspend fun getGaanaSong(songLink:String): GaanaSong?{
|
||||||
|
Log.i("Requesting","https://gaana.com/song/$songLink")
|
||||||
|
return gaanaInterface?.getGaanaSong(seokey = songLink)?.value
|
||||||
|
}
|
||||||
|
private suspend fun getGaanaAlbum(albumLink:String): GaanaAlbum?{
|
||||||
|
Log.i("Requesting","https://gaana.com/album/$albumLink")
|
||||||
|
return gaanaInterface?.getGaanaAlbum(seokey = albumLink)?.value
|
||||||
|
}
|
||||||
|
private suspend fun getGaanaPlaylist(link:String): GaanaPlaylist?{
|
||||||
|
Log.i("Requesting","https://gaana.com/playlist/$link")
|
||||||
|
return gaanaInterface?.getGaanaPlaylist(seokey = link)?.value
|
||||||
|
}
|
||||||
|
private suspend fun getGaanaArtistDetails(link:String): GaanaArtistDetails?{
|
||||||
|
Log.i("Requesting","https://gaana.com/artist/$link")
|
||||||
|
return gaanaInterface?.getGaanaArtistDetails(seokey = link)?.value
|
||||||
|
}
|
||||||
|
private suspend fun getGaanaArtistTracks(link:String,limit:Int = 50): GaanaArtistTracks?{
|
||||||
|
Log.i("Requesting","Tracks of: https://gaana.com/artist/$link")
|
||||||
|
return gaanaInterface?.getGaanaArtistTracks(seokey = link,limit = limit)?.value
|
||||||
|
}
|
||||||
}
|
}
|
@ -163,7 +163,7 @@ class SpotifyFragment : Fragment() {
|
|||||||
viewModel.trackList.observe(viewLifecycleOwner, {
|
viewModel.trackList.observe(viewLifecycleOwner, {
|
||||||
if (it.isNotEmpty()){
|
if (it.isNotEmpty()){
|
||||||
Log.i("SpotifyFragment","TrackList Updated")
|
Log.i("SpotifyFragment","TrackList Updated")
|
||||||
adapter.submitList(it)
|
adapter.submitList(it,Source.Spotify)
|
||||||
checkIfAllDownloaded()
|
checkIfAllDownloaded()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -45,44 +45,41 @@ class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
when (type) {
|
when (type) {
|
||||||
"track" -> {
|
"track" -> {
|
||||||
uiScope.launch {
|
uiScope.launch {
|
||||||
val trackObject = getTrackDetails(link)
|
getTrackDetails(link)?.also {
|
||||||
folderType = "Tracks"
|
folderType = "Tracks"
|
||||||
val tempTrackList = mutableListOf<Track>()
|
if(File(finalOutputDir(it.name,folderType,subFolder)).exists()){//Download Already Present!!
|
||||||
if(File(finalOutputDir(trackObject?.name!!,folderType,subFolder)).exists()){//Download Already Present!!
|
it.downloaded = DownloadStatus.Downloaded
|
||||||
trackObject.downloaded = DownloadStatus.Downloaded
|
|
||||||
}
|
}
|
||||||
tempTrackList.add(trackObject)
|
trackList.value = listOf(it).toTrackDetailsList()
|
||||||
trackList.value = tempTrackList.toTrackDetailsList()
|
title.value = it.name
|
||||||
title.value = trackObject.name
|
coverUrl.value = it.album!!.images?.get(0)!!.url!!
|
||||||
coverUrl.value = trackObject.album!!.images?.get(0)!!.url!!
|
|
||||||
withContext(Dispatchers.IO){
|
withContext(Dispatchers.IO){
|
||||||
databaseDAO.insert(DownloadRecord(
|
databaseDAO.insert(DownloadRecord(
|
||||||
type = "Track",
|
type = "Track",
|
||||||
name = title.value!!,
|
name = title.value!!,
|
||||||
link = "https://open.spotify.com/$type/$link",
|
link = "https://open.spotify.com/$type/$link",
|
||||||
coverUrl = coverUrl.value!!,
|
coverUrl = coverUrl.value!!,
|
||||||
totalFiles = tempTrackList.size,
|
totalFiles = 1,
|
||||||
downloaded = trackObject.downloaded == DownloadStatus.Downloaded,
|
downloaded = it.downloaded == DownloadStatus.Downloaded,
|
||||||
directory = finalOutputDir(trackObject.name!!,folderType,subFolder)
|
directory = finalOutputDir(it.name,folderType,subFolder)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
"album" -> {
|
"album" -> {
|
||||||
uiScope.launch {
|
uiScope.launch {
|
||||||
val albumObject = getAlbumDetails(link)
|
val albumObject = getAlbumDetails(link)
|
||||||
folderType = "Albums"
|
folderType = "Albums"
|
||||||
subFolder = albumObject?.name.toString()
|
subFolder = albumObject?.name.toString()
|
||||||
val tempTrackList = mutableListOf<Track>()
|
|
||||||
albumObject?.tracks?.items?.forEach {
|
albumObject?.tracks?.items?.forEach {
|
||||||
if(File(finalOutputDir(it.name!!,folderType,subFolder)).exists()){//Download Already Present!!
|
if(File(finalOutputDir(it.name!!,folderType,subFolder)).exists()){//Download Already Present!!
|
||||||
it.downloaded = DownloadStatus.Downloaded
|
it.downloaded = DownloadStatus.Downloaded
|
||||||
}
|
}
|
||||||
it.album = Album(images = listOf(Image(url = albumObject.images?.get(0)?.url)))
|
it.album = Album(images = listOf(Image(url = albumObject.images?.get(0)?.url)))
|
||||||
tempTrackList.add(it)
|
|
||||||
}
|
}
|
||||||
trackList.value = tempTrackList.toTrackDetailsList()
|
trackList.value = albumObject?.tracks?.items?.toTrackDetailsList()
|
||||||
title.value = albumObject?.name
|
title.value = albumObject?.name
|
||||||
coverUrl.value = albumObject?.images?.get(0)?.url
|
coverUrl.value = albumObject?.images?.get(0)?.url
|
||||||
withContext(Dispatchers.IO){
|
withContext(Dispatchers.IO){
|
||||||
@ -91,8 +88,8 @@ class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
name = title.value!!,
|
name = title.value!!,
|
||||||
link = "https://open.spotify.com/$type/$link",
|
link = "https://open.spotify.com/$type/$link",
|
||||||
coverUrl = coverUrl.value.toString(),
|
coverUrl = coverUrl.value.toString(),
|
||||||
totalFiles = tempTrackList.size,
|
totalFiles = trackList.value?.size ?: 0,
|
||||||
downloaded = File(finalOutputDir(type = folderType,subFolder = subFolder)).listFiles()?.size == tempTrackList.size,
|
downloaded = File(finalOutputDir(type = folderType,subFolder = subFolder)).listFiles()?.size == trackList.value?.size,
|
||||||
directory = finalOutputDir(type = folderType,subFolder = subFolder)
|
directory = finalOutputDir(type = folderType,subFolder = subFolder)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -149,11 +146,9 @@ class SpotifyViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun List<Track>.toTrackDetailsList() = this.map {
|
private fun List<Track>.toTrackDetailsList() = this.map {
|
||||||
val artistsList = mutableListOf<String>()
|
|
||||||
it.artists?.forEach { artist -> artistsList.add(artist!!.name!!) }
|
|
||||||
TrackDetails(
|
TrackDetails(
|
||||||
title = it.name.toString(),
|
title = it.name.toString(),
|
||||||
artists = artistsList,
|
artists = it.artists?.map { artist -> artist?.name.toString() } ?: listOf(),
|
||||||
durationSec = (it.duration_ms/1000).toInt(),
|
durationSec = (it.duration_ms/1000).toInt(),
|
||||||
albumArt = File(
|
albumArt = File(
|
||||||
Environment.getExternalStorageDirectory(),
|
Environment.getExternalStorageDirectory(),
|
||||||
|
@ -196,7 +196,7 @@ class YoutubeFragment : Fragment() {
|
|||||||
* TrackList Binding Observer!
|
* TrackList Binding Observer!
|
||||||
**/
|
**/
|
||||||
viewModel.trackList.observe(viewLifecycleOwner, {
|
viewModel.trackList.observe(viewLifecycleOwner, {
|
||||||
adapter.submitList(it)
|
adapter.submitList(it,Source.YouTube)
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,7 +30,7 @@ abstract class BaseViewModel:ViewModel() {
|
|||||||
abstract var subFolder:String
|
abstract var subFolder:String
|
||||||
open val trackList = MutableLiveData<MutableList<TrackDetails>>()
|
open val trackList = MutableLiveData<MutableList<TrackDetails>>()
|
||||||
private val viewModelJob:CompletableJob = Job()
|
private val viewModelJob:CompletableJob = Job()
|
||||||
open val uiScope = CoroutineScope(Dispatchers.Default + viewModelJob)
|
open val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
|
||||||
|
|
||||||
private val loading = "Loading!"
|
private val loading = "Loading!"
|
||||||
open var title = MutableLiveData<String>().apply { value = loading }
|
open var title = MutableLiveData<String>().apply { value = loading }
|
||||||
|
@ -125,7 +125,7 @@ object Provider {
|
|||||||
@Singleton
|
@Singleton
|
||||||
fun getGaanaInterface(moshi: Moshi,okHttpClient: OkHttpClient):GaanaInterface{
|
fun getGaanaInterface(moshi: Moshi,okHttpClient: OkHttpClient):GaanaInterface{
|
||||||
val retrofit = Retrofit.Builder()
|
val retrofit = Retrofit.Builder()
|
||||||
.baseUrl("http://api.gaana.com/")
|
.baseUrl("https://api.gaana.com/")
|
||||||
.client(okHttpClient)
|
.client(okHttpClient)
|
||||||
.addConverterFactory(MoshiConverterFactory.create(moshi))
|
.addConverterFactory(MoshiConverterFactory.create(moshi))
|
||||||
.build()
|
.build()
|
||||||
|
@ -179,6 +179,11 @@ fun bindImage(imgView: ImageView, imgUrl: String?,source: Source?) {
|
|||||||
defaultDir+".Images/" + imgUrl.substringBeforeLast('/',imgUrl).substringAfterLast('/',imgUrl) + ".jpeg"
|
defaultDir+".Images/" + imgUrl.substringBeforeLast('/',imgUrl).substringAfterLast('/',imgUrl) + ".jpeg"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Source.Gaana -> {
|
||||||
|
File(
|
||||||
|
Environment.getExternalStorageDirectory(),
|
||||||
|
Provider.defaultDir +".Images/" + (imgUrl.substringBeforeLast('/').substringAfterLast('/')) + ".jpeg")
|
||||||
|
}
|
||||||
else -> File(
|
else -> File(
|
||||||
Environment.getExternalStorageDirectory(),
|
Environment.getExternalStorageDirectory(),
|
||||||
defaultDir+".Images/" + imgUrl.substringAfterLast('/',imgUrl) + ".jpeg"
|
defaultDir+".Images/" + imgUrl.substringAfterLast('/',imgUrl) + ".jpeg"
|
||||||
|
@ -49,6 +49,7 @@ import com.shabinder.spotiflyer.MainActivity
|
|||||||
import com.shabinder.spotiflyer.R
|
import com.shabinder.spotiflyer.R
|
||||||
import com.shabinder.spotiflyer.models.DownloadObject
|
import com.shabinder.spotiflyer.models.DownloadObject
|
||||||
import com.shabinder.spotiflyer.models.TrackDetails
|
import com.shabinder.spotiflyer.models.TrackDetails
|
||||||
|
import com.shabinder.spotiflyer.utils.Provider
|
||||||
import com.shabinder.spotiflyer.utils.copyTo
|
import com.shabinder.spotiflyer.utils.copyTo
|
||||||
import com.tonyodev.fetch2.*
|
import com.tonyodev.fetch2.*
|
||||||
import com.tonyodev.fetch2core.DownloadBlock
|
import com.tonyodev.fetch2core.DownloadBlock
|
||||||
@ -628,6 +629,11 @@ class ForegroundService : Service(){
|
|||||||
defaultDir +".Images/" + url.substringBeforeLast('/',url).substringAfterLast('/',url) + ".jpeg"
|
defaultDir +".Images/" + url.substringBeforeLast('/',url).substringAfterLast('/',url) + ".jpeg"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
"gaana" -> {
|
||||||
|
File(
|
||||||
|
Environment.getExternalStorageDirectory(),
|
||||||
|
Provider.defaultDir +".Images/" + (url.substringBeforeLast('/').substringAfterLast('/')) + ".jpeg")
|
||||||
|
}
|
||||||
else -> File(
|
else -> File(
|
||||||
Environment.getExternalStorageDirectory(),
|
Environment.getExternalStorageDirectory(),
|
||||||
defaultDir +".Images/" + url.substringAfterLast('/') + ".jpeg")
|
defaultDir +".Images/" + url.substringAfterLast('/') + ".jpeg")
|
||||||
|
Loading…
Reference in New Issue
Block a user