Commit 2c237577d349dea55b20fab5275e82438839b5a6

Authored by Marko Tikvić
1 parent a7bf420dd5
Exists in master

fixed int formating bug

1 package webutility 1 package webutility
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "strings" 5 "strings"
6 "time" 6 "time"
7 ) 7 )
8 8
9 const ( 9 const (
10 YYYYMMDD_sl = "2006/01/02" 10 YYYYMMDD_sl = "2006/01/02"
11 YYYYMMDD_ds = "2006-01-02" 11 YYYYMMDD_ds = "2006-01-02"
12 YYYYMMDD_dt = "2006.01.02." 12 YYYYMMDD_dt = "2006.01.02."
13 13
14 DDMMYYYY_sl = "02/01/2006" 14 DDMMYYYY_sl = "02/01/2006"
15 DDMMYYYY_ds = "02-01-2006" 15 DDMMYYYY_ds = "02-01-2006"
16 DDMMYYYY_dt = "02.01.2006." 16 DDMMYYYY_dt = "02.01.2006."
17 17
18 YYYYMMDD_HHMMSS_sl = "2006/01/02 15:04:05" 18 YYYYMMDD_HHMMSS_sl = "2006/01/02 15:04:05"
19 YYYYMMDD_HHMMSS_ds = "2006-01-02 15:04:05" 19 YYYYMMDD_HHMMSS_ds = "2006-01-02 15:04:05"
20 YYYYMMDD_HHMMSS_dt = "2006.01.02. 15:04:05" 20 YYYYMMDD_HHMMSS_dt = "2006.01.02. 15:04:05"
21 21
22 DDMMYYYY_HHMMSS_sl = "02/01/2006 15:04:05" 22 DDMMYYYY_HHMMSS_sl = "02/01/2006 15:04:05"
23 DDMMYYYY_HHMMSS_ds = "02-01-2006 15:04:05" 23 DDMMYYYY_HHMMSS_ds = "02-01-2006 15:04:05"
24 DDMMYYYY_HHMMSS_dt = "02.01.2006. 15:04:05" 24 DDMMYYYY_HHMMSS_dt = "02.01.2006. 15:04:05"
25 ) 25 )
26 26
27 var ( 27 var (
28 regularYear = [12]int64{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 28 regularYear = [12]int64{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
29 leapYear = [12]int64{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 29 leapYear = [12]int64{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
30 ) 30 )
31 31
32 func Systime() int64 { 32 func Systime() int64 {
33 return time.Now().Unix() 33 return time.Now().Unix()
34 } 34 }
35 35
36 func DateToEpoch(date, format string) int64 { 36 func DateToEpoch(date, format string) int64 {
37 t, err := time.Parse(format, date) 37 t, err := time.Parse(format, date)
38 if err != nil { 38 if err != nil {
39 fmt.Println(err.Error()) 39 fmt.Println(err.Error())
40 return 0 40 return 0
41 } 41 }
42 return t.Unix() 42 return t.Unix()
43 } 43 }
44 44
45 func EpochToDate(e int64, format string) string { 45 func EpochToDate(e int64, format string) string {
46 return time.Unix(e, 0).Format(format) 46 return time.Unix(e, 0).Format(format)
47 } 47 }
48 48
49 func EpochToDayMonthYear(timestamp int64) (d, m, y int64) { 49 func EpochToDayMonthYear(timestamp int64) (d, m, y int64) {
50 datestring := EpochToDate(timestamp, DDMMYYYY_sl) 50 datestring := EpochToDate(timestamp, DDMMYYYY_sl)
51 parts := strings.Split(datestring, "/") 51 parts := strings.Split(datestring, "/")
52 d = StringToInt64(parts[0]) 52 d = StringToInt64(parts[0])
53 m = StringToInt64(parts[1]) 53 m = StringToInt64(parts[1])
54 y = StringToInt64(parts[2]) 54 y = StringToInt64(parts[2])
55 return d, m, y 55 return d, m, y
56 } 56 }
57 57
58 func DaysInMonth(year, month int64) int64 { 58 func DaysInMonth(year, month int64) int64 {
59 if month < 1 || month > 12 { 59 if month < 1 || month > 12 {
60 return 0 60 return 0
61 } 61 }
62 if IsLeapYear(year) { 62 if IsLeapYear(year) {
63 return leapYear[month-1] 63 return leapYear[month-1]
64 } 64 }
65 return regularYear[month-1] 65 return regularYear[month-1]
66 } 66 }
67 67
68 func IsLeapYear(year int64) bool { 68 func IsLeapYear(year int64) bool {
69 return year%4 == 0 && !((year%100 == 0) && (year%400 != 0)) 69 return year%4 == 0 && !((year%100 == 0) && (year%400 != 0))
70 } 70 }
71
72 // FirstDayOfNextMonthEpoch ...
73 func FirstDayOfNextMonthEpoch(e int64) int64 {
74 d, m, y := EpochToDayMonthYear(e)
75 m++
76 if m > 12 {
77 m = 1
78 y++
79 }
80 d = 1
81
82 date := fmt.Sprintf("%02d/%02d/%d", d, m, y)
83
84 return DateToEpoch(date, DDMMYYYY_sl)
85 }
71 86
document/document.go
1 package document 1 package document
2 2
3 import ( 3 import (
4 "errors" 4 "errors"
5 "fmt" 5 "fmt"
6 "io" 6 "io"
7 "mime" 7 "mime"
8 "net/http" 8 "net/http"
9 "os" 9 "os"
10 "strings" 10 "strings"
11 "time" 11 "time"
12 12
13 web "git.to-net.rs/marko.tikvic/webutility" 13 web "git.to-net.rs/marko.tikvic/webutility"
14 ) 14 )
15 15
16 // Document ... 16 // Document ...
17 type Document struct { 17 type Document struct {
18 ID int64 `json:"id"` 18 ID int64 `json:"id"`
19 FileName string `json:"fileName"` 19 FileName string `json:"fileName"`
20 Extension string `json:"extension"` 20 Extension string `json:"extension"`
21 ContentType string `json:"contentType"` 21 ContentType string `json:"contentType"`
22 Size int64 `json:"fileSize"` 22 Size int64 `json:"fileSize"`
23 UploadedBy string `json:"uploadedBy"` 23 UploadedBy string `json:"uploadedBy"`
24 LastModifiedBy string `json:"lastModifiedBy"` 24 LastModifiedBy string `json:"lastModifiedBy"`
25 TimeUploaded int64 `json:"timeUploaded"` 25 TimeUploaded int64 `json:"timeUploaded"`
26 TimeLastModified int64 `json:"timeLastModified"` 26 TimeLastModified int64 `json:"timeLastModified"`
27 RoleAccessLevel int64 `json:"accessLevel"` 27 RoleAccessLevel int64 `json:"accessLevel"`
28 Description string `json:"description"` 28 Description string `json:"description"`
29 Download *DownloadLink `json:"download"` 29 Download *DownloadLink `json:"download"`
30 Path string `json:"-"` 30 Path string `json:"-"`
31 directory string 31 directory string
32 data []byte 32 data []byte
33 } 33 }
34 34
35 // OpenFileAsDocument ... 35 // OpenFileAsDocument ...
36 func OpenFileAsDocument(path string) (*Document, error) { 36 func OpenFileAsDocument(path string) (*Document, error) {
37 d := &Document{Path: path} 37 d := &Document{Path: path}
38 38
39 f, err := os.Open(d.Path) 39 f, err := os.Open(d.Path)
40 if err != nil { 40 if err != nil {
41 return nil, err 41 return nil, err
42 } 42 }
43 defer f.Close() 43 defer f.Close()
44 44
45 stats, err := f.Stat() 45 stats, err := f.Stat()
46 if err != nil { 46 if err != nil {
47 return nil, err 47 return nil, err
48 } 48 }
49 49
50 d.FileName = stats.Name() 50 d.FileName = stats.Name()
51 d.Size = stats.Size() 51 d.Size = stats.Size()
52 d.Extension = FileExtension(d.FileName) 52 d.Extension = FileExtension(d.FileName)
53 53
54 d.data = make([]byte, d.Size) 54 d.data = make([]byte, d.Size)
55 if _, err = f.Read(d.data); err != nil { 55 if _, err = f.Read(d.data); err != nil {
56 return nil, err 56 return nil, err
57 } 57 }
58 58
59 return d, err 59 return d, err
60 } 60 }
61 61
62 // DownloadLink ... 62 // DownloadLink ...
63 type DownloadLink struct { 63 type DownloadLink struct {
64 Method string `json:"method"` 64 Method string `json:"method"`
65 URL string `json:"url"` 65 URL string `json:"url"`
66 } 66 }
67 67
68 // SetDownloadInfo ... 68 // SetDownloadInfo ...
69 func (d *Document) SetDownloadInfo(method, url string) { 69 func (d *Document) SetDownloadInfo(method, url string) {
70 d.Download = &DownloadLink{ 70 d.Download = &DownloadLink{
71 Method: method, 71 Method: method,
72 URL: url, 72 URL: url,
73 } 73 }
74 } 74 }
75 75
76 // ServeDocument writes d's buffer to w and sets appropriate headers according to d's content type 76 // ServeDocument writes d's buffer to w and sets appropriate headers according to d's content type
77 // and downloadPrompt. 77 // and downloadPrompt.
78 func ServeDocument(w http.ResponseWriter, d *Document, downloadPrompt bool) error { 78 func ServeDocument(w http.ResponseWriter, d *Document, downloadPrompt bool) error {
79 f, err := os.Open(d.Path) 79 f, err := os.Open(d.Path)
80 if err != nil { 80 if err != nil {
81 return err 81 return err
82 } 82 }
83 defer f.Close() 83 defer f.Close()
84 84
85 web.SetContentType(w, mime.TypeByExtension(d.Extension)) 85 web.SetContentType(w, mime.TypeByExtension(d.Extension))
86 web.SetResponseStatus(w, http.StatusOK) 86 web.SetResponseStatus(w, http.StatusOK)
87 if downloadPrompt { 87 if downloadPrompt {
88 w.Header().Set("Content-Disposition", "attachment; filename="+d.FileName) 88 w.Header().Set("Content-Disposition", "attachment; filename="+d.FileName)
89 } 89 }
90 90
91 buf := make([]byte, d.Size) 91 buf := make([]byte, d.Size)
92 if _, err := f.Read(buf); err != nil { 92 if _, err := f.Read(buf); err != nil {
93 return err 93 return err
94 } 94 }
95 95
96 w.Header().Set("Content-Length", fmt.Sprintf("%d", d.Size)) 96 w.Header().Set("Content-Length", fmt.Sprintf("%d", d.Size))
97 web.WriteResponse(w, buf) 97 web.WriteResponse(w, buf)
98 98
99 return nil 99 return nil
100 } 100 }
101 101
102 // FileExists ... 102 // FileExists ...
103 func FileExists(path string) bool { 103 func FileExists(path string) bool {
104 temp, err := os.Open(path) 104 temp, err := os.Open(path)
105 defer temp.Close() 105 defer temp.Close()
106 106
107 if err != nil { 107 if err != nil {
108 return false 108 return false
109 } 109 }
110 110
111 return true 111 return true
112 } 112 }
113 113
114 // ParseDocument ... 114 // ParseDocument ...
115 func ParseDocument(req *http.Request) (doc *Document, err error) { 115 func ParseDocument(req *http.Request) (doc *Document, err error) {
116 req.ParseMultipartForm(32 << 20) 116 req.ParseMultipartForm(32 << 20)
117 file, fheader, err := req.FormFile("document") 117 file, fheader, err := req.FormFile("document")
118 if err != nil { 118 if err != nil {
119 return doc, err 119 return doc, err
120 } 120 }
121 121
122 claims, _ := web.GetTokenClaims(req) 122 claims, _ := web.GetTokenClaims(req)
123 owner := claims.Username 123 owner := claims.Username
124 124
125 fname := fheader.Filename 125 fname := fheader.Filename
126 126
127 fsize := fheader.Size 127 fsize := fheader.Size
128 ftype := fmt.Sprintf("%v", fheader.Header["Content-Type"][0]) 128 ftype := fmt.Sprintf("%v", fheader.Header["Content-Type"][0])
129 129
130 fextn := FileExtension(fname) 130 fextn := FileExtension(fname)
131 if fextn == "" { 131 if fextn == "" {
132 return doc, errors.New("invalid extension") 132 return doc, errors.New("invalid extension")
133 } 133 }
134 134
135 doc = new(Document) 135 doc = new(Document)
136 136
137 doc.FileName = fname 137 doc.FileName = fname
138 doc.Size = fsize 138 doc.Size = fsize
139 doc.ContentType = ftype 139 doc.ContentType = ftype
140 doc.Extension = "." + fextn 140 doc.Extension = "." + fextn
141 141
142 t := time.Now().Unix() 142 t := time.Now().Unix()
143 doc.TimeUploaded = t 143 doc.TimeUploaded = t
144 doc.TimeLastModified = t 144 doc.TimeLastModified = t
145 145
146 doc.UploadedBy = owner 146 doc.UploadedBy = owner
147 doc.LastModifiedBy = owner 147 doc.LastModifiedBy = owner
148 doc.RoleAccessLevel = 0 148 doc.RoleAccessLevel = 0
149 149
150 doc.data = make([]byte, doc.Size) 150 doc.data = make([]byte, doc.Size)
151 if _, err = io.ReadFull(file, doc.data); err != nil { 151 if _, err = io.ReadFull(file, doc.data); err != nil {
152 return doc, err 152 return doc, err
153 } 153 }
154 154
155 return doc, nil 155 return doc, nil
156 } 156 }
157 157
158 // DirectoryFromPath ... 158 // DirectoryFromPath ...
159 func DirectoryFromPath(path string) (dir string) { 159 func DirectoryFromPath(path string) (dir string) {
160 parts := strings.Split(path, "/") 160 parts := strings.Split(path, "/")
161 if len(parts) == 1 { 161 if len(parts) == 1 {
162 return "" 162 return ""
163 } 163 }
164 164
165 dir = parts[0] 165 dir = parts[0]
166 for _, p := range parts[1 : len(parts)-1] { 166 for _, p := range parts[1 : len(parts)-1] {
167 dir += "/" + p 167 dir += "/" + p
168 } 168 }
169 169
170 return dir 170 return dir
171 } 171 }
172 172
173 // SaveToFile ... 173 // SaveToFile ...
174 func (d *Document) SaveToFile(path string) (f *os.File, err error) { 174 func (d *Document) SaveToFile(path string) (f *os.File, err error) {
175 d.Path = path 175 d.Path = path
176 176
177 if FileExists(path) { 177 if FileExists(path) {
178 err = fmt.Errorf("file %s alredy exists", path) 178 err = fmt.Errorf("file %s alredy exists", path)
179 return nil, err 179 return nil, err
180 } 180 }
181 181
182 if parentDir := DirectoryFromPath(path); parentDir != "" { 182 if parentDir := DirectoryFromPath(path); parentDir != "" {
183 if err = os.MkdirAll(parentDir, os.ModePerm); err != nil { 183 if err = os.MkdirAll(parentDir, os.ModePerm); err != nil {
184 if !os.IsExist(err) { 184 if !os.IsExist(err) {
185 return nil, err 185 return nil, err
186 } 186 }
187 } 187 }
188 } 188 }
189 189
190 if f, err = os.Create(path); err != nil { 190 if f, err = os.Create(path); err != nil {
191 return nil, err 191 return nil, err
192 } 192 }
193 193
194 if _, err = f.Write(d.data); err != nil { 194 if _, err = f.Write(d.data); err != nil {
195 f.Close() 195 f.Close()
196 d.DeleteFile() 196 d.DeleteFile()
197 return nil, err 197 return nil, err
198 } 198 }
199 f.Close() 199 f.Close()
200 200
201 return f, nil 201 return f, nil
202 } 202 }
203 203
204 func DeleteFile(path string) error { 204 func DeleteFile(path string) error {
205 return os.Remove(path) 205 return os.Remove(path)
206 } 206 }
207 207
208 func DeleteDocuments(docs []*Document) error {
209 for _, d := range docs {
210 if err := d.DeleteFile(); err != nil {
211 return err
212 }
213 }
214 return nil
215 }
216
208 // DeleteFile ... 217 // DeleteFile ...
209 func (d *Document) DeleteFile() error { 218 func (d *Document) DeleteFile() error {
210 return os.Remove(d.Path) 219 return os.Remove(d.Path)
211 } 220 }
212 221
213 func FileExtension(path string) string { 222 func FileExtension(path string) string {
214 parts := strings.Split(path, ".") // because name can contain dots 223 parts := strings.Split(path, ".") // because name can contain dots
215 if len(parts) < 2 { 224 if len(parts) < 2 {
216 return "" 225 return ""
217 } 226 }
218 return "." + parts[len(parts)-1] 227 return "." + parts[len(parts)-1]
219 } 228 }
220 229
1 package webutility 1 package webutility
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 ) 5 )
6 6
7 // ClampInt64 ... 7 // ClampInt64 ...
8 func ClampInt64(v, min, max int64) int64 { 8 func ClampInt64(v, min, max int64) int64 {
9 if v < min { 9 if v < min {
10 return min 10 return min
11 } else if v > max { 11 } else if v > max {
12 return max 12 return max
13 } 13 }
14 14
15 return v 15 return v
16 } 16 }
17 17
18 // InRangeInt64 ... 18 // InRangeInt64 ...
19 func InRangeInt64(v, min, max int64) bool { 19 func InRangeInt64(v, min, max int64) bool {
20 return (v >= min && v <= max) 20 return (v >= min && v <= max)
21 } 21 }
22 22
23 // Int64ToString ... 23 // Int64ToString ...
24 func Int64ToString(i int64) string { 24 func Int64ToString(i int64) string {
25 return fmt.Sprintf("%d", i) 25 return fmt.Sprintf("%d", i)
26 } 26 }
27 27
28 // Int64PtrToString ... 28 // Int64PtrToString ...
29 func Int64PtrToString(i *int64) string { 29 func Int64PtrToString(i *int64) string {
30 if i == nil { 30 if i == nil {
31 return "" 31 return ""
32 } 32 }
33 return fmt.Sprintf("%d", *i) 33 return fmt.Sprintf("%d", *i)
34 } 34 }
35 35
36 // BoolToInt64 ... 36 // BoolToInt64 ...
37 func BoolToInt64(b bool) int64 { 37 func BoolToInt64(b bool) int64 {
38 if b { 38 if b {
39 return 1 39 return 1
40 } 40 }
41 return 0 41 return 0
42 } 42 }
43 43
44 // Int64ToBool ... 44 // Int64ToBool ...
45 func Int64ToBool(i int64) bool { 45 func Int64ToBool(i int64) bool {
46 return i != 0 46 return i != 0
47 } 47 }
48 48
49 func MaxInt(vars ...int) (max int) { 49 func MaxInt(vars ...int) (max int) {
50 max = vars[0] 50 max = vars[0]
51 for _, v := range vars { 51 for _, v := range vars {
52 if v > max { 52 if v > max {
53 max = v 53 max = v
54 } 54 }
55 } 55 }
56 return max 56 return max
57 } 57 }
58 58
59 func MinInt64(vars ...int64) (min int64) { 59 func MinInt64(vars ...int64) (min int64) {
60 min = vars[0] 60 min = vars[0]
61 for _, v := range vars { 61 for _, v := range vars {
62 if v < min { 62 if v < min {
63 min = v 63 min = v
64 } 64 }
65 } 65 }
66 return min 66 return min
67 } 67 }
68 68
69 func FormatInt64Number(i int64) string { 69 func FormatInt64Number(i int64) string {
70 res := "" 70 res := ""
71 71
72 for i >= 1000 { 72 for i >= 1000 {
73 rem := i % 1000 73 rem := i % 1000
74 i = i / 1000 74 i = i / 1000
75 res = res + fmt.Sprintf(".%03d", rem) 75 //res = res + fmt.Sprintf(".%03d", rem)
76 res = fmt.Sprintf(".%03d", rem) + res
76 } 77 }
77 res = fmt.Sprintf("%d", i) + res 78 res = fmt.Sprintf("%d", i) + res
78 return res 79 return res
79 } 80 }
80 81