mirror of
https://github.com/WhaleFell/SMSBoom.git
synced 2026-05-11 00:40:03 +08:00
🦄 refactor: 优化项目结构,优化日志显示。
This commit is contained in:
73
smsboom.py
73
smsboom.py
@@ -1,26 +1,19 @@
|
|||||||
# encoding=utf8
|
# encoding=utf8
|
||||||
# 短信测压主程序
|
# 短信测压主程序
|
||||||
|
import json
|
||||||
import pathlib
|
import pathlib
|
||||||
import sys
|
import sys
|
||||||
from typing import List, Union
|
|
||||||
import click
|
|
||||||
import json
|
|
||||||
import httpx
|
|
||||||
from loguru import logger
|
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
|
||||||
import time
|
import time
|
||||||
import sys
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
from typing import List, Union
|
||||||
|
|
||||||
from utils import API, default_header
|
import click
|
||||||
|
import httpx
|
||||||
|
|
||||||
# logger config
|
from utils import default_header
|
||||||
logger.remove()
|
from utils.log import logger
|
||||||
logger.add(
|
from utils.models import API
|
||||||
sink=sys.stdout,
|
from utils.req import reqFunc
|
||||||
format="<green>{time:YYYY-MM-DD at HH:mm:ss}</green> - <level>{level}</level> - <level>{message}</level>",
|
|
||||||
colorize=True,
|
|
||||||
backtrace=True
|
|
||||||
)
|
|
||||||
|
|
||||||
# current directory
|
# current directory
|
||||||
path = pathlib.Path(__file__).parent
|
path = pathlib.Path(__file__).parent
|
||||||
@@ -70,38 +63,6 @@ def load_getapi() -> list:
|
|||||||
# return None
|
# return None
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
def reqAPI(api: API, client: httpx.Client) -> httpx.Response:
|
|
||||||
if isinstance(api.data, dict):
|
|
||||||
resp = client.request(method=api.method, json=api.data,
|
|
||||||
headers=api.header, url=api.url)
|
|
||||||
else:
|
|
||||||
resp = client.request(method=api.method, data=api.data,
|
|
||||||
headers=api.header, url=api.url)
|
|
||||||
return resp
|
|
||||||
|
|
||||||
|
|
||||||
def req(api: Union[API, str], phone: tuple):
|
|
||||||
"""请求接口方法"""
|
|
||||||
# 多手机号支持
|
|
||||||
if isinstance(phone, tuple):
|
|
||||||
phone_lst = [_ for _ in phone]
|
|
||||||
else:
|
|
||||||
phone_lst = [phone]
|
|
||||||
|
|
||||||
with httpx.Client(headers=default_header, verify=False) as client:
|
|
||||||
for ph in phone_lst:
|
|
||||||
try:
|
|
||||||
if isinstance(api, API):
|
|
||||||
api = api.handle_API(ph)
|
|
||||||
resp = reqAPI(api, client)
|
|
||||||
logger.info(f"{api.desc}-{resp.text[:30]}")
|
|
||||||
else:
|
|
||||||
api = api.replace("[phone]", ph)
|
|
||||||
resp = client.get(url=api, headers=default_header)
|
|
||||||
logger.info(f"GETAPI接口-{resp.text[:30]}")
|
|
||||||
except httpx.HTTPError as why:
|
|
||||||
logger.error(f"请求失败{why}")
|
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
@click.option("--thread", "-t", help="线程数(默认64)", default=64)
|
@click.option("--thread", "-t", help="线程数(默认64)", default=64)
|
||||||
@@ -126,16 +87,16 @@ def run(thread: int, phone: Union[str, tuple], interval: int, super: bool = Fals
|
|||||||
i += 1
|
i += 1
|
||||||
logger.success(f"第{i}波轰炸开始!")
|
logger.success(f"第{i}波轰炸开始!")
|
||||||
for api in _api:
|
for api in _api:
|
||||||
pool.submit(req, api, phone)
|
pool.submit(reqFunc, api, phone)
|
||||||
for api_get in _api_get:
|
for api_get in _api_get:
|
||||||
pool.submit(req, api_get, phone)
|
pool.submit(reqFunc, api_get, phone)
|
||||||
logger.success(f"第{i}波轰炸提交结束!休息{interval}s.....")
|
logger.success(f"第{i}波轰炸提交结束!休息{interval}s.....")
|
||||||
time.sleep(interval)
|
time.sleep(interval)
|
||||||
else:
|
else:
|
||||||
for api in _api:
|
for api in _api:
|
||||||
pool.submit(req, api, phone)
|
pool.submit(reqFunc, api, phone)
|
||||||
for api_get in _api_get:
|
for api_get in _api_get:
|
||||||
pool.submit(req, api_get, phone)
|
pool.submit(reqFunc, api_get, phone)
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
@@ -147,9 +108,11 @@ def update():
|
|||||||
try:
|
try:
|
||||||
with httpx.Client(verify=False, timeout=10) as client:
|
with httpx.Client(verify=False, timeout=10) as client:
|
||||||
# print(API_json_url)
|
# print(API_json_url)
|
||||||
GETAPI_json = client.get(GETAPI_json_url, headers=default_header).content.decode(encoding="utf8")
|
GETAPI_json = client.get(
|
||||||
api_json = client.get(API_json_url, headers=default_header).content.decode(encoding="utf8")
|
GETAPI_json_url, headers=default_header).content.decode(encoding="utf8")
|
||||||
|
api_json = client.get(
|
||||||
|
API_json_url, headers=default_header).content.decode(encoding="utf8")
|
||||||
|
|
||||||
except Exception as why:
|
except Exception as why:
|
||||||
logger.error(f"拉取更新失败:{why}请关闭所有代理软件多尝试几次!")
|
logger.error(f"拉取更新失败:{why}请关闭所有代理软件多尝试几次!")
|
||||||
else:
|
else:
|
||||||
|
|||||||
59
utils.py
59
utils.py
@@ -12,65 +12,6 @@ default_header = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Sql(object):
|
|
||||||
"""处理SQL数据"""
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
'''初始化数据库'''
|
|
||||||
# 数据库路径
|
|
||||||
db_path = Path.cwd().joinpath("api.db")
|
|
||||||
# 连接数据库,不检查是否在同一个路径.
|
|
||||||
self.client = sqlite3.connect(
|
|
||||||
db_path, timeout=6, check_same_thread=False)
|
|
||||||
self.cursor = self.client.cursor()
|
|
||||||
self.newTable()
|
|
||||||
|
|
||||||
def newTable(self):
|
|
||||||
'''初始化表结构'''
|
|
||||||
sql = '''
|
|
||||||
CREATE TABLE IF NOT EXISTS API200 (
|
|
||||||
id INT NULL,
|
|
||||||
url TEXT NOT NULL,
|
|
||||||
primary key (url)
|
|
||||||
);
|
|
||||||
'''
|
|
||||||
self.cursor.execute(sql)
|
|
||||||
self.client.commit()
|
|
||||||
|
|
||||||
def update(self, url):
|
|
||||||
'''插入数据'''
|
|
||||||
sql = '''
|
|
||||||
INSERT INTO API200 (ID,url) VALUES (null,?)
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
self.cursor.execute(sql, (url,))
|
|
||||||
self.client.commit()
|
|
||||||
return True
|
|
||||||
except sqlite3.IntegrityError:
|
|
||||||
# print(f"{url} 数据重复!")
|
|
||||||
return False
|
|
||||||
|
|
||||||
def select(self) -> list:
|
|
||||||
'''获取所有接口'''
|
|
||||||
sql = '''
|
|
||||||
SELECT url FROM API200;
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
self.cursor.execute(sql)
|
|
||||||
result = self.cursor.fetchall()
|
|
||||||
urls = []
|
|
||||||
for url in result:
|
|
||||||
urls.append(url[0])
|
|
||||||
return urls
|
|
||||||
except Exception as e:
|
|
||||||
print('读取出现错误!', e)
|
|
||||||
|
|
||||||
def __del__(self) -> None:
|
|
||||||
'''对象被删除时执行的函数'''
|
|
||||||
print(f"共改变{self.client.total_changes}条数据!,正在关闭数据库连接......")
|
|
||||||
self.client.close()
|
|
||||||
|
|
||||||
|
|
||||||
class API(BaseModel):
|
class API(BaseModel):
|
||||||
"""处理自定义 API 数据"""
|
"""处理自定义 API 数据"""
|
||||||
desc: str = "Default"
|
desc: str = "Default"
|
||||||
|
|||||||
3
utils/__init__.py
Normal file
3
utils/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
default_header = {
|
||||||
|
"User-Agent": "Mozilla/5.0 (Linux; U; Android 10; zh-cn; Mi 10 Build/QKQ1.191117.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/79.0.3945.147 Mobile Safari/537.36 XiaoMi/MiuiBrowser/13.5.40"
|
||||||
|
}
|
||||||
44
utils/log.py
Normal file
44
utils/log.py
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# encoding=utf8
|
||||||
|
# 日志模块
|
||||||
|
from loguru import logger
|
||||||
|
import pathlib
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
# 终端日志输出格式
|
||||||
|
stdout_fmt = '{level.icon} <cyan>{time:HH:mm:ss,SSS}</cyan> ' \
|
||||||
|
'[<level>{level}</level>] ' \
|
||||||
|
'<cyan>{thread.name}</cyan> ' \
|
||||||
|
'<blue>{module}</blue>:<cyan>{line}</cyan> - ' \
|
||||||
|
'<level>{message}</level>'
|
||||||
|
|
||||||
|
# 日志文件记录格式
|
||||||
|
# logfile_fmt = '<light-green>{time:YYYY-MM-DD HH:mm:ss,SSS}</light-green> ' \
|
||||||
|
# '[<level>{level: <5}</level>] ' \
|
||||||
|
# '<cyan>{process.name}({process.id})</cyan>:' \
|
||||||
|
# '<cyan>{thread.name: <10}({thread.id: <5})</cyan> | ' \
|
||||||
|
# '<blue>{module}</blue>.<blue>{function}</blue>:' \
|
||||||
|
# '<blue>{line}</blue> - <level>{message}</level>'
|
||||||
|
|
||||||
|
logfile_fmt = '<light-green>{time:YYYY-MM-DD HH:mm:ss,SSS}</light-green> ' \
|
||||||
|
'[<level>{level}</level>] ' \
|
||||||
|
'<blue>{module}</blue>.<blue>{function}</blue>:' \
|
||||||
|
'<blue>{line}</blue> - <level>{message}</level>'
|
||||||
|
|
||||||
|
log_pathDir = pathlib.Path(os.getcwd()).resolve().joinpath('logs')
|
||||||
|
if not log_pathDir.is_dir():
|
||||||
|
log_pathDir.mkdir()
|
||||||
|
log_path = log_pathDir.joinpath('run.log').resolve()
|
||||||
|
|
||||||
|
logger.remove()
|
||||||
|
|
||||||
|
if not os.environ.get('PYTHONIOENCODING'): # 设置编码
|
||||||
|
os.environ['PYTHONIOENCODING'] = 'utf-8'
|
||||||
|
|
||||||
|
logger.add(sys.stderr, level='INFO', format=stdout_fmt, enqueue=True)
|
||||||
|
# 输出到文件
|
||||||
|
# logger.add(log_path, level='DEBUG', format=logfile_fmt,
|
||||||
|
# enqueue=True, encoding='utf-8')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
logger.info("test")
|
||||||
53
utils/models.py
Normal file
53
utils/models.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# encoding=utf8
|
||||||
|
# 一些模型
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from typing import Union, Optional
|
||||||
|
from datetime import datetime
|
||||||
|
import json
|
||||||
|
from utils import default_header
|
||||||
|
|
||||||
|
class API(BaseModel):
|
||||||
|
"""处理自定义 API 数据"""
|
||||||
|
desc: str = "Default"
|
||||||
|
url: str
|
||||||
|
method: str = "GET"
|
||||||
|
header: Optional[Union[str, dict]] = default_header
|
||||||
|
data: Optional[Union[str, dict]]
|
||||||
|
|
||||||
|
def replace_data(self, content: Union[str, dict], phone: str) -> str:
|
||||||
|
# 统一转换成 str 再替换. ' -> "
|
||||||
|
if phone:
|
||||||
|
content = str(content).replace("[phone]", phone).replace(
|
||||||
|
"[timestamp]", self.timestamp_new()).replace("'", '"')
|
||||||
|
|
||||||
|
# 尝试 json 化
|
||||||
|
try:
|
||||||
|
return json.loads(content.replace("'", '"'))
|
||||||
|
except:
|
||||||
|
return content
|
||||||
|
|
||||||
|
def timestamp_new(self) -> str:
|
||||||
|
"""返回整数字符串时间戳"""
|
||||||
|
return str(int(datetime.now().timestamp()))
|
||||||
|
|
||||||
|
def handle_API(self, phone: str=None):
|
||||||
|
""" 传入手机号处理 API
|
||||||
|
:param API: one API basemodel
|
||||||
|
:return: API basemodel
|
||||||
|
"""
|
||||||
|
# 仅仅当传入 phone 参数时添加 Referer
|
||||||
|
# fix: 这段代码很有问题.......
|
||||||
|
if phone:
|
||||||
|
# 进入的 header 是个字符串
|
||||||
|
if self.header == "":
|
||||||
|
self.header = {}
|
||||||
|
self.header['Referer'] = self.url # 增加 Referer
|
||||||
|
|
||||||
|
self.header = self.replace_data(self.header, phone)
|
||||||
|
if not self.header.get('Referer'):
|
||||||
|
self.header['Referer'] = self.url # 增加 Referer
|
||||||
|
|
||||||
|
self.data = self.replace_data(self.data, phone)
|
||||||
|
self.url = self.replace_data(self.url, phone)
|
||||||
|
# print(self)
|
||||||
|
return self
|
||||||
40
utils/req.py
Normal file
40
utils/req.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# encoding=utf8
|
||||||
|
# 请求的方法
|
||||||
|
import httpx
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
from utils import default_header
|
||||||
|
from utils.models import API
|
||||||
|
from utils.log import logger
|
||||||
|
|
||||||
|
def reqAPI(api: API, client: httpx.Client) -> httpx.Response:
|
||||||
|
if isinstance(api.data, dict):
|
||||||
|
resp = client.request(method=api.method, json=api.data,
|
||||||
|
headers=api.header, url=api.url)
|
||||||
|
else:
|
||||||
|
resp = client.request(method=api.method, data=api.data,
|
||||||
|
headers=api.header, url=api.url)
|
||||||
|
return resp
|
||||||
|
|
||||||
|
|
||||||
|
def reqFunc(api: Union[API, str], phone: tuple):
|
||||||
|
"""请求接口方法"""
|
||||||
|
# 多手机号支持
|
||||||
|
if isinstance(phone, tuple):
|
||||||
|
phone_lst = [_ for _ in phone]
|
||||||
|
else:
|
||||||
|
phone_lst = [phone]
|
||||||
|
|
||||||
|
with httpx.Client(headers=default_header, verify=False) as client:
|
||||||
|
for ph in phone_lst:
|
||||||
|
try:
|
||||||
|
if isinstance(api, API):
|
||||||
|
api = api.handle_API(ph)
|
||||||
|
resp = reqAPI(api, client)
|
||||||
|
logger.info(f"{api.desc}-{resp.text[:30]}")
|
||||||
|
else:
|
||||||
|
api = api.replace("[phone]", ph)
|
||||||
|
resp = client.get(url=api, headers=default_header)
|
||||||
|
logger.info(f"GETAPI接口-{resp.text[:30]}")
|
||||||
|
except httpx.HTTPError as why:
|
||||||
|
logger.error(f"请求失败{why}")
|
||||||
63
utils/sql.py
Normal file
63
utils/sql.py
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# encoding=utf8
|
||||||
|
# 读写sqlite数据库
|
||||||
|
from pathlib import Path
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
class Sql(object):
|
||||||
|
"""处理SQL数据"""
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
'''初始化数据库'''
|
||||||
|
# 数据库路径
|
||||||
|
db_path = Path.cwd().joinpath("api.db")
|
||||||
|
# 连接数据库,不检查是否在同一个线程.
|
||||||
|
self.client = sqlite3.connect(
|
||||||
|
db_path, timeout=6, check_same_thread=False)
|
||||||
|
self.cursor = self.client.cursor()
|
||||||
|
self.newTable()
|
||||||
|
|
||||||
|
def newTable(self):
|
||||||
|
'''初始化表结构'''
|
||||||
|
sql = '''
|
||||||
|
CREATE TABLE IF NOT EXISTS API200 (
|
||||||
|
id INT NULL,
|
||||||
|
url TEXT NOT NULL,
|
||||||
|
primary key (url)
|
||||||
|
);
|
||||||
|
'''
|
||||||
|
self.cursor.execute(sql)
|
||||||
|
self.client.commit()
|
||||||
|
|
||||||
|
def update(self, url):
|
||||||
|
'''插入数据'''
|
||||||
|
sql = '''
|
||||||
|
INSERT INTO API200 (ID,url) VALUES (null,?)
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
self.cursor.execute(sql, (url,))
|
||||||
|
self.client.commit()
|
||||||
|
return True
|
||||||
|
except sqlite3.IntegrityError:
|
||||||
|
# print(f"{url} 数据重复!")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def select(self) -> list:
|
||||||
|
'''获取所有接口'''
|
||||||
|
sql = '''
|
||||||
|
SELECT url FROM API200;
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
self.cursor.execute(sql)
|
||||||
|
result = self.cursor.fetchall()
|
||||||
|
urls = []
|
||||||
|
for url in result:
|
||||||
|
urls.append(url[0])
|
||||||
|
return urls
|
||||||
|
except Exception as e:
|
||||||
|
print('读取出现错误!', e)
|
||||||
|
|
||||||
|
def __del__(self) -> None:
|
||||||
|
'''对象被删除时执行的函数'''
|
||||||
|
print(f"共改变{self.client.total_changes}条数据!,正在关闭数据库连接......")
|
||||||
|
self.client.close()
|
||||||
|
|
||||||
Reference in New Issue
Block a user