-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
229 lines (194 loc) · 5.97 KB
/
main.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
package main
import (
"flag"
"fmt"
"github.com/cratonica/trayhost"
"github.com/deet/picturelife-experimental-uploader/local"
"github.com/deet/picturelife-experimental-uploader/web"
"log"
"os"
"path/filepath"
"runtime"
"sync"
"time"
)
var hostFlag = flag.String("host", "http://localhost", "host to test")
var portFlag = flag.String("port", "3000", "port number on host")
var envFlag = flag.String("env", "production", "blank (specify host and port), production, or staging")
var clientfileFlag = flag.String("clientfile", "client.json", "Path to client credentials JSON file. Needs to be a JSON object with two string values: ClientId and ClientSecret")
var concurrentUploadsFlag = flag.Int("concurrent", 4, "maximum number of concurrent uploads")
var watchFlag = flag.Bool("watch", false, "watch a directory instead of uploading it immediately")
var configFlag = flag.Bool("config", false, "enable config mode")
var uploadRawFlag = flag.String("upload-raw", "", "upload RAW images?")
var uploadImagesFlag = flag.String("upload-images", "", "upload images?")
var uploadVideosFlag = flag.String("upload-videos", "", "upload videos?")
var guiFlag = flag.Bool("gui", true, "Enable GUI in CLI mode")
func init() {
flag.Parse()
}
func processUploads(appState *local.State, mainWg *sync.WaitGroup) {
defer mainWg.Done()
// Setup concurrency limiting channel
for i := 0; i < *concurrentUploadsFlag; i++ {
appState.MaxUploadsChan <- 1
}
log.Println("Concurrent uploads:", *concurrentUploadsFlag)
var uploadWg sync.WaitGroup
watchHappening, directHappening := true, true
for {
if !watchHappening && !directHappening {
log.Println("Waiting for upload routines to finish")
uploadWg.Wait()
return
}
select {
case incomingFile, watchOk := <-appState.WatchFileChan:
if watchOk {
<-appState.MaxUploadsChan
uploadWg.Add(1)
go appState.HandleFile(incomingFile, &uploadWg)
} else {
//log.Println("Watch channel is closed")
watchHappening = false
}
case incomingFile, directOk := <-appState.DirectFileChan:
if directOk {
<-appState.MaxUploadsChan
uploadWg.Add(1)
go appState.HandleFile(incomingFile, &uploadWg)
} else {
//log.Println("Direct channel closed")
directHappening = false
}
}
time.Sleep(10 * time.Millisecond)
}
}
func configApiConnect(appState *local.State) {
switch *envFlag {
case "production":
log.Println("USING PRODUCTION API")
appState.Api.Host = "https://api.picturelife.com"
appState.Api.ServicesHost = "https://services.picturelife.com"
case "staging":
appState.Api.Host = "https://api-staging.picturelife.com"
appState.Api.ServicesHost = "https://services-staging.picturelife.com"
case "development":
appState.Api.Host = "http://localhost"
appState.Api.ServicesHost = "http://localhost"
appState.Api.Port = "3000"
appState.Api.ServicesPort = "3001"
default:
panic("No environment set")
}
}
func configState(appState *local.State) {
if *uploadRawFlag != "" {
if *uploadRawFlag == "true" {
appState.UploadRaw = true
} else if *uploadRawFlag == "false" {
appState.UploadRaw = false
}
}
if *uploadImagesFlag != "" {
if *uploadImagesFlag == "true" {
appState.UploadImages = true
} else if *uploadImagesFlag == "false" {
appState.UploadImages = false
}
}
if *uploadVideosFlag != "" {
if *uploadVideosFlag == "true" {
appState.UploadVideo = true
} else if *uploadVideosFlag == "false" {
appState.UploadVideo = false
}
}
appState.Save()
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
runtime.LockOSThread()
go func() {
var appState local.State
filePath := flag.Arg(0)
statePath := fmt.Sprintf("data/data_%s.json", *envFlag)
appState = local.NewState(statePath)
if *configFlag {
configState(&appState)
if filePath == "" {
return
}
}
appState.Load()
configApiConnect(&appState)
credentialsErr := appState.Api.LoadClientCredentials(*clientfileFlag)
if credentialsErr != nil {
panic("API CREDENTIALS ARE REQUIRED")
}
appState.UpdateToken()
appState.Save()
log.Println("Have token:", appState.Api.AccessToken.Token)
appState.WatchFileChan = make(chan local.File, 1)
appState.DirectFileChan = make(chan local.File, 1)
appState.MaxUploadsChan = make(chan int, *concurrentUploadsFlag)
var mainWg sync.WaitGroup
mainWg.Add(1)
go processUploads(&appState, &mainWg)
if filePath == "" {
fmt.Printf("\nGUI MODE\n\n")
fmt.Println("Visit: http://localhost:7111/ in your web browser.")
fmt.Printf("\n\n")
// This should be started after launching the upload routines
go web.StartWebUi(&appState)
appState.UpdateDirectoryWatchers()
appState.UploadWatchedDirectories()
} else {
fmt.Printf("\nCLI MODE\n\n")
filePath, err := filepath.Abs(filePath)
if err != nil {
panic("Could not determine absolute file path.")
}
passedFile, err := os.Open(filePath)
if err != nil {
panic("Could not check path.")
}
if *guiFlag {
fmt.Println("GUI enabled. Visit: http://localhost:7111/ in your web browser.")
go web.StartWebUi(&appState)
}
if *watchFlag {
appState.WatchFilesystem(filePath)
} else {
log.Println("Not watching")
if fileInfo, _ := passedFile.Stat(); fileInfo.IsDir() {
log.Println("Passed directory")
mainWg.Add(1)
go func() {
log.Println("Trying to upload directory")
appState.UploadDirectory(filePath, appState.DirectFileChan)
mainWg.Done()
}()
} else {
log.Println("Passed file")
mainWg.Add(1)
go func() {
log.Println("Trying to upload file")
_, _, err := appState.UploadFile(filePath, appState.DirectFileChan)
if err != nil {
log.Println(err)
}
mainWg.Done()
}()
}
}
}
//appState.DoneChan = make(chan int)
log.Println("Waiting for main routines to finish")
mainWg.Wait()
}()
// Enter the host system's event loop
trayhost.EnterLoop("Open Picturelife", iconData)
// This is only reached once the user chooses the Exit menu item
fmt.Println("Exiting")
}