package main import ( "context" "fmt" "log" "os" // added for logging to file "time" "github.com/chromedp/chromedp" ) const ( webUrl = "https://gisem.dei.estg.ipleiria.pt" ) var waitTime int var isVerbose bool var maxTime int var logFile string func main() { //* Parse the flags wait, verbose, headless, logFile, timeout, replacePass, err := parseFlags() if err != nil { log.Fatalf("Failed to parse flags: %v", err) } waitTime = wait isVerbose = verbose maxTime = timeout if logFile != "" { file, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) if err != nil { log.Fatalf("Failed to open log file: %v", err) } defer file.Close() log.SetOutput(file) } if isVerbose { fmt.Println("Waiting time:", waitTime) fmt.Println("Verbose mode:", isVerbose) fmt.Println("Headless mode:", headless) if logFile == "" { fmt.Println("Logging to file: disabled") } else { fmt.Println("Logging to file:", logFile) } if maxTime == -1 { log.Println("Max time: disabled") } else { log.Println("Max time:", maxTime) } } //* Welcome message welcomeMessage() if logFile != "" { fmt.Println("Logging to file:", logFile) fmt.Println("(No text will be shown because logging is enabled, dont worry, the program is still running)") log.Print("Starting new program... (logging to file)\n\n") isVerbose = true if maxTime == -1 { log.Println("Max time: disabled") } else { log.Println("Max time:", maxTime) } } creds, err := getCreds() if replacePass { creds, err = promptAndSaveCreds(credFile) if err != nil { log.Fatalf("Failed to get credentials: %v", err) } if isVerbose { log.Println("Credentials replaced") } } if err != nil { // If the credentials file doesn't exist, prompt for credentials if err.Error() == "credentials file not found: stat "+credFile+": no such file or directory" { // The file doesn't exist, create it by prompting for credentials creds, err = promptAndSaveCreds(credFile) if err != nil { log.Fatalf("Failed to get credentials: %v", err) } } else { log.Fatalf("Failed to get credentials: %v", err) } } opts := append(chromedp.DefaultExecAllocatorOptions[:], chromedp.Flag("headless", headless), // Disable headless mode chromedp.Flag("disable-gpu", headless), // Enable GPU chromedp.Flag("start-maximized", !headless), // Start maximized ) allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...) defer cancel() ctx, cancel := chromedp.NewContext(allocCtx) defer cancel() //* Navigate to the website if err := chromedp.Run(ctx, chromedp.Navigate(webUrl)); err != nil { log.Fatalf("Failed to navigate: %v", err) } if isVerbose { log.Println("Navigated to the website") } //* Check if there's a login button var isVisible bool if err := chromedp.Run(ctx, chromedp.Tasks{ chromedp.WaitVisible(loginButton), chromedp.Evaluate(fmt.Sprintf("document.querySelector('%s').offsetParent !== null", loginButton), &isVisible), }); err != nil { log.Fatalf("Failed to evaluate: %v", err) } if isVerbose { log.Println("Login button visible:", isVisible) } if isVisible { log.Println("Logging in...") if err := login(ctx, creds); err != nil { log.Fatalf("Failed to login: %v", err) } time.Sleep(1 * time.Second) log.Println("Logged in!") if isVerbose { log.Println("Waiting for activation...") } if err := marcarPresenca(ctx); err != nil { log.Println("Failed to mark presence: %v", err) } else { log.Println("Presence marked!") } } log.Print("Program finished successfully! (logging to file) \n\n") }