Compare commits

...

2 Commits

Author SHA1 Message Date
0db0405ea1 viewer and parser added
All checks were successful
SonarQube Scan / SonarQube Trigger (push) Successful in 1m44s
2024-12-20 00:00:21 +09:00
f8fe2c089f package path modified 2024-12-19 22:52:05 +09:00
7 changed files with 408 additions and 52 deletions

View File

@ -0,0 +1,25 @@
on:
# Trigger analysis when pushing to your main branches, and when creating a pull request.
push:
branches:
- main
- master
- develop
- 'releases/**'
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
name: SonarQube Scan
jobs:
sonarqube:
name: SonarQube Trigger
runs-on: ubuntu-latest
steps:
- name: Checking out
uses: actions/checkout@v4
with:
# Disabling shallow clone is recommended for improving relevancy of reporting
fetch-depth: 0
- name: SonarQube Scan
uses: kitabisa/sonarqube-action@v1.2.0
with:
host: https://sonar.ailaplacelab.com
login: sqa_a3988da69583c0ae606dae085f14e6ec901675f7

107
app.py
View File

@ -1,67 +1,72 @@
from mexc_sdk import Spot
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from pymongo import MongoClient
from datetime import datetime
import uvicorn
from urllib.parse import quote_plus
from dotenv import load_dotenv
import logging
import os
import yaml
with open("coin.yaml", "r") as file:
data = yaml.safe_load(file)
interest_coins = data["interest"]
# Set up logging
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
# Load the environment variables from the .env file
load_dotenv()
app = FastAPI()
class TradeBot(object):
def __init__(self, api_key, api_secret):
self.client = Spot(api_key=api_key, api_secret=api_secret)
self.symbol = "BTCUSDT"
def change_symbol(self, new_symbol):
self.symbol = new_symbol
# Setup templates directory
templates = Jinja2Templates(directory="templates")
def time(self):
# Format is in dict
return f"Server Time: {self.client.time()['serverTime']}"
MONGO_URI = f'mongodb://{quote_plus(os.getenv("DB_USER"))}:{quote_plus(os.getenv("DB_PWD"))}@{os.getenv("DB_HOST")}:{os.getenv("DB_PORT")}'
client = MongoClient(MONGO_URI)
db = client[os.getenv("DB_NAME")] # Replace with your database name
# collection = db["XRP"]
def get_market_price(self, symbol=None):
"""Get current market price for a symbol"""
try:
symbol = symbol or self.symbol
ticker = self.client.ticker_price(symbol)
price = float(ticker["price"])
logger.info(f"Current {symbol} price: {price}")
return price
except Exception as e:
logger.error(f"Error getting market price: {str(e)}")
return None
def get_account_balance(self):
"""Get account balance for all assets"""
try:
account_info = self.client.account_info()
balances = account_info["balances"]
@app.get("/", response_class=HTMLResponse)
async def read_data(request: Request):
return templates.TemplateResponse(
request=request, name="index.html", context={"coins": interest_coins}
)
logger.info("Account balances:")
for balance in balances:
if float(balance["free"]) > 0 or float(balance["locked"]) > 0:
logger.info(
f"{balance['asset']}: Free={balance['free']}, Locked={balance['locked']}"
)
return balances
except Exception as e:
logger.error(f"Error getting account balance: {str(e)}")
return None
@app.get("/coin/{coin}")
async def view_coin_graph(request: Request, coin: str):
if coin in interest_coins:
return templates.TemplateResponse(
request=request, name="coin.html", context={"coin": coin}
)
else:
return {"coin": "not found"}
@app.get("/data/{coin}")
async def get_data(coin):
collection = db[coin]
# Get last 100 data points, sorted by time
cursor = (
collection.find({}, {"_id": 0, "timestamp": 1, "price": 1})
.sort("timestamp", -1)
.limit(100)
)
data = list(cursor)
# Format the data for Chart.js
times = []
prices = []
for item in reversed(data): # Reverse to show oldest to newest
times.append(str(item["timestamp"]))
prices.append(float(item["price"]))
return {"times": times, "prices": prices}
if __name__ == "__main__":
# Access the variables
api_key = os.getenv("API_KEY")
api_secret = os.getenv("API_SECRET")
tb = TradeBot(api_key, api_secret)
print(tb.time())
tb.get_market_price()
tb.get_account_balance()
uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True)

9
coin.yaml Normal file
View File

@ -0,0 +1,9 @@
interest :
- BTC
- XRP
- DOGE
- ETH
- SOL
base:
- USDT

View File

@ -3,7 +3,7 @@ cattrs==24.1.2
exceptiongroup==1.2.2
importlib_resources==6.4.5
jsii==1.106.0
mexc-sdk @ file:///mnt/c/Users/dongho/Desktop/mexc/mexc-api-sdk/dist/python/mexc_sdk-1.0.0-py3-none-any.whl
mexc-sdk @ ./package/mexc_sdk-1.0.0-py3-none-any.whl
publication==0.0.3
python-dateutil==2.9.0.post0
python-dotenv==1.0.1

153
server.py Normal file
View File

@ -0,0 +1,153 @@
from mexc_sdk import Spot
from dotenv import load_dotenv
import yaml
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure, OperationFailure
import pytz
import logging
import os
from datetime import datetime
import time
from urllib.parse import quote_plus
# Set up logging
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
# Load the environment variables from the .env file
load_dotenv()
class MongoDBConn(object):
def __init__(self):
"""Initialize MongoDB connection parameters"""
self.username = quote_plus(os.getenv("DB_USER"))
self.password = quote_plus(os.getenv("DB_PWD"))
self.host = os.getenv("DB_HOST")
self.port = os.getenv("DB_PORT")
self.db_name = os.getenv("DB_NAME")
self.client = None
self.db = None
def connect(self):
"""Establish connection to MongoDB"""
try:
# Create connection URI
uri = f"mongodb://{self.username}:{self.password}@{self.host}:{self.port}"
# Connect to MongoDB
self.client = MongoClient(uri)
# Test the connection
self.client.admin.command("ping")
# Get database reference
self.db = self.client[self.db_name]
logger.info("Successfully connected to MongoDB")
return True
except ConnectionFailure as e:
logger.error(f"Could not connect to MongoDB: {e}")
return False
except OperationFailure as e:
logger.error(f"Authentication failed: {e}")
return False
except Exception as e:
logger.error(f"An error occurred: {e}")
return False
def close(self):
"""Close the MongoDB connection"""
if self.client:
self.client.close()
logger.info("MongoDB connection closed")
def insert_coin_price(self, collection_name, document):
"""Insert a single document into a collection"""
try:
collection = self.db[collection_name]
result = collection.insert_one(document)
logger.info(f"Document inserted with ID: {result.inserted_id}")
return result.inserted_id
except Exception as e:
logger.error(f"Error inserting document: {e}")
return None
class TradeBot(object):
def __init__(self, api_key, api_secret, mdb: MongoDBConn):
self.client = Spot(api_key=api_key, api_secret=api_secret)
self._load_coin()
self.timezone = pytz.timezone("Asia/Seoul")
self.mdb = mdb
def ttime(self):
# Format is in dict
return f"Server Time: {self.client.time()['serverTime']}"
def _get_current_time(self):
return datetime.now(self.timezone)
def _get_market_price(self, symbol=None):
"""Get current market price for a symbol"""
try:
symbol = symbol or self.symbol
ticker = self.client.ticker_price(symbol)
price = float(ticker["price"])
logger.info(f"Current {symbol} price: {price}")
return price
except Exception as e:
logger.error(f"Error getting market price: {str(e)}")
return None
def get_all_interset_market_price(self):
for coin in self.interest_coins:
data = {}
data["price"] = self._get_market_price(symbol=coin + self.base)
data["timestamp"] = self._get_current_time()
self.mdb.insert_coin_price(collection_name=coin, document=data)
def get_account_balance(self):
"""Get account balance for all assets"""
try:
account_info = self.client.account_info()
balances = account_info["balances"]
logger.info("Account balances:")
for balance in balances:
if float(balance["free"]) > 0 or float(balance["locked"]) > 0:
logger.info(
f"{balance['asset']}: Free={balance['free']}, Locked={balance['locked']}"
)
return balances
except Exception as e:
logger.error(f"Error getting account balance: {str(e)}")
return None
def _load_coin(self):
data = None
with open("coin.yaml", "r") as file:
data = yaml.safe_load(file)
self.interest_coins = data["interest"]
self.base = data["base"][0]
def main(tb: TradeBot):
while True:
tb.get_all_interset_market_price()
time.sleep(5)
if __name__ == "__main__":
mdb = MongoDBConn()
mdb.connect()
api_key = os.getenv("API_KEY")
api_secret = os.getenv("API_SECRET")
tb = TradeBot(api_key, api_secret, mdb)
main(tb)

123
templates/coin.html Normal file
View File

@ -0,0 +1,123 @@
<!DOCTYPE html>
<html>
<head>
<title>XRP Price Live Chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"></script>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f5f5f5;
}
.container {
max-width: 1200px;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
h1 {
color: #333;
text-align: center;
margin-bottom: 20px;
}
.chart-container {
position: relative;
height: 60vh;
width: 100%;
}
</style>
</head>
<body>
<div class="container">
<h1>XRP Price Live Chart</h1>
<div class="chart-container">
<canvas id="priceChart"></canvas>
</div>
</div>
<script>
let chart;
async function fetchData() {
try {
const response = await fetch('/data/{{coin}}');
const data = await response.json();
return data;
} catch (error) {
console.error('Error fetching data:', error);
return null;
}
}
async function updateChart() {
const data = await fetchData();
if (!data) return;
if (chart) {
chart.data.labels = data.times;
chart.data.datasets[0].data = data.prices;
chart.update();
} else {
const ctx = document.getElementById('priceChart').getContext('2d');
chart = new Chart(ctx, {
type: 'line',
data: {
labels: data.times,
datasets: [{
label: 'XRP Price (USD)',
data: data.prices,
borderColor: 'rgb(75, 192, 192)',
borderWidth: 2,
fill: true,
backgroundColor: 'rgba(75, 192, 192, 0.1)',
tension: 0.1,
pointRadius: 1,
pointHoverRadius: 5
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'XRP Price History'
}
},
scales: {
y: {
beginAtZero: false,
ticks: {
callback: function(value) {
return '$' + value.toFixed(4);
}
}
},
x: {
ticks: {
maxTicksLimit: 10,
maxRotation: 45,
minRotation: 45
}
}
},
interaction: {
intersect: false,
mode: 'index'
}
}
});
}
}
// Update every 5 seconds
updateChart();
setInterval(updateChart, 5000);
</script>
</body>
</html>

41
templates/index.html Normal file
View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Billionaire yes</title>
<style>
/* Add your CSS here */
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
</style>
</head>
<body>
<!-- Add your content here -->
<header>
<h1>To Become Billionaire</h1>
</header>
<main>
<section>
<h2>Interested Coints Live Chart</h2>
<ul>
{% for coin in coins %}
<li><a href="/coin/{{coin}}">{{coin}}</a></li>
{% endfor %}
</ul>
</section>
</main>
<footer>
<p>&copy; 2024 Dongho Kim</p>
</footer>
<script>
// Add your JavaScript here
</script>
</body>
</html>