repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
f08fc05
parent
7deb53b
author
Eric Bower
date
2023-08-17 16:43:27 +0000 UTC
refactor: move Cmd to own file
3 files changed,  +319, -315
M Makefile
+1, -1
1@@ -74,7 +74,7 @@ pgs-deploy: pgs-static pgs-site
2 	scp -R ./public/* hey@pgs.sh:/pgs-prod
3 .PHONY: pgs-site-deploy
4 
5-format:
6+fmt:
7 	go fmt ./...
8 .PHONY: format
9 
A pgs/cli.go
+318, -0
  1@@ -0,0 +1,318 @@
  2+package pgs
  3+
  4+import (
  5+	"errors"
  6+	"fmt"
  7+
  8+	"github.com/gliderlabs/ssh"
  9+	"github.com/picosh/pico/db"
 10+	"github.com/picosh/pico/shared"
 11+	"github.com/picosh/pico/shared/storage"
 12+	"github.com/picosh/pico/wish/send/utils"
 13+	"go.uber.org/zap"
 14+)
 15+
 16+func getHelpText(userName, projectName string) string {
 17+	helpStr := "commands: [help, stats, ls, rm, link, unlink, prune, retain, depends]\n\n"
 18+	sshCmdStr := fmt.Sprintf("ssh %s@pgs.sh", userName)
 19+	helpStr += fmt.Sprintf("`%s help`: prints this screen\n", sshCmdStr)
 20+	helpStr += fmt.Sprintf("`%s stats`: prints stats for user\n", sshCmdStr)
 21+	helpStr += fmt.Sprintf("`%s ls`: lists projects\n", sshCmdStr)
 22+	helpStr += fmt.Sprintf("`%s rm %s`: deletes `%s`\n", sshCmdStr, projectName, projectName)
 23+	helpStr += fmt.Sprintf("`%s link %s project-b`: symbolic link from `%s` to `project-b`\n", sshCmdStr, projectName, projectName)
 24+	helpStr += fmt.Sprintf(
 25+		"`%s unlink %s`: alias for `link %s %s`, which removes symbolic link for `%s`\n",
 26+		sshCmdStr, projectName, projectName, projectName, projectName,
 27+	)
 28+	helpStr += fmt.Sprintf("`%s prune %s`: removes all projects that match prefix `%s` and is not linked to another project\n", sshCmdStr, projectName, projectName)
 29+	helpStr += fmt.Sprintf("`%s retain %s`: alias for `prune` but retains the (3) most recently updated projects\n", sshCmdStr, projectName)
 30+	helpStr += fmt.Sprintf("`%s depends %s`: lists all projects linked to `%s`\n", sshCmdStr, projectName, projectName)
 31+	return helpStr
 32+}
 33+
 34+type Cmd struct {
 35+	user    *db.User
 36+	session ssh.Session
 37+	log     *zap.SugaredLogger
 38+	store   storage.ObjectStorage
 39+	dbpool  db.DB
 40+	write   bool
 41+}
 42+
 43+func (c *Cmd) rmProjectAssets(projectName string) error {
 44+	bucketName := shared.GetAssetBucketName(c.user.ID)
 45+	bucket, err := c.store.GetBucket(bucketName)
 46+	if err != nil {
 47+		return err
 48+	}
 49+
 50+	fileList, err := c.store.ListFiles(bucket, projectName+"/", true)
 51+	if err != nil {
 52+		return err
 53+	}
 54+
 55+	for _, file := range fileList {
 56+		intent := []byte(fmt.Sprintf("deleted (%s)\n", file.Name()))
 57+		if c.write {
 58+			err = c.store.DeleteFile(bucket, file.Name())
 59+			if err == nil {
 60+				_, _ = c.session.Write(intent)
 61+			} else {
 62+				return err
 63+			}
 64+		} else {
 65+			_, _ = c.session.Write(intent)
 66+		}
 67+	}
 68+	return nil
 69+}
 70+
 71+func (c *Cmd) help() {
 72+	_, _ = c.session.Write([]byte(getHelpText(c.user.Name, "project-a")))
 73+}
 74+
 75+func (c *Cmd) stats(maxSize int) error {
 76+	bucketName := shared.GetAssetBucketName(c.user.ID)
 77+	bucket, err := c.store.UpsertBucket(bucketName)
 78+	if err != nil {
 79+		return err
 80+	}
 81+
 82+	totalFileSize, err := c.store.GetBucketQuota(bucket)
 83+	if err != nil {
 84+		return err
 85+	}
 86+
 87+	projects, err := c.dbpool.FindProjectsByUser(c.user.ID)
 88+	if err != nil {
 89+		return err
 90+	}
 91+
 92+	str := "stats\n"
 93+	str += "=====\n"
 94+	str += fmt.Sprintf(
 95+		"space:\t\t%.4f/%.4fGB, %.4f%%\n",
 96+		shared.BytesToGB(int(totalFileSize)),
 97+		shared.BytesToGB(maxSize),
 98+		(float32(totalFileSize)/float32(maxSize))*100,
 99+	)
100+	str += fmt.Sprintf("projects:\t%d\n", len(projects))
101+	_, _ = c.session.Write([]byte(str))
102+
103+	return nil
104+}
105+
106+func (c *Cmd) ls() error {
107+	projects, err := c.dbpool.FindProjectsByUser(c.user.ID)
108+	if err != nil {
109+		return err
110+	}
111+
112+	if len(projects) == 0 {
113+		out := "no linked projects found\n"
114+		_, _ = c.session.Write([]byte(out))
115+	}
116+
117+	for _, project := range projects {
118+		out := fmt.Sprintf("%s (links to: %s)\n", project.Name, project.ProjectDir)
119+		if project.Name == project.ProjectDir {
120+			out = fmt.Sprintf("%s\n", project.Name)
121+		}
122+		_, _ = c.session.Write([]byte(out))
123+	}
124+
125+	return nil
126+}
127+
128+func (c *Cmd) unlink(projectName string) error {
129+	c.log.Infof("user (%s) running `unlink` command with (%s)", c.user.Name, projectName)
130+	project, err := c.dbpool.FindProjectByName(c.user.ID, projectName)
131+	if err != nil {
132+		return errors.Join(err, fmt.Errorf("project (%s) does not exit", projectName))
133+	}
134+
135+	err = c.dbpool.LinkToProject(c.user.ID, project.ID, project.Name, c.write)
136+	if err != nil {
137+		return err
138+	}
139+
140+	return nil
141+}
142+
143+func (c *Cmd) link(projectName, linkTo string) error {
144+	c.log.Infof("user (%s) running `link` command with (%s) (%s)", c.user.Name, projectName, linkTo)
145+
146+	projectDir := linkTo
147+	_, err := c.dbpool.FindProjectByName(c.user.ID, linkTo)
148+	if err != nil {
149+		e := fmt.Errorf("(%s) project doesn't exist", linkTo)
150+		return e
151+	}
152+
153+	project, err := c.dbpool.FindProjectByName(c.user.ID, projectName)
154+	projectID := ""
155+	if err == nil {
156+		projectID = project.ID
157+		c.log.Infof("user (%s) already has project (%s), updating ...", c.user.Name, projectName)
158+		err = c.dbpool.LinkToProject(c.user.ID, project.ID, projectDir, c.write)
159+		if err != nil {
160+			return err
161+		}
162+	} else {
163+		c.log.Infof("user (%s) has no project record (%s), creating ...", c.user.Name, projectName)
164+		if !c.write {
165+			out := fmt.Sprintf("(%s) cannot create a new project without `--write` permission, aborting ...\n", projectName)
166+			_, _ = c.session.Write([]byte(out))
167+			return nil
168+		}
169+		id, err := c.dbpool.InsertProject(c.user.ID, projectName, projectName)
170+		if err != nil {
171+			return err
172+		}
173+		projectID = id
174+	}
175+
176+	c.log.Infof("user (%s) linking (%s) to (%s) ...", c.user.Name, projectName, projectDir)
177+	err = c.dbpool.LinkToProject(c.user.ID, projectID, projectDir, c.write)
178+	if err != nil {
179+		return err
180+	}
181+
182+	out := fmt.Sprintf("(%s) might have orphaned assets, removing ...\n", projectName)
183+	_, _ = c.session.Write([]byte(out))
184+
185+	err = c.rmProjectAssets(projectName)
186+	if err != nil {
187+		return err
188+	}
189+
190+	out = fmt.Sprintf("(%s) now points to (%s)\n", projectName, linkTo)
191+	_, _ = c.session.Write([]byte(out))
192+	return nil
193+}
194+
195+func (c *Cmd) depends(projectName string) error {
196+	projects, err := c.dbpool.FindProjectLinks(c.user.ID, projectName)
197+	if err != nil {
198+		return err
199+	}
200+
201+	if len(projects) == 0 {
202+		out := fmt.Sprintf("no projects linked to this project (%s) found\n", projectName)
203+		_, _ = c.session.Write([]byte(out))
204+		return nil
205+	}
206+
207+	for _, project := range projects {
208+		out := fmt.Sprintf("%s (links to: %s)\n", project.Name, project.ProjectDir)
209+		if project.Name == project.ProjectDir {
210+			out = fmt.Sprintf("%s\n", project.Name)
211+		}
212+		_, _ = c.session.Write([]byte(out))
213+	}
214+
215+	return nil
216+}
217+
218+// delete all the projects and associated assets matching prefix
219+// but keep the latest N records
220+func (c *Cmd) prune(prefix string, keepNumLatest int) error {
221+	c.log.Infof("user (%s) running `clean` command for (%s)", c.user.Name, prefix)
222+	if prefix == "" || prefix == "*" {
223+		e := fmt.Errorf("must provide valid prefix")
224+		return e
225+	}
226+
227+	projects, err := c.dbpool.FindProjectsByPrefix(c.user.ID, prefix)
228+	if err != nil {
229+		return err
230+	}
231+
232+	rmProjects := []*db.Project{}
233+	for _, project := range projects {
234+		links, err := c.dbpool.FindProjectLinks(c.user.ID, project.Name)
235+		if err != nil {
236+			return err
237+		}
238+
239+		if len(links) == 0 {
240+			out := fmt.Sprintf("project (%s) is available to delete\n", project.Name)
241+			_, _ = c.session.Write([]byte(out))
242+			rmProjects = append(rmProjects, project)
243+		}
244+	}
245+
246+	goodbye := rmProjects
247+	if keepNumLatest > 0 {
248+		goodbye = rmProjects[:len(rmProjects)-keepNumLatest]
249+	}
250+
251+	for _, project := range goodbye {
252+		err = c.rmProjectAssets(project.Name)
253+		if err != nil {
254+			return err
255+		}
256+
257+		out := fmt.Sprintf("(%s) removing ...\n", project.Name)
258+		_, _ = c.session.Write([]byte(out))
259+
260+		if c.write {
261+			c.log.Infof("(%s) removing ...", project.Name)
262+			err = c.dbpool.RemoveProject(project.ID)
263+			if err != nil {
264+				return err
265+			}
266+		}
267+	}
268+
269+	return nil
270+}
271+
272+func (c *Cmd) rm(projectName string) error {
273+	c.log.Infof("user (%s) running `rm` command for (%s)", c.user.Name, projectName)
274+	project, err := c.dbpool.FindProjectByName(c.user.ID, projectName)
275+	if err == nil {
276+		c.log.Infof("found project (%s) (%s), checking dependencies ...", projectName, project.ID)
277+
278+		links, err := c.dbpool.FindProjectLinks(c.user.ID, projectName)
279+		if err != nil {
280+			return err
281+		}
282+
283+		if len(links) > 0 {
284+			e := fmt.Errorf("project (%s) has (%d) other projects linking to it, cannot delete project until they have been unlinked or removed, aborting ...", projectName, len(links))
285+			return e
286+		}
287+
288+		out := fmt.Sprintf("(%s) removing ...\n", project.Name)
289+		_, _ = c.session.Write([]byte(out))
290+		if c.write {
291+			c.log.Infof("(%s) removing ...", project.Name)
292+			err = c.dbpool.RemoveProject(project.ID)
293+			if err != nil {
294+				return err
295+			}
296+		}
297+	} else {
298+		e := fmt.Errorf("(%s) project not found for user (%s)", projectName, c.user.Name)
299+		return e
300+	}
301+
302+	err = c.rmProjectAssets(project.Name)
303+	return err
304+}
305+
306+func (c *Cmd) bail(err error) {
307+	if err == nil {
308+		return
309+	}
310+	c.log.Error(err)
311+	utils.ErrorHandler(c.session, err)
312+}
313+
314+func (c *Cmd) notice() {
315+	if !c.write {
316+		out := fmt.Sprintf("\nNOTICE: changes not commited, use `--write` to save operation\n")
317+		_, _ = c.session.Write([]byte(out))
318+	}
319+}
M pgs/wish.go
+0, -314
  1@@ -1,7 +1,6 @@
  2 package pgs
  3 
  4 import (
  5-	"errors"
  6 	"fmt"
  7 	"strings"
  8 
  9@@ -9,11 +8,8 @@ import (
 10 	"github.com/gliderlabs/ssh"
 11 	"github.com/picosh/pico/db"
 12 	uploadassets "github.com/picosh/pico/filehandlers/assets"
 13-	"github.com/picosh/pico/shared"
 14-	"github.com/picosh/pico/shared/storage"
 15 	"github.com/picosh/pico/wish/cms/util"
 16 	"github.com/picosh/pico/wish/send/utils"
 17-	"go.uber.org/zap"
 18 )
 19 
 20 func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) {
 21@@ -35,316 +31,6 @@ func getUser(s ssh.Session, dbpool db.DB) (*db.User, error) {
 22 	return user, nil
 23 }
 24 
 25-type ProjectDetails struct {
 26-	session ssh.Session
 27-	store   storage.ObjectStorage
 28-}
 29-
 30-func getHelpText(userName, projectName string) string {
 31-	helpStr := "commands: [help, stats, ls, rm, link, unlink, prune, retain, depends]\n\n"
 32-	sshCmdStr := fmt.Sprintf("ssh %s@pgs.sh", userName)
 33-	helpStr += fmt.Sprintf("`%s help`: prints this screen\n", sshCmdStr)
 34-	helpStr += fmt.Sprintf("`%s stats`: prints stats for user\n", sshCmdStr)
 35-	helpStr += fmt.Sprintf("`%s ls`: lists projects\n", sshCmdStr)
 36-	helpStr += fmt.Sprintf("`%s rm %s`: deletes `%s`\n", sshCmdStr, projectName, projectName)
 37-	helpStr += fmt.Sprintf("`%s link %s project-b`: symbolic link from `%s` to `project-b`\n", sshCmdStr, projectName, projectName)
 38-	helpStr += fmt.Sprintf(
 39-		"`%s unlink %s`: alias for `link %s %s`, which removes symbolic link for `%s`\n",
 40-		sshCmdStr, projectName, projectName, projectName, projectName,
 41-	)
 42-	helpStr += fmt.Sprintf("`%s prune %s`: removes all projects that match prefix `%s` and is not linked to another project\n", sshCmdStr, projectName, projectName)
 43-	helpStr += fmt.Sprintf("`%s retain %s`: alias for `prune` but retains the (3) most recently updated projects\n", sshCmdStr, projectName)
 44-	helpStr += fmt.Sprintf("`%s depends %s`: lists all projects linked to `%s`\n", sshCmdStr, projectName, projectName)
 45-	return helpStr
 46-}
 47-
 48-type Cmd struct {
 49-	user    *db.User
 50-	session ssh.Session
 51-	log     *zap.SugaredLogger
 52-	store   storage.ObjectStorage
 53-	dbpool  db.DB
 54-	write   bool
 55-}
 56-
 57-func (c *Cmd) rmProjectAssets(projectName string) error {
 58-	bucketName := shared.GetAssetBucketName(c.user.ID)
 59-	bucket, err := c.store.GetBucket(bucketName)
 60-	if err != nil {
 61-		return err
 62-	}
 63-
 64-	fileList, err := c.store.ListFiles(bucket, projectName+"/", true)
 65-	if err != nil {
 66-		return err
 67-	}
 68-
 69-	for _, file := range fileList {
 70-		intent := []byte(fmt.Sprintf("deleted (%s)\n", file.Name()))
 71-		if c.write {
 72-			err = c.store.DeleteFile(bucket, file.Name())
 73-			if err == nil {
 74-				_, _ = c.session.Write(intent)
 75-			} else {
 76-				return err
 77-			}
 78-		} else {
 79-			_, _ = c.session.Write(intent)
 80-		}
 81-	}
 82-	return nil
 83-}
 84-
 85-func (c *Cmd) help() {
 86-	_, _ = c.session.Write([]byte(getHelpText(c.user.Name, "project-a")))
 87-}
 88-
 89-func (c *Cmd) stats(maxSize int) error {
 90-	bucketName := shared.GetAssetBucketName(c.user.ID)
 91-	bucket, err := c.store.UpsertBucket(bucketName)
 92-	if err != nil {
 93-		return err
 94-	}
 95-
 96-	totalFileSize, err := c.store.GetBucketQuota(bucket)
 97-	if err != nil {
 98-		return err
 99-	}
100-
101-	projects, err := c.dbpool.FindProjectsByUser(c.user.ID)
102-	if err != nil {
103-		return err
104-	}
105-
106-	str := "stats\n"
107-	str += "=====\n"
108-	str += fmt.Sprintf(
109-		"space:\t\t%.4f/%.4fGB, %.4f%%\n",
110-		shared.BytesToGB(int(totalFileSize)),
111-		shared.BytesToGB(maxSize),
112-		(float32(totalFileSize)/float32(maxSize))*100,
113-	)
114-	str += fmt.Sprintf("projects:\t%d\n", len(projects))
115-	_, _ = c.session.Write([]byte(str))
116-
117-	return nil
118-}
119-
120-func (c *Cmd) ls() error {
121-	projects, err := c.dbpool.FindProjectsByUser(c.user.ID)
122-	if err != nil {
123-		return err
124-	}
125-
126-	if len(projects) == 0 {
127-		out := "no linked projects found\n"
128-		_, _ = c.session.Write([]byte(out))
129-	}
130-
131-	for _, project := range projects {
132-		out := fmt.Sprintf("%s (links to: %s)\n", project.Name, project.ProjectDir)
133-		if project.Name == project.ProjectDir {
134-			out = fmt.Sprintf("%s\n", project.Name)
135-		}
136-		_, _ = c.session.Write([]byte(out))
137-	}
138-
139-	return nil
140-}
141-
142-func (c *Cmd) unlink(projectName string) error {
143-	c.log.Infof("user (%s) running `unlink` command with (%s)", c.user.Name, projectName)
144-	project, err := c.dbpool.FindProjectByName(c.user.ID, projectName)
145-	if err != nil {
146-		return errors.Join(err, fmt.Errorf("project (%s) does not exit", projectName))
147-	}
148-
149-	err = c.dbpool.LinkToProject(c.user.ID, project.ID, project.Name, c.write)
150-	if err != nil {
151-		return err
152-	}
153-
154-	return nil
155-}
156-
157-func (c *Cmd) link(projectName, linkTo string) error {
158-	c.log.Infof("user (%s) running `link` command with (%s) (%s)", c.user.Name, projectName, linkTo)
159-
160-	projectDir := linkTo
161-	_, err := c.dbpool.FindProjectByName(c.user.ID, linkTo)
162-	if err != nil {
163-		e := fmt.Errorf("(%s) project doesn't exist", linkTo)
164-		return e
165-	}
166-
167-	project, err := c.dbpool.FindProjectByName(c.user.ID, projectName)
168-	projectID := ""
169-	if err == nil {
170-		projectID = project.ID
171-		c.log.Infof("user (%s) already has project (%s), updating ...", c.user.Name, projectName)
172-		err = c.dbpool.LinkToProject(c.user.ID, project.ID, projectDir, c.write)
173-		if err != nil {
174-			return err
175-		}
176-	} else {
177-		c.log.Infof("user (%s) has no project record (%s), creating ...", c.user.Name, projectName)
178-		if !c.write {
179-			out := fmt.Sprintf("(%s) cannot create a new project without `--write` permission, aborting ...\n", projectName)
180-			_, _ = c.session.Write([]byte(out))
181-			return nil
182-		}
183-		id, err := c.dbpool.InsertProject(c.user.ID, projectName, projectName)
184-		if err != nil {
185-			return err
186-		}
187-		projectID = id
188-	}
189-
190-	c.log.Infof("user (%s) linking (%s) to (%s) ...", c.user.Name, projectName, projectDir)
191-	err = c.dbpool.LinkToProject(c.user.ID, projectID, projectDir, c.write)
192-	if err != nil {
193-		return err
194-	}
195-
196-	out := fmt.Sprintf("(%s) might have orphaned assets, removing ...\n", projectName)
197-	_, _ = c.session.Write([]byte(out))
198-
199-	err = c.rmProjectAssets(projectName)
200-	if err != nil {
201-		return err
202-	}
203-
204-	out = fmt.Sprintf("(%s) now points to (%s)\n", projectName, linkTo)
205-	_, _ = c.session.Write([]byte(out))
206-	return nil
207-}
208-
209-func (c *Cmd) depends(projectName string) error {
210-	projects, err := c.dbpool.FindProjectLinks(c.user.ID, projectName)
211-	if err != nil {
212-		return err
213-	}
214-
215-	if len(projects) == 0 {
216-		out := fmt.Sprintf("no projects linked to this project (%s) found\n", projectName)
217-		_, _ = c.session.Write([]byte(out))
218-		return nil
219-	}
220-
221-	for _, project := range projects {
222-		out := fmt.Sprintf("%s (links to: %s)\n", project.Name, project.ProjectDir)
223-		if project.Name == project.ProjectDir {
224-			out = fmt.Sprintf("%s\n", project.Name)
225-		}
226-		_, _ = c.session.Write([]byte(out))
227-	}
228-
229-	return nil
230-}
231-
232-// delete all the projects and associated assets matching prefix
233-// but keep the latest N records
234-func (c *Cmd) prune(prefix string, keepNumLatest int) error {
235-	c.log.Infof("user (%s) running `clean` command for (%s)", c.user.Name, prefix)
236-	if prefix == "" || prefix == "*" {
237-		e := fmt.Errorf("must provide valid prefix")
238-		return e
239-	}
240-
241-	projects, err := c.dbpool.FindProjectsByPrefix(c.user.ID, prefix)
242-	if err != nil {
243-		return err
244-	}
245-
246-	rmProjects := []*db.Project{}
247-	for _, project := range projects {
248-		links, err := c.dbpool.FindProjectLinks(c.user.ID, project.Name)
249-		if err != nil {
250-			return err
251-		}
252-
253-		if len(links) == 0 {
254-			out := fmt.Sprintf("project (%s) is available to delete\n", project.Name)
255-			_, _ = c.session.Write([]byte(out))
256-			rmProjects = append(rmProjects, project)
257-		}
258-	}
259-
260-	goodbye := rmProjects
261-	if keepNumLatest > 0 {
262-		goodbye = rmProjects[:len(rmProjects)-keepNumLatest]
263-	}
264-
265-	for _, project := range goodbye {
266-		err = c.rmProjectAssets(project.Name)
267-		if err != nil {
268-			return err
269-		}
270-
271-		out := fmt.Sprintf("(%s) removing ...\n", project.Name)
272-		_, _ = c.session.Write([]byte(out))
273-
274-		if c.write {
275-			c.log.Infof("(%s) removing ...", project.Name)
276-			err = c.dbpool.RemoveProject(project.ID)
277-			if err != nil {
278-				return err
279-			}
280-		}
281-	}
282-
283-	return nil
284-}
285-
286-func (c *Cmd) rm(projectName string) error {
287-	c.log.Infof("user (%s) running `rm` command for (%s)", c.user.Name, projectName)
288-	project, err := c.dbpool.FindProjectByName(c.user.ID, projectName)
289-	if err == nil {
290-		c.log.Infof("found project (%s) (%s), checking dependencies ...", projectName, project.ID)
291-
292-		links, err := c.dbpool.FindProjectLinks(c.user.ID, projectName)
293-		if err != nil {
294-			return err
295-		}
296-
297-		if len(links) > 0 {
298-			e := fmt.Errorf("project (%s) has (%d) other projects linking to it, cannot delete project until they have been unlinked or removed, aborting ...", projectName, len(links))
299-			return e
300-		}
301-
302-		out := fmt.Sprintf("(%s) removing ...\n", project.Name)
303-		_, _ = c.session.Write([]byte(out))
304-		if c.write {
305-			c.log.Infof("(%s) removing ...", project.Name)
306-			err = c.dbpool.RemoveProject(project.ID)
307-			if err != nil {
308-				return err
309-			}
310-		}
311-	} else {
312-		e := fmt.Errorf("(%s) project not found for user (%s)", projectName, c.user.Name)
313-		return e
314-	}
315-
316-	err = c.rmProjectAssets(project.Name)
317-	return err
318-}
319-
320-func (c *Cmd) bail(err error) {
321-	if err == nil {
322-		return
323-	}
324-	c.log.Error(err)
325-	utils.ErrorHandler(c.session, err)
326-}
327-
328-func (c *Cmd) notice() {
329-	if !c.write {
330-		out := fmt.Sprintf("\nNOTICE: changes not commited, use `--write` to save operation\n")
331-		_, _ = c.session.Write([]byte(out))
332-	}
333-}
334-
335 func WishMiddleware(handler *uploadassets.UploadAssetHandler) wish.Middleware {
336 	dbpool := handler.DBPool
337 	log := handler.Cfg.Logger