diff --git a/plausibleclient/client.go b/plausibleclient/client.go index 15289ad..54d76d1 100644 --- a/plausibleclient/client.go +++ b/plausibleclient/client.go @@ -4,6 +4,8 @@ import ( "net/http" "net/http/cookiejar" "net/url" + + "github.com/PuerkitoBio/goquery" ) type Client struct { @@ -12,6 +14,7 @@ type Client struct { password string loggedIn bool mutexkv *MutexKV + baseURL string } func (c *Client) login() error { @@ -30,6 +33,7 @@ func NewClient(username, password string) *Client { c := Client{} c.username = username c.password = password + c.baseURL = "https://plausible.io" jar, err := cookiejar.New(nil) if err != nil { @@ -44,3 +48,18 @@ func NewClient(username, password string) *Client { return &c } + +func (c *Client) getDocument(path string) (*goquery.Document, error) { + resp, err := c.httpClient.Get(c.baseURL + path) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + doc, err := goquery.NewDocumentFromReader(resp.Body) + if err != nil { + return nil, err + } + + return doc, nil +} diff --git a/plausibleclient/goal.go b/plausibleclient/goal.go index ded389b..d808d01 100644 --- a/plausibleclient/goal.go +++ b/plausibleclient/goal.go @@ -33,14 +33,7 @@ func (c *Client) CreateGoal(domain string, goalType GoalType, goal string) (*Goa c.mutexkv.Lock(domain) defer c.mutexkv.Unlock(domain) - resp, err := c.httpClient.Get("https://plausible.io/" + domain + "/goals/new") - if err != nil { - return nil, err - } - defer resp.Body.Close() - - // Load the HTML document - doc, err := goquery.NewDocumentFromReader(resp.Body) + doc, err := c.getDocument("/" + domain + "/goals/new") if err != nil { return nil, err } @@ -122,14 +115,7 @@ func (c *Client) GetGoal(domain string, id int) (*Goal, error) { result := Goal{ID: id, Domain: domain} - resp, err := c.httpClient.Get("https://plausible.io/" + domain + "/settings") - if err != nil { - return nil, err - } - defer resp.Body.Close() - - // Load the HTML document - doc, err := goquery.NewDocumentFromReader(resp.Body) + doc, err := c.getDocument("/" + domain + "/settings/goals") if err != nil { return nil, err } @@ -137,7 +123,7 @@ func (c *Client) GetGoal(domain string, id int) (*Goal, error) { cssSelector := fmt.Sprintf(`button[data-to="/%s/goals/%d"]`, domain, id) doc.Find(cssSelector).Each(func(i int, s *goquery.Selection) { var c string - s.SiblingsFiltered("small").Each(func(i int, s *goquery.Selection) { + s.SiblingsFiltered("span").Each(func(i int, s *goquery.Selection) { h, _ := s.Html() c = strings.TrimSpace(h) }) @@ -163,14 +149,7 @@ func (c *Client) DeleteGoal(domain string, id int) error { c.mutexkv.Lock(domain) defer c.mutexkv.Unlock(domain) - resp, err := c.httpClient.Get("https://plausible.io/" + domain + "/settings") - if err != nil { - return err - } - defer resp.Body.Close() - - // Load the HTML document - doc, err := goquery.NewDocumentFromReader(resp.Body) + doc, err := c.getDocument("/" + domain + "/settings/goals") if err != nil { return err } diff --git a/plausibleclient/shared_link.go b/plausibleclient/shared_link.go index b609698..494d55c 100644 --- a/plausibleclient/shared_link.go +++ b/plausibleclient/shared_link.go @@ -27,14 +27,7 @@ func (c *Client) CreateSharedLink(domain, password string) (*SharedLink, error) c.mutexkv.Lock(domain) defer c.mutexkv.Unlock(domain) - resp, err := c.httpClient.Get("https://plausible.io/sites/" + domain + "/shared-links/new") - if err != nil { - return nil, err - } - defer resp.Body.Close() - - // Load the HTML document - doc, err := goquery.NewDocumentFromReader(resp.Body) + doc, err := c.getDocument("/sites/" + domain + "/shared-links/new") if err != nil { return nil, err } @@ -105,14 +98,7 @@ func (c *Client) DeleteSharedLink(domain, id string) error { c.mutexkv.Lock(domain) defer c.mutexkv.Unlock(domain) - resp, err := c.httpClient.Get("https://plausible.io/" + domain + "/settings") - if err != nil { - return err - } - defer resp.Body.Close() - - // Load the HTML document - doc, err := goquery.NewDocumentFromReader(resp.Body) + doc, err := c.getDocument("/" + domain + "/settings/visibility") if err != nil { return err } diff --git a/plausibleclient/site.go b/plausibleclient/site.go index 3995e04..44dc217 100644 --- a/plausibleclient/site.go +++ b/plausibleclient/site.go @@ -16,15 +16,8 @@ func (c *Client) CreateSite(domain, timezone string) (*SiteSettings, error) { return nil, err } } - // get csrf token - resp, err := c.httpClient.Get("https://plausible.io/sites/new") - if err != nil { - return nil, err - } - defer resp.Body.Close() - // Load the HTML document - doc, err := goquery.NewDocumentFromReader(resp.Body) + doc, err := c.getDocument("/sites/new") if err != nil { return nil, err } @@ -57,15 +50,8 @@ func (c *Client) DeleteSite(domain string) error { return err } } - // get csrf token - resp, err := c.httpClient.Get("https://plausible.io/" + domain + "/settings") - if err != nil { - return nil - } - defer resp.Body.Close() - // Load the HTML document - doc, err := goquery.NewDocumentFromReader(resp.Body) + doc, err := c.getDocument("/" + domain + "/settings/danger-zone") if err != nil { return err } @@ -82,7 +68,7 @@ func (c *Client) DeleteSite(domain string) error { values := url.Values{} values.Add("_csrf_token", csrfToken) values.Add("_method", "delete") - resp, err = c.httpClient.PostForm("https://plausible.io/"+domain, values) + _, err = c.httpClient.PostForm("https://plausible.io/"+domain, values) return err } @@ -93,15 +79,8 @@ func (c *Client) UpdateSite(domain, timezone string) (*SiteSettings, error) { return nil, err } } - // get csrf token - resp, err := c.httpClient.Get("https://plausible.io/" + domain + "/settings") - if err != nil { - return nil, err - } - defer resp.Body.Close() - // Load the HTML document - doc, err := goquery.NewDocumentFromReader(resp.Body) + doc, err := c.getDocument("/" + domain + "/settings/general") if err != nil { return nil, err } @@ -141,13 +120,8 @@ func (c *Client) GetSiteSettings(domain string) (*SiteSettings, error) { return nil, err } } - resp, err := c.httpClient.Get("https://plausible.io/" + domain + "/settings") - if err != nil { - return nil, err - } - defer resp.Body.Close() - doc, err := goquery.NewDocumentFromReader(resp.Body) + doc, err := c.getDocument("/" + domain + "/settings/general") if err != nil { return nil, err } @@ -169,6 +143,11 @@ func (c *Client) GetSiteSettings(domain string) (*SiteSettings, error) { return nil, fmt.Errorf("could not find timezone in HTML document for %s", domain) } + doc, err = c.getDocument("/" + domain + "/settings/visibility") + if err != nil { + return nil, err + } + var sharedLinks []string doc.Find(`[value*='https://plausible.io/share/']`).Each(func(i int, s *goquery.Selection) { sharedLink, sharedLinkExists := s.Attr("value") @@ -177,6 +156,11 @@ func (c *Client) GetSiteSettings(domain string) (*SiteSettings, error) { } }) + doc, err = c.getDocument("/" + domain + "/settings/goals") + if err != nil { + return nil, err + } + var goals []int var errs []error doc.Find(`button[data-to*="/` + domain + `/goals/"]`).Each(func(i int, s *goquery.Selection) { @@ -203,3 +187,27 @@ func (c *Client) GetSiteSettings(domain string) (*SiteSettings, error) { Goals: goals, }, nil } + +func (c *Client) ListSites() ([]string, error) { + if !c.loggedIn { + err := c.login() + if err != nil { + return nil, err + } + } + doc, err := c.getDocument("/sites") + if err != nil { + return nil, err + } + + var domains []string + doc.Find("a[href*='/settings']").Each(func(i int, s *goquery.Selection) { + href, exists := s.Attr("href") + parts := strings.Split(href, "/") + if exists { + domains = append(domains, parts[1]) + } + }) + + return domains, nil +}