...
1
2
3
4
5 package upload
6
7 import (
8 "bytes"
9 "net/http"
10 "os"
11 "path/filepath"
12 "regexp"
13 "strings"
14 "time"
15 )
16
17 var (
18 dateRE = regexp.MustCompile(`(\d\d\d\d-\d\d-\d\d)[.]json$`)
19 dateFormat = time.DateOnly
20
21 )
22
23
24
25 func (u *uploader) uploadReportDate(fname string) time.Time {
26 match := dateRE.FindStringSubmatch(fname)
27 if match == nil || len(match) < 2 {
28 u.logger.Printf("malformed report name: missing date: %q", filepath.Base(fname))
29 return time.Time{}
30 }
31 d, err := time.Parse(dateFormat, match[1])
32 if err != nil {
33 u.logger.Printf("malformed report name: bad date: %q", filepath.Base(fname))
34 return time.Time{}
35 }
36 return d
37 }
38
39 func (u *uploader) uploadReport(fname string) {
40 thisInstant := u.startTime
41
42
43
44 today := thisInstant.Format(time.DateOnly)
45 match := dateRE.FindStringSubmatch(fname)
46 if match == nil || len(match) < 2 {
47 u.logger.Printf("Report name %q missing date", filepath.Base(fname))
48 } else if match[1] > today {
49 u.logger.Printf("Report date for %q is later than today (%s)", filepath.Base(fname), today)
50 return
51 }
52 buf, err := os.ReadFile(fname)
53 if err != nil {
54 u.logger.Printf("%v reading %s", err, fname)
55 return
56 }
57 if u.uploadReportContents(fname, buf) {
58
59 }
60 }
61
62
63 func (u *uploader) uploadReportContents(fname string, buf []byte) bool {
64 fdate := strings.TrimSuffix(filepath.Base(fname), ".json")
65 fdate = fdate[len(fdate)-len(time.DateOnly):]
66
67 newname := filepath.Join(u.dir.UploadDir(), fdate+".json")
68
69
70 {
71 lockname := newname + ".lock"
72 lockfile, err := os.OpenFile(lockname, os.O_CREATE|os.O_EXCL, 0666)
73 if err != nil {
74 u.logger.Printf("Failed to acquire lock %s: %v", lockname, err)
75 return false
76 }
77 _ = lockfile.Close()
78 defer os.Remove(lockname)
79 }
80
81 if _, err := os.Stat(newname); err == nil {
82
83
84 u.logger.Printf("After acquire: report already uploaded")
85 _ = os.Remove(fname)
86 return false
87 }
88
89 endpoint := u.uploadServerURL + "/" + fdate
90 b := bytes.NewReader(buf)
91 resp, err := http.Post(endpoint, "application/json", b)
92 if err != nil {
93 u.logger.Printf("Error upload %s to %s: %v", filepath.Base(fname), endpoint, err)
94 return false
95 }
96
97 if resp.StatusCode != 200 {
98 u.logger.Printf("Failed to upload %s to %s: %s", filepath.Base(fname), endpoint, resp.Status)
99 if resp.StatusCode >= 400 && resp.StatusCode < 500 {
100 err := os.Remove(fname)
101 if err == nil {
102 u.logger.Printf("Removed local/%s", filepath.Base(fname))
103 } else {
104 u.logger.Printf("Error removing local/%s: %v", filepath.Base(fname), err)
105 }
106 }
107 return false
108 }
109
110 if err := os.WriteFile(newname, buf, 0644); err == nil {
111 os.Remove(fname)
112 }
113 u.logger.Printf("Uploaded %s to %q", fdate+".json", endpoint)
114 return true
115 }
116
View as plain text