diff --git a/api.py b/api.py index 993ae01..73e720a 100644 --- a/api.py +++ b/api.py @@ -3,6 +3,7 @@ from pydantic import BaseModel from datetime import datetime, timedelta from statistics import median from uuid import uuid4 +from random import randint # Fix 3.3 + 0.15 = 3.4499999999999997 from decimal import Decimal as d @@ -27,7 +28,7 @@ def stat_run(cdm_change): # Низшее значение, высшее значение # Изменение баланса и time2cdm # Прирост за счёт алмазов, за счёт time2cdm - + # Получаем все балансы db = read() bals = [] @@ -110,7 +111,7 @@ def gen_id(): return str(i) return 'Full?' -class User_add(BaseModel): +class Add_user(BaseModel): token: str id: str = None tg: str = None @@ -118,8 +119,8 @@ class User_add(BaseModel): mine: str = None nick: str passwd: str -@app.post('/api/user_add/') -def user_add(it: User_add): +@app.post('/api/add_user/') +def add_user(it: Add_user): token, id, tg, ds, mine, nick, passwd = it.token, it.id, it.tg, it.ds, it.mine, it.nick, it.passwd id = gen_id() if token_check(token): @@ -138,11 +139,11 @@ def user_add(it: User_add): else: return 'Error' -class User_del(BaseModel): +class Del_user(BaseModel): token: str id: str -@app.post('/api/user_del/') -def user_del(it: User_del): +@app.post('/api/del_user/') +def del_user(it: Del_user): token, id = it.token, it.id if token_check(token): db = read() @@ -160,12 +161,12 @@ def user_del(it: User_del): else: return 'Error' -class Coins_add(BaseModel): +class Add_coins(BaseModel): token: str id: str amount: str -@app.post('/api/coins_add/') -def coins_add(it: Coins_add): +@app.post('/api/add_coins/') +def add_coins(it: Add_coins): token, id, amount = it.token, it.id, abs(float(it.amount)) if token_check(token): db = read() @@ -176,12 +177,12 @@ def coins_add(it: Coins_add): else: return 'Error' -class Coins_del(BaseModel): +class Del_coins(BaseModel): token: str id: str amount: str -@app.post('/api/coins_del/') -def coins_del(it: Coins_del): +@app.post('/api/del_coins/') +def del_coins(it: Del_coins): token, id, amount = it.token, it.id, abs(float(it.amount)) if token_check(token): db = read() @@ -195,13 +196,13 @@ def coins_del(it: Coins_del): else: return 'Error' -class Coins_transfer(BaseModel): +class Transfer_coins(BaseModel): token: str src_id: str dst_id: str amount: str -@app.post('/api/coins_transfer/') -def coins_transfer(it: Coins_transfer): +@app.post('/api/transfer_coins/') +def transfer_coins(it: Transfer_coins): token, src_id, dst_id, amount = it.token, it.src_id, it.dst_id, float(it.amount) if token_check(token): db = read() @@ -448,25 +449,32 @@ def get_time(it: Get_time2cdm): else: return 'Error' +from typing import Optional + class Get_stat(BaseModel): token: str + date: Optional[str] = datetime.today().strftime('%Y-%m-%d') @app.post('/api/get_stat/') def get_stat(it: Get_stat): - token = it.token + token, date = it.token, it.date if token_check(token): stat_run(0) db = read('stat.json') - date = datetime.today().strftime('%Y-%m-%d') + #date = datetime.today().strftime('%Y-%m-%d') + if date not in db: + return 'Not found' stats = db[date] return stats else: return 'Error' -class Token_gen(BaseModel): +############# USER API ################ + +class Gen_token(BaseModel): token: str id: str -@app.post('/api/token_gen/') -def token_gen(it: Token_gen): +@app.post('/api/gen_token/') +def gen_token(it: Gen_token): token, id = it.token, it.id if token_check(token): user_token = str(uuid4()) @@ -477,6 +485,68 @@ def token_gen(it: Token_gen): else: return 'Error' +class List_fp(BaseModel): + token: str + id: str +@app.post('/api/list_fp/') +def list_fp(it: List_fp): + token, id = it.token, it.id + if token_check(token): + user_api = read('user_api.json') + if id not in user_api['fp']: + user_api['fp'][id] = [] + write(user_api, 'user_api.json') + return user_api['fp'][id] + else: + return 'Error' + +def gen_fp_id(user_api): + ok = False + while not ok: + ok = True + fp_id = str(randint(5236, 645862)) + if fp_id in user_api['fp']: + ok = False + return fp_id + +class Gen_fp(BaseModel): + token: str + id: str + amount: str +@app.post('/api/gen_fp/') +def gen_fp(it: Gen_fp): + token, id, amount = it.token, it.id, it.amount + if token_check(token): + user_api = read('user_api.json') + if id not in user_api['fp']: + user_api['fp'][id] = [] + write(user_api, 'user_api.json') + if len(user_api['fp'][id]) >= 5: + return 'Limit' + fp_id = gen_fp_id(user_api) + user_api['fp'][fp_id] = [id, amount] + user_api['fp'][id].append(fp_id) + write(user_api, 'user_api.json') + return fp_id + else: + return 'Error' + +class Del_fp(BaseModel): + token: str + fp_id: str +@app.post('/api/del_fp/') +def del_fp(it: Del_fp): + token, fp_id = it.token, it.fp_id + if token_check(token): + user_api = read('user_api.json') + id = user_api['fp'][fp_id][0] + del user_api['fp'][fp_id] + user_api['fp'][id].remove(fp_id) + write(user_api, 'user_api.json') + return 'OK' + else: + return 'Error' + if __name__ == '__main__': import uvicorn uvicorn.run(app, host='0.0.0.0', port=7001) diff --git a/call2api.py b/call2api.py index ccf35d1..19b4fea 100644 --- a/call2api.py +++ b/call2api.py @@ -41,7 +41,7 @@ def user_in_db(token, id=None, tg=None, ds=None, mine=None, nick=None): #print(data) return call('api/user_in_db/', data) -def user_add(token, nick, passwd, tg=None, ds=None, mine=None): +def add_user(token, nick, passwd, tg=None, ds=None, mine=None): passwd = hash(passwd) data = {'token': token, 'nick': nick, 'passwd': passwd} if tg: @@ -51,23 +51,23 @@ def user_add(token, nick, passwd, tg=None, ds=None, mine=None): if mine: data['mine'] = mine print(data) - return call('api/user_add/', data) + return call('api/add_user/', data) -def user_del(token, id): +def del_user(token, id): data = {'token': token, 'id': id} - return call('api/user_del/', data) + return call('api/del_user/', data) -def coins_add(token, id, amount): +def add_coins(token, id, amount): data = {'token': token, 'id': id, 'amount': amount} - return call('api/coins_add/', data) + return call('api/add_coins/', data) -def coins_del(token, id, amount): +def del_coins(token, id, amount): data = {'token': token, 'id': id, 'amount': amount} - return call('api/coins_del/', data) + return call('api/del_coins/', data) -def coins_transfer(token, src_id, dst_id, amount): +def transfer_coins(token, src_id, dst_id, amount): data = {'token': token, 'src_id': src_id, 'dst_id': dst_id, 'amount': amount} - return call('api/coins_transfer/', data) + return call('api/transfer_coins/', data) def update_tg(token, id, tg): if tg != None: @@ -96,7 +96,6 @@ def update_time(token, id, time): data = {'token': token, 'id': id, 'time': time} return call('api/update_time/', data) - def check_bal(token, id): data = {'token': token, 'id': id} return call('api/check_bal/', data) @@ -125,8 +124,10 @@ def get_time2cdm(token, id): data = {'token': token, 'id': id} return call('api/get_time2cdm/', data) -def get_stat(token): +def get_stat(token, date = None): data = {'token': token} + if date: + data['date'] = date return loads(call('api/get_stat/', data, fix=False)) def transfer_callback(addr, token, src_nick, dst_nick, amount): @@ -134,12 +135,25 @@ def transfer_callback(addr, token, src_nick, dst_nick, amount): data = {'token': token, 'src_nick': src_nick, 'dst_nick': dst_nick, 'amount': amount} return call(addr + 'api/transfer_callback/', data, pre=False) -def token_gen(token, id): +def gen_token(token, id): data = {'token': token, 'id': id} - return call('api/token_gen/', data) + return call('api/gen_token/', data) + +def gen_fp_mess(token, nick, amount, chat_id, fp_id): + data = {'token': token, 'nick': nick, 'amount': amount, 'chat_id': chat_id, 'fp_id': fp_id} + return call('http://127.0.0.1:7002/api/gen_fp_mess/', data, pre=False) + +def list_fp(token, id): + data = {'token': token, 'id': id} + return call('api/list_fp/', data) + +def gen_fp(token, id, amount): + data = {'token': token, 'id': id, 'amount': amount} + return call('api/gen_fp/', data) + +def del_fp(token, fp_id): + data = {'token': token, 'fp_id': fp_id} + return call('api/del_fp/', data) -def fp_generate(token, nick, amount, chat_id): - data = {'token': token, 'nick': nick, 'amount': amount, 'chat_id': chat_id} - return call('http://127.0.0.1:7002/api/fp_generate/', data, pre=False) #print( user_in_db('ee77b9d8-44f3-4e01-a702-69d5524ee50b', '1234') ) diff --git a/db.py b/db.py index ea42d5a..c3ab356 100644 --- a/db.py +++ b/db.py @@ -35,7 +35,7 @@ if not os.path.exists('stat.json'): print('Created new stat.json') if not os.path.exists('user_api.json'): - db = {'tokens': {}} + db = {'tokens': {}, 'fp': {}} js = json.dumps(db, indent=2) with open("user_api.json", "w") as outfile: outfile.write(js) diff --git a/tg.py b/tg.py index 56b8177..ec38da3 100644 --- a/tg.py +++ b/tg.py @@ -49,23 +49,32 @@ def start(message): if message.text == '/start': bot.reply_to(message, 'Всё работает', reply_markup=markup) else: - try: - nick, amount = message.text.split(' ')[1].split('_') + #try: + if 1: + #nick, amount = message.text.split(' ')[1].split('_') + fp_id = message.text.split(' ')[1] + dst_id, amount = read('user_api.json')['fp'][fp_id] + nick = get_nick(API_TOKEN, dst_id) + if float(amount) <= 0.0001: bot.reply_to(message, 'Слишком малое или недопустимое значение.') return amount = str(float(amount)) # Защиты от 1000 нулей в начале src_id = user_in_db(API_TOKEN, tg=message.chat.id) - dst_id = user_in_db(API_TOKEN, nick=nick) + #dst_id = user_in_db(API_TOKEN, nick=nick) if dst_id == 'false': bot.reply_to(message, 'Не существует такого пользователя.') else: - status = coins_transfer(API_TOKEN, src_id, dst_id, amount) + print(src_id) + print(amount) + status = transfer_coins(API_TOKEN, src_id, dst_id, amount) if status == 'No_money': bot.reply_to(message, 'Недостаточно средств.') elif status == 'OK': bot.reply_to(message, f'''Успешно переведено {hcode(amount)} CDM. Адресат: {hcode(nick)}''', parse_mode='HTML') + + del_fp(API_TOKEN, fp_id) tg_dst = get_tg(API_TOKEN, dst_id) ds_dst = get_ds(API_TOKEN, dst_id) @@ -74,9 +83,8 @@ def start(message): transfer_callback('http://127.0.0.1:7002/', API_TOKEN, src_nick, nick, amount) elif ds_dst != 'null': transfer_callback('http://127.0.0.1:7003/', API_TOKEN, src_nick, nick, amount) - #bot.reply_to(message, f'CATCHED PAYLOAD: {str(params)}') - except: - pass + #except: + # pass @bot.message_handler(commands=['help']) def help(message): @@ -90,7 +98,7 @@ def help(message): /bal - Баланс /pay ник сумма - Перевод /stats - Статистика -/token_gen - (Ре)генерация токена API` +/gen_token - (Ре)генерация токена API` [Исходный код](https://gitea.del.pw/justuser/CryptoDM) [API и документация](https://cdm-api.del.pw/docs#/) @@ -108,7 +116,7 @@ def reg(message): com, nick, passwd = message.text.split() # Проверяем нет ли такого же ника if user_in_db(API_TOKEN, nick=nick) == 'false': - if user_add(API_TOKEN, nick, passwd, tg=message.chat.id) == 'OK': + if add_user(API_TOKEN, nick, passwd, tg=message.chat.id) == 'OK': bot.reply_to(message, 'Вы успешно зарегистрированны!') else: bot.reply_to(message, 'Что-то пошло не так...') @@ -201,7 +209,7 @@ def pay(message): if dst_id == 'false': bot.reply_to(message, 'Не существует такого пользователя.') else: - status = coins_transfer(API_TOKEN, src_id, dst_id, amount) + status = transfer_coins(API_TOKEN, src_id, dst_id, amount) if status == 'No_money': bot.reply_to(message, 'Недостаточно средств.') elif status == 'OK': @@ -268,11 +276,11 @@ def set_course(message): CDM в час: `{conf['time2cdm']*3600}`''', parse_mode = 'Markdown') -@bot.message_handler(commands=['token_gen']) -def token_gen_tg(message): +@bot.message_handler(commands=['gen_token']) +def gen_token_tg(message): if checkauth(message): id = user_in_db(API_TOKEN, tg=message.chat.id) - token = token_gen(API_TOKEN, id) + token = gen_token(API_TOKEN, id) bot.reply_to(message, f'''Ваш новый токен: {hcode(f"{token}")} ⚠️ВНИМАНИЕ, не передавайте никому токен. Администрация не спрашивает токены.⚠️''', parse_mode='HTML') @@ -305,17 +313,22 @@ def transfer_callback_api(it: Transfer_callback_api): return 'Error' # Генерация сообщения с быстрым платежом -class Fp_generate_api(BaseModel): +class Gen_fp_mess_api(BaseModel): token: str nick: str amount: str chat_id: str -@app.post('/api/fp_generate/') -def fp_generate_api(it: Fp_generate_api): - try: - token, nick, amount, chat_id = it.token, it.nick, it.amount, it.chat_id + fp_id: str +@app.post('/api/gen_fp_mess/') +def gen_fp_mess_api(it: Gen_fp_mess_api): + #try: + if 1: + token, nick, amount, chat_id, fp_id = it.token, it.nick, it.amount, it.chat_id, it.fp_id + token, fp_id, chat_id = it.token, it.fp_id, it.chat_id keyboard = telebot.types.InlineKeyboardMarkup() - url_button = telebot.types.InlineKeyboardButton('ОПЛАТИТЬ', url=f'https://t.me/cdm_bank_bot?start={nick}_{amount}') + url_button = telebot.types.InlineKeyboardButton('ОПЛАТИТЬ' + , url=f'https://t.me/cdm_bank_bot?start={fp_id}') + #, url=f'https://t.me/cdm_bank_bot?start={nick}_{amount}') keyboard.add(url_button) bot.send_message(int(chat_id), f''' `----- ЧЕК -----` @@ -325,11 +338,11 @@ def fp_generate_api(it: Fp_generate_api): #[ОПЛАТИТЬ](https://t.me/cdm_bank_bot?start={nick}_{amount})''', parse_mode='Markdown') return 'OK' - except: - return 'Error' + #except: + # return 'Error' def run_api(): - uvicorn.run(app, host='127.0.0.1', port=7002) + uvicorn.run(app, host='0.0.0.0', port=7002) # Запускаем API для переводов api = Thread(target=run_api) diff --git a/user_api.py b/user_api.py index 308004e..18f22bb 100644 --- a/user_api.py +++ b/user_api.py @@ -1,10 +1,11 @@ from fastapi import FastAPI, Request, HTTPException from pydantic import BaseModel +from typing import Optional from time import time # Отключение логирования для уменьшения нагрузки import logging -logging.disable(logging.CRITICAL) +#logging.disable(logging.CRITICAL) # Fix 3.3 + 0.15 = 3.4499999999999997 from decimal import Decimal as d @@ -19,7 +20,7 @@ from call2api import * app = FastAPI() API_TOKEN = read('conf.json')['api_token'] -def token_check(nick, token): +def check_token(nick, token): db = read('user_api.json') id = user_in_db(API_TOKEN, nick=nick) if id != 'false' and token == db['tokens'][id]: @@ -50,7 +51,7 @@ def check_token_user(request: Request, it: Check_token_user): if too_fast(request): raise HTTPException(status_code=randint(100,999), detail=f"{choice(FAKE_TEXTS)}") nick, token = it.nick, it.token - if token_check(nick, token): + if check_token(nick, token): return 'OK' else: return 'Error' @@ -63,35 +64,12 @@ def check_bal_user(request: Request, it: Check_bal_user): if too_fast(request): raise HTTPException(status_code=randint(100,999), detail=f"{choice(FAKE_TEXTS)}") nick, token = it.nick, it.token - if token_check(nick, token): + if check_token(nick, token): id = user_in_db(API_TOKEN, nick=nick) return check_bal(API_TOKEN, id) else: return 'Error' -class Coins_transfer_user(BaseModel): - nick: str - token: str - dst_nick: str - amount: str -@app.post('/api/coins_transfer/') -def coins_transfer_user(request: Request, it: Coins_transfer_user): - if too_fast(request): - raise HTTPException(status_code=randint(100,999), detail=f"{choice(FAKE_TEXTS)}") - nick, token, dst_nick, amount = it.nick, it.token, it.dst_nick, str(float(it.amount)) - if token_check(nick, token): - id = user_in_db(API_TOKEN, nick=nick) - dst_id = user_in_db(API_TOKEN, nick=dst_nick) - if dst_id == 'false': - return 'Error' - if coins_transfer(API_TOKEN, id, dst_id, amount) == 'OK': - tg_dst = get_tg(API_TOKEN, dst_id) - if tg_dst != 'null': - transfer_callback('http://127.0.0.1:7002/', API_TOKEN, nick, dst_nick, amount) - return 'OK' - else: - return 'Error' - class Get_time2cdm_user(BaseModel): nick: str token: str @@ -100,7 +78,7 @@ def get_time_user(request: Request, it: Get_time2cdm_user): if too_fast(request): raise HTTPException(status_code=randint(100,999), detail=f"{choice(FAKE_TEXTS)}") nick, token = it.nick, it.token - if token_check(nick, token): + if check_token(nick, token): id = user_in_db(API_TOKEN, nick=nick) return get_time2cdm(API_TOKEN, id) else: @@ -109,28 +87,91 @@ def get_time_user(request: Request, it: Get_time2cdm_user): class Get_stat_user(BaseModel): nick: str token: str + date: Optional[str] = None @app.post('/api/get_stat/') def get_stat_user(request: Request, it: Get_stat_user): if too_fast(request): raise HTTPException(status_code=randint(100,999), detail=f"{choice(FAKE_TEXTS)}") - nick, token = it.nick, it.token - if token_check(nick, token): - return get_stat(API_TOKEN) + nick, token, date = it.nick, it.token, it.date + if check_token(nick, token): + if date != None: + return get_stat(API_TOKEN, date) + else: + return get_stat(API_TOKEN) else: return 'Error' -class Fp_generate_user(BaseModel): +class Transfer_coins_user(BaseModel): + nick: str + token: str + dst_nick: str + amount: str +@app.post('/api/transfer_coins/') +def transfer_coins_user(request: Request, it: Transfer_coins_user): + if too_fast(request): + raise HTTPException(status_code=randint(100,999), detail=f"{choice(FAKE_TEXTS)}") + nick, token, dst_nick, amount = it.nick, it.token, it.dst_nick, str(float(it.amount)) + if check_token(nick, token): + id = user_in_db(API_TOKEN, nick=nick) + dst_id = user_in_db(API_TOKEN, nick=dst_nick) + if dst_id == 'false': + return 'Error' + if transfer_coins(API_TOKEN, id, dst_id, amount) == 'OK': + tg_dst = get_tg(API_TOKEN, dst_id) + if tg_dst != 'null': + transfer_callback('http://127.0.0.1:7002/', API_TOKEN, nick, dst_nick, amount) + return 'OK' + else: + return 'Error' + +class Gen_fp_user(BaseModel): nick: str token: str amount: str chat_id: str -@app.post('/api/fp_generate/') -def fp_generate_user(request: Request, it: Fp_generate_user): +@app.post('/api/gen_fp/') +def gen_fp_user(request: Request, it: Gen_fp_user): if too_fast(request): raise HTTPException(status_code=randint(100,999), detail=f"{choice(FAKE_TEXTS)}") nick, token, amount, chat_id = it.nick, it.token, it.amount, it.chat_id - if token_check(nick, token): - return fp_generate(token, nick, amount, chat_id) + if check_token(nick, token): + id = user_in_db(API_TOKEN, nick=nick) + fp_id = gen_fp(API_TOKEN, id, amount) + if fp_id == 'Error': + return 'Error' + elif fp_id == 'Limit': + return 'Limit' + else: + return gen_fp_mess(token, nick, amount, chat_id, fp_id) + + else: + return 'Error' + +class List_fp_user(BaseModel): + nick: str + token: str +@app.post('/api/list_fp/') +def list_fp_user(request: Request, it: List_fp_user): + if too_fast(request): + raise HTTPException(status_code=randint(100,999), detail=f"{choice(FAKE_TEXTS)}") + nick, token = it.nick, it.token + if check_token(nick, token): + id = user_in_db(API_TOKEN, nick=nick) + return list_fp(API_TOKEN, id) + else: + return 'Error' + +class Del_fp_user(BaseModel): + nick: str + token: str + fp_id: str +@app.post('/api/del_fp_user/') +def del_fp_user(request: Request, it: Del_fp_user): + if too_fast(request): + raise HTTPException(status_code=randint(100,999), detail=f"{choice(FAKE_TEXTS)}") + nick, token, fp_id = it.nick, it.token, it.fp_id + if check_token(nick, token): + return del_fp(API_TOKEN, fp_id) else: return 'Error'