1
- from itertools import ifilterfalse
2
1
import logging
3
- import re
4
2
import errors
5
3
import forms
6
- import comment
7
4
from urllib2 import Request , HTTPError
5
+ from rtkit .parser import RTParser
8
6
9
7
10
8
class RTResource (object ):
@@ -40,10 +38,6 @@ def request(self, method, path=None, payload=None, headers=None):
40
38
41
39
42
40
class RTResponse (object ):
43
- HEADER = re .compile (r'^RT/(?P<v>.+)\s+(?P<s>(?P<i>\d+).+)' )
44
- COMMENT = re .compile (r'^#\s+.+$' )
45
- SECTION = re .compile (r'^--' , re .M | re .U )
46
-
47
41
def __init__ (self , request , response ):
48
42
self .headers = response .headers
49
43
self .body = response .read ()
@@ -53,7 +47,7 @@ def __init__(self, request, response):
53
47
self .logger .info (request .get_method ())
54
48
self .logger .info (request .get_full_url ())
55
49
self .logger .debug ('HTTP_STATUS: {0}' .format (self .status ))
56
- r = self .HEADER .match (self .body )
50
+ r = RTParser .HEADER .match (self .body )
57
51
if r :
58
52
self .status = r .group ('s' )
59
53
self .status_int = int (r .group ('i' ))
@@ -63,105 +57,13 @@ def __init__(self, request, response):
63
57
self .status_int = 500
64
58
self .logger .debug ('%r' % self .body )
65
59
try :
66
- decoder = self . _decode
60
+ decoder = RTParser . decode
67
61
if self .status_int == 409 :
68
- decoder = self . _decode_comment
69
- self .parsed = self . _parse (self .body , decoder )
62
+ decoder = RTParser . decode_comment
63
+ self .parsed = RTParser . parse (self .body , decoder )
70
64
except errors .RTResourceError as e :
71
65
self .parsed = []
72
66
self .status_int = e .status_int
73
67
self .status = '{0} {1}' .format (e .status_int , e .msg )
74
68
self .logger .debug ('RESOURCE_STATUS: {0}' .format (self .status ))
75
69
self .logger .info (self .parsed )
76
-
77
- @classmethod
78
- def _parse (cls , body , decoder ):
79
- r""" Return a list of RFC5322-like section
80
- >>> decode = RTResponse._decode
81
- >>> body = '''
82
- ...
83
- ... # c1
84
- ... spam: 1
85
- ... ham: 2,
86
- ... 3
87
- ... eggs:'''
88
- >>> RTResponse._parse(body, decode)
89
- [[('spam', '1'), ('ham', '2, 3'), ('eggs', '')]]
90
- >>> RTResponse._parse('# spam 1 does not exist.', decode)
91
- Traceback (most recent call last):
92
- ...
93
- RTNotFoundError: spam 1 does not exist
94
- >>> RTResponse._parse('# Spam 1 created.', decode)
95
- [[('id', 'spam/1')]]
96
- >>> RTResponse._parse('No matching results.', decode)
97
- []
98
- >>> decode = RTResponse._decode_comment
99
- >>> RTResponse._parse('# spam: 1\n# ham: 2', decode)
100
- [[('spam', '1'), ('ham', '2')]]
101
- """
102
- section = cls ._build (body )
103
- if len (section ) == 1 :
104
- try :
105
- comment .check (section [0 ])
106
- except comment .RTNoMatch :
107
- section = ''
108
- except comment .RTCreated as e :
109
- section = [['id: {0}' .format (e .id )]]
110
- return [decoder (lines ) for lines in section ]
111
-
112
- @classmethod
113
- def _decode (cls , lines ):
114
- """ Return a list of 2-tuples parsing 'k: v' and skipping comments
115
- >>> RTResponse._decode(['# c1: c2', 'spam: 1', 'ham: 2, 3', 'eggs:'])
116
- [('spam', '1'), ('ham', '2, 3'), ('eggs', '')]
117
- >>> RTResponse._decode(['<!DOCTYPE HTML PUBLIC >', '<html><head>',])
118
- []
119
- """
120
- try :
121
- lines = ifilterfalse (cls .COMMENT .match , lines )
122
- return [(k , v .strip (' ' )) for k , v in [l .split (':' , 1 ) for l in lines ]]
123
- except ValueError :
124
- return []
125
-
126
- @classmethod
127
- def _decode_comment (cls , lines ):
128
- """ Return a list of 2-tuples parsing '# k: v'
129
- >>> RTResponse._decode_comment(['# c1: c2', 'spam: 1', 'ham: 2, 3', 'eggs:'])
130
- [('c1', 'c2')]
131
- >>>
132
- """
133
- lines = filter (cls .COMMENT .match , lines )
134
- return [(k .strip ('# ' ), v .strip (' ' )) for k , v in [l .split (':' , 1 ) for l in lines ]]
135
-
136
- @classmethod
137
- def _build (cls , body ):
138
- """ Build logical lines from a RFC5322-like string
139
- >>> body = '''RT/1.2.3 200 Ok
140
- ...
141
- ... # a
142
- ... b
143
- ... spam: 1
144
- ...
145
- ... ham: 2,
146
- ... 3
147
- ... --
148
- ... # c
149
- ... spam: 4
150
- ... ham:
151
- ... --
152
- ... a -- b
153
- ... '''
154
- >>> RTResponse._build(body)
155
- [['# a b', 'spam: 1', 'ham: 2, 3'], ['# c', 'spam: 4', 'ham:'], ['a -- b']]
156
- """
157
- def build_section (section ):
158
- logic_lines = []
159
- for line in filter (None , section .splitlines ()):
160
- if cls .HEADER .match (line ):
161
- continue
162
- if line [0 ].isspace ():
163
- logic_lines [- 1 ] += ' ' + line .strip (' ' )
164
- else :
165
- logic_lines .append (line )
166
- return logic_lines
167
- return [build_section (b ) for b in cls .SECTION .split (body )]
0 commit comments