add qrcode support

This commit is contained in:
Y. T. Chung
2015-06-21 15:59:46 +08:00
parent 4f52975d17
commit d638a38339
4 changed files with 63 additions and 9 deletions

View File

@@ -79,3 +79,6 @@ optional = true
[dependencies.simplesched]
git = "https://github.com/zonyitoo/simplesched.git"
[dependencies.qrcode]
git = "https://github.com/kennytm/qrcode-rust.git"

View File

@@ -164,7 +164,7 @@ fn main() {
config.local = Some(SocketAddr::new(local_addr, local_port));
}
config.enable_udp = matches.value_of("ENABLE_UDP").is_some();
config.enable_udp = matches.is_present("ENABLE_UDP");
info!("ShadowSocks {}", shadowsocks::VERSION);

View File

@@ -153,7 +153,7 @@ fn main() {
panic!("`server-addr`, `server-port`, `method` and `password` should be provided together");
}
config.enable_udp = matches.value_of("ENABLE_UDP").is_some();
config.enable_udp = matches.is_present("ENABLE_UDP");
if !cfg!(feature = "enable-udp") && config.enable_udp {
error!("Please compile shadowsocks with --cfg feature=\"enable-udp\"");

View File

@@ -1,6 +1,7 @@
extern crate rustc_serialize;
extern crate clap;
extern crate shadowsocks;
extern crate qrcode;
use std::str;
@@ -9,20 +10,61 @@ use rustc_serialize::json::{ToJson, as_pretty_json};
use clap::{App, Arg};
use qrcode::QrCode;
use shadowsocks::config::{Config, ConfigType, ServerConfig};
fn encode(filename: &str) {
const BLACK: &'static str = "\x1b[40m \x1b[0m";
const WHITE: &'static str = "\x1b[47m \x1b[0m";
fn encode_url(svr: &ServerConfig) -> String {
let url = format!("{}:{}@{}:{}", svr.method.to_string(), svr.password, svr.addr, svr.port);
format!("ss://{}", url.as_bytes().to_base64(URL_SAFE))
}
fn print_qrcode(encoded: &str) {
let qrcode = QrCode::new(encoded.as_bytes()).unwrap();
for _ in 0..qrcode.width()+2 {
print!("{}", WHITE);
}
println!("");
for y in 0..qrcode.width() {
print!("{}", WHITE);
for x in 0..qrcode.width() {
let color = if qrcode[(x, y)] {
BLACK
} else {
WHITE
};
print!("{}", color);
}
println!("{}", WHITE);
}
for _ in 0..qrcode.width()+2 {
print!("{}", WHITE);
}
println!("");
}
fn encode(filename: &str, need_qrcode: bool) {
let config = Config::load_from_file(filename, ConfigType::Server).unwrap();
for svr in config.server {
let url = format!("{}:{}@{}:{}", svr.method.to_string(), svr.password, svr.addr, svr.port);
let encoded = format!("ss://{}", url.as_bytes().to_base64(URL_SAFE));
let encoded = encode_url(&svr);
println!("{}", encoded);
if need_qrcode {
print_qrcode(&encoded);
}
}
}
fn decode(encoded: &str) {
fn decode(encoded: &str, need_qrcode: bool) {
if !encoded.starts_with("ss://") {
panic!("Malformed input: {:?}", encoded);
}
@@ -55,6 +97,10 @@ fn decode(encoded: &str) {
let svrconfig_json = svrconfig.to_json();
println!("{}", as_pretty_json(&svrconfig_json));
if need_qrcode {
print_qrcode(encoded);
}
}
fn main() {
@@ -66,13 +112,18 @@ fn main() {
.help("Encode the server configuration in the provided JSON file"))
.arg(Arg::with_name("DECODE").short("d").long("decode")
.takes_value(true)
.help("Decode the server configuration from the provide ShadowSocks URL"));
.help("Decode the server configuration from the provide ShadowSocks URL"))
.arg(Arg::with_name("QRCODE").short("c").long("qrcode")
.takes_value(false)
.help("Generate the QRCode with the provided configuration"));
let matches = app.get_matches();
let need_qrcode = matches.is_present("QRCODE");
if let Some(file) = matches.value_of("ENCODE") {
encode(file);
encode(file, need_qrcode);
} else if let Some(encoded) = matches.value_of("DECODE") {
decode(encoded);
decode(encoded, need_qrcode);
} else {
println!("Use -h for more detail");
}