Class: Storage

Inherits:
Object
  • Object
show all
Defined in:
lib/storage.rb

Overview

Handles storage of daily logs and people

Defined Under Namespace

Classes: LogNotFoundError

Constant Summary collapse

FILE_SUFFIX =
'.yaml'

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Storage

Returns a new instance of Storage.



16
17
18
# File 'lib/storage.rb', line 16

def initialize(config)
  @config = config
end

Instance Method Details

#all_daysArray<DailyLog>

Return all logs for all available days

Returns:

  • (Array<DailyLog>)

    List of all logs



26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/storage.rb', line 26

def all_days
  return [] unless folder_exists?

  logs = []
  Dir.glob(File.join(@config.storage_path, "*#{FILE_SUFFIX}")).map do |file|
    next if file.end_with?('people.yaml')

    logs << load_log(file)
  end

  logs
end

#create_file_skeleton(date) ⇒ Object

Create file for a new day if it does not exist

Parameters:

  • date (Date)

    The date, used as the file name.



92
93
94
95
96
# File 'lib/storage.rb', line 92

def create_file_skeleton(date)
  create_folder

  File.write(filepath(date), YAML.dump(DailyLog.new(date:, entries: []))) unless File.exist?(filepath(date))
end

#create_folderObject

Create folder if not exists already.



162
163
164
# File 'lib/storage.rb', line 162

def create_folder
  Dir.mkdir(@config.storage_path) unless Dir.exist?(@config.storage_path)
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

Parameters:

  • start_date (Date)

    The start date, inclusive

  • end_date (Date) (defaults to: nil)

    The end date, inclusive

  • epics_only (Boolean) (defaults to: nil)

    If true, only return logs with epic entries

  • tags_filter (Array<String>) (defaults to: nil)

    If provided, only return logs with entries that have at least one of the tags

Returns:



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/storage.rb', line 64

def days_between(start_date, end_date = nil, epics_only = nil, tags_filter = 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 tags_filter
        # Safeguard against entries without any tags, not just empty array
        tmp_logs.entries.keep_if { |entry| entry.tags && (entry.tags & tags_filter).size > 0 }
      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.

Parameters:

  • date (Date)

    The date

Returns:

  • (String)

    The filepath



169
170
171
# File 'lib/storage.rb', line 169

def filepath(date)
  File.join(@config.storage_path, "#{date}#{FILE_SUFFIX}")
end

#folder_exists?Boolean

Returns:

  • (Boolean)


20
21
22
# File 'lib/storage.rb', line 20

def folder_exists?
  Dir.exist?(@config.storage_path)
end

#load_log(file) ⇒ Object



98
99
100
101
102
103
# File 'lib/storage.rb', line 98

def load_log(file)
  load_log!(file)
rescue LogNotFoundError
  WorkLogger.error "No work log found for #{file}. Aborting."
  nil
end

#load_log!(file) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/storage.rb', line 105

def load_log!(file)
  WorkLogger.debug "Loading file #{file}"
  begin
    log = YAML.load_file(file, permitted_classes: [Date, Time, DailyLog, LogEntry])
    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_peopleObject



134
135
136
137
138
139
# File 'lib/storage.rb', line 134

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

Returns:

  • (Array<Person>)

    List of people



143
144
145
146
147
148
# File 'lib/storage.rb', line 143

def load_people!
  people_file = File.join(@config.storage_path, 'people.yaml')
  return [] unless File.exist?(people_file)

  YAML.load_file(people_file, permitted_classes: [Person])
end

#load_single_log_file(file, headline = true) ⇒ Object



128
129
130
131
132
# File 'lib/storage.rb', line 128

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

#tagsSet<String>

Return all tags as a set

Returns:

  • (Set<String>)

    Set of all tags



41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/storage.rb', line 41

def tags
  logs = all_days
  tags = Set[]
  logs.each do |log|
    log.entries.each do |entry|
      next unless entry.tags

      entry.tags.each do |tag|
        tags << tag
      end
    end
  end
  tags
end

#write_log(file, daily_log) ⇒ Object



118
119
120
121
122
123
124
125
126
# File 'lib/storage.rb', line 118

def write_log(file, daily_log)
  create_folder

  WorkLogger.debug "Writing to file #{file}"

  File.open(file, 'w') do |f|
    f.puts daily_log.to_yaml
  end
end

#write_people!(people) ⇒ Object

Write people to the people file

Parameters:

  • people (Array<Person>)

    List of people



152
153
154
155
156
157
158
159
# File 'lib/storage.rb', line 152

def write_people!(people)
  create_folder

  people_file = File.join(@config.storage_path, 'people.yaml')
  File.open(people_file, 'w') do |f|
    f.puts people.to_yaml
  end
end