velocity-python 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of velocity-python might be problematic. Click here for more details.

File without changes
velocity/misc/conv.py ADDED
@@ -0,0 +1,420 @@
1
+ import re
2
+ import codecs
3
+ import decimal
4
+ from email.utils import parseaddr
5
+ from datetime import datetime, date, time
6
+ import pprint
7
+
8
+ # oconv converts data to be displayed or rendered.
9
+ class oconv(object):
10
+ @staticmethod
11
+ def none(data):
12
+ if data == None:
13
+ return ''
14
+ if data == 'None':
15
+ return ''
16
+ if data == 'null':
17
+ return ''
18
+ return data
19
+
20
+ @staticmethod
21
+ def phone(data):
22
+ if data == None:
23
+ return ''
24
+ if data == 'None':
25
+ return ''
26
+ if not data:
27
+ return data
28
+ data = re.search(r'\d{10}$', re.sub("[^0-9]", "", data)).group()
29
+ return "({}) {}-{}".format(data[:3],data[3:6],data[6:])
30
+
31
+
32
+ @staticmethod
33
+ def day_of_week(data, abbrev=False):
34
+ if isinstance(data, list):
35
+ new = []
36
+ for day in data:
37
+ new.append(oconv.day_of_week(day, abbrev=abbrev))
38
+ return ','.join(new)
39
+ if data == None:
40
+ return ''
41
+ if data == 'None':
42
+ return ''
43
+ if not data:
44
+ return data
45
+ if abbrev:
46
+ return {
47
+ 1: 'Mon',
48
+ 2: 'Tue',
49
+ 3: 'Wed',
50
+ 4: 'Thu',
51
+ 5: 'Fri',
52
+ 6: 'Sat',
53
+ 7: 'Sun'
54
+ }[int(data)]
55
+ return {
56
+ 1: 'Monday',
57
+ 2: 'Tuesday',
58
+ 3: 'Wednesday',
59
+ 4: 'Thursday',
60
+ 5: 'Friday',
61
+ 6: 'Saturday',
62
+ 7: 'Sunday'
63
+ }[int(data)]
64
+
65
+ @staticmethod
66
+ def date(*args, **kwds):
67
+ kwds.setdefault('fmt','%Y-%m-%d')
68
+ def _(param):
69
+ if isinstance(param,(datetime, date)):
70
+ return param.strftime( kwds['fmt'] )
71
+ else:
72
+ return param
73
+ if args and args[0]:
74
+ return _(args[0])
75
+ return _
76
+
77
+ @staticmethod
78
+ def time(*args, **kwds):
79
+ kwds.setdefault('fmt','%X')
80
+ def _(param):
81
+ if isinstance(param,(datetime, time)):
82
+ return param.strftime( kwds['fmt'] )
83
+ else:
84
+ return param
85
+ if args and args[0]:
86
+ return _(args[0])
87
+ return _
88
+
89
+ @staticmethod
90
+ def timestamp(*args, **kwds):
91
+ kwds.setdefault('fmt','%c')
92
+ def _(param):
93
+ if isinstance(param,(datetime)):
94
+ return param.strftime( kwds['fmt'] )
95
+ else:
96
+ return param
97
+ if args:
98
+ return _(args[0])
99
+ return _
100
+
101
+ @staticmethod
102
+ def email(data):
103
+ if data == None:
104
+ return ''
105
+ if data == 'None':
106
+ return ''
107
+ return data.lower()
108
+
109
+ @staticmethod
110
+ def pointer(data):
111
+ try:
112
+ return int(data)
113
+ except:
114
+ return ''
115
+
116
+ @staticmethod
117
+ def rot13(data):
118
+ return codecs.decode(data,'rot13')
119
+
120
+ @staticmethod
121
+ def boolean(data):
122
+ if isinstance(data,str):
123
+ if data.lower() in ['false','','f','off','no']:
124
+ return False
125
+ return bool(data)
126
+
127
+ @staticmethod
128
+ def money(data):
129
+ if data in [None,'']:
130
+ return ''
131
+ data = re.sub("[^0-9\.-]", "", str(data))
132
+ return '${:,.2f}'.format(decimal.Decimal(data))
133
+
134
+ @staticmethod
135
+ def round(precision, data=None):
136
+ def function(data):
137
+ data = re.sub("[^0-9\.]", "", str(data))
138
+ if data == '':
139
+ return '0'
140
+ return '{:.{prec}f}'.format(decimal.Decimal(data), prec=precision)
141
+ if data == None:
142
+ return function
143
+ return function(data)
144
+
145
+ @staticmethod
146
+ def ein(data):
147
+ if data == None:
148
+ return ''
149
+ if data == 'None':
150
+ return ''
151
+ if not data:
152
+ return data
153
+ data = re.search(r'\d{9}$', re.sub("[^0-9]", "", data)).group()
154
+ return "{}-{}".format(data[:2],data[2:])
155
+
156
+ @staticmethod
157
+ def list(data):
158
+ if data in (None,'None'):
159
+ return None
160
+ if isinstance(data, list):
161
+ return data
162
+ if isinstance(data, str):
163
+ if data[0] == '[':
164
+ return eval(data)
165
+ return [data]
166
+
167
+ @staticmethod
168
+ def title(data):
169
+ if data == None:
170
+ return ''
171
+ if data == 'None':
172
+ return ''
173
+ return str(data).title()
174
+
175
+ @staticmethod
176
+ def lower(data):
177
+ if data == None:
178
+ return ''
179
+ if data == 'None':
180
+ return ''
181
+ return str(data).lower()
182
+
183
+ @staticmethod
184
+ def upper(data):
185
+ if data == None:
186
+ return ''
187
+ if data == 'None':
188
+ return ''
189
+ return str(data).upper()
190
+
191
+ @staticmethod
192
+ def padding(length, char):
193
+ def inner(data):
194
+ if data is None:
195
+ return ''
196
+ return str(data).rjust(length, char)
197
+ return inner
198
+
199
+ @staticmethod
200
+ def pprint(data):
201
+ try:
202
+ return pprint.pformat(eval(data))
203
+ except:
204
+ return data
205
+
206
+ @staticmethod
207
+ def string(data):
208
+ if data == None:
209
+ return ''
210
+ return str(data)
211
+
212
+ # iconv converts data to be stored in the database.
213
+ # The source is generally user input from html forms.
214
+ class iconv(object):
215
+ @staticmethod
216
+ def none(data):
217
+ if data == '':
218
+ return None
219
+ if data == 'null':
220
+ return None
221
+ if data == '@NULL':
222
+ return None
223
+ return data
224
+
225
+ @staticmethod
226
+ def phone(data):
227
+ if data == 'None':
228
+ return None
229
+ if not data:
230
+ return data
231
+ return re.search(r'\d{10}$', re.sub("[^0-9]", "", data)).group()
232
+
233
+ @staticmethod
234
+ def day_of_week(data):
235
+ if not data:
236
+ return data
237
+ return {
238
+ 'monday': 1,
239
+ 'tuesday': 2,
240
+ 'wednesday': 3,
241
+ 'thursday': 4,
242
+ 'friday': 5,
243
+ 'saturday': 6,
244
+ 'sunday': 7,
245
+ 'mon': 1,
246
+ 'tue': 2,
247
+ 'wed': 3,
248
+ 'thu': 4,
249
+ 'fri': 5,
250
+ 'sat': 6,
251
+ 'sun': 7
252
+ }[data.lower()]
253
+
254
+ @staticmethod
255
+ def date(*args, **kwds):
256
+ kwds.setdefault('fmt', '%Y-%m-%d')
257
+ def _(param):
258
+ if isinstance(param,str):
259
+ return datetime.strptime(param, kwds['fmt']).date()
260
+ else:
261
+ return param
262
+ if args and args[0]:
263
+ return _(args[0])
264
+ return _
265
+
266
+ @staticmethod
267
+ def time(*args, **kwds):
268
+ kwds.setdefault('fmt','%X')
269
+ def _(param):
270
+ if isinstance(param, str):
271
+ return datetime.strptime(param, kwds['fmt']).time()
272
+ else:
273
+ return param
274
+ if args and args[0]:
275
+ return _(args[0])
276
+ return _
277
+
278
+ @staticmethod
279
+ def timestamp(*args, **kwds):
280
+ kwds.setdefault('fmt','%c')
281
+ def _(param):
282
+ if isinstance(param, str):
283
+ return datetime.strptime(param, kwds['fmt'])
284
+ else:
285
+ return param
286
+ if args and args[0]:
287
+ return _(args[0])
288
+ return _
289
+
290
+ @staticmethod
291
+ def email(data):
292
+ if not data:
293
+ return None
294
+ if data == 'None':
295
+ return None
296
+ data = data.strip().lower()
297
+ if '@' not in data:
298
+ raise Exception()
299
+ email = parseaddr(data)[1]
300
+ mailbox,domain = email.split('@')
301
+ if '.' in domain:
302
+ if len(domain.split('.')[1]) < 1:
303
+ raise Exception()
304
+ else:
305
+ raise Exception()
306
+ return data
307
+
308
+ @staticmethod
309
+ def integer(data):
310
+ return int(re.sub("[^0-9\.-]", "", str(data)))
311
+
312
+ @staticmethod
313
+ def boolean(data):
314
+ if isinstance(data,str):
315
+ if data.lower() in ['false','','f','off','no']:
316
+ return False
317
+ return bool(data)
318
+
319
+ @staticmethod
320
+ def rot13(data):
321
+ return codecs.encode(data,'rot13')
322
+
323
+ @staticmethod
324
+ def pointer(data):
325
+ if data == '@new': return data
326
+ if data == '': return None
327
+ if data == None: return None
328
+ if data == '@NULL': return None
329
+ return int(data)
330
+
331
+ @staticmethod
332
+ def money(data):
333
+ if data == 'None':
334
+ return None
335
+ if not data:
336
+ return data
337
+ return decimal.Decimal(re.sub("[^0-9\.-]", "", str(data)))
338
+
339
+ @staticmethod
340
+ def round(precision, data=None):
341
+ def function(data):
342
+ if data == 'None':
343
+ return None
344
+ if not data:
345
+ return data
346
+ if isinstance(data, str):
347
+ data = re.sub("[^0-9\.-]", "", data)
348
+ return decimal.Decimal(data).quantize(decimal.Decimal(10) ** -precision, rounding=decimal.ROUND_HALF_UP)
349
+ if data == None:
350
+ return function
351
+ return function(data)
352
+
353
+ @staticmethod
354
+ def decimal(data):
355
+ if data == 'None':
356
+ return None
357
+ if not data:
358
+ return data
359
+ return decimal.Decimal(re.sub("[^0-9\.-]", "", str(data)))
360
+
361
+ @staticmethod
362
+ def ein(data):
363
+ if data == 'None':
364
+ return None
365
+ if not data:
366
+ return data
367
+ return re.search(r'^\d{9}$', re.sub("[^0-9]", "", data)).group()
368
+
369
+ @staticmethod
370
+ def list(data):
371
+ if data in (None,'None'):
372
+ return None
373
+ if isinstance(data, str):
374
+ if data[0] == '[':
375
+ return data
376
+ if not isinstance(data, list):
377
+ data = [data]
378
+ return repr(data)
379
+
380
+ @staticmethod
381
+ def title(data):
382
+ if data == None:
383
+ return ''
384
+ if data == 'None':
385
+ return ''
386
+ return str(data).title()
387
+
388
+ @staticmethod
389
+ def lower(data):
390
+ if data == None:
391
+ return ''
392
+ if data == 'None':
393
+ return ''
394
+ return str(data).lower()
395
+
396
+
397
+ @staticmethod
398
+ def upper(data):
399
+ if data == None:
400
+ return ''
401
+ if data == 'None':
402
+ return ''
403
+ return str(data).upper()
404
+
405
+ @staticmethod
406
+ def padding(length, char):
407
+ def inner(data):
408
+ if data in [None,'None','']:
409
+ return None
410
+ return str(data).rjust(length, char)
411
+ return inner
412
+
413
+ @staticmethod
414
+ def string(data):
415
+ if data == '':
416
+ return None
417
+ return str(data)
418
+
419
+ if __name__=='__main__':
420
+ print(iconv.money("$123.441.234c"))
velocity/misc/db.py ADDED
@@ -0,0 +1,85 @@
1
+ import numbers
2
+ import random
3
+ import string
4
+ from functools import wraps
5
+ from velocity.db import exceptions
6
+
7
+ #TBD implement or delete all this code. It is not used anywhere.
8
+ def NotSupported(*args, **kwds):
9
+ raise Exception("Sorry, the driver for this database is not installed")
10
+
11
+
12
+ def NOTNULL(x):
13
+ """ Helper function to filter out NULL values from keys/values functions """
14
+ return len(x) == 2 and x[1] is not None
15
+
16
+
17
+ def pipe(func, primary, secondary, *args, **kwds):
18
+ with primary.transaction() as pri:
19
+ with secondary.transaction() as sec:
20
+ func(pri, sec, *args, **kwds)
21
+
22
+
23
+ class join(object):
24
+ @classmethod
25
+ def _or(cls, *args, **kwargs):
26
+ return '(' + ' or '.join(cls._list(*args, **kwargs)) + ')'
27
+
28
+ @classmethod
29
+ def _and(cls, *args, **kwargs):
30
+ return '(' + ' and '.join(cls._list(*args, **kwargs)) + ')'
31
+
32
+ @classmethod
33
+ def _list(cls, *args, **kwargs):
34
+ vals = []
35
+ vals.extend(args)
36
+ for key,val in kwargs.items():
37
+ if isinstance(val, numbers.Number):
38
+ vals.append("{}={}".format(key,val))
39
+ else:
40
+ vals.append("{}='{}'".format(key,val))
41
+ return vals
42
+
43
+
44
+
45
+ def return_default(default=None):
46
+ """
47
+ Decorator that sets a default value for a function.
48
+ If an exception is raised within the function, the decorator
49
+ catches the exception and returns the default value instead.
50
+ """
51
+ def decorator(f):
52
+ f.default = default
53
+ @wraps(f)
54
+ def return_default(self, *args, **kwds):
55
+ sp = self.tx.create_savepoint(cursor=self.table.cursor)
56
+ try:
57
+ result = f(self, *args, **kwds)
58
+ except (exceptions.DbApplicationError,
59
+ exceptions.DbTableMissingError,
60
+ exceptions.DbColumnMissingError,
61
+ exceptions.DbTruncationError,
62
+ StopIteration,
63
+ exceptions.DbObjectExistsError):
64
+ self.tx.rollback_savepoint(sp, cursor=self.table.cursor)
65
+ return f.default
66
+ self.tx.release_savepoint(sp, cursor=self.table.cursor)
67
+ return result
68
+ return return_default
69
+ return decorator
70
+
71
+
72
+ def randomword(length=None):
73
+ """
74
+ Generate a random word consisting of lowercase letters. This is used to generate random savepoint names.
75
+ The length of the word can be specified, otherwise a random length between 5 and 15 will be used.
76
+
77
+ Parameters:
78
+ length (int, optional): The length of the random word. If not provided, a random length between 5 and 15 will be used.
79
+
80
+ Returns:
81
+ str: The randomly generated word.
82
+ """
83
+ if length is None:
84
+ length = random.randint(5,15)
85
+ return ''.join(random.choice(string.ascii_lowercase) for i in range(length))
@@ -0,0 +1,147 @@
1
+ import openpyxl
2
+ from openpyxl.styles import NamedStyle, Font, Border, Side, Alignment
3
+ from openpyxl.utils import get_column_letter
4
+ from io import BytesIO
5
+ import base64
6
+
7
+ def extract(d, keys):
8
+ return [d[key] for key in keys]
9
+
10
+
11
+ def autosize_columns(ws, fixed={}):
12
+ # Try to autosize the columns (doesn't always work due to dynamic
13
+ # content, font family and font size differences, etc.) There is no
14
+ # easy way to do this when buiding excel files.
15
+ for col in ws.columns:
16
+ max_length = 0
17
+ for cell in col:
18
+ try: # Necessary to avoid error on empty cells
19
+ if len(str(cell.value)) > max_length:
20
+ max_length = len(cell.value)
21
+ except:
22
+ pass
23
+ adjusted_width = (max_length + 2) * 1.2
24
+ try:
25
+ l = get_column_letter(col[0].column)
26
+ if l in fixed:
27
+ adjusted_width = fixed['l']
28
+ ws.column_dimensions[l].width = adjusted_width
29
+ except:
30
+ l = col[0].column
31
+ if l in fixed:
32
+ adjusted_width = fixed['l']
33
+ ws.column_dimensions[l].width = adjusted_width
34
+
35
+
36
+ def create_spreadsheet(headers,
37
+ rows,
38
+ fileorbuffer,
39
+ styles={},
40
+ merge=[],
41
+ formats={},
42
+ named_styles=[],
43
+ freeze_panes='A2',
44
+ dimensions=None,
45
+ auto_size=True):
46
+ wb = openpyxl.Workbook()
47
+ ws = wb.active
48
+
49
+ local_styles = {}
50
+
51
+ style = NamedStyle(name="col_header")
52
+ style.font = Font(bold=True)
53
+ style.border = Border(bottom=Side(style='medium', color="000000"))
54
+ local_styles[style.name] = style
55
+
56
+ style = NamedStyle(name="sum_total")
57
+ style.border = Border(bottom=Side(style='double', color="000000"))
58
+ local_styles[style.name] = style
59
+
60
+ style = NamedStyle(name="sub_total")
61
+ style.font = Font(bold=True)
62
+ style.border = Border(bottom=Side(style='thin', color="000000"))
63
+ local_styles[style.name] = style
64
+
65
+ style = NamedStyle(name="bold")
66
+ style.font = Font(bold=True)
67
+ local_styles[style.name] = style
68
+
69
+ style = NamedStyle(name="align_right")
70
+ style.font = Font(bold=True)
71
+ style.border = Border(top=Side(style='thin', color="000000"))
72
+ style.alignment = Alignment(horizontal="right", vertical="center")
73
+ local_styles[style.name] = style
74
+
75
+ style = NamedStyle(name="align_left")
76
+ style.font = Font(bold=True)
77
+ style.border = Border(top=Side(style='thin', color="000000"))
78
+ style.alignment = Alignment(horizontal="left", vertical="center")
79
+ local_styles[style.name] = style
80
+
81
+ style = NamedStyle(name="align_right_double")
82
+ style.font = Font(bold=True)
83
+ style.border = Border(top=Side(style='double', color="000000"))
84
+ style.alignment = Alignment(horizontal="right", vertical="center")
85
+ local_styles[style.name] = style
86
+
87
+ style = NamedStyle(name="align_left_double")
88
+ style.font = Font(bold=True)
89
+ style.border = Border(top=Side(style='double', color="000000"))
90
+ style.alignment = Alignment(horizontal="left", vertical="center")
91
+ local_styles[style.name] = style
92
+
93
+ for style in named_styles:
94
+ local_styles[style.name] = style
95
+
96
+ for style in local_styles.values():
97
+ wb.add_named_style(style)
98
+
99
+ ws.append(headers)
100
+
101
+ [ws.append(row) for row in rows]
102
+
103
+ if freeze_panes:
104
+ ws.freeze_panes = freeze_panes
105
+
106
+ if auto_size:
107
+ autosize_columns(ws)
108
+
109
+ if dimensions:
110
+ for key, val in dimensions.get('rows', {}).items():
111
+ ws.row_dimensions[key].height = val
112
+ for key, val in dimensions.get('columns', {}).items():
113
+ ws.column_dimensions[key].width = val
114
+
115
+ for cell, style in styles.items():
116
+ ws[cell].style = style
117
+
118
+ for cell_range in merge:
119
+ ws.merge_cells(cell_range)
120
+
121
+ for cell, format in formats.items():
122
+ ws[cell].number_format = format
123
+
124
+ wb.save(fileorbuffer)
125
+
126
+
127
+ def getDownloadableSpreadsheet(headers,
128
+ rows,
129
+ styles={},
130
+ merge=[],
131
+ formats={},
132
+ named_styles=[],
133
+ freeze_panes='A2',
134
+ dimensions=None,
135
+ auto_size=True):
136
+ buffer = BytesIO()
137
+ create_spreadsheet(headers,
138
+ rows,
139
+ buffer,
140
+ styles,
141
+ merge,
142
+ formats,
143
+ named_styles,
144
+ freeze_panes,
145
+ dimensions,
146
+ auto_size)
147
+ return base64.b64encode(buffer.getvalue()).decode()