|
|
@@ -0,0 +1,213 @@
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
+
|
|
|
+from odoo import models, fields
|
|
|
+from httpx import Client
|
|
|
+from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
|
+
|
|
|
+from odoo.exceptions import UserError
|
|
|
+
|
|
|
+
|
|
|
+class Daily3dos(models.Model):
|
|
|
+ _name = 'daily.3dos'
|
|
|
+ _description = 'Daily 3dos'
|
|
|
+
|
|
|
+ name = fields.Char(string='Name', default=fields.datetime.now())
|
|
|
+
|
|
|
+ state = fields.Selection([
|
|
|
+ ('draft', 'Draft'),
|
|
|
+ ('done', 'Done'),
|
|
|
+ ], string='State', default='draft')
|
|
|
+
|
|
|
+ daily_3dos_line_ids = fields.One2many('daily.3dos.line', 'daily_3dos_id', string='Daily 3dos Lines')
|
|
|
+
|
|
|
+ def btn_execute(self):
|
|
|
+ # 获取所有3DOS账户配置
|
|
|
+ if self.daily_3dos_line_ids:
|
|
|
+ all_3dos_account = []
|
|
|
+ for line in self.daily_3dos_line_ids:
|
|
|
+ if line.line_state != 'done':
|
|
|
+ all_3dos_account.append(
|
|
|
+ self.env['daily.3dos.config'].search([('account', '=', line.account)], limit=1))
|
|
|
+ else:
|
|
|
+ all_3dos_account = self.env['daily.3dos.config'].search([('activate', '=', True)])
|
|
|
+
|
|
|
+ if not all_3dos_account:
|
|
|
+ raise UserError('先设置3dos账号!')
|
|
|
+
|
|
|
+ # 创建字典, 记录每个账号的领取结果
|
|
|
+ save_data = {}
|
|
|
+
|
|
|
+ with ThreadPoolExecutor(max_workers=len(all_3dos_account)) as executor:
|
|
|
+ futures = []
|
|
|
+ for account in all_3dos_account:
|
|
|
+ email, password = account.account, account.password
|
|
|
+ futures.append(executor.submit(self.account_handle, email, password))
|
|
|
+
|
|
|
+ for future in as_completed(futures):
|
|
|
+ result = future.result()
|
|
|
+ if result:
|
|
|
+ save_data.update(result)
|
|
|
+
|
|
|
+ for email, data in save_data.items():
|
|
|
+ message, state = data
|
|
|
+ # 判定 line 里面是否 name 是否 等于 email, 如果是, 更新当条数据, 如果不是, 创建数据
|
|
|
+ email_exists = any(email == line.account for line in self.daily_3dos_line_ids)
|
|
|
+ if email_exists:
|
|
|
+ line = self.env['daily.3dos.line'].search([('account', '=', email), ('daily_3dos_id', '=', self.id)])
|
|
|
+ line.write({
|
|
|
+ 'line_state': state,
|
|
|
+ 'message': message,
|
|
|
+ })
|
|
|
+ else:
|
|
|
+ self.env['daily.3dos.line'].create({
|
|
|
+ 'daily_3dos_id': self.id,
|
|
|
+ 'line_state': state,
|
|
|
+ 'account': email,
|
|
|
+ 'message': message,
|
|
|
+ })
|
|
|
+
|
|
|
+ return {
|
|
|
+ 'type': 'ir.actions.client',
|
|
|
+ 'tag': 'display_notification',
|
|
|
+ 'params': {
|
|
|
+ 'title': '提示',
|
|
|
+ 'message': '操作成功!',
|
|
|
+ 'sticky': False,
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ def account_handle(self, email, password):
|
|
|
+ save_data = {}
|
|
|
+ email = email
|
|
|
+ password = password
|
|
|
+
|
|
|
+ client = Client(proxy="http://127.0.0.1:7890")
|
|
|
+
|
|
|
+ login_url = "https://api.dashboard.3dos.io/api/auth/login"
|
|
|
+ login_headers = {
|
|
|
+ "Accept": "application/json, text/plain, */*",
|
|
|
+ "Accept-Encoding": "gzip, deflate, br, zstd",
|
|
|
+ "Accept-Language": "zh-CN,zh;q=0.9",
|
|
|
+ "Content-Type": "application/json",
|
|
|
+ "Origin": "https://dashboard.3dos.io",
|
|
|
+ "Priority": "u=1, i",
|
|
|
+ "Referer": "https://dashboard.3dos.io/",
|
|
|
+ "Sec-CH-UA": '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
|
|
|
+ "Sec-CH-UA-Mobile": "?0",
|
|
|
+ "Sec-CH-UA-Platform": '"Windows"',
|
|
|
+ "Sec-Fetch-Dest": "empty",
|
|
|
+ "Sec-Fetch-Mode": "cors",
|
|
|
+ "Sec-Fetch-Site": "same-site",
|
|
|
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
|
|
|
+ }
|
|
|
+ login_payload = {
|
|
|
+ "email": email,
|
|
|
+ "password": password
|
|
|
+ }
|
|
|
+
|
|
|
+ try:
|
|
|
+ login_response = client.post(login_url, json=login_payload, headers=login_headers)
|
|
|
+ except Exception as e:
|
|
|
+ save_data[email] = [str(f"登录请求失败:{e}"), 'error']
|
|
|
+ return save_data
|
|
|
+
|
|
|
+ if login_response.status_code == 200:
|
|
|
+ login_data = login_response.json()
|
|
|
+ data = login_data.get("data")
|
|
|
+ token = data.get("access_token") or data.get("token")
|
|
|
+ token_type = data.get("token_type")
|
|
|
+ if not token or not token_type:
|
|
|
+ save_data[email] = [f"登录响应中未找到 Token 或 Token 类型!", 'error']
|
|
|
+ return save_data
|
|
|
+
|
|
|
+ authorization_header = f"{token_type} {token}"
|
|
|
+ else:
|
|
|
+ save_data[email] = [f"登录失败!状态码:{login_response.status_code}", 'error']
|
|
|
+ return save_data
|
|
|
+
|
|
|
+ options_url = "https://api.dashboard.3dos.io/api/claim-reward"
|
|
|
+ options_headers = {
|
|
|
+ "Accept": "*/*",
|
|
|
+ "Accept-Encoding": "gzip, deflate, br, zstd",
|
|
|
+ "Accept-Language": "zh-CN,zh;q=0.9",
|
|
|
+ "Access-Control-Request-Headers": "authorization,cache-control,content-type,expires,pragma",
|
|
|
+ "Access-Control-Request-Method": "POST",
|
|
|
+ "Origin": "https://dashboard.3dos.io",
|
|
|
+ "Priority": "u=1, i",
|
|
|
+ "Referer": "https://dashboard.3dos.io/",
|
|
|
+ "Sec-Fetch-Dest": "empty",
|
|
|
+ "Sec-Fetch-Mode": "cors",
|
|
|
+ "Sec-Fetch-Site": "same-site",
|
|
|
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
|
|
|
+ }
|
|
|
+
|
|
|
+ try:
|
|
|
+ options_response = client.options(options_url, headers=options_headers)
|
|
|
+ except Exception as e:
|
|
|
+ save_data[email] = [f"OPTIONS 请求失败:{e}", 'error']
|
|
|
+ return save_data
|
|
|
+
|
|
|
+ claim_url = "https://api.dashboard.3dos.io/api/claim-reward"
|
|
|
+ claim_headers = {
|
|
|
+ "Accept": "application/json, text/plain, */*",
|
|
|
+ "Authorization": authorization_header,
|
|
|
+ "Cache-Control": "no-cache",
|
|
|
+ "Content-Type": "application/json",
|
|
|
+ "Expires": "0",
|
|
|
+ "Origin": "https://dashboard.3dos.io",
|
|
|
+ "Pragma": "no-cache",
|
|
|
+ "Priority": "u=1, i",
|
|
|
+ "Referer": "https://dashboard.3dos.io/",
|
|
|
+ "Sec-CH-UA": '"Chromium";v="130", "Google Chrome";v="130", "Not?A_Brand";v="99"',
|
|
|
+ "Sec-CH-UA-Mobile": "?0",
|
|
|
+ "Sec-CH-UA-Platform": '"Windows"',
|
|
|
+ "Sec-Fetch-Dest": "empty",
|
|
|
+ "Sec-Fetch-Mode": "cors",
|
|
|
+ "Sec-Fetch-Site": "same-site",
|
|
|
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
|
|
|
+ }
|
|
|
+ claim_payload = {
|
|
|
+ "id": "daily-reward-api"
|
|
|
+ }
|
|
|
+
|
|
|
+ try:
|
|
|
+ claim_response = client.post(claim_url, json=claim_payload, headers=claim_headers)
|
|
|
+ except Exception as e:
|
|
|
+ save_data[email] = [f"claim-reward 请求失败:{e}", 'error']
|
|
|
+ return save_data
|
|
|
+
|
|
|
+ tmp_message = claim_response.json()
|
|
|
+ message = tmp_message.get("message")
|
|
|
+
|
|
|
+ if claim_response.status_code not in [200, 429]:
|
|
|
+ save_data[email] = [f"claim 报错: {message}, 状态码{claim_response.status_code}", 'error']
|
|
|
+ return save_data
|
|
|
+
|
|
|
+ save_data[email] = [message, 'done']
|
|
|
+ print(f"{email}: {message}")
|
|
|
+ return save_data
|
|
|
+
|
|
|
+
|
|
|
+class Daily3dosLine(models.Model):
|
|
|
+ _name = 'daily.3dos.line'
|
|
|
+ _description = 'Daily 3dos Line'
|
|
|
+
|
|
|
+ daily_3dos_id = fields.Many2one('daily.3dos', string='Daily 3dos')
|
|
|
+ line_state = fields.Selection([
|
|
|
+ ('draft', 'Draft'),
|
|
|
+ ('error', 'Error'),
|
|
|
+ ('done', 'Done'),
|
|
|
+ ], string='Line State', default='draft')
|
|
|
+ account = fields.Char(string='Account')
|
|
|
+ password = fields.Char(string='Password')
|
|
|
+ message = fields.Char(string='Message')
|
|
|
+
|
|
|
+
|
|
|
+class Daily3dosConfig(models.Model):
|
|
|
+ _name = 'daily.3dos.config'
|
|
|
+ _description = 'Daily 3dos Config'
|
|
|
+
|
|
|
+ activate = fields.Boolean(string='Activate', default=True)
|
|
|
+ account = fields.Char(string='Account')
|
|
|
+ password = fields.Char(string='Password')
|
|
|
+ description = fields.Text(string='Description')
|