recipe-kt/app/src/main/java/xyz/pixelatedw/recipe/utils/RecipeParser.kt

142 lines
3.1 KiB
Kotlin
Raw Normal View History

2025-08-08 23:21:33 +03:00
package xyz.pixelatedw.recipe.utils
import android.content.Context
import android.net.Uri
import androidx.core.text.trimmedLength
import androidx.documentfile.provider.DocumentFile
import io.github.wasabithumb.jtoml.JToml
import xyz.pixelatedw.recipe.data.AppDatabase
2025-08-08 23:21:33 +03:00
import xyz.pixelatedw.recipe.data.Recipe
import xyz.pixelatedw.recipe.data.RecipeTag
import xyz.pixelatedw.recipe.data.Tag
2025-08-08 23:21:33 +03:00
import java.io.BufferedReader
import java.io.File
import java.io.FileOutputStream
2025-08-08 23:21:33 +03:00
import java.io.InputStreamReader
private val recipeFiles = mutableListOf<DocumentFile>()
fun getRecipes(ctx: Context, db: AppDatabase, uri: Uri?) {
2025-08-08 23:21:33 +03:00
if (uri == null) {
return
}
val path = ""
2025-08-08 23:21:33 +03:00
val dir = DocumentFile.fromTreeUri(ctx, uri)
if (dir != null) {
parseDir(ctx, dir, path)
for (file in recipeFiles) {
parseRecipe(ctx, db, file)
}
}
}
fun parseDir(ctx: Context, dir: DocumentFile, path: String) {
val fileList: Array<DocumentFile> = dir.listFiles()
for (file in fileList) {
if (file.isDirectory) {
parseDir(ctx, file, path + File.separator + file.name)
continue;
}
if (file.isFile && file.name?.endsWith(".jpg") == true) {
val picsDir = File(ctx.filesDir, path)
picsDir.mkdirs()
val newFile = File(picsDir, file.name!!)
ctx.contentResolver.openInputStream(file.uri).use { inStream ->
FileOutputStream(newFile, false).use { outStream ->
inStream?.copyTo(outStream)
}
2025-08-08 23:21:33 +03:00
}
}
if (file.isFile && file.name?.endsWith(".md") == true) {
recipeFiles.add(file)
}
2025-08-08 23:21:33 +03:00
}
}
private fun parseRecipe(ctx: Context, db: AppDatabase, file: DocumentFile) {
2025-08-08 23:21:33 +03:00
val lastModified = file.lastModified()
val inputStream = ctx.contentResolver.openInputStream(file.uri)
val reader = BufferedReader(InputStreamReader(inputStream))
val text = reader.readText()
val lines = text.lines()
val sb = StringBuilder()
var hasToml = false
var frontMatterSize = 0
for (line in lines) {
2025-08-08 23:21:33 +03:00
frontMatterSize += line.trimmedLength() + 1
if (line == "+++") {
if (hasToml) {
break
}
hasToml = true
continue
}
sb.appendLine(line)
}
if (!hasToml) {
reader.close()
return
}
2025-08-08 23:21:33 +03:00
val toml = JToml.jToml()
val doc = toml.readFromString(sb.toString())
if (!doc.contains("title")) {
reader.close()
return
2025-08-08 23:21:33 +03:00
}
val recipeTitle = doc["title"]!!.asPrimitive().asString()
val pics = arrayListOf<String>()
if (doc.contains("pics")) {
for (tomlElem in doc["pics"]!!.asArray()) {
pics.add(tomlElem!!.asPrimitive().asString())
}
}
val tags = arrayListOf<Tag>()
if (doc.contains("tags")) {
for (tomlElem in doc["tags"]!!.asArray()) {
val tag = Tag(tomlElem!!.asPrimitive().asString())
tags.add(tag)
val recipeWithTags = RecipeTag(recipeTitle, tag.name)
db.tagDao().insert(tag)
db.recipeWithTagsDao().insert(recipeWithTags)
}
}
var recipePreview: String? = null
for (pic in pics) {
recipePreview = pic
}
2025-08-08 23:21:33 +03:00
val content = text.substring(frontMatterSize..<text.length)
val recipe = Recipe(
title = recipeTitle,
preview = recipePreview,
2025-08-08 23:21:33 +03:00
lastModified = lastModified,
content = content
)
db.recipeDao().insert(recipe)
println(recipe)
reader.close()
2025-08-08 23:21:33 +03:00
}