Skip to content

Commit

Permalink
Removed unnessary imports, and implemented Linux functions for MIME h…
Browse files Browse the repository at this point in the history
…andling #3
  • Loading branch information
odrobnik committed Mar 7, 2025
1 parent 05e5972 commit 1e56fae
Show file tree
Hide file tree
Showing 15 changed files with 304 additions and 280 deletions.
7 changes: 6 additions & 1 deletion Demos/SwiftIMAPCLI/OSLogHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
//

import Foundation
import OSLog
import Logging

#if canImport(OSLog)

import OSLog

// Custom LogHandler that bridges Swift Logging to OSLog
struct OSLogHandler: LogHandler {
let label: String
Expand Down Expand Up @@ -57,3 +60,5 @@ struct OSLogHandler: LogHandler {
os_log("%{public}@", log: log, type: type, message.description)
}
}

#endif
35 changes: 21 additions & 14 deletions Demos/SwiftIMAPCLI/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,32 @@ import Logging
import SwiftDotenv
import NIOIMAP

#if canImport(OSLog)

import OSLog

// Set default log level to info - will only show important logs
// Per the cursor rules: Use OS_LOG_DISABLE=1 to see log output as needed
LoggingSystem.bootstrap { label in
// Create an OSLog-based logger
let category = label.split(separator: ".").last?.description ?? "default"
let osLogger = OSLog(subsystem: "com.cocoanetics.SwiftIMAPCLI", category: category)

// Set log level to info by default (or trace if verbose logging is enabled)
var handler = OSLogHandler(label: label, log: osLogger)
// Check if we need verbose logging
if ProcessInfo.processInfo.environment["ENABLE_DEBUG_OUTPUT"] == "1" {
handler.logLevel = .trace
} else {
handler.logLevel = .info
}

return handler
// Create an OSLog-based logger
let category = label.split(separator: ".").last?.description ?? "default"
let osLogger = OSLog(subsystem: "com.cocoanetics.SwiftIMAPCLI", category: category)

// Set log level to info by default (or trace if SWIFT_LOG_LEVEL is set to trace)
var handler = OSLogHandler(label: label, log: osLogger)

// Check if we need verbose logging
if ProcessInfo.processInfo.environment["ENABLE_DEBUG_OUTPUT"] == "1" {
handler.logLevel = .trace
} else {
handler.logLevel = .info
}

return handler
}

#endif

// Create a logger for the main application using Swift Logging
let logger = Logger(label: "com.cocoanetics.SwiftIMAPCLI.Main")

Expand Down
97 changes: 51 additions & 46 deletions Demos/SwiftSMTPCLI/OSLogHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,59 @@
//

import Foundation
import OSLog
import Logging

#if canImport(OSLog)

import OSLog

// Custom LogHandler that bridges Swift Logging to OSLog
struct OSLogHandler: LogHandler {
let label: String
let log: OSLog
// Required property for LogHandler protocol
var logLevel: Logging.Logger.Level = .debug // Set to debug to capture all logs
// Required property for LogHandler protocol
var metadata = Logging.Logger.Metadata()
// Required subscript for LogHandler protocol
subscript(metadataKey metadataKey: String) -> Logging.Logger.Metadata.Value? {
get {
return metadata[metadataKey]
}
set {
metadata[metadataKey] = newValue
}
}
// Initialize with a label and OSLog instance
init(label: String, log: OSLog) {
self.label = label
self.log = log
}
// Required method for LogHandler protocol
func log(level: Logging.Logger.Level, message: Logging.Logger.Message, metadata: Logging.Logger.Metadata?, source: String, file: String, function: String, line: UInt) {
// Map Swift Logging levels to OSLog types
let type: OSLogType
switch level {
case .trace, .debug:
type = .debug
case .info, .notice:
type = .info
case .warning:
type = .default
case .error:
type = .error
case .critical:
type = .fault
}
// Log the message using OSLog
os_log("%{public}@", log: log, type: type, message.description)
}
let label: String
let log: OSLog
// Required property for LogHandler protocol
var logLevel: Logging.Logger.Level = .debug // Set to debug to capture all logs
// Required property for LogHandler protocol
var metadata = Logging.Logger.Metadata()
// Required subscript for LogHandler protocol
subscript(metadataKey metadataKey: String) -> Logging.Logger.Metadata.Value? {
get {
return metadata[metadataKey]
}
set {
metadata[metadataKey] = newValue
}
}
// Initialize with a label and OSLog instance
init(label: String, log: OSLog) {
self.label = label
self.log = log
}
// Required method for LogHandler protocol
func log(level: Logging.Logger.Level, message: Logging.Logger.Message, metadata: Logging.Logger.Metadata?, source: String, file: String, function: String, line: UInt) {
// Map Swift Logging levels to OSLog types
let type: OSLogType
switch level {
case .trace, .debug:
type = .debug
case .info, .notice:
type = .info
case .warning:
type = .default
case .error:
type = .error
case .critical:
type = .fault
}
// Log the message using OSLog
os_log("%{public}@", log: log, type: type, message.description)
}
}

#endif
8 changes: 7 additions & 1 deletion Demos/SwiftSMTPCLI/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@

import Foundation
import SwiftSMTP
import OSLog
import Logging
import SwiftDotenv
import SwiftMailCore


#if canImport(OSLog)

import OSLog

// Set default log level to info - will only show important logs
// Per the cursor rules: Use OS_LOG_DISABLE=1 to see log output as needed
LoggingSystem.bootstrap { label in
Expand All @@ -28,6 +32,8 @@ LoggingSystem.bootstrap { label in
return handler
}

#endif

// Create a logger for the main application using Swift Logging
let logger = Logger(label: "com.cocoanetics.SwiftSMTPCLI.Main")

Expand Down
66 changes: 0 additions & 66 deletions Sources/SwiftIMAP/Extensions/String+Utilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,74 +3,8 @@

import Foundation
import NIOIMAPCore
import UniformTypeIdentifiers

extension String {
/// Sanitize a filename to ensure it's valid
/// - Returns: A sanitized filename
func sanitizedFileName() -> String {
let invalidCharacters = CharacterSet(charactersIn: ":/\\?%*|\"<>")
return self
.components(separatedBy: invalidCharacters)
.joined(separator: "_")
.replacingOccurrences(of: " ", with: "_")
}

/// Get a file extension for a given MIME type
/// - Parameter mimeType: The full MIME type (e.g., "text/plain", "image/jpeg")
/// - Returns: An appropriate file extension (without the dot)
static func fileExtension(for mimeType: String) -> String? {
// Try to get the UTType from the MIME type
if let utType = UTType(mimeType: mimeType) {
// Get the preferred file extension
if let preferredExtension = utType.preferredFilenameExtension {
return preferredExtension
}
}

return nil
}

// Helper function to get MIME type from file URL using UTI
static func mimeType(for fileExtension: String) -> String {
// First try to get UTType from file extension

if let utType = UTType(filenameExtension: fileExtension) {
// If we have a UTType, try to get its MIME type
if let mimeType = utType.preferredMIMEType {
return mimeType
}
}


// Fallback to common extensions if UTI doesn't work
let pathExtension = fileExtension.lowercased()
switch pathExtension {
case "jpg", "jpeg":
return "image/jpeg"
case "png":
return "image/png"
case "gif":
return "image/gif"
case "svg":
return "image/svg+xml"
case "pdf":
return "application/pdf"
case "txt":
return "text/plain"
case "html", "htm":
return "text/html"
case "doc", "docx":
return "application/msword"
case "xls", "xlsx":
return "application/vnd.ms-excel"
case "zip":
return "application/zip"
default:
return "application/octet-stream"
}
}

/// Parse a string range (e.g., "1:10") into a SequenceSet
/// - Returns: A SequenceSet object
/// - Throws: An error if the range string is invalid
Expand Down
1 change: 0 additions & 1 deletion Sources/SwiftIMAP/IMAP/Handler/FetchHeadersHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// A specialized handler for IMAP fetch headers operations

import Foundation
import os.log
@preconcurrency import NIOIMAP
import NIOIMAPCore
import NIO
Expand Down
1 change: 0 additions & 1 deletion Sources/SwiftIMAP/IMAP/Handler/FetchPartHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// A specialized handler for IMAP fetch part operations

import Foundation
import os.log
@preconcurrency import NIOIMAP
import NIOIMAPCore
import NIO
Expand Down
1 change: 0 additions & 1 deletion Sources/SwiftIMAP/IMAP/Handler/FetchStructureHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// A specialized handler for IMAP fetch structure operations

import Foundation
import os.log
@preconcurrency import NIOIMAP
import NIOIMAPCore
import NIO
Expand Down
1 change: 0 additions & 1 deletion Sources/SwiftIMAP/IMAP/Handler/LogoutHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Handler for IMAP LOGOUT command

import Foundation
import os.log
@preconcurrency import NIOIMAP
import NIOIMAPCore
import NIO
Expand Down
1 change: 0 additions & 1 deletion Sources/SwiftIMAP/IMAP/Handler/MoveHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Handler for IMAP MOVE command

import Foundation
import os.log
@preconcurrency import NIOIMAP
import NIOIMAPCore
import NIO
Expand Down
1 change: 0 additions & 1 deletion Sources/SwiftIMAP/IMAP/Handler/SelectHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Handler for IMAP SELECT command

import Foundation
import os.log
@preconcurrency import NIOIMAP
import NIOIMAPCore
import NIO
Expand Down
Loading

0 comments on commit 1e56fae

Please sign in to comment.