#!/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