utils.go (view raw)
1package main
2
3import (
4 "archive/zip"
5 "fmt"
6 "io"
7 "os"
8 "path"
9 "path/filepath"
10 "strings"
11 "time"
12)
13
14func isGemini(filename string) bool {
15 extension := path.Ext(filename)
16 return extension == ".gmi" || extension == ".gemini"
17}
18
19func timeago(t *time.Time) string {
20 d := time.Since(*t)
21 if d.Seconds() < 60 {
22 seconds := int(d.Seconds())
23 if seconds == 1 {
24 return "1 second ago"
25 }
26 return fmt.Sprintf("%d seconds ago", seconds)
27 } else if d.Minutes() < 60 {
28 minutes := int(d.Minutes())
29 if minutes == 1 {
30 return "1 minute ago"
31 }
32 return fmt.Sprintf("%d minutes ago", minutes)
33 } else if d.Hours() < 24 {
34 hours := int(d.Hours())
35 if hours == 1 {
36 return "1 hour ago"
37 }
38 return fmt.Sprintf("%d hours ago", hours)
39 } else {
40 days := int(d.Hours()) / 24
41 if days == 1 {
42 return "1 day ago"
43 }
44 return fmt.Sprintf("%d days ago", days)
45 }
46}
47
48// safe
49func getUserDirectory(username string) string {
50 // extra filepath.clean just to be safe
51 userFolder := path.Join(c.FilesDirectory, filepath.Clean(username))
52 return userFolder
53}
54
55// ugh idk
56func safeGetFilePath(username string, filename string) string {
57 return path.Join(getUserDirectory(username), filepath.Clean(filename))
58}
59
60// TODO move into checkIfValidFile. rename it
61func userHasSpace(user string, newBytes int) bool {
62 userPath := path.Join(c.FilesDirectory, user)
63 size, err := dirSize(userPath)
64 if err != nil || size+int64(newBytes) > c.MaxUserBytes {
65 return false
66 }
67 return true
68}
69
70func dirSize(path string) (int64, error) {
71 var size int64
72 err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
73 if err != nil {
74 return err
75 }
76 if !info.IsDir() {
77 size += info.Size()
78 }
79 return err
80 })
81 return size, err
82}
83
84/// Perform some checks to make sure the file is OK
85func checkIfValidFile(filename string, fileBytes []byte) error {
86 if len(filename) == 0 {
87 return fmt.Errorf("Please enter a filename")
88 }
89 if len(filename) > 256 { // arbitrarily chosen
90 return fmt.Errorf("Filename is too long")
91 }
92 ext := strings.ToLower(path.Ext(filename))
93 found := false
94 for _, mimetype := range c.OkExtensions {
95 if ext == mimetype {
96 found = true
97 }
98 }
99 if !found {
100 return fmt.Errorf("Invalid file extension: %s", ext)
101 }
102 if len(fileBytes) > c.MaxFileBytes {
103 return fmt.Errorf("File too large. File was %d bytes, Max file size is %d", len(fileBytes), c.MaxFileBytes)
104 }
105 //
106 return nil
107}
108
109func zipit(source string, target io.Writer) error {
110 archive := zip.NewWriter(target)
111
112 info, err := os.Stat(source)
113 if err != nil {
114 return nil
115 }
116
117 var baseDir string
118 if info.IsDir() {
119 baseDir = filepath.Base(source)
120 }
121
122 filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
123 if err != nil {
124 return err
125 }
126
127 header, err := zip.FileInfoHeader(info)
128 if err != nil {
129 return err
130 }
131
132 if baseDir != "" {
133 header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source))
134 }
135
136 if info.IsDir() {
137 header.Name += "/"
138 } else {
139 header.Method = zip.Deflate
140 }
141
142 writer, err := archive.CreateHeader(header)
143 if err != nil {
144 return err
145 }
146
147 if info.IsDir() {
148 return nil
149 }
150
151 file, err := os.Open(path)
152 if err != nil {
153 return err
154 }
155 defer file.Close()
156 _, err = io.Copy(writer, file)
157 return err
158 })
159
160 archive.Close()
161
162 return err
163}