@@ -30,6 +30,7 @@ func (cmd *Command) Run(args []string) error {
30
30
fmt .Println (" sync" )
31
31
fmt .Println (" import" )
32
32
fmt .Println (" fetch" )
33
+ fl .PrintDefaults ()
33
34
}
34
35
fl .Parse (args )
35
36
subc := fl .Arg (0 )
@@ -55,7 +56,7 @@ func (cmd *Command) Run(args []string) error {
55
56
default :
56
57
return fmt .Errorf ("Invalid command: %q" , subc )
57
58
}
58
- return r .Run (fl .Args ())
59
+ return r .Run (fl .Args ()[ 1 :]) // consume first arg
59
60
}
60
61
61
62
/////
@@ -74,17 +75,18 @@ type dmfrImportCommand struct {
74
75
75
76
func (cmd * dmfrImportCommand ) Run (args []string ) error {
76
77
fl := flag .NewFlagSet ("import" , flag .ExitOnError )
78
+ fl .Usage = func () {
79
+ fmt .Println ("Usage: import [feedids...]" )
80
+ fl .PrintDefaults ()
81
+ }
77
82
fl .Var (& cmd .extensions , "ext" , "Include GTFS Extension" )
78
83
fl .IntVar (& cmd .workers , "workers" , 1 , "Worker threads" )
79
84
fl .StringVar (& cmd .dburl , "dburl" , os .Getenv ("DMFR_DATABASE_URL" ), "Database URL (default: $DMFR_DATABASE_URL)" )
80
85
fl .StringVar (& cmd .gtfsdir , "gtfsdir" , "." , "GTFS Directory" )
81
86
fl .StringVar (& cmd .coverdate , "date" , "" , "Service on date" )
82
87
fl .Uint64Var (& cmd .limit , "limit" , 0 , "Import at most n feeds" )
83
88
fl .BoolVar (& cmd .dryrun , "dryrun" , false , "Dry run; print feeds that would be imported and exit" )
84
- fl .Usage = func () {
85
- fmt .Println ("Usage: import [feedids...]" )
86
- }
87
- fl .Parse (args [1 :])
89
+ fl .Parse (args )
88
90
cmd .feedids = fl .Args ()
89
91
if cmd .adapter == nil {
90
92
writer := mustGetWriter (cmd .dburl , true )
@@ -146,33 +148,34 @@ func (cmd *dmfrImportCommand) Run(args []string) error {
146
148
return nil
147
149
}
148
150
var wg sync.WaitGroup
149
- jobs := make (chan int , len (qlookup ))
150
- results := make (chan FeedVersionImport , len (qlookup ))
151
+ jobs := make (chan ImportOptions , len (qlookup ))
152
+ results := make (chan ImportResult , len (qlookup ))
151
153
for w := 0 ; w < cmd .workers ; w ++ {
152
154
wg .Add (1 )
153
- go dmfrImportWorker (w , cmd .adapter , cmd . extensions , cmd . gtfsdir , jobs , results , & wg )
155
+ go dmfrImportWorker (w , cmd .adapter , jobs , results , & wg )
154
156
}
155
157
for fvid := range qlookup {
156
- jobs <- fvid
158
+ jobs <- ImportOptions { FeedVersionID : fvid , Directory : cmd . gtfsdir , Extensions : cmd . extensions }
157
159
}
158
160
close (jobs )
159
161
wg .Wait ()
160
162
close (results )
161
163
// Read out results
162
- for fviresult := range results {
163
- i := qlookup [fviresult .FeedVersionID ]
164
- if fviresult .Success {
165
- log .Info ("Feed %s (id:%d): FeedVersion %s (id:%d): success: count: %v errors: %v" , i .OnestopID , i .FeedID , i .SHA1 , fviresult .FeedVersionID , fviresult .EntityCount , fviresult .ErrorCount )
164
+ for result := range results {
165
+ fvid := result .FeedVersionImport .FeedVersionID
166
+ i := qlookup [fvid ]
167
+ if result .FeedVersionImport .Success {
168
+ log .Info ("Feed %s (id:%d): FeedVersion %s (id:%d): success: count: %v errors: %v" , i .OnestopID , i .FeedID , i .SHA1 , fvid , result .FeedVersionImport .EntityCount , result .FeedVersionImport .ErrorCount )
166
169
} else {
167
- log .Info ("Feed %s (id:%d): FeedVersion %s (id:%d): error: %s" , i .OnestopID , i .FeedID , i .SHA1 , i .SHA1 , fviresult .FeedVersionID , err .Error ())
170
+ log .Info ("Feed %s (id:%d): FeedVersion %s (id:%d): error: %s" , i .OnestopID , i .FeedID , i .SHA1 , i .SHA1 , result . FeedVersionImport .FeedVersionID , err .Error ())
168
171
}
169
172
}
170
173
return nil
171
174
}
172
175
173
- func dmfrImportWorker (id int , adapter gtdb.Adapter , exts [] string , gtfsdir string , jobs <- chan int , results chan <- FeedVersionImport , wg * sync.WaitGroup ) {
174
- for fvid := range jobs {
175
- fviresult , err := MainImportFeedVersion (adapter , fvid , exts , gtfsdir )
176
+ func dmfrImportWorker (id int , adapter gtdb.Adapter , jobs <- chan ImportOptions , results chan <- ImportResult , wg * sync.WaitGroup ) {
177
+ for opts := range jobs {
178
+ fviresult , err := MainImportFeedVersion (adapter , opts )
176
179
if err != nil {
177
180
log .Info ("Error: %s" , err .Error ())
178
181
}
@@ -184,24 +187,27 @@ func dmfrImportWorker(id int, adapter gtdb.Adapter, exts []string, gtfsdir strin
184
187
/////
185
188
186
189
type dmfrFetchCommand struct {
187
- workers int
188
- limit int
189
- dburl string
190
- gtfsdir string
191
- feedids []string
192
- adapter gtdb.Adapter
190
+ workers int
191
+ limit int
192
+ dburl string
193
+ gtfsdir string
194
+ allowdups bool
195
+ feedids []string
196
+ adapter gtdb.Adapter
193
197
}
194
198
195
199
func (cmd * dmfrFetchCommand ) Run (args []string ) error {
196
200
fl := flag .NewFlagSet ("fetch" , flag .ExitOnError )
197
201
fl .IntVar (& cmd .workers , "workers" , 1 , "Worker threads" )
198
- fl .IntVar (& cmd .limit , "limit" , 0 , "Fetch at most n feeds" )
199
- fl .StringVar (& cmd .dburl , "dburl" , os .Getenv ("DMFR_DATABASE_URL" ), "Database URL (default: $DMFR_DATABASE_URL) " )
202
+ fl .IntVar (& cmd .limit , "limit" , 0 , "Maximum number of feeds to fetch " )
203
+ fl .StringVar (& cmd .dburl , "dburl" , os .Getenv ("DMFR_DATABASE_URL" ), "Database URL" )
200
204
fl .StringVar (& cmd .gtfsdir , "gtfsdir" , "." , "GTFS Directory" )
205
+ fl .BoolVar (& cmd .allowdups , "allow-duplicate-contents" , false , "Allow duplicate internal SHA1 contents" )
201
206
fl .Usage = func () {
202
207
fmt .Println ("Usage: fetch [feedids...]" )
208
+ fl .PrintDefaults ()
203
209
}
204
- fl .Parse (args [ 1 :] )
210
+ fl .Parse (args )
205
211
feedids := fl .Args ()
206
212
if cmd .adapter == nil {
207
213
writer := mustGetWriter (cmd .dburl , true )
@@ -229,56 +235,68 @@ func (cmd *dmfrFetchCommand) Run(args []string) error {
229
235
if cmd .limit > 0 && cmd .limit < len (feeds ) {
230
236
feeds = feeds [:cmd .limit ]
231
237
}
238
+ osids := map [int ]string {}
239
+ for _ , feed := range feeds {
240
+ osids [feed .ID ] = feed .FeedID
241
+ }
232
242
///////////////
233
243
// Here we go
234
244
log .Info ("Fetching %d feeds" , len (feeds ))
235
245
fetchNew := 0
236
246
fetchFound := 0
237
247
fetchErrs := 0
238
248
var wg sync.WaitGroup
239
- jobs := make (chan Feed , len (feeds ))
249
+ jobs := make (chan FetchOptions , len (feeds ))
240
250
results := make (chan FetchResult , len (feeds ))
241
251
for w := 0 ; w < cmd .workers ; w ++ {
242
252
wg .Add (1 )
243
- go dmfrFetchWorker (w , cmd .adapter , cmd . gtfsdir , jobs , results , & wg )
253
+ go dmfrFetchWorker (w , cmd .adapter , jobs , results , & wg )
244
254
}
245
255
for _ , feed := range feeds {
246
- jobs <- feed
256
+ opts := FetchOptions {
257
+ FeedID : feed .ID ,
258
+ Directory : cmd .gtfsdir ,
259
+ IgnoreDuplicateContents : cmd .allowdups ,
260
+ }
261
+ jobs <- opts
247
262
}
248
263
close (jobs )
249
264
wg .Wait ()
250
265
close (results )
251
266
for fr := range results {
267
+ osid := osids [fr .FeedVersion .FeedID ]
252
268
if err != nil {
253
- log .Info ("Feed %s (id:%d): url: %s critical error: %s" , fr . OnestopID , fr .FeedVersion .FeedID , fr .FeedVersion .URL , err .Error ())
269
+ log .Info ("Feed %s (id:%d): url: %s critical error: %s" , osid , fr .FeedVersion .FeedID , fr .FeedVersion .URL , err .Error ())
254
270
fetchErrs ++
255
271
} else if fr .FetchError != nil {
256
- log .Info ("Feed %s (id:%d): url: %s fetch error: %s" , fr . OnestopID , fr .FeedVersion .FeedID , fr .FeedVersion .URL , fr .FetchError .Error ())
272
+ log .Info ("Feed %s (id:%d): url: %s fetch error: %s" , osid , fr .FeedVersion .FeedID , fr .FeedVersion .URL , fr .FetchError .Error ())
257
273
fetchErrs ++
258
- } else if fr .Found {
259
- log .Info ("Feed %s (id:%d): url: %s found: %s (id:%d)" , fr .OnestopID , fr .FeedVersion .FeedID , fr .FeedVersion .URL , fr .FeedVersion .SHA1 , fr .FeedVersion .ID )
274
+ } else if fr .FoundSHA1 {
275
+ log .Info ("Feed %s (id:%d): url: %s found zip sha1: %s (id:%d)" , osid , fr .FeedVersion .FeedID , fr .FeedVersion .URL , fr .FeedVersion .SHA1 , fr .FeedVersion .ID )
276
+ fetchFound ++
277
+ } else if fr .FoundDirSHA1 {
278
+ log .Info ("Feed %s (id:%d): url: %s found contents sha1: %s (id:%d)" , osid , fr .FeedVersion .FeedID , fr .FeedVersion .URL , fr .FeedVersion .SHA1Dir , fr .FeedVersion .ID )
260
279
fetchFound ++
261
280
} else {
262
- log .Info ("Feed %s (id:%d): url: %s new: %s (id:%d)" , fr . OnestopID , fr .FeedVersion .FeedID , fr .FeedVersion .URL , fr .FeedVersion .SHA1 , fr .FeedVersion .ID )
281
+ log .Info ("Feed %s (id:%d): url: %s new: %s (id:%d)" , osid , fr .FeedVersion .FeedID , fr .FeedVersion .URL , fr .FeedVersion .SHA1 , fr .FeedVersion .ID )
263
282
fetchNew ++
264
283
}
265
284
}
266
285
log .Info ("Existing: %d New: %d Errors: %d" , fetchFound , fetchNew , fetchErrs )
267
286
return nil
268
287
}
269
288
270
- func dmfrFetchWorker (id int , adapter gtdb.Adapter , gtfsdir string , jobs <- chan Feed , results chan <- FetchResult , wg * sync.WaitGroup ) {
271
- for feed := range jobs {
289
+ func dmfrFetchWorker (id int , adapter gtdb.Adapter , jobs <- chan FetchOptions , results chan <- FetchResult , wg * sync.WaitGroup ) {
290
+ for opts := range jobs {
272
291
var fr FetchResult
273
292
err := adapter .Tx (func (atx gtdb.Adapter ) error {
274
293
var fe error
275
- fr , fe = MainFetchFeed (atx , feed . ID , gtfsdir )
294
+ fr , fe = MainFetchFeed (atx , opts )
276
295
return fe
277
296
})
278
297
if err != nil {
279
298
fmt .Println ("Critical error:" , err )
280
299
}
281
- fr .OnestopID = feed .FeedID
282
300
results <- fr
283
301
}
284
302
wg .Done ()
@@ -294,11 +312,12 @@ type dmfrSyncCommand struct {
294
312
295
313
func (cmd * dmfrSyncCommand ) Run (args []string ) error {
296
314
fl := flag .NewFlagSet ("sync" , flag .ExitOnError )
297
- fl .StringVar (& cmd .dburl , "dburl" , os .Getenv ("DMFR_DATABASE_URL" ), "Database URL (default: $DMFR_DATABASE_URL)" )
298
315
fl .Usage = func () {
299
316
fmt .Println ("Usage: sync <filenames...>" )
317
+ fl .PrintDefaults ()
300
318
}
301
- fl .Parse (args [1 :])
319
+ fl .StringVar (& cmd .dburl , "dburl" , os .Getenv ("DMFR_DATABASE_URL" ), "Database URL (default: $DMFR_DATABASE_URL)" )
320
+ fl .Parse (args )
302
321
cmd .filenames = fl .Args ()
303
322
if cmd .adapter == nil {
304
323
writer := mustGetWriter (cmd .dburl , true )
@@ -319,6 +338,7 @@ func (dmfrValidateCommand) Run(args []string) error {
319
338
fl := flag .NewFlagSet ("validate" , flag .ExitOnError )
320
339
fl .Usage = func () {
321
340
fmt .Println ("Usage: validate <filenames...>" )
341
+ fl .PrintDefaults ()
322
342
}
323
343
fl .Parse (args )
324
344
if fl .NArg () == 0 {
0 commit comments