Skip to content

Commit

Permalink
introduce highlevel API
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Virkus committed Jun 16, 2020
1 parent 0573cff commit 390b24e
Show file tree
Hide file tree
Showing 19 changed files with 858 additions and 16 deletions.
38 changes: 38 additions & 0 deletions example/enough_mail_example.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:io';

import 'package:enough_mail/enough_mail.dart';

String userName = 'user.name';
Expand All @@ -14,6 +15,7 @@ int smtpServerPort = 465;
bool isSmtpServerSecure = true;

void main() async {
//await mailExample();
await discoverExample();
await imapExample();
await smtpExample();
Expand Down Expand Up @@ -46,6 +48,42 @@ Future<void> discoverExample() async {
}
}

Future<void> mailExample() async {
var email = userName + '@domain.com';
var config = await Discover.discover(email);
var incoming = MailServerConfig()
..serverConfig = config.preferredIncomingServer
..authentication = PlainAuthentication(userName, password);
var account = MailAccount()
..email = email
..incoming = incoming;
//TODO specify outgoing server configuration
var mailClient = MailClient(account, isLogEnabled: false);
await mailClient.connect();
var mailboxesResponse =
await mailClient.listMailboxesAsTree(createIntermediate: false);
if (mailboxesResponse.isOkStatus) {
print(mailboxesResponse.result);
await mailClient.selectInbox();
var fetchResponse = await mailClient.fetchMessages(count: 20);
if (fetchResponse.isOkStatus) {
for (var msg in fetchResponse.result) {
printMessage(msg);
}
}
}
mailClient.eventBus.on<MailLoadEvent>().listen((event) {
print('New message at ${DateTime.now()}:');
printMessage(event.message);
});
mailClient.startPolling();
// print('flat:');
// var mailboxesFlatResponse = await mailClient.listMailboxes();
// if (mailboxesFlatResponse.isSuccess) {
// print(mailboxesFlatResponse.result);
// }
}

Future<void> imapExample() async {
var client = ImapClient(isLogEnabled: false);
await client.connectToServer(imapServerHost, imapServerPort,
Expand Down
9 changes: 8 additions & 1 deletion lib/enough_mail.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
library enough_mail;

export 'imap/events.dart';
export 'imap/imap_events.dart';
export 'imap/imap_client.dart';
export 'imap/mailbox.dart';
export 'imap/response.dart';
Expand All @@ -24,6 +24,13 @@ export 'codecs/quoted_printable_mail_codec.dart';
export 'discover/client_config.dart';
export 'discover/discover.dart';

export 'mail/mail_account.dart';
export 'mail/mail_authentication.dart';
export 'mail/mail_client.dart';
export 'mail/mail_events.dart';
export 'mail/mail_response.dart';
export 'mail/tree.dart';

export 'mail_address.dart';
export 'media_type.dart';
export 'message_builder.dart';
Expand Down
10 changes: 6 additions & 4 deletions lib/imap/imap_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'package:enough_mail/src/imap/all_parsers.dart';
import 'package:enough_mail/src/imap/imap_response.dart';
import 'package:enough_mail/src/imap/imap_response_reader.dart';

import 'events.dart';
import 'imap_events.dart';

/// Describes a capability
class Capability {
Expand Down Expand Up @@ -85,7 +85,8 @@ class ImapClient {
/// _log(event.eventType);
/// });
/// ```
EventBus eventBus;
EventBus get eventBus => _eventBus;
EventBus _eventBus;

bool _isSocketClosingExpected = false;

Expand All @@ -110,7 +111,8 @@ class ImapClient {
///
/// Compare [eventBus] for more information.
ImapClient({EventBus bus, bool isLogEnabled = false}) {
eventBus ??= EventBus();
bus ??= EventBus();
_eventBus = bus;
_isLogEnabled = isLogEnabled ?? false;
_imapResponseReader = ImapResponseReader(onServerResponse);
}
Expand Down Expand Up @@ -1201,7 +1203,7 @@ class ImapClient {
_socket?.writeln('$id $command');
}

Future<dynamic> close() {
Future<dynamic> closeConnection() {
_log('Closing socket for host ${serverInfo.host}');
_isSocketClosingExpected = true;
return _socket?.close();
Expand Down
2 changes: 1 addition & 1 deletion lib/imap/events.dart → lib/imap/imap_events.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ImapExpungeEvent extends ImapEvent {
/// Notifies about a sequence of messages that have been deleted.
/// This event can only be triggered if the server is QRESYNC compliant and after the client has enabled QRESYNC.
class ImapVanishedEvent extends ImapEvent {
/// Sequence of messages that have been expunged
/// UID sequence of messages that have been expunged
final MessageSequence vanishedMessages;

/// true when the vanished messages do not lead to updated sequence IDs
Expand Down
26 changes: 25 additions & 1 deletion lib/imap/mailbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class Mailbox {
isInbox || isDrafts || isSent || isJunk || isTrash || isArchive;

Mailbox();
Mailbox.setup(this.name, this.flags) {
Mailbox.setup(this.name, this.path, this.flags) {
isMarked = hasFlag(MailboxFlag.marked);
hasChildren = hasFlag(MailboxFlag.hasChildren);
isSelected = hasFlag(MailboxFlag.select);
Expand All @@ -69,6 +69,30 @@ class Mailbox {
return flags.contains(flag);
}

Mailbox getParent(List<Mailbox> knownMailboxes, String separator,
{bool create = true, bool createIntermediate = true}) {
var lastSplitIndex = path.lastIndexOf(separator);
if (lastSplitIndex == -1) {
// this is a root mailbox, eg 'Inbox'
return null;
}
var parentPath = path.substring(0, lastSplitIndex);
var parent = knownMailboxes.firstWhere((box) => box.path == parentPath,
orElse: () => null);
if (parent == null && create) {
lastSplitIndex = parentPath.lastIndexOf(separator);
var parentName = lastSplitIndex == -1
? parentPath
: parentPath.substring(lastSplitIndex + 1);
parent = Mailbox.setup(parentName, parentPath, [MailboxFlag.noSelect]);
if ((lastSplitIndex != -1) && (!createIntermediate)) {
parent = parent.getParent(knownMailboxes, separator,
create: true, createIntermediate: false);
}
}
return parent;
}

@override
String toString() {
var buffer = StringBuffer()..write('"')..write(path)..write('"');
Expand Down
26 changes: 26 additions & 0 deletions lib/mail/mail_account.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:enough_mail/discover/client_config.dart';
import 'package:enough_mail/enough_mail.dart';

import 'mail_authentication.dart';

class MailServerConfig {
ServerConfig serverConfig;
MailAuthentication authentication;
List<Capability> serverCapabilities;

String pathSeparator;

bool supports(String capabilityName) {
return (serverCapabilities.firstWhere((c) => c.name == capabilityName,
orElse: () => null) !=
null);
}
}

class MailAccount {
String name;
String email;
MailServerConfig incoming;
MailServerConfig outgoing;
String outgoingClientDomain = 'enough.de';
}
36 changes: 36 additions & 0 deletions lib/mail/mail_authentication.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'package:enough_mail/discover/client_config.dart';
import 'package:enough_mail/imap/imap_client.dart';
import 'package:enough_mail/pop/pop_client.dart';
import 'package:enough_mail/smtp/smtp_client.dart';

import 'mail_response.dart';

abstract class MailAuthentication {
Future<MailResponse> authenticate(ServerConfig serverConfig,
{ImapClient imap, PopClient pop, SmtpClient smtp});
}

class PlainAuthentication extends MailAuthentication {
String userName;
String password;
PlainAuthentication(this.userName, this.password);

@override
Future<MailResponse> authenticate(ServerConfig serverConfig,
{ImapClient imap, PopClient pop, SmtpClient smtp}) async {
switch (serverConfig.type) {
case ServerType.imap:
var imapResponse = await imap.login(userName, password);
return MailResponseHelper.createFromImap(imapResponse);
break;
case ServerType.pop:
var popResponse = await pop.login(userName, password);
return MailResponseHelper.createFromPop(popResponse);
break;
case ServerType.smtp:
break;
default:
throw StateError('Unknown server type ${serverConfig.typeName}');
}
}
}
Loading

0 comments on commit 390b24e

Please sign in to comment.