|
@@ -0,0 +1,131 @@
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
+"""
|
|
|
+Created on 2023-03-01
|
|
|
+---------
|
|
|
+@summary: redis 过滤器
|
|
|
+---------
|
|
|
+@author: dzr
|
|
|
+"""
|
|
|
+from feapder.db.redisdb import RedisDB
|
|
|
+from feapder.dedup.basefilter import BaseFilter
|
|
|
+
|
|
|
+
|
|
|
+class RedisFilter(BaseFilter):
|
|
|
+ redis_db = None
|
|
|
+
|
|
|
+ def __init__(self, ip_ports=None, user_pass=None, redis_url=None, expire_time=None):
|
|
|
+ if ip_ports:
|
|
|
+ self.__class__.redis_db = RedisDB(
|
|
|
+ ip_ports=ip_ports,
|
|
|
+ user_pass=user_pass,
|
|
|
+ decode_responses=True,
|
|
|
+ ) # 集群
|
|
|
+ elif redis_url:
|
|
|
+ self.__class__.redis_db = RedisDB(redis_url=redis_url) # 单机
|
|
|
+ else:
|
|
|
+ self.__class__.redis_db = RedisDB()
|
|
|
+
|
|
|
+ self._ex = expire_time or 86400 * 365 * 2 # 2年 = 86400 * 365 * 2
|
|
|
+ self._prefix1 = 'list_'
|
|
|
+ self._prefix2 = 'pylist_'
|
|
|
+
|
|
|
+ def __repr__(self):
|
|
|
+ return "<RedisFilter: {}>".format(self.redis_db)
|
|
|
+
|
|
|
+ def exists(self, key):
|
|
|
+ """全量python检索"""
|
|
|
+ if self.redis_db.exists(self._prefix2 + key) > 0:
|
|
|
+ return True
|
|
|
+ return False
|
|
|
+
|
|
|
+ def add(self, keys, *args, **kwargs):
|
|
|
+ """
|
|
|
+ 添加数据
|
|
|
+ @param keys: 检查关键词在 redis 中是否存在,支持列表批量
|
|
|
+ @return: list / 单个值(如果数据已存在 返回 False 否则返回 True, 可以理解为是否添加成功)
|
|
|
+ """
|
|
|
+ is_list = isinstance(keys, list)
|
|
|
+ keys = keys if is_list else [keys]
|
|
|
+
|
|
|
+ is_added = []
|
|
|
+ for key in keys:
|
|
|
+ if not self.exists(key):
|
|
|
+ is_added.append(
|
|
|
+ self.redis_db.set(self._prefix2 + key, 1, ex=self._ex)
|
|
|
+ )
|
|
|
+ else:
|
|
|
+ is_added.append(False)
|
|
|
+
|
|
|
+ return is_added if is_list else is_added[0]
|
|
|
+
|
|
|
+ def get(self, keys):
|
|
|
+ """
|
|
|
+ 检查数据是否存在
|
|
|
+ @param keys: list / 单个值
|
|
|
+ @return: list / 单个值 (存在返回True 不存在返回False)
|
|
|
+ """
|
|
|
+ is_list = isinstance(keys, list)
|
|
|
+ keys = keys if is_list else [keys]
|
|
|
+
|
|
|
+ is_exist = []
|
|
|
+ for key in keys:
|
|
|
+ is_exist.append(self.exists(key))
|
|
|
+
|
|
|
+ # 判断数据本身是否重复
|
|
|
+ temp_set = set()
|
|
|
+ for i, key in enumerate(keys):
|
|
|
+ if key in temp_set:
|
|
|
+ is_exist[i] = True
|
|
|
+ else:
|
|
|
+ temp_set.add(key)
|
|
|
+
|
|
|
+ return is_exist if is_list else is_exist[0]
|
|
|
+
|
|
|
+
|
|
|
+class MRedisFilter(RedisFilter):
|
|
|
+ redis_dbs = {}
|
|
|
+
|
|
|
+ def __init__(self, redis_conf=None, **kwargs):
|
|
|
+ super(MRedisFilter, self).__init__(**kwargs)
|
|
|
+ if not redis_conf:
|
|
|
+ self.__class__.redis_dbs[self._prefix2] = RedisDB()
|
|
|
+ else:
|
|
|
+ if not isinstance(redis_conf, dict):
|
|
|
+ raise ValueError("redis_conf 必须是一个 dict")
|
|
|
+
|
|
|
+ for prefix, conf in redis_conf.items():
|
|
|
+ self.__class__.redis_dbs[prefix] = RedisDB(
|
|
|
+ ip_ports=conf['redisdb_ip_port'],
|
|
|
+ user_pass=conf['redisdb_user_pass'],
|
|
|
+ db=conf['redisdb_db']
|
|
|
+ )
|
|
|
+
|
|
|
+ def __repr__(self):
|
|
|
+ return "<MRedisFilter: {}>".format(self.redis_dbs)
|
|
|
+
|
|
|
+ def exists(self, key):
|
|
|
+ """lua增量检索/python增量检索"""
|
|
|
+ for prefix, redis_db in self.redis_dbs.items():
|
|
|
+ if redis_db.exists(prefix + key) > 0:
|
|
|
+ return True
|
|
|
+ return False
|
|
|
+
|
|
|
+ def add(self, keys, *args, **kwargs):
|
|
|
+ """
|
|
|
+ 添加数据
|
|
|
+ @param keys: 检查关键词在 redis 中是否存在,支持列表批量
|
|
|
+ @return: list / 单个值(如果数据已存在 返回 False 否则返回 True, 可以理解为是否添加成功)
|
|
|
+ """
|
|
|
+ is_list = isinstance(keys, list)
|
|
|
+ keys = keys if is_list else [keys]
|
|
|
+
|
|
|
+ redis_db = self.redis_dbs[self._prefix2]
|
|
|
+
|
|
|
+ is_added = []
|
|
|
+ for key in keys:
|
|
|
+ if not self.exists(key):
|
|
|
+ is_added.append(redis_db.set(self._prefix2 + key, 1, ex=self._ex))
|
|
|
+ else:
|
|
|
+ is_added.append(False)
|
|
|
+
|
|
|
+ return is_added if is_list else is_added[0]
|