diff --git a/gluon/contrib/mockimaplib.py b/gluon/contrib/mockimaplib.py deleted file mode 100644 index 89975900..00000000 --- a/gluon/contrib/mockimaplib.py +++ /dev/null @@ -1,254 +0,0 @@ -# -*- encoding: utf-8 -*- - -from imaplib import ParseFlags - -# mockimaplib: A very simple mock server module for imap client APIs -# Copyright (C) 2014 Alan Etkin -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or(at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this program. If not, see -# - -""" -mockimaplib allows you to test applications connecting to a dummy imap -service. For more details on the api subset implemented, -refer to the imaplib docs. - -The client should configure a dictionary to map imap string queries to sets -of entries stored in a message dummy storage dictionary. The module includes -a small set of default message records (SPAM and MESSAGES), two mailboxes -(Draft and INBOX) and a list of query/resultset entries (RESULTS). - -Usage: - ->>> import mockimaplib ->>> connection = mockimaplib.IMAP4_SSL() ->>> connection.login(, ) -None ->>> connection.select("INBOX") -("OK", ... ) -# fetch commands specifying single uid or message id -# will try to get messages recorded in SPAM ->>> connection.uid(...) - -# returns a string list of matching message ids ->>> connection.search() -("OK", ... "1 2 ... n") -""" - -MESSAGES = ( -'MIME-Version: 1.0\r\nReceived: by 10.140.91.199 with HTTP; Mon, 27 Jan 2014 13:52:30 -0800 (PST)\r\nDate: Mon, 27 Jan 2014 19:52:30 -0200\r\nDelivered-To: nurse@example.com\r\nMessage-ID: <10101010101010010000010101010001010101001010010000001@mail.example.com>\r\nSubject: spam1\r\nFrom: Mr. Gumby \r\nTo: The nurse \r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nNurse!\r\n\r\n\r\n', -'MIME-Version: 1.0\r\nReceived: by 10.140.91.199 with HTTP; Mon, 27 Jan 2014 13:52:47 -0800 (PST)\r\nDate: Mon, 27 Jan 2014 19:52:47 -0200\r\nDelivered-To: nurse@example.com\r\nMessage-ID: <101010101010100100000101010100010101010010100100000010@mail.example.com>\r\nSubject: spam2\r\nFrom: Mr. Gumby \r\nTo: The nurse \r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nNurse, nurse!', -'MIME-Version: 1.0\r\nReceived: by 10.140.91.199 with HTTP; Mon, 27 Jan 2014 13:54:54 -0800 (PST)\r\nDate: Mon, 27 Jan 2014 19:54:54 -0200\r\nDelivered-To: nurse@example.com\r\nMessage-ID: <1010101010101001000001010101000101010100101001000000101@mail.example.com>\r\nSubject: spamalot1\r\nFrom: Mr. Gumby \r\nTo: The nurse \r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nNurse!\r\n\r\n\r\n', -'MIME-Version: 1.0\r\n\r\nReceived: by 10.140.91.199 with HTTP; Mon, 27 Jan 2014 13:54:54 -0800 (PST)\r\nDate: Mon, 27 Jan 2014 19:54:54 -0200\r\nDelivered-To: nurse@example.com\r\nMessage-ID: <101010101010100100000101010100010101010010100100000010101@mail.example.com>\r\nSubject: spamalot2\r\nFrom: Mr. Gumby \r\nTo: The nurse \r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nNurse! ... Nurse! ... Nurse!\r\n\r\n\r\n') - -SPAM = { - "INBOX": [ - {"uid": "483209", - "headers": MESSAGES[0], - "complete": MESSAGES[0], - "flags": ""}, - {"uid": "483211", - "headers": MESSAGES[1], - "complete": MESSAGES[1], - "flags": ""}, - {"uid": "483225", - "headers": MESSAGES[2], - "complete": MESSAGES[2], - "flags": ""}], - "Draft":[ - {"uid": "483432", - "headers": MESSAGES[3], - "complete": MESSAGES[3], - "flags": ""},] -} - -RESULTS = { - # : [ | , ...] - "INBOX": { - "(ALL)": (1, 2, 3), - "(1:3)": (1, 2, 3)}, - "Draft": { - "(1:1)": (1,)}, -} - -class Connection(object): - """Dummy connection object for the imap client. - By default, uses the module SPAM and RESULT - sets (use Connection.setup for custom values)""" - def login(self, user, password): - pass - - def __init__(self): - self._readonly = False - self._mailbox = None - self.setup() - - def list(self): - return ('OK', ['(\\HasNoChildren) "/" "%s"' % key for key in self.spam]) - - def select(self, tablename, readonly=False): - self._readonly = readonly - """args: mailbox, boolean - result[1][0] -> int last message id / mailbox lenght - result[0] = 'OK' - """ - self._mailbox = tablename - return ('OK', (len(SPAM[self._mailbox]), None)) - - def uid(self, command, uid, arg): - """ args: - command: "search" | "fetch" - uid: None | uid - parts: "(ALL)" | "(RFC822 FLAGS)" | "(RFC822.HEADER FLAGS)" - - "search", None, "(ALL)" -> ("OK", ("uid_1 uid_2 ... uid_", None)) - "search", None, "" -> ("OK", ("uid_1 uid_2 ... uid_n", None)) - "fetch", uid, parts -> ("OK", ((" ...", ""), "") - [0] [1][0][0] [1][0][1] [1][1] - """ - if command == "search": - return self._search(arg) - elif command == "fetch": - return self._fetch(uid, arg) - - def _search(self, query): - return ("OK", (" ".join([str(item["uid"]) for item in self._get_messages(query)]), None)) - - def _fetch(self, value, arg): - try: - message = self.spam[self._mailbox][value - 1] - message_id = value - except TypeError: - for x, item in enumerate(self.spam[self._mailbox]): - if item["uid"] == value: - message = item - message_id = x + 1 - break - - parts = "headers" - if arg in ("(ALL)", "(RFC822 FLAGS)"): - parts = "complete" - - return ("OK", (("%s " % message_id, message[parts]), message["flags"])) - - def _get_messages(self, query): - if query.strip().isdigit(): - return [self.spam[self._mailbox][int(query.strip()) - 1],] - elif query[1:-1].strip().isdigit(): - return [self.spam[self._mailbox][int(query[1:-1].strip()) -1],] - elif query[1:-1].replace("UID", "").strip().isdigit(): - for item in self.spam[self._mailbox]: - if item["uid"] == query[1:-1].replace("UID", "").strip(): - return [item,] - messages = [] - try: - for m in self.results[self._mailbox][query]: - try: - self.spam[self._mailbox][m - 1]["id"] = m - messages.append(self.spam[self._mailbox][m - 1]) - except TypeError: - for x, item in enumerate(self.spam[self._mailbox]): - if item["uid"] == m: - item["id"] = x + 1 - messages.append(item) - break - except IndexError: - # message removed - pass - return messages - except KeyError: - raise ValueError("The client issued an unexpected query: %s" % query) - - def setup(self, spam={}, results={}): - """adds custom message and query databases or sets - the values to the module defaults. - """ - - self.spam = spam - self.results = results - if not spam: - for key in SPAM: - self.spam[key] = [] - for d in SPAM[key]: - self.spam[key].append(d.copy()) - if not results: - for key in RESULTS: - self.results[key] = RESULTS[key].copy() - - - def search(self, first, query): - """ args: - first: None - query: string with mailbox query (flags, date, uid, id, ...) - example: '2:15723 BEFORE 27-Jan-2014 FROM "gumby"' - result[1][0] -> "id_1 id_2 ... id_n" - """ - messages = self._get_messages(query) - ids = " ".join([str(item["id"]) for item in messages]) - return ("OK", (ids, None)) - - def append(self, mailbox, flags, struct_time, message): - """ - result, data = self.connection.append(mailbox, flags, struct_time, message) - if result == "OK": - uid = int(re.findall("\d+", str(data))[-1]) - """ - last = self.spam[mailbox][-1] - try: - uid = int(last["uid"]) +1 - except ValueError: - alluids = [] - for _mailbox in self.spam.keys(): - for item in self.spam[_mailbox]: - try: - alluids.append(int(item["uid"])) - except: - pass - if len(alluids) > 0: - uid = max(alluids) + 1 - else: - uid = 1 - flags = "FLAGS " + flags - item = {"uid": str(uid), "headers": message, "complete": message, "flags": flags} - self.spam[mailbox].append(item) - return ("OK", "spam spam %s spam" % uid) - - - def store(self, *args): - """ - implements some flag commands - args: ("", "<+|->FLAGS", "(\\Flag1 \\Flag2 ... \\Flagn)") - """ - message = self.spam[self._mailbox][int(args[0] - 1)] - old_flags = ParseFlags(message["flags"]) - flags = ParseFlags("FLAGS" + args[2]) - if args[1].strip().startswith("+"): - message["flags"] = "FLAGS (%s)" % " ".join(set(flags + old_flags)) - elif args[1].strip().startswith("-"): - message["flags"] = "FLAGS (%s)" % " ".join([flag for flag in old_flags if not flag in flags]) - - def expunge(self): - """implements removal of deleted flag messages""" - for x, item in enumerate(self.spam[self._mailbox]): - if "\\Deleted" in item["flags"]: - self.spam[self._mailbox].pop(x) - - -class IMAP4(object): - """>>> connection = IMAP4() # creates the dummy imap4 client object""" - def __new__(self, *args, **kwargs): - # args: (server, port) - return Connection() - -IMAP4_SSL = IMAP4