image upload works to nostr.build
This commit is contained in:
@@ -1,14 +1,20 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.actions
|
package com.vitorpamplona.amethyst.ui.actions
|
||||||
|
|
||||||
import android.content.ContentResolver
|
import android.content.ContentResolver
|
||||||
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.provider.OpenableColumns
|
||||||
|
import android.util.Log
|
||||||
import android.webkit.MimeTypeMap
|
import android.webkit.MimeTypeMap
|
||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import com.vitorpamplona.amethyst.BuildConfig
|
import com.vitorpamplona.amethyst.BuildConfig
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
import okhttp3.MediaType.Companion.toMediaType
|
||||||
|
import okhttp3.RequestBody.Companion.asRequestBody
|
||||||
import okio.BufferedSink
|
import okio.BufferedSink
|
||||||
import okio.source
|
import okio.source
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileOutputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
|
||||||
@@ -21,13 +27,13 @@ object ImageUploader {
|
|||||||
fun uploadImage(
|
fun uploadImage(
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
server: ServersAvailable,
|
server: ServersAvailable,
|
||||||
|
context: Context,
|
||||||
contentResolver: ContentResolver,
|
contentResolver: ContentResolver,
|
||||||
onSuccess: (String, String?) -> Unit,
|
onSuccess: (String, String?) -> Unit,
|
||||||
onError: (Throwable) -> Unit
|
onError: (Throwable) -> Unit
|
||||||
) {
|
) {
|
||||||
val contentType = contentResolver.getType(uri)
|
val contentType = contentResolver.getType(uri)
|
||||||
val imageInputStream = contentResolver.openInputStream(uri)
|
val imageInputStream = contentResolver.openInputStream(uri)
|
||||||
|
|
||||||
checkNotNull(imageInputStream) {
|
checkNotNull(imageInputStream) {
|
||||||
"Can't open the image input stream"
|
"Can't open the image input stream"
|
||||||
}
|
}
|
||||||
@@ -41,10 +47,14 @@ object ImageUploader {
|
|||||||
ImgurServer()
|
ImgurServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadImage(imageInputStream, contentType, myServer, server, onSuccess, onError)
|
val file = getRealPathFromURI(uri, context)?.let { File(it) } // create path from uri
|
||||||
|
if (file != null) {
|
||||||
|
uploadImage(file, imageInputStream, contentType, myServer, server, onSuccess, onError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun uploadImage(
|
fun uploadImage(
|
||||||
|
file: File,
|
||||||
inputStream: InputStream,
|
inputStream: InputStream,
|
||||||
contentType: String?,
|
contentType: String?,
|
||||||
server: FileServer,
|
server: FileServer,
|
||||||
@@ -52,38 +62,47 @@ object ImageUploader {
|
|||||||
onSuccess: (String, String?) -> Unit,
|
onSuccess: (String, String?) -> Unit,
|
||||||
onError: (Throwable) -> Unit
|
onError: (Throwable) -> Unit
|
||||||
) {
|
) {
|
||||||
var category = "fileToUpload"
|
val category = contentType?.toMediaType()?.toString()?.split("/")?.get(0) ?: "image"
|
||||||
if (serverType != ServersAvailable.NOSTR_BUILD) {
|
|
||||||
category = contentType?.toMediaType()?.toString()?.split("/")?.get(0) ?: "image"
|
|
||||||
}
|
|
||||||
val fileName = randomChars()
|
val fileName = randomChars()
|
||||||
val extension = contentType?.let { MimeTypeMap.getSingleton().getExtensionFromMimeType(it) } ?: ""
|
val extension = contentType?.let { MimeTypeMap.getSingleton().getExtensionFromMimeType(it) } ?: ""
|
||||||
|
|
||||||
val client = OkHttpClient.Builder().build()
|
val client = OkHttpClient.Builder().build()
|
||||||
|
val requestBody: RequestBody
|
||||||
val requestBody: RequestBody = MultipartBody.Builder()
|
|
||||||
.setType(MultipartBody.FORM)
|
|
||||||
.addFormDataPart(
|
|
||||||
category,
|
|
||||||
"$fileName.$extension",
|
|
||||||
object : RequestBody() {
|
|
||||||
override fun contentType(): MediaType? =
|
|
||||||
contentType?.toMediaType()
|
|
||||||
|
|
||||||
override fun writeTo(sink: BufferedSink) {
|
|
||||||
inputStream.source().use(sink::writeAll)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
val requestBuilder = Request.Builder()
|
val requestBuilder = Request.Builder()
|
||||||
server.clientID()?.let {
|
|
||||||
requestBuilder.addHeader("Authorization", it)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serverType == ServersAvailable.NOSTR_BUILD) {
|
if (serverType == ServersAvailable.NOSTR_BUILD) {
|
||||||
requestBuilder.addHeader("Content-Type", "multipart/form-data")
|
requestBuilder.addHeader("Content-Type", "multipart/form-data")
|
||||||
|
requestBody = MultipartBody.Builder()
|
||||||
|
.setType(MultipartBody.FORM)
|
||||||
|
.addFormDataPart(
|
||||||
|
"fileToUpload",
|
||||||
|
"$fileName.$extension",
|
||||||
|
file.asRequestBody(contentType?.toMediaType())
|
||||||
|
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
} else {
|
||||||
|
requestBody = MultipartBody.Builder()
|
||||||
|
.setType(MultipartBody.FORM)
|
||||||
|
.addFormDataPart(
|
||||||
|
category,
|
||||||
|
"$fileName.$extension",
|
||||||
|
|
||||||
|
object : RequestBody() {
|
||||||
|
override fun contentType(): MediaType? =
|
||||||
|
contentType?.toMediaType()
|
||||||
|
|
||||||
|
override fun writeTo(sink: BufferedSink) {
|
||||||
|
inputStream.source().use(sink::writeAll)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
server.clientID()?.let {
|
||||||
|
requestBuilder.addHeader("Authorization", it)
|
||||||
}
|
}
|
||||||
|
|
||||||
requestBuilder
|
requestBuilder
|
||||||
@@ -118,6 +137,38 @@ object ImageUploader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getRealPathFromURI(uri: Uri, context: Context): String? {
|
||||||
|
val returnCursor = context.contentResolver.query(uri, null, null, null, null)
|
||||||
|
val nameIndex = returnCursor!!.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
||||||
|
returnCursor.moveToFirst()
|
||||||
|
val name = returnCursor.getString(nameIndex)
|
||||||
|
val file = File(context.filesDir, name)
|
||||||
|
try {
|
||||||
|
val inputStream: InputStream? = context.contentResolver.openInputStream(uri)
|
||||||
|
val outputStream = FileOutputStream(file)
|
||||||
|
var read = 0
|
||||||
|
val maxBufferSize = 1 * 1024 * 1024
|
||||||
|
val bytesAvailable: Int = inputStream?.available() ?: 0
|
||||||
|
val bufferSize = Math.min(bytesAvailable, maxBufferSize)
|
||||||
|
val buffers = ByteArray(bufferSize)
|
||||||
|
while (inputStream?.read(buffers).also {
|
||||||
|
if (it != null) {
|
||||||
|
read = it
|
||||||
|
}
|
||||||
|
} != -1
|
||||||
|
) {
|
||||||
|
outputStream.write(buffers, 0, read)
|
||||||
|
}
|
||||||
|
Log.e("File Size", "Size " + file.length())
|
||||||
|
inputStream?.close()
|
||||||
|
outputStream.close()
|
||||||
|
Log.e("File Path", "Path " + file.path)
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
Log.e("Exception", e.message!!)
|
||||||
|
}
|
||||||
|
return file.path
|
||||||
|
}
|
||||||
|
|
||||||
abstract class FileServer {
|
abstract class FileServer {
|
||||||
abstract fun postUrl(contentType: String?): String
|
abstract fun postUrl(contentType: String?): String
|
||||||
abstract fun parseUrlFromSucess(body: String): String?
|
abstract fun parseUrlFromSucess(body: String): String?
|
||||||
@@ -154,9 +205,8 @@ class ImgurServer : FileServer() {
|
|||||||
|
|
||||||
class NostrBuildServer : FileServer() {
|
class NostrBuildServer : FileServer() {
|
||||||
override fun postUrl(contentType: String?) = "https://nostr.build/api/upload/android.php"
|
override fun postUrl(contentType: String?) = "https://nostr.build/api/upload/android.php"
|
||||||
|
|
||||||
override fun parseUrlFromSucess(body: String): String? {
|
override fun parseUrlFromSucess(body: String): String? {
|
||||||
val url = jacksonObjectMapper().readTree(body)
|
val url = jacksonObjectMapper().readTree(body) // return url.toString()
|
||||||
return url.toString().replace("\"", "")
|
return url.toString().replace("\"", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ open class NewMediaModel : ViewModel() {
|
|||||||
ImageUploader.uploadImage(
|
ImageUploader.uploadImage(
|
||||||
uri = uri,
|
uri = uri,
|
||||||
server = serverToUse,
|
server = serverToUse,
|
||||||
|
context = context,
|
||||||
contentResolver = contentResolver,
|
contentResolver = contentResolver,
|
||||||
onSuccess = { imageUrl, mimeType ->
|
onSuccess = { imageUrl, mimeType ->
|
||||||
createNIP94Record(imageUrl, mimeType, description)
|
createNIP94Record(imageUrl, mimeType, description)
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ open class NewPostViewModel : ViewModel() {
|
|||||||
ImageUploader.uploadImage(
|
ImageUploader.uploadImage(
|
||||||
uri = it,
|
uri = it,
|
||||||
server = server,
|
server = server,
|
||||||
|
context = context,
|
||||||
contentResolver = contentResolver,
|
contentResolver = contentResolver,
|
||||||
onSuccess = { imageUrl, mimeType ->
|
onSuccess = { imageUrl, mimeType ->
|
||||||
if (server == ServersAvailable.IMGUR_NIP_94 || server == ServersAvailable.NOSTRIMG_NIP_94) {
|
if (server == ServersAvailable.IMGUR_NIP_94 || server == ServersAvailable.NOSTRIMG_NIP_94) {
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ class NewUserMetadataViewModel : ViewModel() {
|
|||||||
ImageUploader.uploadImage(
|
ImageUploader.uploadImage(
|
||||||
uri = it,
|
uri = it,
|
||||||
server = account.defaultFileServer,
|
server = account.defaultFileServer,
|
||||||
|
context = context,
|
||||||
contentResolver = context.contentResolver,
|
contentResolver = context.contentResolver,
|
||||||
onSuccess = { imageUrl, mimeType ->
|
onSuccess = { imageUrl, mimeType ->
|
||||||
onUploading(false)
|
onUploading(false)
|
||||||
|
|||||||
Reference in New Issue
Block a user