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,68 +82,79 @@ 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") | ||||||
| 		username := mux.Vars(r)["actor"]  // get the needed actor from the muxer (url variable {actor} below)
 | 		pageStr := r.URL.Query().Get("page") // get the page from the query string as string
 | ||||||
| 		actor, err := LoadActor(username) // load the actor from disk
 | 		username := mux.Vars(r)["actor"]     // get the needed actor from the muxer (url variable {actor} below)
 | ||||||
| 		if err != nil {                   // either actor requested has illegal characters or
 | 		actor, err := LoadActor(username)    // load the actor from disk
 | ||||||
|  | 		if err != nil {                      // either actor requested has illegal characters or
 | ||||||
| 			log.Info("Can't load local actor") // we don't have such actor
 | 			log.Info("Can't load local actor") // we don't have such actor
 | ||||||
| 			fmt.Fprintf(w, "404 - page not found") | 			fmt.Fprintf(w, "404 - page not found") | ||||||
| 			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", | 			postsPerPage := 100 | ||||||
| 			"next" : "` + baseURL + actor.name + `/outbox?max_id=99524642494530460&page=true", | 			filename := storage + slash + "actors" + slash + actor.name + slash + "outbox.txt" | ||||||
| 			"orderedItems" :[ | 			lines, err := ReadLines(filename, (page-1)*postsPerPage, page*(postsPerPage+1)-1) | ||||||
| 				{ | 			if err != nil { | ||||||
| 					"actor" : "https://` + baseURL + actor.name + `", | 				log.Info("Can't read outbox file") | ||||||
| 					"cc" : [ | 				log.Info(err) | ||||||
| 					   "https://` + baseURL + actor.name + `/followers" | 				return | ||||||
| 					], | 			} | ||||||
| 					"id" : "https://` + baseURL + actor.name + `/` + id + `", | 			responseMap := make(map[string]interface{}) | ||||||
| 					"object" : { | 			responseMap["@context"] = context() | ||||||
| 					   "attributedTo" : "https://` + baseURL + actor.name + `", | 			responseMap["id"] = baseURL + actor.name + "/outbox?page=" + pageStr | ||||||
| 					   "cc" : [ | 			totalLines, err := lineCounter(filename) | ||||||
| 						  "https://` + baseURL + actor.name + `/followers" | 			if err != nil { | ||||||
| 					   ], | 				log.Info("The file was deleted? It was okay a few lines above. Wtf?") | ||||||
| 					   "content" : "` + content + `", | 				log.Info(err) | ||||||
| 					   "id" : "https://` + baseURL + actor.name + `/` + id + `", | 				return | ||||||
| 					   "inReplyTo" : null, | 			} | ||||||
| 					   "published" : "2019-08-26T16:25:26Z", | 			if page*postsPerPage < totalLines { | ||||||
| 					   "to" : [ | 				responseMap["next"] = baseURL + actor.name + "/outbox?page=" + strconv.Itoa(page+1) | ||||||
| 						  "https://www.w3.org/ns/activitystreams#Public" | 			} | ||||||
| 					   ], | 			if page > 1 { | ||||||
| 					   "type" : "Note", | 				responseMap["prev"] = baseURL + actor.name + "/outbox?page=" + strconv.Itoa(page-1) | ||||||
| 					   "url" : "https://` + baseURL + actor.name + `/` + id + `" | 			} | ||||||
| 					}, | 			responseMap["partOf"] = baseURL + actor.name + "/outbox" | ||||||
| 					"published" : "2019-08-26T16:25:26Z", | 			responseMap["type"] = "OrderedCollectionPage" | ||||||
| 					"to" : [ | 
 | ||||||
| 					   "https://www.w3.org/ns/activitystreams#Public" | 			orderedItems := make(map[string]interface{}) | ||||||
| 					], | 
 | ||||||
| 					"type" : "Create" | 			for item := range lines { | ||||||
| 				 } | 				// read the line
 | ||||||
| 			], | 				// parse the hash
 | ||||||
| 			"partOf" : "` + baseURL + actor.name + `/outbox", | 				// build the filename
 | ||||||
| 			"prev" : "` + baseURL + actor.name + `/outbox?min_id=99982453036184436&page=true", | 				// open the file
 | ||||||
| 			"type" : "OrderedCollectionPage" | 				// 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([]byte(response)) | 		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