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

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 

13 

14import math 

15import re 

16 

17 

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 """ 

23 

24 def __init__(self, raw, cmd=None, cfg={}): 

25 super(Response, self).__init__(raw) 

26 

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) 

32 

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 = [] 

47 

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) 

67 

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 

76 

77 def addRecord(self, h): 

78 """ 

79 Add a record to the record list 

80 """ 

81 self.__records.append(Record(h)) 

82 return self 

83 

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 

91 

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 

98 

99 def getColumnKeys(self): 

100 """ 

101 Get Column Names 

102 """ 

103 return self.__columnkeys 

104 

105 def getColumns(self): 

106 """ 

107 Get List of Columns 

108 """ 

109 return self.__columns 

110 

111 def getCommand(self): 

112 """ 

113 Get Command used in this request 

114 """ 

115 return self.__command 

116 

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 

125 

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 

135 

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 ) 

143 

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 

156 

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 

170 

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 } 

182 

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 

191 

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 

202 

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 

212 

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 } 

228 

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 

239 

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 

248 

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 

256 

257 def getRecords(self): 

258 """ 

259 Get all Records 

260 """ 

261 return self.__records 

262 

263 def getRecordsCount(self): 

264 """ 

265 Get count of rows in this response 

266 """ 

267 return len(self.__records) 

268 

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() 

279 

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() 

290 

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() 

299 

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 

308 

309 def rewindRecordList(self): 

310 """ 

311 Reset index in record list back to zero 

312 """ 

313 self.__recordIndex = 0 

314 return self 

315 

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 

325 

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 

333 

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)) 

341 

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()