atheme-ruby 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -50,12 +50,12 @@ If an option is missing, the default ones as stated above are used.
50
50
 
51
51
  ### Login
52
52
 
53
- The initial session uses an anonymous login which can be re-choosen by logging out.
53
+ The initial session uses an anonymous login which can be re-choosen by logging out.
54
54
 
55
55
  To login with an account registered with NickServ use the following:
56
56
 
57
57
  @session.login(username, password, ip="127.0.0.1") #=> you'll get a cookie on success
58
- @session.logged_in? #=> true or false
58
+ @session.logged_in? #=> true or false
59
59
 
60
60
  The cookie is a random generated string from Atheme for your current login session and will be valid for one(1) hour or until the server is shut down or restarted.
61
61
 
@@ -76,7 +76,7 @@ You can call any commands you want to perform like you do on IRC; Each param goe
76
76
 
77
77
  @session.chanserv.info('#opers') # /msg chanserv info #opers
78
78
  @session.chanserv.list # /msg chanserv list
79
- @session.nickserv.mark("Nick", "ON", "marking Nick") # Marks Nick with a note
79
+ @session.nickserv.mark!("Nick", "ON", "marking Nick") # Marks Nick with a note
80
80
 
81
81
  I think you're getting the point...
82
82
  However, you can perform additional questions on these return values:
@@ -90,19 +90,41 @@ Or a bit simplier if you want to run multiple ones on one User/Channel/...
90
90
 
91
91
  @session.nickserv.info("Nick") do |n|
92
92
  n.mark!("marking...")
93
- n.set_vhost!("omg.that.is.awesome")
93
+ n.vhost!("omg.that.is.awesome")
94
94
  n.reset_password!
95
95
  end
96
96
 
97
97
  Take a look into _lib/atheme/services/*_ and _lib/atheme/entities/*_ to find available subcommands.
98
98
  The commands which call the API return a Atheme::Entity or a subclass like Atheme::User or Atheme::Channel etc. You can call #raw_output on these to get the raw service reply of the command you called.
99
99
 
100
+ ### Error-Handling
101
+
102
+ Errors can occur if you do not have the permissions to run a command you would like, specifies the wrong arguments or forget one.
103
+ There are many possibilities that something went wrong, especially if you have a long command-chain.
104
+
105
+ You can test if your command or your command-chain run successfully by asking #success? or #error? on it.
106
+
107
+ cmd = @session.chanserv.info("#opers").fdrop!
108
+ cmd.success? #=> true on success, false otherwise
109
+
110
+ If the API returned an error, you can inspect it:
111
+
112
+ cmd.error #=> Holds the Exception ($!)
113
+ cmd.skipped_methods #=> Array of [method, args, block] which have been skipped due to the exception
114
+
115
+ You can read more about the fault codes here: [Atheme XMLRPC - Fault codes](https://github.com/atheme/atheme/blob/master/doc/XMLRPC#L106)
116
+
117
+
118
+ ### Known limitations/bugs
119
+
120
+ * [Attributes of entities do not update until refetch/reinitialize of the whole object](https://github.com/Flauschbaellchen/atheme-ruby/issues/1)
121
+
122
+
100
123
  TODO
101
124
  ----
102
125
  * Tests!
103
126
  * Docs!
104
127
  * Add more parsers/subcommands to all kinds of services (pull requests welcome)
105
- * Brainstorming: Catch API-Errors and handle them gracefully. Provide a #success? method to decide if the command was successfully executed or not. Need to handle chains like the ones above.
106
128
 
107
129
  Contributing to atheme-ruby
108
130
  ---------------------------
@@ -5,6 +5,85 @@ module Atheme
5
5
  @session.chanserv.info(@token)
6
6
  end
7
7
 
8
+ # Returns the channel's name
9
+ def name
10
+ match(/^Information\son\s([&#+][^:]+):$/)
11
+ end
12
+
13
+ # Returns the founder as an Atheme::User object
14
+ def founder
15
+ Atheme::User.new(@session, match(/Founder\s+:\s+(\w+)/))
16
+ end
17
+
18
+ # Returns the successor as an Atheme::User object
19
+ # Returns nil if noone has been set
20
+ def successor
21
+ match(/Successor\s+:\s+\(none\)/) ? nil : Atheme::User.new(@session, match(/Successor\s+:\s+(\w+)/))
22
+ end
23
+
24
+ # Date object which is set to the time when the channel was registered
25
+ def registered
26
+ Date.parse(match(/Registered\s+:\s+(\w+ [0-9]{2} [0-9(:?)]+ [0-9]{4})/))
27
+ end
28
+
29
+ # Date object which is set to the time when the channel was last used
30
+ def last_used
31
+ Date.parse(match(/Last\sused\s+:\s+(\w+ [0-9]{2} [0-9(:?)]+ [0-9]{4})/)) rescue nil
32
+ end
33
+
34
+ # String of the mode locked on the channel, e.g. "+Ctn-ksi"
35
+ def mlock
36
+ match(/Mode\slock\s+:\s+([-+A-Za-z0-9]*)/)
37
+ end
38
+ alias_method :mode_lock, :mlock
39
+
40
+ # Sets the given mlock/mode lock on the channel, e.g. +mntF-kljf or +ntlL 40 #foo2
41
+ def mlock!(modes)
42
+ @session.chanserv.set(self.name, :mlock, modes)
43
+ end
44
+ alias_method :mode_lock!, :mlock!
45
+
46
+ # Entry message of the channel, if set - otherwise nil.
47
+ def entrymsg
48
+ match(/Entrymsg\s+:\s+(.+)/)
49
+ end
50
+
51
+ # Sets the entrymsg for the channel.
52
+ # Call without arguments to clear it.
53
+ def entrymsg!(msg=nil)
54
+ msg.kind_of?(String) ? @session.chanserv.set(self.name, :entrymsg, msg) : @session.chanserv.set(self.name, :entrymsg)
55
+ end
56
+
57
+ # Returns the hannel's URL if one has been set, otherwise nil.
58
+ def url
59
+ match(/URL\s+:\s+(.+)/)
60
+ end
61
+
62
+ # Sets the URL for the channel.
63
+ # Call without arguments to clear it.
64
+ def url!(url=nil)
65
+ url.kind_of?(String) ? @session.chanserv.set(self.name, :url, url) : @session.chanserv.set(self.name, :url)
66
+ end
67
+
68
+ # Array of channel flags
69
+ def flags
70
+ match(/Flags\s+:\s+(.+)$/).split rescue []
71
+ end
72
+
73
+ # Prefix character used on the channel, e.g. "!"
74
+ def prefix
75
+ match(/Prefix\s+:\s+([^\s])/)
76
+ end
77
+
78
+ # Allows you to customize the channel fantasy trigger
79
+ # for your channel. This is particularly useful if you have
80
+ # channel bots that conflict with ChanServ's default fantasy
81
+ # prefix. Providing no prefix argument (or DEFAULT) resets
82
+ # the channel fantasy prefix to the network default prefix
83
+ def prefix!(prefix="DEFAULT")
84
+ @session.chanserv.set(self.name, :prefix, prefix)
85
+ end
86
+
8
87
  # Forcefully removes the channel, including
9
88
  # all data associated with it (like access lists etc)
10
89
  # and cannot be restored.
@@ -13,7 +92,7 @@ module Atheme
13
92
  @session.chanserv.fdrop(self.name)
14
93
  end
15
94
 
16
- # close! prevents a channel from being used. Anyone
95
+ # close prevents a channel from being used. Anyone
17
96
  # who enters is immediately kickbanned. The channel
18
97
  # cannot be dropped and foundership cannot be
19
98
  # transferred.
@@ -21,7 +100,7 @@ module Atheme
21
100
  # On executing this method, it will immediately kick all
22
101
  # users from the channel.
23
102
  #
24
- # Use unclose!/open! to reopen a channel. While closed,
103
+ # Use unclose/open to reopen a channel. While closed,
25
104
  # channels will still expire.
26
105
  #
27
106
  # Only opers may use this.
@@ -35,7 +114,7 @@ module Atheme
35
114
  def open!
36
115
  @session.chanserv.close(self.name, :off)
37
116
  end
38
- alias_method :unclose!, :open!
117
+ alias_method :unclose, :open
39
118
 
40
119
  # Gives someone channel admin/protection (+a) permissions
41
120
  # If the nick is omitted the action is performed
@@ -103,7 +182,7 @@ module Atheme
103
182
  change_permissions(:devoice, nick)
104
183
  end
105
184
 
106
- # mark! allows operators to attach a note to a channel.
185
+ # mark allows operators to attach a note to a channel.
107
186
  # For example, an operator could mark the channel to be a botnet channel.
108
187
  def mark!(reason)
109
188
  @session.chanserv.mark(self.name, :on, reason)
@@ -131,12 +210,12 @@ module Atheme
131
210
  end
132
211
 
133
212
  # Allows you to ban a user or hostmask from a channel.
134
- def ban!(nick_or_host)
213
+ def ban(nick_or_host)
135
214
  @session.chanserv.ban(self.name, nick_or_host)
136
215
  end
137
216
 
138
217
  # Allows you to unban a user or hostmask from a channel.
139
- def unban!(nick_or_host)
218
+ def unban(nick_or_host)
140
219
  @session.chanserv.unban(self.name, nick_or_host)
141
220
  end
142
221
 
@@ -145,7 +224,7 @@ module Atheme
145
224
  #
146
225
  # Your nick will be added to the kick reason.
147
226
  # The reason is optional./cs
148
- def kick!(reason=nil)
227
+ def kick(reason=nil)
149
228
  reason.kind_of?(String) ? @session.chanserv.kick(self.name, nick) : @session.chanserv.kick(self.name, nick, reason)
150
229
  end
151
230
 
@@ -160,7 +239,7 @@ module Atheme
160
239
  end
161
240
 
162
241
  private
163
- def change_permissions(perm, nick=nil)
242
+ def change_permissions(perm, nick)
164
243
  case
165
244
  when nick.kind_of?(String)
166
245
  @session.chanserv.send(perm, self.name, nick)
@@ -169,8 +248,8 @@ module Atheme
169
248
  when nick.kind_of?(Array)
170
249
  nick.each do |n|
171
250
  change_permissions(perm, self.name, n)
172
- end
173
- end
251
+ end
252
+ end
174
253
  end
175
254
 
176
255
  end
@@ -5,6 +5,77 @@ module Atheme
5
5
  @session.nickserv.info(@token)
6
6
  end
7
7
 
8
+ # Returns the nickname (not account name) of the user
9
+ def name
10
+ match(/^Information\son\s([^\s]+)/)
11
+ end
12
+
13
+ # Returns the account name of the user as an Atheme::User object
14
+ def account
15
+ Atheme::User.new(@session, match(/\(account\s([^\(]+)\):/))
16
+ end
17
+
18
+ # Date object which is set to the time when the nick was registered
19
+ def registered
20
+ Date.parse(match(/Registered\s+:\s+(\w+ [0-9]{2} [0-9(:?)]+ [0-9]{4})/))
21
+ end
22
+
23
+ # Unique entity ID. Available only if the user is currently connected
24
+ def entity_id
25
+ match(/Entity\sID\s+:\s+([A-F0-9]+)$/)
26
+ end
27
+
28
+ # Returns the vhost of the nick if set
29
+ def vhost
30
+ match(/vHost\s+:\s+([^\s]+)$/)
31
+ end
32
+
33
+ # Real address of the user's connection
34
+ def real_address
35
+ match(/Real\saddr\s+:\s+([^\s]+)$/)
36
+ end
37
+
38
+ # Date object of the time when the nick was last seen
39
+ def last_seen
40
+ Date.parse(match(/Last\sseen\s+:\s+(\w+ [0-9]{2} [0-9(:?)]+ [0-9]{4})/))
41
+ end
42
+
43
+ # Date object of the time when the user was last seen
44
+ def user_seen
45
+ Date.parse(match(/User\sseen\s+:\s+(\w+ [0-9]{2} [0-9(:?)]+ [0-9]{4})/)) rescue nil
46
+ end
47
+
48
+ # Returns an array of linked nicknames to this nick/account
49
+ def nicks
50
+ match(/Nicks\s+:\s+([^\s]+(?:\s[^\s]+)*)$/).split rescue []
51
+ end
52
+
53
+ # Returns the user's email
54
+ def email
55
+ match(/Email\s+:\s+([^\s]+)/)
56
+ end
57
+
58
+ # Returns the user's language
59
+ def language
60
+ match(/Language\s+:\s+([\w]+)$/)
61
+ end
62
+
63
+ # Returns the user's flags as an array, e.g. HideMail
64
+ def flags
65
+ match(/Flags\s+:\s+(.+)$/).split rescue []
66
+ end
67
+
68
+ # Returns true if the user enabled nick protection, false otherwise
69
+ def protected
70
+ match(/has\s(enabled)\snick\sprotection/) ? true : false
71
+ end
72
+ alias_method :protected?, :protected
73
+
74
+ # Returns the user's groups as an array,
75
+ def groups
76
+ match(/Groups\s+:\s+(.+)$/).split rescue []
77
+ end
78
+
8
79
  # Forcefully removes the account, including
9
80
  # all nicknames, channel access and memos attached to it.
10
81
  # Only opers may use this.
@@ -12,7 +83,7 @@ module Atheme
12
83
  @session.nickserv.fdrop(self.name)
13
84
  end
14
85
 
15
- # freeze! allows operators to "freeze" an abusive user's
86
+ # freeze allows operators to "freeze" an abusive user's
16
87
  # account. This logs out all sessions logged in to the
17
88
  # account and prevents further logins. Thus, users
18
89
  # cannot obtain the access associated with the account.
@@ -25,7 +96,7 @@ module Atheme
25
96
  @session.nickserv.freeze(self.name, :off)
26
97
  end
27
98
 
28
- # mark! allows operators to attach a note to an account.
99
+ # mark allows operators to attach a note to an account.
29
100
  # For example, an operator could mark the account of
30
101
  # a spammer so that others know the user has previously
31
102
  # been warned.
@@ -38,12 +109,13 @@ module Atheme
38
109
  @session.nickserv.mark(self.name, :off)
39
110
  end
40
111
 
41
- # vhost! allows operators to set a virtual host (also
112
+ # vhost allows operators to set a virtual host (also
42
113
  # known as a spoof or cloak) on an account. This vhost
43
114
  # will be set on the user immediately and each time
44
115
  # they identify
45
- def set_vhost!(vhost)
46
- @session.nickserv.vhost(self.name, :on, vhost)
116
+ # If no vhost is given, the current one will be deleted.
117
+ def vhost!(vhost=nil)
118
+ vhost.nil? ? remove_vhost! : @session.nickserv.vhost(self.name, :on, vhost)
47
119
  end
48
120
 
49
121
  # Removes a previously added vhost from the account
data/lib/atheme/entity.rb CHANGED
@@ -42,8 +42,13 @@ module Atheme
42
42
  def fetchable?
43
43
  true
44
44
  end
45
-
46
45
  private :do_fetch!, :fetchable?
46
+
47
+ private
48
+ def match(expression)
49
+ raw_output[expression, 1]
50
+ end
51
+
47
52
  end
48
53
 
49
54
  class Entity < EntityBase
@@ -0,0 +1,23 @@
1
+ module Atheme
2
+ class Error
3
+ attr_reader :error, :skipped_methods
4
+
5
+ def initialize(error=nil)
6
+ @error = error || $!
7
+ @skipped_methods = []
8
+ end
9
+
10
+ def success?
11
+ false
12
+ end
13
+
14
+ def error?
15
+ true
16
+ end
17
+
18
+ def method_missing(meth, *args, &block)
19
+ @skipped_methods << [meth, args, block]
20
+ self
21
+ end
22
+ end
23
+ end
@@ -39,8 +39,7 @@ module Atheme
39
39
  end
40
40
 
41
41
  def match(expression)
42
- ematch = expression.match(raw_output)
43
- ematch && ematch[1]
42
+ raw_output[expression, 1]
44
43
  end
45
44
  end
46
45
 
@@ -76,8 +75,11 @@ module Atheme
76
75
  end
77
76
 
78
77
  def method_missing(method, *args, &block)
79
- raw_output = @session.service_call(service_name, method, *args)
80
-
78
+ begin
79
+ raw_output = @session.service_call(service_name, method, *args)
80
+ rescue
81
+ return Atheme::Error.new
82
+ end
81
83
  response = {raw_output: raw_output}
82
84
  parser = @@parsers.has_key?(service_name) && @@parsers[service_name][method]
83
85
 
@@ -3,44 +3,6 @@ module Atheme
3
3
 
4
4
  parse :info do
5
5
  responds_with Atheme::Channel
6
-
7
- command :name do
8
- match(/^Information\son\s([&#+][^:]+):$/)
9
- end
10
-
11
- command :founder, as: Atheme::User do
12
- match(/Founder\s+:\s+(\w+)/)
13
- end
14
-
15
- command :successor, as: Atheme::User do
16
- match(/Successor\s+:\s+\(none\)/) ? nil : match(/Successor\s+:\s+(\w+)/)
17
- end
18
-
19
- command :registered do
20
- Date.parse(match(/Registered\s+:\s+(\w+ [0-9]{2} [0-9(:?)]+ [0-9]{4})/))
21
- end
22
-
23
- command :last_used do
24
- time = match(/Last\sused\s+:\s+(\w+ [0-9]{2} [0-9(:?)]+ [0-9]{4})/)
25
- time && Date.parse(time)
26
- end
27
-
28
- command :mode_lock do
29
- match(/Mode\slock\s+:\s+([-+A-Za-z0-9]*)/)
30
- end
31
-
32
- command :entry_msg do
33
- match(/Entrymsg\s+:\s+(.+)/)
34
- end
35
-
36
- command :flags do
37
- flags = match(/Flags\s+:\s+(\w+(?:\s\w+)*)$/)
38
- flags && flags.split || []
39
- end
40
-
41
- command :prefix do
42
- match(/Prefix\s+:\s+([^\s])/)
43
- end
44
6
  end
45
7
 
46
8
  parse :list do
@@ -3,66 +3,7 @@ module Atheme
3
3
 
4
4
  parse :info do
5
5
  responds_with Atheme::User
6
-
7
- command :name do
8
- match(/^Information\son\s([^\s]+)/)
9
- end
10
-
11
- command :account, as: Atheme::User do
12
- match(/\(account\s([^\(]+)\):/)
13
- end
14
-
15
- command :registered do
16
- Date.parse(match(/Registered\s+:\s+(\w+ [0-9]{2} [0-9(:?)]+ [0-9]{4})/))
17
- end
18
-
19
- command :entity_id do
20
- match(/Entity\sID\s+:\s+([A-F0-9]+)$/)
21
- end
22
-
23
- command :vhost do
24
- match(/vHost\s+:\s+([^\s]+)$/)
25
- end
26
-
27
- command :real_address do
28
- match(/Real\saddr\s+:\s+([^\s]+)$/)
29
- end
30
-
31
- command :last_seen do
32
- Date.parse(match(/Last\sseen\s+:\s+(\w+ [0-9]{2} [0-9(:?)]+ [0-9]{4})/))
33
- end
34
-
35
- command :user_seen do
36
- time = match(/User\sseen\s+:\s+(\w+ [0-9]{2} [0-9(:?)]+ [0-9]{4})/)
37
- time && Date.parse(time)
38
- end
39
-
40
- command :nicks do
41
- nicks = match(/Nicks\s+:\s+([^\s]+(?:\s[^\s]+)*)$/)
42
- nicks && nicks.split || []
43
- end
44
-
45
- command :email do
46
- match(/Email\s+:\s+([^\s]+)/)
47
- end
48
-
49
- command :language do
50
- match(/Language\s+:\s+([\w]+)$/)
51
- end
52
-
53
- command :flags do
54
- flags = match(/Flags\s+:\s+(\w+(?:\s\w+)*)$/)
55
- flags && flags.split || []
56
- end
57
-
58
- command :protected do
59
- match(/has\s(enabled)\snick\sprotection/) ? true : false
60
- end
61
-
62
- command :groups do
63
- flags = match(/Groups\s+:\s+(.+)$/)
64
- flags && flags.split || []
65
- end
66
6
  end
7
+
67
8
  end
68
9
  end
@@ -1,3 +1,3 @@
1
1
  module Atheme
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/atheme.rb CHANGED
@@ -3,6 +3,7 @@ end
3
3
 
4
4
  require "xmlrpc/client"
5
5
 
6
+ require "atheme/error"
6
7
  require "atheme/helpers"
7
8
  require "atheme/version"
8
9
  require "atheme/session"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atheme-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-29 00:00:00.000000000 Z
12
+ date: 2013-08-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -60,6 +60,7 @@ files:
60
60
  - lib/atheme/entities/channel.rb
61
61
  - lib/atheme/entities/user.rb
62
62
  - lib/atheme/entity.rb
63
+ - lib/atheme/error.rb
63
64
  - lib/atheme/helpers.rb
64
65
  - lib/atheme/service.rb
65
66
  - lib/atheme/services/chanserv.rb