ztm_vehicles_app/ztm_vehicles_app.go

181 lines
4.9 KiB
Go

package main
import (
"fmt"
"strings"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget"
"github.com/gocolly/colly/v2"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/layout"
"strconv"
"fyne.io/fyne/v2/driver/mobile"
)
type numericalEntry struct {
widget.Entry
}
func newNumericalEntry() *numericalEntry {
entry := &numericalEntry{}
entry.ExtendBaseWidget(entry)
return entry
}
func (e *numericalEntry) TypedRune(r rune) {
if (r >= '0' && r <= '9') || r == '.' || r == ',' {
e.Entry.TypedRune(r)
}
}
func (e *numericalEntry) TypedShortcut(shortcut fyne.Shortcut) {
paste, ok := shortcut.(*fyne.ShortcutPaste)
if !ok {
e.Entry.TypedShortcut(shortcut)
return
}
content := paste.Clipboard.Content()
if _, err := strconv.ParseFloat(content, 64); err == nil {
e.Entry.TypedShortcut(shortcut)
}
}
func (e *numericalEntry) Keyboard() mobile.KeyboardType {
return mobile.NumberKeyboard
}
type vehicle struct {
producer string
model string
production_year string
traction_type string
vehicle_registration_plate string
vehicle_number string
operator string
garage string
ticket_machine string
equipment string
}
func vehicleToString(inputVehicle *vehicle) string {
registrationPlate := ""
if len(inputVehicle.vehicle_registration_plate) > 0 {
registrationPlate = fmt.Sprintf(`,o rejestracji %s`, inputVehicle.vehicle_registration_plate)
}
output_string := fmt.Sprintf(
"%s o numerze %s,"+"%s %s,"+"z roku %s,"+"w posiadaniu %s,"+"z zajezdni %s%s",
inputVehicle.traction_type,
inputVehicle.vehicle_number,
inputVehicle.producer,
inputVehicle.model,
inputVehicle.production_year,
inputVehicle.operator,
inputVehicle.garage,
registrationPlate)
return strings.Replace(output_string, ",", ",\n", -1)
}
func getVehiclesByNum(vehicleNum string) string {
searchURL := fmt.Sprintf("https://www.ztm.waw.pl/baza-danych-pojazdow/?ztm_traction=&ztm_make=&ztm_model=&ztm_year=&ztm_registration=&ztm_vehicle_number=%s&ztm_carrier=&ztm_depot=", vehicleNum)
var vehicleURLs []string
c2 := colly.NewCollector(
// Visit only domains:
colly.AllowedDomains("www.ztm.waw.pl"),
)
c2.OnHTML(".grid-row-active", func(e *colly.HTMLElement) {
text := e.Attr("href")
vehicleURLs = append(vehicleURLs, text)
})
c2.Visit(searchURL)
output_string := ""
for _, vehicleURL := range vehicleURLs {
var retrievedData [10]string
// Instantiate default collector
c := colly.NewCollector(
// Visit only domains:
colly.AllowedDomains("www.ztm.waw.pl"),
)
dataIndex := 0
c.OnHTML(".vehicle-details-entry-value", func(e *colly.HTMLElement) {
text := e.Text
retrievedData[dataIndex] = text
dataIndex++
})
c.Visit(vehicleURL)
retrievedVehicle := vehicle{
producer: retrievedData[0],
model: retrievedData[1],
production_year: retrievedData[2],
traction_type: retrievedData[3],
vehicle_registration_plate: retrievedData[4],
vehicle_number: retrievedData[5],
operator: retrievedData[6],
garage: retrievedData[7],
ticket_machine: retrievedData[8],
equipment: retrievedData[9],
}
output_string += vehicleToString(&retrievedVehicle)
output_string += "\n"
output_string += "\n"
}
return output_string
}
func main() {
a := app.New()
w := a.NewWindow("ZTM vehicles")
entryLabel := widget.NewLabel("Podaj numer taborowy pojazdu:")
entry := newNumericalEntry()
output := widget.NewLabel("")
output.Wrapping = fyne.TextWrapWord
//outputContainer := container.NewVScroll(output)
//I create button earlier in order to reference it later inside function of it so I can easily disable it for the time data is fetching. There is probably better way to do it but I could't find it so
executeButton := widget.NewButton("Sprawdź numer", func() {
output.Refresh()
})
executeButton = widget.NewButton("Sprawdź numer", func() {
executeButton.Disable()
executeButton.SetText("Wczytywanie")
if len(strings.TrimSpace(entry.Text)) != 0 {
output_data := getVehiclesByNum(entry.Text)
if output_data != "" {
output.Text = output_data
} else {
output.Text = "Nie znaleziono pojazdu o podanym numerze taborowym w bazie pojazdów WTP"
}
} else {
output.Text = "Nie wprowadzono prawidłowego numeru"
}
output.Refresh()
executeButton.Enable()
executeButton.SetText("Sprawdź numer")
})
executeButton.Importance = widget.HighImportance
clearButton := widget.NewButton("Wyczyść", func() {
entry.Text = ""
output.Text = ""
output.Refresh()
entry.Refresh()
})
buttons := container.New(layout.NewGridLayout(2), clearButton, executeButton)
inputs := container.New(layout.NewGridLayout(1), entryLabel, entry, buttons)
w.SetContent(container.NewVBox(
inputs,
output,
))
w.ShowAndRun()
}