timet 1.3.1 → 1.4.0
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 +59 -0
- data/README.md +7 -24
- data/lib/timet/application.rb +19 -36
- data/lib/timet/application_helper.rb +36 -5
- data/lib/timet/color_codes.rb +61 -0
- data/lib/timet/database.rb +20 -14
- data/lib/timet/table.rb +300 -0
- data/lib/timet/tag_distribution.rb +61 -0
- data/lib/timet/time_block_chart.rb +239 -0
- data/lib/timet/time_report.rb +20 -44
- data/lib/timet/time_report_helper.rb +0 -66
- data/lib/timet/validation_edit_helper.rb +1 -1
- data/lib/timet/version.rb +2 -2
- data/lib/timet.rb +1 -13
- metadata +6 -3
- data/lib/timet/formatter.rb +0 -298
data/lib/timet/time_report.rb
CHANGED
@@ -2,17 +2,20 @@
|
|
2
2
|
|
3
3
|
require 'date'
|
4
4
|
require 'csv'
|
5
|
-
require_relative 'status_helper'
|
6
|
-
require_relative 'formatter'
|
7
5
|
require_relative 'time_report_helper'
|
6
|
+
require_relative 'table'
|
7
|
+
require_relative 'time_block_chart'
|
8
|
+
require_relative 'tag_distribution'
|
8
9
|
|
9
10
|
module Timet
|
10
11
|
# The TimeReport class is responsible for displaying a report of tracked time
|
11
12
|
# entries. It allows filtering the report by time periods and displays
|
12
13
|
# a formatted table with the relevant information.
|
13
14
|
class TimeReport
|
14
|
-
include Formatter
|
15
15
|
include TimeReportHelper
|
16
|
+
include Table
|
17
|
+
include TimeBlockChart
|
18
|
+
include TagDistribution
|
16
19
|
|
17
20
|
# Provides access to the database instance.
|
18
21
|
attr_reader :db
|
@@ -54,15 +57,12 @@ module Timet
|
|
54
57
|
def display
|
55
58
|
return puts 'No tracked time found for the specified filter.' if items.empty?
|
56
59
|
|
57
|
-
|
58
|
-
time_block, duration_by_tag = process_time_entries
|
59
|
-
puts format_table_separator
|
60
|
-
total
|
60
|
+
time_block, duration_by_tag = table
|
61
61
|
|
62
62
|
colors = duration_by_tag.map { |x| x[0] }.sort.each_with_index.to_h
|
63
63
|
print_time_block_chart(time_block, colors)
|
64
64
|
|
65
|
-
|
65
|
+
tag_distribution(duration_by_tag, colors)
|
66
66
|
end
|
67
67
|
|
68
68
|
# Displays a single row of the report.
|
@@ -76,9 +76,9 @@ module Timet
|
|
76
76
|
#
|
77
77
|
# @note The method formats and prints the table header, row, and total duration.
|
78
78
|
def show_row(item)
|
79
|
-
|
79
|
+
header
|
80
80
|
display_time_entry(item)
|
81
|
-
puts
|
81
|
+
puts separator
|
82
82
|
total
|
83
83
|
end
|
84
84
|
|
@@ -116,42 +116,18 @@ module Timet
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
119
|
-
#
|
120
|
-
#
|
121
|
-
# @param item [Array] The item to display.
|
122
|
-
# @param date [String, nil] The date to display. If nil, the date is not displayed.
|
123
|
-
#
|
124
|
-
# @return [void] This method does not return a value; it performs side effects such as printing the row.
|
125
|
-
#
|
126
|
-
# @example Display a time entry
|
127
|
-
# display_time_entry(item, '2021-10-01')
|
128
|
-
#
|
129
|
-
# @note The method formats and prints the row for the time entry.
|
130
|
-
def display_time_entry(item, date = nil)
|
131
|
-
return puts 'Missing time entry data.' unless item
|
132
|
-
|
133
|
-
id, start_time_value, end_time_value, tag_name, notes = item
|
134
|
-
duration = TimeHelper.calculate_duration(start_time_value, end_time_value)
|
135
|
-
start_time = TimeHelper.format_time(start_time_value)
|
136
|
-
end_time = TimeHelper.format_time(end_time_value) || '- -'
|
137
|
-
start_date = date || (' ' * 10)
|
138
|
-
puts format_table_row(id, tag_name[0..5], start_date, start_time, end_time, duration, notes)
|
139
|
-
end
|
140
|
-
|
141
|
-
# Displays the total duration of the tracked time entries.
|
142
|
-
#
|
143
|
-
# @return [void] This method does not return a value; it performs side effects such as printing the total duration.
|
119
|
+
# Writes the CSV rows for the time report.
|
144
120
|
#
|
145
|
-
# @
|
146
|
-
#
|
121
|
+
# @param csv [CSV] The CSV object to which the rows will be written.
|
122
|
+
# @return [void]
|
147
123
|
#
|
148
|
-
# @
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
124
|
+
# @example
|
125
|
+
# csv = CSV.new(file)
|
126
|
+
# write_csv_rows(csv)
|
127
|
+
def write_csv_rows(csv)
|
128
|
+
items.each do |item|
|
129
|
+
csv << format_item(item)
|
130
|
+
end
|
155
131
|
end
|
156
132
|
|
157
133
|
# Filters the items based on the specified filter and tag.
|
@@ -6,58 +6,6 @@ module Timet
|
|
6
6
|
# and validating date formats.
|
7
7
|
# This module is designed to be included in classes that require time report processing functionalities.
|
8
8
|
module TimeReportHelper
|
9
|
-
# Processes each time entry in the items array and updates the time block and duration by tag.
|
10
|
-
#
|
11
|
-
# @return [Array<(Hash, Hash)>] An array containing the updated time block and duration by tag.
|
12
|
-
#
|
13
|
-
# @example
|
14
|
-
# items = [
|
15
|
-
# [start_time1, end_time1, tag1],
|
16
|
-
# [start_time2, end_time2, tag2]
|
17
|
-
# ]
|
18
|
-
# process_time_entries
|
19
|
-
# #=> [{ '2024-10-21' => { 8 => [duration1, tag1], 9 => [duration2, tag2] } }, { tag1 => total_duration1,
|
20
|
-
# tag2 => total_duration2 }]
|
21
|
-
def process_time_entries
|
22
|
-
duration_by_tag = Hash.new(0)
|
23
|
-
time_block = Hash.new { |hash, key| hash[key] = {} }
|
24
|
-
|
25
|
-
items.each_with_index do |item, idx|
|
26
|
-
display_time_entry(item, TimeHelper.extract_date(items, idx))
|
27
|
-
start_time = item[1]
|
28
|
-
end_time = item[2]
|
29
|
-
tag = item[3]
|
30
|
-
time_block = process_time_block_item(start_time, end_time, tag, time_block)
|
31
|
-
|
32
|
-
duration_by_tag[tag] += TimeHelper.calculate_duration(start_time, end_time)
|
33
|
-
end
|
34
|
-
[time_block, duration_by_tag]
|
35
|
-
end
|
36
|
-
|
37
|
-
# Processes a time block item and updates the time block hash.
|
38
|
-
#
|
39
|
-
# @param start_time [Time] The start time of the time block.
|
40
|
-
# @param end_time [Time] The end time of the time block.
|
41
|
-
# @param tag [String] The tag associated with the time block.
|
42
|
-
# @param time_block [Hash] A hash containing time block data, where keys are dates and values are hashes of time
|
43
|
-
# slots and their corresponding values.
|
44
|
-
# @return [Hash] The updated time block hash.
|
45
|
-
#
|
46
|
-
# @example
|
47
|
-
# start_time = Time.new(2024, 10, 21, 8, 0, 0)
|
48
|
-
# end_time = Time.new(2024, 10, 21, 9, 0, 0)
|
49
|
-
# tag = 'work'
|
50
|
-
# time_block = {}
|
51
|
-
# process_time_block_item(start_time, end_time, tag, time_block)
|
52
|
-
# #=> { '2024-10-21' => { 8 => [duration, 'work'] } }
|
53
|
-
def process_time_block_item(*args)
|
54
|
-
start_time, end_time, tag, time_block = args
|
55
|
-
block_hour = TimeHelper.count_seconds_per_hour_block(start_time, end_time, tag)
|
56
|
-
date_line = TimeHelper.timestamp_to_date(start_time)
|
57
|
-
time_block[date_line] = add_hashes(time_block[date_line], block_hour)
|
58
|
-
time_block
|
59
|
-
end
|
60
|
-
|
61
9
|
# Provides predefined date ranges for filtering.
|
62
10
|
#
|
63
11
|
# @return [Hash] A hash containing predefined date ranges.
|
@@ -132,19 +80,5 @@ module Timet
|
|
132
80
|
[summed_number, old_value[1]]
|
133
81
|
end
|
134
82
|
end
|
135
|
-
|
136
|
-
# Writes the CSV rows for the time report.
|
137
|
-
#
|
138
|
-
# @param csv [CSV] The CSV object to which the rows will be written.
|
139
|
-
# @return [void]
|
140
|
-
#
|
141
|
-
# @example
|
142
|
-
# csv = CSV.new(file)
|
143
|
-
# write_csv_rows(csv)
|
144
|
-
def write_csv_rows(csv)
|
145
|
-
items.each do |item|
|
146
|
-
csv << format_item(item)
|
147
|
-
end
|
148
|
-
end
|
149
83
|
end
|
150
84
|
end
|
@@ -75,7 +75,7 @@ module Timet
|
|
75
75
|
# @example Print an error message for an invalid date
|
76
76
|
# print_error('Invalid date: 2023-13-32')
|
77
77
|
def print_error(message)
|
78
|
-
puts "
|
78
|
+
puts "Invalid date: #{message}".red
|
79
79
|
end
|
80
80
|
|
81
81
|
# Updates a time field (start or end) of a tracking item with a formatted date value.
|
data/lib/timet/version.rb
CHANGED
data/lib/timet.rb
CHANGED
@@ -1,18 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Require the Timet::Application class from the 'timet/application' file.
|
4
|
-
#
|
5
|
-
# @note This statement loads the Timet::Application class, which is responsible for handling the command-line
|
6
|
-
# interface and user commands.
|
7
3
|
require_relative 'timet/application'
|
8
|
-
|
9
|
-
# Require the Timet::Database class from the 'timet/database' file.
|
10
|
-
#
|
11
|
-
# @note This statement loads the Timet::Database class, which provides database access for managing time tracking data.
|
12
4
|
require_relative 'timet/database'
|
13
|
-
|
14
|
-
# Require the Timet::TimeReport class from the 'timet/time_report' file.
|
15
|
-
#
|
16
|
-
# @note This statement loads the Timet::TimeReport class, which is responsible for displaying a report
|
17
|
-
# of tracked time entries.
|
18
5
|
require_relative 'timet/time_report'
|
6
|
+
require_relative 'timet/color_codes'
|
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
|
+
version: 1.4.0
|
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-10-
|
11
|
+
date: 2024-10-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -80,9 +80,12 @@ files:
|
|
80
80
|
- lib/timet.rb
|
81
81
|
- lib/timet/application.rb
|
82
82
|
- lib/timet/application_helper.rb
|
83
|
+
- lib/timet/color_codes.rb
|
83
84
|
- lib/timet/database.rb
|
84
|
-
- lib/timet/formatter.rb
|
85
85
|
- lib/timet/status_helper.rb
|
86
|
+
- lib/timet/table.rb
|
87
|
+
- lib/timet/tag_distribution.rb
|
88
|
+
- lib/timet/time_block_chart.rb
|
86
89
|
- lib/timet/time_helper.rb
|
87
90
|
- lib/timet/time_report.rb
|
88
91
|
- lib/timet/time_report_helper.rb
|
data/lib/timet/formatter.rb
DELETED
@@ -1,298 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Timet
|
4
|
-
# This module is responsible for formatting the output of the `timet` application.
|
5
|
-
# It provides methods for formatting the table header, separators, and rows.
|
6
|
-
module Formatter
|
7
|
-
CHAR_MAPPING = {
|
8
|
-
0..120 => '_',
|
9
|
-
121..450 => '▁',
|
10
|
-
451..900 => '▂',
|
11
|
-
901..1350 => '▃',
|
12
|
-
1351..1800 => '▄',
|
13
|
-
1801..2250 => '▅',
|
14
|
-
2251..2700 => '▆',
|
15
|
-
2701..3150 => '▇',
|
16
|
-
3151..3600 => '█'
|
17
|
-
}.freeze
|
18
|
-
|
19
|
-
# Formats the header of the time tracking report table.
|
20
|
-
#
|
21
|
-
# @return [void] This method does not return a value; it performs side effects such as printing
|
22
|
-
# the formatted header.
|
23
|
-
#
|
24
|
-
# @example Format and print the table header
|
25
|
-
# format_table_header
|
26
|
-
#
|
27
|
-
# @note The method constructs a string representing the table header and prints it.
|
28
|
-
def format_table_header
|
29
|
-
header = <<~TABLE
|
30
|
-
Tracked time report \e[5m\u001b[31m[#{@filter}]\033[0m:
|
31
|
-
#{format_table_separator}
|
32
|
-
\033[32m| Id | Date | Tag | Start | End | Duration | Notes |\033[0m
|
33
|
-
#{format_table_separator}
|
34
|
-
TABLE
|
35
|
-
puts header
|
36
|
-
end
|
37
|
-
|
38
|
-
# Formats the separator line for the time tracking report table.
|
39
|
-
#
|
40
|
-
# @return [String] The formatted separator line.
|
41
|
-
#
|
42
|
-
# @example Get the formatted table separator
|
43
|
-
# format_table_separator # => '+-------+------------+--------+----------+----------+----------+------------+'
|
44
|
-
#
|
45
|
-
# @note The method returns a string representing the separator line for the table.
|
46
|
-
def format_table_separator
|
47
|
-
'+-------+------------+--------+----------+----------+----------+--------------------+'
|
48
|
-
end
|
49
|
-
|
50
|
-
# Formats a row of the time tracking report table.
|
51
|
-
#
|
52
|
-
# @param row [Array] The row data to be formatted.
|
53
|
-
# @return [String] The formatted row.
|
54
|
-
#
|
55
|
-
# @example Format a table row
|
56
|
-
# format_table_row(1, 'work', '2023-10-01', '12:00:00', '14:00:00', 7200, 'Completed task X')
|
57
|
-
#
|
58
|
-
# @note The method formats each element of the row and constructs a string representing the formatted row.
|
59
|
-
def format_table_row(*row)
|
60
|
-
id, tag, start_date, start_time, end_time, duration, notes = row
|
61
|
-
"| #{id.to_s.rjust(5)} | #{start_date} | #{tag.ljust(6)} | #{start_time.split[1]} | " \
|
62
|
-
"#{end_time.split[1].rjust(8)} | #{@db.seconds_to_hms(duration).rjust(8)} | #{format_notes(notes)} |"
|
63
|
-
end
|
64
|
-
|
65
|
-
# Formats the notes column of the time tracking report table.
|
66
|
-
#
|
67
|
-
# @param notes [String, nil] The notes to be formatted.
|
68
|
-
# @return [String] The formatted notes.
|
69
|
-
#
|
70
|
-
# @example Format notes
|
71
|
-
# format_notes('This is a long note that needs to be truncated')
|
72
|
-
#
|
73
|
-
# @note The method truncates the notes to a maximum of 20 characters and pads them to a fixed width.
|
74
|
-
def format_notes(notes)
|
75
|
-
spaces = 17
|
76
|
-
return ' ' * spaces unless notes
|
77
|
-
|
78
|
-
max_length = spaces - 3
|
79
|
-
notes = "#{notes.slice(0, max_length)}..." if notes.length > max_length
|
80
|
-
notes.ljust(spaces)
|
81
|
-
end
|
82
|
-
|
83
|
-
# @!method format_tag_distribution(duration_by_tag)
|
84
|
-
# Formats and displays the tag distribution.
|
85
|
-
#
|
86
|
-
# @example
|
87
|
-
# duration_by_tag = { "timet" => 3600, "nextjs" => 1800 }
|
88
|
-
# Formatter.format_tag_distribution(duration_by_tag)
|
89
|
-
# # Output:
|
90
|
-
# # timet: 66.67% \u001b[38;5;42m====================\u001b[0m
|
91
|
-
# # nextjs: 33.33% \u001b[38;5;42m==========\u001b[0m
|
92
|
-
#
|
93
|
-
# @param duration_by_tag [Hash<String, Integer>] A hash where keys are tags and values are durations in seconds.
|
94
|
-
# @return [void] This method outputs the formatted tag distribution to the console.
|
95
|
-
def format_tag_distribution(duration_by_tag, colors)
|
96
|
-
total = duration_by_tag.values.sum
|
97
|
-
return unless total.positive?
|
98
|
-
|
99
|
-
factor = duration_by_tag.size < 3 ? 2 : 1
|
100
|
-
sorted_duration_by_tag = duration_by_tag.sort_by { |_, duration| -duration }
|
101
|
-
process_and_print_tags(sorted_duration_by_tag, factor, total, colors)
|
102
|
-
end
|
103
|
-
|
104
|
-
# Processes and prints the tag distribution information.
|
105
|
-
#
|
106
|
-
# @param sorted_duration_by_tag [Array<Array(String, Numeric)>] An array of arrays where each inner array contains a
|
107
|
-
# tag and its corresponding duration, sorted by duration in descending order.
|
108
|
-
# @param factor [Numeric] The factor used to adjust the bar length.
|
109
|
-
# @param total [Numeric] The total duration of all tags combined.
|
110
|
-
# @return [void] This method outputs the tag distribution information to the standard output.
|
111
|
-
def process_and_print_tags(*args)
|
112
|
-
sorted_duration_by_tag, factor, total, colors = args
|
113
|
-
block = '▅'
|
114
|
-
sorted_duration_by_tag.each do |tag, duration|
|
115
|
-
value, bar_length = calculate_value_and_bar_length(duration, total, factor)
|
116
|
-
puts "#{tag.rjust(8)}: #{value.to_s.rjust(7)}% \u001b[38;5;#{colors[tag] + 1}m#{block * bar_length}\u001b[0m"
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
# Calculates the value and bar length for a given duration, total duration, and factor.
|
121
|
-
#
|
122
|
-
# @param duration [Numeric] The duration for the current tag.
|
123
|
-
# @param total [Numeric] The total duration.
|
124
|
-
# @param factor [Numeric] A factor to adjust the formatting.
|
125
|
-
# @return [Array<(Float, Integer)>] An array containing the calculated value and bar length.
|
126
|
-
#
|
127
|
-
# @example
|
128
|
-
# calculate_value_and_bar_length(50, 100, 2) #=> [50.0, 25]
|
129
|
-
def calculate_value_and_bar_length(duration, total, factor)
|
130
|
-
value = (duration.to_f / total * 100).round(2)
|
131
|
-
bar_length = (value / factor).round
|
132
|
-
[value, bar_length]
|
133
|
-
end
|
134
|
-
|
135
|
-
# Prints a time block chart based on the provided time block and colors.
|
136
|
-
#
|
137
|
-
# @param time_block [Hash] A hash where the keys are time blocks and the values are hashes of time slots and their
|
138
|
-
# corresponding values.
|
139
|
-
# Example: { "block1" => { 10 => "value1", 11 => "value2" }, "block2" => { 12 => "value3" } }
|
140
|
-
# @param colors [Hash] A hash where the keys are time slots and the values are the colors to be used
|
141
|
-
# for those slots.
|
142
|
-
# Example: { 10 => "red", 11 => "blue", 12 => "green" }
|
143
|
-
#
|
144
|
-
# @return [void] This method does not return a value; it prints the chart directly to the output.
|
145
|
-
#
|
146
|
-
# @example
|
147
|
-
# time_block = { "block1" => { 10 => "value1", 11 => "value2" }, "block2" => { 12 => "value3" } }
|
148
|
-
# colors = { 10 => "red", 11 => "blue", 12 => "green" }
|
149
|
-
# print_time_block_chart(time_block, colors)
|
150
|
-
#
|
151
|
-
# @note This method relies on two helper methods: `print_header` and `print_blocks`.
|
152
|
-
# Ensure these methods are defined and available in the scope where `print_time_block_chart` is called.
|
153
|
-
#
|
154
|
-
# @see #print_header
|
155
|
-
# @see #print_blocks
|
156
|
-
def print_time_block_chart(time_block, colors)
|
157
|
-
start_time = time_block.values.map(&:keys).flatten.uniq.min.to_i
|
158
|
-
print_header(start_time)
|
159
|
-
print_blocks(time_block, colors, start_time)
|
160
|
-
end
|
161
|
-
|
162
|
-
# Prints the header of the time block chart.
|
163
|
-
#
|
164
|
-
# The header includes a visual representation of the time slots from the given start time to 23.
|
165
|
-
# Each time slot is formatted as a two-digit number and aligned to the right within a fixed width.
|
166
|
-
#
|
167
|
-
# @param start_time [Integer] The starting time for the chart. This should be an integer between 0 and 23.
|
168
|
-
#
|
169
|
-
# @return [void] This method does not return a value; it prints the header directly to the output.
|
170
|
-
#
|
171
|
-
# @example
|
172
|
-
# print_header(10)
|
173
|
-
# # Output:
|
174
|
-
# #
|
175
|
-
# # ⏳ ↦ [ 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
|
176
|
-
#
|
177
|
-
# @note The method assumes that the start_time is within the valid range of 0 to 23.
|
178
|
-
# If the start_time is outside this range, the output may not be as expected.
|
179
|
-
def print_header(start_time)
|
180
|
-
puts
|
181
|
-
print "\u001b[38;5;244m┌╴W ╴╴╴╴╴⏰ ╴╴╴╴╴╴┬\u001b[0m "
|
182
|
-
(start_time..23).each { |hour| print format('%02d', hour).ljust(4) }
|
183
|
-
puts ''
|
184
|
-
end
|
185
|
-
|
186
|
-
# Prints the block characters for each hour in the time block chart.
|
187
|
-
#
|
188
|
-
# This method iterates over each hour from 0 to 23, retrieves the corresponding
|
189
|
-
# block character using the `get_block_char` method, and prints it aligned for
|
190
|
-
# readability. It also adds a double newline at the end for separation.
|
191
|
-
#
|
192
|
-
# @param time_block [Hash] A hash where the keys are formatted hour strings
|
193
|
-
# (e.g., "00", "01") and the values are the corresponding
|
194
|
-
# values to determine the block character.
|
195
|
-
# @example
|
196
|
-
# time_block = { "00" => 100, "01" => 200, ..., "23" => 300 }
|
197
|
-
# print_blocks(time_block)
|
198
|
-
# # Output:
|
199
|
-
# # ▁ ▂ ▃ ▄ ▅ ▆ ▇ █ ▁ ▂ ▃ ▄ ▅ ▆ ▇ █ ▁ ▂ ▃ ▄ ▅ ▆ ▇ █
|
200
|
-
# #
|
201
|
-
# # (followed by two newlines)
|
202
|
-
#
|
203
|
-
def print_blocks(time_block, colors, start_time)
|
204
|
-
return unless time_block
|
205
|
-
|
206
|
-
weeks = []
|
207
|
-
time_block.each_key do |date_string|
|
208
|
-
date = Date.parse(date_string)
|
209
|
-
day = date.strftime('%a')[0..1]
|
210
|
-
date1 = date_string
|
211
|
-
if %w[Sa Su].include?(day)
|
212
|
-
day = "\u001b[38;5;1m#{day}\u001b[0m"
|
213
|
-
date1 = "\u001b[38;5;1m#{date1}\u001b[0m"
|
214
|
-
end
|
215
|
-
|
216
|
-
weeks << date.cweek
|
217
|
-
n = weeks.size - 1
|
218
|
-
week = if (weeks[n] == weeks[n - 1]) && n.positive?
|
219
|
-
' '
|
220
|
-
else
|
221
|
-
"\e[4m#{weeks[n]}\e[0m"
|
222
|
-
end
|
223
|
-
puts "\u001b[38;5;244m┆ ┆\u001b[0m" if week != ' ' && n.positive?
|
224
|
-
print "\u001b[38;5;244m┆\u001b[0m#{week} #{date1} #{day} \u001b[38;5;244m┆\u001b[0m "
|
225
|
-
time_block_initial = time_block[date_string]
|
226
|
-
print_time_blocks(start_time, time_block_initial, colors)
|
227
|
-
puts
|
228
|
-
end
|
229
|
-
puts "\u001b[38;5;244m└╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴╴┴\u001b[0m"
|
230
|
-
end
|
231
|
-
|
232
|
-
# Prints time blocks for each hour from the start time to 23.
|
233
|
-
#
|
234
|
-
# @param start_time [Integer] The starting hour for printing time blocks.
|
235
|
-
# @param time_block_initial [Hash] A hash containing time block data, where keys are formatted hours and values
|
236
|
-
# are arrays containing block data.
|
237
|
-
# @param colors [Hash] A hash mapping tags to color codes.
|
238
|
-
# @return [void]
|
239
|
-
#
|
240
|
-
# @example
|
241
|
-
# time_block_initial = {
|
242
|
-
# '01' => ['block_char_data', 'tag']
|
243
|
-
# }
|
244
|
-
# colors = { 'tag' => 1 }
|
245
|
-
# print_time_blocks(1, time_block_initial, colors) # Prints time blocks for hours 1 to 23
|
246
|
-
def print_time_blocks(start_time, time_block_initial, colors)
|
247
|
-
(start_time..23).each do |hour|
|
248
|
-
tag, block_char = get_formatted_block_char(hour, time_block_initial)
|
249
|
-
print_colored_block(block_char, tag, colors)
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
# Returns the formatted block character and its associated tag for a given hour.
|
254
|
-
#
|
255
|
-
# @param hour [Integer] The hour for which to retrieve the block character.
|
256
|
-
# @param time_block_initial [Hash] A hash containing time block data, where keys are formatted hours and values
|
257
|
-
# are arrays containing block data.
|
258
|
-
# @return [Array<(String, String)>] An array containing the tag and the block character.
|
259
|
-
#
|
260
|
-
# @example
|
261
|
-
# time_block_initial = {
|
262
|
-
# '01' => ['block_char_data', 'tag']
|
263
|
-
# }
|
264
|
-
# get_formatted_block_char(1, time_block_initial) #=> ['tag', 'block_char']
|
265
|
-
def get_formatted_block_char(hour, time_block_initial)
|
266
|
-
formatted_hour = format('%02d', hour)
|
267
|
-
hour_data = time_block_initial[formatted_hour]
|
268
|
-
tag = hour_data&.last
|
269
|
-
[tag, get_block_char(hour_data&.first)]
|
270
|
-
end
|
271
|
-
|
272
|
-
# Prints a colored block character based on the provided tag and block character.
|
273
|
-
#
|
274
|
-
# @param block_char [String] The block character to be printed.
|
275
|
-
# @param tag [String] The tag associated with the block character, used to determine the color.
|
276
|
-
# @param colors [Hash] A hash mapping tags to color codes.
|
277
|
-
#
|
278
|
-
# @example
|
279
|
-
# colors = { 'tag' => 1 }
|
280
|
-
# print_colored_block('X', 'tag', colors) # Prints a colored block character 'XX'
|
281
|
-
def print_colored_block(block_char, tag, colors)
|
282
|
-
color_code = colors[tag]
|
283
|
-
block = block_char * 2
|
284
|
-
colored_block = color_code ? "\u001b[38;5;#{color_code + 1}m#{block}\u001b[0m " : block
|
285
|
-
print colored_block.ljust(4)
|
286
|
-
end
|
287
|
-
|
288
|
-
# Determines the block character based on the value.
|
289
|
-
#
|
290
|
-
# @param value [Integer] The value to determine the block character for.
|
291
|
-
# @return [String] The block character corresponding to the value.
|
292
|
-
def get_block_char(value)
|
293
|
-
return ' ' unless value
|
294
|
-
|
295
|
-
CHAR_MAPPING.find { |range, _| range.include?(value) }&.last || ' '
|
296
|
-
end
|
297
|
-
end
|
298
|
-
end
|