def getRating(self, source, group, force=False): if group not in self.ratings.keys() or force: level = ymConfig.getConfig('setting').get('group_rate')[str(group)] if str(group) in ymConfig.getConfig( 'setting').get('group_rate').keys() else ymConfig.getConfig('setting').get('rating') rs = {k: v for k, v in ymConfig.getConfig(source).get('rating').items() if v <= level} rating = sorted(rs.items(), key=lambda d: d[1], reverse=True) self.ratings[group] = rating[0][0] logger.info(f"rating {group} is {self.ratings[group]}")
def _formatData(self, data: list): result: [YandeData] = [] for YandeDataOne in data: yande: YandeData = YandeData() yr = YandeDataOne['rating'] if self.hasAction == RipperConst.POPULAR and ymConfig.getConfig('yande').get('rating')[yr] > \ ymConfig.getConfig('yande').get('rating')[self.hasRating]: continue yande.__dict__.update(YandeDataOne) result.append(yande) return result
async def PicDeaHandler(self, app: Slave, message: GroupMessage): plains = message.messageChain.get(Plain) quote: Quote = message.messageChain.get(Quote)[0] plain: Plain = quote.origin.get(Plain)[0] if any(text.__dict__['text'].strip() == '好' for text in plains): if not self.Permitted(message): # await app.sendGroupMessage(message.sender.group, [At(message.sender.id), Plain('权限不足')]) pass else: if plain.text == '[图片]': if (message.sender.group.id << 32) + quote.id in self.GCache.keys(): cache = self.GCache[(message.sender.group.id << 32) + quote.id] image: Image = cache[0] ext = cache[1] else: try: quote_source: GroupMessage = await app.messageFromId(quote.id) image: Image = quote_source.messageChain.get(Image)[0] ext = 'jpg' except UnknownTarget: mec = MeCh.create([At(message.sender.id), Plain('不在本地与消息缓存中,无法保存')]) await app.sendGroupMessage(message.sender.group, mec) return te = await saveUrlPicture(image.url, image.imageId, 'application/YummyPicture/save/pic', ext) msg = [At(message.sender.id), Plain(te)] await app.sendGroupMessage(message.sender.group, MeCh.create(msg)) elif any(text.__dict__['text'].strip() == '图源' for text in plains): if plain and plain.text in ['[图片]', '[动画表情]']: try: if (k := (message.sender.group.id << 32) + quote.id) in self.GCache.keys(): url = self.GCache[k][0].url else: quote_source: GroupMessage = await app.messageFromId(quote.id) image: Image = quote_source.messageChain.get(Image)[0] url = image.url searcher: Searcher = Searcher() result = await searcher.useApiKey().setUrl(url).get() msg = [] connector: ProxyConnector = ProxyConnector() if proxy := ymConfig.getConfig('setting').get('proxy'): connector = ProxyConnector.from_url(proxy) for one in result: if float(sim := one['header']['similarity']) < 50: continue img_byte = await request(url=one['header']['thumbnail'], connector=connector, close=False) img = Image.fromUnsafeBytes(img_byte) msg.append(img) if 'ext_urls' in one['data']: ext = one['data']['ext_urls'] else: ext = one['header']['thumbnail'] msg.append(Plain(f"相似度{sim}%,链接{ext}"))
async def MSGDeaHandler(self, app: Slave, message: GroupMessage, commands): cmd = commands[0].upper() if not self.Permitted(message): return msg = [At(message.sender.id)] try: if cmd == self.APP_COMMANDS[0]: # ym ymConfig.getConfig(commands[1]).set(commands[2], commands[3]) await ymConfig.save(commands[1]) await self.initYummyPicture() msg.append(Plain('Success')) if cmd == self.APP_COMMANDS[1]: # aa if commands[1].isnumeric(): ymConfig.getConfig('setting').addList('admins', int(commands[1])) await ymConfig.save('setting') msg.append(Plain('Added')) else: msg.append(Plain('Wrong param')) if cmd == self.APP_COMMANDS[2]: # ra if commands[1].isnumeric(): ymConfig.getConfig('setting').rmList('admins', int(commands[1])) await ymConfig.save('setting') msg.append(Plain('Removed')) else: msg.append(Plain('Wrong param')) if cmd == self.APP_COMMANDS[3]: # gr if commands[1].isnumeric() and commands[2].isnumeric(): ymConfig.getConfig('setting').addDict('group_rate', str(commands[1]), int(commands[2])) self.getRating(self.ym, message.sender.group.id, True) await ymConfig.save('setting') msg.append(Plain('Success')) except IndexError: msg.append(Plain('Wrong param')) if len(msg) > 1: await app.sendGroupMessage(message.sender.group, MeCh.create(msg))
class JASearcher: sources = [ 'https://www.javbus.com/uncensored/search/', 'https://www.javbus.com/search/', 'https://btsow.com/search/' ] source = 2 url = sources[2] api_key = ymConfig.getConfig('setting').get('search_key') connector: ProxyConnector = None def setSource(self, source: int): if len(self.sources) > source > 0: self.source = source self.url = self.sources[source] return self else: raise JASearcherSourceNotFoundException def setID(self, gid: str): if self.source == 2: self.url += gid return self def useProxy(self): if proxy := ymConfig.getConfig('setting').get('proxy'): self.connector = ProxyConnector.from_url(proxy) return self else:
async def get(self, check_size: bool = False, size="sample") -> bytes: try: headers = {} connector: ProxyConnector = ProxyConnector() proxy = ymConfig.getConfig('setting').get('proxy') if proxy: connector = ProxyConnector.from_url(proxy) if size == "sample": self.url = self.sample_url elif size == "file": self.url = self.file_url elif size == "jpeg": self.url = self.jpeg_url async with aiohttp.request('GET', self.url, headers=headers, connector=connector, timeout=aiohttp.ClientTimeout(600)) as resp: img_bytes: bytes = await resp.read() if connector: await connector.close() if check_size: pass '''img: PIL.Image.Image = PIL.Image.open(BytesIO(initial_bytes=img_bytes)) if img.size != (self.width, self.height): raise ValueError(f'Image Size Error: expected {(self.width, self.height)} but got {img.size}')''' except (asyncio.TimeoutError, ValueError) as e: raise e except PIL.UnidentifiedImageError: raise ValueError(f'Image load fail {str(img_bytes[:20])}...') return img_bytes
async def get(self, offest=0, limit=40) -> 'list': await self.__build() # params = {} connector: ProxyConnector = ProxyConnector() proxy = ymConfig.getConfig('setting').get('proxy') if proxy: connector = ProxyConnector.from_url(proxy) data: list = [] for k, t in self.rips.items(): async with aiohttp.request('GET', k, connector=connector) as response: raw = await response.read() logger.debug(k + f"\n[{t[0]}, {t[1]}]") data = data + json.loads(raw)['posts'][t[0]:t[1]] result: [AnipicData] = [] for one in data: anipic: AnipicData = AnipicData() one['file_url'] = f"https://images.anime-pictures.net/{one['md5'][0:3]}/{one['md5'] + one['ext']}" anipic.__dict__.update(one) async with aiohttp.request( 'GET', f'https://anime-pictures.net/pictures/view_post/{anipic.id}?type=json', connector=connector, timeout=aiohttp.ClientTimeout(20)) as oneInfo: meta = json.loads(await oneInfo.read()) anipic.tags = meta['tags'] result.append(anipic) if connector: await connector.close() return result
def useProxy(self): proxy = ymConfig.getConfig('setting').get('proxy') if proxy: self.connector = ProxyConnector.from_url(proxy) return self else: raise SearcherProxyNotFoundException
class PictureRipperListener(Listener): bcc: Broadcast try: from application.Economy import Economy from application.Economy.EconomyListener import notEnough Economy = Economy price = 5 except ImportError: Economy = None notEnough = None Tick = {} BlockedKeywords = ['翻译翻译'] ym = ymConfig.getConfig('setting').get('ripper') pkg = importlib.import_module('application.YummyPicture.yummy.' + ym) dataClass = getattr(pkg, f'{ym.capitalize()}Data') ripperClass = getattr(pkg, f'{ym.capitalize()}Ripper') databaseClass = getattr(pkg, f'{ym.capitalize()}Database') db = databaseClass() ratings = {} GCache = {} APP_COMMANDS = [ '.YM', '.AA', '.RA', '.GR', './N', './P', './S', './R', './D', './J' ] QUOTE_COMMANDS = ['x2', '好', '图源', '我不喜欢'] def run(self): @self.bcc.receiver(GroupMessage, headless_decoraters=[Depend(self.cmdFilter)]) async def groupCmdHandler(app: Slave, message: GroupMessage): commands = message.messageChain.asDisplay().split(' ') await self.MSGDeaHandler(app, message, commands) await self.RipperHandler(app, message, commands) @self.bcc.receiver(GroupMessage, headless_decoraters=[Depend(self.quoteFilter)]) async def groupQuoteHandler(app: Slave, message: GroupMessage): await self.PicDeaHandler(app, message) @self.bcc.receiver(GroupMessage, headless_decoraters=[Depend(self.seTuTextFilter)]) async def groupSeTuTextHandler(app: Slave, message: GroupMessage): await self.seTuTextHandler(app, message) def cmdFilter(self, message: MessageChain): message: str = message.asDisplay() # match = self.ripeReg(message) dis: [str] = message.split(' ')[0].upper() if dis[:3] not in self.APP_COMMANDS: raise ExecutionStop() def quoteFilter(self, message: MessageChain): if not message.has(Quote): raise ExecutionStop() if plains := message.get(Plain): if all(text.__dict__['text'].strip() not in self.QUOTE_COMMANDS for text in plains): raise ExecutionStop() else:
async def __buildToken(self): token: str = ymConfig.getConfig('anipic').get('token') if not token: token = 'a_0' token_arr = token.split('_') if int(time.time()) - int(token_arr[1]) > 60 * 60 * 24 * 30: token = await self.fetToken ymConfig.getConfig('anipic').set( 'token', token + (f'_{int(time.time())}' if token else '')) self.token = token await ymConfig.save('anipic') logger.debug('Token expired! fetched!') else: self.token = token_arr[0] logger.info('Token usable!') if self.token: self.parm('token', self.token)
async def initYummyPicture(self): ymConfig.reload() self.ratings = {} self.ym = ymConfig.getConfig('setting').get('ripper') logger.debug('reload configs') pkg = importlib.import_module('application.YummyPicture.yummy.' + self.ym) self.dataClass = getattr(pkg, f'{self.ym.capitalize()}Data') self.ripperClass = getattr(pkg, f'{self.ym.capitalize()}Ripper') self.databaseClass = getattr(pkg, f'{self.ym.capitalize()}Database') self.db = self.databaseClass()
def __buildRating(self) -> 'EhentaiRipper': if ymConfig.getConfig('setting').get( 'enable_rating_check') != 'disable' and self.hasRating: if self.hasAction == RipperConst.DETAIL: if self.hasRating == 'h' and self.gdr and self.gdr == 'non-h': self.rip = self.rip.replace('/g/', '/k/') return self if self.hasRating == 'non-h': self.gr = 'non-h' self.category -= self.cats['non_h'] return self
def __buildRating(self): if ymConfig.getConfig('setting').get('enable_rating_check') != 'disable' and self.hasRating: pos = self.rip.find('rating:') if pos != -1: rating = self.rip[pos:pos + 8] self.rip = self.rip.replace(rating, 'rating:' + self.hasRating) else: if self.hasRating == 's': self.rip = self.rip.replace('tags=', 'tags=rating:s+') elif self.hasRating == 'q': self.rip = self.rip.replace('tags=', 'tags=-rating:e+') else: # rating e pass
async def fetToken(self) -> 'str': connector: ProxyConnector = ProxyConnector() proxy = ymConfig.getConfig('setting').get('proxy') if proxy: connector = ProxyConnector.from_url(proxy) user = ymConfig.getConfig('anipic').get('user') password = ymConfig.getConfig('anipic').get('password') async with aiohttp.request('POST', 'https://anime-pictures.net/login/submit', params={ 'login': user, 'password': password }, connector=connector) as response: raw = await response.read() if connector: await connector.close() result = json.loads(raw) if result['success']: return result['token'] else: return ''
def __buildRating(self) -> 'AnipicRipper': if self.has_action == RipperConst.NEW: if ymConfig.getConfig('setting').get( 'enable_rating_check') != 'disable' and self.has_rating: pos = self.rip.find('erotic') if pos != -1: if self.has_rating != '2': self.rip = self.rip.replace('erotic', '') self.parm('denied_tags', 'erotic') else: if self.has_rating != '2': self.parm('denied_tags', 'erotic') # info(f"new url {self.rip}") return self
async def get(self) -> 'list': # params = {} self.__build() connector: ProxyConnector = ProxyConnector() proxy = ymConfig.getConfig('setting').get('proxy') if proxy: connector = ProxyConnector.from_url(proxy) data: list = [] for k, t in self.rips.items(): async with aiohttp.request('GET', k, connector=connector) as response: raw = await response.read() logger.debug(k + f"\n[{t[0]}, {t[1]}]") data = data + json.loads(raw)[t[0]:t[1]] result: list = self._formatData(data) await connector.close() self.hasParm = 0 self.hasAction = '' self.rips.clear() return result
class Searcher: url = 'https://saucenao.com/search.php?db=999&output_type=2&testmode=1&numres=5' api_key = ymConfig.getConfig('setting').get('search_key') connector: ProxyConnector = None def setUrl(self, url: str): self.url += f'&url={url}' return self def useApiKey(self): if self.api_key: self.url += f'&api_key={self.api_key}' return self else: raise SearcherKeyNotFoundException def useProxy(self): proxy = ymConfig.getConfig('setting').get('proxy') if proxy: self.connector = ProxyConnector.from_url(proxy) return self else: raise SearcherProxyNotFoundException async def get(self) -> list: headers = {} try: async with aiohttp.request('GET', self.url, headers=headers, connector=self.connector, timeout=aiohttp.ClientTimeout(600)) as resp: logger.info(self.url) result = json.loads(await resp.read())['results'] if self.connector: await self.connector.close() except (asyncio.TimeoutError, ValueError) as e: raise e return result
msg.append(Plain('未搜索到')) await app.sendGroupMessage(message.sender.group, MeCh.create(msg)) except ClientConnectorError: msg = [At(message.sender.id), Plain('爬,老子不开心了')] await app.sendGroupMessage(message.sender.group, MeCh.create(msg)) except UnknownTarget: msg = [At(message.sender.id), Plain('不在本地与消息缓存中,无法搜索,请重发图片')] await app.sendGroupMessage(message.sender.group, MeCh.create(msg)) elif any(text.__dict__['text'].strip().lower() == 'x2' for text in plains): if not self.Permitted(message): # await app.sendGroupMessage(message.sender.group, [At(message.sender.id), Plain('权限不足')]) # return pass if plain and plain.text in ['[图片]', '[动画表情]']: connector: ProxyConnector = None if proxy := ymConfig.getConfig('setting').get('proxy'): connector = ProxyConnector.from_url(proxy) if (message.sender.group.id << 32) + quote.id in self.GCache.keys(): cache = self.GCache[(message.sender.group.id << 32) + quote.id] url = cache[0].url else: quote_source: GroupMessage = await app.messageFromId(quote.id) image: Image = quote_source.messageChain.get(Image)[0] url = image.url try: data = await w2x(url, connector) img = Image.fromUnsafeBytes(data[0]) with enter_message_send_context(UploadMethods.Group): msg_chain = await MeCh.create([img]).build() image: Image = msg_chain.__root__[0] m = await app.sendGroupMessage(message.sender.group, msg_chain)
def useProxy(self): if proxy := ymConfig.getConfig('setting').get('proxy'): self.connector = ProxyConnector.from_url(proxy) return self
def Permitted(message: GroupMessage): return message.sender.id in ymConfig.getConfig('setting').get('admins')
async def get(self) -> 'list': # params = {} self.__build() connector: ProxyConnector = ProxyConnector() if proxy := ymConfig.getConfig('setting').get('proxy'): connector = ProxyConnector.from_url(proxy)
async def get(self) -> 'list': self.__build() cookies = {'nw': '1'} connector: ProxyConnector = ProxyConnector() proxy = ymConfig.getConfig('setting').get('proxy') if proxy: connector = ProxyConnector.from_url(proxy) if self.hasAction != RipperConst.DETAIL: find = ['table', 'itg gltc'] else: find = ['div', 'gdtm'] result: [EhentaiData] = [] for k, t in self.rips.items(): logger.debug(k + f"\n[{t[0]}, {t[1]}]") async with aiohttp.request('GET', k, cookies=cookies, connector=connector) as response: soup = BeautifulSoup((await response.read()).decode("utf-8"), "lxml") sear = soup.find_all(find[0], class_=find[1]) if self.hasAction == RipperConst.DETAIL: sear = sear[t[0]:t[1]] # no ads for one in sear: link = one.contents[0].contents[0]['href'] async with aiohttp.request('GET', link, connector=connector) as oneInfo: url = BeautifulSoup(await oneInfo.read(), "lxml").find_all( 'img', id='img')[0]['src'] ehentai: EhentaiData = EhentaiData() ehentai.__dict__.update({'preview': url}) result.append(ehentai) else: rm = self.perPages[self.hasAction] tables = sear[0].contents[1:rm + 1] tables += sear[0].contents[rm + 2:] tables = tables[t[0]:t[1]] for ga in tables: la = ga.contents[2].contents[0]['href'].split('/') body = { "method": "gdata", "gidlist": [[int(la[-3]), la[-2]]], "namespace": 1 } json.dumps(body, indent=1) async with aiohttp.request( 'POST', self.api, json=body, connector=connector, timeout=aiohttp.ClientTimeout(20)) as oneInfo: one = json.loads(await oneInfo.read()) ehentai: EhentaiData = EhentaiData() ehentai.__dict__.update(one['gmetadata'][0]) ehentai.gr = self.gr ehentai.id = ehentai.gid ehentai.preview = f"https://ehgt.org/m/{str(1000000000 + int(la[-3]))[1:7]}/{la[-3]}-00.jpg" result.append(ehentai) await connector.close() self.hasParm = 0 self.hasAction = '' self.rips.clear() return result