1 |
Author: ulm |
2 |
Date: 2009-06-20 10:37:25 +0000 (Sat, 20 Jun 2009) |
3 |
New Revision: 587 |
4 |
|
5 |
Modified: |
6 |
trunk/ChangeLog |
7 |
trunk/man/news-tng.eselect.5 |
8 |
trunk/modules/news-tng.eselect |
9 |
Log: |
10 |
Support mbox output format. |
11 |
|
12 |
Modified: trunk/ChangeLog |
13 |
=================================================================== |
14 |
--- trunk/ChangeLog 2009-06-08 05:59:09 UTC (rev 586) |
15 |
+++ trunk/ChangeLog 2009-06-20 10:37:25 UTC (rev 587) |
16 |
@@ -1,3 +1,10 @@ |
17 |
+2009-06-20 Ulrich Mueller <ulm@g.o> |
18 |
+ |
19 |
+ * modules/news-tng.eselect (do_read): Support mbox output format. |
20 |
+ (day_of_week, rfc2047_encode, mail_header): New functions. |
21 |
+ (describe_read_options): Add the new --mbox option. |
22 |
+ * man/news-tng.eselect.5: Update man page. |
23 |
+ |
24 |
2009-06-07 Ulrich Mueller <ulm@g.o> |
25 |
|
26 |
* libs/editor-variable.bash.in (do_set): Output a message |
27 |
|
28 |
Modified: trunk/man/news-tng.eselect.5 |
29 |
=================================================================== |
30 |
--- trunk/man/news-tng.eselect.5 2009-06-08 05:59:09 UTC (rev 586) |
31 |
+++ trunk/man/news-tng.eselect.5 2009-06-20 10:37:25 UTC (rev 587) |
32 |
@@ -2,7 +2,7 @@ |
33 |
.\" Distributed under the terms of the GNU General Public License v2 |
34 |
.\" $Id$ |
35 |
.\" |
36 |
-.TH news-tng.eselect 5 "April 2009" "Gentoo Linux" eselect |
37 |
+.TH news-tng.eselect 5 "June 2009" "Gentoo Linux" eselect |
38 |
.SH NAME |
39 |
news-tng.eselect \- Yet another GLEP 42 news module for Gentoo's eselect |
40 |
.SH SYNOPSIS |
41 |
@@ -12,7 +12,7 @@ |
42 |
.B eselect news-tng list |
43 |
.br |
44 |
.B eselect news-tng read |
45 |
-.RB [ \-\-raw ] |
46 |
+.RB [ \-\-mbox | \-\-raw ] |
47 |
.RI [ item ...] |
48 |
.br |
49 |
.B eselect news-tng unread |
50 |
@@ -40,7 +40,7 @@ |
51 |
[3] 2009-04-06 (read) Migration to X.org Server 1.5 |
52 |
.SH ACTION: READ |
53 |
.B eselect news-tng read |
54 |
-.RB [ \-\-raw ] |
55 |
+.RB [ \-\-mbox | \-\-raw ] |
56 |
.RI [ item ...] |
57 |
.br |
58 |
Read news item(s), selected by their |
59 |
@@ -53,9 +53,11 @@ |
60 |
.B all |
61 |
select all unread items or all items, respectively. |
62 |
Default is to read all unread news, if no item is specified. |
63 |
-With option |
64 |
+With options |
65 |
+.B \-\-mbox |
66 |
+or |
67 |
.BR \-\-raw , |
68 |
-output the item in raw format. |
69 |
+output the item(s) in mbox format or in raw format, respectively. |
70 |
.SH ACTION: UNREAD |
71 |
.B eselect news-tng unread |
72 |
.RI [ item ...] |
73 |
|
74 |
Modified: trunk/modules/news-tng.eselect |
75 |
=================================================================== |
76 |
--- trunk/modules/news-tng.eselect 2009-06-08 05:59:09 UTC (rev 586) |
77 |
+++ trunk/modules/news-tng.eselect 2009-06-20 10:37:25 UTC (rev 587) |
78 |
@@ -95,6 +95,66 @@ |
79 |
echo en |
80 |
} |
81 |
|
82 |
+# calculate day of week for given year ($1), month ($2), and day ($3) |
83 |
+# using Chr. Zeller's formula for the new calendar |
84 |
+day_of_week() { |
85 |
+ local a=${1##*(0)} m=${2##*(0)} q=${3##*(0)} |
86 |
+ local -a wd=( Sat Sun Mon Tue Wed Thu Fri ) |
87 |
+ [[ ${m} -le 2 ]] && (( a--, m += 12 )) |
88 |
+ echo ${wd[(q + (m+1)*13/5 + a + a/4 - a/100 + a/400) % 7]} |
89 |
+} |
90 |
+ |
91 |
+# encode header as quoted-printable |
92 |
+rfc2047_encode() { |
93 |
+ local s=$1 i c LC_ALL=C |
94 |
+ echo -n "=?UTF-8?Q?" |
95 |
+ for (( i=0; i<${#s}; i++ )); do |
96 |
+ c=${s:i:1} |
97 |
+ if [[ ${c} < ' ' || ${c} > '~' || ${c} =~ [=?_()\\] ]]; then |
98 |
+ printf '=%02X' "'${c}" |
99 |
+ else |
100 |
+ echo -n "${c/ /_}" |
101 |
+ fi |
102 |
+ done |
103 |
+ echo "?=" |
104 |
+} |
105 |
+ |
106 |
+# output message header in e-mail/mbox format |
107 |
+mail_header() { |
108 |
+ local item=$1 author=$2 title=$3 posted=$4 |
109 |
+ local -a mname=( 0 Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ) |
110 |
+ local year=0001 month=01 day=01 time="00:00:00" wd addr name |
111 |
+ |
112 |
+ # "date -d" is not portable, therefore we do manual processing |
113 |
+ if [[ ${posted} == +([0-9])-+([0-9])-+([0-9]) ]]; then |
114 |
+ year=${posted%%-*} |
115 |
+ month=${posted#*-*(0)}; month=${month%%-*} |
116 |
+ day=${posted##*-} |
117 |
+ fi |
118 |
+ wd=$(day_of_week "${year}" "${month}" "${day}") |
119 |
+ |
120 |
+ if [[ ${author} == *([^<>])\<+([^<>])\> ]]; then |
121 |
+ # GLEP 42 says this must look like "Real Name <email@address>" |
122 |
+ name=${author%%*( )<*} |
123 |
+ addr=${author##*<}; addr=${addr%%>*} |
124 |
+ elif [[ ${author} == +([^<>]) ]]; then |
125 |
+ addr=${author} |
126 |
+ fi |
127 |
+ |
128 |
+ [[ ${name} == *([[:ascii:]]) ]] || name=$(rfc2047_encode ${name}) |
129 |
+ [[ ${title} == *([[:ascii:]]) ]] || title=$(rfc2047_encode ${title}) |
130 |
+ |
131 |
+ echo "From ${addr} ${wd} ${mname[month]} ${day} ${time} ${year}" |
132 |
+ echo "From: ${name} <${addr}>" |
133 |
+ #echo "Reply-To: DO NOT REPLY <devnull@×××××××××.invalid>" |
134 |
+ echo "Subject: ${title}" |
135 |
+ echo "Date: ${wd}, ${day} ${mname[month]} ${year} ${time} +0000" |
136 |
+ echo "Message-Id: <glep42-${item}@gentoo.org>" |
137 |
+ echo "MIME-Version: 1.0" |
138 |
+ echo "Content-Type: text/plain; charset=UTF-8" |
139 |
+ echo "Content-Transfer-Encoding: 8bit" |
140 |
+} |
141 |
+ |
142 |
### list action |
143 |
|
144 |
describe_list() { |
145 |
@@ -162,6 +222,7 @@ |
146 |
echo "new : Read unread news items (default)" |
147 |
echo "all : Read all news items" |
148 |
echo "item : Number of item (from 'list' action)" |
149 |
+ echo "--mbox : Output in mbox format" |
150 |
echo "--raw : Output in raw format" |
151 |
} |
152 |
|
153 |
@@ -171,13 +232,17 @@ |
154 |
|
155 |
do_read() { |
156 |
local -a items=( $(find_items unread read) ) repos dirs |
157 |
- local n=${#items[@]} item repo stat dir header line i seq repos_upd raw |
158 |
- local ifs_save=${IFS-$' \t\n'} |
159 |
+ local n=${#items[@]} format=cooked ifs_save=${IFS-$' \t\n'} |
160 |
+ local item repo stat dir header line i seq repos_upd author title posted |
161 |
|
162 |
- if [[ $1 = --raw ]]; then |
163 |
- raw=1 |
164 |
+ while [[ $# -gt 0 ]]; do |
165 |
+ case ${1##--} in |
166 |
+ mbox) format=mbox ;; |
167 |
+ raw) format=raw ;; |
168 |
+ *) break ;; |
169 |
+ esac |
170 |
shift |
171 |
- fi |
172 |
+ done |
173 |
|
174 |
# expand special values "new" and "all" |
175 |
if [[ $# -eq 0 || $1 = new || $1 = all ]]; then |
176 |
@@ -186,7 +251,7 @@ |
177 |
seq="${seq} ${i}" |
178 |
done |
179 |
set -- ${seq} |
180 |
- [[ $# -eq 0 && -z ${raw} ]] && echo "No news is good news." |
181 |
+ [[ $# -eq 0 && ${format} = cooked ]] && echo "No news is good news." |
182 |
fi |
183 |
|
184 |
for i in "$@"; do |
185 |
@@ -199,25 +264,51 @@ |
186 |
stat=${item%%/*}; item=${item#*/} |
187 |
repo=${item%%/*}; item=${item#*/} |
188 |
find_repo_dir "${repo}" |
189 |
- if [[ -n ${raw} ]]; then |
190 |
- read_item "${dir}" "${item}" |
191 |
- else |
192 |
- write_list_start "${item}" |
193 |
- header=$(read_item "${dir}" "${item}" header) |
194 |
- IFS=$'\n' |
195 |
- for line in ${header}; do |
196 |
- case "${line%%: *}" in |
197 |
- Title) |
198 |
- write_kv_list_entry \ |
199 |
- "${line%%: *}" "$(highlight "${line#*: }")" ;; |
200 |
- Author|Translator|Posted|Revision) |
201 |
- write_kv_list_entry "${line%%: *}" "${line#*: }" ;; |
202 |
- esac |
203 |
- done |
204 |
- IFS=${ifs_save} |
205 |
- echo |
206 |
- read_item "${dir}" "${item}" body |
207 |
- fi |
208 |
+ case ${format} in |
209 |
+ raw) |
210 |
+ read_item "${dir}" "${item}" |
211 |
+ ;; |
212 |
+ cooked) |
213 |
+ write_list_start "${item}" |
214 |
+ header=$(read_item "${dir}" "${item}" header) |
215 |
+ IFS=$'\n' |
216 |
+ for line in ${header}; do |
217 |
+ case "${line%%: *}" in |
218 |
+ Title) |
219 |
+ write_kv_list_entry \ |
220 |
+ "${line%%: *}" "$(highlight "${line#*: }")" ;; |
221 |
+ Author|Translator|Posted|Revision) |
222 |
+ write_kv_list_entry "${line%%: *}" "${line#*: }" ;; |
223 |
+ esac |
224 |
+ done |
225 |
+ IFS=${ifs_save} |
226 |
+ echo |
227 |
+ read_item "${dir}" "${item}" body |
228 |
+ ;; |
229 |
+ mbox) |
230 |
+ header=$(read_item "${dir}" "${item}" header) |
231 |
+ author=""; title=""; posted="" |
232 |
+ IFS=$'\n' |
233 |
+ for line in ${header}; do |
234 |
+ case "${line%%: *}" in |
235 |
+ Author) [[ -z ${author} ]] && author=${line#*: } ;; |
236 |
+ Title) [[ -z ${title} ]] && title=${line#*: } ;; |
237 |
+ Posted) [[ -z ${posted} ]] && posted=${line#*: } ;; |
238 |
+ esac |
239 |
+ done |
240 |
+ mail_header "${item}" "${author}" "${title}" "${posted}" |
241 |
+ echo |
242 |
+ for line in ${header}; do |
243 |
+ case "${line%%: *}" in |
244 |
+ Title|Author|Translator|Posted|Revision) |
245 |
+ echo "${line}" ;; |
246 |
+ esac |
247 |
+ done |
248 |
+ IFS=${ifs_save} |
249 |
+ echo |
250 |
+ read_item "${dir}" "${item}" body | sed 's/^>*From />&/;$q' |
251 |
+ ;; |
252 |
+ esac |
253 |
[[ $? -ne 0 ]] && write_error_msg "Error reading item \"${item}\"" |
254 |
echo |