Module plibs.core

Expand source code
import datetime
import random
import string
import time

import aioredis
import redis
from redis import WatchError


class AsyncRedisUtil:
    """
    异步redis操作
    """

    def __init__(self):
        self.r = None

    async def init(self, host='127.0.0.1', port=6379, password=None, db=0, **kwargs):
        self.r = await aioredis.create_redis_pool(f'redis://{host}:{port}', password=password, db=db, **kwargs)

    async def _exp_of_none(self, *args, exp_of_none, callback):
        key = args[0]
        tr = self.r.multi_exec()
        fun = getattr(tr, callback)
        exp = await self.r.ttl(key)
        if exp == -2:
            fun(*args)
            tr.expire(key, exp_of_none)
            ret, _ = await tr.execute()
        else:
            fun(*args)
            ret = await tr.execute()
        return ret

    async def set(self, key, value, exp=None):
        assert self.r, 'must call init first'
        await self.r.set(key, value, expire=exp)

    async def get(self, key, default=None):
        assert self.r, 'must call init first'
        value = await self.r.get(key)
        if value is None:
            return default
        return value.decode()

    async def get_or_set(self, key, default=None, value_fun=None):
        """
        获取或者设置缓存
        """
        assert self.r, 'must call init first'
        value = await self.r.get(key)
        if value is None and default:
            return default
        if value is not None:
            return value.decode()
        if value_fun:
            value, exp = await value_fun()
            await self.r.set(key, value, exp)
        return value

    async def delete(self, key):
        """
        缓存清除,接收list or str
        """
        assert self.r, 'must call init first'
        return await self.r.delete(key)

    async def sadd(self, name, values, exp_of_none=-1):
        assert self.r, 'must call init first'
        return await self._exp_of_none(name, values, exp_of_none=exp_of_none, callback='sadd')

    async def hset(self, name, key, value, exp_of_none=-1):
        assert self.r, 'must call init first'
        return await self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hset')

    async def hincrby(self, name, key, value=1, exp_of_none=-1):
        assert self.r, 'must call init first'
        return await self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hincrby')

    async def hincrbyfloat(self, name, key, value, exp_of_none=-1):
        assert self.r, 'must call init first'
        return await self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hincrbyfloat')

    async def incrby(self, name, value=1, exp_of_none=-1):
        assert self.r, 'must call init first'
        return await self._exp_of_none(name, value, exp_of_none=exp_of_none, callback='incrby')

    async def hget(self, name, key, default=0):
        """
        缓存清除,接收list or str
        """
        assert self.r, 'must call init first'
        v = await self.r.hget(name, key)
        if v is None:
            return default
        return v.decode()

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        self.r.close()
        await self.r.wait_closed()


class RedisUtil:
    """
    封装缓存方法
    """

    def __init__(self, conn=None, host='127.0.0.1', port=6379, password='', db=0, **kwargs):
        if conn:
            self.r = conn  # type:redis.Redis
        else:
            pool = redis.ConnectionPool(host=host, port=port, password=password, db=db, **kwargs)
            self.r = redis.Redis(connection_pool=pool)

    def _exp_of_none(self, *args, exp_of_none, callback):
        with self.r.pipeline() as pipe:
            while True:
                try:
                    fun = getattr(pipe, callback)
                    key = args[0]
                    exp = self.r.ttl(key)
                    pipe.watch(key)
                    if exp == -2:
                        ret = fun(*args)
                        pipe.expire(key, exp_of_none)
                    else:
                        ret = fun(*args)
                    pipe.execute()
                    return ret
                except WatchError:
                    continue

    def get_or_set(self, key, default=None, value_fun=None):
        """
        获取或者设置缓存
        """
        value = self.r.get(key)
        if value is None and default:
            return default
        if value is not None:
            return value.decode()
        if value_fun:
            value, exp = value_fun()
            self.r.set(key, value, exp)
        return value

    def get(self, key, default=None):
        value = self.r.get(key)
        if value is None:
            return default
        return value.decode()

    def set(self, key, value, exp=None):
        """
        设置缓存
        """
        return self.r.set(key, value, exp)

    def delete(self, key):
        """
        缓存清除,接收list or str
        """
        return self.r.delete(key)

    def sadd(self, name, values, exp_of_none=-1):
        return self._exp_of_none(name, values, exp_of_none=exp_of_none, callback='sadd')

    def hset(self, name, key, value, exp_of_none=-1):
        return self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hset')

    def hincrby(self, name, key, value=1, exp_of_none=-1):
        return self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hincrby')

    def hincrbyfloat(self, name, key, value, exp_of_none=-1):
        return self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hincrbyfloat')

    def incrby(self, name, value=1, exp_of_none=-1):
        return self._exp_of_none(name, value, exp_of_none=exp_of_none, callback='incrby')

    def hget(self, name, key, default=0):
        """
        缓存清除,接收list or str
        """
        v = self.r.hget(name, key)
        if v is None:
            return default
        return v.decode()


def datetime_now(d=0, h=0, m=0):
    """
    取之前时间
    """
    tmp = datetime.datetime.now()
    if d:
        tmp -= datetime.timedelta(days=d)
    if h:
        tmp -= datetime.timedelta(hours=h)
    if m:
        tmp -= datetime.timedelta(minutes=m)
    return tmp


def datetime2timestamp(time_):
    """
    时间转时间戳
    """
    return int(time.mktime(time_.timetuple()))


def rest_seconds(mode) -> int:
    """
    获取剩余秒数
    """
    assert mode in ['month', 'week', 'day'], 'mode must be one of month,week,year'
    if mode == 'day':
        return datetime2timestamp(datetime_now(d=-1).date()) - datetime2timestamp(datetime_now())
    if mode == 'week':
        now = datetime_now()
        offset = 7 - now.weekday()
        weekend = now.date() + datetime.timedelta(days=offset)
        return datetime2timestamp(weekend) - datetime2timestamp(now)
    if mode == 'month':
        now = datetime_now()
        next_month = now.date().replace(day=28) + datetime.timedelta(days=4)
        return datetime2timestamp(next_month - datetime.timedelta(days=next_month.day - 1)) - datetime2timestamp(now)


def generate_random_string(length, is_digits=False, exclude=None):
    """
    生成任意长度字符串
    """
    if exclude is None:
        exclude = []
    if is_digits:
        all_char = string.digits
    else:
        all_char = string.ascii_letters + string.digits
    if exclude:
        for char in exclude:
            all_char.replace(char, '')
    return ''.join(random.sample(all_char, length))


def join_params(params, key=None, filter_none=True, exclude_keys=None, sep='&', reverse=False, key_alias='key'):
    """
    字典排序拼接参数
    """
    tmp = []
    for p in sorted(params, reverse=reverse):
        value = params[p]
        if filter_none and value in [None, '']:
            continue
        if exclude_keys:
            if p in exclude_keys:
                continue
        tmp.append('{0}={1}'.format(p, value))
    if key:
        tmp.append('{0}={1}'.format(key_alias, key))
    ret = sep.join(tmp)
    return ret

Functions

def datetime2timestamp(time_)

时间转时间戳

Expand source code
def datetime2timestamp(time_):
    """
    时间转时间戳
    """
    return int(time.mktime(time_.timetuple()))
def datetime_now(d=0, h=0, m=0)

取之前时间

Expand source code
def datetime_now(d=0, h=0, m=0):
    """
    取之前时间
    """
    tmp = datetime.datetime.now()
    if d:
        tmp -= datetime.timedelta(days=d)
    if h:
        tmp -= datetime.timedelta(hours=h)
    if m:
        tmp -= datetime.timedelta(minutes=m)
    return tmp
def generate_random_string(length, is_digits=False, exclude=None)

生成任意长度字符串

Expand source code
def generate_random_string(length, is_digits=False, exclude=None):
    """
    生成任意长度字符串
    """
    if exclude is None:
        exclude = []
    if is_digits:
        all_char = string.digits
    else:
        all_char = string.ascii_letters + string.digits
    if exclude:
        for char in exclude:
            all_char.replace(char, '')
    return ''.join(random.sample(all_char, length))
def join_params(params, key=None, filter_none=True, exclude_keys=None, sep='&', reverse=False, key_alias='key')

字典排序拼接参数

Expand source code
def join_params(params, key=None, filter_none=True, exclude_keys=None, sep='&', reverse=False, key_alias='key'):
    """
    字典排序拼接参数
    """
    tmp = []
    for p in sorted(params, reverse=reverse):
        value = params[p]
        if filter_none and value in [None, '']:
            continue
        if exclude_keys:
            if p in exclude_keys:
                continue
        tmp.append('{0}={1}'.format(p, value))
    if key:
        tmp.append('{0}={1}'.format(key_alias, key))
    ret = sep.join(tmp)
    return ret
def rest_seconds(mode)

获取剩余秒数

Expand source code
def rest_seconds(mode) -> int:
    """
    获取剩余秒数
    """
    assert mode in ['month', 'week', 'day'], 'mode must be one of month,week,year'
    if mode == 'day':
        return datetime2timestamp(datetime_now(d=-1).date()) - datetime2timestamp(datetime_now())
    if mode == 'week':
        now = datetime_now()
        offset = 7 - now.weekday()
        weekend = now.date() + datetime.timedelta(days=offset)
        return datetime2timestamp(weekend) - datetime2timestamp(now)
    if mode == 'month':
        now = datetime_now()
        next_month = now.date().replace(day=28) + datetime.timedelta(days=4)
        return datetime2timestamp(next_month - datetime.timedelta(days=next_month.day - 1)) - datetime2timestamp(now)

Classes

class AsyncRedisUtil

异步redis操作

Expand source code
class AsyncRedisUtil:
    """
    异步redis操作
    """

    def __init__(self):
        self.r = None

    async def init(self, host='127.0.0.1', port=6379, password=None, db=0, **kwargs):
        self.r = await aioredis.create_redis_pool(f'redis://{host}:{port}', password=password, db=db, **kwargs)

    async def _exp_of_none(self, *args, exp_of_none, callback):
        key = args[0]
        tr = self.r.multi_exec()
        fun = getattr(tr, callback)
        exp = await self.r.ttl(key)
        if exp == -2:
            fun(*args)
            tr.expire(key, exp_of_none)
            ret, _ = await tr.execute()
        else:
            fun(*args)
            ret = await tr.execute()
        return ret

    async def set(self, key, value, exp=None):
        assert self.r, 'must call init first'
        await self.r.set(key, value, expire=exp)

    async def get(self, key, default=None):
        assert self.r, 'must call init first'
        value = await self.r.get(key)
        if value is None:
            return default
        return value.decode()

    async def get_or_set(self, key, default=None, value_fun=None):
        """
        获取或者设置缓存
        """
        assert self.r, 'must call init first'
        value = await self.r.get(key)
        if value is None and default:
            return default
        if value is not None:
            return value.decode()
        if value_fun:
            value, exp = await value_fun()
            await self.r.set(key, value, exp)
        return value

    async def delete(self, key):
        """
        缓存清除,接收list or str
        """
        assert self.r, 'must call init first'
        return await self.r.delete(key)

    async def sadd(self, name, values, exp_of_none=-1):
        assert self.r, 'must call init first'
        return await self._exp_of_none(name, values, exp_of_none=exp_of_none, callback='sadd')

    async def hset(self, name, key, value, exp_of_none=-1):
        assert self.r, 'must call init first'
        return await self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hset')

    async def hincrby(self, name, key, value=1, exp_of_none=-1):
        assert self.r, 'must call init first'
        return await self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hincrby')

    async def hincrbyfloat(self, name, key, value, exp_of_none=-1):
        assert self.r, 'must call init first'
        return await self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hincrbyfloat')

    async def incrby(self, name, value=1, exp_of_none=-1):
        assert self.r, 'must call init first'
        return await self._exp_of_none(name, value, exp_of_none=exp_of_none, callback='incrby')

    async def hget(self, name, key, default=0):
        """
        缓存清除,接收list or str
        """
        assert self.r, 'must call init first'
        v = await self.r.hget(name, key)
        if v is None:
            return default
        return v.decode()

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        self.r.close()
        await self.r.wait_closed()

Methods

async def delete(self, key)

缓存清除,接收list or str

Expand source code
async def delete(self, key):
    """
    缓存清除,接收list or str
    """
    assert self.r, 'must call init first'
    return await self.r.delete(key)
async def get(self, key, default=None)
Expand source code
async def get(self, key, default=None):
    assert self.r, 'must call init first'
    value = await self.r.get(key)
    if value is None:
        return default
    return value.decode()
async def get_or_set(self, key, default=None, value_fun=None)

获取或者设置缓存

Expand source code
async def get_or_set(self, key, default=None, value_fun=None):
    """
    获取或者设置缓存
    """
    assert self.r, 'must call init first'
    value = await self.r.get(key)
    if value is None and default:
        return default
    if value is not None:
        return value.decode()
    if value_fun:
        value, exp = await value_fun()
        await self.r.set(key, value, exp)
    return value
async def hget(self, name, key, default=0)

缓存清除,接收list or str

Expand source code
async def hget(self, name, key, default=0):
    """
    缓存清除,接收list or str
    """
    assert self.r, 'must call init first'
    v = await self.r.hget(name, key)
    if v is None:
        return default
    return v.decode()
async def hincrby(self, name, key, value=1, exp_of_none=-1)
Expand source code
async def hincrby(self, name, key, value=1, exp_of_none=-1):
    assert self.r, 'must call init first'
    return await self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hincrby')
async def hincrbyfloat(self, name, key, value, exp_of_none=-1)
Expand source code
async def hincrbyfloat(self, name, key, value, exp_of_none=-1):
    assert self.r, 'must call init first'
    return await self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hincrbyfloat')
async def hset(self, name, key, value, exp_of_none=-1)
Expand source code
async def hset(self, name, key, value, exp_of_none=-1):
    assert self.r, 'must call init first'
    return await self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hset')
async def incrby(self, name, value=1, exp_of_none=-1)
Expand source code
async def incrby(self, name, value=1, exp_of_none=-1):
    assert self.r, 'must call init first'
    return await self._exp_of_none(name, value, exp_of_none=exp_of_none, callback='incrby')
async def init(self, host='127.0.0.1', port=6379, password=None, db=0, **kwargs)
Expand source code
async def init(self, host='127.0.0.1', port=6379, password=None, db=0, **kwargs):
    self.r = await aioredis.create_redis_pool(f'redis://{host}:{port}', password=password, db=db, **kwargs)
async def sadd(self, name, values, exp_of_none=-1)
Expand source code
async def sadd(self, name, values, exp_of_none=-1):
    assert self.r, 'must call init first'
    return await self._exp_of_none(name, values, exp_of_none=exp_of_none, callback='sadd')
async def set(self, key, value, exp=None)
Expand source code
async def set(self, key, value, exp=None):
    assert self.r, 'must call init first'
    await self.r.set(key, value, expire=exp)
class RedisUtil (conn=None, host='127.0.0.1', port=6379, password='', db=0, **kwargs)

封装缓存方法

Expand source code
class RedisUtil:
    """
    封装缓存方法
    """

    def __init__(self, conn=None, host='127.0.0.1', port=6379, password='', db=0, **kwargs):
        if conn:
            self.r = conn  # type:redis.Redis
        else:
            pool = redis.ConnectionPool(host=host, port=port, password=password, db=db, **kwargs)
            self.r = redis.Redis(connection_pool=pool)

    def _exp_of_none(self, *args, exp_of_none, callback):
        with self.r.pipeline() as pipe:
            while True:
                try:
                    fun = getattr(pipe, callback)
                    key = args[0]
                    exp = self.r.ttl(key)
                    pipe.watch(key)
                    if exp == -2:
                        ret = fun(*args)
                        pipe.expire(key, exp_of_none)
                    else:
                        ret = fun(*args)
                    pipe.execute()
                    return ret
                except WatchError:
                    continue

    def get_or_set(self, key, default=None, value_fun=None):
        """
        获取或者设置缓存
        """
        value = self.r.get(key)
        if value is None and default:
            return default
        if value is not None:
            return value.decode()
        if value_fun:
            value, exp = value_fun()
            self.r.set(key, value, exp)
        return value

    def get(self, key, default=None):
        value = self.r.get(key)
        if value is None:
            return default
        return value.decode()

    def set(self, key, value, exp=None):
        """
        设置缓存
        """
        return self.r.set(key, value, exp)

    def delete(self, key):
        """
        缓存清除,接收list or str
        """
        return self.r.delete(key)

    def sadd(self, name, values, exp_of_none=-1):
        return self._exp_of_none(name, values, exp_of_none=exp_of_none, callback='sadd')

    def hset(self, name, key, value, exp_of_none=-1):
        return self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hset')

    def hincrby(self, name, key, value=1, exp_of_none=-1):
        return self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hincrby')

    def hincrbyfloat(self, name, key, value, exp_of_none=-1):
        return self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hincrbyfloat')

    def incrby(self, name, value=1, exp_of_none=-1):
        return self._exp_of_none(name, value, exp_of_none=exp_of_none, callback='incrby')

    def hget(self, name, key, default=0):
        """
        缓存清除,接收list or str
        """
        v = self.r.hget(name, key)
        if v is None:
            return default
        return v.decode()

Methods

def delete(self, key)

缓存清除,接收list or str

Expand source code
def delete(self, key):
    """
    缓存清除,接收list or str
    """
    return self.r.delete(key)
def get(self, key, default=None)
Expand source code
def get(self, key, default=None):
    value = self.r.get(key)
    if value is None:
        return default
    return value.decode()
def get_or_set(self, key, default=None, value_fun=None)

获取或者设置缓存

Expand source code
def get_or_set(self, key, default=None, value_fun=None):
    """
    获取或者设置缓存
    """
    value = self.r.get(key)
    if value is None and default:
        return default
    if value is not None:
        return value.decode()
    if value_fun:
        value, exp = value_fun()
        self.r.set(key, value, exp)
    return value
def hget(self, name, key, default=0)

缓存清除,接收list or str

Expand source code
def hget(self, name, key, default=0):
    """
    缓存清除,接收list or str
    """
    v = self.r.hget(name, key)
    if v is None:
        return default
    return v.decode()
def hincrby(self, name, key, value=1, exp_of_none=-1)
Expand source code
def hincrby(self, name, key, value=1, exp_of_none=-1):
    return self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hincrby')
def hincrbyfloat(self, name, key, value, exp_of_none=-1)
Expand source code
def hincrbyfloat(self, name, key, value, exp_of_none=-1):
    return self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hincrbyfloat')
def hset(self, name, key, value, exp_of_none=-1)
Expand source code
def hset(self, name, key, value, exp_of_none=-1):
    return self._exp_of_none(name, key, value, exp_of_none=exp_of_none, callback='hset')
def incrby(self, name, value=1, exp_of_none=-1)
Expand source code
def incrby(self, name, value=1, exp_of_none=-1):
    return self._exp_of_none(name, value, exp_of_none=exp_of_none, callback='incrby')
def sadd(self, name, values, exp_of_none=-1)
Expand source code
def sadd(self, name, values, exp_of_none=-1):
    return self._exp_of_none(name, values, exp_of_none=exp_of_none, callback='sadd')
def set(self, key, value, exp=None)

设置缓存

Expand source code
def set(self, key, value, exp=None):
    """
    设置缓存
    """
    return self.r.set(key, value, exp)