vivaplusdl/vivaweb.go

106 lines
2.4 KiB
Go

package main
import (
"errors"
"fmt"
"github.com/PuerkitoBio/goquery"
"log"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
)
const BASE_URL = "https://vivaplus.tv/"
const SIGN_IN_URL = BASE_URL + "supporters/sign_in"
type WebClient struct {
csrfToken string
cookies *cookiejar.Jar
}
func NewWebClient() *WebClient {
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatalf("error creating cookiejar: %w", err)
}
return &WebClient{
cookies: jar,
}
}
func (w *WebClient) RegisterCookies(rawUrl string, resp *http.Response) {
u, err := url.Parse(rawUrl)
if err != nil {
log.Fatalf("error parsing url: %v", err)
}
w.cookies.SetCookies(u, resp.Cookies())
}
func (w *WebClient) UseCookies(rawUrl string, req *http.Request) {
u, err := url.Parse(rawUrl)
if err != nil {
log.Fatalf("error parsing url: %v", err)
}
for _, c := range w.cookies.Cookies(u) {
req.AddCookie(c)
}
}
func (w *WebClient) FetchCsrfToken() error {
resp, err := http.Get(SIGN_IN_URL)
if err != nil {
return fmt.Errorf("error getting sign in page: %w", err)
}
defer resp.Body.Close()
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
return fmt.Errorf("error parsing sign in page: %w", err)
}
w.RegisterCookies(SIGN_IN_URL, resp)
csrfTokenElement := doc.Find("meta[name='csrf-token']").First()
if csrfTokenElement == nil {
return errors.New("error getting csrf token element")
}
var exists bool
w.csrfToken, exists = csrfTokenElement.Attr("content")
if !exists {
return errors.New("error content attribute does not exist")
}
return nil
}
func (w *WebClient) VivaLogin(username, password string) error {
err := w.FetchCsrfToken()
if err != nil {
return err
}
form := url.Values{}
form.Set("email", username)
form.Set("password", password)
println("Encoded form:", form.Encode())
println("CSRF token:", w.csrfToken)
req, err := http.NewRequest("POST", SIGN_IN_URL, strings.NewReader(form.Encode()))
w.UseCookies(SIGN_IN_URL, req)
for _, c := range req.Cookies() {
println("Cookie:", c.Name, "=", c.Value)
}
if err != nil {
return fmt.Errorf("error creating login request: %w", err)
}
req.Header.Add("x-csrf-token", w.csrfToken)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("error logging in: %w", err)
}
log.Printf("Status code: %d", resp.StatusCode)
return nil
}