Source code for zcooldl.utils

# @FILENAME : utils
# @AUTHOR : lonsty
# @DATE : 2019/9/9 11:09
import os
import random
import time
from collections import namedtuple
from functools import wraps
from typing import Iterable


[docs]def retry(exceptions, tries=3, delay=1, backoff=2, logger=None): """Retry calling the decorated function using an exponential backoff. :param exceptions: The exception to check. may be a tuple of exceptions to check. :param tries: Number of times to try (not retry) before giving up. :param delay: Initial delay between retries in seconds. :param backoff: Backoff multiplier (e.g. value of 2 will double the delay each retry). :param logger: Logger to use. If None, print. """ def deco_retry(f): @wraps(f) def f_retry(*args, **kwargs): mtries, mdelay = tries, delay or random.uniform(0.5, 1.5) while mtries > 1: try: return f(*args, **kwargs) except exceptions as e: if logger: logger.warning('{}, Retrying in {} seconds...'.format(e, mdelay)) # else: # print('{}, Retrying in {} seconds...'.format(e, mdelay)) time.sleep(mdelay) mtries -= 1 mdelay *= backoff return f(*args, **kwargs) return f_retry # true decorator return deco_retry
[docs]def mkdirs_if_not_exist(dir): """文件夹不存在时则创建。 :param str dir: 文件夹路径,支持多级 """ if not os.path.isdir(dir): try: os.makedirs(dir) except FileExistsError: pass
[docs]def safe_filename(filename): """去掉文件名中的非法字符。 :param str filename: 文件名 :return str: 合法文件名 """ return "".join([c for c in filename if c not in r'\/:*?"<>|']).strip()
[docs]def parse_resources(ids, names, collections): """解析用户名或 ID。 :param str ids: 半角逗号分隔的用户 ID :param str names: 半角逗号分隔的用户名 :return list: 包含 User 数据的列表 """ Resource = namedtuple('Resource', 'id name collection') resources = [] if collections: resources = [Resource(None, None, collection) for collection in collections.split(',')] elif names: resources = [Resource(None, name, None) for name in names.split(',')] elif ids: resources = [Resource(uid, None, None) for uid in ids.split(',')] return resources # TODO: 去重
[docs]def sort_records(records: Iterable, order: dict): """根据自定义的排序规则排序 :param Iterable records: 要排序的记录 :param dict order: 自定义的排序 :return: """ def _order_by(obj: namedtuple): if obj.type == 'topic': return (order[obj.type], obj.index, obj.objid, obj.title, obj.url) return (order[obj.type], obj.objid, obj.index, obj.title, obj.url) return sorted(records, key=_order_by)