bpl 0.0.1

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