offlineimap rev 503
"Automatic Subversion Change Mailer" <[email protected]> Wed, 16 Jul 2003 16:03:59 -0500 (CDT)
| Newsgroups | gmane.mail.imap.offlineimap.subversion |
|---|---|
| Message-ID | <[email protected]> |
You are receiving this message because
all commits get sent to this address.
Author: jgoerzen
Date: 2003-07-16 16:03:53 -0500 (Wed, 16 Jul 2003)
New Revision: 503
Modified:
imaplib/head/imap2/Exceptions.py
imaplib/head/imap2/parser/Objects.py
imaplib/head/imap2/parser/grammar.g
imaplib/head/imap2/parser/grammar.py
imaplib/head/imap2/parser/grammarTest.py
Log:
Some progress to objectifying the results
Diff:
Added: imaplib/head/imap2/Exceptions.py
==============================================================================
--- imaplib/head/imap2/Exceptions.py 2003-07-16 20:30:49 UTC (rev 502)
+++ imaplib/head/imap2/Exceptions.py 2003-07-16 21:03:53 UTC (rev 503)
@@ -0,0 +1,8 @@
+class IMAPException(Exception):
+ pass
+
+class FatalError(IMAPException):
+ pass
+
+class StreamError(IMAPException):
+ pass
Added: imaplib/head/imap2/parser/Objects.py
==============================================================================
--- imaplib/head/imap2/parser/Objects.py 2003-07-16 20:30:49 UTC (rev 502)
+++ imaplib/head/imap2/parser/Objects.py 2003-07-16 21:03:53 UTC (rev 503)
@@ -0,0 +1,67 @@
+# Implementation of grammar from RFC3501
+# $Id: grammar.g 491 2003-07-16 19:38:49Z jgoerzen $
+
+# COPYRIGHT #
+# Copyright (C) 2003 John Goerzen
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 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 General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# END OF COPYRIGHT #
+
+__all__ = ['Response', 'ResponseCode', 'Capabilities']
+
+from UserDict import UserDict
+from UserList import UserList
+
+from imap2 import Exceptions
+
+class Response:
+ def __init__(self, response_done, data):
+ self.result = response_done['result']
+ self.donetype = response_done['donetype']
+ detail = response_done['detail']
+ self.code = None
+ if detail.has_key('code'):
+ self.code = detail['code']
+ self.text = detail['text']
+ self.tag = None
+ if response_done.has_key('tag'):
+ self.tag = response_done['tag']
+
+ self.errorcheck()
+
+ def errorcheck(self):
+ if self.donetype == 'fatal':
+ raise Exceptions.FatalError, "Fatal response to command. Result: %s %s" % (self.result, self.detail)
+ elif self.donetype != 'tagged':
+ raise Exceptions.StreamError, "Expected a fatal or tagged result but got %s" % self.donetype
+
+ def __repr__(self):
+ return "<Response: [result=%s] [donetype=%s] [code=%s] [text=%s] [tag=%s]>" %\
+ (self.result, self.donetype, self.code, self.text, self.tag)
+
+class ResponseCode:
+ def __init__(self, codelist):
+ self.codename = codelist[0]
+ self.codeinfo = codelist[1:]
+
+ def __repr__(self):
+ return "<ResponseCode: [codename=%s] [codeinfo=%s]>" % \
+ (self.codename, self.codeinfo)
+
+class Capabilities(UserList):
+ """Stores capabilities. You may access this as a list of strings."""
+ def __init__(self, capabilities):
+ self.data = capabilities
+
Modified: imaplib/head/imap2/parser/grammar.g
==============================================================================
--- imaplib/head/imap2/parser/grammar.g 2003-07-16 20:30:49 UTC (rev 502)
+++ imaplib/head/imap2/parser/grammar.g 2003-07-16 21:03:53 UTC (rev 503)
@@ -216,7 +216,7 @@
# This rule does not enforce IMAP4rev1
rule capability_data: "(?i)CAPABILITY" {{ v = [] }}
(SP capability {{ v.append(capability) }})+
- {{ return v }}
+ {{ return Capabilities(v) }}
#rule command:
#rule command_any:
#rule command_auth:
@@ -432,13 +432,18 @@
| capability_data {{ v = capability_data}} ) CRLF {{ return v }}
rule response_done: (response_tagged {{ v = response_tagged}}
| response_fatal {{ v = response_fatal}}) {{ return v}}
- rule response_fatal: ASTERISK SP resp_cond_bye CRLF {{ return resp_cond_bye}}
+ rule response_fatal: ASTERISK SP resp_cond_bye CRLF
+ {{ v = {'donetype': 'fatal'} }}
+ {{ v.update(resp_cond_bye)}}
+ {{ return v }}
rule response_tagged: tag SP resp_cond_state CRLF
- {{ return {'tag': tag, 'state': resp_cond_state} }}
+ {{ v = {'tag': tag, 'donetype':'tagged'} }}
+ {{ v.update(resp_cond_state) }}
+ {{ return v }}
rule resp_cond_auth: resp_cond_auth_tok SP resp_text
{{ return {'result': resp_cond_auth_tok, 'detail': resp_text} }}
rule resp_cond_bye: r'(?i)BYE' SP resp_text
- {{ return {'result': BYE, 'detail': resp_text} }}
+ {{ return {'result': 'BYE', 'detail': resp_text} }}
rule resp_cond_state: resp_cond_state_tok SP resp_text
{{ return {'result': resp_cond_state_tok, 'detail': resp_text} }}
rule resp_text: {{ v = {} }}
@@ -463,7 +468,7 @@
| r'(?i)UNSEEN' SP nz_number {{ v = ['UNSEEN', nz_number] }}
| atom {{v = [atom]}} [SP {{ v.append('') }}
(RESP_TEXT_CHAR {{ v[1] += RESP_TEXT_CHAR}})+]
- ) {{ return v }}
+ ) {{ return ResponseCode(v) }}
##############################
# S
Modified: imaplib/head/imap2/parser/grammar.py
==============================================================================
--- imaplib/head/imap2/parser/grammar.py 2003-07-16 20:30:49 UTC (rev 502)
+++ imaplib/head/imap2/parser/grammar.py 2003-07-16 21:03:53 UTC (rev 503)
@@ -1,5 +1,5 @@
# Implementation of grammar from RFC3501
-# $Id: grammar.g 491 2003-07-16 19:38:49Z jgoerzen $
+# $Id: grammar.g 499 2003-07-16 20:30:49Z jgoerzen $
# COPYRIGHT #
# Copyright (C) 2003 John Goerzen
@@ -492,7 +492,7 @@
capability = self.capability()
v.append(capability)
if self._peek('SP', 'END', 'RESP_TEXT_CHAR', 'CRLF', 'RBRACKET') != 'SP': break
- return v
+ return Capabilities(v)
def continue_req(self):
PLUS = self._scan('PLUS')
@@ -1039,14 +1039,18 @@
SP = self._scan('SP')
resp_cond_bye = self.resp_cond_bye()
CRLF = self._scan('CRLF')
- return resp_cond_bye
+ v = {'donetype': 'fatal'}
+ v.update(resp_cond_bye)
+ return v
def response_tagged(self):
tag = self.tag()
SP = self._scan('SP')
resp_cond_state = self.resp_cond_state()
CRLF = self._scan('CRLF')
- return {'tag': tag, 'state': resp_cond_state}
+ v = {'tag': tag, 'donetype':'tagged'}
+ v.update(resp_cond_state)
+ return v
def resp_cond_auth(self):
resp_cond_auth_tok = self._scan('resp_cond_auth_tok')
@@ -1058,7 +1062,7 @@
self._scan("r'(?i)BYE'")
SP = self._scan('SP')
resp_text = self.resp_text()
- return {'result': BYE, 'detail': resp_text}
+ return {'result': 'BYE', 'detail': resp_text}
def resp_cond_state(self):
resp_cond_state_tok = self._scan('resp_cond_state_tok')
@@ -1149,7 +1153,7 @@
RESP_TEXT_CHAR = self._scan('RESP_TEXT_CHAR')
v[1] += RESP_TEXT_CHAR
if self._peek('RESP_TEXT_CHAR', 'RBRACKET') != 'RESP_TEXT_CHAR': break
- return v
+ return ResponseCode(v)
def section(self):
v = None
Modified: imaplib/head/imap2/parser/grammarTest.py
==============================================================================
--- imaplib/head/imap2/parser/grammarTest.py 2003-07-16 20:30:49 UTC (rev 502)
+++ imaplib/head/imap2/parser/grammarTest.py 2003-07-16 21:03:53 UTC (rev 503)
@@ -29,11 +29,13 @@
# These examples are from the RFC.
def test_ex_Connect(self):
result = parse("* OK IMAP4rev1 Service Ready\r\n", 'goal_connect')
- self.assertEquals(result, {'result': 'OK', 'detail': {'text': 'IMAP4rev1 Service Ready'}})
+ self.assertEquals(repr(result),
+ "{'result': 'OK', 'detail': {'text': 'IMAP4rev1 Service Ready'}}")
def test_ex_Login(self):
result = parse("a001 OK LOGIN completed\r\n")
- self.assertEquals(result, {'data': [], 'response': {'state': {'result': 'OK', 'detail': {'text': 'LOGIN completed'}}, 'tag': 'a001'}})
+ self.assertEquals(repr(result),
+ '<Response: [result=OK] [donetype=tagged] [code=None] [text=LOGIN completed] [tag=a001]>')
def test_ex_Select(self):
result = parse("* 18 EXISTS\r\n" + \
@@ -42,18 +44,22 @@
"* OK [UNSEEN 17] Message 17 is the first unseen message\r\n" + \
"* OK [UIDVALIDITY 3857529045] UIDs valid\r\n" +
"a002 OK [READ-WRITE] SELECT completed\r\n")
- self.assertEquals(result, {'data': [{'EXISTS': 18L}, {'flags': ['\\Answered', '\\Flagged', '\\Deleted', '\\Seen', '\\Draft']}, {'RECENT': 2L}, {'result': 'OK', 'detail': {'text': 'Message 17 is the first unseen message', 'code': ['UNSEEN', 17L]}}, {'result': 'OK', 'detail': {'text': 'UIDs valid', 'code': ['UIDVALIDITY', 3857529045L]}}], 'response': {'state': {'result': 'OK', 'detail': {'text': 'SELECT completed', 'code': ['READ-WRITE']}}, 'tag': 'a002'}})
+ self.assertEquals(repr(result),
+ '<Response: [result=OK] [donetype=tagged] [code=<ResponseCode: [codename=READ-WRITE] [codeinfo=[]]>] [text=SELECT completed] [tag=a002]>')
def test_Courier_Connect(self):
result = parse("* OK [CAPABILITY IMAP4rev1 CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE AUTH=PLAIN] Courier-IMAP ready. Copyright 1998-2003 Double Precision, Inc. See COPYING for distribution information.\r\n", "goal_connect")
- self.assertEquals(result, {'result': 'OK', 'detail': {'text': 'Courier-IMAP ready. Copyright 1998-2003 Double Precision, Inc. See COPYING for distribution information.', 'code': [['IMAP4rev1', 'CHILDREN', 'NAMESPACE', 'THREAD=ORDEREDSUBJECT', 'THREAD=REFERENCES', 'SORT', 'QUOTA', 'IDLE', 'AUTH=PLAIN']]}})
+ self.assertEquals(repr(result),
+ "{'result': 'OK', 'detail': {'text': 'Courier-IMAP ready. Copyright 1998-2003 Double Precision, Inc. See COPYING for distribution information.', 'code': <ResponseCode: [codename=['IMAP4rev1', 'CHILDREN', 'NAMESPACE', 'THREAD=ORDEREDSUBJECT', 'THREAD=REFERENCES', 'SORT', 'QUOTA', 'IDLE', 'AUTH=PLAIN']] [codeinfo=[]]>}}")
def test_Courier_Capability(self):
result = parse("* CAPABILITY IMAP4rev1 CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE\r\n2 OK CAPABILITY completed\r\n")
- self.assertEquals(result, {'data': [['IMAP4rev1', 'CHILDREN', 'NAMESPACE', 'THREAD=ORDEREDSUBJECT', 'THREAD=REFERENCES', 'SORT', 'QUOTA', 'IDLE']], 'response': {'state': {'result': 'OK', 'detail': {'text': 'CAPABILITY completed'}}, 'tag': '2'}})
+ self.assertEquals(repr(result),
+ '<Response: [result=OK] [donetype=tagged] [code=None] [text=CAPABILITY completed] [tag=2]>')
class RuleTestCase(unittest.TestCase):
def test_capability_data(self):
result = parse("CAPABILITY IMAP4rev1 CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA IDLE AUTH=PLAIN", "test_capability_data")
- self.assertEquals(result, ['IMAP4rev1', 'CHILDREN', 'NAMESPACE', 'THREAD=ORDEREDSUBJECT', 'THREAD=REFERENCES', 'SORT', 'QUOTA', 'IDLE', 'AUTH=PLAIN'])
+ self.assertEquals(repr(result),
+ "['IMAP4rev1', 'CHILDREN', 'NAMESPACE', 'THREAD=ORDEREDSUBJECT', 'THREAD=REFERENCES', 'SORT', 'QUOTA', 'IDLE', 'AUTH=PLAIN']")