first commit

This commit is contained in:
jack
2025-11-12 16:36:38 +08:00
commit 756cb1e7d8
13 changed files with 1356 additions and 0 deletions
+98
View File
@@ -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)
+25
View File
@@ -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
'''
+15
View File
@@ -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)
+236
View File
@@ -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!')
+58
View File
@@ -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)