tazpkg view tazpanel/pkgs.cgi @ rev 886

Change icons presentation in code - free to use anywhere, simplify icons substitution, minify html, misc
author Aleksej Bobylev <al.bobylev@gmail.com>
date Thu Dec 10 04:08:41 2015 +0200 (2015-12-10)
parents 48af4b236d99
children 1c61f2488440
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
16 export BLOCKED="$PKGS_DB/blocked-packages.list" TEXTDOMAIN='tazpkg' output=html
18 get_config
20 _() { local T="$1"; shift; printf "$(gettext "$T")" "$@"; echo; }
21 _n() { local T="$1"; shift; printf "$(gettext "$T")" "$@"; }
22 _p() {
23 local S="$1" P="$2" N="$3"; shift 3;
24 printf "$(ngettext "$S" "$P" "$N")" "$@"; }
27 #------
28 # menu
29 #------
31 case "$1" in
32 menu)
33 TEXTDOMAIN_original=$TEXTDOMAIN
34 export TEXTDOMAIN='tazpkg'
36 cat <<EOT
37 <li tabindex="0">
38 <span>$(gettext 'Packages')</span>
39 <menu>
40 <li><a data-icon="@info@" href="pkgs.cgi">$(gettext 'Summary')</a></li>
41 <li><a data-icon="@list@" href="pkgs.cgi?list&amp;my=my&amp;cat=all&amp;repo=Any">$(gettext 'My packages')</a></li>
42 <li><a data-icon="@refresh@" href="pkgs.cgi?recharge" data-root>$(gettext 'Recharge list')</a></li>
43 <li><a data-icon="@upgrade@" href="pkgs.cgi?up" data-root>$(gettext 'Check updates')</a></li>
44 <li><a data-icon="@admin@" href="pkgs.cgi?admin" data-root>$(gettext 'Administration')</a></li>
45 </menu>
46 </li>
47 EOT
48 export TEXTDOMAIN=$TEXTDOMAIN_original
49 exit
50 esac
54 #
55 # AJAX commands
56 #
58 case " $(GET) " in
61 *\ filelist\ * )
62 # Show installed files list
63 pkg=$(GET pkg)
64 cd "$PKGS_DB"
66 header
67 echo -n '<pre>'
68 if [ -f "$INSTALLED/$pkg/files.list" ]; then
69 files=$(wc -l < "$INSTALLED/$pkg/files.list")
70 sort "$INSTALLED/$pkg/files.list"
71 echo -n '</pre><footer>'
72 _p '%s file' '%s files' "$files" "$files"
73 echo '</footer>'
74 else
75 lzcat files.list.lzma undigest/*/files.list.lzma 2>/dev/null | \
76 awk -vp="$pkg:" '$1==p{print $2}' | sort
77 echo '</pre>'
78 fi
79 exit 0 ;;
82 *\ status\ * )
83 # Show package status
85 # Space at end is flag -> do not check equivalents
86 pkg=$(GET pkg | tr -d ' ')
87 orig_pkg=''
88 data_icon="@pkgi@"
89 responce='i'
91 if ! grep -q "^$pkg"$'\t' "$PKGS_DB/installed.info"; then
92 # Package not installed
93 data_icon="@pkg@"; responce='n'
94 equivs=$(grep "^$pkg=" "$PKGS_DB/packages.equiv")
95 if [ "$(GET pkg)" == "$pkg" -a -n "$equivs" ]; then
96 # Check equivalent packages
97 for equiv in ${equivs#*=}; do
98 case $equiv in
99 *:*)
100 if grep -q "^${equiv%:*}"$'\t' "$PKGS_DB/installed.info" &&
101 grep -q "^${equiv#*:}"$'\t' "$PKGS_DB/installed.info"; then
102 # Equivalent installed
103 orig_pkg="$pkg→"; pkg="${equiv#*:}"
104 data_icon="@pkgi@"; responce='i'; break
105 fi;;
106 *)
107 if grep -q "^$equiv"$'\t' "$PKGS_DB/installed.info"; then
108 # Equivalent installed
109 orig_pkg="$pkg→"; pkg="$equiv"
110 data_icon="@pkgi@"; responce='i'; break
111 fi;;
112 esac
113 done
114 fi
115 fi
117 # Installed and blocked?
118 [ "$data_icon" == "@pkgi@" ] && grep -q "^$pkg$" "$BLOCKED" && data_icon="@pkgib@"
120 if [ $(GET web) == 'y' ]; then
121 # Request from page http://pkgs.slitaz.org/ for example:
122 # http://127.0.0.1:82/pkgs.cgi?status&web=y&pkg=nano
123 # Allow http://pkgs.slitaz.org/ to get information from tazpanel server
124 header "Access-Control-Allow-Origin: http://pkgs.slitaz.org"
125 echo -n "$responce"
126 else
127 # Local request: don't check CORS (fails for cross domain requests unconditionally)
128 header
129 echo -n "<a data-icon=\"$data_icon\" href=\"?info=${pkg//+/%2B}\">$orig_pkg$pkg</a>"
130 fi
131 exit 0
132 ;;
135 *\ app_img\ * )
136 # Show application image
137 pkg=$(GET app_img)
139 # check for icons defined with packages.icons file
140 if [ -f "$PKGS_DB/packages.icons" ]; then
141 predefined_icon="$(awk -F$'\t' -vpkg="$pkg" '$1==pkg{print $2}' "$PKGS_DB/packages.icons")"
142 fi
143 predefined_icon="${predefined_icon:-package-x-generic}.png"
145 current_user=$(id -un)
146 if [ -n "$current_user" ]; then
147 current_user_home=$(awk -F: -vu="$current_user" '$1==u{print $6}' /etc/passwd)
148 current_icon_theme=$(grep gtk-icon-theme-name "$current_user_home/.gtkrc-2.0" | cut -d'"' -f2)
149 fi
150 current_icon_theme="/usr/share/icons/$current_icon_theme"
152 # Preferred default icon is 48px package-x-generic
153 default_pkg_icon=$(find -L "$current_icon_theme" -type f -path '*48*' -name "$predefined_icon" | head -n1)
154 # ... or package-x-generic with the bigger size
155 if [ -z "$default_pkg_icon" ]; then
156 default_pkg_icon=$(find -L "$current_icon_theme" -type f -name "$predefined_icon" | sort | tail -n1)
157 fi
159 # Preferred package icon size is 48px
160 pkg_icon=$(find -L "$current_icon_theme" -type f -path '*48*' -name "$pkg.png" | head -n1)
161 # ... or just bigger one
162 if [ -z "$pkg_icon" ]; then
163 pkg_icon=$(find -L "$current_icon_theme" -type f -name "$pkg.png" | sort | tail -n1)
164 fi
165 # ... or one from pixmaps
166 if [ -z "$pkg_icon" ]; then
167 pkg_icon=$(find -L /usr/share/pixmaps -type f -name "$pkg.png" | head -n1)
168 fi
170 # Cache app icon maximum for 24h (note Cache-Control was introduced in HTTP 1.1)
171 header "HTTP/1.1 200 OK" "Content-Type: image/png" "Cache-Control: public, max-age=86400"
172 cat "${pkg_icon:-$default_pkg_icon}"
173 exit 0 ;;
176 *\ show_receipt\ * )
177 # Show package receipt
178 pkg=$(GET show_receipt)
179 if [ -f "$INSTALLED/$pkg/receipt" ]; then
180 # Redirects to the receipt view
181 header "HTTP/1.1 301 Moved Permanently" "Location: index.cgi?file=$INSTALLED/$pkg/receipt"
182 exit 0
183 else
184 temp_receipt=$(mktemp -d)
185 wget -O "$temp_receipt/receipt" -T 5 "http://hg.slitaz.org/wok/raw-file/tip/$pkg/receipt"
186 if [ -e "$temp_receipt" ]; then
187 # Redirects to the receipt view
188 header "HTTP/1.1 301 Moved Permanently" "Location: index.cgi?file=$temp_receipt/receipt"
189 exit 0
190 else
191 header; xhtml_header
192 msg err "$(_ 'Receipt for package %s unavailable' "$pkg")"
193 xhtml_footer
194 exit 0
195 fi
196 fi
197 ;;
199 esac
202 header
205 # xHTML 5 header with special side bar for categories.
206 TITLE=$(TEXTDOMAIN='tazpkg'; _ 'Packages')
209 pkg_info_link() {
210 echo "<a data-icon=\"$2\" href=\"?info=${1//+/%2B}\">$1</a>" | sed 's| data-icon=""||'
211 }
214 # Display localized short description
216 i18n_desc() {
217 for L in $LANG ${LANG%%_*}; do
218 if [ -e "$PKGS_DB/packages-desc.$L" ]; then
219 LOCDESC=$(awk -F$'\t' -vp=$1 '{if ($1 == p) print $2}' $PKGS_DB/packages-desc.$L)
220 if [ -n "$LOCDESC" ]; then
221 SHORT_DESC="$LOCDESC"
222 break
223 fi
224 fi
225 done
226 }
229 select_package_icon() {
230 if [ -d "$INSTALLED/$1" ]; then
231 if grep -q "^$1$" "$BLOCKED"
232 then echo "@pkgib@"
233 else echo "@pkgi@"
234 fi
235 else echo "@pkg@"
236 fi
237 }
240 # We need packages information for list and search
242 parse_packages_info() {
243 IFS=$'\t'
244 while read PACKAGE VERSION CATEGORY SHORT_DESC WEB_SITE TAGS SIZES DEPENDS; do
245 i18n_desc "$PACKAGE"
246 cat <<EOT
247 <tr>
248 <td><input type="checkbox" name="pkg" value="$PACKAGE">$(pkg_info_link "$PACKAGE" "$(select_package_icon "$PACKAGE")")</td>
249 <td>$VERSION</td>
250 <td>$SHORT_DESC</td>
251 </tr>
252 EOT
253 done
254 unset IFS
255 }
258 # Show button
260 show_button() {
261 for button in $@; do
262 class=''; misc=''
263 case $button in
264 recharge) icon="@refresh@"; label=$(_ 'Recharge list'); misc=' data-root';;
265 up) icon="@upgrade@"; label=$(_ 'Check upgrades'); misc=' data-root';;
266 list) icon="@list@"; label=$(_ 'My packages');;
267 tags) icon="@tags@"; label=$(_ 'Tags');;
268 linkable) icon="@link@"; label=$(_ 'Linkable packages');;
269 admin) icon="@admin@"; label=$(_ 'Administration'); misc=' data-root';;
270 *Install*nf*) icon="@install@"; label=$(_ 'Install (Non Free)');;
271 *Install*) icon="@install@"; label=$(_ 'Install');;
272 *Remove*) icon="@remove@"; label=$(_ 'Remove');;
273 *Link*) icon="@link@"; label=$(_ 'Link');;
274 *Block*) icon="@lock@"; label=$(_ 'Block');;
275 *Unblock*) icon="@unlock@"; label=$(_ 'Unblock');;
276 *Chblock*) icon="@chlock@"; label=$(_ '(Un)block');;
277 *Repack*) icon="@repack@"; label=$(_ 'Repack');;
278 *saveconf*) icon="@save@"; label=$(_ 'Save configuration');;
279 *listconf*) icon="@list@"; label=$(_ 'List configuration files');;
280 *quickcheck*) icon="@check@"; label=$(_ 'Quick check');;
281 *fullcheck*) icon="@check@"; label=$(_ 'Full check');;
282 *clean*) icon="@remove@"; label=$(_ 'Clean');;
283 *setlink*) icon="@link@"; label=$(_ 'Set link');;
284 *removelink*) icon="@unlink@"; label=$(_ 'Remove link');;
285 *add-mirror) icon="@add@"; label=$(_n 'Add mirror');;
286 *add-repo) icon="@add@"; label=$(_n 'Add repository');;
287 toggle) icon="@toggle@"; label=$(_n 'Toggle all');;
288 esac
289 if [ "$button" == 'toggle' ]; then
290 echo -n "<span class=\"float-right\"><button data-icon=\"$icon\" onclick=\"checkBoxes()\">$label</button></span>"
291 else
292 echo -n "<button data-icon=\"$icon\" name=\"${button%%=*}\" value=\"${button#*=}\"$misc>$label</button>"
293 fi
294 done
295 }
299 #
300 # xHTML functions
301 #
304 table_head() {
305 cat <<EOT
306 <table class="wide zebra pkglist" id="head1">
307 <thead id="head2">
308 <tr>
309 <td>$(_ 'Name')</td>
310 <td>$(_ 'Version')</td>
311 <td>$(_ 'Description')</td>
312 </tr>
313 </thead>
314 <tbody>
315 EOT
316 }
319 repo_list() {
320 if [ -n "$(ls "$PKGS_DB/undigest" 2>/dev/null)" ]; then
321 case "$repo" in
322 Public)
323 ;;
324 ""|Any)
325 for i in "$PKGS_DB/undigest/"* ; do
326 [ -d "$i" ] && echo "$i$1"
327 done ;;
328 *)
329 ls "$PKGS_DB/undigest/$repo$1" 2>/dev/null
330 return ;;
331 esac
332 fi
333 [ -e "$PKGS_DB$1" ] && echo "$PKGS_DB$1"
334 }
337 repo_name() {
338 case "$1" in
339 $PKGS_DB)
340 echo "Public" ;;
341 $PKGS_DB/undigest/*)
342 echo ${1#$PKGS_DB/undigest/} ;;
343 esac
344 }
347 header_repo_name() {
348 [ -d "$PKGS_DB/undigest" ] && [ "$repo" != "Public" ] && \
349 _ 'Repository: %s' $(repo_name $1)
350 }
353 # Print links to the pages
355 pager() {
356 : ${PAGE_SIZE=100}
357 [ "$PAGE_SIZE" -ne 0 ] && \
358 awk -F'"' -vpage="$page" -vsize="$PAGE_SIZE" -vnum_lines="$(wc -l < $1)" \
359 -vtext="$(_ 'Pages:') " -vurl="?list&amp;page=" '
360 BEGIN{
361 num_pages = int(num_lines / size) + (num_lines % size != 0)
362 if (num_pages != 1) printf "<p>%s", text
363 }
364 {
365 if (num_pages == 1) exit
366 r = NR % size
367 if (r == 1) {
368 p = int(NR / size) + 1
369 printf "<button class=\"pages%s\" name=\"page\" value=\"%s\" title=\"%s\n···\n", p==page?" current":"", p, $6
370 } else if (r == 0)
371 printf "%s\">%s</button> ", $6, int(NR / size)
372 }
373 END{
374 if (num_pages == 1) exit
375 if (r != 0) printf "%s\">%s</button>", $6, int(NR / size) + 1
376 print "</p>"
377 }' "$1"
378 }
381 # Show packages list by category or tag
383 show_list() {
384 : ${PAGE_SIZE=100}
385 page=$(GET page); page=${page:-1}
386 cached=$(mktemp)
387 [ -n "$tag" ] && cat=''
388 {
389 for L in $LANG ${LANG%%_*}; do
390 if [ -e "$PKGS_DB/packages-desc.$L" ]; then
391 sed '/^#/d' "$PKGS_DB/packages-desc.$L"; break
392 fi
393 done
394 [ -f "$BLOCKED" ] && cat "$BLOCKED"
395 sed 's|.*|&\ti|' "$PKGS_DB/installed.info"
396 [ "$cat" == 'extra' ] || [ $1 == 'my' ] || cat "$i/packages.info"
397 [ "$cat" == 'extra' ] &&
398 sed 's,\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\).*,\1\t\5\textra\t\2\thttp://mirror.slitaz.org/packages/get/\1\t-\t-\t-\t-,' "$PKGS_DB/extra.list"
399 # Last list entry will miss, so add fake line
400 echo 'zzzzzzzz'
401 } | sort -t$'\t' -k1,1 | sed '/^$/d' | awk -F$'\t' -vc="${cat:--}" -vt="${tag:--}" '
402 {
403 if (PKG && PKG != $1) {
404 if (SEL) {
405 if (DSCL) DSC = DSCL
406 printf "<tr><td><input type=\"checkbox\" name=\"pkg\" value=\"%s\" id=\"%s\">", PKG, PKG
408 if (INS) {
409 if (BLK) printf "<a data-icon=\"@pkgib@\" ";
410 else printf "<a data-icon=\"@pkgi@\" ";
411 } else printf "<a data-icon=\"@pkg@\" ";
413 printf "href=\"?info=%s\">%s</a></td>", gensub(/\+/, "%2B", "g", PKG), PKG
415 printf "<td>%s</td><td>%s</td><td><a href=\"%s\"></a></td></tr>\n", VER, DSC, WEB
416 }
417 VER = DSC = WEB = DSCL = INS = BLK = SEL = ""
418 }
420 PKG = $1
421 if (NF == 1) { BLK = "b"; next }
422 if (NF == 2) { DSCL = $2; next }
423 if (c == "all" || $3 == c || index(" "$6" ", " "t" ")) { SEL = 1 }
424 if (SEL) {
425 if ($10 == "i") { VER = $2; DSC = $4; WEB = $5; INS = "i"; next}
426 if (! INS) { VER = $2; DSC = $4; WEB = $5 }
427 }
428 }' > "$cached"
430 pager="$(pager $cached)"
431 case $PAGE_SIZE in
432 0) list="$(cat $cached)";;
433 *) list="$(tail -n+$((($page-1)*$PAGE_SIZE+1)) $cached | head -n$PAGE_SIZE)";;
434 esac
436 if [ "$pager" != "<p>$(_ 'Pages:') </p>" ] && [ -n "${list:1:1}" ]; then
437 cat <<EOT
438 <h3>$(header_repo_name $i)</h3>
439 $pager
440 $(table_head)
441 $list
442 </tbody></table>
443 $pager
444 EOT
445 fi
446 rm -f "$cached"
449 ### Re-select packages when you return to the page
451 # Find the packages list
452 pkgs=$(echo "$QUERY_STRING&" | awk '
453 BEGIN { RS="&"; FS="=" }
454 $1=="pkg" { printf "\"%s\", ", $2 }
455 ')
456 pkgs=$(httpd -d "${pkgs%, }")
457 # now pkgs='"pkg1", "pkg2", ... "pkgn"'
459 if [ -n "$pkgs" ]; then
460 cat <<EOT
461 <script type="text/javascript">
462 var pkgs = [$pkgs];
463 var theForm = document.getElementById('pkglist');
464 for (index = 0; index < pkgs.length; index++) {
465 if (document.getElementById(pkgs[index])) {
466 // check existing
467 document.getElementById(pkgs[index]).checked = 'true';
468 }
469 else {
470 // add other as hidden
471 var hInput = document.createElement('input');
472 hInput.type = 'hidden';
473 hInput.name = 'pkg';
474 hInput.value = pkgs[index];
475 theForm.appendChild(hInput);
476 }
477 }
478 document.getElementById('countSelected').textContent = pkgs.length;
479 </script>
480 EOT
481 fi
482 }
485 # Show a single package link
487 show_package_link() {
488 echo -n "<span><a data-icon=\"$(select_package_icon "$1")\" "
489 echo "href=\"?info=${1//+/%2B}\">$1</a></span> "
490 }
493 # Show links for "info" page
495 show_info_links() {
496 if [ -n "$1" ]; then
497 if [ "$3" == 'tag' ]; then icon="@tag@"; else icon="@clock@"; fi
498 case "$4" in
499 provide) echo -n "<tr><td><b>$2</b></td><td>"; noeq=' ';;
500 '') echo -n "<tr><td><b>$2</b></td><td>"; noeq='';;
501 *) echo -n "<tr><td><b><a href=\"?suggested=${4//+/%2B}\">$2</a></b></td><td>";;
502 esac
504 echo $1 | tr ' ' $'\n' | awk -vt="$3" -vi="$icon" -vnoeq="$noeq" '{
505 printf "<span><a data-icon=\"%s\" ", i;
506 printf "href=\"?%s=%s\">%s%s</a></span>", t, gensub(/\+/, "%2B", "g", $1), $1, noeq
507 }'
508 echo "</td></tr>"
509 fi
510 }
513 tazpanel_header() {
514 [ -n "$(GET noheader)" ] && return
516 xhtml_header "$1" | sed 's/id="content"/id="content-sidebar"/'
518 cat <<EOT
519 <form class="search">
520 <a data-icon="@web@" href="http://pkgs.slitaz.org/" target="_blank" title="$(_n 'Web search tool')"></a>
521 <input type="search" name="search" value="$(GET search)" results="5" autosave="pkgsearch" autocomplete="on"><!--
522 --><button type="submit">$(_n 'Search')</button><!--
523 --><button name="files" value="yes">$(_n 'Files')</button><!--
524 --></form>
525 EOT
527 repo=$(COOKIE repo); repo=${repo:-Public}; [ -n "$(GET repo)" ] && repo=$(GET repo)
528 my=$(COOKIE my); my=${my:-my}; [ -n "$(GET my)" ] && my=$(GET my)
529 cat=$(COOKIE cat); cat=${cat:-all}; [ -n "$(GET cat)" ] && cat=$(GET cat)
531 cat <<EOT
532 <script type="text/javascript">
533 function setCookie(name) {
534 if (name=='cat') {
535 var cats = document.getElementsByName('cat');
536 for (var i = 0; i < cats.length; i++) {
537 if (cats[i].checked) {
538 document.cookie = name + "=" + cats[i].value;
539 break;
540 }
541 }
542 } else {
543 document.cookie = name+"="+document.getElementById(name).value;
544 }
545 }
546 function setValue(name, value) {
547 document.getElementById(name).value=value;
548 setCookie(name);
549 }
550 </script>
551 <form method="post" action="?list" style="position: absolute">
553 <div id="sidebar">
554 <select id="my" value="$my" onchange="setCookie('my'); this.form.submit()">
555 <option value="my">$(_ 'My packages')</option>
556 <option value="no">$(_ 'All packages')</option>
557 </select>
558 <script type="text/javascript">setValue('my', "$my")</script>
560 <h4>$(_ 'Categories')</h4>
562 <div class="wide zebra">
563 $(echo 'base-system x-window utilities network games graphics office
564 multimedia development system-tools security misc meta non-free all
565 extra' | tr ' ' '\n' | awk -vcat="$cat" -vn="1" '{
566 system("gettext " $1 | getline tr)
567 printf "<input type=\"radio\" name=\"cat\" id=\"c%s\" ", n
568 printf "value=\"%s\"%s ", $1, $1==cat?" checked":""
569 printf "onclick=\"setCookie(&#39;cat&#39;); this.form.submit()\">"
570 printf "<label for=\"c%s\">%s</label>\n", n, tr
571 n++
572 }')
573 </div>
574 EOT
576 if [ -d "$PKGS_DB/undigest" ]; then
577 cat <<EOT
578 <h4>$(_ 'Repository')</h4>
580 <select id="repo" onchange="setCookie('repo')">
581 <option value="Public">$(_ 'Public')</option>
582 $(IFS=$'\n'; for i in $(ls "$PKGS_DB/undigest"); do
583 echo "<option value=\"$i\">$i</option>"
584 done; unset IFS)
585 <option value="Any">$(_ 'Any')</option>
586 </select>
587 <script type="text/javascript">setValue('repo', "$repo")</script>
588 EOT
589 fi
591 cat <<EOT
592 <a data-icon="@tags@" href="?tags">$(_ 'All tags...')</a><br/>
593 <a data-icon="@list@" href="?cats">$(_ 'All categories...')</a>
594 </div>
595 </form>
596 EOT
597 }
602 #
603 # Commands
604 #
607 case " $(GET) " in
610 *\ linkable\ *)
611 #
612 # List linkable packages.
613 #
614 tazpanel_header "$(_ 'Linkable packages')"
615 loading_msg "$(_ 'Listing linkable packages...')"
617 cat <<EOT
618 <form class="wide">
619 $(_ 'Selection:') $(show_button do=Link)
620 EOT
621 table_head
622 target=$(readlink "$PKGS_DB/fslink")
623 # FIXME: get $INSTALLED value using conf files from --root=$target
624 for pkg in $(ls "$target/$INSTALLED"); do
625 [ -s "$pkg/receipt" ] && continue
626 . "$target/$INSTALLED/$pkg/receipt"
627 i18n_desc "$pkg"
628 cat <<EOT
629 <tr>
630 <td><input type="checkbox" name="pkg" value="$pkg" /><a data-icon="@pkg@" href="?info=${pkg//+/%2B}">$pkg</a></td>
631 <td>$VERSION</td>
632 <td>$SHORT_DESC</td>
633 <td><a data-img="@web@" href="$WEB_SITE"></a></td>
634 </tr>
635 EOT
636 done
637 cat <<EOT
638 </tbody>
639 </table>
640 </form>
641 EOT
642 ;;
645 *\ cats\ *)
646 #
647 # List of all categories.
648 #
649 tazpanel_header "$(_ 'Categories list')"
651 for pkgsinfo in $(repo_list /packages.info); do
652 cat <<EOT
653 <section>
654 <header>$(header_repo_name $(dirname "$pkgsinfo"))</header>
655 <table class="wide zebra center">
656 <thead>
657 <tr>
658 <td>$(_ 'Category')</td>
659 <td>$(_ 'Available packages')</td>
660 <td>$(_ 'Installed packages')</td>
661 </tr>
662 </thead>
663 <tbody>
664 EOT
665 {
666 awk -F$'\t' '{print $3}' "$pkgsinfo" | sort | uniq -c
667 awk -F$'\t' '{print $3}' "$PKGS_DB/installed.info" | sed 's|.*|& i|' | sort | uniq -c
668 } | sort -k2,2 | awk '
669 {
670 c [$2] = "."
671 if ($3) { i[$2] = $1; } else { m[$2] = $1; }
672 }
673 END {
674 for (n in c) print n, m[n], i[n]
675 }' | sort | awk '{
676 printf "<tr><td><a href=\"?list&amp;cat=%s\">%s</a></td><td>%d</td><td>%d</td></tr>", $1, $1, $2, $3
677 }'
678 cat <<EOT
679 </tbody>
680 </table>
681 </section>
682 EOT
683 done
684 ;;
687 *\ list\ *|*\ page\ *)
688 #
689 # List all packages by category.
690 #
691 tazpanel_header "$(_ 'Packages list')"
692 loading_msg "$(_ 'Listing packages...')"
694 bcat="<b>$cat</b>"; brepo="<b>$repo</b>"
695 case $repo in
696 Any)
697 case $my in
698 my) title=$(_ 'Installed packages of category "%s"' "$bcat");;
699 *) title=$(_ 'All packages of category "%s"' "$bcat");;
700 esac ;;
701 *)
702 case $my in
703 my) title=$(_ 'Installed packages of category "%s" in repository "%s"' "$bcat" "$brepo");;
704 *) title=$(_ 'All packages of category "%s" in repository "%s"' "$bcat" "$brepo");;
705 esac ;;
706 esac
708 cat <<EOT
709 <p>$title</p>
710 EOT
712 [ ! -f $PKGS_DB/packages.info ] && msg warn \
713 "$(_ 'You can not view a list of all packages until recharging lists.')"
715 [ "$REMOTE_USER" == "root" ] && cat <<EOT
716 <section>
717 <div>$(_ 'Selected packages:') <span id="countSelected"></span></div>
718 <footer>
719 $({
720 [ "$my" != 'my' ] && show_button do=Install
721 show_button do=Chblock do=Remove
722 } | sed 's|button |button form="pkglist" |g')
723 $(show_button toggle)
724 </footer>
725 </section>
726 EOT
727 cat <<EOT
729 <form id="pkglist" class="wide">
730 EOT
731 for i in $(repo_list ""); do
732 show_list ${my#no}
733 done
734 cat <<EOT
735 </form>
736 <script type="text/javascript">window.onscroll = scrollHandler; setCountSelPkgs();</script>
737 EOT
738 ;;
741 *\ suggested\ *)
742 #
743 # List all suggested packages
744 #
745 tazpanel_header "$(_ 'Packages list')"
746 loading_msg "$(_ 'Listing packages...')"
748 pkg=$(GET suggested)
749 suggested_pkgs=$(. $INSTALLED/$pkg/receipt; echo $SUGGESTED)
750 [ -z "$suggested_pkgs" ] && xhtml_footer && exit
752 cat <<EOT
753 <p>$(_ 'Packages suggested by %s' "<b>$pkg</b>")</p>
754 EOT
756 [ "$REMOTE_USER" == "root" ] && cat <<EOT
757 <section>
758 <div>$(_ 'Selected packages:') <span id="countSelected"></span></div>
759 <footer>
760 $({
761 show_button do=Install do=Chblock do=Remove
762 } | sed 's|button |button form="pkglist" |g')
763 $(show_button toggle)
764 </footer>
765 </section>
766 EOT
768 cat <<EOT
769 <form id="pkglist" class="wide">
770 EOT
771 table_head
772 for pkg in $suggested_pkgs; do
773 grep "^$pkg"$'\t' "$PKGS_DB/packages.info" | parse_packages_info
774 done
775 cat <<EOT
776 </tbody></table>
777 </form>
778 <script type="text/javascript">window.onscroll = scrollHandler; setCountSelPkgs();</script>
779 EOT
780 ;;
783 *\ search\ *)
784 #
785 # Search for packages. Here default is to search in packages.desc
786 # and so get result including packages names and descriptions
787 #
788 tazpanel_header "$(_ 'Search packages')"
789 loading_msg "$(_ 'Searching packages...')"
791 pkg=$(GET search); [ -z "$pkg" ] && xhtml_footer && exit
792 cd $PKGS_DB
794 cat <<EOT
795 <section>
796 <div>$(_ 'Selected packages:') <span id="countSelected"></span></div>
797 <footer>
798 $(show_button do=Install do=Chblock do=Remove | sed 's|button |button form="pkglist" |g')
799 $(show_button toggle)
800 </footer>
801 </section>
803 <form id="pkglist" class="wide">
804 EOT
805 if [ -n "$(GET files)" -o -n "$(echo $pkg | grep '/')" ]; then
806 cat <<EOT
807 <table class="wide zebra filelist">
808 <thead>
809 <tr>
810 <td>$(_ 'Package')</td>
811 <td>$(_ 'File')</td>
812 </tr>
813 <thead>
814 <tbody>
815 EOT
816 lzcat $(repo_list /files.list.lzma) | grep -Ei ": .*$(GET search)" | \
817 while read PACKAGE FILE; do
818 PACKAGE=${PACKAGE%:}
819 cat <<EOT
820 <tr>
821 <td><input type="checkbox" name="pkg" value="$PACKAGE">$(pkg_info_link "$PACKAGE" "$(select_package_icon "$PACKAGE")")</td>
822 <td>$(echo "$FILE" | sed "s|$pkg|<span class=\"diff-add\">&</span>|gI")</td>
823 </tr>
824 EOT
825 done
826 else
827 table_head
828 awk -F$'\t' 'BEGIN{IGNORECASE = 1}
829 $1 " " $4 ~ /'$pkg'/{print $0}' $(repo_list /packages.info) | parse_packages_info
830 fi
831 cat <<EOT
832 </tbody>
833 </table>
834 </form>
835 <script type="text/javascript">window.onscroll = scrollHandler; setCountSelPkgs();</script>
836 EOT
837 ;;
840 *\ recharge\ *)
841 #
842 # Lets recharge the packages list
843 #
844 tazpanel_header "$(_ 'Recharge')"
845 loading_msg "$(_ 'Recharging lists...')"
847 cat <<EOT
848 <p>$(_ 'Recharge checks for new or updated packages')</p>
850 <section>
851 <header>
852 <span data-icon="sync">$(_ 'Recharging log')</span>
853 <form>$(show_button up)</form>
854 </header>
855 EOT
856 echo $(_ 'Recharging packages list') | log
857 export output="html"; tazpkg recharge
858 cat <<EOT
859 <footer>$(_ 'Packages lists are up-to-date. You should check for upgrades now.')</footer>
860 </section>
861 EOT
862 ;;
865 *\ up\ *)
866 #
867 # Upgrade packages
868 #
869 tazpanel_header "$(_ 'Up packages')"
870 loading_msg "$(_ 'Checking for upgrades...')"
872 cat <<EOT
873 <section>
874 <div>$(_ 'Selected packages:') <span id="countSelected"></span></div>
875 <footer>
876 $(show_button do=Install do=Chblock do=Remove | sed 's|button |button form="pkglist" |g')
877 $(show_button toggle)
878 </footer>
880 <form id="pkglist" class="wide">
881 EOT
883 tazpkg up -c
885 cat <<EOT
886 </form>
887 </section>
889 <script type="text/javascript">window.onscroll = scrollHandler; setCountSelPkgs();</script>
890 EOT
891 ;;
894 *\ do\ *)
895 #
896 # Do an action on one or some packages
897 #
898 tazpanel_header "TazPkg: $(GET do)"
899 loading_msg
901 # Find the command
902 cmd=$(echo $(GET do) | tr [:upper:] [:lower:])
904 # Find the packages list
905 pkgs=$(echo $QUERY_STRING | awk 'BEGIN{RS="&";FS="="}{if($1=="pkg")print $2}')
906 pkgs=$(httpd -d "$pkgs")
908 # Describe the command
909 bpkgs="<b>$pkgs</b>"; opt=''
910 case $cmd in
911 install) MSG="$(_ 'Installing: %s' "$bpkgs")"; opt='--forced'; cmd='get-install' ;;
912 remove) MSG="$(_ 'Removing: %s' "$bpkgs")" ;;
913 link) MSG="$(_ 'Linking: %s' "$bpkgs")"; opt="$(readlink $PKGS_DB/fslink)" ;;
914 block) MSG="$(_ 'Blocking: %s' "$bpkgs")" ;;
915 unblock) MSG="$(_ 'Unblocking: %s' "$bpkgs")" ;;
916 chblock) MSG="$(_ '(Un)blocking: %s' "$bpkgs")" ;;
917 repack) MSG="$(_ 'Repacking: %s' "$bpkgs")" ;;
918 esac
920 cat <<EOT
921 <div>$MSG</div>
922 EOT
923 # Do the command for all asked packages
924 cd /tmp
925 export output='html'
926 pkgs_total=$(echo $pkgs | wc -w)
927 pkg_current='1'
928 unset sequence
930 for pkg in $pkgs; do
931 [ "$pkgs_total" -ne 1 ] && sequence="$pkg_current/$pkgs_total"
932 #echo $(_n 'y') |
933 tazpkg $cmd $pkg $opt --sequence="$sequence"
934 pkg_current=$((pkg_current+1))
935 done
936 ;;
939 *\ info\ *)
940 #
941 # Packages info
942 #
943 tazpanel_header "$(_ 'Package info')"
944 loading_msg "$(_ 'Getting package info...')"
946 pkg="$(GET info)"
948 # Package state
949 if [ -d "$INSTALLED/$pkg" ]; then
950 STATE="$(_ 'installed package')"
951 elif [ -e "$PKGS_DB/packages.info" -a \
952 -n "$(awk -F$'\t' -vp="$pkg" '$1==p{print $1}' "$PKGS_DB/packages.info")" ]; then
953 STATE="$(_ 'mirrored package')"
954 elif grep -qs "^$pkg=" $PKGS_DB/packages.equiv; then
955 cat <<EOT
956 <section>
957 <header>
958 <span data-icon="pkg">$(_ 'Packages providing %s' "$pkg")</span>
959 </header>
960 EOT
961 for pkg in $(sed "/^$pkg=/!d;s/^$pkg=//" $PKGS_DB/packages.equiv); do
962 name=${pkg#*:}
963 echo "<p>"
964 show_package_link "$name"
965 condition=${pkg%:*}
966 [ "$name" == "$condition" ] ||
967 echo "($(_ "if") $(show_package_link "$condition")$(_ "is installed")) "
968 echo "</p>"
969 done
970 xhtml_footer; exit 0
971 else
972 msg err "$(_ 'Package "%s" not available.' "$pkg")"
973 xhtml_footer; exit 0
974 fi
976 cat <<EOT
977 <section>
978 <header>
979 <span data-icon="$(select_package_icon "$pkg")">$(_ 'Package %s' "$pkg")</span>
980 <form>
981 <input type="hidden" name="pkg" value="${pkg#get-}"/>
982 EOT
984 # Get receipt variables, show Install/Remove buttons
985 if [ -d "$INSTALLED/$pkg" ]; then
986 . $INSTALLED/$pkg/receipt
987 files=$(wc -l < $INSTALLED/$pkg/files.list)
988 [ "$REMOTE_USER" == 'root' ] && show_button do=Remove
989 else
990 cd $PKGS_DB
991 eval "$(awk -F$'\t' -vp=$pkg '
992 $1==p{
993 printf "PACKAGE=\"%s\"; VERSION=\"%s\"; CATEGORY=\"%s\"; ", $1, $2, $3
994 printf "SHORT_DESC=\"%s\"; WEB_SITE=\"%s\"; TAGS=\"%s\"; ", $4, $5, $6
995 printf "SIZES=\"%s\"; DEPENDS=\"%s\"", $7, $8
996 }' packages.info undigest/*/packages.info)"
997 if [ -z "$PACKAGE" ]; then
998 eval "$(awk -F'|' -vp=$pkg '
999 $1==p{
1000 printf "PACKAGE=\"%s\"; SHORT_DESC=\"%s\"; WEB_SITE=\"%s\"; ", $1, $2, $3
1001 printf "CATEGORY=\"%s\"; VERSION=\"%s\"; LICENSE=\"%s\"; ", $4, $5, $6
1002 }' extra.list undigest/*/extra.list)"
1003 [ -z "$CATEGORY" ] && CATEGORY='non-free'
1004 fi
1005 PACKED_SIZE=${SIZES% *}
1006 UNPACKED_SIZE=${SIZES#* }
1007 [ "$REMOTE_USER" == 'root' ] &&
1008 if [ "${pkg#get-}" != "$pkg" ]; then
1009 show_button 'do=Install&amp;nf'
1010 else
1011 show_button do=Install
1012 fi
1013 fi
1015 # Show Block/Unblock, and Repack buttons
1016 [ "$REMOTE_USER" == "root" ] &&
1017 if [ -d $INSTALLED/$pkg ]; then
1018 if grep -qs "^$pkg$" "$BLOCKED"; then
1019 show_button do=Unblock
1020 else
1021 show_button do=Block
1022 fi
1023 show_button do=Repack
1024 fi
1026 # Translate short description
1027 i18n_desc $pkg
1029 # Show info table
1030 cat <<EOT
1031 </form>
1032 </header>
1034 <table class="wide zebra summary" id="infoTable">
1035 <tbody>
1036 <tr><td><b>$(_ 'Name')</b></td><td>$PACKAGE
1037 <div id="appImg"><img src="pkgs.cgi?app_img=$PACKAGE"/></div>
1038 </td></tr>
1040 <tr><td><b>$(_ 'State')</b></td><td>$STATE</td></tr>
1042 $([ -n "$VERSION" ] && echo "<tr><td><b>$(_ 'Version')</b></td><td>$VERSION</td></tr>")
1044 <tr><td><b>$(_ 'Category')</b></td><td><a href="?list&amp;cat=$CATEGORY">$(_n "$CATEGORY")</a></td></tr>
1046 <tr><td><b>$(_ 'Description')</b></td><td>$SHORT_DESC</td></tr>
1048 $([ -n "$MAINTAINER" ] && echo "<tr><td><b>$(_ 'Maintainer')</b></td><td>$MAINTAINER</td></tr>")
1050 $([ -n "$LICENSE" ] && echo "<tr><td><b>$(_ 'License')</b></td><td><a href=\"?license=$pkg\">$LICENSE</a></td></tr>")
1052 <tr><td><b>$(_ 'Website')</b></td><td><a href="$WEB_SITE" target="_blank">$WEB_SITE</a></td></tr>
1054 $(show_info_links "$TAGS" "$(_ 'Tags')" 'tag')
1056 $([ -n "$PACKED_SIZE" ] && echo "<tr><td><b>$(_ 'Sizes')</b></td><td>${PACKED_SIZE/.0/}/${UNPACKED_SIZE/.0/}</td></tr>")
1058 $(show_info_links "$DEPENDS" "$(_ 'Depends')" 'info')
1060 $(show_info_links "$PROVIDE" "$(_ 'Provide')" 'info' 'provide')
1062 $(show_info_links "$SUGGESTED" "$(_ 'Suggested')" 'info' "$PACKAGE")
1063 </tbody>
1064 </table>
1066 <footer>
1067 <a data-icon="@text@" href="?show_receipt=$pkg">$(_ 'View receipt')</a>
1068 <a data-icon="@slitaz@" href="?improve=$pkg">$(_ 'Improve package')</a>
1069 </footer>
1070 </section>
1072 EOT
1074 # Show description
1075 DESC="$(@@MODULES@@/description "$pkg")"
1076 [ -n "$DESC" ] && echo "<section id=\"desc\">$DESC</section>"
1078 # Show configuration files list
1079 CONFIGS="$(tazpkg list-config $pkg | sed 's|\(.*\)|\1 \1|')"
1080 [ -n "$CONFIGS" ] && cat <<EOT
1081 <section>
1082 <header>$(_ 'Configuration files')</header>
1083 <pre>$(printf '<a href="index.cgi?file=%s">%s</a>\n' $CONFIGS)</pre>
1084 </section>
1085 EOT
1087 # Show installed files list
1088 pkg=${pkg//+/%2B}
1089 cat <<EOT
1090 <section>
1091 <header>$(_ 'Installed files')</header>
1092 <span id="fileList">
1093 <div style="text-align: center;"><span data-icon="@clock@">$(_ 'Please wait')</span></div>
1094 </span>
1095 </section>
1098 <script type="text/javascript">
1099 var links = document.getElementById('infoTable').getElementsByTagName('a');
1100 for (var i = 0; i < links.length; i++) {
1101 if (links[i].dataset.icon=="@clock@") {
1102 links[i].parentNode.id = 'link' + i;
1103 pkg = links[i].textContent.replace(/\+/g, '%2B');
1104 ajax('?status&pkg=' + pkg, '1', 'link' + i);
1108 ajax('pkgs.cgi?filelist&pkg=$pkg', '1', 'fileList');
1109 </script>
1110 EOT
1111 ;;
1114 *\ admin\ * )
1116 # TazPkg configuration page
1118 tazpanel_header "$(_ 'Administration')"
1119 loading_msg
1121 cmd=$(GET admin)
1122 pager="$(GET pager)"; pager=${pager:-$PAGE_SIZE}; pager=${pager:-100}
1123 mirror="$(GET mirror)"; mirror="${mirror%/}/"
1124 repository="$PKGS_DB/undigest/$(GET repository)"
1125 link="$(GET link)"; link=${link%/}
1127 case "$cmd" in
1128 clean)
1129 rm -rf $CACHE_DIR/* ;;
1130 add-mirror)
1131 echo "$mirror" >> $(GET file) ;;
1132 rm-mirror)
1133 sed -i "/^"$(echo $mirror | sed 's|/|\\/|g')"$/d" $(GET file) ;;
1134 select-mirror)
1135 tazpkg setup-mirror "${mirror}packages/$(cat /etc/slitaz-release)/" | log ;;
1136 add-repo)
1137 mkdir -p $repository
1138 echo "$mirror" > $repository/mirror
1139 echo "$mirror" > $repository/mirrors ;;
1140 rm-repo)
1141 rm -rf $repository ;;
1142 setlink)
1143 [ -d "$link/$INSTALLED" ] && ln -fs $link $PKGS_DB/fslink ;;
1144 removelink)
1145 rm -f $PKGS_DB/fslink ;;
1146 pager)
1147 TP_CONF=/etc/slitaz/tazpanel.conf
1148 if [ -z "$PAGE_SIZE" ]; then
1149 echo -e "\n# Size of packages list page\nPAGE_SIZE=\"$pager\"" >> $TP_CONF
1150 else
1151 sed -i "s|PAGE_SIZE=.*|PAGE_SIZE=\"$pager\"|" $TP_CONF
1152 fi ;;
1153 esac
1155 cat <<EOT
1156 <p>$(_ 'TazPkg administration and settings')</p>
1158 <form id="actions">
1159 <input type="hidden" name="admin"/>
1160 $(show_button action=saveconf action=listconf action=quickcheck action=fullcheck)
1161 </form>
1162 EOT
1163 case "$(GET action)" in
1164 saveconf)
1165 loading_msg "$(_ 'Creating the package...')"
1166 echo "<pre>"
1167 cd /tmp
1168 tazpkg repack-config | filter_taztools_msgs
1169 echo -n "$(_ 'Path:') "; ls /tmp/config-*.tazpkg
1170 echo "</pre>" ;;
1171 listconf)
1172 echo "<h4>$(_ 'Configuration files')</h4>"
1173 echo "<ul>"
1174 tazpkg list-config | while read file; do
1175 if [ -e $file ]; then
1176 echo -n "<li><a href=\"index.cgi?file=$file\">$file</a>"
1177 md5file="$(grep -l " $file$" $INSTALLED/*/md5sum)"
1178 [ "$(grep -h " $file$" $md5file)" != "$(md5sum $file)" ] &&
1179 echo -n " " &&
1180 date -d @$(stat -c %Y $file)
1181 echo "</li>"
1182 else
1183 echo "<li>$file</li>"
1184 fi
1185 done
1186 echo "</ul>" ;;
1187 quickcheck)
1188 loading_msg "$(_ 'Checking packages consistency...')"
1189 tazpkg check
1190 ;;
1191 fullcheck)
1192 loading_msg "$(_ 'Full packages check...')"
1193 tazpkg check --full
1194 ;;
1195 dvdimage)
1196 dev=$(POST dvdimage)
1197 mkdir -p /mnt/packages 2> /dev/null
1198 echo "<pre>"
1199 mount -t iso9660 -o loop,ro $dev /mnt/packages &&
1200 /mnt/packages/install.sh &&
1201 _ '%s is installed on /mnt/packages' $dev
1202 echo "</pre>" ;;
1203 dvdusbkey)
1204 mkdir -p /mnt/packages 2> /dev/null
1205 for tag in "LABEL=\"packages-$version\" TYPE=\"iso9660\"" \
1206 "LABEL=\"sources-$version\" TYPE=\"iso9660\"" ; do
1207 dev=$(blkid | grep "$tag" | cut -d: -f1)
1208 [ -n "$dev" ] || continue
1209 echo "<pre>"
1210 mount -t iso9660 -o ro $dev /mnt/packages &&
1211 /mnt/packages/install.sh &&
1212 _ '%s is installed on /mnt/packages' $dev
1213 echo "</pre>"
1214 break
1215 done ;;
1216 esac
1218 cache_files=$(find $CACHE_DIR -name '*.tazpkg' | wc -l)
1219 cache_size=$(du -sh $CACHE_DIR | cut -f1 | sed 's|\.0||')
1220 [ "$cache_files" == 0 ] && cache_size="0K"
1221 mirror=$(cat $PKGS_DB/mirror)
1222 default_mirror=${mirror%/packages/*}
1223 cat <<EOT
1224 <section>
1225 <header>$(_ 'Packages cache')</header>
1226 <form class="wide">
1227 <div>$(_ 'Packages in the cache: %s (%s)' $cache_files $cache_size)</div>
1228 <footer>$(show_button admin=clean)</footer>
1229 </form>
1230 </section>
1233 <section>
1234 <header>$(_ 'Current mirror list')</header>
1235 EOT
1237 # List mirrors
1238 version=$(cat /etc/slitaz-release)
1239 for i in $PKGS_DB/mirrors $PKGS_DB/undigest/*/mirrors; do
1240 [ -s $i ] || continue
1241 if [ $i != $PKGS_DB/mirrors ]; then
1242 echo "<h4>$(_ 'Repository: %s' "$(repo_name $(dirname $i))")</h4>"
1243 fi
1244 cat <<EOT
1245 <form class="wide">
1246 <input type="hidden" name="admin" value="select-mirror"/>
1247 <table class="wide zebra">
1248 EOT
1249 while read line; do
1250 cat <<EOT
1251 <tr>
1252 <td>
1253 <input type="radio" name="mirror" id="$line" value="$line" onchange="this.form.submit()"
1254 $([ "$line" == "$default_mirror/" ] && echo -n 'checked="checked"')>
1255 <label for="$line"><code>$line</code></label></td>
1256 <td><a data-img="@web@" href="$line" target="_blank"></a></td>
1257 <td><a data-img="@remove@" href="?admin=rm-mirror&amp;mirror=$line&amp;file=$i" title="$(_ 'Delete')"></a></td>
1258 </tr>
1259 EOT
1260 done < $i
1261 cat <<EOT
1262 </table>
1263 </form>
1265 <form class="wide">
1266 <footer>
1267 <input type="hidden" name="file" value="$i" />
1268 <input type="text" name="mirror" size="40" />
1269 $(show_button admin=add-mirror)
1270 </footer>
1271 </form>
1272 EOT
1273 done
1274 cat <<EOT
1275 </section>
1278 <section>
1279 <header>$(_ 'Private repositories')</header>
1280 EOT
1281 if [ -n "$(ls $PKGS_DB/undigest 2> /dev/null)" ]; then
1282 cat <<EOT
1283 <table class="wide zebra">
1284 EOT
1285 ls $PKGS_DB/undigest 2> /dev/null | while read repo ; do
1286 cat <<EOT
1287 <tr>
1288 <td><code>$repo</code></td>
1289 <td><a data-img="@remove@" href="?admin=rm-repo&amp;repository=$repo" title="$(_ 'Delete')"></a></td>
1290 </tr>
1291 EOT
1292 done
1293 cat <<EOT
1294 </table>
1295 EOT
1296 fi
1298 cat <<EOT
1299 <form class="wide">
1300 <table>
1301 <tr><td>$(_ 'Name')</td><td><input type="text" name="repository" size="10"/></td></tr>
1302 <tr><td>$(_ 'URL:')</td><td><input type="text" name="mirror" value="http://"></td></tr>
1303 </table>
1304 <footer>
1305 $(show_button admin=add-repo)
1306 </footer>
1307 </form>
1308 </section>
1311 <section>
1312 <header>$(_ 'Link to another SliTaz installation')</header>
1313 <form class="wide">
1314 <div>
1315 $(_ "This link points to the root of another SliTaz installation. You will be able to install packages using soft links to it.")
1316 </div>
1317 $(dir_chooser "link" "$(readlink $PKGS_DB/fslink 2> /dev/null)")
1318 <footer>
1319 $(show_button admin=setlink admin=removelink)
1320 </footer>
1321 </form>
1322 </section>
1325 <section>
1326 <header id="dvd">$(_ 'SliTaz packages DVD')</header>
1328 <div>
1329 $(_ "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)
1331 <form method="post" action='?admin&amp;action=dvdimage'>
1332 $(_ 'Install from ISO image:')
1333 $(file_chooser "dvdimage" "/root/packages-$version.iso")
1334 </form>
1335 </div>
1337 <footer>
1338 <button data-icon="@download@" onclick='http://mirror.slitaz.org/iso/$version/packages-$version.iso'>
1339 $(_ 'Download DVD image')</button>
1340 <button data-icon="@link@" onclick='?admin&amp;action=dvdusbkey'>
1341 $(_ 'Install from DVD/USB key')</button>
1342 </footer>
1343 </section>
1346 <section>
1347 <header>$(_ 'Packages list')</header>
1348 <form class="wide">
1349 <div>
1350 $(_ 'Long list of packages is paginated. Here you can set the page size (default: 100, turning off the pager: 0).')
1351 </div>
1352 <input type="hidden" name="admin" value="pager"/>
1353 <input type="number" name="pager" value="$pager" min="0" step="10" size="4"/>
1354 <footer>
1355 <button data-icon="@ok@" type="submit">$(_ 'Set')</button>
1356 </footer>
1357 </form>
1358 </section>
1359 EOT
1360 ;;
1363 *\ license\ *)
1365 # Show licenses for installed packages
1367 tazpanel_header "$(_ 'Administration')"
1369 pkg=$(GET license)
1370 case $pkg in
1371 /*) [ -e $pkg ] && {
1372 echo "<h2>${pkg#/usr/share/licenses/}</h2>"
1373 case $pkg in
1374 *.htm*) cat $pkg ;;
1375 *) echo "<pre style=\"white-space: pre-wrap\">"
1376 cat $pkg | htmlize | sed 's|\([hf]t*t*ps*://[a-zA-Z0-9./_-]*[a-zA-Z0-9/_-]\)|<a href="\1">\1</a>|'
1377 echo "</pre>"
1378 ;;
1379 esac
1380 } ;;
1381 *) echo "<h2>$(_ 'Licenses for package %s' $pkg)</h2>"
1382 OFFLINE=''
1383 if [ -e "$PKGS_DB/installed/$pkg" ]; then
1384 for lic in $(grep /usr/share/licenses/ $PKGS_DB/installed/$pkg/files.list); do
1385 OFFLINE="$OFFLINE <li><a href=\"?license=$lic\">licenses/<b>${lic#/usr/share/licenses/}</b></a></li>\n"
1386 done
1387 echo "\
1388 Apache|Apache-2.0||||http://www.apache.org/licenses/#Artistic|Artistic-2.0||||#\
1389 BSD|BSD-2-Clause||||#BSD3|BSD-3-Clause||||#CC-BY-SA||by-sa/4.0/|||#\
1390 CC-SA||by-sa/4.0/|||#CC-BY-ND||by-nd/4.0/|||#CC-BY-NC-SA||by-nc-sa/4.0/|||#\
1391 CC-BY-NC-ND||by-nc-nd/4.0/|||#CC-BY-NC||by-nc/4.0/|||#CC-BY||by/4.0/|||#\
1392 cc-pd|||||http://creativecommons.org/publicdomain/#CDDL|CDDL-1.0||||#\
1393 CECILL|CECILL-2.1||||#Eclipse|EPL-1.0||||#EPL|EPL-1.0||||#FDL|||fdl||#\
1394 GPL|gpl-license||gpl|gpl.txt|#GPL2|GPL-2.0||old-licenses/gpl-2.0||#\
1395 GPL3|GPL-3.0||gpl|gpl.txt|#ISC|ISC||||#LGPL|lgpl-license||lgpl||#\
1396 LGPL2|||old-licenses/lgpl-2.0||#\
1397 LGPL2.1|LGPL-2.1||old-licenses/lgpl-2.1|lgpl.txt|#LGPL3|LGPL-3.0||lgpl||#\
1398 LPPL|LPPL-1.3c||||#MIT|MIT|||mit.txt|#MPL|MPL-2.0|||mozilla.txt|#\
1399 MPL2|MPL-2.0||||#PublicDomain|||||http://creativecommons.org/publicdomain/#\
1400 QPL|QPL-1.0||||#SIL_OFL|OFL-1.1||||#OFL|OFL-1.1||||#zlib/libpng|Zlib||||" | \
1401 awk -vlicenses="$(. $PKGS_DB/installed/$pkg/receipt; echo "$LICENSE")" \
1402 -vtext="$(_ '%s license on %s website' %s %s)" \
1403 -vro="$(_ 'Read online:')" -vrl="$(_ 'Read local:')" \
1404 -vofflic="$OFFLINE" '
1405 BEGIN{ FS="|"; RS="#"; split(licenses, lic, " "); if (offlic) OFFLINE[0]=offlic }
1406 function link1(u, l, ll, w) {
1407 return sprintf("\t<li><a href=\"%s%s\">" text "</a></li>", u, l, "<b>" ll "</b>", w) }
1408 function link2(u, l, ll) {
1409 return sprintf("\t<li><a href=\"%s%s\">%s</b></a></li>", u, l, ll) }
1410 function link_osl(n) {
1411 return link1("http://opensource.org/licenses/", n, n, "OSL") }
1412 function link_cc(n) {
1413 split(n, ll, "/")
1414 return link1("http://creativecommons.org/licenses/", n, ll[1], "Creative Commons") }
1415 function link_gnu(n) {
1416 split(n, ll, "/")
1417 return link1("https://www.gnu.org/licenses/", n ".html", ll[2] ? ll[2] : ll[1], "GNU") }
1418 function link_loc(n) {
1419 return link2("?license=/usr/share/licenses/", n, "licenses/<b>" n "</b>") }
1420 function link_url(n) {
1421 return link2(n, "", n) }
1423 if ($1 == lic[1] || $1 == lic[2] || $1 == lic[3] || $1 == lic[4]) {
1424 if ($2) ONLINE[$2]=link_osl($2)
1425 if ($3) ONLINE[$3]=link_cc($3)
1426 if ($4) ONLINE[$4]=link_gnu($4)
1427 if ($5) OFFLINE[$5]=link_loc($5)
1428 if ($6) OFFLINE[$6]=link_url($6)
1431 END{
1432 if (length(ONLINE) > 0) { print "<p>" ro "</p>\n<ul>"; for (o in ONLINE) print ONLINE[o]; print "</ul>" }
1433 if (length(OFFLINE) > 0) { print "<p>" rl "</p>\n<ul>"; for (o in OFFLINE) print OFFLINE[o]; print "</ul>" }
1434 }'
1435 fi ;;
1436 esac
1437 ;;
1440 *\ tags\ *)
1442 # Show tag cloud
1444 tazpanel_header "$(_ 'Tags list')"
1446 brepo="<b>$repo</b>"
1447 case $repo in
1448 Any) title="$(_ 'List of tags in all repositories')" ;;
1449 *) title="$(_ 'List of tags in repository "%s"' "$brepo")" ;;
1450 esac
1451 echo "<p>$title</p><p id=\"tags\">"
1452 to_read=''
1453 for i in $(repo_list ''); do
1454 if [ -e "$i/packages.info" ]; then
1455 to_read="$to_read $i/packages.info"
1456 elif [ -e "$i/installed.info" ]; then
1457 to_read="$to_read $i/installed.info"
1458 fi
1459 done
1461 TAGS="$(awk -F$'\t' '{if($6){print $6}}' $to_read | tr ' ' $'\n' | sort | uniq -c)"
1462 MAX="$(echo "$TAGS" | awk '{if ($1 > MAX) MAX = $1} END{print MAX}')"
1463 echo "$TAGS" | awk -vMAX="$MAX" '{
1464 printf "<a class=\"tag%s\" href=\"?tag=%s\" title=\"%s\">%s</a> ", int($1 * 7 / MAX + 1), $2, $1, $2
1465 }'
1466 echo "</p>"
1467 ;;
1470 *\ tag\ *)
1472 # Show packages with matching tag
1474 tag=$(GET tag)
1475 tazpanel_header "$(_ 'Tag "%s"' $tag)"
1477 [ "$REMOTE_USER" == 'root' ] && cat <<EOT
1478 <section>
1479 <div>$(_ 'Selected packages:') <span id="countSelected"></span></div>
1480 <footer>
1481 $(show_button do=Install do=Chblock do=Remove | sed 's|button |button form="pkglist" |g')
1482 $(show_button toggle)
1483 </footer>
1484 </section>
1485 EOT
1486 cat <<EOT
1487 <form id="pkglist" class="wide">
1488 EOT
1489 for i in $(repo_list ""); do
1490 show_list all
1491 done
1492 cat <<EOT
1493 </form>
1494 <script type="text/javascript">window.onscroll = scrollHandler; setCountSelPkgs();</script>
1495 EOT
1496 ;;
1499 *\ blocked\ *)
1501 # Show blocked packages list
1503 tazpanel_header "$(_ 'Blocked packages list')"
1505 cat <<EOT
1506 <section>
1507 <div>$(_ 'Selected packages:') <span id="countSelected"></span></div>
1508 <footer>
1509 $(show_button do=Unblock | sed 's|button |button form="pkglist" |g')
1510 $(show_button toggle)
1511 </footer>
1512 </section>
1514 <form id="pkglist" class="wide">
1515 EOT
1516 table_head
1517 for i in $(cat "$BLOCKED"); do
1518 awk -F$'\t' -vp="$i" '
1519 $1 == p {
1520 printf "<tr><td><input type=\"checkbox\" name=\"pkg\" value=\"%s\">", $1
1521 printf "<a data-icon=\"@pkgib@\" href=\"?info=%s\">%s</a>", gensub(/\+/, "%2B", "g", $1), $1
1522 printf "</td><td>%s</td><td>%s</td><td>", $2, $4
1523 printf "<a href=\"%s\"></a></td></tr>\n", $5
1525 ' $PKGS_DB/installed.info
1526 done
1527 cat <<EOT
1528 </tbody>
1529 </table>
1530 </form>
1531 <script type="text/javascript">window.onscroll = scrollHandler; setCountSelPkgs();</script>
1532 EOT
1533 ;;
1536 *\ improve\ *)
1538 # Improving packages by the community effort
1540 pkg=$(GET improve)
1541 tazpanel_header "$(_ 'Improve package "%s"' $pkg)"
1543 msg warn 'Under construction!<br/>It is only imitation of working'
1545 user=$(POST user); type=$(POST type); text="$(POST text)"
1546 login=$(POST login); password=$(POST password)
1548 login_c=$(COOKIE login); password_c=$(COOKIE password)
1549 mail_hash=$(COOKIE mail_hash); user_name=$(COOKIE user_name)
1551 n=$'\n'
1553 if [ -n "$login" ]; then
1554 # Get mail hash and user Name from bugs.slitaz.org
1555 page="$(busybox wget --post-data "auth=${login}&pass=${password}&id=" \
1556 -O- "http://bugs.slitaz.org/bugs.cgi?user=${login}")"
1557 # Parse page and get:
1558 mail_hash="$(echo "$page" | fgrep '<h2>' | cut -d/ -f5 | cut -c 1-32)"
1559 user_name="$(echo "$page" | fgrep '<h2>' | cut -d'>' -f3 | cut -d'<' -f1)"
1561 # Put variables to the session Cookies (they clean in browser close)
1562 cat <<EOT
1563 <script type="text/javascript">
1564 document.cookie = "login=$login";
1565 document.cookie = "password=$password";
1566 document.cookie = "mail_hash=$mail_hash";
1567 document.cookie = "user_name=$user_name";
1568 </script>
1569 EOT
1570 login_c="$login"; password_c="$password"
1571 fi
1573 if [ -z "$login_c" ]; then
1574 cat <<EOT
1575 <section>
1576 <div>$(_ 'Please log in using your TazBug account.')</div>
1577 <form method="post">
1578 <input type="hidden" name="improve" value="$pkg"/>
1579 <table>
1580 <tr><td>$(_ 'Login:')</td>
1581 <td><input type="text" name="login"/></td></tr>
1582 <tr><td>$(_ 'Password:')</td>
1583 <td><input type="password" name="password"/></td></tr>
1584 <tr><td colspan="2">
1585 <label><input type="checkbox" name="rememberme"/>$(_ 'Remember me')</label></td></tr>
1586 <tr><td colspan="2">
1587 <button type="submit" data-icon="@user@">$(_ 'Log in')</button></td></tr>
1588 </table>
1589 </form>
1590 <footer>
1591 <a href="http://bugs.slitaz.org/bugs.cgi?signup&online" target="_blank">$(_ 'Create new account')</a>
1592 </footer>
1593 </section>
1594 EOT
1595 xhtml_footer; exit 0
1596 fi
1599 # Get receipt variables, show Install/Remove buttons
1600 if [ -d $INSTALLED/$pkg ]; then
1601 . $INSTALLED/$pkg/receipt
1602 else
1603 cd $PKGS_DB
1604 eval "$(awk -F$'\t' -vp=$pkg '
1605 $1==p{
1606 printf "VERSION=\"%s\"; SHORT_DESC=\"%s\"; TAGS=\"%s\"; ", $2, $4, $6
1607 }' packages.info undigest/*/packages.info)"
1608 fi
1610 RECEIPT="$(wget -O - http://hg.slitaz.org/wok/raw-file/tip/$pkg/receipt | htmlize)"
1611 DESCRIPTION="$(wget -O - http://hg.slitaz.org/wok/raw-file/tip/$pkg/description.txt | htmlize)"
1612 DESCRIPTION="$(separator)$n${DESCRIPTION:-(empty)}$n$(separator)"
1614 if [ -z "$type" ]; then
1615 cat <<EOT
1616 <section>
1617 <header>
1618 $(_ 'Improve package "%s"' $pkg)
1619 <form><button name="info" value="$pkg" data-icon="@back@">$(_ 'Back')</button></form>
1620 </header>
1622 <div style="display:none">
1623 <span id="newVersion">Current version: $VERSION${n}New version: $VERSION${n}Link to announce: http://</span>
1624 <span id="improveShortDesc">Short description (English):$n$SHORT_DESC</span>
1625 <span id="translateShortDesc">Short description (English):$n$SHORT_DESC$n${n}Language: $LANG${n}Short description:$n$SHORT_DESC</span>
1626 <span id="improveDesc">Description (English):$n$DESCRIPTION</span>
1627 <span id="translateDesc">Language: $LANG${n}Description:$n$DESCRIPTION</span>
1628 <span id="improveCategory">Old category: $CATEGORY${n}New category: $CATEGORY</span>
1629 <span id="improveTags">Tags: $TAGS</span>
1630 <span id="addIcon">Link to application icon (48x48px): http://</span>
1631 <span id="addScreenshot">Link to application screenshot: http://</span>
1632 <span id="improveReceipt">$RECEIPT</span>
1633 <span id="improveOther"></span>
1634 </div>
1636 <form method="post" class="wide">
1638 <table class="wide">
1639 <tr><td style="vertical-align:bottom">
1640 <input type="hidden" name="improve" value="$pkg"/>
1641 <input type="hidden" name="user" value="$login_c"/>
1642 &nbsp;$(_ 'How can you help:')<br/>
1643 <select name='type' id="improveType" onchange="improveAction()">
1644 <option value=''>$(_ 'Please select an action')
1645 <option value='newVersion'>$(_ 'Report new version')
1646 <option value='improveShortDesc'>$(_ 'Improve short description')
1647 <option value='translateShortDesc'>$(_ 'Translate short description')
1648 <option value='improveDesc'>$(_ 'Add or improve description')
1649 <option value='translateDesc'>$(_ 'Translate description')
1650 <option value='improveCategory'>$(_ 'Improve category')
1651 <option value='improveTags'>$(_ 'Add or improve tags')
1652 <option value='addIcon'>$(_ 'Add application icon')
1653 <option value='addScreenshot'>$(_ 'Add application screenshot')
1654 <option value='improveReceipt'>$(_ 'Improve receipt')
1655 <option value='improveOther'>$(_ 'Other')
1656 </select>
1657 </td>
1658 <td id="user_info">$user_name
1659 <img src="http://www.gravatar.com/avatar/$mail_hash?s=48&amp;d=identicon"
1660 style="border-radius: 0.3rem"/>
1661 </td></tr>
1662 </table>
1664 <textarea name="text" id="improveText" style="width:100%; resize: vertical; min-height:10rem"></textarea>
1665 <footer>
1666 <button type="submit" data-icon="@slitaz@">$(_ 'Send')</button>
1667 </footer>
1668 </form>
1669 </section>
1670 EOT
1671 else
1672 cat <<EOT
1673 <section>
1674 <header>
1675 $(_ 'Thank you!')
1676 <form><button name="info" value="$pkg" data-icon="@back@">$(_ 'Back')</button></form>
1677 </header>
1678 <div>The following information was sent to SliTaz developers:</div>
1679 <pre class="scroll"><b>User:</b> $user
1680 <b>Type:</b> $type
1681 <b>Package:</b> $pkg
1682 <b>Message:</b>
1683 $(echo "$text" | htmlize)</pre>
1684 </section>
1685 EOT
1686 fi
1687 ;;
1690 *)
1692 # Default to summary
1694 tazpanel_header
1695 loading_msg
1697 cat <<EOT
1698 <form>
1699 EOT
1700 fslink=$(readlink $PKGS_DB/fslink)
1701 [ -n "$fslink" -a -d "$fslink/$INSTALLED" ] && show_button linkable
1702 show_button recharge up admin
1703 cat <<EOT
1704 </form>
1706 <section>
1707 <header>$(_ 'Summary')</header>
1709 <table class="wide zebra">
1710 <tr>
1711 <td>$(_ 'Last recharge:')</td>
1712 <td>$(list=$PKGS_DB/ID
1713 if [ -e $list ]; then
1714 # Timezone offset as string, ex. '+0200' for EET (+2 hours)
1715 ohhmm="$(date +%z)"
1716 # Timezone offset in the seconds
1717 offset=$(( 60 * (60 * ${ohhmm:0:3} + ${ohhmm:3:2}) ))
1718 daynow=$(( ($(date +%s) + $offset) / 86400 ))
1719 dayupd=$(( ($(date -r $list +%s) + $offset) / 86400 ))
1720 days=$(( $daynow - $dayupd ))
1721 time=$(date -r $list +%R)
1722 ago="$(_p '%d day ago.' '%d days ago.' $days $days)"
1723 case $days in
1724 0) _ 'Today at %s.' $time;;
1725 1) _ 'Yesterday at %s.' $time;;
1726 [2-9]) echo $ago;;
1727 *) echo "<span style='color:red'>$ago</span>"
1728 _ 'It is recommended to [recharge] the lists.' | \
1729 sed 's|\[|<a data-icon="@refresh@" href="?recharge">|;s|\]|</a>|';;
1730 esac
1731 else
1732 _ 'never.'
1733 _ 'You need to [download] the lists for further work.' | \
1734 sed 's|\[|<a data-icon="@download@" href="?recharge" data-root>|;s|\]|</a>|'
1735 fi)</td></tr>
1736 <tr>
1737 <td>$(_ 'Installed packages:')</td>
1738 <td><a href="?list&amp;my=my&amp;cat=all&amp;repo=Any">
1739 <b>$(cat $PKGS_DB/installed.info | wc -l)</b>
1740 </a></td></tr>
1741 <tr>
1742 <td>$(_ 'Mirrored packages:')</td>
1743 <td><a href="?list&amp;my=no&amp;cat=all&amp;repo=Any">
1744 <b>$(cat $PKGS_DB/packages.list | wc -l)</b>
1745 </a></td></tr>
1746 <tr>
1747 <td>$(_ 'Upgradeable packages:')</td>
1748 <td><a href="?up">
1749 <b>$(cat $PKGS_DB/packages.up | wc -l)</b>
1750 </a></td></tr>
1751 <tr>
1752 <td>$(_ 'Installed files:')</td>
1753 <td><b>$(cat $INSTALLED/*/files.list | wc -l)</b></td></tr>
1754 <tr>
1755 <td>$(_ 'Blocked packages:')</td>
1756 <td><a href="?blocked">
1757 <b>$(wc -l < "$BLOCKED")</b>
1758 </a></td></tr>
1759 </table>
1760 </section>
1763 <section>
1764 <header>
1765 $(_ 'Latest log entries')
1766 <form action="index.cgi">
1767 <button name="file" value="$LOG" data-icon="@view@">$(_ 'Show')</button>
1768 </form>
1769 </header>
1770 <pre>$(tail -n 5 $LOG | tac | fgrep "-" | awk '{print $1, $2, $3, $4, $5, "<a href=\"?info=" $6 "\">" $6 "</a>", $7}')</pre>
1771 </section>
1772 EOT
1773 ;;
1774 esac
1776 # xHTML 5 footer
1777 xhtml_footer
1778 exit 0