insulin 0.0.9

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
+ InstalledFiles
7
+ _yardoc
8
+ coverage
9
+ doc/
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ spec/reports
14
+ test/tmp
15
+ test/version_tmp
16
+ tmp
17
+ *swp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in insulin.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,52 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ insulin (0.0.7)
5
+ bson_ext
6
+ mongo
7
+ thor
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ aruba (0.4.11)
13
+ childprocess (>= 0.2.3)
14
+ cucumber (>= 1.1.1)
15
+ ffi (>= 1.0.11)
16
+ rspec (>= 2.7.0)
17
+ bson (1.6.4)
18
+ bson_ext (1.6.4)
19
+ bson (~> 1.6.4)
20
+ builder (3.0.0)
21
+ childprocess (0.3.3)
22
+ ffi (~> 1.0.6)
23
+ cucumber (1.2.1)
24
+ builder (>= 2.1.2)
25
+ diff-lcs (>= 1.1.3)
26
+ gherkin (~> 2.11.0)
27
+ json (>= 1.4.6)
28
+ diff-lcs (1.1.3)
29
+ ffi (1.0.11)
30
+ gherkin (2.11.1)
31
+ json (>= 1.4.6)
32
+ json (1.7.3)
33
+ mongo (1.6.4)
34
+ bson (~> 1.6.4)
35
+ rspec (2.10.0)
36
+ rspec-core (~> 2.10.0)
37
+ rspec-expectations (~> 2.10.0)
38
+ rspec-mocks (~> 2.10.0)
39
+ rspec-core (2.10.1)
40
+ rspec-expectations (2.10.0)
41
+ diff-lcs (~> 1.1.3)
42
+ rspec-mocks (2.10.1)
43
+ thor (0.15.3)
44
+
45
+ PLATFORMS
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ aruba
50
+ cucumber
51
+ insulin!
52
+ rspec (~> 2.6)
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Sam
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
+ NONINFRINGEMENT. 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,37 @@
1
+ What's this?
2
+ ============
3
+
4
+ Well I was recently diagnosed with Type-1 Diabetes. I've been collecting lots of data related to my condiiton using [OnTrack](https://play.google.com/store/apps/details?id=com.gexperts.ontrack), and wanted to do more interesting things with it. Hence this.
5
+
6
+ For now all it does is ingest a CSV file, parse it into some nice JSON, and stuff it into MongoDB.
7
+
8
+ Install
9
+ =======
10
+
11
+ gem install insulin
12
+
13
+ Also requires MongoDB. Instructions for installing Mongo on Ubuntu are [here](http://docs.mongodb.org/manual/tutorial/install-mongodb-on-debian-or-ubuntu-linux/).
14
+
15
+ Usage
16
+ =====
17
+
18
+ insulin ingest </path/to/on_track_export_file.csv>
19
+
20
+ This will take that file, turn it onto some nice JSON, and push into a number of collections in a MongoDB database called 'insulin'. You can see them with
21
+
22
+ $ mongo insulin
23
+ MongoDB shell version: 2.0.6
24
+ connecting to: insulin
25
+ > db.events.find({serial : 266})
26
+ { "_id" : ObjectId("4ff07b371508cc259c8a8f0c"), "serial" : 266, "timestamp" : ISODate("2012-06-28T09:21:05Z"), "tzoffset" : "+0100", "timezone" : "BST", "unixtime" : 1340875265, "day" : "thursday", "date" : "2012-06-28", "time" : "10:21:05 BST", "type" : "medication", "subtype" : "humalog", "tag" : "after breakfast", "value" : 4, "notes" : { "food" : [ "2 bacon", "2 toast" ], "note" : [ "test note" ] } }
27
+ >
28
+
29
+ Next steps
30
+ ==========
31
+
32
+ * Get it generating custom CSVs for Spreadsheeting
33
+ * Get it doing some analysis
34
+ * Give it a [meteor](http://meteor.com/) front-end (might require some help from [Chris](https://github.com/mrchrisadams)). Graphs, yo
35
+ * Possibly connect to [this API](http://platform.fatsecret.com/api/) to extract carb values from plain-text food descriptions (this may be a little ambitious, we'll see)
36
+
37
+
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env rake
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
4
+
5
+ require "bundler/gem_tasks"
6
+ require "insulin/version"
7
+
8
+ task :build do
9
+ system "gem build insulin.gemspec"
10
+ # system "mv insulin*gem pkg/"
11
+ end
12
+
13
+ task :release => :build do
14
+ system "gem push pkg/insulin-#{Insulin::VERSION}.gem"
15
+ end
16
+
17
+ task :rspec do
18
+ system "bundle exec rspec"
19
+ end
data/TODO.md ADDED
@@ -0,0 +1,2 @@
1
+ * Rake tasks to build, move to pkg/, publish
2
+ * Executable needs to handle config somehow (~/.insulinrc maybe)
data/bin/insulin ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ # needs to handle passing config. ~/.insulin or somrthing
3
+ require 'insulin'
4
+ require 'thor'
5
+
6
+ module Insulin
7
+ class I < Thor
8
+ map "-i" => :ingest
9
+
10
+ desc "ingest", "ingest OnTrack CSV export FILE"
11
+ def ingest file
12
+ csv = Insulin::OnTrackCsvFile.new file
13
+ mongo = Insulin::MongoHandle.new ({"database" => "insulin"})
14
+ csv.save_events mongo
15
+ end
16
+ end
17
+ end
18
+
19
+ Insulin::I.start
data/conf/insulin.yaml ADDED
@@ -0,0 +1,8 @@
1
+ mongo:
2
+ host: localhost
3
+ database: insulin
4
+
5
+ note_keys:
6
+ F: food
7
+ B: booze
8
+ N: note
@@ -0,0 +1,8 @@
1
+ mongo:
2
+ host: localhost
3
+ database: insulin_dev
4
+
5
+ note_keys:
6
+ F: food
7
+ B: booze
8
+ N: note
@@ -0,0 +1,18 @@
1
+ 287,"Jun 30, 2012 1:55:02 PM",Glucose,,After Lunch,3.6,"N: new pot of strips"
2
+ 286,"Jun 30, 2012 12:07:56 PM",Medication,Humalog,Lunch,6.0,"F: fry-up"
3
+ 281,"Jun 29, 2012 8:46:58 PM",Medication,Humalog,Dinner,6.0,"F: Japanese takeaway"
4
+ 278,"Jun 29, 2012 1:02:13 PM",Medication,Humalog,Lunch,6.0,"Fishfinger sandwich, salad"
5
+ 277,"Jun 29, 2012 1:02:04 PM",Glucose,,Lunch,5.6,""
6
+ 276,"Jun 29, 2012 10:00:54 AM",Weight,,Breakfast,58.0,""
7
+ 275,"Jun 29, 2012 8:45:13 AM",Medication,Humalog,Breakfast,4.0,"F:2 eggs, 2 toast"
8
+ 274,"Jun 29, 2012 8:37:47 AM",Glucose,,Breakfast,3.9,""
9
+ 273,"Jun 28, 2012 10:52:14 PM",Medication,Lantus,Bedtime,14.0,""
10
+ 272,"Jun 28, 2012 10:46:13 PM",Glucose,,Bedtime,5.7,""
11
+ 271,"Jun 28, 2012 7:30:50 PM",Medication,Humalog,Dinner,8.0,"F: turkey stir-fry"
12
+ 270,"Jun 28, 2012 7:06:35 PM",Glucose,,Dinner,5.7,""
13
+ 268,"Jun 28, 2012 1:52:47 PM",Medication,Humalog,Lunch,4.0,"F: haloumi salad"
14
+ 267,"Jun 28, 2012 1:35:50 PM",Glucose,,Lunch,4.3,""
15
+ 266,"Jun 28, 2012 10:21:05 AM",Medication,Humalog,Breakfast,4.0,"F:2 bacon, 2 toast
16
+ N:test note"
17
+ 265,"Jun 28, 2012 9:42:17 AM",Glucose,,Breakfast,6.1,""
18
+ 262,"Jun 27, 2012 11:58:07 PM",Exercise,Drumming,,120.0,""
data/insulin.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/insulin/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Sam"]
6
+ gem.email = ["sam@cruft.co"]
7
+ gem.description = %q{Doing stuff with my diabetes data}
8
+ gem.summary = %q{Doing stuff with my diabetes data}
9
+ gem.homepage = "http://pikesley.github.com/insulin/"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "insulin"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Insulin::VERSION
17
+
18
+ gem.executables << 'insulin'
19
+
20
+ gem.add_dependency "thor"
21
+ gem.add_dependency "mongo"
22
+ gem.add_dependency "bson_ext"
23
+
24
+ gem.add_development_dependency "rspec", "~> 2.6"
25
+ gem.add_development_dependency "cucumber"
26
+ gem.add_development_dependency "aruba"
27
+ end
@@ -0,0 +1,21 @@
1
+ module Insulin
2
+ # Author:: Sam (mailto:sam@cruft.co)
3
+ # License:: MIT
4
+
5
+ # This class is a simple wrapper around a YAML config file
6
+ class Config < Hash
7
+
8
+ # Open the file at 'path'. If no path is provided, go to default
9
+ def initialize path = nil
10
+ if not path
11
+ path = "conf/insulin.yaml"
12
+ end
13
+ self.update YAML.load File.open path
14
+ end
15
+
16
+ # Return a particular section (as a hash)
17
+ def get_section section
18
+ return self[section]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,40 @@
1
+ module Insulin
2
+ # Author:: Sam (mailto:sam@cruft.co)
3
+ # License:: MIT
4
+
5
+ # This class represents a single OnTrack event (BG, meds, etc)
6
+ class Event < Hash
7
+
8
+ # We expect to be passed a hash
9
+ def initialize h
10
+ self.update h
11
+ end
12
+
13
+ # Save the event to Mongo via mongo_handle
14
+ def save mongo_handle
15
+
16
+ # Save to each of these collections
17
+ clxns = [
18
+ "events",
19
+ self["type"],
20
+ self["subtype"],
21
+ self["date"]
22
+ ]
23
+
24
+ clxns.each do |c|
25
+ if c
26
+ mongo_handle.db.collection(c).update(
27
+ {
28
+ "serial" => self["serial"]
29
+ },
30
+ self,
31
+ {
32
+ # Upsert: update if exists, otherwise insert
33
+ :upsert => true
34
+ }
35
+ )
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,23 @@
1
+ require 'mongo'
2
+
3
+ module Insulin
4
+ # Author:: Sam (mailto:sam@cruft.co)
5
+ # License:: MIT
6
+
7
+ # This class is a simple wrapper around a MongoDB connection
8
+ class MongoHandle
9
+ attr_reader :db, :connection
10
+
11
+ # Set up the connection as described by 'conf'
12
+ def initialize conf
13
+ @conf = conf
14
+ @connection = Mongo::Connection.new
15
+ @db = @connection.db @conf["database"]
16
+ end
17
+
18
+ # Drop this database
19
+ def drop_db
20
+ @connection.drop_database @conf["database"]
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,61 @@
1
+ module Insulin
2
+ # Author:: Sam (mailto:sam@cruft.co)
3
+ # License:: MIT
4
+
5
+ # This class represents a CSV file as exported by OnTrack
6
+ class OnTrackCsvFile
7
+ attr_reader :file, :lines, :events
8
+
9
+ # Take the path to the CSV, open it, process it
10
+ def initialize csv_path
11
+ @csv_path = csv_path
12
+ @file = File.new @csv_path
13
+ self.read_lines
14
+ self.create_events
15
+ end
16
+
17
+ # Read the lines
18
+ def read_lines
19
+ @lines = []
20
+
21
+ # Where an event has more than one note, a 'line' will contain '\n's
22
+ l = ""
23
+ while line = @file.gets
24
+ # Stuff the line in to 'l'
25
+ l << line
26
+
27
+ # A '"' at the end of the line closes the event
28
+ if line[-2] == '"'
29
+
30
+ # Create a CsvLine, stripping the final '\n'
31
+ o = Insulin::OnTrackCsvLine.new l[0..-2]
32
+ @lines << o
33
+
34
+ # Reset the placeholder
35
+ l = ""
36
+ end
37
+ end
38
+
39
+ # Sort the list by the serial numbers (required for a future feature)
40
+ @lines.sort_by! {|o| o["serial"]}
41
+ end
42
+
43
+ # Turn the lines into Events
44
+ def create_events
45
+ @events = []
46
+ @lines.each do |l|
47
+ e = Insulin::Event.new l
48
+ @events << e
49
+ end
50
+ end
51
+
52
+ # Save the events to Mongo
53
+ def save_events mongo
54
+ print "saving %d events to mongo... " % @events.count
55
+ @events.each do |e|
56
+ e.save mongo
57
+ end
58
+ puts "done"
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,39 @@
1
+ module Insulin
2
+ # Author:: Sam (mailto:sam@cruft.co)
3
+ # License:: MIT
4
+
5
+ # This class represents a single OnTrack CSV line
6
+ class OnTrackCsvLine < Hash
7
+
8
+ # Parse the passed-in CSV line
9
+ def initialize line
10
+
11
+ # Split on commas
12
+ bits = line.split ","
13
+ self["serial"] = bits[0].to_i
14
+
15
+ # OnTrack embeds commas in the dates of its CSVs. Duh
16
+ self.update OnTrackDate.new "%s%s" % [
17
+ bits[1],
18
+ bits[2]
19
+ ]
20
+ self["type"] = bits[3].downcase
21
+ self["subtype"] = bits[4].downcase if not bits[4] == ""
22
+ self["tag"] = bits[5].downcase
23
+ self["value"] = bits[6].to_f
24
+
25
+ # Notes get complicated. Everything from field 7 to the end will be part
26
+ # of the notes
27
+ notes = bits[7..-1]
28
+
29
+ # We may have embedded commas
30
+ notes = notes.join ","
31
+
32
+ # Strip the trailing '\n'
33
+ notes = notes[1..-2]
34
+
35
+ # See Insulin::OnTrackNoteSet
36
+ self["notes"] = OnTrackNoteSet.new notes if not notes == ""
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,25 @@
1
+ require "time"
2
+
3
+ module Insulin
4
+ # Author:: Sam (mailto:sam@cruft.co)
5
+ # License:: MIT
6
+
7
+ # OnTrack uses really shitty date formats, including embedding a comma in the
8
+ # CSV export file. Christ on a crutch
9
+ class OnTrackDate < Hash
10
+
11
+ # Parse the strind 'd', looking for datetime information
12
+ def initialize d
13
+ t = Time.parse d
14
+
15
+ # We extract loads of stuff. Might be useful one day
16
+ self["timestamp"] = t
17
+ self["tzoffset"] = t.strftime "%z"
18
+ self["timezone"] = t.zone
19
+ self["unixtime"] = t.to_i
20
+ self["day"] = t.strftime("%A").downcase
21
+ self["date"] = t.strftime "%F"
22
+ self["time"] = t.strftime "%T #{self['timezone']}"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,46 @@
1
+ module Insulin
2
+ # Author:: Sam (mailto:sam@cruft.co)
3
+ # License:: MIT
4
+
5
+ # Class representing a single OnTrack note
6
+ class OnTrackNote
7
+
8
+ # Lookups. We will only deal with notes of these types
9
+ @@keys = {
10
+ "F" => 'food',
11
+ "B" => 'booze',
12
+ "N" => 'note'
13
+ }
14
+
15
+ attr_reader :type, :content
16
+
17
+ # Parse the raw note 'n'
18
+ def initialize n
19
+
20
+ # Key/value splits on ':'
21
+ bits = n.split ":"
22
+
23
+ # Remove leading/trailing cruft from key part
24
+ t = bits[0].strip
25
+
26
+ # We only deal with the keys we know about
27
+ if @@keys.keys.include? t
28
+
29
+ # Remove cruft from content, downcase
30
+ @content = bits[1].strip.downcase
31
+
32
+ # These keys mean we turn the content into a list
33
+ if ["F", "B"].include? t
34
+ a = []
35
+ @content.split(",").each do |v|
36
+ a << v.strip
37
+ end
38
+ @content = a
39
+ end
40
+
41
+ # Set key from lookup list
42
+ @type = @@keys[t]
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,45 @@
1
+ module Insulin
2
+ # Author:: Sam (mailto:sam@cruft.co)
3
+ # License:: MIT
4
+
5
+ # This class represents a set of notes
6
+ class OnTrackNoteSet < Hash
7
+
8
+ # Parse the string 's'
9
+ def initialize s
10
+
11
+ # Notes separated by newlines
12
+ l = s.split"\n"
13
+
14
+ # For each line
15
+ l.each do |n|
16
+
17
+ # Make a note
18
+ x = OnTrackNote.new n
19
+
20
+ # This field will only exists for notes of a valid type
21
+ if x.type
22
+
23
+ # If we don't yet have this key
24
+ if not self[x.type]
25
+
26
+ # If the content is a list
27
+ if x.content.class.name == "Array"
28
+
29
+ # This becomes our value
30
+ self[x.type] = x.content
31
+ else
32
+
33
+ # Otherwise make it onto a list
34
+ self[x.type] = [x.content]
35
+ end
36
+ else
37
+
38
+ # This key exists, so we append this value
39
+ self[x.type] << x.content
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,5 @@
1
+ module Insulin
2
+
3
+ # Current version
4
+ VERSION = "0.0.9"
5
+ end
data/lib/insulin.rb ADDED
@@ -0,0 +1,17 @@
1
+ require "insulin/version"
2
+ require "insulin/config"
3
+ require "insulin/mongo_handle"
4
+ require "insulin/on_track_date"
5
+ require "insulin/on_track_note"
6
+ require "insulin/on_track_note_set"
7
+ require "insulin/on_track_csv_line"
8
+ require "insulin/on_track_csv_file"
9
+ require "insulin/event"
10
+ # Author:: Sam (mailto:sam@cruft.co)
11
+ # License:: MIT
12
+
13
+ # OnTrack[https://play.google.com/store/apps/details?id=com.gexperts.ontrack&hl=en]
14
+ # can export its data as a CSV. Insulin takes this data, parses it into
15
+ # (possibly) useful formats, and stuffs it into MongoDB
16
+ module Insulin
17
+ end
@@ -0,0 +1,12 @@
1
+ require 'insulin'
2
+
3
+ describe Insulin::Config do
4
+ config = Insulin::Config.new
5
+
6
+ it "should return the correct section" do
7
+ config["mongo"].should == {
8
+ "host"=>"localhost",
9
+ "database"=>"insulin"
10
+ }
11
+ end
12
+ end
@@ -0,0 +1,48 @@
1
+ require 'insulin'
2
+
3
+ describe Insulin::Event do
4
+ event = Insulin::Event.new Insulin::OnTrackCsvLine.new %q{266,"Jun 28, 2012 10:21:05 AM",Medication,Humalog,After Breakfast,4.0,"F:2 bacon, 2 toast
5
+ N:test note
6
+ X:fail note
7
+ N:other note"}
8
+
9
+ it "should have the correct type" do
10
+ event["type"].should == "medication"
11
+ end
12
+
13
+ conf = Insulin::Config.new 'conf/insulin_dev.yaml'
14
+ mconf = conf.get_section "mongo"
15
+ mongo = Insulin::MongoHandle.new mconf
16
+
17
+ event.save mongo
18
+ clxns = [
19
+ "events",
20
+ event["type"],
21
+ event["subtype"],
22
+ event["date"]
23
+ ]
24
+
25
+ clxns.each do |c|
26
+ item = mongo.db.collection(c).find_one(
27
+ {"serial" => 266}
28
+ )
29
+
30
+ it "should save to the '%s' collection" % c do
31
+ item.should_not == nil
32
+ end
33
+
34
+ it "saved event should have correct type" do
35
+ item["type"].should == "medication"
36
+ end
37
+
38
+ it "saved event should have correct tag" do
39
+ item["tag"].should == "after breakfast"
40
+ end
41
+
42
+ it "saved event should have correct value" do
43
+ item["value"].should == 4.0
44
+ end
45
+ end
46
+
47
+ mongo.drop_db
48
+ end
@@ -0,0 +1,33 @@
1
+ require 'insulin'
2
+
3
+ describe Insulin::MongoHandle do
4
+ conf = Insulin::Config.new 'conf/insulin_dev.yaml'
5
+ mconf = conf.get_section "mongo"
6
+
7
+ handle = Insulin::MongoHandle.new mconf
8
+
9
+ it "should make a connection to mongo" do
10
+ handle.connection.database_names.size.should >= 1
11
+ end
12
+
13
+ it "should have a database" do
14
+ handle.db.name.should == mconf["database"]
15
+ end
16
+
17
+ it "should drop the database" do
18
+ handle.drop_db
19
+ handle.connection.database_names.include?(mconf["database"]).should_not ==
20
+ true
21
+ end
22
+
23
+
24
+ it "should respond correctly to being passed a hash" do
25
+ prod_handle = Insulin::MongoHandle.new(
26
+ {
27
+ "database" => "prawn"
28
+ }
29
+ )
30
+ prod_handle.db.name.should == "prawn"
31
+ prod_handle.drop_db
32
+ end
33
+ end
@@ -0,0 +1,60 @@
1
+ require 'insulin'
2
+
3
+ describe Insulin::OnTrackCsvFile do
4
+ csv_file = Insulin::OnTrackCsvFile.new 'files/on_track.csv'
5
+
6
+ it "should open the file" do
7
+ csv_file.file.path.should == 'files/on_track.csv'
8
+ end
9
+
10
+ it "should create csv lines" do
11
+ csv_file.lines[0].class.name.should == "Insulin::OnTrackCsvLine"
12
+ end
13
+
14
+ it "line with serial 266 should have proper noteset" do
15
+ csv_file.lines.each do |c|
16
+ if c["serial"] == 266
17
+ c["notes"].should == {
18
+ "food"=>[
19
+ "2 bacon",
20
+ "2 toast"
21
+ ],
22
+ "note"=>[
23
+ "test note"
24
+ ]
25
+ }
26
+ end
27
+ end
28
+ end
29
+
30
+ it "lines should be sorted by serial" do
31
+ error = false
32
+ last_serial = 0
33
+ csv_file.lines.each do |l|
34
+ if not l["serial"] > last_serial
35
+ error = true
36
+ end
37
+ last_serial = l["serial"]
38
+ end
39
+ error.should_not == true
40
+ end
41
+
42
+ it "should create events" do
43
+ csv_file.events[0].class.name.should == "Insulin::Event"
44
+ end
45
+
46
+ before :all do
47
+ config = Insulin::Config.new 'conf/insulin_dev.yaml'
48
+ mconf = config.get_section "mongo"
49
+ @mongo = Insulin::MongoHandle.new mconf
50
+ end
51
+
52
+ it "should save events" do
53
+ csv_file.save_events @mongo
54
+ @mongo.db.collection("events").count.should >= 17
55
+ end
56
+
57
+ after :all do
58
+ @mongo.drop_db
59
+ end
60
+ end
@@ -0,0 +1,67 @@
1
+ require 'insulin'
2
+
3
+ describe Insulin::OnTrackCsvLine do
4
+ csv = Insulin::OnTrackCsvLine.new %q{199,"Jun 22, 2012 8:01:39 AM",Glucose,,Breakfast,5.7,""}
5
+
6
+ it "should have the correct serial" do
7
+ csv["serial"].should == 199
8
+ end
9
+
10
+ it "should have the correct time" do
11
+ csv["time"].should == "08:01:39 BST"
12
+ end
13
+
14
+ it "should have the correct date" do
15
+ csv["date"].should == "2012-06-22"
16
+ end
17
+
18
+ it "should have the correct type" do
19
+ csv["type"].should == "glucose"
20
+ end
21
+
22
+ it "should have a null subtype" do
23
+ csv["subtype"].should == nil
24
+ end
25
+
26
+ it "should have the correct tag" do
27
+ csv["tag"].should == "breakfast"
28
+ end
29
+
30
+ it "should have the correct value" do
31
+ csv["value"].should == 5.7
32
+ end
33
+
34
+ it "should have the correct notes" do
35
+ csv["notes"].should == nil
36
+ end
37
+
38
+ csv_with_note = Insulin::OnTrackCsvLine.new %q{266,"Jun 28, 2012 10:21:05 AM",Medication,Humalog,After Breakfast,4.0,"F:2 bacon, 2 toast
39
+ N:test note
40
+ X:fail note
41
+ N:other note"}
42
+
43
+ it "should have the correct subtype" do
44
+ csv_with_note["subtype"].should == "humalog"
45
+ end
46
+
47
+ it "should have the correct day" do
48
+ csv_with_note["day"].should == "thursday"
49
+ end
50
+
51
+ it "should have the correct unixtime" do
52
+ csv_with_note["unixtime"].should == 1340875265
53
+ end
54
+
55
+ it "should have the correct notes" do
56
+ csv_with_note["notes"].should == {
57
+ "food" => [
58
+ "2 bacon",
59
+ "2 toast"
60
+ ],
61
+ "note" => [
62
+ "test note",
63
+ "other note"
64
+ ]
65
+ }
66
+ end
67
+ end
@@ -0,0 +1,31 @@
1
+ require 'insulin'
2
+
3
+ describe Insulin::OnTrackDate do
4
+ otd = Insulin::OnTrackDate.new "Jun 22 2012 9:00:12 AM"
5
+
6
+ it "should have the correct timestamp" do
7
+ otd["timestamp"].to_s.should == "2012-06-22 09:00:12 +0100"
8
+ end
9
+
10
+ it "should have the correct time" do
11
+ otd["time"].should == "09:00:12 BST"
12
+ end
13
+
14
+ it "should have the correct date" do
15
+ otd["date"].should == "2012-06-22"
16
+ end
17
+
18
+ it "should have the correct day" do
19
+ otd["day"].should == "friday"
20
+ end
21
+
22
+ otd_gmt = Insulin::OnTrackDate.new "Jan 22 2012 9:00:12 PM"
23
+
24
+ it "should have the correct timestamp" do
25
+ otd_gmt["timestamp"].to_s.should == "2012-01-22 21:00:12 +0000"
26
+ end
27
+
28
+ it "should have the correct time and TZ" do
29
+ otd_gmt["time"].should == "21:00:12 GMT"
30
+ end
31
+ end
@@ -0,0 +1,47 @@
1
+ require 'insulin'
2
+
3
+ describe Insulin::OnTrackNoteSet do
4
+ simple_note_set = Insulin::OnTrackNoteSet.new "F: turkey breast, salad"
5
+
6
+ it "should have the correct notes" do
7
+ simple_note_set.should == {
8
+ "food" => [
9
+ "turkey breast",
10
+ "salad"
11
+ ]
12
+ }
13
+ end
14
+
15
+ multiple_note_set = Insulin::OnTrackNoteSet.new "F: turkey breast, salad
16
+ N:After wine. No overnight hypo.
17
+ N:some other note
18
+ B: glass of wine"
19
+
20
+ it "should have the correct notes" do
21
+ multiple_note_set.should == {
22
+ "food" => [
23
+ "turkey breast",
24
+ "salad"
25
+ ],
26
+ "note" => [
27
+ "after wine. no overnight hypo.",
28
+ "some other note"
29
+ ],
30
+ "booze" => [
31
+ "glass of wine"
32
+ ]
33
+ }
34
+ end
35
+
36
+ failing_note_set = Insulin::OnTrackNoteSet.new "F: turkey breast, salad
37
+ X:This should fail"
38
+
39
+ it "should have the correct notes" do
40
+ failing_note_set.should == {
41
+ "food" => [
42
+ "turkey breast",
43
+ "salad"
44
+ ]
45
+ }
46
+ end
47
+ end
@@ -0,0 +1,24 @@
1
+ require 'insulin'
2
+
3
+ describe Insulin::OnTrackNote do
4
+ note = Insulin::OnTrackNote.new "N:After wine. No overnight hypo."
5
+
6
+ it "should have the correct note" do
7
+ note.type.should == "note"
8
+ note.content.should == "after wine. no overnight hypo."
9
+ end
10
+
11
+ list_note = Insulin::OnTrackNote.new "F: turkey breast, salad"
12
+
13
+ it "should have the correct list-type note" do
14
+ list_note.type.should == "food"
15
+ list_note.content.should == ["turkey breast", "salad"]
16
+ end
17
+
18
+ fail_note = Insulin::OnTrackNote.new "X: this one should fail"
19
+
20
+ it "should handle the fail note correctly" do
21
+ fail_note.type.should == nil
22
+ fail_note.content.should == nil
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,181 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: insulin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.9
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sam
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
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: mongo
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: bson_ext
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
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
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '2.6'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '2.6'
78
+ - !ruby/object:Gem::Dependency
79
+ name: cucumber
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: aruba
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: Doing stuff with my diabetes data
111
+ email:
112
+ - sam@cruft.co
113
+ executables:
114
+ - insulin
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - .rspec
120
+ - Gemfile
121
+ - Gemfile.lock
122
+ - LICENSE
123
+ - README.md
124
+ - Rakefile
125
+ - TODO.md
126
+ - bin/insulin
127
+ - conf/insulin.yaml
128
+ - conf/insulin_dev.yaml
129
+ - files/on_track.csv
130
+ - insulin.gemspec
131
+ - lib/insulin.rb
132
+ - lib/insulin/config.rb
133
+ - lib/insulin/event.rb
134
+ - lib/insulin/mongo_handle.rb
135
+ - lib/insulin/on_track_csv_file.rb
136
+ - lib/insulin/on_track_csv_line.rb
137
+ - lib/insulin/on_track_date.rb
138
+ - lib/insulin/on_track_note.rb
139
+ - lib/insulin/on_track_note_set.rb
140
+ - lib/insulin/version.rb
141
+ - spec/insulin_config_spec.rb
142
+ - spec/insulin_event_spec.rb
143
+ - spec/insulin_mongo_handle_spec.rb
144
+ - spec/insulin_on_track_csv_file_spec.rb
145
+ - spec/insulin_on_track_csv_line_spec.rb
146
+ - spec/insulin_on_track_date_spec.rb
147
+ - spec/insulin_on_track_note_set_spec.rb
148
+ - spec/insulin_on_track_note_spec.rb
149
+ homepage: http://pikesley.github.com/insulin/
150
+ licenses: []
151
+ post_install_message:
152
+ rdoc_options: []
153
+ require_paths:
154
+ - lib
155
+ required_ruby_version: !ruby/object:Gem::Requirement
156
+ none: false
157
+ requirements:
158
+ - - ! '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ none: false
163
+ requirements:
164
+ - - ! '>='
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 1.8.24
170
+ signing_key:
171
+ specification_version: 3
172
+ summary: Doing stuff with my diabetes data
173
+ test_files:
174
+ - spec/insulin_config_spec.rb
175
+ - spec/insulin_event_spec.rb
176
+ - spec/insulin_mongo_handle_spec.rb
177
+ - spec/insulin_on_track_csv_file_spec.rb
178
+ - spec/insulin_on_track_csv_line_spec.rb
179
+ - spec/insulin_on_track_date_spec.rb
180
+ - spec/insulin_on_track_note_set_spec.rb
181
+ - spec/insulin_on_track_note_spec.rb