timet 1.4.2 → 1.4.3
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/README.md +3 -1
- data/lib/timet/application.rb +28 -41
- data/lib/timet/application_helper.rb +76 -0
- data/lib/timet/time_report.rb +46 -13
- 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: 7754392fd614ebc62c53293166db637a9593f8497b4cc22ea3ea602bc51546f7
|
4
|
+
data.tar.gz: e4f699cf2725be5cf6849a5946323270d078ab1d6fa13892877f17ce161b1d1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a8be74697ff40c179a0546662fc7b067d0ceddf4da159ea3107c87fef68b3f6cb7a7c3e61ff9c9115bcc799d5d5278fe209629a892077783aa56c77c772c81f
|
7
|
+
data.tar.gz: bd9131bccca060ea7d8a7710d9a96b6c784cfeca7312a9146f8fa5c31d8bd0e40b3a58e82ec670328baf5e92d0d2f8b3fa8e80a47a25a0f771c2cb1a6c5e667b
|
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
|
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.
|
@@ -94,16 +101,42 @@ module Timet
|
|
94
101
|
# @return [void] This method does not return a value; it performs side effects such as writing the CSV file.
|
95
102
|
#
|
96
103
|
# @example Export the report to a CSV file
|
97
|
-
# time_report.
|
104
|
+
# time_report.export_csv
|
98
105
|
#
|
99
106
|
# @note The method writes the items to a CSV file and prints a confirmation message.
|
100
|
-
def
|
101
|
-
file_name = "#{
|
107
|
+
def export_csv
|
108
|
+
file_name = "#{csv_filename}.csv"
|
102
109
|
write_csv(file_name)
|
103
110
|
|
104
111
|
puts "The #{file_name} has been exported."
|
105
112
|
end
|
106
113
|
|
114
|
+
def export_icalendar
|
115
|
+
file_name = "#{ics_filename}.ics"
|
116
|
+
|
117
|
+
cal = Icalendar::Calendar.new
|
118
|
+
items.each do |item|
|
119
|
+
dtstart = Time.at(item[1]).to_datetime
|
120
|
+
end_time = item[2] || TimeHelper.current_timestamp
|
121
|
+
dtend = Time.at(end_time).to_datetime
|
122
|
+
|
123
|
+
tag = item[3]
|
124
|
+
notes = item[4]
|
125
|
+
cal.event do |e|
|
126
|
+
e.dtstart = dtstart
|
127
|
+
e.dtend = dtend
|
128
|
+
e.summary = tag
|
129
|
+
e.description = notes
|
130
|
+
e.ip_class = 'PRIVATE'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
cal.publish
|
134
|
+
|
135
|
+
File.write(file_name, cal.to_ical)
|
136
|
+
|
137
|
+
puts "The #{file_name} has been generated."
|
138
|
+
end
|
139
|
+
|
107
140
|
private
|
108
141
|
|
109
142
|
# Writes the items to a CSV file.
|
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.3
|
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-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|