timet 1.4.2 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +3 -1
- data/lib/timet/application.rb +28 -41
- data/lib/timet/application_helper.rb +76 -0
- data/lib/timet/tag_distribution.rb +29 -17
- data/lib/timet/time_report.rb +17 -25
- data/lib/timet/time_report_helper.rb +67 -0
- data/lib/timet/time_statistics.rb +13 -0
- data/lib/timet/version.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c617b0cdad056a121039feaacfb0fe04df4e3e21cea8d9261e0414a01c2e9014
|
4
|
+
data.tar.gz: cac525344920d23e05ed0cab8798aa70e0153337328cac6bb170c6d96b9b509a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e48e71078a2cfb0e7f92a67b008f323b487366ad41392e0027a1d229e29680018dbcf1b13012322735f94302e5c0e03576d544dd7b1897fd3973cf49ee7cc1d1
|
7
|
+
data.tar.gz: 2a5a3fdabd064518b57aac6142c690dba881ce3d68ace78bd6770d5679fc11f24a71878a7422a80482aaaffb0e723bd8aa4c9a0ebf2de2fa5b8ee35a3082d98d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,35 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.4.4] - 2024-11-12
|
4
|
+
|
5
|
+
**Improvements:**
|
6
|
+
- Refactored tag distribution and time statistics methods:
|
7
|
+
- Split `process_and_print_tags` into `print_summary` and `print_tags_info` for better modularity and readability.
|
8
|
+
- Added Yardoc comments to document the new methods and updated existing comments for clarity.
|
9
|
+
- Introduced `totals` method in `TimeStatistics` to calculate and return total duration, average duration, and standard deviation.
|
10
|
+
- Refactored export methods to `TimeReportHelper`:
|
11
|
+
- Moved `export_csv` and `export_icalendar` methods from `TimeReport` to `TimeReportHelper`.
|
12
|
+
- Created private methods `add_events`, `create_event`, and `convert_to_datetime` in `TimeReportHelper` to handle iCalendar event creation and conversion.
|
13
|
+
- Ensured that the iCalendar file generation logic is encapsulated within the `TimeReportHelper` module.
|
14
|
+
|
15
|
+
**Tasks:**
|
16
|
+
- Bumped version to 1.4.4.
|
17
|
+
- Updated `Gemfile.lock`.
|
18
|
+
|
19
|
+
## [1.4.3] - 2024-11-06
|
20
|
+
|
21
|
+
**Improvements:**
|
22
|
+
- **Refactor export logic**: Introduced a new `ReportExporter` class to handle the export of reports to CSV and iCalendar formats, addressing the Feature Envy code smell and making the `ApplicationHelper` module more modular.
|
23
|
+
- **Update gem dependencies**: Updated several gems to their latest versions, including `icalendar`, `sqlite3`, `json`, `parser`, `rubocop`, and `rubocop-ast`.
|
24
|
+
- **Refactor `TimeReport` initialization**: Refactored `TimeReport` initialization to use an options hash instead of individual parameters, and added support for exporting tracking summaries to iCalendar format.
|
25
|
+
- **Enhance command descriptions**: Improved the descriptions of the `start`, `stop`, `resume`, `summary`, `edit`, `delete`, and `cancel` commands, and added an `--ics` option to the `summary` command for iCalendar export.
|
26
|
+
- **Add `icalendar` gem**: Added the `icalendar` gem to support iCalendar functionality and updated the `timet` gem version to `1.4.3`.
|
27
|
+
|
28
|
+
**Bug Fixes:**
|
29
|
+
- Corrected platform names in the lockfile.
|
30
|
+
- Updated the `TimeReport` spec to use the new options hash in the `TimeReport` initialization.
|
31
|
+
|
32
|
+
|
3
33
|
## [1.4.2] - 2024-11-01
|
4
34
|
|
5
35
|
**Improvements:**
|
data/README.md
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
- **Block Time Plot:** Visualizes the distribution of tracked time across a specified range of dates. Each column represents the amount of time tracked during a specific hour, with a header showing the hours and a row for each date displaying the time blocks for each hour.
|
23
23
|
- **Tag Distribution Plot:** Illustrates the proportion of total tracked time allocated to each tag, showing the relative contribution of each tag to the overall time tracked.
|
24
24
|
- **Detailed Statistics:** Displays detailed statistics for each tag, including total duration, average duration, and standard deviation.
|
25
|
+
- **iCalendar Export:** Easily export your time tracking data to iCalendar format for integration with calendar applications.
|
25
26
|
|
26
27
|
**Examples:**
|
27
28
|
|
@@ -181,7 +182,8 @@ gem install timet
|
|
181
182
|
| `timet summary yesterday (y)` | Display a report of tracked time for yesterday. | `timet su y` |
|
182
183
|
| `timet summary week (w)` | Display a report of tracked time for the week. | `timet su w` |
|
183
184
|
| `timet summary month (m)` | Display a report of tracked time for the month. | `timet su m` |
|
184
|
-
| `timet su t --csv=[filename]` | Display a report of tracked time for today and export
|
185
|
+
| `timet su t --csv=[filename]` | Display a report of tracked time for today and export to CSV file | `timet su t --csv=file.csv` |
|
186
|
+
| `timet su w --ics=[filename]` | Display a report of tracked time for week and export to iCalendar file | `timet su w --ics=file.csv` |
|
185
187
|
| `timet delete [id]` | Delete a task by its ID. | `timet d [id]` |
|
186
188
|
| `timet cancel` | Cancel active time tracking. | `timet c` |
|
187
189
|
| `timet edit [id]` | Update a task's notes, tag, start, or end fields. | `timet e [id]` |
|
data/lib/timet/application.rb
CHANGED
@@ -36,8 +36,9 @@ module Timet
|
|
36
36
|
VALID_STATUSES_FOR_INSERTION = %i[no_items complete].freeze
|
37
37
|
|
38
38
|
desc "start [tag] --notes='' --pomodoro=[min]",
|
39
|
-
'
|
40
|
-
|
39
|
+
'Start time tracking for a task labeled with the provided [tag], notes and "pomodoro time"
|
40
|
+
in minutes (optional).
|
41
|
+
tt start project1 "Starting project1" --pomodoro=25'
|
41
42
|
option :notes, type: :string, desc: 'Add a note'
|
42
43
|
option :pomodoro, type: :numeric, desc: 'Pomodoro time in minutes'
|
43
44
|
# Starts a new tracking session with the given tag and optional notes.
|
@@ -76,7 +77,7 @@ module Timet
|
|
76
77
|
summary
|
77
78
|
end
|
78
79
|
|
79
|
-
desc 'stop', '
|
80
|
+
desc 'stop', 'Stop time tracking'
|
80
81
|
# Stops the current tracking session if there is one in progress.
|
81
82
|
#
|
82
83
|
# @return [void] This method does not return a value; it performs side effects such as updating the tracking item
|
@@ -99,7 +100,7 @@ module Timet
|
|
99
100
|
summary unless display
|
100
101
|
end
|
101
102
|
|
102
|
-
desc 'resume (r) [id]', '
|
103
|
+
desc 'resume (r) [id]', 'Resume last task (id is an optional parameter) => tt resume'
|
103
104
|
# Resumes the last tracking session if it was completed.
|
104
105
|
#
|
105
106
|
# @return [void] This method does not return a value; it performs side effects such as resuming a tracking session
|
@@ -131,48 +132,34 @@ module Timet
|
|
131
132
|
end
|
132
133
|
end
|
133
134
|
|
134
|
-
desc 'summary (su) [time_scope] [tag] --csv=csv_filename',
|
135
|
-
'
|
136
|
-
|
135
|
+
desc 'summary (su) [time_scope] [tag] --csv=csv_filename --ics=ics_filename',
|
136
|
+
'Display a summary of tracked time and export to CSV.
|
137
|
+
[time_scope] => [today (t), yesterday (y), week (w), month (m). => tt su yesterday
|
138
|
+
[start_date]..[end_date]] => tt su 2024-10-03..2024-10-20
|
139
|
+
[tag] => tt su Task1
|
140
|
+
--csv=csv_filename => tt su month --csv=myfile
|
141
|
+
--ics=ics_filename => tt su week --csv=mycalendar'
|
142
|
+
option :csv, type: :string, desc: 'Export to CSV'
|
143
|
+
option :ics, type: :string, desc: 'Export to iCalendar'
|
137
144
|
# Generates a summary of tracking items based on the provided time_scope and tag, and optionally exports the summary
|
138
|
-
# to a CSV file.
|
145
|
+
# to a CSV file and/or an iCalendar file.
|
139
146
|
#
|
140
|
-
# @param time_scope [String, nil] The
|
141
|
-
#
|
142
|
-
# @param tag [String, nil] The tag to
|
147
|
+
# @param time_scope [String, nil] The filter to apply when fetching items. Possible values include 'today',
|
148
|
+
# 'yesterday', 'week', 'month', or a date range in the format 'YYYY-MM-DD..YYYY-MM-DD'.
|
149
|
+
# @param tag [String, nil] The tag to filter the items by.
|
143
150
|
#
|
144
|
-
# @return [void] This method does not return a value; it performs side effects such as displaying
|
145
|
-
# exporting
|
146
|
-
#
|
147
|
-
# @example Generate a summary for today
|
148
|
-
# summary('today')
|
149
|
-
#
|
150
|
-
# @example Generate a summary for a specific tag
|
151
|
-
# summary(nil, 'work')
|
152
|
-
#
|
153
|
-
# @example Generate a summary for a date range and export to CSV
|
154
|
-
# summary('2023-01-01..2023-01-31', nil, csv: 'summary.csv')
|
155
|
-
#
|
156
|
-
# @note The method initializes a `TimeReport` object with the database, time_scope, tag, and optional CSV filename.
|
157
|
-
# @note The method calls `display` on the `TimeReport` object to show the summary.
|
158
|
-
# @note If a CSV filename is provided and there are items to export, the method calls `export_sheet` to export the
|
159
|
-
# summary to a CSV file.
|
160
|
-
# @note If no items are found to export, it prints a message indicating that no items were found.
|
151
|
+
# @return [void] This method does not return a value; it performs side effects such as displaying
|
152
|
+
# and exporting the report.
|
161
153
|
def summary(time_scope = nil, tag = nil)
|
162
|
-
|
163
|
-
report = TimeReport.new(@db,
|
164
|
-
|
165
|
-
report.display
|
166
|
-
items = report.items
|
167
|
-
if csv_filename && items.any?
|
168
|
-
report.export_sheet
|
169
|
-
elsif items.empty?
|
170
|
-
puts 'No items found to export'
|
171
|
-
end
|
154
|
+
options = build_options(time_scope, tag)
|
155
|
+
report = TimeReport.new(@db, options)
|
156
|
+
display_and_export_report(report, options)
|
172
157
|
end
|
173
158
|
|
174
159
|
desc 'edit (e) [id] [field] [value]',
|
175
|
-
'
|
160
|
+
'Edit task, [field] (notes, tag, start or end) and [value] are optional parameters.
|
161
|
+
Update notes => tt edit 12 notes "Update note"
|
162
|
+
Update start time => tt edit 12 start 12:33'
|
176
163
|
# Edits a specific tracking item by its ID, allowing the user to modify fields such as notes, tag, start time, or
|
177
164
|
# end time.
|
178
165
|
#
|
@@ -211,7 +198,7 @@ module Timet
|
|
211
198
|
display_item(updated_item || item)
|
212
199
|
end
|
213
200
|
|
214
|
-
desc 'delete (d) [id]', '
|
201
|
+
desc 'delete (d) [id]', 'Delete task => tt d 23'
|
215
202
|
# Deletes a specific tracking item by its ID after confirming with the user.
|
216
203
|
#
|
217
204
|
# @param id [Integer] The ID of the tracking item to be deleted.
|
@@ -238,7 +225,7 @@ module Timet
|
|
238
225
|
delete_item_and_print_message(id, "Deleted #{id}")
|
239
226
|
end
|
240
227
|
|
241
|
-
desc 'cancel (c)', '
|
228
|
+
desc 'cancel (c)', 'Cancel active time tracking => tt c'
|
242
229
|
# Cancels the active time tracking session by deleting the last tracking item.
|
243
230
|
#
|
244
231
|
# @return [void] This method does not return a value; it performs side effects such as deleting the active tracking
|
@@ -184,5 +184,81 @@ module Timet
|
|
184
184
|
tag, notes = item.values_at(Application::FIELD_INDEX['tag'], Application::FIELD_INDEX['notes'])
|
185
185
|
start(tag, notes)
|
186
186
|
end
|
187
|
+
|
188
|
+
# Builds a hash of options to be used when initializing a TimeReport instance.
|
189
|
+
#
|
190
|
+
# @param time_scope [String, nil] The filter to apply when fetching items. Possible values include 'today',
|
191
|
+
# 'yesterday', 'week', 'month', or a date range in the format 'YYYY-MM-DD..YYYY-MM-DD'.
|
192
|
+
# @param tag [String, nil] The tag to filter the items by.
|
193
|
+
#
|
194
|
+
# @return [Hash] A hash containing the filter, tag, CSV filename, and iCalendar filename.
|
195
|
+
#
|
196
|
+
# @example Build options with a filter and tag
|
197
|
+
# build_options('today', 'work') # => { filter: 'today', tag: 'work', csv: nil, ics: nil }
|
198
|
+
def build_options(time_scope, tag)
|
199
|
+
csv_filename = options[:csv]&.split('.')&.first
|
200
|
+
ics_filename = options[:ics]&.split('.')&.first
|
201
|
+
{
|
202
|
+
filter: time_scope,
|
203
|
+
tag: tag,
|
204
|
+
csv: csv_filename,
|
205
|
+
ics: ics_filename
|
206
|
+
}
|
207
|
+
end
|
208
|
+
|
209
|
+
# @note This class is responsible for exporting reports to CSV and iCalendar formats.
|
210
|
+
class ReportExporter
|
211
|
+
# Exports the report to a CSV file if the `csv` option is provided.
|
212
|
+
#
|
213
|
+
# @param report [TimeReport] The report object to export.
|
214
|
+
# @param options [Hash] The options hash containing export settings.
|
215
|
+
# @option options [String] :csv The filename to use when exporting the report to CSV.
|
216
|
+
# @return [void]
|
217
|
+
def self.export_csv_report(report, options)
|
218
|
+
report.export_csv if options[:csv]
|
219
|
+
end
|
220
|
+
|
221
|
+
# Exports the report to an iCalendar file if the `ics` option is provided.
|
222
|
+
#
|
223
|
+
# @param report [TimeReport] The report object to export.
|
224
|
+
# @param options [Hash] The options hash containing export settings.
|
225
|
+
# @option options [String] :ics The filename to use when exporting the report to iCalendar.
|
226
|
+
# @return [void]
|
227
|
+
def self.export_icalendar_report(report, options)
|
228
|
+
report.export_icalendar if options[:ics]
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
# Displays the report and exports it to a CSV file and/or an iCalendar file if specified.
|
233
|
+
#
|
234
|
+
# @param report [TimeReport] The TimeReport instance to display and export.
|
235
|
+
# @param options [Hash] A hash containing the options for exporting the report.
|
236
|
+
# @option options [String, nil] :csv The filename to use when exporting the report to CSV.
|
237
|
+
# @option options [String, nil] :ics The filename to use when exporting the report to iCalendar.
|
238
|
+
#
|
239
|
+
# @return [void] This method does not return a value; it performs side effects such as displaying
|
240
|
+
# and exporting the report.
|
241
|
+
#
|
242
|
+
# @example Display and export the report to CSV and iCalendar
|
243
|
+
# display_and_export_report(report, { csv: 'report.csv', ics: 'icalendar.ics' })
|
244
|
+
def display_and_export_report(report, options)
|
245
|
+
report.display
|
246
|
+
export_report(report, options)
|
247
|
+
end
|
248
|
+
|
249
|
+
# Exports the given report in CSV and iCalendar formats if there are items, otherwise prints a message.
|
250
|
+
#
|
251
|
+
# @param report [Report] The report to be exported.
|
252
|
+
# @param options [Hash] The options to pass to the exporter.
|
253
|
+
# @return [void]
|
254
|
+
def export_report(report, options)
|
255
|
+
items = report.items
|
256
|
+
if items.any?
|
257
|
+
ReportExporter.export_csv_report(report, options)
|
258
|
+
ReportExporter.export_icalendar_report(report, options)
|
259
|
+
else
|
260
|
+
puts 'No items found to export'
|
261
|
+
end
|
262
|
+
end
|
187
263
|
end
|
188
264
|
end
|
@@ -34,31 +34,43 @@ module Timet
|
|
34
34
|
|
35
35
|
# Processes and prints the tag distribution information.
|
36
36
|
#
|
37
|
-
# @param
|
38
|
-
# tag and its corresponding duration, sorted by duration in descending order.
|
37
|
+
# @param time_stats [Object] An object containing the time statistics, including totals and sorted durations by tag.
|
39
38
|
# @param total [Numeric] The total duration of all tags combined.
|
39
|
+
# @param colors [Object] An object containing color formatting methods.
|
40
40
|
# @return [void] This method outputs the tag distribution information to the standard output.
|
41
41
|
def process_and_print_tags(time_stats, total, colors)
|
42
|
-
time_stats
|
43
|
-
|
44
|
-
end
|
42
|
+
print_summary(time_stats, total)
|
43
|
+
print_tags_info(time_stats, total, colors)
|
45
44
|
end
|
46
45
|
|
47
|
-
# Prints the
|
46
|
+
# Prints the summary information including total duration, average duration, and standard deviation.
|
48
47
|
#
|
49
|
-
# @param
|
50
|
-
# @param duration [Numeric] The duration associated with the tag.
|
48
|
+
# @param time_stats [Object] An object containing the time statistics, including totals.
|
51
49
|
# @param total [Numeric] The total duration of all tags combined.
|
52
|
-
# @
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
50
|
+
# @return [void] This method outputs the summary information to the standard output.
|
51
|
+
def print_summary(time_stats, total)
|
52
|
+
avg = (time_stats.totals[:avg] / 60.0).round(1)
|
53
|
+
sd = (time_stats.totals[:sd] / 60.0).round(1)
|
54
|
+
summary = "#{' ' * TAG_SIZE} #{'Summary'.underline}: "
|
55
|
+
summary += "[T: #{(total / 3600.0).round(1)}h, AVG: #{avg}min SD: #{sd}min]".white
|
56
|
+
puts summary
|
57
|
+
end
|
60
58
|
|
61
|
-
|
59
|
+
# Prints the detailed information for each tag.
|
60
|
+
#
|
61
|
+
# @param time_stats [Object] An object containing the time statistics, including sorted durations by tag.
|
62
|
+
# @param total [Numeric] The total duration of all tags combined.
|
63
|
+
# @param colors [Object] An object containing color formatting methods.
|
64
|
+
# @return [void] This method outputs the detailed tag information to the standard output.
|
65
|
+
def print_tags_info(time_stats, total, colors)
|
66
|
+
time_stats.sorted_duration_by_tag.each do |tag, duration|
|
67
|
+
value, bar_length = calculate_value_and_bar_length(duration, total)
|
68
|
+
horizontal_bar = generate_horizontal_bar(bar_length, colors[tag])
|
69
|
+
formatted_tag = tag[0...TAG_SIZE].rjust(TAG_SIZE)
|
70
|
+
stats = generate_stats(tag, time_stats)
|
71
|
+
|
72
|
+
puts "#{formatted_tag}: #{value.to_s.rjust(5)}% #{horizontal_bar} [#{stats}]"
|
73
|
+
end
|
62
74
|
end
|
63
75
|
|
64
76
|
# Generates a horizontal bar for display based on the bar length and color index.
|
data/lib/timet/time_report.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'date'
|
4
4
|
require 'csv'
|
5
|
+
require 'icalendar'
|
5
6
|
require_relative 'time_report_helper'
|
6
7
|
require_relative 'table'
|
7
8
|
require_relative 'time_block_chart'
|
@@ -24,26 +25,32 @@ module Timet
|
|
24
25
|
attr_reader :items
|
25
26
|
|
26
27
|
# Provides access to the CSV filename.
|
27
|
-
attr_reader :
|
28
|
+
attr_reader :csv_filename
|
29
|
+
|
30
|
+
# Provides access to the ICS filename.
|
31
|
+
attr_reader :ics_filename
|
28
32
|
|
29
33
|
# Initializes a new instance of the TimeReport class.
|
30
34
|
#
|
31
35
|
# @param db [Database] The database instance to use for fetching data.
|
32
|
-
# @param
|
33
|
-
#
|
34
|
-
#
|
35
|
-
# @
|
36
|
+
# @param options [Hash] A hash containing optional parameters.
|
37
|
+
# @option options [String, nil] :filter The filter to apply when fetching items. Possible values include 'today',
|
38
|
+
# 'yesterday', 'week', 'month', or a date range in the format 'YYYY-MM-DD..YYYY-MM-DD'.
|
39
|
+
# @option options [String, nil] :tag The tag to filter the items by.
|
40
|
+
# @option options [String, nil] :csv The filename to use when exporting the report to CSV.
|
41
|
+
# @option options [String, nil] :ics The filename to use when exporting the report to iCalendar.
|
36
42
|
#
|
37
43
|
# @return [void] This method does not return a value; it performs side effects such as initializing the
|
38
44
|
# instance variables.
|
39
45
|
#
|
40
46
|
# @example Initialize a new TimeReport instance with a filter and tag
|
41
|
-
# TimeReport.new(db, 'today', 'work', 'report.csv')
|
42
|
-
def initialize(db,
|
47
|
+
# TimeReport.new(db, filter: 'today', tag: 'work', csv: 'report.csv', ics: 'icalendar.ics')
|
48
|
+
def initialize(db, options = {})
|
43
49
|
@db = db
|
44
|
-
@
|
45
|
-
@
|
46
|
-
@
|
50
|
+
@csv_filename = options[:csv]
|
51
|
+
@ics_filename = options[:ics]
|
52
|
+
@filter = formatted_filter(options[:filter])
|
53
|
+
@items = options[:filter] ? filter_items(@filter, options[:tag]) : @db.all_items
|
47
54
|
end
|
48
55
|
|
49
56
|
# Displays the report of tracked time entries.
|
@@ -89,21 +96,6 @@ module Timet
|
|
89
96
|
total
|
90
97
|
end
|
91
98
|
|
92
|
-
# Exports the report to a CSV file.
|
93
|
-
#
|
94
|
-
# @return [void] This method does not return a value; it performs side effects such as writing the CSV file.
|
95
|
-
#
|
96
|
-
# @example Export the report to a CSV file
|
97
|
-
# time_report.export_sheet
|
98
|
-
#
|
99
|
-
# @note The method writes the items to a CSV file and prints a confirmation message.
|
100
|
-
def export_sheet
|
101
|
-
file_name = "#{filename}.csv"
|
102
|
-
write_csv(file_name)
|
103
|
-
|
104
|
-
puts "The #{file_name} has been exported."
|
105
|
-
end
|
106
|
-
|
107
99
|
private
|
108
100
|
|
109
101
|
# Writes the items to a CSV file.
|
@@ -80,5 +80,72 @@ module Timet
|
|
80
80
|
[summed_number, old_value[1]]
|
81
81
|
end
|
82
82
|
end
|
83
|
+
|
84
|
+
# Exports the report to a CSV file.
|
85
|
+
#
|
86
|
+
# @return [void] This method does not return a value; it performs side effects such as writing the CSV file.
|
87
|
+
#
|
88
|
+
# @example Export the report to a CSV file
|
89
|
+
# time_report.export_csv
|
90
|
+
#
|
91
|
+
# @note The method writes the items to a CSV file and prints a confirmation message.
|
92
|
+
def export_csv
|
93
|
+
file_name = "#{csv_filename}.csv"
|
94
|
+
write_csv(file_name)
|
95
|
+
|
96
|
+
puts "The #{file_name} has been exported."
|
97
|
+
end
|
98
|
+
|
99
|
+
# Generates an iCalendar file and writes it to disk.
|
100
|
+
#
|
101
|
+
# @return [void]
|
102
|
+
def export_icalendar
|
103
|
+
file_name = "#{ics_filename}.ics"
|
104
|
+
cal = add_events
|
105
|
+
|
106
|
+
File.write(file_name, cal.to_ical)
|
107
|
+
|
108
|
+
puts "The #{file_name} has been generated."
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
# Creates an iCalendar object and adds events to it.
|
114
|
+
#
|
115
|
+
# @return [Icalendar::Calendar] the populated iCalendar object
|
116
|
+
def add_events
|
117
|
+
cal = Icalendar::Calendar.new
|
118
|
+
items.each do |item|
|
119
|
+
event = create_event(item)
|
120
|
+
cal.add_event(event)
|
121
|
+
end
|
122
|
+
cal.publish
|
123
|
+
cal
|
124
|
+
end
|
125
|
+
|
126
|
+
# Creates an iCalendar event from the given item.
|
127
|
+
#
|
128
|
+
# @param item [Array] the item containing event details
|
129
|
+
# @return [Icalendar::Event] the created event
|
130
|
+
def create_event(item)
|
131
|
+
dtstart = convert_to_datetime(item[1])
|
132
|
+
dtend = convert_to_datetime(item[2] || TimeHelper.current_timestamp)
|
133
|
+
|
134
|
+
Icalendar::Event.new.tap do |e|
|
135
|
+
e.dtstart = dtstart
|
136
|
+
e.dtend = dtend
|
137
|
+
e.summary = item[3]
|
138
|
+
e.description = item[4]
|
139
|
+
e.ip_class = 'PRIVATE'
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# Converts a timestamp to a DateTime object.
|
144
|
+
#
|
145
|
+
# @param timestamp [Integer] the timestamp to convert
|
146
|
+
# @return [DateTime] the converted DateTime object
|
147
|
+
def convert_to_datetime(timestamp)
|
148
|
+
Time.at(timestamp).to_datetime
|
149
|
+
end
|
83
150
|
end
|
84
151
|
end
|
@@ -27,6 +27,19 @@ module Timet
|
|
27
27
|
calculate_durations_by_tag
|
28
28
|
end
|
29
29
|
|
30
|
+
# Returns a hash containing the total duration, average duration, and standard deviation of durations.
|
31
|
+
#
|
32
|
+
# @return [Hash] A hash with the following keys:
|
33
|
+
# - :total [Numeric] The total duration.
|
34
|
+
# - :avg [Numeric] The average duration.
|
35
|
+
# - :sd [Numeric] The standard deviation of the durations.
|
36
|
+
def totals
|
37
|
+
@duration_by_tag.values.flatten
|
38
|
+
|
39
|
+
durations = @duration_by_tag.values.flatten
|
40
|
+
{ total: @total_duration, avg: durations.mean, sd: durations.standard_deviation }
|
41
|
+
end
|
42
|
+
|
30
43
|
# Calculates the duration for each tag and updates the @duration_by_tag and @total_duration attributes.
|
31
44
|
#
|
32
45
|
# @return [void]
|
data/lib/timet/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Frank Vielma
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-11-
|
11
|
+
date: 2024-11-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|