package main import ( _ "embed" "fmt" "io" "log" "net/http" "os" "regexp" "strconv" "github.com/PuerkitoBio/goquery" ) var Error *log.Logger var Warning *log.Logger func init() { log.SetFlags(log.Lmicroseconds | log.Lshortfile) logFile, err := os.Create("main.log") if err != nil { log.Printf("Error creating log file: %v", err) return } logger := io.MultiWriter(os.Stdout, logFile) log.SetOutput(logger) Error = log.New(io.MultiWriter(logFile, os.Stderr, os.Stdout), fmt.Sprintf("%sERROR:%s ", "\033[0;101m", "\033[0m"), log.Lmicroseconds|log.Lshortfile) Warning = log.New(io.MultiWriter(logFile, os.Stdout), fmt.Sprintf("%sWarning:%s ", "\033[0;93m", "\033[0m"), log.Lmicroseconds|log.Lshortfile) } var priceRegex = regexp.MustCompile(`\d+`) const url = "https://jysk.hr/spavaca-soba/madraci/madraci-s-oprugama/madrac-s-oprugama-140x200-gold-s110-dreamzone" //go:embed db.ddl var ddl string func main() { db := DB{path: "jysk.db"} err := db.Open() if err != nil { Error.Fatalf("Error opening database: %v", err) return } defer db.Close() err = db.Init(ddl) if err != nil { Error.Fatalf("Error initializing database: %v", err) return } log.Printf("Fetching price from url %s", url) price, err := GetPrice(url) if err != nil { Error.Fatalf("Error getting price: %v", err) return } log.Printf("Fetched price as '%d' from url %q", price, url) err = SavePrice(&db, price) if err != nil { Error.Fatalf("Error saving price: %v", err) return } log.Printf("Price '%d' saved to db", price) } func GetPrice(url string) (int, error) { price := 0 res, err := http.Get(url) if err != nil { return price, fmt.Errorf("failed querying url %s with error %w", url, err) } defer res.Body.Close() if res.StatusCode != http.StatusOK { return price, fmt.Errorf("failed getting data from %s with status: %s", url, res.Status) } doc, err := goquery.NewDocumentFromReader(res.Body) if err != nil { log.Fatal(err) } doc.Find("span.ssr-product-price__value").Each(func(i int, s *goquery.Selection) { log.Printf("Found price element with text: %s", s.Text()) res := priceRegex.FindStringSubmatch(s.Text()) if len(res) != 1 { Error.Fatalf("failed parsing price: %q", res) return } price, err = strconv.Atoi(res[0]) if err != nil { Error.Fatalf("failed converting price to int: %v", err) return } }) return price, nil }