#!/bin/sh
# File-Header {{{
# Filename:     msgid-chooser
# Purpose:      prompt for message-id and get it from newsserver
# Author:       Michael Prokop / www.michael-prokop.at / www.grml.org
# Requires:     netcat [optional: dialog, dialog, klipper/dcop]
# Tested On:    Debian Linux: bash 2.05b.0; zsh 4.2.0
# Category:     Usenet/Utilities
# Availability: http://www.michael-prokop.at/computer/config/bin/msgid-chooser
# Latest change: Don Aug 19 08:56:50 CEST 2004
# }}}
################################################################################
# FAQ {{{
# ====
# Q: I've pasted a message-id into the dialog-interface and want to remove
#    the content of the dialog faster than pressing backspace multiple times.
# 
# A: use the readline-capabilties of your terminal
#    e.g. ctrl+u -> del to start of line
# 
# Q: I get a "381 PASS required 502 Authentication error" error?!
#
# A: See "TODO"-section. Currently authentication isn't supported for more
#    than one server.
#
# Q: I found a bug.
#
# A: Please report it to <msgid-chooser@michel-prokop.at>.
# }}}
################################################################################
# Version Information {{{
# 0.6:   fixed update-option [Bug-Report by Karl Voit];
#        fixed COLOR-function;
#        improved protability of script;
#        improved error-handling;
#        added FAQ and additional comments;
# 0.5:   added option '--version' additionally to '-v';
#        created debian-package including manual-page;
# 0.4:   update-option (-u or --update);
# 0.3:   support user-authentication on newsserver;
#        do some error handling if no valid message-id given
#        e.g.: too many "<>" or missing ones;
# 0.2:   support ~/.msgid-chooser and newsserver-menu;
# 0.1:   first working release;

# Contributions (alphabetical order):
# Andreas Gredler:  shell-programming
# Karl Voit:        testing, feature-requests, bug-report(s)
# Martin Piskernig: testing, feature-requests
# Sven Guckes:      testing, feature-requests, ideas for error-handling (sed)

# TODO / FIXME / ideas:
# set username/password serverbased - list them at appropriating server(?)
# support more than 5 newsservers (dynamic menu)
# improve portability
# improve checking for available programs
# improve option-parsing [use of getopt()]
# improve $TMP-STUFF (http://www.shelldorado.com/goodcoding/tempfiles.html)
# use of trap(?)
# }}}
################################################################################
# Notes {{{
# Of course something like the following function could replace this script:
#
# function GG {
#   wget -U links "http://groups.google.de/groups?selm=$1&output=gplain" \
#        -O ${2:=ARTICLE}
# }
#
# *but* groups.google.com does *not*:
#       * provide access to "X-No-Archive: Yes"-postings
#       * do some colorization-stuff like console-output does
#       * do some error-handling
#       * let you get postings from different newsserver (which may also
#         require authorization)
#       * provide realtime-access to postings (only daily archive)
# }}}
################################################################################
# Main Script {{{

# some variables
  PATH=${PATH:-'/bin/:/sbin/:/usr/local/bin:/usr/bin:/usr/sbin'}
  TMP=${TMPDIR:-/tmp}
  URL='http://www.michael-prokop.at/computer/config/bin/msgid-chooser'
  PN=`basename "$0"` # program name
  DN=`dirname  "$0"` # name of directory msgid-chooser is located in

# Does there exist a config file?
if [ -r $HOME/.msgid-chooser ]; then
  source $HOME/.msgid-chooser
fi

# Do you want colors?
if [ "$COLOR" == "no" ]; then
  export COLOR=no
else
  if [ "$COLORTERM" == "yes" ]; then
    export COLOR=yes
  fi
fi

# Which browser do you want to use for postings via google?
# Do you want to use a GUI-browser?
if [ "$DISPLAY" == "" ]; then
  if [ "$BROWSER" == "" ]; then
    export BROWSER=w3m
  fi
else
  if [ "$BROWSER" == "" ]; then
    export DISPLAY=:0
    export BROWSER='opera -remote openURL("$URL$",new-page)'
  fi
fi

# Which newsserver do want to set by default?
if [ "$MYNEWSSERVER" == "" ]; then
  #MYNEWSSERVER=aconews.univie.ac.at
  MYNEWSSERVER=usenet.univie.ac.at
fi

if ! [ -w $TMP ] ; then
  echo "$TMP not writeable. Sorry."
  exit -1
fi

#if [ "`which dialog 2>/dev/null`" ] ; then
if [ -x `which dialog` ]; then
  DIALOG=dialog
else
  echo "No dialog found. Sorry." ; exit -1;
fi

if [ "`which netcat 2>/dev/null`" ] ; then
  NC=netcat
else
  if [ "`which nc 2>/dev/null`" ] ; then
    NC=nc
  else
    echo "No netcat found. Sorry." ; exit -1;
  fi
fi

if [ "$COLOR" == "yes" ]; then
    RED="\033[40m\033[31m"
    BLUE="\033[40m\033[34m"
    NO_COLOUR="\033[0m"
  else
    RED=""
    BLUE=""
    NO_COLOUR=""
fi

# variable(s)
VERSION=0.6
UP2DATE=2004-06-21
POSTING_DOS=$TMP/posting.dos.$$
POSTING_UNIX=$TMP/posting.unix.$$

# dialog-stuff (non-console)
dialogprintmsg() {
  sed 's/
$//' $POSTING_DOS > $POSTING_UNIX
  rm $POSTING_DOS
  $DIALOG --colors --clear --title "Posting:" --textbox $POSTING_UNIX 0 0
}

dialoggetmsg() {
if [ "$USERAUTH" == "" ]; then
  echo -en "article ${DIAMSGID}\r\nquit\r\n" | $NC $DIANEWSSERVER 119 > $POSTING_DOS
  if [ "`grep '430 No such article' $POSTING_DOS `" ] ; then
    $DIALOG --yesno "Posting not found. Do you want to search for it at groups.google.com with $BROWSER?" 0 0
    SEL0=$?
    case $SEL0 in
      0) $SETDISPLAY
         URL=http://groups.google.at/groups\?selm=$DIAMSGID
         $BROWSER $URL
         exit -1
         ;;
      1) echo "Cancel key pressed" ;;
      255) echo "[ESCAPE] key pressed" ;;
    esac
  else
   dialogprintmsg
  fi
else
  echo -en "authinfo user $USERAUTH\r\nauthinfo pass $PASSWD\r\narticle ${DIAMSGID}\r\nquit\r\n" | $NC $DIANEWSSERVER 119 > $POSTING_DOS
  if [ "`grep '430 No such article' $POSTING_DOS `" ] ; then
    $DIALOG --yesno "Posting not found. Do you want to search for it at groups.google.com with $BROWSER?" 0 0
    SEL0=$?
    case $SEL0 in
      0) $SETDISPLAY
         URL=http://groups.google.at/groups\?selm=$DIAMSGID
         $BROWSER $URL
         exit -1
         ;;
      1) echo "Cancel key pressed" ;;
      255) echo "[ESCAPE] key pressed" ;;
    esac
  else
   dialogprintmsg
  fi
fi
}

# prompt for message-id
askformessageid() {
INPUT2=$TMP/input.$$
$DIALOG --backtitle "$PN" \
        --inputbox "Enter the posting's message-id:" 7 70 2>$INPUT2

SEL2=$?
DIAMSGID=`sed -e 's/^<*/</' -e 's/>*$/>/' $INPUT2`
#         sed -e 's/>\+/>/' -e 's/<\+/</'

if [ "`ps u | grep '[k]lipper'`" ] ; then 
  dcop --all-sessions --user $USER klipper klipper setClipboardContents "$DIAMSGID"
fi

case $SEL2 in
  0) if [ "$DIAMSGID" != "" ]; then
       dialoggetmsg
       rm $POSTING_UNIX $INPUT1 $INPUT2
     else
       $DIALOG --backtitle "$PN" --msgbox "Error: no message-id given. Quitting. \
                                         Press any key ..." 6 45
       rm $INPUT1 $INPUT2
     fi
     ;;
  1) echo "Cancel key pressed"
     rm $INPUT1 $INPUT2 ;;
  255) echo "[ESCAPE] key pressed" ;;
esac
}

setnewsserver() {
DIANEWSSERVER=$1
}

# list some default newsservers
# if you want to use this feature set $MYNEWSERVER1 to
# $MYNEWSERVER4 (at least 1 and 2) in ~/.mgsid-chooser
askforserver() {
INPUT1=$TMP/newsserver.$$

if [ "$MYNEWSSERVER1" != "" ] && [ "$MYNEWSSERVER2" != "" ]; then
  $DIALOG --menu "Which newsserver do you want to use?" 10 40 5 "Newsserver1:" $MYNEWSSERVER1 \
               "Newsserver2:" "$MYNEWSSERVER2" "Newsserver3:" "$MYNEWSSERVER3" \
               "Newsserver4:" "$MYNEWSSERVER4" "Alternative:" "another one" 2>$INPUT1

SEL3=`cat $INPUT1`

case $SEL3 in
  Newsserver1:) setnewsserver $MYNEWSSERVER1 && askformessageid ;;
  Newsserver2:) setnewsserver $MYNEWSSERVER2 && askformessageid ;;
  Newsserver3:) setnewsserver $MYNEWSSERVER3 && askformessageid ;;
  Newsserver4:) setnewsserver $MYNEWSSERVER4 && askformessageid ;;
  Newsserver5:) setnewsserver $MYNEWSSERVER5 && askformessageid ;;
  Alternative:) dynamicserver ;;
  1) echo "Cancel is Press" 
     rm $INPUT1;;
  255) echo "[ESCAPE] key pressed" ;;
esac

else
  dynamicserver
fi
}

# prompt for newsserver of $MYNEWSSERVER1/$MYNEWSSERVER2 is not set
dynamicserver() {
  $DIALOG --backtitle "$PN" \
          --inputbox "Enter the newsserver:" 8 70 "$MYNEWSSERVER" 2>$INPUT1

SEL1=$?
DIANEWSSERVER=`cat $INPUT1`

case $SEL1 in
  0) askformessageid ;;
  1) echo "Cancel is Press" 
     rm $INPUT1;;
  255) echo "[ESCAPE] key pressed" ;;
esac
}

# console-stuff (non-dialog)
consolegetmsg() {
if [ "$USERAUTH" == "" ]; then
  echo -en "article ${MSGID}\r\nquit\r\n" | $NC $NEWSSERVER 119 > $POSTING_DOS
else
  echo -en "authinfo user $USERAUTH\r\nauthinfo pass $PASSWD\r\narticle ${MSGID}\r\nquit\r\n" | $NC $NEWSSERVER 119 > $POSTING_DOS
fi
}

consoleprintmsg() {
  which sed 2>&1 1>/dev/null ; if [ "`echo $?`" != "0" ]; then
    echo "No sed found. Sorry." ; exit -1;
  fi

  which grep 2>&1 1>/dev/null ; if [ "`echo $?`" != "0" ]; then
    echo "No grep found. Sorry." ; exit -1;
  fi

  CODES=`grep -E "^[0-9]{3}\ " $POSTING_DOS`
  HEADER=`sed -e '/^
/q' $POSTING_DOS | grep -Ev "^[0-9]{3}\ "`
  BODY=`sed -rne '/^
/,/^\./p' $POSTING_DOS`
  echo -en "${RED}${HEADER}${NO_COLOUR}"
  echo -en "${BLUE}${BODY}${NO_COLOUR}\n"
  echo -e "\nServercodes:\n${CODES}"
}

# Start program
if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
cat << EOF
msgid-chooser: $VERSION [$UP2DATE]

msgid-chooser comes with ABSOLUTELY NO WARRANTY; for details type
\`msgid-chooser -vv'. msgid-chooser is free software, and you are
welcome to redistribute it under certain conditions; type
\`msgid-chooser -vv' for details.

Usage: $PN [<message-id>] [newsserver]
===========================================================================
If you want to use (the interactive tool) dialog use the following command:

$PN

If you don't want to use dialog (for example pipe
posting to \$PAGER), use the following command:

$PN <msg-id>

If you want to specify the newsserver use a second parameter:

$PN <msg-id> newsserver

Update msgid-chooser via option "-u" or "--update".

Print this help via option "-h" or "--help".

If you want to specify some values more static than via \$VARIABLE
you might want to use the file ~/.msgid-chooser - e.g.:

$ cat ~/.msgid-chooser
############ BOF ####################################################
# some defaults
DISPLAY=":0"
BROWSER="w3m"
MYNEWSSERVER=aconews.univie.ac.at
# user authentication
USERAUTH=""
PASSWD=""

# if the following values are set they will be prompted in a menu:
MYNEWSSERVER1=aconews.univie.ac.at
MYNEWSSERVER2=news.tugraz.at
MYNEWSSERVER3=news.opera.com
MYNEWSSERVER4=news.individual.de
############ EOF ####################################################
Copyright (C) Michael Prokop <mika@grml.org> [2004]
EOF
  exit 0
fi

if [ "$1" == "-u" ] || [ "$1" == "--update" ]; then
   if [ -w "$DN" ] ; then
     echo "update $PN from http://www.michael-prokop.at/computer/config/bin/msgid-chooser"
     echo "old version:" `$PN -v`
     wget $URL -q --cache=off -O $PN
     echo "new version:" `$PN -v`
     exit 0
   else
    echo "No writing permissions in $DN. Exiting."
    exit -1
   fi
fi

if [ "$1" == "-v" ] || [ "$1" == "--version" ] ; then
  echo msgid-chooser: $VERSION
  exit 0
fi

if [ "$1" == "-vv" ]; then
cat << EOF
msgid-chooser: $VERSION [$UP2DATE]
Copyright (C) Michael Prokop <mika@grml.org> [2004]

    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.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.

To contact the developer, please mail to <msgid-chooser@michel-prokop.at>
EOF
  exit 0
fi

# Remove temporary file at exit or signal
# trap "rm -f $POSTING_DOS $POSTING_UNIX $INPUT1 $INPUT2" 0
# trap "exit 1" 1 2 3 15

if [ "$#" -eq "0" ]; then
  askforserver
else
  MSGID=`echo $1 | sed -e 's/^<*/</' -e 's/>*$/>/'`
#  MSGID="$1"
  if [ "$2" != "" ]; then
    NEWSSERVER="$2"
  else
    NEWSSERVER=$MYNEWSSERVER
  fi
  consolegetmsg && consoleprintmsg ; rm $POSTING_DOS
fi

# }}}
######### EOF ##################################################################
# vim:foldmethod=marker
