Rewrite 'picasso' to Kotlin

This commit is contained in:
Niko Diamadis
2022-11-02 07:41:00 +01:00
parent f8db0e94ce
commit 637e8802a4
4 changed files with 123 additions and 140 deletions

View File

@@ -1,41 +0,0 @@
package com.github.gotify.picasso;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import com.github.gotify.log.Log;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Request;
import com.squareup.picasso.RequestHandler;
/**
* Adapted from https://github.com/square/picasso/issues/1395#issuecomment-220929377 By
* https://github.com/SmartDengg
*/
public class PicassoDataRequestHandler extends RequestHandler {
private static final String DATA_SCHEME = "data";
@Override
public boolean canHandleRequest(Request data) {
String scheme = data.uri.getScheme();
return DATA_SCHEME.equalsIgnoreCase(scheme);
}
@Override
public Result load(Request request, int networkPolicy) {
String uri = request.uri.toString();
String imageDataBytes = uri.substring(uri.indexOf(",") + 1);
byte[] bytes = Base64.decode(imageDataBytes.getBytes(), Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
if (bitmap == null) {
String show = uri.length() > 50 ? uri.substring(0, 49) + "..." : uri;
RuntimeException malformed = new RuntimeException("Malformed data uri: " + show);
Log.e("Could not load image", malformed);
throw malformed;
}
return new Result(bitmap, Picasso.LoadedFrom.NETWORK);
}
}

View File

@@ -0,0 +1,40 @@
package com.github.gotify.picasso
import android.graphics.BitmapFactory
import android.util.Base64
import com.github.gotify.log.Log
import com.squareup.picasso.Picasso
import com.squareup.picasso.Request
import com.squareup.picasso.RequestHandler
/**
* Adapted from https://github.com/square/picasso/issues/1395#issuecomment-220929377 By
* https://github.com/SmartDengg
*/
class PicassoDataRequestHandler : RequestHandler() {
companion object {
private const val DATA_SCHEME = "data"
}
override fun canHandleRequest(data: Request): Boolean {
val scheme = data.uri.scheme
return DATA_SCHEME.equals(scheme, ignoreCase = true)
}
override fun load(request: Request, networkPolicy: Int): Result {
val uri = request.uri.toString()
val imageDataBytes = uri.substring(uri.indexOf(",") + 1)
val bytes = Base64.decode(imageDataBytes.toByteArray(), Base64.DEFAULT)
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
if (bitmap == null) {
val show = if (uri.length > 50) uri.substring(0, 49) + "..." else uri
val malformed = RuntimeException("Malformed data uri: $show")
Log.e("Could not load image", malformed)
throw malformed
}
return Result(bitmap, Picasso.LoadedFrom.NETWORK)
}
}

View File

@@ -1,99 +0,0 @@
package com.github.gotify.picasso;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import com.github.gotify.R;
import com.github.gotify.Settings;
import com.github.gotify.Utils;
import com.github.gotify.api.Callback;
import com.github.gotify.api.CertUtils;
import com.github.gotify.api.ClientFactory;
import com.github.gotify.client.api.ApplicationApi;
import com.github.gotify.log.Log;
import com.github.gotify.messages.provider.MessageImageCombiner;
import com.squareup.picasso.OkHttp3Downloader;
import com.squareup.picasso.Picasso;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
public class PicassoHandler {
private static final int PICASSO_CACHE_SIZE = 50 * 1024 * 1024; // 50 MB
private static final String PICASSO_CACHE_SUBFOLDER = "picasso-cache";
private Context context;
private Settings settings;
private Cache picassoCache;
private Picasso picasso;
private Map<Long, String> appIdToAppImage = new ConcurrentHashMap<>();
public PicassoHandler(Context context, Settings settings) {
this.context = context;
this.settings = settings;
picassoCache =
new Cache(
new File(context.getCacheDir(), PICASSO_CACHE_SUBFOLDER),
PICASSO_CACHE_SIZE);
picasso = makePicasso();
}
private Picasso makePicasso() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.cache(picassoCache);
CertUtils.applySslSettings(builder, settings.sslSettings());
OkHttp3Downloader downloader = new OkHttp3Downloader(builder.build());
return new Picasso.Builder(context)
.addRequestHandler(new PicassoDataRequestHandler())
.downloader(downloader)
.build();
}
public Bitmap getImageFromUrl(String url) throws IOException {
return picasso.load(url).get();
}
public Bitmap getIcon(Long appId) {
if (appId == -1) {
return BitmapFactory.decodeResource(context.getResources(), R.drawable.gotify);
}
try {
return getImageFromUrl(
Utils.resolveAbsoluteUrl(settings.url() + "/", appIdToAppImage.get(appId)));
} catch (IOException e) {
Log.e("Could not load image for notification", e);
}
return BitmapFactory.decodeResource(context.getResources(), R.drawable.gotify);
}
public void updateAppIds() {
ClientFactory.clientToken(settings.url(), settings.sslSettings(), settings.token())
.createService(ApplicationApi.class)
.getApps()
.enqueue(
Callback.call(
(apps) -> {
appIdToAppImage.clear();
appIdToAppImage.putAll(MessageImageCombiner.appIdToImage(apps));
},
(t) -> {
appIdToAppImage.clear();
}));
}
public Picasso get() {
return picasso;
}
public void evict() throws IOException {
picassoCache.evictAll();
}
}

View File

@@ -0,0 +1,83 @@
package com.github.gotify.picasso
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import com.github.gotify.R
import com.github.gotify.Settings
import com.github.gotify.Utils
import com.github.gotify.api.Callback
import com.github.gotify.api.CertUtils
import com.github.gotify.api.ClientFactory
import com.github.gotify.client.api.ApplicationApi
import com.github.gotify.log.Log
import com.github.gotify.messages.provider.MessageImageCombiner
import com.squareup.picasso.OkHttp3Downloader
import com.squareup.picasso.Picasso
import okhttp3.Cache
import okhttp3.OkHttpClient
import java.io.File
import java.io.IOException
class PicassoHandler(private val context: Context, private val settings: Settings) {
companion object {
private const val PICASSO_CACHE_SIZE = 50 * 1024 * 1024 // 50 MB
private const val PICASSO_CACHE_SUBFOLDER = "picasso-cache"
}
private val picassoCache = Cache(
File(context.cacheDir, PICASSO_CACHE_SUBFOLDER),
PICASSO_CACHE_SIZE.toLong()
)
private val picasso: Picasso = makePicasso()
private val appIdToAppImage: MutableMap<Long, String> = mutableMapOf()
private fun makePicasso(): Picasso {
val builder = OkHttpClient.Builder()
builder.cache(picassoCache)
CertUtils.applySslSettings(builder, settings.sslSettings())
val downloader = OkHttp3Downloader(builder.build())
return Picasso.Builder(context)
.addRequestHandler(PicassoDataRequestHandler())
.downloader(downloader)
.build()
}
@Throws(IOException::class)
fun getImageFromUrl(url: String): Bitmap {
return picasso.load(url).get()
}
fun getIcon(appId: Long): Bitmap {
if (appId == -1L) {
return BitmapFactory.decodeResource(context.resources, R.drawable.gotify)
}
try {
return getImageFromUrl(
Utils.resolveAbsoluteUrl("${settings.url()}/", appIdToAppImage[appId])
)
} catch (e: IOException) {
Log.e("Could not load image for notification", e)
}
return BitmapFactory.decodeResource(context.resources, R.drawable.gotify)
}
fun updateAppIds() {
ClientFactory.clientToken(settings.url(), settings.sslSettings(), settings.token())
.createService(ApplicationApi::class.java)
.apps
.enqueue(Callback.call({ apps ->
appIdToAppImage.clear()
appIdToAppImage.putAll(MessageImageCombiner.appIdToImage(apps))
}) { appIdToAppImage.clear() })
}
fun get() = picasso
@Throws(IOException::class)
fun evict() {
picassoCache.evictAll()
}
}