bpl 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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bpl.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Florin T.PATRASCU
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,140 @@
1
+ ### Blood Pressure Logger (BPL)
2
+
3
+ A very simple gem to help you track your [blood pressure](http://en.wikipedia.org/wiki/Blood_pressure) values over time. With BPL you can also:
4
+
5
+ - export your data to other applications; Numbers, Excel, etc.
6
+ - view history for a given period of time
7
+ - and more
8
+
9
+ Your privacy is very important, this is why the BPL application is open source and it is using only local resources such as the small database stored on your computer. A basic guarantee that your data is safe and completely under your own control.
10
+
11
+ ## Installation
12
+
13
+ Install the BP gem:
14
+
15
+ $ gem install bpl
16
+
17
+ Create a new folder `.bp` in your home directory:
18
+
19
+ $ mkdir ~/.bp
20
+
21
+
22
+ ## Usage
23
+
24
+ You'll have to initialize the database first, this is a one-time command:
25
+
26
+ $ bpl init
27
+
28
+ After that you can start recording your BP measurements as needed. Examples:
29
+
30
+ $ bpl 145/81/67/L/87 -d 2012/12/10 -t 16:30 -m notes
31
+ $ bpl 136/60/66
32
+ $ bpl 136/60/66/r
33
+ $ bpl 125/71/67/L/87 -d 2012/12/11 -m "some notes"
34
+ $ bpl 136/60/66/l/85
35
+ $ bpl 120/64/67/L/87 -D "2012/12/10 16:30"
36
+
37
+ BPL expects you to enter the following values:
38
+
39
+ SYS/DIA/HR/ARM/WEIGHT
40
+
41
+ Where:
42
+
43
+ SYS: systolic pressure.
44
+ DIA: diastolic pressure.
45
+ HR: heart rate
46
+ ARM: 'l' or 'r'. Left or right. It is optional; LEFT arm, if not specified.
47
+ WEIGHT: weight (optional, see note below)
48
+
49
+ You can also specify the date, date and time, and an optional comment, as seen in the previous set of examples.
50
+
51
+ A special **note** to remember when you log your data. Your weight is important but you're not required to specify it every time you add a new measurement. Specify your weight at least once or very time it is changing. The last weight value will be reused when not specified explicitly in the measurement.
52
+
53
+ ### Other useful commands
54
+ A handful of command lines and switches are provided for your convenience.
55
+
56
+ **View**
57
+ - display a page with the most recent records, or recorded at a specified date/time. Example:
58
+
59
+ $ bpl view
60
+ $ bpl view -d 2012/08/01
61
+ $ bpl view -d 08/14 -t 09:31:10
62
+
63
+ **Remove**
64
+ delete a record by record id. The record id can be observed with the **view** command. Example:
65
+
66
+ $ bpl view -d 08/14 -t 09:31:10
67
+ +--+-------------------+---+---+--+-----+------+-----+
68
+ |Id| Date |Sys|Dia|Hr| Arm |Weight|Notes|
69
+ +--+-------------------+---+---+--+-----+------+-----+
70
+ |2 |2012-09-25 09:31:11|120|80 |67|LEFT |90 | |
71
+ |1 |2012-09-25 09:30:30|1 |2 |3 |RIGHT|90 | |
72
+ +--+-------------------+---+---+--+-----+------+-----+
73
+
74
+ $ bpl remove 1
75
+ record: #1, was removed.
76
+
77
+ **Export to CSV**
78
+ export your data to a file that can be imported by other applications, including Numbers or Excel.
79
+
80
+ Here is an example exporting the data to the screen:
81
+
82
+ $ bpl export -d 9/14
83
+ ID,DATE,SYS,DIA,HR,ARM,WEIGHT,NOTES
84
+ 2,'2012-09-25 09:31:11',120,80,67,'LEFT',90,''
85
+
86
+ And to a specified file:
87
+
88
+ $ bpl export -d 2012/08/01 -f > my_bp.csv
89
+ $
90
+
91
+ **Init**
92
+ use init with `-f` if you want to wipe out clean your local database. Warning, your data cannot be restored after this point in time. Example:
93
+
94
+ $ bpl init -f
95
+
96
+ **Help**
97
+
98
+ $ bpl -h
99
+
100
+ Simple blood pressure logger
101
+
102
+ Available commands: history, series, delete, view, init, plot
103
+
104
+ Examples:
105
+
106
+ $ bpl 145/81/67/L/87 -d 2012/12/10 -t 16:30 -m notes
107
+ $ bpl 136/60/66
108
+ $ bpl 136/60/66/r
109
+ $ bpl 125/71/67/L/87 -d 2012/12/11 -m "some notes"
110
+ $ bpl 136/60/66/l/85
111
+ $ bpl 120/64/67/L/87 -D "2012/12/10 16:30"
112
+ $ bpl export -d 2012/08/01 -f > my_bp.csv
113
+
114
+ The following options apply:
115
+ --date, -d <s>: Date (default: 2012/10/31)
116
+ --time, -t <s>: Time (default: 11:01:31)
117
+ --datetime, -D <s>: Specify the date and the time, surrounded with quotes ";
118
+ --message, -m <s>: Notes, comments
119
+ --force, -f: Force database initialization, all the data will be lost
120
+ --raw, -r: used to view the data without formatting
121
+ --page, -p <i>: total number of records to view (default: 15)
122
+ --all, -a: export the entire dataset, all the records
123
+ --quiet, -q: no echoing to console
124
+ --help, -h: Show this message
125
+
126
+
127
+ ### TODO
128
+
129
+ - plot the data for simple visualizations
130
+
131
+ ## Contributing
132
+
133
+ 1. Fork it
134
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
135
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
136
+ 4. Push to the branch (`git push origin my-new-feature`)
137
+ 5. Create new Pull Request
138
+
139
+ ## License
140
+ MIT, please see the attached LICENSE.txt for more details.
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require "bundler/gem_tasks"
4
+ require 'rspec/core/rake_task'
5
+
6
+ Bundler::GemHelper.install_tasks
7
+
8
+ desc 'Default: run tests.'
9
+ task :default => [:spec]
10
+
11
+ task :spec do
12
+ RSpec::Core::RakeTask.new(:spec) do |t|
13
+ t.pattern = './spec/**/*_spec.rb'
14
+ end
15
+ end
data/bin/bpl ADDED
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ require "date"
6
+ require "bundler/setup"
7
+ require 'yajl'
8
+ require 'active_record'
9
+ require "lib_trollop"
10
+ require "bpl"
11
+ require "bpl/version"
12
+ require "models/blood_pressure"
13
+ require "create_blood"
14
+ require 'tablizer'
15
+ require "chronic"
16
+
17
+ # Simple Blood Pressure logger
18
+ #
19
+ # Florin, 2012.10.15
20
+
21
+
22
+ SUB_COMMANDS = %w(history series delete view init plot)
23
+
24
+ # db_config = YAML::load(File.open(File.join(File.dirname(__FILE__),
25
+ # '../config','database.yml'))) [ENV['ENV'] ? ENV['ENV'] : 'development']
26
+ # ActiveRecord::Base.establish_connection(db_config)
27
+
28
+ ActiveRecord::Base.establish_connection :adapter => "sqlite3",
29
+ :database => File.expand_path("~/.bp/blood.sqlite3")
30
+ opts = Trollop::options do
31
+ banner <<-BANNER
32
+ Simple blood pressure logger
33
+
34
+ Available commands: #{SUB_COMMANDS.join(", ")}
35
+
36
+ Examples:
37
+
38
+ $ bpl 145/81/67/L/87 -d 2012/12/10 -t 16:30 -m notes
39
+ $ bpl 136/60/66
40
+ $ bpl 136/60/66/r
41
+ $ bpl view --all
42
+ $ bpl 125/71/67/L/87 -d 2012/12/11 -m "some notes"
43
+ $ bpl 136/60/66/l/85
44
+ $ bpl 120/64/67/L/87 -D "2012/12/10 16:30"
45
+ $ bpl export -r -a
46
+ $ bpl export -d 2012/08/01 -f > my_bp.csv
47
+
48
+ The following options apply:
49
+ BANNER
50
+
51
+ now = Time.now
52
+
53
+ opt :date, "Date", :short => "-d", :default => now.strftime("%Y/%m/%d"), :type => String
54
+ opt :time, "Time", :short => "-t", :default => now.strftime("%H:%M:%S"), :type => String
55
+ opt :datetime, "Specify the date and the time, surrounded with quotes \";", :short => "-D", :type => String
56
+ opt :message, "Notes, comments", :short => "-m", :type => String
57
+ opt :force, "Force database initialization, all the data will be lost", :short => "-f"
58
+ opt :raw, "used to view the data without formatting", :short => "-r", :default => false
59
+ opt :page, "total number of records to view", :short => "-p", :default => 15, :type => Integer
60
+ opt :all, "export the entire dataset, all the records", :short => "-a", :default => false
61
+ opt :quiet, "no echoing to console", :short => "-q", :default => false
62
+
63
+ end
64
+
65
+ include Bpl
66
+ Bpl.options opts
67
+
68
+ # Check the command line parameters
69
+ cmd = ARGV.shift # get the subcommand
70
+
71
+ # optimize the two regex and build a clever one to rule them all :)
72
+ # use http://rubular.com, to validate
73
+ # hints: http://strugglingwithruby.blogspot.ca/2009/05/regular-expressions-in-ruby.html
74
+ case cmd
75
+ when /^(\d+)\/(\d+)\/(\d+)(?:\/([lr]))(?:\/(\d+))$/i, /^(\d+)\/(\d+)\/(\d+)(?:\/([lr]))?$/i
76
+ begin
77
+ Bpl.add($1, $2, $3, $4, $5)
78
+ rescue => e
79
+ puts "Exception in BPL: #{e} at #{e.backtrace.join("\n")}"
80
+ end
81
+
82
+ when "history", "view"
83
+ Bpl.view
84
+
85
+ when "export"
86
+ puts Bpl.export
87
+
88
+ when "delete", "remove"
89
+ Bpl.remove ARGV[0]
90
+
91
+ when "init"
92
+ puts "Initializing the blood database ..."
93
+ begin
94
+ CreateBlood.up
95
+ rescue => e
96
+ if opts[:force]
97
+ # ActiveRecord::Base.connection.drop_database db_config["database"] rescue nil
98
+ CreateBlood.down
99
+ CreateBlood.up
100
+ puts " - done."
101
+ else
102
+ puts "error: #{e.message}"
103
+ puts "use -f, to force the process and overwrite the data. All your previous data will be lost!"
104
+ end
105
+ end
106
+
107
+ else
108
+ Trollop::die "unknown command #{cmd.inspect}"
109
+ end
110
+
data/bpl.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/bpl/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "bpl"
6
+ gem.version = Bpl::VERSION
7
+ gem.authors = ["Florin T.PATRASCU"]
8
+ gem.email = ["florin.patrascu@gmail.com"]
9
+ gem.description = %q{BPL is a gem to help you track your blood pressure and view your records over time}
10
+ gem.summary = %q{Blood pressure logger}
11
+ gem.homepage = ""
12
+
13
+ gem.files = `git ls-files`.split($/)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.require_paths = ["lib"]
17
+
18
+ # Gem dependencies for run-time
19
+ gem.add_runtime_dependency "yajl-ruby"
20
+ gem.add_runtime_dependency 'sqlite3'
21
+ gem.add_runtime_dependency 'yajl-ruby'
22
+ gem.add_runtime_dependency 'chronic'
23
+ gem.add_runtime_dependency 'activerecord-sqlserver-adapter'
24
+ gem.add_runtime_dependency 'activerecord'
25
+ gem.add_runtime_dependency 'time_of_day'
26
+ gem.add_runtime_dependency 'tablizer'
27
+
28
+ # Gem dependencies for development
29
+ gem.add_development_dependency "rspec"
30
+
31
+ end
@@ -0,0 +1,3 @@
1
+ development:
2
+ adapter: sqlite3
3
+ database: db/blood.sqlite3
@@ -0,0 +1,3 @@
1
+ module Bpl
2
+ VERSION = "0.0.1"
3
+ end
data/lib/bpl.rb ADDED
@@ -0,0 +1,112 @@
1
+ require "bpl/version"
2
+ require 'yajl'
3
+ require "models/blood_pressure"
4
+ require "csv"
5
+
6
+ module Bpl
7
+ def options(opts={})
8
+ @opts=opts
9
+ end
10
+
11
+ def self.add(sys, dia, hr, arm='l', weight=nil)
12
+ @sys = sys.to_i
13
+ @dia = dia.to_i
14
+ @hr = hr.to_i
15
+ @arm = arm
16
+ @weight = weight
17
+
18
+ if weight.nil?
19
+ begin
20
+ @weight = BloodPressure.most_recent.weight
21
+ rescue => e
22
+ puts "Problems: #{e.message}"
23
+ puts "You should add your weight next time. It is: 0, now."
24
+ @weight = 0
25
+ end
26
+ end
27
+
28
+ if @opts[:datetime]
29
+ @created_at = Chronic.parse @opts[:datetime]
30
+ else
31
+ @created_at = Chronic.parse "#{@opts[:date]} #{@opts[:time]}"
32
+ end
33
+
34
+ bp = BloodPressure.new(:sys => @sys, :dia => @dia, :hr => @hr,
35
+ :arm => arm(@arm), :weight => @weight,
36
+ :created_at => @created_at,
37
+ :notes => @opts[:message])
38
+ bp.save
39
+ Bpl.echo unless @opts[:quiet]
40
+ bp
41
+ end
42
+
43
+ def self.remove(id)
44
+ begin
45
+ BloodPressure.find(id).delete unless id.nil?
46
+ puts "record: \##{id}, was removed."
47
+ rescue => e
48
+ puts e.message
49
+ end
50
+
51
+ end
52
+
53
+ def self.view(silent=false)
54
+ table = [['ID', 'DATE', 'SYS', 'DIA', 'HR', 'ARM', 'WEIGHT', 'NOTES']]
55
+ records = []
56
+
57
+ if @opts[:all]
58
+ records = BloodPressure.all_records
59
+ else
60
+ records = BloodPressure.records_since(Chronic.parse(@opts[:date]), @opts[:page])
61
+ end
62
+
63
+ if records.empty?
64
+ puts "the database has no records."
65
+ else
66
+ records.each do |r|
67
+ table << [r.id ,"#{r.date_collected} #{r.time_collected.time_of_day}", r.sys, r.dia, r.hr, r.arm, r.weight, r.notes.nil? ? '' : r.notes]
68
+ end
69
+
70
+ if @opts[:raw]
71
+ table.shift
72
+ puts table.inspect
73
+ else
74
+ puts Tablizer::Table.new(table, header: true) # can add align: 'ansi_rjust'
75
+ end unless silent
76
+ end
77
+
78
+ table
79
+ end
80
+
81
+ def self.echo
82
+ puts "[#{@created_at.inspect}] Sys: #{@sys}, DIA: #{@dia}, HR: #{@hr}, arm: #{arm(@arm)}, W: #{@weight}; Notes: #{@opts[:message]}"
83
+ end
84
+
85
+ def self.export
86
+ begin
87
+ table = Bpl.view true
88
+ csv_string = CSV.generate do |csv|
89
+ csv << table[0]
90
+ table.shift
91
+ table.each do |r|
92
+ csv << [r[0], "'#{r[1]}'", r[2], r[3], r[4], "'#{r[5]}'", r[6], "'#{r[7]}'"]
93
+ end
94
+ end
95
+
96
+ csv_string
97
+ rescue => e
98
+ # puts e.inspect
99
+ # puts e.backtrace
100
+ # or:
101
+ puts caller
102
+ puts "Error while exporting the data: #{e.message}"
103
+ ''
104
+ end
105
+ end
106
+
107
+ protected
108
+ def arm(which_one)
109
+ which_one =~ /[rR]/ ? 'RIGHT' : 'LEFT'
110
+ end
111
+
112
+ end
@@ -0,0 +1,27 @@
1
+ require 'active_record'
2
+
3
+ class CreateBlood < ActiveRecord::Migration
4
+ def self.up
5
+ create_table :blood_pressures do |t|
6
+ t.column :sys, :integer
7
+ t.column :dia, :integer
8
+ t.column :hr, :integer
9
+ t.column :arm, :string
10
+ t.column :weight, :integer
11
+ t.column :notes, :text
12
+ t.timestamps
13
+ end
14
+ add_index :blood_pressures, [:created_at]
15
+ end
16
+
17
+ def self.down
18
+ drop_table :blood_pressures
19
+ end
20
+ end
21
+
22
+ # other methods:
23
+ # def init_db
24
+ # ActiveRecord::Schema.define do
25
+ # .....
26
+ # end
27
+ # end