Working on blog stuff
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# Blog module
|
||||
|
||||
A simple blog module for darkstorm-backend.
|
||||
|
||||
## Requests
|
||||
|
||||
### Author info
|
||||
|
||||
> GET /author/{authorID}
|
||||
|
||||
```json
|
||||
```
|
||||
|
||||
### Blog
|
||||
|
||||
#### Specific blog
|
||||
|
||||
> GET /blog/{blogID}
|
||||
|
||||
Return:
|
||||
|
||||
```json
|
||||
{
|
||||
id: "blogID",
|
||||
createTime: 0, // creation time in Unix format
|
||||
updateTime: 0, // last update time in Unix format
|
||||
author: "authorID",
|
||||
favicon: "favicon url",
|
||||
title: "blog title",
|
||||
blog: "blog", // blog will have been converted to HTML
|
||||
}
|
||||
```
|
||||
|
||||
#### Latest blogs
|
||||
|
||||
> GET /blog?page=0
|
||||
|
||||
Will return up to 5 blogs. `page` query is optional (implies 0 if not set).
|
||||
|
||||
Return:
|
||||
|
||||
```json
|
||||
{
|
||||
num: 1, // Number of returned results, returns up to 5 results
|
||||
blogs: [
|
||||
{
|
||||
id: "blogID",
|
||||
createTime: 0, // creation time in Unix format
|
||||
updateTime: 0, // last update time in Unix format
|
||||
author: "authorID",
|
||||
favicon: "favicon url",
|
||||
title: "blog title",
|
||||
blog: "blog", // blog will have been converted to HTML
|
||||
}
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Blog List
|
||||
|
||||
> GET /blog/list?page=0
|
||||
|
||||
Will return up to 50 IDs. `page` query is optional (implies 0 if not set).
|
||||
|
||||
Return:
|
||||
|
||||
```json
|
||||
{
|
||||
num: 1, // Number of returned results, returns up to 50 results
|
||||
blogList: [
|
||||
{
|
||||
id: "blogID",
|
||||
createTime: 0, // Unix format
|
||||
},
|
||||
{
|
||||
id: "blogID",
|
||||
createTime: 0, // Unix format
|
||||
},
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,54 @@
|
||||
package blog
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/CalebQ42/darkstorm-server/internal/backend"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type Author struct {
|
||||
ID string `json:"id" bson:"_id"`
|
||||
About string `json:"about" bson:"about"`
|
||||
PicURL string `json:"picurl" bson:"picurl"`
|
||||
}
|
||||
|
||||
func (b *BlogApp) AboutCaleb() (*Author, error) {
|
||||
res := b.authCol.FindOne(context.Background(), bson.M{"_id": "caleb_gardner"})
|
||||
if res.Err() != nil {
|
||||
log.Println("error getting about me:", res.Err())
|
||||
if res.Err() == mongo.ErrNoDocuments {
|
||||
return nil, backend.ErrNotFound
|
||||
}
|
||||
return nil, res.Err()
|
||||
}
|
||||
var aboutMe Author
|
||||
err := res.Decode(&aboutMe)
|
||||
if err != nil {
|
||||
log.Println("error decoding about me:", res)
|
||||
return nil, err
|
||||
}
|
||||
return &aboutMe, nil
|
||||
}
|
||||
|
||||
func (b *BlogApp) GetAuthorInfo(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
}
|
||||
|
||||
func (b *BlogApp) SetAuthorInfo(w http.ResponseWriter, r *http.Request) {
|
||||
hdr, err := b.back.VerifyHeader(w, r, "managment", true)
|
||||
if hdr == nil {
|
||||
if err != nil {
|
||||
log.Println("error verifying apiKey:", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if hdr.Key.AppID != "blog" {
|
||||
backend.ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application not authorized")
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package blog
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/CalebQ42/darkstorm-server/internal/backend"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type Blog struct {
|
||||
ID string `json:"id" bson:"_id"`
|
||||
Author string `json:"author" bson:"author"`
|
||||
Favicon string `json:"favicon" bson:"favicon"`
|
||||
Title string `json:"title" bson:"title"`
|
||||
Blog string `json:"blog" bson:"blog"`
|
||||
CreateTime int `json:"createTime" bson:"createTime"`
|
||||
UpdateTime int `json:"updateTime" bson:"updateTime"`
|
||||
}
|
||||
|
||||
func (b *Blog) ConvertBlog() {
|
||||
//TODO: parse BBCode/Markdown from blog
|
||||
//b.Blog = bbCodeConvert(b.Blog)
|
||||
}
|
||||
|
||||
func (b *BlogApp) GetAuthor(blog *Blog) (*Author, error) {
|
||||
res := b.authCol.FindOne(context.Background(), bson.M{"_id": blog.Author})
|
||||
if res.Err() != nil {
|
||||
if res.Err() == mongo.ErrNoDocuments {
|
||||
return nil, backend.ErrNotFound
|
||||
}
|
||||
return nil, res.Err()
|
||||
}
|
||||
var author Author
|
||||
err := res.Decode(&author)
|
||||
return &author, err
|
||||
}
|
||||
|
||||
func (b *BlogApp) GetBlog(ID string) (*Blog, error) {
|
||||
res := b.blogCol.FindOne(context.Background(), bson.M{"_id": ID})
|
||||
if res.Err() != nil {
|
||||
if res.Err() == mongo.ErrNoDocuments {
|
||||
return nil, backend.ErrNotFound
|
||||
}
|
||||
return nil, res.Err()
|
||||
}
|
||||
var blog Blog
|
||||
err := res.Decode(blog)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blog.ConvertBlog()
|
||||
return &blog, nil
|
||||
}
|
||||
|
||||
func (b *BlogApp) Blog(w http.ResponseWriter, r *http.Request) {
|
||||
blogID := r.PathValue("blogID")
|
||||
if blogID == "" {
|
||||
backend.ReturnError(w, http.StatusBadRequest, "badRequest", "Must provide a blogID")
|
||||
return
|
||||
}
|
||||
blog, err := b.GetBlog(blogID)
|
||||
if err != nil {
|
||||
if err == backend.ErrNotFound {
|
||||
backend.ReturnError(w, http.StatusNotFound, "notFound", "Not blog found with the given ID")
|
||||
return
|
||||
}
|
||||
log.Println("error getting blog:", err)
|
||||
backend.ReturnError(w, http.StatusInternalServerError, "internal", "Server error")
|
||||
return
|
||||
}
|
||||
json.NewEncoder(w).Encode(blog)
|
||||
}
|
||||
|
||||
func (b *BlogApp) GetLatestBlogs(page int64) ([]Blog, error) {
|
||||
res, err := b.blogCol.Find(context.Background(), bson.M{}, options.Find().
|
||||
SetSort(bson.M{"createTime": 1}).
|
||||
SetLimit(5).
|
||||
SetSkip(page*5))
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, backend.ErrNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
var out []Blog
|
||||
err = res.All(context.Background(), &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := range out {
|
||||
out[i].ConvertBlog()
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (b *BlogApp) LatestBlogs(w http.ResponseWriter, r *http.Request) {
|
||||
var page int
|
||||
var err error
|
||||
pagQuery := r.URL.Query().Get("page")
|
||||
if pagQuery != "" {
|
||||
page, err = strconv.Atoi(pagQuery)
|
||||
if err != nil {
|
||||
page = 0
|
||||
}
|
||||
}
|
||||
blogs, err := b.GetLatestBlogs(int64(page))
|
||||
if err != nil && err != backend.ErrNotFound {
|
||||
backend.ReturnError(w, http.StatusInternalServerError, "internal", "internal error")
|
||||
return
|
||||
}
|
||||
var ret struct {
|
||||
Blogs []Blog `json:"blogs"`
|
||||
Num int `json:"num"`
|
||||
}
|
||||
ret.Num = len(blogs)
|
||||
ret.Blogs = blogs
|
||||
json.NewEncoder(w).Encode(ret)
|
||||
}
|
||||
|
||||
type BlogListResult struct {
|
||||
ID string `json:"id" bson:"_id"`
|
||||
CreateTime int `json:"createTime" bson:"createTime"`
|
||||
}
|
||||
|
||||
func (b *BlogApp) GetBlogList(page int64) ([]BlogListResult, error) {
|
||||
res, err := b.blogCol.Find(context.Background(), bson.M{}, options.Find().
|
||||
SetProjection(bson.M{"_id": 1, "createTime": 1}).
|
||||
SetSort(bson.M{"createTime": 1}).
|
||||
SetLimit(50).
|
||||
SetSkip(page*50))
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil, backend.ErrNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
var out []BlogListResult
|
||||
err = res.All(context.Background(), &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (b *BlogApp) BlogList(w http.ResponseWriter, r *http.Request) {
|
||||
var page int
|
||||
var err error
|
||||
pagQuery := r.URL.Query().Get("page")
|
||||
if pagQuery != "" {
|
||||
page, err = strconv.Atoi(pagQuery)
|
||||
if err != nil {
|
||||
page = 0
|
||||
}
|
||||
}
|
||||
blogList, err := b.GetBlogList(int64(page))
|
||||
if err != nil && err != backend.ErrNotFound {
|
||||
backend.ReturnError(w, http.StatusInternalServerError, "internal", "internal error")
|
||||
return
|
||||
}
|
||||
var ret struct {
|
||||
BlogList []BlogListResult `json:"blogList"`
|
||||
Num int `json:"num"`
|
||||
}
|
||||
ret.Num = len(blogList)
|
||||
ret.BlogList = blogList
|
||||
json.NewEncoder(w).Encode(ret)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package blog
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/CalebQ42/darkstorm-server/internal/backend"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type BlogApp struct {
|
||||
back *backend.Backend
|
||||
blogCol *mongo.Collection
|
||||
authCol *mongo.Collection
|
||||
}
|
||||
|
||||
func NewBlogApp(b *backend.Backend, db *mongo.Database, mux *http.ServeMux) *BlogApp {
|
||||
out := &BlogApp{
|
||||
back: b,
|
||||
blogCol: db.Collection("blog"),
|
||||
authCol: db.Collection("author"),
|
||||
}
|
||||
// setup mux
|
||||
mux.HandleFunc("GET /blog/", out.LatestBlogs)
|
||||
mux.HandleFunc("GET /blog/{blogID}", out.Blog)
|
||||
//TODO
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user