Auto update subscriptions when adding a url

This commit is contained in:
2dust committed 2024-06-07 21:06:27 +08:00
1 parent 748405473b
commit ac7eb28e91
5 files changed
+121 -137

No files matched your search

@@ -58,23 +58,11 @@ object SubscriptionUpdater {
"subscription automatic update: ---${subscription.remarks}"
)
val configs = Utils.getUrlContentWithCustomUserAgent(subscription.url)
importBatchConfig(configs, i.first)
AngConfigManager.importBatchConfig(configs, i.first, false)
notification.setContentText("Updating ${subscription.remarks}")
}
notificationManager.cancel(3)
return Result.success()
}
}
fun importBatchConfig(server: String?, subid: String = "") {
val append = false
val count = AngConfigManager.importBatchConfig(server, subid, append)
if (count <= 0) {
AngConfigManager.importBatchConfig(Utils.decode(server), subid, append)
}
if (count <= 0) {
AngConfigManager.appendCustomConfigServer(server, subid)
}
}
}
@@ -40,7 +40,6 @@ import com.v2ray.ang.util.AngConfigManager
import com.v2ray.ang.util.MmkvManager
import com.v2ray.ang.util.Utils
import com.v2ray.ang.viewmodel.MainViewModel
import com.v2ray.ang.viewmodel.SubViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -64,7 +63,6 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
}
private var mItemTouchHelper: ItemTouchHelper? = null
val mainViewModel: MainViewModel by viewModels()
val subViewModel: SubViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -429,7 +427,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
.show()
lifecycleScope.launch(Dispatchers.IO) {
val count = subViewModel.importBatchConfig(server, mainViewModel.subscriptionId, true)
val count = AngConfigManager.importBatchConfig(server, mainViewModel.subscriptionId, true)
delay(500L)
launch(Dispatchers.Main) {
if (count > 0) {
@@ -524,7 +522,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
.show()
lifecycleScope.launch(Dispatchers.IO) {
val count = subViewModel.updateConfigViaSubAll()
val count = AngConfigManager.updateConfigViaSubAll()
delay(500L)
launch(Dispatchers.Main) {
if (count > 0) {
@@ -4,7 +4,6 @@ import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
@@ -13,8 +12,8 @@ import com.v2ray.ang.databinding.ActivitySubSettingBinding
import com.v2ray.ang.databinding.LayoutProgressBinding
import com.v2ray.ang.dto.SubscriptionItem
import com.v2ray.ang.extension.toast
import com.v2ray.ang.util.AngConfigManager
import com.v2ray.ang.util.MmkvManager
import com.v2ray.ang.viewmodel.SubViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -24,7 +23,6 @@ class SubSettingActivity : BaseActivity() {
var subscriptions: List<Pair<String, SubscriptionItem>> = listOf()
private val adapter by lazy { SubSettingRecyclerAdapter(this) }
val subViewModel: SubViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -63,7 +61,7 @@ class SubSettingActivity : BaseActivity() {
.show()
lifecycleScope.launch(Dispatchers.IO) {
val count = subViewModel.updateConfigViaSubAll()
val count = AngConfigManager.updateConfigViaSubAll()
delay(500L)
launch(Dispatchers.Main) {
if (count > 0) {
@@ -3,6 +3,7 @@ package com.v2ray.ang.util
import android.content.Context
import android.graphics.Bitmap
import android.text.TextUtils
import android.util.Log
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonPrimitive
@@ -10,8 +11,7 @@ import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import com.google.gson.reflect.TypeToken
import com.tencent.mmkv.MMKV
import com.v2ray.ang.AppConfig.PROTOCOL_HTTP
import com.v2ray.ang.AppConfig.PROTOCOL_HTTPS
import com.v2ray.ang.AppConfig
import com.v2ray.ang.R
import com.v2ray.ang.dto.*
import com.v2ray.ang.util.MmkvManager.KEY_SELECTED_SERVER
@@ -202,9 +202,9 @@ object AngConfigManager {
// }
/**
* import config form qrcode or...
* parse config form qrcode or...
*/
private fun importConfig(
private fun parseConfig(
str: String?,
subid: String,
removedSelectedServer: ServerConfig?
@@ -214,13 +214,6 @@ object AngConfigManager {
return R.string.toast_none_data
}
//maybe Subscription
if ((str.startsWith(PROTOCOL_HTTP) || str.startsWith(PROTOCOL_HTTPS))
) {
MmkvManager.importUrlAsSubscription(str)
return 0
}
val config = if (str.startsWith(EConfigType.VMESS.protocolScheme)) {
VmessFmt.parseVmess(str)
} else if (str.startsWith(EConfigType.SHADOWSOCKS.protocolScheme)) {
@@ -259,21 +252,20 @@ object AngConfigManager {
return 0
}
/**
* share config
*/
private fun shareConfig(guid: String): String {
try {
val config = MmkvManager.decodeServerConfig(guid) ?: return ""
return config.configType.protocolScheme + when (config.configType) {
EConfigType.VMESS -> VmessFmt.toUri(config)
EConfigType.CUSTOM -> ""
EConfigType.SHADOWSOCKS -> ShadowsocksFmt.toUri(config)
EConfigType.SHADOWSOCKS -> ShadowsocksFmt.toUri(config)
EConfigType.SOCKS -> SocksFmt.toUri(config)
EConfigType.VLESS-> VlessFmt.toUri(config)
EConfigType.TROJAN-> TrojanFmt.toUri(config)
EConfigType.VLESS -> VlessFmt.toUri(config)
EConfigType.TROJAN -> TrojanFmt.toUri(config)
EConfigType.WIREGUARD -> WireguardFmt.toUri(config)
}
} catch (e: Exception) {
@@ -394,7 +386,44 @@ object AngConfigManager {
// }
// }
fun importBatchConfig(servers: String?, subid: String, append: Boolean): Int {
fun importBatchConfig(server: String?, subid: String, append: Boolean): Int {
var count = parseBatchConfig(server, subid, append)
if (count <= 0) {
count = parseBatchConfig(Utils.decode(server), subid, append)
}
if (count <= 0) {
count = parseCustomConfigServer(server, subid)
}
if (parseBatchSubscription(server, subid) > 0) {
updateConfigViaSubAll()
return 1
}
return count
}
fun parseBatchSubscription(servers: String?, subid: String): Int {
try {
if (servers == null) {
return 0
}
var count = 0
servers.lines()
.reversed()
.forEach { str ->
if (str.startsWith(AppConfig.PROTOCOL_HTTP) || str.startsWith(AppConfig.PROTOCOL_HTTPS)) {
count += MmkvManager.importUrlAsSubscription(str)
}
}
return count
} catch (e: Exception) {
e.printStackTrace()
}
return 0
}
fun parseBatchConfig(servers: String?, subid: String, append: Boolean): Int {
try {
if (servers == null) {
return 0
@@ -415,16 +444,12 @@ object AngConfigManager {
if (!append) {
MmkvManager.removeServerViaSubid(subid)
}
// var servers = server
// if (server.indexOf("vmess") >= 0 && server.indexOf("vmess") == server.lastIndexOf("vmess")) {
// servers = server.replace("\n", "")
// }
var count = 0
servers.lines()
.reversed()
.forEach {
val resId = importConfig(it, subid, removedSelectedServer)
val resId = parseConfig(it, subid, removedSelectedServer)
if (resId == 0) {
count++
}
@@ -436,7 +461,7 @@ object AngConfigManager {
return 0
}
fun appendCustomConfigServer(server: String?, subid: String): Int {
fun parseCustomConfigServer(server: String?, subid: String): Int {
if (server == null) {
return 0
}
@@ -493,4 +518,72 @@ object AngConfigManager {
return 0
}
}
fun updateConfigViaSubAll(): Int {
var count = 0
try {
MmkvManager.decodeSubscriptions().forEach {
count += updateConfigViaSub(it)
}
} catch (e: Exception) {
e.printStackTrace()
return 0
}
return count
}
private fun updateConfigViaSub(it: Pair<String, SubscriptionItem>): Int {
try {
if (TextUtils.isEmpty(it.first)
|| TextUtils.isEmpty(it.second.remarks)
|| TextUtils.isEmpty(it.second.url)
) {
return 0
}
if (!it.second.enabled) {
return 0
}
val url = Utils.idnToASCII(it.second.url)
if (!Utils.isValidUrl(url)) {
return 0
}
Log.d(AppConfig.ANG_PACKAGE, url)
var configText = try {
Utils.getUrlContentWithCustomUserAgent(url)
} catch (e: Exception) {
e.printStackTrace()
""
}
if (configText.isEmpty()) {
configText = try {
val httpPort = Utils.parseInt(
settingsStorage?.decodeString(AppConfig.PREF_HTTP_PORT),
AppConfig.PORT_HTTP.toInt()
)
Utils.getUrlContentWithCustomUserAgent(url, httpPort)
} catch (e: Exception) {
e.printStackTrace()
""
}
}
if (configText.isEmpty()) {
return 0
}
return parseConfigViaSub(configText, it.first, false)
} catch (e: Exception) {
e.printStackTrace()
return 0
}
}
private fun parseConfigViaSub(server: String?, subid: String, append: Boolean): Int {
var count = parseBatchConfig(server, subid, append)
if (count <= 0) {
count = parseBatchConfig(Utils.decode(server), subid, append)
}
if (count <= 0) {
count = parseCustomConfigServer(server, subid)
}
return count
}
}
@@ -1,93 +0,0 @@
package com.v2ray.ang.viewmodel
import android.app.Application
import android.text.TextUtils
import android.util.Log
import androidx.lifecycle.AndroidViewModel
import com.tencent.mmkv.MMKV
import com.v2ray.ang.AppConfig
import com.v2ray.ang.dto.SubscriptionItem
import com.v2ray.ang.util.AngConfigManager
import com.v2ray.ang.util.MmkvManager
import com.v2ray.ang.util.Utils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
class SubViewModel(application: Application) : AndroidViewModel(application) {
private val settingsStorage by lazy {
MMKV.mmkvWithID(
MmkvManager.ID_SETTING,
MMKV.MULTI_PROCESS_MODE
)
}
private val tcpingTestScope by lazy { CoroutineScope(Dispatchers.IO) }
fun updateConfigViaSubAll(): Int {
var count = 0
try {
MmkvManager.decodeSubscriptions().forEach {
count += updateConfigViaSub(it)
}
} catch (e: Exception) {
e.printStackTrace()
return 0
}
return count
}
fun updateConfigViaSub(it: Pair<String, SubscriptionItem>): Int {
try {
if (TextUtils.isEmpty(it.first)
|| TextUtils.isEmpty(it.second.remarks)
|| TextUtils.isEmpty(it.second.url)
) {
return 0
}
if (!it.second.enabled) {
return 0
}
val url = Utils.idnToASCII(it.second.url)
if (!Utils.isValidUrl(url)) {
return 0
}
Log.d(AppConfig.ANG_PACKAGE, url)
var configText = try {
Utils.getUrlContentWithCustomUserAgent(url)
} catch (e: Exception) {
e.printStackTrace()
""
}
if (configText.isEmpty()) {
configText = try {
val httpPort = Utils.parseInt(
settingsStorage?.decodeString(AppConfig.PREF_HTTP_PORT),
AppConfig.PORT_HTTP.toInt()
)
Utils.getUrlContentWithCustomUserAgent(url, httpPort)
} catch (e: Exception) {
e.printStackTrace()
""
}
}
if (configText.isEmpty()) {
return 0
}
return importBatchConfig(configText, it.first, false)
} catch (e: Exception) {
e.printStackTrace()
return 0
}
}
fun importBatchConfig(server: String?, subid: String = "", append: Boolean): Int {
var count = AngConfigManager.importBatchConfig(server, subid, append)
if (count <= 0) {
count = AngConfigManager.importBatchConfig(Utils.decode(server), subid, append)
}
if (count <= 0) {
count = AngConfigManager.appendCustomConfigServer(server, subid)
}
return count
}
}