mirror of
https://github.com/Cocoanetics/SwiftMail.git
synced 2026-03-17 20:02:25 +00:00
cleanup
This commit is contained in:
@@ -30,17 +30,7 @@ LoggingSystem.bootstrap { label in
|
||||
// Create a logger for the main application using Swift Logging
|
||||
let logger = Logger(label: "com.cocoanetics.SwiftIMAP.Main")
|
||||
|
||||
// Helper function for debug prints - only prints when ENABLE_DEBUG_OUTPUT is set
|
||||
func debugPrint(_ message: String) {
|
||||
if ProcessInfo.processInfo.environment["ENABLE_DEBUG_OUTPUT"] == "1" {
|
||||
print("DEBUG: \(message)")
|
||||
}
|
||||
}
|
||||
|
||||
print("📧 SwiftIMAPCLI - Email Reading Test")
|
||||
print("Debug mode: OS_LOG_DISABLE=\(ProcessInfo.processInfo.environment["OS_LOG_DISABLE"] ?? "not set")")
|
||||
print("Debug mode: OS_ACTIVITY_MODE=\(ProcessInfo.processInfo.environment["OS_ACTIVITY_MODE"] ?? "not set")")
|
||||
print("Debug mode: SWIFT_LOG_LEVEL=\(ProcessInfo.processInfo.environment["SWIFT_LOG_LEVEL"] ?? "not set")")
|
||||
|
||||
do {
|
||||
// Configure SwiftDotenv with the specified path
|
||||
@@ -72,7 +62,6 @@ do {
|
||||
logger.info("Host: \(host)")
|
||||
logger.info("Port: \(port)")
|
||||
logger.info("Username: \(username)")
|
||||
debugPrint("IMAP configuration: \(host):\(port) with username \(username)")
|
||||
|
||||
// Create an IMAP server instance
|
||||
let server = IMAPServer(host: host, port: port)
|
||||
@@ -81,20 +70,13 @@ do {
|
||||
await Task {
|
||||
do {
|
||||
// Connect to the server
|
||||
debugPrint("Connecting to IMAP server \(host):\(port)...")
|
||||
try await server.connect()
|
||||
debugPrint("Connection established successfully")
|
||||
|
||||
// Login with credentials
|
||||
debugPrint("Authenticating with username \(username)...")
|
||||
try await server.login(username: username, password: password)
|
||||
debugPrint("Authentication successful")
|
||||
|
||||
// Detect standard folders
|
||||
logger.notice("Detecting standard folders...")
|
||||
debugPrint("Detecting standard folders...")
|
||||
let detectedConfig = try await server.detectStandardFolders()
|
||||
debugPrint("Standard folders detected successfully")
|
||||
|
||||
// Print detected folder configuration
|
||||
print("\n📁 Detected Standard Folders:")
|
||||
@@ -106,26 +88,19 @@ do {
|
||||
print("")
|
||||
|
||||
// Select the INBOX mailbox and get mailbox information
|
||||
debugPrint("Selecting INBOX mailbox...")
|
||||
let mailboxStatus = try await server.selectMailbox("INBOX")
|
||||
debugPrint("INBOX selected. Message count: \(mailboxStatus.messageCount)")
|
||||
|
||||
|
||||
// Print mailbox information
|
||||
if mailboxStatus.messageCount > 0 {
|
||||
// Fetch the 10 latest complete emails including attachments
|
||||
logger.notice("Fetching latest emails...")
|
||||
debugPrint("Fetching latest emails...")
|
||||
|
||||
let startMessage = SequenceNumber(max(1, mailboxStatus.messageCount - 9))
|
||||
let endMessage = SequenceNumber(mailboxStatus.messageCount)
|
||||
debugPrint("Fetching messages from sequence \(startMessage) to \(endMessage)")
|
||||
|
||||
do {
|
||||
// Use the fetchEmails method with the sequence number set
|
||||
let emails = try await server.fetchMessages(using: SequenceNumberSet(startMessage...endMessage))
|
||||
debugPrint("\(emails.count) emails fetched successfully")
|
||||
|
||||
logger.notice("📧 Latest Complete Emails (\(emails.count)) 📧")
|
||||
print("\n📧 Latest Complete Emails (\(emails.count)) 📧")
|
||||
|
||||
// Display emails using the improved debug description format
|
||||
@@ -135,41 +110,25 @@ do {
|
||||
}
|
||||
|
||||
} catch {
|
||||
logger.error("Failed to fetch emails: \(error.localizedDescription)")
|
||||
print("Failed to fetch emails: \(error.localizedDescription)")
|
||||
debugPrint("ERROR: \(error)")
|
||||
}
|
||||
} else {
|
||||
logger.notice("No messages in mailbox")
|
||||
print("No messages in mailbox")
|
||||
}
|
||||
|
||||
// Logout from the server
|
||||
debugPrint("Logging out...")
|
||||
try await server.logout()
|
||||
debugPrint("Logout successful")
|
||||
|
||||
// Close the connection
|
||||
debugPrint("Disconnecting...")
|
||||
try await server.disconnect()
|
||||
debugPrint("Disconnection complete")
|
||||
}
|
||||
catch let error as NIOIMAP.IMAPDecoderError {
|
||||
|
||||
let string = String(buffer: error.buffer)
|
||||
print(string)
|
||||
debugPrint("ERROR: \(error)")
|
||||
|
||||
}
|
||||
catch {
|
||||
logger.error("Error: \(error.localizedDescription)")
|
||||
debugPrint("ERROR: \(error)")
|
||||
exit(1)
|
||||
}
|
||||
}.value
|
||||
|
||||
} catch {
|
||||
logger.error("Error: \(error.localizedDescription)")
|
||||
debugPrint("ERROR: \(error)")
|
||||
exit(1)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import NIOCore
|
||||
import Logging
|
||||
|
||||
/// Base class for SMTP command handlers that provides common functionality
|
||||
open class BaseSMTPHandler<T>: ChannelInboundHandler, RemovableChannelHandler, SMTPCommandHandler, LoggableHandler {
|
||||
open class BaseSMTPHandler<T>: ChannelInboundHandler, RemovableChannelHandler, SMTPCommandHandler {
|
||||
public typealias InboundIn = SMTPResponse
|
||||
public typealias InboundOut = Never
|
||||
public typealias ResultType = T
|
||||
@@ -14,9 +14,6 @@ open class BaseSMTPHandler<T>: ChannelInboundHandler, RemovableChannelHandler, S
|
||||
/// The promise that will be fulfilled when the command completes
|
||||
public let promise: EventLoopPromise<ResultType>
|
||||
|
||||
/// Logger for handler operations
|
||||
public var logger: Logger
|
||||
|
||||
/// Initialize a new handler
|
||||
/// - Parameters:
|
||||
/// - commandTag: Optional tag for the command (not commonly used in SMTP but included for consistency)
|
||||
@@ -24,7 +21,6 @@ open class BaseSMTPHandler<T>: ChannelInboundHandler, RemovableChannelHandler, S
|
||||
public required init(commandTag: String?, promise: EventLoopPromise<ResultType>) {
|
||||
self.commandTag = commandTag
|
||||
self.promise = promise
|
||||
self.logger = Logger(label: "com.cocoanetics.SwiftSMTP.Handler.\(String(describing: type(of: self)))")
|
||||
}
|
||||
|
||||
/// Process a response line from the server
|
||||
@@ -75,7 +71,6 @@ open class BaseSMTPHandler<T>: ChannelInboundHandler, RemovableChannelHandler, S
|
||||
/// - data: The data read from the channel
|
||||
public func channelRead(context: ChannelHandlerContext, data: NIOAny) {
|
||||
let response = self.unwrapInboundIn(data)
|
||||
logger.debug("Received response: \(response)")
|
||||
|
||||
// Process the response
|
||||
let isComplete = processResponse(response)
|
||||
|
||||
@@ -13,18 +13,15 @@ public final class DataHandler: BaseSMTPHandler<Bool> {
|
||||
- Returns: Whether the handler is complete
|
||||
*/
|
||||
override public func processResponse(_ response: SMTPResponse) -> Bool {
|
||||
logger.debug("Received DATA response: \(response.code) \(response.message)")
|
||||
|
||||
// 3xx responses are considered successful for DATA command (server is ready for content)
|
||||
if response.code >= 300 && response.code < 400 {
|
||||
logger.info("Server ready for email content")
|
||||
promise.succeed(true)
|
||||
} else {
|
||||
// Any other response is considered a failure
|
||||
logger.warning("DATA command rejected: \(response.code) \(response.message)")
|
||||
promise.succeed(false)
|
||||
}
|
||||
|
||||
return true // Always complete after a single response
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,18 +13,15 @@ public final class MailFromHandler: BaseSMTPHandler<Bool> {
|
||||
- Returns: Whether the handler is complete
|
||||
*/
|
||||
override public func processResponse(_ response: SMTPResponse) -> Bool {
|
||||
logger.debug("Received MAIL FROM response: \(response.code) \(response.message)")
|
||||
|
||||
// 2xx responses are considered successful
|
||||
if response.code >= 200 && response.code < 300 {
|
||||
logger.info("Sender accepted")
|
||||
promise.succeed(true)
|
||||
} else {
|
||||
// Any other response is considered a failure
|
||||
logger.warning("Sender rejected: \(response.code) \(response.message)")
|
||||
promise.succeed(false)
|
||||
}
|
||||
|
||||
return true // Always complete after a single response
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,19 +15,16 @@ public final class QuitHandler: BaseSMTPHandler<Bool> {
|
||||
override public func processResponse(_ response: SMTPResponse) -> Bool {
|
||||
// For QUIT command, any response is considered successful since we're going to close the connection anyway
|
||||
// But we should log the response for debugging purposes
|
||||
logger.debug("Server response to QUIT: \(response.code) \(response.message)")
|
||||
|
||||
// 2xx responses are considered successful
|
||||
if response.code >= 200 && response.code < 300 {
|
||||
logger.debug("QUIT command successful")
|
||||
promise.succeed(true)
|
||||
} else {
|
||||
// Even non-2xx responses are logged but we still succeed the promise
|
||||
// since we'll be closing the connection anyway
|
||||
logger.warning("Unexpected response to QUIT: \(response.code) \(response.message)")
|
||||
promise.succeed(false)
|
||||
}
|
||||
|
||||
return true // Always complete after a single response
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,18 +13,15 @@ public final class RcptToHandler: BaseSMTPHandler<Bool> {
|
||||
- Returns: Whether the handler is complete
|
||||
*/
|
||||
override public func processResponse(_ response: SMTPResponse) -> Bool {
|
||||
logger.debug("Received RCPT TO response: \(response.code) \(response.message)")
|
||||
|
||||
// 2xx responses are considered successful
|
||||
if response.code >= 200 && response.code < 300 {
|
||||
logger.info("Recipient accepted")
|
||||
promise.succeed(true)
|
||||
} else {
|
||||
// Any other response is considered a failure
|
||||
logger.warning("Recipient rejected: \(response.code) \(response.message)")
|
||||
promise.succeed(false)
|
||||
}
|
||||
|
||||
return true // Always complete after a single response
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,3 @@ public protocol SMTPCommandHandler {
|
||||
/// - promise: The promise to fulfill when the command completes
|
||||
init(commandTag: String?, promise: EventLoopPromise<ResultType>)
|
||||
}
|
||||
|
||||
/// Protocol for handlers that can have a logger set
|
||||
public protocol LoggableHandler {
|
||||
/// Logger for handler operations
|
||||
var logger: Logger { get set }
|
||||
}
|
||||
|
||||
@@ -13,18 +13,15 @@ public final class SendContentHandler: BaseSMTPHandler<Bool> {
|
||||
- Returns: Whether the handler is complete
|
||||
*/
|
||||
override public func processResponse(_ response: SMTPResponse) -> Bool {
|
||||
logger.debug("Received email content response: \(response.code) \(response.message)")
|
||||
|
||||
// 2xx responses are considered successful
|
||||
if response.code >= 200 && response.code < 300 {
|
||||
logger.info("Email content accepted")
|
||||
promise.succeed(true)
|
||||
} else {
|
||||
// Any other response is considered a failure
|
||||
logger.warning("Email content rejected: \(response.code) \(response.message)")
|
||||
promise.succeed(false)
|
||||
}
|
||||
|
||||
return true // Always complete after a single response
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,18 +13,15 @@ public final class StartTLSHandler: BaseSMTPHandler<Bool> {
|
||||
- Returns: Whether the handler is complete
|
||||
*/
|
||||
override public func processResponse(_ response: SMTPResponse) -> Bool {
|
||||
logger.debug("Received STARTTLS response: \(response.code) \(response.message)")
|
||||
|
||||
// 2xx responses are considered successful
|
||||
if response.code >= 200 && response.code < 300 {
|
||||
logger.info("STARTTLS command accepted")
|
||||
promise.succeed(true)
|
||||
} else {
|
||||
// Any other response is considered a failure
|
||||
logger.warning("STARTTLS command rejected: \(response.code) \(response.message)")
|
||||
promise.succeed(false)
|
||||
}
|
||||
|
||||
return true // Always complete after a single response
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user