Completed
Push — master ( 155177...203d27 )
by Chris
01:26
created

camel2hyphen()   A

Complexity

Conditions 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
1
"""Standard filters."""
2
3
import re
4
5
import json
6
from string import ascii_lowercase
7
8
9
def camel2hyphen(string, **kwargs):
10
    """Convert a camelCaseString into a hyphenated one.
11
12
    Args:
13
        string (str): The string to format.
14
15
    Returns:
16
        string (str): The formatted string.
17
    """
18
    # CREDIT: http://stackoverflow.com/questions/1175208/
19
    # elegant-python-function-to-convert-camelcase-to-snake-case
20
    # (modified to use hyphen instead of underscores.)
21
    s1 = re.sub('(.)([A-Z][a-z]+)', r'\1-\2', string)
22
    return re.sub('([a-z0-9])([A-Z])', r'\1-\2', s1).lower()
23
24
25
def to_json(string, **kwargs):
26
    """Render json using native python module.
27
28
    Args:
29
        string (str): The string to format.
30
31
    Returns:
32
        string (str): The formatted string.
33
    """
34
    return json.dumps(string, **kwargs)
35
36
37
def css_selector(string, lowercase=True):
38
    """Convert a string to a css selector friendly format.
39
40
    Args:
41
        word (str): The string to format.
42
43
    Returns:
44
        word (str): The formatted word.
45
    """
46
    if not isinstance(string, str):
47
        return string
48
    string = string.replace(' ', '_')
49
    if not lowercase:
50
        return string
51
    return string.lower()
52
53
54
def title(word, capitalize=False):
55
    """Convert a string to a title format, where the words are capitalized.
56
57
    Args:
58
        word (str): The string to format.
59
60
    Returns:
61
        word (str): The formatted word.
62
    """
63
    def _capitalize(w):
64
        return '{0}{1}'.format(w[0].upper(), w[1:])
65
66
    if word is None:
67
        return ''
68
    words = word.split(' ')
69
    for i, word in enumerate(words):
70
        if i == 0 or capitalize:
71
            words[i] = _capitalize(word)
72
    return ' '.join(words)
73
74
75
def firstof(seq):
76
    """Return the first item that is truthy in a sequence.
77
78
    Equivalent to Djangos' firstof.
79
80
    Args:
81
        seq (list): A list of values.
82
83
    Returns:
84
        value (mixed): The output, depending on the truthiness of the input.
85
    """
86
    if not any(seq):
87
        return ''
88
    if all(seq):
89
        return seq[0]
90
    while seq:
91
        item = seq.pop(0)
92
        if item:
93
            return item
94
    return ''
95
96
97
def questionize_label(word):
98
    """Convert a word to a true/false style question format.
99
100
    If a user follows the convention of using `is_something`, or
101
    `has_something`, for a boolean value, the *property* text will
102
    automatically be converted into a more human-readable
103
    format, e.g. 'Something?' for is_ and Has Something? for has_.
104
105
    Args:
106
        word (str): The string to format.
107
108
    Returns:
109
        word (str): The formatted word.
110
    """
111
    if word is None:
112
        return ''
113
    if word.startswith('is_'):
114
        return '{0}?'.format(word[3:])
115
    elif word.startswith('has_'):
116
        return '{0}?'.format(word[4:])
117
    return word
118
119
120
def add(lst, arg):
121
    """Add an item to a list.
122
123
    Equivalent to Djangos' add.
124
125
    Args:
126
        lst (list): A list.
127
        arg (mixed): Any value to append to the list.
128
129
    Returns:
130
        list: The updated list.
131
    """
132
    lst.append(arg)
133
    return lst
134
135
136
def cut(val, removals):
137
    """Remove some value from a string.
138
139
    Similar to Djangos' cut, but accepts N arguments to remove, in turn.
140
141
    Args:
142
        val (str): A string.
143
        removals (list): Alist of values to remove in turn, from the value.
144
145
    Returns:
146
        str: The updated string.
147
    """
148
    def _cut(val, tocut):
149
        return val.replace(tocut, '')
150
    for r in removals:
151
        val = _cut(val, r)
152
    return val
153
154
155
def addslashes(val):
156
    """Add slashes before all single quotes in a given string.
157
158
    Equivalent to Djangos' addslashes.
159
160
    Args:
161
        val (str): A string.
162
163
    Returns:
164
        str: The updated string.
165
    """
166
    return val.replace("'", "\\'")
167
168
169
def default(val, default):
170
    """Default to a given value if another given value is falsy.
171
172
    Equivalent to Djangos' default.
173
174
    Args:
175
        val (mixed): A mixed value that is truthy or falsy.
176
        default (mixed): A default replacement value.
177
178
    Returns:
179
        mixed: The default given value, or the original value.
180
    """
181
    return default if not val else val
182
183
184
def default_if_none(val, default):
185
    """Default to a given value if another given value is None.
186
187
    Equivalent to Djangos' default_if_none.
188
189
    Args:
190
        val (mixed): A mixed value that may or may not be None.
191
        default (mixed): A default replacement value.
192
193
    Returns:
194
        mixed: The default given value, or the original value.
195
    """
196
    return default if val is None else val
197
198
199
def get_digit(val, index):
200
    """Return the digit of a value specified by an index.
201
202
    Equivalent to Djangos' get_digit.
203
204
    Args
205
        val (int): An integer.
206
        index (int): The index to check against.
207
208
    Returns:
209
        int: The original integer if index is invalid, otherwise the digit
210
        at the specified index.
211
    """
212
    digits = reversed(list(str(val)))
213
    for k, digit in enumerate(digits):
214
        if k + 1 == int(index):
215
            return int(digit)
216
    return val
217
218
219
def length_is(val, length):
220
    """Return True if the length of a given value matches a given length.
221
222
    Equivalent to Djangos' length_is.
223
224
    Args:
225
        val (mixed): A value to check the length of.
226
        length (int): The length to check.
227
228
    Returns:
229
        bool: The value of checking the length against length.
230
    """
231
    return len(val) == length
232
233
234
def is_url(val):
235
    """Return true if a value is a url string, otherwise false.
236
237
    Args:
238
        val (mixed): The value to check.
239
240
    Returns:
241
        bool: True if the value is an http string, False if not.
242
    """
243
    if isinstance(val, (str, unicode)):
244
        return val.startswith('http://') or val.startswith('https://')
245
    return False
246
247
248
def ljust(string, amt):
249
    """Left-align the value by the amount specified.
250
251
    Equivalent to Djangos' ljust.
252
253
    Args:
254
        string (str): The string to adjust.
255
        amt (int): The amount of space to adjust by.
256
257
    Returns:
258
        str: The padded string.
259
    """
260
    return string.ljust(amt)
261
262
263
def rjust(string, amt):
264
    """Right-align the value by the amount specified.
265
266
    Equivalent to Djangos' rjust.
267
268
    Args:
269
        string (str): The string to adjust.
270
        amt (int): The amount of space to adjust by.
271
272
    Returns:
273
        str: The padded string.
274
    """
275
    return string.rjust(amt)
276
277
278
def make_list(val, coerce_numbers=True):
279
    """Make a list from a given value.
280
281
    Roughly equivalent to Djangos' make_list, with some enhancements.
282
283
    Args:
284
        val (mixed): The value to convert.
285
        coerce_numbers (bool, optional): Whether or not string number
286
            should be coerced back to their original values.
287
288
    Returns:
289
        mixed: If dict is given, return d.items(). If list is given, return it.
290
            If integers given, return a list of digits.
291
            Otherwise, return a list of characters.
292
    """
293
    if isinstance(val, dict):
294
        return val.items()
295
    if isinstance(val, list):
296
        return val
297
    vals = list(str(val))
298
    if coerce_numbers and isinstance(val, str):
299
        lst = []
300
        for v in vals:
301
            try:
302
                lst.append(int(v))
303
            except ValueError:
304
                lst.append(v)
305
        return lst
306
    return vals
307
308
309
def phone2numeric(phoneword):
310
    """Convert a phoneword string into the translated number equivalent.
311
312
    Roughly equivalent to Djangos' phone2numeric.
313
314
    Args:
315
        phoneword (str): The phoneword string.
316
317
    Returns:
318
        str: The converted string digits.
319
    """
320
    two, three = ['a', 'b', 'c'], ['d', 'e', 'f']
321
    four, five = ['g', 'h', 'i'], ['j', 'k', 'l']
322
    six, seven = ['m', 'n', 'o'], ['p', 'q', 'r', 's']
323
    eight, nine = ['t', 'u', 'v'], ['w', 'x', 'y', 'z']
324
    newdigits = ''
325
    for digit in list(phoneword.lower()):
326
        if digit in two:
327
            newdigits += '2'
328
        elif digit in three:
329
            newdigits += '3'
330
        elif digit in four:
331
            newdigits += '4'
332
        elif digit in five:
333
            newdigits += '5'
334
        elif digit in six:
335
            newdigits += '6'
336
        elif digit in seven:
337
            newdigits += '7'
338
        elif digit in eight:
339
            newdigits += '8'
340
        elif digit in nine:
341
            newdigits += '9'
342
        else:
343
            newdigits += digit
344
    return newdigits
345
346
347
def pagetitle(string, remove_first=False, divider=' > '):
348
    """Convert a string of characters to page-title format.
349
350
    Args:
351
        string (str): The string to conert.
352
        remove_first (bool, optional): Remove the first instance of the
353
            delimiter of the newly formed title.
354
355
    Returns:
356
        str: The converted string.
357
    """
358
    _title = divider.join(string.split('/'))
359
    if remove_first:
360
        _title = _title.replace(divider, '', 1)
361
    return _title
362
363
364
def slugify(string):
365
    """Convert a string of characters to URL slug format.
366
367
    All characters replacing all characters with hyphens if invalid.
368
    Roughly equivalent to Djangos' slugify.
369
370
    Args:
371
        string (str): The string to slugify.
372
373
    Returns:
374
        str: The slugified string.
375
    """
376
    slug = ''
377
    accepted = ['-', '_'] + list(ascii_lowercase) + list('01234567890')
378
    end = len(string) - 1
379
    for k, char in enumerate(string.lower().strip()):
380
        if char not in accepted:
381
            # Forget about the last char if it would get replaced.
382
            if k < end:
383
                slug += '-'
384
        else:
385
            slug += char
386
    return slug
387
388
389
def greet(name, greeting='Hello'):
390
    """Add a greeting to a given name.
391
392
    Args:
393
        name (str): The name to greet.
394
        greeting (str, optional): An optional greeting override.
395
396
    Returns:
397
        str: The updated greeting string.
398
    """
399
    return '{0}, {1}!'.format(greeting, name)
400
401
402
def islist(item):
403
    """Check if an is item is a list - not just a sequence.
404
405
    Args:
406
        item (mixed): The item to check as a list.
407
408
    Returns:
409
        result (bool): True if the item is a list, False if not.
410
411
    """
412
    return isinstance(item, list)
413
414
415
def sql2dict(queryset):
416
    """Return a SQL alchemy style query result into a list of dicts.
417
418
    Args:
419
        queryset (object): The SQL alchemy result.
420
421
    Returns:
422
        result (list): The converted query set.
423
424
    """
425
    if queryset is None:
426
        return []
427
    return [record.__dict__ for record in queryset]
428