func handleImageDetails(ctx context.Context, w http.ResponseWriter, r *http.Request) { db := sq.DB(ctx) img, err := ImageByID(db, web.Args(ctx).ByIndex(0)) switch err { case nil: // all good case sq.ErrNotFound: web.StdHTMLResp(w, http.StatusNotFound) return default: log.Error("cannot get image", "image", web.Args(ctx).ByIndex(0), "error", err.Error()) web.StdJSONResp(w, http.StatusInternalServerError) return } img.Tags, err = ImageTags(db, img.ImageID) if err != nil { log.Error("cannot get image", "image", web.Args(ctx).ByIndex(0), "error", err.Error()) web.StdJSONResp(w, http.StatusInternalServerError) return } web.JSONResp(w, img, http.StatusOK) }
func handleGetNote(ctx context.Context, w http.ResponseWriter, r *http.Request) { var note Note key := datastore.NewKey(ctx, "Note", web.Args(ctx).ByIndex(0), 0, nil) if err := datastore.Get(ctx, key, ¬e); err != nil { log.Debug("cannot get note", "noteId", web.Args(ctx).ByIndex(0), "error", err.Error()) // XXX - what about not found? web.StdJSONResp(w, http.StatusInternalServerError) return } web.JSONResp(w, note, http.StatusOK) }
func HandleDisplayNote(ctx context.Context, w http.ResponseWriter, r *http.Request) { args := web.Args(ctx) note, err := NoteByID(pg.DB(ctx), stoint(args.ByIndex(0))) /* if err != nil { if err == pg.ErrNotFound { web.StdJSONErr(w, http.StatusNotFound) } else { log.Printf("cannot get %q note: %s", args.ByIndex(0), err) web.StdJSONErr(w, http.StatusInternalServerError) } return } if !note.IsPublic { acc, ok := auth.Authenticated(pg.DB(ctx), r) if !ok || acc.AccountID != note.OwnerID { web.StdJSONErr(w, http.StatusUnauthorized) return } } */ fmt.Println(err) tmpl.Render(w, "note_details.html", note) }
func HandlePasteUpdate(ctx context.Context, w http.ResponseWriter, r *http.Request) { var input struct { Content string } if err := json.NewDecoder(r.Body).Decode(&input); err != nil { web.StdJSONResp(w, http.StatusBadRequest) return } if input.Content == "" { web.JSONErr(w, `"Content" is required"`, http.StatusBadRequest) return } pid, _ := strconv.ParseInt(web.Args(ctx).ByIndex(0), 10, 64) db := pg.DB(ctx) paste, err := UpdatePaste(db, Paste{ ID: pid, Content: input.Content, }) switch err { case nil: web.JSONResp(w, paste, http.StatusOK) case pg.ErrNotFound: web.StdJSONResp(w, http.StatusNotFound) default: log.Printf("cannot update paste %d: %s", pid, err) web.StdJSONResp(w, http.StatusInternalServerError) } }
func handleTopicDetails(ctx context.Context, w http.ResponseWriter, r *http.Request) { db := pg.DB(ctx) tid, _ := strconv.ParseInt(web.Args(ctx).ByIndex(0), 10, 64) topic, err := TopicByID(db, tid) switch err { case nil: // all good case pg.ErrNotFound: respond404(w, r) return default: log.Error("cannot get topic by ID", "topic", web.Args(ctx).ByIndex(0), "error", err.Error()) respond500(w, r) return } page, _ := strconv.ParseInt(r.URL.Query().Get("page"), 10, 64) comments, err := Comments(db, CommentsOpts{ Offset: (page - 1) * 200, Limit: 200, TopicID: topic.TopicID, }) if err != nil { log.Error("cannot get comments for topic", "topic", fmt.Sprint(topic.TopicID), "error", err.Error()) respond500(w, r) return } context := struct { Topic *Topic Comments []*Comment }{ Topic: topic, Comments: comments, } render(w, "topic_details.tmpl", context) }
// handlePublicKey return public RSA key for requested key ID. func handlePublicKey(ctx context.Context, w http.ResponseWriter, r *http.Request) { kid := web.Args(ctx).ByIndex(0) key, ok := keys.Manager(ctx).KeyByID(kid) if !ok { web.JSONErr(w, "key not found", http.StatusNotFound) return } w.Header().Set("Content-Type", "application/pkix-crl") w.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s.pub"`, kid)) fmt.Fprint(w, key) }
func handleGetPaste(ctx context.Context, w http.ResponseWriter, r *http.Request) { pid := web.Args(ctx).ByIndex(0) db.mu.Lock() b, ok := db.mem[pid] db.mu.Unlock() if !ok { w.WriteHeader(http.StatusNotFound) fmt.Fprintln(w, "not found") } else { w.Write(b) } }
func HandlePasteDetails(ctx context.Context, w http.ResponseWriter, r *http.Request) { pid, _ := strconv.ParseInt(web.Args(ctx).ByIndex(0), 10, 64) db := pg.DB(ctx) paste, err := PasteByID(db, pid) switch err { case nil: web.JSONResp(w, paste, http.StatusOK) case pg.ErrNotFound: web.StdJSONResp(w, http.StatusNotFound) default: log.Printf("cannot get paste %d: %s", pid, err) web.StdJSONResp(w, http.StatusInternalServerError) } }
func HandleUpdateNote(ctx context.Context, w http.ResponseWriter, r *http.Request) { var input Note if err := json.NewDecoder(r.Body).Decode(&input); err != nil { web.JSONErr(w, err.Error(), http.StatusBadRequest) return } if errs := validateNote(&input); len(errs) > 0 { web.JSONErrs(w, errs, http.StatusBadRequest) return } tx, err := pg.DB(ctx).Beginx() if err != nil { log.Printf("cannot start transaction: %s", err) web.StdJSONErr(w, http.StatusInternalServerError) return } defer tx.Rollback() acc, ok := auth.AuthRequired(tx, w, r) if !ok { return } noteID := stoint(web.Args(ctx).ByIndex(0)) if ok, err := IsNoteOwner(tx, noteID, acc.AccountID); err != nil { log.Printf("cannot check %d note owner: %s", noteID, err) web.StdJSONErr(w, http.StatusInternalServerError) return } else if !ok { web.JSONErr(w, "you are not owner of this note", http.StatusUnauthorized) return } note, err := UpdateNote(tx, input) if err != nil { log.Printf("cannot update %d note: %s", noteID, err) web.StdJSONErr(w, http.StatusInternalServerError) return } if err := tx.Commit(); err != nil { log.Printf("cannot commit transaction: %s", err) web.StdJSONErr(w, http.StatusInternalServerError) return } web.JSONResp(w, note, http.StatusOK) }
func HandleDeleteNote(ctx context.Context, w http.ResponseWriter, r *http.Request) { tx, err := pg.DB(ctx).Beginx() if err != nil { log.Printf("cannot start transaction: %s", err) web.StdJSONErr(w, http.StatusInternalServerError) return } defer tx.Rollback() acc, ok := auth.AuthRequired(tx, w, r) if !ok { return } noteID := stoint(web.Args(ctx).ByIndex(0)) if ok, err := IsNoteOwner(tx, noteID, acc.AccountID); err != nil { if err == pg.ErrNotFound { web.StdJSONErr(w, http.StatusNotFound) } else { log.Printf("cannot check %d note owner: %s", noteID, err) web.StdJSONErr(w, http.StatusInternalServerError) } return } else if !ok { web.JSONErr(w, "you are not owner of this note", http.StatusUnauthorized) return } if err := DeleteNote(tx, noteID); err != nil { log.Printf("cannot delete %d note: %s", noteID, err) web.StdJSONErr(w, http.StatusInternalServerError) return } if err := tx.Commit(); err != nil { log.Printf("cannot commit transaction: %s", err) web.StdJSONErr(w, http.StatusInternalServerError) return } w.WriteHeader(http.StatusGone) }
func handleCreateComment(ctx context.Context, w http.ResponseWriter, r *http.Request) { input := struct { Content string }{ Content: r.FormValue("content"), } var errs []string if len(input.Content) == 0 { errs = append(errs, `"content" is required`) } if len(errs) != 0 { w.WriteHeader(http.StatusBadRequest) fmt.Fprintf(w, "%v", errs) return } db := pg.DB(ctx) tid, _ := strconv.ParseInt(web.Args(ctx).ByIndex(0), 10, 64) c, err := CreateComment(db, Comment{ TopicID: tid, Content: input.Content, AuthorID: 1, }) switch err { case nil: // ok default: log.Error("cannot create comment", "topic", fmt.Sprint(tid), "error", err.Error()) respond500(w, r) return } http.Redirect(w, r, fmt.Sprintf("/t/%d", c.TopicID), http.StatusSeeOther) }
func handlePutPaste(ctx context.Context, w http.ResponseWriter, r *http.Request) { pid := web.Args(ctx).ByIndex(0) handleStorePaste(pid, w, r) }
func handleServeImage(ctx context.Context, w http.ResponseWriter, r *http.Request) { img, err := ImageByID(sq.DB(ctx), web.Args(ctx).ByIndex(0)) switch err { case nil: // all good case sq.ErrNotFound: web.StdJSONResp(w, http.StatusNotFound) return default: log.Error("cannot get object", "object", web.Args(ctx).ByIndex(0), "error", err.Error()) web.StdJSONResp(w, http.StatusInternalServerError) return } if web.CheckLastModified(w, r, img.Created) { return } fs := FileStore(ctx) fd, err := fs.Read(img.Created.Year(), img.ImageID) if err != nil { log.Error("cannot read image file", "image", img.ImageID, "error", err.Error()) web.StdJSONResp(w, http.StatusInternalServerError) return } defer fd.Close() w.Header().Set("X-Image-ID", img.ImageID) w.Header().Set("X-Image-Width", fmt.Sprint(img.Width)) w.Header().Set("X-Image-Height", fmt.Sprint(img.Height)) w.Header().Set("X-Image-Created", img.Created.Format(time.RFC3339)) w.Header().Set("Content-Type", "image/jpeg") if r.URL.Query().Get("resize") == "" { io.Copy(w, fd) return } image, err := jpeg.Decode(fd) if err != nil { log.Error("cannot read image file", "image", img.ImageID, "error", err.Error()) web.StdJSONResp(w, http.StatusInternalServerError) return } var width, height int if _, err := fmt.Sscanf(r.URL.Query().Get("resize"), "%dx%d", &width, &height); err != nil { log.Error("cannot resize image", "image", img.ImageID, "error", err.Error()) } else { switch img.Orientation { case 1: // all good case 3: image = imaging.Rotate180(image) case 8: image = imaging.Rotate90(image) case 6: image = imaging.Rotate270(image) default: log.Debug("unknown image orientation", "decoder", "EXIF", "image", img.ImageID, "value", fmt.Sprint(img.Orientation)) } image = imaging.Fill(image, width, height, imaging.Center, imaging.Linear) } imaging.Encode(w, image, imaging.JPEG) }
func handleTagImage(ctx context.Context, w http.ResponseWriter, r *http.Request) { var input struct { Name string Value string } if err := json.NewDecoder(r.Body).Decode(&input); err != nil { web.JSONErr(w, err.Error(), http.StatusBadRequest) return } var errs []string if input.Name == "" { errs = append(errs, `"name" is required`) } if input.Value == "" { errs = append(errs, `"value" is required`) } if len(errs) != 0 { web.JSONErrs(w, errs, http.StatusBadRequest) return } db := sq.DB(ctx) img, err := ImageByID(db, web.Args(ctx).ByIndex(0)) switch err { case nil: // all good case sq.ErrNotFound: web.JSONErr(w, "parent image does not exist", http.StatusBadRequest) return default: log.Error("database error", "image", web.Args(ctx).ByIndex(0), "error", err.Error()) web.StdJSONResp(w, http.StatusInternalServerError) return } tag, err := CreateTag(db, Tag{ ImageID: img.ImageID, Name: input.Name, Value: input.Value, }) switch err { case nil: // all good, update storage meta case sq.ErrConflict: web.JSONResp(w, tag, http.StatusOK) return default: log.Error("cannot create object", "error", err.Error()) web.StdJSONResp(w, http.StatusInternalServerError) return } if img.Tags, err = ImageTags(db, img.ImageID); err != nil { log.Error("cannot get image tags", "image", img.ImageID, "error", err.Error()) web.StdJSONResp(w, http.StatusInternalServerError) return } fs := FileStore(ctx) if err := fs.PutMeta(img); err != nil { log.Error("cannot store image metadata", "image", img.ImageID, "error", err.Error()) web.StdJSONResp(w, http.StatusInternalServerError) return } web.JSONResp(w, tag, http.StatusCreated) }