├── rss.db
├── requirements.txt
├── templates
├── admin.html
├── index.html
└── subindex.html
├── config.py
├── .github
└── workflows
│ └── python-app.yml.bak
├── readme.md
├── rss.py
├── .gitignore
├── manage.py
├── models.py
└── bot.py
/rss.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/9bie/rsspusher/HEAD/rss.db
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 |
2 | feedparser==6.0.0
3 | Flask==1.1.2
4 | peewee==3.14.0
5 | python-telegram-bot==13.1
6 |
--------------------------------------------------------------------------------
/templates/admin.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Admin
6 |
7 |
8 | 实话实说吧,我懒得写了
9 | 启动bot
10 |
11 |
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | # coding:utf-8
2 | import os
3 | TIMER = 10*60 # second
4 | TIMEOUT = 30
5 | DEBUG = True
6 | if DEBUG:
7 | import logging
8 | logger = logging.getLogger('peewee')
9 | logger.setLevel(logging.DEBUG)
10 | logger.addHandler(logging.StreamHandler())
11 |
12 | # Bot
13 | TELEGRAM_KEYS = os.environ["TELEGRAM_KEYS"]
14 | IS_WEBHOOK = False
15 | URL = "https://i.9bie.org"
16 | WEBHOOKING = URL + "/"+TELEGRAM_KEYS
17 |
18 |
19 | # DataBase
20 | ISMYSQL = False
21 | DB_PATH = "rss.db"
22 | MYSQL_HOST = "localhost"
23 | MYSQL_DATABASE = "rss"
24 | MYSQL_USERNAME = "root"
25 | MYSQL_PASSWORD = "root"
26 | MYSQL_PORT = 3306
27 |
28 |
--------------------------------------------------------------------------------
/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
20 |
21 |
--------------------------------------------------------------------------------
/.github/workflows/python-app.yml.bak:
--------------------------------------------------------------------------------
1 |
2 | name: RssPusher
3 |
4 | on:
5 | schedule:
6 | - cron: '0/10 * * * *'
7 | push:
8 | branches:
9 | - master
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - name: 'Checkout codes'
15 | uses: actions/checkout@v2 # 拉取最新的代码
16 | - name: Set up Python 3.8.15
17 | uses: actions/setup-python@v2 # 设置 python 版本
18 | with:
19 | python-version: 3.8.15
20 | - name: Install xmllint
21 | run: sudo apt install libgirepository1.0-dev
22 | - name: Install dependencies # 安装依赖
23 | run: |
24 | python -m pip install --upgrade pip
25 | pip install -r requirements.txt
26 | - name: send rss
27 | env:
28 | TELEGRAM_KEYS: ${{ secrets.TELEGRAM_TOKEN }}
29 | run: |
30 | python rss.py
31 | - name: Commit
32 | run: |
33 | git config --global user.email blackguwc@163.com
34 | git config --global user.name 9bie
35 | git add .
36 | git commit -m "update the rssdb" -a
37 | continue-on-error: true
38 | - name: Push changes
39 | uses: ad-m/github-push-action@master
40 | with:
41 | branch: master
42 | github_token: ${{ secrets.GITHUB_TOKEN }}
43 |
44 |
--------------------------------------------------------------------------------
/templates/subindex.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | RssPusher
6 |
7 |
8 |
9 |
12 |
13 |
14 | {# #}
15 |
16 |
17 |
18 |
19 |
37 |
38 |
45 |
46 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Rss Pusher
2 | 推送指定站点RSS消息到web和tg列表
3 |
4 | 请使用python3运行,当然理论上python2也是可以的
5 |
6 | ## how to build
7 | 修改 `config.py`
8 |
9 | 填写好`TELEGRAM_KEYS`,为你的bot keys
10 |
11 | 如果设置了`IS_WEBHOOK = True`,如果没有请忽略下面一行
12 |
13 | 填写好`URL`,确保tg服务器能访问到你的`URL/tg_keys`
14 |
15 | 修改`TIMER`为获取rss的间隔,单位秒,默认五分钟
16 |
17 | 之后运行`models.py`创建数据库
18 |
19 | 最后直接运行`python manager.py`可以用debug模式运行,然后用nginx反代。
20 |
21 | 或者使用正规方式`gunicorn -w 2 -b 127.0.0.1:5000 manage:app`启动服务
22 |
23 | 之后用nginx反代本地5000端口即可。
24 |
25 | 之后找到你的bot发送`/help`,bot正确运行
26 |
27 |
28 | # how to use
29 | ## en
30 | ###Rss Pusher Usage
31 |
32 | #### User
33 | - **/create** [id] Create a channel, other users can join your channel based on id
34 | - **/join** [id] join the source and recv the rss push
35 | - **/leave** [id] cancel recv the rss push.if you are master for this channel,this channel will delete
36 | - **/list** [id] View the rss subscription link in the channel
37 | - **/myself** View your own information, including channels created/administrated/joined
38 | - **/help** you see now
39 | #### Admin
40 | - **/add** [id] [title] [rss link] add the rss link
41 | - **/delete** [id] [rss_id] delete the rss target.id from **/list**
42 | - **/privilege** [id] [telegram_id] set ont follows to admin.(you must channel master)
43 | - **/update** Only for developers.Update rss subscription now
44 | ## zh
45 | #### User
46 | - **/create** [id] 创建个rss订阅频道,其他用户可以根据这个id加入你的频道
47 | - **/join** [id] 加入一个频道,之后你将会收到这个频道的更新推送
48 | - **/leave** [id] 离开某个频道,如果你是这个频道的创建者,频道将会删除
49 | - **/list** [id] 查看该频道的rss订阅列表
50 | - **/myself** 查看你创建/管理/加入的频道
51 | - **/help** 你现在正在看到的
52 | #### Admin
53 | - **/add** [id] [title] [rss link] 给频道添加一个rss订阅链接
54 | - **/delete** [id] [rss_id] 删除频道内一个rss订阅链接,rss_id可以从 **/list** 里查看
55 | - **/privilege** [id] [telegram_id] 设置一个telegram用户为管理员,该成员必须再本频道发送过 **/help** 或以外的参数(你必须为频道创建者从才能使用本命令)
56 | - **/update** 仅对开发者开放,立刻更新所有rss推送
57 |
58 | ## todo
59 |
60 | ### web主页
61 | 定制不同的rsschannel的不同独立rss主页页面
62 |
63 | ## 用到的模块
64 |
65 | - python-telegram-bot
66 | - peewee
67 | - feedparser
--------------------------------------------------------------------------------
/rss.py:
--------------------------------------------------------------------------------
1 | import feedparser
2 | import re
3 | import models
4 | import socket
5 | from config import TIMEOUT
6 | from threading import Thread
7 | from bot import send_all_follows
8 |
9 | socket.setdefaulttimeout(TIMEOUT)
10 | def delete_html(html):
11 | dr = re.compile(r'<[^>]+>', re.S)
12 | dd = dr.sub('', html)
13 | return dd
14 |
15 |
16 | def check(target):
17 | result = feedparser.parse(target)
18 | if result.feed == {}:
19 | return ""
20 | else:
21 | if "title" in result.feed:
22 | return result.feed.title
23 | else:
24 | return "NoneTitle"
25 |
26 | def mutiThread(r):
27 | report = ""
28 | report_s = ""
29 | try:
30 | print("[RSS]Now:{}".format(r.Rss))
31 | data = feedparser.parse(r.Rss)
32 | for entries in data.entries:
33 | summary = delete_html(entries.summary)
34 | if summary != "" and len(summary) >= 20:
35 | summary = summary[:50]
36 | if models.DataBase.select().where(
37 | models.DataBase.Url == entries.link
38 | ).exists():
39 | continue
40 | models.DataBase.create(
41 | Title=entries.title,
42 | Url=entries.link,
43 | Summary=summary,
44 | Form=r,
45 | )
46 |
47 | report_s += '\t{}\n'.format(entries.link, entries.title)
48 |
49 | if report_s != "":
50 | if "subtitle" not in data.feed:
51 | report += "{}:\n".format(data.feed.title) + report_s
52 | else:
53 | report += "{} - {}:\n".format(data.feed.title, data.feed.subtitle) + report_s
54 |
55 | if report != "":
56 | send_all_follows(r, report)
57 | except Exception as e:
58 | print("Some Error:{}".format(e))
59 |
60 | def main():
61 | rss = models.RssList.select()
62 | lists = []
63 |
64 | for r in rss:
65 | lists.append(Thread(target=mutiThread,args=(r,)))
66 | for i in lists:
67 | i.start()
68 | for j in lists:
69 | j.join()
70 |
71 |
72 | if __name__ == '__main__':
73 | main()
74 |
75 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 | *.db
9 | .idea/
10 | # Distribution / packaging
11 | .Python
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | pip-wheel-metadata/
25 | share/python-wheels/
26 | *.egg-info/
27 | .installed.cfg
28 | *.egg
29 | MANIFEST
30 |
31 | # PyInstaller
32 | # Usually these files are written by a python script from a template
33 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
34 | *.manifest
35 | *.spec
36 |
37 | # Installer logs
38 | pip-log.txt
39 | pip-delete-this-directory.txt
40 |
41 | # Unit test / coverage reports
42 | htmlcov/
43 | .tox/
44 | .nox/
45 | .coverage
46 | .coverage.*
47 | .cache
48 | nosetests.xml
49 | coverage.xml
50 | *.cover
51 | *.py,cover
52 | .hypothesis/
53 | .pytest_cache/
54 |
55 | # Translations
56 | *.mo
57 | *.pot
58 |
59 | # Django stuff:
60 | *.log
61 | local_settings.py
62 | db.sqlite3
63 | db.sqlite3-journal
64 |
65 | # Flask stuff:
66 | instance/
67 | .webassets-cache
68 |
69 | # Scrapy stuff:
70 | .scrapy
71 |
72 | # Sphinx documentation
73 | docs/_build/
74 |
75 | # PyBuilder
76 | target/
77 |
78 | # Jupyter Notebook
79 | .ipynb_checkpoints
80 |
81 | # IPython
82 | profile_default/
83 | ipython_config.py
84 |
85 | # pyenv
86 | .python-version
87 |
88 | # pipenv
89 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
90 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
91 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
92 | # install all needed dependencies.
93 | #Pipfile.lock
94 |
95 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
96 | __pypackages__/
97 |
98 | # Celery stuff
99 | celerybeat-schedule
100 | celerybeat.pid
101 |
102 | # SageMath parsed files
103 | *.sage.py
104 |
105 | # Environments
106 | .env
107 | .venv
108 | env/
109 | venv/
110 | ENV/
111 | env.bak/
112 | venv.bak/
113 |
114 | # Spyder project settings
115 | .spyderproject
116 | .spyproject
117 |
118 | # Rope project settings
119 | .ropeproject
120 |
121 | # mkdocs documentation
122 | /site
123 |
124 | # mypy
125 | .mypy_cache/
126 | .dmypy.json
127 | dmypy.json
128 |
129 | # Pyre type checker
130 | .pyre/
131 |
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | from threading import Timer, Thread
2 |
3 | from time import sleep
4 |
5 | from flask import *
6 | import rss
7 | from bot import *
8 | # from flask_login import login_user, logout_user, login_required,current_user
9 | from models import DataBase
10 |
11 | app = Flask(__name__)
12 |
13 | Timer(TIMER, rss.main).start()
14 |
15 |
16 | @app.route('/start')
17 | def start():
18 | if IS_WEBHOOK:
19 | bot.setWebhook(WEBHOOKING)
20 | return "ok"
21 |
22 |
23 |
24 | @app.route("/" + TELEGRAM_KEYS, methods=["POST"])
25 | def tg_event():
26 | update = telegram.Update.de_json(request.get_json(force=True), bot)
27 |
28 | if update.message is None:
29 | return "Show me your TOKEN please!"
30 | Bot(update).handle()
31 | return "ok"
32 |
33 |
34 | @app.route('/')
35 | @app.route("/")
36 | def index(id=""):
37 | page = request.args.get('page', '')
38 | if not page:
39 | page = 0
40 | else:
41 | page = int(page)
42 | try:
43 | if id == "":
44 | return render_template('index.html')
45 | else:
46 | lists = []
47 | if not models.RssChannel.select().where(
48 | models.RssChannel.Customize == id
49 | ).exists():
50 | return "channel not found", 404
51 | items = DataBase.select().where(
52 | DataBase.Form == models.RssChannel.get(Customize=id)
53 | ).paginate(page, 50)
54 | for i in items:
55 | lists.append(
56 | {
57 | "Form": models.RssListFriendShip.get(RssList=i.Form).CustomizeTitle,
58 | "Title": i.Title,
59 | "Url": i.Url,
60 | "Summary": i.Summary if i.Summary is not None else ""
61 | }
62 | )
63 | return render_template('subindex.html', items=lists)
64 | except Exception as e:
65 | return "Have some error:{}\nPlease link @bakabie".format(e), 500
66 |
67 |
68 | def update():
69 | update_id = 0
70 | while True:
71 | bot.deleteWebhook()
72 | if update_id == 0:
73 | updates = telegram.Bot(TELEGRAM_KEYS).get_updates()
74 | else:
75 | updates = telegram.Bot(TELEGRAM_KEYS).get_updates(offset=update_id)
76 | for update in updates:
77 | update_id = update.update_id + 1
78 | print(update)
79 | Bot(update).handle()
80 | sleep(3)
81 |
82 |
83 | if not IS_WEBHOOK:
84 | Thread(target=update).start()
85 |
86 | if __name__ == '__main__':
87 | app.run()
88 |
--------------------------------------------------------------------------------
/models.py:
--------------------------------------------------------------------------------
1 | import json
2 | import random
3 | import string
4 |
5 | from peewee import *
6 |
7 | from config import *
8 |
9 | db = SqliteDatabase(DB_PATH) if not ISMYSQL else MySQLDatabase(host=MYSQL_HOST, database=MYSQL_DATABASE,
10 | user=MYSQL_USERNAME, password=MYSQL_PASSWORD,
11 | port=MYSQL_PORT)
12 |
13 |
14 | class BaseModel(Model):
15 | class Meta:
16 | database = db
17 |
18 |
19 | class Follows(BaseModel):
20 | ID = PrimaryKeyField()
21 | Telegram_id = IntegerField(null=False, unique=True)
22 | PassWD = CharField(null=True)
23 |
24 |
25 | class RssChannel(BaseModel):
26 | ID = PrimaryKeyField()
27 | Customize = CharField(null=False, unique=True)
28 | Master = ForeignKeyField(Follows, related_name="master")
29 |
30 |
31 | class RssList(BaseModel):
32 | ID = PrimaryKeyField()
33 | # Title = CharField(null=False)
34 | Rss = CharField(null=False, unique=True)
35 |
36 |
37 | class RssListFriendShip(BaseModel):
38 | RssList = ForeignKeyField(RssList, related_name="rss_list")
39 | RssChannel = ForeignKeyField(RssChannel, related_name="rss_channel")
40 | CustomizeTitle = CharField(null=False)
41 |
42 |
43 | class RssMember(BaseModel):
44 | Follows = ForeignKeyField(Follows, related_name="follows")
45 | RssChannel = ForeignKeyField(RssChannel, related_name="rss_channel")
46 |
47 |
48 | class RssAdmin(BaseModel):
49 | Follows = ForeignKeyField(Follows, related_name="follows")
50 | RssChannel = ForeignKeyField(RssChannel, related_name="rss_channel")
51 |
52 |
53 | class DataBase(BaseModel):
54 | ID = PrimaryKeyField()
55 | Title = CharField(null=False)
56 | Url = CharField(null=False, unique=True)
57 | Summary = TextField(null=True)
58 | Form = ForeignKeyField(RssList, related_name="rss_list")
59 |
60 |
61 | def create_table():
62 | db.connect()
63 | db.create_tables([Follows, RssChannel, RssList, RssListFriendShip, RssMember, RssAdmin, DataBase])
64 |
65 |
66 | def random_password():
67 | return ''.join(random.sample(string.ascii_letters + string.digits, 8))
68 |
69 |
70 | ## 字符串转字典
71 | def str_to_dict(dict_str):
72 | if isinstance(dict_str, str) and dict_str != '':
73 | new_dict = json.loads(dict_str)
74 | else:
75 | new_dict = ""
76 | return new_dict
77 |
78 |
79 | # 字典转对象
80 | def dict_to_obj(dict, obj, exclude=None):
81 | for key in dict:
82 | if exclude:
83 | if key in exclude:
84 | continue
85 | setattr(obj, key, dict[key])
86 | return obj
87 |
88 |
89 | # peewee转dict
90 | def obj_to_dict(obj, exclude=None):
91 | print(obj.__dict__)
92 | dict = obj.__dict__['__data__']
93 | if exclude:
94 | for key in exclude:
95 | if key in dict: dict.pop(key)
96 | return dict
97 |
98 |
99 | # peewee转list
100 | def query_to_list(query, exclude=None):
101 | list = []
102 | for obj in query:
103 | dict = obj_to_dict(obj, exclude)
104 | list.append(dict)
105 | return list
106 |
107 |
108 | if __name__ == '__main__':
109 | create_table()
110 |
--------------------------------------------------------------------------------
/bot.py:
--------------------------------------------------------------------------------
1 | # coding:utf-8
2 | import re
3 |
4 | import telegram
5 |
6 | import models
7 | from config import *
8 | from time import sleep
9 | # from rss import check
10 | bot = telegram.Bot(token=TELEGRAM_KEYS)
11 |
12 |
13 | class Bot:
14 |
15 | def __init__(self, update):
16 | self.update = update
17 | if update.message is None:
18 | self.command = ""
19 | self.param = []
20 | return
21 | self.chat_id = update.message.chat_id
22 | self.data = update.message.to_dict()
23 | if "text" not in self.data:
24 | self.command = ""
25 | self.param = []
26 | else:
27 | self.command = self.data["text"].split()[0]
28 | self.param = self.data["text"].split()
29 |
30 | def __grant(self, param_number):
31 | if len(self.param) < param_number:
32 | bot.send_message(chat_id=self.chat_id, text="参数错误.可以发送/help查询如何使用")
33 | return False
34 | if not models.Follows.select().where(
35 | models.Follows.Telegram_id == self.chat_id
36 | ).exists():
37 | models.Follows.create(
38 | Telegram_id=self.chat_id
39 | )
40 | return True
41 |
42 | def __is_channel_exists(self, id):
43 | if not models.RssChannel.select().where(
44 | models.RssChannel.Customize == id
45 | ).exists():
46 | bot.send_message(chat_id=self.chat_id, text="找不到频道.")
47 | return False
48 | return True
49 |
50 | def __are_you_admin(self, channel_customize):
51 | if not models.RssAdmin.select().where(
52 | models.RssAdmin.RssChannel == models.RssChannel.get(Customize=channel_customize),
53 | models.RssAdmin.Follows == models.Follows.get(Telegram_id=self.chat_id)
54 | ).exists():
55 | bot.send_message(chat_id=self.chat_id, text="你不是该频道的管理员.")
56 | return False
57 | return True
58 |
59 | def __create(self):
60 |
61 | if not self.__grant(param_number=2):
62 | return
63 | if models.RssChannel.select().where(
64 | models.RssChannel.Master == models.Follows.get(Telegram_id=self.chat_id)
65 | ).count() >= 3:
66 | bot.send_message(chat_id=self.chat_id, text="你已经超出最大频道限制(数量为3条,请联系管理员 @bakabie)")
67 | return
68 | is_match = re.match("^[_a-zA-Z0-9]+$",self.param[1])
69 | if not is_match:
70 | bot.send_message(chat_id=self.chat_id,text="仅限字母数字下划线且不超过8位")
71 | return
72 | if len(self.param[1])> 8:
73 | bot.send_message("仅限字母数字下划线且不超过8位")
74 | return
75 | if models.RssChannel.select().where(
76 | models.RssChannel.Customize == self.param[1]
77 | ).exists():
78 | bot.send_message(chat_id=self.chat_id, text="频道已经存在,请换个id.")
79 | return
80 | new_channel = models.RssChannel.create(
81 | Customize=self.param[1],
82 | Master=models.Follows.get(Telegram_id=self.chat_id)
83 | )
84 | models.RssAdmin.create(
85 | Follows=models.Follows.get(Telegram_id=self.chat_id),
86 | RssChannel=new_channel
87 | )
88 | models.RssMember.create(
89 | Follows=models.Follows.get(Telegram_id=self.chat_id),
90 | RssChannel=new_channel
91 | )
92 |
93 | bot.send_message(chat_id=self.chat_id, text="成功, 你创建的频道id为:\n\t - {}\n"
94 | " 其他用户可以根据这个id加入你的频道接受推送.\n你的主页为:\n\t - {}".format(self.param[1],URL+"/"+self.param[1]),)
95 |
96 | def __join(self):
97 | if not self.__grant(param_number=2):
98 | return
99 | id = self.param[1]
100 | if not models.RssChannel.select().where(
101 | models.RssChannel.Customize == id
102 | ).exists():
103 | bot.send_message(chat_id=self.chat_id, text="找不到频道.")
104 | return
105 | if models.RssMember.select().where(
106 | models.RssMember.Follows == models.Follows.get(Telegram_id=self.chat_id),
107 | models.RssMember.RssChannel == models.RssChannel.get(Customize=id)
108 | ).exists():
109 | bot.send_message(chat_id=self.chat_id, text="你已经加入了这个频道.")
110 | return
111 | models.RssMember.create(
112 | Follows=models.Follows.get(Telegram_id=self.chat_id),
113 | RssChannel=models.RssChannel.get(Customize=id)
114 | )
115 | bot.send_message(chat_id=self.chat_id, text="成功.")
116 |
117 | def __leave(self):
118 | if not self.__grant(param_number=2):
119 | return
120 | id = self.param[1]
121 | if not self.__is_channel_exists(id):
122 | return
123 |
124 | if not models.RssMember.select().where(
125 | models.RssMember.Follows == models.Follows.get(Telegram_id=self.chat_id),
126 | models.RssMember.RssChannel == models.RssChannel.get(Customize=id)
127 | ).exists():
128 | bot.send_message(chat_id=self.chat_id, text="你已经加入了这个频道.")
129 | return
130 | models.RssMember.delete().where(
131 | models.RssMember.Follows == models.Follows.get(Telegram_id=self.chat_id),
132 | models.RssMember.RssChannel == models.RssChannel.get(Customize=id)
133 | ).execute()
134 | if models.RssChannel.get(Customize=id).Master == models.Follows.get(Telegram_id=self.chat_id):
135 | check = []
136 | for i in models.RssListFriendShip.select().where(
137 | models.RssListFriendShip.RssChannel == models.RssChannel.get(Customize=id)):
138 | check.append(i.RssList)
139 | models.RssListFriendShip.delete().where(
140 | models.RssListFriendShip.RssChannel == models.RssChannel.get(Customize=id)).execute()
141 | for rss in check:
142 | if not models.RssListFriendShip.select().where(
143 | models.RssListFriendShip.RssList == rss
144 | ).exists():
145 | models.RssList.delete().where(models.RssList.ID == rss.ID).execute()
146 | models.DataBase.delete().where(models.DataBase.Form == rss).execute()
147 | models.RssList.delete().where(models.RssList.ID)
148 | models.RssMember.delete().where(
149 | models.RssMember.RssChannel == models.RssChannel.get(Customize=id)).execute()
150 | models.RssAdmin.delete().where(models.RssAdmin.RssChannel == models.RssChannel.get(Customize=id)).execute()
151 | models.RssChannel.delete().where(models.RssChannel.Customize == id).execute()
152 | bot.send_message(chat_id=self.chat_id, text="成功!")
153 |
154 | def __list(self):
155 | if not self.__grant(param_number=2):
156 | return
157 | id = self.param[1]
158 | if not self.__is_channel_exists(id):
159 | return
160 | results = ""
161 | rsslists = models.RssListFriendShip.select().where(
162 | models.RssListFriendShip.RssChannel == models.RssChannel().get(Customize=id)
163 | )
164 | for i in rsslists:
165 | results += "Rss id: {}\n\t - Title:{}\n\t - Rss:{}\n\t".format(
166 | i.RssList.ID,
167 | i.CustomizeTitle,
168 | i.RssList.Rss)
169 | if results == "":
170 | bot.send_message(chat_id=self.chat_id, text="没有任何东西在频道里.")
171 | else:
172 | bot.send_message(chat_id=self.chat_id, text=results, parse_mode="html")
173 |
174 | def __myself(self):
175 | if not self.__grant(param_number=1):
176 | return
177 | master = "\n*You are master for*:"
178 | rss_master = models.RssChannel.select().where(
179 | models.RssChannel.Master == models.Follows.get(Telegram_id=self.chat_id)
180 | )
181 |
182 | for i in rss_master:
183 | master += "\n\t - Rss Channel ID: {}\n".format(i.Customize)
184 | rss_admin = models.RssAdmin.select().where(
185 | models.RssAdmin.Follows == models.Follows.get(Telegram_id=self.chat_id)
186 | )
187 | admin = "\n*You are Admin for*:"
188 | for j in rss_admin:
189 | admin += "\n\t - Rss Channel ID: {}\n".format(j.RssChannel.Customize)
190 | rss_member = models.RssMember.select().where(
191 | models.RssMember.Follows == models.Follows.get(Telegram_id=self.chat_id)
192 | )
193 | member = "\n*You are joined*:"
194 | for k in rss_member:
195 | member += "\n\t - Rss Channel ID: {}\n".format(k.RssChannel.Customize)
196 | bot.send_message(chat_id=self.chat_id, text=master + admin + member, parse_mode="markdown")
197 |
198 | def __add(self):
199 | if not self.__grant(param_number=3):
200 | return
201 | id = self.param[1]
202 | title = self.param[2]
203 | link = self.param[3]
204 | if not self.__is_channel_exists(id):
205 | return
206 | if not self.__are_you_admin(id):
207 | return
208 | pattern = re.compile(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+')
209 | if len(re.findall(pattern, link)) == 0:
210 | bot.send_message(chat_id=self.chat_id, text="请输入正确的rss连接")
211 | return
212 | else:
213 |
214 | if not models.RssList.select().where(
215 | models.RssList.Rss == link
216 | ).exists():
217 | models.RssList.create(
218 | # title = check(link)
219 | Rss=link,
220 | )
221 | if models.RssListFriendShip.select().where(
222 | models.RssListFriendShip.RssList == models.RssList.get(Rss=link),
223 | models.RssListFriendShip.RssChannel == models.RssChannel.get(Customize=id)
224 | ).exists():
225 | bot.send_message(chat_id=self.chat_id, text="您已经加入了")
226 | return
227 | models.RssListFriendShip.create(
228 | RssList=models.RssList.get(Rss=link),
229 | RssChannel=models.RssChannel.get(Customize=id),
230 | CustomizeTitle=title
231 | )
232 | bot.send_message(chat_id=self.chat_id, text="成功!")
233 |
234 | def __delete(self):
235 | if not self.__grant(param_number=2):
236 | return
237 | id = self.param[1]
238 | if not self.__is_channel_exists(id):
239 | return
240 | if not self.__are_you_admin(id):
241 | return
242 |
243 | rss_id = self.param[2]
244 | if not models.RssList.select().where(
245 | models.RssList.ID == rss_id
246 | ).exists():
247 | bot.send_message(chat_id=self.chat_id, text="找不到rss id.")
248 | return
249 | if not models.RssListFriendShip.select().where(
250 | models.RssListFriendShip.RssList == models.RssList.get(ID=rss_id),
251 | models.RssListFriendShip.RssChannel == models.RssChannel.get(Customize=id)
252 | ).exists():
253 | bot.send_message(chat_id=self.chat_id, text="该频道为添加这个rss.")
254 | return
255 | models.RssListFriendShip.delete().where(
256 | models.RssListFriendShip.RssChannel == models.RssChannel.get(Customize=id),
257 | models.RssListFriendShip.RssList == models.RssList.get(ID=rss_id)
258 | ).execute()
259 | if not models.RssListFriendShip.select().where(
260 | models.RssListFriendShip.RssList == models.RssList.get(ID=rss_id)
261 | ).exists():
262 | models.DataBase.delete().where(
263 | models.DataBase.Form == models.RssList.get(ID=int(rss_id))
264 | ).execute()
265 | models.RssList.delete().where(
266 | models.RssList.ID == int(rss_id)
267 | ).execute()
268 |
269 | bot.send_message(chat_id=self.chat_id, text="成功!")
270 |
271 | def __privilege(self):
272 | if not self.__grant(param_number=3):
273 | return
274 | id = self.param[1]
275 | telegram_id = self.param[2]
276 | if not self.__is_channel_exists(id):
277 | return
278 | if models.RssChannel.get(Customize=id).Master != models.Follows.get(Telegram_id=self.chat_id):
279 | bot.send_message(chat_id=self.chat_id, text="抱歉,你不是该频道的管理员.")
280 | return
281 | if not models.Follows.select().where(
282 | models.Follows.Telegram_id == telegram_id
283 | ).exists():
284 | bot.send_message(chat_id=self.chat_id, text="抱歉,目标并未加入我们这个bot,目标至少要在我们这发送一条以上正确指令(/help)就行")
285 | return
286 | if models.RssAdmin.select().where(
287 | models.RssAdmin.Follows == models.Follows.get(Telegram_id=telegram_id),
288 | models.RssAdmin.RssChannel == models.RssChannel.get(Customize=id)
289 | ).exists():
290 | bot.send_message(chat_id=self.chat_id, text="目标用户已经是管理员了")
291 | return
292 | models.RssAdmin.create(
293 | Follows=models.Follows.get(Telegram_id=telegram_id),
294 | RssChannel=models.RssChannel.get(Customize=id)
295 | )
296 | bot.send_message(chat_id=self.chat_id, text="成功!")
297 | return
298 |
299 | def __change_pwd(self):
300 | pass
301 |
302 | def __update(self):
303 | bot.send_message(chat_id=self.chat_id, text="mei xie.")
304 | return
305 |
306 | def handle(self):
307 | try:
308 | if self.command == "/help":
309 | self.__grant(1)
310 | if len(self.param) >= 2:
311 | if self.param[1] == "en":
312 | bot.send_message(chat_id=self.chat_id,
313 | text="*Rss Pusher Usage:*\n"
314 | "*User:*\n"
315 | "\t - /create [id] Create a channel, other users can join your channel based on id"
316 | "\t - /join [id] join the source and recv the rss push\n"
317 | "\t - /leave [id] cancel recv the rss push.if you are master for this channel,"
318 | "this channel will delete\n"
319 | "\t - /list [id] View the rss subscription link in the channel\n"
320 | "\t - /myself View your own information, includi"
321 | "ng channels created/administrated/joined\n"
322 | "\t - /help you see now\n"
323 | "*Admin:*\n"
324 | "\t - /add [id] [title] [rss link] add the rss link\n"
325 | "\t - /delete [id] [rss_id] delete the rss target.id from /list\n"
326 | "\t - /privilege [id] [telegram_id] set ont follows to admin.(you must channel master)\n"
327 | "\t - /update Only for developers.Update rss subscription now\n"
328 | , parse_mode="markdown")
329 | return
330 | else:
331 | bot.send_message(chat_id=self.chat_id,
332 | text="*Rss Pusher Usage:*\n*"
333 | "User:*\n"
334 | "\t- /create [id] 创建个rss订阅频道,其他用户可以根据这个id加入你的频道\n"
335 | "\t- /join [id] 加入一个频道,之后你将会收到这个频道的更新推送\n"
336 | "\t- /leave** [id] 离开某个频道,如果你是这个频道的创建者,频道将会删除\n"
337 | "\t- /list [id] 查看该频道的rss订阅列表\n"
338 | "\t- /myself 查看你创建/管理/加入的频道\n"
339 | "\t- /help 你现在正在看到的\n"
340 | "*Admin:*\n"
341 | "\t- /add [id] [title] [rss link] 给频道添加一个rss订阅链接\n"
342 | "\t- /delete [id] [rss_id] 删除频道内一个rss订阅链接,rss_id可以从 **/list** 里查看\n"
343 | "\t- /privilege [id] [telegram_id] 设置一个telegram用户为管理员,该成员必须再本频道发送过 /help 或以外的参数(你必须为频道创建者从才能使用本命令)\n"
344 | "\t- /update 仅对开发者开放,立刻更新所有rss推送\n"
345 | , parse_mode="markdown"
346 | )
347 | return
348 |
349 | elif self.command == "/about":
350 | bot.send_message(chat_id=self.chat_id,
351 | text="Made By 9bie's gongdi english and jiushi."
352 | "\nWeb:{}\nGithub: https://github.com/9bie/rsspusher".format(URL))
353 | return
354 | elif self.command == "/create":
355 | self.__create()
356 | elif self.command == "/join":
357 | self.__join()
358 | elif self.command == "/add":
359 | self.__add()
360 | elif self.command == "/delete":
361 | self.__delete()
362 | elif self.command == "/leave":
363 | self.__leave()
364 | elif self.command == "/list":
365 | self.__list()
366 | elif self.command == "/myself":
367 | self.__myself()
368 | elif self.command == "/privilege":
369 | self.__privilege()
370 | elif self.command == "/change_pwd":
371 | self.__change_pwd()
372 | elif self.command == "/update":
373 | self.__update()
374 | elif self.command == "":
375 | return
376 | else:
377 | if self.chat_id >= 0:
378 | bot.send_message(chat_id=self.chat_id,
379 | text="我不知道你在说啥,你可以发送/help给我查询.")
380 | return
381 | except Exception as e:
382 | if DEBUG is False:
383 | e = "*" * 20
384 | bot.send_message(chat_id=self.chat_id, text="*RssPusher Exception*:\n\t - {}".format(e),
385 | parse_mode="markdown")
386 |
387 |
388 | def send_all_follows(rsslist, msg):
389 | try:
390 |
391 | rssfriendship = models.RssListFriendShip.select().where(
392 | models.RssListFriendShip.RssList == rsslist
393 | )
394 | for c in rssfriendship:
395 | follows = models.RssMember.select().where(
396 | models.RssMember.RssChannel == c.RssChannel
397 | )
398 | for f in follows:
399 |
400 | bot.send_message(chat_id=f.Follows.Telegram_id, text=msg, parse_mode="html")
401 | except Exception as e:
402 | print("Have some errors:{}".format(e))
403 |
--------------------------------------------------------------------------------