dsu 2.2.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/Gemfile.lock +2 -2
- data/README.md +64 -10
- data/lib/dsu/cli.rb +5 -0
- data/lib/dsu/models/entry_group.rb +7 -3
- data/lib/dsu/presenters/base_presenter_ex.rb +26 -0
- data/lib/dsu/presenters/export/all_presenter.rb +47 -0
- data/lib/dsu/presenters/export/dates_presenter.rb +56 -0
- data/lib/dsu/presenters/export/messages.rb +31 -0
- data/lib/dsu/presenters/export/service_callable.rb +20 -0
- data/lib/dsu/services/entry_group/exporter_service.rb +63 -0
- data/lib/dsu/subcommands/delete.rb +1 -1
- data/lib/dsu/subcommands/export.rb +59 -0
- data/lib/dsu/subcommands/theme.rb +2 -2
- data/lib/dsu/support/color_themable.rb +5 -3
- data/lib/dsu/version.rb +1 -1
- data/lib/dsu/views/export.rb +26 -0
- data/lib/locales/en/commands.yml +5 -1
- data/lib/locales/en/subcommands.yml +77 -7
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dac644f91b9d952fc3ef289c0ed147f428fcb485418af0e93a64c1478670bf15
|
4
|
+
data.tar.gz: c605401ea6b2917af9a6c96617fcc4c2b7b57963282654e0e189ec57e3f5dc05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbbb3642b22b661b68c14dab8236b553cd5dc4a4c9be80fb6fdce07dc344276a235f68b8593cab8279a09ecf68827c0c1c86283276f89440c5dc9f166c95a57c
|
7
|
+
data.tar.gz: a0727206ac2d647abafb20975eb88b396e1ff5abe37e98ae5f4502a99dbe43f19767d51a5611155bb1848dace96c17ba5d235ff0a1ca9ded099f9f44634d8a89
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
## [2.3.0] 2023-12-25
|
2
|
+
|
3
|
+
Enhancements
|
4
|
+
|
5
|
+
- Added `dsu export` command to export all DSU entries or DSU entries between two given dates. Entries are written to a comma-delimited csv file located in your OS temp folder. For more information see `dsu help export` or the README.md file.
|
6
|
+
|
7
|
+
Changes
|
8
|
+
|
9
|
+
- Updated README.md to reflect new `dsu export` command.
|
10
|
+
- Fix misspelling of "cancelable" to "cancellable" in the codebase.
|
11
|
+
- Update ruby gems.
|
12
|
+
|
13
|
+
## [2.2.2] 2023-12-23
|
14
|
+
|
15
|
+
Changes
|
16
|
+
|
17
|
+
- README.md updates.
|
18
|
+
|
19
|
+
Bug fix
|
20
|
+
|
21
|
+
- Fix `dsu config` shortcut command mapping bug that caused `dsu c` to display `dsu delete` command help instead of `dsu config` command help.
|
22
|
+
|
1
23
|
## [2.2.1] 2023-12-23
|
2
24
|
|
3
25
|
Changes
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dsu (2.
|
4
|
+
dsu (2.3.0)
|
5
5
|
activemodel (>= 7.0.8, < 8.0)
|
6
6
|
activesupport (>= 7.0.8, < 8.0)
|
7
7
|
colorize (>= 0.8.1, < 1.0)
|
@@ -98,7 +98,7 @@ GEM
|
|
98
98
|
rubocop (~> 1.41)
|
99
99
|
rubocop-factory_bot (2.24.0)
|
100
100
|
rubocop (~> 1.33)
|
101
|
-
rubocop-performance (1.20.
|
101
|
+
rubocop-performance (1.20.1)
|
102
102
|
rubocop (>= 1.48.1, < 2.0)
|
103
103
|
rubocop-ast (>= 1.30.0, < 2.0)
|
104
104
|
rubocop-rspec (2.25.0)
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# `dsu`- Streamline Your Daily Stand-Up Meeting Participation!
|
2
2
|
|
3
3
|
[![Ruby](https://github.com/gangelo/dsu/actions/workflows/ruby.yml/badge.svg)](https://github.com/gangelo/dsu/actions/workflows/ruby.yml)
|
4
|
-
[![GitHub version](http://badge.fury.io/gh/gangelo%2Fdsu.svg)](https://badge.fury.io/gh/gangelo%2Fdsu)
|
5
|
-
[![Gem Version](https://badge.fury.io/rb/dsu.svg)](https://badge.fury.io/rb/dsu)
|
4
|
+
[![GitHub version](http://badge.fury.io/gh/gangelo%2Fdsu.svg?refresh=2)](https://badge.fury.io/gh/gangelo%2Fdsu)
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/dsu.svg?refresh=2)](https://badge.fury.io/rb/dsu)
|
6
6
|
[![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://www.rubydoc.info/gems/dsu/)
|
7
7
|
[![Report Issues](https://img.shields.io/badge/report-issues-red.svg)](https://github.com/gangelo/dsu/issues)
|
8
8
|
[![License](http://img.shields.io/badge/license-MIT-yellowgreen.svg)](#license)
|
@@ -42,6 +42,7 @@ Commands:
|
|
42
42
|
dsu config|c SUBCOMMAND # Manage configuration...
|
43
43
|
dsu delete|d SUBCOMMAND # Delete DSU entries...
|
44
44
|
dsu edit|e SUBCOMMAND # Edit DSU entries...
|
45
|
+
dsu export|x SUBCOMMAND # Export DSU entries...
|
45
46
|
dsu help [COMMAND] # Describe available...
|
46
47
|
dsu info|i # Displays information...
|
47
48
|
dsu list|l SUBCOMMAND # Displays DSU entries...
|
@@ -58,8 +59,9 @@ The folowing section outlines how to use the `dsu` gem.
|
|
58
59
|
## Adding DSU Entries
|
59
60
|
The next thing you may want to do is `add` some DSU activities (entries) for a particular day:
|
60
61
|
|
61
|
-
|
62
|
-
|
62
|
+
`$ dsu add [OPTIONS] DESCRIPTION`
|
63
|
+
|
64
|
+
`$ dsu a [OPTIONS] DESCRIPTION`
|
63
65
|
|
64
66
|
Adding DSU entry using this command will _add_ the DSU entry for the given day or date, and then _display_ the DSU entries for that day or date.
|
65
67
|
|
@@ -69,18 +71,21 @@ Adding DSU entry using this command will _add_ the DSU entry for the given day o
|
|
69
71
|
If you need to add a DSU entry for the current day (today), you can use the `-n`|`--today` option. Today (`-n`) is the default; therefore, the `-n` flag is optional if you want to add a DSU entry for the _current day_ (today). For example, the below commands will both accomplish the same thing:
|
70
72
|
|
71
73
|
`$ dsu add [-n|--today] "Pair with John on ticket IN-12345"`
|
74
|
+
|
72
75
|
`$ dsu a "Pair with John on ticket IN-12345"`
|
73
76
|
|
74
77
|
### Yesterday
|
75
78
|
If for some reason you need to add a DSU entry for yesterday, you can use the `-y`| `--yesterday` option. Both of the below commands accomplish the same thing:
|
76
79
|
|
77
80
|
`$ dsu add --yesterday "Pick up ticket IN-12345"`
|
81
|
+
|
78
82
|
`$ dsu a -y "Pick up ticket IN-12345"`
|
79
83
|
|
80
84
|
### Tomorrow
|
81
85
|
If you need to add a DSU entry for tomorrow, you can use the `-t`|`--tomorrow` option:
|
82
86
|
|
83
87
|
`$ dsu add --tomorrow "Pick up ticket IN-12345"`
|
88
|
+
|
84
89
|
`$ dsu a -t "Pick up ticket IN-12345"`
|
85
90
|
|
86
91
|
### Miscellaneous Date
|
@@ -91,6 +96,7 @@ Both of the below examples will accomplish the same thing, assuming the current
|
|
91
96
|
**NOTE:** When **including year**, dates must be entered in `YYYY/MM/DD` format.
|
92
97
|
|
93
98
|
`$ dsu add --date 2023/12/31 "Attend New Years Coffee Meet & Greet"`
|
99
|
+
|
94
100
|
`$ dsu a -d 12/31 "Attend New Years Coffee Meet & Greet"`
|
95
101
|
|
96
102
|
See the [Dates](#dates) section for more information on acceptable DATE formats used by `dsu`.
|
@@ -100,13 +106,13 @@ You can display DSU entries for a particular day or date using any of the follow
|
|
100
106
|
|
101
107
|
- `$ dsu list today`
|
102
108
|
- `$ dsu l n` # Equivalent to the above, only using shortcuts
|
103
|
-
- `$ dsu list tomorrow
|
109
|
+
- `$ dsu list tomorrow`
|
104
110
|
- `$ dsu l t` # Equivalent to the above, only using shortcuts
|
105
|
-
- `$ dsu list yesterday
|
111
|
+
- `$ dsu list yesterday`
|
106
112
|
- `$ dsu l y` # Equivalent to the above, only using shortcuts
|
107
|
-
- `$ dsu list date
|
113
|
+
- `$ dsu list date DATE|MNEMONIC`
|
108
114
|
- `$ dsu l d DATE|MNEMONIC` # Equivalent to the above, only using shortcuts
|
109
|
-
- `$ dsu list dates
|
115
|
+
- `$ dsu list dates OPTIONS`
|
110
116
|
- `$ dsu l dd OPTIONS` # Equivalent to the above, only using shortcuts
|
111
117
|
|
112
118
|
See the [Dates](#dates) section for more information on acceptable DATE formats used by `dsu`.
|
@@ -118,6 +124,7 @@ See the [Mnemonics](#mnemonics) section for more information on acceptable MNEMO
|
|
118
124
|
The following displays the entries for "Today", where `Time.now == '2023-05-06 08:54:57.6861 -0400'`
|
119
125
|
|
120
126
|
`$ dsu list today`
|
127
|
+
|
121
128
|
`$ dsu l t`
|
122
129
|
```shell
|
123
130
|
#=>
|
@@ -130,7 +137,9 @@ Friday, (Yesterday) 2023-05-05
|
|
130
137
|
```
|
131
138
|
|
132
139
|
`$ dsu list date 5/7/2023`
|
140
|
+
|
133
141
|
`$ dsu list d 2023/7/5`
|
142
|
+
|
134
143
|
`$ dsu l d 7/5` # When omitting YYYY, MM/DD is assumed
|
135
144
|
|
136
145
|
```shell
|
@@ -151,22 +160,27 @@ For more information, see the [Mnemonics](#mnemonics) section for more informati
|
|
151
160
|
|
152
161
|
##### Display the DSU entries for the last 3 days
|
153
162
|
`$ dsu list dates --from yesterday --to -2`
|
163
|
+
|
154
164
|
`$ dsu l dd -f y -t -2`
|
155
165
|
|
156
166
|
##### Display the DSU entries for 1/1 to 1/4 for the current year
|
157
167
|
`$ dsu list dates --from 1/1 --to +3`
|
168
|
+
|
158
169
|
`$ dsu l dd -f 1/1 -t +3`
|
159
170
|
|
160
171
|
##### Display the DSU entries for 1/2 to 1/5
|
161
172
|
`$ dsu list dates --from 1/5 --to -3`
|
173
|
+
|
162
174
|
`$ dsu l dd -f 1/5 -t -3`
|
163
175
|
|
164
176
|
##### Display the DSU entries for the last week
|
165
177
|
`$ dsu list dates --from today --to -6`
|
178
|
+
|
166
179
|
`$ dsu l dd -f n -t -6`
|
167
180
|
|
168
181
|
##### Display the DSU entries back 1 week from yesterday's date
|
169
182
|
`$ dsu list dates --from -7 --to +6`
|
183
|
+
|
170
184
|
`$ dsu l dd -f -7 -t +6`
|
171
185
|
|
172
186
|
**NOTE:** **The above example is silly,** but it illustrates the fact that you can use relative mnemonics for both `--from` and `--to` options. While you *can* use relative mnemonics for both the `--from` and `--to` options, there is usually a more intuitive way.
|
@@ -176,6 +190,7 @@ For example:
|
|
176
190
|
This can be accomplished MUCH easier by using the `yesterday` mnemonic. This will display the DSU entries back 1 week from yesterday's date.
|
177
191
|
|
178
192
|
`$ dsu list dates --from yesterday --to -6`
|
193
|
+
|
179
194
|
`$ dsu l dd -f y -t -6`
|
180
195
|
|
181
196
|
## Browsing DSU Entries
|
@@ -214,6 +229,7 @@ If no entries exist for the DSU date, the editor will open and allow you to add
|
|
214
229
|
The following will edit your DSU entry group entries for "Today", where `Time.now == '2023-05-09 12:13:45.8273 -0400'`. Simply follow the directions in the editor file, then save and close your editor to apply the changes:
|
215
230
|
|
216
231
|
`$ dsu edit today`
|
232
|
+
|
217
233
|
`$ dsu e n`
|
218
234
|
|
219
235
|
```shell
|
@@ -257,20 +273,22 @@ from: Interative planning meeting 11:00AM.
|
|
257
273
|
|
258
274
|
#### Add an Entry
|
259
275
|
|
260
|
-
Simply type a new entry on a separate line.
|
276
|
+
Simply type a new entry on a separate line.
|
261
277
|
|
262
278
|
For example...
|
263
279
|
```
|
264
280
|
Add me to this entry group.
|
265
281
|
```
|
266
282
|
|
283
|
+
**NOTE:** Any entry that starts with a `#` in the first character position will be ignored.*
|
284
|
+
|
267
285
|
#### Delete an Entry
|
268
286
|
|
269
287
|
Simply delete the entry.
|
270
288
|
|
271
289
|
For example...
|
272
290
|
```
|
273
|
-
# Delete this
|
291
|
+
# Delete this entry from the editor file
|
274
292
|
from: Interative planning meeting 11:00AM.
|
275
293
|
to: <deleted>
|
276
294
|
```
|
@@ -315,6 +333,7 @@ See the [Mnemonics](#mnemonics) section for more information on acceptable MNEMO
|
|
315
333
|
The following example deletes the entry group and *all* entries for today's date.
|
316
334
|
|
317
335
|
`$ dsu delete today`
|
336
|
+
|
318
337
|
`$ dsu d n`
|
319
338
|
```shell
|
320
339
|
#=>
|
@@ -324,6 +343,7 @@ Deleted 1 entry group(s).
|
|
324
343
|
The following example deletes the entry group and *all* entries for yesterday's date.
|
325
344
|
|
326
345
|
`$ dsu delete yesterday`
|
346
|
+
|
327
347
|
`$ dsu d y`
|
328
348
|
```shell
|
329
349
|
#=>
|
@@ -333,6 +353,7 @@ Deleted 1 entry group(s).
|
|
333
353
|
The following example deletes the entry group and *all* entries for tomorrow's date.
|
334
354
|
|
335
355
|
`$ dsu delete tomorrow`
|
356
|
+
|
336
357
|
`$ dsu d t`
|
337
358
|
```shell
|
338
359
|
#=>
|
@@ -343,6 +364,7 @@ Deleted 1 entry group(s).
|
|
343
364
|
The following deletes the entry group and all entries for 12/17 of the current year.
|
344
365
|
|
345
366
|
`$ dsu delete date 12/17`
|
367
|
+
|
346
368
|
`$ dsu d d 12/17`
|
347
369
|
```shell
|
348
370
|
#=>
|
@@ -353,12 +375,44 @@ Deleted 1 entry group(s)
|
|
353
375
|
The following deletes the entry group and all entries for the past week, starting from today (12/17/2023).
|
354
376
|
|
355
377
|
`$ dsu delete dates --from today --to -6`
|
378
|
+
|
356
379
|
`$ dsu d dd -f n -t -6`
|
357
380
|
```shell
|
358
381
|
#=>
|
359
382
|
Are you sure you want to delete all the entries for 2023-12-11 thru 2023-12-17 (7 entry groups)? [y/N]> y
|
360
383
|
Deleted 7 entry group(s).
|
361
384
|
```
|
385
|
+
|
386
|
+
## Exporting DSU Entries
|
387
|
+
|
388
|
+
Some ingenious soul may want to write a utility at some point, so `dsu` provides the means to export its data into a `csv` file for convenience. Of course, if you feel so inclined, you may also use the `dsu` entry group `json` files directly. The `dsu` entry group `json` files can be located by running the `dsu info` command, and locating the "Entries folder" value.
|
389
|
+
|
390
|
+
If you want to use a `csv` file, you can export `dsu` entries to a `csv` file by using any of the following commands:
|
391
|
+
|
392
|
+
- `$ dsu export all`
|
393
|
+
- `$ dsu x a` # Equivalent to the above, only using shortcuts
|
394
|
+
- `$ dsu export dates OPTIONS`
|
395
|
+
- `$ dsu x dd OPTIONS` # Equivalent to the above, only using shortcuts
|
396
|
+
|
397
|
+
**NOTE:** Each `export` command will prompt you to confirm the export. If confirmed, `dsu` will write a `csv` file to your operating systems temp folder, in the following format: `"dsu-<timestamp>-<from date>-thru-<to date>.csv"`:
|
398
|
+
|
399
|
+
Where:
|
400
|
+
- <timestamp> = '%Y%m%d%H%M%S'
|
401
|
+
- <from date> = the date of the earliest entry group exported (if `export all`) or the earliest date of the entry group dates to be exported (if `export dates`).
|
402
|
+
- <to date> = the date of the most resent entry group exported (if `export all`) or the most recent date of the entry group dates to be exported (if `export dates`).
|
403
|
+
-
|
404
|
+
### For example
|
405
|
+
|
406
|
+
The following command, when run on December 25, 2023, at 20:15:46...
|
407
|
+
|
408
|
+
`$ dsu export dates -f 1/1/1999 -t 12/23/2023`
|
409
|
+
|
410
|
+
...will export `dsu` entries for all Entry Groups that fall between the dates of January 1st, 1999 through December 23rd 2023 in the time zone it was executed, and write them to the following file:
|
411
|
+
|
412
|
+
`/var/folders/yv/5n77gtzn7z33ytwgr9mlbbrhf5rws6/T/dsu-20231225201546-1999-01-01-thru-2023-12-23.csv`
|
413
|
+
|
414
|
+
For more information, see `dsu` help (`$ dsu export` or `dsu help export`) for more information.
|
415
|
+
|
362
416
|
## Customizing the `dsu` Configuration File
|
363
417
|
To customize the `dsu` configuration file, you may follow the instructions outlined here. It is only recommended that you customize the `dsu` configuration file *only* if you are working with an official release (`n.n.n.n`).
|
364
418
|
|
data/lib/dsu/cli.rb
CHANGED
@@ -7,6 +7,7 @@ require_relative 'subcommands/browse'
|
|
7
7
|
require_relative 'subcommands/config'
|
8
8
|
require_relative 'subcommands/delete'
|
9
9
|
require_relative 'subcommands/edit'
|
10
|
+
require_relative 'subcommands/export'
|
10
11
|
require_relative 'subcommands/list'
|
11
12
|
require_relative 'subcommands/theme'
|
12
13
|
|
@@ -18,6 +19,7 @@ module Dsu
|
|
18
19
|
map I18n.t('commands.config.key_mappings') => :config
|
19
20
|
map I18n.t('commands.delete.key_mappings') => :delete
|
20
21
|
map I18n.t('commands.edit.key_mappings') => :edit
|
22
|
+
map I18n.t('commands.export.key_mappings') => :export
|
21
23
|
map I18n.t('commands.help.key_mappings') => :help
|
22
24
|
map I18n.t('commands.info.key_mappings') => :info
|
23
25
|
map I18n.t('commands.list.key_mappings') => :list
|
@@ -60,6 +62,9 @@ module Dsu
|
|
60
62
|
desc I18n.t('commands.edit.desc'), I18n.t('commands.edit.usage')
|
61
63
|
subcommand :edit, Subcommands::Edit
|
62
64
|
|
65
|
+
desc I18n.t('commands.export.desc'), I18n.t('commands.export.usage')
|
66
|
+
subcommand :export, Subcommands::Export
|
67
|
+
|
63
68
|
desc I18n.t('commands.theme.desc'), I18n.t('commands.theme.usage')
|
64
69
|
subcommand :theme, Subcommands::Theme
|
65
70
|
|
@@ -120,9 +120,7 @@ module Dsu
|
|
120
120
|
next unless entry_file_name.match?(ENTRIES_FILE_NAME_REGEX)
|
121
121
|
|
122
122
|
entry_date = File.basename(entry_file_name, '.*')
|
123
|
-
|
124
|
-
entry_group_hash = read!(file_path: file_path)
|
125
|
-
Services::EntryGroup::HydratorService.new(entry_group_hash: entry_group_hash).call
|
123
|
+
find time: Time.parse(entry_date)
|
126
124
|
end
|
127
125
|
end
|
128
126
|
|
@@ -167,6 +165,12 @@ module Dsu
|
|
167
165
|
end
|
168
166
|
end
|
169
167
|
|
168
|
+
def entry_groups(between:)
|
169
|
+
entry_group_times(between: between).filter_map do |time|
|
170
|
+
Models::EntryGroup.find(time: Time.parse(time))
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
170
174
|
def find(time:)
|
171
175
|
file_path = entries_path_for(time: time)
|
172
176
|
entry_group_hash = read!(file_path: file_path)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'delegate'
|
4
|
+
require_relative '../models/color_theme'
|
5
|
+
require_relative '../support/color_themable'
|
6
|
+
|
7
|
+
module Dsu
|
8
|
+
module Presenters
|
9
|
+
class BasePresenterEx
|
10
|
+
include Support::ColorThemable
|
11
|
+
|
12
|
+
def initialize(options: {})
|
13
|
+
@options = options || {}
|
14
|
+
@color_theme = Models::ColorTheme.find(theme_name: theme_name)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :color_theme, :options
|
20
|
+
|
21
|
+
def theme_name
|
22
|
+
@theme_name ||= options.fetch(:theme_name, Models::Configuration.new.theme_name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../models/entry_group'
|
4
|
+
require_relative '../../services/entry_group/exporter_service'
|
5
|
+
require_relative '../../support/ask'
|
6
|
+
require_relative '../base_presenter_ex'
|
7
|
+
require_relative 'messages'
|
8
|
+
require_relative 'service_callable'
|
9
|
+
|
10
|
+
module Dsu
|
11
|
+
module Presenters
|
12
|
+
module Export
|
13
|
+
class AllPresenter < BasePresenterEx
|
14
|
+
include Messages
|
15
|
+
include ServiceCallable
|
16
|
+
include Support::Ask
|
17
|
+
|
18
|
+
def render(response:)
|
19
|
+
return display_cancelled_message unless response
|
20
|
+
|
21
|
+
export_file_path = exporter_service_call
|
22
|
+
|
23
|
+
display_exported_message
|
24
|
+
display_exported_to_message(file_path: export_file_path)
|
25
|
+
end
|
26
|
+
|
27
|
+
def display_export_prompt
|
28
|
+
yes?(prompt_with_options(prompt: export_prompt, options: export_prompt_options))
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def entry_groups
|
34
|
+
@entry_groups ||= Models::EntryGroup.all
|
35
|
+
end
|
36
|
+
|
37
|
+
def export_prompt
|
38
|
+
I18n.t('subcommands.export.prompts.export_all_confirm', count: entry_groups.count)
|
39
|
+
end
|
40
|
+
|
41
|
+
def export_prompt_options
|
42
|
+
I18n.t('subcommands.export.prompts.options')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../models/entry_group'
|
4
|
+
require_relative '../../support/ask'
|
5
|
+
require_relative '../base_presenter_ex'
|
6
|
+
require_relative 'messages'
|
7
|
+
require_relative 'service_callable'
|
8
|
+
|
9
|
+
module Dsu
|
10
|
+
module Presenters
|
11
|
+
module Export
|
12
|
+
class DatesPresenter < BasePresenterEx
|
13
|
+
include Messages
|
14
|
+
include ServiceCallable
|
15
|
+
include Support::Ask
|
16
|
+
|
17
|
+
def initialize(from:, to:, options: {})
|
18
|
+
super(options: options)
|
19
|
+
|
20
|
+
@from = from
|
21
|
+
@to = to
|
22
|
+
end
|
23
|
+
|
24
|
+
def render(response:)
|
25
|
+
return display_cancelled_message unless response
|
26
|
+
|
27
|
+
export_file_path = exporter_service_call
|
28
|
+
|
29
|
+
display_exported_message
|
30
|
+
display_exported_to_message(file_path: export_file_path)
|
31
|
+
end
|
32
|
+
|
33
|
+
def display_export_prompt
|
34
|
+
yes?(prompt_with_options(prompt: export_prompt, options: export_prompt_options))
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_reader :from, :to, :options
|
40
|
+
|
41
|
+
def entry_groups
|
42
|
+
Models::EntryGroup.entry_groups(between: [from, to])
|
43
|
+
end
|
44
|
+
|
45
|
+
def export_prompt
|
46
|
+
I18n.t('subcommands.export.prompts.export_dates_confirm',
|
47
|
+
from: from.to_date, to: to.to_date, count: entry_groups.count)
|
48
|
+
end
|
49
|
+
|
50
|
+
def export_prompt_options
|
51
|
+
I18n.t('subcommands.export.prompts.options')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../models/entry_group'
|
4
|
+
require_relative '../base_presenter_ex'
|
5
|
+
|
6
|
+
module Dsu
|
7
|
+
module Presenters
|
8
|
+
module Export
|
9
|
+
module Messages
|
10
|
+
def display_export_prompt
|
11
|
+
raise NotImplementedError
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def display_cancelled_message
|
17
|
+
puts apply_theme(I18n.t('subcommands.export.messages.cancelled'), theme_color: color_theme.info)
|
18
|
+
end
|
19
|
+
|
20
|
+
def display_exported_message
|
21
|
+
puts apply_theme(I18n.t('subcommands.export.messages.exported'), theme_color: color_theme.success)
|
22
|
+
end
|
23
|
+
|
24
|
+
def display_exported_to_message(file_path:)
|
25
|
+
puts apply_theme(I18n.t('subcommands.export.messages.exported_to', file_path: file_path),
|
26
|
+
theme_color: color_theme.success)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../services/entry_group/exporter_service'
|
4
|
+
|
5
|
+
module Dsu
|
6
|
+
module Presenters
|
7
|
+
module Export
|
8
|
+
module ServiceCallable
|
9
|
+
private
|
10
|
+
|
11
|
+
def exporter_service_call
|
12
|
+
@exporter_service_call ||= begin
|
13
|
+
exporter_service = Services::EntryGroup::ExporterService.new(entry_groups: entry_groups, options: options)
|
14
|
+
exporter_service.call
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'csv'
|
4
|
+
require_relative '../../models/entry_group'
|
5
|
+
require_relative '../../support/fileable'
|
6
|
+
|
7
|
+
module Dsu
|
8
|
+
module Services
|
9
|
+
module EntryGroup
|
10
|
+
class ExporterService
|
11
|
+
include Support::Fileable
|
12
|
+
|
13
|
+
def initialize(entry_groups:, options: {})
|
14
|
+
raise ArgumentError, 'Argument entry_groups is nil' if entry_groups.nil?
|
15
|
+
|
16
|
+
@entry_groups = entry_groups
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
CSV.open(export_file_name, 'w') do |csv|
|
22
|
+
csv << %i[version entry_group entry_no total_entries entry_group_entry]
|
23
|
+
|
24
|
+
entry_groups.each do |entry_group|
|
25
|
+
next unless entry_group.exist?
|
26
|
+
|
27
|
+
entry_group.entries.each_with_index do |entry, index|
|
28
|
+
csv << [
|
29
|
+
entry_group.version,
|
30
|
+
entry_group.time.to_date,
|
31
|
+
index + 1,
|
32
|
+
entry_group.entries.count,
|
33
|
+
entry.description
|
34
|
+
]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
export_file_name
|
40
|
+
end
|
41
|
+
|
42
|
+
def export_file_name
|
43
|
+
@export_file_name ||= begin
|
44
|
+
file_name = "dsu-#{export_timestamp}-#{times.min.to_date}-thru-#{times.max.to_date}.csv"
|
45
|
+
File.join(temp_folder, file_name)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
attr_reader :entry_groups, :options
|
52
|
+
|
53
|
+
def times
|
54
|
+
@times ||= entry_groups.map(&:time)
|
55
|
+
end
|
56
|
+
|
57
|
+
def export_timestamp
|
58
|
+
Time.now.in_time_zone.strftime('%Y%m%d%H%M%S')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -91,7 +91,7 @@ module Dsu
|
|
91
91
|
message = I18n.t('subcommands.delete.messages.deleted', count: deleted_count)
|
92
92
|
Views::Shared::Success.new(messages: message).render
|
93
93
|
else
|
94
|
-
message = I18n.t('subcommands.delete.messages.
|
94
|
+
message = I18n.t('subcommands.delete.messages.cancelled')
|
95
95
|
Views::Shared::Info.new(messages: message).render
|
96
96
|
end
|
97
97
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../support/command_options/dsu_times'
|
4
|
+
require_relative '../support/command_options/time_mnemonic'
|
5
|
+
require_relative '../support/time_formatable'
|
6
|
+
require_relative '../views/export'
|
7
|
+
require_relative '../views/shared/error'
|
8
|
+
require_relative 'base_subcommand'
|
9
|
+
|
10
|
+
module Dsu
|
11
|
+
module Subcommands
|
12
|
+
class Export < BaseSubcommand
|
13
|
+
include Support::CommandOptions::TimeMnemonic
|
14
|
+
include Support::TimeFormatable
|
15
|
+
|
16
|
+
# TODO: I18n.
|
17
|
+
map %w[a] => :all
|
18
|
+
map %w[dd] => :dates
|
19
|
+
|
20
|
+
desc I18n.t('subcommands.export.all.desc'), I18n.t('subcommands.export.all.usage')
|
21
|
+
long_desc I18n.t('subcommands.export.all.long_desc')
|
22
|
+
option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
|
23
|
+
def all
|
24
|
+
Views::Export.new(presenter: all_presenter(options: options)).render
|
25
|
+
end
|
26
|
+
|
27
|
+
desc I18n.t('subcommands.export.dates.desc'), I18n.t('subcommands.export.dates.usage')
|
28
|
+
long_desc I18n.t('subcommands.export.dates.long_desc',
|
29
|
+
date_option_description: date_option_description,
|
30
|
+
mnemonic_option_description: mnemonic_option_description)
|
31
|
+
option :from, type: :string, required: true, aliases: '-f', banner: 'DATE|MNEMONIC'
|
32
|
+
option :to, type: :string, required: true, aliases: '-t', banner: 'DATE|MNEMONIC'
|
33
|
+
option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
|
34
|
+
def dates
|
35
|
+
options = configuration.to_h.merge(self.options).with_indifferent_access
|
36
|
+
times, errors = Support::CommandOptions::DsuTimes.dsu_times_for(from_option: options[:from], to_option: options[:to]) # rubocop:disable Layout/LineLength
|
37
|
+
if errors.any?
|
38
|
+
Views::Shared::Error.new(messages: errors).render
|
39
|
+
return
|
40
|
+
end
|
41
|
+
|
42
|
+
times = times_sort(times: times, entries_display_order: options[:entries_display_order])
|
43
|
+
Views::Export.new(presenter: dates_presenter_for(from: times.min, to: times.max, options: options)).render
|
44
|
+
rescue ArgumentError => e
|
45
|
+
Views::Shared::Error.new(messages: e.message).render
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def all_presenter(options:)
|
51
|
+
Presenters::Export::AllPresenter.new(options: options)
|
52
|
+
end
|
53
|
+
|
54
|
+
def dates_presenter_for(from:, to:, options:)
|
55
|
+
Presenters::Export::DatesPresenter.new(from: from, to: to, options: options)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -40,7 +40,7 @@ module Dsu
|
|
40
40
|
Views::Shared::Info.new(messages: "\n#{message}").render
|
41
41
|
true
|
42
42
|
else
|
43
|
-
message = I18n.t('subcommands.theme.create.messages.
|
43
|
+
message = I18n.t('subcommands.theme.create.messages.cancelled')
|
44
44
|
Views::Shared::Info.new(messages: "\n#{message}").render
|
45
45
|
false
|
46
46
|
end
|
@@ -71,7 +71,7 @@ module Dsu
|
|
71
71
|
change_theme
|
72
72
|
I18n.t('subcommands.theme.delete.messages.deleted', theme_name: theme_name)
|
73
73
|
else
|
74
|
-
I18n.t('subcommands.theme.delete.messages.
|
74
|
+
I18n.t('subcommands.theme.delete.messages.cancelled')
|
75
75
|
end
|
76
76
|
Views::Shared::Info.new(messages: "\n#{message}").render
|
77
77
|
end
|
@@ -6,10 +6,12 @@ module Dsu
|
|
6
6
|
module Support
|
7
7
|
module ColorThemable
|
8
8
|
def prompt_with_options(prompt:, options:)
|
9
|
+
# HACK: This module needs to be refactored to be more generic.
|
10
|
+
target_color_theme = defined?(color_theme) ? color_theme : self
|
9
11
|
options = "[#{options.join('/')}]"
|
10
|
-
"#{apply_theme(prompt, theme_color:
|
11
|
-
"#{apply_theme(options, theme_color: prompt_options)}" \
|
12
|
-
"#{apply_theme('>', theme_color:
|
12
|
+
"#{apply_theme(prompt, theme_color: target_color_theme.prompt)} " \
|
13
|
+
"#{apply_theme(options, theme_color: target_color_theme.prompt_options)}" \
|
14
|
+
"#{apply_theme('>', theme_color: target_color_theme.prompt)}"
|
13
15
|
end
|
14
16
|
|
15
17
|
module_function
|
data/lib/dsu/version.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../models/color_theme'
|
4
|
+
require_relative '../models/configuration'
|
5
|
+
require_relative '../support/color_themable'
|
6
|
+
|
7
|
+
module Dsu
|
8
|
+
module Views
|
9
|
+
class Export
|
10
|
+
include Support::ColorThemable
|
11
|
+
|
12
|
+
def initialize(presenter:)
|
13
|
+
@presenter = presenter
|
14
|
+
end
|
15
|
+
|
16
|
+
def render
|
17
|
+
response = presenter.display_export_prompt
|
18
|
+
presenter.render response: response
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :presenter
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/locales/en/commands.yml
CHANGED
@@ -58,13 +58,17 @@ en:
|
|
58
58
|
desc: config|c SUBCOMMAND
|
59
59
|
usage: Manage configuration file for this gem
|
60
60
|
delete:
|
61
|
-
key_mappings:
|
61
|
+
key_mappings: d
|
62
62
|
desc: delete|d SUBCOMMAND
|
63
63
|
usage: Delete DSU entries for the given SUBCOMMAND
|
64
64
|
edit:
|
65
65
|
desc: edit|e SUBCOMMAND
|
66
66
|
usage: Edit DSU entries for the given SUBCOMMAND
|
67
67
|
key_mappings: e
|
68
|
+
export:
|
69
|
+
key_mappings: x
|
70
|
+
desc: export|x SUBCOMMAND
|
71
|
+
usage: Export DSU entries for the given SUBCOMMAND
|
68
72
|
info:
|
69
73
|
key_mappings: i
|
70
74
|
desc: info|i
|
@@ -118,9 +118,9 @@ en:
|
|
118
118
|
long_desc: |
|
119
119
|
Deletes the DSU entries for the given OPTIONS.
|
120
120
|
|
121
|
-
$ dsu dates OPTIONS
|
121
|
+
$ dsu delete dates OPTIONS
|
122
122
|
|
123
|
-
$ dsu dd OPTIONS
|
123
|
+
$ dsu d dd OPTIONS
|
124
124
|
|
125
125
|
OPTIONS:
|
126
126
|
|
@@ -191,7 +191,7 @@ en:
|
|
191
191
|
$ dsu delete y
|
192
192
|
messages:
|
193
193
|
deleted: Deleted %{count} entry group(s).
|
194
|
-
|
194
|
+
cancelled: Cancelled.
|
195
195
|
prompts:
|
196
196
|
are_you_sure: Are you sure you want to delete all the entries for %{dates} (%{count} entry groups)?
|
197
197
|
edit:
|
@@ -217,6 +217,76 @@ en:
|
|
217
217
|
usage: Edits the DSU entries for yesterday
|
218
218
|
long_desc: |
|
219
219
|
Edits the DSU entries for yesterday.
|
220
|
+
export:
|
221
|
+
dates:
|
222
|
+
desc: dates|dd OPTIONS
|
223
|
+
usage: Exports the DSU entries for the OPTIONS provided
|
224
|
+
long_desc: |
|
225
|
+
Exports the DSU entries for the given OPTIONS.
|
226
|
+
|
227
|
+
$ dsu export dates OPTIONS
|
228
|
+
|
229
|
+
$ dsu x dd OPTIONS
|
230
|
+
|
231
|
+
OPTIONS:
|
232
|
+
|
233
|
+
-f|--from DATE|MNEMONIC: The DATE or MNEMONIC that represents the start of the range of DSU dates to export. If a relative mnemonic is used (+/-n, e.g +1, -1, etc.), the date calculated will be relative to the current date (e.g. `<MNEMONIC>.to_i.days.from_now(Time.now)`).
|
234
|
+
|
235
|
+
-t|--to DATE|MNEMONIC: The DATE or MNEMONIC that represents the end of the range of DSU dates to export. If a relative mnemonic is used (+/-n, e.g +1, -1, etc.), the date calculated will be relative to the date that resulting from the `--from` option date calculation.
|
236
|
+
|
237
|
+
%{date_option_description}
|
238
|
+
|
239
|
+
%{mnemonic_option_description}
|
240
|
+
|
241
|
+
EXAMPLES:
|
242
|
+
|
243
|
+
NOTE: All examples can substitute their respective short form options (e.g. `-f`, `-t`, etc. for `--from`, `--to`, etc.).
|
244
|
+
|
245
|
+
The below will export the DSU entries for the range of dates from 1/1 to 1/4 for the current year:
|
246
|
+
|
247
|
+
$ dsu export dates --from 1/1 --to +3
|
248
|
+
|
249
|
+
This will export the DSU entries for the range of dates from 1/2 to 1/5 for the year 2022:
|
250
|
+
|
251
|
+
$ dsu x dd --from 1/5/2022 --to -3
|
252
|
+
|
253
|
+
This (assuming "today" is 1/10) will export the DSU entries for the last week 1/10 to 1/3 of the current year:
|
254
|
+
|
255
|
+
$ dsu export dates --from today --to -7
|
256
|
+
|
257
|
+
This (assuming "today" is 5/23) will export the DSU entries for the last week 5/16 to 5/22.
|
258
|
+
This example simply illustrates the fact that you can use relative mnemonics for
|
259
|
+
both `--from` and `--to` options; this doesn't mean you should do so...
|
260
|
+
|
261
|
+
While you can use relative mnemonics for both `--from` and `--to` options,
|
262
|
+
there is always a more intuitive way. The below example basically exports one week of DSU entries back 1 week from yesterday's date:
|
263
|
+
|
264
|
+
$ dsu export dates --from -7 --to +6
|
265
|
+
|
266
|
+
The above can be accomplished MUCH easier by simply using the `yesterday` mnemonic...
|
267
|
+
|
268
|
+
This (assuming "today" is 5/23) will delete the DSU entries back 1 week from yesterday's date 5/16 to 5/22:
|
269
|
+
|
270
|
+
$ dsu x dd --from yesterday --to -6
|
271
|
+
all:
|
272
|
+
desc: all|a
|
273
|
+
usage: Exports all DSU entries
|
274
|
+
long_desc: |
|
275
|
+
Exports all DSU entries.
|
276
|
+
|
277
|
+
$ dsu export all
|
278
|
+
|
279
|
+
$ dsu x a
|
280
|
+
messages:
|
281
|
+
exported: Export successful.
|
282
|
+
exported_to: Entry groups exported to %{file_path}.
|
283
|
+
cancelled: Cancelled.
|
284
|
+
prompts:
|
285
|
+
export_all_confirm: Export all the entries (%{count} entry groups)?
|
286
|
+
export_dates_confirm: Export all the entries for %{from} thru %{to} (%{count} entry groups)?
|
287
|
+
options:
|
288
|
+
- y
|
289
|
+
- N
|
220
290
|
list:
|
221
291
|
date:
|
222
292
|
desc: date|d DATE|MNEMONIC
|
@@ -233,9 +303,9 @@ en:
|
|
233
303
|
long_desc: |
|
234
304
|
Displays the DSU entries for the given OPTIONS.
|
235
305
|
|
236
|
-
$ dsu dates OPTIONS
|
306
|
+
$ dsu list dates OPTIONS
|
237
307
|
|
238
|
-
$ dsu dd OPTIONS
|
308
|
+
$ dsu l dd OPTIONS
|
239
309
|
|
240
310
|
OPTIONS:
|
241
311
|
|
@@ -331,7 +401,7 @@ en:
|
|
331
401
|
already_exists: Color theme "%{theme_name}" already exists.
|
332
402
|
messages:
|
333
403
|
created: Created color theme "%{theme_name}".
|
334
|
-
|
404
|
+
cancelled: Cancelled.
|
335
405
|
delete:
|
336
406
|
desc: delete THEME_NAME
|
337
407
|
usage: Deletes the existing dsu color theme THEME_NAME
|
@@ -344,7 +414,7 @@ en:
|
|
344
414
|
errors:
|
345
415
|
cannot_delete: Color theme "%{theme_name}" cannot be deleted.
|
346
416
|
messages:
|
347
|
-
|
417
|
+
cancelled: Cancelled.
|
348
418
|
deleted: Deleted color theme "%{theme_name}".
|
349
419
|
list:
|
350
420
|
desc: list
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dsu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gene M. Angelo, Jr.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-12-
|
11
|
+
date: 2023-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -179,11 +179,16 @@ files:
|
|
179
179
|
- lib/dsu/models/entry_group.rb
|
180
180
|
- lib/dsu/models/migration_version.rb
|
181
181
|
- lib/dsu/presenters/base_presenter.rb
|
182
|
+
- lib/dsu/presenters/base_presenter_ex.rb
|
182
183
|
- lib/dsu/presenters/color_theme_presenter.rb
|
183
184
|
- lib/dsu/presenters/color_theme_show_presenter.rb
|
184
185
|
- lib/dsu/presenters/configuration_presenter.rb
|
185
186
|
- lib/dsu/presenters/entry_group_presenter.rb
|
186
187
|
- lib/dsu/presenters/entry_presenter.rb
|
188
|
+
- lib/dsu/presenters/export/all_presenter.rb
|
189
|
+
- lib/dsu/presenters/export/dates_presenter.rb
|
190
|
+
- lib/dsu/presenters/export/messages.rb
|
191
|
+
- lib/dsu/presenters/export/service_callable.rb
|
187
192
|
- lib/dsu/services/color_theme/hydrator_service.rb
|
188
193
|
- lib/dsu/services/configuration/hydrator_service.rb
|
189
194
|
- lib/dsu/services/entry/hydrator_service.rb
|
@@ -191,6 +196,7 @@ files:
|
|
191
196
|
- lib/dsu/services/entry_group/counter_service.rb
|
192
197
|
- lib/dsu/services/entry_group/deleter_service.rb
|
193
198
|
- lib/dsu/services/entry_group/editor_service.rb
|
199
|
+
- lib/dsu/services/entry_group/exporter_service.rb
|
194
200
|
- lib/dsu/services/entry_group/hydrator_service.rb
|
195
201
|
- lib/dsu/services/migration_version/hydrator_service.rb
|
196
202
|
- lib/dsu/services/stderr_redirector_service.rb
|
@@ -202,6 +208,7 @@ files:
|
|
202
208
|
- lib/dsu/subcommands/config.rb
|
203
209
|
- lib/dsu/subcommands/delete.rb
|
204
210
|
- lib/dsu/subcommands/edit.rb
|
211
|
+
- lib/dsu/subcommands/export.rb
|
205
212
|
- lib/dsu/subcommands/list.rb
|
206
213
|
- lib/dsu/subcommands/theme.rb
|
207
214
|
- lib/dsu/support/ask.rb
|
@@ -237,6 +244,7 @@ files:
|
|
237
244
|
- lib/dsu/views/entry_group/shared/no_entries_to_display_for_week_of.rb
|
238
245
|
- lib/dsu/views/entry_group/shared/no_entries_to_display_for_year_of.rb
|
239
246
|
- lib/dsu/views/entry_group/show.rb
|
247
|
+
- lib/dsu/views/export.rb
|
240
248
|
- lib/dsu/views/shared/error.rb
|
241
249
|
- lib/dsu/views/shared/info.rb
|
242
250
|
- lib/dsu/views/shared/message.rb
|