morning-pages-journal 2.0.0

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.
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in morning-pages-journal.gemspec
4
+ gemspec
@@ -0,0 +1,70 @@
1
+ Morning Pages Journal
2
+ =====================
3
+
4
+ A command line tool to manage morning pages.
5
+
6
+ Morning Pages are three pages of longhand, stream of consciousness writing,
7
+ done first thing in the morning. *There is no wrong way to do Morning Pages*–
8
+ they are not high art. They are not even “writing.” They are about
9
+ anything and everything that crosses your mind– and they are for your eyes
10
+ only. Morning Pages provoke, clarify, comfort, cajole, prioritize and
11
+ synchronize the day at hand. Do not over-think Morning Pages: just put
12
+ three pages of anything on the page…and then do three more pages tomorrow.
13
+
14
+ I thought I had a great idea. I wrote the code, then I found out somebody else did it. Anyway, here is my code...
15
+
16
+ Usage
17
+ -----
18
+
19
+ ### To open current day morning page in editor:
20
+
21
+ $ mp
22
+
23
+ ### To list morning pages and progress:
24
+
25
+ $ mp list # current month
26
+ $ mp list -w # current week
27
+ $ mp list -d # curent day
28
+ $ mp list -m # current month
29
+ $ mp list -y # current year
30
+
31
+ ### To get stats:
32
+
33
+ $ mp stat # current month
34
+ $ mp stat -w # current week
35
+ $ mp stat -d # curent day
36
+ $ mp stat -m # current month
37
+ $ mp stat -y # current year
38
+
39
+ ### To count words:
40
+
41
+ $ mp words # current month
42
+ $ mp words -w # current week
43
+ $ mp words -d # curent day
44
+ $ mp words -m # current month
45
+ $ mp words -y # current year
46
+
47
+ Configuration
48
+ -------------
49
+
50
+ A `~/.mp.yml` file will be created that looks like
51
+
52
+ editor: mate
53
+ folder: ~/.morning-pages/
54
+ words: 750
55
+ stats: 50
56
+
57
+ You can change setting manually or use
58
+
59
+ mp config <key> <value>
60
+ mp config editor vi
61
+
62
+ You can also specify a config file and run any of the commands
63
+
64
+ mp -c custom.yaml list
65
+
66
+
67
+ Installation
68
+ ------------
69
+
70
+ gem install morning-pages-journal
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/mp ADDED
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env ruby
2
+ $: << File.dirname(__FILE__) + '/../lib'
3
+
4
+ require 'trollop'
5
+ require 'morning-pages-journal'
6
+ require "yaml"
7
+
8
+ def range(sub_opts)
9
+ range = (sub_opts[:day] && :day) || (sub_opts[:week] && :week) || (sub_opts[:month] && :month) || (sub_opts[:year] && :year) || :month
10
+ end
11
+
12
+ SUB_COMMANDS = %w(list stat words config)
13
+ opts = Trollop.options do
14
+ banner "Usage: mp [options] [list | stat | words] [options]"
15
+ opt :config,"Configuration file", :required => false, :type => :string, :default => "~/.mp.yml"
16
+ stop_on SUB_COMMANDS
17
+ end
18
+
19
+ cli = MorningPagesJournal::CLI.new(opts)
20
+
21
+ if ARGV.empty?
22
+ cli.open
23
+ else
24
+ cmd = ARGV.shift # get the subcomman
25
+
26
+ def parse_options
27
+ Trollop.options do
28
+ opt :day,"Show only for the day", :required => false, :default => false
29
+ opt :week,"Show only for the week", :required => false , :default => false
30
+ opt :month,"Show only for the month", :required => false, :default => false
31
+ opt :year,"Show only for the year", :required => false, :default => false
32
+ end
33
+ end
34
+
35
+ case cmd
36
+ when "list"
37
+ sub_opts = parse_options
38
+
39
+ cli.list(:range => range(sub_opts))
40
+ when "stat"
41
+ sub_opts = parse_options
42
+
43
+ cli.stat(:range => range(sub_opts))
44
+ when "words"
45
+ sub_opts = parse_options
46
+
47
+ cli.words(:range => range(sub_opts))
48
+ when "config"
49
+ raise Trollop::die("config requires 2 arguments key and value") if ARGV.size != 2
50
+ key = ARGV.shift
51
+ value = ARGV.shift
52
+
53
+ cli.update_config(key, value)
54
+ else
55
+ puts "Unknown command '#{cmd}'".color(:red)
56
+ end
57
+
58
+ end
@@ -0,0 +1,6 @@
1
+ require "morning-pages-journal/version"
2
+ require "morning-pages-journal/journal"
3
+
4
+ module MorningPagesJournal
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,236 @@
1
+ require 'date'
2
+ require 'rainbow'
3
+
4
+ module MorningPagesJournal
5
+
6
+ class Page
7
+ attr_reader :file_path
8
+
9
+ def initialize(file_path)
10
+ @file_path = file_path
11
+ end
12
+
13
+ def date
14
+ return @date if @date
15
+
16
+ s = @file_path.split("/")
17
+
18
+ year_month = s[s.size-2]
19
+ day = s[s.size-1].split(".")[0]
20
+
21
+ @date = Date.parse("#{year_month}-#{day}")
22
+ @date
23
+ end
24
+
25
+ def words
26
+ @count ||= `wc -w #{@file_path}`.split(" ")[0]
27
+ end
28
+
29
+ def word_count(hash = Hash.new(0))
30
+ content.split.inject(hash) { |h,v| h[v] += 1; h }
31
+ end
32
+
33
+ def content
34
+ File.open(@file_path).read
35
+ end
36
+
37
+ end
38
+
39
+ class Journal
40
+
41
+ def initialize(options)
42
+ raise "Base folder is required" unless options[:base_folder]
43
+ @base_folder = options[:base_folder]
44
+ end
45
+
46
+ def today_folder
47
+ folder = Date.today.strftime("%Y-%m")
48
+ File.join(@base_folder,folder)
49
+ end
50
+
51
+ def today_file
52
+ file_name = Date.today.strftime("%d")
53
+ File.join(today_folder,"#{file_name}.txt")
54
+ end
55
+
56
+ def pages
57
+ @pages ||= pages_files.collect { |path| Page.new(path) }.sort { |a, b| a.date <=> a.date }
58
+ end
59
+
60
+ def get_page(date)
61
+ @pages.select {|p| p.date == date }.first
62
+ end
63
+
64
+ def each_day(range = :month)
65
+ return if pages.empty?
66
+ max = pages.last.date
67
+ min = date_starting_at(max, range)
68
+
69
+ min.upto(max).each do |date|
70
+ yield date
71
+ end
72
+ end
73
+
74
+ def min_date(range = :month)
75
+ # pages.first.date
76
+ date_starting_at(max_date,range)
77
+ end
78
+
79
+ def max_date
80
+ pages.last.date
81
+ end
82
+
83
+ def word_count(range=:month)
84
+ hash = Hash.new(0)
85
+ pages_from(min_date(range),max_date).each do |p|
86
+ p.word_count(hash)
87
+ end
88
+ hash
89
+ end
90
+
91
+ def average_words
92
+ w = pages.collect {|p| p.words.to_i}
93
+ w.inject(0.0) { |sum, el| sum + el } / w.size
94
+ end
95
+
96
+ def pages_from(from,to)
97
+ pages.select do |p|
98
+ p.date >= from && p.date <= to
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def pages_files
105
+ Dir.glob("#{File.expand_path(@base_folder)}/**/*").reject {|fn| File.directory?(fn) }
106
+ end
107
+
108
+ def date_starting_at(date,range)
109
+ case range
110
+ when :day then date
111
+ when :week then date - (date.wday-1)
112
+ when :month then date - (date.mday-1)
113
+ when :year then date - (date.yday-1)
114
+ end
115
+ end
116
+ end
117
+
118
+ class CLI
119
+
120
+ def initialize(command_line_arguments)
121
+ @opts = command_line_arguments
122
+ @opts[:config] = File.expand_path(@opts[:config])
123
+ end
124
+
125
+ def opts
126
+ @opts
127
+ end
128
+
129
+ def config
130
+ create_config_if_not_exists!
131
+
132
+ @config ||= YAML::load(File.open(opts[:config]))
133
+ end
134
+
135
+
136
+ def config_words
137
+ config["words"] || 750
138
+ end
139
+
140
+ def stats_words
141
+ (config["stats"] || 50).to_i
142
+ end
143
+
144
+ def open
145
+ journal = MorningPagesJournal::Journal.new(:base_folder => config["folder"])
146
+ editor = config["editor"]
147
+
148
+ system "mkdir -p #{journal.today_folder} ; #{editor} #{journal.today_file}"
149
+ end
150
+
151
+ def list(options)
152
+ journal = MorningPagesJournal::Journal.new(:base_folder => config["folder"])
153
+
154
+ month_name = ""
155
+ total_words = 0
156
+ journal.each_day(options[:range]) do |date|
157
+ if month_name != date.strftime("%B")
158
+ month_name = date.strftime("%B")
159
+ puts month_name
160
+ puts "-" * 100
161
+ end
162
+
163
+ page = journal.get_page(date)
164
+
165
+ words,color = if page
166
+ if page.words.to_i < config_words
167
+ [page.words.to_i, :red]
168
+ else
169
+ [page.words.to_i, :green]
170
+ end
171
+ else
172
+ [0,:yellow]
173
+ end
174
+
175
+ total_words += words
176
+ puts "#{date.strftime('%a, %d')}\t#{words.to_s.color(color)}\t" + ("="* (words/10).to_i).color(color)
177
+
178
+ if date.strftime('%a') == "Sat"
179
+ puts ""
180
+ end
181
+ end
182
+ end
183
+
184
+ def stat(options)
185
+ journal = MorningPagesJournal::Journal.new(:base_folder => config["folder"])
186
+
187
+ min_date = journal.min_date(options[:range])
188
+ days = ((journal.max_date+1) - min_date).to_i
189
+ morning_pages = journal.pages_from(min_date,journal.max_date).size
190
+ missed = days - morning_pages
191
+
192
+ puts "Average Words:\t#{journal.average_words.to_i}\n"
193
+ puts "From:\t#{min_date}"
194
+ puts "To:\t#{journal.max_date}"
195
+ puts "Total days:\t#{days}"
196
+ puts "Morning pages:\t#{morning_pages}"
197
+ puts "Missed:\t#{missed}"
198
+ puts "\n"
199
+ end
200
+
201
+ def words(options)
202
+ journal = MorningPagesJournal::Journal.new(:base_folder => config["folder"])
203
+ journal.word_count(options[:range]).sort_by {|k,v| v}.reverse.take(stats_words).each do |e|
204
+ puts "#{e[0]}\t#{e[1]}"
205
+ end
206
+ end
207
+
208
+ def update_config(key,value)
209
+ c = config
210
+ c[key] = value
211
+
212
+ File.open(opts[:config],"w+") do |f|
213
+ f.write YAML::dump(c)
214
+ end
215
+ end
216
+
217
+ private
218
+
219
+ def create_config_if_not_exists!
220
+ unless File.exists?(opts[:config])
221
+ File.open(opts[:config],"w+") do |f|
222
+ f.write YAML::dump({
223
+ "editor" => "mate",
224
+ "folder" => "~/.morning-pages/",
225
+ "words" => 750,
226
+ "stats" => 50
227
+ })
228
+ end
229
+ end
230
+
231
+ end
232
+
233
+ end
234
+
235
+
236
+ end
@@ -0,0 +1,7 @@
1
+ module Morning
2
+ module Pages
3
+ module Journal
4
+ VERSION = "2.0.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "morning-pages-journal/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "morning-pages-journal"
7
+ s.version = Morning::Pages::Journal::VERSION
8
+ s.authors = ["Federico Dayan"]
9
+ s.email = ["federico.dayan@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Command line tool to manage morning pages}
12
+ s.description = %q{Morning pages are three pages of writing done every day. This tool organizes pages and keep track of progress. It does not share anything of course }
13
+
14
+ s.rubyforge_project = "morning-pages-journal"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+
25
+ s.add_dependency 'trollop'
26
+ s.add_dependency 'rainbow'
27
+ s.add_development_dependency 'rspec'
28
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe MorningPagesJournal::Page do
4
+
5
+ end
@@ -0,0 +1,17 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: morning-pages-journal
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Federico Dayan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-13 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: trollop
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rainbow
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: ! 'Morning pages are three pages of writing done every day. This tool
63
+ organizes pages and keep track of progress. It does not share anything of course '
64
+ email:
65
+ - federico.dayan@gmail.com
66
+ executables:
67
+ - mp
68
+ extensions: []
69
+ extra_rdoc_files: []
70
+ files:
71
+ - .gitignore
72
+ - .rspec
73
+ - Gemfile
74
+ - README.md
75
+ - Rakefile
76
+ - bin/mp
77
+ - lib/morning-pages-journal.rb
78
+ - lib/morning-pages-journal/journal.rb
79
+ - lib/morning-pages-journal/version.rb
80
+ - morning-pages-journal.gemspec
81
+ - spec/morning-pages-journal/page_spec.rb
82
+ - spec/spec_helper.rb
83
+ homepage: ''
84
+ licenses: []
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project: morning-pages-journal
103
+ rubygems_version: 1.8.18
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Command line tool to manage morning pages
107
+ test_files:
108
+ - spec/morning-pages-journal/page_spec.rb
109
+ - spec/spec_helper.rb