Skip to content

Functions

src.utils.strings.decode_url(url: str) -> yarl.URL

Unescapes and decodes a URL string and returns it as a URL object.

Parameters:

Name Type Description Default
url str

URL string to format.

required

Returns:

Type Description
URL

Formatted URL object.

Source code in src\utils\strings.py
108
109
110
111
112
113
114
115
116
117
118
119
120
def decode_url(url: str) -> yarl.URL:
    """Unescapes and decodes a URL string and returns it as a URL object.

    Args:
        url: URL string to format.

    Returns:
        Formatted URL object.
    """
    st = codecs.decode(
        html.unescape(parse.unquote(url)),
        'unicode_escape')
    return yarl.URL(st)

src.utils.strings.is_multiline(text: Union[str, list[str]]) -> Union[bool, list[bool]]

Check if text or list of texts given contains multiline text (a newline character).

Parameters:

Name Type Description Default
text str | list[str]

String to check or list of strings to check.

required

Returns:

Type Description
bool | list[bool]

True/False or list of True/False values.

Source code in src\utils\strings.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
def is_multiline(text: Union[str, list[str]]) -> Union[bool, list[bool]]:
    """Check if text or list of texts given contains multiline text (a newline character).

    Args:
        text: String to check or list of strings to check.

    Returns:
        True/False or list of True/False values.
    """
    # String Given
    if isinstance(text, str):
        if '\n' in text or '\r' in text:
            return True
        return False
    # List Given
    if isinstance(text, list):
        return [bool('\n' in t or '\r' in t) for t in text]
    # Invalid data type provided
    raise Exception("Invalid type passed to 'is_multiline', can only accept a string or list of strings.\n"
                    f"Received the value: {text}")

src.utils.strings.strip_lines(text: str, num: int, sep: str = '\n') -> str

Removes a number of leading or trailing lines from a multiline string.

1
2
3
4
Args:
    text: Multiline string.
    num: Positive integer for number leading lines, negative integer for number of trailing lines.
    sep: Newline separator to use for split, defaults to '

'.

1
2
Returns:
    String with lines stripped.
Source code in src\utils\strings.py
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
def strip_lines(text: str, num: int, sep: str = '\n') -> str:
    """Removes a number of leading or trailing lines from a multiline string.

    Args:
        text: Multiline string.
        num: Positive integer for number leading lines, negative integer for number of trailing lines.
        sep: Newline separator to use for split, defaults to '\n'.

    Returns:
        String with lines stripped.
    """
    if num == 0:
        return text
    if num < 0:
        return '\n'.join(text.split(sep)[:num])
    return '\n'.join(text.split(sep)[num:])

src.utils.strings.get_line(text: str, i: int, sep: str = '\n') -> str

Get line by index from a multiline string.

1
2
3
4
Args:
    text: Multiline string.
    i: Index of the line.
    sep: Newline separator to use for split, defaults to '

'.

1
2
Returns:
    Isolated line.
Source code in src\utils\strings.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
def get_line(text: str, i: int, sep: str = '\n') -> str:
    """Get line by index from a multiline string.

    Args:
        text: Multiline string.
        i: Index of the line.
        sep: Newline separator to use for split, defaults to '\n'.

    Returns:
        Isolated line.
    """
    if abs(i) > text.count('\n'):
        raise IndexError(f"Not enough lines in multiline string. Index of {i} is invalid.")
    return text.split(sep)[i]

src.utils.strings.get_lines(text: str, num: int, sep: str = '\n') -> str

Separate a number of lines from a multiline string.

1
2
3
4
Args:
    text: Multiline string.
    num: Number of lines to separate and return, negative integer for trailing lines.
    sep: Newline separator to use for split, defaults to '

'.

1
2
Returns:
    Isolated lines.
Source code in src\utils\strings.py
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
def get_lines(text: str, num: int, sep: str = '\n') -> str:
    """Separate a number of lines from a multiline string.

    Args:
        text: Multiline string.
        num: Number of lines to separate and return, negative integer for trailing lines.
        sep: Newline separator to use for split, defaults to '\n'.

    Returns:
        Isolated lines.
    """
    if num == 0 or abs(num) > text.count('\n') + 1:
        return text
    if num < 0:
        return '\n'.join(text.split(sep)[num:])
    return '\n'.join(text.split(sep)[:num])

src.utils.strings.normalize_str(st: str, no_space: bool = False) -> str

Normalizes a string for safe comparison.

Parameters:

Name Type Description Default
st str

String to normalize.

required
no_space bool

If True remove all spaces, otherwise just leading and trailing spaces.

False

Returns:

Type Description
str

Normalized string.

Source code in src\utils\strings.py
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
def normalize_str(st: str, no_space: bool = False) -> str:
    """Normalizes a string for safe comparison.

    Args:
        st: String to normalize.
        no_space: If True remove all spaces, otherwise just leading and trailing spaces.

    Returns:
        Normalized string.
    """
    # Ignore accents and unusual characters
    st = unicodedata.normalize("NFD", st).encode("ascii", "ignore").decode("utf8")

    # Remove spaces?
    st = st.replace(' ', '') if no_space else st.strip()

    # Remove punctuation and make lowercase
    return st.translate(str.maketrans("", "", string.punctuation)).lower()

src.utils.strings.normalize_ver(st: str) -> str

Normalize a version string for safe comparison.

Parameters:

Name Type Description Default
st str

String to normalize.

required

Returns:

Type Description
str

Normalized version string.

Source code in src\utils\strings.py
227
228
229
230
231
232
233
234
235
236
def normalize_ver(st: str) -> str:
    """Normalize a version string for safe comparison.

    Args:
        st: String to normalize.

    Returns:
        Normalized version string.
    """
    return ''.join([n for n in st if n in '.0123456789'])

src.utils.strings.str_to_bool(st: str) -> bool

Converts a truthy string value to a bool. Conversion is case-insensitive.

Parameters:

Name Type Description Default
st str

True values are y, yes, t, true, on and 1. False values are n, no, f, false, off and 0.

required

Returns:

Type Description
bool

Equivalent boolean value.

Raises:

Type Description
ValueError

If string provided isn't a recognized truthy expression.

Source code in src\utils\strings.py
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
def str_to_bool(st: str) -> bool:
    """Converts a truthy string value to a bool. Conversion is case-insensitive.

    Args:
        st: True values are y, yes, t, true, on and 1.
            False values are n, no, f, false, off and 0.

    Returns:
        Equivalent boolean value.

    Raises:
        ValueError: If string provided isn't a recognized truthy expression.
    """
    try:
        return STR_BOOL_MAP[st.lower()]
    except KeyError:
        raise ValueError(f"Couldn't discern boolean value of string '{st}'!")

src.utils.strings.str_to_bool_safe(st: str, default: bool = False) -> bool

Utility wrapper for str_to_bool, returns default if error is raised.

Source code in src\utils\strings.py
258
259
260
261
262
def str_to_bool_safe(st: str, default: bool = False) -> bool:
    """Utility wrapper for str_to_bool, returns default if error is raised."""
    with suppress(Exception):
        return str_to_bool(st)
    return default

src.utils.strings.msg_bold(msg: str) -> str

Wraps a console string with a bold tag.

Parameters:

Name Type Description Default
msg str

Text to wrap in a bold tag.

required

Returns:

Type Description
str

Wrapped message.

Source code in src\utils\strings.py
270
271
272
273
274
275
276
277
278
279
def msg_bold(msg: str) -> str:
    """Wraps a console string with a bold tag.

    Args:
        msg: Text to wrap in a bold tag.

    Returns:
        Wrapped message.
    """
    return f"[b]{msg}[/b]"

src.utils.strings.msg_italics(msg: str) -> str

Wraps a console string with an italics tag.

Parameters:

Name Type Description Default
msg str

Message to wrap in an italics tag.

required

Returns:

Type Description
str

Wrapped message.

Source code in src\utils\strings.py
282
283
284
285
286
287
288
289
290
291
def msg_italics(msg: str) -> str:
    """Wraps a console string with an italics tag.

    Args:
        msg: Message to wrap in an italics tag.

    Returns:
        Wrapped message.
    """
    return f"[i]{msg}[/i]"

src.utils.strings.msg_error(msg: str, reason: Optional[str] = None) -> str

Adds a defined 'error' color tag to Proxyshop console message.

Parameters:

Name Type Description Default
msg str

String wrap in color tag.

required
reason str | None

Reason for the error to include in the message, if provided.

None

Returns:

Type Description
str

Formatted string.

Source code in src\utils\strings.py
294
295
296
297
298
299
300
301
302
303
304
305
def msg_error(msg: str, reason: Optional[str] = None) -> str:
    """Adds a defined 'error' color tag to Proxyshop console message.

    Args:
        msg: String wrap in color tag.
        reason: Reason for the error to include in the message, if provided.

    Returns:
        Formatted string.
    """
    msg = f'[color={ConsoleMessages.error}]{msg}[/color]'
    return f"{msg_bold(msg)} - {msg_italics(reason)}" if reason else msg

src.utils.strings.msg_warn(msg: str, reason: Optional[str] = None) -> str

Adds a defined 'warning' color tag to Proxyshop console message.

Parameters:

Name Type Description Default
msg str

String to wrap in color tag.

required
reason str | None

Reason for the warning to include in the message, if provided.

None

Returns:

Type Description
str

Formatted string.

Source code in src\utils\strings.py
308
309
310
311
312
313
314
315
316
317
318
319
def msg_warn(msg: str, reason: Optional[str] = None) -> str:
    """Adds a defined 'warning' color tag to Proxyshop console message.

    Args:
        msg: String to wrap in color tag.
        reason: Reason for the warning to include in the message, if provided.

    Returns:
        Formatted string.
    """
    msg = f'[color={ConsoleMessages.warning}]{msg}[/color]'
    return f"{msg_bold(msg)} - {msg_italics(reason)}" if reason else msg

src.utils.strings.msg_success(msg: str) -> str

Adds a defined 'success' color tag to Proxyshop console message.

Parameters:

Name Type Description Default
msg str

String to wrap in color tag.

required

Returns:

Type Description
str

Formatted string.

Source code in src\utils\strings.py
322
323
324
325
326
327
328
329
330
331
def msg_success(msg: str) -> str:
    """Adds a defined 'success' color tag to Proxyshop console message.

    Args:
        msg: String to wrap in color tag.

    Returns:
        Formatted string.
    """
    return f'[color={ConsoleMessages.success}]{msg}[/color]'

src.utils.strings.msg_info(msg: str) -> str

Adds defined 'info' color tag to Proxyshop console message.

Parameters:

Name Type Description Default
msg str

String to wrap in color tag.

required

Returns:

Type Description
str

Formatted string.

Source code in src\utils\strings.py
334
335
336
337
338
339
340
341
342
343
def msg_info(msg: str) -> str:
    """Adds defined 'info' color tag to Proxyshop console message.

    Args:
        msg: String to wrap in color tag.

    Returns:
        Formatted string.
    """
    return f'[color={ConsoleMessages.info}]{msg}[/color]'

src.utils.strings.get_bullet_points(text: list[str], char: str = '•') -> str

Turns a list of strings into a joined bullet point list string.

Parameters:

Name Type Description Default
text list[str]

List of strings.

required
char str

Character to use as bullet.

'•'

Returns:

Type Description
str

Joined string with bullet points and newlines.

Source code in src\utils\strings.py
346
347
348
349
350
351
352
353
354
355
356
357
358
359
def get_bullet_points(text: list[str], char: str = '•') -> str:
    """Turns a list of strings into a joined bullet point list string.

    Args:
        text: List of strings.
        char: Character to use as bullet.

    Returns:
        Joined string with bullet points and newlines.
    """
    if not text:
        return ""
    bullet = f"\n{char} "
    return str(bullet + bullet.join(text))