tazpkg view tazpanel/pkgs.cgi @ rev 747

Add and use icons from Faenza icon theme (new light look and feel); fix last recharge date (pay respect to timezone time offset); add few comments; stylize search toolbar; fix "up" command; admin: select mirror as standard way to select item from list; open external links in the new tab (or new window); and a ton of other small changes.
author Aleksej Bobylev <al.bobylev@gmail.com>
date Wed Jan 21 17:53:26 2015 +0200 (2015-01-21)
parents c4c2d523a719
children f2975370bd27
line source
1 #!/bin/sh
2 #
3 # TazPkg CGI interface - Manage packages via a browser
4 #
5 # This CGI interface extensively uses tazpkg to manage packages and have
6 # its own code for some tasks. Please KISS, it is important and keep speed
7 # in mind. Thanks, Pankso.
8 #
9 # (C) 2011-2014 SliTaz GNU/Linux - BSD License
10 #
12 . /lib/libtaz.sh
13 . lib/libtazpanel
15 . /etc/slitaz/slitaz.conf
16 . /etc/slitaz/tazpkg.conf
18 get_config
19 header
21 _() { local T="$1"; shift; printf "$(gettext "$T")" "$@"; echo; }
22 _n() { local T="$1"; shift; printf "$(gettext "$T")" "$@"; }
23 _p() {
24 local S="$1" P="$2" N="$3"; shift; shift; shift;
25 printf "$(ngettext "$S" "$P" "$N")" "$@"; }
28 # xHTML 5 header with special side bar for categories.
29 TITLE=$(TEXTDOMAIN='tazpkg'; _ 'TazPanel - Packages')
30 xhtml_header | sed 's/id="content"/id="content-sidebar"/'
32 export TEXTDOMAIN='tazpkg'
34 pkg_info_link()
35 {
36 echo "<a class=\"$2\" href=\"?info=${1//+/%2B}\">$1</a>" | sed 's| class=""||'
37 }
40 # Display localized short description
42 i18n_desc() {
43 for L in $LANG ${LANG%%_*}; do
44 if [ -e "$PKGS_DB/packages-desc.$L" ]; then
45 LOCDESC=$(awk -F$'\t' -vp=$1 '{if ($1 == p) print $2}' $PKGS_DB/packages-desc.$L)
46 if [ -n "$LOCDESC" ]; then
47 SHORT_DESC="$LOCDESC"
48 break
49 fi
50 fi
51 done
52 }
55 # We need packages information for list and search
57 parse_packages_desc() {
58 IFS="|"
59 cut -f 1,2,3,5 -d "|" | while read PACKAGE VERSION SHORT_DESC WEB_SITE
60 do
61 class=pkg; [ -d $INSTALLED/${PACKAGE% } ] && class=pkgi
62 i18n_desc $PACKAGE
63 cat << EOT
64 <tr>
65 <td><input type="checkbox" name="pkg" value="$PACKAGE">$(pkg_info_link $PACKAGE $class)</td>
66 <td>$VERSION</td>
67 <td>$SHORT_DESC</td>
68 <td><a class="w" href="$WEB_SITE"></a></td>
69 </tr>
70 EOT
71 done
72 unset IFS
73 }
76 parse_packages_info() {
77 IFS=$'\t'
78 while read PACKAGE VERSION CATEGORY SHORT_DESC WEB_SITE TAGS SIZES DEPENDS; do
79 class=pkg; grep -q "^$PACKAGE$'\t'" $PKGS_DB/installed.info && class=pkgi
80 i18n_desc $PACKAGE
81 cat << EOT
82 <tr>
83 <td><input type="checkbox" name="pkg" value="$PACKAGE">$(pkg_info_link $PACKAGE $class)</td>
84 <td>$VERSION</td>
85 <td>$SHORT_DESC</td>
86 <td><a class="w" href="$WEB_SITE"></a></td>
87 </tr>
88 EOT
89 done
90 unset IFS
91 }
94 # Show button
95 show_button() {
96 for button in $@; do
97 case $button in
98 recharge) img='tp-recharge'; label="$(_ 'Recharge list')" ;;
99 up) img='tp-up'; label="$(_ 'Check upgrades')" ;;
100 list) img='tp-list'; label="$(_ 'My packages')" ;;
101 tags) img='tp-tag'; label="$(_ 'Tags')" ;;
102 linkable) img='tp-link'; label="$(_ 'Linkable packages')" ;;
103 admin) img='tp-admin'; label="$(_ 'Administration')" ;;
104 *Install*nf*) img='tp-pkg-ins'; label="$(_ 'Install (Non Free)')" ;;
105 *Install*) img='tp-pkg-ins'; label="$(_ 'Install')" ;;
106 *Remove*) img='tp-pkg-rem'; label="$(_ 'Remove')" ;;
107 *Link*) img='tp-link'; label="$(_ 'Link')" ;;
108 *Block*) img='tp-block'; label="$(_ 'Block')" ;;
109 *Unblock*) img='tp-unblock'; label="$(_ 'Unblock')" ;;
110 *Repack*) img='tp-repack'; label="$(_ 'Repack')" ;;
111 *saveconf*) img='tp-save'; label="$(_ 'Save configuration')" ;;
112 *listconf*) img='tp-list'; label="$(_ 'List configuration files')" ;;
113 *quickcheck*) img='tp-check'; label="$(_ 'Quick check')" ;;
114 *fullcheck*) img='tp-check'; label="$(_ 'Full check')" ;;
115 *clean*) img='tp-remove'; label="$(_ 'Clean')" ;;
116 *setlink*) img='tp-link'; label="$(_ 'Set link')" ;;
117 *removelink*) img='tp-remove'; label="$(_ 'Remove link')" ;;
118 *add-mirror) img='tp-add'; label="$(_n 'Add mirror')" ;;
119 *add-repo) img='tp-add'; label="$(_n 'Add repository')" ;;
120 esac
121 cat << EOT
122 <button class="button" type="submit" name="${button%%=*}" value="${button#*=}">
123 <img src="$IMAGES/$img.png"/>$label
124 </button>
125 EOT
126 done
127 }
131 #
132 # xHTML functions
133 #
136 # ENTER will search but user may search for a button, so put one.
138 search_form() {
139 [ -z "$repo" ] && repo="$(GET repo)"
140 [ -z "$repo" ] && repo="Any"
141 cat << EOT
142 <form method="get" action="">
143 <div class="search"><input
144 type="search" name="search" results="5" autosave="pkgsearch" autocomplete="on"><input
145 type="submit" value="$(_n 'Search')"><input
146 type="submit" value="$(_n 'Files')" name="files">
147 </div>
148 </form>
149 EOT
150 }
153 table_head() {
154 cat << EOT
155 <table class="zebra pkglist">
156 <thead>
157 <tr>
158 <td>$(_ 'Name')</td>
159 <td>$(_ 'Version')</td>
160 <td>$(_ 'Description')</td>
161 <td>$(_ 'Web')</td>
162 </tr>
163 </thead>
164 <tbody>
165 EOT
166 }
169 sidebar() {
170 repo=$(COOKIE repo); repo=${repo:-Public}; [ -n "$(GET repo)" ] && repo=$(GET repo)
171 my=$(COOKIE my); my=${my:-my}; [ -n "$(GET my)" ] && my=$(GET my)
172 cat=$(COOKIE cat); cat=${cat:-all}; [ -n "$(GET cat)" ] && cat=$(GET cat)
174 cat << EOT
175 <script type="text/javascript">
176 function setCookie(name) {
177 document.cookie = name+"="+document.getElementById(name).value; }
178 function setValue(name, value) {
179 document.getElementById(name).value=value;
180 setCookie(name); }
181 </script>
182 <form method="post" action="?list">
184 <div id="sidebar">
185 <select id="my" value="$my" onchange="setCookie('my'); this.form.submit()">
186 <option value="my">$(_ 'My packages')</option>
187 <option value="no">$(_ 'All packages')</option>
188 </select>
190 <h4>$(_ 'Categories')</h4>
192 <div class="select_wrap">
193 <select id="cat" size="16" onclick="setCookie('cat'); this.form.submit()">
194 <option value="base-system" >$(_ 'base-system')</option>
195 <option value="x-window" >$(_ 'x-window')</option>
196 <option value="utilities" >$(_ 'utilities')</option>
197 <option value="network" >$(_ 'network')</option>
198 <option value="games" >$(_ 'games')</option>
199 <option value="graphics" >$(_ 'graphics')</option>
200 <option value="office" >$(_ 'office')</option>
201 <option value="multimedia" >$(_ 'multimedia')</option>
202 <option value="development" >$(_ 'development')</option>
203 <option value="system-tools">$(_ 'system-tools')</option>
204 <option value="security" >$(_ 'security')</option>
205 <option value="misc" >$(_ 'misc')</option>
206 <option value="meta" >$(_ 'meta')</option>
207 <option value="non-free" >$(_ 'non-free')</option>
208 <option value="all" >$(_ 'all')</option>
209 <option value="extra" >$(_ 'extra')</option>
210 </select>
211 <script type="text/javascript">
212 setValue('my', "$my")
213 setValue('cat', "$cat")
214 </script>
215 </div>
216 EOT
218 if [ -d $PKGS_DB/undigest ]; then
219 cat << EOT
220 <h4>$(_ 'Repository')</h4>
222 <select id="repo" onchange="setCookie('repo')">
223 <option value="Public">$(_ 'Public')</option>
224 $(for i in $(ls $PKGS_DB/undigest); do
225 echo "<option value=\"$i\">$i</option>"
226 done)
227 <option value="Any">$(_ 'Any')</option>
228 </select>
229 <script type="text/javascript">setValue('repo', "$repo")</script>
230 EOT
231 fi
232 cat << EOT
233 <a href="?tags">$(_ 'All tags...')</a>
234 <a href="?cats">$(_ 'All categories...')</a>
235 </div>
236 </form>
237 EOT
238 }
241 repo_list() {
242 if [ -n "$(ls $PKGS_DB/undigest/ 2> /dev/null)" ]; then
243 case "$repo" in
244 Public)
245 ;;
246 ""|Any)
247 for i in $PKGS_DB/undigest/* ; do
248 [ -d "$i" ] && echo "$i$1"
249 done ;;
250 *)
251 echo "$PKGS_DB/undigest/$repo$1"
252 return ;;
253 esac
254 fi
255 echo "$PKGS_DB$1"
256 }
259 repo_name() {
260 case "$1" in
261 $PKGS_DB)
262 echo "Public" ;;
263 $PKGS_DB/undigest/*)
264 echo ${1#$PKGS_DB/undigest/} ;;
265 esac
266 }
269 header_repo_name() {
270 [ -d $PKGS_DB/undigest ] && [ "$repo" != "Public" ] && \
271 echo "<h3>$(_ 'Repository: %s' $(repo_name $1))</h3>"
272 }
275 # Print links to the pages
277 pager() {
278 PAGE_SIZE=${PAGE_SIZE:-100}
279 [ "$PAGE_SIZE" != "0" ] && \
280 awk -F'"' -vpage="$page" -vsize="$PAGE_SIZE" -vnum_lines="$(wc -l < $1)" -vtext="$(_ 'Pages:') " -vurl="?list&amp;page=" '
281 BEGIN{
282 num_pages = int(num_lines / size) + (num_lines % size != 0)
283 if (num_pages != 1) printf "<p>%s", text
284 }
285 {
286 if (num_pages == 1) exit
287 r = NR % size
288 if (r == 1) {
289 p = int(NR / size) + 1
290 printf "<a class=\"pages%s\" href=\"%s%s\" title=\"%s\n···\n", p==page?" current":"", url, p, $6
291 } else if (r == 0)
292 printf "%s\">%s</a> ", $6, int(NR / size)
293 }
294 END{
295 if (num_pages == 1) exit
296 if (r != 0) printf "%s\">%s</a>", $6, int(NR / size) + 1
297 print "</p>"
298 }' $1
299 }
302 # Show packages list by category or tag
304 show_list() {
305 PAGE_SIZE=${PAGE_SIZE:-100}
306 page=$(GET page); page=${page:-1}
307 cached=$(mktemp)
308 [ -n "$tag" ] && cat=''
309 {
310 for L in $LANG ${LANG%%_*}; do
311 if [ -e "$PKGS_DB/packages-desc.$L" ]; then
312 sed '/^#/d' $PKGS_DB/packages-desc.$L; break
313 fi
314 done
315 [ -e "$i/blocked-packages.list" ] && cat $i/blocked-packages.list
316 sed 's|.*|&\ti|' $i/installed.info
317 [ "$cat" == 'extra' ] || [ $1 == 'my' ] || cat $i/packages.info
318 [ "$cat" == 'extra' ] && sed 's|.*|&\t-\textra\t-\thttp://mirror.slitaz.org/packages/get/&\t-\t-\t-|' $PKGS_DB/extra.list
319 } | sort -t$'\t' -k1,1 | sed '/^$/d' | awk -F$'\t' -vc="${cat:--}" -vt="${tag:--}" '
320 {
321 if (PKG && PKG != $1) {
322 if (SEL) {
323 if (DSCL) DSC = DSCL
324 printf "<tr><td><input type=\"checkbox\" name=\"pkg\" value=\"%s\"><a class=\"pkg%s%s\" href=\"?info=%s\">%s</a></td><td>%s</td><td>%s</td><td><a href=\"%s\"></a></td></tr>\n", PKG, INS, BLK, gensub(/\+/, "%2B", "g", PKG), PKG, VER, DSC, WEB
325 }
326 VER = DSC = WEB = DSCL = INS = BLK = SEL = ""
327 }
329 PKG = $1
330 if (NF == 1) { BLK = "b"; next }
331 if (NF == 2) { DSCL = $2; next }
332 if (c == "all" || $3 == c || index(" "$6" ", " "t" ")) { SEL = 1 }
333 if (SEL) {
334 if ($9 == "i") { VER = $2; DSC = $4; WEB = $5; INS = "i"; next}
335 if (! INS) { VER = $2; DSC = $4; WEB = $5 }
336 }
337 }' > $cached
339 pager="$(pager $cached)"
340 case $PAGE_SIZE in
341 0) list="$(cat $cached)";;
342 *) list="$(tail -n+$((($page-1)*$PAGE_SIZE+1)) $cached | head -n$PAGE_SIZE)";;
343 esac
345 if [ "$pager" != "<p>$(_ 'Pages:') </p>" ] && [ -n "${list:1:1}" ]; then
346 cat << EOT
347 $(header_repo_name $i)
348 $pager
349 $(table_head)
350 $list
351 </tbody></table>
352 $pager
353 EOT
354 fi
355 rm -f $cached
356 }
359 # Show links for "info" page
361 show_info_links() {
362 if [ -n "$1" ]; then
363 echo -n "<tr><td><b>$2</b></td><td>"
364 echo $1 | tr ' ' $'\n' | awk -vt="$3" '{
365 printf "<a href=\"?%s=%s\">%s</a>   ", t, gensub(/\+/, "%2B", "g", $1), $1
366 }'
367 echo "</td></tr>"
368 fi
369 }
373 #
374 # Commands
375 #
378 case " $(GET) " in
381 *\ linkable\ *)
382 #
383 # List linkable packages.
384 #
385 search_form; sidebar
386 LOADING_MSG=$(_ 'Listing linkable packages...'); loading_msg
388 cat << EOT
389 <h2>$(_ 'Linkable packages')</h2>
391 <form method="get" action="">
392 <div id="actions">
393 <div class="float-left">$(_ 'Selection:') $(show_button do=Link)</div>
394 <div class="float-right">$(show_button recharge up)</div>
395 </div>
396 EOT
397 table_head
398 target=$(readlink $PKGS_DB/fslink)
399 for pkg in $(ls $target/$INSTALLED); do
400 [ -s $pkg/receipt ] && continue
401 . $target/$INSTALLED/$pkg/receipt
402 i18n_desc $pkg
403 cat << EOT
404 <tr>
405 <td><input type="checkbox" name="pkg" value="$pkg" /><a class="pkg" href="?info=${pkg//+/%2B}">$pkg</a></td>
406 <td>$VERSION</td>
407 <td>$SHORT_DESC</td>
408 <td><a class="w" href="$WEB_SITE"></a></td>
409 </tr>
410 EOT
411 done
412 cat << EOT
413 </tbody>
414 </table>
415 </form>
416 EOT
417 ;;
420 *\ cats\ *)
421 #
422 # List of all categories.
423 #
424 search_form; sidebar
426 echo "<h2>$(_ 'Categories list')</h2>"
428 for pkgsinfo in $(repo_list /packages.info); do
429 header_repo_name $(dirname $pkgsinfo)
430 cat << EOT
431 <table class="zebra outbox">
432 <thead>
433 <tr>
434 <td>$(_ 'Category')</td>
435 <td>$(_ 'Available packages')</td>
436 <td>$(_ 'Installed packages')</td>
437 </tr>
438 </thead>
439 <tbody>
440 EOT
441 {
442 awk -F$'\t' '{print $3}' $pkgsinfo | sort | uniq -c
443 awk -F$'\t' '{print $3}' $PKGS_DB/installed.info | sed 's|.*|& i|' | sort | uniq -c
444 } | sort -k2,2 | awk '
445 {
446 c [$2] = "."
447 if ($3) { i[$2] = $1; } else { m[$2] = $1; }
448 }
449 END {
450 for (n in c) print n, m[n], i[n]
451 }' | sort | awk '{
452 printf "<tr><td><a href=\"?list&amp;cat=%s\">%s</a></td><td>%d</td><td>%d</td></tr>", $1, $1, $2, $3
453 }'
454 echo '</tbody></table>'
455 done
456 ;;
459 *\ list\ *)
460 #
461 # List all packages by category.
462 #
463 search_form; sidebar
464 LOADING_MSG="$(_ 'Listing packages...')"; loading_msg
466 bcat="<b>$cat</b>"; brepo="<b>$repo</b>"
467 case $repo in
468 Any)
469 case $my in
470 my) title="$(_ 'Installed packages of category "%s"' "$bcat")" ;;
471 *) title="$(_ 'All packages of category "%s"' "$bcat")" ;;
472 esac ;;
473 *)
474 case $my in
475 my) title="$(_ 'Installed packages of category "%s" in repository "%s"' "$bcat" "$brepo")" ;;
476 *) title="$(_ 'All packages of category "%s" in repository "%s"' "$bcat" "$brepo")" ;;
477 esac ;;
478 esac
480 cat << EOT
481 <h2>$(_ 'Packages list')</h2>
482 <p>$title</p>
484 <form method="get" action="">
485 <div id="actions">
486 <div class="float-left">$(_ 'Selection:')
487 $([ "$my" != 'my' ] && show_button do=Install)
488 $(show_button do=Remove)
489 </div>
490 <div class="float-right">$(show_button recharge up)</div>
491 </div>
492 EOT
493 for i in $(repo_list ""); do
494 show_list ${my#no}
495 done
496 echo '</form>'
497 ;;
500 *\ search\ *)
501 #
502 # Search for packages. Here default is to search in packages.desc
503 # and so get result including packages names and descriptions
504 #
505 pkg=$(GET search); [ -z "$pkg" ] && xhtml_footer && exit
506 cd $PKGS_DB
508 search_form; sidebar
509 LOADING_MSG="$(_ 'Searching packages...')"; loading_msg
511 cat << EOT
512 <h2>$(_ 'Search packages')</h2>
514 <form method="get" action="">
515 <div id="actions">
516 <div class="float-left">$(_ 'Selection:'; show_button do=Install do=Remove)
517 <a href="$(cat $PANEL/lib/checkbox.js)">$(_ 'Toogle all')</a></div>
518 <div class="float-right">$(show_button recharge up)</div>
519 </div>
520 EOT
521 if [ -n "$(GET files)" ]; then
522 cat <<EOT
523 <table class="zebra outbox filelist">
524 <thead>
525 <tr>
526 <td>$(_ 'Package')</td>
527 <td>$(_ 'File')</td>
528 </tr>
529 <thead>
530 <tbody>
531 EOT
532 lzcat $(repo_list /files.list.lzma) | grep -Ei ": .*$(GET search)" | \
533 while read PACKAGE FILE; do
534 PACKAGE=${PACKAGE%:}
535 class=pkg; [ -d $INSTALLED/$PACKAGE ] && class=pkgi
536 cat << EOT
537 <tr>
538 <td><input type="checkbox" name="pkg" value="$PACKAGE">$(pkg_info_link $PACKAGE $class)</td>
539 <td>$(echo "$FILE" | sed "s|$pkg|<span class=\"diff-add\">$pkg</span>|g")</td>
540 </tr>
541 EOT
542 done
543 else
544 table_head
545 awk -F$'\t' 'BEGIN{IGNORECASE = 1}
546 $1 $4 ~ /'$pkg'/{print $0}' $(repo_list /packages.info) | parse_packages_info
547 fi
548 cat << EOT
549 </tbody>
550 </table>
551 </form>
552 EOT
553 ;;
556 *\ recharge\ *)
557 #
558 # Lets recharge the packages list
559 #
560 search_form; sidebar
561 LOADING_MSG="$(_ 'Recharging lists...')"; loading_msg
563 cat << EOT
564 <h2>$(_ 'Recharge')</h2>
566 <form method="get" action="">
567 <div id="actions">
568 <div class="float-left">
569 <p>$(_ 'Recharge checks for new or updated packages')</p>
570 </div>
571 <div class="float-right">$(show_button up)</div>
572 </div>
573 <div class="wrapper">
574 <pre>
575 EOT
576 echo $(_ 'Recharging packages list') | log
577 tazpkg recharge | filter_taztools_msgs
578 cat << EOT
579 </pre>
580 </div>
581 <p>$(_ 'Packages lists are up-to-date. You should check for upgrades now.')</p>
582 EOT
583 ;;
586 *\ up\ *)
587 #
588 # Upgrade packages
589 #
590 search_form; sidebar
591 LOADING_MSG="$(_ 'Checking for upgrades...')"; loading_msg
593 cat << EOT
594 <h2>$(_ 'Up packages')</h2>
596 <form method="get" action="">
597 <div id="actions">
598 <div class="float-left">$(_ 'Selection:'; show_button do=Install do=Remove)
599 <button class="button" onclick="$(cat $PANEL/lib/checkbox.js)">$(_ 'Toogle all')</button></div>
600 <div class="float-right">$(show_button recharge)</div>
601 </div>
602 EOT
603 # Ask tazpkg to make "packages.up" file
604 tazpkg up --check >/dev/null
605 table_head
607 for pkg in $(cat $PKGS_DB/packages.up); do
608 grep -hs "^$pkg " $PKGS_DB/packages.info $PKGS_DB/undigest/*/packages.info | parse_packages_info
609 done
611 echo "</tbody></table></form>"
612 ;;
615 *\ do\ *)
616 #
617 # Do an action on one or some packages
618 #
619 search_form; sidebar
620 loading_msg
622 # Find the command
623 cmd=$(echo $(GET do) | tr [:upper:] [:lower:])
625 # Find the packages list
626 pkgs=$(echo $QUERY_STRING | awk 'BEGIN{RS="&";FS="="}{if($1=="pkg")print $2}')
627 pkgs=$(httpd -d "$pkgs")
629 # Describe the command
630 bpkgs="<b>$pkgs</b>"; opt=''
631 case $cmd in
632 install) MSG="$(_ 'Installing: %s' "$bpkgs")"; opt=--forced; cmd=get-install ;;
633 remove) MSG="$(_ 'Removing: %s' "$bpkgs")" ;;
634 link) MSG="$(_ 'Linking: %s' "$bpkgs")"; opt=$(readlink $PKGS_DB/fslink) ;;
635 block) MSG="$(_ 'Blocking: %s' "$bpkgs")" ;;
636 unblock) MSG="$(_ 'Unblocking: %s' "$bpkgs")" ;;
637 repack) MSG="$(_ 'Repacking: %s' "$bpkgs")" ;;
638 esac
640 cat << EOT
641 <h2>TazPkg: $(GET do)</h2>
642 <p>$MSG</p>
643 EOT
644 # Do the command for all asked packages
645 for pkg in $pkgs; do
646 echo '<pre>'
647 echo $(_n 'y') | tazpkg $cmd $pkg $opt 2>/dev/null | filter_taztools_msgs
648 echo '</pre>'
649 done ;;
652 *\ info\ *)
653 #
654 # Packages info
655 #
656 pkg=$(GET info)
657 search_form; sidebar
658 LOADING_MSG=$(_ 'Getting package info...'); loading_msg
660 cat << EOT
661 <h2>$(_ 'Package %s' $pkg)</h2>
663 <form method="get" action="">
664 <input type="hidden" name="pkg" value="${pkg#get-}"/>
665 <div id="actions">
666 EOT
668 # Get receipt variables, show Install/Remove buttons
669 if [ -d $INSTALLED/$pkg ]; then
670 . $INSTALLED/$pkg/receipt
671 files=$(wc -l < $INSTALLED/$pkg/files.list)
672 show_button do=Remove
673 else
674 cd $PKGS_DB
675 eval "$(awk -F$'\t' -vp=$pkg '
676 $1==p{
677 printf "PACKAGE=\"%s\"; VERSION=\"%s\"; CATEGORY=\"%s\"; ", $1, $2, $3
678 printf "SHORT_DESC=\"%s\"; WEB_SITE=\"%s\"; TAGS=\"%s\"; ", $4, $5, $6
679 printf "SIZES=\"%s\"; DEPENDS=\"%s\"", $7, $8
680 }' packages.info undigest/*/packages.info)"
681 PACKED_SIZE=${SIZES% *}
682 UNPACKED_SIZE=${SIZES#* }
683 if [ "${pkg#get-}" != "$pkg" ]; then
684 show_button "do=Install&amp;nf"
685 else
686 show_button do=Install
687 fi
688 fi
690 # Show Block/Unblock, and Repack buttons
691 if [ -d $INSTALLED/$pkg ]; then
692 if grep -qs "^$pkg$" $PKGS_DB/blocked-packages.list; then
693 show_button do=Unblock
694 else
695 show_button do=Block
696 fi
697 show_button do=Repack
698 fi
700 # Translate short description
701 i18n_desc $pkg
703 # Show info table
704 cat << EOT
705 </div>
706 <table class="zebra summary outbox">
707 <tbody>
708 <tr><td><b>$(_ 'Name')</b></td><td>$PACKAGE</td></tr>
709 <tr><td><b>$(_ 'Version')</b></td><td>$VERSION</td></tr>
710 <tr><td><b>$(_ 'Category')</b></td><td><a href="?cat=$CATEGORY">$CATEGORY</a></td></tr>
711 <tr><td><b>$(_ 'Description')</b></td><td>$SHORT_DESC</td></tr>
712 $([ -n "$MAINTAINER" ] && echo "<tr><td><b>$(_ 'Maintainer')</b></td><td>$MAINTAINER</td></tr>")
713 $([ -n "$LICENSE" ] && echo "<tr><td><b>$(_ 'License')</b></td><td><a href=\"?license=$pkg\">$LICENSE</a></td></tr>")
714 <tr><td><b>$(_ 'Website')</b></td><td><a href="$WEB_SITE" target="_blank">$WEB_SITE</a></td></tr>
715 $(show_info_links "$TAGS" "$(_ 'Tags')" 'tag')
716 <tr><td><b>$(_ 'Sizes')</b></td><td>$PACKED_SIZE/$UNPACKED_SIZE</td></tr>
717 $(show_info_links "$DEPENDS" "$(_ 'Depends')" 'info')
718 $(show_info_links "$SUGGESTED" "$(_ 'Suggested')" 'info')
719 </tbody>
720 </table>
721 EOT
723 # Show description
724 DESC="$(tazpkg desc $pkg)"
725 [ -n "$DESC" ] && echo "<pre>$DESC</pre>"
727 # Show configuration files list
728 CONFIGS="$(tazpkg list-config $pkg | sed 's|\(.*\)|\1 \1|')"
729 [ -n "$CONFIGS" ] && echo "<p>$(_ 'Configuration files')</p><pre>$(printf '<a href="index.cgi?file=%s">%s</a>\n' $CONFIGS)</pre>"
731 # Show installed files list
732 if [ -d $INSTALLED/$pkg ]; then
733 cat << EOT
734 <p>$(_ 'Installed files: %s' $(wc -l < $INSTALLED/$pkg/files.list))</p>
736 <pre>$(sort $INSTALLED/$pkg/files.list)</pre>
737 EOT
738 else
739 cat << EOT
740 <p>$(_ 'Installed files: %s' ' ')</p>
742 <pre>
743 $(lzcat files.list.lzma undigest/*/files.list.lzma 2> /dev/null | awk -vp="$pkg:" '$1==p{print $2}' | sort)
744 </pre>
745 EOT
746 fi
747 ;;
750 *\ admin\ * )
751 #
752 # TazPkg configuration page
753 #
754 cmd=$(GET admin)
755 pager="$(GET pager)"; pager=${pager:-$PAGE_SIZE}; pager=${pager:-100}
756 mirror="$(GET mirror)"; mirror="${mirror%/}/"
757 repository="$PKGS_DB/undigest/$(GET repository)"
758 link="$(GET link)"; link=${link%/}
759 search_form; sidebar
760 loading_msg
762 case "$cmd" in
763 clean)
764 rm -rf $CACHE_DIR/* ;;
765 add-mirror)
766 echo "$mirror" >> $(GET file) ;;
767 rm-mirror)
768 sed -i "/^"$(echo $mirror | sed 's|/|\\/|g')"$/d" $(GET file) ;;
769 select-mirror)
770 tazpkg setup-mirror "${mirror}packages/$(cat /etc/slitaz-release)/" | log ;;
771 add-repo)
772 mkdir -p $repository
773 echo "$mirror" > $repository/mirror
774 echo "$mirror" > $repository/mirrors ;;
775 rm-repo)
776 rm -rf $repository ;;
777 setlink)
778 [ -d "$link/$INSTALLED" ] && ln -fs $link $PKGS_DB/fslink ;;
779 removelink)
780 rm -f $PKGS_DB/fslink ;;
781 pager)
782 TP_CONF=/etc/slitaz/tazpanel.conf
783 if [ -z "$PAGE_SIZE" ]; then
784 echo -e "\n# Size of packages list page\nPAGE_SIZE=\"$pager\"" >> $TP_CONF
785 else
786 sed -i "s|PAGE_SIZE=.*|PAGE_SIZE=\"$pager\"|" $TP_CONF
787 fi ;;
788 esac
790 cat << EOT
791 <h2>$(_ 'Administration')</h2>
793 <p>$(_ 'TazPkg administration and settings')</p>
795 <form method="get" action="">
796 <input type="hidden" name="admin" />
798 <div id="actions">
799 $(show_button action=saveconf action=listconf action=quickcheck action=fullcheck)
800 </div>
801 </form>
802 EOT
803 case "$(GET action)" in
804 saveconf)
805 LOADING_MSG=$(_ 'Creating the package...'); loading_msg
806 echo "<pre>"
807 cd /tmp
808 tazpkg repack-config | filter_taztools_msgs
809 echo -n "$(_ 'Path:') "; ls /tmp/config-*.tazpkg
810 echo "</pre>" ;;
811 listconf)
812 echo "<h4>$(_ 'Configuration files')</h4>"
813 echo "<ul>"
814 tazpkg list-config | while read file; do
815 if [ -e $file ]; then
816 echo "<li><a href=\"index.cgi?file=$file\">$file</a></li>"
817 else
818 echo "<li>$file</li>"
819 fi
820 done
821 echo "</ul>" ;;
822 quickcheck)
823 LOADING_MSG=$(_ 'Checking packages consistency...'); loading_msg
824 echo "<pre>"
825 tazpkg check
826 echo "</pre>" ;;
827 fullcheck)
828 LOADING_MSG=$(_ 'Full packages check...'); loading_msg
829 echo "<pre>"
830 tazpkg check --full
831 echo "</pre>" ;;
832 dvdimage)
833 dev=$(POST dvdimage)
834 mkdir -p /mnt/packages 2> /dev/null
835 echo "<pre>"
836 mount -t iso9660 -o loop,ro $dev /mnt/packages &&
837 /mnt/packages/install.sh &&
838 _ '%s is installed on /mnt/packages' $dev
839 echo "</pre>" ;;
840 dvdusbkey)
841 mkdir -p /mnt/packages 2> /dev/null
842 for tag in "LABEL=\"packages-$version\" TYPE=\"iso9660\"" \
843 "LABEL=\"sources-$version\" TYPE=\"iso9660\"" ; do
844 dev=$(blkid | grep "$tag" | cut -d: -f1)
845 [ -n "$dev" ] || continue
846 echo "<pre>"
847 mount -t iso9660 -o ro $dev /mnt/packages &&
848 /mnt/packages/install.sh &&
849 _ '%s is installed on /mnt/packages' $dev
850 echo "</pre>"
851 break
852 done ;;
853 esac
855 cache_files=$(find $CACHE_DIR -name '*.tazpkg' | wc -l)
856 cache_size=$(du -sh $CACHE_DIR | cut -f1 | sed 's|\.0||')
857 [ "$cache_files" == 0 ] && cache_size="0K"
858 mirror=$(cat $PKGS_DB/mirror)
859 default_mirror=${mirror%/packages/*}
860 cat << EOT
861 <article>
862 <h3>$(_ 'Packages cache')</h3>
864 <form method="get" action="">
865 <p>$(_ 'Packages in the cache: %s (%s)' $cache_files $cache_size)
866 $(show_button admin=clean)
867 </p>
868 </form>
869 </article>
872 <article>
873 <h3>$(_ 'Current mirror list')</h3>
874 EOT
876 # List mirrors
877 version=$(cat /etc/slitaz-release)
878 for i in $PKGS_DB/mirrors $PKGS_DB/undigest/*/mirrors; do
879 [ -s $i ] || continue
880 if [ $i != $PKGS_DB/mirrors ]; then
881 echo "<h4>$(_ 'Repository: %s' "$(repo_name $(dirname $i))")</h4>"
882 fi
883 cat << EOT
884 <form method="get" action="">
885 <input type="hidden" name="admin" value="select-mirror"/>
886 <table class="zebra">
887 EOT
888 while read line; do
889 cat << EOT
890 <tr>
891 <td>
892 <input type="radio" name="mirror" id="$line" value="$line" onchange="this.form.submit()"
893 $([ "$line" == "$default_mirror/" ] && echo -n 'checked="checked"')>
894 <label for="$line"><code>$line</code></label></td>
895 <td><a class="w" href="$line" target="_blank"></a></td>
896 <td><a href="?admin=rm-mirror&amp;mirror=$line&amp;file=$i">
897 <img src="$IMAGES/tp-remove.png" title="$(_ 'Delete')"/></a></td>
898 </tr>
899 EOT
900 done < $i
901 cat << EOT
902 </table>
903 </form>
905 <form method="get" action="">
906 <p>
907 <input type="hidden" name="file" value="$i" />
908 <input type="text" name="mirror" size="40" />
909 $(show_button admin=add-mirror)
910 </p>
911 </form>
912 EOT
913 done
914 echo "</article><article>"
915 echo "<h3>$(_ 'Private repositories')</h3>"
916 if [ -n "$(ls $PKGS_DB/undigest 2> /dev/null)" ]; then
917 echo '<table class="zebra">'
918 ls $PKGS_DB/undigest 2> /dev/null | while read repo ; do
919 cat <<EOT
920 <tr><td><a href="?admin=rm-repo&amp;repository=$repo"><img src="$IMAGES/tp-remove.png" title="$(_ 'Delete')"></a>$repo</td></tr>
921 EOT
922 done
923 echo '</table>'
924 fi
926 cat << EOT
927 <form method="get" action="">
928 <p>$(_ 'Name') <input type="text" name="repository" size="10"/>
929 $(_ 'URL:') <input type="text" name="mirror" value="http://">
930 $(show_button admin=add-repo)</p>
931 </form>
932 </article>
935 <article>
936 <h3>$(_ 'Link to another SliTaz installation')</h3>
938 <p>$(_ "This link points to the root of another SliTaz installation. \
939 You will be able to install packages using soft links to it.")</p>
941 <form method="get" action="">
942 <p>
943 <input type="text" name="link" value="$(readlink $PKGS_DB/fslink 2> /dev/null)"/>
944 $(show_button admin=setlink admin=removelink)
945 </p>
946 </form>
947 </article>
950 <article>
951 <h3 id="dvd">$(_ 'SliTaz packages DVD')</h3>
953 <p>$(_ "A bootable DVD image of all available packages for the %s version is \
954 generated every day. It also contains a copy of the website and can be used \
955 without an internet connection. This image can be installed on a DVD or a USB \
956 key." $version)</p>
958 <button class="button" onclick='http://mirror.slitaz.org/iso/$version/packages-$version.iso'>
959 <img src="$IMAGES/tp-dl-dvd.png" />$(_ 'Download DVD image')</button>
960 <button class="button" onclick='?admin&amp;action=dvdusbkey'>
961 <img src="$IMAGES/tp-link.png" />$(_ 'Install from DVD/USB key')</button>
962 <div class="box">
963 <form method="post" action='?admin&amp;action=dvdimage'>
964 $(_ 'Install from ISO image:')
965 <input type="text" name="dvdimage" size="40" value="/root/packages-$version.iso" />
966 </div>
967 </form>
968 </article>
971 <article>
972 <h3>$(_ 'Packages list')</h3>
974 <p>$(_ 'Long list of packages is paginated. Here you can set the page size (default: 100, turning off the pager: 0).')</p>
975 <form method="get" action="">
976 <input type="hidden" name="admin" value="pager" />
977 <input type="number" name="pager" value="$pager" min="0" step="10" size="4" />
978 <button class="button" type="submit">$(_ 'Set')</button>
979 </form>
980 </article>
981 EOT
982 ;;
985 *\ license\ *)
986 #
987 # Show licenses for installed packages
988 #
989 search_form; sidebar
991 pkg=$(GET license)
992 case $pkg in
993 /*) [ -e $pkg ] && {
994 echo "<h2>${pkg#/usr/share/licenses/}</h2>"
995 case $pkg in
996 *.htm*) cat $pkg ;;
997 *) echo "<pre style=\"white-space: pre-wrap\">"
998 cat $pkg | htmlize | sed 's|\([hf]t*t*ps*://[a-zA-Z0-9./_-]*[a-zA-Z0-9/_-]\)|<a href="\1">\1</a>|'
999 echo "</pre>"
1000 ;;
1001 esac
1002 } ;;
1003 *) echo "<h2>$(_ 'Licenses for package %s' $pkg)</h2>"
1004 OFFLINE=''
1005 if [ -e "$PKGS_DB/installed/$pkg" ]; then
1006 for lic in $(grep /usr/share/licenses/ $PKGS_DB/installed/$pkg/files.list); do
1007 OFFLINE="$OFFLINE <li><a href=\"?license=$lic\">licenses/<b>${lic#/usr/share/licenses/}</b></a></li>\n"
1008 done
1009 echo "\
1010 Apache|Apache-2.0||||http://www.apache.org/licenses/#Artistic|Artistic-2.0||||#\
1011 BSD|BSD-2-Clause||||#BSD3|BSD-3-Clause||||#CC-BY-SA||by-sa/4.0/|||#\
1012 CC-SA||by-sa/4.0/|||#CC-BY-ND||by-nd/4.0/|||#CC-BY-NC-SA||by-nc-sa/4.0/|||#\
1013 CC-BY-NC-ND||by-nc-nd/4.0/|||#CC-BY-NC||by-nc/4.0/|||#CC-BY||by/4.0/|||#\
1014 cc-pd|||||http://creativecommons.org/publicdomain/#CDDL|CDDL-1.0||||#\
1015 CECILL|CECILL-2.1||||#Eclipse|EPL-1.0||||#EPL|EPL-1.0||||#FDL|||fdl||#\
1016 GPL|gpl-license||gpl|gpl.txt|#GPL2|GPL-2.0||old-licenses/gpl-2.0||#\
1017 GPL3|GPL-3.0||gpl|gpl.txt|#ISC|ISC||||#LGPL|lgpl-license||lgpl||#\
1018 LGPL2|||old-licenses/lgpl-2.0||#\
1019 LGPL2.1|LGPL-2.1||old-licenses/lgpl-2.1|lgpl.txt|#LGPL3|LGPL-3.0||lgpl||#\
1020 LPPL|LPPL-1.3c||||#MIT|MIT|||mit.txt|#MPL|MPL-2.0|||mozilla.txt|#\
1021 MPL2|MPL-2.0||||#PublicDomain|||||http://creativecommons.org/publicdomain/#\
1022 QPL|QPL-1.0||||#SIL_OFL|OFL-1.1||||#OFL|OFL-1.1||||#zlib/libpng|Zlib||||" | \
1023 awk -vlicenses="$(. $PKGS_DB/installed/$pkg/receipt; echo "$LICENSE")" \
1024 -vtext="$(_ '%s license on %s website' %s %s)" \
1025 -vro="$(_ 'Read online:')" -vrl="$(_ 'Read local:')" \
1026 -vofflic="$OFFLINE" '
1027 BEGIN{ FS="|"; RS="#"; split(licenses, lic, " "); if (offlic) OFFLINE[0]=offlic }
1028 function link1(u, l, ll, w) {
1029 return sprintf("\t<li><a href=\"%s%s\">" text "</a></li>", u, l, "<b>" ll "</b>", w) }
1030 function link2(u, l, ll) {
1031 return sprintf("\t<li><a href=\"%s%s\">%s</b></a></li>", u, l, ll) }
1032 function link_osl(n) {
1033 return link1("http://opensource.org/licenses/", n, n, "OSL") }
1034 function link_cc(n) {
1035 split(n, ll, "/")
1036 return link1("http://creativecommons.org/licenses/", n, ll[1], "Creative Commons") }
1037 function link_gnu(n) {
1038 split(n, ll, "/")
1039 return link1("https://www.gnu.org/licenses/", n ".html", ll[2] ? ll[2] : ll[1], "GNU") }
1040 function link_loc(n) {
1041 return link2("?license=/usr/share/licenses/", n, "licenses/<b>" n "</b>") }
1042 function link_url(n) {
1043 return link2(n, "", n) }
1045 if ($1 == lic[1] || $1 == lic[2] || $1 == lic[3] || $1 == lic[4]) {
1046 if ($2) ONLINE[$2]=link_osl($2)
1047 if ($3) ONLINE[$3]=link_cc($3)
1048 if ($4) ONLINE[$4]=link_gnu($4)
1049 if ($5) OFFLINE[$5]=link_loc($5)
1050 if ($6) OFFLINE[$6]=link_url($6)
1053 END{
1054 if (length(ONLINE) > 0) { print "<p>" ro "</p>\n<ul>"; for (o in ONLINE) print ONLINE[o]; print "</ul>" }
1055 if (length(OFFLINE) > 0) { print "<p>" rl "</p>\n<ul>"; for (o in OFFLINE) print OFFLINE[o]; print "</ul>" }
1056 }'
1057 fi ;;
1058 esac
1059 ;;
1062 *\ tags\ *)
1064 # Show tag cloud
1066 search_form; sidebar
1068 echo "<h2>$(_ 'Tags list')</h2>"
1069 brepo="<b>$repo</b>"
1070 case $repo in
1071 Any) title="$(_ 'List of tags in all repositories')" ;;
1072 *) title="$(_ 'List of tags in repository "%s"' "$brepo")" ;;
1073 esac
1074 echo "<p>$title</p><p id=\"tags\">"
1075 to_read=""
1076 for i in $(repo_list ""); do
1077 if [ ! -e $i/packages.info ]; then
1078 list=installed
1079 else
1080 list=packages
1081 fi
1082 to_read="$to_read $i/$list.info"
1083 done
1084 TAGS="$(awk -F$'\t' '{if($6){print $6}}' $to_read | tr ' ' $'\n' | sort | uniq -c)"
1085 MAX="$(echo "$TAGS" | awk '{if ($1 > MAX) MAX = $1} END{print MAX}')"
1086 echo "$TAGS" | awk -vMAX="$MAX" '{
1087 printf "<a class=\"tag%s\" href=\"?tag=%s\" title=\"%s\">%s</a> ", int($1 * 7 / MAX + 1), $2, $1, $2
1088 }'
1089 echo "</p>"
1090 ;;
1093 *\ tag\ *)
1095 # Show packages with matching tag
1097 search_form; sidebar
1099 tag=$(GET tag)
1100 cat << EOT
1101 <h2>$(_ 'Tag "%s"' $tag)</h2>
1103 <form method="get" action="">
1104 <div id="actions">
1105 <div class="float-left">
1106 $(_ 'Selection:'; show_button do=Install do=Remove)
1107 </div>
1108 <div class="float-right">
1109 $(show_button tags)
1110 </div>
1111 </div>
1112 EOT
1113 for i in $(repo_list ""); do
1114 show_list all
1115 done
1116 echo '</form>'
1117 ;;
1120 *\ blocked\ *)
1122 # Show blocked packages list
1124 search_form; sidebar
1126 cat << EOT
1127 <h2>$(_ 'Blocked packages list')</h2>
1129 <form method="get" action="">
1130 <div id="actions">
1131 <div class="float-left">$(_ 'Selection:'; show_button do=Unblock)
1132 </div>
1133 </div>
1134 EOT
1135 table_head
1136 for i in $(cat $PKGS_DB/blocked-packages.list); do
1137 awk -F$'\t' -vp="$i" '{
1138 if ($1 == p)
1139 printf "<tr><td><input type=\"checkbox\" name=\"pkg\" value=\"%s\"><a class=\"pkgib\" href=\"?info=%s\">%s</a></td><td>%s</td><td>%s</td><td><a href=\"%s\"></a></td></tr>\n", $1, gensub(/\+/, "%2B", "g", $1), $1, $2, $4, $5
1140 }' $PKGS_DB/installed.info
1141 done
1142 echo '</tbody></table></form>'
1143 ;;
1146 *)
1148 # Default to summary
1150 search_form; sidebar
1152 cat << EOT
1153 <h2>$(_ 'Summary')</h2>
1155 <form method="get" action="">
1156 <div id="actions">
1157 EOT
1158 fslink=$(readlink $PKGS_DB/fslink)
1159 [ -n "$fslink" -a -d "$fslink/$INSTALLED" ] && show_button linkable
1160 show_button recharge up admin
1161 cat << EOT
1162 </div>
1164 <article>
1165 <h3>$(_ 'Summary')</h3>
1166 <table class="zebra summary">
1167 <tbody>
1168 <tr>
1169 <td>$(_ 'Last recharge:')</td>
1170 <td>$(list=$PKGS_DB/ID
1171 if [ -e $list ]; then
1172 ohhmm="$(date +%z)" # '+0200' for EET (+2 hours)
1173 offset=$(( 60 * (60 * ${ohhmm:0:3} + ${ohhmm:3:2}) )) # in the seconds
1174 daynow=$(( ($(date +%s) + $offset) / 86400 ))
1175 dayupd=$(( ($(date -r $list +%s) + $offset) / 86400 ))
1176 days=$(( $daynow - $dayupd ))
1177 time=$(date -r $list +%R)
1178 ago="$(_p '%d day ago.' '%d days ago.' $days $days)"
1179 case $days in
1180 0) _ 'Today at %s.' $time;;
1181 1) _ 'Yesterday at %s.' $time;;
1182 [2-9]) echo $ago;;
1183 *) echo "<span style='color:red'>$ago</span>"
1184 _ 'It is recommended to [recharge] the lists.' | \
1185 sed 's|\[|<a href="?recharge">|;s|\]|</a>|';;
1186 esac
1187 else
1188 _ 'never.'
1189 _ 'You need to [download] the lists for further work.' | \
1190 sed 's|\[|<a href="?recharge">|;s|\]|</a>|'
1191 fi)</td></tr>
1192 <tr>
1193 <td>$(_ 'Installed packages:')</td>
1194 <td><a href="?list&amp;my=my&amp;cat=all&amp;repo=Any">
1195 <b>$(cat $PKGS_DB/installed.info | wc -l)</b>
1196 </a></td></tr>
1197 <tr>
1198 <td>$(_ 'Mirrored packages:')</td>
1199 <td><a href="?list&amp;my=no&amp;cat=all&amp;repo=Any">
1200 <b>$(cat $PKGS_DB/packages.list | wc -l)</b>
1201 </a></td></tr>
1202 <tr>
1203 <td>$(_ 'Upgradeable packages:')</td>
1204 <td><a href="?up">
1205 <b>$(cat $PKGS_DB/packages.up | wc -l)</b>
1206 </a></td></tr>
1207 <tr>
1208 <td>$(_ 'Installed files:')</td>
1209 <td><b>$(cat $INSTALLED/*/files.list | wc -l)</b></td></tr>
1210 <tr>
1211 <td>$(_ 'Blocked packages:')</td>
1212 <td><a href="?blocked">
1213 <b>$(cat $PKGS_DB/blocked-packages.list | wc -l)</b>
1214 </a></td></tr>
1215 </tbody>
1216 </table></article>
1218 <article>
1219 <h3>$(_ 'Latest log entries')</h3>
1221 <pre>
1222 $(tail -n 5 $LOG | fgrep "-" | awk '{print $1, $2, $3, $4, $5, "<a href=\"?info=" $6 "\">" $6 "</a>", $7}')
1223 <a href="index.cgi?file=$LOG">$(_ 'more...')</a>
1224 </pre>
1225 </article>
1226 EOT
1227 ;;
1228 esac
1230 # xHTML 5 footer
1231 export TEXTDOMAIN='tazpkg'
1232 xhtml_footer
1233 exit 0