f4f5ed77814f41878251028a1a106ca679e7d352
[bloat] / service / transport.go
1 package service
2
3 import (
4         "context"
5         "fmt"
6         "net/http"
7         "path"
8
9         "github.com/gorilla/mux"
10 )
11
12 var (
13         ctx       = context.Background()
14         cookieAge = "31536000"
15 )
16
17 func getContextWithSession(ctx context.Context, req *http.Request) context.Context {
18         sessionID, err := req.Cookie("session_id")
19         if err != nil {
20                 return ctx
21         }
22         return context.WithValue(ctx, "session_id", sessionID.Value)
23 }
24
25 func NewHandler(s Service, staticDir string) http.Handler {
26         r := mux.NewRouter()
27
28         r.PathPrefix("/static").Handler(http.StripPrefix("/static",
29                 http.FileServer(http.Dir(path.Join(".", staticDir)))))
30
31         r.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
32                 err := s.ServeHomePage(ctx, w)
33                 if err != nil {
34                         s.ServeErrorPage(ctx, w, err)
35                         return
36                 }
37         }).Methods(http.MethodGet)
38
39         r.HandleFunc("/signin", func(w http.ResponseWriter, req *http.Request) {
40                 err := s.ServeSigninPage(ctx, w)
41                 if err != nil {
42                         s.ServeErrorPage(ctx, w, err)
43                         return
44                 }
45         }).Methods(http.MethodGet)
46
47         r.HandleFunc("/signin", func(w http.ResponseWriter, req *http.Request) {
48                 instance := req.FormValue("instance")
49                 url, sessionId, err := s.GetAuthUrl(ctx, instance)
50                 if err != nil {
51                         s.ServeErrorPage(ctx, w, err)
52                         return
53                 }
54
55                 w.Header().Add("Set-Cookie", fmt.Sprintf("session_id=%s;max-age=%s", sessionId, cookieAge))
56                 w.Header().Add("Location", url)
57                 w.WriteHeader(http.StatusSeeOther)
58         }).Methods(http.MethodPost)
59
60         r.HandleFunc("/oauth_callback", func(w http.ResponseWriter, req *http.Request) {
61                 ctx := getContextWithSession(context.Background(), req)
62                 token := req.URL.Query().Get("code")
63                 _, err := s.GetUserToken(ctx, "", nil, token)
64                 if err != nil {
65                         s.ServeErrorPage(ctx, w, err)
66                         return
67                 }
68
69                 w.Header().Add("Location", "/timeline")
70                 w.WriteHeader(http.StatusSeeOther)
71         }).Methods(http.MethodGet)
72
73         r.HandleFunc("/timeline", func(w http.ResponseWriter, req *http.Request) {
74                 ctx := getContextWithSession(context.Background(), req)
75
76                 maxID := req.URL.Query().Get("max_id")
77                 sinceID := req.URL.Query().Get("since_id")
78                 minID := req.URL.Query().Get("min_id")
79
80                 err := s.ServeTimelinePage(ctx, w, nil, maxID, sinceID, minID)
81                 if err != nil {
82                         s.ServeErrorPage(ctx, w, err)
83                         return
84                 }
85         }).Methods(http.MethodGet)
86
87         r.HandleFunc("/thread/{id}", func(w http.ResponseWriter, req *http.Request) {
88                 ctx := getContextWithSession(context.Background(), req)
89                 id, _ := mux.Vars(req)["id"]
90                 reply := req.URL.Query().Get("reply")
91                 err := s.ServeThreadPage(ctx, w, nil, id, len(reply) > 1)
92                 if err != nil {
93                         s.ServeErrorPage(ctx, w, err)
94                         return
95                 }
96         }).Methods(http.MethodGet)
97
98         r.HandleFunc("/like/{id}", func(w http.ResponseWriter, req *http.Request) {
99                 ctx := getContextWithSession(context.Background(), req)
100                 id, _ := mux.Vars(req)["id"]
101                 err := s.Like(ctx, w, nil, id)
102                 if err != nil {
103                         s.ServeErrorPage(ctx, w, err)
104                         return
105                 }
106
107                 w.Header().Add("Location", req.Header.Get("Referer"))
108                 w.WriteHeader(http.StatusSeeOther)
109         }).Methods(http.MethodGet)
110
111         r.HandleFunc("/unlike/{id}", func(w http.ResponseWriter, req *http.Request) {
112                 ctx := getContextWithSession(context.Background(), req)
113                 id, _ := mux.Vars(req)["id"]
114                 err := s.UnLike(ctx, w, nil, id)
115                 if err != nil {
116                         s.ServeErrorPage(ctx, w, err)
117                         return
118                 }
119
120                 w.Header().Add("Location", req.Header.Get("Referer"))
121                 w.WriteHeader(http.StatusSeeOther)
122         }).Methods(http.MethodGet)
123
124         r.HandleFunc("/retweet/{id}", func(w http.ResponseWriter, req *http.Request) {
125                 ctx := getContextWithSession(context.Background(), req)
126                 id, _ := mux.Vars(req)["id"]
127                 err := s.Retweet(ctx, w, nil, id)
128                 if err != nil {
129                         s.ServeErrorPage(ctx, w, err)
130                         return
131                 }
132
133                 w.Header().Add("Location", req.Header.Get("Referer"))
134                 w.WriteHeader(http.StatusSeeOther)
135         }).Methods(http.MethodGet)
136
137         r.HandleFunc("/unretweet/{id}", func(w http.ResponseWriter, req *http.Request) {
138                 ctx := getContextWithSession(context.Background(), req)
139                 id, _ := mux.Vars(req)["id"]
140                 err := s.UnRetweet(ctx, w, nil, id)
141                 if err != nil {
142                         s.ServeErrorPage(ctx, w, err)
143                         return
144                 }
145
146                 w.Header().Add("Location", req.Header.Get("Referer"))
147                 w.WriteHeader(http.StatusSeeOther)
148         }).Methods(http.MethodGet)
149
150         r.HandleFunc("/post", func(w http.ResponseWriter, req *http.Request) {
151                 ctx := getContextWithSession(context.Background(), req)
152                 content := req.FormValue("content")
153                 replyToID := req.FormValue("reply_to_id")
154                 err := s.PostTweet(ctx, w, nil, content, replyToID)
155                 if err != nil {
156                         s.ServeErrorPage(ctx, w, err)
157                         return
158                 }
159
160                 w.Header().Add("Location", req.Header.Get("Referer"))
161                 w.WriteHeader(http.StatusSeeOther)
162         }).Methods(http.MethodPost)
163
164         return r
165 }