Coverage for hexonet/apiconnector/response.py: 99%
179 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 09:07 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 09:07 +0000
1# -*- coding: utf-8 -*-
2"""
3 hexonet.apiconnector.response
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 This module covers all necessary functionality to
6 work with Backend API responses.
7 :copyright: © 2018 by HEXONET GmbH.
8 :license: MIT, see LICENSE for more details.
9"""
10from hexonet.apiconnector.responsetemplate import ResponseTemplate as RT
11from hexonet.apiconnector.column import Column
12from hexonet.apiconnector.record import Record
14import math
15import re
18class Response(RT, object):
19 """
20 The Response class covers all necessary functionality to cover access to
21 Backend API response data in a useful way.
22 """
24 def __init__(self, raw, cmd=None, cfg={}):
25 super(Response, self).__init__(raw)
27 if re.search(r"\{[A-Z_]+\}", self._raw):
28 for key, value in cfg.items():
29 self._raw = self._raw.replace("{%s}" % (key), value)
30 self._raw = re.sub(r"\{[A-Z_]+\}", "", self._raw)
31 super(Response, self).__init__(self._raw)
33 # The API Command used within this request
34 self.__command = cmd
35 if (self.__command is not None) and ("PASSWORD" in self.__command):
36 self.__command["PASSWORD"] = "***"
37 # Column names available in this responsse.
38 # NOTE: this includes also FIRST, LAST, LIMIT, COUNT, TOTAL
39 # and maybe further specific columns in case of a list query
40 self.__columnkeys = []
41 # Container of Column Instances
42 self.__columns = []
43 # Record Index we currently point to in record list
44 self.__recordIndex = 0
45 # Record List (List of rows)
46 self.__records = []
48 h = self.getHash()
49 if "PROPERTY" in h:
50 colKeys = list(h["PROPERTY"].keys())
51 count = 0
52 for c in colKeys:
53 d = h["PROPERTY"][c]
54 self.addColumn(c, d)
55 mylen = len(d)
56 if mylen > count:
57 count = mylen
58 for i in range(count):
59 d = {}
60 for k in colKeys:
61 col = self.getColumn(k)
62 if col is not None:
63 v = col.getDataByIndex(i)
64 if v is not None:
65 d[k] = v
66 self.addRecord(d)
68 def addColumn(self, key, data):
69 """
70 Add a column to the column list
71 """
72 col = Column(key, data)
73 self.__columns.append(col)
74 self.__columnkeys.append(key)
75 return self
77 def addRecord(self, h):
78 """
79 Add a record to the record list
80 """
81 self.__records.append(Record(h))
82 return self
84 def getColumn(self, key):
85 """
86 Get column by column name
87 """
88 if self.__hasColumn(key):
89 return self.__columns[self.__columnkeys.index(key)]
90 return None
92 def getColumnIndex(self, colkey, index):
93 """
94 Get Data by Column Name and Index
95 """
96 col = self.getColumn(colkey)
97 return col.getDataByIndex(index) if (col is not None) else None
99 def getColumnKeys(self):
100 """
101 Get Column Names
102 """
103 return self.__columnkeys
105 def getColumns(self):
106 """
107 Get List of Columns
108 """
109 return self.__columns
111 def getCommand(self):
112 """
113 Get Command used in this request
114 """
115 return self.__command
117 def getCommandPlain(self):
118 """
119 Get Command used in this request in plain text
120 """
121 tmp = ""
122 for key, val in self.__command.items():
123 tmp += "%s = %s\n" % (key, val)
124 return tmp
126 def getCurrentPageNumber(self):
127 """
128 Get Page Number of current List Query
129 """
130 first = self.getFirstRecordIndex()
131 limit = self.getRecordsLimitation()
132 if (first is not None) and (limit):
133 return math.floor(first / limit) + 1
134 return None
136 def getCurrentRecord(self):
137 """
138 Get Record of current record index
139 """
140 return (
141 self.__records[self.__recordIndex] if (self.__hasCurrentRecord()) else None
142 )
144 def getFirstRecordIndex(self):
145 """
146 Get Index of first row in this response
147 """
148 col = self.getColumn("FIRST")
149 if col is not None:
150 f = col.getDataByIndex(0)
151 if f is not None:
152 return int(f)
153 if len(self.__records):
154 return 0
155 return None
157 def getLastRecordIndex(self):
158 """
159 Get last record index of the current list query
160 """
161 col = self.getColumn("LAST")
162 if col is not None:
163 data = col.getDataByIndex(0)
164 if data is not None:
165 return int(data)
166 len = self.getRecordsCount()
167 if len:
168 return len - 1
169 return None
171 def getListHash(self):
172 """
173 Get Response as List Hash including useful meta data for tables
174 """
175 lh = []
176 for rec in self.getRecords():
177 lh.append(rec.getData())
178 return {
179 "LIST": lh,
180 "meta": {"columns": self.getColumnKeys(), "pg": self.getPagination()},
181 }
183 def getNextRecord(self):
184 """
185 Get next record in record list
186 """
187 if self.__hasNextRecord():
188 self.__recordIndex += 1
189 return self.__records[self.__recordIndex]
190 return None
192 def getNextPageNumber(self):
193 """
194 Get Page Number of next list query
195 """
196 cp = self.getCurrentPageNumber()
197 if cp is None:
198 return None
199 page = cp + 1
200 pages = self.getNumberOfPages()
201 return page if (page <= pages) else pages
203 def getNumberOfPages(self):
204 """
205 Get the number of pages available for this list query
206 """
207 t = self.getRecordsTotalCount()
208 limit = self.getRecordsLimitation()
209 if t and limit:
210 return math.ceil(t / self.getRecordsLimitation())
211 return 0
213 def getPagination(self):
214 """
215 Get object containing all paging data
216 """
217 return {
218 "COUNT": self.getRecordsCount(),
219 "CURRENTPAGE": self.getCurrentPageNumber(),
220 "FIRST": self.getFirstRecordIndex(),
221 "LAST": self.getLastRecordIndex(),
222 "LIMIT": self.getRecordsLimitation(),
223 "NEXTPAGE": self.getNextPageNumber(),
224 "PAGES": self.getNumberOfPages(),
225 "PREVIOUSPAGE": self.getPreviousPageNumber(),
226 "TOTAL": self.getRecordsTotalCount(),
227 }
229 def getPreviousPageNumber(self):
230 """
231 Get Page Number of previous list query
232 """
233 cp = self.getCurrentPageNumber()
234 if cp is not None:
235 cp = cp - 1
236 if cp:
237 return cp
238 return None
240 def getPreviousRecord(self):
241 """
242 Get previous record in record list
243 """
244 if self.__hasPreviousRecord():
245 self.__recordIndex -= 1
246 return self.__records[self.__recordIndex]
247 return None
249 def getRecord(self, idx):
250 """
251 Get Record at given index
252 """
253 if idx >= 0 and len(self.__records) > idx:
254 return self.__records[idx]
255 return None
257 def getRecords(self):
258 """
259 Get all Records
260 """
261 return self.__records
263 def getRecordsCount(self):
264 """
265 Get count of rows in this response
266 """
267 return len(self.__records)
269 def getRecordsTotalCount(self):
270 """
271 Get total count of records available for the list query
272 """
273 col = self.getColumn("TOTAL")
274 if col is not None:
275 t = col.getDataByIndex(0)
276 if t is not None:
277 return int(t)
278 return self.getRecordsCount()
280 def getRecordsLimitation(self):
281 """
282 Get limit(ation) setting of the current list query
283 """
284 col = self.getColumn("LIMIT")
285 if col is not None:
286 data = col.getDataByIndex(0)
287 if data is not None:
288 return int(data)
289 return self.getRecordsCount()
291 def hasNextPage(self):
292 """
293 Check if this list query has a next page
294 """
295 cp = self.getCurrentPageNumber()
296 if cp is None:
297 return False
298 return (cp + 1) <= self.getNumberOfPages()
300 def hasPreviousPage(self):
301 """
302 Check if this list query has a previous page
303 """
304 cp = self.getCurrentPageNumber()
305 if cp is None:
306 return False
307 return (cp - 1) > 0
309 def rewindRecordList(self):
310 """
311 Reset index in record list back to zero
312 """
313 self.__recordIndex = 0
314 return self
316 def __hasColumn(self, key):
317 """
318 Check if column exists in response
319 """
320 try:
321 self.__columnkeys.index(key)
322 except ValueError:
323 return False
324 return True
326 def __hasCurrentRecord(self):
327 """
328 Check if the record list contains a record for the
329 current record index in use
330 """
331 tlen = len(self.__records)
332 return tlen > 0 and self.__recordIndex >= 0 and self.__recordIndex < tlen
334 def __hasNextRecord(self):
335 """
336 Check if the record list contains a next record for the
337 current record index in use
338 """
339 next = self.__recordIndex + 1
340 return self.__hasCurrentRecord() and (next < len(self.__records))
342 def __hasPreviousRecord(self):
343 """
344 Check if the record list contains a previous record for the
345 current record index in use
346 """
347 return self.__recordIndex > 0 and self.__hasCurrentRecord()