cinch 2.0.3 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,83 @@
1
+ module Cinch
2
+ # Provide blocking access to user/channel information.
3
+ module Syncable
4
+ # Blocks until the object is synced.
5
+ #
6
+ # @return [void]
7
+ # @api private
8
+ def wait_until_synced(attr)
9
+ attr = attr.to_sym
10
+ waited = 0
11
+ while true
12
+ return if attribute_synced?(attr)
13
+ waited += 1
14
+
15
+ if waited % 100 == 0
16
+ bot.loggers.warn "A synced attribute ('%s' for %s) has not been available for %d seconds, still waiting" % [attr, self.inspect, waited / 10]
17
+ bot.loggers.warn caller.map {|s| " #{s}"}
18
+
19
+ if waited / 10 >= 30
20
+ bot.loggers.warn " Giving up..."
21
+ raise Exceptions::SyncedAttributeNotAvailable, "'%s' for %s" % [attr, self.inspect]
22
+ end
23
+ end
24
+ sleep 0.1
25
+ end
26
+ end
27
+
28
+ # @api private
29
+ # @return [void]
30
+ def sync(attribute, value, data = false)
31
+ if data
32
+ @data[attribute] = value
33
+ else
34
+ instance_variable_set("@#{attribute}", value)
35
+ end
36
+ @synced_attributes << attribute
37
+ end
38
+
39
+ # @return [Boolean]
40
+ # @api private
41
+ def attribute_synced?(attribute)
42
+ @synced_attributes.include?(attribute)
43
+ end
44
+
45
+ # @return [void]
46
+ # @api private
47
+ def unsync(attribute)
48
+ @synced_attributes.delete(attribute)
49
+ end
50
+
51
+ # @return [void]
52
+ # @api private
53
+ # @since 1.0.1
54
+ def unsync_all
55
+ @synced_attributes.clear
56
+ end
57
+
58
+ # @param [Symbol] attribute
59
+ # @param [Boolean] data
60
+ # @param [Boolean] unsync
61
+ # @api private
62
+ def attr(attribute, data = false, unsync = false)
63
+ unless unsync
64
+ if @when_requesting_synced_attribute
65
+ @when_requesting_synced_attribute.call(attribute)
66
+ end
67
+ wait_until_synced(attribute)
68
+ end
69
+
70
+ if data
71
+ return @data[attribute]
72
+ else
73
+ return instance_variable_get("@#{attribute}")
74
+ end
75
+ end
76
+
77
+ # @api private
78
+ # @return [void]
79
+ def mark_as_synced(attribute)
80
+ @synced_attributes << attribute
81
+ end
82
+ end
83
+ end
@@ -90,7 +90,8 @@ module Cinch
90
90
  # of IO or String).
91
91
  #
92
92
  # @param [#<<] io The object to write the data to.
93
- # @return [void]
93
+ # @return [Boolean] True if the transfer finished
94
+ # successfully, false otherwise.
94
95
  # @note This method blocks.
95
96
  # @example Saving to a file
96
97
  # f = File.open("/tmp/foo", "w")
@@ -103,12 +104,28 @@ module Cinch
103
104
  def accept(io)
104
105
  socket = TCPSocket.new(@ip, @port)
105
106
  total = 0
106
- while buf = socket.read(1024)
107
+
108
+ while buf = socket.readpartial(8192)
107
109
  total += buf.bytesize
108
110
 
109
- socket.write [total].pack("N")
111
+ begin
112
+ socket.write_nonblock [total].pack("N")
113
+ rescue Errno::EWOULDBLOCK, Errno::AGAIN
114
+ # Nobody cares about ACKs, really. And if the sender
115
+ # couldn't receive it at this point, he probably doesn't
116
+ # care, either.
117
+ end
110
118
  io << buf
119
+
120
+ # Break here in case the sender doesn't close the
121
+ # connection on the final ACK.
122
+ break if total == @size
111
123
  end
124
+
125
+ socket.close
126
+ return true
127
+ rescue EOFError
128
+ return false
112
129
  end
113
130
 
114
131
  # @return [Boolean] True if the DCC originates from a private ip
@@ -544,8 +544,8 @@ module Cinch
544
544
  end
545
545
 
546
546
 
547
- if msg.message =~ /^\001DCC SEND (\S+) (\d+) (\d+)(?: (\d+))?\001$/
548
- process_dcc_send($1, $2, $3, $4, msg, events)
547
+ if msg.message =~ /^\001DCC SEND (?:"([^"]+)"|(\S+)) (\d+) (\d+)(?: (\d+))?\001$/
548
+ process_dcc_send($1 || $2, $3, $4, $5, msg, events)
549
549
  end
550
550
  end
551
551
 
@@ -24,6 +24,9 @@ module Cinch
24
24
 
25
25
  # @since 2.0.0
26
26
  def unregister_plugins(plugins)
27
+ if plugins == self
28
+ plugins = self.dup
29
+ end
27
30
  plugins.each { |plugin| unregister_plugin(plugin) }
28
31
  end
29
32
 
@@ -26,7 +26,7 @@ class String
26
26
  self.tr("a-z", "A-Z")
27
27
  when :rfc1459
28
28
  self.tr("a-z{}|~", "A-Z[]\\\\^")
29
- when :strict-rfc1459
29
+ when :"strict-rfc1459"
30
30
  self.tr("a-z{}|", "A-Z[]\\\\")
31
31
  end
32
32
  end
@@ -35,6 +35,12 @@ module Cinch
35
35
  # @param [String] payload
36
36
  # @return [String]
37
37
  def generate(user, password, payload)
38
+ # duplicate the passed strings because we are modifying them
39
+ # later and they might come from the configuration store or
40
+ # similar
41
+ user = user.dup
42
+ password = password.dup
43
+
38
44
  data = Base64.decode64(payload).force_encoding("ASCII-8BIT")
39
45
 
40
46
  p, g, y = unpack_payload(data)
@@ -294,7 +294,7 @@ module Cinch
294
294
  if @bot.irc.isupport["MONITOR"] > 0
295
295
  @bot.irc.send "MONITOR - #@name"
296
296
  else
297
- @monitored_timer.stop
297
+ @monitored_timer.stop if @monitored_timer
298
298
  end
299
299
 
300
300
  @monitored = false
@@ -1,4 +1,4 @@
1
1
  module Cinch
2
2
  # Version of the library
3
- VERSION = '2.0.3'
3
+ VERSION = '2.0.4'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cinch
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.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: 2012-06-27 00:00:00.000000000 Z
12
+ date: 2013-02-05 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A simple, friendly DSL for creating IRC bots
15
15
  email:
@@ -47,6 +47,7 @@ files:
47
47
  - lib/cinch/isupport.rb
48
48
  - lib/cinch/helpers.rb
49
49
  - lib/cinch/handler.rb
50
+ - lib/cinch/#syncable.rb#
50
51
  - lib/cinch/handler_list.rb
51
52
  - lib/cinch/rubyext/module.rb
52
53
  - lib/cinch/rubyext/float.rb