hbtrack 0.0.5 → 0.0.6
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/.gitignore +1 -1
- data/.rspec +1 -0
- data/.travis.yml +6 -0
- data/README.md +28 -40
- data/hbtrack.gemspec +30 -0
- data/lib/hbtrack/command/add_command.rb +48 -0
- data/lib/hbtrack/command/list_command.rb +71 -0
- data/lib/hbtrack/command/remove_command.rb +37 -0
- data/lib/hbtrack/command/update_command.rb +94 -0
- data/lib/hbtrack/command.rb +26 -0
- data/lib/hbtrack/error_handler.rb +28 -0
- data/lib/hbtrack/habit.rb +40 -19
- data/lib/hbtrack/habit_printer.rb +23 -15
- data/lib/hbtrack/habit_tracker.rb +27 -155
- data/lib/hbtrack/report/calendar.rb +84 -0
- data/lib/hbtrack/report/generator.rb +31 -0
- data/lib/hbtrack/report/report.html.erb +89 -0
- data/lib/hbtrack/stat_formatter.rb +9 -20
- data/lib/hbtrack/store.rb +18 -0
- data/lib/hbtrack/util.rb +29 -19
- data/lib/hbtrack/version.rb +1 -1
- data/lib/hbtrack.rb +42 -10
- metadata +30 -5
- data/.rubocop.yml +0 -2
- data/lib/hbtrack/cli.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36d2ea881a273459943278a8ed55e05162544426
|
4
|
+
data.tar.gz: 05f7cb9199065ab8eca1f558a4d7bda5dc971341
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17b23168d92bb400ff17d5b6685268fb5aafbf3ed2f27e9a8685dea89e56316e3af7a4af0ab23f93ce1b525aab0d9746b84ac76714df560eb33ea03cf22cb5ba
|
7
|
+
data.tar.gz: 73b292c9e40a08ed498879ebba2c1c88f82f17a5d902c84aa4074f404341b01e457bbdcfe96729bf32c8f2de87dedb80bc78e92ee3792a4c5a18d736633d68e4
|
data/.gitignore
CHANGED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# Hbtrack [](https://badge.fury.io/rb/hbtrack) [](https://travis-ci.org/kw7oe/hbtrack)
|
2
2
|
|
3
3
|
`hbtrack` is a simple command lines tool to keep track of your daily habits. The functionality of the current version is very limited.
|
4
4
|
|
@@ -10,42 +10,36 @@ gem install hbtrack
|
|
10
10
|
|
11
11
|
## Usage
|
12
12
|
|
13
|
-
#### Add a new habit
|
14
13
|
```
|
15
|
-
|
16
|
-
```
|
17
|
-
Duplicate habit name will be ignore.
|
14
|
+
Usage: hbtrack <command> [<habit_name>] [options]
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
Commands:
|
17
|
+
add: Add habit(s)
|
18
|
+
remove: Remove habit(s)
|
19
|
+
list: List habit(s)
|
20
|
+
done: Mark habit(s) as done
|
21
|
+
undone: Mark habit(s) as undone
|
24
22
|
|
23
|
+
Options:
|
24
|
+
-h, --help Show help messages of the command
|
25
25
|
```
|
26
|
-
$ hbtrack undone habit_name
|
27
|
-
```
|
28
|
-
This will mark the current habit as undone for the current day.
|
29
26
|
|
30
|
-
|
31
|
-
```
|
32
|
-
$ hbtrack done/undone -y habit_name
|
33
|
-
```
|
27
|
+
**Note:** For more details about available options for each command, type `hbtrack <command> -h`
|
34
28
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
29
|
+
## Features
|
30
|
+
- [x] List all habits
|
31
|
+
- with completion rate or total/done/undone count
|
32
|
+
- [x] Add single or multiple habits at once
|
33
|
+
- [x] Mark:
|
34
|
+
- single or mutiple habits as done/undone
|
35
|
+
- remaining habits of as done/undone
|
36
|
+
- habit(s) as done for specific day with `--day DAY`
|
37
|
+
- [x] Remove single or multiple habits at once
|
38
|
+
- [x] Generate report in HTML format. *(In Progress)*
|
39
39
|
|
40
|
-
|
40
|
+
## Output
|
41
41
|
|
42
|
-
|
43
|
-
```
|
44
|
-
$ hbtrack list
|
45
|
-
```
|
46
|
-
This will list all the habits you added and its progress for the current month.
|
47
|
-
|
48
|
-
**Output:**
|
42
|
+
### List all habits:
|
49
43
|
```
|
50
44
|
August 2017
|
51
45
|
-----------
|
@@ -62,12 +56,7 @@ All: 15, Done: 13, Undone: 2
|
|
62
56
|
|
63
57
|
**Note:** The actual output is colorized where green color font indicate done and red color font indicate undone.
|
64
58
|
|
65
|
-
|
66
|
-
```
|
67
|
-
$ hbtrack list habit_name
|
68
|
-
```
|
69
|
-
|
70
|
-
**Output:**
|
59
|
+
### List a habit:
|
71
60
|
```
|
72
61
|
workout
|
73
62
|
-------
|
@@ -75,13 +64,11 @@ workout
|
|
75
64
|
August 2017 : *** All: 3, Done: 3, Undone: 0
|
76
65
|
```
|
77
66
|
|
67
|
+
### List all habits with `-p`:
|
78
68
|
|
79
69
|
Extra options such as `-p` or `--percentage` can be provided to list the stats of your habits in terms of completion rate.
|
80
|
-
```
|
81
|
-
$ hbtrack list -p habit_name
|
82
|
-
```
|
83
70
|
|
84
|
-
|
71
|
+
|
85
72
|
```
|
86
73
|
August 2017
|
87
74
|
-----------
|
@@ -118,6 +105,7 @@ The first line represent the name of the habit. The second rows onward represent
|
|
118
105
|
* `2017,6` represent your progress during June 2017.
|
119
106
|
* `1` is used to represent done.
|
120
107
|
* `0` is used to represent undone.
|
108
|
+
* Black space is used to represent not recorded/dayoff.
|
121
109
|
* Each habit is seperated by a newline. For example:
|
122
110
|
|
123
111
|
```
|
@@ -129,7 +117,7 @@ read
|
|
129
117
|
```
|
130
118
|
|
131
119
|
## Bugs/Features
|
132
|
-
The project is still
|
120
|
+
The project is still under development.
|
133
121
|
|
134
122
|
If there are any bugs/features request, feel free to create a new issues.
|
135
123
|
|
data/hbtrack.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
lib = File.expand_path('../lib', __FILE__)
|
5
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
|
+
require 'hbtrack/version'
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = 'hbtrack'
|
10
|
+
spec.version = Hbtrack::VERSION
|
11
|
+
spec.authors = ['kw7oe']
|
12
|
+
spec.email = ['choongkwern@hotmail.com']
|
13
|
+
|
14
|
+
spec.summary = 'A CLI to track your habits.'
|
15
|
+
spec.description = 'Habit Tracker CLI'
|
16
|
+
spec.homepage = 'https://github.com/kw7oe/hbtrack'
|
17
|
+
spec.license = 'MIT'
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
20
|
+
f.match(%r{^(test|spec|features)/})
|
21
|
+
end
|
22
|
+
spec.bindir = 'exe'
|
23
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = ['lib']
|
25
|
+
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
27
|
+
spec.add_development_dependency 'minitest', '~> 5.10'
|
28
|
+
spec.add_development_dependency 'rspec', '~> 3.6'
|
29
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
30
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'hbtrack/command'
|
5
|
+
require 'hbtrack/store'
|
6
|
+
|
7
|
+
module Hbtrack
|
8
|
+
class AddCommand < Command
|
9
|
+
def initialize(hbt, options)
|
10
|
+
super(hbt, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute
|
14
|
+
return add(@names) unless @names.empty?
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_option_parser
|
19
|
+
OptionParser.new do |opts|
|
20
|
+
opts.banner = 'Usage: hbtrack add [<habit_name>]'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def add(names)
|
25
|
+
added = []
|
26
|
+
names.each do |name|
|
27
|
+
@hbt.find(name) do
|
28
|
+
@hbt.create(name)
|
29
|
+
added << name
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
Store.new(@hbt.habits, @hbt.output_file_name).save
|
34
|
+
|
35
|
+
output = [
|
36
|
+
Hbtrack::Util.green("Add #{added.join(',')}!")
|
37
|
+
]
|
38
|
+
|
39
|
+
names -= added
|
40
|
+
unless names.empty?
|
41
|
+
output << "\n"
|
42
|
+
output << Hbtrack::Util.blue("#{names.join(',')} already existed!")
|
43
|
+
end
|
44
|
+
|
45
|
+
output.join
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'hbtrack/command'
|
5
|
+
|
6
|
+
module Hbtrack
|
7
|
+
class ListCommand < Command
|
8
|
+
attr_reader :printer, :formatter
|
9
|
+
|
10
|
+
def initialize(hbt, options)
|
11
|
+
@percentage = false
|
12
|
+
|
13
|
+
super(hbt, options)
|
14
|
+
@formatter = @percentage ? CompletionRateSF.new : CompleteSF.new
|
15
|
+
@printer = HabitPrinter.new(@formatter)
|
16
|
+
end
|
17
|
+
|
18
|
+
def execute
|
19
|
+
return list_all(@printer) if @all
|
20
|
+
return list(@names[0], @printer) unless @names.empty?
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_option_parser
|
25
|
+
OptionParser.new do |opts|
|
26
|
+
opts.banner = 'Usage: hbtrack list [<habit_name>] [options]'
|
27
|
+
opts.separator ''
|
28
|
+
opts.separator 'Options:'
|
29
|
+
|
30
|
+
opts.on('-p', '--percentage', 'List habit(s) with completion rate') do
|
31
|
+
@percentage = true
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on('-a', '--all', 'List all habits') do
|
35
|
+
@all = true
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on_tail('-h', '--help', 'Prints this help') do
|
39
|
+
puts opts
|
40
|
+
exit
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def list(name, printer)
|
46
|
+
habit = @hbt.find(name) do
|
47
|
+
return ErrorHandler.raise_habit_not_found(name)
|
48
|
+
end
|
49
|
+
|
50
|
+
title = Util.title habit.name
|
51
|
+
progress = printer.print_all_progress(habit)
|
52
|
+
footer = "\n" + habit.overall_stat_description(printer.formatter)
|
53
|
+
|
54
|
+
"#{title}#{progress}\n#{footer}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def list_all(printer)
|
58
|
+
return Util.blue 'No habits added yet.' if @hbt.habits.empty?
|
59
|
+
|
60
|
+
title = Util.title Util.current_month
|
61
|
+
progress = @hbt.habits.each_with_index.map do |h, index|
|
62
|
+
space = @hbt.longest_name.length - h.name_length
|
63
|
+
"#{index + 1}. " \
|
64
|
+
"#{printer.print_latest_progress(h, space)}"
|
65
|
+
end.join("\n")
|
66
|
+
footer = "\n" + @hbt.overall_stat_description(@formatter)
|
67
|
+
|
68
|
+
"#{title}#{progress}\n#{footer}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'hbtrack/command'
|
5
|
+
require 'hbtrack/store'
|
6
|
+
|
7
|
+
module Hbtrack
|
8
|
+
class RemoveCommand < Command
|
9
|
+
def initialize(hbt, options)
|
10
|
+
super(hbt, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute
|
14
|
+
return remove(@names) if @names
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_option_parser
|
19
|
+
OptionParser.new do |opts|
|
20
|
+
opts.banner = 'Usage: hbtrack remove [<habit_name>]'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def remove(names)
|
25
|
+
names.each do |name|
|
26
|
+
habit = @hbt.find(name) do
|
27
|
+
return ErrorHandler.raise_if_habit_error(name)
|
28
|
+
end
|
29
|
+
|
30
|
+
@hbt.habits.delete(habit)
|
31
|
+
end
|
32
|
+
|
33
|
+
Store.new(@hbt.habits, @hbt.output_file_name).save
|
34
|
+
Hbtrack::Util.blue("Remove #{names.join(',')}!")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'hbtrack/command'
|
5
|
+
require 'hbtrack/store'
|
6
|
+
|
7
|
+
module Hbtrack
|
8
|
+
class UpdateCommand < Command
|
9
|
+
def initialize(hbt, options, is_done)
|
10
|
+
@day = Date.today
|
11
|
+
@is_done = is_done
|
12
|
+
@remaining = false
|
13
|
+
super(hbt, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute
|
17
|
+
return update_remaining(@day, @is_done) if @remaining
|
18
|
+
return update_all(@day, @is_done) if @all
|
19
|
+
return update(@names, @day, @is_done) if @names
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_option_parser
|
24
|
+
action = @is_done ? 'Done' : 'Undone'
|
25
|
+
OptionParser.new do |opts|
|
26
|
+
opts.banner = "Usage: hbtrack #{action.downcase} [<habit_name>] [options]"
|
27
|
+
opts.separator ''
|
28
|
+
opts.separator 'Options:'
|
29
|
+
opts.on('-a', '--all', "#{action} all habits") do
|
30
|
+
@all = true
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on('-r', '--remaining', "#{action} remaining habits") do
|
34
|
+
@remaining = true
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on('-y', '--yesterday', "#{action} habit(s) for yesterday") do
|
38
|
+
@day = Date.today - 1
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on('--day DAY', OptionParser::OctalInteger, "#{action} habit(s) for specific day") do |day|
|
42
|
+
@day = Date.new(Date.today.year, Date.today.month, day.to_i)
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on('-h', '--help', 'Prints this help') do
|
46
|
+
puts opts
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def update(names, day, is_done)
|
53
|
+
names.each do |name|
|
54
|
+
habit = if is_done
|
55
|
+
@hbt.find_or_create(name)
|
56
|
+
else
|
57
|
+
@hbt.find(name) do
|
58
|
+
return ErrorHandler.raise_if_habit_error(name)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
habit.done(is_done, day)
|
63
|
+
end
|
64
|
+
|
65
|
+
Store.new(@hbt.habits, @hbt.output_file_name).save
|
66
|
+
|
67
|
+
Hbtrack::Util.green("#{action(is_done)} #{names.join(',')}!")
|
68
|
+
end
|
69
|
+
|
70
|
+
def update_all(day, is_done)
|
71
|
+
@hbt.habits.each { |habit| habit.done(is_done, day) }
|
72
|
+
|
73
|
+
Store.new(@hbt.habits, @hbt.output_file_name).save
|
74
|
+
|
75
|
+
Hbtrack::Util.green("#{action(is_done)} all habits!")
|
76
|
+
end
|
77
|
+
|
78
|
+
def update_remaining(day, is_done)
|
79
|
+
@hbt.habits.each do |habit|
|
80
|
+
habit.done(is_done, day) if habit.done_for(date: day).nil?
|
81
|
+
end
|
82
|
+
|
83
|
+
Store.new(@hbt.habits, @hbt.output_file_name).save
|
84
|
+
|
85
|
+
Hbtrack::Util.green("#{action(is_done)} remaining habit(s)!")
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def action(is_done)
|
91
|
+
is_done ? 'Done' : 'Undone'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hbtrack
|
4
|
+
class Command
|
5
|
+
def initialize(hbt, options)
|
6
|
+
@hbt = hbt
|
7
|
+
@all = false
|
8
|
+
@option_parser = create_option_parser
|
9
|
+
|
10
|
+
unprocess_option = @option_parser.parse(options)
|
11
|
+
@names = unprocess_option
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute
|
15
|
+
help
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_option_parser
|
19
|
+
raise 'Not Implemented'
|
20
|
+
end
|
21
|
+
|
22
|
+
def help
|
23
|
+
@option_parser.help
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hbtrack
|
4
|
+
class ErrorHandler
|
5
|
+
class << self
|
6
|
+
def raise_error_msg(msg)
|
7
|
+
Util.red msg
|
8
|
+
end
|
9
|
+
|
10
|
+
def raise_if_habit_error(habit_name)
|
11
|
+
return raise_invalid_arguments if habit_name.nil?
|
12
|
+
raise_habit_not_found(habit_name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def raise_habit_not_found(habit_name)
|
16
|
+
raise_error_msg "Invalid habit: #{habit_name} not found."
|
17
|
+
end
|
18
|
+
|
19
|
+
def raise_invalid_arguments
|
20
|
+
raise_error_msg 'Invalid argument: habit_name is expected.'
|
21
|
+
end
|
22
|
+
|
23
|
+
def raise_habit_name_too_long
|
24
|
+
raise_error_msg 'habit_name too long.'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/hbtrack/habit.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'date'
|
4
|
+
require 'hbtrack/util'
|
4
5
|
|
5
|
-
module Hbtrack
|
6
|
-
|
6
|
+
module Hbtrack
|
7
7
|
# Habit class
|
8
8
|
class Habit
|
9
|
-
attr_accessor :name
|
10
|
-
attr_reader :progress
|
11
|
-
|
9
|
+
attr_accessor :name, :progress
|
12
10
|
# Class Methods
|
13
11
|
|
14
12
|
class << self
|
@@ -66,14 +64,12 @@ module Hbtrack
|
|
66
64
|
end
|
67
65
|
|
68
66
|
# Get the latest progress key.
|
69
|
-
#
|
67
|
+
#
|
70
68
|
# @return [Symbol] latest progress key
|
71
|
-
def latest_key
|
69
|
+
def latest_key
|
72
70
|
key = Habit.get_progress_key_from(Date.today)
|
73
|
-
if progress[key].nil?
|
74
|
-
|
75
|
-
end
|
76
|
-
key
|
71
|
+
initialize_progress_hash_from(key) if progress[key].nil?
|
72
|
+
key
|
77
73
|
end
|
78
74
|
|
79
75
|
# Get the latest progress.
|
@@ -90,12 +86,12 @@ module Hbtrack
|
|
90
86
|
stat_for_progress(latest_key)
|
91
87
|
end
|
92
88
|
|
93
|
-
# Find the month in progress with
|
89
|
+
# Find the month in progress with
|
94
90
|
# the longest name
|
95
|
-
#
|
91
|
+
#
|
96
92
|
# @return [String] month
|
97
93
|
def longest_month
|
98
|
-
key = progress.keys.max_by do |x|
|
94
|
+
key = progress.keys.max_by do |x|
|
99
95
|
Util.get_month_from(x).length
|
100
96
|
end
|
101
97
|
Util.get_month_from(key)
|
@@ -103,7 +99,7 @@ module Hbtrack
|
|
103
99
|
|
104
100
|
# Update the status of the progress
|
105
101
|
#
|
106
|
-
# @param done [true, false] If true, it is marked as done.
|
102
|
+
# @param done [true, false] If true, it is marked as done.
|
107
103
|
# Else, marked as undone.
|
108
104
|
# @param date [Date] The date of the progress
|
109
105
|
# @return [void]
|
@@ -113,17 +109,25 @@ module Hbtrack
|
|
113
109
|
update_progress_for(key, date.day, done)
|
114
110
|
end
|
115
111
|
|
112
|
+
# TODO: test needed
|
113
|
+
# Get the done status for specific date
|
114
|
+
#
|
115
|
+
# @return [Integer]
|
116
|
+
def done_for(date:) # TODO: Test needed
|
117
|
+
latest_progress.split('')[date.day - 1]
|
118
|
+
end
|
119
|
+
|
116
120
|
# Get the stat of the progress.
|
117
121
|
#
|
118
122
|
# @param key [Symbol] key for the progress
|
119
|
-
# @return [Hash] stat of the progress in the form of
|
123
|
+
# @return [Hash] stat of the progress in the form of
|
120
124
|
# == Example:
|
121
125
|
#
|
122
126
|
# habit.stat_for_progress("2017,5".to_sym)
|
123
127
|
# # => { done: 5, undone: 2 }
|
124
128
|
def stat_for_progress(key)
|
125
129
|
undone = @progress[key].split('').count { |x| x == '0' }
|
126
|
-
done = @progress[key].
|
130
|
+
done = @progress[key].split('').count { |x| x == '1' }
|
127
131
|
{ done: done, undone: undone }
|
128
132
|
end
|
129
133
|
|
@@ -141,11 +145,28 @@ module Hbtrack
|
|
141
145
|
arr.join('')
|
142
146
|
end
|
143
147
|
|
148
|
+
def overall_stat
|
149
|
+
done = 0
|
150
|
+
undone = 0
|
151
|
+
@progress.each do |key, _value|
|
152
|
+
stat = stat_for_progress(key)
|
153
|
+
done += stat[:done]
|
154
|
+
undone += stat[:undone]
|
155
|
+
end
|
156
|
+
{ done: done, undone: undone }
|
157
|
+
end
|
158
|
+
|
159
|
+
def overall_stat_description(formatter)
|
160
|
+
Util.title('Total') +
|
161
|
+
formatter.format(overall_stat)
|
162
|
+
end
|
163
|
+
|
144
164
|
def to_s
|
145
165
|
"#{name}\n" + progress_output + "\n"
|
146
166
|
end
|
147
167
|
|
148
168
|
private
|
169
|
+
|
149
170
|
def initialize_progress_hash_from(key)
|
150
171
|
@progress[key] = '' unless @progress.key? key
|
151
172
|
end
|
@@ -153,8 +174,8 @@ module Hbtrack
|
|
153
174
|
def update_progress_for(key, day, done)
|
154
175
|
i = day - @progress[key].length - 1
|
155
176
|
result = @progress[key].split('')
|
156
|
-
i.times { result << '
|
157
|
-
result[day-1] = done ? '1' : '0'
|
177
|
+
i.times { result << ' ' }
|
178
|
+
result[day - 1] = done ? '1' : '0'
|
158
179
|
@progress[key] = result.join('')
|
159
180
|
end
|
160
181
|
end
|
@@ -1,13 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'hbtrack/util'
|
4
|
+
|
3
5
|
module Hbtrack
|
4
|
-
# This class contains the methods that
|
6
|
+
# This class contains the methods that
|
5
7
|
# are used to format the progress of a Habit
|
6
8
|
# into string
|
7
9
|
class HabitPrinter
|
10
|
+
attr_accessor :formatter
|
8
11
|
|
9
|
-
def initialize(
|
10
|
-
@
|
12
|
+
def initialize(formatter = CompleteSF.new)
|
13
|
+
@formatter = formatter
|
11
14
|
end
|
12
15
|
|
13
16
|
def calculate_space_needed_for(habit, key)
|
@@ -16,30 +19,35 @@ module Hbtrack
|
|
16
19
|
|
17
20
|
def print_latest_progress(habit, no_of_space = 0)
|
18
21
|
habit.name.to_s + ' ' * no_of_space + ' : ' +
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
22
|
+
print_progress(
|
23
|
+
habit.latest_progress,
|
24
|
+
habit.latest_stat
|
25
|
+
)
|
23
26
|
end
|
24
27
|
|
25
28
|
def print_all_progress(habit)
|
26
|
-
habit.progress.map do |key, value|
|
29
|
+
habit.progress.map do |key, value|
|
27
30
|
space = calculate_space_needed_for(habit, key)
|
28
31
|
Util.convert_key_to_date(key, space) +
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
print_progress(
|
33
|
+
value,
|
34
|
+
habit.stat_for_progress(key)
|
35
|
+
)
|
33
36
|
end.join("\n")
|
34
37
|
end
|
35
38
|
|
36
39
|
def print_progress(progress, stat)
|
37
40
|
output = progress.split('').map do |x|
|
38
|
-
x == '0'
|
41
|
+
if x == '0'
|
42
|
+
Util.red('*')
|
43
|
+
elsif x == '1'
|
44
|
+
Util.green('*')
|
45
|
+
else
|
46
|
+
' '
|
47
|
+
end
|
39
48
|
end.join('')
|
40
49
|
output + ' ' * (32 - progress.size) +
|
41
|
-
@
|
50
|
+
@formatter.format(stat)
|
42
51
|
end
|
43
52
|
end
|
44
53
|
end
|
45
|
-
|