remind101 0.1.2 → 0.2.0

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