2026-02-22 00:47:44 +02:00
|
|
|
package xyz.pixelatedw.recipe.utils
|
|
|
|
|
|
2026-02-22 17:57:55 +02:00
|
|
|
import android.content.Context
|
2026-02-22 00:47:44 +02:00
|
|
|
import android.os.Handler
|
|
|
|
|
import android.os.Looper
|
|
|
|
|
import androidx.documentfile.provider.DocumentFile
|
|
|
|
|
import xyz.pixelatedw.recipe.MainActivity
|
|
|
|
|
import java.io.DataInputStream
|
|
|
|
|
import java.io.File
|
|
|
|
|
import java.io.FileOutputStream
|
|
|
|
|
import java.net.Socket
|
|
|
|
|
import java.nio.ByteBuffer
|
|
|
|
|
import java.nio.charset.StandardCharsets
|
|
|
|
|
import java.util.concurrent.Executors
|
|
|
|
|
|
2026-02-22 17:57:55 +02:00
|
|
|
const val DEFAULT_SYNC_SERVER_IP = "192.168.0.100"
|
|
|
|
|
const val DEFAULT_SYNC_SERVER_PORT = 9696
|
2026-02-22 00:47:44 +02:00
|
|
|
|
|
|
|
|
fun sync(ctx: MainActivity) {
|
|
|
|
|
val executor = Executors.newSingleThreadExecutor()
|
|
|
|
|
val handler = Handler(Looper.getMainLooper())
|
|
|
|
|
|
2026-02-22 17:57:55 +02:00
|
|
|
executor.execute {
|
2026-02-22 00:47:44 +02:00
|
|
|
try {
|
2026-02-22 17:57:55 +02:00
|
|
|
val prefs = ctx.getPreferences(Context.MODE_PRIVATE)
|
|
|
|
|
val syncServerIp = prefs.getString("syncServerIp", DEFAULT_SYNC_SERVER_IP)
|
|
|
|
|
val syncServerPort = prefs.getInt("syncServerPort", DEFAULT_SYNC_SERVER_PORT)
|
|
|
|
|
|
|
|
|
|
val conn = Socket(syncServerIp, syncServerPort)
|
2026-02-22 00:47:44 +02:00
|
|
|
val stream = conn.getInputStream()
|
|
|
|
|
|
|
|
|
|
val inputStream = DataInputStream(stream)
|
|
|
|
|
|
|
|
|
|
var buffer = ByteArray(8)
|
|
|
|
|
inputStream.read(buffer)
|
|
|
|
|
val filesSent = ByteBuffer.wrap(buffer).getLong().toInt()
|
|
|
|
|
|
2026-02-22 17:57:55 +02:00
|
|
|
for (f in 0..<filesSent) {
|
2026-02-22 00:47:44 +02:00
|
|
|
buffer = ByteArray(8)
|
|
|
|
|
inputStream.read(buffer)
|
|
|
|
|
val nameBufLen = ByteBuffer.wrap(buffer).getLong().toInt()
|
|
|
|
|
|
|
|
|
|
buffer = ByteArray(nameBufLen)
|
|
|
|
|
inputStream.read(buffer)
|
2026-02-22 17:57:55 +02:00
|
|
|
val fileFullPath =
|
|
|
|
|
StandardCharsets.UTF_8.decode(ByteBuffer.wrap(buffer)).toString();
|
2026-02-22 00:47:44 +02:00
|
|
|
val fileName = fileFullPath.split("/").last()
|
|
|
|
|
val filePath = fileFullPath.replace(fileName, "")
|
|
|
|
|
|
|
|
|
|
buffer = ByteArray(8)
|
|
|
|
|
inputStream.read(buffer)
|
|
|
|
|
val contentBufLen = ByteBuffer.wrap(buffer).getLong().toInt()
|
|
|
|
|
|
|
|
|
|
var parentDir = ctx.filesDir
|
|
|
|
|
if (filePath.isNotEmpty()) {
|
|
|
|
|
parentDir = File(ctx.filesDir, filePath)
|
|
|
|
|
parentDir.mkdirs()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val newFile = File(parentDir, fileName)
|
|
|
|
|
|
|
|
|
|
val fos = FileOutputStream(newFile, false)
|
|
|
|
|
var usedBytes = 0
|
|
|
|
|
var blockSize = 1024
|
|
|
|
|
while (usedBytes != contentBufLen) {
|
|
|
|
|
if (usedBytes + blockSize > contentBufLen) {
|
|
|
|
|
blockSize = contentBufLen - usedBytes
|
2026-02-22 17:57:55 +02:00
|
|
|
} else if (blockSize > contentBufLen) {
|
2026-02-22 00:47:44 +02:00
|
|
|
blockSize = contentBufLen
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val contentBuffer = ByteArray(blockSize)
|
|
|
|
|
val readBytes = inputStream.read(contentBuffer)
|
|
|
|
|
|
|
|
|
|
fos.write(contentBuffer, 0, readBytes)
|
|
|
|
|
fos.flush()
|
|
|
|
|
usedBytes += readBytes
|
|
|
|
|
}
|
|
|
|
|
fos.close()
|
|
|
|
|
|
|
|
|
|
// println("new file: ${newFile.absolutePath} | $contentBufLen | ${newFile.length()}")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val docDir = DocumentFile.fromFile(ctx.filesDir)
|
|
|
|
|
parseDir(ctx, docDir, "")
|
|
|
|
|
parseRecipeFiles(ctx)
|
|
|
|
|
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
e.printStackTrace()
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-22 17:57:55 +02:00
|
|
|
handler.post {
|
2026-02-22 00:47:44 +02:00
|
|
|
val recipes = ctx.db.recipeWithTagsDao().getAll()
|
|
|
|
|
ctx.recipeView.setRecipes(recipes)
|
2026-02-22 17:57:55 +02:00
|
|
|
// println("syncing complete")
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-02-22 00:47:44 +02:00
|
|
|
}
|