-
Notifications
You must be signed in to change notification settings - Fork 0
/
filestore.go
81 lines (70 loc) · 2.21 KB
/
filestore.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package main
import (
"bytes"
"encoding/json"
"github.com/bitly/go-nsq"
"github.com/joinmytalk/xlog"
"io"
"net/http"
"os"
"path"
)
// FileUploadStore abstracts the filesystem where files are uploaded to.
type FileUploadStore struct {
UploadDir string
TmpDir string
NSQ *nsq.Writer
Topic string
}
// ServeHTTP serves HTTP request from the FileUploadStore.
func (store *FileUploadStore) ServeHTTP(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, path.Join(store.UploadDir, r.URL.Path))
}
// Store stores a new file with a specified id in the filesystem. If the
// file isn't a PDF file, it also attempts a conversion to a PDF file.
func (store *FileUploadStore) Store(id string, uploadedFile io.Reader, origFileName string) (isPDF bool, err error) {
filename := path.Join(store.UploadDir, id+".pdf")
tmpFile := path.Join(store.TmpDir, id+"_"+origFileName)
tmpf, err := os.OpenFile(tmpFile, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
return false, err
}
io.Copy(tmpf, uploadedFile)
tmpf.Close()
f, err := os.Open(tmpFile)
if err != nil {
return false, err
}
defer f.Close()
buf := make([]byte, 4)
if _, err = f.Read(buf); err != nil {
return false, err
}
if bytes.Equal(buf, []byte("%PDF")) {
xlog.Debugf("%s is a PDF file, renaming to %s", tmpFile, filename)
os.Rename(tmpFile, filename)
return true, nil
}
if err = store.ConvertFileToPDF(id, tmpFile, filename); err != nil {
xlog.Errorf("conversion to PDF of %s failed: %v", tmpFile, err)
os.Remove(tmpFile)
os.Remove(filename)
return false, err
}
return false, nil
}
// Remove removes an uploaded file from the file store.
func (store *FileUploadStore) Remove(uploadID string) {
filePath := path.Join(store.UploadDir, uploadID+".pdf")
xlog.Debugf("FileUploadStore: remove %s", filePath)
os.Remove(filePath)
}
// ConvertFileToPDF attempts to convert a file to PDF.
func (store *FileUploadStore) ConvertFileToPDF(id, src, target string) error {
msg, _ := json.Marshal(map[string]string{"src_file": src, "target_file": target, "upload_id": id})
if _, _, err := store.NSQ.Publish(store.Topic, msg); err != nil {
xlog.Errorf("Queuing message to NSQ %s failed: %v", store.NSQ.Addr, err)
return err
}
return nil
}