Guest User

Untitled

a guest
Mar 11th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.84 KB | None | 0 0
  1. require 'rubygems'
  2. require 'eventmachine'
  3. require 'dataflow'
  4.  
  5. # Experimenting with dataflow + EM
  6. def do_pop_stuff
  7. pop_client = EventMachine::POP::POP3Client.new('pop.gmail.com', 995, true, 'username', 'password')
  8. print "stat: #{pop_client.stat}\n"
  9. pop_client.mails.each do |m|
  10. print m.raw + "\n"
  11. end
  12. end
  13.  
  14.  
  15. module EventMachine
  16. module POP
  17. class POPMail
  18. attr_accessor :uidl
  19.  
  20. def initialize(number, client)
  21. @number = number
  22. @client = client
  23. end
  24.  
  25. def header
  26. @client.header(@number)
  27. end
  28.  
  29. def raw
  30. @client.retr(@number)
  31. end
  32. end
  33.  
  34. class POP3Connection < EM::Connection
  35. include Protocols::LineText2
  36. include Dataflow
  37.  
  38. attr_accessor :username, :password, :guard
  39.  
  40. def self.connect(host, port, ssl, username, password, guard)
  41. p "connecting"
  42. EM.connect(host, port, self) do |c|
  43. c.username = username
  44. c.password = password
  45. c.guard = guard
  46. end
  47. end
  48.  
  49. def post_init
  50. start_tls
  51. @responder = :login
  52. @mails = []
  53. p "post init"
  54. end
  55.  
  56. def login
  57. p "logging in"
  58. send_data "USER #{username}\r\n"
  59. @responder = :receive_user
  60. end
  61.  
  62. def receive_user
  63. send_data "PASS #{password}\r\n"
  64. @responder = :receive_auth_response
  65. end
  66.  
  67. def receive_auth_response
  68. if @line.match(/\+OK/)
  69. unify @guard, ""
  70. else
  71. raise StandardError, "Could not authenticate"
  72. end
  73. end
  74.  
  75. def send_data(data)
  76. p "send: #{data}"
  77. super
  78. end
  79.  
  80. def receive_line(line)
  81. p "recv: #{line}"
  82. @line = line
  83. send @responder if @responder
  84. end
  85.  
  86. def auth_guard
  87. @guard.object_id # force wait on variable
  88. end
  89.  
  90. def send_command(command, *args)
  91. auth_guard
  92.  
  93. @responder = "receive_#{command.downcase}"
  94.  
  95. data = command
  96. data += " " + args.join(" ") unless args.empty?
  97. send_data "#{data}\r\n"
  98.  
  99. @result = Dataflow::Variable.new
  100. end
  101.  
  102. def stat
  103. p "sSTAT"
  104. send_command("STAT")
  105. end
  106.  
  107. def receive_stat
  108. matches = @line.match(/\+OK (\d+) (\d+)/)
  109. unify @result, matches[1].to_i
  110. end
  111.  
  112. def retr(number)
  113. @body = []
  114. send_command("RETR", number)
  115. end
  116.  
  117. def receive_retr
  118. if @line =~ /^\+OK/
  119. # ignore
  120. elsif @line == "."
  121. unify @result, @body.join("\n")
  122. else
  123. @body << @line
  124. end
  125. end
  126.  
  127. def header(number)
  128. send_command("TOP", number, 0)
  129. end
  130.  
  131. def receive_header
  132. if @line =~ /^\+OK/
  133. # ignore
  134. elsif @line == "."
  135. unify @result, @header.join("\n")
  136. else
  137. @header << @line
  138. end
  139. end
  140.  
  141. def mails
  142. @mail ||= send_command("UIDL")
  143. end
  144.  
  145. def receive_uidl
  146. if @line == "."
  147. unify @result, @mails
  148. elsif @line == "+OK"
  149. # ignore
  150. else
  151. matches = @line.match(/(\d+) (.*)/)
  152. mail = POPMail.new(matches[1], self)
  153. mail.uidl = matches[2]
  154. @mails << mail
  155. end
  156. end
  157.  
  158. def queue_command(*args)
  159. end
  160.  
  161. def do_next_command
  162. end
  163.  
  164. def need_raw_mails
  165. end
  166.  
  167. end
  168.  
  169. class POP3Client
  170. include Dataflow
  171.  
  172. def initialize(*args)
  173. @connection = nil
  174. guard = Dataflow::Variable.new
  175.  
  176. EM.next_tick {
  177. @connection = EventMachine::POP::POP3Connection.connect(*args.push(guard))
  178. }
  179.  
  180. guard.object_id # wait until connection is complete
  181. @connection
  182. end
  183.  
  184. def method_missing(*args)
  185. @connection.send(*args)
  186. end
  187. end
  188. end
  189. end
  190.  
  191. EM.run {
  192.  
  193. Thread.abort_on_exception = true
  194. EM.defer {
  195. do_pop_stuff
  196. }
  197.  
  198. }
Add Comment
Please, Sign In to add comment