diff --git a/database.py b/database.py index aff56eb..01f7074 100644 --- a/database.py +++ b/database.py @@ -338,6 +338,14 @@ class database: return i[0] return None + def getChatIdList(self) -> int: + with self._value_lock: + cur = self._db.execute('SELECT DISTINCT chatId FROM chatList;') + r = [] + for i in cur: + r.append(i[0]) + return r + def getChatName(self, chat_id: int, maxCacheTime: int = 3600) -> Optional[str]: with self._value_lock: cur = self._db.execute('SELECT name FROM chatNameCache WHERE id = ? AND time > ?;', (chat_id, round(time()) - maxCacheTime)) @@ -360,6 +368,7 @@ class database: return None def getRSSList(self) -> Optional[List[RSSEntry]]: + '''返回不带chatList和hashList的RSS列表''' with self._value_lock: cur = self._db.execute(f'SELECT * FROM RSSList;') r = [] diff --git a/manage.py b/manage.py index 5204301..1cd4e0f 100644 --- a/manage.py +++ b/manage.py @@ -14,6 +14,13 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . from enum import Enum, unique +from html import escape +from math import ceil, floor +from typing import List +from readset import settings +from rssbotlib import have_rssbotlib +from RSSEntry import ChatEntry, RSSEntry +from textc import textc, timeToStr @unique @@ -22,6 +29,13 @@ class InlineKeyBoardForManage(Enum): ManageByRSS = 1 ManageByChatId = 2 FirstPage = 3 + LastPage = 4 + PrevPage = 5 + NextPage = 6 + ManageMenu = 7 + RSSManage = 8 + ChatManage = 9 + BackToList = 10 def getInlineKeyBoardForManage(): @@ -37,3 +51,136 @@ def getInlineKeyBoardForManage(): i += 1 d[i].append({'text': '关闭', 'callback_data': f'3,{InlineKeyBoardForManage.Close.value}'}) return {'inline_keyboard': d} + + +def getInlineKeyBoardForManageRSSList(RSSEntries: List[RSSEntry], page: int = 1, lastPage: bool = False, itemIndex: int = None, base: str = None, back: str = None): + d = [] + i = -1 + lineLimit = 7 + if base is None: + base = f'3,{InlineKeyBoardForManage.ManageByRSS.value}' + l = len(RSSEntries) + pn = ceil(l / lineLimit) + if lastPage: + page = pn + if itemIndex is not None and itemIndex >= 0: + page = floor(itemIndex / lineLimit) + 1 + if l != 0: + page = max(min(pn, page), 1) + s = max(lineLimit * (page - 1), 0) + n = min(lineLimit * page, l) + while s < n: + rss = RSSEntries[s] + d.append([]) + i = i + 1 + d[i].append({'text': rss.title, 'callback_data': f'{base},{InlineKeyBoardForManage.RSSManage.value},{s},{rss.id}'}) + s = s + 1 + if pn != 1: + d.append([]) + i = i + 1 + if page != 1: + d[i].append({'text': '上一页', 'callback_data': f'{base},{InlineKeyBoardForManage.PrevPage.value},{page}'}) + if page != pn: + d[i].append({'text': '下一页', 'callback_data': f'{base},{InlineKeyBoardForManage.NextPage.value},{page}'}) + d.append([]) + i = i + 1 + if page != 1: + d[i].append({'text': '首页', 'callback_data': f'{base},{InlineKeyBoardForManage.FirstPage.value}'}) + if page != pn: + d[i].append({'text': '尾页', 'callback_data': f'{base},{InlineKeyBoardForManage.LastPage.value}'}) + d.append([]) + i = i + 1 + d[i].append({'text': '返回', 'callback_data': f'3,{InlineKeyBoardForManage.ManageMenu.value}' if back is None else back}) + return {'inline_keyboard': d} + + +def getInlineKeyBoardForManageChatList(m, chatList: List[int], page: int = 1, lastPage: bool = False, itemIndex: int = None): + d = [] + i = -1 + lineLimit = 7 + base = f'3,{InlineKeyBoardForManage.ManageByChatId.value}' + l = len(chatList) + pn = ceil(l / lineLimit) + if lastPage: + page = pn + if itemIndex is not None and itemIndex >= 0: + page = floor(itemIndex / lineLimit) + 1 + if l != 0: + page = max(min(pn, page), 1) + s = max(lineLimit * (page - 1), 0) + n = min(lineLimit * page, l) + while s < n: + chat_id = chatList[s] + d.append([]) + i = i + 1 + d[i].append({'text': m.getChatName(chat_id), 'callback_data': f'{base},{InlineKeyBoardForManage.ChatManage.value},{s},{chat_id}'}) + s = s + 1 + if pn != 1: + d.append([]) + i = i + 1 + if page != 1: + d[i].append({'text': '上一页', 'callback_data': f'{base},{InlineKeyBoardForManage.PrevPage.value},{page}'}) + if page != pn: + d[i].append({'text': '下一页', 'callback_data': f'{base},{InlineKeyBoardForManage.NextPage.value},{page}'}) + d.append([]) + i = i + 1 + if page != 1: + d[i].append({'text': '首页', 'callback_data': f'{base},{InlineKeyBoardForManage.FirstPage.value}'}) + if page != pn: + d[i].append({'text': '尾页', 'callback_data': f'{base},{InlineKeyBoardForManage.LastPage.value}'}) + d.append([]) + i = i + 1 + d[i].append({'text': '返回', 'callback_data': f'3,{InlineKeyBoardForManage.ManageMenu.value}'}) + return {'inline_keyboard': d} + + +def getTextContentForRSSInManageList(m, rssEntry: RSSEntry, s: settings, chatId: int = None) -> str: + text = textc() + text.addtotext( + f"""{rssEntry.title}""") + ttl = 0 if rssEntry.interval is None else rssEntry.interval + ttl = max(min(ttl, s.maxTTL), s.minTTL) + temp = f'更新间隔:{ttl}分' + if rssEntry.lasterrortime is not None and rssEntry.lasterrortime >= rssEntry.lastupdatetime and rssEntry.errorcount > 0: + temp = f'{temp}({s.retryTTL[rssEntry.errorcount]}分)' + text.addtotext(temp) + temp = '上次更新时间:未知' if rssEntry.lastupdatetime is None or rssEntry.lastupdatetime < 0 else f'上次更新时间:{timeToStr(rssEntry.lastupdatetime)}' + text.addtotext(temp) + if rssEntry.lasterrortime is not None: + temp = f'上次更新失败时间:{timeToStr(rssEntry.lasterrortime)}' + text.addtotext(temp) + if rssEntry.errorcount > 0: + temp = f'连续更新失败次数:{rssEntry.errorcount}' + text.addtotext(temp) + if chatId is not None: + chatName = m.getChatName(chatId) + temp = chatName if chatId < 0 else f'{escape(chatName)}' + text.addtotext(f'订阅用户:{temp}') + if len(rssEntry.chatList) > 0: + chatEntry: ChatEntry = rssEntry.chatList[0] + config = chatEntry.config + text.addtotext("设置:") + text.addtotext(f"禁用预览:{config.disable_web_page_preview}") + text.addtotext(f"显示RSS标题:{config.show_RSS_title}") + text.addtotext(f"显示内容标题:{config.show_Content_title}") + text.addtotext(f"显示内容:{config.show_content}") + text.addtotext(f"发送媒体:{config.send_media}") + text += f"单独一行显示链接:{config.display_entry_link}" + text += f"发送图片为文件:{config.send_img_as_file}" + if have_rssbotlib: + text += f'发送原始像素格式的Pixiv动图:{config.send_ugoira_with_origin_pix_fmt}' + text += f'发送Pixiv动图为{config.send_ugoira_method}' + text += f"发送时压缩过大图片:{config.compress_big_image}" + text += f"RSS全局设置:" + text += f"发送时使用原文件名:{config.send_origin_file_name}" + return text.tostr() + + +def getInlineKeyBoardForRSSInManageList(rss: RSSEntry, index: int, chatId: int = None, chatIndex: int = None): + d = [] + i = -1 + d.append([]) + i += 1 + have_chat_id = chatId is not None and chatIndex is not None + d[i].append({'text': '返回', 'callback_data': (f'3,{InlineKeyBoardForManage.ManageByChatId.value},{InlineKeyBoardForManage.ChatManage.value},{chatIndex},{chatId}' if have_chat_id else f'3,{InlineKeyBoardForManage.ManageByRSS.value}') + f',{InlineKeyBoardForManage.BackToList.value},{index}' }) + return {'inline_keyboard': d} diff --git a/rssbot.py b/rssbot.py index ecc0e00..07a5555 100644 --- a/rssbot.py +++ b/rssbot.py @@ -42,7 +42,7 @@ from miraiDatabase import MiraiDatabase from mirai import Mirai from blackList import BlackList, InlineKeyBoardForBlackList, getInlineKeyBoardForBlackList, getTextContentForBlackInfo, getInlineKeyBoardForBlackInfo, getTextContentForUnbanBlackInfo, getInlineKeyBoardForUnbanBlackInfo, BlackInfo from json import loads -from manage import getInlineKeyBoardForManage, InlineKeyBoardForManage +from manage import getInlineKeyBoardForManage, InlineKeyBoardForManage, getInlineKeyBoardForManageRSSList, getInlineKeyBoardForManageChatList, getTextContentForRSSInManageList, getInlineKeyBoardForRSSInManageList MAX_ITEM_IN_MEDIA_GROUP = 10 @@ -2006,14 +2006,124 @@ class callbackQueryHandle(Thread): return elif self._inlineKeyBoardForManageCommand in [InlineKeyBoardForManage.ManageByRSS, InlineKeyBoardForManage.ManageByChatId]: innerCommand = None + is_rss_manage = False + rssManageCommand = None + rssManageChatIndex = None + rssManageChatId = None + rssManageRSSId = None + rssManageIndex = None + rssManageSubList = None if len(self._inputList) > 2: try: innerCommand = InlineKeyBoardForManage(int(self._inputList[2])) except Exception: self.answer('未知的按钮。') return - if innerCommand is None or innerCommand == InlineKeyBoardForManage.FirstPage: - pass + if innerCommand is None or innerCommand in [InlineKeyBoardForManage.FirstPage, InlineKeyBoardForManage.LastPage, InlineKeyBoardForManage.NextPage, InlineKeyBoardForManage.PrevPage, InlineKeyBoardForManage.BackToList]: + page = 1 + lastPage = False + itemIndex = None + if innerCommand == InlineKeyBoardForManage.LastPage: + lastPage = True + elif innerCommand == InlineKeyBoardForManage.NextPage: + page = int(self._inputList[3]) + 1 + elif innerCommand == InlineKeyBoardForManage.PrevPage: + page = int(self._inputList[3]) - 1 + elif innerCommand == InlineKeyBoardForManage.BackToList: + itemIndex = int(self._inputList[3]) + if self._inlineKeyBoardForManageCommand == InlineKeyBoardForManage.ManageByRSS: + rssList = self._main._db.getRSSList() + di['text'] = '列表如下:' + di['reply_markup'] = getInlineKeyBoardForManageRSSList(rssList, page, lastPage, itemIndex) + self._main._request("editMessageText", "post", json=di) + return + else: + chatList = self._main._db.getChatIdList() + di['text'] = '列表如下:' + di['reply_markup'] = getInlineKeyBoardForManageChatList(self._main, chatList, page, lastPage, itemIndex) + self._main._request("editMessageText", "post", json=di) + return + elif innerCommand == InlineKeyBoardForManage.ChatManage: + innerCommand2 = None + try: + index = max(int(self._inputList[3]), 0) + chat_id = int(self._inputList[4]) + except Exception: + self.answer('未知的按钮。') + return + if len(self._inputList) > 5: + try: + innerCommand2 = InlineKeyBoardForManage(int(self._inputList[5])) + except Exception: + self.answer('未知的按钮。') + return + if innerCommand2 is None or innerCommand2 in [InlineKeyBoardForManage.FirstPage, InlineKeyBoardForManage.LastPage, InlineKeyBoardForManage.NextPage, InlineKeyBoardForManage.PrevPage, InlineKeyBoardForManage.BackToList]: + page = 1 + lastPage = False + itemIndex = None + if innerCommand2 == InlineKeyBoardForManage.LastPage: + lastPage = True + elif innerCommand2 == InlineKeyBoardForManage.NextPage: + page = int(self._inputList[6]) + 1 + elif innerCommand2 == InlineKeyBoardForManage.PrevPage: + page = int(self._inputList[6]) - 1 + elif innerCommand2 == InlineKeyBoardForManage.BackToList: + itemIndex = int(self._inputList[6]) + rssList = self._main._db.getRSSListByChatId(chat_id) + di['text'] = '列表如下:' + di['reply_markup'] = getInlineKeyBoardForManageRSSList(rssList, page, lastPage, itemIndex, base=f"3,{InlineKeyBoardForManage.ManageByChatId.value},{InlineKeyBoardForManage.ChatManage.value},{index},{chat_id}", back=f"3,{InlineKeyBoardForManage.ManageByChatId.value},{InlineKeyBoardForManage.BackToList.value},{index}") + self._main._request("editMessageText", "post", json=di) + return + elif innerCommand2 == InlineKeyBoardForManage.RSSManage: + try: + rssManageIndex = int(self._inputList[6]) + rssManageRSSId = int(self._inputList[7]) + except Exception: + self.answer('未知的按钮。') + return + rssManageChatId = chat_id + rssManageChatIndex = index + if len(self._inputList) > 8: + try: + rssManageCommand = InlineKeyBoardForManage(int(self._inputList[8])) + except Exception: + self.answer('未知的按钮。') + return + if len(self._inputList) > 9: + rssManageSubList = self._inputList[9:] + is_rss_manage = True + elif innerCommand == InlineKeyBoardForManage.RSSManage: + is_rss_manage = True + try: + rssManageIndex = int(self._inputList[3]) + rssManageRSSId = int(self._inputList[4]) + except: + self.answer('未知的按钮。') + return + if len(self._inputList) > 5: + try: + rssManageCommand = InlineKeyBoardForManage(int(self._inputList[5])) + except Exception: + self.answer('未知的按钮。') + return + if len(self._inputList) > 6: + rssManageSubList = self._inputList[6:] + if is_rss_manage: + if rssManageChatId is not None: + rssEntry = self._main._db.getRSSByIdAndChatId(rssManageRSSId, rssManageChatId) + else: + pass + if rssManageCommand is None: + di['text'] = getTextContentForRSSInManageList(self._main, rssEntry, self._main._setting, rssManageChatId) + di['parse_mode'] = 'HTML' + di['reply_markup'] = getInlineKeyBoardForRSSInManageList(rssEntry, rssManageIndex, rssManageChatId, rssManageChatIndex) + self._main._request("editMessageText", "post", json=di) + return + elif self._inlineKeyBoardForManageCommand == InlineKeyBoardForManage.ManageMenu: + di['text'] = '请选择管理模式:' + di['reply_markup'] = getInlineKeyBoardForManage() + self._main._request("editMessageText", "post", json=di) + return else: self.answer('未知的按钮。') return