新增了一些功能,修复了一些小问题

This commit is contained in:
zayac 2024-01-20 12:12:08 +08:00
parent 5a70b345a2
commit a0a03b61d0
13 changed files with 341 additions and 12 deletions

0
src/bot/__init__.py Normal file
View File

107
src/bot/bot.py Normal file
View File

@ -0,0 +1,107 @@
import schedule
import telebot
import time
import threading
from telebot import types
from src.core.报数 import text_count_by_telegram_id, get_net_win_by_telegram_id
from src.core.查询存款失败用户 import get_pay_failed_by_telegram_id
from src.entity.user import get_all_users
TOKEN = '6013830443:AAGzq1Tgtr_ZejU7bv0mab14xOwi0_64d0w'
bot = telebot.TeleBot(TOKEN)
def load_registered_users():
"""
Load registered users from the data source.
"""
registered_users = set()
for user in get_all_users():
ids = user.telegram_ids.split(',')
registered_users.update(map(int, ids))
return registered_users
registered_users = load_registered_users()
def schedule_user_updates():
"""
Schedule regular user updates.
"""
schedule.every(1).hour.do(lambda: load_registered_users())
thread = threading.Thread(target=run_schedule)
thread.start()
def run_schedule():
"""
Run scheduled tasks.
"""
while True:
schedule.run_pending()
time.sleep(1)
def is_registered(user_id):
"""
Check if a user is registered.
"""
return user_id in registered_users
def registered_user_only(func):
"""
Decorator to restrict access to registered users only.
"""
def wrapper(message):
if not is_registered(message.from_user.id):
bot.send_message(message.chat.id, "您需要注册才能使用此功能")
return
return func(message)
return wrapper
def create_menu():
"""
Create a reply keyboard menu.
"""
markup = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True)
markup.row_width = 3
markup.add(types.KeyboardButton("报数"),
types.KeyboardButton("负盈利"),
types.KeyboardButton("查失败"))
return markup
@bot.message_handler(commands=['start'])
@registered_user_only
def handle_start(message):
bot.send_message(message.chat.id, "菜单已生成:", reply_markup=create_menu())
@bot.message_handler(commands=['userid'])
def user_id(message):
bot.reply_to(message, f"您的用户 ID 是: {message.from_user.id}")
@bot.message_handler(func=lambda message: True)
@registered_user_only
def handle_message(message):
# 获取用户id
telegram_id = message.from_user.id
response_mapping = {
"报数": text_count_by_telegram_id(telegram_id),
"负盈利": get_net_win_by_telegram_id(telegram_id),
"查失败": get_pay_failed_by_telegram_id(telegram_id)
}
response = response_mapping.get(message.text, "未知选项")
bot.send_message(message.chat.id, response)
schedule_user_updates() # Schedule the user updates
bot.polling() # Start polling

View File

View File

@ -0,0 +1,82 @@
import re
def extract_urls(text):
return re.findall(r'https?://\S+', text)
def read_file(filename):
try:
with open(filename, 'r') as file:
return file.read()
except IOError as e:
print(f"Error reading file {filename}: {e}")
raise
def write_file(filename, content):
try:
with open(filename, 'w') as file:
file.write(content)
except IOError as e:
print(f"Error writing to file {filename}: {e}")
raise
def replace_urls(js_content, url_mapping):
for placeholder, url in url_mapping.items():
js_content = js_content.replace(placeholder, url)
return js_content
def get_hth_url_mapping(urls, is_seo):
if is_seo:
return {
"{{hthApp}}": urls[4],
"{{hthtyApp}}": urls[5],
"{{hthPc}}": urls[0],
"{{hthH5}}": urls[1]
}
else:
return {
"{{hthApp}}": urls[2],
"{{hthtyApp}}": urls[3],
"{{hthPc}}": urls[0],
"{{hthH5}}": urls[1]
}
def change_url(text):
try:
urls = extract_urls(text)
expected_filename = None
if len(urls) >= 10:
js_content = read_file('ky.js.template')
ky_url_mapping = {
"{{kyApp1}}": urls[0],
"{{kyApp2}}": urls[1],
"{{kyPc1}}": urls[2],
"{{kyPc2}}": urls[3],
"{{kyH51}}": urls[4],
"{{kyH52}}": urls[5]
}
updated_content = replace_urls(js_content, ky_url_mapping)
expected_filename = 'ky.js'
write_file(expected_filename, updated_content)
elif len(urls) == 6:
js_content = read_file('hth.js.template')
is_seo = 'SEO' in text
hth_url_mapping = get_hth_url_mapping(urls, is_seo)
updated_content = replace_urls(js_content, hth_url_mapping)
expected_filename = 'hth.js'
write_file(expected_filename, updated_content)
else:
expected_filename = 'unknown.js' # 或者选择适合的默认文件名
# 如果一切顺利,返回 True 和预期的文件名
return True, expected_filename
except Exception as e:
# 如果在过程中发生任何异常,打印错误并返回 False 和预期的文件名
print(f"An error occurred: {e}")
return False, expected_filename if expected_filename else 'unknown.js'

View File

@ -0,0 +1,48 @@
import telebot
from loguru import logger
from src.change_url.change_url import change_url
TOKEN = '6013830443:AAGzq1Tgtr_ZejU7bv0mab14xOwi0_64d0w'
bot = telebot.TeleBot(TOKEN)
ky = ['技术客服域名值班']
hth = ['YYZBH②拒绝私聊', '3-信息同步频道']
@bot.message_handler(func=lambda message: message.forward_date is not None)
def handle_forwarded_message(message):
# if message.forward_from:
# # 直接获取转发来源用户信息
# user = message.forward_from
# user_id = user.id
# user_first_name = user.first_name
# user_username = user.username if user.username else "No username"
#
# response = f"消息转发自 ID: {user_id}, 名字: {user_first_name}, 用户名: {user_username}"
# logger.debug(response)
# elif message.forward_from_chat:
# # 获取转发来源频道信息
# channel = message.forward_from_chat
# channel_id = channel.id
# channel_title = channel.title
#
# response = f"消息转发自频道 ID: {channel_id}, 名称: {channel_title}"
# logger.debug(response)
# else:
# # 处理无法识别的转发
# user_info = message.forward_origin
# response = f"这是一条转发的消息。{user_info}"
try:
res, filename = change_url(message.text)
if res:
msg = f'{filename}修改成功'
else:
msg = f'{filename}修改失败'
except Exception as e:
logger.error(f"An error occurred in change_url: {e}")
msg = "处理您的请求时发生错误。"
bot.reply_to(message, msg)
bot.polling()

17
src/change_url/hth.js Normal file
View File

@ -0,0 +1,17 @@
const hthCode = '3016341'
var hth_link = {
hthApp: '{{hthApp}}/?i_code='+hthCode,
hthtyApp: '{{hthtyApp}}/?i_code='+hthCode,
hthPc: '{{hthPc}}/register/?i_code='+hthCode,
hthH5: '{{hthH5}}/entry/register?i_code='+hthCode,
}
function visit_hth(key) {
window['open'](hth_link[key]);
try {
LA.track(key);
} catch (error) {
console.error('An error occurred while tracking:', error);
}
}

20
src/change_url/ky.js Normal file
View File

@ -0,0 +1,20 @@
const kyCode = '97238304'
var ky_link = {
kyApp1: '{{kyApp1}}/?i_code='+kyCode,
kyApp2: '{{kyApp2}}/?i_code='+kyCode,
kyPc1: '{{kyPc1}}/register/?i_code='+kyCode,
kyPc2: '{{kyPc2}}/register?i_code='+kyCode,
kyH51: '{{kyH51}}/entry/register?i_code='+kyCode,
kyH52: '{{kyH52}}/entry/register?i_code='+kyCode
}
function visit_ky(key) {
window['open'](ky_link[key]);
try {
LA.track(key);
} catch (error) {
console.error('An error occurred while tracking:', error);
}
}

View File

@ -2,7 +2,7 @@ import time
import schedule
from loguru import logger
from 报数 import get_net_win, text_count_by_user
from 报数 import get_net_win_by_user, text_count_by_user
from 查询存款失败用户 import get_pay_failed_by_user
from src.core.constant import BOT_TOKEN, COUNT_GROUP_ID
@ -27,7 +27,7 @@ def query_failed_deposit(username, password):
def query_net_win(username, password) -> None:
logger.info(f'Running query_net_win for username: {username}')
user = get_user_by_username_and_password(username, password)
send_message(BOT_TOKEN, COUNT_GROUP_ID, get_net_win(user))
send_message(BOT_TOKEN, COUNT_GROUP_ID, get_net_win_by_user(user))
logger.info(f'Finished query_net_win for username: {username}')

View File

@ -5,10 +5,11 @@ import pyperclip
from src import logger
from src.core import util
from src.core.util import get_curr_day
from src.entity.database import db
from src.entity.finance import Finance, get_finance
from src.entity.user import User
from src.entity.visual_list import VisualInfo, get_curr_data, get_visual_list
from src.entity.user import User, get_user_by_telegram_id
from src.entity.visual_list import VisualInfo, get_visual_list
def get_statics(account, date=util.get_curr_day()) -> VisualInfo:
@ -38,6 +39,16 @@ def text_count_by_user(user: User, date: str) -> str:
return text
def text_count_by_telegram_id(telegram_id: int) -> str:
visual_list = count_by_user(get_user_by_telegram_id(telegram_id), get_curr_day())
text = '\n\n'.join(
f'{result.agentName}\n注册:{result.isNew}\n首存:{result.firstCount}\n日活:{int(result.countBets)}\n流水:{int(result.bets)}'
for result in visual_list
)
logger.info(f'Generated text: {text}')
return text
def get_finances_by_user(user: User, date) -> List[Finance]:
accounts = user.accounts
start_date = util.get_first_day_by_str(date)
@ -46,8 +57,16 @@ def get_finances_by_user(user: User, date) -> List[Finance]:
return [future.result() for future in futures]
def get_net_win(user: User, date: str) -> str:
def get_net_win_by_user(user: User, date: str) -> str:
finances = get_finances_by_user(user, date)
finance_strings = [f"{finance.name}: {finance.netProfit}" for finance in finances]
logger.info(f'Finance strings: {finance_strings}')
return '\n'.join(finance_strings)
def get_net_win_by_telegram_id(telegram_id: int) -> str:
user = get_user_by_telegram_id(telegram_id)
finances = get_finances_by_user(user, get_curr_day())
finance_strings = [f"{finance.name}: {finance.netProfit}" for finance in finances]
logger.info(f'Finance strings: {finance_strings}')
return '\n'.join(finance_strings)

View File

@ -5,10 +5,10 @@ from loguru import logger
from src.core import api_request
from src.core.constant import PAY_RECORD_LIST_URL
from src.core.util import get_first_day_month
from src.core.util import get_first_day_month, get_curr_day
from src.entity.account import Account
from src.entity.member import MemberList, get_member_list
from src.entity.user import User
from src.entity.user import User, get_user_by_telegram_id
def get_pay_record_list(account: Account, date: str) -> Dict[str, List[str]]:
@ -80,3 +80,24 @@ def get_pay_failed_by_user(user: User, date: str) -> Optional[str]:
logger.info(text)
return text
def get_pay_failed_by_telegram_id(telegram_id: int) -> Optional[str]:
user = get_user_by_telegram_id(telegram_id)
with ThreadPoolExecutor(max_workers=len(user.accounts)) as executor:
futures = [executor.submit(get_pay_record_list, account, get_curr_day()) for account in user.accounts]
# 使用列表推导式构建结果字符串
text_lines = [
"{}\n{}".format(res['name'], '\n'.join(res['names']))
for future in futures if (res := future.result())['names']
]
text = '\n'.join(text_lines)
if not text:
logger.info('无存款失败用户')
return '无存款失败用户'
logger.info(text)
return text

View File

@ -1,7 +1,8 @@
from dataclasses import dataclass
from typing import List
from cachetools import cached, TTLCache
from sqlalchemy import String
from sqlalchemy import String, func
from sqlalchemy.dialects.mssql import TINYINT
from sqlalchemy.orm import Mapped, mapped_column, relationship
@ -32,3 +33,17 @@ def get_user_by_username_and_password(username: str, password: str) -> User:
user = session.query(User).filter(
User.username == username and User.password == password and User.status == 1).one()
return user
def get_all_users():
with db.Session() as session:
users = session.query(User).filter(User.status == 1).all()
return users
@cached(TTLCache(maxsize=100, ttl=3600))
def get_user_by_telegram_id(telegram_id: int) -> User:
with db.Session() as session:
user = session.query(User).filter(
User.status == 1 and func.find_in_set(telegram_id, User.telegram_ids) > 0).one()
return user

View File

@ -10,7 +10,7 @@ from PyQt6.QtWidgets import (QApplication, QCheckBox, QDateEdit, QHBoxLayout,
QTabWidget, QTextEdit, QVBoxLayout, QWidget, QMessageBox, QSystemTrayIcon, QMenu)
from src.core.message_client import send_message
from src.core.util import convert_data,resource_path
from src.core.util import convert_data, resource_path
from src.entity.member import get_today_new_member_list
from src.entity.pay_record import get_latest_deposit_user
from src.entity.user import get_user_by_username_and_password
@ -343,7 +343,7 @@ class Application(QMainWindow):
def handle_data_change(self, table, cell_data, col, account_username, notifications):
if table.rowCount() > 1 and col != 0:
old_data_str = table.item(table.rowCount()-1, col).text()
old_data_str = table.item(table.rowCount() - 2, col).text()
old_data = convert_data(old_data_str)
new_data = convert_data(cell_data)

View File

@ -3,7 +3,7 @@ import time
from PyQt6.QtCore import QObject, QRunnable, QThread, pyqtSignal
from src.core.salary import get_salary
from src.core.报数 import get_net_win, text_count_by_user
from src.core.报数 import get_net_win_by_user, text_count_by_user
from src.core.查询存款失败用户 import get_pay_failed_by_user
from src.entity.banner_info import get_banner_info
@ -54,7 +54,7 @@ class ButtonTask(QRunnable):
auto_clipboard = True
notify = True
elif self.query_type == '负盈利':
result = get_net_win(self.user, self.selected_date_str)
result = get_net_win_by_user(self.user, self.selected_date_str)
elif self.query_type == '薪资':
result = get_salary(self.user, self.selected_date_str)