2023-11-05 18:07:37 +00:00
|
|
|
|
import os
|
|
|
|
|
import json
|
2023-11-06 04:34:17 +00:00
|
|
|
|
from datetime import datetime, timedelta
|
2023-11-05 08:44:06 +00:00
|
|
|
|
from decimal import Decimal
|
2023-10-25 14:22:04 +00:00
|
|
|
|
|
|
|
|
|
from config import Config
|
|
|
|
|
from core.builtins import Bot
|
2023-11-07 10:05:54 +00:00
|
|
|
|
from core.logger import Logger
|
2023-11-05 17:38:43 +00:00
|
|
|
|
from core.utils.http import get_url
|
2023-10-25 14:22:04 +00:00
|
|
|
|
from core.utils.storedata import get_stored_list, update_stored_list
|
|
|
|
|
|
2023-11-05 08:41:30 +00:00
|
|
|
|
ONE_K = Decimal('1000')
|
|
|
|
|
# https://openai.com/pricing
|
|
|
|
|
BASE_COST_GPT_3_5 = Decimal('0.002') # gpt-3.5-turbo: $0.002 / 1K tokens
|
|
|
|
|
# We are not tracking specific tool usage like searches b/c I'm too lazy, use a universal multiplier
|
|
|
|
|
THIRD_PARTY_MULTIPLIER = Decimal('1.5')
|
|
|
|
|
PROFIT_MULTIPLIER = Decimal('1.1') # At the time we are really just trying to break even
|
|
|
|
|
PRICE_PER_1K_TOKEN = BASE_COST_GPT_3_5 * THIRD_PARTY_MULTIPLIER * PROFIT_MULTIPLIER
|
2023-11-07 08:17:16 +00:00
|
|
|
|
USD_TO_CNY = Decimal('7.3') # Assuming 1 USD = 7.3 CNY
|
|
|
|
|
CNY_TO_PETAL = 100 # 100 petal = 1 CNY
|
2023-11-05 08:41:30 +00:00
|
|
|
|
|
2023-11-06 04:34:17 +00:00
|
|
|
|
|
2023-11-07 08:17:16 +00:00
|
|
|
|
async def get_petal_exchange_rate():
|
2023-11-05 18:07:37 +00:00
|
|
|
|
api_key = Config('exchange_rate_api_key')
|
2023-11-07 10:14:28 +00:00
|
|
|
|
api_url = f'https://v6.exchangerate-api.com/v6/{api_key}/pair/USD/CNY'
|
2023-11-09 05:12:48 +00:00
|
|
|
|
try:
|
|
|
|
|
data = await get_url(api_url, 200, fmt='json')
|
|
|
|
|
if data['result'] == "success":
|
|
|
|
|
exchange_rate = data['conversion_rate']
|
|
|
|
|
petal_value = exchange_rate * CNY_TO_PETAL
|
|
|
|
|
return {"exchange_rate": exchange_rate, "exchanged_petal": petal_value}
|
2023-12-07 13:09:55 +00:00
|
|
|
|
except Exception:
|
|
|
|
|
Logger.error(traceback.format_exc())
|
2023-11-05 18:07:37 +00:00
|
|
|
|
|
2023-11-06 04:34:17 +00:00
|
|
|
|
|
2023-11-05 18:11:49 +00:00
|
|
|
|
async def load_or_refresh_cache():
|
2023-11-05 18:07:37 +00:00
|
|
|
|
cache_dir = Config('cache_path')
|
2023-11-07 08:17:16 +00:00
|
|
|
|
file_path = os.path.join(cache_dir, 'petal_exchange_rate_cache.json')
|
2023-11-05 18:07:37 +00:00
|
|
|
|
if os.path.exists(file_path):
|
2023-11-07 09:42:01 +00:00
|
|
|
|
with open(file_path, 'r') as file:
|
|
|
|
|
data = json.load(file)
|
2023-12-07 13:09:55 +00:00
|
|
|
|
return data["exchanged_petal"]
|
2023-11-05 18:07:37 +00:00
|
|
|
|
|
2023-11-07 08:17:16 +00:00
|
|
|
|
exchanged_petal_data = await get_petal_exchange_rate()
|
|
|
|
|
if exchanged_petal_data:
|
2023-12-07 13:09:55 +00:00
|
|
|
|
Logger.info(f'Petal exchange rate is expired or cannot be found. Updating...')
|
2023-11-05 18:07:37 +00:00
|
|
|
|
with open(file_path, 'w') as file:
|
2023-12-07 13:09:55 +00:00
|
|
|
|
exchanged_petal_data["update_time"] = datetime.now().strftime("%Y-%m-%d")
|
2023-11-07 08:17:16 +00:00
|
|
|
|
json.dump(exchanged_petal_data, file)
|
2023-11-07 09:21:22 +00:00
|
|
|
|
return exchanged_petal_data["exchanged_petal"]
|
2023-11-05 18:07:37 +00:00
|
|
|
|
|
2023-11-06 04:34:17 +00:00
|
|
|
|
|
2023-11-05 17:37:20 +00:00
|
|
|
|
async def count_petal(tokens):
|
2023-11-07 10:05:54 +00:00
|
|
|
|
Logger.info(f'{tokens} tokens have been consumed while calling AI.')
|
2023-11-07 08:17:16 +00:00
|
|
|
|
petal_exchange_rate = await load_or_refresh_cache()
|
2023-11-05 08:41:30 +00:00
|
|
|
|
price = tokens / ONE_K * PRICE_PER_1K_TOKEN
|
2023-11-07 08:17:16 +00:00
|
|
|
|
if petal_exchange_rate:
|
2023-11-07 08:23:45 +00:00
|
|
|
|
petal = price * Decimal(petal_exchange_rate).quantize(Decimal('0.00'))
|
2023-11-07 08:17:16 +00:00
|
|
|
|
else:
|
2023-11-07 10:05:54 +00:00
|
|
|
|
Logger.warn(f'Unable to obtain real-time exchange rate, use {USD_TO_CNY} to calculate petals.')
|
2023-11-07 08:17:16 +00:00
|
|
|
|
petal = price * USD_TO_CNY * CNY_TO_PETAL
|
2023-11-05 08:41:30 +00:00
|
|
|
|
return petal
|
2023-10-25 14:22:04 +00:00
|
|
|
|
|
2023-11-06 04:34:17 +00:00
|
|
|
|
|
2023-11-05 18:07:37 +00:00
|
|
|
|
async def gained_petal(msg: Bot.MessageSession, amount):
|
2023-10-25 14:22:04 +00:00
|
|
|
|
if Config('openai_api_key') and Config('enable_get_petal'):
|
2023-11-21 10:44:40 +00:00
|
|
|
|
limit = Config('petal_gained_limit', 10)
|
2023-10-25 14:22:04 +00:00
|
|
|
|
p = get_stored_list(msg.target.client_name, 'gainedpetal')
|
|
|
|
|
if not p:
|
|
|
|
|
p = [{}]
|
|
|
|
|
p = p[0]
|
|
|
|
|
now = datetime.now().timestamp()
|
|
|
|
|
if msg.target.target_id not in p:
|
|
|
|
|
p[msg.target.target_id] = {'time': now, 'amount': amount}
|
|
|
|
|
p = [p]
|
|
|
|
|
update_stored_list(msg.target.client_name, 'gainedpetal', p)
|
|
|
|
|
msg.data.modify_petal(amount)
|
|
|
|
|
return msg.locale.t('petal.message.gained.success', amount=amount)
|
|
|
|
|
else:
|
|
|
|
|
if now - p[msg.target.target_id]['time'] > 60 * 60 * 24:
|
|
|
|
|
p[msg.target.target_id] = {'time': now, 'amount': amount}
|
|
|
|
|
p = [p]
|
|
|
|
|
msg.data.modify_petal(amount)
|
|
|
|
|
update_stored_list(msg.target.client_name, 'gainedpetal', p)
|
|
|
|
|
else:
|
|
|
|
|
if p[msg.target.target_id]['amount'] + amount > limit:
|
|
|
|
|
return msg.locale.t('petal.message.gained.limit')
|
|
|
|
|
p[msg.target.target_id]['amount'] += amount
|
|
|
|
|
p = [p]
|
|
|
|
|
update_stored_list(msg.target.client_name, 'gainedpetal', p)
|
|
|
|
|
msg.data.modify_petal(amount)
|
|
|
|
|
return msg.locale.t('petal.message.gained.success', amount=amount)
|
|
|
|
|
|
|
|
|
|
|
2023-11-05 18:07:37 +00:00
|
|
|
|
async def lost_petal(msg: Bot.MessageSession, amount):
|
2023-10-25 14:22:04 +00:00
|
|
|
|
if Config('openai_api_key') and Config('enable_get_petal'):
|
2023-11-21 10:44:40 +00:00
|
|
|
|
limit = Config('petal_lost_limit', 5)
|
2023-10-25 14:22:04 +00:00
|
|
|
|
p = get_stored_list(msg.target.client_name, 'lostpetal')
|
|
|
|
|
if not p:
|
|
|
|
|
p = [{}]
|
|
|
|
|
p = p[0]
|
|
|
|
|
now = datetime.now().timestamp()
|
|
|
|
|
if msg.target.target_id not in p:
|
|
|
|
|
p[msg.target.target_id] = {'time': now, 'amount': amount}
|
|
|
|
|
p = [p]
|
|
|
|
|
update_stored_list(msg.target.client_name, 'lostpetal', p)
|
|
|
|
|
msg.data.modify_petal(-amount)
|
|
|
|
|
return msg.locale.t('petal.message.lost.success', amount=amount)
|
|
|
|
|
else:
|
|
|
|
|
if now - p[msg.target.target_id]['time'] > 60 * 60 * 24:
|
|
|
|
|
p[msg.target.target_id] = {'time': now, 'amount': amount}
|
|
|
|
|
p = [p]
|
|
|
|
|
msg.data.modify_petal(-amount)
|
|
|
|
|
update_stored_list(msg.target.client_name, 'lostpetal', p)
|
|
|
|
|
else:
|
|
|
|
|
if p[msg.target.target_id]['amount'] + amount > limit:
|
|
|
|
|
return msg.locale.t('petal.message.lost.limit')
|
|
|
|
|
p[msg.target.target_id]['amount'] += amount
|
|
|
|
|
p = [p]
|
|
|
|
|
update_stored_list(msg.target.client_name, 'lostpetal', p)
|
|
|
|
|
msg.data.modify_petal(-amount)
|
2023-11-05 17:37:20 +00:00
|
|
|
|
return msg.locale.t('petal.message.lost.success', amount=amount)
|