created handler

This commit is contained in:
Darko Luketic 2017-02-10 22:00:26 +01:00
parent 6a483096dd
commit 9ae93fd26a
6 changed files with 279 additions and 113 deletions

58
main.go
View File

@ -1,3 +1,59 @@
package main package main
func main() {} import (
"net/http"
"github.com/Sirupsen/logrus"
"github.com/dalu/wiki/wiki"
"github.com/dalu/wiki/wiki/storage"
"github.com/dalu/wiki/wiki/storage/mongo"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
func main() {
log := logrus.New()
ms, e := mgo.Dial("localhost")
if e != nil {
log.Fatal("could not connect to mongodb", e.Error())
}
defer ms.Close()
mongostore := mongo.New(ms, mongo.Config{Database: "wiki"})
if e := initializeWiki(mongostore); e != nil {
log.Fatal("initializeWiki: ", e.Error())
}
mux := http.NewServeMux()
wikiHandler := wiki.NewWikiHandler(mongostore, log)
mux.Handle(wiki.DefaultMountPath, http.StripPrefix(wiki.DefaultMountPath, wikiHandler))
log.Fatal(http.ListenAndServe(":8080", mux))
}
func initializeWiki(s storage.WikiStorage) error {
_, e := s.GetTermByName("")
if e != nil {
if e == mgo.ErrNotFound {
t1 := new(storage.Term)
t1.ID = bson.NewObjectId()
t1.Language = "en" //TODO: create a Main_Page for all languages
t1.Redirect = "Main_Page"
t2 := new(storage.Term)
t2.ID = bson.NewObjectId()
t2.Language = "en"
t2.Name = "Main Page"
t2.Slug = "Main_Page"
if e := s.CreateTerm(t1); e != nil {
return e
}
if e := s.CreateTerm(t2); e != nil {
return e
}
} else {
return e
}
}
return nil
}

88
wiki/handler.go Normal file
View File

@ -0,0 +1,88 @@
package wiki
import (
"encoding/json"
"net/http"
"github.com/Sirupsen/logrus"
"github.com/dalu/wiki/wiki/storage"
)
const DefaultMountPath = "/wiki/"
const (
methodGET = "GET"
methodPOST = "POST"
)
type wikiHandler struct {
s storage.WikiStorage
l *logrus.Logger
}
func NewWikiHandler(s storage.WikiStorage, l *logrus.Logger) *wikiHandler {
l.Level = logrus.DebugLevel
return &wikiHandler{
s: s,
l: l,
}
}
func (h *wikiHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case methodGET:
h.handleGET(w, r)
case methodPOST:
h.handlePOST(w, r)
default:
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
}
}
func (h *wikiHandler) handleGET(w http.ResponseWriter, r *http.Request) {
action := r.URL.Query().Get("action")
switch action {
case "":
h.l.Debug("show hit")
h.show(w, r)
case "edit":
h.l.Debug("edit hit")
case "new":
h.l.Debug("new hit")
case "revision":
h.l.Debug("revision hit")
case "revisions":
h.l.Debug("revisions hit")
}
}
func (h *wikiHandler) handlePOST(w http.ResponseWriter, r *http.Request) {}
// -----
func (h *wikiHandler) show(w http.ResponseWriter, r *http.Request) {
term, e := h.s.GetTermBySlug(r.URL.Path)
if e != nil {
h.l.Error("wikihandler.show.GetTermBySlug:", e)
return
}
if term.Redirect != "" {
http.Redirect(w, r, DefaultMountPath+term.Redirect, http.StatusTemporaryRedirect)
return
}
if term.CurrentRevisionID == "" {
http.Redirect(w, r, DefaultMountPath+r.URL.Path+"?action=new", http.StatusTemporaryRedirect)
return
}
revision, e := h.s.GetRevisionByID(term.CurrentRevisionID)
if e != nil {
h.l.Error("wikihandler.show.GetRevisionByTermID:", e)
return
}
// temporary
if e := json.NewEncoder(w).Encode(revision); e != nil {
h.l.Error("wikihandler.show.NewEncoder:", e)
http.Error(w, e.Error(), http.StatusInternalServerError)
}
}

View File

@ -1,12 +1,10 @@
package storage package storage
type Storage interface { type WikiStorage interface {
TermStorage TermStorage
ContentStorage RevisionStorage
DiffStorage
} }
type TermStorage interface { type TermStorage interface {
CreateTerm(term *Term) error CreateTerm(term *Term) error
UpdateTerm(term *Term) error UpdateTerm(term *Term) error
@ -14,24 +12,16 @@ type TermStorage interface {
GetTermByName(name string) (*Term, error) GetTermByName(name string) (*Term, error)
GetTermBySlug(slug string) (*Term, error) GetTermBySlug(slug string) (*Term, error)
GetTermByID(id string) (*Term, error) GetTermByID(id string) (*Term, error)
GetTerms() ([]Term, error) GetTerms() ([]*Term, error)
GenerateSlug(name string) string
} }
type ContentStorage interface { type RevisionStorage interface {
CreateContent(content *Content) error CreateRevision(revision *Revision) error
UpdateContent(content *Content) error RemoveRevision(revision *Revision) error
RemoveContent(content *Content) error RemoveRevisionsByTermID(termID string) error
GetContentByTermName(termName string) (*Content, error) GetRevisionByTermName(termName string) (*Revision, error)
GetContentByTermID(termID string) (*Content, error) GetRevisionByTermSlug(termSlug string) (*Revision, error)
GetContentByID(id string) (*Content, error) GetRevisionByTermID(termID string) (*Revision, error)
GetContents() ([]Content, error) GetRevisionByID(id string) (*Revision, error)
} GetRevisions() ([]*Revision, error)
type DiffStorage interface {
CreateDiff(diff *Diff) error
UpdateDiff(diff *Diff) error
RemoveDiff(diff *Diff) error
GetDiff(term string) (*Diff, error)
GetDiffs() ([]Diff, error)
} }

View File

@ -1,21 +1,24 @@
package storage package storage
import "gopkg.in/mgo.v2/bson" import (
"time"
"gopkg.in/mgo.v2/bson"
)
type Term struct { type Term struct {
ID bson.ObjectId `bson:"_id,omitempty"` ID bson.ObjectId `bson:"_id,omitempty"`
Slug string Slug string `bson:"slug"`
Name string Language string `bson:"lang"`
Name string `bson:"name"`
CurrentRevisionID string `bson:"revision_id,omitempty"`
Redirect string `bson:"redirect,omitempty"`
} }
type Content struct { type Revision struct {
ID bson.ObjectId `bson:"_id,omitempty"` ID bson.ObjectId `bson:"_id,omitempty"`
TermID string TermID string `bson:"term_id"`
Text string AuthorIP string `bson:"author_ip"`
} PublishDate time.Time `bson:"date"`
Text string `bson:"text"`
type Diff struct {
ID bson.ObjectId `bson:"_id,omitempty"`
ContentID string
} }

View File

@ -9,71 +9,65 @@ import (
const ( const (
databaseDefault = "wiki" databaseDefault = "wiki"
termCollectionDefault = "term" termCollectionDefault = "term"
contentCollectionDefault = "content" RevisionCollectionDefault = "revision"
diffCollectionDefault = "diff"
) )
type mongoStorage struct { type mongoStorage struct {
ms *mgo.Session ms *mgo.Session
database string database string
termCollection string termCollection string
contentCollection string revisionCollection string
diffCollection string
} }
type Config struct { type Config struct {
Database string Database string
TermCollection string TermCollection string
ContentCollection string RevisionCollection string
DiffCollection string
} }
func New(ms *mgo.Session, config Config) *mongoStorage { func New(ms *mgo.Session, config Config) mongoStorage {
if config.Database == "" { if config.Database == "" {
config.Database = databaseDefault config.Database = databaseDefault
} }
if config.TermCollection == "" { if config.TermCollection == "" {
config.TermCollection = termCollectionDefault config.TermCollection = termCollectionDefault
} }
if config.ContentCollection == "" { if config.RevisionCollection == "" {
config.ContentCollection = contentCollectionDefault config.RevisionCollection = RevisionCollectionDefault
} }
if config.DiffCollection == "" {
config.DiffCollection = diffCollectionDefault return mongoStorage{
}
return &mongoStorage{
ms: ms.Clone(), ms: ms.Clone(),
database: config.Database, database: config.Database,
termCollection: config.TermCollection, termCollection: config.TermCollection,
contentCollection: config.ContentCollection, revisionCollection: config.RevisionCollection,
diffCollection: config.DiffCollection,
} }
} }
// Term // --- Term ---
func (s *mongoStorage) CreateTerm(term *storage.Term) error { func (s mongoStorage) CreateTerm(term *storage.Term) error {
ms := s.ms.Copy() ms := s.ms.Copy()
defer ms.Close() defer ms.Close()
c := ms.DB(s.database).C(s.termCollection) c := ms.DB(s.database).C(s.termCollection)
return c.Insert(term) return c.Insert(term)
} }
func (s *mongoStorage) UpdateTerm(term *storage.Term) error { func (s mongoStorage) UpdateTerm(term *storage.Term) error {
ms := s.ms.Copy() ms := s.ms.Copy()
defer ms.Close() defer ms.Close()
c := ms.DB(s.database).C(s.termCollection) c := ms.DB(s.database).C(s.termCollection)
return c.UpdateId(term.ID, term) return c.UpdateId(term.ID, term)
} }
func (s *mongoStorage) RemoveTerm(term *storage.Term) error { func (s mongoStorage) RemoveTerm(term *storage.Term) error {
ms := s.ms.Copy() ms := s.ms.Copy()
defer ms.Close() defer ms.Close()
c := ms.DB(s.database).C(s.termCollection) c := ms.DB(s.database).C(s.termCollection)
return c.RemoveId(term.ID) return c.RemoveId(term.ID)
} }
func (s *mongoStorage) GetTermByName(name string) (*storage.Term, error) { func (s mongoStorage) GetTermByName(name string) (*storage.Term, error) {
ms := s.ms.Copy() ms := s.ms.Copy()
defer ms.Close() defer ms.Close()
c := ms.DB(s.database).C(s.termCollection) c := ms.DB(s.database).C(s.termCollection)
@ -84,98 +78,129 @@ func (s *mongoStorage) GetTermByName(name string) (*storage.Term, error) {
return term, nil return term, nil
} }
func (s *mongoStorage) GetTerms() ([]storage.Term, error) { func (s mongoStorage) GetTermBySlug(slug string) (*storage.Term, error) {
ms := s.ms.Copy() ms := s.ms.Copy()
defer ms.Close() defer ms.Close()
c := ms.DB(s.database).C(s.termCollection) c := ms.DB(s.database).C(s.termCollection)
terms := []storage.Term{} term := new(storage.Term)
if e := c.Find(bson.M{"slug": slug}).One(term); e != nil {
return nil, e
}
return term, nil
}
func (s mongoStorage) GetTermByID(id string) (*storage.Term, error) {
ms := s.ms.Copy()
defer ms.Close()
c := ms.DB(s.database).C(s.termCollection)
term := new(storage.Term)
if e := c.FindId(bson.ObjectIdHex(id)).One(term); e != nil {
return nil, e
}
return term, nil
}
func (s mongoStorage) GetTerms() ([]*storage.Term, error) {
ms := s.ms.Copy()
defer ms.Close()
c := ms.DB(s.database).C(s.termCollection)
terms := []*storage.Term{}
if e := c.Find(nil).All(&terms); e != nil { if e := c.Find(nil).All(&terms); e != nil {
return terms, e return terms, e
} }
return terms, nil return terms, nil
} }
func (s *mongoStorage) GetTermByID(id string) (*storage.Term, error) { // --- Revision ---
panic("implement me")
}
func (s *mongoStorage) GetTermBySlug(slug string) (*storage.Term, error) { func (s mongoStorage) CreateRevision(Revision *storage.Revision) error {
panic("implement me")
}
func (s *mongoStorage) GenerateSlug(name string) string {
panic("implement me")
}
// Content
func (s *mongoStorage) CreateContent(content *storage.Content) error {
ms := s.ms.Copy() ms := s.ms.Copy()
defer ms.Close() defer ms.Close()
c := ms.DB(s.database).C(s.contentCollection) c := ms.DB(s.database).C(s.revisionCollection)
return c.Insert(content) return c.Insert(Revision)
} }
func (s *mongoStorage) UpdateContent(content *storage.Content) error { func (s mongoStorage) RemoveRevision(Revision *storage.Revision) error {
ms := s.ms.Copy() ms := s.ms.Copy()
defer ms.Close() defer ms.Close()
c := ms.DB(s.database).C(s.contentCollection) c := ms.DB(s.database).C(s.revisionCollection)
return c.UpdateId(content.ID, content) return c.RemoveId(Revision.ID)
} }
func (s *mongoStorage) RemoveContent(content *storage.Content) error { func (s mongoStorage) RemoveRevisionsByTermID(termID string) error {
ms := s.ms.Copy() ms := s.ms.Copy()
defer ms.Close() defer ms.Close()
c := ms.DB(s.database).C(s.contentCollection) c := ms.DB(s.database).C(s.revisionCollection)
return c.RemoveId(content.ID) _, e := c.RemoveAll(bson.M{"term_id": termID})
if e != nil {
return e
}
return nil
} }
func (s *mongoStorage) GetContentByTermName(termName string) (*storage.Content, error) { func (s mongoStorage) GetRevisionByTermName(termName string) (*storage.Revision, error) {
ms := s.ms.Copy() ms := s.ms.Copy()
defer ms.Close() defer ms.Close()
c := ms.DB(s.database).C(s.contentCollection) c := ms.DB(s.database).C(s.revisionCollection)
term, e := s.GetTermByName(termName) term, e := s.GetTermByName(termName)
if e != nil { if e != nil {
return nil, e return nil, e
} }
content := new(storage.Content) Revision := new(storage.Revision)
if e := c.Find(bson.M{"term_id": term.ID.Hex()}).One(content); e != nil { if e := c.Find(bson.M{"term_id": term.ID.Hex()}).One(Revision); e != nil {
return nil, e return nil, e
} }
return content, nil return Revision, nil
} }
func (s *mongoStorage) GetContentByID(id string) (*storage.Content, error) { func (s mongoStorage) GetRevisionByTermSlug(termSlug string) (*storage.Revision, error) {
panic("implement me") ms := s.ms.Copy()
defer ms.Close()
c := ms.DB(s.database).C(s.revisionCollection)
term, e := s.GetTermByName(termSlug)
if e != nil {
return nil, e
}
Revision := new(storage.Revision)
if e := c.Find(bson.M{"term_id": term.ID.Hex()}).One(Revision); e != nil {
return nil, e
}
return Revision, nil
} }
func (s *mongoStorage) GetContentByTermID(termID string) (*storage.Content, error) { func (s mongoStorage) GetRevisionByID(id string) (*storage.Revision, error) {
panic("implement me") ms := s.ms.Copy()
defer ms.Close()
c := ms.DB(s.database).C(s.revisionCollection)
Revision := new(storage.Revision)
if e := c.FindId(bson.ObjectIdHex(id)).One(Revision); e != nil {
return nil, e
}
return Revision, nil
} }
func (s *mongoStorage) GetContents() ([]storage.Content, error) { func (s mongoStorage) GetRevisionByTermID(termID string) (*storage.Revision, error) {
panic("implement me") ms := s.ms.Copy()
defer ms.Close()
c := ms.DB(s.database).C(s.revisionCollection)
term, e := s.GetTermByID(termID)
if e != nil {
return nil, e
}
Revision := new(storage.Revision)
if e := c.Find(bson.M{"term_id": term.ID.Hex()}).One(Revision); e != nil {
return nil, e
}
return Revision, nil
} }
// Diff func (s mongoStorage) GetRevisions() ([]*storage.Revision, error) {
ms := s.ms.Copy()
func (s *mongoStorage) CreateDiff(diff *storage.Diff) error { defer ms.Close()
panic("implement me") c := ms.DB(s.database).C(s.revisionCollection)
terms := []*storage.Revision{}
if e := c.Find(nil).All(&terms); e != nil {
return terms, e
} }
return terms, nil
func (s *mongoStorage) UpdateDiff(diff *storage.Diff) error {
panic("implement me")
}
func (s *mongoStorage) RemoveDiff(diff *storage.Diff) error {
panic("implement me")
}
func (s *mongoStorage) GetDiff(term string) (*storage.Diff, error) {
panic("implement me")
}
func (s *mongoStorage) GetDiffs() ([]storage.Diff, error) {
panic("implement me")
} }

View File

@ -1 +1,5 @@
package wiki package wiki
func generateSlug() {}
func diff(text1, text2 string) {}