Bläddra i källkod

uploads seems working.

master
sp 4 år sedan
förälder
incheckning
5f47d33299
11 ändrade filer med 506 tillägg och 145 borttagningar
  1. +1
    -0
      .idea/SFM_Loan_RestApi.iml
  2. +99
    -11
      UploadsOnDisk.go
  3. +30
    -0
      apiV1UploadAnalysis.go
  4. +95
    -0
      apiV1UploadAsImage.go
  5. +31
    -0
      apiV1UploadList.go
  6. +63
    -0
      apiV1UploadThumb.go
  7. +28
    -134
      apiV1Uploads.go
  8. +109
    -0
      apiV1UploadsAsPdf.go
  9. +12
    -0
      apiv1.go
  10. Binär
      assets/thumb_file_icon.webp
  11. +38
    -0
      fileUtil.go

+ 1
- 0
.idea/SFM_Loan_RestApi.iml Visa fil

<module type="WEB_MODULE" version="4"> <module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" /> <component name="Go" enabled="true" />
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$USER_HOME$/GolandProjects/SFM-loan" />
<content url="file://$MODULE_DIR$" /> <content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />

+ 99
- 11
UploadsOnDisk.go Visa fil



import ( import (
"biukop.com/sfm/loan" "biukop.com/sfm/loan"
"context"
"errors" "errors"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"io/ioutil" "io/ioutil"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"sync"
"time"
) )


type uploadsOnDisk struct { type uploadsOnDisk struct {
return m.convertExcelTo("jpg") return m.convertExcelTo("jpg")
} }


var libreOfficeMutex sync.Mutex // make sure we only have one libreoffice running at a time
func (m *uploadsOnDisk) convertExcelTo(format string) (e error) { func (m *uploadsOnDisk) convertExcelTo(format string) (e error) {
if format != "pdf" && format != "jpg" { if format != "pdf" && format != "jpg" {
e = errors.New("unsupported format")
e = errors.New("convert excel to unsupported format " + format)
return return
} }


} }
defer os.RemoveAll(dir) defer os.RemoveAll(dir)


cmd := exec.Command("libreoffice", "--convert-to", format, "--outdir", dir, m.filePath())
strCmd := cmd.String()
log.Debug("command is ", strCmd)
// Create a new context and add a timeout to it
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel() // The cancel should be deferred so resources are cleaned up

// Create the command with our context
cmd := exec.CommandContext(ctx, "libreoffice", "--convert-to", format, "--outdir", dir, m.filePath())

libreOfficeMutex.Lock() //ensure only one libreoffice is running
// This time we can simply use Output() to get the result.
out, e := cmd.Output() out, e := cmd.Output()
libreOfficeMutex.Unlock()

// We want to check the context error to see if the timeout was executed.
// The error returned by cmd.Output() will be OS specific based on what
// happens when a process is killed.
if ctx.Err() == context.DeadlineExceeded {
log.Error(cmd.String(), " timed out")

switch format {
case "pdf":
_, e = copyFile(config.UploadsDir.PdfDefault, m.pdfPath())
break
case "jpg":
_, e = copyFile(config.UploadsDir.JpgDefault, m.jpgPath())
break
}
return
}

// If there's no context error, we know the command completed (or errored).
//fmt.Println("Output:", string(out))
//if err != nil {
// fmt.Println("Non-zero exit code:", err)
//}

// ---------- for cases not using ctx
// for some unknown reason, libreoffice may just hung for ever
//cmd := exec.Command("libreoffice", "--convert-to", format, "--outdir", dir, m.filePath())
//strCmd := cmd.String()
//log.Debug("command is ", strCmd)
//out, e := cmd.Output()
// ------------ end of without ctx

if e != nil { if e != nil {
log.Error("cannot converting Excel to "+format+":", m.Upload, e) log.Error("cannot converting Excel to "+format+":", m.Upload, e)
switch format {
case "pdf":
_, e = copyFile(config.UploadsDir.PdfDefault, m.pdfPath())
break
case "jpg":
_, e = copyFile(config.UploadsDir.JpgDefault, m.jpgPath())
break
}
return return
} else { // success } else { // success
log.Info("convert to "+format, m.Upload, " output: ", string(out)) log.Info("convert to "+format, m.Upload, " output: ", string(out))
out, e := cmd.Output() out, e := cmd.Output()
if e != nil { if e != nil {
log.Error("cannot create png file for PDF", m.Upload, e) log.Error("cannot create png file for PDF", m.Upload, e)
_, e = copyFile(config.UploadsDir.JpgDefault, m.jpgPath())
return return
} else { } else {
log.Info("convert ", m.Upload, " output: ", string(out)) log.Info("convert ", m.Upload, " output: ", string(out))


// montage -mode concatenate -tile 1x 30*png 30.jpg // montage -mode concatenate -tile 1x 30*png 30.jpg
if fileExists(target) { // single file, if fileExists(target) { // single file,
e = os.Rename(target, m.jpgPath()) // there should be only one jpg
_ = ConvertImageToThumbnail(target, m.thumbPath(), 256) _ = ConvertImageToThumbnail(target, m.thumbPath(), 256)
e = os.Rename(target, m.jpgPath()) // there should be only one jpg
} else { // multi-page, we have -0 -1 -2 -3 -4 files } else { // multi-page, we have -0 -1 -2 -3 -4 files
firstPage := dir + string(os.PathSeparator) + "result-0.jpg" firstPage := dir + string(os.PathSeparator) + "result-0.jpg"
_ = ConvertImageToThumbnail(firstPage, m.thumbPath(), 256) _ = ConvertImageToThumbnail(firstPage, m.thumbPath(), 256)
return "", nil return "", nil
} }


func (m *uploadsOnDisk) DeleteAll() (e error) {
eJpg := os.Remove(m.jpgPath())
eFile := os.Remove(m.filePath())
ePdf := os.Remove(m.pdfPath())
eThumb := os.Remove(m.thumbPath())
eMeta := m.Upload.Delete()

strId := strconv.Itoa(int(m.Upload.Id))

errMsg := ""
if eJpg != nil {
errMsg += " jpg "
}

if eFile != nil {
errMsg += " original "
}

if ePdf != nil {
errMsg += " pdf "
}

if eThumb != nil {
errMsg += " thumb "
}

if eMeta != nil {
errMsg += " Meta in DB "
e = errors.New(errMsg + " cannot be deleted " + strId)
}

if errMsg != "" {
log.Error(errMsg, "files on disk cannot be deleted need disk cleaning ", m.Upload)
}
return
}

// GetFileContentType
// tested, not accurate with xls, xlsx, it becomes zip and octstream sometime. // tested, not accurate with xls, xlsx, it becomes zip and octstream sometime.
func GetFileContentType(filename string) (contentType string, e error) { func GetFileContentType(filename string) (contentType string, e error) {
contentType = "" contentType = ""
return return
} }


// Use the net/http package's handy DectectContentType function. Always returns a valid
// Use the net/http package's handy Detect ContentType function. Always returns a valid
// content-type by returning "application/octet-stream" if no others seemed to match. // content-type by returning "application/octet-stream" if no others seemed to match.
contentType = http.DetectContentType(buffer) contentType = http.DetectContentType(buffer)
return return
log.Info("skip converting thumbnail it exists", dstPath) log.Info("skip converting thumbnail it exists", dstPath)
return return
} }
if size <= 0 {
if size <= 0 { //thumb nail width
size = 256 size = 256
} }
// convert -thumbnail 200 abc.png thumb.abc.png // convert -thumbnail 200 abc.png thumb.abc.png


out, e := cmd.Output() out, e := cmd.Output()
if e != nil { if e != nil {
log.Error("Failed to convert thumbnail", e)
_, e = copyFile(config.UploadsDir.ThumbDefault, dstPath)
return return
} else { // success } else { // success
log.Info("success output: \n: ", string(out)) log.Info("success output: \n: ", string(out))
} }
return return
} }

func fileNameWithoutExtTrimSuffix(fileName string) string {
return strings.TrimSuffix(fileName, filepath.Ext(fileName))
}

+ 30
- 0
apiV1UploadAnalysis.go Visa fil

log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"net/http" "net/http"
"strconv" "strconv"
"time"
) )


func apiV1UploadAnalysis(w http.ResponseWriter, r *http.Request, ss *loan.Session) { func apiV1UploadAnalysis(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
} }
apiV1SendJson(ai, w, r, ss) apiV1SendJson(ai, w, r, ss)
} }

func apiV1UploadCreateAnalysis(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
time.Sleep(1 * time.Second)

strId := r.URL.Path[len(apiV1Prefix+"upload-analysis/"):] //remove prefix
Id, e := strconv.Atoi(strId)
if e != nil {
log.Error("Invalid uploads Id cannot convert to integer", Id, e)
apiV1Client403Error(w, r, ss)
return
}

ul := loan.Uploads{}
e = ul.Read(int64(Id))
if e != nil {
log.Error("Upload not found or read error from db", Id, e)
apiV1Client404Error(w, r, ss)
return
}

ai := AiDecodeIncome{}
e = ai.decodeUploadToPayIn(ul)
if e != nil {
log.Error("Cannot decode upload", Id, e)
apiV1Server500Error(w, r)
return
}
apiV1SendJson(ai, w, r, ss)
}

+ 95
- 0
apiV1UploadAsImage.go Visa fil

package main

import (
"biukop.com/sfm/loan"
log "github.com/sirupsen/logrus"
"net/http"
"os"
"strings"
)

func apiV1UploadAsImage(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
// time.Sleep(5* time.Second)

strId := r.URL.Path[len(apiV1Prefix+"upload-as-image/"):] //remove prefix
if strId == "default" {
http.ServeFile(w, r, config.UploadsDir.JpgDefault)
return
}

ul, e := getRequestedUpload(strId, w, r, ss)
if e != nil {
return
}

// if this is image itself, serve it directly
if strings.Contains(strings.ToLower(ul.Upload.Format), "image") {
f, e := os.Open(ul.filePath())
if e == nil {
defer f.Close()
fi, e := f.Stat()
if e == nil {
//w.Header().Set("Content-Disposition", "attachment; filename="+ul.Upload.FileName)
http.ServeContent(w, r, ul.filePath(), fi.ModTime(), f)
return
}
}
// if we reach here, some err has happened
log.Error("failed to serve image file ", ul, e)
apiV1Server500Error(w, r)
return
}

// see if a converted image exist, if not convert it and then send
if !fileExists(ul.jpgPath()) {
e = ul.convertUploadsToJpg()
if e != nil {
// serve a default no preview is available
http.ServeFile(w, r, config.UploadsDir.JpgDefault)
log.Error("error creating preview image", ul, e)
return
}
}
if fileExists(ul.jpgPath()) {
http.ServeFile(w, r, ul.jpgPath())
return
} else {
apiV1Client404Error(w, r, ss)
}

}
func apiV1UploadCreateImage(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
//time.Sleep(1 * time.Second)

strId := r.URL.Path[len(apiV1Prefix+"upload-as-image/"):] //remove prefix
if strId == "" {
apiV1Client404Error(w, r, ss)
return
}

ul, e := getRequestedUpload(strId, w, r, ss)
if e != nil {
return
}

// if this is image itself, serve it directly
if strings.Contains(strings.ToLower(ul.Upload.Format), "image") {
apiV1SendJson(true, w, r, ss)
return
}

// see if a converted image exist, if not convert it and then send
if !fileExists(ul.jpgPath()) {
e = ul.convertUploadsToJpg()
if e != nil {
log.Error("error creating preview image", ul, e)
}
}

if fileExists(ul.jpgPath()) {
apiV1SendJson(true, w, r, ss)
return
} else {
apiV1SendJson(false, w, r, ss)
}
}

+ 31
- 0
apiV1UploadList.go Visa fil

package main

import (
"biukop.com/sfm/loan"
"encoding/json"
log "github.com/sirupsen/logrus"
"net/http"
)

func decodeUploadsMetaListFilter(r *http.Request) (ret loan.UploadListFilter, e error) {
decoder := json.NewDecoder(r.Body)
e = decoder.Decode(&ret)
if e != nil {
log.Error("failed decoding Upload Filter", e.Error())
return
}
return
}

func apiV1UploadMetaList(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
filter, e := decodeUploadsMetaListFilter(r)
if e != nil {
log.Println("invalid filter", e)
apiV1Client403Error(w, r, ss) // bad request
return
}

data := loan.GetUploadMetaList(filter)

apiV1SendJson(data, w, r, ss)
}

+ 63
- 0
apiV1UploadThumb.go Visa fil

package main

import (
"biukop.com/sfm/loan"
log "github.com/sirupsen/logrus"
"net/http"
)

func apiV1UploadAsThumbnail(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
strId := r.URL.Path[len(apiV1Prefix+"upload-as-thumbnail/"):] //remove prefix
if strId == "default" {
http.ServeFile(w, r, config.UploadsDir.ThumbDefault)
return
}
ul, e := getRequestedUpload(strId, w, r, ss)
if e != nil {
return
}

// see if a thumbnail is available already
if !fileExists(ul.thumbPath()) {
e = ul.convertUploadsToThumb()
if e != nil {
// serve a default no preview is available
http.ServeFile(w, r, config.UploadsDir.ThumbDefault)
log.Error("error creating preview image", ul, e)
return
}
}
if fileExists(ul.thumbPath()) {
http.ServeFile(w, r, ul.thumbPath())
return
} else {
apiV1Client404Error(w, r, ss)
}
}

func apiV1UploadCreateThumbnail(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
//time.Sleep(1 * time.Second)
strId := r.URL.Path[len(apiV1Prefix+"upload-as-thumbnail/"):] //remove prefix
if strId == "" {
apiV1Client404Error(w, r, ss)
return
}
ul, e := getRequestedUpload(strId, w, r, ss)
if e != nil {
return
}

// see if a thumbnail is available already
if !fileExists(ul.thumbPath()) {
e = ul.convertUploadsToThumb()
if e != nil {
log.Error("error creating thumbNail image", ul, e)
}
}
if fileExists(ul.thumbPath()) {
apiV1SendJson(true, w, r, ss)
return
} else {
apiV1SendJson(false, w, r, ss)
}
}

+ 28
- 134
apiV1Uploads.go Visa fil

"net/http" "net/http"
"os" "os"
"strconv" "strconv"
"strings"
"time" "time"
) )


apiV1SendJson(ulmeta, w, r, ss) apiV1SendJson(ulmeta, w, r, ss)
} }


func apiV1UploadDelete(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
id := r.URL.Path[len(apiV1Prefix+"upload/"):] //remove prefix
intId, e := strconv.Atoi(id)
if e != nil {
log.Println("invalid id for upload get", id, e)
apiV1Client403Error(w, r, ss) // bad request
return
}

ul := uploadsOnDisk{}
ul.Upload = loan.Uploads{}
e = ul.Upload.Read(int64(intId))
if e != nil {
log.Println("upload not found", id, e)
apiV1Client404Error(w, r, ss) // bad request
return
}

e = ul.DeleteAll()
if e != nil {
log.Println("upload cannot be deleted", id, e)
apiV1Server500Error(w, r) // bad operation
return
}

apiV1SendJson(ul.Upload, w, r, ss)
}

func apiV1UploadOriginalFileGet(w http.ResponseWriter, r *http.Request, ss *loan.Session) { func apiV1UploadOriginalFileGet(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
id := r.URL.Path[len(apiV1Prefix+"upload-original/"):] //remove prefix id := r.URL.Path[len(apiV1Prefix+"upload-original/"):] //remove prefix
intId, e := strconv.Atoi(id) intId, e := strconv.Atoi(id)
return return
} }


func apiV1UploadAsImage(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
strId := r.URL.Path[len(apiV1Prefix+"upload-as-image/"):] //remove prefix
if strId == "default" {
http.ServeFile(w, r, config.UploadsDir.JpgDefault)
return
}

ul, e := getRequestedUpload(strId, w, r, ss)
if e != nil {
return
}
//time.Sleep(5* time.Second);
// if this is image itself, serve it directly
if strings.Contains(strings.ToLower(ul.Upload.Format), "image") {
f, e := os.Open(ul.filePath())
if e == nil {
defer f.Close()
fi, e := f.Stat()
if e == nil {
//w.Header().Set("Content-Disposition", "attachment; filename="+ul.Upload.FileName)
http.ServeContent(w, r, ul.filePath(), fi.ModTime(), f)
return
}
}
// if we reach here, some err has happened
log.Error("failed to serve image file ", ul, e)
apiV1Server500Error(w, r)
return
}

// see if a converted image exist, if not convert it and then send
if !fileExists(ul.jpgPath()) {
e = ul.convertUploadsToJpg()
if e != nil {
// serve a default no preview is available
http.ServeFile(w, r, config.UploadsDir.JpgDefault)
log.Error("error creating preview image", ul, e)
return
}
}
if fileExists(ul.jpgPath()) {
http.ServeFile(w, r, ul.jpgPath())
return
} else {
apiV1Client404Error(w, r, ss)
}

}
func apiV1UploadAsThumbnail(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
strId := r.URL.Path[len(apiV1Prefix+"upload-as-thumbnail/"):] //remove prefix
if strId == "default" {
http.ServeFile(w, r, config.UploadsDir.ThumbDefault)
return
}
ul, e := getRequestedUpload(strId, w, r, ss)
if e != nil {
return
}

// see if a thumbnail is available already
if !fileExists(ul.thumbPath()) {
e = ul.convertUploadsToThumb()
if e != nil {
// serve a default no preview is available
http.ServeFile(w, r, config.UploadsDir.ThumbDefault)
log.Error("error creating preview image", ul, e)
return
}
}
if fileExists(ul.thumbPath()) {
http.ServeFile(w, r, ul.thumbPath())
return
} else {
apiV1Client404Error(w, r, ss)
}
}

func apiV1UploadAsPDF(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
strId := r.URL.Path[len(apiV1Prefix+"upload-as-pdf/"):] //remove prefix
if strId == "default" {
http.ServeFile(w, r, config.UploadsDir.PdfDefault)
return
}
ul, e := getRequestedUpload(strId, w, r, ss)
if e != nil {
return
}

//get file type
fileType, e := ul.GetFileType()
if e != nil {
apiV1Client403Error(w, r, ss)
return
}

// if its ready pdf, no need to convert
if fileType == "pdf" {
f, e := os.Open(ul.filePath())
if e == nil {
defer f.Close()
fi, e := f.Stat()
if e == nil {
if forceHttpDownload(r) {
w.Header().Set("Content-Disposition", "attachment; filename="+ul.Upload.FileName)
}
http.ServeContent(w, r, ul.Upload.FileName, fi.ModTime(), f)
return
}
}
// if we reach here, some err has happened
log.Error("failed to serve pdf file ", ul, e)
apiV1Server500Error(w, r)
return
}

// see if a converted pdf exist, if not convert it and then send
if !fileExists(ul.pdfPath()) {
e = ul.convertUploadsToPDF()
if e != nil {
// serve a default no preview is available
http.ServeFile(w, r, config.UploadsDir.PdfDefault)
log.Error("error creating preview image", ul, e)
return
}
}
if fileExists(ul.pdfPath()) {
http.ServeFile(w, r, ul.pdfPath())
return
} else {
apiV1Client404Error(w, r, ss)
}
}

func forceHttpDownload(r *http.Request) bool { func forceHttpDownload(r *http.Request) bool {
keys, ok := r.URL.Query()["download"] keys, ok := r.URL.Query()["download"]



+ 109
- 0
apiV1UploadsAsPdf.go Visa fil

package main

import (
"biukop.com/sfm/loan"
log "github.com/sirupsen/logrus"
"net/http"
"os"
)

func apiV1UploadAsPDF(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
strId := r.URL.Path[len(apiV1Prefix+"upload-as-pdf/"):] //remove prefix
if strId == "default" {
http.ServeFile(w, r, config.UploadsDir.PdfDefault)
return
}
ul, e := getRequestedUpload(strId, w, r, ss)
if e != nil {
return
}

//get file type
fileType, e := ul.GetFileType()
if e != nil {
apiV1Client403Error(w, r, ss)
return
}

// if its ready pdf, no need to convert
if fileType == "pdf" {
f, e := os.Open(ul.filePath())
if e == nil {
defer f.Close()
fi, e := f.Stat()
if e == nil {
if forceHttpDownload(r) {
w.Header().Set("Content-Disposition", "attachment; filename="+ul.Upload.FileName)
}
http.ServeContent(w, r, ul.Upload.FileName, fi.ModTime(), f)
return
}
}
// if we reach here, some err has happened
log.Error("failed to serve pdf file ", ul, e)
apiV1Server500Error(w, r)
return
}

// see if a converted pdf exist, if not convert it and then send
if !fileExists(ul.pdfPath()) {
e = ul.convertUploadsToPDF()
if e != nil {
// serve a default no preview is available
http.ServeFile(w, r, config.UploadsDir.PdfDefault)
log.Error("error creating preview image", ul, e)
return
}
}
if fileExists(ul.pdfPath()) {
http.ServeFile(w, r, ul.pdfPath())
return
} else {
apiV1Client404Error(w, r, ss)
}
}

func apiV1UploadCreatePDF(w http.ResponseWriter, r *http.Request, ss *loan.Session) {
//time.Sleep(1* time.Second)

strId := r.URL.Path[len(apiV1Prefix+"upload-as-pdf/"):] //remove prefix
if strId == "" {
apiV1Client404Error(w, r, ss)
return
}
ul, e := getRequestedUpload(strId, w, r, ss)
if e != nil {
return
}

//get file type
fileType, e := ul.GetFileType()
if e != nil {
apiV1Client403Error(w, r, ss)
return
}

// if its ready pdf, no need to convert
if fileType == "pdf" {
apiV1SendJson(true, w, r, ss)
return
}

// see if a converted pdf exist, if not convert it and then send
if !fileExists(ul.pdfPath()) {
e = ul.convertUploadsToPDF()
if e != nil {
log.Error("error creating pdf", ul, e)
_, e = copyFile(config.UploadsDir.PdfDefault, ul.pdfPath())
if e != nil {
log.Error("failed copy default pdf", e)
}
}
}
if fileExists(ul.pdfPath()) {
apiV1SendJson(true, w, r, ss)
return
} else {
apiV1SendJson(false, w, r, ss)
}
}

+ 12
- 0
apiv1.go Visa fil

{"GET", "lender-upload/", apiV1UploadOriginalFileGet}, {"GET", "lender-upload/", apiV1UploadOriginalFileGet},


{"GET", "upload-analysis/", apiV1UploadAnalysis}, {"GET", "upload-analysis/", apiV1UploadAnalysis},
{"PUT", "upload-analysis/", apiV1UploadCreateAnalysis},
{"GET", "upload-as-image/", apiV1UploadAsImage}, {"GET", "upload-as-image/", apiV1UploadAsImage},
{"PUT", "upload-as-image/", apiV1UploadCreateImage},
{"GET", "upload-as-thumbnail/", apiV1UploadAsThumbnail}, {"GET", "upload-as-thumbnail/", apiV1UploadAsThumbnail},
{"PUT", "upload-as-thumbnail/", apiV1UploadCreateThumbnail},
{"GET", "upload-as-pdf/", apiV1UploadAsPDF}, {"GET", "upload-as-pdf/", apiV1UploadAsPDF},
{"PUT", "upload-as-pdf/", apiV1UploadCreatePDF},
{"GET", "upload-original/", apiV1UploadOriginalFileGet}, {"GET", "upload-original/", apiV1UploadOriginalFileGet},
{"GET", "upload/", apiV1UploadMetaGet}, {"GET", "upload/", apiV1UploadMetaGet},
{"DELETE", "upload/", apiV1UploadDelete},
{"POST", "upload-meta-list/", apiV1UploadMetaList},


{"GET", "login", apiV1DumpRequest}, {"GET", "login", apiV1DumpRequest},
} }
{"GET", "lender-upload/", apiV1UploadOriginalFileGet}, {"GET", "lender-upload/", apiV1UploadOriginalFileGet},


{"GET", "upload-analysis/", apiV1UploadAnalysis}, {"GET", "upload-analysis/", apiV1UploadAnalysis},
{"PUT", "upload-analysis/", apiV1UploadCreateAnalysis},
{"GET", "upload-as-image/", apiV1UploadAsImage}, {"GET", "upload-as-image/", apiV1UploadAsImage},
{"PUT", "upload-as-image/", apiV1UploadCreateImage},
{"GET", "upload-as-thumbnail/", apiV1UploadAsThumbnail}, {"GET", "upload-as-thumbnail/", apiV1UploadAsThumbnail},
{"PUT", "upload-as-thumbnail/", apiV1UploadCreateThumbnail},
{"GET", "upload-as-pdf/", apiV1UploadAsPDF}, {"GET", "upload-as-pdf/", apiV1UploadAsPDF},
{"PUT", "upload-as-pdf/", apiV1UploadCreatePDF},
{"GET", "upload-original/", apiV1UploadOriginalFileGet}, {"GET", "upload-original/", apiV1UploadOriginalFileGet},
{"GET", "upload-meta/", apiV1UploadMetaGet}, {"GET", "upload-meta/", apiV1UploadMetaGet},
{"DELETE", "upload/", apiV1UploadDelete},
{"POST", "upload-meta-list/", apiV1UploadMetaList},


{"GET", "login", apiV1EmptyResponse}, {"GET", "login", apiV1EmptyResponse},
} }

Binär
assets/thumb_file_icon.webp Visa fil

Before After

+ 38
- 0
fileUtil.go Visa fil

package main

import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
)

func fileNameWithoutExtTrimSuffix(fileName string) string {
return strings.TrimSuffix(fileName, filepath.Ext(fileName))
}

func copyFile(src, dst string) (int64, error) {
sourceFileStat, err := os.Stat(src)
if err != nil {
return 0, err
}

if !sourceFileStat.Mode().IsRegular() {
return 0, fmt.Errorf("%s is not a regular file", src)
}

source, err := os.Open(src)
if err != nil {
return 0, err
}
defer source.Close()

destination, err := os.Create(dst)
if err != nil {
return 0, err
}
defer destination.Close()
nBytes, err := io.Copy(destination, source)
return nBytes, err
}

Laddar…
Avbryt
Spara