diff --git a/database.py b/database.py
index 17eb146..aff56eb 100644
--- a/database.py
+++ b/database.py
@@ -68,6 +68,12 @@ reason TEXT,
name TEXT,
PRIMARY KEY (userId)
)'''
+CHATNAMECACHE_TABLE = '''CREATE TABLE chatNameCache (
+id INT,
+name TEXT,
+time INT,
+PRIMARY KEY (id)
+)'''
@unique
@@ -142,6 +148,9 @@ class database:
if v < [1, 0, 0, 8]:
self._db.execute('ALTER TABLE RSSList ADD settings TEXT;')
self._db.commit()
+ if v < [1, 0, 0, 9]:
+ self._db.execute(CHATNAMECACHE_TABLE)
+ self._db.commit()
self._db.execute('VACUUM;')
self.__updateExistsTable()
self.__write_version()
@@ -161,10 +170,12 @@ class database:
self._db.execute(HASHLIST_TABLE)
if 'userBlackList' not in self._exist_tables:
self._db.execute(USERBLACKLIST_TABLE)
+ if 'chatNameCache' not in self._exist_tables:
+ self._db.execute(CHATNAMECACHE_TABLE)
self._db.commit()
def __init__(self, m, loc: str):
- self._version = [1, 0, 0, 8]
+ self._version = [1, 0, 0, 9]
self._value_lock = Lock()
self._db = sqlite3.connect(loc, check_same_thread=False)
self._db.execute('VACUUM;')
@@ -327,6 +338,13 @@ class database:
return i[0]
return None
+ 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))
+ for i in cur:
+ return i[0]
+ return None
+
def getChatRSSCount(self) -> int:
with self._value_lock:
cur = self._db.execute('SELECT COUNT(*) FROM chatList;')
@@ -341,6 +359,14 @@ class database:
return i[0]
return None
+ def getRSSList(self) -> Optional[List[RSSEntry]]:
+ with self._value_lock:
+ cur = self._db.execute(f'SELECT * FROM RSSList;')
+ r = []
+ for i in cur:
+ r.append(RSSEntry(i, self._main._setting.maxCount))
+ return r
+
def getRSSByIdAndChatId(self, id: int, chatId: int) -> RSSEntry:
while self._value_lock:
cur = self._db.execute('SELECT RSSList.title, RSSList.url, RSSList.interval, RSSList.lastupdatetime, RSSList.id, RSSList.lasterrortime, RSSList.forceupdate, RSSList.errorcount, RSSList.settings, chatList.config FROM chatList INNER JOIN RSSList ON RSSList.id = chatList.id WHERE chatList.chatId = ? AND chatlist.id = ?;', (chatId, id))
@@ -424,6 +450,15 @@ class database:
except:
return False
+ def saveChatName(self, chatId: int, name: str) -> bool:
+ with self._value_lock:
+ try:
+ self._db.execute('INSERT OR REPLACE INTO chatNameCache VALUES (?, ?, ?);', (chatId, name, round(time())))
+ self._db.commit()
+ return True
+ except:
+ return False
+
def setRSSForceUpdate(self, id: int, forceupdate: bool) -> bool:
with self._value_lock:
try:
diff --git a/manage.py b/manage.py
new file mode 100644
index 0000000..5204301
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,39 @@
+# (C) 2021-2022 lifegpc
+# This file is part of rssbot.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# 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
+
+
+@unique
+class InlineKeyBoardForManage(Enum):
+ Close = 0
+ ManageByRSS = 1
+ ManageByChatId = 2
+ FirstPage = 3
+
+
+def getInlineKeyBoardForManage():
+ d = []
+ i = -1
+ d.append([])
+ i += 1
+ d[i].append({'text': '按RSS管理', 'callback_data': f'3,{InlineKeyBoardForManage.ManageByRSS.value}'})
+ d.append([])
+ i += 1
+ d[i].append({'text': '按用户管理', 'callback_data': f'3,{InlineKeyBoardForManage.ManageByChatId.value}'})
+ d.append([])
+ i += 1
+ d[i].append({'text': '关闭', 'callback_data': f'3,{InlineKeyBoardForManage.Close.value}'})
+ return {'inline_keyboard': d}
diff --git a/rssbot.py b/rssbot.py
index 3951817..ecc0e00 100644
--- a/rssbot.py
+++ b/rssbot.py
@@ -42,6 +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
MAX_ITEM_IN_MEDIA_GROUP = 10
@@ -856,6 +857,34 @@ class main:
return False, ''
return False
+ def getChatName(self, chatId: int) -> str:
+ name = self._db.getChatName(chatId)
+ if name is not None:
+ return name
+ re = self._request('getChat', 'post', {'chat_id': chatId})
+ if re is not None and 'ok' in re and re['ok']:
+ name = None
+ re = re['result']
+ type = re['type']
+ if type == 'private':
+ name = re['first_name']
+ if 'last_name' in re:
+ name = name + ' ' + re['last_name']
+ if 'username' in re:
+ name = name + '(@' + re['username'] + ')'
+ else:
+ name = re['title']
+ if 'username' in re:
+ name = name + '(@' + re['username'] + ')'
+ if name is not None:
+ self._db.saveChatName(chatId, name)
+ else:
+ name = str(chatId)
+ return name
+ else:
+ print(re)
+ return str(chatId)
+
def _updateLoop(self):
d = {'allowed_updates': ['message', 'edited_message',
'channel_post', 'edited_channel_post', 'callback_query']}
@@ -1164,7 +1193,7 @@ class messageHandle(Thread):
return
if self._botCommand is None and self._data['chat']['type'] in ['group', 'supergroup']:
return
- if self._botCommand is None or self._botCommand not in ['/help', '/rss', '/rsslist', '/ban', '/banlist', '/unban', '/status']:
+ if self._botCommand is None or self._botCommand not in ['/help', '/rss', '/rsslist', '/ban', '/banlist', '/unban', '/status', '/manage']:
self._botCommand = '/help'
di = {'chat_id': self._chatId}
if self.__getChatType() in ['supergroup', 'group'] and self._fromUserId is not None:
@@ -1176,7 +1205,8 @@ class messageHandle(Thread):
/ban 封禁某用户
/banlist 查询被封禁列表
/unban 取消封禁某用户
-/status 返回Bot状态'''
+/status 返回Bot状态
+/manage 管理所有RSS订阅'''
elif self._botCommand == '/rss':
self._botCommandPara = self._getCommandlinePara()
self._uri = None
@@ -1310,6 +1340,12 @@ RSS订阅总数: {self._main._db.getChatRSSCount()}
内容散列个数: {self._main._db.getHashCount()}
黑名单(不含配置文件)总数: {self._main._db.getUserBlackListCount()}'''
di['parse_mode'] = 'HTML'
+ elif self._botCommand == '/manage':
+ if self._fromUserId is None or not self._main._setting.botOwnerList.isOwner(self._fromUserId):
+ di['text'] = '❌你没有权限操作,请与Bot主人进行PY交易以获得权限。'
+ else:
+ di['text'] = '请选择管理模式:'
+ di['reply_markup'] = getInlineKeyBoardForManage()
re = self._main._request('sendMessage', 'post', json=di)
if self._botCommand == '/rss' and self._uri is not None and re is not None and 'ok' in re and re['ok']:
re = re['result']
@@ -1951,9 +1987,37 @@ class callbackQueryHandle(Thread):
di['reply_markup'] = getInlineKeyBoardForBlackList(self._main._blackList.getBlackList(), itemIndex=int(self._inputList[2]))
self._main._request("editMessageText", "post", json=di)
return
+ elif self._loc == 3:
+ if 'message' not in self._data:
+ self.answer('找不到信息。')
+ return
+ if self._fromUserId is None or not self._isOwn:
+ self.answer('❌你没有权限操作,请与Bot主人进行PY交易以获得权限。')
+ return
+ try:
+ self._inlineKeyBoardForManageCommand = InlineKeyBoardForManage(int(self._inputList[1]))
+ except Exception:
+ self.answer('未知的按钮。')
+ return
+ di = {'chat_id': self._data['message']['chat']['id'],
+ 'message_id': self._data['message']['message_id']}
+ if self._inlineKeyBoardForManageCommand == InlineKeyBoardForManage.Close:
+ self._main._request("deleteMessage", "post", json=di)
+ return
+ elif self._inlineKeyBoardForManageCommand in [InlineKeyBoardForManage.ManageByRSS, InlineKeyBoardForManage.ManageByChatId]:
+ innerCommand = 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
else:
self.answer('未知的按钮。')
return
+ self.answer('未知的按钮。')
if __name__ == "__main__":