fewald-worklog 0.2.20 → 0.2.22

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7fab9613b51251c6cc9e6cd0f43dd1bd663db717c4783f2a1863b1441c7d8314
4
- data.tar.gz: a73221bf9dec2a5ada555243d7258fe4b68ba1427e6deaf8c303afd71dabdf41
3
+ metadata.gz: 03ec04755ea87ebd6808b5b9256ad07a0c95514e35ed719628531cbb5cb5a0d9
4
+ data.tar.gz: e8c62ab27e88132df53066704a09d0baf585b1c5208c1c2481e0b3940f69419c
5
5
  SHA512:
6
- metadata.gz: 94922720491591e24299a6da3abdd92e716a6cd61c1e91ea1cb05f880c4b11b0a4de36e04051d548b372653575753a633f279268d7e21b68c5cb895de17e7eaf
7
- data.tar.gz: 604b44430a2c1b85856cf461e4d79aa7425acc95694eca1fa557909cb80fbc6b80879b2dec0f61ae5bdf8093dc6483a779e96600716f4606d3f35f237feea219
6
+ metadata.gz: e735b3fb91b5125e6607e2a2b018fd41038f8b02c32c31fc8bd0f2f56f87ec40ede9731361071071e752addd260f10b65a50bc6678aa8b6d8618bba0acfa975d
7
+ data.tar.gz: 85a223a42f4b88a1957e74f570aca7eac3f879a8967b2a40dc266e192b4a36142ae82635df11cb22fb1d1fc941cffa6bd0c3a4b1ba131bec179c1a60913dacca
data/.version CHANGED
@@ -1 +1 @@
1
- 0.2.20
1
+ 0.2.22
data/lib/cli.rb CHANGED
@@ -31,7 +31,7 @@ class WorklogCLI < Thor
31
31
  # Initialize the CLI with the given arguments, options, and configuration
32
32
  def initialize(args = [], options = {}, config = {})
33
33
  @config = Worklog::Configuration.load
34
- @storage = Storage.new(@config)
34
+ @storage = Worklog::Storage.new(@config)
35
35
  super
36
36
  end
37
37
 
data/lib/daily_log.rb CHANGED
@@ -2,52 +2,65 @@
2
2
 
3
3
  require 'hash'
4
4
 
5
- # DailyLog is a container for a day's work log.
6
- class DailyLog
7
- # Container for a day's work log.
8
- include Hashify
5
+ module Worklog
6
+ # DailyLog is a container for a day's work log.
7
+ class DailyLog
8
+ # Container for a day's work log.
9
+ include Hashify
9
10
 
10
- # Represents a single day's work log.
11
- attr_accessor :date, :entries
11
+ # Represents a single day's work log.
12
+ attr_accessor :date, :entries
12
13
 
13
- def initialize(params = {})
14
- @date = params[:date]
15
- @entries = params[:entries]
16
- end
14
+ def initialize(params = {})
15
+ @date = params[:date]
16
+ @entries = params[:entries]
17
+ end
17
18
 
18
- # Returns true if there are people mentioned in any entry of the current day.
19
- #
20
- # @return [Boolean] true if there are people mentioned, false otherwise.
21
- def people?
22
- people.size.positive?
23
- end
19
+ # Returns true if there are people mentioned in any entry of the current day.
20
+ #
21
+ # @return [Boolean] true if there are people mentioned, false otherwise.
22
+ def people?
23
+ people.size.positive?
24
+ end
24
25
 
25
- # Returns a hash of people mentioned in the log for the current day
26
- # with the number of times they are mentioned.
27
- # People are defined as words starting with @ or ~.
28
- #
29
- # @return [Hash<String, Integer>]
30
- def people
31
- entries.map { |entry| entry.people.to_a }.flatten.tally
32
- end
26
+ # Returns a hash of people mentioned in the log for the current day
27
+ # with the number of times they are mentioned.
28
+ # People are defined as words starting with @ or ~.
29
+ #
30
+ # @return [Hash<String, Integer>]
31
+ def people
32
+ entries.map { |entry| entry.people.to_a }.flatten.tally
33
+ end
33
34
 
34
- # Returns a sorted list of tags used in the entries for the current day.
35
- #
36
- # @return [Array<String>]
37
- #
38
- # @example
39
- # log = DailyLog.new(date: Date.today,
40
- # entries: [LogEntry.new(message: "Work on something", tags: ['work', 'project'])])
41
- # log.tags # => ["project", "work"]
42
- def tags
43
- entries.flat_map(&:tags).uniq.sort
44
- end
35
+ # Returns a sorted list of tags used in the entries for the current day.
36
+ #
37
+ # @return [Array<String>]
38
+ #
39
+ # @example
40
+ # log = DailyLog.new(date: Date.today,
41
+ # entries: [LogEntry.new(message: "Work on something", tags: ['work', 'project'])])
42
+ # log.tags # => ["project", "work"]
43
+ def tags
44
+ entries.flat_map(&:tags).uniq.sort
45
+ end
46
+
47
+ # Create a DailyLog from a hash with symbolized keys
48
+ #
49
+ # @param hash [Hash] the hash to convert
50
+ # @return [DailyLog] the created DailyLog object
51
+ def self.from_hash(hash)
52
+ new(
53
+ date: hash[:date],
54
+ entries: hash[:entries].map { |entry| LogEntry.from_hash(entry) }
55
+ )
56
+ end
45
57
 
46
- # Equals method to compare two DailyLog objects.
47
- #
48
- # @param other [DailyLog] the other DailyLog object to compare with
49
- # @return [Boolean] true if both DailyLog objects have the same date and entries, false otherwise
50
- def ==(other)
51
- date == other.date && entries == other.entries
58
+ # Equals method to compare two DailyLog objects.
59
+ #
60
+ # @param other [DailyLog] the other DailyLog object to compare with
61
+ # @return [Boolean] true if both DailyLog objects have the same date and entries, false otherwise
62
+ def ==(other)
63
+ date == other.date && entries == other.entries
64
+ end
52
65
  end
53
66
  end
data/lib/log_entry.rb CHANGED
@@ -5,115 +5,133 @@ require 'rainbow'
5
5
  require 'daily_log'
6
6
  require 'hash'
7
7
 
8
- # A single log entry in a DailyLog.
9
- # @see DailyLog
10
- # @!attribute [rw] time
11
- # @return [DateTime] the date and time of the log entry.
12
- # @!attribute [rw] tags
13
- # @return [Array<String>] the tags associated with the log entry.
14
- # @!attribute [rw] ticket
15
- # @return [String] the ticket associated with the log entry.
16
- # @!attribute [rw] url
17
- # @return [String] the URL associated with the log entry.
18
- # @!attribute [rw] epic
19
- # @return [Boolean] whether the log entry is an epic.
20
- # @!attribute [rw] message
21
- # @return [String] the message of the log entry.
22
- # @!attribute [rw] project
23
- # @return [String] the project associated with the log entry.
24
- class LogEntry
25
- PERSON_REGEX = /(?:\s|^)[~@](\w+)/
26
-
27
- include Hashify
28
-
29
- attr_accessor :time, :tags, :ticket, :url, :epic, :message, :project
30
-
31
- attr_reader :day
32
-
33
- def initialize(params = {})
34
- @time = params[:time]
35
- # If tags are nil, set to empty array.
36
- # This is similar to the CLI default value.
37
- @tags = params[:tags] || []
38
- @ticket = params[:ticket]
39
- @url = params[:url] || ''
40
- @epic = params[:epic]
41
- @message = params[:message]
42
- @project = params[:project]
43
-
44
- # Back reference to the day
45
- @day = params[:day] || nil
46
- end
8
+ module Worklog
9
+ # A single log entry in a DailyLog.
10
+ # @see DailyLog
11
+ # @!attribute [rw] time
12
+ # @return [DateTime] the date and time of the log entry.
13
+ # @!attribute [rw] tags
14
+ # @return [Array<String>] the tags associated with the log entry.
15
+ # @!attribute [rw] ticket
16
+ # @return [String] the ticket associated with the log entry.
17
+ # @!attribute [rw] url
18
+ # @return [String] the URL associated with the log entry.
19
+ # @!attribute [rw] epic
20
+ # @return [Boolean] whether the log entry is an epic.
21
+ # @!attribute [rw] message
22
+ # @return [String] the message of the log entry.
23
+ # @!attribute [rw] project
24
+ # @return [String] the project associated with the log entry.
25
+ class LogEntry
26
+ PERSON_REGEX = /(?:\s|^)[~@](\w+)/
27
+
28
+ include Hashify
29
+
30
+ attr_accessor :time, :tags, :ticket, :url, :epic, :message, :project
31
+
32
+ attr_reader :day
33
+
34
+ def initialize(params = {})
35
+ @time = params[:time]
36
+ # If tags are nil, set to empty array.
37
+ # This is similar to the CLI default value.
38
+ @tags = params[:tags] || []
39
+ @ticket = params[:ticket]
40
+ @url = params[:url] || ''
41
+ @epic = params[:epic]
42
+ @message = params[:message]
43
+ @project = params[:project]
44
+
45
+ # Back reference to the day
46
+ @day = params[:day] || nil
47
+ end
47
48
 
48
- # Returns true if the entry is an epic, false otherwise.
49
- # @return [Boolean]
50
- def epic?
51
- @epic == true
52
- end
49
+ # Returns true if the entry is an epic, false otherwise.
50
+ # @return [Boolean]
51
+ def epic?
52
+ @epic == true
53
+ end
53
54
 
54
- # Returns the message string with formatting without the time.
55
- # @param known_people Hash[String, Person] A hash of people with their handles as keys.
56
- def message_string(known_people = nil)
57
- # replace all mentions of people with their names.
58
- msg = @message.dup
59
- people.each do |person|
60
- next unless known_people && known_people[person]
61
-
62
- msg.gsub!(/[~@]#{person}/) do |match|
63
- s = ''
64
- s += ' ' if match[0] == ' '
65
- s += "#{Rainbow(known_people[person].name).underline} (~#{person})" if known_people && known_people[person]
66
- s
55
+ # Returns the message string with formatting without the time.
56
+ # @param known_people Hash[String, Person] A hash of people with their handles as keys.
57
+ def message_string(known_people = nil)
58
+ # replace all mentions of people with their names.
59
+ msg = @message.dup
60
+ people.each do |person|
61
+ next unless known_people && known_people[person]
62
+
63
+ msg.gsub!(/[~@]#{person}/) do |match|
64
+ s = ''
65
+ s += ' ' if match[0] == ' '
66
+ s += "#{Rainbow(known_people[person].name).underline} (~#{person})" if known_people && known_people[person]
67
+ s
68
+ end
67
69
  end
68
- end
69
70
 
70
- s = ''
71
+ s = ''
71
72
 
72
- s += if epic
73
- Rainbow("[EPIC] #{msg}").bg(:white).fg(:black)
74
- else
75
- msg
76
- end
73
+ s += if epic
74
+ Rainbow("[EPIC] #{msg}").bg(:white).fg(:black)
75
+ else
76
+ msg
77
+ end
77
78
 
78
- s += " [#{Rainbow(@ticket).fg(:blue)}]" if @ticket
79
+ s += " [#{Rainbow(@ticket).fg(:blue)}]" if @ticket
79
80
 
80
- # Add tags in brackets if defined.
81
- s += ' [' + @tags.map { |tag| "#{tag}" }.join(', ') + ']' if @tags && @tags.size > 0
81
+ # Add tags in brackets if defined.
82
+ s += ' [' + @tags.map { |tag| "#{tag}" }.join(', ') + ']' if @tags && @tags.size > 0
82
83
 
83
- # Add URL in brackets if defined.
84
- s += " [#{@url}]" if @url && @url != ''
84
+ # Add URL in brackets if defined.
85
+ s += " [#{@url}]" if @url && @url != ''
85
86
 
86
- s += " [#{@project}]" if @project && @project != ''
87
+ s += " [#{@project}]" if @project && @project != ''
87
88
 
88
- s
89
- end
89
+ s
90
+ end
90
91
 
91
- def people
92
- # Return people that are mentioned in the entry. People are defined as character sequences
93
- # starting with @ or ~. Whitespaces are used to separate people. Punctuation is ignored.
94
- # Empty set if no people are mentioned.
95
- # @return [Set<String>]
96
- @message.scan(PERSON_REGEX).flatten.uniq.sort.to_set
97
- end
92
+ def people
93
+ # Return people that are mentioned in the entry. People are defined as character sequences
94
+ # starting with @ or ~. Whitespaces are used to separate people. Punctuation is ignored.
95
+ # Empty set if no people are mentioned.
96
+ # @return [Set<String>]
97
+ @message.scan(PERSON_REGEX).flatten.uniq.sort.to_set
98
+ end
98
99
 
99
- # Return true if there are people in the entry.
100
- #
101
- # @return [Boolean]
102
- def people?
103
- people.size.positive?
104
- end
100
+ # Return true if there are people in the entry.
101
+ #
102
+ # @return [Boolean]
103
+ def people?
104
+ people.size.positive?
105
+ end
105
106
 
106
- # Convert the log entry to YAML format.
107
- def to_yaml
108
- to_hash.to_yaml
109
- end
107
+ # Create a LogEntry from a hash with symbolized keys
108
+ #
109
+ # @param hash [Hash] the hash to convert
110
+ # @return [LogEntry] the created LogEntry object
111
+ def self.from_hash(hash)
112
+ new(
113
+ time: hash[:time],
114
+ tags: hash[:tags],
115
+ ticket: hash[:ticket],
116
+ url: hash[:url],
117
+ epic: hash[:epic],
118
+ message: hash[:message],
119
+ project: hash[:project]
120
+ )
121
+ end
122
+
123
+ # Convert the log entry to YAML format.
124
+ def to_yaml
125
+ to_hash.to_yaml
126
+ end
110
127
 
111
- # Compare two log entries for equality.
112
- #
113
- # @param other [LogEntry] The other log entry to compare against.
114
- # @return [Boolean] True if the log entries are equal, false otherwise.
115
- def ==(other)
116
- time == other.time && tags == other.tags && ticket == other.ticket && url == other.url &&
117
- epic == other.epic && message == other.message
128
+ # Compare two log entries for equality.
129
+ #
130
+ # @param other [LogEntry] The other log entry to compare against.
131
+ # @return [Boolean] True if the log entries are equal, false otherwise.
132
+ def ==(other)
133
+ time == other.time && tags == other.tags && ticket == other.ticket && url == other.url &&
134
+ epic == other.epic && message == other.message
135
+ end
118
136
  end
119
137
  end
data/lib/statistics.rb CHANGED
@@ -10,7 +10,7 @@ class Statistics
10
10
  # Initialize the Statistics class.
11
11
  def initialize(config)
12
12
  @config = config
13
- @storage = Storage.new(config)
13
+ @storage = Worklog::Storage.new(config)
14
14
  end
15
15
 
16
16
  # Calculate statistics for the work log for all days.
data/lib/storage.rb CHANGED
@@ -6,177 +6,189 @@ require 'log_entry'
6
6
  require 'worklogger'
7
7
  require 'person'
8
8
 
9
- # Handles storage of daily logs and people
10
- class Storage
11
- # LogNotFoundError is raised when a log file is not found
12
- class LogNotFoundError < StandardError; end
9
+ # Alias for classes to handle existing log entries
10
+ DailyLog = Worklog::DailyLog
11
+ LogEntry = Worklog::LogEntry
13
12
 
14
- FILE_SUFFIX = '.yaml'
13
+ module Worklog
14
+ # Handles storage of daily logs and people
15
+ class Storage
16
+ # LogNotFoundError is raised when a log file is not found
17
+ class LogNotFoundError < StandardError; end
15
18
 
16
- # Regular expression to match daily log file names
17
- LOG_PATTERN = /\d{4}-\d{2}-\d{2}#{FILE_SUFFIX}\z/
19
+ FILE_SUFFIX = '.yaml'
18
20
 
19
- def initialize(config)
20
- @config = config
21
- end
21
+ # Regular expression to match daily log file names
22
+ LOG_PATTERN = /\d{4}-\d{2}-\d{2}#{FILE_SUFFIX}\z/
22
23
 
23
- def folder_exists?
24
- Dir.exist?(@config.storage_path)
25
- end
24
+ def initialize(config)
25
+ @config = config
26
+ end
26
27
 
27
- # Return all logs for all available days
28
- # @return [Array<DailyLog>] List of all logs
29
- def all_days
30
- return [] unless folder_exists?
28
+ def folder_exists?
29
+ Dir.exist?(@config.storage_path)
30
+ end
31
31
 
32
- logs = []
33
- Dir.glob(File.join(@config.storage_path, "*#{FILE_SUFFIX}")).map do |file|
34
- next unless file.match?(LOG_PATTERN)
32
+ # Return all logs for all available days
33
+ # @return [Array<DailyLog>] List of all logs
34
+ def all_days
35
+ return [] unless folder_exists?
35
36
 
36
- logs << load_log(file)
37
- end
37
+ logs = []
38
+ Dir.glob(File.join(@config.storage_path, "*#{FILE_SUFFIX}")).map do |file|
39
+ next unless file.match?(LOG_PATTERN)
38
40
 
39
- logs
40
- end
41
+ logs << load_log(file)
42
+ end
43
+
44
+ logs
45
+ end
41
46
 
42
- # Return all tags as a set
43
- # @return [Set<String>] Set of all tags
44
- def tags
45
- logs = all_days
46
- tags = Set[]
47
- logs.each do |log|
48
- log.entries.each do |entry|
49
- next unless entry.tags
50
-
51
- entry.tags.each do |tag|
52
- tags << tag
47
+ # Return all tags as a set
48
+ # @return [Set<String>] Set of all tags
49
+ def tags
50
+ logs = all_days
51
+ tags = Set[]
52
+ logs.each do |log|
53
+ log.entries.each do |entry|
54
+ next unless entry.tags
55
+
56
+ entry.tags.each do |tag|
57
+ tags << tag
58
+ end
53
59
  end
54
60
  end
61
+ tags
55
62
  end
56
- tags
57
- end
58
63
 
59
- # Return days between start_date and end_date
60
- # If end_date is nil, return logs from start_date to today
61
- #
62
- # @param [Date] start_date The start date, inclusive
63
- # @param [Date] end_date The end date, inclusive
64
- # @param [Boolean] epics_only If true, only return logs with epic entries
65
- # @param [Array<String>] tags_filter If provided, only return logs with entries that have at least one of the tags
66
- # @return [Array<DailyLog>] List of logs
67
- def days_between(start_date, end_date = nil, epics_only = nil, tags_filter = nil)
68
- return [] unless folder_exists?
69
-
70
- logs = []
71
- end_date = Date.today if end_date.nil?
72
-
73
- return [] if start_date > end_date
74
-
75
- while start_date <= end_date
76
- if File.exist?(filepath(start_date))
77
- tmp_logs = load_log!(filepath(start_date))
78
- tmp_logs.entries.keep_if { |entry| entry.epic? } if epics_only
79
-
80
- if tags_filter
81
- # Safeguard against entries without any tags, not just empty array
82
- tmp_logs.entries.keep_if { |entry| entry.tags && (entry.tags & tags_filter).size > 0 }
64
+ # Return days between start_date and end_date
65
+ # If end_date is nil, return logs from start_date to today
66
+ #
67
+ # @param [Date] start_date The start date, inclusive
68
+ # @param [Date] end_date The end date, inclusive
69
+ # @param [Boolean] epics_only If true, only return logs with epic entries
70
+ # @param [Array<String>] tags_filter If provided, only return logs with entries that have at least one of the tags
71
+ # @return [Array<DailyLog>] List of logs
72
+ def days_between(start_date, end_date = nil, epics_only = nil, tags_filter = nil)
73
+ return [] unless folder_exists?
74
+
75
+ logs = []
76
+ end_date = Date.today if end_date.nil?
77
+
78
+ return [] if start_date > end_date
79
+
80
+ while start_date <= end_date
81
+ if File.exist?(filepath(start_date))
82
+ tmp_logs = load_log!(filepath(start_date))
83
+ tmp_logs.entries.keep_if { |entry| entry.epic? } if epics_only
84
+
85
+ if tags_filter
86
+ # Safeguard against entries without any tags, not just empty array
87
+ tmp_logs.entries.keep_if { |entry| entry.tags && (entry.tags & tags_filter).size > 0 }
88
+ end
89
+
90
+ logs << tmp_logs if tmp_logs.entries.length > 0
83
91
  end
84
92
 
85
- logs << tmp_logs if tmp_logs.entries.length > 0
93
+ start_date += 1
86
94
  end
95
+ logs
96
+ end
87
97
 
88
- start_date += 1
98
+ # Create file for a new day if it does not exist
99
+ # @param [Date] date The date, used as the file name.
100
+ def create_file_skeleton(date)
101
+ File.write(filepath(date), YAML.dump(DailyLog.new(date:, entries: []))) unless File.exist?(filepath(date))
89
102
  end
90
- logs
91
- end
92
103
 
93
- # Create file for a new day if it does not exist
94
- # @param [Date] date The date, used as the file name.
95
- def create_file_skeleton(date)
96
- File.write(filepath(date), YAML.dump(DailyLog.new(date:, entries: []))) unless File.exist?(filepath(date))
97
- end
104
+ def load_log(file)
105
+ load_log!(file)
106
+ rescue LogNotFoundError
107
+ WorkLogger.error "No work log found for #{file}. Aborting."
108
+ nil
109
+ end
98
110
 
99
- def load_log(file)
100
- load_log!(file)
101
- rescue LogNotFoundError
102
- WorkLogger.error "No work log found for #{file}. Aborting."
103
- nil
104
- end
111
+ def load_log!(file)
112
+ WorkLogger.debug "Loading file #{file}"
113
+
114
+ # Alias DailyLog to Worklog::DailyLog
105
115
 
106
- def load_log!(file)
107
- WorkLogger.debug "Loading file #{file}"
108
- begin
109
- log = YAML.load_file(file, permitted_classes: [Date, Time, DailyLog, LogEntry])
110
- log.entries.each do |entry|
111
- entry.time = Time.parse(entry.time) unless entry.time.respond_to?(:strftime)
116
+ begin
117
+ yaml_content = File.read(file)
118
+ cleaned_yaml = yaml_content.gsub(%r{!ruby/object:[^\s]+}, '')
119
+ log = DailyLog.from_hash(YAML.safe_load(cleaned_yaml, permitted_classes: [Date, Time], symbolize_names: true))
120
+
121
+ log.entries.each do |entry|
122
+ entry.time = Time.parse(entry.time) unless entry.time.respond_to?(:strftime)
123
+ end
124
+ log
125
+ rescue Errno::ENOENT
126
+ raise LogNotFoundError
112
127
  end
113
- log
114
- rescue Errno::ENOENT
115
- raise LogNotFoundError
116
128
  end
117
- end
118
129
 
119
- def write_log(file, daily_log)
120
- WorkLogger.debug "Writing to file #{file}"
130
+ def write_log(file, daily_log)
131
+ WorkLogger.debug "Writing to file #{file}"
121
132
 
122
- File.open(file, 'w') do |f|
123
- f.puts daily_log.to_yaml
133
+ File.open(file, 'w') do |f|
134
+ f.puts daily_log.to_yaml
135
+ end
124
136
  end
125
- end
126
137
 
127
- # Load a single log file and return its entries
128
- def load_single_log_file(file, headline = true)
129
- daily_log = load_log!(file)
130
- puts "Work log for #{Rainbow(daily_log.date).gold}:" if headline
131
- daily_log.entries
132
- end
138
+ # Load a single log file and return its entries
139
+ def load_single_log_file(file, headline = true)
140
+ daily_log = load_log!(file)
141
+ puts "Work log for #{Rainbow(daily_log.date).gold}:" if headline
142
+ daily_log.entries
143
+ end
133
144
 
134
- # Load all people from the people file, or return an empty array if the file does not exist
135
- #
136
- # @return [Array<Person>] List of people
137
- def load_people
138
- load_people!
139
- rescue Errno::ENOENT
140
- WorkLogger.info 'Unable to load people.'
141
- []
142
- end
145
+ # Load all people from the people file, or return an empty array if the file does not exist
146
+ #
147
+ # @return [Array<Person>] List of people
148
+ def load_people
149
+ load_people!
150
+ rescue Errno::ENOENT
151
+ WorkLogger.info 'Unable to load people.'
152
+ []
153
+ end
143
154
 
144
- # Load all people from the people file and return them as a hash with handle as key
145
- # @return [Hash<String, Person>] Hash of people with handle as key
146
- def load_people_hash
147
- load_people.to_h { |person| [person.handle, person] }
148
- end
155
+ # Load all people from the people file and return them as a hash with handle as key
156
+ # @return [Hash<String, Person>] Hash of people with handle as key
157
+ def load_people_hash
158
+ load_people.to_h { |person| [person.handle, person] }
159
+ end
149
160
 
150
- # Load all people from the people file
151
- # @return [Array<Person>] List of people
152
- def load_people!
153
- people_file = File.join(@config.storage_path, 'people.yaml')
154
- return [] unless File.exist?(people_file)
161
+ # Load all people from the people file
162
+ # @return [Array<Person>] List of people
163
+ def load_people!
164
+ people_file = File.join(@config.storage_path, 'people.yaml')
165
+ return [] unless File.exist?(people_file)
155
166
 
156
- YAML.load_file(people_file, permitted_classes: [Person])
157
- end
167
+ YAML.load_file(people_file, permitted_classes: [Person])
168
+ end
158
169
 
159
- # Write people to the people file
160
- # @param [Array<Person>] people List of people
161
- def write_people!(people)
162
- people_file = File.join(@config.storage_path, 'people.yaml')
163
- File.open(people_file, 'w') do |f|
164
- f.puts people.to_yaml
170
+ # Write people to the people file
171
+ # @param [Array<Person>] people List of people
172
+ def write_people!(people)
173
+ people_file = File.join(@config.storage_path, 'people.yaml')
174
+ File.open(people_file, 'w') do |f|
175
+ f.puts people.to_yaml
176
+ end
165
177
  end
166
- end
167
178
 
168
- # Create folder if not exists already.
169
- def create_default_folder
170
- # Do nothing if the storage path is not the default path
171
- return unless @config.default_storage_path?
179
+ # Create folder if not exists already.
180
+ def create_default_folder
181
+ # Do nothing if the storage path is not the default path
182
+ return unless @config.default_storage_path?
172
183
 
173
- Dir.mkdir(@config.storage_path) unless Dir.exist?(@config.storage_path)
174
- end
184
+ Dir.mkdir(@config.storage_path) unless Dir.exist?(@config.storage_path)
185
+ end
175
186
 
176
- # Construct filepath for a given date.
177
- # @param [Date] date The date
178
- # @return [String] The filepath
179
- def filepath(date)
180
- File.join(@config.storage_path, "#{date}#{FILE_SUFFIX}")
187
+ # Construct filepath for a given date.
188
+ # @param [Date] date The date
189
+ # @return [String] The filepath
190
+ def filepath(date)
191
+ File.join(@config.storage_path, "#{date}#{FILE_SUFFIX}")
192
+ end
181
193
  end
182
194
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fewald-worklog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.20
4
+ version: 0.2.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Friedrich Ewald