package main import ( "context" "fmt" "strings" "log" "encoding/json" "github.com/jackc/pgx/pgxpool" "time" "net/http" // "io/ioutil" // "github.com/davecgh/go-spew/spew" ) type ImageType struct { // Type string `json:"type"` Url string `json:"url"` } type PublicKeyType struct { PublicKeyPem string `json:"publicKeyPem"` } type UserJson struct { ID string `json:"id"` Type string `json:"type"` Inbox string `json:"inbox"` Outbox string `json:"outbox"` Followers string `json:"followers"` Following string `json:"following"` Url string `json:"url"` PreferredUsername string `json:"preferredUsername"` Name string `json:"name"` Summary string `json:"summary"` Icon ImageType `json:"icon"` Image ImageType `json:"image"` PublicKey PublicKeyType `json:"publicKey"` instance string } type PostJson struct { ID string `json:"id"` InReplyTo string `json:"inReplyTo"` normalized string posthash []byte receivedAt time.Time `json:"created_at"` Content string `json:"content"` Conversation string `json:"conversation"` Published time.Time `json:"published"` Source string `json:"source"` Summary string `json:"summary"` // Ignoring tag for now To []string `json:"to"` Type string `json:"type"` Actor string `json:"actor"` AttributedTo string `json:"attributedTo"` instance string } type ConnRequest struct { conn chan *pgxpool.Conn b chan bool } func requestConn() { conn, _:= pool.Acquire(context.Background()) defer conn.Release() for connRequest := range requestconnchan { fmt.Println("Sending request") connRequest.conn <-conn _ = <-connRequest.b } } func check_post(uri string) (PostJson, error) { // conn, _:= pool.Acquire(context.Background()) // defer conn.Release() connrequest := ConnRequest{} connrequest.conn = make(chan *pgxpool.Conn) connrequest.b = make(chan bool) requestconnchan <- connrequest myconn := <-connrequest.conn var postjson PostJson selectRet := myconn.QueryRow(context.Background(), "SELECT id, inReplyTo, published, summary, content, normalized, attributedto, posthash, received_at FROM posts WHERE id = $1", uri) err := selectRet.Scan(&postjson.ID, &postjson.InReplyTo, &postjson.Published, &postjson.Summary, &postjson.Content, &postjson.normalized, &postjson.AttributedTo, &postjson.posthash, &postjson.receivedAt) close(connrequest.b) if err == nil { fmt.Println("First return!") return postjson, nil } log.Print(uri) endslash := strings.Index(uri[8:], "/") postjson.instance = uri[8:endslash+8] client := http.Client{} req, _ := http.NewRequest("GET", uri, nil) req.Header.Add("Accept", "application/ld+json") resp, err := client.Do(req) err = json.NewDecoder(resp.Body).Decode(&postjson) if err != nil { return postjson, err } if postjson.InReplyTo != "" && postjson.InReplyTo != uri { log.Print("GOING INTO NEW POST: ", postjson.InReplyTo) go check_post(postjson.InReplyTo) } check_user(postjson.AttributedTo) // This must be done BEFORE the `INSERT INTO posts` below connrequest = ConnRequest{} connrequest.conn = make(chan *pgxpool.Conn) connrequest.b = make(chan bool) requestconnchan <- connrequest myconn = <-connrequest.conn _, err = myconn.Exec(context.Background(), "INSERT INTO posts (id, inReplyTo, published, summary, content, normalized, attributedto, posthash, instance) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9)", postjson.ID, postjson.InReplyTo, postjson.Published, postjson.Summary, postjson.Content, postjson.normalized, postjson.AttributedTo, postjson.posthash, postjson.instance) close(connrequest.b) if err != nil { log.Print("INSERT posts ", err) return postjson, err } for _, to := range postjson.To { if to != "https://www.w3.org/ns/activitystreams#Public" { log.Print("Going into: " + to) go check_user(to) } } fmt.Println("Second return") return postjson, nil } func check_user(uri string) (UserJson, error) { // conn, _:= pool.Acquire(context.Background()) // defer conn.Release() connrequest := ConnRequest{} connrequest.conn = make(chan *pgxpool.Conn) connrequest.b = make(chan bool) requestconnchan <- connrequest myconn := <-connrequest.conn var userjson UserJson selectRet := myconn.QueryRow(context.Background(), "SELECT id, actor_type, inbox, outbox, followers, following, url, preferredUsername, name, summary, icon, image, publicKey, instance FROM accounts WHERE id = $1", uri) err := selectRet.Scan(&userjson.ID, &userjson.Type, &userjson.Inbox, &userjson.Outbox, &userjson.Followers, &userjson.Following, &userjson.Url, &userjson.PreferredUsername, &userjson.Name, &userjson.Summary, &userjson.Icon.Url, &userjson.Image.Url, &userjson.PublicKey.PublicKeyPem, &userjson.instance) close(connrequest.b) if err == nil { fmt.Println("First return!") return userjson, nil } endslash := strings.Index(uri[8:], "/") userjson.instance = uri[8:endslash+8] client := http.Client{} req, _ := http.NewRequest("GET", uri, nil) req.Header.Add("Accept", "application/ld+json") resp, err := client.Do(req) if err != nil { //log.Fatal(err) return userjson, err } err = json.NewDecoder(resp.Body).Decode(&userjson) if err != nil { //log.Fatal(err) return userjson, err } connrequest = ConnRequest{} connrequest.conn = make(chan *pgxpool.Conn) connrequest.b = make(chan bool) requestconnchan <- connrequest myconn = <-connrequest.conn _, err = myconn.Exec(context.Background(), "INSERT INTO accounts (id, actor_type, inbox, outbox, followers, following, url, preferredUsername, name, summary, icon, image, publicKey, instance) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)", userjson.ID, userjson.Type, userjson.Inbox, userjson.Outbox, userjson.Followers, userjson.Following, userjson.Url, userjson.PreferredUsername, userjson.Name, userjson.Summary, userjson.Icon.Url, userjson.Image.Url, userjson.PublicKey.PublicKeyPem, userjson.instance) close(connrequest.b) if err != nil { //log.Fatal("INSERT accounts ", err) return userjson, err } fmt.Println("Second return") return userjson, nil } //var pool *pgxpool.Pool /* func main() { getDbPool() // userjson := check_user("https://islamicate.space/users/fikran") // _ = check_user("https://social.farhan.codes/users/testacct555") // postjson := spew.Dump(userjson) postjson, err := check_post("https://social.farhan.codes/objects/39cb2c26-153e-4e2e-bb3e-4d6971c04df1") if err != nil { log.Fatal("The error is: ", err) } fmt.Println(postjson) // check_post("https://honk.tedunangst.com/u/tedu/h/v1Mz2rgpw1b45g99vS") } */