def base64_decode(obj): """ Decode using base64 :param obj: :return: """ return mark_safe(Str.base64_decode(obj))
def base64_encode(obj): """ Base64 encode the specified string. :param obj: :return: """ return mark_safe(Str.base64_encode(obj))
def _parse_datetime(dct): FORMAT_24H = ('%H:%M:%S', '%H:%M') FORMAT_12H = ('%I:%M:%S%p', '%I:%M%p', '%I:%M:%S %p', '%I:%M %p', '%I%p', '%I %p') def get_time(time_str): if Str.contains_any(time_str, 'am', 'pm', 'a.m.', 'p.m.'): return Dt.get_time(time_str, FORMAT_12H, default_value=False) elif ':' in time_str: return Dt.get_time(time_str, FORMAT_24H, default_value=False) return False def fuzzy_is_datetime(dt): # 2014 year = re.match(r'\d{4}', dt) # 10:30pm time = re.match(r'\d?\d\d', dt) return bool(year or time) for k, v in dct.items(): if isinstance(v, str) and not Str.is_int(v): try: time_value = get_time(v) if time_value is not False: dct[k] = time_value elif fuzzy_is_datetime(v): dct[k] = parser.parse(v) except: pass return dct
def __init__(self, cursor, query: str, rows_per_page=10, current_page=1): """ :param cursor: connection.cursor() :param query: the query without the limit command :param rows_per_page: :param current_page: 1-index (first page is 1) :return: """ self.backend = DbNorm.get_backend_engine() self.cursor = cursor self.query = query self.rows_per_page = Str.int_val(rows_per_page, 10) self.current_page = Str.int_val(current_page, 1) self.count() if self.row_count > 0: self.page_count = math.ceil(self.row_count / rows_per_page)
def as_css_id(the_str, post_fix=None): """ Format the specified string as valid css_id value. "123 Hello $2" => "hello-2" :param the_str: :param post_fix: :return: """ css_id = Str.to_css_id(the_str) if post_fix is not None: css_id += post_fix.__str__() return css_id
def has_field(cls, model: models.Model, field_name: str): """ Check if the model has the column with specified name. :param model: :param field_name: :return: """ for f in model._meta.fields: if Str.eq(f.name, field_name): return True return False
def __init__(self, filter): self.filter_str = filter if not Str.contains(filter, ':'): self.filter_name = filter else: m = Filter.PARSE_REGEX.match(filter) if m: self.filter_name = m.group('filter') self.filter_param = m.group('param') else: raise ValueError('Invalid filter "%s"' % filter)
def gen_data_tags(cls, data_dict: dict): """ Return the the string of all data (ie. ' data-key1="value1" data-key2="value2"') :param data_dict: :return: """ result = '' if data_dict: for k, v in data_dict.items(): result += ' data-%s="%s"' % (Str.snake_to_kebab(k), defaultfilters.escape(v)) return mark_safe(result)
def as_thumbnail(link, dimension='200x300'): if not link: return None if hasattr(link, 'url'): link = link.url width, height = Str.split_parts(dimension, 'x', 1, [200, 300]) title = basename(link) or link result = '<a class="lazifier-img-link" href="{link}" title="{title}"><img class="lazifier-thumbnail" src="{link}" alt="" ' \ 'style="max-width: {width}px; max-height={height}px" /></a>' \ .format(link=escape(link), title=escape(title), width=width, height=height) return mark_safe(result)
def gen_attr_tags(cls, attr_dict: dict): """ Return the the string of all the attributes (ie. ' attr1="value1" attr2="value2"') :param attr_dict: :return: """ result = '' if attr_dict: for k, v in attr_dict.items(): if k.lower() in ['disabled', 'readonly', 'checked']: result += ' %s' % k.lower() else: result += ' %s="%s"' % (Str.snake_to_kebab(k), defaultfilters.escape(v)) return mark_safe(result)
def convert_to_int(cls, str_list): """ Convert a list of string into a list of int :param str_list: ["1", "2.99", "0.11"] => [1, 3, 0] :return: [] """ if not str_list: return [] int_list = [] for s in str_list: val = Str.int_val(s, None) if val is not None: int_list.append(val) return int_list
def get_page_query(self, page_number): """ Get the mysql query for the specified page. :param page_number: 1-index (first page is 1) :return: """ # [LIMIT {[offset,] row_count | row_count OFFSET offset}] page_number = Str.int_val(page_number, 1) if page_number <= 0: page_number = 1 elif self.row_count > 0 and page_number > self.page_count: page_number = self.page_count offset = (page_number - 1) * self.rows_per_page row_count = self.rows_per_page db_norm = DbNorm.get_db_normalizer() limit_query = db_norm.limit(offset, row_count) query = '%s %s' % (self.query, limit_query) return query
def _return_command(cls, cmd_dict: dict, options: dict): # convert key from redirect_url into redirectUrl cmd_dict['options'] = dict((Str.snake_to_camel(k), v) for k, v in options.items()) return HttpResponse(Json.to_json(cmd_dict, pretty=True))
def _make_attr(cls, attr, value, is_clean_value=False): if not value: return '' value = value if is_clean_value else defaultfilters.escape(value) return mark_safe(' %s="%s"' % (Str.to_css_id(attr), value))
def as_table(data, filter_param=None): """ Turn queryset or list row_dict into a table. :param data: queryset|list of [row_dict] :param filter_param: comma separated list of column. Syntax: queryset|as_table:'include_me, !not_include, include2' eg. users|as_table:'!age, !password' eg. group|as_table:'name, group_count' :return: """ if not data: return None result = [] filter_list = [] exclude_list = [] model = Obj.getattr(data, 'model', None, False) if filter_param: filter_param_list = Lst.strip_string(filter_param.split(',')) for the_filter in filter_param_list: assert isinstance(the_filter, str) if the_filter.startswith('!'): exclude_list.append(the_filter[1:]) else: filter_list.append(the_filter) if isinstance(data, dict): sub_tables = {} for key, row in data.items(): if isinstance(row, list): sub_tables[key] = as_table(row, filter_param) continue row_dict = Obj.get_dict(row, filter_list, exclude_list, verbose_key=True, get_display=True) result.append(row_dict) if sub_tables: context = {'sub_tables': sub_tables} html = render_to_string('lazifier/table_filter/as_table_filter_sub_tables_layout.html', context) return mark_safe(html) else: if isinstance(data, collections.Iterable): for row in data: row_dict = Obj.get_dict(row, filter_list, exclude_list, verbose_key=True, get_display=True) for k, v in row_dict.items(): if isinstance(v, list): if v: row_dict[k] = as_table(v, filter_param) result.append(row_dict) else: result.append(Obj.get_dict(data, verbose_key=True)) if result: headers = [] if model is not None: columns = result[0].keys() headers = list(Mdl.get_field_verbose(model, columns).values()) else: for k, v in result[0].items(): if Str.is_int(k): headers.append(type(v).__name__) elif type(k) is str and k.islower(): headers.append(Str.snake_to_title(k)) else: headers.append(k) context = {'headers': headers, 'data': result} html = render_to_string('lazifier/table_filter/as_table_filter_layout.html', context) else: return None return mark_safe(html)
def getattr(cls, obj, attr_name: str, default_value=None, execute_callable: bool = True): """ Similar to native getattr() function, however it supports the dot notation to extract the sub-attr eg. Obj.getattr(person, "contact.name") This will first get the contact from the "person" object and then get the name from that. :param obj: :param attr_name: the attribute name, use dot to go further into sub-object eg. "doctor.phone_num". :param execute_callable: if attr is a function run the function and return the result :return: """ if obj is None: return default_value not_found = 'getattr() Not Found' attr_name = str(attr_name) attrs = attr_name.split('.') # no name return none if not attrs: return default_value for att, last_item in last_iter(attrs): val = getattr(obj, att, not_found) # if not found using getattr then try to use some other alternative methods if val is not_found: # test positive int to get attr using index instead of name (ie. lists and tuples) if Str.is_positive_int(att) \ and (isinstance(obj, list) or isinstance(obj, tuple)): index = int(att) if index < len(obj): val = obj[index] elif Obj.has_func(obj, '__getitem__', '__contains__'): if att in obj: val = obj[att] elif Str.is_positive_int(att): index = int(att) if index in obj: val = obj[index] if val is not_found: return default_value if val is None and not last_item: return default_value # endif not found if callable(val) and not isinstance(val, Manager) and execute_callable: # watch out for bound vs unbound method # ref: https://docs.python.org/3/library/inspect.html#inspect.ismethod # is bound method (ie. func of an instance, ie. not static) # if inspect.ismethod(val): (bounded, not use for now) val = val.__call__() obj = val return obj
# all test self.assertTrue(Lst.any([1, 2, 3], lambda x: x == 1)) self.assertFalse(Lst.any([1, 2, 3], lambda x: x == 7)) self.assertTrue(Lst.all([2, 4, 8], lambda x: x % 2 == 0)) self.assertFalse(Lst.all([2, 5, 8], lambda x: x % 2 == 0)) class StrTest(SimpleTestCase): def test_str(self): self.assertEqual(Str.casefold('ViỆt Nam'), Str.casefold('việt nam')) self.assertTrue(Str.eq('a', 'A')) self.assertFalse(Str.eq('a', 'A', case=True)) self.assertTrue(Str.contains("Hello", "hell")) self.assertFalse(Str.contains("Hello", "hell", case=True)) # base64 plain_str = 'hello world!' b64 = 'aGVsbG8gd29ybGQh' self.assertEqual(Str.base64_encode(plain_str), b64) self.assertEqual(Str.base64_decode(b64), plain_str) plain_str = 'this is a test' b64 = 'dGhpcyBpcyBhIHRlc3Q=' self.assertEqual(Str.base64_encode(plain_str), b64) self.assertEqual(Str.base64_decode(b64), plain_str) # is_int() self.assertTrue(Str.is_int('0')) self.assertTrue(Str.is_int('1'))
def test_str(self): self.assertEqual(Str.casefold('ViỆt Nam'), Str.casefold('việt nam')) self.assertTrue(Str.eq('a', 'A')) self.assertFalse(Str.eq('a', 'A', case=True))
def get_time(time_str): if Str.contains_any(time_str, 'am', 'pm', 'a.m.', 'p.m.'): return Dt.get_time(time_str, FORMAT_12H, default_value=False) elif ':' in time_str: return Dt.get_time(time_str, FORMAT_24H, default_value=False) return False
def get_id_tag_string(cls, css_id: str, id_prefix=''): if id_prefix: id_prefix = id_prefix.strip('-') + '-' return mark_safe( cls._make_attr('id', Str.to_css_id(id_prefix + css_id)))