[+] Upload

This commit is contained in:
2025-10-26 12:31:16 +08:00
parent 5fbacee18f
commit 6f2037a9dc
4 changed files with 86 additions and 9 deletions
+2
View File
@@ -3,8 +3,10 @@
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:usesCleartextTraffic="true"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
@@ -38,11 +38,13 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import aza.instant.network.BackendClient
import aza.instant.ui.theme.ProjectInstantTheme
import kotlinx.coroutines.launch
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import java.util.UUID
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -65,6 +67,7 @@ fun FileListerScreen(modifier: Modifier = Modifier) {
var picture by remember { mutableStateOf<Picture?>(null) }
val scrollState = rememberScrollState()
val coroutineScope = rememberCoroutineScope()
val backendClient = remember { BackendClient() }
Column(
modifier = modifier.fillMaxSize(),
@@ -121,16 +124,25 @@ fun FileListerScreen(modifier: Modifier = Modifier) {
picture = renderSvgAndroid(context, svg)
// Save picture to file
val file = File(latestImage.parent, "${latestImage.nameWithoutExtension}.framed.${System.currentTimeMillis()}.jpg")
file.createNewFile()
file.outputStream().use { outputStream ->
val renderedImageFile = File(latestImage.parent, "${latestImage.nameWithoutExtension}.framed.${System.currentTimeMillis()}.jpg")
renderedImageFile.createNewFile()
renderedImageFile.outputStream().use { outputStream ->
Bitmap.createBitmap(picture!!).compress(Bitmap.CompressFormat.JPEG, 90, outputStream)
}
feedbackText = "Rendered ${latestImage.name}"
feedbackText = "Rendered ${latestImage.name}, now uploading..."
val response = backendClient.uploadImage(
id = UUID.randomUUID().toString(),
ownerKey = "1234",
originalPhoto = latestImage,
editedPhoto = renderedImageFile
)
feedbackText = "Upload response: ${response.status}"
} catch (e: Exception) {
feedbackText = "Error rendering: ${e.message}"
Log.e("MainActivity", "Error rendering", e)
feedbackText = "Error during operation: ${e.message}"
Log.e("MainActivity", "Error during render or upload", e)
}
} else {
feedbackText = "No images found in CA_IMAGES"
@@ -138,7 +150,7 @@ fun FileListerScreen(modifier: Modifier = Modifier) {
}
},
) {
Text(text = "Render Latest Image")
Text(text = "Render and Upload")
}
}
@@ -0,0 +1,60 @@
package aza.instant.network
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.HttpTimeoutConfig
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.plugins.timeout
import io.ktor.client.request.*
import io.ktor.client.request.forms.*
import io.ktor.client.statement.*
import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.serialization.json.Json
import java.io.File
class BackendClient {
private val client = HttpClient(CIO) {
install(ContentNegotiation) {
json(Json {
prettyPrint = true
isLenient = true
ignoreUnknownKeys = true
})
}
}
companion object {
private const val API_KEY = "meowmeow"
private const val SERVER_URL = "http://172.16.0.212:3000" // For Android emulator
}
suspend fun uploadImage(
id: String,
ownerKey: String,
originalPhoto: File,
editedPhoto: File
): HttpResponse {
val origB = originalPhoto.readBytes()
val editB = editedPhoto.readBytes()
println(origB.size)
println(editB.size)
return client.post("$SERVER_URL/upload") {
headers {
append("x-instant-key", API_KEY)
}
setBody(
MultiPartFormDataContent(
formData {
append("id", id)
append("owner_key", ownerKey)
append("\"photo\"", originalPhoto.name, ContentType.Image.JPEG, origB.size.toLong()) { write(origB) }
append("\"edited_photo\"", editedPhoto.name, ContentType.Image.JPEG, editB.size.toLong()) { write(editB) }
}
)
)
timeout { HttpTimeoutConfig(1 * 60 * 1000L) }
}
}
}