atheme-ruby 0.0.3 → 0.0.4

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.
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