fitbit_alarms_cli 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d57a33a593111e65cceae5cd7670984e5dc59e5b
4
+ data.tar.gz: ad04ddaeb8c523ce2c67e7c384ec4d6ac11fedf2
5
+ SHA512:
6
+ metadata.gz: cd90a5ced0d0c465a57b638381144a4b8e66dcbc6ce8c12e5db0c6ffe0f736bd18c0860871f827c7524e4c3c30f5944a8ae868d2fdc464add71a18c1f62cad0f
7
+ data.tar.gz: a1b0cca80a312f6fe5f3c2ff12f3c926788c37bc848ed3159fa74eb21eca3d0320c7396b228e8552d4764afc8dd0da5fb0e9378c39ae94178e3be18547b5b3ff
@@ -0,0 +1,22 @@
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
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
@@ -0,0 +1 @@
1
+ 2.1.2
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ cache: bundler
3
+ script: "bundle exec rake test"
4
+ rvm:
5
+ - 2.1.2
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'bundler', '~> 1.6'
4
+ gem 'fitgem'
5
+ gem 'rake'
6
+ gem 'thor'
7
+
8
+ group :test do
9
+ #gem 'backports'
10
+ #gem 'coveralls', :require => false
11
+ #gem 'json', :platforms => [:ruby_19]
12
+ #gem 'rubocop', '>= 0.23', :platforms => [:ruby_19, :ruby_20, :ruby_21]
13
+ gem 'minitest', '~> 5.3.5'
14
+ gem 'simplecov', :require => false
15
+ #gem 'yardstick'
16
+ end
17
+
18
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Ben Colon
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.
@@ -0,0 +1,31 @@
1
+ # FitbitAlarmsCli
2
+
3
+ A CLI gem to setup Fitbit alarms
4
+
5
+ ## Installation
6
+
7
+ Install the gem on your system:
8
+
9
+ $ gem install fitbit_alarms_cli
10
+
11
+ ## Usage
12
+
13
+ Enjoy `fac` executable
14
+
15
+ ```bash
16
+ Commands:
17
+ fac add # Add a new alarm
18
+ fac help [COMMAND] # Describe available commands or one specific command
19
+ fac list # List all alarms
20
+ fac remove # Remove an alarm
21
+ fac setup # Start the setup of Fitbit Alarms CLI
22
+ fac version # Fitbit Alarms CLI version
23
+ ```
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/fitbit_alarms_cli/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ t.pattern = "test/*_test.rb"
7
+ end
data/bin/fac ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/ruby
2
+ require "fitbit_alarms_cli"
3
+ FitbitAlarmsCli::Commands.start(ARGV)
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "fitbit_alarms_cli/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "fitbit_alarms_cli"
8
+ spec.version = FitbitAlarmsCli::VERSION
9
+ spec.authors = ["Ben Colon"]
10
+ spec.email = ["ben@colon.com.fr"]
11
+ spec.summary = "A CLI gem to setup Fitbit alarms"
12
+ spec.description = "A CLI gem to setup Fitbit alarms"
13
+ spec.homepage = "https://github.com/bencolon/fitbit_alarms_cli"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = ["fac"]
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+ end
@@ -0,0 +1,74 @@
1
+ require "thor"
2
+ require "fitbit_alarms_cli/version"
3
+ require "fitbit_alarms_cli/setup"
4
+ require "fitbit_alarms_cli/client"
5
+
6
+ module FitbitAlarmsCli
7
+ class Commands < Thor
8
+ desc "version", "Fitbit Alarms CLI version"
9
+ def version
10
+ puts "Fitbit Alarms CLI - v#{VERSION}"
11
+ end
12
+
13
+ desc "setup", "Run the setup of Fitbit Alarms CLI"
14
+ long_desc <<-LONGDESC
15
+ Guide you to setup Fitbit Alarms CLI across authentication process.
16
+ LONGDESC
17
+ def setup
18
+ Setup.start
19
+ end
20
+
21
+ desc "list", "List all alarms"
22
+ long_desc <<-LONGDESC
23
+ List all Fitbit alarms. By default, list all alarms from ALL you devices.
24
+
25
+ With -D option, you can specify a device ID to get only device's alarms.
26
+ LONGDESC
27
+ option :device, :aliases => :"-D", :type => :numeric
28
+ def list
29
+ client = Client.new
30
+ client.list_alarms(options)
31
+ end
32
+
33
+ desc "add TIME", "Add a new alarm"
34
+ long_desc <<-LONGDESC
35
+ Add a new alarm with <time>. <time> should be HH:MM+TZ:00 formatted.
36
+ \x5 By default, the new alarm is assigned to the first device with these settings: today, enabled and no recurring.
37
+
38
+ With -e option, you can enabled/disabled the alarm (true or false).
39
+
40
+ With -d option, you can set the day(s) the alarm will be active for recurring alarm only.
41
+ \x5 You have to pass coma separated values (MONDAY,FRIDAY,...).
42
+
43
+ With -r option, you can set if it's a one time alarm or a recurring alarm (true or false).
44
+
45
+ With -l option, you can add a label to the alarm.
46
+ \x5 Unfortunately, this label will not be displayed on you're Fitbit :(
47
+ \x5 I really hope this feature will be added asap to the Fitbit firmware.
48
+
49
+ With -D option, you can specify a device ID to specify on which device the alarm has to be added.
50
+ LONGDESC
51
+ option :enabled, :aliases => :"-e", :type => :boolean
52
+ option :week_days, :aliases => :"-d", :type => :array
53
+ option :recurring, :aliases => :"-r", :type => :boolean
54
+ option :label, :aliases => :"-l", :type => :string
55
+ option :device_id, :aliases => :"-D", :type => :numeric
56
+ def add(time)
57
+ client = Client.new
58
+ client.add_alarm(time, options)
59
+ end
60
+
61
+ desc "remove ALARM_ID", "Remove an alarm"
62
+ long_desc <<-LONGDESC
63
+ Remove the alarm with the corresponding <alarm_id>.
64
+ \x5 By default, try to remove the alarm from the first device.
65
+
66
+ With -D option, you can specify the device ID from where the alarm has to be removed.
67
+ LONGDESC
68
+ option :device, :aliases => :"-D", :type => :numeric
69
+ def remove(alarm_id)
70
+ client = Client.new
71
+ client.remove_alarm(alarm_id, options)
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,116 @@
1
+ require 'yaml'
2
+ require 'fitgem'
3
+
4
+ module FitbitAlarmsCli
5
+ class Client
6
+ MAX_ALARMS_COUNT = 8
7
+
8
+ def initialize
9
+ unless File.exists?(Setup::AUTH_FILE_PATH)
10
+ puts "You haven't setup FitbitAlarmsCli."
11
+ puts "Please run `fac setup` before."
12
+ exit
13
+ end
14
+
15
+ auth = YAML.load_file(Setup::AUTH_FILE_PATH)
16
+ unless auth[:consumer_key] && auth[:consumer_secret] && auth[:token] && auth[:secret]
17
+ puts "FitbitAlarmsCli configuration seems corrupted."
18
+ puts "Please run `fac setup` again."
19
+ exit
20
+ end
21
+
22
+ @client = Fitgem::Client.new({ :consumer_key => auth[:consumer_key],
23
+ :consumer_secret => auth[:consumer_secret],
24
+ :token => auth[:token],
25
+ :secret => auth[:secret] })
26
+ end
27
+
28
+ def list_alarms(options)
29
+ if options[:device]
30
+ puts_device_alarms(options[:device])
31
+ else
32
+ check_response(devices = @client.devices)
33
+ devices.each do |device|
34
+ puts_device_alarms(device['id'])
35
+ end
36
+ end
37
+ end
38
+
39
+ def add_alarm(time, options)
40
+ unless /^\d{2}:\d{2}\+\d{2}:\d{2}$/.match(time)
41
+ puts_and_exit "ERROR: Invalid time. Time should be HH:MM+TZ:00 formatted (ex: 23:30+02:00)."
42
+ end
43
+
44
+ device_id = options[:device] || first_device
45
+ alarms = @client.get_alarms(device_id)
46
+ puts_and_exit "ERROR: You reached the maximum alarms count (8) on this device." if alarms["trackerAlarms"].count == MAX_ALARMS_COUNT
47
+
48
+ settings = { :device_id => device_id,
49
+ :time => time,
50
+ :enabled => true,
51
+ :recurring => false,
52
+ :weekDays => Time.now.strftime("%A").upcase
53
+ }
54
+
55
+ # symbolize_keys and update weird week_days API params
56
+ options = options.each_with_object({}) do |(k,v), h|
57
+ k = "weekDays" if k == "week_days"
58
+ h[k.to_sym] = v
59
+ end
60
+
61
+ settings.merge!(options)
62
+ check_response(@client.add_alarm(settings))
63
+
64
+ list_alarms(options)
65
+ end
66
+
67
+ def remove_alarm(alarm_id, options)
68
+ device_id = options[:device] || first_device
69
+ check_response(@client.delete_alarm(alarm_id, device_id))
70
+ list_alarms(options)
71
+ end
72
+
73
+ private
74
+
75
+ def first_device
76
+ @client.devices.first["id"]
77
+ end
78
+
79
+ def check_response(response)
80
+ puts_and_exit "ERROR: #{response["errors"]}" if response.is_a?(Hash) && response["errors"]
81
+ end
82
+
83
+ def puts_device_alarms(device_id)
84
+ puts "Device ##{device_id}\n--------------------------------"
85
+ check_response(response = @client.get_alarms(device_id))
86
+ format_alarms(response["trackerAlarms"])
87
+ end
88
+
89
+ def format_alarms(alarms)
90
+ puts_and_exit " Device not found." unless alarms
91
+ puts_and_exit " No alarms set on this device." if alarms.empty?
92
+
93
+ alarms.each do |alarm|
94
+ label = alarm['label'] ? " (#{alarm['label']})" : ""
95
+ time = alarm['time']
96
+ day = alarm['recurring'] ? "" : today_or_tomorrow(time[0..1], time[3..4], time[5..10])
97
+ recurring = alarm['recurring'] ? " every #{alarm['weekDays']}" : ""
98
+ enabled = alarm['enabled'] ? 'enabled' : 'disabled'
99
+ synced = alarm['syncedToDevice'] ? "synced" : "not synced"
100
+
101
+ puts " Alarm ##{alarm['alarmId']}#{label}, #{day}at #{alarm['time']}#{recurring} is #{enabled}/#{synced}."
102
+ end
103
+ end
104
+
105
+ def today_or_tomorrow(h, m, tz)
106
+ now = Time.now
107
+ alarm = Time.new(now.year, now.month, now.day, h, m, 0, tz)
108
+ now < alarm ? "today " : "tomorrow "
109
+ end
110
+
111
+ def puts_and_exit(message)
112
+ puts message
113
+ exit
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,74 @@
1
+ module FitbitAlarmsCli
2
+ module Setup
3
+ AUTH_FILE_PATH = "#{Dir.home}/.fitbit_alarms_cli"
4
+
5
+ def self.start
6
+ if File.exists?(AUTH_FILE_PATH)
7
+ puts "You already setup FitbitAlarmsCli."
8
+ puts "Are you sure you want to setup it again? yes/no"
9
+ response = $stdin.gets
10
+ exit if response.strip != "yes"
11
+ end
12
+ run
13
+ end
14
+
15
+ private
16
+
17
+ def self.run
18
+ @auth = {}
19
+
20
+ intro
21
+ consumer_infos
22
+ tokens
23
+ congrats
24
+
25
+ rescue Exception => e
26
+ puts "An error has ocurred during authentication. Please try again."
27
+ puts e.message
28
+ #puts e.backtrace.inspect
29
+ end
30
+
31
+ def self.intro
32
+ puts "First, go register a new Fitbit application at https://dev.fitbit.com/apps/new"
33
+ puts "Fill the form and come back"
34
+ puts "Press a key to continue..."
35
+ $stdin.gets
36
+ end
37
+
38
+ def self.consumer_infos
39
+ begin
40
+ puts "Enter the consumer key you got and press enter:"
41
+ end while (key = $stdin.gets.strip).empty?
42
+ @auth[:consumer_key] = key
43
+
44
+ begin
45
+ puts "Enter the consumer secret you got and press enter:"
46
+ end while (secret = $stdin.gets.strip).empty?
47
+ @auth[:consumer_secret] = secret
48
+
49
+ @client = Fitgem::Client.new({ :consumer_key => @auth[:consumer_key],
50
+ :consumer_secret => @auth[:consumer_secret] })
51
+ end
52
+
53
+ def self.tokens
54
+ request_token = @client.authentication_request_token
55
+
56
+ puts "Your application is now set up, you now have to authorize this app access you data."
57
+ puts "Visit the following link, log in if needed, and then authorize the app."
58
+ puts request_token.authorize_url
59
+
60
+ puts "When you've authorized that app, enter the verifier code you got and press enter:"
61
+ verifier = $stdin.gets.strip
62
+ access_token = @client.authorize(request_token.token, request_token.secret, :oauth_verifier => verifier)
63
+ @auth[:token] = access_token.token
64
+ @auth[:secret] = access_token.secret
65
+
66
+ File.open(AUTH_FILE_PATH, "w") {|f| YAML.dump(@auth, f) }
67
+ end
68
+
69
+ def self.congrats
70
+ puts "Congrats, FitbitAlarmsCli is setup!"
71
+ puts "Have a look to the help to enjoy it: `fac help`"
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,3 @@
1
+ module FitbitAlarmsCli
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class FitbitAlarmsCliTest < MiniTest::Unit::TestCase
4
+ def test_check
5
+ assert true
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ require 'simplecov'
2
+ #require 'coveralls'
3
+
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ #Coveralls::SimpleCov::Formatter,
7
+ ]
8
+
9
+ SimpleCov.start do
10
+ minimum_coverage 100
11
+ end
12
+
13
+ require 'fitbit_alarms_cli'
14
+ require 'minitest'
15
+ require 'minitest/autorun'
16
+ require 'minitest/pride'
17
+
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fitbit_alarms_cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ben Colon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-25 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A CLI gem to setup Fitbit alarms
14
+ email:
15
+ - ben@colon.com.fr
16
+ executables:
17
+ - fac
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ".gitignore"
22
+ - ".ruby-version"
23
+ - ".travis.yml"
24
+ - Gemfile
25
+ - LICENSE.txt
26
+ - README.md
27
+ - Rakefile
28
+ - bin/fac
29
+ - fitbit_alarms_cli.gemspec
30
+ - lib/fitbit_alarms_cli.rb
31
+ - lib/fitbit_alarms_cli/client.rb
32
+ - lib/fitbit_alarms_cli/setup.rb
33
+ - lib/fitbit_alarms_cli/version.rb
34
+ - test/fitbit_alarms_cli_test.rb
35
+ - test/test_helper.rb
36
+ homepage: https://github.com/bencolon/fitbit_alarms_cli
37
+ licenses:
38
+ - MIT
39
+ metadata: {}
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 2.2.2
57
+ signing_key:
58
+ specification_version: 4
59
+ summary: A CLI gem to setup Fitbit alarms
60
+ test_files:
61
+ - test/fitbit_alarms_cli_test.rb
62
+ - test/test_helper.rb