WIP: working on printing paged outbox
parent
47dfecbeb3
commit
29ad8059ba
|
@ -482,7 +482,7 @@ func (a *Actor) appendToOutbox(iri string) (err error) {
|
||||||
// create outbox file if it doesn't exist
|
// create outbox file if it doesn't exist
|
||||||
var outbox *os.File
|
var outbox *os.File
|
||||||
|
|
||||||
outboxFilePath := storage + slash + "actors" + slash + a.name + slash + "outbox"
|
outboxFilePath := storage + slash + "actors" + slash + a.name + slash + "outbox.txt"
|
||||||
outbox, err = os.OpenFile(outboxFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
outbox, err = os.OpenFile(outboxFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Cannot create or open outbox file")
|
log.Info("Cannot create or open outbox file")
|
||||||
|
@ -491,7 +491,7 @@ func (a *Actor) appendToOutbox(iri string) (err error) {
|
||||||
}
|
}
|
||||||
defer outbox.Close()
|
defer outbox.Close()
|
||||||
|
|
||||||
outbox.Write([]byte(iri))
|
outbox.Write([]byte(iri + "\n"))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,7 @@ func Serve() {
|
||||||
|
|
||||||
var outboxHandler http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) {
|
var outboxHandler http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("content-type", "application/activity+json; charset=utf-8")
|
w.Header().Set("content-type", "application/activity+json; charset=utf-8")
|
||||||
|
pageStr := r.URL.Query().Get("page") // get the page from the query string as string
|
||||||
username := mux.Vars(r)["actor"] // get the needed actor from the muxer (url variable {actor} below)
|
username := mux.Vars(r)["actor"] // get the needed actor from the muxer (url variable {actor} below)
|
||||||
actor, err := LoadActor(username) // load the actor from disk
|
actor, err := LoadActor(username) // load the actor from disk
|
||||||
if err != nil { // either actor requested has illegal characters or
|
if err != nil { // either actor requested has illegal characters or
|
||||||
|
@ -90,60 +91,70 @@ func Serve() {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var response string
|
var response []byte
|
||||||
if r.URL.Query().Get("page") == "" {
|
if pageStr == "" {
|
||||||
//TODO fix total items
|
//TODO fix total items
|
||||||
response = `{
|
response = []byte(`{
|
||||||
"@context" : "https://www.w3.org/ns/activitystreams",
|
"@context" : "https://www.w3.org/ns/activitystreams",
|
||||||
"first" : "` + baseURL + actor.name + `/outbox?page=true",
|
"first" : "` + baseURL + actor.name + `/outbox?page=true",
|
||||||
"id" : "` + baseURL + actor.name + `/outbox",
|
"id" : "` + baseURL + actor.name + `/outbox",
|
||||||
"last" : "` + baseURL + actor.name + `/outbox?min_id=0&page=true",
|
"last" : "` + baseURL + actor.name + `/outbox?min_id=0&page=1",
|
||||||
"totalItems" : 10,
|
"totalItems" : 10,
|
||||||
"type" : "OrderedCollection"
|
"type" : "OrderedCollection"
|
||||||
}`
|
}`)
|
||||||
} else {
|
} else {
|
||||||
content := "Hello, World!"
|
page, err := strconv.Atoi(pageStr) // get page number from query string
|
||||||
id := "asfdasdf"
|
if err != nil {
|
||||||
response = `
|
log.Info("Page number not a number, assuming 1")
|
||||||
{
|
page = 1
|
||||||
"@context" : "https://www.w3.org/ns/activitystreams",
|
|
||||||
"id" : "` + baseURL + actor.name + `/outbox?min_id=0&page=true",
|
|
||||||
"next" : "` + baseURL + actor.name + `/outbox?max_id=99524642494530460&page=true",
|
|
||||||
"orderedItems" :[
|
|
||||||
{
|
|
||||||
"actor" : "https://` + baseURL + actor.name + `",
|
|
||||||
"cc" : [
|
|
||||||
"https://` + baseURL + actor.name + `/followers"
|
|
||||||
],
|
|
||||||
"id" : "https://` + baseURL + actor.name + `/` + id + `",
|
|
||||||
"object" : {
|
|
||||||
"attributedTo" : "https://` + baseURL + actor.name + `",
|
|
||||||
"cc" : [
|
|
||||||
"https://` + baseURL + actor.name + `/followers"
|
|
||||||
],
|
|
||||||
"content" : "` + content + `",
|
|
||||||
"id" : "https://` + baseURL + actor.name + `/` + id + `",
|
|
||||||
"inReplyTo" : null,
|
|
||||||
"published" : "2019-08-26T16:25:26Z",
|
|
||||||
"to" : [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
],
|
|
||||||
"type" : "Note",
|
|
||||||
"url" : "https://` + baseURL + actor.name + `/` + id + `"
|
|
||||||
},
|
|
||||||
"published" : "2019-08-26T16:25:26Z",
|
|
||||||
"to" : [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
],
|
|
||||||
"type" : "Create"
|
|
||||||
}
|
}
|
||||||
],
|
postsPerPage := 100
|
||||||
"partOf" : "` + baseURL + actor.name + `/outbox",
|
filename := storage + slash + "actors" + slash + actor.name + slash + "outbox.txt"
|
||||||
"prev" : "` + baseURL + actor.name + `/outbox?min_id=99982453036184436&page=true",
|
lines, err := ReadLines(filename, (page-1)*postsPerPage, page*(postsPerPage+1)-1)
|
||||||
"type" : "OrderedCollectionPage"
|
if err != nil {
|
||||||
}`
|
log.Info("Can't read outbox file")
|
||||||
|
log.Info(err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
w.Write([]byte(response))
|
responseMap := make(map[string]interface{})
|
||||||
|
responseMap["@context"] = context()
|
||||||
|
responseMap["id"] = baseURL + actor.name + "/outbox?page=" + pageStr
|
||||||
|
totalLines, err := lineCounter(filename)
|
||||||
|
if err != nil {
|
||||||
|
log.Info("The file was deleted? It was okay a few lines above. Wtf?")
|
||||||
|
log.Info(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if page*postsPerPage < totalLines {
|
||||||
|
responseMap["next"] = baseURL + actor.name + "/outbox?page=" + strconv.Itoa(page+1)
|
||||||
|
}
|
||||||
|
if page > 1 {
|
||||||
|
responseMap["prev"] = baseURL + actor.name + "/outbox?page=" + strconv.Itoa(page-1)
|
||||||
|
}
|
||||||
|
responseMap["partOf"] = baseURL + actor.name + "/outbox"
|
||||||
|
responseMap["type"] = "OrderedCollectionPage"
|
||||||
|
|
||||||
|
orderedItems := make(map[string]interface{})
|
||||||
|
|
||||||
|
for item := range lines {
|
||||||
|
// read the line
|
||||||
|
// parse the hash
|
||||||
|
// build the filename
|
||||||
|
// open the file
|
||||||
|
// unmarshal
|
||||||
|
// append to orderedItems
|
||||||
|
}
|
||||||
|
|
||||||
|
responseMap["orderedItems"] = orderedItems
|
||||||
|
|
||||||
|
response, err = json.Marshal(responseMap)
|
||||||
|
if err != nil {
|
||||||
|
log.Info("can't marshal map to json")
|
||||||
|
log.Info(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.Write(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
var inboxHandler http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) {
|
var inboxHandler http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -200,7 +211,6 @@ func Serve() {
|
||||||
accept["object"] = activity
|
accept["object"] = activity
|
||||||
accept["type"] = "Accept"
|
accept["type"] = "Accept"
|
||||||
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Couldn't retrieve remote actor info, maybe server is down?")
|
log.Info("Couldn't retrieve remote actor info, maybe server is down?")
|
||||||
log.Info(err)
|
log.Info(err)
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
package activityserve
|
package activityserve
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
// "net/url"
|
// "net/url"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -50,3 +54,49 @@ func FormatHeaders(header http.Header) string {
|
||||||
func context() [1]string {
|
func context() [1]string {
|
||||||
return [1]string{"https://www.w3.org/ns/activitystreams"}
|
return [1]string{"https://www.w3.org/ns/activitystreams"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadLines reads specific lines from a file and returns them as
|
||||||
|
// an array of strings
|
||||||
|
func ReadLines(filename string, from, to int) (lines []string, err error) {
|
||||||
|
lines = make([]string, to-from)
|
||||||
|
reader, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
log.Info("could not read file")
|
||||||
|
log.Info(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sc := bufio.NewScanner(reader)
|
||||||
|
line := 0
|
||||||
|
for sc.Scan() {
|
||||||
|
line++
|
||||||
|
if line >= from && line <= to {
|
||||||
|
lines = append(lines, sc.Text())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lines, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func lineCounter(filename string) (int, error) {
|
||||||
|
r, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
log.Info("could not read file")
|
||||||
|
log.Info(err)
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
buf := make([]byte, 32*1024)
|
||||||
|
count := 0
|
||||||
|
lineSep := []byte{'\n'}
|
||||||
|
|
||||||
|
for {
|
||||||
|
c, err := r.Read(buf)
|
||||||
|
count += bytes.Count(buf[:c], lineSep)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case err == io.EOF:
|
||||||
|
return count, nil
|
||||||
|
|
||||||
|
case err != nil:
|
||||||
|
return count, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue