first commit
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import time
|
||||
|
||||
import psycopg2
|
||||
from psycopg2 import Error
|
||||
|
||||
|
||||
class CreateRssRecord(object):
|
||||
def __init__(self):
|
||||
self.hostname = 'erhe.top'
|
||||
self.port = 20788
|
||||
self.database = 'freshrss'
|
||||
self.user = 'freshrss'
|
||||
self.password = 'freshrss'
|
||||
self.conn = None
|
||||
|
||||
def connect(self):
|
||||
"""连接到 PostgreSQL 数据库"""
|
||||
try:
|
||||
self.conn = psycopg2.connect(
|
||||
dbname=self.database,
|
||||
user=self.user,
|
||||
password=self.password,
|
||||
host=self.hostname,
|
||||
port=self.port
|
||||
)
|
||||
except Error as e:
|
||||
print(f"Error connecting to the database: {e}")
|
||||
else:
|
||||
print("Connected to the database successfully.")
|
||||
|
||||
if not self.conn:
|
||||
raise Exception("Database connection failed")
|
||||
|
||||
def check_and_insert(self, data):
|
||||
"""检查 URL 是否存在,如果不存在则插入整个数据字典"""
|
||||
try:
|
||||
with self.conn.cursor() as cursor:
|
||||
# 检查 URL 是否存在
|
||||
select_sql = "SELECT COUNT(*) FROM freshrsstoor_feed WHERE url = %s"
|
||||
cursor.execute(select_sql, (data['url'],))
|
||||
result = cursor.fetchone()
|
||||
if result[0] == 0:
|
||||
# URL 不存在,插入新记录
|
||||
columns = ', '.join(data.keys())
|
||||
values = ', '.join(['%s'] * len(data))
|
||||
insert_sql = """INSERT INTO freshrsstoor_feed
|
||||
(url, kind, category, "name", website, description, "lastUpdate", priority, "pathEntries", "httpAuth", "error", "ttl", attributes, "cache_nbEntries", "cache_nbUnreads")
|
||||
VALUES ('{}', {}, {}, '{}', '{}', '{}', {}, {}, '{}', '{}', {}, {}, '{}', {}, {});""".format(
|
||||
data['url'],
|
||||
data['kind'],
|
||||
data['category'],
|
||||
data['name'],
|
||||
data['website'],
|
||||
data['description'],
|
||||
data['lastUpdate'],
|
||||
data['priority'],
|
||||
data['pathEntries'],
|
||||
data['httpAuth'],
|
||||
data['error'],
|
||||
data['ttl'],
|
||||
data['attributes'],
|
||||
data['cache_nbEntries'],
|
||||
data['cache_nbUnreads']
|
||||
)
|
||||
cursor.execute(insert_sql, tuple(data.values()))
|
||||
self.conn.commit()
|
||||
print("Data inserted successfully.")
|
||||
else:
|
||||
print("URL already exists.")
|
||||
except Error as e:
|
||||
print(f"Error: {e}")
|
||||
finally:
|
||||
if self.conn is not None:
|
||||
self.conn.close()
|
||||
|
||||
|
||||
# 使用示例
|
||||
if __name__ == "__main__":
|
||||
cr = CreateRssRecord()
|
||||
cr.connect()
|
||||
insert_data = {
|
||||
'url': 'https://rsshub.app/jike/topic/556688fae4b00c57d9dd46ee',
|
||||
'category': 7,
|
||||
'name': '今日份的摄影 - 即刻圈子',
|
||||
'website': 'http://finance.sina.com.cn/china/',
|
||||
'description': '爱摄影的即友都在这里~分享原创摄影作品,感受照片背后的共鸣吧! - Powered by RSSHub',
|
||||
'kind': 0,
|
||||
'lastUpdate': int(time.time()),
|
||||
'priority': 10,
|
||||
'pathEntries': '',
|
||||
'httpAuth': '',
|
||||
'error': 0,
|
||||
'ttl': 0,
|
||||
'attributes': '{"curl_params":null,"ssl_verify":null,"timeout":null}',
|
||||
'cache_nbEntries': 0,
|
||||
'cache_nbUnreads': 0
|
||||
}
|
||||
cr.check_and_insert(insert_data)
|
||||
@@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import aiohttp
|
||||
import asyncio
|
||||
|
||||
|
||||
async def fetch(url):
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(url) as response:
|
||||
return await response.text()
|
||||
|
||||
|
||||
async def main():
|
||||
url = 'http://api.ip.cc'
|
||||
content = await fetch(url)
|
||||
print(content)
|
||||
|
||||
|
||||
asyncio.run(main())
|
||||
|
||||
'''
|
||||
Proxy server: 175.99.17.215
|
||||
port: 6011
|
||||
username: lumi-jiege0210
|
||||
password: aaaAAA111
|
||||
'''
|
||||
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import httpx
|
||||
|
||||
|
||||
def get_public_ip():
|
||||
try:
|
||||
# 使用 httpx 发起请求
|
||||
response = httpx.get("https://httpbin.org/ip", timeout=10)
|
||||
response.raise_for_status() # 检查请求是否成功
|
||||
ip_data = response.json()
|
||||
return ip_data["origin"]
|
||||
except httpx.RequestError as e:
|
||||
print(f"An error occurred while obtaining the public IP address.:{e}")
|
||||
exit(1)
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
|
||||
import requests
|
||||
|
||||
# 青龙面板的地址
|
||||
url = "https://auto.erhe.top"
|
||||
|
||||
|
||||
# 登录青龙面板
|
||||
def login():
|
||||
response = requests.post(f"{url}/api/user/login", json={"username": "toor", "password": "!QAZ2wsx+0913"})
|
||||
print(response)
|
||||
if response.status_code != 200:
|
||||
print(response.status_code)
|
||||
print(response.text)
|
||||
exit(0)
|
||||
return response.json()['data']['token']
|
||||
|
||||
|
||||
# 获取任务列表
|
||||
def get_tasks(token):
|
||||
response = requests.get(f"{url}/api/crons", headers={"Authorization": f"Bearer {token}"})
|
||||
return response.json()['data']['data']
|
||||
|
||||
|
||||
# 创建任务
|
||||
def create_task(task_template, token):
|
||||
payload = {
|
||||
"name": task_template["name"],
|
||||
"command": task_template["command"],
|
||||
"schedule": task_template["schedule"],
|
||||
"labels": task_template["labels"]
|
||||
}
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
response = requests.post(f"{url}/api/crons", headers=headers, json=payload)
|
||||
return response.json()
|
||||
|
||||
|
||||
# 创建视图分类
|
||||
def create_view_type(token):
|
||||
view_type_list = ['base', 'spider_common']
|
||||
for view_type in view_type_list:
|
||||
payload = {
|
||||
"name": view_type,
|
||||
"filters": {
|
||||
'property': 'labels',
|
||||
'operation': 'Reg',
|
||||
'value': view_type
|
||||
},
|
||||
'filterRelation': 'and'
|
||||
}
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
response = requests.post(f"{url}/api/crons", headers=headers, json=payload)
|
||||
|
||||
|
||||
# 主逻辑
|
||||
def main():
|
||||
while True:
|
||||
try:
|
||||
token = login()
|
||||
print(f"已连接到 {url}")
|
||||
tasks = get_tasks(token)
|
||||
tasks_names = [task['name'] for task in tasks]
|
||||
if tasks:
|
||||
print("Current tasks name: \n{}, \ntotal: {}".format('\n'.join(tasks_names), str(len(tasks_names))))
|
||||
else:
|
||||
print("Tasks list is empty")
|
||||
|
||||
project_path = '/ql/data/scripts/auto/'
|
||||
base_path = os.path.join(project_path, 'base')
|
||||
spider_path = os.path.join(project_path, 'spider')
|
||||
message_path = os.path.join(project_path, 'message')
|
||||
manual_path = os.path.join(project_path, 'manual')
|
||||
daily_path = os.path.join(project_path, 'daily')
|
||||
tasks_template = [{
|
||||
'base_tasks': [
|
||||
{
|
||||
"name": "每天开始自动创建日志",
|
||||
"command": "python3 {}/base_daily_logs_generate.py".format(base_path),
|
||||
"schedule": "0 0 * * *",
|
||||
"labels": ["base"]
|
||||
},
|
||||
{
|
||||
"name": "每天结束自动发送日志",
|
||||
"command": "python3 {}/base_daily_logs_send.py".format(base_path),
|
||||
"schedule": "58 23 * * *",
|
||||
"labels": ["base"]
|
||||
},
|
||||
{
|
||||
"name": "每天自动删除旧数据",
|
||||
"command": "python3 {}/base_timing_remove_data.py".format(base_path),
|
||||
"schedule": "1 0 * * *",
|
||||
"labels": ["base"]
|
||||
},
|
||||
{
|
||||
"name": "每天新闻汇总,发送到邮箱",
|
||||
"command": "python3 {}/base_news_data_collation.py".format(base_path),
|
||||
"schedule": "0 10 6,12,18 * * *",
|
||||
"labels": ["base"]
|
||||
},
|
||||
{
|
||||
"name": "定时刷新 freshrss 订阅源",
|
||||
"command": "python3 {}/update_feed.py".format(base_path),
|
||||
"schedule": "0 6,22 * * *",
|
||||
"labels": ["base"]
|
||||
}
|
||||
],
|
||||
'spider': [
|
||||
{
|
||||
"name": "自动执行反斗限免爬虫",
|
||||
"command": "python3 {}/news_get_apprcn.py".format(spider_path),
|
||||
"schedule": "0 0 3,6,9,12,15,18,21 * * *",
|
||||
"labels": ["spider"]
|
||||
},
|
||||
{
|
||||
"name": "自动执行chiphell爬虫",
|
||||
"command": "python3 {}/news_get_chiphell.py".format(spider_path),
|
||||
"schedule": "0 0 3,6,9,12,15,18,21 * * *",
|
||||
"labels": ["spider"]
|
||||
},
|
||||
{
|
||||
"name": "自动执行hello_github爬虫",
|
||||
"command": "python3 {}/news_get_hello_github.py".format(spider_path),
|
||||
"schedule": "0 0 3,6,9,12,15,18,21 * * *",
|
||||
"labels": ["spider"]
|
||||
},
|
||||
{
|
||||
"name": "自动执行Anyknew爬虫",
|
||||
"command": "python3 {}/news_get_news.py".format(spider_path),
|
||||
"schedule": "0 0 3,6,9,12,15,18,21 * * *",
|
||||
"labels": ["spider"]
|
||||
},
|
||||
{
|
||||
"name": "自动执行币界网文章爬虫",
|
||||
"command": "python3 {}/spider_web3_coin_world.py".format(spider_path),
|
||||
"schedule": "0 0 3,6,9,12,15,18,21 * * *",
|
||||
"labels": ["spider"]
|
||||
},
|
||||
{
|
||||
"name": "获取 web3 新闻",
|
||||
"command": "python3 {}/spider_web3_news.py".format(spider_path),
|
||||
"schedule": "0 0 3,6,9,12,15,18,21 * * *",
|
||||
"labels": ["spider"]
|
||||
},
|
||||
{
|
||||
"name": "自动执行dlt爬虫",
|
||||
"command": "python3 {}/spider_get_and_check_dlt.py".format(spider_path),
|
||||
"schedule": "30 22 * * 1,3,6",
|
||||
"labels": ["spider"]
|
||||
}
|
||||
],
|
||||
'message_tasks': [
|
||||
{
|
||||
"name": "获取coin实时数据",
|
||||
"command": "python3 {}/message_coin_detail.py".format(message_path),
|
||||
"schedule": "0 * * * *",
|
||||
"labels": ["message"]
|
||||
},
|
||||
{
|
||||
"name": "对比大乐透最新一期数据,匹配已购买号码,发送消息",
|
||||
"command": "python3 {}/message_dlt.py".format(message_path),
|
||||
"schedule": "30 22 * * 1,3,6",
|
||||
"labels": ["message"]
|
||||
},
|
||||
{
|
||||
"name": "获取未来 7 天的天气预报",
|
||||
"command": "python3 {}/message_get_one_week_weather.py".format(message_path),
|
||||
"schedule": "0 0 6,22 * * *",
|
||||
"labels": ["message"]
|
||||
},
|
||||
{
|
||||
"name": "从 freshrss-psql 数据库中读取数据并发送",
|
||||
"command": "python3 {}/message_rss_data_handel.py".format(message_path),
|
||||
"schedule": "30 6,9,12,18,22 * * *",
|
||||
"labels": ["message"]
|
||||
},
|
||||
{
|
||||
"name": "空投任务消息",
|
||||
"command": "python3 {}/message_airdrop_tasks.py".format(message_path),
|
||||
"schedule": "0 8,20 * * *",
|
||||
"labels": ["message"]
|
||||
},
|
||||
{
|
||||
"name": "链捕手快讯消息推送",
|
||||
"command": "python3 {}/message_chaincatcher.py".format(message_path),
|
||||
"schedule": "0 */2 * * *",
|
||||
"labels": ["message"]
|
||||
}
|
||||
],
|
||||
'manual': [
|
||||
{
|
||||
"name": "手动读取rss订阅新闻",
|
||||
"command": "python3 {}/read_news.py".format(manual_path),
|
||||
"schedule": "0 0 1 1 *",
|
||||
"labels": ["manual"]
|
||||
}
|
||||
],
|
||||
'daily': [
|
||||
{
|
||||
"name": "3dos自动签到",
|
||||
"command": "python3 {}/daily_3dos.py".format(daily_path),
|
||||
"schedule": "*/5 * * * *",
|
||||
"labels": ["daily"]
|
||||
}
|
||||
],
|
||||
}]
|
||||
|
||||
for task_template in tasks_template:
|
||||
for task_type, task_list in task_template.items():
|
||||
for task in task_list:
|
||||
task_name = task["name"]
|
||||
if task_name in tasks_names:
|
||||
print("Task {} already exists.".format(task_name))
|
||||
else:
|
||||
result = create_task(task, token)
|
||||
print("Task creation result:", result)
|
||||
|
||||
# 创建所有任务之后, 创建视图分类
|
||||
# create_view_type(token)
|
||||
break # 正常执行完成后退出循环
|
||||
|
||||
except Exception as e:
|
||||
print("An error occurred: ", e)
|
||||
print("Retrying...")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
print('done!')
|
||||
@@ -0,0 +1,58 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import httpx
|
||||
|
||||
|
||||
class GotifyNotifier:
|
||||
def __init__(self, title, message, token_name=''):
|
||||
self.gotify_url = 'https://gotify.erhe.top'
|
||||
self.app_token = self.match_token_name(token_name)
|
||||
self.title = title
|
||||
self.message = message
|
||||
|
||||
def match_token_name(self, name):
|
||||
token_name_dict = {
|
||||
'base': 'A8EVb0Cmxnb2vfk',
|
||||
'coin': 'AgfOJESqDKftBTQ',
|
||||
'dlt': 'A3bqt9Dlbs.fPUb',
|
||||
'AirdropTasksNews': 'Aoe0VKt-kkZnm8d',
|
||||
'weather': 'A9KF--mx_12PjSu',
|
||||
'news': 'AT2QGp_vyCX4akW',
|
||||
'CheckAndRemind': 'Aw7XKE2Ppk7Dgwk',
|
||||
'test': 'A0Xg6ZE5946iBYg',
|
||||
}
|
||||
|
||||
token = token_name_dict.get(name)
|
||||
if token:
|
||||
return token
|
||||
else:
|
||||
return token_name_dict['base']
|
||||
|
||||
def send_message(self):
|
||||
# 构建POST请求的headers
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
# 构建POST请求的body
|
||||
body = {
|
||||
'title': self.title,
|
||||
'message': self.message
|
||||
}
|
||||
|
||||
# 发送POST请求
|
||||
with httpx.Client() as client:
|
||||
response = client.post(
|
||||
url=f"{self.gotify_url}/message?token={self.app_token}",
|
||||
headers=headers,
|
||||
json=body
|
||||
)
|
||||
|
||||
# 或者可以使用 curl
|
||||
# curl -k "https://gotify.erhe.top/message?token=A0Xg6ZE5946iBYg" -F "title=测试发送信息" -F "message=假装有信息,测试发送" -F "priority=5"
|
||||
|
||||
# 检查响应状态码
|
||||
if response.status_code == 200:
|
||||
print('Gotify Message sent successfully!')
|
||||
else:
|
||||
print('Failed to send message:', response.text)
|
||||
Reference in New Issue
Block a user