func main() { svcConfig := &service.Config{ Name: "KnowledgeDB", DisplayName: "Knowledge DB", Description: "Knowledge DB - Webserver", } prg := &program{} s, err := service.New(prg, svcConfig) if err != nil { log.Fatal(err) } logger, err := s.Logger(nil) if err != nil { log.Fatal(err) } log.SetServiceLogger(logger) if len(os.Args) == 2 { command := os.Args[1] err := service.Control(s, command) if err != nil { log.Fatalf("%v\n\nValidOperations: %v", err, service.ControlAction) } return } err = s.Run() if err != nil { log.Error(err) } }
func renderTemplate(w http.ResponseWriter, tmpl string, p interface{}) { tmplInstance, ok := templates[tmpl] if !ok { log.Fatal("Invalid Template:", tmpl) } err := tmplInstance.ExecuteTemplate(w, "base.html", p) if err != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) log.Fatal("Template Error", err) } }
func initTemplates() { templateDir := path.Join(config.ApplicationDir, "templates") html := []string{ "markdown", // needed for "renderMarkdown" "edit_document", "view_document", "create_document", "search_result", "index", "tag", "licenses", } myFuncs := template.FuncMap{ "fmtDateTime": func(t time.Time) string { return t.Format("02.01.2006 15:04:05") }, "markdown": func(text string) template.HTML { return markdown.ToHtml(text) }, } templates = make(map[string]*template.Template) addTemplate := func(name string, files ...string) { fList := make([]string, len(files)) for i, f := range files { fList[i] = path.Join(templateDir, f) } templates[name] = template.Must(template.New(name).Funcs(myFuncs).ParseFiles(fList...)) } for _, t := range html { addTemplate(t, "base.html", t+".html") } for k, v := range mdContent { f, err := os.Open(path.Join(templateDir, v)) if err != nil { log.Fatal(err) } defer f.Close() content, err := ioutil.ReadAll(f) if err != nil { log.Fatal(err) } mdContent[k] = string(content) } }
func Init(allDocs GetAllDocsFn) { var err error idx_path := path.Join(config.Current.DataDir, index_name) index, err = bleve.Open(idx_path) if err == bleve.ErrorIndexPathDoesNotExist { log.Info("Creating new Index") indexMapping := bleve.NewIndexMapping() indexMapping.DefaultAnalyzer = config.Current.DefaultAnalyzer entryMapping := bleve.NewDocumentMapping() textField := bleve.NewTextFieldMapping() entryMapping.AddFieldMappingsAt("Body", textField) entryMapping.AddFieldMappingsAt("Title", textField) tagField := bleve.NewTextFieldMapping() tagField.Analyzer = tag_analyzer entryMapping.AddFieldMappingsAt("Tags", tagField) indexMapping.AddDocumentMapping("entry", entryMapping) index, err = bleve.New(idx_path, indexMapping) if err != nil { log.Fatal(err) } // reindex existing documents indexRebuildingLogged := false for itm := range allDocs() { if !indexRebuildingLogged { indexRebuildingLogged = true log.Info("Start rebuilding Search-Index") } index.Index(itm.Id(), itm.Content()) } if indexRebuildingLogged { log.Info("Finished rebuilding Search-Index") } } else if err == nil { log.Info("Opening existing Index") } else { log.Fatal(err) } }
func (s httpServer) Serve(exit <-chan struct{}) { r := mux.NewRouter() r.HandleFunc("/new", s.serveCreateEntry).Methods("GET", "POST") r.HandleFunc("/delete/{id}", s.withDoc(s.serveDeleteEntry)).Methods("POST") r.HandleFunc("/edit/{id}", s.withDoc(s.serveEditEntry)).Methods("GET", "POST") r.HandleFunc("/view/{id}", s.withDoc(s.serveViewEntry)).Methods("GET") r.HandleFunc("/search", s.serveSearchEntries).Methods("POST") r.HandleFunc("/alltags", s.serveAllTags).Methods("GET") r.HandleFunc("/tag/{tag}", s.serveTagDetails).Methods("GET") r.HandleFunc("/licenses", s.serveLicenses).Methods("GET") r.HandleFunc("/help", s.serveMarkdown("help")).Methods("GET") r.HandleFunc("/", s.serveIndex).Methods("GET") r.PathPrefix("/").Handler(http.FileServer(http.Dir(path.Join(config.ApplicationDir, "static")))).Methods("GET") ln, err := net.Listen("tcp", config.Current.HttpAddr) if err != nil { log.Fatal(err) return } srv := http.Server{Handler: r} go func() { log.Info("Starting Webserver") srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}) }() select { case <-exit: } log.Info("Stopping Webserver") ln.Close() }
func renderMarkdown(w http.ResponseWriter, contentName string) { md, ok := mdContent[contentName] if !ok { log.Fatal("Invalid Pagename:", contentName) } renderTemplate(w, "markdown", md) }
func StoreEntry(id string, entry *Entry) { err := storage.Update(func(tx *bolt.Tx) error { b, err := tx.CreateBucketIfNotExists(documentBucket) if err != nil { return err } oldTags, err := fetchOldTags(b, id) if err != nil { return err } for _, t := range oldTags { if !containsTag(t, entry.Tags) { if err := removeIDFromTag(tx, t, id); err != nil { return err } } } for _, t := range entry.Tags { if !containsTag(t, oldTags) { if err := addIDToTag(tx, t, id); err != nil { return err } } } entry.LastModified = time.Now() return b.Put([]byte(id), encodeData(entry)) }) if err != nil { log.Fatal(err) } }
func init() { ApplicationDir = path.Dir(os.Args[0]) Current = Config{ HttpAddr: ":80", DataDir: ApplicationDir, DefaultAnalyzer: "standard", } f, err := os.Open(path.Join(ApplicationDir, "config.json")) if err != nil { log.Fatal(err) } defer f.Close() decoder := json.NewDecoder(f) err = decoder.Decode(&Current) if err != nil { log.Fatal(err) } }
func DeleteEntry(id string, entry *Entry) { err := storage.Update(func(tx *bolt.Tx) error { for _, t := range entry.Tags { removeIDFromTag(tx, t, id) } b, _ := tx.CreateBucketIfNotExists(documentBucket) b.Delete([]byte(id)) return nil }) if err != nil { log.Fatal(err) } index.Delete(id) }
func LoadEntry(id string) (entry *Entry) { err := storage.View(func(tx *bolt.Tx) error { entry = new(Entry) b := tx.Bucket(documentBucket) if b == nil { return nil } decodeData(b.Get([]byte(id)), entry) return nil }) if err != nil { log.Fatal(err) } return entry }