From 0b08befaa890956bed84e92ec8015ef8a1806671 Mon Sep 17 00:00:00 2001 From: m15o Date: Sun, 28 Nov 2021 15:31:51 +0100 Subject: [PATCH] Add email --- assets/style.css | 4 --- go.mod | 8 +++-- go.sum | 14 +++++++++ model/user.go | 1 + storage/migration.go | 2 +- storage/sql.go | 2 ++ storage/sql/schema_version_7.sql | 2 ++ storage/user.go | 10 +++---- web/handler/form/settings.go | 2 ++ web/handler/handler.go | 3 +- web/handler/html.go | 23 ++++++++------- web/handler/html/settings.html | 13 ++++++--- web/handler/html/user.html | 4 ++- web/handler/settings_show.go | 7 ++--- web/handler/settings_update.go | 2 +- web/handler/user_show.go | 50 ++++++++++++++++++++++++++++++++ 16 files changed, 111 insertions(+), 36 deletions(-) create mode 100644 storage/sql/schema_version_7.sql diff --git a/assets/style.css b/assets/style.css index 720262f..1973a04 100644 --- a/assets/style.css +++ b/assets/style.css @@ -50,10 +50,6 @@ dd { margin-bottom: 1em; } -.profile-picture { - float: right; -} - nav { margin-bottom: 1em; } diff --git a/go.mod b/go.mod index d845af6..c49097f 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,13 @@ module status go 1.16 require ( - github.com/fogleman/gg v1.3.0 // indirect - github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/fogleman/gg v1.3.0 + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 + github.com/gorilla/feeds v1.1.1 github.com/gorilla/mux v1.8.0 github.com/gorilla/sessions v1.2.1 + github.com/kr/pretty v0.3.0 // indirect github.com/lib/pq v1.10.4 golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 - golang.org/x/image v0.0.0-20211028202545-6944b10bf410 // indirect + golang.org/x/image v0.0.0-20211028202545-6944b10bf410 ) diff --git a/go.sum b/go.sum index 9f70a0b..3c1cc1f 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,27 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/gorilla/feeds v1.1.1 h1:HwKXxqzcRNg9to+BbvJog4+f3s/xzvtZXICcQGutYfY= +github.com/gorilla/feeds v1.1.1/go.mod h1:Nk0jZrvPFZX1OBe5NPiddPw7CfwF6Q9eqzaBbaightA= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ= @@ -21,3 +33,5 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= diff --git a/model/user.go b/model/user.go index cc671fc..99e1d50 100644 --- a/model/user.go +++ b/model/user.go @@ -15,6 +15,7 @@ type User struct { About string Style string Picture string + Email string CreatedAt time.Time } diff --git a/storage/migration.go b/storage/migration.go index a04a0c3..b3ac4a2 100644 --- a/storage/migration.go +++ b/storage/migration.go @@ -7,7 +7,7 @@ import ( "strconv" ) -const schemaVersion = 6 +const schemaVersion = 7 func Migrate(db *sql.DB) { var currentVersion int diff --git a/storage/sql.go b/storage/sql.go index e771881..2cd228a 100644 --- a/storage/sql.go +++ b/storage/sql.go @@ -38,4 +38,6 @@ alter column about TYPE TEXT;`, add column style TEXT not null DEFAULT '';`, "schema_version_6": `alter table users add column picture varchar(500) not null DEFAULT '';`, + "schema_version_7": `alter table users + add column email varchar(500) not null DEFAULT '';`, } diff --git a/storage/sql/schema_version_7.sql b/storage/sql/schema_version_7.sql new file mode 100644 index 0000000..ed7537c --- /dev/null +++ b/storage/sql/schema_version_7.sql @@ -0,0 +1,2 @@ +alter table users + add column email varchar(500) not null DEFAULT ''; \ No newline at end of file diff --git a/storage/user.go b/storage/user.go index 9f2524b..2c2fc46 100644 --- a/storage/user.go +++ b/storage/user.go @@ -4,10 +4,10 @@ import ( "status/model" ) -const queryFindName = `SELECT name, hash, created_at, homepage, about, style, picture FROM users WHERE name=lower($1);` +const queryFindName = `SELECT name, hash, created_at, homepage, about, style, picture, email FROM users WHERE name=lower($1);` func (s *Storage) queryUser(q string, params ...interface{}) (user model.User, err error) { - err = s.db.QueryRow(q, params...).Scan(&user.Name, &user.Hash, &user.CreatedAt, &user.Homepage, &user.About, &user.Style, &user.Picture) + err = s.db.QueryRow(q, params...).Scan(&user.Name, &user.Hash, &user.CreatedAt, &user.Homepage, &user.About, &user.Style, &user.Picture, &user.Email) return } @@ -77,11 +77,11 @@ func (s *Storage) DeleteUser(username string) error { return err } -func (s *Storage) UpdateSettings(username, homepage, about, style, picture string) error { - stmt, err := s.db.Prepare(`UPDATE users SET homepage = $1, about = $2, style = $3, picture = $4 WHERE name = $5;`) +func (s *Storage) UpdateSettings(username, homepage, about, style, picture, email string) error { + stmt, err := s.db.Prepare(`UPDATE users SET homepage = $1, about = $2, style = $3, picture = $4, email = $5 WHERE name = $6;`) if err != nil { return err } - _, err = stmt.Exec(homepage, about, style, picture, username) + _, err = stmt.Exec(homepage, about, style, picture, email, username) return err } diff --git a/web/handler/form/settings.go b/web/handler/form/settings.go index 9338731..7882eab 100644 --- a/web/handler/form/settings.go +++ b/web/handler/form/settings.go @@ -9,6 +9,7 @@ type SettingsForm struct { About string Style string Picture string + Email string } func NewSettingsForm(r *http.Request) *SettingsForm { @@ -17,5 +18,6 @@ func NewSettingsForm(r *http.Request) *SettingsForm { About: r.FormValue("about"), Style: r.FormValue("style"), Picture: r.FormValue("picture"), + Email: r.FormValue("email"), } } diff --git a/web/handler/handler.go b/web/handler/handler.go index 88f9f20..432c032 100644 --- a/web/handler/handler.go +++ b/web/handler/handler.go @@ -63,7 +63,6 @@ func New(cfg *config.Config, sess *session.Session, data *storage.Storage) (http sess: sess, } h.initTpl() - router.HandleFunc("/", h.showIndexView).Methods(http.MethodGet) router.HandleFunc("/login", h.showLoginView).Methods(http.MethodGet) router.HandleFunc("/check-login", h.checkLogin).Methods(http.MethodPost) @@ -80,8 +79,10 @@ func New(cfg *config.Config, sess *session.Session, data *storage.Storage) (http router.HandleFunc("/edit", h.updateStatus).Methods(http.MethodPost) router.HandleFunc("/manage", h.showManageView).Methods(http.MethodGet) + router.HandleFunc("/users/{user}.atom", h.showAtomView).Methods(http.MethodGet) router.HandleFunc("/users/{user}", h.showUserView).Methods(http.MethodGet) router.HandleFunc("/users/{user}/status.json", h.showUserStatusView).Methods(http.MethodGet) + router.HandleFunc("/users/{user}/status.png", h.showUserStatusImageView).Methods(http.MethodGet) router.PathPrefix("/assets/").Handler( http.StripPrefix("/assets/", diff --git a/web/handler/html.go b/web/handler/html.go index 985f036..9b9f051 100644 --- a/web/handler/html.go +++ b/web/handler/html.go @@ -179,12 +179,6 @@ var TplMap = map[string]string{ -{{ end }}`, - "remove_success": `{{ define "content" }} -
- {{ template "flash" .flash }} - Back home -
{{ end }}`, "settings": `{{ define "content" }}
@@ -196,22 +190,27 @@ var TplMap = map[string]string{
- + +
+ +
+ +
- +
- +
- +
@@ -224,11 +223,13 @@ var TplMap = map[string]string{ {{ define "content" }}
-

{{ .user }}

+
Homepage
{{ .homepage }}
+
Email
+
{{ .email }}
About
{{ .about }}
diff --git a/web/handler/html/settings.html b/web/handler/html/settings.html index cc0c86c..273087d 100644 --- a/web/handler/html/settings.html +++ b/web/handler/html/settings.html @@ -8,22 +8,27 @@
- + +
+ +
+ +
- +
- +
- +
diff --git a/web/handler/html/user.html b/web/handler/html/user.html index 02678b8..93a6099 100644 --- a/web/handler/html/user.html +++ b/web/handler/html/user.html @@ -5,11 +5,13 @@ {{ define "content" }}
-

{{ .user }}

+
Homepage
{{ .homepage }}
+
Email
+
{{ .email }}
About
{{ .about }}
diff --git a/web/handler/settings_show.go b/web/handler/settings_show.go index f034b95..957ab86 100644 --- a/web/handler/settings_show.go +++ b/web/handler/settings_show.go @@ -24,10 +24,7 @@ func (h *Handler) showSettingsView(w http.ResponseWriter, r *http.Request) { } session.Save(r, w) h.renderLayout(w, "settings", map[string]interface{}{ - "flash": flash, - "About": user.About, - "Homepage": user.Homepage, - "Style": user.Style, - "Picture": user.Picture, + "flash": flash, + "User": user, }, username) } diff --git a/web/handler/settings_update.go b/web/handler/settings_update.go index c6bcc97..15f2fd7 100644 --- a/web/handler/settings_update.go +++ b/web/handler/settings_update.go @@ -13,7 +13,7 @@ func (h *Handler) updateSettings(w http.ResponseWriter, r *http.Request) { return } f := form.NewSettingsForm(r) - if err := h.storage.UpdateSettings(user, f.Homepage, f.About, f.Style, f.Picture); err != nil { + if err := h.storage.UpdateSettings(user, f.Homepage, f.About, f.Style, f.Picture, f.Email); err != nil { serverError(w, err) return } diff --git a/web/handler/user_show.go b/web/handler/user_show.go index 6f79413..404f2c5 100644 --- a/web/handler/user_show.go +++ b/web/handler/user_show.go @@ -2,9 +2,11 @@ package handler import ( "encoding/json" + "fmt" "github.com/fogleman/gg" "github.com/golang/freetype" "github.com/golang/freetype/truetype" + "github.com/gorilla/feeds" "github.com/gorilla/mux" "golang.org/x/image/font" "golang.org/x/image/font/gofont/goregular" @@ -14,6 +16,7 @@ import ( "image/color" "image/draw" "strconv" + "time" //"image/png" "net/http" @@ -77,6 +80,7 @@ func (h *Handler) showUserView(w http.ResponseWriter, r *http.Request) { "homepage": user.Homepage, "about": template.HTML(user.About), "picture": user.Picture, + "email": user.Email, "style": template.CSS(user.Style), "showMore": showMore, "page": page, @@ -197,3 +201,49 @@ func (h *Handler) showUserStatusImageView(w http.ResponseWriter, r *http.Request //avatar := createAvatar(text) //png.Encode(w, avatar) } + +func (h *Handler) showAtomView(w http.ResponseWriter, r *http.Request) { + username := mux.Vars(r)["user"] + user, err := h.storage.UserByName(username) + if err != nil { + notFound(w) + return + } + + now := time.Now() + feed := &feeds.Feed{ + Title: user.Name, + Link: &feeds.Link{Href: fmt.Sprintf("https://status.cafe/users/%s", username)}, // TODO change the scheme? + Author: &feeds.Author{Name: user.Name, Email: "todo@todo.com"}, // TODO EMAIL + Created: now, + } + + statuses, _, err := h.storage.StatusByUsername(user.Name, 20, 0) + if err != nil { + serverError(w, err) + return + } + + for _, status := range statuses { + if err != nil { + serverError(w, err) + return + } + feed.Items = append(feed.Items, &feeds.Item{ + Title: status.Content, + Link: &feeds.Link{Href: fmt.Sprintf("https://status.cafe/users/%s/%d", username, status.Id)}, + Author: &feeds.Author{Name: user.Name}, + Content: status.Content, + Created: status.CreatedAt, + }) + } + atom, err := feed.ToAtom() + if err != nil { + serverError(w, err) + return + } + + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Content-Type", "application/atom+xml") + w.Write([]byte(atom)) +}