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
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
type Storage interface {
type WikiStorage interface {
TermStorage
ContentStorage
DiffStorage
RevisionStorage
}
type TermStorage interface {
CreateTerm(term *Term) error
UpdateTerm(term *Term) error
@ -14,24 +12,16 @@ type TermStorage interface {
GetTermByName(name string) (*Term, error)
GetTermBySlug(slug string) (*Term, error)
GetTermByID(id string) (*Term, error)
GetTerms() ([]Term, error)
GenerateSlug(name string) string
GetTerms() ([]*Term, error)
}
type ContentStorage interface {
CreateContent(content *Content) error
UpdateContent(content *Content) error
RemoveContent(content *Content) error
GetContentByTermName(termName string) (*Content, error)
GetContentByTermID(termID string) (*Content, error)
GetContentByID(id string) (*Content, error)
GetContents() ([]Content, error)
type RevisionStorage interface {
CreateRevision(revision *Revision) error
RemoveRevision(revision *Revision) error
RemoveRevisionsByTermID(termID string) error
GetRevisionByTermName(termName string) (*Revision, error)
GetRevisionByTermSlug(termSlug string) (*Revision, error)
GetRevisionByTermID(termID string) (*Revision, 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
import "gopkg.in/mgo.v2/bson"
import (
"time"
"gopkg.in/mgo.v2/bson"
)
type Term struct {
ID bson.ObjectId `bson:"_id,omitempty"`
Slug string
Name string
ID bson.ObjectId `bson:"_id,omitempty"`
Slug string `bson:"slug"`
Language string `bson:"lang"`
Name string `bson:"name"`
CurrentRevisionID string `bson:"revision_id,omitempty"`
Redirect string `bson:"redirect,omitempty"`
}
type Content struct {
ID bson.ObjectId `bson:"_id,omitempty"`
TermID string
Text string
}
type Diff struct {
ID bson.ObjectId `bson:"_id,omitempty"`
ContentID string
type Revision struct {
ID bson.ObjectId `bson:"_id,omitempty"`
TermID string `bson:"term_id"`
AuthorIP string `bson:"author_ip"`
PublishDate time.Time `bson:"date"`
Text string `bson:"text"`
}

View File

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

View File

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