morning-pages-journal 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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