Class: Worklog::Storage
- Inherits:
-
Object
- Object
- Worklog::Storage
- Defined in:
- lib/storage.rb
Overview
Handles storage of daily logs and people
Defined Under Namespace
Classes: LogNotFoundError
Constant Summary collapse
- FILE_SUFFIX =
'.yaml'- LOG_PATTERN =
Regular expression to match daily log file names
/\d{4}-\d{2}-\d{2}#{FILE_SUFFIX}\z/- PERSON_TEMPLATE =
The template for the people YAML file. This template is used to create a new people file if it does not exist.
<<~YAML --- # Each person is defined by the following attributes: # - handle: <unique_handle> # github_username: <github_username> # name: <full_name> # team: <team_name> # email: <email_address> # role: <role_in_team> # inactive: <true_or_false> # --- Define your people below this line --- YAML
Instance Method Summary collapse
-
#all_days ⇒ Array<DailyLog>
Return all logs for all available days.
-
#create_default_files ⇒ Object
This method assumes that the storage folder already exists.
-
#create_default_folder ⇒ void
Create folder if not exists already.
-
#create_file_skeleton(date) ⇒ Object
Create file for a new day if it does not exist.
-
#days_between(start_date, end_date = nil, epics_only = nil, tags_filter = nil) ⇒ Array<DailyLog>
Return days between start_date and end_date If end_date is nil, return logs from start_date to today.
-
#filepath(date) ⇒ String
Construct filepath for a given date.
- #folder_exists? ⇒ Boolean
-
#initialize(config) ⇒ Storage
constructor
A new instance of Storage.
- #load_log(file) ⇒ Object
- #load_log!(file) ⇒ Object
-
#load_people ⇒ Array<Person>
Load all people from the people file, or return an empty array if the file does not exist.
-
#load_people! ⇒ Array<Person>
Load all people from the people file.
-
#load_people_hash ⇒ Hash<String, Person>
Load all people from the people file and return them as a hash with handle as key.
-
#load_single_log_file(file, headline = true) ⇒ Object
Load a single log file and return its entries.
-
#people_filepath ⇒ String
Return the full absolute filepath for the people.yaml file.
-
#tags ⇒ Set<String>
Return all tags as a set.
- #write_log(file, daily_log) ⇒ Object
-
#write_people!(people) ⇒ Object
Write people to the people file.
Constructor Details
#initialize(config) ⇒ Storage
Returns a new instance of Storage.
35 36 37 |
# File 'lib/storage.rb', line 35 def initialize(config) @config = config end |
Instance Method Details
#all_days ⇒ Array<DailyLog>
Return all logs for all available days
45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/storage.rb', line 45 def all_days return [] unless folder_exists? logs = [] Dir.glob(File.join(@config.storage_path, "*#{FILE_SUFFIX}")).map do |file| next unless file.match?(LOG_PATTERN) logs << load_log(file) end logs end |
#create_default_files ⇒ Object
This method assumes that the storage folder already exists. It creates default files like people.yaml if they do not exist.
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/storage.rb', line 210 def create_default_files WorkLogger.info 'Creating default files in storage folder if they do not exist.' # projects_file = File.join(@config.storage_path, 'projects.yaml') # unless File.exist?(projects_file) # File.write(projects_file, [].to_yaml) # end if File.exist?(people_filepath) WorkLogger.info 'people.yaml already exists, skipping creation.' else WorkLogger.info 'Creating default people.yaml file.' File.write(people_filepath, PERSON_TEMPLATE) end # Write the default config file if it does not exist if File.exist?(Configuration.config_file_path) WorkLogger.info "Configuration file (#{Configuration.config_file_path}) already exists, skipping creation." else WorkLogger.info "Creating default configuration file at #{Configuration.config_file_path}." File.write(Configuration.config_file_path, Configuration::CONFIGURATION_TEMPLATE.result) end end |
#create_default_folder ⇒ void
This method returns an undefined value.
Create folder if not exists already.
196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/storage.rb', line 196 def create_default_folder WorkLogger.debug 'Creating storage folder if it does not exist.' # Do nothing if the storage path is not the default path unless @config.default_storage_path? WorkLogger.debug 'Custom storage path detected, skipping creation of default storage folder.' return end Dir.mkdir(@config.storage_path) unless Dir.exist?(@config.storage_path) end |
#create_file_skeleton(date) ⇒ Object
Create file for a new day if it does not exist
111 112 113 |
# File 'lib/storage.rb', line 111 def create_file_skeleton(date) File.write(filepath(date), YAML.dump(DailyLog.new(date:, entries: []))) unless File.exist?(filepath(date)) end |
#days_between(start_date, end_date = nil, epics_only = nil, tags_filter = nil) ⇒ Array<DailyLog>
Return days between start_date and end_date If end_date is nil, return logs from start_date to today
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/storage.rb', line 83 def days_between(start_date, end_date = nil, epics_only = nil, = nil) return [] unless folder_exists? logs = [] end_date = Date.today if end_date.nil? return [] if start_date > end_date while start_date <= end_date if File.exist?(filepath(start_date)) tmp_logs = load_log!(filepath(start_date)) tmp_logs.entries.keep_if { |entry| entry.epic? } if epics_only if # Safeguard against entries without any tags, not just empty array tmp_logs.entries.keep_if { |entry| entry.&.intersect?() } end logs << tmp_logs if tmp_logs.entries.length > 0 end start_date += 1 end logs end |
#filepath(date) ⇒ String
Construct filepath for a given date.
237 238 239 |
# File 'lib/storage.rb', line 237 def filepath(date) File.join(@config.storage_path, "#{date}#{FILE_SUFFIX}") end |
#folder_exists? ⇒ Boolean
39 40 41 |
# File 'lib/storage.rb', line 39 def folder_exists? Dir.exist?(@config.storage_path) end |
#load_log(file) ⇒ Object
115 116 117 118 119 120 |
# File 'lib/storage.rb', line 115 def load_log(file) load_log!(file) rescue LogNotFoundError WorkLogger.error "No work log found for #{file}. Aborting." nil end |
#load_log!(file) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/storage.rb', line 122 def load_log!(file) WorkLogger.debug "Loading file #{file}" begin yaml_content = File.read(file) cleaned_yaml = yaml_content.gsub(%r{!ruby/object:[^\s]+}, '') log = DailyLog.from_hash(YAML.safe_load(cleaned_yaml, permitted_classes: [Date, Time], symbolize_names: true)) log.entries.each do |entry| entry.time = Time.parse(entry.time) unless entry.time.respond_to?(:strftime) end log rescue Errno::ENOENT raise LogNotFoundError end end |
#load_people ⇒ Array<Person>
Load all people from the people file, or return an empty array if the file does not exist
159 160 161 162 163 164 |
# File 'lib/storage.rb', line 159 def load_people load_people! rescue Errno::ENOENT WorkLogger.info 'Unable to load people.' [] end |
#load_people! ⇒ Array<Person>
Load all people from the people file
174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/storage.rb', line 174 def load_people! return [] unless File.exist?(people_filepath) yamltext = File.read(people_filepath) if yamltext != yamltext.gsub(/^- !.*$/, '-') WorkLogger.debug 'The people.yaml file contains deprecated syntax. Migrating now.' yamltext.gsub!(/^- !.*$/, '-') File.write(people_filepath, yamltext) end YAML.load(yamltext, permitted_classes: []).map { |person_hash| Person.from_hash(person_hash) } end |
#load_people_hash ⇒ Hash<String, Person>
Load all people from the people file and return them as a hash with handle as key
168 169 170 |
# File 'lib/storage.rb', line 168 def load_people_hash load_people.to_h { |person| [person.handle, person] } end |
#load_single_log_file(file, headline = true) ⇒ Object
Load a single log file and return its entries
150 151 152 153 154 |
# File 'lib/storage.rb', line 150 def load_single_log_file(file, headline = true) daily_log = load_log!(file) puts "Work log for #{Rainbow(daily_log.date).gold}:" if headline daily_log.entries end |
#people_filepath ⇒ String
Return the full absolute filepath for the people.yaml file
243 244 245 |
# File 'lib/storage.rb', line 243 def people_filepath File.join(@config.storage_path, 'people.yaml') end |
#tags ⇒ Set<String>
Return all tags as a set
60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/storage.rb', line 60 def logs = all_days = Set[] logs.each do |log| log.entries.each do |entry| next unless entry. entry..each do |tag| << tag end end end end |
#write_log(file, daily_log) ⇒ Object
138 139 140 141 142 143 144 145 146 147 |
# File 'lib/storage.rb', line 138 def write_log(file, daily_log) WorkLogger.debug "Writing to file #{file}" File.open(file, 'w') do |f| # Sort entries by time before saving daily_log.entries.sort_by!(&:time) f.puts daily_log.to_yaml end end |
#write_people!(people) ⇒ Object
Write people to the people file
188 189 190 191 192 |
# File 'lib/storage.rb', line 188 def write_people!(people) File.open(people_filepath, 'w') do |f| f.puts people.to_yaml end end |