diff options
-rw-r--r-- | activityPubStruct.go | 14 | ||||
-rw-r--r-- | cacheDatabase.go | 8 | ||||
-rw-r--r-- | client.go | 91 | ||||
-rw-r--r-- | database.go | 8 | ||||
-rw-r--r-- | main.go | 10 | ||||
-rw-r--r-- | static/posts.html | 5 |
6 files changed, 94 insertions, 42 deletions
diff --git a/activityPubStruct.go b/activityPubStruct.go index 459259a..2c57c61 100644 --- a/activityPubStruct.go +++ b/activityPubStruct.go @@ -1,6 +1,8 @@ package main import ( + "time" + "encoding/json" "html/template" ) @@ -19,7 +21,7 @@ type ActivityRaw struct { ToRaw json.RawMessage `json:"to,omitempty"` BtoRaw json.RawMessage `json:"bto,omitempty"` CcRaw json.RawMessage `json:"cc,omitempty"` - Published string `json:"published,omitempty"` + Published time.Time `json:"published,omitempty"` ActorRaw json.RawMessage `json:"actor,omitempty"` ObjectRaw json.RawMessage `json:"object,omitempty"` } @@ -100,7 +102,7 @@ type Activity struct { To []string `json:"to, omitempty"` Bto []string `json:"bto,omitempty"` Cc []string `json:"cc, omitempty"` - Published string `json:"published,omitempty"` + Published time.Time `json:"published,omitempty"` Object *ObjectBase `json:"object, omitempty"` } @@ -123,8 +125,8 @@ type ObjectBase struct { InReplyTo []ObjectBase `json:"inReplyTo,omitempty"` Location string `json:"location,omitempty"` Preview *NestedObjectBase `json:"preview,omitempty"` - Published string `json:"published,omitempty"` - Updated string `json:"updated,omitempty"` + Published time.Time `json:"published,omitempty"` + Updated time.Time `json:"updated,omitempty"` Object *NestedObjectBase `json:"object,omitempty"` Attachment []ObjectBase `json:"attachment,omitempty"` Replies *CollectionBase `json:"replies,omitempty"` @@ -169,13 +171,13 @@ type NestedObjectBase struct { InReplyTo []ObjectBase `json:"inReplyTo,omitempty"` Location string `json:"location,omitempty"` Preview ObjectBase `json:"preview,omitempty"` - Published string `json:"published,omitempty"` + Published time.Time `json:"published,omitempty"` Attachment []ObjectBase `json:"attachment,omitempty"` Replies *CollectionBase `json:"replies,omitempty"` StartTime string `json:"startTime,omitempty"` Summary string `json:"summary,omitempty"` Tag []ObjectBase `json:"tag,omitempty"` - Updated string `json:"updated,omitempty"` + Updated time.Time `json:"updated,omitempty"` Deleted string `json:"deleted,omitempty"` Url []ObjectBase `json:"url,omitempty"` Href string `json:"href,omitempty"` diff --git a/cacheDatabase.go b/cacheDatabase.go index ffe5dad..d735cfe 100644 --- a/cacheDatabase.go +++ b/cacheDatabase.go @@ -92,7 +92,7 @@ func WriteActivitytoCache(db *sql.DB, obj ObjectBase) { return } - if obj.Updated == "" { + if obj.Updated.IsZero() { obj.Updated = obj.Published } @@ -127,7 +127,7 @@ func WriteActivitytoCacheWithAttachment(db *sql.DB, obj ObjectBase, attachment O return } - if obj.Updated == "" { + if obj.Updated.IsZero() { obj.Updated = obj.Published } @@ -158,7 +158,7 @@ func WriteAttachmentToCache(db *sql.DB, obj ObjectBase) { return } - if obj.Updated == "" { + if obj.Updated.IsZero() { obj.Updated = obj.Published } @@ -189,7 +189,7 @@ func WritePreviewToCache(db *sql.DB, obj NestedObjectBase) { return } - if obj.Updated == "" { + if obj.Updated.IsZero() { obj.Updated = obj.Published } @@ -5,6 +5,7 @@ import ( "fmt" _ "github.com/lib/pq" "html/template" + "log" "net/http" "regexp" "sort" @@ -94,11 +95,27 @@ type PostBlacklist struct { Regex string } +func mod(i, j int) bool { + return i%j == 0 +} + +func sub(i, j int) int { + return i - j +} + +func unixToReadable(u int) string { + return time.Unix(int64(u), 0).Format("Jan 02, 2006") +} + +func timeToReadableLong(t time.Time) string { + return t.Format("01/02/06(Mon)03:04:05") +} + func IndexGet(w http.ResponseWriter, r *http.Request, db *sql.DB) { t := template.Must(template.New("").Funcs(template.FuncMap{ - "mod": func(i, j int) bool { return i%j == 0 }, - "sub": func(i, j int) int { return i - j }, - "unixtoreadable": func(u int) string { return time.Unix(int64(u), 0).Format("Jan 02, 2006") }}).ParseFiles("./static/main.html", "./static/index.html")) + "mod": mod, + "sub": sub, + "unixtoreadable": unixToReadable}).ParseFiles("./static/main.html", "./static/index.html")) actor := GetActorFromDB(db, Domain) @@ -125,13 +142,17 @@ func IndexGet(w http.ResponseWriter, r *http.Request, db *sql.DB) { data.Themes = &Themes - t.ExecuteTemplate(w, "layout", data) + err := t.ExecuteTemplate(w, "layout", data) + if err != nil { + // TODO: actual error handler + log.Printf("IndexGet: %s\n", err) + } } func NewsGet(w http.ResponseWriter, r *http.Request, db *sql.DB, timestamp int) { t := template.Must(template.New("").Funcs(template.FuncMap{ - "sub": func(i, j int) int { return i - j }, - "unixtoreadable": func(u int) string { return time.Unix(int64(u), 0).Format("Jan 02, 2006") }}).ParseFiles("./static/main.html", "./static/news.html")) + "sub": mod, + "unixtoreadable": unixToReadable}).ParseFiles("./static/main.html", "./static/news.html")) actor := GetActorFromDB(db, Domain) @@ -160,14 +181,18 @@ func NewsGet(w http.ResponseWriter, r *http.Request, db *sql.DB, timestamp int) data.Themes = &Themes - t.ExecuteTemplate(w, "layout", data) + err = t.ExecuteTemplate(w, "layout", data) + if err != nil { + // TODO: actual error handler + log.Printf("NewsGet: %s\n", err) + } } func AllNewsGet(w http.ResponseWriter, r *http.Request, db *sql.DB) { t := template.Must(template.New("").Funcs(template.FuncMap{ - "mod": func(i, j int) bool { return i%j == 0 }, - "sub": func(i, j int) int { return i - j }, - "unixtoreadable": func(u int) string { return time.Unix(int64(u), 0).Format("Jan 02, 2006") }}).ParseFiles("./static/main.html", "./static/anews.html")) + "mod": mod, + "sub": sub, + "unixtoreadable": unixToReadable}).ParseFiles("./static/main.html", "./static/anews.html")) actor := GetActorFromDB(db, Domain) @@ -186,7 +211,11 @@ func AllNewsGet(w http.ResponseWriter, r *http.Request, db *sql.DB) { data.Themes = &Themes - t.ExecuteTemplate(w, "layout", data) + err := t.ExecuteTemplate(w, "layout", data) + if err != nil { + // TODO: actual error handler + log.Printf("AllNewsGet: %s\n", err) + } } func OutboxGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection Collection) { @@ -229,7 +258,8 @@ func OutboxGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection Co "add": func(i, j int) int { return i + j }, - "sub": func(i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/nposts.html", "./static/top.html", "./static/bottom.html", "./static/posts.html")) + "timeToReadableLong": timeToReadableLong, + "sub": sub}).ParseFiles("./static/main.html", "./static/nposts.html", "./static/top.html", "./static/bottom.html", "./static/posts.html")) actor := collection.Actor @@ -280,7 +310,11 @@ func OutboxGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection Co returnData.Themes = &Themes - t.ExecuteTemplate(w, "layout", returnData) + err := t.ExecuteTemplate(w, "layout", returnData) + if err != nil { + // TODO: actual error handler + log.Printf("OutboxGet: %s\n", err) + } } func CatalogGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection Collection) { @@ -305,7 +339,7 @@ func CatalogGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection C } return false }, - "sub": func(i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/ncatalog.html", "./static/top.html")) + "sub": sub}).ParseFiles("./static/main.html", "./static/ncatalog.html", "./static/top.html")) actor := collection.Actor @@ -337,7 +371,11 @@ func CatalogGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection C returnData.Themes = &Themes - t.ExecuteTemplate(w, "layout", returnData) + err := t.ExecuteTemplate(w, "layout", returnData) + if err != nil { + // TODO: actual error handler + log.Printf("CatalogGet: %s\n", err) + } } func ArchiveGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection Collection) { @@ -354,8 +392,8 @@ func ArchiveGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection C "parseAttachment": func(obj ObjectBase, catalog bool) template.HTML { return ParseAttachment(obj, catalog) }, - "mod": func(i, j int) bool { return i%j == 0 }, - "sub": func(i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/archive.html", "./static/bottom.html")) + "mod": mod, + "sub": sub}).ParseFiles("./static/main.html", "./static/archive.html", "./static/bottom.html")) actor := collection.Actor @@ -387,7 +425,11 @@ func ArchiveGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection C returnData.Themes = &Themes - t.ExecuteTemplate(w, "layout", returnData) + err := t.ExecuteTemplate(w, "layout", returnData) + if err != nil { + // TODO: actual error handler + log.Printf("ArchiveGet: %s\n", err) + } } func PostGet(w http.ResponseWriter, r *http.Request, db *sql.DB) { @@ -419,7 +461,8 @@ func PostGet(w http.ResponseWriter, r *http.Request, db *sql.DB) { link := "<a href=\"" + actor.Name + "/" + shortURL(actor.Outbox, op) + "#" + shortURL(actor.Outbox, id) + "\" title=\"" + title + "\" class=\"replyLink\">>>" + shortURL(actor.Outbox, id) + "</a>" return template.HTML(link) }, - "sub": func(i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/npost.html", "./static/top.html", "./static/bottom.html", "./static/posts.html")) + "timeToReadableLong": timeToReadableLong, + "sub": sub}).ParseFiles("./static/main.html", "./static/npost.html", "./static/top.html", "./static/bottom.html", "./static/posts.html")) path := r.URL.Path actor := GetActorFromPath(db, path, "/") @@ -482,7 +525,11 @@ func PostGet(w http.ResponseWriter, r *http.Request, db *sql.DB) { returnData.Themes = &Themes - t.ExecuteTemplate(w, "layout", returnData) + err := t.ExecuteTemplate(w, "layout", returnData) + if err != nil { + // TODO: actual error handler + log.Printf("PostGet: %s\n") + } } func GetBoardCollection(db *sql.DB) []Board { @@ -739,13 +786,13 @@ func GetActorsFollowPostFromId(db *sql.DB, actors []string, id string) Collectio type ObjectBaseSortDesc []ObjectBase func (a ObjectBaseSortDesc) Len() int { return len(a) } -func (a ObjectBaseSortDesc) Less(i, j int) bool { return a[i].Updated > a[j].Updated } +func (a ObjectBaseSortDesc) Less(i, j int) bool { return a[i].Updated.After(a[j].Updated) } func (a ObjectBaseSortDesc) Swap(i, j int) { a[i], a[j] = a[j], a[i] } type ObjectBaseSortAsc []ObjectBase func (a ObjectBaseSortAsc) Len() int { return len(a) } -func (a ObjectBaseSortAsc) Less(i, j int) bool { return a[i].Published < a[j].Published } +func (a ObjectBaseSortAsc) Less(i, j int) bool { return a[i].Published.Before(a[j].Published) } func (a ObjectBaseSortAsc) Swap(i, j int) { a[i], a[j] = a[j], a[i] } type BoardSortAsc []Board diff --git a/database.go b/database.go index 0a99086..b0a5736 100644 --- a/database.go +++ b/database.go @@ -175,16 +175,16 @@ func WriteObjectToDB(db *sql.DB, obj ObjectBase) ObjectBase { if len(obj.Attachment) > 0 { if obj.Preview.Href != "" { obj.Preview.Id = fmt.Sprintf("%s/%s", obj.Actor, CreateUniqueID(db, obj.Actor)) - obj.Preview.Published = time.Now().UTC().Format(time.RFC3339) - obj.Preview.Updated = time.Now().UTC().Format(time.RFC3339) + obj.Preview.Published = time.Now().UTC() + obj.Preview.Updated = time.Now().UTC() obj.Preview.AttributedTo = obj.Id WritePreviewToDB(db, *obj.Preview) } for i, _ := range obj.Attachment { obj.Attachment[i].Id = fmt.Sprintf("%s/%s", obj.Actor, CreateUniqueID(db, obj.Actor)) - obj.Attachment[i].Published = time.Now().UTC().Format(time.RFC3339) - obj.Attachment[i].Updated = time.Now().UTC().Format(time.RFC3339) + obj.Attachment[i].Published = time.Now().UTC() + obj.Attachment[i].Updated = time.Now().UTC() obj.Attachment[i].AttributedTo = obj.Id WriteAttachmentToDB(db, obj.Attachment[i]) WriteActivitytoDBWithAttachment(db, obj, obj.Attachment[i], *obj.Preview) @@ -1640,8 +1640,8 @@ func CreateObject(objType string) ObjectBase { var nObj ObjectBase nObj.Type = objType - nObj.Published = time.Now().UTC().Format(time.RFC3339) - nObj.Updated = time.Now().UTC().Format(time.RFC3339) + nObj.Published = time.Now().UTC() + nObj.Updated = time.Now().UTC() return nObj } @@ -1780,7 +1780,7 @@ func CreateAttachmentObject(file multipart.File, header *multipart.FileHeader) ( image.Href = Domain + "/" + tempFile.Name() image.MediaType = contentType image.Size = size - image.Published = time.Now().UTC().Format(time.RFC3339) + image.Published = time.Now().UTC() nAttachment = append(nAttachment, image) @@ -1812,7 +1812,7 @@ func ParseCommentForReplies(db *sql.DB, comment string, op string) []ObjectBase if isValid { var reply = new(ObjectBase) reply.Id = links[i] - reply.Published = time.Now().UTC().Format(time.RFC3339) + reply.Published = time.Now().UTC() validLinks = append(validLinks, *reply) } } @@ -2397,7 +2397,7 @@ func ResizeAttachmentToPreview(db *sql.DB) { var mediatype string var name string var size int - var published string + var published time.Time rows.Scan(&id, &href, &mediatype, &name, &size, &published) diff --git a/static/posts.html b/static/posts.html index b9cac5e..eab6a99 100644 --- a/static/posts.html +++ b/static/posts.html @@ -45,7 +45,10 @@ } </script> {{ end }} - <span class="subject"><b>{{ .Name }}</b></span><span class="name"><b>{{ if .AttributedTo }} {{.AttributedTo }} {{ else }} Anonymous {{ end }}</b></span><span class="tripcode"> {{ .TripCode }} </span><span>{{ .Published }} <a id="{{ .Id }}-anchor" href="/{{ $board.Name }}/{{ short $board.Actor.Outbox $opId }}#{{ short $board.Actor.Outbox .Id }}">No.</a> <a id="{{ .Id }}-link" title="{{ .Id }}" {{ if eq .Type "Note" }} href="javascript:quote('{{ $board.Actor.Id }}', '{{ $opId }}', '{{ .Id }}')" {{ end }}>{{ short $board.Actor.Outbox .Id }}</a> {{ if ne .Type "Tombstone" }}<a href="javascript:report('{{ $board.Actor.Id }}', '{{ .Id }}')">[Report]</a>{{ end }}</span> + <span class="subject"><b>{{ .Name }}</b></span> + <span class="name"><b>{{ if .AttributedTo }} {{.AttributedTo }} {{ else }} Anonymous {{ end }}</b></span> + <span class="tripcode"> {{ .TripCode }} </span> + <span>{{ .Published | timeToReadableLong }} <a id="{{ .Id }}-anchor" href="/{{ $board.Name }}/{{ short $board.Actor.Outbox $opId }}#{{ short $board.Actor.Outbox .Id }}">No.</a> <a id="{{ .Id }}-link" title="{{ .Id }}" {{ if eq .Type "Note" }} href="javascript:quote('{{ $board.Actor.Id }}', '{{ $opId }}', '{{ .Id }}')" {{ end }}>{{ short $board.Actor.Outbox .Id }}</a> {{ if ne .Type "Tombstone" }}<a href="javascript:report('{{ $board.Actor.Id }}', '{{ .Id }}')">[Report]</a>{{ end }}</span> <p id="{{ .Id }}-content" style="white-space: pre-wrap; margin: 10px 30px 10px 30px;">{{ parseContent $board.Actor $opId .Content $thread }}</p> {{ if .Replies }} {{ $replies := .Replies }} |