From 3de478f8bae8a123e5f5ad477b1dd2700a981324 Mon Sep 17 00:00:00 2001 From: Yaroslav Sidlovsky Date: Mon, 10 Sep 2018 19:16:35 +0300 Subject: [PATCH] test client added + some changes --- src/imap.cr | 44 +++++++++++++++++++++++++++++++++----------- test.cr | 22 ++++++++++++++++++++++ 2 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 test.cr diff --git a/src/imap.cr b/src/imap.cr index d19c30a..7515676 100644 --- a/src/imap.cr +++ b/src/imap.cr @@ -9,9 +9,8 @@ module Imap @logger : Logger def initialize(host = "imap.gmail.com", port = 993, username = "", password = "", loglevel = Logger::ERROR) - @logger = Logger.new(STDOUT) + @logger = Logger.new(STDERR) @logger.level = loglevel - @mailboxes = [] of String @socket = TCPSocket.new(host, port) tls_socket = OpenSSL::SSL::Socket::Client.new(@socket.as(TCPSocket), sync_close: true, hostname: host) @@ -33,15 +32,24 @@ module Imap end private def command(command : String, *parameters, &block : String -> Bool) - command_and_parameter = "tag #{command}" - params = parameters.join(" ") - command_and_parameter += " #{params}" if params && params.size > 0 - @logger.info "=====> #{command_and_parameter}" + command_and_parameter = case command + when "DONE" + command + else + "tag #{command}" + end + + if parameters.size > 0 + params = parameters.join(" ") + command_and_parameter += " #{params}" + end socket << command_and_parameter << "\r\n" socket.flush + @logger.debug "Sent: #{command_and_parameter}" while (line = socket.gets) + @logger.debug " Got: #{line}" break unless block.call(line) end end @@ -78,14 +86,28 @@ module Imap # Sends an IDLE command, # raises exception if server doesn't support IDLE - def idle + def idle(&block : String, UInt32 ->) raise "Server doesn't support IDLE" unless @caps.includes?("IDLE") - command("IDLE") do |line| - puts line - true + + spawn do + command("IDLE") do |line| + if line =~ /\+ idling/ + # nothing to do + elsif line =~ /\* (\d+) ([A-Z]+)/ + block.call($2, $1.to_u32) + else + next false + end + true + end end end + # Sends a DONE command + def done + command("DONE") + end + # Sends a SELECT command to select a +mailbox+ so that messages # in the +mailbox+ can be accessed. def select(mailbox) @@ -166,7 +188,7 @@ module Imap end end if ip && from - @logger.info "from: #{from} ip: #{ip}" + @logger.debug "from: #{from} ip: #{ip}" from = nil ip = nil end diff --git a/test.cr b/test.cr new file mode 100644 index 0000000..3bbed9d --- /dev/null +++ b/test.cr @@ -0,0 +1,22 @@ +require "logger" + +require "./imap" + +if ARGV.size < 2 + STDERR.puts "Usage: #{PROGRAM_NAME} " + exit 1 +end + +imap = Imap::Client.new(host: "imap.gmail.com", port: 993, username: ARGV[0], password: ARGV[1], loglevel: Logger::DEBUG) +mailboxes = imap.list +if mailboxes.includes?("INBOX") + imap.select("INBOX") + imap.idle do |name, value| + puts "#{name} => #{value}" + end +end + +while true + sleep 5 + imap.done +end