|
|
@@ -2,6 +2,7 @@ package com.github.kr328.clash.service
|
|
|
|
|
|
import android.content.Context
|
|
|
import com.github.kr328.clash.service.data.Database
|
|
|
+import com.github.kr328.clash.service.data.Imported
|
|
|
import com.github.kr328.clash.service.data.ImportedDao
|
|
|
import com.github.kr328.clash.service.data.Pending
|
|
|
import com.github.kr328.clash.service.data.PendingDao
|
|
|
@@ -13,10 +14,13 @@ import com.github.kr328.clash.service.util.directoryLastModified
|
|
|
import com.github.kr328.clash.service.util.generateProfileUUID
|
|
|
import com.github.kr328.clash.service.util.importedDir
|
|
|
import com.github.kr328.clash.service.util.pendingDir
|
|
|
+import com.github.kr328.clash.service.util.sendProfileChanged
|
|
|
import kotlinx.coroutines.CoroutineScope
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
import kotlinx.coroutines.launch
|
|
|
import kotlinx.coroutines.withContext
|
|
|
+import okhttp3.OkHttpClient
|
|
|
+import okhttp3.Request
|
|
|
import java.io.FileNotFoundException
|
|
|
import java.util.*
|
|
|
|
|
|
@@ -40,6 +44,10 @@ class ProfileManager(private val context: Context) : IProfileManager,
|
|
|
type = type,
|
|
|
source = source,
|
|
|
interval = 0,
|
|
|
+ upload = 0,
|
|
|
+ total = 0,
|
|
|
+ download = 0,
|
|
|
+ expire = 0,
|
|
|
)
|
|
|
|
|
|
PendingDao().insert(pending)
|
|
|
@@ -68,6 +76,10 @@ class ProfileManager(private val context: Context) : IProfileManager,
|
|
|
type = Profile.Type.File,
|
|
|
source = imported.source,
|
|
|
interval = imported.interval,
|
|
|
+ upload = imported.upload,
|
|
|
+ total = imported.total,
|
|
|
+ download = imported.download,
|
|
|
+ expire = imported.expire,
|
|
|
)
|
|
|
|
|
|
cloneImportedFiles(uuid, newUUID)
|
|
|
@@ -93,13 +105,21 @@ class ProfileManager(private val context: Context) : IProfileManager,
|
|
|
type = imported.type,
|
|
|
source = source,
|
|
|
interval = interval,
|
|
|
+ upload = 0,
|
|
|
+ total = 0,
|
|
|
+ download = 0,
|
|
|
+ expire = 0,
|
|
|
)
|
|
|
)
|
|
|
} else {
|
|
|
val newPending = pending.copy(
|
|
|
name = name,
|
|
|
source = source,
|
|
|
- interval = interval
|
|
|
+ interval = interval,
|
|
|
+ upload = 0,
|
|
|
+ total = 0,
|
|
|
+ download = 0,
|
|
|
+ expire = 0,
|
|
|
)
|
|
|
|
|
|
PendingDao().update(newPending)
|
|
|
@@ -108,6 +128,81 @@ class ProfileManager(private val context: Context) : IProfileManager,
|
|
|
|
|
|
override suspend fun update(uuid: UUID) {
|
|
|
scheduleUpdate(uuid, true)
|
|
|
+ ImportedDao().queryByUUID(uuid)?.let {
|
|
|
+ if (it.type == Profile.Type.Url) {
|
|
|
+ updateFlow(it)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ suspend fun updateFlow(old: Imported) {
|
|
|
+ val client = OkHttpClient()
|
|
|
+ try {
|
|
|
+ val request = Request.Builder()
|
|
|
+ .url(old.source)
|
|
|
+ .header("User-Agent", "ClashforWindows/0.19.23")
|
|
|
+ .build()
|
|
|
+
|
|
|
+ client.newCall(request).execute().use { response ->
|
|
|
+ if (!response.isSuccessful || response.headers["subscription-userinfo"] == null) return
|
|
|
+
|
|
|
+ var upload: Long = 0
|
|
|
+ var download: Long = 0
|
|
|
+ var total: Long = 0
|
|
|
+ var expire: Long = 0
|
|
|
+
|
|
|
+ val userinfo = response.headers["subscription-userinfo"]
|
|
|
+ if (response.isSuccessful && userinfo != null) {
|
|
|
+
|
|
|
+ val flags = userinfo.split(";")
|
|
|
+ for (flag in flags) {
|
|
|
+ val info = flag.split("=")
|
|
|
+ when {
|
|
|
+ info[0].contains("upload") -> upload =
|
|
|
+ info[1].toLong()
|
|
|
+
|
|
|
+ info[0].contains("download") -> download =
|
|
|
+ info[1].toLong()
|
|
|
+
|
|
|
+ info[0].contains("total") -> total =
|
|
|
+ info[1].toLong()
|
|
|
+
|
|
|
+ info[0].contains("expire") -> {
|
|
|
+ if (info[1].isNotEmpty()) {
|
|
|
+ expire = info[1].toLong()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ val new = Imported(
|
|
|
+ old.uuid,
|
|
|
+ old.name,
|
|
|
+ old.type,
|
|
|
+ old.source,
|
|
|
+ old.interval,
|
|
|
+ upload,
|
|
|
+ download,
|
|
|
+ total,
|
|
|
+ expire,
|
|
|
+ old?.createdAt ?: System.currentTimeMillis()
|
|
|
+ )
|
|
|
+
|
|
|
+ if (old != null) {
|
|
|
+ ImportedDao().update(new)
|
|
|
+ } else {
|
|
|
+ ImportedDao().insert(new)
|
|
|
+ }
|
|
|
+
|
|
|
+ PendingDao().remove(new.uuid)
|
|
|
+ context.sendProfileChanged(new.uuid)
|
|
|
+ // println(response.body!!.string())
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (e: Exception) {
|
|
|
+ System.out.println(e)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
override suspend fun commit(uuid: UUID, callback: IFetchObserver?) {
|
|
|
@@ -163,6 +258,10 @@ class ProfileManager(private val context: Context) : IProfileManager,
|
|
|
val type = pending?.type ?: imported?.type ?: return null
|
|
|
val source = pending?.source ?: imported?.source ?: return null
|
|
|
val interval = pending?.interval ?: imported?.interval ?: return null
|
|
|
+ val upload = pending?.upload ?: imported?.upload ?: return null
|
|
|
+ val download = pending?.download ?: imported?.download ?: return null
|
|
|
+ val total = pending?.total ?: imported?.total ?: return null
|
|
|
+ val expire = pending?.expire ?: imported?.expire ?: return null
|
|
|
|
|
|
return Profile(
|
|
|
uuid,
|
|
|
@@ -171,6 +270,10 @@ class ProfileManager(private val context: Context) : IProfileManager,
|
|
|
source,
|
|
|
active != null && imported?.uuid == active,
|
|
|
interval,
|
|
|
+ upload,
|
|
|
+ download,
|
|
|
+ total,
|
|
|
+ expire,
|
|
|
resolveUpdatedAt(uuid),
|
|
|
imported != null,
|
|
|
pending != null
|