Schulferien als XML (Download & Konvertierung iCal)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Thorsten1867
Beiträge: 1360
Registriert: 04.02.2005 15:40
Computerausstattung: [Windows 10 x64] [PB V5.7x]
Wohnort: Kaufbeuren
Kontaktdaten:

Schulferien als XML (Download & Konvertierung iCal)

Beitrag von Thorsten1867 »

Nachdem ich an der Berechnung der Winterferientermine gescheitert bin (geht wohl nur mit Mondkalender usw.), habe ich beschlossen, die Ferientermine einfach komplett aus dem Internet zu holen und entsprechend aufzubereiten.
Vielleicht hat ja noch jemand Verwendung dafür. Mit kleineren Änderungen könnte man die Proceduren bestimmt auch für andere iCal-Kalender anpassen.

Code: Alles auswählen

;/ Schulferien als XML 
;/ [ Download & iCal -> XML ]
;/ (c) 2013  Thorsten Hoeppner

#File = 0
#XML = 0

#Pfad = "D:\Temp\" ; entsprechend anpassen!

#Bundesland = "Bayern" ; siehe www.schulferien.org (entsprechend Dateiname -> Ferien_Bayern_2013.ics)
#FerienURL = "http://www.schulferien.org/iCal/Ferien/icals/"

InitNetwork() 

Structure FerienStructure
  Name.s
  start.l
  ende.l
EndStructure

Procedure.s DownloadFerien() ; Download Ferien.ics, wenn XML nicht existiert
  jahr$ = Str(Year(Date()))
  ics$ = "Ferien_"+#Bundesland+"_"+jahr$+".ics"
  If FileSize(#Pfad+"Ferien_"+jahr$+".xml") <= 0
    If ReceiveHTTPFile(#FerienURL+ics$, #Pfad+ics$)
      ProcedureReturn #Pfad+ics$
    EndIf  
  EndIf
  ProcedureReturn ""
EndProcedure

Procedure.s ConvertICal(File.s)
  NewList Ferien.FerienStructure()
  XMLFile$ = #Pfad+"Ferien.xml"
  If ReadFile(#File, File)
    While Eof(#File) = #Null
      If UCase(ReadString(#File)) = "BEGIN:VEVENT"
        AddElement(Ferien())
        Repeat
          ical$ = ReadString(#File)
          Select UCase(StringField(ical$,1,":"))
            Case "SUMMARY"
              Ferien()\Name = StringField(StringField(ical$,2,":"),1," ")
            Case "DTSTART;VALUE=DATE"
              Ferien()\start = ParseDate("%yyyy%mm%dd", StringField(ical$,2,":"))
            Case "DTEND;VALUE=DATE"
              Ferien()\ende = AddDate(ParseDate("%yyyy%mm%dd", StringField(ical$,2,":")), #PB_Date_Day, -1)
          EndSelect
        Until UCase(ical$) = "END:VEVENT" Or Eof(#File)
      EndIf
    Wend
    CloseFile(#File)
  EndIf
  
  If ListSize(Ferien()) ; nach Datum sortieren
    SortStructuredList(Ferien(), #PB_Sort_Ascending, OffsetOf(FerienStructure\start), #PB_Sort_Long) 
  EndIf
  
  If CreateXML(#XML) ; XML-Datei erstellen
    *MainNode = CreateXMLNode(RootXMLNode(#XML)) 
    If *MainNode
      SetXMLNodeName(*MainNode, "Ferien")
      ForEach Ferien()
        *Node = CreateXMLNode(*MainNode, -1)
        If *Node
          Select Ferien()\Name ;{ Nodename
            Case "Winterferien"
              SetXMLNodeName(*Node, "Winter")
            Case "Osterferien"
              SetXMLNodeName(*Node, "Ostern")
            Case "Pfingstferien"
              SetXMLNodeName(*Node, "Pfingsten")
            Case "Sommerferien"
              SetXMLNodeName(*Node, "Sommer")
            Case "Herbstferien"
              SetXMLNodeName(*Node, "Herbst")
            Case "Weihnachtsferien"
              If Year(Ferien()\start) = Year(Ferien()\ende)
                SetXMLNodeName(*Node, "Neujahr")
              Else
                SetXMLNodeName(*Node, "Weihnachten")
              EndIf
            Default ; Fehler
              SetXMLNodeName(*Node, "Fehler")
          EndSelect ;}
          SetXMLAttribute(*Node, "name", Ferien()\Name)
          SetXMLAttribute(*Node, "start", Str(Ferien()\start))
          SetXMLAttribute(*Node, "ende", Str(Ferien()\ende))
          SetXMLNodeText(*Node, FormatDate("%dd.%mm.%yyyy",Ferien()\start)+" - "+FormatDate("%dd.%mm.%yyyy",Ferien()\ende)) 
        EndIf
      Next
      If ListSize(Ferien())
        jahr$ = Str(Year(Ferien()\start))
        SetXMLAttribute(*MainNode, "jahr", jahr$)
        XMLFile$ = #Pfad+"Ferien_"+jahr$+".xml"
      EndIf
      SaveXML(#XML, XMLFile$)
    EndIf
    FreeXML(#XML)
  EndIf
  ProcedureReturn XMLFile$
EndProcedure


;- ***** Test *****
 
File$ = DownloadFerien() ; iCal-Datei ggf. downloaden
If File$
  XMLFile$ = ConvertICal(File$) ; Konvertiere nach XML
  DeleteFile(File$)
Else
  XMLFile$ = #Pfad+"Ferien_"+Str(Year(Date()))+".xml"
EndIf

If LoadXML(#XML, XMLFile$) ; XML mit Ferien auslesen
  *MainNode = MainXMLNode(#XML)      
  If *MainNode
    Debug " --- Ferientermine "+GetXMLAttribute(*MainNode, "jahr")+" ---"
    *Node = ChildXMLNode(*MainNode)
    While *Node ; alle Ferien auslesen
      Debug "-> "+GetXMLAttribute(*Node, "name")+": "+GetXMLNodeText(*Node) 
      *Node = NextXMLNode(*Node)
    Wend
    Debug ""
    Debug " --- einzelner Ferientermin ---"
    *Node = XMLNodeFromPath(*MainNode, "Winter") ; Winterferien auslesen
    If *Node
      Debug "-> "+GetXMLAttribute(*Node, "name")+": "+GetXMLNodeText(*Node) 
    EndIf
  EndIf
  FreeXML(#XML)
EndIf
Download of PureBasic - Module
Download of PureBasic - Programmes

[Windows 11 x64] [PB V6]

Bild