Class: Worklog
Overview
Main class providing all worklog functionality. This class is the main entry point for the application. It handles command line arguments, configuration, and logging.
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
Instance Method Summary collapse
- #add(message, options = {}) ⇒ Object
- #edit(options = {}) ⇒ Object
-
#initialize(config = nil) ⇒ Worklog
constructor
A new instance of Worklog.
- #people(_options = {}) ⇒ Object
- #remove(options = {}) ⇒ Object
- #show(options = {}) ⇒ Object
-
#start_end_date(options) ⇒ Array
Parse the start and end date based on the options provided.
- #stats(_options = {}) ⇒ Object
- #summary(options = {}) ⇒ Object
- #tags(_options = {}) ⇒ Object
Methods included from StringHelper
Constructor Details
#initialize(config = nil) ⇒ Worklog
Returns a new instance of Worklog.
25 26 27 28 29 30 |
# File 'worklog/worklog.rb', line 25 def initialize(config = nil) @config = config || Configuration.new @storage = Storage.new(@config) WorkLogger.level = @config.log_level == :debug ? Logger::Severity::DEBUG : Logger::Severity::INFO end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
23 24 25 |
# File 'worklog/worklog.rb', line 23 def config @config end |
Instance Method Details
#add(message, options = {}) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'worklog/worklog.rb', line 32 def add(, = {}) # Remove leading and trailing whitespaces # Raise an error if the message is empty = .strip raise ArgumentError, 'Message cannot be empty' if .empty? date = Date.strptime([:date], '%Y-%m-%d') time = Time.strptime([:time], '%H:%M:%S') @storage.create_file_skeleton(date) daily_log = @storage.load_log!(@storage.filepath(date)) daily_log.entries << LogEntry.new(time:, tags: [:tags], ticket: [:ticket], url: [:url], epic: [:epic], message:) # Sort by time in case an entry was added later out of order. daily_log.entries.sort_by!(&:time) @storage.write_log(@storage.filepath([:date]), daily_log) WorkLogger.info Rainbow("Added entry on #{[:date]}: #{}").green end |
#edit(options = {}) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'worklog/worklog.rb', line 54 def edit( = {}) date = Date.strptime([:date], '%Y-%m-%d') # Load existing log log = @storage.load_log(@storage.filepath(date)) unless log WorkLogger.error "No work log found for #{[:date]}. Aborting." exit 1 end txt = Editor::EDITOR_PREAMBLE.result_with_hash(content: YAML.dump(log)) return_val = Editor.open_editor(txt) @storage.write_log(@storage.filepath(date), YAML.load(return_val, permitted_classes: [Date, Time, DailyLog, LogEntry])) WorkLogger.info Rainbow("Updated work log for #{[:date]}").green end |
#people(_options = {}) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'worklog/worklog.rb', line 88 def people( = {}) puts 'People mentioned in the work log:' mentions = {} all_logs = @storage.all_days all_people = @storage.load_people people_map = all_people.to_h { |person| [person.handle, person] } all_logs.map(&:people).each do |people| mentions.merge!(people) { |_key, oldval, newval| oldval + newval } end mentions.each do |handle, v| if people_map.key?(handle) print "#{Rainbow(people_map[handle].name).gold} (#{handle})" else print handle end puts ": #{v} #{pluralize(v, 'occurrence')}" end end |
#remove(options = {}) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'worklog/worklog.rb', line 147 def remove( = {}) date = Date.strptime([:date], '%Y-%m-%d') unless File.exist?(@storage.filepath(date)) WorkLogger.error Rainbow("No work log found for #{[:date]}. Aborting.").red exit 1 end daily_log = @storage.load_log!(@storage.filepath([:date])) if daily_log.entries.empty? WorkLogger.error Rainbow("No entries found for #{[:date]}. Aborting.").red exit 1 end removed_entry = daily_log.entries.pop @storage.write_log(@storage.filepath(date), daily_log) WorkLogger.info Rainbow("Removed entry: #{removed_entry.}").green end |
#show(options = {}) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'worklog/worklog.rb', line 72 def show( = {}) people = @storage.load_people! printer = Printer.new(people) start_date, end_date = start_end_date() entries = @storage.days_between(start_date, end_date) if entries.empty? printer.no_entries(start_date, end_date) else entries.each do |entry| printer.print_day(entry, entries.size > 1, [:epics_only]) end end end |
#start_end_date(options) ⇒ Array
Parse the start and end date based on the options provided
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'worklog/worklog.rb', line 169 def start_end_date() if [:days] # Safeguard against negative days raise ArgumentError, 'Number of days cannot be negative' if [:days].negative? start_date = Date.today - [:days] end_date = Date.today elsif [:from] start_date = DateParser.parse_date_string!([:from], true) end_date = DateParser.parse_date_string!([:to], false) if [:to] else start_date = Date.strptime([:date], '%Y-%m-%d') end_date = start_date end [start_date, end_date] end |
#stats(_options = {}) ⇒ Object
125 126 127 128 129 130 131 132 133 |
# File 'worklog/worklog.rb', line 125 def stats( = {}) stats = Statistics.new(@config).calculate puts "#{format_left('Total days')}: #{stats.total_days}" puts "#{format_left('Total entries')}: #{stats.total_entries}" puts "#{format_left('Total epics')}: #{stats.total_epics}" puts "#{format_left('Entries per day')}: #{format('%.2f', stats.avg_entries)}" puts "#{format_left('First entry')}: #{stats.first_entry}" puts "#{format_left('Last entry')}: #{stats.last_entry}" end |
#summary(options = {}) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 |
# File 'worklog/worklog.rb', line 135 def summary( = {}) start_date, end_date = start_end_date() entries = @storage.days_between(start_date, end_date).map(&:entries).flatten # Do nothing if no entries are found. if entries.empty? Printer.new.no_entries(start_date, end_date) return end puts Summary.generate_summary(entries) end |
#tags(_options = {}) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'worklog/worklog.rb', line 110 def ( = {}) all_logs = @storage.all_days puts Rainbow('Tags used in the work log:').gold # Count all tags used in the work log = all_logs.map(&:entries).flatten.map(&:tags).flatten.compact.tally # Determine length of longest tag for formatting # Add one additonal space for formatting max_len = .empty? ? 0 : .keys.map(&:length).max + 1 .sort.each { |k, v| puts "#{Rainbow(k.ljust(max_len)).gold}: #{v} #{pluralize(v, 'occurrence')}" } end |