From 0db0405ea1b9ab32a7bf1c8c49979f15b383399c Mon Sep 17 00:00:00 2001 From: dongho Date: Fri, 20 Dec 2024 00:00:21 +0900 Subject: [PATCH] viewer and parser added --- .gitea/workflows/analyze.yaml | 25 ++++++ app.py | 107 ++++++++++++------------ coin.yaml | 9 ++ server.py | 153 ++++++++++++++++++++++++++++++++++ templates/coin.html | 123 +++++++++++++++++++++++++++ templates/index.html | 41 +++++++++ 6 files changed, 407 insertions(+), 51 deletions(-) create mode 100644 .gitea/workflows/analyze.yaml create mode 100644 coin.yaml create mode 100644 server.py create mode 100644 templates/coin.html create mode 100644 templates/index.html diff --git a/.gitea/workflows/analyze.yaml b/.gitea/workflows/analyze.yaml new file mode 100644 index 0000000..bb8042a --- /dev/null +++ b/.gitea/workflows/analyze.yaml @@ -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 \ No newline at end of file diff --git a/app.py b/app.py index 19eeea6..94da6e5 100644 --- a/app.py +++ b/app.py @@ -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) diff --git a/coin.yaml b/coin.yaml new file mode 100644 index 0000000..d8b0afe --- /dev/null +++ b/coin.yaml @@ -0,0 +1,9 @@ +interest : + - BTC + - XRP + - DOGE + - ETH + - SOL + +base: + - USDT \ No newline at end of file diff --git a/server.py b/server.py new file mode 100644 index 0000000..6ac9072 --- /dev/null +++ b/server.py @@ -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) diff --git a/templates/coin.html b/templates/coin.html new file mode 100644 index 0000000..f0a5747 --- /dev/null +++ b/templates/coin.html @@ -0,0 +1,123 @@ + + + + XRP Price Live Chart + + + + +
+

XRP Price Live Chart

+
+ +
+
+ + + + \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..3e66aa1 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,41 @@ + + + + + + Billionaire yes + + + + +
+

To Become Billionaire

+
+ +
+
+

Interested Coints Live Chart

+
    + {% for coin in coins %} +
  • {{coin}}
  • + {% endfor %} +
+
+
+ + + + + + \ No newline at end of file