mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2024-09-30 00:40:49 +00:00
Merge pull request #391 from believethehype/nostrbuild
Added example for Image upload on nostr.build
This commit is contained in:
commit
771bb3fc27
@ -1,14 +1,20 @@
|
||||
package com.vitorpamplona.amethyst.ui.actions
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.provider.OpenableColumns
|
||||
import android.util.Log
|
||||
import android.webkit.MimeTypeMap
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.vitorpamplona.amethyst.BuildConfig
|
||||
import okhttp3.*
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.RequestBody.Companion.asRequestBody
|
||||
import okio.BufferedSink
|
||||
import okio.source
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
@ -21,46 +27,68 @@ object ImageUploader {
|
||||
fun uploadImage(
|
||||
uri: Uri,
|
||||
server: ServersAvailable,
|
||||
context: Context,
|
||||
contentResolver: ContentResolver,
|
||||
onSuccess: (String, String?) -> Unit,
|
||||
onError: (Throwable) -> Unit
|
||||
) {
|
||||
val contentType = contentResolver.getType(uri)
|
||||
val imageInputStream = contentResolver.openInputStream(uri)
|
||||
|
||||
checkNotNull(imageInputStream) {
|
||||
"Can't open the image input stream"
|
||||
}
|
||||
|
||||
val myServer = if (server == ServersAvailable.IMGUR) {
|
||||
ImgurServer()
|
||||
} else if (server == ServersAvailable.NOSTRIMG) {
|
||||
NostrImgServer()
|
||||
} else if (server == ServersAvailable.NOSTR_BUILD) {
|
||||
NostrBuildServer()
|
||||
} else {
|
||||
ImgurServer()
|
||||
}
|
||||
|
||||
uploadImage(imageInputStream, contentType, myServer, 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(
|
||||
file: File,
|
||||
inputStream: InputStream,
|
||||
contentType: String?,
|
||||
server: FileServer,
|
||||
serverType: ServersAvailable,
|
||||
onSuccess: (String, String?) -> Unit,
|
||||
onError: (Throwable) -> Unit
|
||||
) {
|
||||
val category = contentType?.toMediaType()?.toString()?.split("/")?.get(0) ?: "image"
|
||||
|
||||
val fileName = randomChars()
|
||||
val extension = contentType?.let { MimeTypeMap.getSingleton().getExtensionFromMimeType(it) } ?: ""
|
||||
|
||||
val client = OkHttpClient.Builder().build()
|
||||
val requestBody: RequestBody
|
||||
val requestBuilder = Request.Builder()
|
||||
|
||||
val requestBody: RequestBody = MultipartBody.Builder()
|
||||
if (serverType == ServersAvailable.NOSTR_BUILD) {
|
||||
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()
|
||||
@ -71,18 +99,16 @@ object ImageUploader {
|
||||
}
|
||||
)
|
||||
.build()
|
||||
|
||||
val requestBuilder = Request.Builder()
|
||||
}
|
||||
|
||||
server.clientID()?.let {
|
||||
requestBuilder.header("Authorization", it)
|
||||
requestBuilder.addHeader("Authorization", it)
|
||||
}
|
||||
|
||||
requestBuilder
|
||||
.header("User-Agent", "Amethyst/${BuildConfig.VERSION_NAME}")
|
||||
.addHeader("User-Agent", "Amethyst/${BuildConfig.VERSION_NAME}")
|
||||
.url(server.postUrl(contentType))
|
||||
.post(requestBody)
|
||||
|
||||
val request = requestBuilder.build()
|
||||
|
||||
client.newCall(request).enqueue(object : Callback {
|
||||
@ -111,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 fun postUrl(contentType: String?): String
|
||||
abstract fun parseUrlFromSucess(body: String): String?
|
||||
@ -146,12 +204,10 @@ class ImgurServer : FileServer() {
|
||||
}
|
||||
|
||||
class NostrBuildServer : FileServer() {
|
||||
override fun postUrl(contentType: String?) = "https://nostr.build/api/upload/amethyst.php"
|
||||
|
||||
override fun postUrl(contentType: String?) = "https://nostr.build/api/upload/android.php"
|
||||
override fun parseUrlFromSucess(body: String): String? {
|
||||
val tree = jacksonObjectMapper().readTree(body)
|
||||
val url = tree?.get("data")?.get("link")?.asText()
|
||||
return url
|
||||
val url = jacksonObjectMapper().readTree(body) // return url.toString()
|
||||
return url.toString().replace("\"", "")
|
||||
}
|
||||
|
||||
override fun clientID() = null
|
||||
|
@ -44,6 +44,8 @@ open class NewMediaModel : ViewModel() {
|
||||
selectedServer = ServersAvailable.IMGUR_NIP_94
|
||||
} else if (selectedServer == ServersAvailable.NOSTRIMG) {
|
||||
selectedServer = ServersAvailable.NOSTRIMG_NIP_94
|
||||
} else if (selectedServer == ServersAvailable.NOSTR_BUILD) {
|
||||
selectedServer = ServersAvailable.NOSTR_BUILD_NIP_94
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,6 +77,7 @@ open class NewMediaModel : ViewModel() {
|
||||
ImageUploader.uploadImage(
|
||||
uri = uri,
|
||||
server = serverToUse,
|
||||
context = context,
|
||||
contentResolver = contentResolver,
|
||||
onSuccess = { imageUrl, mimeType ->
|
||||
createNIP94Record(imageUrl, mimeType, description)
|
||||
|
@ -116,6 +116,7 @@ fun ImageVideoPost(postViewModel: NewMediaModel, acc: Account) {
|
||||
val fileServers = listOf(
|
||||
Triple(ServersAvailable.IMGUR_NIP_94, stringResource(id = R.string.upload_server_imgur_nip94), stringResource(id = R.string.upload_server_imgur_nip94_explainer)),
|
||||
Triple(ServersAvailable.NOSTRIMG_NIP_94, stringResource(id = R.string.upload_server_nostrimg_nip94), stringResource(id = R.string.upload_server_nostrimg_nip94_explainer)),
|
||||
Triple(ServersAvailable.NOSTR_BUILD_NIP_94, stringResource(id = R.string.upload_server_nostrbuild_nip94), stringResource(id = R.string.upload_server_nostrbuild_nip94_explainer)),
|
||||
Triple(ServersAvailable.NIP95, stringResource(id = R.string.upload_server_relays_nip95), stringResource(id = R.string.upload_server_relays_nip95_explainer))
|
||||
)
|
||||
|
||||
@ -192,6 +193,7 @@ fun ImageVideoPost(postViewModel: NewMediaModel, acc: Account) {
|
||||
|
||||
if (postViewModel.selectedServer == ServersAvailable.NOSTRIMG_NIP_94 ||
|
||||
postViewModel.selectedServer == ServersAvailable.IMGUR_NIP_94 ||
|
||||
postViewModel.selectedServer == ServersAvailable.NOSTR_BUILD_NIP_94 ||
|
||||
postViewModel.selectedServer == ServersAvailable.NIP95
|
||||
) {
|
||||
Row(
|
||||
|
@ -590,6 +590,7 @@ enum class ServersAvailable {
|
||||
NOSTRIMG,
|
||||
IMGUR_NIP_94,
|
||||
NOSTRIMG_NIP_94,
|
||||
NOSTR_BUILD_NIP_94,
|
||||
NIP95
|
||||
}
|
||||
|
||||
@ -610,8 +611,10 @@ fun ImageVideoDescription(
|
||||
val fileServers = listOf(
|
||||
Triple(ServersAvailable.IMGUR, stringResource(id = R.string.upload_server_imgur), stringResource(id = R.string.upload_server_imgur_explainer)),
|
||||
Triple(ServersAvailable.NOSTRIMG, stringResource(id = R.string.upload_server_nostrimg), stringResource(id = R.string.upload_server_nostrimg_explainer)),
|
||||
Triple(ServersAvailable.NOSTR_BUILD, stringResource(id = R.string.upload_server_nostrbuild), stringResource(id = R.string.upload_server_nostrbuild_explainer)),
|
||||
Triple(ServersAvailable.IMGUR_NIP_94, stringResource(id = R.string.upload_server_imgur_nip94), stringResource(id = R.string.upload_server_imgur_nip94_explainer)),
|
||||
Triple(ServersAvailable.NOSTRIMG_NIP_94, stringResource(id = R.string.upload_server_nostrimg_nip94), stringResource(id = R.string.upload_server_nostrimg_nip94_explainer)),
|
||||
Triple(ServersAvailable.NOSTR_BUILD_NIP_94, stringResource(id = R.string.upload_server_nostrbuild_nip94), stringResource(id = R.string.upload_server_nostrbuild_nip94_explainer)),
|
||||
Triple(ServersAvailable.NIP95, stringResource(id = R.string.upload_server_relays_nip95), stringResource(id = R.string.upload_server_relays_nip95_explainer))
|
||||
)
|
||||
|
||||
@ -741,6 +744,7 @@ fun ImageVideoDescription(
|
||||
|
||||
if (selectedServer == ServersAvailable.NOSTRIMG_NIP_94 ||
|
||||
selectedServer == ServersAvailable.IMGUR_NIP_94 ||
|
||||
selectedServer == ServersAvailable.NOSTR_BUILD_NIP_94 ||
|
||||
selectedServer == ServersAvailable.NIP95
|
||||
) {
|
||||
Row(
|
||||
|
@ -145,9 +145,10 @@ open class NewPostViewModel : ViewModel() {
|
||||
ImageUploader.uploadImage(
|
||||
uri = it,
|
||||
server = server,
|
||||
context = context,
|
||||
contentResolver = contentResolver,
|
||||
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 || server == ServersAvailable.NOSTR_BUILD_NIP_94) {
|
||||
createNIP94Record(imageUrl, mimeType, description)
|
||||
} else {
|
||||
isUploadingImage = false
|
||||
|
@ -171,6 +171,7 @@ class NewUserMetadataViewModel : ViewModel() {
|
||||
ImageUploader.uploadImage(
|
||||
uri = it,
|
||||
server = account.defaultFileServer,
|
||||
context = context,
|
||||
contentResolver = context.contentResolver,
|
||||
onSuccess = { imageUrl, mimeType ->
|
||||
onUploading(false)
|
||||
|
@ -333,12 +333,18 @@
|
||||
<string name="upload_server_nostrimg">nostrimg.com - less secure</string>
|
||||
<string name="upload_server_nostrimg_explainer">Uploads to NostrImg. NostrImg can change your image at any time</string>
|
||||
|
||||
<string name="upload_server_nostrbuild">nostr.build- less secure</string>
|
||||
<string name="upload_server_nostrbuild_explainer">Uploads to nostr.build. Nostr.build can change your image at any time</string>
|
||||
|
||||
<string name="upload_server_imgur_nip94">Verifiable Imgur (NIP-94)</string>
|
||||
<string name="upload_server_imgur_nip94_explainer">Protects from Imgur modifying the content afterwards. This is a new NIP: other clients might not see the image</string>
|
||||
|
||||
<string name="upload_server_nostrimg_nip94">Verifiable NostrImg (NIP-94)</string>
|
||||
<string name="upload_server_nostrimg_nip94_explainer">Protects from NostrImg modifying the content afterwards. This is a new NIP: other clients might not see the image</string>
|
||||
|
||||
<string name="upload_server_nostrbuild_nip94">Verifiable Nostr.build (NIP-94)</string>
|
||||
<string name="upload_server_nostrbuild_nip94_explainer">Protects from Nostr.build modifying the content afterwards. This is a new NIP: other clients might not see the image</string>
|
||||
|
||||
<string name="upload_server_relays_nip95">Your relays (NIP-95)</string>
|
||||
<string name="upload_server_relays_nip95_explainer">Files are uploaded to and hosted by relays. They are free from a fixed url (third-party dependency). Make sure to have a NIP-95 relay in your relay list</string>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user