Add local folder config
parent
5355dc5b38
commit
39d137a81c
|
@ -33,9 +33,11 @@ import java.net.URLDecoder
|
|||
val IMAGE_PREVIEW = Regex("^/image/preview/\\d+$")
|
||||
val IMAGE_FULL = Regex("^/image/full/\\d+$")
|
||||
|
||||
val SHARE_URL = Regex("/api/share/url/.+$")
|
||||
val SHARE_BLOB = Regex("/api/share/blob/.+$")
|
||||
val SHARE_LOCAL = Regex("/api/share/local/\\d+$")
|
||||
val SHARE_URL = Regex("^/api/share/url/.+$")
|
||||
val SHARE_BLOB = Regex("^/api/share/blob/.+$")
|
||||
val SHARE_LOCAL = Regex("^/api/share/local/\\d+$")
|
||||
|
||||
val CONFIG_LOCAL_FOLDES = Regex("^/api/config/local-folders$")
|
||||
}
|
||||
|
||||
init {
|
||||
|
@ -178,6 +180,12 @@ import java.net.URLDecoder
|
|||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun configSetLocalFolders(json: String?) {
|
||||
if (json == null) return;
|
||||
query.configSetLocalFolders(json)
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
private fun routerGet(path: String): WebResourceResponse {
|
||||
val parts = path.split("/").toTypedArray()
|
||||
|
@ -199,6 +207,8 @@ import java.net.URLDecoder
|
|||
return makeResponse(dlService!!.shareBlobFromUrl(URLDecoder.decode(parts[4], "UTF-8")))
|
||||
} else if (path.matches(API.SHARE_LOCAL)) {
|
||||
return makeResponse(dlService!!.shareLocal(parts[4].toLong()))
|
||||
} else if (path.matches(API.CONFIG_LOCAL_FOLDES)) {
|
||||
return makeResponse(query.getLocalFoldersConfig())
|
||||
} else {
|
||||
throw Exception("Not Found")
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ class SystemImage {
|
|||
var size = 0L
|
||||
var mtime = 0L
|
||||
var dataPath = ""
|
||||
var bucketId = 0L
|
||||
var bucketName = ""
|
||||
|
||||
var isVideo = false
|
||||
var videoDuration = 0L
|
||||
|
@ -50,7 +52,9 @@ class SystemImage {
|
|||
MediaStore.Images.Media.ORIENTATION,
|
||||
MediaStore.Images.Media.DATE_TAKEN,
|
||||
MediaStore.Images.Media.DATE_MODIFIED,
|
||||
MediaStore.Images.Media.DATA
|
||||
MediaStore.Images.Media.DATA,
|
||||
MediaStore.Images.Media.BUCKET_ID,
|
||||
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
|
||||
)
|
||||
|
||||
// Add video-specific fields
|
||||
|
@ -69,6 +73,8 @@ class SystemImage {
|
|||
val dateTakenColumn = projection.indexOf(MediaStore.Images.Media.DATE_TAKEN)
|
||||
val dateModifiedColumn = projection.indexOf(MediaStore.Images.Media.DATE_MODIFIED)
|
||||
val dataColumn = projection.indexOf(MediaStore.Images.Media.DATA)
|
||||
val bucketIdColumn = projection.indexOf(MediaStore.Images.Media.BUCKET_ID)
|
||||
val bucketNameColumn = projection.indexOf(MediaStore.Images.Media.BUCKET_DISPLAY_NAME)
|
||||
|
||||
// Query content resolver
|
||||
ctx.contentResolver.query(
|
||||
|
@ -91,6 +97,8 @@ class SystemImage {
|
|||
image.dateTaken = cursor.getLong(dateTakenColumn)
|
||||
image.mtime = cursor.getLong(dateModifiedColumn)
|
||||
image.dataPath = cursor.getString(dataColumn)
|
||||
image.bucketId = cursor.getLong(bucketIdColumn)
|
||||
image.bucketName = cursor.getString(bucketNameColumn)
|
||||
image.mCollection = collection
|
||||
|
||||
// Swap width/height if orientation is 90 or 270
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.database.sqlite.SQLiteOpenHelper
|
|||
import android.database.sqlite.SQLiteDatabase
|
||||
import gallery.memories.R
|
||||
|
||||
class DbService(val context: Context) : SQLiteOpenHelper(context, "memories", null, 31) {
|
||||
class DbService(val context: Context) : SQLiteOpenHelper(context, "memories", null, 34) {
|
||||
override fun onCreate(db: SQLiteDatabase) {
|
||||
db.execSQL("""
|
||||
CREATE TABLE images (
|
||||
|
@ -16,6 +16,8 @@ class DbService(val context: Context) : SQLiteOpenHelper(context, "memories", nu
|
|||
dayid INTEGER,
|
||||
exif_uid TEXT,
|
||||
basename TEXT,
|
||||
bucket_id INTEGER,
|
||||
bucket_name TEXT,
|
||||
flag INTEGER
|
||||
)
|
||||
""")
|
||||
|
@ -24,6 +26,7 @@ class DbService(val context: Context) : SQLiteOpenHelper(context, "memories", nu
|
|||
db.execSQL("CREATE INDEX images_local_id ON images (local_id)")
|
||||
db.execSQL("CREATE INDEX images_dayid ON images (dayid)")
|
||||
db.execSQL("CREATE INDEX images_flag ON images (flag)")
|
||||
db.execSQL("CREATE INDEX images_bucket ON images (bucket_id)")
|
||||
}
|
||||
|
||||
override fun onUpgrade(database: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
|
|
|
@ -35,6 +35,9 @@ class TimelineQuery(private val mCtx: AppCompatActivity) {
|
|||
var deleteIntentLauncher: ActivityResultLauncher<IntentSenderRequest>
|
||||
var deleteCallback: ((ActivityResult?) -> Unit)? = null
|
||||
|
||||
// Caches
|
||||
var mEnabledBuckets: Set<String>? = null
|
||||
|
||||
init {
|
||||
// Register intent launcher for callback
|
||||
deleteIntentLauncher = mCtx.registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result: ActivityResult? ->
|
||||
|
@ -46,11 +49,17 @@ class TimelineQuery(private val mCtx: AppCompatActivity) {
|
|||
|
||||
@Throws(JSONException::class)
|
||||
fun getByDayId(dayId: Long): JSONArray {
|
||||
// Filter for enabled buckets
|
||||
val enabledBuckets = getEnabledBucketIds().joinToString(",")
|
||||
|
||||
// Get list of images from DB
|
||||
val imageIds: MutableSet<Long> = ArraySet()
|
||||
val datesTaken: MutableMap<Long, Long> = HashMap()
|
||||
val sql = "SELECT local_id, date_taken FROM images WHERE dayid = ?"
|
||||
mDb.rawQuery(sql, arrayOf(dayId.toString())).use { cursor ->
|
||||
mDb.rawQuery("""
|
||||
SELECT local_id, date_taken FROM images
|
||||
WHERE dayid = ?
|
||||
AND bucket_id IN ($enabledBuckets)
|
||||
""", arrayOf(dayId.toString())).use { cursor ->
|
||||
while (cursor.moveToNext()) {
|
||||
val localId = cursor.getLong(0)
|
||||
datesTaken[localId] = cursor.getLong(1)
|
||||
|
@ -95,8 +104,14 @@ class TimelineQuery(private val mCtx: AppCompatActivity) {
|
|||
|
||||
@Throws(JSONException::class)
|
||||
fun getDays(): JSONArray {
|
||||
mDb.rawQuery(
|
||||
"SELECT dayid, COUNT(local_id) FROM images GROUP BY dayid",
|
||||
// Filter for enabled buckets
|
||||
val enabledBuckets = getEnabledBucketIds().joinToString(",")
|
||||
|
||||
// Get this day's images
|
||||
mDb.rawQuery("""
|
||||
SELECT dayid, COUNT(local_id) FROM images
|
||||
WHERE bucket_id IN ($enabledBuckets)
|
||||
GROUP BY dayid""",
|
||||
null
|
||||
).use { cursor ->
|
||||
val days = JSONArray()
|
||||
|
@ -304,11 +319,62 @@ class TimelineQuery(private val mCtx: AppCompatActivity) {
|
|||
// Delete file with same local_id and insert new one
|
||||
mDb.beginTransaction()
|
||||
mDb.execSQL("DELETE FROM images WHERE local_id = ?", arrayOf(id))
|
||||
mDb.execSQL("INSERT OR IGNORE INTO images (local_id, mtime, basename, date_taken, dayid) VALUES (?, ?, ?, ?, ?)", arrayOf(
|
||||
id, image.mtime, name, dateTaken, dayId
|
||||
mDb.execSQL("""
|
||||
INSERT OR IGNORE INTO images
|
||||
(local_id, mtime, basename, date_taken, dayid, bucket_id, bucket_name)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
""", arrayOf(
|
||||
image.fileId,
|
||||
image.mtime,
|
||||
image.baseName,
|
||||
dateTaken,
|
||||
dayId,
|
||||
image.bucketId,
|
||||
image.bucketName
|
||||
))
|
||||
mDb.setTransactionSuccessful()
|
||||
mDb.endTransaction()
|
||||
Log.v(TAG, "Inserted file to local DB: $id / $name / $dayId")
|
||||
}
|
||||
|
||||
fun getEnabledBucketIds(): Set<String> {
|
||||
if (mEnabledBuckets != null) return mEnabledBuckets!!
|
||||
mEnabledBuckets = mCtx.getSharedPreferences(mCtx.getString(R.string.preferences_key), 0)
|
||||
.getStringSet(mCtx.getString(R.string.preferences_enabled_local_folders), null) ?: setOf()
|
||||
return mEnabledBuckets!!
|
||||
}
|
||||
|
||||
fun getLocalFoldersConfig(): JSONArray {
|
||||
val array = JSONArray()
|
||||
val enabledSet = getEnabledBucketIds()
|
||||
|
||||
val sql = "SELECT bucket_id, bucket_name FROM images GROUP BY bucket_id"
|
||||
mDb.rawQuery(sql, emptyArray()).use { cursor ->
|
||||
while (cursor.moveToNext()) {
|
||||
val obj = JSONObject()
|
||||
val id = cursor.getLong(0)
|
||||
obj.put("id", id)
|
||||
obj.put("name", cursor.getString(1))
|
||||
obj.put("enabled", enabledSet.contains(id.toString()))
|
||||
array.put(obj)
|
||||
}
|
||||
}
|
||||
|
||||
return array
|
||||
}
|
||||
|
||||
fun configSetLocalFolders(json: String) {
|
||||
val enabledSet = mutableSetOf<String>()
|
||||
val array = JSONArray(json)
|
||||
for (i in 0 until array.length()) {
|
||||
val obj = array.getJSONObject(i)
|
||||
if (obj.getBoolean("enabled")) {
|
||||
enabledSet.add(obj.getLong("id").toString())
|
||||
}
|
||||
}
|
||||
mEnabledBuckets = enabledSet
|
||||
mCtx.getSharedPreferences(mCtx.getString(R.string.preferences_key), 0).edit()
|
||||
.putStringSet(mCtx.getString(R.string.preferences_enabled_local_folders), enabledSet)
|
||||
.apply()
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
<string name="preferences_theme_dark">themeDark</string>
|
||||
<string name="preferences_last_sync_time">lastDbSyncTime</string>
|
||||
<string name="preferences_has_media_permission">hasMediaPermission</string>
|
||||
<string name="preferences_enabled_local_folders">enabledLocalFolders</string>
|
||||
|
||||
<!-- https://www.whatismybrowser.com/guides/the-latest-user-agent/chrome -->
|
||||
<string name="ua_chrome">"Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.5672.76 Mobile Safari/537.36"</string>
|
||||
|
|
Loading…
Reference in New Issue