aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client.go31
-rw-r--r--database.go14
-rw-r--r--databaseschema.psql1
-rw-r--r--main.go46
-rw-r--r--static/anews.html10
-rw-r--r--static/index.html25
-rw-r--r--static/main.html19
-rw-r--r--static/nadmin.html19
-rw-r--r--static/news.html6
9 files changed, 120 insertions, 51 deletions
diff --git a/client.go b/client.go
index f71fb7d..f4575f5 100644
--- a/client.go
+++ b/client.go
@@ -79,12 +79,15 @@ type Removed struct {
type NewsItem struct {
Title string
- Content string
+ Content template.HTML
Time int
}
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 }, "unixtoreadable": func(u int) string { return time.Unix(int64(u), 0).Format("Jan 02, 2006") }}).ParseFiles("./static/main.html", "./static/index.html"))
+ 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"))
actor := GetActorFromDB(db, Domain)
@@ -113,7 +116,9 @@ func IndexGet(w http.ResponseWriter, r *http.Request, db *sql.DB) {
}
func NewsGet(w http.ResponseWriter, r *http.Request, db *sql.DB, timestamp int) {
- t := template.Must(template.New("").Funcs(template.FuncMap{"unixtoreadable": func(u int) string { return time.Unix(int64(u), 0).Format("Jan 02, 2006") }}).ParseFiles("./static/main.html", "./static/news.html"))
+ 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"))
actor := GetActorFromDB(db, Domain)
@@ -144,7 +149,10 @@ func NewsGet(w http.ResponseWriter, r *http.Request, db *sql.DB, timestamp int)
}
func AllNewsGet(w http.ResponseWriter, r *http.Request, db *sql.DB) {
- t := template.Must(template.New("").Funcs(template.FuncMap{"unixtoreadable": func(u int) string { return time.Unix(int64(u), 0).Format("Jan 02, 2006") }}).ParseFiles("./static/main.html", "./static/anews.html"))
+ 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"))
actor := GetActorFromDB(db, Domain)
@@ -165,8 +173,9 @@ func AllNewsGet(w http.ResponseWriter, r *http.Request, db *sql.DB) {
}
func OutboxGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection Collection){
+ t := template.Must(template.New("").Funcs(template.FuncMap{
+ "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"))
- t := template.Must(template.ParseFiles("./static/main.html", "./static/nposts.html", "./static/top.html", "./static/bottom.html", "./static/posts.html"))
actor := collection.Actor
@@ -214,9 +223,8 @@ func OutboxGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection Co
}
func CatalogGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection Collection){
-
- t := template.Must(template.ParseFiles("./static/main.html", "./static/ncatalog.html", "./static/top.html"))
-
+ t := template.Must(template.New("").Funcs(template.FuncMap{
+ "sub": func (i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/ncatalog.html", "./static/top.html"))
actor := collection.Actor
var returnData PageData
@@ -249,8 +257,8 @@ func CatalogGet(w http.ResponseWriter, r *http.Request, db *sql.DB, collection C
}
func PostGet(w http.ResponseWriter, r *http.Request, db *sql.DB){
-
- t := template.Must(template.ParseFiles("./static/main.html", "./static/npost.html", "./static/top.html", "./static/bottom.html", "./static/posts.html"))
+ t := template.Must(template.New("").Funcs(template.FuncMap{
+ "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"))
path := r.URL.Path
actor := GetActorFromPath(db, path, "/")
@@ -322,10 +330,11 @@ func GetBoardCollection(db *sql.DB) []Board {
if boardActor.Id == "" {
boardActor = FingerActor(e.Id)
}
- board.Name = "/" + boardActor.Name + "/"
+ board.Name = boardActor.Name
board.PrefName = boardActor.PreferredUsername
board.Location = "/" + boardActor.Name
board.Actor = boardActor
+ board.Restricted = boardActor.Restricted
collection = append(collection, board)
}
diff --git a/database.go b/database.go
index baae16a..edab4f6 100644
--- a/database.go
+++ b/database.go
@@ -7,6 +7,7 @@ import (
"sort"
"strings"
"time"
+ "html/template"
_ "github.com/lib/pq"
)
@@ -1546,10 +1547,15 @@ func getNewsFromDB(db *sql.DB, limit int) []NewsItem {
defer rows.Close()
for rows.Next() {
n := NewsItem{}
- err = rows.Scan(&n.Title, &n.Content, &n.Time)
+ var content string
+ err = rows.Scan(&n.Title, &content, &n.Time)
if CheckError(err, "error scanning news from db") != nil {
return news
}
+
+ content = strings.ReplaceAll(content, "\n", "<br>")
+ n.Content = template.HTML(content)
+
news = append(news, n)
}
@@ -1558,6 +1564,7 @@ func getNewsFromDB(db *sql.DB, limit int) []NewsItem {
func getNewsItemFromDB(db *sql.DB, timestamp int) (NewsItem, error) {
var news NewsItem
+ var content string
query := `select title, content, time from newsItem where time=$1 limit 1`
rows, err := db.Query(query, timestamp)
@@ -1568,11 +1575,14 @@ func getNewsItemFromDB(db *sql.DB, timestamp int) (NewsItem, error) {
defer rows.Close()
rows.Next()
- err = rows.Scan(&news.Title, &news.Content, &news.Time)
+ err = rows.Scan(&news.Title, &content, &news.Time)
if err != nil {
return news, err
}
+
+ content = strings.ReplaceAll(content, "\n", "<br>")
+ news.Content = template.HTML(content)
return news, nil
}
diff --git a/databaseschema.psql b/databaseschema.psql
index 43767f3..02c229b 100644
--- a/databaseschema.psql
+++ b/databaseschema.psql
@@ -226,3 +226,4 @@ ALTER TABLE actor ADD COLUMN IF NOT EXISTS publicKeyPem varchar(100) default '';
ALTER TABLE activitystream ADD COLUMN IF NOT EXISTS sensitive boolean default false;
ALTER TABLE cacheactivitystream ADD COLUMN IF NOT EXISTS sensitive boolean default false;
+
diff --git a/main.go b/main.go
index 7a30721..0c1e4fa 100644
--- a/main.go
+++ b/main.go
@@ -501,7 +501,8 @@ func main() {
http.Redirect(w, r, "/" + *Key + "/" + redirect, http.StatusSeeOther)
} else if manage && actor.Name != "" {
- t := template.Must(template.ParseFiles("./static/main.html", "./static/manage.html"))
+ t := template.Must(template.New("").Funcs(template.FuncMap{
+ "sub": func (i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/manage.html"))
follow := GetActorCollection(actor.Following)
follower := GetActorCollection(actor.Followers)
@@ -554,8 +555,8 @@ func main() {
t.ExecuteTemplate(w, "layout", adminData)
} else if admin || actor.Id == Domain {
-
- t := template.Must(template.ParseFiles("./static/main.html", "./static/nadmin.html"))
+ t := template.Must(template.New("").Funcs(template.FuncMap{
+ "sub": func (i, j int) int { return i - j }}).ParseFiles("./static/main.html", "./static/nadmin.html"))
actor := GetActor(Domain)
follow := GetActorCollection(actor.Following).Items
@@ -590,12 +591,21 @@ func main() {
http.HandleFunc("/" + *Key + "/addboard", func(w http.ResponseWriter, r *http.Request) {
+ id, _ := GetPasswordFromSession(r)
+
+ actor := GetActorFromDB(db, Domain)
+
+
+ if id == "" || (id != actor.Id && id != Domain) {
+ t := template.Must(template.ParseFiles("./static/verify.html"))
+ t.Execute(w, "")
+ return
+ }
+
var newActorActivity Activity
var board Actor
r.ParseForm()
- actor := GetActorFromDB(db, Domain)
-
var restrict bool
if r.FormValue("restricted") == "True" {
restrict = true
@@ -625,10 +635,22 @@ func main() {
})
http.HandleFunc("/" + *Key + "/postnews", func(w http.ResponseWriter, r *http.Request) {
+
+ id, _ := GetPasswordFromSession(r)
+
+ actor := GetActorFromDB(db, Domain)
+
+
+ if id == "" || (id != actor.Id && id != Domain) {
+ t := template.Must(template.ParseFiles("./static/verify.html"))
+ t.Execute(w, "")
+ return
+ }
+
var newsitem NewsItem
newsitem.Title = r.FormValue("title")
- newsitem.Content = r.FormValue("summary")
+ newsitem.Content = template.HTML(r.FormValue("summary"))
WriteNewsToDB(db, newsitem)
@@ -636,6 +658,18 @@ func main() {
})
http.HandleFunc("/" + *Key + "/newsdelete/", func(w http.ResponseWriter, r *http.Request){
+
+ id, _ := GetPasswordFromSession(r)
+
+ actor := GetActorFromDB(db, Domain)
+
+
+ if id == "" || (id != actor.Id && id != Domain) {
+ t := template.Must(template.ParseFiles("./static/verify.html"))
+ t.Execute(w, "")
+ return
+ }
+
timestamp := r.URL.Path[13+len(*Key):]
tsint, err := strconv.Atoi(timestamp)
diff --git a/static/anews.html b/static/anews.html
index 127760a..08bfdfa 100644
--- a/static/anews.html
+++ b/static/anews.html
@@ -22,16 +22,16 @@
<h1>{{ .Title }}</h1>
<div style="margin-top:50px;">
- <table align="center" style="text-align: left;">
+ <table style="text-align: left;">
{{ range $i, $e := .NewsItems }}
<tr>
<td>
+ <div class="box" style="width:800px; padding: 25px; margin-bottom: 25px;">
{{ if $.Board.ModCred }}<a href="/{{ $.Key }}/newsdelete/{{ $e.Time }}">[Delete] </a>{{end}}
- <a href="/news/{{.Time}}">{{unixtoreadable $e.Time}} - {{$e.Title}}</a>
- {{ if eq $i 0 }}
- <br><p>{{$e.Content}}</p>
- {{ end }}
+ <a href="/news/{{.Time}}">{{unixtoreadable $e.Time}} - {{$e.Title}}</a>
+ <br><p style="margin-left: 25px;">{{$e.Content}}</p>
+ </div>
</td>
</tr>
{{ end }}
diff --git a/static/index.html b/static/index.html
index 61aeab8..520829e 100644
--- a/static/index.html
+++ b/static/index.html
@@ -20,45 +20,42 @@
{{ define "content" }}
<div style="text-align: center; max-width: 800px; margin: 0 auto;">
<h1>{{ .Title }}</h1>
- <p style="text-align: justify">{{ .PreferredUsername }} is a federated image board based on activitypub. The current version of the code running the server is still a work in progress, expect a bumpy ride for the time being. Get the server code <a href="https://github.com/FChannel0">here</a>.</p>
+ <p style="text-align: justify">{{ .PreferredUsername }} is a federated image board based on activitypub. The current version of the code running the server is still a work in progress, expect a bumpy ride for the time being. Get the server code at <a href="https://github.com/FChannel0">https://github.com/FChannel0</a>.</p>
<div style="margin-top:50px;">
-
<div style="display: grid;border-right: 2px solid #820404">
<div style="display: inline-grid;grid-column: 1 / 4;border-bottom: 2px solid #820404;border-left: 2px solid #820404;border-top: 2px solid #820404;"><span style="font-size: 1.5em;font-weight: bold;">Local boards</span></div>
{{ range .Boards }}
- <div style="whitespace: nowrap;display: inline-grid;text-align: left;padding: 5px;border-bottom: 2px solid #820404;border-left: 2px solid #820404;"><a href="{{.Location}}">{{.Name}} - {{.PrefName}}</a></div>
+ <div style="whitespace: nowrap;display: inline-grid;text-align: left;padding: 5px;border-bottom: 2px solid #820404;border-left: 2px solid #820404;"><a href="{{.Location}}"><b>{{.Name}}</b> - {{.PrefName}} {{ if not .Restricted }} [NSFW] {{ end }}</a></div>
{{ end }}
{{ range .BoardRemainer }}
<div style="whitespace: nowrap;display: inline-grid;text-align: left;padding: 5px;border-bottom: 2px solid #820404;border-left: 2px solid #820404;"></div>
{{ end }}
</div>
-
</div>
- <div style="margin-top:50px;">
- <table align="center" style="text-align: left;">
+ {{ if .NewsItems }}
+ <div class="popup-box" style="margin-top:50px;">
+ <table style="text-align: left; margin: 25px;">
<th>
- <tr><a href="/news">{{ .PreferredUsername }} news</a></tr>
+ <tr><h4><a href="/news">{{ .PreferredUsername }} News</a></h4></tr>
</th>
-
{{ range $i, $e := .NewsItems }}
<tr>
<td>{{ if $.Board.ModCred }}<a href="/{{ $.Key }}/newsdelete/{{ $e.Time }}">[Delete] </a>{{end}}
<a href="/news/{{.Time}}">{{unixtoreadable $e.Time}} - {{$e.Title}}</a>
- {{ if eq $i 0 }}
- <br><p>{{$e.Content}}</p>
- {{ end }}
+ <br><p style="margin-left: 25px;">{{$e.Content}}</p>
</td>
</tr>
{{ end }}
</table>
</div>
+ {{ end }}
- <div style="margin-top:50px;">
- <table align="center" style="text-align: left;">
+ <div class="popup-box" style="margin-top:50px;">
+ <table style="text-align: left; margin: 25px;">
<th>
- <tr>Current known instances</tr>
+ <tr><h4>Current known instances</h4></tr>
</th>
{{ range .InstanceIndex }}
diff --git a/static/main.html b/static/main.html
index 70e3c23..00b395f 100644
--- a/static/main.html
+++ b/static/main.html
@@ -40,6 +40,14 @@
background-color: #f9f9e0;
{{ end }}
}
+
+ .box {
+ {{ if .Board.Restricted }}
+ background-color: #eff5ff;
+ {{ else }}
+ background-color: #f9f9e0;
+ {{ end }}
+ }
.quote {
color: #789922;
@@ -76,8 +84,15 @@
</head>
<body>
<ul style="display: inline; padding:0;">
- {{range .Boards}}
- <li style="display: inline;"><a href="{{.Location}}">{{.Name}}</a></li>
+ {{ $l := len .Boards }}
+ {{range $i, $e := .Boards}}
+ {{ if eq $i 0 }}
+ <li style="display: inline;">[<a href="{{.Location}}">{{$e.Name}} </a>/</li>
+ {{ else if eq $i (sub $l 1) }}
+ <li style="display: inline;"><a href="{{.Location}}">{{$e.Name}}</a>]</li>
+ {{ else }}
+ <li style="display: inline;"><a href="{{.Location}}">{{$e.Name}} </a>/</li>
+ {{ end }}
{{end}}
</ul>
{{ if .Board.ModCred }}
diff --git a/static/nadmin.html b/static/nadmin.html
index 877e1e5..88b92c9 100644
--- a/static/nadmin.html
+++ b/static/nadmin.html
@@ -17,21 +17,24 @@
<option value="False">False</option>
</select>
</form>
-
+ <ul style="display: inline-block; padding: 0;">
+ <li style="display: inline-block;"><a href="#following">Subscribed</a></li>
+ <!-- <li style="display: inline-block;"><a href="javascript:show('followers')">Followers</a></li> -->
+ <li style="display: inline-block;"><a href="#reported">Reported</a></li>
+ </ul>
+</div>
+
+<div class="popup-box" style="margin-bottom: 25px; padding: 12px;">
<h3>Post News</h3>
<form id="news" action="/{{ .Key }}/postnews" method="post" enctype="application/x-www-form-urlencoded">
<label>Title:</label><br>
- <input type="text" name="title" placeholder="{{.Actor}} was created!" required><input type="submit" value="Post"><br>
+ <input type="text" name="title" placeholder="New Board" required><input type="submit" value="Post"><br>
<label>Content:</label><br>
<textarea name="summary" rows="8" cols="50"></textarea><br>
</form>
+</div>
+
- <ul style="display: inline-block; padding: 0;">
- <li style="display: inline-block;"><a href="#following">Subscribed</a></li>
- <!-- <li style="display: inline-block;"><a href="javascript:show('followers')">Followers</a></li> -->
- <li style="display: inline-block;"><a href="#reported">Reported</a></li>
- </ul>
-</div>
<div id="following" class="popup-box" style="margin-bottom: 25px; padding: 12px;">
<h4 style="margin: 0; margin-bottom: 5px;">Subscribed</h4>
diff --git a/static/news.html b/static/news.html
index 757c420..4bd43e1 100644
--- a/static/news.html
+++ b/static/news.html
@@ -20,9 +20,9 @@
{{ define "content" }}
<div style="text-align: left; max-width: 800px; margin: 0 auto;">
- {{ range .NewsItems }}
- <p><h1>{{unixtoreadable .Time}} - {{.Title}}</h1><br>{{.Content}}</p>
- {{ end }}
+ {{ range .NewsItems }}
+ <p><h1>{{unixtoreadable .Time}} - {{.Title}}</h1><br>{{.Content}}</p>
+ {{ end }}
</div>
{{ end }}