taslim19
commited on
Commit
·
d384b52
0
Parent(s):
uploading
Browse files- Dockerfile +38 -0
- OneApi/__init__.py +50 -0
- OneApi/__main__.py +42 -0
- OneApi/api/create_project.py +22 -0
- OneApi/api/create_user.py +22 -0
- OneApi/api/delete_project.py +21 -0
- OneApi/api/delete_user.py +17 -0
- OneApi/api/disconnect_git.py +18 -0
- OneApi/api/exists.py +19 -0
- OneApi/api/get_projects.py +18 -0
- OneApi/api/get_repos.py +21 -0
- OneApi/api/host.py +22 -0
- OneApi/api/project_info.py +18 -0
- OneApi/api/set_repo.py +21 -0
- OneApi/api/user_info.py +16 -0
- OneApi/database/__init__.py +1 -0
- OneApi/database/methods/__init__.py +18 -0
- OneApi/database/methods/add_log.py +25 -0
- OneApi/database/methods/delete_user.py +25 -0
- OneApi/database/methods/disconnect_git.py +16 -0
- OneApi/database/methods/get_repo.py +21 -0
- OneApi/database/methods/get_repos.py +46 -0
- OneApi/database/methods/set_repo.py +43 -0
- OneApi/database/methods/user_info.py +20 -0
- OneApi/database/user.py +159 -0
- OneApi/deployment/__init__.py +5 -0
- OneApi/deployment/deployment.py +9 -0
- OneApi/deployment/host.py +87 -0
- OneApi/others/__init__.py +1 -0
- OneApi/others/gen_token.py +25 -0
- docker-compose.yml +32 -0
- mano.pem +27 -0
- requirements.txt +10 -0
- variables.py +6 -0
Dockerfile
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Use Python 3.11 slim image
|
2 |
+
FROM python:3.11-slim
|
3 |
+
|
4 |
+
# Set working directory
|
5 |
+
WORKDIR /app
|
6 |
+
|
7 |
+
# Install system dependencies
|
8 |
+
RUN apt-get update && apt-get install -y \
|
9 |
+
git \
|
10 |
+
curl \
|
11 |
+
wget \
|
12 |
+
&& rm -rf /var/lib/apt/lists/*
|
13 |
+
|
14 |
+
# Copy requirements first for better caching
|
15 |
+
COPY requirements.txt .
|
16 |
+
|
17 |
+
# Install Python dependencies
|
18 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
19 |
+
|
20 |
+
# Copy the entire application
|
21 |
+
COPY . .
|
22 |
+
|
23 |
+
# Create necessary directories
|
24 |
+
RUN mkdir -p /app/logs
|
25 |
+
|
26 |
+
# Expose port
|
27 |
+
EXPOSE 8080
|
28 |
+
|
29 |
+
# Set environment variables
|
30 |
+
ENV PYTHONPATH=/app
|
31 |
+
ENV PORT=8080
|
32 |
+
|
33 |
+
# Health check
|
34 |
+
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
|
35 |
+
CMD curl -f http://localhost:8080/ || exit 1
|
36 |
+
|
37 |
+
# Run the application
|
38 |
+
CMD ["python", "-m", "OneApi"]
|
OneApi/__init__.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from motor.motor_asyncio import AsyncIOMotorClient
|
2 |
+
from pymongo import MongoClient
|
3 |
+
import logging
|
4 |
+
from variables import *
|
5 |
+
import os
|
6 |
+
from quart import Quart
|
7 |
+
from pyrogram import *
|
8 |
+
from variables import *
|
9 |
+
import asyncio
|
10 |
+
|
11 |
+
logging.basicConfig(
|
12 |
+
format="[OneApi] %(name)s - %(levelname)s - %(message)s",
|
13 |
+
handlers=[logging.FileHandler("log.txt"), logging.StreamHandler()],
|
14 |
+
level=logging.INFO,
|
15 |
+
)
|
16 |
+
|
17 |
+
MONGO_DB_URI = os.environ.get("MONGO_DB_URL") or VAR_MONGO_DB_URI
|
18 |
+
API_ID = os.environ.get("API_ID") or VAR_API_ID
|
19 |
+
API_HASH = os.environ.get("API_HASH") or VAR_API_HASH
|
20 |
+
HANDLER = ["/"]
|
21 |
+
TOKEN = os.environ.get("TOKEN") or VAR_TOKEN
|
22 |
+
MY_VERSION = 0.1
|
23 |
+
DEVS = os.environ.get("DEVS") or VAR_DEVS
|
24 |
+
# _______________________________________
|
25 |
+
if not API_ID or not API_HASH or not TOKEN or not MONGO_DB_URI:
|
26 |
+
raise ValueError("Bro thought he can run anything lol, i mean you forgot some vars put on variables.py")
|
27 |
+
exit()
|
28 |
+
# _-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_-_+_|
|
29 |
+
if len(TOKEN) > 50: bot = Client("OneApi", session_string=TOKEN, api_id=API_ID, api_hash=API_HASH, plugins=dict(root="OneApi/pyro"))
|
30 |
+
else: bot = Client("OneApi", bot_token=TOKEN, api_id=API_ID, api_hash=API_HASH, plugins=dict(root="OneApi/pyro"))
|
31 |
+
# ———— R U N ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
32 |
+
async def run(command):
|
33 |
+
try:
|
34 |
+
process = await asyncio.create_subprocess_shell(
|
35 |
+
command,
|
36 |
+
stdout=asyncio.subprocess.PIPE,
|
37 |
+
stderr=asyncio.subprocess.PIPE,
|
38 |
+
start_new_session=True
|
39 |
+
)
|
40 |
+
stdout, stderr = await process.communicate()
|
41 |
+
if stdout:
|
42 |
+
return stdout.decode().strip()
|
43 |
+
if stderr:
|
44 |
+
return stderr.decode().strip()
|
45 |
+
except Exception as e:
|
46 |
+
logging.error(f"Failed to run command '{command}': {e}")
|
47 |
+
return False
|
48 |
+
# _______________________________________________________________
|
49 |
+
DATABASE = AsyncIOMotorClient(MONGO_DB_URI)["OneApi"]
|
50 |
+
app = Quart(__name__)
|
OneApi/__main__.py
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from quart_cors import cors
|
2 |
+
from quart import *
|
3 |
+
import asyncio
|
4 |
+
import os
|
5 |
+
from . import *
|
6 |
+
|
7 |
+
# BLUEPRINTS _____________________
|
8 |
+
from .api.exists import exists_bp
|
9 |
+
from .api.create_user import create_user_bp
|
10 |
+
from .api.get_projects import get_projects_bp
|
11 |
+
from .api.create_project import create_project_bp
|
12 |
+
from .api.delete_project import delete_project_bp
|
13 |
+
from .api.user_info import user_info_bp
|
14 |
+
from .api.get_repos import get_repos_bp
|
15 |
+
from .api.delete_user import delete_user_bp
|
16 |
+
from .api.disconnect_git import disconnect_git_bp
|
17 |
+
from .api.set_repo import set_repo_bp
|
18 |
+
from .api.project_info import project_info_bp
|
19 |
+
from .api.host import host_bp
|
20 |
+
|
21 |
+
app.register_blueprint(exists_bp)
|
22 |
+
app.register_blueprint(create_user_bp)
|
23 |
+
app.register_blueprint(get_projects_bp)
|
24 |
+
app.register_blueprint(create_project_bp)
|
25 |
+
app.register_blueprint(delete_project_bp)
|
26 |
+
app.register_blueprint(user_info_bp)
|
27 |
+
app.register_blueprint(get_repos_bp)
|
28 |
+
app.register_blueprint(delete_user_bp)
|
29 |
+
app.register_blueprint(disconnect_git_bp)
|
30 |
+
app.register_blueprint(set_repo_bp)
|
31 |
+
app.register_blueprint(project_info_bp)
|
32 |
+
app.register_blueprint(host_bp)
|
33 |
+
# ---------------------------------
|
34 |
+
|
35 |
+
app = cors(app, allow_origin="*")
|
36 |
+
|
37 |
+
@app.route('/')
|
38 |
+
async def home():
|
39 |
+
return jsonify({'success': 'server online'}), 200
|
40 |
+
|
41 |
+
if __name__ == '__main__':
|
42 |
+
app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
|
OneApi/api/create_project.py
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ..database import *
|
2 |
+
from quart import *
|
3 |
+
from .. import *
|
4 |
+
|
5 |
+
user = user()
|
6 |
+
create_project_bp = Blueprint('create_project', __name__)
|
7 |
+
|
8 |
+
@app.route('/create_project/', methods=['POST'])
|
9 |
+
async def create_project():
|
10 |
+
data = await request.get_json()
|
11 |
+
if not data or not 'user_id' in data and not 'name' in data and not 'plan' in data:
|
12 |
+
return jsonify({'error': 'missing user_id or name'}), 400
|
13 |
+
user_id = int(data.get('user_id'))
|
14 |
+
name = data.get('name')
|
15 |
+
plan = data.get('plan')
|
16 |
+
mano = await user.create_project(name, user_id, plan)
|
17 |
+
if mano == 'ok':
|
18 |
+
return jsonify({'message': 'Successfully created'}), 200
|
19 |
+
elif 'Error' in mano:
|
20 |
+
return jsonify({'error': mano}), 400
|
21 |
+
else:
|
22 |
+
return jsonify({'message': mano}), 400
|
OneApi/api/create_user.py
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ..database import *
|
2 |
+
from quart import *
|
3 |
+
from .. import *
|
4 |
+
|
5 |
+
user = user()
|
6 |
+
create_user_bp = Blueprint('create_user', __name__)
|
7 |
+
|
8 |
+
@app.route('/create_user/', methods=['POST'])
|
9 |
+
async def create_user():
|
10 |
+
data = await request.get_json()
|
11 |
+
if not data or not 'user_id' in data and not 'name' in data: return jsonify({'error': 'missing user_id & name'}), 400
|
12 |
+
user_id = int(data.get('user_id'))
|
13 |
+
name = data.get('name')
|
14 |
+
d = await user.create(name, user_id)
|
15 |
+
if d == 'exists':
|
16 |
+
return jsonify({'message': "user exists"}), 400
|
17 |
+
elif 'Error' in str(d):
|
18 |
+
return jsonify({'error': d}), 400
|
19 |
+
elif d =='ok':
|
20 |
+
return jsonify({'message': 'done'}), 200
|
21 |
+
elif d == "Not connected":
|
22 |
+
return jsonify({'message': 'The user is not connected with GitHub app.'}), 400
|
OneApi/api/delete_project.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ..database import *
|
2 |
+
from quart import *
|
3 |
+
from .. import *
|
4 |
+
|
5 |
+
user = user()
|
6 |
+
delete_project_bp = Blueprint('delete_project', __name__)
|
7 |
+
|
8 |
+
@app.route('/delete_project/', methods=['POST'])
|
9 |
+
async def delete_project():
|
10 |
+
data = await request.get_json()
|
11 |
+
if not data or not 'user_id' in data and not 'project_id' in data:
|
12 |
+
return jsonify({'error': 'missing user_id or project_id'}), 400
|
13 |
+
user_id = int(data.get('user_id'))
|
14 |
+
project_id = int(data.get('project_id'))
|
15 |
+
mano = await user.delete_project(user_id, project_id)
|
16 |
+
if mano == 'Project not found' or mano == 'not exists':
|
17 |
+
return jsonify({'message': mano}), 404
|
18 |
+
elif 'Error' in mano:
|
19 |
+
return jsonify({'error': mano}), 400
|
20 |
+
elif 'ok' in mano:
|
21 |
+
return jsonify({'message': mano}), 200
|
OneApi/api/delete_user.py
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ..database import *
|
2 |
+
from quart import *
|
3 |
+
from .. import *
|
4 |
+
|
5 |
+
user = user()
|
6 |
+
delete_user_bp = Blueprint('delete_user', __name__)
|
7 |
+
|
8 |
+
@app.route('/delete_user/', methods=['POST'])
|
9 |
+
async def delete_user():
|
10 |
+
data = await request.get_json()
|
11 |
+
if not data or not 'user_id' in data: return jsonify({'error': 'missing user_id'}), 400
|
12 |
+
user_id = int(data.get('user_id'))
|
13 |
+
d = await user.delete_user(user_id)
|
14 |
+
if d is True:
|
15 |
+
return jsonify({"message": "Successfully deleted user!"}), 200
|
16 |
+
elif "Error" in d:
|
17 |
+
return jsonify({"error": d}), 400
|
OneApi/api/disconnect_git.py
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ..database import *
|
2 |
+
from quart import *
|
3 |
+
from .. import *
|
4 |
+
import logging
|
5 |
+
|
6 |
+
user = user()
|
7 |
+
disconnect_git_bp = Blueprint('disconnect_git', __name__)
|
8 |
+
|
9 |
+
@app.route('/disconnect_git/', methods=['POST'])
|
10 |
+
async def disconnect_git():
|
11 |
+
data = await request.get_json()
|
12 |
+
if not data or not 'user_id' in data: return jsonify({'error': 'missing user_id'}), 400
|
13 |
+
user_id = int(data.get('user_id'))
|
14 |
+
mano = await user.disconnect_git(user_id)
|
15 |
+
if mano is True:
|
16 |
+
return jsonify({"message": "Successfully disconnected git"}), 200
|
17 |
+
elif 'Error' in mano:
|
18 |
+
return jsonify({'error': mano}), 400
|
OneApi/api/exists.py
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ..database import *
|
2 |
+
from quart import *
|
3 |
+
from .. import *
|
4 |
+
import logging
|
5 |
+
|
6 |
+
user = user()
|
7 |
+
exists_bp = Blueprint('exists', __name__)
|
8 |
+
|
9 |
+
@app.route('/exists/', methods=['POST'])
|
10 |
+
async def exists():
|
11 |
+
data = await request.get_json()
|
12 |
+
if not data or not 'user_id' in data: return jsonify({'error': 'missing user_id'}), 400
|
13 |
+
user_id = int(data.get('user_id'))
|
14 |
+
|
15 |
+
d = await user.find(user_id, check=True)
|
16 |
+
if d: return jsonify({'message': 'user exists'}), 200
|
17 |
+
elif not d: return jsonify({'message': "user not found"}), 404
|
18 |
+
elif 'Error' in d: return jsonify({'error': d}), 400
|
19 |
+
else: logging.info(d)
|
OneApi/api/get_projects.py
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ..database import *
|
2 |
+
from quart import *
|
3 |
+
from .. import *
|
4 |
+
|
5 |
+
user = user()
|
6 |
+
get_projects_bp = Blueprint('get_projects', __name__)
|
7 |
+
|
8 |
+
@app.route('/get_projects/', methods=['POST'])
|
9 |
+
async def get_projects():
|
10 |
+
data = await request.get_json()
|
11 |
+
if not data or not 'user_id' in data: return jsonify({'error': 'missing user_id'}), 400
|
12 |
+
user_id = int(data.get('user_id'))
|
13 |
+
ohk = await user.get_projects(user_id)
|
14 |
+
if ohk == "projects not found" or ohk == "not exists":
|
15 |
+
return jsonify({"message": ohk}), 404
|
16 |
+
elif 'Error' in ohk:
|
17 |
+
return jsonify({"error": ohk}), 400
|
18 |
+
return jsonify({"message": ohk}), 200
|
OneApi/api/get_repos.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ..database import *
|
2 |
+
from quart import *
|
3 |
+
from .. import *
|
4 |
+
|
5 |
+
user = user()
|
6 |
+
get_repos_bp = Blueprint('get_repos', __name__)
|
7 |
+
|
8 |
+
@app.route('/get_repos/', methods=['POST'])
|
9 |
+
async def get_repos():
|
10 |
+
data = await request.get_json()
|
11 |
+
if not data or not 'user_id' in data: return jsonify({'error': 'missing user_id'}), 400
|
12 |
+
user_id = int(data.get('user_id'))
|
13 |
+
d = await user.get_repos(user_id)
|
14 |
+
if d == "not exists":
|
15 |
+
return jsonify({'message': 'user not exists'}), 404
|
16 |
+
elif d == 'failed':
|
17 |
+
return jsonify({'message': "Failed to get user repos"}), 400
|
18 |
+
elif 'Error' in d:
|
19 |
+
return jsonify({'error': d}), 400
|
20 |
+
else:
|
21 |
+
return jsonify({'message': d}), 200
|
OneApi/api/host.py
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ..database import *
|
2 |
+
from quart import *
|
3 |
+
import logging
|
4 |
+
from .. import *
|
5 |
+
from ..deployment.deployment import Deployment
|
6 |
+
|
7 |
+
user = user()
|
8 |
+
deploy = Deployment()
|
9 |
+
host_bp = Blueprint('host', __name__)
|
10 |
+
|
11 |
+
@app.route('/host/', methods=['POST'])
|
12 |
+
async def host():
|
13 |
+
data = await request.get_json()
|
14 |
+
if not data or not 'user_id' in data and not 'project_id' in data: return jsonify({'error': 'missing user_id or project_id'}), 400
|
15 |
+
user_id = int(data.get('user_id'))
|
16 |
+
project_id = int(data.get('project_id'))
|
17 |
+
|
18 |
+
mm = await deploy.host(user_id, project_id)
|
19 |
+
logging.info(f"DEBUG HOST API 18: {mm}")
|
20 |
+
if mm is True:
|
21 |
+
return jsonify({'message': 'Successfully hosted!'}), 200
|
22 |
+
return jsonify({'message': mm}), 400
|
OneApi/api/project_info.py
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ..database import *
|
2 |
+
from quart import *
|
3 |
+
from .. import *
|
4 |
+
|
5 |
+
user = user()
|
6 |
+
project_info_bp = Blueprint('project_info', __name__)
|
7 |
+
|
8 |
+
@app.route('/project_info/', methods=['POST'])
|
9 |
+
async def project_info():
|
10 |
+
data = await request.get_json()
|
11 |
+
if not data or not 'user_id' in data and not 'project_id' in data: return jsonify({'error': 'missing user_id or project_id'}), 400
|
12 |
+
user_id = int(data.get('user_id'))
|
13 |
+
project_id = int(data.get('project_id'))
|
14 |
+
|
15 |
+
mano = await user.find(f'p{user_id}{project_id}', project=True)
|
16 |
+
if mano:
|
17 |
+
return jsonify({'message': mano}), 200
|
18 |
+
return jsonify({'message': 'Cannot find the project!'}), 400
|
OneApi/api/set_repo.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ..database import *
|
2 |
+
from quart import *
|
3 |
+
from .. import *
|
4 |
+
|
5 |
+
user = user()
|
6 |
+
set_repo_bp = Blueprint('set_repo', __name__)
|
7 |
+
|
8 |
+
@app.route('/set_repo/', methods=['POST'])
|
9 |
+
async def set_repo():
|
10 |
+
data = await request.get_json()
|
11 |
+
if not data or not 'user_id' in data and not 'project_id' in data and not 'repo_id' in data: return jsonify({'error': 'missing user_id or project_id or repo_id'}), 400
|
12 |
+
user_id = int(data.get('user_id'))
|
13 |
+
project_id = int(data.get('project_id'))
|
14 |
+
repo_id = int(data.get('repo_id'))
|
15 |
+
|
16 |
+
mano = await user.set_repo(user_id, project_id, repo_id)
|
17 |
+
if mano == 'ok':
|
18 |
+
return jsonify({'message': mano}), 200
|
19 |
+
elif 'Error' in str(mano):
|
20 |
+
return jsonify({'error': mano}), 400
|
21 |
+
return jsonify({'message': mano}), 400
|
OneApi/api/user_info.py
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ..database import *
|
2 |
+
from quart import *
|
3 |
+
from .. import *
|
4 |
+
|
5 |
+
user = user()
|
6 |
+
user_info_bp = Blueprint('user_info', __name__)
|
7 |
+
|
8 |
+
@app.route('/user_info/', methods=['POST'])
|
9 |
+
async def user_info():
|
10 |
+
data = await request.get_json()
|
11 |
+
if not data or not 'user_id' in data: return jsonify({'error': 'missing user_id'}), 400
|
12 |
+
user_id = int(data.get('user_id'))
|
13 |
+
d = await user.user_info(user_id)
|
14 |
+
if d == 'not exists': return jsonify({'message': "user not found"}), 404
|
15 |
+
elif 'error' in d: return jsonify({'error': d}), 400
|
16 |
+
return jsonify({'message': d}), 200
|
OneApi/database/__init__.py
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
from .user import *
|
OneApi/database/methods/__init__.py
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .user_info import UserInfo
|
2 |
+
from .get_repos import GetRepos
|
3 |
+
from .delete_user import DeleteUser
|
4 |
+
from .disconnect_git import DisconnectGit
|
5 |
+
from .set_repo import SetRepo
|
6 |
+
from .add_log import addLog
|
7 |
+
from .get_repo import GetRepo
|
8 |
+
|
9 |
+
class Methods(
|
10 |
+
UserInfo,
|
11 |
+
GetRepos,
|
12 |
+
DeleteUser,
|
13 |
+
DisconnectGit,
|
14 |
+
SetRepo,
|
15 |
+
addLog,
|
16 |
+
GetRepo,
|
17 |
+
):
|
18 |
+
pass
|
OneApi/database/methods/add_log.py
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import traceback
|
2 |
+
import logging
|
3 |
+
|
4 |
+
class addLog:
|
5 |
+
async def add_log(self, user_id: int, project_id: int, log_text: str):
|
6 |
+
try:
|
7 |
+
db, cb = self.db, self.cb
|
8 |
+
user = await self.find(user_id)
|
9 |
+
project = await db.find_one({"_id": f"p{user_id}{project_id}"})
|
10 |
+
if not user: return 'not exists'
|
11 |
+
elif not project: return 'Project not found'
|
12 |
+
|
13 |
+
log = project.get('logs')[-10000:]
|
14 |
+
log += f"{self.lf}: {log_text}"
|
15 |
+
|
16 |
+
await db.update_one(
|
17 |
+
{"_id": f"p{user_id}{project_id}"},
|
18 |
+
{"$set": {
|
19 |
+
"logs": log
|
20 |
+
}}
|
21 |
+
)
|
22 |
+
return True
|
23 |
+
except Exception as r:
|
24 |
+
logging.error(traceback.format_exc())
|
25 |
+
return False
|
OneApi/database/methods/delete_user.py
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import traceback
|
2 |
+
import logging
|
3 |
+
|
4 |
+
class DeleteUser:
|
5 |
+
async def delete_user(self, user_id: int):
|
6 |
+
try:
|
7 |
+
user = await self.find(user_id)
|
8 |
+
if not user: "not exists"
|
9 |
+
db, cb = self.db, self.cb
|
10 |
+
await db.update_one({"_id": 1}, {"$pull": {"users": user_id}})
|
11 |
+
await db.delete_one({"_id": user_id})
|
12 |
+
for x in user.get('projects'):
|
13 |
+
if x.get('project_id'):
|
14 |
+
try: await db.delete_one({"_id": f"{user_id}{int(x.get('project_id'))}"})
|
15 |
+
except: pass
|
16 |
+
try:
|
17 |
+
await cb.update_one({"_id": 1}, {"$pull": {"users": user_id}})
|
18 |
+
await cb.delete_one({"_id": user_id})
|
19 |
+
except Exception as e: logging.error("Error on deleting user callback data ^_^: {user_id}, {e}")
|
20 |
+
return True
|
21 |
+
except Exception as e:
|
22 |
+
logging.error(traceback.format_exc())
|
23 |
+
return f"Error: {e}"
|
24 |
+
|
25 |
+
|
OneApi/database/methods/disconnect_git.py
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import traceback
|
2 |
+
import logging
|
3 |
+
|
4 |
+
class DisconnectGit:
|
5 |
+
async def disconnect_git(self, user_id: int):
|
6 |
+
try:
|
7 |
+
user = await self.find(user_id, check=True)
|
8 |
+
if not user: "not exists"
|
9 |
+
db, cb = self.db, self.cb
|
10 |
+
await cb.update_one({"_id": 1}, {"$pull": {"users": user_id}})
|
11 |
+
await cb.delete_one({"_id": user_id})
|
12 |
+
return True
|
13 |
+
except Exception as e:
|
14 |
+
logging.error(traceback.format_exc())
|
15 |
+
return f"Error: {e}"
|
16 |
+
|
OneApi/database/methods/get_repo.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
import traceback
|
3 |
+
|
4 |
+
class GetRepo:
|
5 |
+
async def get_repo(self, user_id: int, repo_id: int):
|
6 |
+
try:
|
7 |
+
db, cb = self.db, self.cb
|
8 |
+
user = await self.find(user_id)
|
9 |
+
if not user: return 'not exists'
|
10 |
+
hmm = await self.get_repos(user_id)
|
11 |
+
|
12 |
+
if not hmm: return False
|
13 |
+
|
14 |
+
yes = False
|
15 |
+
for x in hmm:
|
16 |
+
if int(x.get('id', 0)) == int(repo_id):
|
17 |
+
yes = x
|
18 |
+
break
|
19 |
+
if yes: return yes
|
20 |
+
except: logging.error(traceback.format_exc())
|
21 |
+
return False
|
OneApi/database/methods/get_repos.py
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import traceback
|
2 |
+
import logging
|
3 |
+
import httpx
|
4 |
+
|
5 |
+
class GetRepos:
|
6 |
+
async def get_repos(self, user_id: int):
|
7 |
+
try:
|
8 |
+
db, cb = self.db, self.cb
|
9 |
+
user = await self.find(user_id)
|
10 |
+
if not user: return 'not exists'
|
11 |
+
installation_id = (await cb.find_one({"_id": int(user_id)})).get('installation_id', None)
|
12 |
+
if not installation_id: return "not exists"
|
13 |
+
token = await self.gen_token(installation_id)
|
14 |
+
url = "https://api.github.com/installation/repositories?page=1"
|
15 |
+
headers = {
|
16 |
+
"Authorization": f"Bearer {token}",
|
17 |
+
"Accept": "application/vnd.github+json"
|
18 |
+
}
|
19 |
+
async with httpx.AsyncClient() as mano:
|
20 |
+
r = await mano.get(url, headers=headers)
|
21 |
+
if r.status_code == 200:
|
22 |
+
data = r.json()
|
23 |
+
if not data.get("repositories"): return []
|
24 |
+
ily = []
|
25 |
+
for x in data.get("repositories"):
|
26 |
+
name, full_name, id = x.get('name'), x.get('full_name'), x.get('id')
|
27 |
+
ily.append({'name': name, 'id': id, 'full_name': full_name})
|
28 |
+
try: pages = list(range(2, int(str(r.headers.get('Link', ''))[126])+1))
|
29 |
+
except Exception as w:
|
30 |
+
logging.error(f"GetRepos 30: {w}")
|
31 |
+
pages = []
|
32 |
+
for x in pages:
|
33 |
+
url = f"https://api.github.com/installation/repositories?page={x}"
|
34 |
+
k = await mano.get(url, headers=headers)
|
35 |
+
data = k.json()
|
36 |
+
if k.status_code == 200 and data.get("repositories"):
|
37 |
+
for x in data["repositories"]:
|
38 |
+
name, full_name, id = x.get('name'), x.get('full_name'), x.get('id')
|
39 |
+
ily.append({'name': name, 'id': id, 'full_name': full_name})
|
40 |
+
return ily
|
41 |
+
else:
|
42 |
+
logging.info(f"Failed to get repos of user: {user_id}: {r.text}")
|
43 |
+
return "failed"
|
44 |
+
except Exception as w:
|
45 |
+
logging.error(traceback.format_exc())
|
46 |
+
return f"Error: {w}"
|
OneApi/database/methods/set_repo.py
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import traceback
|
2 |
+
import logging
|
3 |
+
|
4 |
+
class SetRepo:
|
5 |
+
async def set_repo(self, user_id: int, project_id: int, repo_id: int):
|
6 |
+
try:
|
7 |
+
db, cb = self.db, self.cb
|
8 |
+
user = await self.find(user_id)
|
9 |
+
project = await db.find_one({"_id": f"p{user_id}{project_id}"})
|
10 |
+
if not user: return 'not exists'
|
11 |
+
elif not project: return 'Project not found'
|
12 |
+
|
13 |
+
hmm = await self.get_repos(user_id)
|
14 |
+
if not hmm:
|
15 |
+
logging.info(f"Set repo 16: {hmm}")
|
16 |
+
return 'Repo not found'
|
17 |
+
|
18 |
+
yes = False
|
19 |
+
for x in hmm:
|
20 |
+
if int(x.get('id', 0)) == int(repo_id):
|
21 |
+
yes = True
|
22 |
+
name = x.get('name')
|
23 |
+
break
|
24 |
+
if not yes:
|
25 |
+
logging.info("Cannot find project")
|
26 |
+
return 'Repo not found'
|
27 |
+
|
28 |
+
log = project.get('logs')
|
29 |
+
log += f"{self.lf}: Repo linked successfully"
|
30 |
+
|
31 |
+
await db.update_one(
|
32 |
+
{"_id": f"p{user_id}{project_id}"},
|
33 |
+
{"$set": {
|
34 |
+
"logs": log,
|
35 |
+
"repo": repo_id,
|
36 |
+
"repo_name": name
|
37 |
+
}}
|
38 |
+
)
|
39 |
+
return 'ok'
|
40 |
+
except Exception as e:
|
41 |
+
logging.error(traceback.format_exc())
|
42 |
+
return f"Error: {e}"
|
43 |
+
|
OneApi/database/methods/user_info.py
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import traceback
|
2 |
+
import logging
|
3 |
+
import httpx
|
4 |
+
|
5 |
+
class UserInfo:
|
6 |
+
async def user_info(self, user_id):
|
7 |
+
try:
|
8 |
+
from ..user import db
|
9 |
+
user = await self.find(user_id)
|
10 |
+
if not user: return "not exists"
|
11 |
+
data = {
|
12 |
+
"name": user.get('name'),
|
13 |
+
"coins": user.get('coins'),
|
14 |
+
"projects": len(user.get('projects')),
|
15 |
+
"git": user.get('git')
|
16 |
+
}
|
17 |
+
return data
|
18 |
+
except Exception as w:
|
19 |
+
logging.error(traceback.format_exc())
|
20 |
+
return f'Error: {w}'
|
OneApi/database/user.py
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .. import DATABASE
|
2 |
+
import logging
|
3 |
+
import traceback
|
4 |
+
from .methods import *
|
5 |
+
import httpx
|
6 |
+
from ..others import *
|
7 |
+
|
8 |
+
db = DATABASE['user_nelskk']
|
9 |
+
|
10 |
+
class user(Methods):
|
11 |
+
def __init__(self):
|
12 |
+
self.db = db
|
13 |
+
self.cb = DATABASE['cb']
|
14 |
+
self.gen_token = gen_token
|
15 |
+
self.lf = "\n[ElevenHost]"
|
16 |
+
async def find(self, user_id, project=False, check=False):
|
17 |
+
try:
|
18 |
+
if project:
|
19 |
+
return await db.find_one({"_id": str(user_id)})
|
20 |
+
elif check:
|
21 |
+
if await db.find_one({"_id": int(user_id)}) and await self.cb.find_one({"_id": user_id}):
|
22 |
+
return True
|
23 |
+
return False
|
24 |
+
user = await db.find_one({"_id": int(user_id)})
|
25 |
+
return user
|
26 |
+
except Exception as w:
|
27 |
+
e = traceback.format_exc()
|
28 |
+
logging.error(e)
|
29 |
+
return f"Error: {w}"
|
30 |
+
async def create(self, name: str, user_id: int):
|
31 |
+
try:
|
32 |
+
if await self.find(user_id): return "exists"
|
33 |
+
if not await self.cb.find_one({"_id": user_id}): return "Not connected"
|
34 |
+
url = "https://api.github.com/installation/repositories"
|
35 |
+
installation_id = await self.cb.find_one({"_id": user_id})
|
36 |
+
if installation_id and installation_id.get('installation_id'):
|
37 |
+
token = await self.gen_token(installation_id.get('installation_id'))
|
38 |
+
if not token: return "Not connected"
|
39 |
+
else: return "Not connected"
|
40 |
+
|
41 |
+
headers = {
|
42 |
+
"Authorization": f"Bearer {token}",
|
43 |
+
"Accept": "application/vnd.github+json"
|
44 |
+
}
|
45 |
+
|
46 |
+
async with httpx.AsyncClient() as client:
|
47 |
+
response = await client.get(url, headers=headers)
|
48 |
+
if response.status_code == 200:
|
49 |
+
data = response.json()
|
50 |
+
if data["repositories"]:
|
51 |
+
owner = data["repositories"][0]["owner"]
|
52 |
+
owner = owner["login"]
|
53 |
+
else: owner = 'CannotFound'
|
54 |
+
else:
|
55 |
+
logging.warn(f"GitHub doesn't give 200 status code: {response.text}")
|
56 |
+
return "Not connected"
|
57 |
+
|
58 |
+
await db.update_one({"_id": 1}, {"$addToSet": {"users": user_id}}, upsert=True)
|
59 |
+
await db.update_one(
|
60 |
+
{"_id": user_id},
|
61 |
+
{"$set": {"name": name, "coins": 0, "projects": [], 'latest_project': 0, 'git': owner}},
|
62 |
+
upsert=True
|
63 |
+
)
|
64 |
+
|
65 |
+
return 'ok'
|
66 |
+
|
67 |
+
except Exception as w:
|
68 |
+
e = traceback.format_exc()
|
69 |
+
logging.error(e)
|
70 |
+
return f"Error: {w}"
|
71 |
+
|
72 |
+
async def get_projects(self, user_id: int):
|
73 |
+
try:
|
74 |
+
if not await self.find(user_id): return "not exists"
|
75 |
+
user = await self.find(user_id)
|
76 |
+
if user.get('projects'):
|
77 |
+
return user.get('projects')
|
78 |
+
return 'projects not found'
|
79 |
+
except Exception as oh:
|
80 |
+
e = traceback.format_exc()
|
81 |
+
logging.error(e)
|
82 |
+
return f"Error: {oh}"
|
83 |
+
|
84 |
+
async def create_project(self, name: str, user_id: int, plan: str):
|
85 |
+
try:
|
86 |
+
user = await self.find(user_id)
|
87 |
+
if not user: return "not exists"
|
88 |
+
elif name and len(name) < 4:
|
89 |
+
return 'Name too short'
|
90 |
+
|
91 |
+
name, latest_project = name[:15], int(user.get('latest_project', 0)) + 1
|
92 |
+
coins = user.get('coins', 0)
|
93 |
+
|
94 |
+
if any(proj.get('name') == name for proj in user.get('projects', [])):
|
95 |
+
return "Name already used"
|
96 |
+
|
97 |
+
if plan == 'free':
|
98 |
+
plan_price = 0
|
99 |
+
elif plan == 'basic':
|
100 |
+
plan_price = 99
|
101 |
+
elif plan == 'advance':
|
102 |
+
plan_price = 199
|
103 |
+
elif plan == 'pro':
|
104 |
+
plan_price = 269
|
105 |
+
else: return 'Plan not found'
|
106 |
+
if coins < plan_price:
|
107 |
+
return 'insufficient coins'
|
108 |
+
|
109 |
+
if plan_price != 0: await db.update_one({"_id": user_id}, {"$set": {'coins': coins-plan_price}})
|
110 |
+
|
111 |
+
await db.update_one(
|
112 |
+
{"_id": f'p{user_id}{latest_project}'},
|
113 |
+
{"$set": {
|
114 |
+
"name": name,
|
115 |
+
"id": latest_project,
|
116 |
+
"plan": plan,
|
117 |
+
"ram": 10000,
|
118 |
+
"rom": 100000000,
|
119 |
+
"repo": 0,
|
120 |
+
"repo_name": 'Not set',
|
121 |
+
"apt-allowed": False,
|
122 |
+
"language": 'None',
|
123 |
+
"logs": f"[ElevenHost]: Project successfully created!"
|
124 |
+
}},
|
125 |
+
upsert=True
|
126 |
+
)
|
127 |
+
await db.update_one(
|
128 |
+
{"_id": user_id},
|
129 |
+
{"$addToSet": {
|
130 |
+
"projects": {
|
131 |
+
'name': name,
|
132 |
+
'project_id': latest_project
|
133 |
+
}
|
134 |
+
}}
|
135 |
+
)
|
136 |
+
await db.update_one({"_id": user_id}, {"$set": {"latest_project": latest_project}})
|
137 |
+
return 'ok'
|
138 |
+
except Exception as e:
|
139 |
+
logging.error(traceback.format_exc())
|
140 |
+
return f'Error: {e}'
|
141 |
+
|
142 |
+
async def delete_project(self, user_id: int, project_id: int):
|
143 |
+
try:
|
144 |
+
user = await self.find(user_id)
|
145 |
+
if not user:
|
146 |
+
return "not exists"
|
147 |
+
if not user.get('projects'):
|
148 |
+
return "Project not found"
|
149 |
+
if not any(proj.get('project_id') == project_id for proj in user.get('projects', [])):
|
150 |
+
return "Project not found"
|
151 |
+
await db.delete_one({"_id": f"p{user_id}{project_id}"})
|
152 |
+
await db.update_one(
|
153 |
+
{"_id": user_id},
|
154 |
+
{"$pull": {"projects": {"project_id": project_id}}}
|
155 |
+
)
|
156 |
+
return "ok"
|
157 |
+
except Exception as e:
|
158 |
+
logging.error(traceback.format_exc())
|
159 |
+
return f"Error: {e}"
|
OneApi/deployment/__init__.py
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .host import Host
|
2 |
+
class Methods(
|
3 |
+
Host
|
4 |
+
):
|
5 |
+
pass
|
OneApi/deployment/deployment.py
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .. import *
|
2 |
+
from . import Methods
|
3 |
+
from ..database import user
|
4 |
+
|
5 |
+
class Deployment(Methods):
|
6 |
+
def __init__(self):
|
7 |
+
self.lf = "\n[ElevenHost]"
|
8 |
+
self.database = user()
|
9 |
+
self.cb = DATABASE['cb']
|
OneApi/deployment/host.py
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .. import *
|
2 |
+
import logging
|
3 |
+
import traceback
|
4 |
+
import asyncio
|
5 |
+
import aiofiles
|
6 |
+
import aiofiles.os
|
7 |
+
import yaml
|
8 |
+
|
9 |
+
async def check_yaml(data):
|
10 |
+
f = "FileFormatInvalidError:"
|
11 |
+
if not data.get('language'):
|
12 |
+
return f'{f} Project language not found in ElevenHost.yaml'
|
13 |
+
elif not data.get('version'):
|
14 |
+
return f'{f} Project language version not found in ElevenHost.yaml'
|
15 |
+
elif not data.get('build'):
|
16 |
+
return f'{f} Build not found on ElevenHost.yaml'
|
17 |
+
elif not data.get('packages'):
|
18 |
+
return f'{f} Packages not found in ElevenHost.yaml'
|
19 |
+
elif not data.get("start"):
|
20 |
+
return f'{f} start not found in ElevenHost.yaml'
|
21 |
+
else: return True
|
22 |
+
|
23 |
+
async def create_docker(data):
|
24 |
+
dockerfile = f"FROM {data.get('language')}:{data.get('version')}\n\n"
|
25 |
+
dockerfile += ''.join([f"RUN {x}\n\n" for x in data.get('build')])
|
26 |
+
dockerfile += ''.join([f"RUN apt-get install {x} -y\n\n" for x in data.get('packages')])
|
27 |
+
dockerfile += f"COPY . /app/\n\nCMD {data.get('start')[0]}\n"
|
28 |
+
return dockerfile
|
29 |
+
|
30 |
+
class Host:
|
31 |
+
async def host(self, user_id: int, project_id: int):
|
32 |
+
database = self.database
|
33 |
+
user = await database.find(user_id)
|
34 |
+
project = await database.find(f"p{user_id}{project_id}", project=True)
|
35 |
+
if not user: return 'not exists'
|
36 |
+
elif not project: return 'Project not found'
|
37 |
+
repo_id = project.get('repo', 0)
|
38 |
+
repo = await database.get_repo(user_id, repo_id)
|
39 |
+
if not repo: return "Repo not found"
|
40 |
+
|
41 |
+
installation_id = (await self.cb.find_one({"_id": int(user_id)})).get('installation_id', None)
|
42 |
+
if not installation_id: return "not exists"
|
43 |
+
token = await database.gen_token(installation_id)
|
44 |
+
|
45 |
+
try:
|
46 |
+
folder = f"deployment{user_id}"
|
47 |
+
await database.add_log(user_id, project_id, "Clonning repo from github...")
|
48 |
+
await run(f"rm -rf {folder}")
|
49 |
+
await run(f"mkdir {folder}")
|
50 |
+
ok = await run(f"cd {folder} && git clone https://x-access-token:{token}@github.com/{repo.get('full_name')}/")
|
51 |
+
repo_folder = f"{folder}/{repo.get('name')}"
|
52 |
+
|
53 |
+
if not await aiofiles.os.path.isdir(repo_folder):
|
54 |
+
await database.add_log(user_id, project_id, f"Error on clonning repo: {ok}")
|
55 |
+
return 'Failed to host repo'
|
56 |
+
ls = await run(f"ls {repo_folder}")
|
57 |
+
|
58 |
+
await database.add_log(
|
59 |
+
user_id,
|
60 |
+
project_id,
|
61 |
+
f"Successfully clonned repo!, Files found in repo: {len(ls.split('\n')) if '\n' in ls else 0}"
|
62 |
+
)
|
63 |
+
|
64 |
+
if not await aiofiles.os.path.isfile(f"{repo_folder}/ElevenHost.yaml"):
|
65 |
+
await database.add_log(
|
66 |
+
user_id,
|
67 |
+
project_id,
|
68 |
+
f"Error:\nCannot find ElevenHost.yaml on your repo"
|
69 |
+
)
|
70 |
+
return "ElevenHost.yaml not found"
|
71 |
+
|
72 |
+
async with aiofiles.open(f"{repo_folder}/ElevenHost.yaml", mode='r') as mano:
|
73 |
+
ctx = mano.read()
|
74 |
+
data = yaml.safe_load(ctx)
|
75 |
+
chk = await check_yaml(data)
|
76 |
+
|
77 |
+
if not chk is True:
|
78 |
+
await database.add_log(user_id, project_id, chk)
|
79 |
+
return chk
|
80 |
+
|
81 |
+
return True
|
82 |
+
except Exception as w:
|
83 |
+
logging.error(traceback.format_exc())
|
84 |
+
return f"Error: {w}"
|
85 |
+
|
86 |
+
|
87 |
+
|
OneApi/others/__init__.py
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
from .gen_token import gen_token
|
OneApi/others/gen_token.py
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import jwt
|
2 |
+
from time import time
|
3 |
+
import httpx
|
4 |
+
|
5 |
+
with open("mano.pem", "r") as f:
|
6 |
+
PRIVATE_KEY = f.read()
|
7 |
+
APP_ID = "1109508"
|
8 |
+
|
9 |
+
async def gen_token(installation_id):
|
10 |
+
payload = {
|
11 |
+
"iat": int(time()),
|
12 |
+
"exp": int(time()) + 60,
|
13 |
+
"iss": APP_ID,
|
14 |
+
}
|
15 |
+
jwt_token = jwt.encode(payload, PRIVATE_KEY, algorithm="RS256")
|
16 |
+
url = f"https://api.github.com/app/installations/{installation_id}/access_tokens"
|
17 |
+
headers = {
|
18 |
+
"Authorization": f"Bearer {jwt_token}",
|
19 |
+
"Accept": "application/vnd.github+json",
|
20 |
+
}
|
21 |
+
async with httpx.AsyncClient() as client:
|
22 |
+
response = await client.post(url, headers=headers)
|
23 |
+
if response.status_code == 201:
|
24 |
+
return response.json().get("token")
|
25 |
+
return None
|
docker-compose.yml
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
version: '3.8'
|
2 |
+
|
3 |
+
services:
|
4 |
+
oneapi:
|
5 |
+
build: .
|
6 |
+
ports:
|
7 |
+
- "8080:8080"
|
8 |
+
environment:
|
9 |
+
- MONGO_DB_URL=mongodb://mongo:27017/OneApi
|
10 |
+
- API_ID=${API_ID:-29764570}
|
11 |
+
- API_HASH=${API_HASH:-7676192e491329a1b859b2184e5d7823}
|
12 |
+
- TOKEN=${TOKEN:-BQCDh4MAZuO8dsEXNE9pCZtV297oEptGvaTC75QL9GSgnhG8eZP4GVWQqPCzbKxyhN8iCsDX2HG72JIC_LVOYL6-aB3TcuY9eafbv2sKq-usHKOUA8lXf1RUzkaeYA1QNvjSU9hZrKCbrH6NtfuPzkFQeRCYhK-z2GDekhykPqLEHJu0hewOYtdwbC_om47iF3rUL94Wi3UOhAVzr_IZeklt8IIbL6stzR7dIce17ZbIlNGsVwZr6qMgBh-CYl4A0XlCh_iuMyRAmYHJ9nBQR-OhxuwewMDl9R8AvvHxnE3KYEbX2NGTFaOacWg5mtd4cm8OIf8ese4oC-TnspkFSmUPEQwNXwAAAAG1SBMOAQ}
|
13 |
+
- DEVS=${DEVS:-5965055071}
|
14 |
+
- PORT=8080
|
15 |
+
depends_on:
|
16 |
+
- mongo
|
17 |
+
volumes:
|
18 |
+
- ./logs:/app/logs
|
19 |
+
restart: unless-stopped
|
20 |
+
|
21 |
+
mongo:
|
22 |
+
image: mongo:6.0
|
23 |
+
ports:
|
24 |
+
- "27017:27017"
|
25 |
+
environment:
|
26 |
+
- MONGO_INITDB_DATABASE=OneApi
|
27 |
+
volumes:
|
28 |
+
- mongo_data:/data/db
|
29 |
+
restart: unless-stopped
|
30 |
+
|
31 |
+
volumes:
|
32 |
+
mongo_data:
|
mano.pem
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
-----BEGIN RSA PRIVATE KEY-----
|
2 |
+
MIIEpAIBAAKCAQEA1gNfDkAFX+K/ug05GXdigs4sHrL/ZDSV2Vj4h8uZb6UXJeoe
|
3 |
+
I6O2kjKC5Zbo2F+JwbC0nhnzhlngUadjUWXJtnkANyEPk+Hxk56qIo2akRN8KHEL
|
4 |
+
aWpXPznwj0ZxP4s3hEwgmDc7n5Kpl9w8nYT6MAUuyB2NZ6E/dRTPU6NHDyuf0yhS
|
5 |
+
h98A2ZXcqWHrwtVUHq/I4oEAfu3xvUhoYeODS5MrJV2oLy2crXPUb2t1/AyIl5q4
|
6 |
+
9B3Dj4UYKZTEEDUjCZ+oueo8XDA5xCv8WYYsdYf484lf3po8f4yLBEI2i9aWGnEs
|
7 |
+
enWsOI65MYyvXagUbzFyN0XnZNNp3T0xgvoJMwIDAQABAoIBAEywEJPOpR5i5kkJ
|
8 |
+
C/jwKsCsmGq3wYRqw3eKxiQC9QxooA7aAcrLk1R3/SfAF9fRBE//vfkZW4Y9FoCr
|
9 |
+
9o7oZouYeFdI5YgcYrB/HoAbNdPeo5LqTyiLDpB9dpIgr9wRSueBT/y7bgYUS+k6
|
10 |
+
5g2b5ProIIdc75q+0TpnJpPV4lSwqWTt6IcuXadx/YdgFLtfa07z1mMwBUQi/GXZ
|
11 |
+
kjJkpTNG22pItP1oYSY22EfuIFYkmsx2c44VT61D/Xa01ABk4pOSYZzQXePqymG5
|
12 |
+
qI1w7SsuOFQVZIGYuiM8fBBv4Yd9MyJ4KBWG24H2TFw0XjiLmQgYBWuv15foSujv
|
13 |
+
7+z2s6ECgYEA7TmPTShVj4DrGiSsGjgYbHTXybWdxdDnP7b+39/e2tFFax+n06sP
|
14 |
+
1YzWWhQI40uZ0kyCLLiSS6arxhjw9swzAet2NsN+k9u72Qz/Y/XIVT8mmXBc+4I3
|
15 |
+
2YwJU0cPx2unGjUHYx9Am+23o3KHceIFDtyAsljBiJ0CAuTbg9r+APcCgYEA5vOE
|
16 |
+
YV23spoe6SME9XpMKLHreSWUWCeMVhkPJZIIlkCHD2m8o+sB1+MApnRBvHWHU5sC
|
17 |
+
OOYzt7fMQM/c2aLLSVwGl7Be5XURBcBq984pxq9uolUb0OcTYPIh23ZtlV+Zi1Xr
|
18 |
+
b/42DiWVIVFN8gmt59adPe6X3n/1pnHJwIbnZqUCgYEAyZpxPpFYpWxaYQ1pdZ7W
|
19 |
+
otVpzfKa8tJmtK9AS+Jl8nCHHlL4vdpSypm2UTdVllVZlG+Q8ZCqQ8CRmvj3T8aa
|
20 |
+
UrdY75GUsPO84Ok64iiu6EOS+jOT0esIq8lm428w6bmDebI3ZPXaYqnTtwRON2pu
|
21 |
+
AgNDHE5xqzhDzVHRfG1QEGECgYBG5/L31cclbY4Z8+d82nxxbhamjjQaUKIUeQMe
|
22 |
+
fNRoFQ2iXMtO5EMfnhFACad5DfhrYcbv4zVzrVlneKoMo5+YOUnI3px0BFoiku4E
|
23 |
+
gOZwmsHz0v+ERr27YPumHpkMaFqC3fE35CuCcmVz4jt1GSWsbUa/kfZMmKq53Gud
|
24 |
+
0Y1QBQKBgQCMdt81IsLWCTUQI09Y+9tq/9CqGOUhRGXwG9RCaWrqBBLWWgR8kQVK
|
25 |
+
pYdR2MlqHpwywcOAhlOU7r0Cmbonf8cnZuFv6FMI405KExSMIUyhhrbDbYwPNEUo
|
26 |
+
ODb/k7oa2AanEasVm8uQgoA/RSNA1zyzFZ8tkFDJ1V6CSQgzAkLAXg==
|
27 |
+
-----END RSA PRIVATE KEY-----
|
requirements.txt
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
quart
|
2 |
+
motor==3.6.0
|
3 |
+
pymongo[srv]
|
4 |
+
kurigram
|
5 |
+
TgCrypto
|
6 |
+
quart-cors
|
7 |
+
cryptography
|
8 |
+
pyjwt
|
9 |
+
aiofiles
|
10 |
+
pyyaml
|
variables.py
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
VAR_TOKEN = "8185712635:AAFqz_RmsleAbfSeVw--SGw5PaWQS3Cqan0"
|
2 |
+
VAR_MONGO_DB_URI = "mongodb+srv://xdragxt:[email protected]/?retryWrites=true&w=majority&appName=dragtest"
|
3 |
+
VAR_API_ID = 21188444
|
4 |
+
VAR_API_HASH = "031ff911c40173e28290e2f44fcb4b56"
|
5 |
+
VAR_DEVS = 7361622601
|
6 |
+
|