Documentation
¶
Index ¶
- Variables
- func SetFlash(w http.ResponseWriter, level string, value string)
- type BadRequestError
- type Comment
- type CommentAccessor
- type CommentHookFn
- type CommentNode
- type CommentPresenter
- type CommentPresentersTree
- type CommentSeenByUser
- type ErrorResponder
- type HandleE
- type Maybe404Error
- type MethodNotAllowedError
- type Server
- func (s *Server) AddCommentHook(fn CommentHookFn)
- func (s *Server) AddStoryHook(fn StoryHookFn)
- func (s *Server) HandleCommentEdit() HandleE
- func (s *Server) HandleCommentUpdateAction() HandleE
- func (s *Server) HandleIndex() HandleE
- func (s *Server) HandleOAuthCallback() HandleE
- func (s *Server) HandleOAuthDestroy() HandleE
- func (s *Server) HandleOAuthStart() HandleE
- func (s *Server) HandleShow() HandleE
- func (s *Server) HandleSubmit() HandleE
- func (s *Server) HandleSubmitAction() HandleE
- func (s *Server) HandleSubmitCommentAction() HandleE
- func (s *Server) HandleVoteCommentAction() HandleE
- func (s *Server) HandleVoteStoryAction() HandleE
- func (s *Server) Prepare() error
- func (s *Server) ServeHTTP(res http.ResponseWriter, req *http.Request)
- func (s *Server) Start() error
- func (s *Server) Stop()
- type ServerConfig
- type Store
- type Story
- type StoryHookFn
- type StorySeenByUser
- type UnauthorizedError
- type UnprocessableEntityError
- type User
- type UserSettings
- type Vote
Constants ¶
This section is empty.
Variables ¶
var NowFunc func() time.Time = time.Now
Functions ¶
Types ¶
type BadRequestError ¶
type BadRequestError struct {
// contains filtered or unexported fields
}
BadRequestError responds with bad request status code
func BadRequest ¶
func BadRequest(err error) *BadRequestError
func (*BadRequestError) Error ¶
func (e *BadRequestError) Error() string
func (*BadRequestError) RespondError ¶
func (e *BadRequestError) RespondError(w http.ResponseWriter, r *http.Request) bool
type Comment ¶
type Comment struct {
ID string `db:"id"`
ParentCommentID sql.NullString `db:"parent_comment_id"`
StoryID string `db:"story_id"`
Body string `db:"body"`
Score int64 `db:"score"`
AuthorID string `db:"author_id"`
Author string `db:"author"`
CreatedAt time.Time `db:"created_at"`
}
func NewComment ¶
func (*Comment) GetParentCommentID ¶
func (c *Comment) GetParentCommentID() sql.NullString
type CommentAccessor ¶
type CommentAccessor interface {
GetID() string
GetParentCommentID() sql.NullString
GetScore() int64
Age() time.Time
}
TODO we should probably refactor these structs, their name are unclear for now, it'll do the job.
type CommentHookFn ¶
CommentHookFn represents a function suitable for Commet hooks
type CommentNode ¶
type CommentNode struct {
Comment CommentAccessor
Children []*CommentNode
}
CommentTree is a simple tree of comments ordered by score
type CommentPresenter ¶
type CommentPresenter struct {
ID string
StoryID string
Path string
ParentPath string
StoryPath string
Body template.HTML
Score int64
Author string
CreatedAt time.Time
Children []*CommentPresenter
Upvoted bool
CanEdit bool
}
TODO move this in a better place
func NewCommentPresenter ¶
func NewCommentPresenter(c *CommentNode) *CommentPresenter
TODO missing fields
func (*CommentPresenter) Age ¶
func (c *CommentPresenter) Age() time.Time
func (*CommentPresenter) GetScore ¶
func (c *CommentPresenter) GetScore() int64
func (*CommentPresenter) SetCanEdit ¶
CanEdit returns true if the given user is the author and if the creation date is still within the given edit window.
type CommentPresentersTree ¶
type CommentPresentersTree []*CommentPresenter
func NewCommentPresentersTree ¶
func NewCommentPresentersTree(comments []CommentAccessor) CommentPresentersTree
func (CommentPresentersTree) SetCanEdits ¶
type CommentSeenByUser ¶
func (*CommentSeenByUser) GetID ¶
func (c *CommentSeenByUser) GetID() string
func (*CommentSeenByUser) GetParentCommentID ¶
func (c *CommentSeenByUser) GetParentCommentID() sql.NullString
type ErrorResponder ¶
type ErrorResponder interface {
RespondError(w http.ResponseWriter, r *http.Request) bool
}
type HandleE ¶
type HandleE func(http.ResponseWriter, *http.Request, httprouter.Params) error
HandleE is a httprouter.Handle that also returns an error.
type Maybe404Error ¶
type Maybe404Error struct {
// contains filtered or unexported fields
}
Maybe404Error responds with not found status code, if its supplied error is sql.ErrNoRows.
func Maybe404 ¶
func Maybe404(err error) *Maybe404Error
func (*Maybe404Error) Error ¶
func (e *Maybe404Error) Error() string
func (*Maybe404Error) Is404 ¶
func (e *Maybe404Error) Is404() bool
func (*Maybe404Error) RespondError ¶
func (e *Maybe404Error) RespondError(w http.ResponseWriter, r *http.Request) bool
type MethodNotAllowedError ¶
type MethodNotAllowedError struct {
// contains filtered or unexported fields
}
MethodNotAllowedError responds with a method not allowed status code.
func MethodNotAllowed ¶
func MethodNotAllowed(method string, path string) *MethodNotAllowedError
func (*MethodNotAllowedError) Error ¶
func (e *MethodNotAllowedError) Error() string
func (*MethodNotAllowedError) RespondError ¶
func (e *MethodNotAllowedError) RespondError(w http.ResponseWriter, r *http.Request) bool
type Server ¶
type Server struct {
// Logger is the server logger
Logger zerolog.Logger
// contains filtered or unexported fields
}
Server represents the HTTP server component, with all its runtime dependencies.
func NewServer ¶
func NewServer(config *ServerConfig, logger zerolog.Logger, store Store, authService authentication.AuthService) *Server
NewServer returns a server instance, configured with given components and with middlewares installed.
func (*Server) AddCommentHook ¶
func (s *Server) AddCommentHook(fn CommentHookFn)
AddCommentHook registers a given CommentHookFn, that will be called every time a story is submitted. Multiple hooks will be called in the order they were registered. If a hook fails and returns an error, it will interrupt the request but won't prevent the Comment to be created.
func (*Server) AddStoryHook ¶
func (s *Server) AddStoryHook(fn StoryHookFn)
AddStoryHook registers a given StoryHookFn, that will be called every time a story is submitted. Multiple hooks will be called in the order they were registered. If a hook fails and returns an error, it will interrupt the request but won't prevent the Story to be created.
func (*Server) HandleCommentEdit ¶
func (*Server) HandleCommentUpdateAction ¶
func (*Server) HandleIndex ¶
HandleIndex handles requests for the root path, listing sorted paginated stories. If the client isn't authenticated, it serves a template with no upvoting nor commenting capabilities.
func (*Server) HandleOAuthCallback ¶
HandleOAuthCallback handles requests of the OAuth provider redirects the user back to Tabloid, after successfully authenticating him on its side.
func (*Server) HandleOAuthDestroy ¶
HandleOAuthDestroy handles requests destroying the current session.
func (*Server) HandleOAuthStart ¶
HandleOAuthStart handles requests starting the OAauth authentication process.
func (*Server) HandleShow ¶
HandleShow handles requests to access a particular Story, showing all its comments and allowing the user to comment if authenticated.
func (*Server) HandleSubmit ¶
HandleSubmit handles requests to get the form for submitting a Story. It redirects to the root path if not authenticated.
func (*Server) HandleSubmitAction ¶
HandleSubmitAction handles requests for when a user submit a Story form. It redirects the user to the root path if not authenticated. In case someone bypass the client-side form validations with invalid form data, it returns a HTTP error.
func (*Server) HandleSubmitCommentAction ¶
HandleSubmitCommentAction handles requests for when a user submit a Comment form for a given Story. It redirects the user to the root path if not authenticated. In case someone bypass the client-side form validations with invalid form data, it returns a HTTP error.
func (*Server) HandleVoteCommentAction ¶
HandleVoteCommentAction handles requests to vote on a comment. It redirects back to the Story on which the Comment was posted on. If not authenticated, it redirects to the root path.
func (*Server) HandleVoteStoryAction ¶
HandleVoteStoryAction handles requests to vote on a given Story. If not authenticated, it redirects to the root path.
func (*Server) Prepare ¶
Prepare setups all internal components, like connecting to the database, declaring routes and loading templates.
func (*Server) ServeHTTP ¶
func (s *Server) ServeHTTP(res http.ResponseWriter, req *http.Request)
ServeHTTP implements a http.Handler that answers incoming requests.
type ServerConfig ¶
type ServerConfig struct {
Addr string
StoriesPerPage int
EditWindowInMinutes int
FrontPageTimeBaseInHours int
FrontPageGravity float64
}
ServerConfig represents the settings required for the server to operate.
type Store ¶
type Store interface {
Connect() error
FindStory(ID string) (*Story, error)
FindStoryWithVote(ID string, userID string) (*StorySeenByUser, error)
ListStories(page int, perPage int) ([]*Story, error)
ListStoriesWithVotes(userID string, page int, perPage int) ([]*StorySeenByUser, error)
InsertStory(item *Story) error
FindComment(commentID string) (*Comment, error)
ListComments(storyID string) ([]*Comment, error)
ListCommentsWithVotes(storyID string, userID string) ([]*CommentSeenByUser, error)
InsertComment(comment *Comment) error
UpdateComment(comment *Comment) error
FindUserByLogin(login string) (*User, error)
CreateOrUpdateUser(login string, email string) (string, error)
CreateOrUpdateVoteOnStory(storyID string, userID string, up bool) error
CreateOrUpdateVoteOnComment(storyID string, userID string, up bool) error
UpdateUser(user *User) error
}
type Story ¶
type StoryHookFn ¶
StoryHookFn represents a function suitable for Story hooks
type StorySeenByUser ¶
type UnauthorizedError ¶
type UnauthorizedError struct {
// contains filtered or unexported fields
}
UnauthorizedError responds with unauthorized status code.
func Unauthorized ¶
func Unauthorized(path string) *UnauthorizedError
func (*UnauthorizedError) Error ¶
func (e *UnauthorizedError) Error() string
func (*UnauthorizedError) RespondError ¶
func (e *UnauthorizedError) RespondError(w http.ResponseWriter, r *http.Request) bool
type UnprocessableEntityError ¶
type UnprocessableEntityError struct {
// contains filtered or unexported fields
}
UnprocessableEntityErrorError responds with bad request status code, listing fields that are invalid.
func UnprocessableEntity ¶
func UnprocessableEntity(fieldNames ...string) *UnprocessableEntityError
func UnprocessableEntityWithError ¶
func UnprocessableEntityWithError(err error, fieldNames ...string) *UnprocessableEntityError
func (*UnprocessableEntityError) Error ¶
func (e *UnprocessableEntityError) Error() string
func (*UnprocessableEntityError) RespondError ¶
func (e *UnprocessableEntityError) RespondError(w http.ResponseWriter, r *http.Request) bool
type UserSettings ¶
type UserSettings struct {
SendDailyDigest bool `json:"send_daily_digest,omitempty"`
}
func (*UserSettings) Scan ¶
func (us *UserSettings) Scan(value interface{}) error