#!/bin/bash
#
# cleanpackagecache.sh
# Cleans old versions of packages from /var/tmp/osbuild-packagecache
# Tejas Guruswamy <masterpatricko@gmail.com> 2009
# 
# Usage: cleanpackagecache.sh [-q|--quiet] [-np|--noprogressind]


function simple_progress_indicator {
  chars=( "-" "\\" "|" "/" )
  interval=1
  count=0
 
  while true
  do
    pos=$(($count % 4))
 
    echo -en "\b${chars[$pos]}"
 
    (( count++ ))
    sleep $interval
  done
}

function stop_progress_indicator {
  kill $1 2>/dev/null
  echo
}

function awesome_progress_indicator {
  length=50
  barlength=$(( $1 * $length / 100 ))
  spacelength=$(( $length - $barlength ))
  progressbox=$(
    bar=$(printf "%*s" $barlength ""); echo -n "[${bar// /#}"
    spaces=$(printf "%*s" $spacelength ""); echo -n "${spaces}] ${1}%")
  backspaces=$(printf "%*s" ${#progressbox} "")
  echo -en "${backspaces// /\b}"
  echo -n "$progressbox"
}

E_BADARGS=255
E_DIRMISSING=244

NOPROGRESSIND=false
QUIET=false

while [ $# -gt 0 ]; do    # Until you run out of parameters . . .
  case "$1" in
    -q|--quiet)
      QUIET=true
      NOPROGRESSIND=true
      ;;
    -np|--noprogressind)
      NOPROGRESSIND=true
      ;;
    --help)
      echo "Usage: $(basename $0) [-q|--quiet] [-np|--noprogressind] [--help]."
      echo "Remove obsolete rpm files from /var/tmp/osbuild-packagecache."
      echo -e "  -q, --quiet\t\tsupress all output"
      echo -e "  -np, --noprogressind\tdo not display the progress indicators (provides a performance boost)"
      echo -e "  --help\t\tdisplay this usage message"
      echo -e "\nWritten by Tejas Guruswamy <masterpatricko@gmail.com>"
      exit
      ;;
    *)
      echo "Unrecognised argument. See $(basename $0) --help." >&2
      exit $E_BADARGS
      ;;
  esac
  shift       # Check next set of parameters.
done

if [ ! -d "/var/tmp/osbuild-packagecache" ]; then
	echo "No package cache dir found." >&2
	exit $E_DIRMISSING
fi

txttempdir=$(mktemp -d)

trap 'if [ -n $pid ]; then stop_progress_indicator $pid; fi; if [ -d $txttempdir ]; then rm -rf $txttempdir; fi; exit' TERM INT EXIT

oldsize=$(du -s /var/tmp/osbuild-packagecache | cut -f1)

$QUIET || echo "Using temporary directory: $txttempdir"
progress=0

$QUIET || echo -n "Executing rpm command ...   "

$NOPROGRESSIND || simple_progress_indicator &
$NOPROGRESSIND || pid=$!
find /var/tmp/osbuild-packagecache -type f -name "*.rpm" -print0 | xargs -0 rpm -qp --queryformat="%{NAME} %{VERSION}.%{RELEASE} %{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm\n" | sort > ${txttempdir}/filelist.txt
$NOPROGRESSIND || stop_progress_indicator $pid
$NOPROGRESSIND || unset pid 

$QUIET || echo "Splitting files by rpm ... "

totallines=$(wc -l ${txttempdir}/filelist.txt | cut -f1 -d' ')
k=0
progress=0
while read txtline; do
  (( k++ ))
  (( progress = totallines>0?(k * 100 / $totallines):100 ))
  $NOPROGRESSIND || awesome_progress_indicator $progress
  packagename=$(echo "$txtline" | cut -f1 -d' ')
  echo "$txtline" >> ${txttempdir}/${packagename}.txt
done < ${txttempdir}/filelist.txt

$QUIET || echo
$QUIET || echo "Choosing rpms to delete ... "

totallines=$(ls ${txttempdir} | wc -l)
k=0
progress=0
ls "$txttempdir" | while read txtfilename; do
  (( k++ ))
  (( progress = totallines>0?(k * 100 / $totallines):100 ))
  $NOPROGRESSIND || awesome_progress_indicator $progress
  if [ "$txtfilename" = "filelist.txt" -o "$txtfilename" = "filestodelete.txt" ]; then
  continue
  fi
  sort -k2 -V "${txttempdir}/${txtfilename}" | head -n'-1' | cut -f3 -d' ' >> ${txttempdir}/filestodelete.txt
done

$QUIET || echo
$QUIET || echo "Deleting unused rpms ... "

totallines=$(wc -l ${txttempdir}/filestodelete.txt | cut -f1 -d' ')
k=0
progress=0
while read txtline; do
  (( k++ ))
  (( progress = totallines>0?(k * 100 / $totallines):100 ))
  $NOPROGRESSIND || awesome_progress_indicator $progress
  find /var/tmp/osbuild-packagecache -type f -name "$txtline" -delete
done < ${txttempdir}/filestodelete.txt

$QUIET || echo
$QUIET || echo " ---- "
newsize=$(du -s /var/tmp/osbuild-packagecache | cut -f1)
sizefree=$((oldsize - newsize))
$QUIET || echo "Files deleted: $(wc -l ${txttempdir}/filestodelete.txt | cut -f1 -d' ') out of $(wc -l ${txttempdir}/filelist.txt | cut -f1 -d' ') packages."
if [ $sizefree -ge 1024 ]; then
  $QUIET || echo "$(( $sizefree / 1024 ))M recovered."
else
  $QUIET || echo "${sizefree}K recovered."
fi
$QUIET || echo "Finished."
exit
