├── .DS_Store ├── icon.png ├── Trace (Proxy-helper).alfredworkflow ├── proxy.conf ├── readme.md ├── info.plist ├── trace.sh └── workflowHandler.sh /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yiichou/Trace.alfredworkflow/HEAD/.DS_Store -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yiichou/Trace.alfredworkflow/HEAD/icon.png -------------------------------------------------------------------------------- /Trace (Proxy-helper).alfredworkflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yiichou/Trace.alfredworkflow/HEAD/Trace (Proxy-helper).alfredworkflow -------------------------------------------------------------------------------- /proxy.conf: -------------------------------------------------------------------------------- 1 | # format: 2 | # Name Setting 3 | # e.g 4 | # AutoProxyName http://auto-proxy-pac-url 5 | # SocksName server:port 6 | # 7 | Workshop http://192.168.50.155/proxy.pac 8 | Workshop 192.168.50.155:1080 9 | Home http://192.168.99.1/proxy.pac -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Trace (Proxy-helper).alfredworkflow 2 | 3 | 在 Mac 上切换代理是一件麻烦的事情,然而不幸的是一旦你有了这个需求往往也意味着你需要频繁进行这个操作 4 | 5 | 于是我造了这个偷懒用的 alfredworkflow 6 | 7 | 希望有人能用得着 8 | 9 | ### Quickly start 10 | 11 | 1. Download 12 | 13 | https://github.com/IvanChou/Trace.alfredworkflow/raw/master/Trace%20(Proxy-helper).alfredworkflow 14 | 15 | 2. Setting 16 | 17 | - Doubule click `trace` in Alfred Workflows Preferences 18 | - Click `Open workflow folder` to open Finder 19 | - Open `proxy.conf` and modify it like sample 20 | 21 | 3. Use 22 | 23 | Call out your alfred, and type `trace` 24 | 25 | ![](http://ww4.sinaimg.cn/mw690/006pIUL1gw1f69r4xsjf0j30g10790tq.jpg) 26 | 27 | 4. Enjoy it! 28 | 29 | ### More feature 30 | 31 | When you change your proxy setting via Trace, OSX may ask your password to allow this operation everytime. 32 | 33 | To slove this question, you can do something more: 34 | 35 | 1. add the following line to `/etc/sudoers/` 36 | 37 | ``` 38 | yourusername ALL=NOPASSWD: /usr/sbin/networksetup 39 | # e.g. 40 | IChou ALL=NOPASSWD: /usr/sbin/networksetup 41 | ``` 42 | > Remeber the file `/etc/sudoers/` must be end with a empty line!! 43 | 44 | 2. re-link the scripts of trace 45 | 46 | ![](http://ww4.sinaimg.cn/large/006pIUL1gw1f6c4lm9l0qj30kh07o75b.jpg) 47 | 48 | ### About Trace 49 | 50 | It's inspired by Fate. "Trace on!" -------------------------------------------------------------------------------- /info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bundleid 6 | com.ichou.trace 7 | category 8 | Tools 9 | connections 10 | 11 | 0A04DEF2-C41B-4F12-88E5-146DE053D89A 12 | 13 | 14 | destinationuid 15 | A70A4E1E-712E-4575-967A-0AA64960904D 16 | modifiers 17 | 0 18 | modifiersubtext 19 | 20 | 21 | 22 | 5FC791A7-9A51-4BFB-BC0D-93167FF8AF3B 23 | 24 | 25 | destinationuid 26 | 0A04DEF2-C41B-4F12-88E5-146DE053D89A 27 | modifiers 28 | 0 29 | modifiersubtext 30 | 31 | 32 | 33 | 34 | createdby 35 | iChou 36 | description 37 | 快速切换系统代理配置 38 | disabled 39 | 40 | name 41 | Trace (Proxy-helper) 42 | objects 43 | 44 | 45 | config 46 | 47 | lastpathcomponent 48 | 49 | onlyshowifquerypopulated 50 | 51 | output 52 | 0 53 | removeextension 54 | 55 | sticky 56 | 57 | 58 | type 59 | alfred.workflow.output.notification 60 | uid 61 | A70A4E1E-712E-4575-967A-0AA64960904D 62 | version 63 | 0 64 | 65 | 66 | config 67 | 68 | concurrently 69 | 70 | escaping 71 | 102 72 | script 73 | sh trace.sh {query} 74 | type 75 | 0 76 | 77 | type 78 | alfred.workflow.action.script 79 | uid 80 | 0A04DEF2-C41B-4F12-88E5-146DE053D89A 81 | version 82 | 0 83 | 84 | 85 | config 86 | 87 | argumenttype 88 | 2 89 | escaping 90 | 102 91 | keyword 92 | trace 93 | queuedelaycustom 94 | 3 95 | queuedelayimmediatelyinitially 96 | 97 | queuedelaymode 98 | 0 99 | queuemode 100 | 1 101 | runningsubtext 102 | I am the bone of my sword... 103 | script 104 | sh trace.sh list_proxy proxy_config {query} 105 | subtext 106 | 卫宫士郎固有技能——投影 107 | title 108 | Trace 109 | type 110 | 0 111 | withspace 112 | 113 | 114 | type 115 | alfred.workflow.input.scriptfilter 116 | uid 117 | 5FC791A7-9A51-4BFB-BC0D-93167FF8AF3B 118 | version 119 | 0 120 | 121 | 122 | readme 123 | 124 | uidata 125 | 126 | 0A04DEF2-C41B-4F12-88E5-146DE053D89A 127 | 128 | ypos 129 | 100 130 | 131 | 5FC791A7-9A51-4BFB-BC0D-93167FF8AF3B 132 | 133 | ypos 134 | 100 135 | 136 | A70A4E1E-712E-4575-967A-0AA64960904D 137 | 138 | ypos 139 | 100 140 | 141 | 142 | webaddress 143 | yii.im 144 | 145 | 146 | -------------------------------------------------------------------------------- /trace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Source the workflow library 4 | . workflowHandler.sh 5 | 6 | # Config file 7 | PROFILE_CONF='proxy.conf' 8 | 9 | # Icons folder 10 | ICONS_DIR="./icons" 11 | 12 | # Current device 13 | DEVICE='' 14 | 15 | # ======== private ======== 16 | function get_curr_proxy_url() 17 | { 18 | networksetup -getautoproxyurl $DEVICE | grep URL | awk '{print $2}' 19 | } 20 | 21 | function get_curr_socks_server() 22 | { 23 | networksetup -getsocksfirewallproxy $DEVICE | grep Server | awk '{print $2}' 24 | } 25 | 26 | function get_curr_socks_port() 27 | { 28 | networksetup -getsocksfirewallproxy $DEVICE | grep Port | awk '{print $2}' 29 | } 30 | 31 | function get_curr_proxy_state() 32 | { 33 | networksetup -getautoproxyurl $DEVICE | grep Enabled | awk '{print $2}' 34 | } 35 | 36 | function get_curr_socks_state() 37 | { 38 | networksetup -getsocksfirewallproxy $DEVICE | grep -E '^Enabled' | awk '{print $2}' 39 | } 40 | 41 | function get_curr_proxy_setting() 42 | { 43 | if [[ $(get_curr_proxy_state) = 'Yes' ]]; then 44 | proxy_setting=$(get_curr_proxy_url) 45 | elif [[ $(get_curr_socks_state) = 'Yes' ]]; then 46 | proxy_setting="$(get_curr_socks_server):$(get_curr_socks_port)" 47 | else 48 | proxy_setting='' 49 | fi 50 | 51 | echo $proxy_setting 52 | } 53 | # ======== private ======== 54 | 55 | # Generate feedback results 56 | function list_proxy() 57 | { 58 | local cnt=0 59 | local curr_setting=$(get_curr_proxy_setting) 60 | local title subtitle arg icon 61 | 62 | while IFS=' ' read proxy_name proxy_setting; do 63 | uid="trace-$cnt" 64 | let cnt+=1 65 | 66 | icon="$ICONS_DIR/$proxy_name.png" 67 | 68 | # Use default workflow icon if not found 69 | if [ ! -f "$icon" ]; then 70 | icon="icon.png" 71 | fi 72 | 73 | if [[ $curr_setting = $proxy_setting ]]; then 74 | title="Now: $proxy_name" 75 | else 76 | title="$proxy_name" 77 | fi 78 | 79 | if [ ${proxy_setting:0:4} = 'http' ]; then 80 | title="$title [AutoProxy]" 81 | else 82 | title="$title" 83 | fi 84 | 85 | subtitle="$proxy_setting" 86 | arg="$proxy_name $proxy_setting" 87 | 88 | addResult "$uid" "$arg" "$title" "$subtitle" "$icon" "yes" 89 | done <$(xmlEncode "$3")$(xmlEncode "$4")$(xmlEncode "$5")" 21 | RESULTS+=("$RESULT") 22 | } 23 | 24 | ############################################################################### 25 | # Prints the feedback xml to stdout 26 | ############################################################################### 27 | getXMLResults() { 28 | echo "" 29 | 30 | # if [ "${#string[@]}" = "0" ]; then 31 | # echo "No results foundPlease try another search term" 32 | # fi 33 | 34 | for R in ${RESULTS[*]}; do 35 | echo "$R" | tr "\n" " " 36 | done 37 | 38 | echo "" 39 | } 40 | 41 | ############################################################################### 42 | # Escapes XML special characters with their entities 43 | ############################################################################### 44 | xmlEncode() { 45 | echo "$1" | sed -e 's/&/\&/g' -e 's/>/\>/g' -e 's/ "$PREFFILE" 105 | fi 106 | echo "$1=$2" >> "$PREFFILE" 107 | } 108 | 109 | ############################################################################### 110 | # Read a value for a given key from the workflow preferences 111 | # 112 | # $1 key 113 | # $2 non-volatile 0/1 114 | # $3 filename (optional, filename will be "settings" if not specified) 115 | ############################################################################### 116 | getPref() { 117 | local BUNDLEID=$(getBundleId) 118 | if [ "$2" = "0" ]; then 119 | local PREFDIR="${VPREFS}${BUNDLEID}" 120 | else 121 | local PREFDIR="${NVPREFS}${BUNDLEID}" 122 | fi 123 | 124 | if [ ! -d "$PREFDIR" ]; then 125 | return 126 | fi 127 | 128 | if [ -z "$3" ]; then 129 | local PREFFILE="${PREFDIR}/settings" 130 | else 131 | local PREFFILE="${PREFDIR}/$3" 132 | fi 133 | 134 | if [ ! -f "$PREFFILE" ]; then 135 | return 136 | fi 137 | 138 | local VALUE=$(sed "/^\#/d" "$PREFFILE" | grep "$1" | tail -n 1 | cut -d "=" -f2-) 139 | echo "$VALUE" 140 | } 141 | 142 | getLang() { 143 | defaults read .GlobalPreferences AppleLanguages | tr -d [:space:] | cut -c2-3 144 | } 145 | --------------------------------------------------------------------------------