gitscope
← marzneshin / Diff · eafb4a4 → eafb4a4
Changes eafb4a4..eafb4a4
Patch commit
diff --git a/Dockerfile b/Dockerfile
index c5439b2..abb5262 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,23 +2,14 @@ FROM python:3.10-slim
ENV PYTHONUNBUFFERED 1
-WORKDIR /code
+WORKDIR /app
-RUN apt-get update \
- && apt-get install -y curl unzip gcc python3-dev \
- && rm -rf /var/lib/apt/lists/*
+COPY . /app
-RUN bash -c "$(curl -L https://github.com/Gozargah/Marzban-scripts/raw/master/install_latest_xray.sh)"
+RUN apt-get update -y \
+ && apt-get install npm make -y --no-install-recommends \
+ && make dashboard-build \
+ && rm -rf /var/lib/apt/lists/* \
+ && pip install --no-cache-dir --upgrade -r /app/requirements.txt
-COPY ./requirements.txt /code/
-RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
-
-COPY . /code
-
-RUN apt-get remove -y curl unzip gcc python3-dev
-
-RUN ln -s /code/marzban-cli.py /usr/bin/marzban-cli \
- && chmod +x /usr/bin/marzban-cli \
- && marzban-cli completion install --shell bash
-
-CMD ["bash", "-c", "alembic upgrade head; python main.py"]
\ No newline at end of file
+CMD ["make", "start"]
diff --git a/app/dashboard/__init__.py b/app/dashboard/__init__.py
deleted file mode 100644
index b49a13b..0000000
--- a/app/dashboard/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-import os
-import subprocess
-from pathlib import Path
-
-from config import DEBUG, VITE_BASE_API
-
-path = '/dashboard/'
-base_dir = Path(__file__).parent
-build_dir = base_dir / 'build'
-
-
-def build():
- proc = subprocess.Popen(
- ['npm', 'run', 'build', '--', '--base', path, '--outDir', build_dir],
- env={**os.environ, 'VITE_BASE_API': VITE_BASE_API},
- cwd=base_dir
- )
- proc.wait()
- with open(build_dir / 'index.html', 'r') as file:
- html = file.read()
- with open(build_dir / '404.html', 'w') as file:
- file.write(html)
\ No newline at end of file
diff --git a/app/marzneshin.py b/app/marzneshin.py
index 941754c..2e823f5 100644
--- a/app/marzneshin.py
+++ b/app/marzneshin.py
@@ -10,20 +10,21 @@ from fastapi import FastAPI, Request, status
from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
-from fastapi.responses import HTMLResponse
-from fastapi.responses import JSONResponse
+from fastapi.responses import HTMLResponse, JSONResponse
from starlette.staticfiles import StaticFiles
-from uvicorn import Server, Config
+from uvicorn import Config, Server
import config
from app.templates import render_template
-from config import DOCS, DEBUG, UVICORN_SSL_KEYFILE, UVICORN_SSL_CERTFILE, UVICORN_UDS, UVICORN_PORT, UVICORN_HOST
-from config import HOME_PAGE_TEMPLATE
+from config import (DEBUG, DOCS, HOME_PAGE_TEMPLATE, UVICORN_HOST,
+ UVICORN_PORT, UVICORN_SSL_CERTFILE, UVICORN_SSL_KEYFILE,
+ UVICORN_UDS)
+
from . import __version__, telegram
-from .dashboard import build_dir, build, base_dir
from .routes import api_router
-from .tasks import record_user_usages, review_users, reset_user_data_usage, \
- record_realtime_bandwidth, send_notifications, delete_expired_reminders, nodes_startup
+from .tasks import (delete_expired_reminders, nodes_startup,
+ record_realtime_bandwidth, record_user_usages,
+ reset_user_data_usage, review_users, send_notifications)
logger = logging.getLogger(__name__)
dashboard_path = "/dashboard/"
@@ -53,14 +54,21 @@ app.add_middleware(
)
scheduler = AsyncIOScheduler(timezone="UTC")
-scheduler.add_job(record_user_usages, 'interval', coalesce=True, seconds=30)
-scheduler.add_job(review_users, 'interval', seconds=600, coalesce=True, max_instances=1)
-scheduler.add_job(reset_user_data_usage, 'interval', coalesce=True, hours=1)
-scheduler.add_job(record_realtime_bandwidth, 'interval', seconds=1, coalesce=True, max_instances=1)
+scheduler.add_job(record_user_usages, "interval", coalesce=True, seconds=30)
+scheduler.add_job(review_users, "interval", seconds=600, coalesce=True, max_instances=1)
+scheduler.add_job(reset_user_data_usage, "interval", coalesce=True, hours=1)
+scheduler.add_job(
+ record_realtime_bandwidth, "interval", seconds=1, coalesce=True, max_instances=1
+)
if config.WEBHOOK_ADDRESS:
scheduler.add_job(send_notifications, "interval", seconds=30, replace_existing=True)
- scheduler.add_job(delete_expired_reminders, "interval", hours=2, start_date=dt.utcnow() + td(minutes=1))
+ scheduler.add_job(
+ delete_expired_reminders,
+ "interval",
+ hours=2,
+ start_date=dt.utcnow() + td(minutes=1),
+ )
@app.on_event("startup")
@@ -87,22 +95,10 @@ def validation_exception_handler(request: Request, exc: RequestValidationError):
async def main():
- if DEBUG:
- proc = await asyncio.create_subprocess_exec(
- 'npm',
- 'run', 'dev', '--', '--host', '0.0.0.0', '--base',
- dashboard_path, '--clearScreen', 'false',
- env={**os.environ, 'VITE_BASE_API': config.VITE_BASE_API},
- cwd=base_dir
- )
- atexit.register(proc.terminate)
- else:
- if not build_dir.is_dir():
- build()
-
+ if not DEBUG:
app.mount(
"/dashboard/",
- StaticFiles(directory=build_dir, html=True),
+ StaticFiles(directory="app/dashboard/dist", html=True),
name="dashboard"
)
scheduler.start()
diff --git a/build_dashboard.sh b/build_dashboard.sh
deleted file mode 100755
index b7aeea6..0000000
--- a/build_dashboard.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-cd `dirname $0`/app/dashboard
-VITE_BASE_API=/api/ npm run build --if-present -- --outDir build --base '/dashboard/'
-cp ./build/index.html ./build/404.html
\ No newline at end of file
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
new file mode 100644
index 0000000..4b19798
--- /dev/null
+++ b/docker-compose.dev.yml
@@ -0,0 +1,8 @@
+services:
+ marzneshin:
+ image: marzneshin:latest
+ restart: always
+ env_file: .env
+ network_mode: host
+ volumes:
+ - /var/lib/marzneshin:/var/lib/marzneshin
diff --git a/docker-compose.yml b/docker-compose.yml
index f647593..4b19798 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,8 +1,8 @@
services:
- marzban:
- image: gozargah/marzban:latest
+ marzneshin:
+ image: marzneshin:latest
restart: always
env_file: .env
network_mode: host
volumes:
- - /var/lib/marzban:/var/lib/marzban
+ - /var/lib/marzneshin:/var/lib/marzneshin
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..f9661dd
--- /dev/null
+++ b/makefile
@@ -0,0 +1,17 @@
+
+start:
+ alembic upgrade head
+ python main.py
+
+dashboard-build:
+ cd app/dashboard/
+ npm install --prefix './app/dashboard'
+ VITE_BASE_API=/api/ npm run build --prefix './app/dashboard' --if-present -- --outDir dist --base '/dashboard/'
+ ls
+ cp ./app/dashboard/dist/index.html ./app/dashboard/dist/404.html
+
+dashboard-dev:
+ npm run dev \
+ -- --host 0.0.0.0 \
+ --base ../app/dashboard/ \
+ --clearScreen false
diff --git a/marzban-cli.py b/marzban-cli.py
index f177171..b904ac8 100755
--- a/marzban-cli.py
+++ b/marzban-cli.py
@@ -1,9 +1,6 @@
#!/usr/bin/env python3
-import os # noqa
-import readline # noqa
-import sys # noqa
-sys.path.insert(0, os.getcwd()) # noqa
+import os
import typer
from typer._completion_shared import Shells
@@ -19,32 +16,45 @@ app.add_typer(cli.user.app, name="user")
# Hidden completion app
-app_completion = typer.Typer(no_args_is_help=True, help="Generate and install completion scripts.", hidden=True)
+app_completion = typer.Typer(
+ no_args_is_help=True, help="Generate and install completion scripts.", hidden=True
+)
app.add_typer(app_completion, name="completion")
def get_default_shell() -> Shells:
- shell = os.environ.get('SHELL')
+ """
+ Find the default shell
+ """
+ shell = os.environ.get("SHELL")
if shell:
- shell = shell.split('/')[-1]
+ shell = shell.split("/")[-1]
if shell in Shells.__members__:
return getattr(Shells, shell)
return Shells.bash
-@app_completion.command(help="Show completion for the specified shell, to copy or customize it.")
-def show(ctx: typer.Context, shell: Shells = typer.Option(None,
- help="The shell to install completion for.",
- case_sensitive=False)) -> None:
+@app_completion.command(
+ help="Show completion for the specified shell, to copy or customize it."
+)
+def show(
+ ctx: typer.Context,
+ shell: Shells = typer.Option(
+ None, help="The shell to install completion for.", case_sensitive=False
+ ),
+) -> None:
if shell is None:
shell = get_default_shell()
typer.completion.show_callback(ctx, None, shell)
@app_completion.command(help="Install completion for the specified shell.")
-def install(ctx: typer.Context, shell: Shells = typer.Option(None,
- help="The shell to install completion for.",
- case_sensitive=False)) -> None:
+def install(
+ ctx: typer.Context,
+ shell: Shells = typer.Option(
+ None, help="The shell to install completion for.", case_sensitive=False
+ ),
+) -> None:
if shell is None:
shell = get_default_shell()
typer.completion.install_callback(ctx, None, shell)
@@ -52,4 +62,4 @@ def install(ctx: typer.Context, shell: Shells = typer.Option(None,
if __name__ == "__main__":
typer.completion.completion_init()
- app(prog_name=os.environ.get('CLI_PROG_NAME'))
+ app(prog_name=os.environ.get("CLI_PROG_NAME"))
diff --git a/install_service.sh b/tools/service-install.sh
similarity index 100%
rename from install_service.sh
rename to tools/service-install.sh