mirror of
https://codeberg.org/scip/ephemerup.git
synced 2025-12-17 04:30:57 +01:00
changes:
- added unit tests
- put all subcmds into one file
- use io.Writer for output, better for testing
- added upload form support
- added api docs
- generalized db engine
- added mail notify support for forms
- enhanced server/SetupAuthStore() to also look up form ids
- added form template (put into .go file by Makefile
- renamed project
This commit is contained in:
@@ -25,8 +25,9 @@ import (
|
||||
"github.com/imroc/req/v3"
|
||||
"github.com/jarcoal/httpmock"
|
||||
"github.com/schollz/progressbar/v3"
|
||||
"github.com/tlinden/cenophane/common"
|
||||
"github.com/tlinden/cenophane/upctl/cfg"
|
||||
"github.com/tlinden/ephemerup/common"
|
||||
"github.com/tlinden/ephemerup/upctl/cfg"
|
||||
"io"
|
||||
"mime"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -49,8 +50,11 @@ type ListParams struct {
|
||||
Apicontext string `json:"apicontext"`
|
||||
}
|
||||
|
||||
const Maxwidth = 10
|
||||
const Maxwidth = 12
|
||||
|
||||
/*
|
||||
Create a new request object for outgoing queries
|
||||
*/
|
||||
func Setup(c *cfg.Config, path string) *Request {
|
||||
client := req.C()
|
||||
if c.Debug {
|
||||
@@ -86,9 +90,12 @@ func Setup(c *cfg.Config, path string) *Request {
|
||||
}
|
||||
|
||||
return &Request{Url: c.Endpoint + path, R: R}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Iterate over args, considering the elements are filenames, and add
|
||||
them to the request.
|
||||
*/
|
||||
func GatherFiles(rq *Request, args []string) error {
|
||||
for _, file := range args {
|
||||
info, err := os.Stat(file)
|
||||
@@ -120,9 +127,48 @@ func GatherFiles(rq *Request, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func UploadFiles(c *cfg.Config, args []string) error {
|
||||
/*
|
||||
Check HTTP Response Code and validate JSON status output, if
|
||||
any. Turns'em into a regular error
|
||||
*/
|
||||
func HandleResponse(c *cfg.Config, resp *req.Response) error {
|
||||
// we expect a json response, extract the error, if any
|
||||
r := Response{}
|
||||
|
||||
if c.Debug {
|
||||
trace := resp.Request.TraceInfo()
|
||||
fmt.Println(trace.Blame())
|
||||
fmt.Println("----------")
|
||||
fmt.Println(trace)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(resp.String()), &r); err != nil {
|
||||
// text output!
|
||||
r.Message = resp.String()
|
||||
}
|
||||
|
||||
if !resp.IsSuccessState() {
|
||||
return fmt.Errorf("bad response: %s (%s)", resp.Status, r.Message)
|
||||
}
|
||||
|
||||
if !r.Success {
|
||||
if len(r.Message) == 0 {
|
||||
if resp.Err != nil {
|
||||
return resp.Err
|
||||
} else {
|
||||
return errors.New("Unknown error")
|
||||
}
|
||||
} else {
|
||||
return errors.New(r.Message)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func UploadFiles(w io.Writer, c *cfg.Config, args []string) error {
|
||||
// setup url, req.Request, timeout handling etc
|
||||
rq := Setup(c, "/file/")
|
||||
rq := Setup(c, "/uploads")
|
||||
|
||||
// collect files to upload from @argv
|
||||
if err := GatherFiles(rq, args); err != nil {
|
||||
@@ -150,47 +196,15 @@ func UploadFiles(c *cfg.Config, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return RespondExtended(resp)
|
||||
if err := HandleResponse(c, resp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return RespondExtended(w, resp)
|
||||
}
|
||||
|
||||
func HandleResponse(c *cfg.Config, resp *req.Response) error {
|
||||
// we expect a json response, extract the error, if any
|
||||
r := Response{}
|
||||
|
||||
if err := json.Unmarshal([]byte(resp.String()), &r); err != nil {
|
||||
// text output!
|
||||
r.Message = resp.String()
|
||||
}
|
||||
|
||||
if c.Debug {
|
||||
trace := resp.Request.TraceInfo()
|
||||
fmt.Println(trace.Blame())
|
||||
fmt.Println("----------")
|
||||
fmt.Println(trace)
|
||||
}
|
||||
|
||||
if !r.Success {
|
||||
if len(r.Message) == 0 {
|
||||
if resp.Err != nil {
|
||||
return resp.Err
|
||||
} else {
|
||||
return errors.New("Unknown error")
|
||||
}
|
||||
} else {
|
||||
return errors.New(r.Message)
|
||||
}
|
||||
}
|
||||
|
||||
// all right
|
||||
if r.Message != "" {
|
||||
fmt.Println(r.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func List(c *cfg.Config, args []string) error {
|
||||
rq := Setup(c, "/list/")
|
||||
func List(w io.Writer, c *cfg.Config, args []string) error {
|
||||
rq := Setup(c, "/uploads")
|
||||
|
||||
params := &ListParams{Apicontext: c.Apicontext}
|
||||
resp, err := rq.R.
|
||||
@@ -201,12 +215,16 @@ func List(c *cfg.Config, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return RespondTable(resp)
|
||||
if err := HandleResponse(c, resp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return UploadsRespondTable(w, resp)
|
||||
}
|
||||
|
||||
func Delete(c *cfg.Config, args []string) error {
|
||||
func Delete(w io.Writer, c *cfg.Config, args []string) error {
|
||||
for _, id := range args {
|
||||
rq := Setup(c, "/file/"+id+"/")
|
||||
rq := Setup(c, "/uploads/"+id+"/")
|
||||
|
||||
resp, err := rq.R.Delete(rq.Url)
|
||||
|
||||
@@ -218,47 +236,67 @@ func Delete(c *cfg.Config, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Upload %s successfully deleted.\n", id)
|
||||
fmt.Fprintf(w, "Upload %s successfully deleted.\n", id)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Describe(c *cfg.Config, args []string) error {
|
||||
func Describe(w io.Writer, c *cfg.Config, args []string) error {
|
||||
if len(args) == 0 {
|
||||
return errors.New("No id provided!")
|
||||
}
|
||||
|
||||
id := args[0] // we describe only 1 object
|
||||
|
||||
rq := Setup(c, "/upload/"+id+"/")
|
||||
rq := Setup(c, "/uploads/"+id)
|
||||
resp, err := rq.R.Get(rq.Url)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return RespondExtended(resp)
|
||||
}
|
||||
|
||||
func Download(c *cfg.Config, args []string) error {
|
||||
id := args[0]
|
||||
|
||||
// progres bar
|
||||
bar := progressbar.Default(100)
|
||||
|
||||
callback := func(info req.DownloadInfo) {
|
||||
if info.Response.Response != nil {
|
||||
bar.Add(1)
|
||||
}
|
||||
if err := HandleResponse(c, resp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return RespondExtended(w, resp)
|
||||
}
|
||||
|
||||
func Download(w io.Writer, c *cfg.Config, args []string) error {
|
||||
if len(args) == 0 {
|
||||
return errors.New("No id provided!")
|
||||
}
|
||||
|
||||
id := args[0]
|
||||
|
||||
rq := Setup(c, "/uploads/"+id+"/file")
|
||||
|
||||
if !c.Silent {
|
||||
// progres bar
|
||||
bar := progressbar.Default(100)
|
||||
|
||||
callback := func(info req.DownloadInfo) {
|
||||
if info.Response.Response != nil {
|
||||
bar.Add(1)
|
||||
}
|
||||
}
|
||||
|
||||
rq.R.SetDownloadCallback(callback)
|
||||
}
|
||||
|
||||
rq := Setup(c, "/file/"+id+"/")
|
||||
resp, err := rq.R.
|
||||
SetOutputFile(id).
|
||||
SetDownloadCallback(callback).
|
||||
Get(rq.Url)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !resp.IsSuccessState() {
|
||||
return fmt.Errorf("bad response: %s", resp.Status)
|
||||
}
|
||||
|
||||
_, params, err := mime.ParseMediaType(resp.Header.Get("Content-Disposition"))
|
||||
if err != nil {
|
||||
os.Remove(id)
|
||||
@@ -278,7 +316,34 @@ func Download(c *cfg.Config, args []string) error {
|
||||
return fmt.Errorf("\nUnable to rename file: " + err.Error())
|
||||
}
|
||||
|
||||
fmt.Printf("%s successfully downloaded to file %s.", id, cleanfilename)
|
||||
fmt.Fprintf(w, "%s successfully downloaded to file %s.", id, cleanfilename)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/**** Forms stuff ****/
|
||||
func CreateForm(w io.Writer, c *cfg.Config) error {
|
||||
// setup url, req.Request, timeout handling etc
|
||||
rq := Setup(c, "/forms")
|
||||
|
||||
// actual post w/ settings
|
||||
resp, err := rq.R.
|
||||
SetFormData(map[string]string{
|
||||
"expire": c.Expire,
|
||||
"description": c.Description,
|
||||
"notify": c.Notify,
|
||||
}).
|
||||
Post(rq.Url)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := HandleResponse(c, resp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return RespondExtended(w, resp)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user