Merge pull request #533 from h4h13/artistImage
Added loading artist image again from old method
This commit is contained in:
commit
0e179d6842
4 changed files with 244 additions and 19 deletions
|
@ -29,24 +29,127 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||||
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
|
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
|
||||||
import com.bumptech.glide.request.target.Target;
|
import com.bumptech.glide.request.target.Target;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import code.name.monkey.retromusic.App;
|
import code.name.monkey.retromusic.App;
|
||||||
import code.name.monkey.retromusic.R;
|
import code.name.monkey.retromusic.R;
|
||||||
import code.name.monkey.retromusic.glide.artistimage.AlbumCover;
|
|
||||||
import code.name.monkey.retromusic.glide.artistimage.ArtistImage;
|
import code.name.monkey.retromusic.glide.artistimage.ArtistImage;
|
||||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder;
|
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder;
|
||||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
|
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
|
||||||
import code.name.monkey.retromusic.model.Album;
|
|
||||||
import code.name.monkey.retromusic.model.Artist;
|
import code.name.monkey.retromusic.model.Artist;
|
||||||
import code.name.monkey.retromusic.model.Song;
|
|
||||||
import code.name.monkey.retromusic.util.ArtistSignatureUtil;
|
import code.name.monkey.retromusic.util.ArtistSignatureUtil;
|
||||||
import code.name.monkey.retromusic.util.CustomArtistImageUtil;
|
import code.name.monkey.retromusic.util.CustomArtistImageUtil;
|
||||||
|
|
||||||
|
|
||||||
|
public class ArtistGlideRequest {
|
||||||
|
|
||||||
|
public static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
|
||||||
|
private static final DiskCacheStrategy DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.SOURCE;
|
||||||
|
private static final int DEFAULT_ERROR_IMAGE = R.drawable.default_artist_art;
|
||||||
|
|
||||||
|
public static DrawableTypeRequest createBaseRequest(RequestManager requestManager, Artist artist, boolean noCustomImage, boolean forceDownload) {
|
||||||
|
boolean hasCustomImage = CustomArtistImageUtil.Companion.getInstance(App.Companion.getContext()).hasCustomArtistImage(artist);
|
||||||
|
if (noCustomImage || !hasCustomImage) {
|
||||||
|
return requestManager.load(new ArtistImage(artist.getName(), forceDownload));
|
||||||
|
} else {
|
||||||
|
return requestManager.load(CustomArtistImageUtil.getFile(artist));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Key createSignature(Artist artist) {
|
||||||
|
return ArtistSignatureUtil.getInstance(App.Companion.getContext()).getArtistSignature(artist.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
final RequestManager requestManager;
|
||||||
|
final Artist artist;
|
||||||
|
boolean noCustomImage;
|
||||||
|
boolean forceDownload;
|
||||||
|
|
||||||
|
private Builder(@NonNull RequestManager requestManager, Artist artist) {
|
||||||
|
this.requestManager = requestManager;
|
||||||
|
this.artist = artist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder from(@NonNull RequestManager requestManager, Artist artist) {
|
||||||
|
return new Builder(requestManager, artist);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaletteBuilder generatePalette(Context context) {
|
||||||
|
return new PaletteBuilder(this, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitmapBuilder asBitmap() {
|
||||||
|
return new BitmapBuilder(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder noCustomImage(boolean noCustomImage) {
|
||||||
|
this.noCustomImage = noCustomImage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder forceDownload(boolean forceDownload) {
|
||||||
|
this.forceDownload = forceDownload;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DrawableRequestBuilder<GlideDrawable> build() {
|
||||||
|
//noinspection unchecked
|
||||||
|
return createBaseRequest(requestManager, artist, noCustomImage, forceDownload)
|
||||||
|
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||||
|
.error(DEFAULT_ERROR_IMAGE)
|
||||||
|
.animate(DEFAULT_ANIMATION)
|
||||||
|
.priority(Priority.LOW)
|
||||||
|
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||||
|
.signature(createSignature(artist));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BitmapBuilder {
|
||||||
|
private final Builder builder;
|
||||||
|
|
||||||
|
public BitmapBuilder(Builder builder) {
|
||||||
|
this.builder = builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitmapRequestBuilder<?, Bitmap> build() {
|
||||||
|
//noinspection unchecked
|
||||||
|
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage, builder.forceDownload)
|
||||||
|
.asBitmap()
|
||||||
|
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||||
|
.error(DEFAULT_ERROR_IMAGE)
|
||||||
|
.animate(DEFAULT_ANIMATION)
|
||||||
|
.priority(Priority.LOW)
|
||||||
|
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||||
|
.signature(createSignature(builder.artist));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PaletteBuilder {
|
||||||
|
final Context context;
|
||||||
|
private final Builder builder;
|
||||||
|
|
||||||
|
public PaletteBuilder(Builder builder, Context context) {
|
||||||
|
this.builder = builder;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitmapRequestBuilder<?, BitmapPaletteWrapper> build() {
|
||||||
|
//noinspection unchecked
|
||||||
|
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage, builder.forceDownload)
|
||||||
|
.asBitmap()
|
||||||
|
.transcode(new BitmapPaletteTranscoder(context), BitmapPaletteWrapper.class)
|
||||||
|
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||||
|
.error(DEFAULT_ERROR_IMAGE)
|
||||||
|
.animate(DEFAULT_ANIMATION)
|
||||||
|
.priority(Priority.LOW)
|
||||||
|
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||||
|
.signature(createSignature(builder.artist));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*//*
|
||||||
public class ArtistGlideRequest {
|
public class ArtistGlideRequest {
|
||||||
|
|
||||||
public static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
|
public static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
|
||||||
|
@ -152,4 +255,4 @@ public class ArtistGlideRequest {
|
||||||
.signature(createSignature(builder.artist));
|
.signature(createSignature(builder.artist));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
|
@ -17,6 +17,7 @@ package code.name.monkey.retromusic.glide
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import code.name.monkey.retromusic.glide.artistimage.ArtistImage
|
import code.name.monkey.retromusic.glide.artistimage.ArtistImage
|
||||||
import code.name.monkey.retromusic.glide.artistimage.ArtistImageLoader
|
import code.name.monkey.retromusic.glide.artistimage.ArtistImageLoader
|
||||||
|
import code.name.monkey.retromusic.glide.artistimage.Factory
|
||||||
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
|
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
|
||||||
import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverLoader
|
import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverLoader
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
|
@ -30,6 +31,6 @@ class RetroMusicGlideModule : GlideModule {
|
||||||
|
|
||||||
override fun registerComponents(context: Context, glide: Glide) {
|
override fun registerComponents(context: Context, glide: Glide) {
|
||||||
glide.register(AudioFileCover::class.java, InputStream::class.java, AudioFileCoverLoader.Factory())
|
glide.register(AudioFileCover::class.java, InputStream::class.java, AudioFileCoverLoader.Factory())
|
||||||
glide.register(ArtistImage::class.java, InputStream::class.java, ArtistImageLoader.Factory())
|
glide.register(ArtistImage::class.java, InputStream::class.java, Factory(context))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,25 +15,131 @@
|
||||||
package code.name.monkey.retromusic.glide.artistimage
|
package code.name.monkey.retromusic.glide.artistimage
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import code.name.monkey.retromusic.deezer.Data
|
||||||
import android.graphics.Canvas
|
import code.name.monkey.retromusic.deezer.DeezerApiService
|
||||||
import android.media.MediaMetadataRetriever
|
import code.name.monkey.retromusic.util.MusicUtil
|
||||||
import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverUtils
|
|
||||||
import code.name.monkey.retromusic.util.ImageUtil
|
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import com.bumptech.glide.Priority
|
import com.bumptech.glide.Priority
|
||||||
|
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader
|
||||||
import com.bumptech.glide.load.data.DataFetcher
|
import com.bumptech.glide.load.data.DataFetcher
|
||||||
import com.bumptech.glide.load.model.GenericLoaderFactory
|
import com.bumptech.glide.load.model.GenericLoaderFactory
|
||||||
|
import com.bumptech.glide.load.model.GlideUrl
|
||||||
import com.bumptech.glide.load.model.ModelLoader
|
import com.bumptech.glide.load.model.ModelLoader
|
||||||
import com.bumptech.glide.load.model.ModelLoaderFactory
|
import com.bumptech.glide.load.model.ModelLoaderFactory
|
||||||
import com.bumptech.glide.load.model.stream.StreamModelLoader
|
import com.bumptech.glide.load.model.stream.StreamModelLoader
|
||||||
import java.io.ByteArrayInputStream
|
import okhttp3.OkHttpClient
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
class AlbumCover(
|
class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean)
|
||||||
|
|
||||||
|
class ArtistImageFetcher(
|
||||||
|
private val context: Context,
|
||||||
|
private val deezerApiService: DeezerApiService,
|
||||||
|
val model: ArtistImage,
|
||||||
|
val urlLoader: ModelLoader<GlideUrl, InputStream>,
|
||||||
|
val width: Int,
|
||||||
|
val height: Int
|
||||||
|
) : DataFetcher<InputStream> {
|
||||||
|
|
||||||
|
private var urlFetcher: DataFetcher<InputStream>? = null
|
||||||
|
private var isCancelled: Boolean = false
|
||||||
|
|
||||||
|
override fun cleanup() {
|
||||||
|
urlFetcher?.cleanup()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getId(): String {
|
||||||
|
return model.artistName
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun cancel() {
|
||||||
|
isCancelled = true
|
||||||
|
urlFetcher?.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadData(priority: Priority?): InputStream? {
|
||||||
|
if (!MusicUtil.isArtistNameUnknown(model.artistName) && PreferenceUtil.isAllowedToDownloadMetadata(context)) {
|
||||||
|
val artists = model.artistName.split(",|&")
|
||||||
|
val response = deezerApiService.getArtistImage(artists[0]).execute()
|
||||||
|
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
throw IOException("Request failed with code: " + response.code());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCancelled) return null
|
||||||
|
|
||||||
|
return try {
|
||||||
|
val deezerResponse = response.body();
|
||||||
|
val imageUrl = deezerResponse?.data?.get(0)?.let { getHighestQuality(it) }
|
||||||
|
val glideUrl = GlideUrl(imageUrl)
|
||||||
|
urlFetcher = urlLoader.getResourceFetcher(glideUrl, width, height)
|
||||||
|
urlFetcher?.loadData(priority)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
} else return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getHighestQuality(imageUrl: Data): String {
|
||||||
|
return when {
|
||||||
|
imageUrl.pictureXl.isNotEmpty() -> imageUrl.pictureXl
|
||||||
|
imageUrl.pictureBig.isNotEmpty() -> imageUrl.pictureBig
|
||||||
|
imageUrl.pictureMedium.isNotEmpty() -> imageUrl.pictureMedium
|
||||||
|
imageUrl.pictureSmall.isNotEmpty() -> imageUrl.pictureSmall
|
||||||
|
imageUrl.picture.isNotEmpty() -> imageUrl.picture
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ArtistImageLoader(
|
||||||
|
val context: Context,
|
||||||
|
val deezerApiService: DeezerApiService,
|
||||||
|
val urlLoader: ModelLoader<GlideUrl, InputStream>
|
||||||
|
) : StreamModelLoader<ArtistImage> {
|
||||||
|
|
||||||
|
override fun getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher<InputStream> {
|
||||||
|
return ArtistImageFetcher(context, deezerApiService, model, urlLoader, width, height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Factory(
|
||||||
|
val context: Context
|
||||||
|
) : ModelLoaderFactory<ArtistImage, InputStream> {
|
||||||
|
private var deezerApiService: DeezerApiService
|
||||||
|
private var okhttpFactory: OkHttpUrlLoader.Factory
|
||||||
|
|
||||||
|
init {
|
||||||
|
okhttpFactory = OkHttpUrlLoader.Factory(OkHttpClient.Builder()
|
||||||
|
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||||
|
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||||
|
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||||
|
.build())
|
||||||
|
deezerApiService = DeezerApiService.invoke(DeezerApiService.createDefaultOkHttpClient(context)
|
||||||
|
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||||
|
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||||
|
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||||
|
.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun build(context: Context?, factories: GenericLoaderFactory?): ModelLoader<ArtistImage, InputStream> {
|
||||||
|
return ArtistImageLoader(context!!, deezerApiService, okhttpFactory.build(context, factories))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun teardown() {
|
||||||
|
okhttpFactory.teardown()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// we need these very low values to make sure our artist image loading calls doesn't block the image loading queue
|
||||||
|
private const val TIMEOUT: Long = 700
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/*class AlbumCover(
|
||||||
var year: Int,
|
var year: Int,
|
||||||
var filePath: String?)
|
var filePath: String?)
|
||||||
|
|
||||||
|
@ -207,7 +313,7 @@ class ArtistImageLoader(
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
/*
|
/*
|
||||||
|
|
||||||
class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean)
|
class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean)
|
||||||
|
|
|
@ -19,6 +19,8 @@ import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.SharedPreferences.Editor;
|
import android.content.SharedPreferences.Editor;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
|
@ -142,11 +144,24 @@ public final class PreferenceUtil {
|
||||||
private static PreferenceUtil sInstance;
|
private static PreferenceUtil sInstance;
|
||||||
private final SharedPreferences mPreferences;
|
private final SharedPreferences mPreferences;
|
||||||
|
|
||||||
|
|
||||||
private PreferenceUtil(@NonNull final Context context) {
|
private PreferenceUtil(@NonNull final Context context) {
|
||||||
mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
mPreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isAllowedToDownloadMetadata(final Context context) {
|
||||||
|
switch (getInstance(context).autoDownloadImagesPolicy()) {
|
||||||
|
case "always":
|
||||||
|
return true;
|
||||||
|
case "only_wifi":
|
||||||
|
final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
|
||||||
|
return netInfo != null && netInfo.getType() == ConnectivityManager.TYPE_WIFI && netInfo.isConnectedOrConnecting();
|
||||||
|
case "never":
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static PreferenceUtil getInstance(Context context) {
|
public static PreferenceUtil getInstance(Context context) {
|
||||||
if (sInstance == null) {
|
if (sInstance == null) {
|
||||||
|
|
Loading…
Reference in a new issue