my_timeline-health_graph 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.markdown +50 -0
- data/app/assets/images/my_timeline/icons/cycle.png +0 -0
- data/app/assets/images/my_timeline/icons/elliptical.png +0 -0
- data/app/assets/images/my_timeline/icons/run.png +0 -0
- data/app/controllers/my_timeline/health_graph_controller.rb +27 -0
- data/app/models/my_timeline/health_graph/cardio_activity.rb +10 -0
- data/app/scrapers/my_timeline/health_graph/cardio_activity_builder.rb +109 -0
- data/app/scrapers/my_timeline/health_graph/health_graph_scraper.rb +69 -0
- data/app/views/my_timeline/health_graph/_control_panel.html.erb +6 -0
- data/config/routes.rb +4 -0
- data/db/migrate/20131103010356_create_health_graph_cardio_activities.rb +20 -0
- data/lib/my_timeline-health_graph.rb +15 -0
- data/lib/my_timeline/health_graph/engine.rb +26 -0
- data/lib/my_timeline/health_graph/railties/health_graph_tasks.rake +13 -0
- data/lib/my_timeline/health_graph/version.rb +5 -0
- data/my_timeline-health_graph.gemspec +20 -0
- metadata +26 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37ff56377034a897b8728a5cc91d58dd272e9b9d
|
4
|
+
data.tar.gz: 387f07977520261141793be61c372de4533e2dc3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1688ff9d3bd3e4bbdba42339a1d5f7f2cce42c75eb1b8287c9f0f2ca96633e19a2140767dfbe5d992fdcfa87843ea2199e27908fee0e4b6405e2a9aca725fae7
|
7
|
+
data.tar.gz: fcff68d995e1e382750422984989a2d6772c974ae4c2d9720f66bff3c22a96c5461846b889f1f53943b652e4498745faaba1fd05218ee8cef369cee5e3bde77a
|
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 Justin Aiken
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
[![Code Climate](https://codeclimate.com/github/JustinAiken/my_timeline-health_graph.png)](https://codeclimate.com/github/JustinAiken/my_timeline-health_graph)
|
2
|
+
|
3
|
+
# My Timeline - Health Graph Plugin
|
4
|
+
#### Health Graph Integration with My Timeline
|
5
|
+
|
6
|
+
### Requirements:
|
7
|
+
- [My Timeline](https://github.com/JustinAiken/my_timeline)
|
8
|
+
- HealthGraph Client API Key/Secret - Get one [here](http://developer.runkeeper.com/healthgraph/registration-authorization)
|
9
|
+
|
10
|
+
### Usage:
|
11
|
+
|
12
|
+
1. Add this gem to your Gemfile:
|
13
|
+
`gem 'my_timeline-health_graph'` and `bundle install`
|
14
|
+
2. Add jupp0r's health_graph library to your Gemfile:
|
15
|
+
`gem 'health_graph', git: 'git://github.com/jupp0r/health_graph.git'`
|
16
|
+
3. Edit `config/initializers/my_timeline.rb` to include your API keys:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
MyTimeline.setup do |config|
|
20
|
+
...
|
21
|
+
end
|
22
|
+
|
23
|
+
MyTimeline::HealthGraph.setup do |config|
|
24
|
+
config.client_id = "lotsofrandomhexchars"
|
25
|
+
config.client_secret = "lotsofrandomhexchars"
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
## Credits
|
30
|
+
|
31
|
+
Original author: [Justin Aiken](https://github.com/JustinAiken)
|
32
|
+
|
33
|
+
## Links
|
34
|
+
|
35
|
+
* [Source](https://github.com/JustinAiken/my_timeline-health_graph)
|
36
|
+
* [Bug Tracker](https://github.com/JustinAiken/my_timeline-health_graph/issues)
|
37
|
+
* [Rubygem](https://rubygems.org/gems/my_timeline-health_graph)
|
38
|
+
|
39
|
+
## Note on Patches/Pull Requests
|
40
|
+
|
41
|
+
* Fork the project.
|
42
|
+
* Make your feature addition or bug fix.
|
43
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
44
|
+
* Commit, do not mess with rakefile, version, or history.
|
45
|
+
* If you want to have your own version, that is fine but bump version in a commit by itself so I can ignore when I pull
|
46
|
+
* Send me a pull request. Bonus points for topic branches.
|
47
|
+
|
48
|
+
## Copyright
|
49
|
+
|
50
|
+
Copyright (c) 2013 Justin Aiken Inc. MIT license (see LICENSE for details).
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MyTimeline
|
2
|
+
class HealthGraphController < MyTimeline::ApplicationController
|
3
|
+
|
4
|
+
def new
|
5
|
+
::HealthGraph.configure do |config|
|
6
|
+
config.client_id = MyTimeline::HealthGraph.client_id
|
7
|
+
config.client_secret = MyTimeline::HealthGraph.client_secret
|
8
|
+
config.authorization_redirect_url = "#{root_url}/health_graph/code"
|
9
|
+
end
|
10
|
+
|
11
|
+
redirect_to ::HealthGraph.authorize_url
|
12
|
+
end
|
13
|
+
|
14
|
+
def show
|
15
|
+
access_token = ::HealthGraph.access_token(params[:code])
|
16
|
+
|
17
|
+
@user.settings(:health_graph).user_token = access_token
|
18
|
+
@user.save!
|
19
|
+
redirect_to control_panel_path, notice: "Connection Successful!"
|
20
|
+
end
|
21
|
+
|
22
|
+
def scrape
|
23
|
+
scrape_status = MyTimeline::HealthGraph::HealthGraphScraper.new(@user).scrape
|
24
|
+
redirect_to :back, notice: scrape_status
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module MyTimeline
|
2
|
+
module HealthGraph
|
3
|
+
class CardioActivityBuilder
|
4
|
+
|
5
|
+
attr_reader :user, :activity, :summary, :health_graph_user
|
6
|
+
|
7
|
+
def initialize(user, health_graph_user)
|
8
|
+
@health_graph_user = health_graph_user
|
9
|
+
@user = user
|
10
|
+
end
|
11
|
+
|
12
|
+
def build_activity(activity)
|
13
|
+
@activity = activity
|
14
|
+
return false if already_exists_in_db?
|
15
|
+
|
16
|
+
@summary = activity.summary
|
17
|
+
|
18
|
+
event = MyTimeline::Event.create(
|
19
|
+
happened_on: activity.start_time,
|
20
|
+
original_id: activity.uri[19..26],
|
21
|
+
external_link: "#{profile_base_url}/activity/#{activity.uri[19..26]}",
|
22
|
+
icon_name: ICONS[activity.type],
|
23
|
+
importance: 5,
|
24
|
+
public: true,
|
25
|
+
description: build_description,
|
26
|
+
)
|
27
|
+
|
28
|
+
new_activity = MyTimeline::HealthGraph::CardioActivity.create(
|
29
|
+
happened_on: activity.start_time,
|
30
|
+
duration: activity.duration,
|
31
|
+
meters: activity.total_distance,
|
32
|
+
uri: activity.uri,
|
33
|
+
calories: summary.total_calories,
|
34
|
+
climb: summary.climb,
|
35
|
+
equipment: summary.equipment,
|
36
|
+
activity_type: activity.type,
|
37
|
+
notes: summary.notes
|
38
|
+
)
|
39
|
+
|
40
|
+
event.linkable = new_activity
|
41
|
+
event.user = user if MyTimeline.user_class
|
42
|
+
event.save
|
43
|
+
|
44
|
+
new_activity.event = event
|
45
|
+
new_activity.save
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def already_exists_in_db?
|
51
|
+
MyTimeline::HealthGraph::CardioActivity.find_by_uri(@activity.uri.to_s).present?
|
52
|
+
end
|
53
|
+
|
54
|
+
def build_description
|
55
|
+
"".tap do |s|
|
56
|
+
s << ACTIVITY_TEXT[activity.type]
|
57
|
+
s << equip_string
|
58
|
+
s << to_miles(activity.total_distance)
|
59
|
+
s << " in #{to_time(activity.duration)}"
|
60
|
+
s << calories_text
|
61
|
+
s << notes
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def calories_text
|
66
|
+
summary.total_calories ? " and burned #{summary.total_calories.to_i} calories" : ""
|
67
|
+
end
|
68
|
+
|
69
|
+
def notes
|
70
|
+
summary.notes ? " (#{summary.notes})" : ""
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_miles(num)
|
74
|
+
formatted = '%.2f' % (num * 0.000621371192)
|
75
|
+
"#{formatted} miles"
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_time(num)
|
79
|
+
seconds = num % 60
|
80
|
+
minutes = (num / 60) % 60
|
81
|
+
hours = num / (60 * 60)
|
82
|
+
|
83
|
+
format "%02d:%02d:%02d", hours, minutes, seconds
|
84
|
+
end
|
85
|
+
|
86
|
+
ICONS = {
|
87
|
+
"Running" => "run.png",
|
88
|
+
"Cycling" => "cycle.png",
|
89
|
+
"Walking" => "walk.png",
|
90
|
+
"Elliptical" => "elliptical.png"
|
91
|
+
}
|
92
|
+
|
93
|
+
ACTIVITY_TEXT = {
|
94
|
+
"Running" => "Ran ",
|
95
|
+
"Cycling" => "Cycled ",
|
96
|
+
"Walking" => "Strolled ",
|
97
|
+
"Elliptical" => "Ran "
|
98
|
+
}
|
99
|
+
|
100
|
+
def equip_string
|
101
|
+
summary.equipment == "None" ? "" : "(on a #{summary.equipment.downcase}) "
|
102
|
+
end
|
103
|
+
|
104
|
+
def profile_base_url
|
105
|
+
health_graph_user.profile.profile
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative 'cardio_activity_builder'
|
2
|
+
|
3
|
+
module MyTimeline
|
4
|
+
module HealthGraph
|
5
|
+
class HealthGraphScraper
|
6
|
+
|
7
|
+
attr_accessor :user, :activities, :health_graph_user, :count
|
8
|
+
|
9
|
+
def initialize(user)
|
10
|
+
::HealthGraph.configure do |config|
|
11
|
+
config.client_id = '0e5a8f038da04633bd539ec664037ea9' #user.settings(:health_graph).client_id
|
12
|
+
config.client_secret = '838ad884eb644ebab93d09f302196244' #user.settings(:health_graph).client_secret
|
13
|
+
config.authorization_redirect_url = ""
|
14
|
+
end
|
15
|
+
|
16
|
+
@user = user
|
17
|
+
|
18
|
+
@health_graph_user = ::HealthGraph::User.new(user.settings(:health_graph).user_token)
|
19
|
+
end
|
20
|
+
|
21
|
+
def scrape(type = :cardio_activities)
|
22
|
+
@count = 0
|
23
|
+
@activities = []
|
24
|
+
|
25
|
+
case type
|
26
|
+
when :cardio_activities then scrape_runs
|
27
|
+
when :strength_activities then scrape_strength
|
28
|
+
end
|
29
|
+
|
30
|
+
"Added #{count} #{type}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def scrape_runs
|
34
|
+
get_runs_from_rk
|
35
|
+
activities.each do |activity|
|
36
|
+
@count += 1 if cardio_builder.build_activity(activity)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def scrape_strength
|
41
|
+
#get_strongs_from_rk
|
42
|
+
# activities.each do |activity|
|
43
|
+
# @count += 1 if strength_builder.build_activity(activity)
|
44
|
+
# end
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_runs_from_rk
|
48
|
+
@feed = health_graph_user.fitness_activities
|
49
|
+
orig_feed = @feed.dup
|
50
|
+
|
51
|
+
#Loop through the pages to get all activies
|
52
|
+
while @feed
|
53
|
+
@activities += @feed.items
|
54
|
+
@feed = @feed.next_page
|
55
|
+
end
|
56
|
+
|
57
|
+
@activities = orig_feed.send :unpack_items, @activities.reverse
|
58
|
+
end
|
59
|
+
|
60
|
+
def cardio_builder
|
61
|
+
@cardio_builder ||= MyTimeline::HealthGraph::CardioActivityBuilder.new(user, health_graph_user)
|
62
|
+
end
|
63
|
+
|
64
|
+
def strength_builder
|
65
|
+
#@strength_builder ||= MyTimeline::HealthGraphScraper::StrengthActivityBuilder.new(user)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<h3> Health Graph Settings </h3>
|
2
|
+
<% if @user.settings(:health_graph).user_token %>
|
3
|
+
<%= button_to "Scrape runs!", health_graph_scrape_path, method: :get, class: "btn btn-primary" %>
|
4
|
+
<% else %>
|
5
|
+
<%= button_to "Connect to Runkeeper", new_health_graph_path, method: :get, class: "btn btn-primary" %>
|
6
|
+
<% end %>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
class CreateHealthGraphCardioActivities < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :my_timeline_health_graph_cardio_activities do |t|
|
4
|
+
t.datetime :happened_on
|
5
|
+
t.float :meters
|
6
|
+
t.float :duration
|
7
|
+
t.integer :calories
|
8
|
+
t.string :routefile
|
9
|
+
t.string :uri
|
10
|
+
t.text :notes
|
11
|
+
t.string :equipment
|
12
|
+
t.float :climb
|
13
|
+
t.string :activity_type
|
14
|
+
|
15
|
+
t.references :event
|
16
|
+
|
17
|
+
t.timestamps
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module MyTimeline
|
2
|
+
module HealthGraph
|
3
|
+
class Engine < ::Rails::Engine
|
4
|
+
isolate_namespace MyTimeline::HealthGraph
|
5
|
+
|
6
|
+
config.autoload_paths << File.expand_path("../../../app/classes/**", __FILE__)
|
7
|
+
config.autoload_paths << File.expand_path("../../../app/scrapers/**", __FILE__)
|
8
|
+
|
9
|
+
config.generators do |g|
|
10
|
+
g.test_framework :rspec, fixture: false
|
11
|
+
g.fixture_replacement :factory_girl, dir: 'spec/factories'
|
12
|
+
g.assets false
|
13
|
+
g.helper false
|
14
|
+
end
|
15
|
+
|
16
|
+
config.after_initialize do |app|
|
17
|
+
MyTimeline.config_object.key :health_graph, defaults: {user_token: nil}
|
18
|
+
MyTimeline.register_plugin :health_graph
|
19
|
+
end
|
20
|
+
|
21
|
+
rake_tasks do
|
22
|
+
load File::expand_path "railties/health_graph_tasks.rake", File.dirname(__FILE__)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
namespace "my_timeline-health_graph" do
|
2
|
+
namespace :install do
|
3
|
+
desc "Copy migrations from my_timeline-health_graph to application"
|
4
|
+
task :migrations do
|
5
|
+
timestamp = Time.now.strftime("%Y%m%d%H%M%S")
|
6
|
+
|
7
|
+
source = File.expand_path "../../../../db/migrate/20131103010356_create_health_graph_cardio_activities.rb", File.dirname(__FILE__)
|
8
|
+
dest = File.expand_path "db/migrate/#{timestamp}_create_health_graph_cardio_activities.my_timeline.rb"
|
9
|
+
puts "cp #{source} #{dest}"
|
10
|
+
`cp #{source} #{dest}`
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
require "my_timeline/health_graph/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "my_timeline-health_graph"
|
7
|
+
s.version = MyTimeline::HealthGraph::VERSION
|
8
|
+
s.authors = ["Justin Aiken"]
|
9
|
+
s.email = ["60tonangel@gmail.com"]
|
10
|
+
s.homepage = "https://www.github.com/JustinAiken/my_timeline-health_graph"
|
11
|
+
s.summary = "HealthGraph plugin for MyTimeline"
|
12
|
+
s.description = "HealthGraph plugin for MyTimeline"
|
13
|
+
|
14
|
+
s.license = 'MIT'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
|
18
|
+
s.add_runtime_dependency "my_timeline", '>= 0.0.4'
|
19
|
+
s.add_runtime_dependency "health_graph"
|
20
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: my_timeline-health_graph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Aiken
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: my_timeline
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.0.4
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 0.0.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: health_graph
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,7 +44,27 @@ email:
|
|
44
44
|
executables: []
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
|
-
files:
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- CHANGELOG.md
|
50
|
+
- Gemfile
|
51
|
+
- LICENSE
|
52
|
+
- README.markdown
|
53
|
+
- app/assets/images/my_timeline/icons/cycle.png
|
54
|
+
- app/assets/images/my_timeline/icons/elliptical.png
|
55
|
+
- app/assets/images/my_timeline/icons/run.png
|
56
|
+
- app/controllers/my_timeline/health_graph_controller.rb
|
57
|
+
- app/models/my_timeline/health_graph/cardio_activity.rb
|
58
|
+
- app/scrapers/my_timeline/health_graph/cardio_activity_builder.rb
|
59
|
+
- app/scrapers/my_timeline/health_graph/health_graph_scraper.rb
|
60
|
+
- app/views/my_timeline/health_graph/_control_panel.html.erb
|
61
|
+
- config/routes.rb
|
62
|
+
- db/migrate/20131103010356_create_health_graph_cardio_activities.rb
|
63
|
+
- lib/my_timeline-health_graph.rb
|
64
|
+
- lib/my_timeline/health_graph/engine.rb
|
65
|
+
- lib/my_timeline/health_graph/railties/health_graph_tasks.rake
|
66
|
+
- lib/my_timeline/health_graph/version.rb
|
67
|
+
- my_timeline-health_graph.gemspec
|
48
68
|
homepage: https://www.github.com/JustinAiken/my_timeline-health_graph
|
49
69
|
licenses:
|
50
70
|
- MIT
|
@@ -65,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
85
|
version: '0'
|
66
86
|
requirements: []
|
67
87
|
rubyforge_project:
|
68
|
-
rubygems_version: 2.0.
|
88
|
+
rubygems_version: 2.0.3
|
69
89
|
signing_key:
|
70
90
|
specification_version: 4
|
71
91
|
summary: HealthGraph plugin for MyTimeline
|