Auto update subscriptions when adding a url
This commit is contained in:
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
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user