├── .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 | 
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 | 
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/\</g' -e "s/'/\'/g" -e 's/"/\"/g'
46 | }
47 |
48 | ###############################################################################
49 | # Read the bundleid from the workflow's info.plist
50 | ###############################################################################
51 | getBundleId() {
52 | /usr/libexec/PlistBuddy -c "Print :bundleid" "info.plist"
53 | }
54 |
55 | ###############################################################################
56 | # Get the workflow data dir
57 | ###############################################################################
58 | getDataDir() {
59 | local BUNDLEID=$(getBundleId)
60 | echo "${NVPREFS}${BUNDLEID}"
61 | }
62 |
63 | ###############################################################################
64 | # Get the workflow cache dri
65 | ###############################################################################
66 | getCacheDir() {
67 | local BUNDLEID=$(getBundleId)
68 | echo "${VPREFS}${BUNDLEID}"
69 | }
70 |
71 | ###############################################################################
72 | # Save key=value to the workflow properties
73 | #
74 | # $1 key
75 | # $2 value
76 | # $3 non-volatile 0/1
77 | # $4 filename (optional, filename will be "settings" if not specified)
78 | ###############################################################################
79 | setPref() {
80 | local BUNDLEID=$(getBundleId)
81 | if [ "$3" = "0" ]; then
82 | local PREFDIR="${VPREFS}${BUNDLEID}"
83 | else
84 | local PREFDIR="${NVPREFS}${BUNDLEID}"
85 | fi
86 |
87 | if [ ! -d "$PREFDIR" ]; then
88 | mkdir -p "$PREFDIR"
89 | fi
90 |
91 | if [ -z "$4" ]; then
92 | local PREFFILE="${PREFDIR}/settings"
93 | else
94 | local PREFFILE="${PREFDIR}/$4"
95 | fi
96 |
97 | if [ ! -f "$PREFFILE" ]; then
98 | touch "$PREFFILE"
99 | fi
100 |
101 | local KEY_EXISTS=$(grep -c "$1=" "$PREFFILE")
102 | if [ "$KEY_EXISTS" = "1" ]; then
103 | local TMP=$(grep -ve "^$1" "$PREFFILE")
104 | echo "$TMP" > "$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 |
--------------------------------------------------------------------------------