woli 0.0.1.pre1 → 0.0.1
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.
- data/CHANGELOG.md +5 -0
- data/README.md +2 -2
- data/bin/woli +2 -2
- data/lib/woli.rb +1 -1
- data/lib/woli/cli/date_parser.rb +44 -0
- data/lib/woli/cli/runner.rb +16 -0
- data/lib/woli/cli/runner_edit.rb +45 -0
- data/lib/woli/cli/runner_init.rb +18 -0
- data/lib/woli/cli/runner_list.rb +14 -0
- data/lib/woli/cli/runner_notify.rb +16 -0
- data/lib/woli/cli/runner_status.rb +26 -0
- data/lib/woli/config.rb +19 -8
- data/lib/woli/diary.rb +1 -1
- data/lib/woli/version.rb +1 -1
- data/spec/woli/{date_parser_spec.rb → cli/date_parser_spec.rb} +9 -8
- data/spec/woli/cli/runner_init_spec.rb +22 -0
- data/spec/woli/cli/runner_list_spec.rb +35 -0
- data/spec/woli/cli/runner_status_spec.rb +44 -0
- data/spec/woli/diary_spec.rb +6 -0
- data/spec/woli_spec.rb +116 -0
- data/woli.gemspec +3 -1
- metadata +116 -37
- data/lib/woli/cli.rb +0 -13
- data/lib/woli/cli/edit.rb +0 -41
- data/lib/woli/cli/list.rb +0 -10
- data/lib/woli/cli/notify.rb +0 -12
- data/lib/woli/cli/status.rb +0 -17
- data/lib/woli/date_parser.rb +0 -44
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -4,13 +4,13 @@ Geek's diary keeper, currently in pre-alpha state :)
|
|
4
4
|
|
5
5
|
## Why would a grown person keep a diary?
|
6
6
|
|
7
|
-
* The ability to recall why a particular time of
|
7
|
+
* The ability to recall why a particular time of your life was worth living is crucial for your
|
8
8
|
long term happiness. Can you recall what you did during this week four years ago? If you can't,
|
9
9
|
it doesn't mean the week was not worth living, but it does mean that you can't derive a feeling
|
10
10
|
of happiness and satisfaction from knowing *why* it was worth living. Keeping a diary helps you
|
11
11
|
recall. You won't lose memories that are worth keeping.
|
12
12
|
|
13
|
-
* A diary helps you reflect on how you spent your time. In
|
13
|
+
* A diary helps you reflect on how you spent your time. In the long run, keeping a diary increases
|
14
14
|
your ability to recognize what's really important for you, what makes you happy. You will be
|
15
15
|
able to shape your days to contain more of those happy moments and important stuff. You will
|
16
16
|
be able to point your life in a direction that will bring you satisfaction and happiness.
|
data/bin/woli
CHANGED
data/lib/woli.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Woli
|
2
|
+
module Cli
|
3
|
+
module DateParser
|
4
|
+
def self.parse_date_long_desc
|
5
|
+
<<-END
|
6
|
+
Specifying DAY:
|
7
|
+
|
8
|
+
1) Implicitly: If no date is given, 'today' is assumed.
|
9
|
+
|
10
|
+
2) Via a keyword: woli edit DAYNAME
|
11
|
+
(Where DAYNAME can be:
|
12
|
+
'today' or 't';
|
13
|
+
'yesterday' or 'y')
|
14
|
+
|
15
|
+
3) Via a date: woli edit DD[-MM[-YYYY]]
|
16
|
+
(Use hyphens, dots or slashes to separate day/month/year.
|
17
|
+
If year or month is not given, current year / current month is assumed.)
|
18
|
+
|
19
|
+
4) Via days ago: woli edit ^DAYS
|
20
|
+
(Where DAYS is a number of days ago. ^1 is yesterday, ^7 is a week ago etc.)
|
21
|
+
END
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.parse_date(fuzzy_date)
|
25
|
+
case fuzzy_date
|
26
|
+
when 'today', 't'
|
27
|
+
Date.today
|
28
|
+
when 'yesterday', 'y'
|
29
|
+
Date.today - 1
|
30
|
+
when /\A\^(?<days_ago>\d+)/
|
31
|
+
Date.today - Integer($~[:days_ago])
|
32
|
+
when /\A(?<day>\d+)([-\.\/](?<month>\d+)([-\.\/](?<year>\d+))?)?\Z/
|
33
|
+
today = Date.today
|
34
|
+
year = $~[:year] ? Integer($~[:year]) : today.year
|
35
|
+
month = $~[:month] ? Integer($~[:month]) : today.month
|
36
|
+
day = $~[:day] ? Integer($~[:day]) : today.day
|
37
|
+
Date.new(year, month, day)
|
38
|
+
else
|
39
|
+
raise Thor::MalformattedArgumentError, "'#{fuzzy_date}' is not a valid way to specify a date."
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'woli'
|
2
|
+
require 'woli/cli/date_parser'
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
module Woli
|
6
|
+
module Cli
|
7
|
+
class Runner < Thor
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'woli/cli/runner_edit'
|
13
|
+
require 'woli/cli/runner_init'
|
14
|
+
require 'woli/cli/runner_list'
|
15
|
+
require 'woli/cli/runner_notify'
|
16
|
+
require 'woli/cli/runner_status'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Woli
|
2
|
+
module Cli
|
3
|
+
class Runner
|
4
|
+
desc 'edit DAY', 'Edit a diary entry for a given day.'
|
5
|
+
long_desc <<-END
|
6
|
+
Edit a diary entry for a given day.
|
7
|
+
|
8
|
+
#{DateParser.parse_date_long_desc}
|
9
|
+
END
|
10
|
+
def edit(fuzzy_date = 'today')
|
11
|
+
date = DateParser.parse_date(fuzzy_date)
|
12
|
+
entry = Woli.diary.load_or_create_entry(date)
|
13
|
+
|
14
|
+
temp_file_name = generate_temp_file_name(entry)
|
15
|
+
save_text_to_temp_file(entry, temp_file_name)
|
16
|
+
edit_file_in_editor(temp_file_name)
|
17
|
+
load_text_from_temp_file(entry, temp_file_name)
|
18
|
+
|
19
|
+
entry.persist
|
20
|
+
rescue ConfigError => e
|
21
|
+
raise Thor::Error, e.message
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def save_text_to_temp_file(entry, temp_file_name)
|
27
|
+
File.write(temp_file_name, entry.text)
|
28
|
+
end
|
29
|
+
|
30
|
+
def load_text_from_temp_file(entry, temp_file_name)
|
31
|
+
entry.text = File.read(temp_file_name)
|
32
|
+
File.delete(temp_file_name)
|
33
|
+
end
|
34
|
+
|
35
|
+
def generate_temp_file_name(entry)
|
36
|
+
"/tmp/woli_edit_entry_#{entry.date.strftime('%Y_%m_%d')}.#{Woli.config['edit_entry_extension']}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def edit_file_in_editor(file_name)
|
40
|
+
tty = `tty`.strip
|
41
|
+
`#{Woli.editor} < #{tty} > #{tty} #{file_name}`
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Woli
|
2
|
+
module Cli
|
3
|
+
class Runner
|
4
|
+
desc 'init', 'Initialize Woli for this user.'
|
5
|
+
long_desc <<-END
|
6
|
+
Creates a ~/.woli directory with Woli configuration.
|
7
|
+
END
|
8
|
+
def init
|
9
|
+
created_config_file_path = Woli::Config.create_config_file_from_template
|
10
|
+
if created_config_file_path
|
11
|
+
say "Default config file created at #{created_config_file_path}."
|
12
|
+
else
|
13
|
+
say "Config file already exists."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Woli
|
2
|
+
module Cli
|
3
|
+
class Runner
|
4
|
+
desc 'list', 'List dates for which there are entries in the diary.'
|
5
|
+
def list
|
6
|
+
Woli.diary.all_entries_dates.each do |date|
|
7
|
+
say date.strftime('%d-%m-%Y')
|
8
|
+
end
|
9
|
+
rescue ConfigError => e
|
10
|
+
raise Thor::Error, e.message
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Woli
|
2
|
+
module Cli
|
3
|
+
class Runner
|
4
|
+
desc 'notify', 'Get notified when you forget to write entries.'
|
5
|
+
def notify
|
6
|
+
notify_config = Woli.config['notification']['missing_entries']
|
7
|
+
|
8
|
+
if Woli.diary.missing_entries_count >= notify_config['days']
|
9
|
+
`#{notify_config['command']}`
|
10
|
+
end
|
11
|
+
rescue ConfigError => e
|
12
|
+
raise Thor::Error, e.message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Woli
|
2
|
+
module Cli
|
3
|
+
class Runner
|
4
|
+
desc 'status', 'Print basic information about the diary.'
|
5
|
+
def status
|
6
|
+
entries_dates = Woli.diary.all_entries_dates
|
7
|
+
date_format = '%d-%m-%Y'
|
8
|
+
|
9
|
+
say "Woli Diary Status"
|
10
|
+
say "================="
|
11
|
+
|
12
|
+
if entries_dates.count > 0
|
13
|
+
coverage = entries_dates.count / Float(entries_dates.last - entries_dates.first + 1)
|
14
|
+
say "First entry: #{entries_dates.first.strftime(date_format)}"
|
15
|
+
say "Last entry: #{entries_dates.last.strftime(date_format)}"
|
16
|
+
say "Coverage: %2d %" % (coverage * 100).round
|
17
|
+
say "Missing entries since the last one: #{Woli.diary.missing_entries_count}"
|
18
|
+
else
|
19
|
+
say "Diary is empty. Run 'woli help edit' to learn how to create entries."
|
20
|
+
end
|
21
|
+
rescue ConfigError => e
|
22
|
+
raise Thor::Error, e.message
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/woli/config.rb
CHANGED
@@ -1,19 +1,30 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
3
|
module Woli
|
4
|
-
|
4
|
+
module Config
|
5
5
|
CONFIG_FILE_NAME = "#{ENV['HOME']}/.woli/config.yml"
|
6
|
-
|
6
|
+
CONFIG_TEMPLATE_FILE_NAME = File.join(File.dirname(__FILE__),
|
7
7
|
'../../templates/default_config.yml')
|
8
8
|
|
9
|
-
def self.
|
10
|
-
|
11
|
-
|
9
|
+
def self.load_config
|
10
|
+
if File.exists?(CONFIG_FILE_NAME)
|
11
|
+
YAML.load_file(CONFIG_FILE_NAME)
|
12
|
+
else
|
13
|
+
raise ConfigError, "Woli not yet initialized. Run 'woli help init' for more info."
|
14
|
+
end
|
12
15
|
end
|
13
16
|
|
14
|
-
def self.
|
15
|
-
|
16
|
-
|
17
|
+
def self.create_config_file_from_template
|
18
|
+
unless File.exists?(CONFIG_FILE_NAME)
|
19
|
+
FileUtils.mkdir_p(File.dirname(CONFIG_FILE_NAME))
|
20
|
+
FileUtils.cp(CONFIG_TEMPLATE_FILE_NAME, CONFIG_FILE_NAME)
|
21
|
+
CONFIG_FILE_NAME
|
22
|
+
else
|
23
|
+
nil
|
24
|
+
end
|
17
25
|
end
|
18
26
|
end
|
27
|
+
|
28
|
+
class ConfigError < RuntimeError
|
29
|
+
end
|
19
30
|
end
|
data/lib/woli/diary.rb
CHANGED
data/lib/woli/version.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
require_relative '
|
2
|
-
require 'woli/date_parser'
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require 'woli/cli/date_parser'
|
3
|
+
require 'thor'
|
3
4
|
|
4
|
-
describe Woli::DateParser do
|
5
|
+
describe Woli::Cli::DateParser do
|
5
6
|
before do
|
6
|
-
@parser = Woli::DateParser
|
7
|
+
@parser = Woli::Cli::DateParser
|
7
8
|
@today = Date.new(2012, 7, 15)
|
8
9
|
Timecop.freeze(@today)
|
9
10
|
end
|
@@ -12,10 +13,6 @@ describe Woli::DateParser do
|
|
12
13
|
Timecop.return
|
13
14
|
end
|
14
15
|
|
15
|
-
it "parses nil as today" do
|
16
|
-
@parser.parse_date(nil).must_equal @today
|
17
|
-
end
|
18
|
-
|
19
16
|
it "parses 't' and 'today' as today" do
|
20
17
|
@parser.parse_date('t').must_equal @today
|
21
18
|
@parser.parse_date('today').must_equal @today
|
@@ -65,4 +62,8 @@ describe Woli::DateParser do
|
|
65
62
|
date1.must_equal date3
|
66
63
|
date1.must_equal date4
|
67
64
|
end
|
65
|
+
|
66
|
+
it "raises error for nil" do
|
67
|
+
proc { @parser.parse_date(nil) }.must_raise Thor::MalformattedArgumentError
|
68
|
+
end
|
68
69
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require 'woli/cli/runner'
|
3
|
+
|
4
|
+
describe Woli::Cli::Runner do
|
5
|
+
before do
|
6
|
+
module Woli::Config ; end
|
7
|
+
@runner = Woli::Cli::Runner.new
|
8
|
+
end
|
9
|
+
describe "init task" do
|
10
|
+
it "creates configuration for the user and informs them" do
|
11
|
+
Woli::Config.expects(:create_config_file_from_template).returns('/home/woli/.woli/config.yml')
|
12
|
+
@runner.expects(:say).with { |text| text =~ %r{created at /home/woli/\.woli/config\.yml} }
|
13
|
+
@runner.init
|
14
|
+
end
|
15
|
+
|
16
|
+
it "informs the user if the config file is already present" do
|
17
|
+
Woli::Config.expects(:create_config_file_from_template).returns(nil)
|
18
|
+
@runner.expects(:say).with { |text| text =~ %r{already exists} }
|
19
|
+
@runner.init
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require 'woli/cli/runner'
|
3
|
+
|
4
|
+
describe Woli::Cli::Runner do
|
5
|
+
before do
|
6
|
+
@diary = mock 'diary'
|
7
|
+
Woli.stubs(:diary).returns(@diary)
|
8
|
+
@runner = Woli::Cli::Runner.new
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "list task" do
|
12
|
+
it "prints dates for all diary entries" do
|
13
|
+
@diary.expects(:all_entries_dates).returns([
|
14
|
+
Date.new(2012, 7, 4),
|
15
|
+
Date.new(2012, 7, 5),
|
16
|
+
Date.new(2012, 7, 6)
|
17
|
+
])
|
18
|
+
expected_output = [
|
19
|
+
'04-07-2012',
|
20
|
+
'05-07-2012',
|
21
|
+
'06-07-2012'
|
22
|
+
]
|
23
|
+
@runner.expects(:say).times(3).with do |output|
|
24
|
+
output == expected_output.shift
|
25
|
+
end
|
26
|
+
@runner.list
|
27
|
+
end
|
28
|
+
|
29
|
+
it "doesn't print anything if the diary is empty" do
|
30
|
+
@diary.expects(:all_entries_dates).returns([])
|
31
|
+
@runner.expects(:say).never
|
32
|
+
@runner.list
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require 'woli/cli/runner'
|
3
|
+
|
4
|
+
describe Woli::Cli::Runner do
|
5
|
+
before do
|
6
|
+
@diary = mock 'diary'
|
7
|
+
@diary.stubs(:all_entries_dates).returns([
|
8
|
+
Date.new(2012, 7, 4),
|
9
|
+
Date.new(2012, 7, 6),
|
10
|
+
Date.new(2012, 7, 7)
|
11
|
+
])
|
12
|
+
@diary.stubs(:missing_entries_count).returns(2)
|
13
|
+
Woli.stubs(:diary).returns(@diary)
|
14
|
+
|
15
|
+
@runner = Woli::Cli::Runner.new
|
16
|
+
|
17
|
+
@output = ''
|
18
|
+
@runner.stubs(:say).with do |to_print|
|
19
|
+
@output << to_print << "\n"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "prints first and last entry dates" do
|
24
|
+
@runner.status
|
25
|
+
@output.must_match /first entry: 04-07-2012/i
|
26
|
+
@output.must_match /last entry: 07-07-2012/i
|
27
|
+
end
|
28
|
+
|
29
|
+
it "prints entry/day coverage" do
|
30
|
+
@runner.status
|
31
|
+
@output.must_match /coverage: 75 %/i
|
32
|
+
end
|
33
|
+
|
34
|
+
it "prints the number of missing entries since the last one" do
|
35
|
+
@runner.status
|
36
|
+
@output.must_match /missing entries[^:]*: 2/i
|
37
|
+
end
|
38
|
+
|
39
|
+
it "informs of empty diary" do
|
40
|
+
@diary.stubs(:all_entries_dates).returns([])
|
41
|
+
@runner.status
|
42
|
+
@output.must_match /diary is empty/i
|
43
|
+
end
|
44
|
+
end
|
data/spec/woli/diary_spec.rb
CHANGED
@@ -48,6 +48,12 @@ describe Woli::Diary do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
describe "#missing_entries_count" do
|
51
|
+
it "returns an Integer" do
|
52
|
+
Timecop.freeze(@repository.all_entries_dates.last + 1) do
|
53
|
+
@diary.missing_entries_count.must_be_kind_of Integer
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
51
57
|
it "returns 0 when the last entry is for today" do
|
52
58
|
Timecop.freeze(@repository.all_entries_dates.last) do
|
53
59
|
@diary.missing_entries_count.must_equal 0
|
data/spec/woli_spec.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require 'woli'
|
3
|
+
|
4
|
+
describe Woli do
|
5
|
+
describe ".config" do
|
6
|
+
after do
|
7
|
+
module Woli
|
8
|
+
@config = nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns config when already loaded" do
|
13
|
+
module Woli
|
14
|
+
@config = :fake_config
|
15
|
+
end
|
16
|
+
Woli.config.must_equal :fake_config
|
17
|
+
end
|
18
|
+
|
19
|
+
it "loads config if not loaded yet" do
|
20
|
+
Woli::Config.expects(:load_config).returns(:fake_config)
|
21
|
+
Woli.config.must_equal :fake_config
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe ".diary" do
|
26
|
+
before do
|
27
|
+
module Woli
|
28
|
+
@repository = :fake_repository
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
after do
|
33
|
+
module Woli
|
34
|
+
@diary = nil
|
35
|
+
@repository = nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns a diary when already created" do
|
40
|
+
module Woli
|
41
|
+
@diary = :fake_diary
|
42
|
+
end
|
43
|
+
Woli.diary.must_equal :fake_diary
|
44
|
+
end
|
45
|
+
|
46
|
+
it "creates a diary if not created yet" do
|
47
|
+
Woli::Diary.expects(:new).with(:fake_repository).returns(:fake_diary)
|
48
|
+
Woli.diary.must_equal :fake_diary
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe ".editor" do
|
53
|
+
before do
|
54
|
+
@old_env_editor = ENV['EDITOR']
|
55
|
+
module Woli
|
56
|
+
@config = { 'editor' => nil }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
after do
|
61
|
+
module Woli
|
62
|
+
@config = nil
|
63
|
+
end
|
64
|
+
ENV['EDITOR'] = @old_env_editor
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns an editor set in the config file if present" do
|
68
|
+
module Woli
|
69
|
+
@config = { 'editor' => 'strange_editor' }
|
70
|
+
end
|
71
|
+
Woli.editor.must_equal 'strange_editor'
|
72
|
+
end
|
73
|
+
|
74
|
+
it "returns an editor set via environment variable if not set via config file" do
|
75
|
+
ENV['EDITOR'] = 'emacs'
|
76
|
+
Woli.editor.must_equal 'emacs'
|
77
|
+
end
|
78
|
+
|
79
|
+
it "returns vim if no environment variable or config file sets the editor" do
|
80
|
+
ENV['EDITOR'] = nil
|
81
|
+
Woli.editor.must_equal 'vim'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe ".repository" do
|
86
|
+
before do
|
87
|
+
module Woli
|
88
|
+
@config = {
|
89
|
+
'repository_class' => 'Woli::FakeRepository',
|
90
|
+
'repository_config' => :fake_config
|
91
|
+
}
|
92
|
+
|
93
|
+
class FakeRepository ; end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
after do
|
98
|
+
module Woli
|
99
|
+
@config = nil
|
100
|
+
@repository = nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
it "returns repository if already created" do
|
105
|
+
module Woli
|
106
|
+
@repository = :fake_repository
|
107
|
+
end
|
108
|
+
Woli.repository.must_equal :fake_repository
|
109
|
+
end
|
110
|
+
|
111
|
+
it "creates a new repository if not yet created" do
|
112
|
+
Woli::FakeRepository.expects(:new).with(:fake_config).returns(:fake_repository)
|
113
|
+
Woli.repository.must_equal :fake_repository
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/woli.gemspec
CHANGED
@@ -20,9 +20,11 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.require_paths = ["lib"]
|
21
21
|
gem.version = Woli::VERSION
|
22
22
|
|
23
|
-
gem.add_dependency 'thor', '
|
23
|
+
gem.add_dependency 'thor', '>= 0.15'
|
24
24
|
|
25
25
|
# == DEVELOPMENT DEPENDENCIES ==
|
26
|
+
gem.add_development_dependency 'rake'
|
27
|
+
|
26
28
|
# Smart irb
|
27
29
|
gem.add_development_dependency 'pry'
|
28
30
|
|
metadata
CHANGED
@@ -1,30 +1,51 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: woli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Jiří Stránský
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thor
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.15
|
21
|
+
version: '0.15'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.15'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
25
46
|
- !ruby/object:Gem::Dependency
|
26
47
|
name: pry
|
27
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
28
49
|
none: false
|
29
50
|
requirements:
|
30
51
|
- - ! '>='
|
@@ -32,10 +53,15 @@ dependencies:
|
|
32
53
|
version: '0'
|
33
54
|
type: :development
|
34
55
|
prerelease: false
|
35
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
36
62
|
- !ruby/object:Gem::Dependency
|
37
63
|
name: minitest
|
38
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
39
65
|
none: false
|
40
66
|
requirements:
|
41
67
|
- - ! '>='
|
@@ -43,10 +69,15 @@ dependencies:
|
|
43
69
|
version: '0'
|
44
70
|
type: :development
|
45
71
|
prerelease: false
|
46
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
47
78
|
- !ruby/object:Gem::Dependency
|
48
79
|
name: mocha
|
49
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
50
81
|
none: false
|
51
82
|
requirements:
|
52
83
|
- - ! '>='
|
@@ -54,10 +85,15 @@ dependencies:
|
|
54
85
|
version: '0'
|
55
86
|
type: :development
|
56
87
|
prerelease: false
|
57
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
58
94
|
- !ruby/object:Gem::Dependency
|
59
95
|
name: timecop
|
60
|
-
requirement:
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
61
97
|
none: false
|
62
98
|
requirements:
|
63
99
|
- - ! '>='
|
@@ -65,10 +101,15 @@ dependencies:
|
|
65
101
|
version: '0'
|
66
102
|
type: :development
|
67
103
|
prerelease: false
|
68
|
-
version_requirements:
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
69
110
|
- !ruby/object:Gem::Dependency
|
70
111
|
name: guard
|
71
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
72
113
|
none: false
|
73
114
|
requirements:
|
74
115
|
- - ! '>='
|
@@ -76,10 +117,15 @@ dependencies:
|
|
76
117
|
version: '0'
|
77
118
|
type: :development
|
78
119
|
prerelease: false
|
79
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
80
126
|
- !ruby/object:Gem::Dependency
|
81
127
|
name: guard-minitest
|
82
|
-
requirement:
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
83
129
|
none: false
|
84
130
|
requirements:
|
85
131
|
- - ! '>='
|
@@ -87,10 +133,15 @@ dependencies:
|
|
87
133
|
version: '0'
|
88
134
|
type: :development
|
89
135
|
prerelease: false
|
90
|
-
version_requirements:
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
91
142
|
- !ruby/object:Gem::Dependency
|
92
143
|
name: rb-inotify
|
93
|
-
requirement:
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
94
145
|
none: false
|
95
146
|
requirements:
|
96
147
|
- - ! '>='
|
@@ -98,10 +149,15 @@ dependencies:
|
|
98
149
|
version: '0'
|
99
150
|
type: :development
|
100
151
|
prerelease: false
|
101
|
-
version_requirements:
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
102
158
|
- !ruby/object:Gem::Dependency
|
103
159
|
name: libnotify
|
104
|
-
requirement:
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
105
161
|
none: false
|
106
162
|
requirements:
|
107
163
|
- - ! '>='
|
@@ -109,10 +165,15 @@ dependencies:
|
|
109
165
|
version: '0'
|
110
166
|
type: :development
|
111
167
|
prerelease: false
|
112
|
-
version_requirements:
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
113
174
|
- !ruby/object:Gem::Dependency
|
114
175
|
name: turn
|
115
|
-
requirement:
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
116
177
|
none: false
|
117
178
|
requirements:
|
118
179
|
- - ! '>='
|
@@ -120,7 +181,12 @@ dependencies:
|
|
120
181
|
version: '0'
|
121
182
|
type: :development
|
122
183
|
prerelease: false
|
123
|
-
version_requirements:
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
124
190
|
description: ! " Woli (as in WOrth LIving) helps you record your memories. Write\n
|
125
191
|
\ a short note about every day you live and make sure your days are worth\n living.
|
126
192
|
Later, review your notes to bring back the memories.\n Change your life if you
|
@@ -133,6 +199,7 @@ extensions: []
|
|
133
199
|
extra_rdoc_files: []
|
134
200
|
files:
|
135
201
|
- .gitignore
|
202
|
+
- CHANGELOG.md
|
136
203
|
- Gemfile
|
137
204
|
- Guardfile
|
138
205
|
- LICENSE
|
@@ -140,22 +207,27 @@ files:
|
|
140
207
|
- Rakefile
|
141
208
|
- bin/woli
|
142
209
|
- lib/woli.rb
|
143
|
-
- lib/woli/cli.rb
|
144
|
-
- lib/woli/cli/
|
145
|
-
- lib/woli/cli/
|
146
|
-
- lib/woli/cli/
|
147
|
-
- lib/woli/cli/
|
210
|
+
- lib/woli/cli/date_parser.rb
|
211
|
+
- lib/woli/cli/runner.rb
|
212
|
+
- lib/woli/cli/runner_edit.rb
|
213
|
+
- lib/woli/cli/runner_init.rb
|
214
|
+
- lib/woli/cli/runner_list.rb
|
215
|
+
- lib/woli/cli/runner_notify.rb
|
216
|
+
- lib/woli/cli/runner_status.rb
|
148
217
|
- lib/woli/config.rb
|
149
|
-
- lib/woli/date_parser.rb
|
150
218
|
- lib/woli/diary.rb
|
151
219
|
- lib/woli/diary_entry.rb
|
152
220
|
- lib/woli/repositories/files.rb
|
153
221
|
- lib/woli/version.rb
|
154
222
|
- spec/spec_helper.rb
|
155
|
-
- spec/woli/date_parser_spec.rb
|
223
|
+
- spec/woli/cli/date_parser_spec.rb
|
224
|
+
- spec/woli/cli/runner_init_spec.rb
|
225
|
+
- spec/woli/cli/runner_list_spec.rb
|
226
|
+
- spec/woli/cli/runner_status_spec.rb
|
156
227
|
- spec/woli/diary_entry_spec.rb
|
157
228
|
- spec/woli/diary_spec.rb
|
158
229
|
- spec/woli/repositories/files_spec.rb
|
230
|
+
- spec/woli_spec.rb
|
159
231
|
- templates/default_config.yml
|
160
232
|
- woli.gemspec
|
161
233
|
homepage: http://github.com/jistr/woli
|
@@ -172,22 +244,29 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
172
244
|
version: '0'
|
173
245
|
segments:
|
174
246
|
- 0
|
175
|
-
hash:
|
247
|
+
hash: 218247984176523748
|
176
248
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
249
|
none: false
|
178
250
|
requirements:
|
179
|
-
- - ! '
|
251
|
+
- - ! '>='
|
180
252
|
- !ruby/object:Gem::Version
|
181
|
-
version:
|
253
|
+
version: '0'
|
254
|
+
segments:
|
255
|
+
- 0
|
256
|
+
hash: 218247984176523748
|
182
257
|
requirements: []
|
183
258
|
rubyforge_project:
|
184
|
-
rubygems_version: 1.8.
|
259
|
+
rubygems_version: 1.8.23
|
185
260
|
signing_key:
|
186
261
|
specification_version: 3
|
187
262
|
summary: Woli, the diary keeper.
|
188
263
|
test_files:
|
189
264
|
- spec/spec_helper.rb
|
190
|
-
- spec/woli/date_parser_spec.rb
|
265
|
+
- spec/woli/cli/date_parser_spec.rb
|
266
|
+
- spec/woli/cli/runner_init_spec.rb
|
267
|
+
- spec/woli/cli/runner_list_spec.rb
|
268
|
+
- spec/woli/cli/runner_status_spec.rb
|
191
269
|
- spec/woli/diary_entry_spec.rb
|
192
270
|
- spec/woli/diary_spec.rb
|
193
271
|
- spec/woli/repositories/files_spec.rb
|
272
|
+
- spec/woli_spec.rb
|
data/lib/woli/cli.rb
DELETED
data/lib/woli/cli/edit.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
module Woli
|
2
|
-
class Cli
|
3
|
-
desc 'edit DAY', 'Edit a diary entry for a given day.'
|
4
|
-
long_desc <<-END
|
5
|
-
Edit a diary entry for a given day.
|
6
|
-
|
7
|
-
#{DateParser.parse_date_long_desc}
|
8
|
-
END
|
9
|
-
def edit(fuzzy_date = 'today')
|
10
|
-
date = DateParser.parse_date(fuzzy_date)
|
11
|
-
entry = Woli.repository.load_entry(date) || DiaryEntry.new(date, '', Woli.repository)
|
12
|
-
|
13
|
-
temp_file_name = generate_temp_file_name(entry)
|
14
|
-
save_text_to_temp_file(entry, temp_file_name)
|
15
|
-
edit_file_in_editor(temp_file_name)
|
16
|
-
load_text_from_temp_file(entry, temp_file_name)
|
17
|
-
|
18
|
-
entry.persist
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def save_text_to_temp_file(entry, temp_file_name)
|
24
|
-
File.write(temp_file_name, entry.text)
|
25
|
-
end
|
26
|
-
|
27
|
-
def load_text_from_temp_file(entry, temp_file_name)
|
28
|
-
entry.text = File.read(temp_file_name)
|
29
|
-
File.delete(temp_file_name)
|
30
|
-
end
|
31
|
-
|
32
|
-
def generate_temp_file_name(entry)
|
33
|
-
"/tmp/woli_edit_entry_#{entry.date.strftime('%Y_%m_%d')}.#{Woli.config['edit_entry_extension']}"
|
34
|
-
end
|
35
|
-
|
36
|
-
def edit_file_in_editor(file_name)
|
37
|
-
tty = `tty`.strip
|
38
|
-
`#{Woli.editor} < #{tty} > #{tty} #{file_name}`
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
data/lib/woli/cli/list.rb
DELETED
data/lib/woli/cli/notify.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
module Woli
|
2
|
-
class Cli
|
3
|
-
desc 'notify', 'Get notified when you forget to write entries.'
|
4
|
-
def notify
|
5
|
-
notify_config = Woli.config['notification']['missing_entries']
|
6
|
-
|
7
|
-
if Woli.diary.missing_entries_count >= notify_config['days']
|
8
|
-
`#{notify_config['command']}`
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
data/lib/woli/cli/status.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
module Woli
|
2
|
-
class Cli
|
3
|
-
desc 'status', 'Print basic information about the diary.'
|
4
|
-
def status
|
5
|
-
entries_dates = Woli.diary.all_entries_dates
|
6
|
-
date_format = '%d-%m-%Y'
|
7
|
-
coverage = entries_dates.count / Float(entries_dates.last - entries_dates.first + 1)
|
8
|
-
|
9
|
-
puts "Woli Diary Status"
|
10
|
-
puts "================="
|
11
|
-
puts "First entry: #{entries_dates.first.strftime(date_format)}"
|
12
|
-
puts "Last entry: #{entries_dates.last.strftime(date_format)}"
|
13
|
-
puts "Coverage: %2d %" % (coverage * 100).round
|
14
|
-
puts "Missing entries since the last one: #{Woli.diary.missing_entries_count}"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
data/lib/woli/date_parser.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
module Woli
|
2
|
-
module DateParser
|
3
|
-
def self.parse_date_long_desc
|
4
|
-
<<-END
|
5
|
-
Specifying DAY:
|
6
|
-
|
7
|
-
1) Implicitly: If no date is given, 'today' is assumed.
|
8
|
-
|
9
|
-
2) Via a keyword: woli edit DAYNAME
|
10
|
-
(Where DAYNAME can be:
|
11
|
-
'today' or 't';
|
12
|
-
'yesterday' or 'y')
|
13
|
-
|
14
|
-
3) Via a date: woli edit DD[-MM[-YYYY]]
|
15
|
-
(Use hyphens, dots or slashes to separate day/month/year.
|
16
|
-
If year or month is not given, current year / current month is assumed.)
|
17
|
-
|
18
|
-
4) Via days ago: woli edit ^DAYS
|
19
|
-
(Where DAYS is a number of days ago. ^1 is yesterday, ^7 is a week ago etc.)
|
20
|
-
END
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.parse_date(fuzzy_date)
|
24
|
-
case fuzzy_date
|
25
|
-
when 'today', 't', nil
|
26
|
-
Date.today
|
27
|
-
when 'yesterday', 'y'
|
28
|
-
Date.today - 1
|
29
|
-
when /\A\^(?<days_ago>\d+)/
|
30
|
-
Date.today - Integer($~[:days_ago])
|
31
|
-
when /\A(?<day>\d+)([-\.\/](?<month>\d+)([-\.\/](?<year>\d+))?)?\Z/
|
32
|
-
today = Date.today
|
33
|
-
year = $~[:year] ? Integer($~[:year]) : today.year
|
34
|
-
month = $~[:month] ? Integer($~[:month]) : today.month
|
35
|
-
day = $~[:day] ? Integer($~[:day]) : today.day
|
36
|
-
Date.new(year, month, day)
|
37
|
-
else
|
38
|
-
self.class.task_help(shell, 'edit')
|
39
|
-
puts
|
40
|
-
raise MalformattedArgumentError, "'#{fuzzy_date}' is not a valid way to specify a date."
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|