コード例 #1
0
ファイル: handlers.go プロジェクト: husio/apps
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)
}
コード例 #2
0
ファイル: note.go プロジェクト: husio/apps
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, &note); 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)
}
コード例 #3
0
ファイル: handlers.go プロジェクト: husio/apps
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)
}
コード例 #4
0
ファイル: handlers.go プロジェクト: husio/apps
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)
	}
}
コード例 #5
0
ファイル: handlers.go プロジェクト: husio/apps
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)
}
コード例 #6
0
ファイル: handlers.go プロジェクト: husio/apps
// 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)
}
コード例 #7
0
ファイル: smallpaste.go プロジェクト: husio/apps
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)
	}
}
コード例 #8
0
ファイル: handlers.go プロジェクト: husio/apps
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)
	}
}
コード例 #9
0
ファイル: handlers.go プロジェクト: husio/apps
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)
}
コード例 #10
0
ファイル: handlers.go プロジェクト: husio/apps
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)
}
コード例 #11
0
ファイル: handlers.go プロジェクト: husio/apps
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)
}
コード例 #12
0
ファイル: smallpaste.go プロジェクト: husio/apps
func handlePutPaste(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	pid := web.Args(ctx).ByIndex(0)
	handleStorePaste(pid, w, r)
}
コード例 #13
0
ファイル: handlers.go プロジェクト: husio/apps
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)
}
コード例 #14
0
ファイル: handlers.go プロジェクト: husio/apps
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)
}