#!/bin/bash

##################
# Αυτό το πρόγραμμα επιβάλλει φραγή σε ορισμένο χρήστη,
# διαγράφει όλες τις σελίδες που δημιούργησε το τελευταίο χρονικό 
# διάστημα (60 λεπτά κανονικά), κάνει αναίρεση όλων των αλλαγών
# που έκανε το ίδιο διάστημα, και ξαναφέρει στη θέση τους όλες τις σελίδες
# που μετακίνησε αυτός.  

#Αν κάποιος άλλος χρήστης επεξεργαστεί μια σελίδα μετά από αλλαγή του βανδάλου, 
#εκείνη η αλλαγή μάλλον δεν θα αναιρεθεί. 


# TODO:
# *αντικατάσταση των awk + sed + awk + awk με κάτι καλύτερο 


##################
# Ελέγξτε τις παρακάτω ρυθμίσεις
#

configdone=""
nocreate=1
reblock=1
# πότε θα λήξει η φραγή;
expiry="2 days"
# αυτό θα φανεί στη σύνοψη επεξεργασίας
reason="βανδαλισμός"
cookiesfile="elwp-login-cookies.txt"
wiki="el.wikipedia.org"
#όνομα χρήστη, κωδικός πρόσβασης στο wiki
lgname="xxxx"
lgpassword="xxxx"
# ελέγχουμε τις πρόσφατες αλλαγές του χρήστη για τα τελευταία... 60 λεπτά
duration=3600
# πόσες συνεισφορές θέλουμε; όχι πάνω από 1000
numedits=1000

### ### ### ####


curlargs="-s -S --retry 10 -H 'Expect:' -c $cookiesfile -b $cookiesfile -f"
curlurl="http://$wiki/w/api.php?action="
if [ ! -z "$reason" ]; then
  reason_arg="--data-urlencode reason=$reason"
  summary_arg="--data-urlencode summary=$reason"
else
  reason_arg=""
  summary_arg=""
fi
if [ ! -z "$nocreate" ]; then
  nocreate_arg="--data-urlencode nocreate=1"
else
  nocreate_arg=""
fi
if [ ! -z "$reblock" ]; then
  reblock_arg="--data-urlencode reblock=1"
else
  reblock_arg=""
fi

function getdaterange() 
{
  today=`date -u +"%Y-%m-%d %H:%M:%S +0000"`
  secs=`date +%s -d "$today"`

  # στην περίπτωση που το δικό μας ρολόι διαφέρει λίγο από του διακομιστή
  startsecs=$(( $secs+300 ))
  # παίρνουμε αλλαγές για την προηγούμενα 60 λεπτά
  endsecs=$(( $secs-$duration ))

  ucstart=`date -u -d @$startsecs +"%Y-%m-%dT%H:%M:%SZ"`
  ucend=`date -u -d @$endsecs +"%Y-%m-%dT%H:%M:%SZ"`

}

function loginerrcheck() {
    if [ $loginresult -ne "0" ]; then 
	echo "Η σύνδεση απέτυχε, μάλλον λάθος κώδικας πρόσβασης"
	if [ -e "$cookiesfile" ]; then
	        rm -f $cookiesfile
		fi
	exit 1
    fi
    loginerr=`echo $login | grep Illegal`
    if [ ! -z "$loginerr" ]; then
	echo "Η σύνδεση απέτυχε, μάλλον λάθος κώδικας πρόσβασης"
	echo "   Περισσότερες πληροφορίες:"
	echo "   $loginerr" | sed -e "s/'/'/g;"
	if [ -e "$cookiesfile" ]; then
	        rm -f $cookiesfile
		fi
	exit 1
    fi
    return 
}

function login() {
    if [ -z "$lgname" -o -z "$lgpassword" ]; then
	echo "Πρέπει να επεξεργαστείτε το αρχείο αυτό και να ελέγξετε τις ρυθμίσεις"
	echo "lgname και lgpassword."
	exit 1
    fi
    login=`curl -s -S  --retry 10 -H 'Expect:' -c $cookiesfile -f --data-urlencode "lgname=$lgname" --data-urlencode "lgpassword=$lgpassword" --data-urlencode "format=xml"  "${curlurl}login"`
    loginresult=$?
    loginerrcheck
    loginneedtoken=`echo $login | grep NeedToken`
    if [ ! -z "$loginneedtoken" ]; then
	tokenname=token
	xmltext="$login"
	getxmlitem
	lgtoken="$xmlitemval"
	login=`curl -s -S  --retry 10 -H 'Expect:' -c $cookiesfile -b $cookiesfile -f --data-urlencode "lgname=$lgname" --data-urlencode "lgpassword=$lgpassword" --data-urlencode "lgtoken=$lgtoken" --data-urlencode "format=xml"  "${curlurl}login"`
	loginresult=$?
        loginerrcheck
	loginneedtoken=`echo $login | grep NeedToken`
	if [ ! -z "$loginneedtoken" ]; then
	        echo "Η σύνδεση απέτυχε (NeedToken μετά από δεύτερη προσπάθεια)"
		    if [ -e "$cookiesfile" ]; then
			rm -f $cookiesfile
			    fi
		        exit 1
			fi
    fi
    echo "Συνδεθήκατε ως $lgname"
}

function getusercontribs() {
  if [ -z "$ucstart"  -o  -z "$ucend" ]; then
     usercontribs=""
  else
      usercontribs=`curl $curlargs --data-urlencode "format=xml" --data-urlencode "list=usercontribs" --data-urlencode "ucuser=$user" --data-urlencode "ucprop=flags|title"  --data-urlencode "ucstart=$ucstart" --data-urlencode "ucend=$ucend" --data-urlencode "uclimit=$numedits" "${curlurl}query"`
  fi
}

function getxmlitem() 
{
  xmlitemval=`echo $xmltext | tr '>' '\n' | grep ${tokenname}= | awk -F${tokenname}= '{ print $2 }' | awk -F'"' '{ print $2 }'` 
}

function blockuser () 
{
  if [ -z "$user" ]; then
    return
  fi

  xmltext=`curl $curlargs --data-urlencode "gettoken=1" --data-urlencode "format=xml" "${curlurl}block"`
  tokenname=blocktoken
  getxmlitem
  blocktoken="$xmlitemval"
  if [ -z "$blocktoken" ]; then 
      echo "Η αίτηση για blocktoken απέτυχε"
      echo "   Περισσότερες πληροφορίες:"
      echo "   $xmltext"
      return 1
  fi

  result=`curl $curlargs --data-urlencode "format=xml" --data-urlencode "token=$blocktoken" --data-urlencode "expiry=$expiry" --data-urlencode "user=$user" $reason_arg $nocreate_arg $reblock_arg "${curlurl}block" `
  if [ "$?" -ne "0" ]; then 
      echo "Η φραγή του χρήστη $user απέτυχε"
      return 1
  fi
  err=`echo $result | grep error`
  if [ ! -z "$err" ]; then
      echo "Η φραγή του χρήστη $user απέτυχε"
      echo "   Περισσότερες πληροφορίες:"
      echo "   $err" | sed -e "s/'/'/g;" | awk -F 'error' '{ print $2 }' |  awk -F '/>' '{ print $1 }'
      return 1
  else
      echo "Επιτυχία! Φράχτηκε ο χρήστης $i."
  fi
}

function rollbackuserchanges {
    if [ -z "$usercontribs" ]; then
	getdaterange
	getusercontribs
    fi
    oldpages=`echo $usercontribs | tr '>' '\n' | grep -v '" new="' | grep -v '" missing="' | awk -F'" title=' '{ print $2 }' | awk -F'"' '{ print $2 }' | sed -e 's/ /_/g;' | sort | uniq` 

    if [ ! -z "$oldpages" ]; then
    #διαφορετικό "κουπόνι" για κάθε σελίδα
      for title in $oldpages; do
	  xmltext=`curl $curlargs --data-urlencode "prop=revisions" --data-urlencode "rvtoken=rollback" --data-urlencode "format=xml" --data-urlencode "titles=$title" "${curlurl}query"`
	  tokenname=rollbacktoken
	  getxmlitem
	  rollbacktoken="$xmlitemval"
	  if [ -z "$rollbacktoken" ]; then 
	      echo "Η αίτηση για rollbacktoken απέτυχε"
	      echo "   Περισσότερες πληροφορίες:"
	      echo "   $xmltext" | sed -e "s/'/'/g;"
	      continue
	  fi
	  result=`curl $curlargs --data-urlencode "format=xml" --data-urlencode "token=$rollbacktoken" --data-urlencode "title=$title" $summary_arg --data-urlencode "user=$user" "${curlurl}rollback" `
	  if [ "$?" -ne "0" ]; then 
	      echo "Η αναίρεση απέτυχε"
	      return 1
	  fi
	  err=`echo $result | grep -i error`
	  if [ ! -z "$err" ]; then
	      echo "Η αναίρεση απέτυχε... ή μας πρόλαβε κάποιος"
	      echo "   Περισσότερες πληροφορίες:"
	      echo "   $err" | sed -e "s/'/'/g;"| awk -F 'error' '{ print $2 }' | awk -F '/>' '{ print $1 }'
	  fi	
      done
      echo "Επιτυχία! Κάναμε αναίρεση όλων των αλλαγών του χρήστη ... εκτός αν είδατε σφάλματα παραπάνω"
  else
      echo "Δεν υπάρχουν αλλαγές του χρήστη προς αναίρεση"
  fi
}

function deletepagefromtitle() {
    xmltext=`curl $curlargs --data-urlencode "prop=info" --data-urlencode "intoken=delete" --data-urlencode "format=xml" --data-urlencode "titles=$title" "${curlurl}query"`
    tokenname=deletetoken
    getxmlitem
    deltoken="$xmlitemval"
    if [ -z "$deltoken" ]; then 
	echo "Η αίτηση για deltoken απέτυχε, μάλλον δεν έχετε το σχετικό δικαίωμα"
	echo "   Περισσότερες πληροφορίες:"
	echo "   $xmltext" | sed -e "s/'/'/g;"
	return 1
    fi
    result=`curl $curlargs --data-urlencode "format=xml" --data-urlencode "token=$deltoken" --data-urlencode "title=$title" $reason_arg "${curlurl}delete" `
    if [ "$?" -ne "0" ]; then 
	echo "Η διαγραφή απέτυχε"
	return 1
    fi
    err=`echo $result | grep -i error`
    if [ ! -z "$err" ]; then
	echo "Η διαγραφή απέτυχε... ή μας πρόλαβε άλλος"
	echo "   Περισσότερες πληροφορίες:"
	echo "$err" | sed -e "s/'/'/g;" | awk -F 'error' '{ print $2 }' | awk -F '/>' '{ print $1 }'
    fi	
}

# διαγράφουμε μια σελίδα μόνο αν...
# δεν έχει κάνει κανένας άλλος μια επεξεργασία; 
# μπα, προς το παρόν διαγράφουμε κάθε σελίδα του
# ΠΡΟΣΟΧΗ... 
function deletenewpages() {
  newpages=`echo $usercontribs | tr '>' '\n' | grep '<item' | grep '" new="' | awk -F'" title=' '{ print $2 }' | awk -F'"' '{ print $2 }' | sed -e 's/ /_/g;'` 

  if [ ! -z "$newpages" ]; then
     # το ίδιο "κουπόνι" για κάθε σελίδα
      titles=`echo $newpages | sed -e 's/ .*//;'`
#μορφή:
# <?xml version="1.0"?><api><query><normalized><n from="title=_test_25_and_stuff" to="title= test 25 and stuff" /></normalized><pages><page pageid="236011" ns="0" title="title= test 25 and stuff" touched="2009-04-14T22:56:40Z" lastrevid="1226911" counter="1" length="33" new="" starttimestamp="2009-04-14T22:56:48Z" deletetoken="02117d557437e2912da0bb4431ee5318+\" /></pages></query></api>

      xmltext=`curl $curlargs --data-urlencode "prop=info" --data-urlencode "intoken=delete" --data-urlencode "format=xml" --data-urlencode "titles=$titles" "${curlurl}query"`
      tokenname=deletetoken
      getxmlitem
      deltoken="$xmlitemval"
      if [ -z "$deltoken" ]; then 
	  echo "Η αίτηση για deltoken απέτυχε, μάλλον δεν έχετε το σχετικό δικαίωμα"
	  echo "   Περισσότερες πληροφορίες:"
	  echo "   $xmltext" | sed -e "s/'/'/g;"
	  return 1
      fi
      for t in $newpages; do
	  echo "μαζική διαγραφή ($t)"
	  result=`curl $curlargs --data-urlencode "format=xml" --data-urlencode "token=$deltoken" --data-urlencode "title=$t" $reason_arg "${curlurl}delete" `
	  if [ "$?" -ne "0" ]; then 
	      echo "Η διαγραφή απέτυχε"
	      return 1
	  fi
	  err=`echo $result | grep -i error`
	  if [ ! -z "$err" ]; then
	      echo "Η διαγραφή απέτυχε... ή μας πρόλαβε άλλος"
	      echo "   Περισσότερες πληροφορίες:"
	      echo "   $err" | sed -e "s/'/'/g;" | awk -F 'error' '{ print $2 }' | awk -F '/>' '{ print $1 }'
	  fi	
      done
      echo "Επιτυχία! Διαγράψαμε όλες τις σελίδες του χρήστη... εκτός αν είδατε σφάλματα παραπάνω"
  else
      echo "Δεν υπάρχουν σελίδες του χρήστη προς διαγραφή"
  fi
}

function showusercontribs() {
  echo "Συνεισφορές του χρήστη $user "
  echo $usercontribs | tr '>' '\n' | grep '<item'
}

function undomoves() {
  usermoves=`curl $curlargs  --data-urlencode "letype=move" --data-urlencode "format=xml" --data-urlencode "list=logevents" --data-urlencode "leuser=$user" "${curlurl}query"`
  movelines=`echo $usermoves | sed -e 's/<\/item>/|/g;' | tr '|' '\n' | grep '<move' | awk -F'"' '{ ORS=">"; for (i=1; i<NF; i++) { if ($i == " title=") old=$(i+1); if ($i == " new_title=") new=$(i+1);} print old"|"new;}' | sed -e "s/ /_/g;"`

  movetitles=`echo $movelines | tr '>' '\n' `
  if [ ! -z "$movetitles" ]; then
      for i in $movetitles; do
	  oldtitle=`echo $i | awk -F'|' '{ print $1 }'`
	  newtitle=`echo $i | awk -F'|' '{ print $2 }'`
	  
          # προετοιμασία
	  title="$oldtitle"
#	  echo "διαγραφή της παλιάς σελίδας $oldtitle αν υπάρχει"
#	  deletepagefromtitle
	  xmltext=`curl $curlargs --data-urlencode "prop=info" --data-urlencode "intoken=move" --data-urlencode "format=xml" --data-urlencode "titles=$newtitle" "${curlurl}query"`
	  tokenname=movetoken
	  getxmlitem
	  movetoken="$xmlitemval"
	  if [ -z "$movetoken" ]; then 
	      echo "Η αίτηση για movetoken απέτυχε"
	      echo "   Περισσότερες πληροφορίες:"
	      echo "   $xmltext" | sed -e "s/'/'/g;"
	      continue
	  fi

          # κάνουμε την μετακίνηση
	  echo "μετακίνηση $newtitle σε $oldtitle"
	  result=`curl $curlargs --data-urlencode "format=xml" --data-urlencode "token=$movetoken" --data-urlencode "from=$newtitle" --data-urlencode "to=$oldtitle" $reason_arg --data-urlencode "noredirect=1" "${curlurl}move" `
	  if [ "$?" -ne "0" ]; then 
	      echo "Η μετακίνηση απέτυχε"
	      return 1
	  fi
	  err=`echo $result | grep -i error`
	  if [ ! -z "$err" ]; then
	      echo "Η μετακίνηση απέτυχε"
	      echo "   Περισσότερες πληροφορίες:"
	      echo "   $err" | sed -e "s/'/'/g;" | awk -F 'error' '{ print $2 }' | awk -F '/>' '{ print $1 }'
	      continue
	  fi	

	  #στην περίπτωση που δεν έχουμε το δικαίωμα να μετακινήσουμε σελίδες χωρίς να αφήσουμε ανακατεύθυνση...
	  title="$newtitle"
	  echo "διαγραφή της καινούργιας σελίδας $newtitle μετά την μετακόμιση (αν υπάρχει)"
	  deletepagefromtitle

      done
      echo "Επιτυχία! Επαναφέραμε όλες τις μετακινήσεις του χρήστη... εκτός αν είδατε σφάλματα παραπάνω"
  else
      echo "Δεν υπάρχουν σελίδες του χρήστη που μετακίνησε."
  fi

}

function blockem() 
{
  echo "Φραγη..."
  blockuser
  getdaterange  
  getusercontribs
  showusercontribs
  echo "Μαζική διαγραφή..."
  deletenewpages
  echo "Μαζική επαναφορά επεξεργασιών..."
  rollbackuserchanges
  echo "Μαζική εμαπαφορά μετακινήσεων..."
  undomoves
}


function checkconfig() {
    if [ -z "$configdone" ]; then
	echo "Πρέπει να επεξεργαστείτε το αρχείο αυτό για να ελέγξετε τις ρυθμίσεις"
	echo "expiry, reason, κλπ, και μετά να βγάλετε το # από τη γραμμή με το configdone."
	exit 1
    fi
}

function checksessioncurrent() {
    if [ -e "$cookiesfile" ]; then
	secs=`cat $cookiesfile | grep 'Token' | awk '{ print $5 }'`
	secs=$(( $secs+60 ))
	secsnow=`date +%s`
	if  [ "$secs" -le "$secsnow" ]; then 
	    #για να αναγκαστούμε να συνδεθούμε ξανά
	    rm -f "$cookiesfile"
	fi
    fi
}

function checkusage() {
    if [ "$1" -eq "0" ]; then
	echo "Χρήση: $0 διεύθυνση-του-βανδάλου 2η-διεύθυνση 3ή..."
	echo "Ο λογαριασμός σας πρέπει να έχει τα σχετικά δικαιώματα."
	echo "Προσοχή: κάθε διεύθυνση πρέπει να περικλείεται σε αποστρόφους αν περιέχει κενό."
	echo "Για παράδειγμα:"
	echo "$0 'mean vandal'   'super mean vandal'   'boring editwar type'"
	echo "Εναλλακτικά, μπορείτε να καλέσετε το πρόγραμμα με"
	echo "cat αρχείο-με-ονόματα-χρηστών | $0 -" 
	echo "και θα διαβάσει τον κατάλογο ονομάτων από το stdin."
	exit 1
    fi
}

##########################
##########################
##
## MAIN
##
checkconfig
checkusage $#
checksessioncurrent
if [ ! -e "$cookiesfile" ]; then
    login
fi

if [ "$1" == "-" ]; then
    while read user; do
	blockem
    done
else 
    for user in "$@"; do
	blockem
    done
fi