Refine parser
This commit is contained in:
@@ -50,9 +50,8 @@ import com.github.shadowsocks.utils.Parser
|
||||
class ParserActivity extends AppCompatActivity {
|
||||
override def onCreate(savedInstanceState: Bundle) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val data = getIntent.getData.toString
|
||||
val profile = Parser.parse(data)
|
||||
if (profile.isEmpty) { // ignore
|
||||
val profiles = Parser.findAll(getIntent.getData.toString)
|
||||
if (profiles.isEmpty) { // ignore
|
||||
finish()
|
||||
return
|
||||
}
|
||||
@@ -60,11 +59,10 @@ class ParserActivity extends AppCompatActivity {
|
||||
val dialog = new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.add_profile_dialog)
|
||||
.setCancelable(false)
|
||||
.setPositiveButton(android.R.string.yes, ((dialog: DialogInterface, id: Int) => {
|
||||
ShadowsocksApplication.profileManager.createProfile(profile.get)
|
||||
}): DialogInterface.OnClickListener)
|
||||
.setPositiveButton(android.R.string.yes, ((_, _) =>
|
||||
profiles.foreach(ShadowsocksApplication.profileManager.createProfile)): DialogInterface.OnClickListener)
|
||||
.setNegativeButton(android.R.string.no, null)
|
||||
.setMessage(data)
|
||||
.setMessage(profiles.mkString("\n"))
|
||||
.create()
|
||||
dialog.setOnDismissListener((dialog: DialogInterface) => finish()) // builder method was added in API 17
|
||||
dialog.show()
|
||||
|
||||
@@ -212,10 +212,8 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe
|
||||
|
||||
override def onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
|
||||
val scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)
|
||||
if (scanResult != null) Parser.parse(scanResult.getContents) match {
|
||||
case Some(profile) => ShadowsocksApplication.profileManager.createProfile(profile)
|
||||
case _ => // ignore
|
||||
}
|
||||
if (scanResult != null)
|
||||
Parser.findAll(scanResult.getContents).foreach(ShadowsocksApplication.profileManager.createProfile)
|
||||
}
|
||||
|
||||
def onMenuItemClick(item: MenuItem) = item.getItemId match {
|
||||
|
||||
@@ -39,44 +39,35 @@
|
||||
|
||||
package com.github.shadowsocks.utils
|
||||
|
||||
import com.github.shadowsocks.database.Profile
|
||||
import java.util.Locale
|
||||
import android.net.Uri
|
||||
import android.util.{Log, Base64}
|
||||
|
||||
import android.util.{Base64, Log}
|
||||
import com.github.shadowsocks.database.Profile
|
||||
|
||||
object Parser {
|
||||
val TAG = "ShadowParser"
|
||||
private val pattern = "(?i)ss://([A-Za-z0-9+/=]+)".r
|
||||
|
||||
def generate (profile: Profile): String = "ss://" + Base64.encodeToString("%s:%s@%s:%d".formatLocal(Locale.ENGLISH,
|
||||
profile.method, profile.password, profile.host, profile.remotePort).getBytes, Base64.NO_PADDING)
|
||||
|
||||
def parse (data: String): Option[Profile] = {
|
||||
try {
|
||||
Log.d(TAG, data)
|
||||
val uri = Uri.parse(data.trim)
|
||||
if (uri.getScheme == Scheme.SS) {
|
||||
val encoded = data.replace(Scheme.SS + "://", "")
|
||||
val content = new String(Base64.decode(encoded, Base64.NO_PADDING), "UTF-8")
|
||||
val methodIdx = content.indexOf(':')
|
||||
val passwordIdx = content.lastIndexOf('@')
|
||||
val hostIdx = content.lastIndexOf(':')
|
||||
val method = content.substring(0, methodIdx)
|
||||
val password = content.substring(methodIdx + 1, passwordIdx)
|
||||
val host = content.substring(passwordIdx + 1, hostIdx)
|
||||
val port = content.substring(hostIdx + 1)
|
||||
def findAll(data: String) = pattern.findAllMatchIn(data).map(m => try {
|
||||
val content = new String(Base64.decode(m.group(1), Base64.NO_PADDING), "UTF-8")
|
||||
val methodIdx = content.indexOf(':')
|
||||
val passwordIdx = content.lastIndexOf('@')
|
||||
val hostIdx = content.lastIndexOf(':')
|
||||
val host = content.substring(passwordIdx + 1, hostIdx)
|
||||
|
||||
val profile = new Profile
|
||||
profile.name = host
|
||||
profile.host = host
|
||||
profile.remotePort = port.toInt
|
||||
profile.localPort = 1080
|
||||
profile.method = method.toLowerCase
|
||||
profile.password = password
|
||||
return Some(profile)
|
||||
}
|
||||
} catch {
|
||||
case ex : Exception => Log.e(TAG, "parser error", ex)// Ignore
|
||||
}
|
||||
None
|
||||
}
|
||||
val profile = new Profile
|
||||
profile.name = host
|
||||
profile.host = host
|
||||
profile.remotePort = content.substring(hostIdx + 1).toInt
|
||||
profile.method = content.substring(0, methodIdx).toLowerCase
|
||||
profile.password = content.substring(methodIdx + 1, passwordIdx)
|
||||
profile
|
||||
} catch {
|
||||
case ex: Exception =>
|
||||
Log.e(TAG, "parser error: " + m.source, ex)// Ignore
|
||||
null
|
||||
}).filter(_ != null)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user