#!/bin/bash # ******************************************************************* # ** @file browse-packages browse a given set of packages # ** # ** Creation: 2013-01-13 dv # ** Last update: $Id$ # ** # ** Copyright (c) 2013-@@YEAR@@ the eisfair team, team(at)eisfair(dot)org # ** # ** This program is free software; you can redistribute it and/or modify # ** it under the terms of the GNU General Public License as published by # ** the Free Software Foundation; either version 2 of the License, or # ** (at your option) any later version. # ******************************************************************* . /var/install/include/eislib . /var/install/include/eismanlib PACKIDX="0" # ******************************************************************* # ** show help on arguments and possible options # ** @param n/a # ** @return n/a # ******************************************************************* show_help() { cat <&1 else eisman install \ --info \ --url="${urlbase}" \ --output="/tmp/tmpresult$$" \ --unstable \ "${name}"="${version}" 2>&1 fi # evaluate exit code if [ "${?}" -ne 0 ] then IFS=${IFS_BAK} rm -f "/tmp/tmpresult$$" anykey return fi # get result text="$(cat /tmp/tmpresult$$)" rm -f "/tmp/tmpresult$$" # print result for line in $text do # in case of an error, we print it on the screen # using bright red color and exit the loop if [ "${line:0:6}" = "error:" ] then mecho -n " " mecho --error "${line}" mecho " " IFS=${IFS_BAK} anykey return fi echo " ${line}" done IFS=${IFS_BAK} local res=$(/var/install/bin/ask 'Install package' 'no') # if ask break, ask returned 255 if [ $? = 255 ] then res='no' fi if [ "${res}" = "yes" ] then if [ "${status}" = "stable" ] then eisman install --auto --url="${urlbase}" "${name}"="${version}" else eisman install --auto --url="${urlbase}" --unstable "${name}"="${version}" fi fi } # ******************************************************************* # ** show details of a selected package # ** @param $1 index in list of packages # ** @return n/a # ******************************************************************* uninstall_package() { local name=$1 eisman uninstall "${name}" } # ******************************************************************* # ** show details of a selected package # ** @param $1 index in list of packages # ** @return n/a # ******************************************************************* show_package_detail() { local idx="${1}" local urlbase eval local name='$PACKAGE_'${idx}'_NAME' eval local version='$PACKAGE_'${idx}'_VERSION' eval local short='$PACKAGE_'${idx}'_SHORT' eval local status='$PACKAGE_'${idx}'_STATUS' eval local url='$PACKAGE_'${idx}'_URL' urlbase="$(get_base_url ${url})" if [ "${work_on_installed}" = "yes" ] then option="--installed" else option="--url=${urlbase}" fi local date=$(query_first 'date' "${name}" "${version}" "${option}") local author=$(query_first 'author' "${name}" "${version}" "${option}") local section=$(query_first 'section' "${name}" "${version}" "${option}") local text=$(query_first 'text' "${name}" "${version}" "${option}") clrhome mecho --info "Package: ${short}" echo echo " $(mecho --warn "Name: ") ${name}" echo " $(mecho --warn "Package: ") ${short}" echo " $(mecho --warn "Version: ") ${version}" echo " $(mecho --warn "Date: ") ${date}" echo " $(mecho --warn "Author: ") ${author}" echo " $(mecho --warn "Status: ") ${status}" echo " $(mecho --warn "Section: ") ${section}" echo " $(mecho --warn "Url: ") ${url}" echo local IFS_BAK=$IFS IFS=" " for line in $text do echo " ${line}" done IFS=${IFS_BAK} if [ "${enable_install}" = "yes" ] then install_package "${name}" "${version}" "${status}" "${urlbase}" echo anykey elif [ "${enable_uninstall}" = "yes" ] then uninstall_package "${name}" echo anykey else anykey return fi } # ******************************************************************* # ** add a package to the list stored in # ** PACKAGE_%_NAME # ** PACKAGE_%_VERSION # ** PACKAGE_%_STATUS # ** PACKAGE_%_URL # ** PACKAGE_%_SHORT # ** @param $1 package # ** @param $2 version # ** @param $3 status # ** @param $4 url # ** @param $5 short # ** @return n/a # ******************************************************************* add_package() { local package="${1}" local version="${2}" local status="${3}" local url="${4}" local short="${5}" local date="${6}" PACKIDX=$(($PACKIDX + 1)) eval 'PACKAGE_'$PACKIDX'_NAME'='$package' eval 'PACKAGE_'$PACKIDX'_VERSION'='$version' eval 'PACKAGE_'$PACKIDX'_SHORT'='$short' eval 'PACKAGE_'$PACKIDX'_STATUS'='$status' eval 'PACKAGE_'$PACKIDX'_URL'='$url' eval 'PACKAGE_'$PACKIDX'_DATE'='$date' } # ******************************************************************* # ** show current progress in percent # ** @param $1 progress in percent # ** @return n/a # ******************************************************************* show_progress() { echo -en "\033[7D" printf "[%3d%%] loading..." "${1}" echo -en "\033[10D" } # ******************************************************************* # ** read query result specified in "browsefile" and store it's # ** content into an array struture. Check for double occurance of # ** packages. # ** @param $1 browse-file with query result # ** @return n/a # ******************************************************************* read_packages() { local browsefile="${1}" local idx=0 local name local status local version local url local short local date local progress='0' local linecount='0' local linetotal # clear screen clrhome # get total number of lines in index linetotal=$(wc -l < ${browsefile}) # init progress display echo -n " " show_progress 0 # read browse data line by line while read -r do local line=$REPLY local field="${line:0:${FIELDHEADER}}" local data="${line:${FIELDHEADER}}" if [ "${field}" = "-----------" ] then if [ "${name}" ] then add_package "${name}" "${version}" "${status}" "${url}" "${short}" "${date}" fi name='' status='' version='' url='' short='' date='' else case ${field} in name*) name="${data}" ;; status*) status="${data}" ;; version*) version="${data}" ;; url*) url="${data}" ;; short*) short="${data}" ;; date*) date="${data}" ;; esac fi # update progress idx=$((${idx} + 1)) if [ ${idx} -ge 50 ] then linecount=$((${linecount} + 50)) progress=$((${linecount} * 100 / ${linetotal})) show_progress "${progress}" idx=0 fi done < ${browsefile} # show final progress show_progress 100 echo } # ******************************************************************* # ** print array content to the screen starting with the given # ** offset # ** @param $1 message to prompt at the top of the screen # ** @param $2 starting index within package array (starting with 1) # ** @param $3 max. number of packages per page # ** @return n/a # ******************************************************************* show_page() { local message=${1} local startidx=${2} local length=${3} # check for max. index if [ "$((${startidx} + ${length} - 1))" -gt "${PACKIDX}" ] then length=$((${PACKIDX} - ${startidx} + 1)) fi local endidx=$((${startidx} + ${length} - 1)) # show the page header clrhome mecho --info "$message" mecho "" if [ "${PACKIDX}" -eq "0" ] then mecho " Available packages: no packages found!" else mecho " Available packages: (${startidx}-${endidx} of ${PACKIDX} total)" fi mecho "" techo --begin '6r 3l 3 11 46* 11' # show packages local idx="${startidx}" while [ ${idx} -le ${endidx} ] do eval local name='$PACKAGE_'$idx'_NAME' eval local version='$PACKAGE_'$idx'_VERSION' eval local short='$PACKAGE_'$idx'_SHORT' eval local status='$PACKAGE_'$idx'_STATUS' eval local url='$PACKAGE_'$idx'_URL' eval local date='$PACKAGE_'$idx'_DATE' local result=$(eisman check "${name}" "${version}") case "${result}" in "installed") inst_status='--info i' ;; "old") inst_status='--std o' ;; "new") inst_status='--warn n' ;; *) inst_status='--warn -' ;; esac version_length=${#version} short_length=${#short} # set the output string case "${status}" in 'stable') p_status='S:' ;; 'testing') p_status='T:' ;; *) p_status='U:' ;; esac techo --row "${idx}." ${inst_status} "${p_status}" \ "${version}" "${short}" "${date}" idx=$(($idx + 1)) done techo --end # set newline before footer if SCROLL given if [ "${SCROLL}" = "yes" ] then echo;echo;echo fi # show legend and refresh screensize first refresh_screensize gotoxy 1 $((${_EISLIB_SCREENSIZE_Y} - 3)) echo echo -n "$(mecho --warn '-') = not installed " echo -n "$(mecho --warn 'n') = New " echo -n "o = Old " echo "$(mecho --info 'i') = Installed" # show hint if SCROLL given if [ "${SCROLL}" = "yes" ] then if [ ${_EISLIB_SCREENSIZE_Y} -lt $((${idx} + 6)) ] then mecho --info 'Use SHIFT + PAGE-UP to scroll up' else echo fi else echo fi } # ******************************************************************* # ** print array content to the screen and ask for user input. # ** The user can browse the list page by page using n=next page and # ** p=previous key entries # ** @param $1 message to prompt at the top of the screen # ** @return n/a # ******************************************************************* browse_packages() { local message="${1}" local idx=1 while true do # get max. number of packages per page local linespp=$((${_EISLIB_SCREENSIZE_Y} - 9)) # set linespp to max if SCROLL given if [ "${SCROLL}" = "yes" ] then linespp='100000' fi # show page content show_page "${message}" "${idx}" "${linespp}" _ask_tmpfile=$(/usr/bin/mktemp -t XXXXXXXXXXXXX) # wait for user selection if [ ${idx} -gt 1 ] then if [ $(($idx + $linespp)) -gt ${PACKIDX} ] then /var/install/bin/ask 'Select' '' "1-${PACKIDX}" \ 'p=previous' '^$=Return' '0=Exit' >${_ask_tmpfile} else /var/install/bin/ask 'Select' '' "1-${PACKIDX}" \ 'p=previous' 'n=next page' '^$=Return' '0=Exit' >${_ask_tmpfile} fi else if [ $(($idx + $linespp)) -gt ${PACKIDX} ] then /var/install/bin/ask 'Select' '' "1-${PACKIDX}" \ '^$=Return' '0=Exit' >${_ask_tmpfile} else /var/install/bin/ask 'Select' '' "1-${PACKIDX}" \ 'n=next page' '^$=Return' '0=Exit' >${_ask_tmpfile} fi fi # fetch user selection local rc="${?}" local answer read answer < ${_ask_tmpfile} rm -f ${_ask_tmpfile} if [ ${rc} = 255 ] then answer=0 fi # evaluate user selection case "${answer}" in '') exit 0 ;; 0) exit 127 ;; 'n') idx=$(($idx + $linespp)) ;; 'p') idx=$(($idx - $linespp)) if [ ${idx} -lt 1 ] then idx=1 fi ;; *) show_package_detail ${answer} ;; esac done } # ******************************************************************* # ** main program # ******************************************************************* main() { message='Select one of the available packages by entering the number' work_on_installed='yes' enable_install='no' enable_uninstall='no' # read option switches while [ "${1:0:2}" = "--" ] do case ${1} in --help) show_help exit 0 ;; --message) shift message="${1}" shift ;; --message=*) message="${1:10}" shift ;; --install) work_on_installed="no" enable_install="yes" shift ;; --uninstall) work_on_installed="yes" enable_uninstall="yes" shift ;; *) echo "error: invalid option switch \"$1\"!" >&2 exit 1 ;; esac done # get parameters if [ "$#" -eq 1 ] then browsefile="$1" else echo 'error: invalid number of arguments!' >&2 exit 1 fi # start browsing if [ -f "${browsefile}" ] then read_packages "${browsefile}" browse_packages "${message}" else echo 'error: browse file not found!' >&2 exit 1 fi exit 0 } # --------------------------------------------------------------------------- # call function main # --------------------------------------------------------------------------- main "${@}" # --------------------------------------------------------------------------- # end # ---------------------------------------------------------------------------