This commit is contained in:
2021-01-05 23:53:22 +08:00
commit afa2a8ea17
6 changed files with 269 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
__pycache__/
*.db
*.txt
!requirements.txt
*.json

63
database.py Normal file
View File

@@ -0,0 +1,63 @@
import sqlite3
class database:
def __check_database(self):
cur = self._db.execute('SELECT * FROM main.sqlite_master;')
self._exist_tables = {}
for i in cur:
if i[0] == 'table':
self._exist_tables[i[1]] = i
for i in ['config', 'RSSList']:
if i not in self._exist_tables:
return False
return True
def __create_table(self):
if 'config' not in self._exist_tables:
self._db.execute(f'''CREATE TABLE config (
version1 INT,
version2 INT,
version3 INT,
version4 INT
);''')
self.__write_version()
if 'RSSList' not in self._exist_tables:
self._db.execute(f'''CREATE TABLE RSSList (
title TEXT,
url TEXT,
interval INT,
lastupdatetime INT,
type INT,
id TEXT,
PRIMARY KEY (url)
);''')
if 'userList' not in self._exist_tables:
self._db.execute('''CREATE TABLE userList (
userId INT,
id TEXT
)''')
if 'channelList' not in self._exist_tables:
self._db.execute('''CREATE TABLE channelList (
channelId INT,
id TEXT
)''')
if 'hashList' not in self._exist_tables:
self._db.execute('''CREATE TABLE hashList (
id TEXT,
hash TEXT,
PRIMARY KEY (hash)
)''')
self._db.commit()
def __init__(self):
self._version = [1, 0, 0, 0]
self._db = sqlite3.connect('data.db')
ok = self.__check_database()
if not ok:
self.__create_table()
def __write_version(self):
self._db.execute(
f'INSERT INTO config VALUES ({self._version[0]}, {self._version[1]}, {self._version[2]}, {self._version[3]});')
self._db.commit()

14
readset.py Normal file
View File

@@ -0,0 +1,14 @@
class settings:
def __init__(self, fn: str=None):
if fn is not None:
self.parse(fn)
def parse(self, fn: str):
d = {}
with open(fn, 'r', encoding='utf8') as f:
t = f.read()
for i in t.splitlines(False):
l = i.split('=', 2)
if len(l) == 2:
d[l[0]] = l[1]
self._token = d['token'] if 'token' in d else None

1
requirements.txt Normal file
View File

@@ -0,0 +1 @@
requests>=2.25.1

129
rssbot.py Normal file
View File

@@ -0,0 +1,129 @@
from database import database
from os.path import exists
from readset import settings
from requests import Session
from traceback import format_exc
from threading import Thread
class main:
def __init__(self):
pass
def _request(self, methodName: str, HTTPMethod: str = 'get', data: dict = None, json: dict = None, returnType: str = 'json'):
try:
r = self._r.request(
HTTPMethod, f'https://api.telegram.org/bot{self._setting._token}/{methodName}', data=data, json=json)
if r.status_code != 200:
return None
if returnType == 'json':
return r.json()
elif returnType == 'text':
return r.text
elif returnType == 'content':
return r.content
except:
print(format_exc())
return None
def _updateLoop(self):
d = {'allowed_updates': [
'message', 'edited_message', 'channel_post', 'edited_channel_post']}
if self._upi is not None:
d['offset'] = self._upi
ud = self._request('getUpdates', 'post', json=d)
print(ud)
if ud is not None and 'ok' in ud and ud['ok']:
for i in ud['result']:
for key in ['message', 'edited_message', 'channel_post', 'edited_channel_post']:
if key in i:
m = messageHandle(self, i[key])
m.start()
self._upi = i['update_id'] + 1
def start(self):
self._db = database()
if not exists('settings.txt'):
print('找不到settings.txt')
return -1
self._setting = settings('settings.txt')
if self._setting._token is None:
print('没有机器人token')
return -1
self._r = Session()
self._me = self._request('getMe')
print(self._me)
if self._me is None:
print('无法读取机器人信息')
self._upi = None
self._updateThread = updateThread(self)
self._updateThread.start()
class updateThread(Thread):
def __init__(self, main: main):
Thread.__init__(self)
self._main = main
def run(self):
while True:
self._main._updateLoop()
class messageHandle(Thread):
def __init__(self, main: main, data: dict):
Thread.__init__(self)
self._main = main
self._data = data
def __getBotCommand(self) -> str:
for i in self._data['entities']:
if i['type'] == 'bot_command':
v = self._data['text'][i['offset']: i['offset'] + i['length']]
founded = v.find('@')
if founded == -1:
return v
return v[0:founded]
return None
def __getChatId(self) -> int:
if 'chat' in self._data:
return self._data['chat']['id']
return None
def __getChatType(self) -> str:
if 'chat' in self._data:
return self._data['chat']['type']
return None
def __getFromUserId(self) -> int:
if 'from' in self._data:
return self._data['from']['id']
return None
def run(self):
print(self._data)
self._messageId = self._data['message_id']
self._chatId = self.__getChatId()
if self._chatId is None:
print('未知的chat id')
return -1
if 'text' in self._data:
if 'entities' in self._data:
self._botCommand = self.__getBotCommand()
if self._botCommand is None:
self._botCommand = '/help'
if self._botCommand not in ['/help']:
self._botCommand = '/help'
di = {'chat_id': self._chatId}
self._fromUserId = self.__getFromUserId()
if self.__getChatType() in ['supergroup', 'group'] and self._fromUserId is not None:
di['reply_to_message_id'] = self._messageId
if self._botCommand == '/help':
di['text'] = '/help 查看帮助'
self._main._request('sendMessage', 'post', json=di)
if __name__ == "__main__":
m = main()
m.start()

57
rssparser.py Normal file
View File

@@ -0,0 +1,57 @@
from xml.dom import minidom
import sys
import requests
class RSSParser:
def __init__(self):
pass
def check(self):
self._root = self.xmldoc.documentElement
if self._root.localName != 'rss' or len(self._root.childNodes) != 1:
return False
self._root2 = self._root.childNodes[0]
if self._root2.localName != 'channel':
return False
m = {}
for i in self._root2.childNodes:
if i.localName == 'item':
pass
else:
m[i.localName] = i.firstChild.nodeValue if len(
i.childNodes) > 0 else i.nodeValue
print()
def normalize(self):
self.removeblank(self.xmldoc.documentElement)
self.xmldoc.normalize()
def parse(self, fn: str):
try:
if fn.find('://') > -1:
re = requests.get(fn)
if re.status_code == 200:
self.xmldoc = minidom.parseString(re.text)
else:
self.xmldoc = minidom.parse(fn)
self.normalize()
return True
except:
return False
def removeblank(self, node):
for i in node.childNodes:
if i.nodeType == minidom.Node.TEXT_NODE:
if i.nodeValue:
i.nodeValue = i.nodeValue.strip()
elif i.nodeType == minidom.Node.ELEMENT_NODE:
self.removeblank(i)
if __name__ == "__main__":
if len(sys.argv) > 1:
fn = sys.argv[1]
p = RSSParser()
p.parse(fn)
p.check()