split out claude package, report weight breakdowns, add slog tracing
This commit is contained in:
+18
-3
@@ -11,7 +11,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -21,6 +21,14 @@ import (
|
||||
"github.com/chromedp/chromedp"
|
||||
)
|
||||
|
||||
// trace logs the start of an operation and, via the returned func, its end and
|
||||
// duration. It is a no-op above debug level, so it only appears with -v.
|
||||
func trace(op string) func() {
|
||||
t0 := time.Now()
|
||||
slog.Debug("begin", "op", op)
|
||||
return func() { slog.Debug("end", "op", op, "dur", time.Since(t0)) }
|
||||
}
|
||||
|
||||
const (
|
||||
baseURL = "https://3dfilamentprofiles.com"
|
||||
challengeText = "Security Checkpoint"
|
||||
@@ -79,6 +87,7 @@ func New(opts ...Option) (*Client, error) {
|
||||
// Allocate the browser bound to the long-lived browserCtx. chromedp ties the
|
||||
// Chrome process lifetime to the context of the first Run, so this must not
|
||||
// be a short-lived per-call context (otherwise the browser dies after it).
|
||||
defer trace("spooldb.launchBrowser")()
|
||||
if err := chromedp.Run(browserCtx, chromedp.Navigate("about:blank")); err != nil {
|
||||
browserCancel()
|
||||
allocCancel()
|
||||
@@ -98,7 +107,7 @@ func chromeErrorf(format string, args ...any) {
|
||||
if strings.HasPrefix(format, "unhandled ") {
|
||||
return
|
||||
}
|
||||
log.Printf("chromedp: "+format, args...)
|
||||
slog.Warn("chromedp: " + fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
// Close shuts down the browser.
|
||||
@@ -121,13 +130,15 @@ func (c *Client) run(ctx context.Context, timeout time.Duration, actions ...chro
|
||||
// awaitChallenge waits until the Vercel checkpoint clears (the headless browser
|
||||
// solves it automatically by running the page's JavaScript).
|
||||
func (c *Client) awaitChallenge(ctx context.Context) error {
|
||||
defer trace("spooldb.awaitChallenge")()
|
||||
deadline := time.Now().Add(45 * time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
for polls := 0; time.Now().Before(deadline); polls++ {
|
||||
var title string
|
||||
if err := c.run(ctx, 10*time.Second, chromedp.Title(&title)); err != nil {
|
||||
return err
|
||||
}
|
||||
if !strings.Contains(title, challengeText) {
|
||||
slog.Debug("challenge cleared", "polls", polls)
|
||||
return nil
|
||||
}
|
||||
select {
|
||||
@@ -141,6 +152,7 @@ func (c *Client) awaitChallenge(ctx context.Context) error {
|
||||
|
||||
// Login authenticates with email/password. Safe to call once per Client.
|
||||
func (c *Client) Login(ctx context.Context, email, password string) error {
|
||||
defer trace("spooldb.login")()
|
||||
if err := c.run(ctx, 45*time.Second, chromedp.Navigate(baseURL+"/login")); err != nil {
|
||||
return fmt.Errorf("navigate to login: %w", err)
|
||||
}
|
||||
@@ -188,6 +200,7 @@ type SpoolInfo struct {
|
||||
// direct URL for the dialog; it is opened from the spool page by the pencil
|
||||
// button, which sits between the QR-code and delete buttons in the card header.
|
||||
func (c *Client) openEdit(ctx context.Context, spoolID string) error {
|
||||
defer trace("spooldb.openEdit")()
|
||||
if !c.loggedIn {
|
||||
return errors.New("not logged in")
|
||||
}
|
||||
@@ -232,6 +245,7 @@ func (c *Client) openEdit(ctx context.Context, spoolID string) error {
|
||||
|
||||
// SpoolInfo opens a spool's edit dialog and reads its location and weights.
|
||||
func (c *Client) SpoolInfo(ctx context.Context, spoolID string) (SpoolInfo, error) {
|
||||
defer trace("spooldb.spoolInfo")()
|
||||
if err := c.openEdit(ctx, spoolID); err != nil {
|
||||
return SpoolInfo{}, err
|
||||
}
|
||||
@@ -265,6 +279,7 @@ func (c *Client) SpoolInfo(ctx context.Context, spoolID string) (SpoolInfo, erro
|
||||
// — the site recomputes remaining filament from the empty-spool weight — and
|
||||
// saves. grams is the weight read off the scale (filament plus spool).
|
||||
func (c *Client) SetTotalWeight(ctx context.Context, spoolID string, grams float64) error {
|
||||
defer trace("spooldb.setTotalWeight")()
|
||||
if err := c.openEdit(ctx, spoolID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user