Gambas: Lokal: Wikibook Download Form1.class

PUBLIC SUB Form1_Open()
  TextBox1.Text = System.Home &/ "wiki"
  Dialog.Path = TextBox1.Text

  TextLabel1.Text = "Zielordner:"
  TextLabel2.Text = "Wikibook:"
  TextBox2.Text = "Gambas"
  TextArea1.Text = ""
  ProgressBar1.value = 0
  Button1.Text = "Schließen"
  Button2.Text = "Verzeichnis ..."
  Button3.Text = "Seiten suchen ..."
  Button4.Text = "Seiten speichern ..."
  
  TextLabel1.Move( 8, 8, 90, 32 )
  TextLabel2.Move( 8, TextLabel1.H + 16, TextLabel1.W, 32 )

  ME.Border = Window.Resizable
  ME.W = 800
  ME.H = 600
  ME.Center
  ME.Text = "Wikibook Download"
END

PUBLIC SUB Form_Resize()
  Button1.Move( ME.W - 175 - 8, ME.H - 32 - 8, 175, 32 )
  Button2.Move( Button1.X, 8, Button1.W, Button1.H )
  Button3.Move( Button1.X, Button2.H + 16, Button1.W, Button1.H )
  Button4.Move( Button1.X, Button2.H + Button3.H + 24, Button1.W, Button1.H )

  TextBox1.Move( TextLabel1.W + 16, 8, ME.W - TextLabel1.W - Button1.W - 32, 32 )
  TextBox2.Move( TextLabel2.W + 16, TextLabel2.Y, ME.W - TextLabel2.W - Button2.W - 32, 32 )

  TextArea1.Move( 8, TextLabel1.H + TextLabel2.H + 24, ME.W - Button1.W - 24, ME.H - TextLabel1.H - TextLabel2.H - ProgressBar1.H - 40 )
  ProgressBar1.Move( 8, ME.H - ProgressBar1.H - 8, ME.W - Button1.W - 24, 32 )
END

PUBLIC SUB Button1_Click()
  ME.Close
END

PUBLIC SUB Button2_Click()
  'Zielverzeichnis auswählen
  Dialog.SelectDirectory()
  TextBox1.Text = Dialog.Path
END

PUBLIC SUB Button3_Click()
  'Im folgenden werden die zum angegebenen Wikibook gehörenden Seiten ermittelt
  DIM sUrl AS String
  DIM sFile AS String
  DIM sCont AS String
  DIM sLine AS String
  DIM aUrls AS String[]
  aUrls = NEW String[]
  
  INC Application.Busy
  ProgressBar1.value = 0
  IF NOT Exist(TextBox1.Text) THEN MKDIR TextBox1.Text
  
  'Url und Speicherort für die Index-Datei zusammensetzen und die Datei downloaden
  ProgressBar1.value = 0.2
  sUrl = "http://de.wikibooks.org/w/index.php?title=Spezial%3APrefixindex&namespace=0&from="
  sUrl = sUrl & UrlEncode(Name2Wiki(TextBox2.Text))
  sFile = TextBox1.Text & File.Separator & "index.html"
  IF Exist(sFile) THEN KILL sFile
  EXEC [ "wget", "-q", sUrl, "-O", sFile ] WAIT

  'Datei einlesen und Auswertung vorbereiten
  ProgressBar1.value = 0.4
  sCont = File.Load(sFile)
  sCont = Replace$( sCont, "\"", "\n" )
  
  'Die Seitennamen herausfiltern
  ProgressBar1.value = 0.6
  FOR EACH sLine IN Split( sCont, "\n" )
    IF sLine LIKE "/wiki/" & UrlEncode(Name2Wiki(TextBox2.Text)) & "*" THEN
      aUrls.Add(sLine)
    ENDIF
  NEXT
  
  'Die Seitennamen zu Urls zusammensetzen
  ProgressBar1.value = 0.8
  sCont = ""
  FOR EACH sLine IN aUrls
    sCont = sCont & "http://de.wikibooks.org" & sLine & "\n"
  NEXT

  TextArea1.Text = sCont
  ProgressBar1.value = 1
  DEC Application.Busy
END

PUBLIC SUB Button4_Click()
  'Im Folgenden werden die zuvor ermittelten Seiten heruntergeladen
  DIM iCur AS Integer
  DIM iAnz AS Integer
  DIM sUrl AS String
  DIM sTemp AS String
  DIM sFile AS String
  DIM sCont AS String
  DIM aUrls AS String[]
  DIM aRep AS String[]
  aUrls = NEW String[]
  aRep = NEW String[]
  
  ProgressBar1.value = 0
  INC Application.Busy
  
  'Die Urls vorbereiten
  aUrls = Split( TextArea1.Text, "\n" )
  aUrls.Remove( aUrls.Length - 1 )
  iAnz = aUrls.Length
  iCur = 0
  aRep = aUrls
  aRep.Reverse
  
  FOR EACH sUrl IN aUrls
    INC iCur
    
    'Zur Url der jeweiligen Seite den zugehörigen Dateinamen ermitteln und downloaden
    sFile = Name2Wiki(UrlDecode(Replace$( sUrl, "http://de.wikibooks.org/wiki/", "" )))
    sFile = TextBox1.Text & File.Separator & sFile
    IF Exist(sFile) THEN KILL sFile
    EXEC [ "wget", "-q", sUrl, "-O", sFile ] WAIT
    
    'Eine Millisekunde warten, sieht seltsam aus, ist aber nötig, damit der
    'Fensterinhalt wieder neu aufgebaut wird, falls das Fenster zwischenzeitlich
    'von anderen Fenstern überlagert wurde
    WAIT 0.001
    
    'In den heruntergeladenen Dateien müssen wir jetzt noch die Links anpassen
    sCont = File.Load(sFile)
    'Für Wikibooks, die den Doppelpunkt als Trennzeichen verwenden, reicht der folgenden Befehl
    sCont = Replace$( sCont, "/wiki/" & Name2Wiki(UrlEncode(TextBox2.Text)), "./" & Name2Wiki(UrlEncode(TextBox2.Text)) )
    'Für Wikibooks, die den Schrägstrich als Trennzeichen verwenden, brauchen wir die folgende Extrarunde
    FOR EACH sUrl IN aRep
      sTemp = UrlDecode(Replace$( sUrl, "http://de.wikibooks.org/wiki/", "" ))
      sCont = Replace$( sCont, sTemp, Name2Wiki(sTemp) )
    NEXT
    File.Save( sFile, sCont )
    
    ProgressBar1.value = iCur / iAnz
  NEXT

  DEC Application.Busy
END

PUBLIC FUNCTION Name2Wiki( sUrl AS String ) AS String
  sUrl = Replace$( sUrl, " ", "_" )
  sUrl = Replace$( sUrl, "/", "_" )
  RETURN sUrl
END

PUBLIC FUNCTION UrlEncode( sUrl AS String ) AS String
  'siehe auch: http://www.blooberry.com/indexdot/html/topics/urlencoding.htm
  DIM sZeichen AS String
  
  FOR EACH sZeichen IN Array( "%", "$", "&", "+", ",", "/", ";", "=", "?", "@", "\"", "<", ">", "{", "}", "|", "\\", "^", "~", "[", "]", "`" )
    sUrl = Replace$( sUrl, sZeichen, "%" & Hex(Asc( sZeichen, 1 )) )
  NEXT
  RETURN sUrl
END

PUBLIC FUNCTION UrlDecode( sUrl AS String ) AS String
  DIM iZahl AS Integer
  FOR iZahl = 20 TO 255
    sUrl = Replace$( sUrl, "%" & Hex(iZahl), Chr(iZahl) )
  NEXT
  RETURN sUrl
END