castero/helpers.py
from bs4 import BeautifulSoup
import re
from email.utils import parsedate_to_datetime
from datetime import datetime
import time
import pytz
def third(n) -> int:
"""Calculates one-third of a given value.
:param n the integer to calculate one-third of
:returns int: one-third of n, rounded down
"""
return int(n / 3)
def median(arr):
"""Determines the median of a list of numbers.
:param arr a list of ints and/or floats of which to determine the median
:returns int or float: the median value in arr
"""
if len(arr) == 0:
return None
arr_sorted = sorted(arr)
midpoint = int(len(arr) / 2)
if len(arr) % 2 == 0:
# even number of elements; get the average of the middle two
result = (arr_sorted[midpoint - 1] + arr_sorted[midpoint]) / 2
else:
result = arr_sorted[midpoint]
return result
def sanitize_path(path) -> str:
"""Replaces any characters in path that the file system may not support.
This method replaces any non-alphanumeric characters with an underscore,
with the exception of hyphens.
:param path the original path
:returns str: the given path with potentially unsafe characters replaced
"""
# adapted from https://stackoverflow.com/a/13593932
path = re.sub("[^\\w\\-]", "_", path)
return path
def is_true(string) -> bool:
"""Determines whether a string represents True.
As the name suggests, any input which is not explicitly evaluated to True
will cause this method to return False.
:param string the string to evaluate
"""
assert isinstance(string, str)
return string in ["True", "true", "1"]
def html_to_plain(html) -> str:
"""Converts a potentially HTML-formatted string to user-friendly plaintext.
:param html the text to convert with potential html tags
:returns str: the given text with html tags removed
"""
soup = BeautifulSoup(html, "html.parser")
return soup.get_text()
def datetime_from_rfc822(date) -> datetime:
"""Convert a date string in RFC822 format into a datetime.
https://www.w3.org/Protocols/rfc822/
https://validator.w3.org/feed/docs/error/InvalidRFC2822Date.html
:param date string for the date/time in RFC822 format
:returns datetime: a matching datetime object, or -1
"""
try:
return parsedate_to_datetime(date).replace(tzinfo=pytz.UTC)
except (TypeError, ValueError):
return -1
def seconds_to_time(seconds: int) -> str:
seconds = max(0, seconds)
return time.strftime("%H:%M:%S", time.gmtime(seconds))