Advertisement
Guest User

get_wikibooks.sh

a guest
Apr 12th, 2012
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 14.38 KB | None | 0 0
  1. #!/bin/bash
  2. #
  3. # get_wikibook.sh
  4. #
  5. # Programm zum Herunterladen von Wikibooks
  6. #
  7. # Copyright (C) 2007 FeG (feg@computer-dc.de)
  8. #
  9. # This program is free software; you can redistribute it and/or modify
  10. # it under the terms of the GNU General Public License as published by
  11. # the Free Software Foundation; either version 2 of the License, or
  12. # (at your option) any later version.
  13. #
  14. # This program is distributed in the hope that it will be useful, but
  15. # WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. # General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU General Public License
  20. # along with this program; if not, write to the Free Software Foundation,
  21. # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
  22.  
  23. # CHANGELOG
  24. #
  25. # Version 0.1
  26. #  * Grundlegende Funktionen zum Herunterladen von Wikibooks mit den Trennzeichen : und /
  27. #  * -v|--verbose gibt zusätzlich Folgendes aus:
  28. #    * eine "Fortschrittsanzeige" bei den Online-Links
  29. #    * beim Trennzeichen / die erstellten Verzeichnisse aus
  30. #  * ersetzt Online-Links: Links auf andere Seiten auf wikibooks.org, CSS-Import-Links, src-Links und CSS-Links ("url=(...)"),
  31. #    deaktivierbar mit -n|--no-online
  32.  
  33. # Standard-Einstellungen
  34.  
  35. # Ländercode der Wikibooks-Seite -> http://XX.wikibooks.org
  36. #
  37. # Sollte zurzeit nicht geändert werden, solange nicht sichergestellt ist, dass die
  38. # andere Wikibooks-Seite die gleichen Trennzeichen verwendet wie die deutsche
  39. WIKILANG=de
  40.  
  41. # --- Don't change anything below here unless you know what you're doing ---
  42. # --- Ändere nichts unterhalb dieser Zeile außer du weißt was du tust ---
  43.  
  44. # Programmversion
  45. version=0.1
  46.  
  47. # Programmname
  48. progname=$(basename $0)
  49.  
  50. # Fehlercodes
  51. E_Aufruf=1
  52. E_ZielverzErstellen=2
  53. E_BuchverzExistiert=3
  54. E_Buchindex=4
  55. E_Seperator=5
  56. E_VerzErstellen=6
  57.  
  58. # Wird ausgegeben, wenn mit --help aufgerufen
  59. print_help()
  60. {
  61.     cat <<EOF
  62. Aufruf: $progname [Optionen] Buch [Zielverzeichnis]
  63.  
  64. Lädt das angegebene Wikibook herunter.
  65.  
  66. Optionen:
  67.       --help          zeigt diese Hilfe an
  68.       --version       zeigt die Programmversion an
  69.  
  70.       -n
  71.       --no-online     schaltet die Ersetzung von Online-Links (Links auf andere Wikibooks-Seiten) ab
  72.       -s S       
  73.       --seperator S   gibt das Trennzeichen (":" oder "/") des Wikibooks an
  74.       -v, --verbose   erzeugt viel Ausgabe
  75.  
  76. Fehlerberichte an <feg@computer-dc.de>.
  77. EOF
  78. }
  79.  
  80. # Wird ausgegeben, wenn mit --version aufgerufen
  81. print_version()
  82. {
  83.     cat <<EOF
  84. $progname $version
  85.  
  86. Copyright (C) 2007 FeG (feg@computer-dc.de)
  87.  
  88. This is free software.  You may redistribute copies of it under the terms of
  89. the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
  90. There is NO WARRANTY, to the extent permitted by law.
  91. EOF
  92. }
  93.  
  94. # Kurze und lange Parameter für den Aufruf von getopt
  95. SHORTOPTS="s:v"
  96. LONGOPTS="help,version,seperator:,verbose"
  97.  
  98. # getopt -T liefert bei neuen Versionen 4 als Fehlercode. Nur neue Versionen können
  99. # mit langen Parametern umgehen
  100. if $(getopt -T &> /dev/null) ; [ $? = 4 ] ; then
  101.   # neue getopt-Version, verwende lange Parameter
  102.   OPTS=$(getopt -o $SHORTOPTS --long $LONGOPTS -n "$progname" -- "$@")
  103. else
  104.   # alte getopt-Version, verwende kurze Parameter
  105.  
  106.   # --help und --version manuell verwerten
  107.   case $1 in --help) print_help ; exit 0 ;; esac
  108.   case $1 in --version) print_version ; exit 0 ;; esac
  109.   OPTS=$(getopt $SHORTOPTS "$@")
  110. fi
  111.  
  112. # Fehler bei getopt
  113. if [ $? -ne 0 ]; then
  114.     echo "'$progname --help' für mehr Informationen" 1>&2
  115.     exit $E_Aufruf
  116. fi
  117.  
  118. # Schreibe getopt-Ergebnisse in $@
  119. eval set -- "$OPTS"
  120.  
  121. # Standardwerte
  122. SEPERATOR="?"
  123. VERBOSE=0
  124. NO_ONLINE=0
  125.  
  126. # getopt-Ergebnisse auswerten
  127. while [ $# -gt 0 ]; do
  128.     case $1 in
  129.         --help)
  130.             print_help
  131.             exit 0
  132.             ;;
  133.         --version)
  134.             print_version
  135.             exit 0
  136.             ;;
  137.         -n|--no-online)
  138.             NO_ONLINE=1
  139.             shift
  140.             ;;
  141.         -s|--seperator)
  142.             if [ "$2" == "/" ] || [ "$2" == ":" ]; then
  143.               SEPERATOR=$2
  144.             else
  145.               SEPERATOR="?"
  146.             fi
  147.             shift 2
  148.             ;;
  149.         -v|--verbose)
  150.             VERBOSE=1
  151.             shift
  152.             ;;
  153.         --)
  154.             shift
  155.             break
  156.             ;;
  157.         *)
  158.             echo "Fehler: Ungültiger Parameter $1" 1>&2
  159.             exit $E_Aufruf
  160.             ;;
  161.     esac
  162. done
  163.  
  164. # Buch angegeben?
  165. if [ $# -lt 1 ]; then
  166.   echo "Aufruf: $progname [Optionen] Buch [Zielverzeichnis]"
  167.   exit $E_Aufruf
  168. fi
  169.  
  170. # Zielverzeichnis
  171. if [ -n "$2" ]; then
  172.   ZIELVERZ=$2
  173.   mkdir -p $ZIELVERZ
  174.   if [ "$?" != "0" ]; then
  175.     echo "Zielverzeichnis \"$ZIELVERZ\" kann nicht erstellt werden. Abbruch."
  176.     exit $E_ZielverzErstellen
  177.   fi
  178. else
  179.   ZIELVERZ=`pwd`
  180. fi
  181.  
  182. # zu ladendes Buch
  183. BUCH=$1
  184. if [ -e "$ZIELVERZ/$BUCH" ]; then
  185.   echo "Buchverzeichnis \"$ZIELVERZ/$BUCH\" existiert bereits. Abbruch."
  186.   exit $E_BuchverzExistiert
  187. fi
  188.  
  189. # cleanup - Löscht das Buchverzeichnis, wenn ein Fehler auftritt, der zum Programmupdate führt
  190. cleanup()
  191. {
  192.   echo -n "Räume auf.. "
  193.   cd "$ZIELVERZ"
  194.   rm -rf "$BUCH"
  195.   if [ $? -eq 0 ]; then
  196.     echo "ok"
  197.   else
  198.     echo "fehlgeschlagen. Buchverzeichnis konnte nicht gelöscht werden."
  199.   fi
  200. }
  201.  
  202. mkdir -p "$ZIELVERZ/$BUCH"
  203. cd "$ZIELVERZ/$BUCH"
  204.  
  205. echo "Beginne mit dem Herunterladen des Wikibooks \"$BUCH\" in den Ordner \"$ZIELVERZ\".."
  206. echo
  207.  
  208. # Index laden:
  209. echo -n "Lade Buchindex.. "
  210. wget -nv -O index.html "http://$WIKILANG.wikibooks.org/w/index.php?title=Spezial%3APrefixindex&namespace=0&from=$BUCH" &> /dev/null
  211. if [ "$?" == "0" ]; then
  212.   echo "ok"
  213. else
  214.   echo "fehlgeschlagen"
  215.   cleanup
  216.   exit $E_Buchindex
  217. fi
  218.  
  219. # Wenn kein Trennzeichen angegeben wurde..
  220. if [ "$SEPERATOR" == "?" ]; then
  221.   # ..versuche, das Trennzeichen zu raten
  222.   echo -n "Kein Trennzeichen angegeben. Rate Trennzeichen... "
  223.  
  224.   # Gibt es Links mit BUCH/ ?
  225.   egrep "href=\"[^\"]*$BUCH/" index.html &> /dev/null
  226.   has_slash=$?
  227.  
  228.   # Gibt es Links mit BUCH: ?
  229.   egrep "href=\"[^\"]*$BUCH:" index.html &> /dev/null
  230.   has_colon=$?
  231.  
  232.   if [ $has_slash -eq 0 ] && [ $has_colon -eq 1 ]; then
  233.     SEPERATOR=/
  234.   elif [ $has_slash -eq 1 ] && [ $has_colon -eq 0 ]; then
  235.     SEPERATOR=:
  236.   else
  237.     echo
  238.     echo "Fehler: Konnte nicht ermitteln, ob das Buch das Trennzeichen ":" oder "/" verwendet"
  239.     echo "Bitte geben Sie das Trennzeichen an:"
  240.     echo $progname -s : BUCH     wenn das Buch das Trennzeichen : verwendet"
  241.     echo $progname -s / BUCH     wenn das Buch das Trennzeichen / verwendet"
  242.     echo
  243.     cleanup
  244.     exit $E_Seperator
  245.   fi
  246.   echo $SEPERATOR
  247. fi
  248.  
  249. if [ "$SEPERATOR" == "/" ]; then
  250.  
  251.   # --- --- --- --- --- --- --- --- ---
  252.   # --- --- --- SEPERATOR / --- --- ---
  253.   # --- --- --- --- --- --- --- --- ---
  254.  
  255.   # Verzeichnisse erstellen:
  256.   echo -n "Erstelle Verzeichnisse.. "
  257.   touch subdirs.txt
  258.  
  259.   # "sed 'y/+/ /; s/%/\\\x/g'" übersetzt codierte URLs
  260.   for i in `cat index.html | tr '"' '\n' | sed 'y/+/ /; s/%/\\\x/g'`; do
  261.     j=`echo -e $i | awk "/^\/wiki\/$BUCH\/.*\// { verz=substr(\\$0,8+${#BUCH}); split(verz,a,/\\/[^\\/]+$/); print a[1] }"`
  262.     if [ -n "$j" ]; then
  263.       egrep ^$j$ subdirs.txt &> /dev/null
  264.       # Nur eintragen, wenn noch nicht in der Liste
  265.       if [ "$?" == "1" ]; then
  266.         echo -e $j >> subdirs.txt
  267.       fi
  268.     fi
  269.   done
  270.  
  271.   mkdir -p `cat subdirs.txt`
  272.   if [ "$?" == "0" ]; then
  273.     echo "ok"
  274.   else
  275.     echo "fehlgeschlagen"
  276.     exit $E_VerzErstellen
  277.   fi
  278.   if [ $VERBOSE -eq 1 ]; then
  279.     echo "Erstellte Verzeichnisse:"
  280.     cat subdirs.txt
  281.     echo
  282.   fi
  283.  
  284.   # Dateien laden:
  285.   echo "Lade Dateien:"
  286.   echo "-------------"
  287.  
  288.   err_count=0
  289.   # Finde alle Einträge die mit "/wiki/$BUCH" beginnen
  290.   for x in `cat index.html | tr '"' '\n' | egrep "^/wiki/$BUCH"`; do
  291.  
  292.     # "/wiki/$BUCH/" abschneiden
  293.     datei=${x:7+${#BUCH}}
  294.  
  295.     # codierte URL übersetzen
  296.     datei=`echo -e "$(echo $datei | sed 'y/+/ /; s/%/\\\x/g')"`
  297.  
  298.     # Ist $datei ein Verzeichnis?
  299.     egrep ^$datei$ subdirs.txt &> /dev/null
  300.     if [ "$?" == "0" ]; then
  301.       # -> Ja: Lade die Verzeichnisseite in das Verzeichnis, ohne führenden _
  302.       # z.B.: $x = _Band1 -> Speichern nach _Band1/Band1
  303.       a=`echo $datei | sed 's#.*/##'`
  304.       target=`echo $datei/${a:1}`
  305.  
  306.     # Wenn abgeschnittener Rest leer ist, ist $x die Haupt-Buchseite
  307.     elif [ -z "$datei" ]; then
  308.       target="$BUCH"
  309.  
  310.     else target=$datei
  311.     fi
  312.  
  313.     # Laden..
  314.     wget -nv -O $target http://$WIKILANG.wikibooks.org$x
  315.     if [ $? -ne 0 ]; then ((err_count++)); fi
  316.   done
  317.   echo "-------------"
  318.   if [ $err_count -ne 0 ]; then
  319.     echo "$err_count Dateien konnten nicht heruntergeladen werden."
  320.     echo
  321.   fi
  322.  
  323.   # Links ersetzen:
  324.   echo -n "Ersetze Links.. "
  325.   for i in $(find -type f); do
  326.     # Links auf lokales Verzeichnis umbiegen
  327.     sed "s#href=\"/wiki/$BUCH#href=\"$ZIELVERZ/$BUCH#g" $i > $i.temp
  328.     mv $i.temp $i
  329.   done
  330.   echo "abgeschlossen"
  331.  
  332.   # Verzeichnis-Links ersetzen:
  333.   # ( Nötig bei Büchern mit / - Navigation, da ein lokales Verzeichnis nicht gleichzeitig eine Seite sein kann.
  334.   #   hier werden Verzeichnisseiten im Verzeichnis selbst und ohne führenden _ abgelegt )
  335.   echo -n "Ersetze Verzeichnis-Links.. "
  336.   for i in $(find -type f); do
  337.     cp $i $i.temp
  338.     for x in `grep -o 'href="[^"]*"' $i | sed 'y/+/ /; s/%/\\\x/g'`; do
  339.       # $x ist 'href="..."', codierte URLs übersetzt
  340.  
  341.       # 'href="' und abschließendes " abschneiden:
  342.       y=`echo ${x:6}`
  343.       y=${y%\"}
  344.  
  345.       # link enthält nun den eigentlichen Link:
  346.       link=`echo -e $y`
  347.  
  348.       # Zeigt $link auf ein Verzeichnis?
  349.       if [ -d "$link" ]; then
  350.         # Übergeordnete Verzeichnisse und führenden _ abschneiden
  351.         replace=`echo $link | sed 's#.*/##'`
  352.         replace=${replace#_}
  353.  
  354.         # $link in der Datei mit $link/$replace ersetzen (aus _Band1 wird _Band1/Band1, wie beim Herunterladen)
  355.         sed "s#href=\"$link\"#href=\"$link/$replace\"#g" $i.temp > $i.temp2
  356.  
  357.         mv $i.temp2 $i.temp
  358.       fi
  359.     done
  360.     mv $i.temp $i
  361.   done
  362.   echo "abgeschlossen"
  363.  
  364. else
  365.  
  366.   # --- --- --- --- --- --- --- --- ---
  367.   # --- --- --- SEPERATOR : --- --- ---
  368.   # --- --- --- --- --- --- --- --- ---
  369.  
  370.   # Dateien herunterladen
  371.   echo "Lade Dateien:"
  372.   echo "-------------"
  373.  
  374.   err_count=0
  375.   # Finde alle Einträge die mit "/wiki/$BUCH" beginnen
  376.   for x in `cat index.html | tr '"' '\n' | egrep "^/wiki/$BUCH"`; do
  377.  
  378.     # "/wiki/" abschneiden
  379.     datei=${x:6}
  380.  
  381.     # codierte URL übersetzen
  382.     datei=`echo -e "$(echo $datei | sed 'y/+/ /; s/%/\\\x/g')"`
  383.  
  384.     # Laden..
  385.     wget -nv -O $datei http://$WIKILANG.wikibooks.org$x
  386.     if [ $? -ne 0 ]; then ((err_count++)); fi
  387.   done
  388.   echo "-------------"
  389.   if [ $err_count -ne 0 ]; then
  390.     echo "$err_count Dateien konnten nicht heruntergeladen werden."
  391.     echo
  392.   fi
  393.  
  394.   # Links ersetzen
  395.   echo -n "Ersetze Links.. "
  396.   for i in $(ls); do
  397.     sed "s#href=\"/wiki/$BUCH#href=\"./$BUCH#g" $i > $i.temp
  398.     mv $i.temp $i
  399.   done
  400.   echo "abgeschlossen"
  401. fi
  402.  
  403. # Online-Links ersetzen
  404. if [ $NO_ONLINE -eq 0 ]; then
  405.   echo -n "Ersetze Online-Links (kann länger dauern).. "
  406.  
  407.   # normale Online-Links (href="...">)
  408.   for i in $(find -type f); do
  409.     cp $i $i.temp
  410.     for x in `grep -o 'href="[^"]*"' $i`; do
  411.       # URL decodieren
  412.       y=`echo $x | sed 'y/+/ /; s/%/\\\x/g'`
  413.  
  414.       # href=" und abschließendes " abschneiden
  415.       y=`echo ${y:6}`
  416.       y=${y%\"}
  417.  
  418.       link=`echo -e $y`
  419.  
  420.       if [ ! -d "$link" ] && [ ! -f "$link" ]; then
  421.         if [ "${link:0:1}" == "/" ]; then
  422.           # & ist ein spezielles Zeichen für sed, muss escaped werden
  423.           link=`echo $link | sed 's/&/\\\&/g'`
  424.           sed "s@$x@href=\"http://$WIKILANG.wikibooks.org$link\"@g" $i.temp > $i.temp2
  425.           mv $i.temp2 $i.temp
  426.         fi
  427.       fi
  428.     done
  429.     mv $i.temp $i
  430.   done
  431.   if [ $VERBOSE -eq 1 ]; then echo -n "href "; fi
  432.  
  433.   # CSS-Imports (@IMPORT "...")
  434.   for i in $(find -type f); do
  435.     cp $i $i.temp
  436.     for x in `grep -io '@IMPORT "[^"]*"' $i`; do
  437.       # x enhält wegen dem Leerzeichen im grep-String abwechseln @import und "(url)"
  438.       if [ "${x:0:1}" == "\"" ]; then
  439.     # x beginnt mit " -> URL
  440.  
  441.         # URL decodieren
  442.         y=`echo $x | sed 'y/+/ /; s/%/\\\x/g'`
  443.  
  444.         # führendes " und abschließendes " abschneiden
  445.         y=${y#\"}
  446.         y=${y%\"}
  447.  
  448.         link=`echo -e $y`
  449.  
  450.         if [ "${link:0:1}" == "/" ]; then
  451.           # & ist ein spezielles Zeichen für sed, muss escaped werden
  452.           link=`echo $link | sed 's/&/\\\&/g'`
  453.           sed "s@$x@\"http://$WIKILANG.wikibooks.org$link\"@g" $i.temp > $i.temp2
  454.           mv $i.temp2 $i.temp
  455.         fi
  456.       fi
  457.     done
  458.     mv $i.temp $i
  459.   done
  460.   if [ $VERBOSE -eq 1 ]; then echo -n "@import "; fi
  461.  
  462.   # JavaScript-Links (src="...">)
  463.   for i in $(find -type f); do
  464.     cp $i $i.temp
  465.     for x in `grep -o 'src="[^"]*"' $i`; do
  466.       # URL decodieren
  467.       y=`echo $x | sed 'y/+/ /; s/%/\\\x/g'`
  468.  
  469.       # src=" und abschließendes " abschneiden
  470.       y=`echo ${y:5}`
  471.       y=${y%\"}
  472.  
  473.       link=`echo -e $y`
  474.  
  475.       if [ "${link:0:1}" == "/" ]; then
  476.         # & ist ein spezielles Zeichen für sed, muss escaped werden
  477.         link=`echo $link | sed 's/&/\\\&/g'`
  478.         sed "s@$x@src=\"http://$WIKILANG.wikibooks.org$link\"@g" $i.temp > $i.temp2
  479.         mv $i.temp2 $i.temp
  480.       fi
  481.     done
  482.     mv $i.temp $i
  483.   done
  484.   if [ $VERBOSE -eq 1 ]; then echo -n "src "; fi
  485.  
  486.   # CSS-Links (url("...")>)
  487.   for i in $(find -type f); do
  488.     cp $i $i.temp
  489.     for x in `grep -o 'url([^\)]*)' $i`; do
  490.       # URL decodieren
  491.       y=`echo $x | sed 'y/+/ /; s/%/\\\x/g'`
  492.  
  493.       # url( und abschließendes ) abschneiden
  494.       y=`echo ${y:4}`
  495.       y=${y%)}
  496.  
  497.       link=`echo -e $y`
  498.  
  499.       if [ "${link:0:1}" == "/" ]; then
  500.         # & ist ein spezielles Zeichen für sed, muss escaped werden
  501.         link=`echo $link | sed 's/&/\\\&/g'`
  502.         sed "s@$x@url(http://$WIKILANG.wikibooks.org$link)@g" $i.temp > $i.temp2
  503.         mv $i.temp2 $i.temp
  504.       fi
  505.     done
  506.     mv $i.temp $i
  507.   done
  508.   if [ $VERBOSE -eq 1 ]; then echo -n "url "; fi
  509.  
  510.   echo "abgeschlossen"
  511. fi
  512.  
  513. # Aufräumen
  514. if [ -e index.html ]; then rm -f index.html; fi
  515. if [ -e subdirs.txt ]; then rm -f subdirs.txt; fi
  516.  
  517. echo
  518. echo "Das Wikibook \"$BUCH\" wurde heruntergeladen."
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement