tazpkg view tazpanel/pkgs.cgi @ rev 832

pkgs.cgi: info page: show more info; show suggested list with descriptions (handy for packages like "gvfs")
author Aleksej Bobylev <al.bobylev@gmail.com>
date Fri Aug 14 03:07:11 2015 +0300 (2015-08-14)
parents 47b3b13dbf6b
children a02e36d44d06
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-2015 SliTaz GNU/Linux - BSD License
10 #
12 . lib/libtazpanel
14 . /etc/slitaz/slitaz.conf
15 . /etc/slitaz/tazpkg.conf
17 export TEXTDOMAIN='tazpkg'
19 get_config
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 3;
25 printf "$(ngettext "$S" "$P" "$N")" "$@"; }
28 #------
29 # menu
30 #------
32 case "$1" in
33 menu)
34 TEXTDOMAIN_original=$TEXTDOMAIN
35 export TEXTDOMAIN='tazpkg'
37 cat <<EOT
38 <li tabindex="0">
39 <span>$(gettext 'Packages')</span>
40 <menu>
41 <li><a data-icon="info" href="pkgs.cgi">$(gettext 'Summary')</a></li>
42 <li><a data-icon="list" href="pkgs.cgi?list&amp;my=my&amp;cat=all&amp;repo=Any">$(gettext 'My packages')</a></li>
43 <li><a data-icon="refresh" href="pkgs.cgi?recharge" data-root>$(gettext 'Recharge list')</a></li>
44 <li><a data-icon="upgrade" href="pkgs.cgi?up" data-root>$(gettext 'Check updates')</a></li>
45 <li><a data-icon="admin" href="pkgs.cgi?admin" data-root>$(gettext 'Administration')</a></li>
46 </menu>
47 </li>
48 EOT
49 export TEXTDOMAIN=$TEXTDOMAIN_original
50 exit
51 esac
55 #
56 # AJAX commands
57 #
59 case " $(GET) " in
62 *\ filelist\ * )
63 # Show installed files list
64 pkg=$(GET pkg)
65 cd $PKGS_DB
67 header
68 if [ -d $INSTALLED/$pkg ]; then
69 files="$(wc -l < $INSTALLED/$pkg/files.list)"
70 cat <<EOT
71 <pre class="scroll">$(sort $INSTALLED/$pkg/files.list)</pre>
72 <footer>$(_p '%s file' '%s files' $files $files)</footer>
73 EOT
74 else
75 cat <<EOT
76 <pre class="scroll">$(lzcat files.list.lzma undigest/*/files.list.lzma \
77 2>/dev/null | awk -vp="$pkg:" '$1==p{print $2}' | sort)</pre>
78 EOT
79 fi
80 exit 0 ;;
83 *\ status\ * )
84 # Show package status
85 pkg=$(GET pkg | tr -d ' ')
86 orig_pkg=''
88 if grep -q "^$pkg"$'\t' $PKGS_DB/installed.info; then
89 # Package installed
90 class='pkgi'
91 else
92 # Package not installed
93 class='pkg'
94 equivs=$(grep "^$pkg=" $PKGS_DB/packages.equiv)
95 if [ "$(GET pkg)" == "$pkg" -a -n "$equivs" ]; then
96 for equiv in ${equivs#*=}; do
97 case $equiv in
98 *:*)
99 if grep -q "^${equiv%:*}"$'\t' "$PKGS_DB/installed.info" &&
100 grep -q "^${equiv#*:}"$'\t' "$PKGS_DB/installed.info"; then
101 # Equivalent installed
102 orig_pkg="$pkg→"; pkg="${equiv#*:}"; class='pkgi'; break
103 fi;;
104 *)
105 if grep -q "^$equiv"$'\t' "$PKGS_DB/installed.info"; then
106 # Equivalent installed
107 orig_pkg="$pkg→"; pkg="$equiv"; class='pkgi'; break
108 fi;;
109 esac
110 done
111 fi
112 fi
114 # Installed and blocked?
115 [ "$class" == 'pkgi' ] && grep -q "^$pkg$" $PKGS_DB/blocked-packages.list && class='pkgib'
117 header
118 echo -n "<a data-icon=\"$class\" href=\"?info=${pkg//+/%2B}\">$orig_pkg$pkg</a>"
119 exit 0 ;;
122 *\ app_img\ * )
123 # Show application image
124 pkg=$(GET app_img)
126 # check for icons defined with packages.icons file
127 if [ -f "$PKGS_DB/packages.icons" ]; then
128 predefined_icon="$(awk -F$'\t' -vpkg="$pkg" '{if ($1 == pkg) print $2}' $PKGS_DB/packages.icons)"
129 fi
130 predefined_icon="${predefined_icon:-package-x-generic}.png"
132 current_user="$(who | cut -d' ' -f1)"
133 if [ -n "$current_user" ]; then
134 current_user_home="$(awk -F: -vu=$current_user '{if($1==u) print $6}' /etc/passwd)"
135 current_icon_theme="$(grep gtk-icon-theme-name $current_user_home/.gtkrc-2.0 | cut -d'"' -f2)"
136 fi
137 current_icon_theme="/usr/share/icons/$current_icon_theme"
139 # Preferred default icon is 48px package-x-generic
140 default_pkg_icon="$(find -L $current_icon_theme -type f -path '*48*' -name $predefined_icon | head -n1)"
141 # ... or package-x-generic with the bigger size
142 if [ -z "$default_pkg_icon" ]; then
143 default_pkg_icon="$(find -L $current_icon_theme -type f -name $predefined_icon | sort | tail -n1)"
144 fi
146 # Preferred package icon size is 48px
147 pkg_icon="$(find -L $current_icon_theme -type f -path '*48*' -name "$pkg.png" | head -n1)"
148 # ... or just bigger one
149 if [ -z "$pkg_icon" ]; then
150 pkg_icon="$(find -L $current_icon_theme -type f -name "$pkg.png" | sort | tail -n1)"
151 fi
152 # ... or one from pixmaps
153 if [ -z "$pkg_icon" ]; then
154 pkg_icon="$(find -L /usr/share/pixmaps -type f -name "$pkg.png" | head -n1)"
155 fi
157 header "Content-Type: image/png"
158 cat "${pkg_icon:-$default_pkg_icon}"
159 exit 0 ;;
162 *\ show_receipt\ * )
163 # Show package receipt
164 pkg=$(GET show_receipt)
165 if [ -d "$INSTALLED/$pkg" ]; then
166 # Redirects to the receipt view
167 header "HTTP/1.1 301 Moved Permanently" "Location: index.cgi?file=$INSTALLED/$pkg/receipt"
168 exit 0
169 else
170 temp_receipt=$(mktemp -d)
171 wget -O $temp_receipt/receipt -T 5 http://hg.slitaz.org/wok/raw-file/tip/$pkg/receipt
172 if [ -e "$temp_receipt" ]; then
173 # Redirects to the receipt view
174 header "HTTP/1.1 301 Moved Permanently" "Location: index.cgi?file=$temp_receipt/receipt"
175 exit 0
176 else
177 header; xhtml_header
178 msg err "$(_ 'Receipt for package %s unavailable' $pkg)"
179 xhtml_footer
180 exit 0
181 fi
182 fi
183 ;;
185 esac
188 header
191 # xHTML 5 header with special side bar for categories.
192 TITLE=$(TEXTDOMAIN='tazpkg'; _ 'Packages')
195 pkg_info_link() {
196 echo "<a data-icon=\"$2\" href=\"?info=${1//+/%2B}\">$1</a>" | sed 's| data-icon=""||'
197 }
200 # Display localized short description
202 i18n_desc() {
203 for L in $LANG ${LANG%%_*}; do
204 if [ -e "$PKGS_DB/packages-desc.$L" ]; then
205 LOCDESC=$(awk -F$'\t' -vp=$1 '{if ($1 == p) print $2}' $PKGS_DB/packages-desc.$L)
206 if [ -n "$LOCDESC" ]; then
207 SHORT_DESC="$LOCDESC"
208 break
209 fi
210 fi
211 done
212 }
215 # We need packages information for list and search
217 parse_packages_desc() {
218 IFS="|"
219 cut -f 1,2,3 -d "|" | while read PACKAGE VERSION SHORT_DESC
220 do
221 class=pkg; [ -d $INSTALLED/${PACKAGE% } ] && class=pkgi
222 i18n_desc $PACKAGE
223 cat <<EOT
224 <tr>
225 <td><input type="checkbox" name="pkg" value="$PACKAGE">$(pkg_info_link $PACKAGE $class)</td>
226 <td>$VERSION</td>
227 <td>$SHORT_DESC</td>
228 </tr>
229 EOT
230 done
231 unset IFS
232 }
235 parse_packages_info() {
236 IFS=$'\t'
237 while read PACKAGE VERSION CATEGORY SHORT_DESC WEB_SITE TAGS SIZES DEPENDS; do
238 class='pkg'
239 if grep -q "^$PACKAGE"$'\t' $PKGS_DB/installed.info; then
240 class='pkgi'
241 grep -q "^$PACKAGE$" $PKGS_DB/blocked-packages.list && class='pkgib'
242 fi
243 i18n_desc $PACKAGE
244 cat <<EOT
245 <tr>
246 <td><input type="checkbox" name="pkg" value="$PACKAGE">$(pkg_info_link $PACKAGE $class)</td>
247 <td>$VERSION</td>
248 <td>$SHORT_DESC</td>
249 </tr>
250 EOT
251 done
252 unset IFS
253 }
256 # Show button
257 show_button() {
258 for button in $@; do
259 class=''; misc=''
260 case $button in
261 recharge) class='refresh'; label="$(_ 'Recharge list')"; misc=' data-root' ;;
262 up) class='upgrade'; label="$(_ 'Check upgrades')"; misc=' data-root' ;;
263 list) class='list'; label="$(_ 'My packages')" ;;
264 tags) class='tags'; label="$(_ 'Tags')" ;;
265 linkable) class='link'; label="$(_ 'Linkable packages')" ;;
266 admin) class='admin'; label="$(_ 'Administration')"; misc=' data-root' ;;
267 *Install*nf*) class='install'; label="$(_ 'Install (Non Free)')" ;;
268 *Install*) class='install'; label="$(_ 'Install')" ;;
269 *Remove*) class='remove'; label="$(_ 'Remove')" ;;
270 *Link*) class='link'; label="$(_ 'Link')" ;;
271 *Block*) class='lock'; label="$(_ 'Block')" ;;
272 *Unblock*) class='unlock'; label="$(_ 'Unblock')" ;;
273 *Chblock*) class='chlock'; label="$(_ '(Un)block')" ;;
274 *Repack*) class='repack'; label="$(_ 'Repack')" ;;
275 *saveconf*) class='save'; label="$(_ 'Save configuration')" ;;
276 *listconf*) class='list'; label="$(_ 'List configuration files')" ;;
277 *quickcheck*) class='check'; label="$(_ 'Quick check')" ;;
278 *fullcheck*) class='check'; label="$(_ 'Full check')" ;;
279 *clean*) class='remove'; label="$(_ 'Clean')" ;;
280 *setlink*) class='link'; label="$(_ 'Set link')" ;;
281 *removelink*) class='unlink'; label="$(_ 'Remove link')" ;;
282 *add-mirror) class='add'; label="$(_n 'Add mirror')" ;;
283 *add-repo) class='add'; label="$(_n 'Add repository')" ;;
284 toggle) class='toggle'; label="$(_n 'Toggle all')" ;;
285 esac
286 if [ "$button" == 'toggle' ]; then
287 echo -n "<span class=\"float-right\"><button data-icon=\"$class\" onclick=\"checkBoxes()\">$label</button></span>"
288 else
289 echo -n "<button data-icon=\"$class\" name=\"${button%%=*}\" value=\"${button#*=}\"$misc>$label</button>"
290 fi
291 done
292 }
296 #
297 # xHTML functions
298 #
301 table_head() {
302 cat <<EOT
303 <table class="wide zebra pkglist" id="head1">
304 <thead id="head2">
305 <tr>
306 <td>$(_ 'Name')</td>
307 <td>$(_ 'Version')</td>
308 <td>$(_ 'Description')</td>
309 </tr>
310 </thead>
311 <tbody>
312 EOT
313 }
316 sidebar() {
317 repo=$(COOKIE repo); repo=${repo:-Public}; [ -n "$(GET repo)" ] && repo=$(GET repo)
318 my=$(COOKIE my); my=${my:-my}; [ -n "$(GET my)" ] && my=$(GET my)
319 cat=$(COOKIE cat); cat=${cat:-all}; [ -n "$(GET cat)" ] && cat=$(GET cat)
321 cat <<EOT
322 <script type="text/javascript">
323 function setCookie(name) {
324 if (name=='cat') {
325 var cats = document.getElementsByName('cat');
326 for (var i = 0; i < cats.length; i++) {
327 if (cats[i].checked) {
328 document.cookie = name + "=" + cats[i].value;
329 break;
330 }
331 }
332 } else {
333 document.cookie = name+"="+document.getElementById(name).value;
334 }
335 }
336 function setValue(name, value) {
337 document.getElementById(name).value=value;
338 setCookie(name);
339 }
340 </script>
341 <form method="post" action="?list" style="position: absolute">
343 <div id="sidebar">
344 <select id="my" value="$my" onchange="setCookie('my'); this.form.submit()">
345 <option value="my">$(_ 'My packages')</option>
346 <option value="no">$(_ 'All packages')</option>
347 </select>
348 <script type="text/javascript">setValue('my', "$my")</script>
350 <h4>$(_ 'Categories')</h4>
352 <div class="wide zebra">
353 $(echo 'base-system x-window utilities network games graphics office
354 multimedia development system-tools security misc meta non-free all
355 extra' | tr ' ' '\n' | awk -vcat="$cat" -vn="1" '{
356 system("gettext " $1 | getline tr)
357 printf "<input type=\"radio\" name=\"cat\" id=\"c%s\" ", n
358 printf "value=\"%s\"%s ", $1, $1==cat?" checked":""
359 printf "onclick=\"setCookie(&#39;cat&#39;); this.form.submit()\">"
360 printf "<label for=\"c%s\">%s</label>\n", n, tr
361 n++
362 }')
363 </div>
364 EOT
366 if [ -d $PKGS_DB/undigest ]; then
367 cat <<EOT
368 <h4>$(_ 'Repository')</h4>
370 <select id="repo" onchange="setCookie('repo')">
371 <option value="Public">$(_ 'Public')</option>
372 $(for i in $(ls $PKGS_DB/undigest); do
373 echo "<option value=\"$i\">$i</option>"
374 done)
375 <option value="Any">$(_ 'Any')</option>
376 </select>
377 <script type="text/javascript">setValue('repo', "$repo")</script>
378 EOT
379 fi
380 cat <<EOT
381 <a data-icon="tags" href="?tags">$(_ 'All tags...')</a><br/>
382 <a data-icon="list" href="?cats">$(_ 'All categories...')</a>
383 </div>
384 </form>
385 EOT
386 }
389 repo_list() {
390 if [ -n "$(ls $PKGS_DB/undigest/ 2>/dev/null)" ]; then
391 case "$repo" in
392 Public)
393 ;;
394 ""|Any)
395 for i in $PKGS_DB/undigest/* ; do
396 [ -d "$i" ] && echo "$i$1"
397 done ;;
398 *)
399 ls "$PKGS_DB/undigest/$repo$1" 2>/dev/null
400 return ;;
401 esac
402 fi
403 [ -e "$PKGS_DB$1" ] && echo "$PKGS_DB$1"
404 }
407 repo_name() {
408 case "$1" in
409 $PKGS_DB)
410 echo "Public" ;;
411 $PKGS_DB/undigest/*)
412 echo ${1#$PKGS_DB/undigest/} ;;
413 esac
414 }
417 header_repo_name() {
418 [ -d $PKGS_DB/undigest ] && [ "$repo" != "Public" ] && \
419 _ 'Repository: %s' $(repo_name $1)
420 }
423 # Print links to the pages
425 pager() {
426 PAGE_SIZE=${PAGE_SIZE:-100}
427 [ "$PAGE_SIZE" != "0" ] && \
428 awk -F'"' -vpage="$page" -vsize="$PAGE_SIZE" -vnum_lines="$(wc -l < $1)" -vtext="$(_ 'Pages:') " -vurl="?list&amp;page=" '
429 BEGIN{
430 num_pages = int(num_lines / size) + (num_lines % size != 0)
431 if (num_pages != 1) printf "<p>%s", text
432 }
433 {
434 if (num_pages == 1) exit
435 r = NR % size
436 if (r == 1) {
437 p = int(NR / size) + 1
438 printf "<button class=\"pages%s\" name=\"page\" value=\"%s\" title=\"%s\n···\n", p==page?" current":"", p, $6
439 } else if (r == 0)
440 printf "%s\">%s</button> ", $6, int(NR / size)
441 }
442 END{
443 if (num_pages == 1) exit
444 if (r != 0) printf "%s\">%s</button>", $6, int(NR / size) + 1
445 print "</p>"
446 }' $1
447 }
450 # Show packages list by category or tag
452 show_list() {
453 PAGE_SIZE=${PAGE_SIZE:-100}
454 page=$(GET page); page=${page:-1}
455 cached=$(mktemp)
456 [ -n "$tag" ] && cat=''
457 {
458 for L in $LANG ${LANG%%_*}; do
459 if [ -e "$PKGS_DB/packages-desc.$L" ]; then
460 sed '/^#/d' $PKGS_DB/packages-desc.$L; break
461 fi
462 done
463 [ -e "$i/blocked-packages.list" ] && cat $i/blocked-packages.list
464 sed 's|.*|&\ti|' $i/installed.info
465 [ "$cat" == 'extra' ] || [ $1 == 'my' ] || cat $i/packages.info
466 [ "$cat" == 'extra' ] &&
467 sed 's,\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\).*,\1\t\5\textra\t\2\thttp://mirror.slitaz.org/packages/get/\1\t-\t-\t-\t-,' $PKGS_DB/extra.list
468 } | sort -t$'\t' -k1,1 | sed '/^$/d' | awk -F$'\t' -vc="${cat:--}" -vt="${tag:--}" '
469 {
470 if (PKG && PKG != $1) {
471 if (SEL) {
472 if (DSCL) DSC = DSCL
473 printf "<tr><td><input type=\"checkbox\" name=\"pkg\" value=\"%s\" id=\"%s\">", PKG, PKG
474 printf "<a data-icon=\"pkg%s%s\" href=\"?info=%s\">%s</a></td>", INS, BLK, gensub(/\+/, "%2B", "g", PKG), PKG
475 printf "<td>%s</td><td>%s</td><td><a href=\"%s\"></a></td></tr>\n", VER, DSC, WEB
476 }
477 VER = DSC = WEB = DSCL = INS = BLK = SEL = ""
478 }
480 PKG = $1
481 if (NF == 1) { BLK = "b"; next }
482 if (NF == 2) { DSCL = $2; next }
483 if (c == "all" || $3 == c || index(" "$6" ", " "t" ")) { SEL = 1 }
484 if (SEL) {
485 if ($10 == "i") { VER = $2; DSC = $4; WEB = $5; INS = "i"; next}
486 if (! INS) { VER = $2; DSC = $4; WEB = $5 }
487 }
488 }' > $cached
490 pager="$(pager $cached)"
491 case $PAGE_SIZE in
492 0) list="$(cat $cached)";;
493 *) list="$(tail -n+$((($page-1)*$PAGE_SIZE+1)) $cached | head -n$PAGE_SIZE)";;
494 esac
496 if [ "$pager" != "<p>$(_ 'Pages:') </p>" ] && [ -n "${list:1:1}" ]; then
497 cat <<EOT
498 <h3>$(header_repo_name $i)</h3>
499 $pager
500 $(table_head)
501 $list
502 </tbody></table>
503 $pager
504 EOT
505 fi
506 rm -f $cached
509 ### Re-select packages when you return to the page
511 # Find the packages list
512 pkgs=$(echo "$QUERY_STRING&" | awk 'BEGIN{RS="&";FS="="}
513 {if ($1=="pkg") printf "\"%s\", ", $2}')
514 pkgs=$(httpd -d "${pkgs%, }")
515 # now pkgs='"pkg1", "pkg2", ... "pkgn"'
517 if [ -n "$pkgs" ]; then
518 cat <<EOT
519 <script type="text/javascript">
520 var pkgs = [$pkgs];
521 var theForm = document.getElementById('pkglist');
522 for (index = 0; index < pkgs.length; index++) {
523 if (document.getElementById(pkgs[index])) {
524 // check existing
525 document.getElementById(pkgs[index]).checked = 'true';
526 }
527 else {
528 // add other as hidden
529 var hInput = document.createElement('input');
530 hInput.type = 'hidden';
531 hInput.name = 'pkg';
532 hInput.value = pkgs[index];
533 theForm.appendChild(hInput);
534 }
535 }
536 document.getElementById('countSelected').innerText = pkgs.length;
537 </script>
538 EOT
539 fi
540 }
543 # Show links for "info" page
545 show_info_links() {
546 if [ -n "$1" ]; then
547 if [ "$3" == 'tag' ]; then icon='tag'; else icon='clock'; fi
548 case "$4" in
549 provide) echo -n "<tr><td><b>$2</b></td><td>"; noeq=' ';;
550 '') echo -n "<tr><td><b>$2</b></td><td>"; noeq='';;
551 *) echo -n "<tr><td><b><a href=\"?suggested=${4//+/%2B}\">$2</a></b></td><td>";;
552 esac
554 echo $1 | tr ' ' $'\n' | awk -vt="$3" -vi="$icon" -vnoeq="$noeq" '{
555 printf "<span><a data-icon=\"%s\" ", i;
556 printf "href=\"?%s=%s\">%s%s</a></span>", t, gensub(/\+/, "%2B", "g", $1), $1, noeq
557 }'
558 echo "</td></tr>"
559 fi
560 }
563 tazpanel_header() {
564 xhtml_header "$1" | sed 's/id="content"/id="content-sidebar"/'
565 cat <<EOT
566 <form class="search"><!--
567 --><a data-icon="web" href="http://pkg.slitaz.org/" target="_blank" title="$(_n 'Web search tool')"></a> <!--
568 --><input type="search" name="search" value="$(GET search)" results="5" autosave="pkgsearch" autocomplete="on"><!--
569 --><button type="submit">$(_n 'Search')</button><!--
570 --><button name="files" value="yes">$(_n 'Files')</button><!--
571 --></form>
572 EOT
573 sidebar
574 }
579 #
580 # Commands
581 #
584 case " $(GET) " in
587 *\ linkable\ *)
588 #
589 # List linkable packages.
590 #
591 tazpanel_header "$(_ 'Linkable packages')"
592 loading_msg "$(_ 'Listing linkable packages...')"
594 cat <<EOT
595 <form class="wide">
596 $(_ 'Selection:') $(show_button do=Link)
597 EOT
598 table_head
599 target=$(readlink $PKGS_DB/fslink)
600 for pkg in $(ls $target/$INSTALLED); do
601 [ -s $pkg/receipt ] && continue
602 . $target/$INSTALLED/$pkg/receipt
603 i18n_desc $pkg
604 cat <<EOT
605 <tr>
606 <td><input type="checkbox" name="pkg" value="$pkg" /><a data-icon="pkg" href="?info=${pkg//+/%2B}">$pkg</a></td>
607 <td>$VERSION</td>
608 <td>$SHORT_DESC</td>
609 <td><a data-img="web" href="$WEB_SITE"></a></td>
610 </tr>
611 EOT
612 done
613 cat <<EOT
614 </tbody>
615 </table>
616 </form>
617 EOT
618 ;;
621 *\ cats\ *)
622 #
623 # List of all categories.
624 #
625 tazpanel_header "$(_ 'Categories list')"
627 for pkgsinfo in $(repo_list /packages.info); do
628 cat <<EOT
629 <section>
630 <header>$(header_repo_name $(dirname $pkgsinfo))</header>
631 <table class="wide zebra center">
632 <thead>
633 <tr>
634 <td>$(_ 'Category')</td>
635 <td>$(_ 'Available packages')</td>
636 <td>$(_ 'Installed packages')</td>
637 </tr>
638 </thead>
639 <tbody>
640 EOT
641 {
642 awk -F$'\t' '{print $3}' $pkgsinfo | sort | uniq -c
643 awk -F$'\t' '{print $3}' $PKGS_DB/installed.info | sed 's|.*|& i|' | sort | uniq -c
644 } | sort -k2,2 | awk '
645 {
646 c [$2] = "."
647 if ($3) { i[$2] = $1; } else { m[$2] = $1; }
648 }
649 END {
650 for (n in c) print n, m[n], i[n]
651 }' | sort | awk '{
652 printf "<tr><td><a href=\"?list&amp;cat=%s\">%s</a></td><td>%d</td><td>%d</td></tr>", $1, $1, $2, $3
653 }'
654 cat <<EOT
655 </tbody>
656 </table>
657 </section>
658 EOT
659 done
660 ;;
663 *\ list\ *|*\ page\ *)
664 #
665 # List all packages by category.
666 #
667 tazpanel_header "$(_ 'Packages list')"
668 loading_msg "$(_ 'Listing packages...')"
670 bcat="<b>$cat</b>"; brepo="<b>$repo</b>"
671 case $repo in
672 Any)
673 case $my in
674 my) title="$(_ 'Installed packages of category "%s"' "$bcat")" ;;
675 *) title="$(_ 'All packages of category "%s"' "$bcat")" ;;
676 esac ;;
677 *)
678 case $my in
679 my) title="$(_ 'Installed packages of category "%s" in repository "%s"' "$bcat" "$brepo")" ;;
680 *) title="$(_ 'All packages of category "%s" in repository "%s"' "$bcat" "$brepo")" ;;
681 esac ;;
682 esac
684 cat <<EOT
685 <p>$title</p>
686 EOT
688 [ ! -f $PKGS_DB/packages.info ] && msg warn \
689 "$(_ 'You can not view a list of all packages until recharging lists.')"
691 [ "$REMOTE_USER" == "root" ] && cat <<EOT
692 <section>
693 <div>$(_ 'Selected packages:') <span id="countSelected"></span></div>
694 <footer>
695 $({
696 [ "$my" != 'my' ] && show_button do=Install
697 show_button do=Chblock do=Remove
698 } | sed 's|button |button form="pkglist" |g')
699 $(show_button toggle)
700 </footer>
701 </section>
702 EOT
703 cat <<EOT
705 <form id="pkglist" class="wide">
706 EOT
707 for i in $(repo_list ""); do
708 show_list ${my#no}
709 done
710 cat <<EOT
711 </form>
712 <script type="text/javascript">window.onscroll = scrollHandler; setCountSelPkgs();</script>
713 EOT
714 ;;
717 *\ suggested\ *)
718 #
719 # List all suggested packages
720 #
721 tazpanel_header "$(_ 'Packages list')"
722 loading_msg "$(_ 'Listing packages...')"
724 pkg=$(GET suggested)
725 suggested_pkgs=$(. $INSTALLED/$pkg/receipt; echo $SUGGESTED)
726 [ -z "$suggested_pkgs" ] && xhtml_footer && exit
728 cat <<EOT
729 <p>$(_ 'Packages suggested by %s' "<b>$pkg</b>")</p>
730 EOT
732 [ "$REMOTE_USER" == "root" ] && cat <<EOT
733 <section>
734 <div>$(_ 'Selected packages:') <span id="countSelected"></span></div>
735 <footer>
736 $({
737 show_button do=Install do=Chblock do=Remove
738 } | sed 's|button |button form="pkglist" |g')
739 $(show_button toggle)
740 </footer>
741 </section>
742 EOT
744 cat <<EOT
745 <form id="pkglist" class="wide">
746 EOT
747 table_head
748 for pkg in $suggested_pkgs; do
749 grep "^$pkg"$'\t' "$PKGS_DB/packages.info" | parse_packages_info
750 done
751 cat <<EOT
752 </tbody></table>
753 </form>
754 <script type="text/javascript">window.onscroll = scrollHandler; setCountSelPkgs();</script>
755 EOT
756 ;;
759 *\ search\ *)
760 #
761 # Search for packages. Here default is to search in packages.desc
762 # and so get result including packages names and descriptions
763 #
764 tazpanel_header "$(_ 'Search packages')"
765 loading_msg "$(_ 'Searching packages...')"
767 pkg=$(GET search); [ -z "$pkg" ] && xhtml_footer && exit
768 cd $PKGS_DB
770 cat <<EOT
771 <section>
772 <div>$(_ 'Selected packages:') <span id="countSelected"></span></div>
773 <footer>
774 $(show_button do=Install do=Chblock do=Remove | sed 's|button |button form="pkglist" |g')
775 $(show_button toggle)
776 </footer>
777 </section>
779 <form id="pkglist" class="wide">
780 EOT
781 if [ -n "$(GET files)" -o -n "$(echo $pkg | grep '/')" ]; then
782 cat <<EOT
783 <table class="wide zebra filelist">
784 <thead>
785 <tr>
786 <td>$(_ 'Package')</td>
787 <td>$(_ 'File')</td>
788 </tr>
789 <thead>
790 <tbody>
791 EOT
792 lzcat $(repo_list /files.list.lzma) | grep -Ei ": .*$(GET search)" | \
793 while read PACKAGE FILE; do
794 PACKAGE=${PACKAGE%:}
795 class='pkg'
796 if [ -d $INSTALLED/$PACKAGE ]; then
797 class='pkgi'
798 grep -q "^$PACKAGE$" $PKGS_DB/blocked-packages.list && class='pkgib'
799 fi
800 cat <<EOT
801 <tr>
802 <td><input type="checkbox" name="pkg" value="$PACKAGE">$(pkg_info_link $PACKAGE $class)</td>
803 <td>$(echo "$FILE" | sed "s|$pkg|<span class=\"diff-add\">&</span>|gI")</td>
804 </tr>
805 EOT
806 done
807 else
808 table_head
809 awk -F$'\t' 'BEGIN{IGNORECASE = 1}
810 $1 " " $4 ~ /'$pkg'/{print $0}' $(repo_list /packages.info) | parse_packages_info
811 fi
812 cat <<EOT
813 </tbody>
814 </table>
815 </form>
816 <script type="text/javascript">window.onscroll = scrollHandler; setCountSelPkgs();</script>
817 EOT
818 ;;
821 *\ recharge\ *)
822 #
823 # Lets recharge the packages list
824 #
825 tazpanel_header "$(_ 'Recharge')"
826 loading_msg "$(_ 'Recharging lists...')"
828 cat <<EOT
829 <p>$(_ 'Recharge checks for new or updated packages')</p>
831 <section>
832 <header>
833 <span data-icon="sync">$(_ 'Recharging log')</span>
834 <form>$(show_button up)</form>
835 </header>
836 EOT
837 echo $(_ 'Recharging packages list') | log
838 export output="html"; tazpkg recharge
839 cat <<EOT
840 <footer>$(_ 'Packages lists are up-to-date. You should check for upgrades now.')</footer>
841 </section>
842 EOT
843 ;;
846 *\ up\ *)
847 #
848 # Upgrade packages
849 #
850 tazpanel_header "$(_ 'Up packages')"
851 loading_msg "$(_ 'Checking for upgrades...')"
853 cat <<EOT
854 <section>
855 <div>$(_ 'Selected packages:') <span id="countSelected"></span></div>
856 <footer>
857 $(show_button do=Install do=Chblock do=Remove | sed 's|button |button form="pkglist" |g')
858 $(show_button toggle)
859 </footer>
860 </section>
862 <form id="pkglist" class="wide">
863 EOT
864 # Ask tazpkg to make "packages.up" file
865 tazpkg up --check >/dev/null
866 table_head
868 for pkg in $(cat $PKGS_DB/packages.up); do
869 grep -hs "^$pkg " $PKGS_DB/packages.info $PKGS_DB/undigest/*/packages.info | parse_packages_info
870 done
872 cat <<EOT
873 </tbody>
874 </table>
875 </form>
876 <script type="text/javascript">window.onscroll = scrollHandler; setCountSelPkgs();</script>
877 EOT
878 ;;
881 *\ do\ *)
882 #
883 # Do an action on one or some packages
884 #
885 tazpanel_header "TazPkg: $(GET do)"
886 loading_msg
888 # Find the command
889 cmd=$(echo $(GET do) | tr [:upper:] [:lower:])
891 # Find the packages list
892 pkgs=$(echo $QUERY_STRING | awk 'BEGIN{RS="&";FS="="}{if($1=="pkg")print $2}')
893 pkgs=$(httpd -d "$pkgs")
895 # Describe the command
896 bpkgs="<b>$pkgs</b>"; opt=''
897 case $cmd in
898 install) MSG="$(_ 'Installing: %s' "$bpkgs")"; opt='--forced'; cmd='get-install' ;;
899 remove) MSG="$(_ 'Removing: %s' "$bpkgs")" ;;
900 link) MSG="$(_ 'Linking: %s' "$bpkgs")"; opt="$(readlink $PKGS_DB/fslink)" ;;
901 block) MSG="$(_ 'Blocking: %s' "$bpkgs")" ;;
902 unblock) MSG="$(_ 'Unblocking: %s' "$bpkgs")" ;;
903 chblock) MSG="$(_ '(Un)blocking: %s' "$bpkgs")" ;;
904 repack) MSG="$(_ 'Repacking: %s' "$bpkgs")" ;;
905 esac
907 cat <<EOT
908 <div>$MSG</div>
909 EOT
910 # Do the command for all asked packages
911 cd /tmp
912 export output='html'
914 for pkg in $pkgs; do
915 #echo $(_n 'y') |
916 tazpkg $cmd $pkg $opt 2>/dev/null | filter_taztools_msgs
917 done
918 ;;
921 *\ info\ *)
922 #
923 # Packages info
924 #
925 tazpanel_header "$(_ 'Package info')"
926 loading_msg "$(_ 'Getting package info...')"
928 pkg="$(GET info)"
930 # Package state
931 if [ -d "$INSTALLED/$pkg" ]; then
932 STATE="$(_ 'installed package')"
933 elif [ -e "$PKGS_DB/packages.info" -a \
934 -n "$(awk -F$'\t' -vp="$pkg" '$1==p{print $1}' "$PKGS_DB/packages.info")" ]; then
935 STATE="$(_ 'mirrored package')"
936 else
937 msg err "$(_ 'Package "%s" not available.' "$pkg")"
938 xhtml_footer; exit 0
939 fi
941 # Symbolic icon
942 if [ -d "$INSTALLED/$pkg" ]; then
943 if grep -q "^$pkg$" "$PKGS_DB/blocked-packages.list"
944 then icon='pkgib'
945 else icon='pkgi'
946 fi
947 else icon='pkg'
948 fi
950 cat <<EOT
951 <section>
952 <header>
953 <span data-icon="$icon">$(_ 'Package %s' "$pkg")</span>
954 <form>
955 <input type="hidden" name="pkg" value="${pkg#get-}"/>
956 EOT
958 # Get receipt variables, show Install/Remove buttons
959 if [ -d "$INSTALLED/$pkg" ]; then
960 . $INSTALLED/$pkg/receipt
961 files=$(wc -l < $INSTALLED/$pkg/files.list)
962 [ "$REMOTE_USER" == 'root' ] && show_button do=Remove
963 else
964 cd $PKGS_DB
965 eval "$(awk -F$'\t' -vp=$pkg '
966 $1==p{
967 printf "PACKAGE=\"%s\"; VERSION=\"%s\"; CATEGORY=\"%s\"; ", $1, $2, $3
968 printf "SHORT_DESC=\"%s\"; WEB_SITE=\"%s\"; TAGS=\"%s\"; ", $4, $5, $6
969 printf "SIZES=\"%s\"; DEPENDS=\"%s\"", $7, $8
970 }' packages.info undigest/*/packages.info)"
971 if [ -z "$PACKAGE" ]; then
972 eval "$(awk -F'|' -vp=$pkg '
973 $1==p{
974 printf "PACKAGE=\"%s\"; SHORT_DESC=\"%s\"; WEB_SITE=\"%s\"; ", $1, $2, $3
975 printf "CATEGORY=\"%s\"; VERSION=\"%s\"; LICENSE=\"%s\"; ", $4, $5, $6
976 }' extra.list undigest/*/extra.list)"
977 [ -z "$CATEGORY" ] && CATEGORY='non-free'
978 fi
979 PACKED_SIZE=${SIZES% *}
980 UNPACKED_SIZE=${SIZES#* }
981 [ "$REMOTE_USER" == 'root' ] &&
982 if [ "${pkg#get-}" != "$pkg" ]; then
983 show_button 'do=Install&amp;nf'
984 else
985 show_button do=Install
986 fi
987 fi
989 # Show Block/Unblock, and Repack buttons
990 [ "$REMOTE_USER" == "root" ] &&
991 if [ -d $INSTALLED/$pkg ]; then
992 if grep -qs "^$pkg$" $PKGS_DB/blocked-packages.list; then
993 show_button do=Unblock
994 else
995 show_button do=Block
996 fi
997 show_button do=Repack
998 fi
1000 # Translate short description
1001 i18n_desc $pkg
1003 # Show info table
1004 cat <<EOT
1005 </form>
1006 </header>
1008 <table class="wide zebra summary" id="infoTable">
1009 <tbody>
1010 <tr><td><b>$(_ 'Name')</b></td><td>$PACKAGE
1011 <div id="appImg"><img src="pkgs.cgi?app_img=$PACKAGE"/></div>
1012 </td></tr>
1014 <tr><td><b>$(_ 'State')</b></td><td>$STATE</td></tr>
1016 $([ -n "$VERSION" ] && echo "<tr><td><b>$(_ 'Version')</b></td><td>$VERSION</td></tr>")
1018 <tr><td><b>$(_ 'Category')</b></td><td><a href="?list&amp;cat=$CATEGORY">$CATEGORY</a></td></tr>
1020 <tr><td><b>$(_ 'Description')</b></td><td>$SHORT_DESC</td></tr>
1022 $([ -n "$MAINTAINER" ] && echo "<tr><td><b>$(_ 'Maintainer')</b></td><td>$MAINTAINER</td></tr>")
1024 $([ -n "$LICENSE" ] && echo "<tr><td><b>$(_ 'License')</b></td><td><a href=\"?license=$pkg\">$LICENSE</a></td></tr>")
1026 <tr><td><b>$(_ 'Website')</b></td><td><a href="$WEB_SITE" target="_blank">$WEB_SITE</a></td></tr>
1028 $(show_info_links "$TAGS" "$(_ 'Tags')" 'tag')
1030 $([ -n "$PACKED_SIZE" ] && echo "<tr><td><b>$(_ 'Sizes')</b></td><td>${PACKED_SIZE/.0/}/${UNPACKED_SIZE/.0/}</td></tr>")
1032 $(show_info_links "$DEPENDS" "$(_ 'Depends')" 'info')
1034 $(show_info_links "$PROVIDE" "$(_ 'Provide')" 'info' 'provide')
1036 $(show_info_links "$SUGGESTED" "$(_ 'Suggested')" 'info' "$PACKAGE")
1037 </tbody>
1038 </table>
1040 <footer>
1041 <a data-icon="text" href="?show_receipt=$pkg">$(_ 'View receipt')</a>
1042 <a data-icon="slitaz" href="?improve=$pkg">$(_ 'Improve package')</a>
1043 </footer>
1044 </section>
1046 EOT
1048 # Show description
1049 DESC="$(tazpkg desc $pkg)"
1050 [ -n "$DESC" ] && echo "<section><pre class=\"pre-wrap\">$DESC</pre></section>"
1052 # Show configuration files list
1053 CONFIGS="$(tazpkg list-config $pkg | sed 's|\(.*\)|\1 \1|')"
1054 [ -n "$CONFIGS" ] && cat <<EOT
1055 <section>
1056 <header>$(_ 'Configuration files')</header>
1057 <pre>$(printf '<a href="index.cgi?file=%s">%s</a>\n' $CONFIGS)</pre>
1058 </section>
1059 EOT
1061 # Show installed files list
1062 pkg=${pkg//+/%2B}
1063 cat <<EOT
1064 <section>
1065 <header>$(_ 'Installed files')</header>
1066 <span id="fileList">
1067 <div style="text-align: center;"><span data-icon="clock">$(_ 'Please wait')</span></div>
1068 </span>
1069 </section>
1072 <script type="text/javascript">
1073 var links = document.getElementById('infoTable').getElementsByTagName('a');
1074 for (var i = 0; i < links.length; i++) {
1075 console.log('i=%s, icon=%s.', i, links[i].dataset.icon);
1076 if (links[i].dataset.icon == 'clock') {
1077 links[i].parentNode.id = 'link' + i;
1078 pkg = links[i].innerText.replace(/\+/g, '%2B');
1079 ajax('?status&pkg=' + pkg, '1', 'link' + i);
1083 ajax('pkgs.cgi?filelist&pkg=$pkg', '1', 'fileList');
1084 </script>
1085 EOT
1086 ;;
1089 *\ admin\ * )
1091 # TazPkg configuration page
1093 tazpanel_header "$(_ 'Administration')"
1094 loading_msg
1096 cmd=$(GET admin)
1097 pager="$(GET pager)"; pager=${pager:-$PAGE_SIZE}; pager=${pager:-100}
1098 mirror="$(GET mirror)"; mirror="${mirror%/}/"
1099 repository="$PKGS_DB/undigest/$(GET repository)"
1100 link="$(GET link)"; link=${link%/}
1102 case "$cmd" in
1103 clean)
1104 rm -rf $CACHE_DIR/* ;;
1105 add-mirror)
1106 echo "$mirror" >> $(GET file) ;;
1107 rm-mirror)
1108 sed -i "/^"$(echo $mirror | sed 's|/|\\/|g')"$/d" $(GET file) ;;
1109 select-mirror)
1110 tazpkg setup-mirror "${mirror}packages/$(cat /etc/slitaz-release)/" | log ;;
1111 add-repo)
1112 mkdir -p $repository
1113 echo "$mirror" > $repository/mirror
1114 echo "$mirror" > $repository/mirrors ;;
1115 rm-repo)
1116 rm -rf $repository ;;
1117 setlink)
1118 [ -d "$link/$INSTALLED" ] && ln -fs $link $PKGS_DB/fslink ;;
1119 removelink)
1120 rm -f $PKGS_DB/fslink ;;
1121 pager)
1122 TP_CONF=/etc/slitaz/tazpanel.conf
1123 if [ -z "$PAGE_SIZE" ]; then
1124 echo -e "\n# Size of packages list page\nPAGE_SIZE=\"$pager\"" >> $TP_CONF
1125 else
1126 sed -i "s|PAGE_SIZE=.*|PAGE_SIZE=\"$pager\"|" $TP_CONF
1127 fi ;;
1128 esac
1130 cat <<EOT
1131 <p>$(_ 'TazPkg administration and settings')</p>
1133 <form id="actions">
1134 <input type="hidden" name="admin"/>
1135 $(show_button action=saveconf action=listconf action=quickcheck action=fullcheck)
1136 </form>
1137 EOT
1138 case "$(GET action)" in
1139 saveconf)
1140 loading_msg "$(_ 'Creating the package...')"
1141 echo "<pre>"
1142 cd /tmp
1143 tazpkg repack-config | filter_taztools_msgs
1144 echo -n "$(_ 'Path:') "; ls /tmp/config-*.tazpkg
1145 echo "</pre>" ;;
1146 listconf)
1147 echo "<h4>$(_ 'Configuration files')</h4>"
1148 echo "<ul>"
1149 tazpkg list-config | while read file; do
1150 if [ -e $file ]; then
1151 echo "<li><a href=\"index.cgi?file=$file\">$file</a></li>"
1152 else
1153 echo "<li>$file</li>"
1154 fi
1155 done
1156 echo "</ul>" ;;
1157 quickcheck)
1158 loading_msg "$(_ 'Checking packages consistency...')"
1159 tazpkg check
1160 ;;
1161 fullcheck)
1162 loading_msg "$(_ 'Full packages check...')"
1163 tazpkg check --full
1164 ;;
1165 dvdimage)
1166 dev=$(POST dvdimage)
1167 mkdir -p /mnt/packages 2> /dev/null
1168 echo "<pre>"
1169 mount -t iso9660 -o loop,ro $dev /mnt/packages &&
1170 /mnt/packages/install.sh &&
1171 _ '%s is installed on /mnt/packages' $dev
1172 echo "</pre>" ;;
1173 dvdusbkey)
1174 mkdir -p /mnt/packages 2> /dev/null
1175 for tag in "LABEL=\"packages-$version\" TYPE=\"iso9660\"" \
1176 "LABEL=\"sources-$version\" TYPE=\"iso9660\"" ; do
1177 dev=$(blkid | grep "$tag" | cut -d: -f1)
1178 [ -n "$dev" ] || continue
1179 echo "<pre>"
1180 mount -t iso9660 -o ro $dev /mnt/packages &&
1181 /mnt/packages/install.sh &&
1182 _ '%s is installed on /mnt/packages' $dev
1183 echo "</pre>"
1184 break
1185 done ;;
1186 esac
1188 cache_files=$(find $CACHE_DIR -name '*.tazpkg' | wc -l)
1189 cache_size=$(du -sh $CACHE_DIR | cut -f1 | sed 's|\.0||')
1190 [ "$cache_files" == 0 ] && cache_size="0K"
1191 mirror=$(cat $PKGS_DB/mirror)
1192 default_mirror=${mirror%/packages/*}
1193 cat <<EOT
1194 <section>
1195 <header>$(_ 'Packages cache')</header>
1196 <form class="wide">
1197 <div>$(_ 'Packages in the cache: %s (%s)' $cache_files $cache_size)</div>
1198 <footer>$(show_button admin=clean)</footer>
1199 </form>
1200 </section>
1203 <section>
1204 <header>$(_ 'Current mirror list')</header>
1205 EOT
1207 # List mirrors
1208 version=$(cat /etc/slitaz-release)
1209 for i in $PKGS_DB/mirrors $PKGS_DB/undigest/*/mirrors; do
1210 [ -s $i ] || continue
1211 if [ $i != $PKGS_DB/mirrors ]; then
1212 echo "<h4>$(_ 'Repository: %s' "$(repo_name $(dirname $i))")</h4>"
1213 fi
1214 cat <<EOT
1215 <form class="wide">
1216 <input type="hidden" name="admin" value="select-mirror"/>
1217 <table class="wide zebra">
1218 EOT
1219 while read line; do
1220 cat <<EOT
1221 <tr>
1222 <td>
1223 <input type="radio" name="mirror" id="$line" value="$line" onchange="this.form.submit()"
1224 $([ "$line" == "$default_mirror/" ] && echo -n 'checked="checked"')>
1225 <label for="$line"><code>$line</code></label></td>
1226 <td><a data-img="web" href="$line" target="_blank"></a></td>
1227 <td><a data-img="remove" href="?admin=rm-mirror&amp;mirror=$line&amp;file=$i" title="$(_ 'Delete')"></a></td>
1228 </tr>
1229 EOT
1230 done < $i
1231 cat <<EOT
1232 </table>
1233 </form>
1235 <form class="wide">
1236 <footer>
1237 <input type="hidden" name="file" value="$i" />
1238 <input type="text" name="mirror" size="40" />
1239 $(show_button admin=add-mirror)
1240 </footer>
1241 </form>
1242 EOT
1243 done
1244 cat <<EOT
1245 </section>
1248 <section>
1249 <header>$(_ 'Private repositories')</header>
1250 EOT
1251 if [ -n "$(ls $PKGS_DB/undigest 2> /dev/null)" ]; then
1252 cat <<EOT
1253 <table class="wide zebra">
1254 EOT
1255 ls $PKGS_DB/undigest 2> /dev/null | while read repo ; do
1256 cat <<EOT
1257 <tr>
1258 <td><code>$repo</code></td>
1259 <td><a data-img="remove" href="?admin=rm-repo&amp;repository=$repo" title="$(_ 'Delete')"></a></td>
1260 </tr>
1261 EOT
1262 done
1263 cat <<EOT
1264 </table>
1265 EOT
1266 fi
1268 cat <<EOT
1269 <form class="wide">
1270 <table>
1271 <tr><td>$(_ 'Name')</td><td><input type="text" name="repository" size="10"/></td></tr>
1272 <tr><td>$(_ 'URL:')</td><td><input type="text" name="mirror" value="http://"></td></tr>
1273 </table>
1274 <footer>
1275 $(show_button admin=add-repo)
1276 </footer>
1277 </form>
1278 </section>
1281 <section>
1282 <header>$(_ 'Link to another SliTaz installation')</header>
1283 <form class="wide">
1284 <div>
1285 $(_ "This link points to the root of another SliTaz installation. You will be able to install packages using soft links to it.")
1286 </div>
1287 <input type="text" name="link" value="$(readlink $PKGS_DB/fslink 2> /dev/null)"/>
1288 <footer>
1289 $(show_button admin=setlink admin=removelink)
1290 </footer>
1291 </form>
1292 </section>
1295 <section>
1296 <header id="dvd">$(_ 'SliTaz packages DVD')</header>
1298 <div>
1299 $(_ "A bootable DVD image of all available packages for the %s version is generated every day. It also contains a copy of the website and can be used without an internet connection. This image can be installed on a DVD or a USB key." $version)
1301 <form method="post" action='?admin&amp;action=dvdimage'>
1302 $(_ 'Install from ISO image:')
1303 <input type="text" name="dvdimage" size="40" value="/root/packages-$version.iso" />
1304 </form>
1305 </div>
1307 <footer>
1308 <button data-icon="download" onclick='http://mirror.slitaz.org/iso/$version/packages-$version.iso'>
1309 $(_ 'Download DVD image')</button>
1310 <button data-icon="link" onclick='?admin&amp;action=dvdusbkey'>
1311 $(_ 'Install from DVD/USB key')</button>
1312 </footer>
1313 </section>
1316 <section>
1317 <header>$(_ 'Packages list')</header>
1318 <form class="wide">
1319 <div>
1320 $(_ 'Long list of packages is paginated. Here you can set the page size (default: 100, turning off the pager: 0).')
1321 </div>
1322 <input type="hidden" name="admin" value="pager"/>
1323 <input type="number" name="pager" value="$pager" min="0" step="10" size="4"/>
1324 <footer>
1325 <button data-icon="ok" type="submit">$(_ 'Set')</button>
1326 </footer>
1327 </form>
1328 </section>
1329 EOT
1330 ;;
1333 *\ license\ *)
1335 # Show licenses for installed packages
1337 tazpanel_header "$(_ 'Administration')"
1339 pkg=$(GET license)
1340 case $pkg in
1341 /*) [ -e $pkg ] && {
1342 echo "<h2>${pkg#/usr/share/licenses/}</h2>"
1343 case $pkg in
1344 *.htm*) cat $pkg ;;
1345 *) echo "<pre style=\"white-space: pre-wrap\">"
1346 cat $pkg | htmlize | sed 's|\([hf]t*t*ps*://[a-zA-Z0-9./_-]*[a-zA-Z0-9/_-]\)|<a href="\1">\1</a>|'
1347 echo "</pre>"
1348 ;;
1349 esac
1350 } ;;
1351 *) echo "<h2>$(_ 'Licenses for package %s' $pkg)</h2>"
1352 OFFLINE=''
1353 if [ -e "$PKGS_DB/installed/$pkg" ]; then
1354 for lic in $(grep /usr/share/licenses/ $PKGS_DB/installed/$pkg/files.list); do
1355 OFFLINE="$OFFLINE <li><a href=\"?license=$lic\">licenses/<b>${lic#/usr/share/licenses/}</b></a></li>\n"
1356 done
1357 echo "\
1358 Apache|Apache-2.0||||http://www.apache.org/licenses/#Artistic|Artistic-2.0||||#\
1359 BSD|BSD-2-Clause||||#BSD3|BSD-3-Clause||||#CC-BY-SA||by-sa/4.0/|||#\
1360 CC-SA||by-sa/4.0/|||#CC-BY-ND||by-nd/4.0/|||#CC-BY-NC-SA||by-nc-sa/4.0/|||#\
1361 CC-BY-NC-ND||by-nc-nd/4.0/|||#CC-BY-NC||by-nc/4.0/|||#CC-BY||by/4.0/|||#\
1362 cc-pd|||||http://creativecommons.org/publicdomain/#CDDL|CDDL-1.0||||#\
1363 CECILL|CECILL-2.1||||#Eclipse|EPL-1.0||||#EPL|EPL-1.0||||#FDL|||fdl||#\
1364 GPL|gpl-license||gpl|gpl.txt|#GPL2|GPL-2.0||old-licenses/gpl-2.0||#\
1365 GPL3|GPL-3.0||gpl|gpl.txt|#ISC|ISC||||#LGPL|lgpl-license||lgpl||#\
1366 LGPL2|||old-licenses/lgpl-2.0||#\
1367 LGPL2.1|LGPL-2.1||old-licenses/lgpl-2.1|lgpl.txt|#LGPL3|LGPL-3.0||lgpl||#\
1368 LPPL|LPPL-1.3c||||#MIT|MIT|||mit.txt|#MPL|MPL-2.0|||mozilla.txt|#\
1369 MPL2|MPL-2.0||||#PublicDomain|||||http://creativecommons.org/publicdomain/#\
1370 QPL|QPL-1.0||||#SIL_OFL|OFL-1.1||||#OFL|OFL-1.1||||#zlib/libpng|Zlib||||" | \
1371 awk -vlicenses="$(. $PKGS_DB/installed/$pkg/receipt; echo "$LICENSE")" \
1372 -vtext="$(_ '%s license on %s website' %s %s)" \
1373 -vro="$(_ 'Read online:')" -vrl="$(_ 'Read local:')" \
1374 -vofflic="$OFFLINE" '
1375 BEGIN{ FS="|"; RS="#"; split(licenses, lic, " "); if (offlic) OFFLINE[0]=offlic }
1376 function link1(u, l, ll, w) {
1377 return sprintf("\t<li><a href=\"%s%s\">" text "</a></li>", u, l, "<b>" ll "</b>", w) }
1378 function link2(u, l, ll) {
1379 return sprintf("\t<li><a href=\"%s%s\">%s</b></a></li>", u, l, ll) }
1380 function link_osl(n) {
1381 return link1("http://opensource.org/licenses/", n, n, "OSL") }
1382 function link_cc(n) {
1383 split(n, ll, "/")
1384 return link1("http://creativecommons.org/licenses/", n, ll[1], "Creative Commons") }
1385 function link_gnu(n) {
1386 split(n, ll, "/")
1387 return link1("https://www.gnu.org/licenses/", n ".html", ll[2] ? ll[2] : ll[1], "GNU") }
1388 function link_loc(n) {
1389 return link2("?license=/usr/share/licenses/", n, "licenses/<b>" n "</b>") }
1390 function link_url(n) {
1391 return link2(n, "", n) }
1393 if ($1 == lic[1] || $1 == lic[2] || $1 == lic[3] || $1 == lic[4]) {
1394 if ($2) ONLINE[$2]=link_osl($2)
1395 if ($3) ONLINE[$3]=link_cc($3)
1396 if ($4) ONLINE[$4]=link_gnu($4)
1397 if ($5) OFFLINE[$5]=link_loc($5)
1398 if ($6) OFFLINE[$6]=link_url($6)
1401 END{
1402 if (length(ONLINE) > 0) { print "<p>" ro "</p>\n<ul>"; for (o in ONLINE) print ONLINE[o]; print "</ul>" }
1403 if (length(OFFLINE) > 0) { print "<p>" rl "</p>\n<ul>"; for (o in OFFLINE) print OFFLINE[o]; print "</ul>" }
1404 }'
1405 fi ;;
1406 esac
1407 ;;
1410 *\ tags\ *)
1412 # Show tag cloud
1414 tazpanel_header "$(_ 'Tags list')"
1416 brepo="<b>$repo</b>"
1417 case $repo in
1418 Any) title="$(_ 'List of tags in all repositories')" ;;
1419 *) title="$(_ 'List of tags in repository "%s"' "$brepo")" ;;
1420 esac
1421 echo "<p>$title</p><p id=\"tags\">"
1422 to_read=''
1423 for i in $(repo_list ''); do
1424 if [ -e "$i/packages.info" ]; then
1425 to_read="$to_read $i/packages.info"
1426 elif [ -e "$i/installed.info" ]; then
1427 to_read="$to_read $i/installed.info"
1428 fi
1429 done
1431 TAGS="$(awk -F$'\t' '{if($6){print $6}}' $to_read | tr ' ' $'\n' | sort | uniq -c)"
1432 MAX="$(echo "$TAGS" | awk '{if ($1 > MAX) MAX = $1} END{print MAX}')"
1433 echo "$TAGS" | awk -vMAX="$MAX" '{
1434 printf "<a class=\"tag%s\" href=\"?tag=%s\" title=\"%s\">%s</a> ", int($1 * 7 / MAX + 1), $2, $1, $2
1435 }'
1436 echo "</p>"
1437 ;;
1440 *\ tag\ *)
1442 # Show packages with matching tag
1444 tag=$(GET tag)
1445 tazpanel_header "$(_ 'Tag "%s"' $tag)"
1447 [ "$REMOTE_USER" == 'root' ] && cat <<EOT
1448 <section>
1449 <div>$(_ 'Selected packages:') <span id="countSelected"></span></div>
1450 <footer>
1451 $(show_button do=Install do=Chblock do=Remove | sed 's|button |button form="pkglist" |g')
1452 $(show_button toggle)
1453 </footer>
1454 </section>
1455 EOT
1456 cat <<EOT
1457 <form id="pkglist" class="wide">
1458 EOT
1459 for i in $(repo_list ""); do
1460 show_list all
1461 done
1462 cat <<EOT
1463 </form>
1464 <script type="text/javascript">window.onscroll = scrollHandler; setCountSelPkgs();</script>
1465 EOT
1466 ;;
1469 *\ blocked\ *)
1471 # Show blocked packages list
1473 tazpanel_header "$(_ 'Blocked packages list')"
1475 cat <<EOT
1476 <section>
1477 <div>$(_ 'Selected packages:') <span id="countSelected"></span></div>
1478 <footer>
1479 $(show_button do=Unblock | sed 's|button |button form="pkglist" |g')
1480 $(show_button toggle)
1481 </footer>
1482 </section>
1484 <form id="pkglist" class="wide">
1485 EOT
1486 table_head
1487 for i in $(cat $PKGS_DB/blocked-packages.list); do
1488 awk -F$'\t' -vp="$i" '{
1489 if ($1 == p)
1490 printf "<tr><td><input type=\"checkbox\" name=\"pkg\" value=\"%s\"><a data-icon=\"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
1491 }' $PKGS_DB/installed.info
1492 done
1493 cat <<EOT
1494 </tbody>
1495 </table>
1496 </form>
1497 <script type="text/javascript">window.onscroll = scrollHandler; setCountSelPkgs();</script>
1498 EOT
1499 ;;
1502 *\ improve\ *)
1504 # Improving packages by the community effort
1506 pkg=$(GET improve)
1507 tazpanel_header "$(_ 'Improve package "%s"' $pkg)"
1509 msg warn 'Under construction!<br/>It is only imitation of working'
1511 user=$(POST user); type=$(POST type); text="$(POST text)"
1512 login=$(POST login); password=$(POST password)
1514 login_c=$(COOKIE login); password_c=$(COOKIE password)
1515 mail_hash=$(COOKIE mail_hash); user_name=$(COOKIE user_name)
1517 n=$'\n'
1519 if [ -n "$login" ]; then
1520 # Get mail hash and user Name from bugs.slitaz.org
1521 page="$(busybox wget --post-data "auth=${login}&pass=${password}&id=" \
1522 -O- "http://bugs.slitaz.org/bugs.cgi?user=${login}")"
1523 # Parse page and get:
1524 mail_hash="$(echo "$page" | fgrep '<h2>' | cut -d/ -f5 | cut -c 1-32)"
1525 user_name="$(echo "$page" | fgrep '<h2>' | cut -d'>' -f3 | cut -d'<' -f1)"
1527 # Put variables to the session Cookies (they clean in browser close)
1528 cat <<EOT
1529 <script type="text/javascript">
1530 document.cookie = "login=$login";
1531 document.cookie = "password=$password";
1532 document.cookie = "mail_hash=$mail_hash";
1533 document.cookie = "user_name=$user_name";
1534 </script>
1535 EOT
1536 login_c="$login"; password_c="$password"
1537 fi
1539 if [ -z "$login_c" ]; then
1540 cat <<EOT
1541 <section>
1542 <div>$(_ 'Please log in using your TazBug account.')</div>
1543 <form method="post">
1544 <input type="hidden" name="improve" value="$pkg"/>
1545 <table>
1546 <tr><td>$(_ 'Login:')</td>
1547 <td><input type="text" name="login"/></td></tr>
1548 <tr><td>$(_ 'Password:')</td>
1549 <td><input type="password" name="password"/></td></tr>
1550 <tr><td colspan="2">
1551 <label><input type="checkbox" name="rememberme"/>$(_ 'Remember me')</label></td></tr>
1552 <tr><td colspan="2">
1553 <button type="submit" data-icon="user">$(_ 'Log in')</button></td></tr>
1554 </table>
1555 </form>
1556 <footer>
1557 <a href="http://bugs.slitaz.org/bugs.cgi?signup&online" target="_blank">$(_ 'Create new account')</a>
1558 </footer>
1559 </section>
1560 EOT
1561 xhtml_footer; exit 0
1562 fi
1565 # Get receipt variables, show Install/Remove buttons
1566 if [ -d $INSTALLED/$pkg ]; then
1567 . $INSTALLED/$pkg/receipt
1568 else
1569 cd $PKGS_DB
1570 eval "$(awk -F$'\t' -vp=$pkg '
1571 $1==p{
1572 printf "VERSION=\"%s\"; SHORT_DESC=\"%s\"; TAGS=\"%s\"; ", $2, $4, $6
1573 }' packages.info undigest/*/packages.info)"
1574 fi
1576 RECEIPT="$(wget -O - http://hg.slitaz.org/wok/raw-file/tip/$pkg/receipt | htmlize)"
1577 DESCRIPTION="$(wget -O - http://hg.slitaz.org/wok/raw-file/tip/$pkg/description.txt | htmlize)"
1578 DESCRIPTION="$(separator)$n${DESCRIPTION:-(empty)}$n$(separator)"
1580 if [ -z "$type" ]; then
1581 cat <<EOT
1582 <section>
1583 <header>
1584 $(_ 'Improve package "%s"' $pkg)
1585 <form><button name="info" value="$pkg" data-icon="back">$(_ 'Back')</button></form>
1586 </header>
1588 <div style="display:none">
1589 <span id="newVersion">Current version: $VERSION${n}New version: $VERSION${n}Link to announce: http://</span>
1590 <span id="improveShortDesc">Short description (English):$n$SHORT_DESC</span>
1591 <span id="translateShortDesc">Short description (English):$n$SHORT_DESC$n${n}Language: $LANG${n}Short description:$n$SHORT_DESC</span>
1592 <span id="improveDesc">Description (English):$n$DESCRIPTION</span>
1593 <span id="translateDesc">Language: $LANG${n}Description:$n$DESCRIPTION</span>
1594 <span id="improveCategory">Old category: $CATEGORY${n}New category: $CATEGORY</span>
1595 <span id="improveTags">Tags: $TAGS</span>
1596 <span id="addIcon">Link to application icon (48x48px): http://</span>
1597 <span id="addScreenshot">Link to application screenshot: http://</span>
1598 <span id="improveReceipt">$RECEIPT</span>
1599 <span id="improveOther"></span>
1600 </div>
1602 <form method="post" class="wide">
1604 <table class="wide">
1605 <tr><td style="vertical-align:bottom">
1606 <input type="hidden" name="improve" value="$pkg"/>
1607 <input type="hidden" name="user" value="$login_c"/>
1608 &nbsp;$(_ 'How can you help:')<br/>
1609 <select name='type' id="improveType" onchange="improveAction()">
1610 <option value=''>$(_ 'Please select an action')
1611 <option value='newVersion'>$(_ 'Report new version')
1612 <option value='improveShortDesc'>$(_ 'Improve short description')
1613 <option value='translateShortDesc'>$(_ 'Translate short description')
1614 <option value='improveDesc'>$(_ 'Add or improve description')
1615 <option value='translateDesc'>$(_ 'Translate description')
1616 <option value='improveCategory'>$(_ 'Improve category')
1617 <option value='improveTags'>$(_ 'Add or improve tags')
1618 <option value='addIcon'>$(_ 'Add application icon')
1619 <option value='addScreenshot'>$(_ 'Add application screenshot')
1620 <option value='improveReceipt'>$(_ 'Improve receipt')
1621 <option value='improveOther'>$(_ 'Other')
1622 </select>
1623 </td>
1624 <td id="user_info">$user_name
1625 <img src="http://www.gravatar.com/avatar/$mail_hash?s=48&amp;d=identicon"
1626 style="border-radius: 0.3rem"/>
1627 </td></tr>
1628 </table>
1630 <textarea name="text" id="improveText" style="width:100%; resize: vertical; min-height:10rem"></textarea>
1631 <footer>
1632 <button type="submit" data-icon="slitaz">$(_ 'Send')</button>
1633 </footer>
1634 </form>
1635 </section>
1636 EOT
1637 else
1638 cat <<EOT
1639 <section>
1640 <header>
1641 $(_ 'Thank you!')
1642 <form><button name="info" value="$pkg" data-icon="back">$(_ 'Back')</button></form>
1643 </header>
1644 <div>The following information was sent to SliTaz developers:</div>
1645 <pre class="scroll"><b>User:</b> $user
1646 <b>Type:</b> $type
1647 <b>Package:</b> $pkg
1648 <b>Message:</b>
1649 $(echo "$text" | htmlize)</pre>
1650 </section>
1651 EOT
1652 fi
1653 ;;
1656 *)
1658 # Default to summary
1660 tazpanel_header
1661 loading_msg
1663 cat <<EOT
1664 <form>
1665 EOT
1666 fslink=$(readlink $PKGS_DB/fslink)
1667 [ -n "$fslink" -a -d "$fslink/$INSTALLED" ] && show_button linkable
1668 show_button recharge up admin
1669 cat <<EOT
1670 </form>
1672 <section>
1673 <header>$(_ 'Summary')</header>
1675 <table class="wide zebra">
1676 <tr>
1677 <td>$(_ 'Last recharge:')</td>
1678 <td>$(list=$PKGS_DB/ID
1679 if [ -e $list ]; then
1680 # Timezone offset as string, ex. '+0200' for EET (+2 hours)
1681 ohhmm="$(date +%z)"
1682 # Timezone offset in the seconds
1683 offset=$(( 60 * (60 * ${ohhmm:0:3} + ${ohhmm:3:2}) ))
1684 daynow=$(( ($(date +%s) + $offset) / 86400 ))
1685 dayupd=$(( ($(date -r $list +%s) + $offset) / 86400 ))
1686 days=$(( $daynow - $dayupd ))
1687 time=$(date -r $list +%R)
1688 ago="$(_p '%d day ago.' '%d days ago.' $days $days)"
1689 case $days in
1690 0) _ 'Today at %s.' $time;;
1691 1) _ 'Yesterday at %s.' $time;;
1692 [2-9]) echo $ago;;
1693 *) echo "<span style='color:red'>$ago</span>"
1694 _ 'It is recommended to [recharge] the lists.' | \
1695 sed 's|\[|<a data-icon="refresh" href="?recharge">|;s|\]|</a>|';;
1696 esac
1697 else
1698 _ 'never.'
1699 _ 'You need to [download] the lists for further work.' | \
1700 sed 's|\[|<a data-icon="download" href="?recharge" data-root>|;s|\]|</a>|'
1701 fi)</td></tr>
1702 <tr>
1703 <td>$(_ 'Installed packages:')</td>
1704 <td><a href="?list&amp;my=my&amp;cat=all&amp;repo=Any">
1705 <b>$(cat $PKGS_DB/installed.info | wc -l)</b>
1706 </a></td></tr>
1707 <tr>
1708 <td>$(_ 'Mirrored packages:')</td>
1709 <td><a href="?list&amp;my=no&amp;cat=all&amp;repo=Any">
1710 <b>$(cat $PKGS_DB/packages.list | wc -l)</b>
1711 </a></td></tr>
1712 <tr>
1713 <td>$(_ 'Upgradeable packages:')</td>
1714 <td><a href="?up">
1715 <b>$(cat $PKGS_DB/packages.up | wc -l)</b>
1716 </a></td></tr>
1717 <tr>
1718 <td>$(_ 'Installed files:')</td>
1719 <td><b>$(cat $INSTALLED/*/files.list | wc -l)</b></td></tr>
1720 <tr>
1721 <td>$(_ 'Blocked packages:')</td>
1722 <td><a href="?blocked">
1723 <b>$(cat $PKGS_DB/blocked-packages.list | wc -l)</b>
1724 </a></td></tr>
1725 </table>
1726 </section>
1729 <section>
1730 <header>
1731 $(_ 'Latest log entries')
1732 <form action="index.cgi">
1733 <button name="file" value="$LOG" data-icon="view">$(_ 'Show')</button>
1734 </form>
1735 </header>
1736 <pre>$(tail -n 5 $LOG | tac | fgrep "-" | awk '{print $1, $2, $3, $4, $5, "<a href=\"?info=" $6 "\">" $6 "</a>", $7}')</pre>
1737 </section>
1738 EOT
1739 ;;
1740 esac
1742 # xHTML 5 footer
1743 xhtml_footer
1744 exit 0