timet 1.6.1.1 → 1.6.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/.qlty/qlty.toml +0 -0
- data/.reek.yml +17 -1
- data/.rubocop.yml +6 -1
- data/CHANGELOG.md +37 -4
- data/README.md +40 -24
- data/lib/timet/application.rb +3 -3
- data/lib/timet/database.rb +32 -25
- data/lib/timet/database_syncer.rb +93 -131
- data/lib/timet/discord_notifier.rb +3 -1
- data/lib/timet/s3_supabase.rb +74 -131
- data/lib/timet/table.rb +0 -4
- data/lib/timet/tag_distribution.rb +181 -160
- data/lib/timet/time_helper.rb +18 -3
- data/lib/timet/time_report.rb +17 -3
- data/lib/timet/utils.rb +8 -8
- data/lib/timet/validation_editor.rb +303 -0
- data/lib/timet/version.rb +2 -2
- metadata +6 -9
- data/lib/timet/item_data_helper.rb +0 -59
- data/lib/timet/time_report_helper.rb +0 -36
- data/lib/timet/time_update_helper.rb +0 -75
- data/lib/timet/time_validation_helper.rb +0 -175
- data/lib/timet/validation_edit_helper.rb +0 -160
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 84fa974afe30946a8b292569e74917c3992097e0ae652339320981f2951f298d
|
|
4
|
+
data.tar.gz: dc6cf2d3f5bd30feebb93db4aa07c436203e53bf1d9d0dbba5166695b622b021
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 49cf7cc38f9e44687d27bee93a8de5678963fd92a9589241e38635afcdf4b86f8229d1c401483d2d6e955ee83e5423ca10f832f4beb0101873e60f5d0ff34821
|
|
7
|
+
data.tar.gz: 2098f1a3c297277bd07425961b3e84425a1189ae5984e21c35649a3a2c517a5a175dfd5b477abb59ba49f78925a9c4ec872006d3be025ddc4ee363bf86ff7004
|
data/.qlty/qlty.toml
ADDED
|
File without changes
|
data/.reek.yml
CHANGED
|
@@ -3,4 +3,20 @@ detectors:
|
|
|
3
3
|
TooManyStatements:
|
|
4
4
|
max_statements: 7
|
|
5
5
|
UncommunicativeVariableName:
|
|
6
|
-
enabled: false
|
|
6
|
+
enabled: false
|
|
7
|
+
FeatureEnvy:
|
|
8
|
+
exclude:
|
|
9
|
+
- fetch_last_id
|
|
10
|
+
- last_item
|
|
11
|
+
- update_time_columns
|
|
12
|
+
TooManyMethods:
|
|
13
|
+
max_methods: 20
|
|
14
|
+
exclude:
|
|
15
|
+
- ValidationEditor
|
|
16
|
+
LongParameterList:
|
|
17
|
+
exclude:
|
|
18
|
+
- process_and_update_time_field
|
|
19
|
+
- invalid_time_value?
|
|
20
|
+
DataClump:
|
|
21
|
+
exclude:
|
|
22
|
+
- TimeValidationHelpers
|
data/.rubocop.yml
CHANGED
|
@@ -4,6 +4,11 @@ AllCops:
|
|
|
4
4
|
SuggestExtensions: false
|
|
5
5
|
Exclude:
|
|
6
6
|
- timet.gemspec
|
|
7
|
+
- "vendor/**/*" # Exclude vendor/bundle gems
|
|
8
|
+
|
|
9
|
+
Metrics/ModuleLength:
|
|
10
|
+
Exclude:
|
|
11
|
+
- 'lib/timet/tag_distribution.rb'
|
|
7
12
|
|
|
8
13
|
Metrics/MethodLength:
|
|
9
14
|
Max: 15
|
|
@@ -11,7 +16,7 @@ Metrics/MethodLength:
|
|
|
11
16
|
plugins: rubocop-rspec
|
|
12
17
|
|
|
13
18
|
RSpec/ExampleLength:
|
|
14
|
-
Max: 15
|
|
19
|
+
Max: 15
|
|
15
20
|
|
|
16
21
|
Metrics/CyclomaticComplexity:
|
|
17
22
|
Max: 8
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,40 @@
|
|
|
1
|
+
## [1.6.3] - 2026-02-28
|
|
2
|
+
|
|
3
|
+
**Improvements:**
|
|
4
|
+
|
|
5
|
+
- **Validation Architecture:** Refactored validation logic from `ValidationEditHelper` module to `ValidationEditor` class for better encapsulation and testability.
|
|
6
|
+
- **Synchronization & Storage:** Simplified `DatabaseSyncer` and `S3Supabase` by extracting modular helper methods, introducing `S3Config` module, and `S3ObjectRef` struct.
|
|
7
|
+
- **Reporting Features:** Added `export_csv` and `export_icalendar` methods to `TimeReport` for enhanced data portability.
|
|
8
|
+
- **Database Refactoring:** Converted `Timet::Database` methods to class methods where appropriate, extracted column checks, and simplified item fetching logic.
|
|
9
|
+
- **Tag Distribution:** Split `TagDistribution` into dedicated formatting and logic modules using a Context struct for clearer rendering.
|
|
10
|
+
- **Dependencies:** Updated `aws-sdk-s3` to `~> 1.213`, removed unused `httparty` gem, and bumped RuboCop, parser, and thor dependencies.
|
|
11
|
+
- **Code Quality:** Updated `.reek.yml` and RuboCop configs to accommodate new method structures, exclusions, and added code coverage badge to README.
|
|
12
|
+
- **Cleanup:** Removed obsolete helper modules (`item_data_helper`, `time_report_helper`, `time_update_helper`, `time_validation_helper`).
|
|
13
|
+
|
|
14
|
+
**Bug Fixes:**
|
|
15
|
+
|
|
16
|
+
- **Status Determination:** Added nil guards to `determine_status` to prevent runtime errors during item status checks.
|
|
17
|
+
- **Data Integrity:** Resolved duplicated `get_item_values` logic in syncer to ensure consistency during inserts and updates.
|
|
18
|
+
- **Validation Logic:** Updated validation methods to correctly handle end datetime adjustments for the next day.
|
|
19
|
+
|
|
20
|
+
## [1.6.2] - 2025-12-28
|
|
21
|
+
|
|
22
|
+
**Improvements:**
|
|
23
|
+
|
|
24
|
+
- **Database Hardening:** Added strict validations for table/column names in `add_column` and allowed fields in `update_item`. `execute_sql` now raises `SQLite3::SQLException` instead of suppressing it, improving error visibility.
|
|
25
|
+
- **Time Parsing Robustness:** Enhanced `TimeHelper#update_time_field` to robustly parse "HH:MM:SS" and "HH:MM" time strings using proper time construction.
|
|
26
|
+
- **Documentation Updates:** Updated README with explicit examples for `resume --pomodoro` and `summary --report` usage, and improved command reference formatting.
|
|
27
|
+
- **Refactoring:** Renamed `Timet::Utils.convert_to_datetime` to `convert_to_time` to better reflect that it returns a `Time` object, and updated related specs.
|
|
28
|
+
- **Dependency Updates:** Updated `aws-sdk-s3` to `~> 1.209.0`, `dotenv` to `~> 3.2`, `rubocop-rake` to `~> 0.7`, and other dependencies in `Gemfile` and `Gemfile.lock`.
|
|
29
|
+
- **CI/CD Enhancements:** Replaced DeepSource integration with Qlty for code analysis and test coverage reporting. Simplified CI workflow and added RuboCop with `continue-on-error` configuration.
|
|
30
|
+
- **Code Quality:** Applied RuboCop fixes including frozen string literals, numeric predicate corrections, and redundant interpolation fixes.
|
|
31
|
+
|
|
32
|
+
**Bug Fixes:**
|
|
33
|
+
|
|
34
|
+
- **Data Consistency:** Updated `update_time_columns` to ensure `updated_at` and `created_at` are populated with a fallback time (start time or current time) if the end time is nil.
|
|
35
|
+
- **Error Propagation:** Fixed `execute_sql` to raise exceptions instead of silently returning empty arrays, improving debugging capabilities.
|
|
36
|
+
- **Configuration:** Updated `.rubocop.yml` to exclude vendor directory and prevent interference from gem configurations.
|
|
37
|
+
|
|
1
38
|
## [1.6.1] - 2025-10-10
|
|
2
39
|
|
|
3
40
|
**New Features:**
|
|
@@ -11,7 +48,6 @@
|
|
|
11
48
|
- **README Updates:** Added new examples for the `--search` option and updated the project homepage URL.
|
|
12
49
|
- **Time Report Filtering:** Enhanced `TimeReport` to incorporate the `--search` option for filtering items by tag or notes.
|
|
13
50
|
|
|
14
|
-
|
|
15
51
|
## [1.6.0] - 2025-09-24
|
|
16
52
|
|
|
17
53
|
**New Features:**
|
|
@@ -28,7 +64,6 @@
|
|
|
28
64
|
- **README Updates:** Added new interactive mode examples for the `edit` command and updated the project homepage URL.
|
|
29
65
|
- **Timezone Consistency:** Improved time handling in `ValidationEditHelper` specs by consistently using `Time.parse().getlocal()` for better timezone accuracy.
|
|
30
66
|
|
|
31
|
-
|
|
32
67
|
## [1.5.9] - 2025-07-30
|
|
33
68
|
|
|
34
69
|
**Improvements:**
|
|
@@ -424,7 +459,6 @@
|
|
|
424
459
|
**Improvements:**
|
|
425
460
|
|
|
426
461
|
- **Refactor `TimeReport` to use `TimeReportHelper` module for utility methods:**
|
|
427
|
-
|
|
428
462
|
- Extracted utility methods (`add_hashes`, `date_ranges`, `format_item`, `valid_date_format?`) into a new `TimeReportHelper` module.
|
|
429
463
|
- Updated `TimeReport` class to include `TimeReportHelper` module.
|
|
430
464
|
- Removed redundant utility methods from `TimeReport` class.
|
|
@@ -434,7 +468,6 @@
|
|
|
434
468
|
- Adjusted formatting in `total` method for better alignment.
|
|
435
469
|
|
|
436
470
|
- **Refactor `Timet::Formatter` to improve readability and modularity:**
|
|
437
|
-
|
|
438
471
|
- Introduced a constant `CHAR_MAPPING` to store block characters for different value ranges.
|
|
439
472
|
- Refactored `format_notes` method to use a more descriptive variable name for the maximum length.
|
|
440
473
|
- Updated `format_tag_distribution` method to accept `colors` parameter and pass it to `process_and_print_tags`.
|
data/README.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
[](https://badge.fury.io/rb/timet)
|
|
2
2
|

|
|
3
|
-
[](https://qlty.sh/gh/frankvielma/projects/timet)
|
|
4
|
+
[](https://qlty.sh/gh/frankvielma/projects/timet)
|
|
5
|
+
|
|
4
6
|
# Timet
|
|
5
7
|
|
|
6
8
|

|
|
7
9
|
|
|
8
|
-
|
|
9
10
|
## Table of Contents
|
|
10
11
|
|
|
11
12
|
- [🔑 Key Features](#key-features)
|
|
@@ -19,7 +20,6 @@
|
|
|
19
20
|
- [Contributing](#contributing)
|
|
20
21
|
- [License](#license)
|
|
21
22
|
|
|
22
|
-
|
|
23
23
|
[Timet](https://rubygems.org/gems/timet) is a command-line tool designed to track your activities by recording the time spent on each task. This tool allows you to monitor your work hours and productivity directly from your terminal, eliminating the need for a graphical interface. Essentially, it's a way to log your time spent on different projects or tasks using simple text commands.
|
|
24
24
|
|
|
25
25
|
<h2 id="key-features">🔑 Key Features:</h2>
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|

|
|
46
46
|
|
|
47
47
|
<a name="requirements"></a>
|
|
48
|
+
|
|
48
49
|
<h2 id="requirements">✔️ Requirements</h2>
|
|
49
50
|
|
|
50
51
|
- Ruby version: >= 3.0.0
|
|
@@ -56,6 +57,7 @@ For older versions of Ruby and Sqlite:
|
|
|
56
57
|
- [Ruby >= 2.4](https://github.com/frankvielma/timet/tree/ruby-2.4.0)
|
|
57
58
|
|
|
58
59
|
<a name="installation"></a>
|
|
60
|
+
|
|
59
61
|
## 💾 Installation
|
|
60
62
|
|
|
61
63
|
Install the gem by executing:
|
|
@@ -65,6 +67,7 @@ gem install timet
|
|
|
65
67
|
```
|
|
66
68
|
|
|
67
69
|
<a name="usage"></a>
|
|
70
|
+
|
|
68
71
|
## ⏳ Usage
|
|
69
72
|
|
|
70
73
|
### Command Aliases
|
|
@@ -125,6 +128,7 @@ gem install timet
|
|
|
125
128
|
Once configured, Timet will automatically send a notification to your Discord channel when a Pomodoro session ends.
|
|
126
129
|
|
|
127
130
|
---
|
|
131
|
+
|
|
128
132
|
---
|
|
129
133
|
|
|
130
134
|
- **`timet stop`:** Stops tracking the current task, records the elapsed time, and displays the total time spent on all tasks.
|
|
@@ -152,6 +156,12 @@ Once configured, Timet will automatically send a notification to your Discord ch
|
|
|
152
156
|
timet resume 1
|
|
153
157
|
```
|
|
154
158
|
|
|
159
|
+
To resume with a Pomodoro timer:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
timet resume 1 --pomodoro=25
|
|
163
|
+
```
|
|
164
|
+
|
|
155
165
|
```
|
|
156
166
|
Tracked time report [today]:
|
|
157
167
|
+-------+------------+--------+----------+----------+----------+--------------------------+
|
|
@@ -216,27 +226,33 @@ Once configured, Timet will automatically send a notification to your Discord ch
|
|
|
216
226
|
```
|
|
217
227
|
|
|
218
228
|
<a name="command-reference"></a>
|
|
229
|
+
|
|
219
230
|
## 📋 Command Reference
|
|
220
231
|
|
|
221
|
-
| Command
|
|
222
|
-
|
|
|
223
|
-
| `timet start [tag] --notes='' --pomodoro=[time]` | Start tracking time for a task labeled [tag] and notes (optional).
|
|
224
|
-
| `timet stop`
|
|
225
|
-
| `timet summary today (t)`
|
|
226
|
-
| `timet summary yesterday (y)`
|
|
227
|
-
| `timet summary week (w)`
|
|
228
|
-
| `timet summary month (m)`
|
|
229
|
-
| `timet su t --csv=[filename]`
|
|
230
|
-
| `timet su w --ics=[filename]`
|
|
231
|
-
| `timet su
|
|
232
|
-
| `timet
|
|
233
|
-
| `timet
|
|
234
|
-
| `timet
|
|
235
|
-
| `timet
|
|
236
|
-
| `timet
|
|
237
|
-
| `timet
|
|
238
|
-
| `timet
|
|
239
|
-
| `timet
|
|
232
|
+
| Command | Description | Example Usage |
|
|
233
|
+
| ------------------------------------------------ | ---------------------------------------------------------------------- | --------------------------------- |
|
|
234
|
+
| `timet start [tag] --notes='' --pomodoro=[time]` | Start tracking time for a task labeled [tag] and notes (optional). | `timet start Task "My notes" 25` |
|
|
235
|
+
| `timet stop` | Stop tracking time. | `timet stop` |
|
|
236
|
+
| `timet summary today (t)` | Display a report of tracked time for today. | `timet su t` or `timet su` |
|
|
237
|
+
| `timet summary yesterday (y)` | Display a report of tracked time for yesterday. | `timet su y` |
|
|
238
|
+
| `timet summary week (w)` | Display a report of tracked time for the week. | `timet su w` |
|
|
239
|
+
| `timet summary month (m)` | Display a report of tracked time for the month. | `timet su m` |
|
|
240
|
+
| `timet su t --csv=[filename]` | Display a report of tracked time for today and export to CSV file | `timet su t --csv=file.csv` |
|
|
241
|
+
| `timet su w --ics=[filename]` | Display a report of tracked time for week and export to iCalendar file | `timet su w --ics=file.csv` |
|
|
242
|
+
| `timet su --report` | Display a detailed report of tag distribution for today. | `timet su --report` |
|
|
243
|
+
| `timet su t --report` | Display a detailed report of tag distribution for today. | `timet su t --report` |
|
|
244
|
+
| `timet su w --report` | Display a detailed report of tag distribution for the week. | `timet su w --report` |
|
|
245
|
+
| `timet summary [time_scope] [tag]` | Display a report of tracked time filtered by tag. | `timet su week mytag` |
|
|
246
|
+
| `timet summary [time_scope] --search=[query]` | Display a report of tracked time filtered by tag or notes. | `timet su week --search="bug"` |
|
|
247
|
+
| `timet delete [id]` | Delete a task by its ID. | `timet d [id]` |
|
|
248
|
+
| `timet cancel` | Cancel active time tracking. | `timet c` |
|
|
249
|
+
| `timet edit [id]` | Update a task's notes, tag, start, or end fields. | `timet e [id]` |
|
|
250
|
+
| `timet su [date]` | Display a report of tracked time for a specific date. | `timet su 2024-01-03` |
|
|
251
|
+
| `timet su [start_date]..[end_date]` | Display a report of tracked time for a date range. | `timet su 2024-01-02..2024-01-03` |
|
|
252
|
+
| `timet resume (r) [id]` | Resume tracking a task by ID or the last completed task. | `timet resume [id]` |
|
|
253
|
+
| `timet resume (r) [id] --pomodoro=[minutes]` | Resume tracking with a Pomodoro timer. | `timet resume 1 --pomodoro=25` |
|
|
254
|
+
| `timet sync` | Sync local db with remote (S3) external db | `timet sync` |
|
|
255
|
+
| `timet version` | Display the current version. | `timet version` |
|
|
240
256
|
|
|
241
257
|
### Date Range in Summary
|
|
242
258
|
|
|
@@ -257,11 +273,13 @@ The `timet summary` command now supports specifying a date range for generating
|
|
|
257
273
|
```
|
|
258
274
|
|
|
259
275
|
<a name="data"></a>
|
|
276
|
+
|
|
260
277
|
## 🗃️ Data
|
|
261
278
|
|
|
262
279
|
Timet's data is stored in `~/.timet`.
|
|
263
280
|
|
|
264
281
|
<a name="s3-cloud-backup-configuration"></a>
|
|
282
|
+
|
|
265
283
|
## 🔒 S3 Cloud Backup Configuration
|
|
266
284
|
|
|
267
285
|
Timet supports backing up and syncing your time tracking data with S3-compatible storage services (such as Supabase S3). To configure S3 backup, follow these steps:
|
|
@@ -284,8 +302,6 @@ S3_REGION=your_s3_region
|
|
|
284
302
|
- Regularly rotate your S3 access credentials
|
|
285
303
|
- Implement appropriate IAM policies to restrict bucket access
|
|
286
304
|
|
|
287
|
-
|
|
288
|
-
|
|
289
305
|
## Development
|
|
290
306
|
|
|
291
307
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/timet/application.rb
CHANGED
|
@@ -4,7 +4,7 @@ require 'thor'
|
|
|
4
4
|
require 'tty-prompt'
|
|
5
5
|
require 'icalendar'
|
|
6
6
|
require_relative 's3_supabase'
|
|
7
|
-
require_relative '
|
|
7
|
+
require_relative 'validation_editor'
|
|
8
8
|
require_relative 'application_helper'
|
|
9
9
|
require_relative 'time_helper'
|
|
10
10
|
require_relative 'version'
|
|
@@ -22,7 +22,6 @@ module Timet
|
|
|
22
22
|
# - delete: Delete a task
|
|
23
23
|
# - cancel: Cancel active time tracking
|
|
24
24
|
class Application < Thor
|
|
25
|
-
include ValidationEditHelper
|
|
26
25
|
include ApplicationHelper
|
|
27
26
|
include TimeHelper
|
|
28
27
|
|
|
@@ -271,7 +270,8 @@ Update start time => tt edit 12 start 12:33'
|
|
|
271
270
|
new_value = prompt_for_new_value(item, field)
|
|
272
271
|
end
|
|
273
272
|
|
|
274
|
-
|
|
273
|
+
editor = Timet::ValidationEditor.new(item, @db)
|
|
274
|
+
updated_item = editor.update(field, new_value)
|
|
275
275
|
@db.update_item(id, field, updated_item[FIELD_INDEX[field]])
|
|
276
276
|
display_item(updated_item)
|
|
277
277
|
end
|
data/lib/timet/database.rb
CHANGED
|
@@ -24,7 +24,7 @@ module Timet
|
|
|
24
24
|
# @note The method creates a new SQLite3 database connection and initializes the necessary tables if they
|
|
25
25
|
# do not already exist.
|
|
26
26
|
def initialize(database_path = DEFAULT_DATABASE_PATH)
|
|
27
|
-
move_old_database_file(database_path)
|
|
27
|
+
self.class.move_old_database_file(database_path)
|
|
28
28
|
|
|
29
29
|
@db = SQLite3::Database.new(database_path)
|
|
30
30
|
create_table
|
|
@@ -73,14 +73,20 @@ module Timet
|
|
|
73
73
|
# @note If the column does not exist, the method executes an SQL `ALTER TABLE` statement to add the column.
|
|
74
74
|
# @note The method prints a message indicating that the column has been added.
|
|
75
75
|
def add_column(table_name, new_column_name, date_type)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
raise 'Invalid table name' unless table_name == 'items'
|
|
77
|
+
raise 'Invalid column name' unless /\A[a-zA-Z0-9_]+\z/.match?(new_column_name)
|
|
78
|
+
raise 'Invalid date type' unless %w[INTEGER TEXT BOOLEAN].include?(date_type)
|
|
79
|
+
return if column_exists?(new_column_name)
|
|
79
80
|
|
|
80
81
|
execute_sql("ALTER TABLE #{table_name} ADD COLUMN #{new_column_name} #{date_type}")
|
|
81
82
|
puts "Column '#{new_column_name}' added to table '#{table_name}'."
|
|
82
83
|
end
|
|
83
84
|
|
|
85
|
+
def column_exists?(new_column_name)
|
|
86
|
+
execute_sql("SELECT count(*) FROM pragma_table_info('items') where name=?",
|
|
87
|
+
[new_column_name]).first.first.positive?
|
|
88
|
+
end
|
|
89
|
+
|
|
84
90
|
# Inserts a new item into the items table.
|
|
85
91
|
#
|
|
86
92
|
# @param start [Integer] The start time of the item.
|
|
@@ -115,6 +121,9 @@ module Timet
|
|
|
115
121
|
#
|
|
116
122
|
# @note The method executes SQL to update the specified field of the item with the given ID.
|
|
117
123
|
def update_item(id, field, value)
|
|
124
|
+
allowed_fields = %w[tag notes start end deleted updated_at created_at]
|
|
125
|
+
raise "Invalid field: #{field}" unless allowed_fields.include?(field)
|
|
126
|
+
|
|
118
127
|
execute_sql("UPDATE items SET #{field} = ?, updated_at = ? WHERE id = ?", [value, Time.now.utc.to_i, id])
|
|
119
128
|
end
|
|
120
129
|
|
|
@@ -143,8 +152,8 @@ module Timet
|
|
|
143
152
|
#
|
|
144
153
|
# @note The method executes SQL to fetch the ID of the last inserted item.
|
|
145
154
|
def fetch_last_id
|
|
146
|
-
|
|
147
|
-
|
|
155
|
+
execute_sql('SELECT id FROM items WHERE deleted IS NULL OR deleted = 0 ORDER BY id DESC LIMIT 1')
|
|
156
|
+
.then { |result| result.empty? ? nil : result.first.first }
|
|
148
157
|
end
|
|
149
158
|
|
|
150
159
|
# Fetches the last item from the items table.
|
|
@@ -156,8 +165,8 @@ module Timet
|
|
|
156
165
|
#
|
|
157
166
|
# @note The method executes SQL to fetch the last item from the 'items' table.
|
|
158
167
|
def last_item
|
|
159
|
-
|
|
160
|
-
|
|
168
|
+
execute_sql('SELECT * FROM items WHERE deleted IS NULL OR deleted = 0 ORDER BY id DESC LIMIT 1')
|
|
169
|
+
.then { |result| result.empty? ? nil : result.first }
|
|
161
170
|
end
|
|
162
171
|
|
|
163
172
|
# Finds an item by its ID.
|
|
@@ -173,8 +182,7 @@ module Timet
|
|
|
173
182
|
# @note If the item is found, it returns the item as an array.
|
|
174
183
|
# @note If the item is not found, it returns nil.
|
|
175
184
|
def find_item(id)
|
|
176
|
-
|
|
177
|
-
result.first.dup if result.any? # Add .dup to create a copy
|
|
185
|
+
execute_sql('SELECT * FROM items WHERE id = ?', [id]).first&.dup
|
|
178
186
|
end
|
|
179
187
|
|
|
180
188
|
# Fetches all items from the items table that have a start time greater than or equal to today.
|
|
@@ -203,9 +211,10 @@ module Timet
|
|
|
203
211
|
#
|
|
204
212
|
# @param id [Integer, nil] The ID of the item to check. If nil, the last item in the table is used.
|
|
205
213
|
#
|
|
214
|
+
# @see StatusHelper#determine_status
|
|
206
215
|
def item_status(id = nil)
|
|
207
|
-
id
|
|
208
|
-
determine_status(find_item(id))
|
|
216
|
+
id ||= fetch_last_id
|
|
217
|
+
self.class.determine_status(find_item(id))
|
|
209
218
|
end
|
|
210
219
|
|
|
211
220
|
# Executes a SQL query and returns the result.
|
|
@@ -221,9 +230,6 @@ module Timet
|
|
|
221
230
|
# @note The method executes the given SQL query with the provided parameters and returns the result.
|
|
222
231
|
def execute_sql(sql, params = [])
|
|
223
232
|
@db.execute(sql, params)
|
|
224
|
-
rescue SQLite3::SQLException => e
|
|
225
|
-
puts "Error: #{e.message}"
|
|
226
|
-
[]
|
|
227
233
|
end
|
|
228
234
|
|
|
229
235
|
# Closes the database connection.
|
|
@@ -276,8 +282,8 @@ module Timet
|
|
|
276
282
|
# @note The method checks if the result set is empty and returns :no_items if true.
|
|
277
283
|
# @note If the last item in the result set has no end time, it returns :in_progress.
|
|
278
284
|
# @note If the last item in the result set has an end time, it returns :complete.
|
|
279
|
-
def determine_status(result)
|
|
280
|
-
return :no_items
|
|
285
|
+
def self.determine_status(result)
|
|
286
|
+
return :no_items unless result
|
|
281
287
|
|
|
282
288
|
last_item_end = result[2]
|
|
283
289
|
return :in_progress unless last_item_end
|
|
@@ -288,11 +294,12 @@ module Timet
|
|
|
288
294
|
# Moves the old database file to the new location if it exists.
|
|
289
295
|
#
|
|
290
296
|
# @param database_path [String] The path to the new SQLite database file.
|
|
291
|
-
def move_old_database_file(database_path)
|
|
297
|
+
def self.move_old_database_file(database_path)
|
|
292
298
|
old_file = File.join(Dir.home, '.timet.db')
|
|
293
299
|
return unless File.exist?(old_file)
|
|
294
300
|
|
|
295
|
-
|
|
301
|
+
dir = File.dirname(database_path)
|
|
302
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
|
296
303
|
FileUtils.mv(old_file, database_path)
|
|
297
304
|
end
|
|
298
305
|
|
|
@@ -312,12 +319,12 @@ module Timet
|
|
|
312
319
|
# @raise [StandardError] If there is an issue executing the SQL queries, an error may be raised.
|
|
313
320
|
#
|
|
314
321
|
def update_time_columns
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
322
|
+
execute_sql('SELECT * FROM items WHERE updated_at IS NULL OR created_at IS NULL')
|
|
323
|
+
.each { |item| update_timestamp_for_item(item[0], item[2] || item[1] || Time.now.to_i) }
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
def update_timestamp_for_item(id, fallback_time)
|
|
327
|
+
execute_sql('UPDATE items SET updated_at = ?, created_at = ? WHERE id = ?', [fallback_time, fallback_time, id])
|
|
321
328
|
end
|
|
322
329
|
end
|
|
323
330
|
end
|