func (r *Repo) loop() { for { select { case doc := <-r.syncCh: _, ok := r.docs[doc.ID] r.docs[doc.ID] = doc if !ok { go func() { r.nextCh <- doc.ID }() } case id := <-r.nextCh: doc := r.docs[id] delete(r.docs, doc.ID) doc2, err := data.GetDocument(bson.ObjectIdHex(id)) if err != nil { panic(err) } doc2.Content = string(doc.Blob) err = doc2.Put() if err != nil { panic(err) } } } }
func ServeDocument(w http.ResponseWriter, r *http.Request) { ctx := GetContext(r) if ctx.Account == nil { http.Redirect(w, r, "/login", http.StatusSeeOther) return } acc := ctx.Account vars := mux.Vars(r) idStr := vars["id"] if !bson.IsObjectIdHex(idStr) { ServeNotFound(w, r) return } id := bson.ObjectIdHex(idStr) doc, err := data.GetDocument(id) catch(r, err) if doc == nil || doc.Deleted { ServeNotFound(w, r) return } mem, err := data.GetMemberProjectAccount(doc.ProjectID, acc.ID) catch(r, err) if mem == nil { ServeForbidden(w, r) return } prj, err := doc.Project() catch(r, err) org, err := prj.Organization() catch(r, err) token := jwt.New(jwt.SigningMethodHS256) token.Claims["accountID"] = ctx.Account.ID.Hex() token.Claims["documentID"] = doc.ID.Hex() token.Claims["expires"] = time.Now().Add(time.Minute * 15).Unix() tokenString, err := token.SignedString([]byte(os.Getenv("SECRET"))) catch(r, err) w.Header().Set("Content-Type", mime.TypeByExtension(".html")) ServeHTMLTemplate(w, r, tplDocumentView, struct { Context *Context Organization *data.Organization Project *data.Project Document *data.Document Token string }{ Context: ctx, Organization: org, Project: prj, Document: doc, Token: tokenString, }) }
func HandleDocumentPublish(w http.ResponseWriter, r *http.Request) { ctx := GetContext(r) if ctx.Account == nil { http.Redirect(w, r, "/login", http.StatusSeeOther) return } vars := mux.Vars(r) idStr := vars["id"] if !bson.IsObjectIdHex(idStr) { ServeNotFound(w, r) return } id := bson.ObjectIdHex(idStr) doc, err := data.GetDocument(id) catch(r, err) if doc == nil || doc.Deleted { ServeNotFound(w, r) return } prj, err := doc.Project() catch(r, err) if prj.OwnerID != ctx.Account.ID { ServeForbidden(w, r) return } if doc.Published { http.Redirect(w, r, "/documents/"+doc.ID.Hex(), http.StatusSeeOther) return } doc.Published = true doc.PublishedAt = time.Now() doc.ShortID, err = data.GenerateShortID() catch(r, err) err = doc.Put() for mgo.IsDup(err) { doc.ShortID, err = data.GenerateShortID() catch(r, err) err = doc.Put() } http.Redirect(w, r, "/documents/"+doc.ID.Hex(), http.StatusSeeOther) }
func (r *Repo) Get(id string) (*hub.Doc, error) { if !bson.IsObjectIdHex(id) { return nil, ErrBadID } doc, err := data.GetDocument(bson.ObjectIdHex(id)) if err != nil { return nil, err } if doc == nil { return nil, nil } return &hub.Doc{ ID: doc.ID.Hex(), Blob: ot.Blob(doc.Content), }, nil }
func HandleDocumentUndelete(w http.ResponseWriter, r *http.Request) { ctx := GetContext(r) if ctx.Account == nil { http.Redirect(w, r, "/login", http.StatusSeeOther) return } vars := mux.Vars(r) idStr := vars["id"] if !bson.IsObjectIdHex(idStr) { ServeNotFound(w, r) return } id := bson.ObjectIdHex(idStr) doc, err := data.GetDocument(id) catch(r, err) if doc == nil { ServeNotFound(w, r) return } prj, err := doc.Project() catch(r, err) if prj.OwnerID != ctx.Account.ID { ServeForbidden(w, r) return } doc.Deleted = false doc.DeletedAt = time.Time{} err = doc.Put() catch(r, err) http.Redirect(w, r, "/projects/"+prj.ID.Hex(), http.StatusSeeOther) }