瀏覽代碼

Make parser state logic a bit more bearable

Alois Mahdal 5 年之前
父節點
當前提交
53ab4ffc74
共有 1 個文件被更改,包括 18 次插入19 次删除
  1. 18
    19
      gcconv.py

+ 18
- 19
gcconv.py 查看文件

@@ -1,6 +1,10 @@
1 1
 # coding=utf-8
2 2
 """Convert Bank statement CSV to Gnucash-acceptable format"""
3 3
 
4
+from collections import namedtuple
5
+
6
+ParserState = namedtuple('ParserState', 'ths nxt')
7
+
4 8
 
5 9
 def valid_formats():
6 10
     return _parsers.keys()
@@ -53,14 +57,13 @@ class BaseTransactionParser(object):
53 57
 
54 58
     def __init__(self):
55 59
         self.transactions = []
56
-        self.state = False
57
-        self.next_state = False
60
+        self.state = ParserState(ths=False, nxt=False)
58 61
 
59 62
     def is_open(self):
60
-        return self.state
63
+        return self.state.ths
61 64
 
62 65
     def is_closed(self):
63
-        return not self.state
66
+        return not self.state.ths
64 67
 
65 68
     def parse_file(self, fpath, encoding='utf-8'):
66 69
         lines_read = 0
@@ -68,7 +71,7 @@ class BaseTransactionParser(object):
68 71
             for line in f.readlines():
69 72
                 line = line.decode(encoding).strip()
70 73
                 lines_read += 1
71
-                self.state = self.pick_state(line, lineno=lines_read)
74
+                self.state = self.advance(line, lineno=lines_read)
72 75
                 if self.is_open():
73 76
                     self.transactions.append(self.parse_line(line).to_gc())
74 77
 
@@ -153,16 +156,14 @@ class MbankTransactionParser(BaseTransactionParser):
153 156
     def parse_line(self, line):
154 157
         return MbankTransaction(line)
155 158
 
156
-    def pick_state(self, line, lineno=None):
159
+    def advance(self, line, lineno=None):
157 160
         """Choose parser state according to current line and line no."""
158
-        if self.next_state:
159
-            self.next_state = False
160
-            return True
161
+        if self.state.nxt:
162
+            return ParserState(ths=True, nxt=False)
161 163
         if self.is_closed() and line.startswith(u'#Datum uskute'):
162
-            self.next_state = True
163
-            return False
164
+            return ParserState(ths=False, nxt=True)
164 165
         if self.is_open() and not line:
165
-            return False
166
+            return ParserState(ths=False, nxt=False)
166 167
         return self.state
167 168
 
168 169
 
@@ -252,14 +253,12 @@ class FioTransactionParser(BaseTransactionParser):
252 253
     def parse_line(self, line):
253 254
         return FioTransaction(line)
254 255
 
255
-    def pick_state(self, line, lineno=None):
256
+    def advance(self, line, lineno=None):
256 257
         """Choose parser state according to current line and line no."""
257
-        if self.next_state:
258
-            self.next_state = False
259
-            return True
260
-        if self.is_closed() and line.startswith(u'"ID operace";"Datum";'):
261
-            self.next_state = True
262
-            return False
258
+        if self.state.nxt:
259
+            return ParserState(ths=True, nxt=False)
260
+        if self.is_open() and line.startswith(u'"ID operace";"Datum";'):
261
+            return ParserState(ths=False, nxt=True)
263 262
         return self.state
264 263
 
265 264