Compare commits

...

27 Commits
main ... main

Author SHA1 Message Date
Your Name
e84c2badad Добавление CDM - /add ; сжигание CDM - /burn 2024-12-07 20:51:58 +03:00
Your Name
d82397477f fix 2024-12-06 12:37:00 +03:00
Your Name
96dd773e5d Исправление бага несуществующей даты статистики 2024-12-06 12:27:24 +03:00
Your Name
0b8878dbb6 fix 2024-12-05 12:59:18 +03:00
Your Name
bac5ba9f36 Исправление маркДАУНА 2024-12-04 21:04:51 +03:00
Your Name
f6e107580b Исправление точки API 2024-12-04 12:19:48 +03:00
Your Name
63309cc094 Добавление проверки айди пользователя и чата 2024-12-04 12:16:43 +03:00
Your Name
71bfb67807 Исправление бага статистики 2024-12-04 12:07:45 +03:00
e124f45b35 Upload files to 'imgs' 2024-12-02 08:46:34 +00:00
f5c57e141c Delete 'imgs/t' 2024-12-02 08:38:19 +00:00
6d1f26c62c Upload files to 'imgs' 2024-12-02 08:38:12 +00:00
Your Name
eb7fca82d8 Создание папки 2024-12-02 11:37:30 +03:00
Your Name
96459ea32e Исправление статистики (вы/в)вода алмазов 2024-12-02 11:30:36 +03:00
Your Name
f76d59ccea up 2024-12-01 20:37:10 +03:00
Your Name
e5711a508e Переработка API, готовый userAPI 2024-12-01 17:34:58 +03:00
Your Name
992989238d Игнорирование конфигураций 2024-12-01 11:04:04 +03:00
Your Name
d35ea3b900 Создание UserAPI. TODO: проверка оплаты счёта. 2024-11-30 12:51:14 +03:00
Your Name
14b5758666 Исправление появления двойного знака минуса 2024-11-30 09:27:45 +03:00
Your Name
2e15398259 Изменение токена по нику на токен по айди 2024-11-30 08:45:14 +03:00
Your Name
3d550af0f6 Расчёт статистики сразу в файл, начисление CDM за время сразу 2024-11-29 12:10:01 +03:00
Your Name
967d49506e Табы, пробелы... 2024-11-08 19:53:16 +03:00
Your Name
f3eb0c9435 Исправление отрицательных значений coins_add, coins_del 2024-11-08 19:37:42 +03:00
Your Name
15f882085a Забыл добавить учёт time2cdm 2024-11-02 10:42:38 +03:00
Your Name
126770e008 Исправление расчёта ввода/вывода алмазов 2024-11-02 10:21:58 +03:00
Your Name
517bcb025c Merge branch 'main' of ssh://git.del.pw:2222/justuser/CryptoDM 2024-11-01 14:03:31 +03:00
Your Name
371f989308 Добавление статистики 2024-11-01 13:52:57 +03:00
8423e6ac9b Delete 'api.py.bak' 2024-10-28 10:11:45 +03:00
10 changed files with 777 additions and 423 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
db.json
user_api.json
conf.json

296
api.py
View File

@ -1,5 +1,11 @@
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional
from datetime import datetime, timedelta
from statistics import median
from uuid import uuid4
from random import randint
from time import sleep
# Fix 3.3 + 0.15 = 3.4499999999999997
from decimal import Decimal as d
@ -19,6 +25,66 @@ def token_check(token):
else:
return False
############## STATS ##################
STAT_RUN = False
def stat_run(cdm_change):
# Общий баланс, среднее значение, медиана
# Низшее значение, высшее значение
# Изменение баланса и time2cdm
# Прирост за счёт алмазов, за счёт time2cdm
# Защита от конфликтов
global STAT_RUN
while STAT_RUN:
sleep(1)
STAT_RUN = True
# Получаем все балансы
db = read()
bals = []
for id in db['id']:
bals.append(db['id'][id]['bal'])
date = datetime.today().strftime('%Y-%m-%d')
stat = read('stat.json')
if date in stat:
stat[date]['gbal'] += cdm_change
else:
stat[date] = {'gbal': sum(bals), 'time2cdm': 0}
stats = {'gbal': 0, 'average': 0, 'median': 0, 'time2cdm': 0,
'gbal_delta': '0', 'time2cdm_delta': '',
'min': 0, 'max': 0,
'up_diamond': 0}
date = datetime.today().strftime('%Y-%m-%d')
yesterday = (datetime.today() - timedelta(days=1)).strftime('%Y-%m-%d')
if yesterday in stat:
gbal_y = stat[yesterday]['gbal']
time2cdm_y = stat[yesterday]['time2cdm']
else:
gbal_y, time2cdm_y = 0, 0
time2cdm = stat[date]['time2cdm']
gbal = stat[date]['gbal']
# Заполняем данные
stats['gbal'] = round(gbal, 3)
stats['average'] = round(sum([x for x in bals if x != 0])/len([x for x in bals if x != 0]), 3)
stats['median'] = round(median([x for x in bals if x != 0]), 3)
stats['time2cdm'] = round(time2cdm, 3)
stats['time2cdm_delta'] = round(time2cdm-time2cdm_y, 3)
stats['gbal_delta'] = round(gbal-gbal_y, 3)
stats['min'] = round(min([x for x in bals if x != 0]), 3)
stats['max'] = round(max(bals), 3)
stats['up_diamond'] = round(gbal - (gbal_y + time2cdm))
stat[date] = stats
write(stat, 'stat.json')
STAT_RUN = False
#######################
class User_in_db(BaseModel):
token: str
id: str = None
@ -54,12 +120,11 @@ def gen_id():
db = read()
for i in range(1,100000):
check = str(i)
print(db)
if check not in db['id']:
return str(i)
return 'Full?'
class User_add(BaseModel):
class Add_user(BaseModel):
token: str
id: str = None
tg: str = None
@ -67,14 +132,14 @@ 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()
print(id)
if token_check(token):
db = read()
db['id'][id] = {'tg': tg, 'ds': ds, 'mine': mine, 'nick': nick, 'passwd': passwd, 'bal': 0.0}
db['id'][id] = {'tg': tg, 'ds': ds, 'mine': mine, 'nick': nick, 'passwd': passwd
, 'bal': 0.0, 'time2cdm': [0, datetime.today().strftime('%Y-%m-%d')]}
db['nick'][nick] = id
if tg:
db['tg'][tg] = id
@ -87,11 +152,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()
@ -109,43 +174,48 @@ 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):
token, id, amount = it.token, it.id, float(it.amount)
@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()
db['id'][id]['bal'] = fix_add(db['id'][id]['bal'], amount)
write(db)
stat_run(amount)
return 'OK'
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):
token, id, amount = it.token, it.id, float(it.amount)
if token_check(token):
db = read()
db['id'][id]['bal'] = fix_sub(db['id'][id]['bal'], amount)
write(db)
return 'OK'
else:
return 'Error'
@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()
if db['id'][id]['bal'] >= amount:
db['id'][id]['bal'] = fix_sub(db['id'][id]['bal'], amount)
write(db)
stat_run(amount*-1)
return 'OK'
else:
return 'Error'
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()
@ -257,7 +327,7 @@ class Update_passwd(BaseModel):
id: str
passwd: str
@app.post('/api/update_passwd/')
def update_tg(it: Update_passwd):
def update_passwd(it: Update_passwd):
token, id, passwd = it.token, it.id, it.passwd
if token_check(token):
db = read()
@ -267,18 +337,61 @@ def update_tg(it: Update_passwd):
else:
return 'Error'
class Add_time(BaseModel):
token: str
id: str
time: str
@app.post('/api/add_time/')
def add_time(it: Add_time):
token, id, time = it.token, it.id, int(it.time)
if token_check(token):
course = read('conf.json')['time2cdm']
amount = time*course
# Пополнение баланса
db = read()
db['id'][id]['bal'] += amount
# Статистика
date = datetime.today().strftime('%Y-%m-%d')
# Для пользователя
t2c_date = db['id'][id]['time2cdm'][1]
if t2c_date != date:
db['id'][id]['time2cdm'][0] = amount
db['id'][id]['time2cdm'][1] = date
else:
db['id'][id]['time2cdm'][0] += amount
write(db)
# Глобально
stat = read('stat.json')
if date not in stat:
stat_run(0)
stat[date]['time2cdm'] += amount
write(stat, 'stat.json')
stat_run(amount)
return 'OK'
else:
return 'Error'
class Check_bal(BaseModel):
token: str
id: str
@app.post('/api/check_bal/')
def check_bal(it: Check_bal):
token, id = it.token, it.id
if token_check(token):
db = read()
return db['id'][id]['bal']
else:
return 'Error'
token, id = it.token, it.id
if token_check(token):
stat_run(0)
db = read()
# Если дата time2cdm прошла - обнулить баланс
date = datetime.today().strftime('%Y-%m-%d')
t2c_date = db['id'][id]['time2cdm'][1]
if t2c_date != date:
db['id'][id]['time2cdm'][0] = 0
db['id'][id]['time2cdm'][1] = date
write(db)
return db['id'][id]['bal']
else:
return 'Error'
class Get_nick(BaseModel):
token: str
@ -340,7 +453,120 @@ def get_passwd(it: Get_passwd):
else:
return 'Error'
# TODO: unauth from account
class Get_time2cdm(BaseModel):
token: str
id: str
@app.post('/api/get_time2cdm/')
def get_time(it: Get_time2cdm):
token, id = it.token, it.id
if token_check(token):
db = read()
return db['id'][id]['time2cdm'][0]
else:
return 'Error'
class Get_stat(BaseModel):
token: str
date: Optional[str] = None
@app.post('/api/get_stat/')
def get_stat(it: Get_stat):
token, date = it.token, it.date
if not date:
date = datetime.today().strftime('%Y-%m-%d')
if token_check(token):
stat_run(0)
db = read('stat.json')
if date not in db:
return 'Not found'
stats = db[date]
return stats
else:
return 'Error'
############# USER API ################
class Gen_token(BaseModel):
token: str
id: str
@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())
user_api = read('user_api.json')
user_api['tokens'][id] = user_token
write(user_api, 'user_api.json')
return user_token
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):
try:
if float(amount) <= 0.0001:
return 'Error'
amount = str(float(amount)) # Защиты от 1000 нулей в начале
except:
return 'Error'
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

View File

@ -1,305 +0,0 @@
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from db import *
app = FastAPI()
def token_check(token):
db = read()
if token in db['tokens']:
return True
else:
return False
class User_in_db(BaseModel):
token: str
id: str = None
tg: str = None
ds: str = None
mine: str = None
nick: str = None
@app.post('/api/user_in_db/')
def user_in_db(it: User_in_db):
token, id, tg, ds, mine, nick = it.token, it.id, it.tg, it.ds, it.mine, it.nick
if token_check(token):
db = read()
if id and id in db['id']:
return id
elif tg and tg in db['tg']:
return db['tg'][tg]
elif ds and ds in db['ds']:
return db['ds'][ds]
elif mine and mine in db['mine']:
return db['mine'][mine]
elif nick and nick in db['nick']:
return db['nick'][nick]
else:
return False
else:
return 'Error'
def gen_id():
db = read()
for i in range(1,100000):
check = str(i)
print(db)
if check not in db['id']:
return str(i)
return 'Full?'
class User_add(BaseModel):
token: str
id: str = None
tg: str = None
ds: str = None
mine: str = None
nick: str
passwd: str
@app.post('/api/user_add/')
def user_add(it: User_add):
token, id, tg, ds, mine, nick, passwd = it.token, it.id, it.tg, it.ds, it.mine, it.nick, it.passwd
id = gen_id()
print(id)
if token_check(token):
db = read()
db['id'][id] = {'tg': tg, 'ds': ds, 'mine': mine, 'nick': nick, 'passwd': passwd, 'bal': 0.0}
db['nick'][nick] = id
if tg:
db['tg'][tg] = id
if ds:
db['ds'][ds] = id
if mine:
db['mine'][mine] = id
write(db)
return 'OK'
else:
return 'Error'
class User_del(BaseModel):
token: str
id: str
@app.post('/api/user_del/')
def user_del(it: User_del):
token, id = it.token, it.id
if token_check(token):
db = read()
tg, ds, mine, nick = db['id'][id]['tg'], db['id'][id]['ds'], db['id'][id]['mine'], db['id'][id]['nick']
del db['nick'][nick]
if tg:
del db['tg'][tg]
if ds:
del db['ds'][ds]
if mine:
del db['mine'][mine]
del db['id'][id]
write(db)
return 'OK'
else:
return 'Error'
class Coins_add(BaseModel):
token: str
id: str
amount: str
@app.post('/api/coins_add/')
def coins_add(it: Coins_add):
token, id, amount = it.token, it.id, float(it.amount)
if token_check(token):
db = read()
db['id'][id]['bal'] += amount
write(db)
return 'OK'
else:
return 'Error'
class Coins_del(BaseModel):
token: str
id: str
amount: str
@app.post('/api/coins_del/')
def coins_del(it: Coins_del):
token, id, amount = it.token, it.id, float(it.amount)
if token_check(token):
db = read()
db['id'][id]['bal'] -= amount
write(db)
return 'OK'
else:
return 'Error'
class Coins_transfer(BaseModel):
token: str
src_id: str
dst_id: str
amount: str
@app.post('/api/coins_transfer/')
def coins_transfer(it: Coins_transfer):
token, src_id, dst_id, amount = it.token, it.src_id, it.dst_id, float(it.amount)
if token_check(token):
db = read()
src_bal = db['id'][src_id]['bal']
if src_bal > amount:
db['id'][src_id]['bal'] -= amount
db['id'][dst_id]['bal'] += amount
write(db)
return 'OK'
else:
return 'No_money'
else:
return 'Error'
class Update_tg(BaseModel):
token: str
id: str
tg: str
@app.post('/api/update_tg/')
def update_tg(it: Update_tg):
token, id, tg = it.token, it.id, it.tg
if token_check(token):
db = read()
cur_tg = db['id'][id]['tg']
del db['tg'][cur_tg]
db['id'][id]['tg'] = tg
db['tg'][tg] = id
write(db)
return 'OK'
else:
return 'Error'
class Update_ds(BaseModel):
token: str
id: str
ds: str
@app.post('/api/update_ds/')
def update_ds(it: Update_ds):
token, id, ds = it.token, it.id, it.ds
if token_check(token):
db = read()
cur_ds = db['id'][id]['ds']
del db['ds'][cur_ds]
db['id'][id]['ds'] = ds
db['ds'][ds] = id
write(db)
return 'OK'
else:
return 'Error'
class Update_mine(BaseModel):
token: str
id: str
mine: str
@app.post('/api/update_mine/')
def update_mine(it: Update_mine):
token, id, mine = it.token, it.id, it.mine
if token_check(token):
db = read()
cur_mine = db['id'][id]['mine']
del db['mine'][cur_mine]
db['id'][id]['mine'] = mine
db['mine'][mine] = id
write(db)
return 'OK'
else:
return 'Error'
class Update_nick(BaseModel):
token: str
id: str
nick: str
@app.post('/api/update_nick/')
def update_nick(it: Update_nick):
token, id, nick = it.token, it.id, it.nick
if token_check(token):
db = read()
cur_nick = db['id'][id]['nick']
del db['nick'][cur_nick]
db['id'][id]['nick'] = nick
db['nick'][nick] = id
write(db)
return 'OK'
else:
return 'Error'
class Update_passwd(BaseModel):
token: str
id: str
passwd: str
@app.post('/api/update_passwd/')
def update_tg(it: Update_tg):
token, id, passwd = it.token, it.id, it.passwd
if token_check(token):
db = read()
db['id'][id]['passwd'] = passwd
write(db)
return 'OK'
else:
return 'Error'
class Check_bal(BaseModel):
token: str
id: str
@app.post('/api/check_bal/')
def check_bal(it: Check_bal):
token, id = it.token, it.id
if token_check(token):
db = read()
return db['id'][id]['bal']
else:
return 'Error'
class Get_nick(BaseModel):
token: str
id: str
@app.post('/api/get_nick/')
def get_nick(it: Get_nick):
token, id = it.token, it.id
if token_check(token):
db = read()
return db['id'][id]['nick']
else:
return 'Error'
class Get_tg(BaseModel):
token: str
id: str
@app.post('/api/get_tg/')
def get_tg(it: Get_tg):
token, id = it.token, it.id
if token_check(token):
db = read()
return db['id'][id]['tg']
else:
return 'Error'
class Get_ds(BaseModel):
token: str
id: str
@app.post('/api/get_ds/')
def get_ds(it: Get_ds):
token, id = it.token, it.id
if token_check(token):
db = read()
return db['id'][id]['ds']
else:
return 'Error'
class Get_mine(BaseModel):
token: str
id: str
@app.post('/api/get_mine/')
def get_mine(it: Get_mine):
token, id = it.token, it.id
if token_check(token):
db = read()
return db['id'][id]['mine']
else:
return 'Error'
# TODO: unauth from account
if __name__ == '__main__':
import uvicorn
uvicorn.run(app, host='127.0.0.1', port=1111)

View File

@ -1,5 +1,5 @@
from requests import post
from json import dumps
from json import dumps, loads
from xxhash import xxh32
from db import *
@ -11,14 +11,20 @@ def hash(text):
text = str(text)
return xxh32(text).hexdigest()
def call(api_url, data, pre=True):
def call(api_url, data, pre=True, fix=True):
if pre:
response = post(url_pre + api_url, data=dumps(data))
else:
response = post(api_url, data=dumps(data))
print(response.status_code)
print(response.text)
return response.text.replace('"', '')
#print(response.status_code)
#print(response.text)
try:
if fix:
return response.text.replace('"', '')
else:
return response.text
except:
return response.text
def user_in_db(token, id=None, tg=None, ds=None, mine=None, nick=None):
data = {'token': token}
@ -35,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:
@ -45,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:
@ -86,6 +92,9 @@ def update_passwd(token, id, passwd):
data = {'token': token, 'id': id, 'passwd': hash(passwd)}
return call('api/update_passwd/', data)
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}
@ -96,25 +105,55 @@ def get_nick(token, id):
return call('api/get_nick/', data)
def get_tg(token, id):
data = {'token': token, 'id': id}
return call('api/get_tg/', data)
data = {'token': token, 'id': id}
return call('api/get_tg/', data)
def get_ds(token, id):
data = {'token': token, 'id': id}
return call('api/get_ds/', data)
data = {'token': token, 'id': id}
return call('api/get_ds/', data)
def get_mine(token, id):
data = {'token': token, 'id': id}
return call('api/get_mine/', data)
data = {'token': token, 'id': id}
return call('api/get_mine/', data)
def get_passwd(token, id):
data = {'token': token, 'id': id}
return call('api/get_passwd/', data)
data = {'token': token, 'id': id}
return call('api/get_passwd/', data)
def get_time2cdm(token, id):
data = {'token': token, 'id': id}
return call('api/get_time2cdm/', data)
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):
amount = str(amount)
data = {'token': token, 'src_nick': src_nick, 'dst_nick': dst_nick, 'amount': amount}
print(addr + 'api/transfer_callback/')
return call(addr + 'api/transfer_callback/', data, pre=False)
def gen_token(token, id):
data = {'token': token, 'id': id}
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)
#print( user_in_db('ee77b9d8-44f3-4e01-a702-69d5524ee50b', '1234') )

23
db.py
View File

@ -15,13 +15,32 @@ if not os.path.exists('db.json'):
if not os.path.exists('conf.json'):
db = {'api_token': 'None',
'tg_token': 'None',
'ds_token': 'None'}
'tg_token': 'None',
'ds_token': 'None',
'push_src_nick': 0,
'push_id': 0,
'push_amount': 0,
'time2cdm': 0,
'owner': 0}
js = json.dumps(db, indent=2)
with open("conf.json", "w") as outfile:
outfile.write(js)
print('Created new conf.json')
if not os.path.exists('stat.json'):
db = {}
js = json.dumps(db, indent=2)
with open("stat.json", "w") as outfile:
outfile.write(js)
print('Created new stat.json')
if not os.path.exists('user_api.json'):
db = {'tokens': {}, 'fp': {}}
js = json.dumps(db, indent=2)
with open("user_api.json", "w") as outfile:
outfile.write(js)
print('Created new user_api.json')
def read(file = 'db.json'):
with open(file, "r", encoding="utf-8") as openfile:
db = json.load(openfile)

87
ds.py
View File

@ -86,16 +86,21 @@ async def help(message):
/nick ник - Смена ника
/bal - Баланс
/pay ник сумма - Перевод
/time2cdm - Конвертация времени на сервере в CDM
/stats - Статистика
`
''')
async def bal(message):
send = message.channel.send
if await checkauth(message):
id = user_in_db(API_TOKEN, ds=message.author.id)
coins = check_bal(API_TOKEN, id)
nick = get_nick(API_TOKEN, id)
await send(f'''Ваш баланс: `{coins}` CDM
send = message.channel.send
if await checkauth(message):
id = user_in_db(API_TOKEN, ds=message.author.id)
coins = check_bal(API_TOKEN, id)
nick = get_nick(API_TOKEN, id)
time = int(get_time(API_TOKEN, id))
hours = time//3600 ; minutes = (time - hours*3600)//60
await send(f'''Ваш баланс: `{coins}` CDM
Время на сервере: `{f"{hours}:{minutes}"}`
Ник: `{nick}`''')
@ -207,23 +212,63 @@ async def pay(message):
else:
await send('/pay ник количество')
async def time2cdm(message):
send = message.channel.send
if await checkauth(message):
id = user_in_db(API_TOKEN, ds=message.author.id)
course = read('conf.json')['time2cdm']
time = int(get_time(API_TOKEN, id))
amount = time*course
if update_time(API_TOKEN, id, '0'):
if coins_add(API_TOKEN, id, str(amount)):
# Статистика
stat = read('stat.json')
date = datetime.today().strftime('%Y-%m-%d')
stat[date]['time2cdm'] += amount
write(stat, 'stat.json')
await send(f'''Вы успешно конвертировали время на сервере в `{str(amount)}` CDM.''')
async def stats(message):
send = message.channel.send
if await checkauth(message):
data = get_stat(API_TOKEN)
bal = f'Баланс ({data["gbal_delta"]})'
t2cdm = f'Time2cdm ({data["time2cdm_delta"]})'
max_len = max(len(bal), len(t2cdm), 19)
await send(f'''```json
{bal.ljust(max_len)}: {data["gbal"]}
{t2cdm.ljust(max_len)}: {data["time2cdm"]}
Среднее значение : {data["average"]}
Медиана : {data["median"]}
Минимум : {data["min"]}
Максимум : {data["max"]}
Ввод/вывод алмазов : {data["up_diamond"]}
```
''')
@bot.event
async def on_message(message):
send = message.channel.send
if command('help', message):
await help(message)
elif command('reg', message):
await reg(message)
elif command('login', message):
await login(message)
elif command('unreg', message):
await unreg(message)
elif command('bal', message):
await bal(message)
elif command('passwd', message):
await passwd(message)
elif command('pay', message):
await pay(message)
send = message.channel.send
if command('help', message):
await help(message)
elif command('reg', message):
await reg(message)
elif command('login', message):
await login(message)
elif command('unreg', message):
await unreg(message)
elif command('bal', message):
await bal(message)
elif command('passwd', message):
await passwd(message)
elif command('pay', message):
await pay(message)
elif command('time2cdm', message):
await time2cdm(message)
elif command('stats', message):
await stats(message)
# API для переводов TG->DS / ...

BIN
imgs/2024-12-02_11-36.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
imgs/2024-12-02_11-46.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

219
tg.py
View File

@ -28,7 +28,6 @@ def checkauth(message, reg = False):
if not reg:
markup = ReplyKeyboardMarkup(resize_keyboard=True)
markup.add('Баланс')
#markup.add('Перевод')
markup.add('Помощь')
bot.reply_to(message, '''Пожалуйста, зарегистрируйтесь или войдите:
/reg Nickname 1234567890
@ -40,31 +39,71 @@ def checkauth(message, reg = False):
@bot.message_handler(commands=['start'])
def start(message):
markup = ReplyKeyboardMarkup(resize_keyboard=True)
markup = ReplyKeyboardMarkup(resize_keyboard=True)
markup.add('Баланс')
markup.add('Помощь')
markup.add('Баланс')
markup.add('Помощь')
if not checkauth(message):
pass
else:
bot.reply_to(message, 'Всё работает', reply_markup=markup)
if not checkauth(message):
return
if message.text == '/start':
bot.reply_to(message, 'Всё работает', reply_markup=markup)
else:
try:
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)
if dst_id == 'false':
bot.reply_to(message, 'Не существует такого пользователя.')
else:
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)
src_nick = nick
if tg_dst != 'null':
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)
except:
pass
@bot.message_handler(commands=['help'])
def help(message):
bot.reply_to(message, f'''Исходный код: https://gitea.del.pw/justuser/CryptoDM
Доступные команды:
{hcode("""/help - Помощь
bot.reply_to(message, f'''
Доступные команды: `
/help - Помощь
/reg ник - Регистрация
/login ник пароль - Войти в аккаунт
/unreg - Выйти из аккаунта
/passwd пароль - Смена пароля
/nick ник - Смена ника
/bal - Баланс
/pay ник сумма - Перевод
""")}
''', parse_mode='HTML')
/stats - Статистика
/gen_token - (Ре)генерация токена API
/chat_id - Айди чата
/user_id - Айди пользователя
/burn - Сжечь CDM`
[Исходный код](https://gitea.del.pw/justuser/CryptoDM)
[Документация UserAPI](https://gitea.del.pw/justuser/cdm_example_user_api)
[UserAPI URL](https://cdm-api.del.pw/docs)
''', parse_mode='Markdown')
@bot.message_handler(commands=['reg'])
def reg(message):
@ -78,7 +117,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, 'Что-то пошло не так...')
@ -99,7 +138,6 @@ def login(message):
return 0
com, nick, passwd = message.text.split()
id = user_in_db(API_TOKEN, nick=nick)
print('!!!!', get_tg(API_TOKEN, id))
if get_tg(API_TOKEN, id) != 'null':
bot.reply_to(message, 'Этот пользователь уже авторизован')
elif get_passwd(API_TOKEN, id) == hash(passwd):
@ -112,21 +150,12 @@ def login(message):
else:
bot.reply_to(message, '/login ник пароль')
@bot.message_handler(commands=['unreg'])
def unreg(message):
id = user_in_db(API_TOKEN, tg=message.chat.id)
if update_tg(API_TOKEN, id, 'None') == 'OK':
bot.reply_to(message, 'Вы успешно вышли из аккаунта')
'''
@bot.message_handler(commands=['unreg'])
def unreg(message):
id = user_in_db(API_TOKEN, tg=message.chat.id)
print(int(id))
print("1")
if user_del(API_TOKEN, id) == 'OK':
bot.reply_to(message, 'OK')
'''
# @bot.message_handler(commands=['unreg'])
# def unreg(message):
# id = user_in_db(API_TOKEN, tg=message.chat.id)
# if update_tg(API_TOKEN, id, 'None') == 'OK':
# bot.reply_to(message, 'Вы успешно вышли из аккаунта')
@bot.message_handler(commands=['passwd'])
def passwd(message):
@ -159,9 +188,11 @@ def nick(message):
def bal(message):
if checkauth(message):
id = user_in_db(API_TOKEN, tg=message.chat.id)
coins = check_bal(API_TOKEN, id)
coins = round(float(check_bal(API_TOKEN, id)), 4)
nick = get_nick(API_TOKEN, id)
bot.reply_to(message, f'''Ваш баланс: {hcode(coins)} CDM
time2cdm = round(float(get_time2cdm(API_TOKEN, id)), 4)
bot.reply_to(message, f'''Ваш баланс: {hcode(f"{coins}")} CDM
Валюта за время (сегодня): {hcode(f"{time2cdm}")}
Ник: {hcode(nick)}''', parse_mode='HTML')
@ -179,7 +210,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':
@ -196,6 +227,97 @@ def pay(message):
else:
bot.reply_to(message, '/pay ник количество')
def format_sign(number):
if '-' in str(number):
return f"{number}"
if number > 0:
return f"+{number}"
elif number == 0:
return f"{number}"
else:
return f"-{number}"
@bot.message_handler(commands=['stats'])
def stats(message):
if checkauth(message):
data = get_stat(API_TOKEN)
bal = f'Баланс ({format_sign(data["gbal_delta"])})'
t2cdm = f'Time2cdm ({format_sign(data["time2cdm_delta"])})'
max_len = max(len(bal), len(t2cdm), 19)
bot.reply_to(message, f'''
```json
{bal.ljust(max_len)}: {data["gbal"]}
{t2cdm.ljust(max_len)}: {data["time2cdm"]}
Среднее значение : {data["average"]}
Медиана : {data["median"]}
Минимум : {data["min"]}
Максимум : {data["max"]}
Ввод/вывод алмазов : {data["up_diamond"]}
```
''', parse_mode='Markdown')
@bot.message_handler(commands=['course'])
def course(message):
conf = read('conf.json')
if message.from_user.id == conf['owner']:
bot.reply_to(message, f'''Текущий курс: `{conf['time2cdm']}`
CDM в час: `{conf['time2cdm']*3600}`''', parse_mode = 'Markdown')
@bot.message_handler(commands=['set_course'])
def set_course(message):
conf = read('conf.json')
if message.from_user.id == conf['owner']:
conf['time2cdm'] = float(message.text.split()[1])
write(conf, 'conf.json')
bot.reply_to(message, f'''Установлен новый курс: `{conf['time2cdm']}`
CDM в час: `{conf['time2cdm']*3600}`''', parse_mode = 'Markdown')
@bot.message_handler(commands=['add'])
def add(message):
conf = read('conf.json')
if message.from_user.id == conf['owner']:
id = user_in_db(API_TOKEN, tg=message.chat.id)
amount = message.text.split()[1]
if add_coins(API_TOKEN, id, amount) == 'OK':
bot.reply_to(message, f'''Начислено `{amount}` CDM.''', parse_mode='Markdown')
else:
bot.reply_to(message, 'Что-то пошло не так...')
@bot.message_handler(commands=['burn'])
def burn(message):
conf = read('conf.json')
if message.from_user.id == conf['owner']:
id = user_in_db(API_TOKEN, tg=message.chat.id)
amount = message.text.split()[1]
if del_coins(API_TOKEN, id, amount) == 'OK':
bot.reply_to(message, f'''🔥Вы безвозвратно сожгли `{amount}` CDM.''', parse_mode='Markdown')
else:
bot.reply_to(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 = gen_token(API_TOKEN, id)
bot.reply_to(message, f'''Ваш новый токен: {hcode(f"{token}")}
ВНИМАНИЕ, не передавайте никому токен. Администрация не спрашивает токены.''', parse_mode='HTML')
@bot.message_handler(commands=['chat_id'])
def chat_id(message):
print(message.chat.id)
print(f'chat_id: `{message.chat.id}`')
bot.reply_to(message, f'chat\_id: `{message.chat.id}`', parse_mode='Markdown')
@bot.message_handler(commands=['user_id'])
def user_id(message):
bot.reply_to(message, f'user\_id: `{message.from_user.id}`', parse_mode='Markdown')
@bot.message_handler(func=lambda message: True)
def checks(message):
if message.text == 'Баланс':
@ -216,7 +338,6 @@ def transfer_callback_api(it: Transfer_callback_api):
if token in db['tokens']:
dst_id = user_in_db(API_TOKEN, nick=dst_nick)
tg_dst = int(get_tg(API_TOKEN, id=dst_id))
print(tg_dst)
bot.send_message(tg_dst, f'''Вам перевели {hcode(amount)} CDM.
Отправитель: {hcode(src_nick)}''', parse_mode='HTML')
@ -224,8 +345,34 @@ def transfer_callback_api(it: Transfer_callback_api):
else:
return 'Error'
# Генерация сообщения с быстрым платежом
class Gen_fp_mess_api(BaseModel):
token: str
nick: str
amount: str
chat_id: str
fp_id: str
@app.post('/api/gen_fp_mess/')
def gen_fp_mess_api(it: Gen_fp_mess_api):
try:
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={fp_id}')
keyboard.add(url_button)
bot.send_message(int(chat_id), f'''
`----- ЧЕК -----`
Сумма: `{amount}` CDM
Получатель: `{nick}`
`---------------`''', parse_mode='Markdown', reply_markup=keyboard)
return 'OK'
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)

180
user_api.py Normal file
View File

@ -0,0 +1,180 @@
from fastapi import FastAPI, Request, HTTPException
from pydantic import BaseModel
from typing import Optional
from time import time
# Отключение логирования для уменьшения нагрузки
import logging
logging.disable(logging.CRITICAL)
# Fix 3.3 + 0.15 = 3.4499999999999997
from decimal import Decimal as d
def fix_add(one, two):
return float(d(str(one)) + d(str(two)))
def fix_sub(one, two):
return float(d(str(one)) - d(str(two)))
from db import *
from call2api import *
app = FastAPI()
API_TOKEN = read('conf.json')['api_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]:
return True
else:
return False
# Анти-DDoS
# Случайные тексты
from faker import Faker
from random import choice, randint
FAKE_TEXTS = [Faker().text(max_nb_chars=100) for _ in range(100)]
# Проверка на частоту обращений
LAST_REQUESTS = {}
def too_fast(request):
ip = request.client.host
now = time()
if ip in LAST_REQUESTS and (now - LAST_REQUESTS[ip]) < 0.1:
return True
LAST_REQUESTS[ip] = time()
return False
class Check_token_user(BaseModel):
nick: str
token: str
@app.post('/api/check_token/')
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 check_token(nick, token):
return 'OK'
else:
return 'Error'
class Check_bal_user(BaseModel):
nick: str
token: str
@app.post('/api/check_bal/')
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 check_token(nick, token):
id = user_in_db(API_TOKEN, nick=nick)
return check_bal(API_TOKEN, id)
else:
return 'Error'
class Get_time2cdm_user(BaseModel):
nick: str
token: str
@app.post('/api/get_time2cdm/')
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 check_token(nick, token):
id = user_in_db(API_TOKEN, nick=nick)
return get_time2cdm(API_TOKEN, id)
else:
return 'Error'
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, 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 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/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 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/')
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'
if __name__ == '__main__':
import uvicorn
uvicorn.run(app, host='0.0.0.0', port=7010)