timetable-extension #1
@ -1 +1,16 @@
 | 
			
		||||
package stations
 | 
			
		||||
package stations
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
func Check() {
 | 
			
		||||
	run()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func run() {
 | 
			
		||||
	data, data2, err := download()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Println(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	parseData(data, data2)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,40 @@
 | 
			
		||||
package stations
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	_ "encoding/xml"
 | 
			
		||||
	_ "errors"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/xml"
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	_ "git.fjla.uk/owlboard/go-types/pkg/database"
 | 
			
		||||
	_ "git.fjla.uk/owlboard/timetable-mgr/log"
 | 
			
		||||
	_ "go.uber.org/zap"
 | 
			
		||||
	"git.fjla.uk/owlboard/go-types/pkg/database"
 | 
			
		||||
	"git.fjla.uk/owlboard/go-types/pkg/upstreamApi"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Parses n number of XML byte arrays
 | 
			
		||||
func parseData(data ...[]byte) ([]database.Station, error) {
 | 
			
		||||
	var stations []upstreamApi.Station
 | 
			
		||||
	for _, d := range data {
 | 
			
		||||
		parsedStations, err := parseXML(d)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		stations = append(stations, parsedStations...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fmt.Println(stations)
 | 
			
		||||
	return nil, nil
 | 
			
		||||
	// Transform from upstreamApi.Station to database.Station
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Parses XML and converts to struct
 | 
			
		||||
func parseXML(data []byte) ([]upstreamApi.Station, error) {
 | 
			
		||||
	var stationList upstreamApi.StationList
 | 
			
		||||
 | 
			
		||||
	reader := bytes.NewReader(data)
 | 
			
		||||
	decoder := xml.NewDecoder(reader)
 | 
			
		||||
	err := decoder.Decode(&stationList)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("error parsing XML: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return stationList.Stations, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1 +1,93 @@
 | 
			
		||||
package stations
 | 
			
		||||
package stations
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"archive/zip"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// URL to RDG XML file
 | 
			
		||||
	url string = "https://internal.nationalrail.co.uk/4.0/stations.zip"
 | 
			
		||||
 | 
			
		||||
	// URL to additional XML file
 | 
			
		||||
	add string = "https://git.fjla.uk/OwlBoard/data/raw/branch/main/knowledgebase/additional.xml"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func download() ([]byte, []byte, error) {
 | 
			
		||||
	data1, err := downloadAndExtractZip(url)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	data2, err := downloadUrl(add)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return data1, data2, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func downloadUrl(url string) ([]byte, error) {
 | 
			
		||||
	resp, err := http.Get(url)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer resp.Body.Close()
 | 
			
		||||
 | 
			
		||||
	if resp.StatusCode != http.StatusOK {
 | 
			
		||||
		return nil, fmt.Errorf("failed to download from %s: status code: %d", url, resp.StatusCode)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	body, err := io.ReadAll(resp.Body)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return body, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func downloadAndExtractZip(url string) ([]byte, error) {
 | 
			
		||||
	resp, err := http.Get(url)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer resp.Body.Close()
 | 
			
		||||
 | 
			
		||||
	if resp.StatusCode != http.StatusOK {
 | 
			
		||||
		return nil, fmt.Errorf("failed to download from %s: status code %d", url, resp.StatusCode)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	body, err := io.ReadAll(resp.Body)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Read zip
 | 
			
		||||
	reader, err := zip.NewReader(bytes.NewReader(body), int64(len(body)))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check zip not empty
 | 
			
		||||
	if len(reader.File) == 0 {
 | 
			
		||||
		return nil, fmt.Errorf("no files found in the zip archive")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Read first file
 | 
			
		||||
	file := reader.File[0]
 | 
			
		||||
	rc, err := file.Open()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer rc.Close()
 | 
			
		||||
 | 
			
		||||
	extractedData, err := io.ReadAll(rc)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return extractedData, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user