forked from lmika/oaipmh
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcmdlist.go
187 lines (149 loc) · 5.35 KB
/
cmdlist.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
package main
import (
"fmt"
"os"
"flag"
"time"
)
// ---------------------------------------------------------------------------------------------------
// List commands
type ListCommand struct {
Ctx *Context
setName *string
beforeDate *string
afterDate *string
flagDetailed *bool
firstResult *int
maxResults *int
listRecords *bool
showDeleted *bool
onlyShowDeleted *bool
}
type listingFn func(listArgs ListIdentifierArgs, firstResult int, maxResults int, callback func(res *HeaderResult) bool) error
// Attempt to parse a date string and return it as a heap allocated time.Time.
// If the string is empty, returns nil. If there was an error parsing the string,
// the program dies
func parseDateString(dateString string) *time.Time {
if (dateString != "") {
parsedTime, err := time.ParseInLocation(DateFormat, dateString, time.Local)
if (err != nil) {
die("Invalid date: " + err.Error())
}
heapAllocTime := new(time.Time)
*heapAllocTime = parsedTime
return heapAllocTime
} else {
return nil
}
}
// Get list identifier arguments
func (lc *ListCommand) genListIdentifierArgsFromCommandLine() ListIdentifierArgs {
var set string
// Get the set. If '-s' is not provided and a provider is used, use the default set.
// Otherwise, search all sets. This implies that if using a provider, '-s ""' must be
// used to search all sets.
set = *(lc.setName)
if set == "" {
set = lc.Ctx.Provider.Set
} else if set == "*" {
set = ""
}
args := ListIdentifierArgs{
Set: set,
From: parseDateString(*(lc.afterDate)),
Until: parseDateString(*(lc.beforeDate)),
}
return args
}
// Returns the appropriate listing function.
func (lc *ListCommand) getListingFn() listingFn {
if *(lc.listRecords) {
return listingFn(lc.Ctx.Session.ListIdentifiersUsingListRecords)
} else {
return listingFn(lc.Ctx.Session.ListIdentifiers)
}
}
// Returns true if the specific header should be shown. This uses the options specified
// by the user.
func (lc *ListCommand) configuredToShowRecord(header *HeaderResult) bool {
if *lc.showDeleted {
return true
} else if *lc.onlyShowDeleted {
return header.Deleted
} else {
return !header.Deleted
}
}
// List the identifiers from a provider
func (lc *ListCommand) listIdentifiers() {
var deletedCount int = 0
args := lc.genListIdentifierArgsFromCommandLine()
listFn := lc.getListingFn()
err := listFn(args, *(lc.firstResult), *(lc.maxResults), func(res *HeaderResult) bool {
if lc.configuredToShowRecord(res) {
fmt.Printf("%s\n", res.Identifier())
}
if (res.Deleted) {
deletedCount += 1
}
return true
})
if (err == nil) {
if (deletedCount > 0) {
if *(lc.showDeleted) {
// If onlyShowDeleted is active, the user expects the deleted records displayed so
// don't bother showing anything.
fmt.Fprintf(os.Stderr, "oaipmh: %d deleted record(s) displayed\n", deletedCount)
} else if !*lc.onlyShowDeleted {
fmt.Fprintf(os.Stderr, "oaipmh: %d deleted record(s) not displayed\n", deletedCount)
}
}
} else {
fmt.Fprintf(os.Stderr, "oaipmh: %s\n", err.Error())
}
}
// List the identifiers in detail from a provider
func (lc *ListCommand) listIdentifiersInDetail() {
var activeCount int = 0
var deletedCount int = 0
args := lc.genListIdentifierArgsFromCommandLine()
listFn := lc.getListingFn()
listFn(args, *(lc.firstResult), *(lc.maxResults), func(res *HeaderResult) bool {
if (res.Deleted) {
deletedCount++
} else {
activeCount++
}
if lc.configuredToShowRecord(res) {
if (res.Deleted) {
fmt.Printf("D ")
} else {
fmt.Printf(". ")
}
fmt.Printf("%-20s ", res.Header.SetSpec[0])
fmt.Printf("%-20s ", res.Header.DateStamp.String())
fmt.Printf("%s\n", res.Identifier())
}
return true
})
fmt.Fprintf(os.Stderr, "%d records: %d active, %d deleted\n", activeCount + deletedCount, activeCount, deletedCount)
}
func (lc *ListCommand) Flags(fs *flag.FlagSet) *flag.FlagSet {
lc.setName = fs.String("s", "", "Select records from this set")
lc.beforeDate = fs.String("B", "", "Select records that were updated before date (YYYY-MM-DD)")
lc.afterDate = fs.String("A", "", "Select records that were updated after date (YYYY-MM-DD)")
lc.flagDetailed = fs.Bool("l", false, "Use detailed listing format")
lc.showDeleted = fs.Bool("d", false, "Show deleted records, along with active ones")
lc.onlyShowDeleted = fs.Bool("D", false, "Only show deleted records")
lc.firstResult = fs.Int("f", 0, "Index of first record to retrieve")
lc.maxResults = fs.Int("c", 100000, "Maximum number of records to retrieve")
lc.listRecords = fs.Bool("R", false, "Use ListRecord instead of ListIdentifier")
return fs
}
func (lc *ListCommand) Run(args []string) {
if *(lc.flagDetailed) {
lc.listIdentifiersInDetail()
} else {
lc.listIdentifiers()
}
}