remind101 0.1.2 → 0.2.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1e634a534ebd0a1286e7583d315615a8796c06ff
4
+ data.tar.gz: b25cf0eb73962fed9269b6373fc75117687a0007
5
+ SHA512:
6
+ metadata.gz: 37534508d3f2990ded85119d03ffa3ea1d19f31f22d615423981910d1f486ae0abda76742e3c4b318c15744b7a5676e41b96eec3fff30a9765f6dd5d31814e10
7
+ data.tar.gz: 132ed59a5d7787aedc4f64f40a6906697b04181da767149a5273de3ef5a4b16a2ef3989089e1b9ec60e22e927a34d9b490dd6a59942011a1b8e21634fc7e2bd4
data/bin/remind101 ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require "remind101"
5
+ # require "remind101/cli"
6
+ Remind101::CLI.start(*ARGV)
@@ -0,0 +1,13 @@
1
+ module Remind101::Client::AccessTokens
2
+
3
+ # Public: Creates a new access token.
4
+ #
5
+ # Examples
6
+ #
7
+ # remind101.post_access_tokens
8
+ #
9
+ # Returns the faraday response.
10
+ def post_access_tokens(hash)
11
+ api_post('/access_tokens', hash)
12
+ end
13
+ end
@@ -1,41 +1,35 @@
1
1
  module Remind101::Client::Groups
2
- extend Remind101::Client::Rescuable
3
2
 
4
3
  # Public: Returns all groups for the current user.
5
4
  #
6
5
  # Examples
7
6
  #
8
- # remind101.groups
9
- # # => [{ ... }]
7
+ # remind101.get_groups
10
8
  #
11
- # Returns an Array of all groups.
12
- def groups(options = {})
13
- api_get('/groups', options).body
9
+ # Returns the faraday response.
10
+ def get_groups(options = {})
11
+ api_get('/groups', options)
14
12
  end
15
13
 
16
14
  # Public: Creates a new group.
17
15
  #
18
16
  # Examples
19
17
  #
20
- # remind101.create_group! name: 'Math 101'
21
- # # => { :id => 4321, :name => "Math 101", ... }
18
+ # remind101.post_group group: { name: 'Math 101' }
22
19
  #
23
- # Returns the created group.
24
- def create_group!(hash)
25
- api_post('/groups', group: hash).body
20
+ # Returns the faraday response.
21
+ def post_group(hash)
22
+ api_post('/groups', hash)
26
23
  end
27
- def_rescued :create_group, :create_group!
28
24
 
29
25
  # Public: Destroys an existing group.
30
26
  #
31
27
  # Examples
32
28
  #
33
- # remind101.destroy_group! 4321
34
- # # => { :id => 4321, :name => "Math 101", ... }
29
+ # remind101.delete_group 4321
35
30
  #
36
31
  # Returns the destroyed group.
37
- def destroy_group!(group_id)
38
- api_delete("/groups/#{group_id}").body
32
+ def delete_group(group_id)
33
+ api_delete("/groups/#{group_id}")
39
34
  end
40
- def_rescued :destroy_group, :destroy_group!
41
35
  end
@@ -1,49 +1,46 @@
1
1
  module Remind101::Client::Messages
2
- extend Remind101::Client::Rescuable
3
2
 
4
3
  # Public: Returns all messages for the current user.
5
4
  #
6
5
  # Examples
7
6
  #
8
- # remind101.messages
9
- # # => [{ ... }]
7
+ # remind101.get_messages
10
8
  #
11
- # Returns an Array of all messages.
12
- def messages(options = {})
13
- api_get('/messages', options).body
9
+ # Returns the faraday response.
10
+ def get_messages(options = {})
11
+ api_get('/messages', options)
14
12
  end
15
13
 
16
- # Public: Creates a new message.
14
+ # Public: Returns a single message for the current user.
15
+ #
16
+ # Examples
17
+ #
18
+ # remind101.get_message(1234)
17
19
  #
18
- # Also aliased as `#send_message!`.
20
+ # Returns the faraday response.
21
+ def get_message(id)
22
+ api_get("/messages/#{id}")
23
+ end
24
+
25
+ # Public: Creates a new message.
19
26
  #
20
27
  # Examples
21
28
  #
22
- # remind101.create_message! body: 'Hello World!', group_ids: [1234]
23
- # # => { :id => 4321, :body => "Hello World!", :group_ids => [1234], ... }
29
+ # remind101.post_message message: { body: 'Hello World!', group_ids: [1234] }
24
30
  #
25
- # Returns the created message.
26
- def create_message!(hash)
27
- api_post('/messages', message: hash).body
31
+ # Returns the faraday response.
32
+ def post_message(hash)
33
+ api_post('/messages', hash)
28
34
  end
29
- def_rescued :create_message, :create_message!
30
- alias_method :send_message!, :create_message!
31
- alias_method :send_message, :create_message
32
35
 
33
36
  # Public: Destroy an existing message.
34
37
  #
35
- # Also aliased as `cancel_message!`.
36
- #
37
38
  # Examples
38
39
  #
39
- # remind101.destroy_message! 4321
40
- # # => { :id => 4321, :body => "Hello World!", :group_ids => [1234], ... }
40
+ # remind101.delete_message 4321
41
41
  #
42
- # Returns the destroyed message.
43
- def destroy_message!(message_id)
44
- api_delete("/messages/#{message_id}").body
42
+ # Returns the faraday response.
43
+ def delete_message(message_id)
44
+ api_delete("/messages/#{message_id}")
45
45
  end
46
- def_rescued :destroy_message, :destroy_message!
47
- alias_method :cancel_message!, :destroy_message!
48
- alias_method :cancel_message, :destroy_message
49
46
  end
@@ -1,64 +1,68 @@
1
1
  module Remind101::Client::Subscribers
2
- extend Remind101::Client::Rescuable
2
+
3
+ # Public: Returns all subscribers for the current user.
4
+ #
5
+ # Examples
6
+ #
7
+ # remind101.get_subscribers
8
+ #
9
+ # Returns the faraday response.
10
+ def get_subscribers(options = {})
11
+ api_get("/subscribers", options)
12
+ end
3
13
 
4
14
  # Public: Returns all subscribers for the given group.
5
15
  #
6
16
  # Examples
7
17
  #
8
- # remind101.subscribers 1234
9
- # #=> [{ ... }]
18
+ # remind101.get_group_subscribers 1234
10
19
  #
11
- # Returns an Array of all subscribers.
12
- def subscribers(group_id, options = {})
13
- api_get("/groups/#{group_id}/subscribers", options).body
20
+ # Returns the faraday response.
21
+ def get_group_subscribers(group_id, options = {})
22
+ api_get("/groups/#{group_id}/subscribers", options)
14
23
  end
15
24
 
16
- # Public: Returns a single subscriber for the given group and subscriber id.
25
+ # Public: Returns a single subscriber.
17
26
  #
18
27
  # Examples
19
28
  #
20
- # remind101.subscriberr 1234, 4321
21
- # # => { ... }
29
+ # remind101.get_subscriber 4321
22
30
  #
23
- # Returns the Hashie::Mash representation of the subscriber.
24
- def subscriber(group_id, subscriber_id, options = {})
25
- api_get("/groups/#{group_id}/subscribers/#{subscriber_id}", options).body
31
+ # Returns the faraday response.
32
+ def get_subscriber(subscriber_id, options = {})
33
+ api_get("/subscribers/#{subscriber_id}", options)
26
34
  end
27
35
 
28
36
  # Public: Updates a subscriber.
29
37
  #
30
38
  # Examples
31
39
  #
32
- # remind101.update_subscriber 1234, 4321, attributes
33
- # # => { ... }
40
+ # remind101.patch_subscriber 4321, attributes
34
41
  #
35
- # Returns the Hashie::Mash representation of the updated subscriber.
36
- def update_subscriber!(group_id, subscriber_id, attributes)
37
- api_patch("/groups/#{group_id}/subscribers/#{subscriber_id}", subscriber: attributes).body
42
+ # Returns the faraday response.
43
+ def rename_subscriber(subscriber_id, name)
44
+ api_post("/subscribers/#{subscriber_id}/rename", name: name)
38
45
  end
39
- def_rescued :update_subscriber, :update_subscriber!
40
46
 
41
47
  # Public: Removes a subscriber from the group.
42
48
  #
43
49
  # Examples
44
50
  #
45
- # remind101.remove_subscriber! 1234, 4321
51
+ # remind101.delete_group_subscriber 1234, 4321
46
52
  #
47
- # Returns the removed subscriber.
48
- def remove_subscriber!(group_id, subscriber_id)
49
- api_delete("/groups/#{group_id}/subscribers/#{subscriber_id}").body
53
+ # Returns the faraday response.
54
+ def delete_group_subscriber(group_id, subscriber_id)
55
+ api_delete("/groups/#{group_id}/subscribers/#{subscriber_id}")
50
56
  end
51
- def_rescued :remove_subscriber, :remove_subscriber!
52
57
 
53
58
  # Public: Removes all subscribers from the group.
54
59
  #
55
60
  # Examples
56
61
  #
57
- # remind101.remove_subscribers!
62
+ # remind101.delete_group_subscribers
58
63
  #
59
- # Returns true if all subscribers were removed.
60
- def remove_subscribers!(group_id)
61
- api_delete("/groups/#{group_id}/subscribers").body
64
+ # Returns the faraday response.
65
+ def delete_group_subscribers(group_id)
66
+ api_delete("/groups/#{group_id}/subscribers")
62
67
  end
63
- def_rescued :remove_subscribers, :remove_subscribers!
64
68
  end
@@ -1,27 +1,47 @@
1
1
  module Remind101
2
2
  class Client
3
- require 'remind101/client/rescuable'
4
3
  require 'remind101/client/connection'
4
+ require 'remind101/client/access_tokens'
5
5
  require 'remind101/client/groups'
6
6
  require 'remind101/client/messages'
7
7
  require 'remind101/client/subscribers'
8
8
 
9
9
  include Connection
10
+ include AccessTokens
10
11
  include Groups
11
12
  include Messages
12
13
  include Subscribers
13
14
 
14
15
  attr_reader :options
15
16
 
17
+ # Public: Creates a new access token and sets it on the client for future requests.
18
+ #
19
+ # Returns the faraday response from creating the access token.
20
+ def authenticate!(username, password)
21
+ post_access_tokens(user: { email: username, password: password }).tap do |response|
22
+ self.auth_token = response.body.auth_token
23
+ # Force the connection to be recreated to use the new auth token.
24
+ @connection = nil
25
+ end
26
+ end
27
+
16
28
  def initialize(options = {})
17
29
  @options = options
18
30
  yield middleware if block_given?
19
31
  end
20
32
 
21
- private
22
-
33
+ # Public: Returns the auth token that's being used for authenticated requests.
34
+ #
35
+ # Returns String.
23
36
  def auth_token
24
37
  options[:auth_token]
25
38
  end
39
+
40
+ # Public: Sets the auth token to be used for authenticated requests.
41
+ #
42
+ # Returns nothing.
43
+ def auth_token=(token)
44
+ options[:auth_token] = token
45
+ end
26
46
  end
27
47
  end
@@ -0,0 +1,86 @@
1
+ require "remind101/command/base"
2
+
3
+ # authentication (login, logout)
4
+ #
5
+ class Remind101::Command::Auth < Remind101::Command::Base
6
+
7
+ # auth
8
+ #
9
+ # Authenticate, display token and current user
10
+ def index
11
+ validate_arguments!
12
+
13
+ Remind101::Command::Help.new.send(:help_for_command, current_command)
14
+ end
15
+
16
+ # auth:login
17
+ #
18
+ # log in with your remind101 credentials
19
+ #
20
+ #Example:
21
+ #
22
+ # $ remind101 auth:login
23
+ # Enter your Remind101 credentials:
24
+ # Email: email@example.com
25
+ # Password (typing will be hidden):
26
+ # Authentication successful.
27
+ #
28
+ def login
29
+ validate_arguments!
30
+
31
+ Remind101::Auth.login
32
+ display "Authentication successful."
33
+ end
34
+
35
+ alias_command "login", "auth:login"
36
+
37
+ # auth:logout
38
+ #
39
+ # clear local authentication credentials
40
+ #
41
+ #Example:
42
+ #
43
+ # $ remind101 auth:logout
44
+ # Local credentials cleared.
45
+ #
46
+ def logout
47
+ validate_arguments!
48
+
49
+ Remind101::Auth.logout
50
+ display "Local credentials cleared."
51
+ end
52
+
53
+ alias_command "logout", "auth:logout"
54
+
55
+ # auth:token
56
+ #
57
+ # display your api token
58
+ #
59
+ #Example:
60
+ #
61
+ # $ remind101 auth:token
62
+ # ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCD
63
+ #
64
+ def token
65
+ validate_arguments!
66
+
67
+ display Remind101::Auth.token
68
+ end
69
+
70
+ # auth:whoami
71
+ #
72
+ # display your remind101 email address
73
+ #
74
+ #Example:
75
+ #
76
+ # $ remind101 auth:whoami
77
+ # email@example.com
78
+ #
79
+ def whoami
80
+ validate_arguments!
81
+
82
+ display Remind101::Auth.user
83
+ end
84
+
85
+ end
86
+
@@ -0,0 +1,154 @@
1
+ require "fileutils"
2
+ require "remind101/command"
3
+
4
+ class Remind101::Command::Base
5
+ include Remind101::Helpers
6
+
7
+ def self.namespace
8
+ self.to_s.split("::").last.downcase
9
+ end
10
+
11
+ attr_reader :args
12
+ attr_reader :options
13
+
14
+ def initialize(args=[], options={})
15
+ @args = args
16
+ @options = options
17
+ end
18
+
19
+ def remind101
20
+ Remind101::Client.new(auth_token: Remind101::Auth.token)
21
+ end
22
+
23
+ protected
24
+
25
+ def self.inherited(klass)
26
+ unless klass == Remind101::Command::Base
27
+ help = extract_help_from_caller(caller.first)
28
+
29
+ Remind101::Command.register_namespace(
30
+ :name => klass.namespace,
31
+ :description => help.first
32
+ )
33
+ end
34
+ end
35
+
36
+ def self.method_added(method)
37
+ return if self == Remind101::Command::Base
38
+ return if private_method_defined?(method)
39
+ return if protected_method_defined?(method)
40
+
41
+ help = extract_help_from_caller(caller.first)
42
+ resolved_method = (method.to_s == "index") ? nil : method.to_s
43
+ command = [ self.namespace, resolved_method ].compact.join(":")
44
+ banner = extract_banner(help) || command
45
+
46
+ Remind101::Command.register_command(
47
+ :klass => self,
48
+ :method => method,
49
+ :namespace => self.namespace,
50
+ :command => command,
51
+ :banner => banner.strip,
52
+ :help => help.join("\n"),
53
+ :summary => extract_summary(help),
54
+ :description => extract_description(help),
55
+ :options => extract_options(help)
56
+ )
57
+
58
+ alias_command command.gsub(/_/, '-'), command if command =~ /_/
59
+ end
60
+
61
+ def self.alias_command(new, old)
62
+ raise "no such command: #{old}" unless Remind101::Command.commands[old]
63
+ Remind101::Command.command_aliases[new] = old
64
+ end
65
+
66
+ #
67
+ # Parse the caller format and identify the file and line number as identified
68
+ # in : http://www.ruby-doc.org/core/classes/Kernel.html#M001397. This will
69
+ # look for a colon followed by a digit as the delimiter. The biggest
70
+ # complication is windows paths, which have a colon after the drive letter.
71
+ # This regex will match paths as anything from the beginning to a colon
72
+ # directly followed by a number (the line number).
73
+ #
74
+ # Examples of the caller format :
75
+ # * c:/Ruby192/lib/.../lib/heroku/command/addons.rb:8:in `<module:Command>'
76
+ # * c:/Ruby192/lib/.../heroku-2.0.1/lib/heroku/command/pg.rb:96:in `<class:Pg>'
77
+ # * /Users/ph7/...../xray-1.1/lib/xray/thread_dump_signal_handler.rb:9
78
+ #
79
+ def self.extract_help_from_caller(line)
80
+ # pull out of the caller the information for the file path and line number
81
+ if line =~ /^(.+?):(\d+)/
82
+ extract_help($1, $2)
83
+ else
84
+ raise("unable to extract help from caller: #{line}")
85
+ end
86
+ end
87
+
88
+ def self.extract_help(file, line_number)
89
+ buffer = []
90
+ lines = Remind101::Command.files[file]
91
+
92
+ (line_number.to_i-2).downto(0) do |i|
93
+ line = lines[i]
94
+ case line[0..0]
95
+ when ""
96
+ when "#"
97
+ buffer.unshift(line[1..-1])
98
+ else
99
+ break
100
+ end
101
+ end
102
+
103
+ buffer
104
+ end
105
+
106
+ def self.extract_banner(help)
107
+ help.first
108
+ end
109
+
110
+ def self.extract_summary(help)
111
+ extract_description(help).split("\n")[2].to_s.split("\n").first
112
+ end
113
+
114
+ def self.extract_description(help)
115
+ help.reject do |line|
116
+ line =~ /^\s+-(.+)#(.+)/
117
+ end.join("\n")
118
+ end
119
+
120
+ def self.extract_options(help)
121
+ help.select do |line|
122
+ line =~ /^\s+-(.+)#(.+)/
123
+ end.inject([]) do |options, line|
124
+ args = line.split('#', 2).first
125
+ args = args.split(/,\s*/).map {|arg| arg.strip}.sort.reverse
126
+ name = args.last.split(' ', 2).first[2..-1]
127
+ options << { :name => name, :args => args }
128
+ end
129
+ end
130
+
131
+ def current_command
132
+ Remind101::Command.current_command
133
+ end
134
+
135
+ def extract_option(key)
136
+ options[key.dup.gsub('-','_').to_sym]
137
+ end
138
+
139
+ def invalid_arguments
140
+ Remind101::Command.invalid_arguments
141
+ end
142
+
143
+ def shift_argument
144
+ Remind101::Command.shift_argument
145
+ end
146
+
147
+ def validate_arguments!
148
+ Remind101::Command.validate_arguments!
149
+ end
150
+
151
+ def escape(value)
152
+ heroku.escape(value)
153
+ end
154
+ end
@@ -0,0 +1,75 @@
1
+ require "remind101/command/base"
2
+
3
+ # manage groups
4
+ #
5
+ class Remind101::Command::Groups < Remind101::Command::Base
6
+
7
+ # groups
8
+ #
9
+ # list groups
10
+ def index
11
+ validate_arguments!
12
+
13
+ groups = remind101.groups
14
+
15
+ if groups.empty?
16
+ display "You have no groups"
17
+ else
18
+ styled_header "My Groups"
19
+ styled_array groups.map { |g| [ g.name, g.class_name ] }
20
+ end
21
+ end
22
+
23
+ # groups:info [CODE]
24
+ #
25
+ # show detailed group information
26
+ def info
27
+ end
28
+
29
+ # groups:create [NAME]
30
+ #
31
+ # create a new group
32
+ #
33
+ # -c, --code CODE # the group code (optional)
34
+ #
35
+ #Examples
36
+ #
37
+ # $ remind101 groups:create "Math 101" -c math101
38
+ #
39
+ def create
40
+ name = shift_argument
41
+ validate_arguments!
42
+
43
+ attributes = { class_name: name }
44
+ attributes[:code] = options[:code] if options[:code]
45
+
46
+ group = action "Creating #{name}" do
47
+ remind101.create_group! attributes
48
+ end
49
+
50
+ hputs([ group.name, group.class_name ].join(" | "))
51
+ end
52
+
53
+ # groups:destroy [CODE]
54
+ #
55
+ # permanently destroy a group
56
+ #
57
+ #Example:
58
+ #
59
+ # $ remind101 groups:destroy math101
60
+ # Destroying math101... done
61
+ #
62
+ def destroy
63
+ code = shift_argument
64
+
65
+ group = remind101.groups.find { |g| g.name == code }
66
+ error("Unable to find a group with that code") if group.nil?
67
+
68
+ message = "WARNING: Potentially Destructive Action\nThis command will destroy @#{code} (#{group.class_name})."
69
+ if confirm_command(code, message)
70
+ action("Destroying @#{code} (#{group.class_name})") do
71
+ remind101.destroy_group!(group.id)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,156 @@
1
+ require "remind101/command/base"
2
+
3
+ # list commands and display help
4
+ #
5
+ class Remind101::Command::Help < Remind101::Command::Base
6
+
7
+ PRIMARY_NAMESPACES = %w( auth groups messages )
8
+
9
+ # help [COMMAND]
10
+ #
11
+ # list available commands or display help for a specific command
12
+ #
13
+ #Examples:
14
+ #
15
+ # $ remind101 help
16
+ # Usage: remind101 COMMAND [--app APP] [command-specific-options]
17
+ #
18
+ # Primary help topics, type "remind101 help TOPIC" for more details:
19
+ #
20
+ # addons # manage addon resources
21
+ # apps # manage apps (create, destroy)
22
+ # ...
23
+ #
24
+ # Additional topics:
25
+ #
26
+ # account # manage remind101 account options
27
+ # accounts # manage multiple remind101 accounts
28
+ # ...
29
+ #
30
+ # $ remind101 help apps:create
31
+ # Usage: remind101 apps:create [NAME]
32
+ #
33
+ # create a new app
34
+ #
35
+ # --addons ADDONS # a comma-delimited list of addons to install
36
+ # -b, --buildpack BUILDPACK # a buildpack url to use for this app
37
+ # -r, --remote REMOTE # the git remote to create, default "remind101"
38
+ # -s, --stack STACK # the stack on which to create the app
39
+ #
40
+ def index
41
+ if command = args.shift
42
+ help_for_command(command)
43
+ else
44
+ help_for_root
45
+ end
46
+ end
47
+
48
+ alias_command "-h", "help"
49
+ alias_command "--help", "help"
50
+
51
+ private
52
+
53
+ def commands_for_namespace(name)
54
+ Remind101::Command.commands.values.select do |command|
55
+ command[:namespace] == name && command[:command] != name
56
+ end
57
+ end
58
+
59
+ def namespaces
60
+ Remind101::Command.namespaces
61
+ end
62
+
63
+ def commands
64
+ Remind101::Command.commands
65
+ end
66
+
67
+ def skip_namespace?(ns)
68
+ return true if ns[:description] =~ /DEPRECATED:/
69
+ return true if ns[:description] =~ /HIDDEN:/
70
+ false
71
+ end
72
+
73
+ def skip_command?(command)
74
+ return true if command[:help] =~ /DEPRECATED:/
75
+ return true if command[:help] =~ /^ HIDDEN:/
76
+ false
77
+ end
78
+
79
+ def primary_namespaces
80
+ PRIMARY_NAMESPACES.map { |name| namespaces[name] }.compact
81
+ end
82
+
83
+ def additional_namespaces
84
+ (namespaces.values - primary_namespaces)
85
+ end
86
+
87
+ def summary_for_namespaces(namespaces)
88
+ size = longest(namespaces.map { |n| n[:name] })
89
+ namespaces.sort_by {|namespace| namespace[:name]}.each do |namespace|
90
+ next if skip_namespace?(namespace)
91
+ name = namespace[:name]
92
+ namespace[:description] ||= legacy_help_for_namespace(name)
93
+ puts " %-#{size}s # %s" % [ name, namespace[:description] ]
94
+ end
95
+ end
96
+
97
+ def help_for_root
98
+ puts "Usage: remind101 COMMAND [command-specific-options]"
99
+ puts
100
+ puts "Primary help topics, type \"remind101 help TOPIC\" for more details:"
101
+ puts
102
+ summary_for_namespaces(primary_namespaces)
103
+ puts
104
+ puts "Additional topics:"
105
+ puts
106
+ summary_for_namespaces(additional_namespaces)
107
+ puts
108
+ end
109
+
110
+ def help_for_namespace(name)
111
+ namespace_commands = commands_for_namespace(name)
112
+
113
+ unless namespace_commands.empty?
114
+ size = longest(namespace_commands.map { |c| c[:banner] })
115
+ namespace_commands.sort_by { |c| c[:banner].to_s }.each do |command|
116
+ next if skip_command?(command)
117
+ command[:summary] ||= legacy_help_for_command(command[:command])
118
+ puts " %-#{size}s # %s" % [ command[:banner], command[:summary] ]
119
+ end
120
+ end
121
+ end
122
+
123
+ def help_for_command(name)
124
+ if command_alias = Remind101::Command.command_aliases[name]
125
+ display("Alias: #{name} redirects to #{command_alias}")
126
+ name = command_alias
127
+ end
128
+ if command = commands[name]
129
+ puts "Usage: remind101 #{command[:banner]}"
130
+
131
+ if command[:help].strip.length > 0
132
+ help = command[:help].split("\n").reject do |line|
133
+ line =~ /HIDDEN/
134
+ end
135
+ puts help[1..-1].join("\n")
136
+ else
137
+ puts
138
+ puts " " + legacy_help_for_command(name).to_s
139
+ end
140
+ puts
141
+ end
142
+
143
+ namespace_commands = commands_for_namespace(name).reject do |command|
144
+ command[:help] =~ /DEPRECATED/
145
+ end
146
+
147
+ if !namespace_commands.empty?
148
+ puts "Additional commands, type \"remind101 help COMMAND\" for more details:"
149
+ puts
150
+ help_for_namespace(name)
151
+ puts
152
+ elsif command.nil?
153
+ error "#{name} is not a remind101 command. See `remind101 help`."
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,32 @@
1
+ require "remind101/command/base"
2
+
3
+ # send messages
4
+ #
5
+ class Remind101::Command::Messages < Remind101::Command::Base
6
+
7
+ # messages:create [MESSAGE]
8
+ #
9
+ # send a new message
10
+ #
11
+ # -c, --code CODE # the group code to send the message to
12
+ #
13
+ #Examples
14
+ #
15
+ # $ remind101 send "Don't forget to study!" -c math101
16
+ #
17
+ def create
18
+ body = shift_argument
19
+ validate_arguments!
20
+
21
+ group = remind101.groups.find { |g| g.name == options[:code] }
22
+ error("Unable to find a group with that code") if group.nil?
23
+
24
+ attributes = { body: body, group_ids: [ group.id ] }
25
+
26
+ action "Sending message: #{body}" do
27
+ remind101.create_message! attributes
28
+ end
29
+ end
30
+
31
+ alias_command "send", "messages:create"
32
+ end
@@ -5,13 +5,17 @@ module Remind101
5
5
  attr_accessor :version
6
6
 
7
7
  def endpoint
8
- @endpoint ||= 'https://api.remind101.com'
8
+ @endpoint ||= 'https://api.remind.com'
9
9
  end
10
10
 
11
11
  def adapter
12
12
  @adapter ||= Faraday.default_adapter
13
13
  end
14
14
 
15
+ def user_agent
16
+ @user_agent ||= "remind101.rb/#{Remind101::VERSION} (#{RUBY_PLATFORM}) ruby/#{RUBY_VERSION}"
17
+ end
18
+
15
19
  def version
16
20
  @version ||= 'v2'
17
21
  end
@@ -1,3 +1,3 @@
1
1
  module Remind101
2
- VERSION = '0.1.2'
2
+ VERSION = '0.2.0'
3
3
  end
data/remind101.gemspec CHANGED
@@ -18,9 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'faraday', '~> 0.8'
22
- spec.add_dependency 'faraday_middleware', '~> 0.9'
21
+ spec.add_dependency 'faraday'
22
+ spec.add_dependency 'faraday_middleware'
23
23
  spec.add_dependency 'hashie', ['>= 1.2', '< 2.1']
24
+ spec.add_dependency 'netrc', '~> 0.7.7'
24
25
 
25
26
  spec.add_development_dependency 'bundler', '~> 1.3'
26
27
  spec.add_development_dependency 'rspec', '~> 2.14'
@@ -6,91 +6,118 @@ describe Remind101::Client do
6
6
  let(:subscriber_id) { 789 }
7
7
  let(:client ) { described_class.new }
8
8
 
9
- describe '#groups' do
10
- before { stub_request(:get, 'https://api.remind101.com/v2/groups') }
9
+ describe '#authenticate!' do
10
+ let(:username) { 'eric@remind101.com' }
11
+ let(:password) { 'foobar' }
12
+ let(:auth_token) { 'a21d9240-f446-4a4b-884a-56127fa59617' }
13
+
14
+ before do
15
+ stub_request(:post, 'https://api.remind.com/v2/access_tokens')
16
+ .with(body: { user: { email: username, password: password } })
17
+ .to_return(body: { auth_token: auth_token })
18
+ end
19
+
20
+ it 'returns an auth token for the user' do
21
+ client.authenticate!(username, password)
22
+ expect(client.auth_token).to eq auth_token
23
+ end
24
+ end
25
+
26
+ describe '#get_groups' do
27
+ before { stub_request(:get, 'https://api.remind.com/v2/groups') }
11
28
 
12
29
  it 'gets the groups' do
13
- client.groups
30
+ client.get_groups
14
31
  end
15
32
  end
16
33
 
17
- describe '#create_group!' do
18
- before { stub_request(:post, 'https://api.remind101.com/v2/groups') }
34
+ describe '#post_group' do
35
+ before { stub_request(:post, 'https://api.remind.com/v2/groups').with(body: body) }
36
+ let(:body) { { group: { name: 'Math 101' } } }
19
37
 
20
38
  it 'creates the group' do
21
- client.create_group! name: 'Math 101'
39
+ client.post_group body
22
40
  end
23
41
  end
24
42
 
25
- describe '#destroy_group!' do
26
- before { stub_request(:delete, "https://api.remind101.com/v2/groups/#{group_id}") }
43
+ describe '#delete_group' do
44
+ before { stub_request(:delete, "https://api.remind.com/v2/groups/#{group_id}") }
27
45
 
28
46
  it 'destroys the group' do
29
- client.destroy_group! group_id
47
+ client.delete_group group_id
48
+ end
49
+ end
50
+
51
+ describe '#get_messages' do
52
+ before { stub_request(:get, 'https://api.remind.com/v2/messages') }
53
+
54
+ it 'gets the messages' do
55
+ client.get_messages
30
56
  end
31
57
  end
32
58
 
33
- describe '#messages' do
34
- before { stub_request(:get, 'https://api.remind101.com/v2/messages') }
59
+ describe '#get_message' do
60
+ before { stub_request(:get, 'https://api.remind.com/v2/messages/1') }
35
61
 
36
62
  it 'gets the messages' do
37
- client.messages
63
+ client.get_message(1)
38
64
  end
39
65
  end
40
66
 
41
- describe '#create_message!' do
42
- before { stub_request(:post, 'https://api.remind101.com/v2/messages') }
67
+ describe '#post_message' do
68
+ before { stub_request(:post, 'https://api.remind.com/v2/messages').with(body: body) }
69
+ let(:body) { { message: { body: "There's a test tomorrow!", recipients: [{ type: 'group', id: [1] }] } } }
43
70
 
44
71
  it 'creates the message' do
45
- client.create_message! body: "There's a test tomorrow!", group_ids: [group_id]
72
+ client.post_message body
46
73
  end
47
74
  end
48
75
 
49
- describe '#destroy_message!' do
50
- before { stub_request(:delete, "https://api.remind101.com/v2/messages/#{message_id}") }
76
+ describe '#delete_message' do
77
+ before { stub_request(:delete, "https://api.remind.com/v2/messages/#{message_id}") }
51
78
 
52
79
  it 'destroys the message' do
53
- client.destroy_message! message_id
80
+ client.delete_message message_id
54
81
  end
55
82
  end
56
83
 
57
- describe '#subscribers' do
58
- before { stub_request(:get, "https://api.remind101.com/v2/groups/#{group_id}/subscribers") }
84
+ describe '#get_subscribers' do
85
+ before { stub_request(:get, "https://api.remind.com/v2/subscribers") }
59
86
 
60
87
  it 'gets the subscribers' do
61
- client.subscribers(group_id)
88
+ client.get_subscribers
62
89
  end
63
90
  end
64
91
 
65
- describe '#subscriber' do
66
- before { stub_request(:get, "https://api.remind101.com/v2/groups/#{group_id}/subscribers/#{subscriber_id}") }
92
+ describe '#get_subscriber' do
93
+ before { stub_request(:get, "https://api.remind.com/v2/subscribers/#{subscriber_id}") }
67
94
 
68
95
  it 'gets the subscriber' do
69
- client.subscriber(group_id, subscriber_id)
96
+ client.get_subscriber(subscriber_id)
70
97
  end
71
98
  end
72
99
 
73
- describe '#update_subscriber!' do
74
- before { stub_request(:patch, "https://api.remind101.com/v2/groups/#{group_id}/subscribers/#{subscriber_id}") }
100
+ describe '#rename_subscriber' do
101
+ before { stub_request(:post, "https://api.remind.com/v2/subscribers/#{subscriber_id}/rename").with(body: { name: 'Eric' }) }
75
102
 
76
103
  it 'updates the subscriber' do
77
- client.update_subscriber!(group_id, subscriber_id, name: 'foo')
104
+ client.rename_subscriber(subscriber_id, 'Eric')
78
105
  end
79
106
  end
80
107
 
81
- describe '#remove_subscriber!' do
82
- before { stub_request(:delete, "https://api.remind101.com/v2/groups/#{group_id}/subscribers/#{subscriber_id}") }
108
+ describe '#delete_group_subscriber' do
109
+ before { stub_request(:delete, "https://api.remind.com/v2/groups/#{group_id}/subscribers/#{subscriber_id}") }
83
110
 
84
111
  it 'removes the subscriber' do
85
- client.remove_subscriber!(group_id, subscriber_id)
112
+ client.delete_group_subscriber(group_id, subscriber_id)
86
113
  end
87
114
  end
88
115
 
89
- describe '#remove_subscribers!' do
90
- before { stub_request(:delete, "https://api.remind101.com/v2/groups/#{group_id}/subscribers") }
116
+ describe '#delete_group_subscribers' do
117
+ before { stub_request(:delete, "https://api.remind.com/v2/groups/#{group_id}/subscribers") }
91
118
 
92
119
  it 'removes the subscriber' do
93
- client.remove_subscribers!(group_id)
120
+ client.delete_group_subscribers(group_id)
94
121
  end
95
122
  end
96
123
  end
metadata CHANGED
@@ -1,54 +1,48 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remind101
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Eric J. Holmes
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-09-03 00:00:00.000000000 Z
11
+ date: 2014-08-27 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: faraday
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
- version: '0.8'
19
+ version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
- version: '0.8'
26
+ version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: faraday_middleware
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
- version: '0.9'
33
+ version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
- version: '0.9'
40
+ version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: hashie
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '1.2'
54
48
  - - <
@@ -57,18 +51,30 @@ dependencies:
57
51
  type: :runtime
58
52
  prerelease: false
59
53
  version_requirements: !ruby/object:Gem::Requirement
60
- none: false
61
54
  requirements:
62
- - - ! '>='
55
+ - - '>='
63
56
  - !ruby/object:Gem::Version
64
57
  version: '1.2'
65
58
  - - <
66
59
  - !ruby/object:Gem::Version
67
60
  version: '2.1'
61
+ - !ruby/object:Gem::Dependency
62
+ name: netrc
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: 0.7.7
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ~>
73
+ - !ruby/object:Gem::Version
74
+ version: 0.7.7
68
75
  - !ruby/object:Gem::Dependency
69
76
  name: bundler
70
77
  requirement: !ruby/object:Gem::Requirement
71
- none: false
72
78
  requirements:
73
79
  - - ~>
74
80
  - !ruby/object:Gem::Version
@@ -76,7 +82,6 @@ dependencies:
76
82
  type: :development
77
83
  prerelease: false
78
84
  version_requirements: !ruby/object:Gem::Requirement
79
- none: false
80
85
  requirements:
81
86
  - - ~>
82
87
  - !ruby/object:Gem::Version
@@ -84,7 +89,6 @@ dependencies:
84
89
  - !ruby/object:Gem::Dependency
85
90
  name: rspec
86
91
  requirement: !ruby/object:Gem::Requirement
87
- none: false
88
92
  requirements:
89
93
  - - ~>
90
94
  - !ruby/object:Gem::Version
@@ -92,7 +96,6 @@ dependencies:
92
96
  type: :development
93
97
  prerelease: false
94
98
  version_requirements: !ruby/object:Gem::Requirement
95
- none: false
96
99
  requirements:
97
100
  - - ~>
98
101
  - !ruby/object:Gem::Version
@@ -100,7 +103,6 @@ dependencies:
100
103
  - !ruby/object:Gem::Dependency
101
104
  name: simplecov
102
105
  requirement: !ruby/object:Gem::Requirement
103
- none: false
104
106
  requirements:
105
107
  - - ~>
106
108
  - !ruby/object:Gem::Version
@@ -108,7 +110,6 @@ dependencies:
108
110
  type: :development
109
111
  prerelease: false
110
112
  version_requirements: !ruby/object:Gem::Requirement
111
- none: false
112
113
  requirements:
113
114
  - - ~>
114
115
  - !ruby/object:Gem::Version
@@ -116,7 +117,6 @@ dependencies:
116
117
  - !ruby/object:Gem::Dependency
117
118
  name: webmock
118
119
  requirement: !ruby/object:Gem::Requirement
119
- none: false
120
120
  requirements:
121
121
  - - ~>
122
122
  - !ruby/object:Gem::Version
@@ -124,7 +124,6 @@ dependencies:
124
124
  type: :development
125
125
  prerelease: false
126
126
  version_requirements: !ruby/object:Gem::Requirement
127
- none: false
128
127
  requirements:
129
128
  - - ~>
130
129
  - !ruby/object:Gem::Version
@@ -132,23 +131,22 @@ dependencies:
132
131
  - !ruby/object:Gem::Dependency
133
132
  name: rake
134
133
  requirement: !ruby/object:Gem::Requirement
135
- none: false
136
134
  requirements:
137
- - - ! '>='
135
+ - - '>='
138
136
  - !ruby/object:Gem::Version
139
137
  version: '0'
140
138
  type: :development
141
139
  prerelease: false
142
140
  version_requirements: !ruby/object:Gem::Requirement
143
- none: false
144
141
  requirements:
145
- - - ! '>='
142
+ - - '>='
146
143
  - !ruby/object:Gem::Version
147
144
  version: '0'
148
145
  description: Ruby client for the Remind101 API.
149
146
  email:
150
147
  - eric@ejholmes.net
151
- executables: []
148
+ executables:
149
+ - remind101
152
150
  extensions: []
153
151
  extra_rdoc_files: []
154
152
  files:
@@ -160,13 +158,19 @@ files:
160
158
  - LICENSE.txt
161
159
  - README.md
162
160
  - Rakefile
161
+ - bin/remind101
163
162
  - lib/remind101.rb
164
163
  - lib/remind101/client.rb
164
+ - lib/remind101/client/access_tokens.rb
165
165
  - lib/remind101/client/connection.rb
166
166
  - lib/remind101/client/groups.rb
167
167
  - lib/remind101/client/messages.rb
168
- - lib/remind101/client/rescuable.rb
169
168
  - lib/remind101/client/subscribers.rb
169
+ - lib/remind101/command/auth.rb
170
+ - lib/remind101/command/base.rb
171
+ - lib/remind101/command/groups.rb
172
+ - lib/remind101/command/help.rb
173
+ - lib/remind101/command/messages.rb
170
174
  - lib/remind101/configuration.rb
171
175
  - lib/remind101/error.rb
172
176
  - lib/remind101/middleware/raise_error.rb
@@ -178,33 +182,26 @@ files:
178
182
  homepage: https://github.com/remind101/remind101.rb
179
183
  licenses:
180
184
  - MIT
185
+ metadata: {}
181
186
  post_install_message:
182
187
  rdoc_options: []
183
188
  require_paths:
184
189
  - lib
185
190
  required_ruby_version: !ruby/object:Gem::Requirement
186
- none: false
187
191
  requirements:
188
- - - ! '>='
192
+ - - '>='
189
193
  - !ruby/object:Gem::Version
190
194
  version: '0'
191
- segments:
192
- - 0
193
- hash: -555288322554717939
194
195
  required_rubygems_version: !ruby/object:Gem::Requirement
195
- none: false
196
196
  requirements:
197
- - - ! '>='
197
+ - - '>='
198
198
  - !ruby/object:Gem::Version
199
199
  version: '0'
200
- segments:
201
- - 0
202
- hash: -555288322554717939
203
200
  requirements: []
204
201
  rubyforge_project:
205
- rubygems_version: 1.8.23
202
+ rubygems_version: 2.0.14
206
203
  signing_key:
207
- specification_version: 3
204
+ specification_version: 4
208
205
  summary: Ruby client for the Remind101 API.
209
206
  test_files:
210
207
  - spec/remind101/client_spec.rb
@@ -1,27 +0,0 @@
1
- module Remind101::Client::Rescuable
2
-
3
- # Internal: Defines a version of the method that will be rescued from
4
- # ClientError's
5
- #
6
- # Example
7
- #
8
- # def my_method!
9
- # raise Remind101::Error::ClientError
10
- # end
11
- # def_rescued :my_method, :my_method!
12
- #
13
- # my_method
14
- # # => false
15
- #
16
- # Returns nothing.
17
- def def_rescued(new, original)
18
- define_method new do |*args, &block|
19
- begin
20
- __send__ original, *args, &block
21
- rescue Remind101::Error::ClientError
22
- false
23
- end
24
- end
25
- end
26
-
27
- end