Handle guest token / session initialization when not connected to internet
This commit is contained in:
parent
0fd17f1af0
commit
ef15e8a306
@ -129,7 +129,12 @@ func main() {
|
|||||||
scraper.InitApi(profile.LoadSession(scraper.UserHandle(*session_name)))
|
scraper.InitApi(profile.LoadSession(scraper.UserHandle(*session_name)))
|
||||||
// fmt.Printf("Operating as user: @%s\n", scraper.the_api.UserHandle)
|
// fmt.Printf("Operating as user: @%s\n", scraper.the_api.UserHandle)
|
||||||
} else {
|
} else {
|
||||||
scraper.InitApi(scraper.NewGuestSession())
|
session, err := scraper.NewGuestSession()
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("Unable to initialize guest session! Might be a network issue")
|
||||||
|
} else {
|
||||||
|
scraper.InitApi(session)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch operation {
|
switch operation {
|
||||||
@ -222,7 +227,10 @@ func main() {
|
|||||||
// - password: twitter account password
|
// - password: twitter account password
|
||||||
func login(username string, password string) {
|
func login(username string, password string) {
|
||||||
// Skip the scraper.the_api variable, just use a local one since no scraping is happening
|
// Skip the scraper.the_api variable, just use a local one since no scraping is happening
|
||||||
api := scraper.NewGuestSession()
|
api, err := scraper.NewGuestSession()
|
||||||
|
if err != nil {
|
||||||
|
die(fmt.Sprintf("Unable to create session: %s", err.Error()), false, 1)
|
||||||
|
}
|
||||||
challenge := api.LogIn(username, password)
|
challenge := api.LogIn(username, password)
|
||||||
if challenge != nil {
|
if challenge != nil {
|
||||||
fmt.Printf("Secondary challenge issued:\n")
|
fmt.Printf("Secondary challenge issued:\n")
|
||||||
|
@ -42,7 +42,10 @@ func (app *Application) Login(w http.ResponseWriter, r *http.Request) {
|
|||||||
panic_if(json.Unmarshal(data, &form)) // TODO: HTTP 400 not 500
|
panic_if(json.Unmarshal(data, &form)) // TODO: HTTP 400 not 500
|
||||||
form.Validate()
|
form.Validate()
|
||||||
if len(form.FormErrors) == 0 {
|
if len(form.FormErrors) == 0 {
|
||||||
api := scraper.NewGuestSession()
|
api, err := scraper.NewGuestSession()
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error()) // Return it as a toast
|
||||||
|
}
|
||||||
challenge := api.LogIn(form.Username, form.Password)
|
challenge := api.LogIn(form.Username, form.Password)
|
||||||
if challenge != nil {
|
if challenge != nil {
|
||||||
panic( // Middleware will trap this panic and return an HTMX error toast
|
panic( // Middleware will trap this panic and return an HTMX error toast
|
||||||
|
@ -62,7 +62,6 @@ func (app *Application) WithMiddlewares() http.Handler {
|
|||||||
|
|
||||||
func (app *Application) SetActiveUser(handle scraper.UserHandle) error {
|
func (app *Application) SetActiveUser(handle scraper.UserHandle) error {
|
||||||
if handle == "no account" {
|
if handle == "no account" {
|
||||||
scraper.InitApi(scraper.NewGuestSession())
|
|
||||||
app.ActiveUser = get_default_user()
|
app.ActiveUser = get_default_user()
|
||||||
app.IsScrapingDisabled = true // API requests will fail b/c not logged in
|
app.IsScrapingDisabled = true // API requests will fail b/c not logged in
|
||||||
} else {
|
} else {
|
||||||
|
@ -11,5 +11,8 @@ var (
|
|||||||
ErrorIsTombstone = errors.New("tweet is a tombstone")
|
ErrorIsTombstone = errors.New("tweet is a tombstone")
|
||||||
ErrRateLimited = errors.New("rate limited")
|
ErrRateLimited = errors.New("rate limited")
|
||||||
ErrorDMCA = errors.New("video is DMCAed, unable to download (HTTP 403 Forbidden)")
|
ErrorDMCA = errors.New("video is DMCAed, unable to download (HTTP 403 Forbidden)")
|
||||||
ErrRequestTimeout = errors.New("request timed out")
|
|
||||||
|
// These are not API errors, but network errors generally
|
||||||
|
ErrNoInternet = errors.New("no internet connection")
|
||||||
|
ErrRequestTimeout = errors.New("request timed out")
|
||||||
)
|
)
|
||||||
|
@ -111,10 +111,10 @@ func (api API) add_authentication_headers(req *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGuestSession() API {
|
func NewGuestSession() (API, error) {
|
||||||
guestAPIString, err := GetGuestToken()
|
guestAPIString, err := GetGuestTokenWithRetries(3, 1*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return API{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
jar, err := cookiejar.New(nil)
|
jar, err := cookiejar.New(nil)
|
||||||
@ -129,7 +129,7 @@ func NewGuestSession() API {
|
|||||||
Jar: jar,
|
Jar: jar,
|
||||||
},
|
},
|
||||||
CSRFToken: "",
|
CSRFToken: "",
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) update_csrf_token() {
|
func (api *API) update_csrf_token() {
|
||||||
|
@ -2,8 +2,11 @@ package scraper
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -15,7 +18,20 @@ type GuestTokenResponse struct {
|
|||||||
|
|
||||||
var guestToken GuestTokenResponse
|
var guestToken GuestTokenResponse
|
||||||
|
|
||||||
|
func GetGuestTokenWithRetries(n int, sleep time.Duration) (ret string, err error) {
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
ret, err = GetGuestToken()
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Printf("Failed to get guest token: %s\nRetrying...", err.Error())
|
||||||
|
time.Sleep(sleep)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func GetGuestToken() (string, error) {
|
func GetGuestToken() (string, error) {
|
||||||
|
// Guest token is still valid; no need for new one
|
||||||
if time.Since(guestToken.RefreshedAt).Hours() < 1 {
|
if time.Since(guestToken.RefreshedAt).Hours() < 1 {
|
||||||
return guestToken.Token, nil
|
return guestToken.Token, nil
|
||||||
}
|
}
|
||||||
@ -29,6 +45,11 @@ func GetGuestToken() (string, error) {
|
|||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
var dnsErr *net.DNSError
|
||||||
|
if errors.As(err, &dnsErr) && dnsErr.Err == "server misbehaving" && dnsErr.Temporary() {
|
||||||
|
return "", ErrNoInternet
|
||||||
|
}
|
||||||
|
|
||||||
return "", fmt.Errorf("Error executing HTTP request:\n %w", err)
|
return "", fmt.Errorf("Error executing HTTP request:\n %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +175,11 @@ func ParseSingleUser(apiUser APIUser) (ret User, err error) {
|
|||||||
|
|
||||||
// Calls API#GetUser and returns the parsed result
|
// Calls API#GetUser and returns the parsed result
|
||||||
func GetUser(handle UserHandle) (User, error) {
|
func GetUser(handle UserHandle) (User, error) {
|
||||||
apiUser, err := NewGuestSession().GetUser(handle)
|
session, err := NewGuestSession() // This endpoint works better if you're not logged in
|
||||||
|
if err != nil {
|
||||||
|
return User{}, err
|
||||||
|
}
|
||||||
|
apiUser, err := session.GetUser(handle)
|
||||||
if apiUser.ScreenName == "" {
|
if apiUser.ScreenName == "" {
|
||||||
if apiUser.IsBanned || apiUser.DoesntExist {
|
if apiUser.IsBanned || apiUser.DoesntExist {
|
||||||
ret := GetUnknownUserWithHandle(handle)
|
ret := GetUnknownUserWithHandle(handle)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user