f2d1e7d0360b35899f4b110a91b13d59261c5dd5
[grml-etc-core.git] / usr_share_grml / zsh / functions / Lookup / Backends / LOOKUP_be_gmane
1 ### vim:ft=zsh:foldmethod=marker
2 ## gmane.org backend for lookup
3 ## Copyright: 2009, Frank Terbeck <ft@bewatermyfriend.org>
4
5 LOOKUP_guard || return 1
6 [[ -n ${lookup_describe} ]] && printf '%s' 'query gmane.org' && return 0
7
8 local lookup_context bookmarks
9 local -A known_sorts known_opers
10 lookup_context="$(LOOKUP_context)"
11
12 # Set up the path name of the bookmark file. Looked up in the :lookup:*
13 # context because it may not be limited to compsys in the future
14 # (maybe someone will write bookmark managing via zsh/curses...). :-)
15 zstyle -s "${lookup_context}" group-bookmarks bookmarks ||
16     bookmarks="${HOME}/.zgmane.bookmarks"
17
18 known_sorts=(
19     date        'sort by date'
20     revdate     'sort by reverse date'
21     relevance   'sort by relevance'
22 )
23
24 known_opers=(
25     and     'require all words'
26     or      'require one word'
27 )
28
29 LOOKUP_guard -fd LOOKUP_help_${backend} ||
30 function LOOKUP_help_${backend}() {
31     # gmane backend help {{{
32     LOOKUP_guard || return 1
33     printf 'usage: %s <query>\n' ${backend}
34     printf '  -G        Open group (like gmane.emacs.orgmode) in gmane'\''s browser mode\n'
35     printf '            Completion will offer bookmarked groups.\n'
36     printf '  -l        search for original list names (like zsh-workers)\n'
37     printf '  -s        match gmane group names (like comp.shell)\n'
38     printf '  -L        list-mode; do not open a browser, just print the results\n'
39     printf '            valid with -l and -s.\n'
40     printf '  -B        browser-mode; opposite of -L\n'
41     printf '  -m        search for Message-Id: header\n'
42     printf '  -a <arg>  match messages only by a certain author\n'
43     printf '  -g <arg>  match messages only from a certain gmane group\n'
44     printf '  -o <arg>  use defined operation in search (%s)\n' "${(j:/:)${(@kon)known_opers}}"
45     printf '  -S <arg>  use given sorting method (%s)\n' "${(j:/:)${(@kon)known_sorts}}"
46     printf '\n Search the archives of the gmane.org mail2news gateway.\n'
47     printf '\n Default sort method: relevance\n'
48     printf ' Default query logic: and\n'
49     printf ' List-mode (-L and -B options) defaults to: off\n'
50     printf ' Default group bookmark file: %s\n' "${HOME}/.zgmane.bookmarks"
51     printf ' All defaults may be altered by the use of styles.\n'
52     printf '\nStyles:\n'
53     printf ' All styles are looked up in this context:\n'
54     printf '    %s\n\n' ${lookup_context}
55     printf ' group-bookmarks:   file that contains group bookmarks (see below)\n'
56     printf '    list-default:   boolean, use list-mode by default if true\n'
57     printf '    default-sort:   change default sorting method\n'
58     printf '    default-oper:   change default query logic\n'
59     printf '\nBookmarks:\n'
60     printf '\n Often you will want to limit your queries to a certain gmane group.\n'
61     printf ' Since these are lengthy at times, it is awful to type them out.\n'
62     printf ' Therefore, this backend gives you a bookmark file. Its format is:\n'
63     printf '    gname.group.name:description\n'
64     printf ' The '\'':description'\'' part is optional.\n'
65     printf ' That way you can search for group names (using -L, -l and -s) and put\n'
66     printf ' your prefered groups into that file. That way you get rid of a lot of\n'
67     printf ' typing by using completion: %% lu gmane -g <tab>\n'
68     printf '\nExamples:\n'
69     printf ' %% zstyle '\'':lookup:*:%s:*'\'' list-default    true\n' ${backend}
70     printf ' %% zstyle '\'':lookup:*:%s:*'\'' default-sort    date\n' ${backend}
71     printf ' %% zstyle '\'':lookup:*:%s:*'\'' default-oper    or\n' ${backend}
72     printf ' %% zstyle '\'':lookup:*:%s:*'\'' group-bookmarks ~/.my_gmane_bookmarks\n' ${backend}
73     printf ' %% lookup %s zsh\n' ${backend}
74     printf ' %% lookup %s -m 20090215095848.GA21661@schmehl.info\n' ${backend}
75     printf ' %% lookup %s -g gmane.comp.shells.fish.user zsh\n' ${backend}
76     printf ' %% lookup %s -L -l zsh-workers\n' ${backend}
77     printf ' %% lookup %s -L -s openbsd\n' ${backend}
78     printf ' %% lookup %s -G gmane.emacs.orgmode\n' ${backend}
79     #}}}
80 }
81 LOOKUP_help && return 0
82
83 if [[ -n ${lookup_complete} ]] ; then
84     # gmane backend completion code {{{
85     local -a comp_args
86
87     LOOKUP_guard -fd __lookup_${backend}_known_operations ||
88     function __lookup_${backend}_known_operations() {
89         local o
90         local -a os
91
92         os=()
93         for o in ${(k)known_opers}; do
94             os+=("$o:${known_opers[$o]}")
95         done
96         _describe -t gmane_opers 'known operations' os
97     }
98
99     LOOKUP_guard -fd __lookup_${backend}_known_sorts ||
100     function __lookup_${backend}_known_sorts() {
101         local s
102         local -a as
103
104         as=()
105         for s in ${(k)known_sorts}; do
106             as+=("$s:${known_sorts[$s]}")
107         done
108         _describe -t gmane_sorts 'known sorting methods' as
109     }
110
111     LOOKUP_guard -fd __lookup_${backend}_group_bookmarks ||
112     function __lookup_${backend}_group_bookmarks() {
113         local -a bms
114
115         if [[ -r ${bookmarks} ]] ; then
116             bms=(${(f)"$(< $bookmarks)"})
117         fi
118         _describe -t gmane_bookmarks 'bookmarked gmane groups' bms
119     }
120
121     comp_args=(
122         '-G[browse gmane group]:group name:__lookup_'${backend}'_group_bookmarks'
123         '-l[search for original list names]:list name:'
124         '-s[match gmane group names]:group name:'
125         '-L[switch to list-mode]'
126         '-m[query for message ids]:Message-Id\::'
127         '-a[author name]:author:'
128         '-g[group name]:group:__lookup_'${backend}'_group_bookmarks'
129         '-o[operations]:operation:__lookup_'${backend}'_known_operations'
130         '-S[sorting method]:sorting method:__lookup_'${backend}'_known_sorts'
131         '*:wikipedia search:true'
132     )
133
134     _arguments -s -w -A '-*' ${comp_args} && return 0
135     _message 'gmane query'
136     return 0
137     #}}}
138 fi
139
140 local author group operation sort ret list_mode
141 local -x QUERY
142
143 # set some defaults via zstyle
144 zstyle -t "${lookup_context}" list-default              && list_mode='yes'
145 zstyle -s "${lookup_context}" default-sort sort         || sort='relevance'
146 zstyle -s "${lookup_context}" default-oper operation    || operation='and'
147
148 # parse options
149 lu_parseopts_args=(
150     G   bool
151     l   bool
152     m   bool
153     s   bool
154     B   bool
155     L   bool
156     a   string
157     g   string
158     o   string
159     S   string
160 )
161 LOOKUP_parseopts "$@" || return 1
162 [[ -n ${opts[-a]} ]] && author="$(LOOKUP_encode ${opts[-a]})"
163 [[ -n ${opts[-g]} ]] && group="$(LOOKUP_encode ${opts[-g]})"
164 [[ -n ${opts[-o]} ]] && operation="${opts[-o]}"
165 [[ -n ${opts[-S]} ]] && sort="${opts[-S]}"
166 [[ -n ${opts[-L]} ]] && list_mode='yes'
167 [[ -n ${opts[-B]} ]] && list_mode=''
168
169 # set QUERY and export parameters for query handlers via $lookup_communicate[]
170 QUERY="${args[*]}"
171 lookup_communicate[author]="${author}"
172 lookup_communicate[group]="${group}"
173 lookup_communicate[operation]="${operation}"
174 lookup_communicate[sort]="${sort}"
175 LOOKUP_query_handler || return 1
176 [[ ${lookup_communicate[author]} != ${author} ]] && author="${lookup_communicate[author]}"
177 [[ ${lookup_communicate[group]} != ${group} ]] && group="${lookup_communicate[group]}"
178 [[ ${lookup_communicate[operation]} != ${operation} ]] && operation="${lookup_communicate[operation]}"
179 [[ ${lookup_communicate[sort]} != ${sort} ]] && sort="${lookup_communicate[sort]}"
180
181 # validate arguments
182 if [[ -z ${(Mk)known_opers:#$operation} ]] ; then
183     printf 'Unknown operation: '\''%s'\''.\n\n' ${mode}
184     QUERY=''
185 elif [[ -z ${(Mk)known_sorts:#$sort} ]] ; then
186     printf 'Unknown sorting method: '\''%s'\''.\n\n' ${mode}
187     QUERY=''
188 fi
189 if [[ -z ${QUERY} ]] &&
190    ( [[ ${opts[-l]} == 'yes' ]] || [[ ${opts[-s]} == 'yes' ]] || [[ ${opts[-m]} == 'yes' ]] )
191    then
192
193     LOOKUP_help -f
194     return 1
195 fi
196 if [[ -z ${QUERY} ]] && [[ -z ${group} ]] && [[ -z ${author} ]] ; then
197     LOOKUP_help -f
198     return 1
199 fi
200
201 LOOKUP_guard -fd LOOKUP_beh_${backend}_list ||
202 function LOOKUP_beh_${backend}_list() {
203     # list mode via tcp_{open,send,close} {{{
204     LOOKUP_guard || return 1
205     setopt localoptions no_warncreateglobal
206     local mode="$1" q="$2"
207
208     LOOKUP_guard -fd tcp_open || autoload -Uz tcp_open
209     LOOKUP_guard -fd tcp_send || autoload -Uz tcp_send
210
211     case ${mode} in
212     (list)
213         tcp_open -q gmane.org 80 gmane || return 1
214         tcp_send -s gmane -- "GET /find.php?list=${q} HTTP/1.1"
215         tcp_send -s gmane -- 'HOST: gmane.org'
216         ;;
217     (match)
218         tcp_open -q dir.gmane.org 80 gmane || return 1
219         tcp_send -s gmane -- "GET /search.php?match=${q} HTTP/1.1"
220         tcp_send -s gmane -- 'HOST: dir.gmane.org'
221         ;;
222     (*)
223         return 1
224         ;;
225     esac
226
227     tcp_send -s gmane -- 'Connection: close'
228     tcp_send -s gmane -- ''
229
230     TCP_SILENT='yes'
231     tcp_read -b -d -s gmane
232     TCP_SILENT=''
233
234     tcp_close -q -s gmane
235
236     results=()
237     for line in ${tcp_lines} ; do
238         [[ ${line} != *'dir.gmane.org'* ]] && continue
239         line=${line//(#b)*\"(http:\/\/dir.gmane.org\/[^\"]#)\"*/${match[1]}}
240         line=${line#http://dir.gmane.org/}
241         [[ -z ${line} ]] && continue
242         [[ ${line} != gmane.* ]] && continue
243         results+=( ${line} )
244     done
245
246     print -l ${results}
247     return 0
248     #}}}
249 }
250
251 # make the actual queries
252 LOOKUP_encode -q
253 if [[ ${opts[-G]} == 'yes' ]] ; then
254     LOOKUP_browser "http://news.gmane.org/${QUERY}"
255     ret="$?"
256 elif [[ ${opts[-l]} == 'yes' ]] ; then
257     if [[ ${list_mode} == 'yes' ]] ; then
258         LOOKUP_beh_${backend}_list 'list' ${QUERY}
259         ret="$?"
260     else
261         LOOKUP_browser "http://gmane.org/find.php?list=${QUERY}"
262         ret="$?"
263     fi
264 elif [[ ${opts[-s]} == 'yes' ]] ; then
265     if [[ ${list_mode} == 'yes' ]] ; then
266         LOOKUP_beh_${backend}_list 'match' ${QUERY}
267         ret="$?"
268     else
269         LOOKUP_browser "http://dir.gmane.org/search.php?match=${QUERY}"
270         ret="$?"
271     fi
272 elif [[ ${opts[-m]} == 'yes' ]] ; then
273     LOOKUP_browser "http://mid.gmane.org/${QUERY}"
274     ret="$?"
275 else
276     LOOKUP_browser "http://search.gmane.org/?query=${QUERY}&author=${author}&group=${group}&DEFAULTOP=${operation}&sort=${sort}"
277     ret="$?"
278 fi
279 return ${ret}