Compare commits
5 Commits
87396a20da
...
9b9c25806b
| Author | SHA1 | Date | |
|---|---|---|---|
| 9b9c25806b | |||
| 065ac7f250 | |||
| 0a5251ec10 | |||
| eb60fc4dd3 | |||
| 888ed093a1 |
@@ -2,6 +2,7 @@ FROM python:3.13-slim
|
|||||||
|
|
||||||
ARG puid=1000
|
ARG puid=1000
|
||||||
ARG pgid=1000
|
ARG pgid=1000
|
||||||
|
ARG debug=false
|
||||||
ENV PYTHONUNBUFFERED=1 \
|
ENV PYTHONUNBUFFERED=1 \
|
||||||
PYTHONDONTWRITEBYTECODE=1 \
|
PYTHONDONTWRITEBYTECODE=1 \
|
||||||
LANG=C.UTF-8 \
|
LANG=C.UTF-8 \
|
||||||
@@ -40,8 +41,13 @@ RUN yarn install
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN pip install --upgrade pip
|
RUN pip install --upgrade pip
|
||||||
|
|
||||||
COPY ./requirements.txt ./requirements.txt
|
COPY requirements*.txt ./
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
RUN if [ "$debug" = "true" ] ; then \
|
||||||
|
pip install --no-cache-dir -r requirements-dev.txt ; \
|
||||||
|
else \
|
||||||
|
pip install --no-cache-dir -r requirements-prod.txt ; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
#COPY . .
|
#COPY . .
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ INSTALLED_APPS = [
|
|||||||
'api',
|
'api',
|
||||||
'torrent',
|
'torrent',
|
||||||
]
|
]
|
||||||
|
if DEBUG:
|
||||||
|
INSTALLED_APPS = ["daphne"] + INSTALLED_APPS
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
@@ -139,6 +141,7 @@ USE_TZ = True
|
|||||||
|
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
STATICFILES_DIRS = [
|
STATICFILES_DIRS = [
|
||||||
|
BASE_DIR / "static",
|
||||||
BASE_DIR / "frontend/dist",
|
BASE_DIR / "frontend/dist",
|
||||||
]
|
]
|
||||||
STATIC_ROOT = BASE_DIR / "static_collected"
|
STATIC_ROOT = BASE_DIR / "static_collected"
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ Including another URLconf
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path, include # Added include for including app URLs
|
from django.urls import path, include # Added include for including app URLs
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
from django.views.generic import RedirectView
|
||||||
from django.contrib.auth.views import (
|
from django.contrib.auth.views import (
|
||||||
PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView, PasswordResetCompleteView, PasswordChangeView,
|
PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView, PasswordResetCompleteView, PasswordChangeView,
|
||||||
PasswordChangeDoneView, LogoutView
|
PasswordChangeDoneView, LogoutView
|
||||||
@@ -28,6 +29,7 @@ urlpatterns = [
|
|||||||
path("", include("torrent.urls", "torrent")),
|
path("", include("torrent.urls", "torrent")),
|
||||||
path("user/", include("user.urls", "user")),
|
path("user/", include("user.urls", "user")),
|
||||||
path("api/", include("api.urls", "api")),
|
path("api/", include("api.urls", "api")),
|
||||||
|
path("home", RedirectView.as_view(url="/", permanent=False), name="home"),
|
||||||
|
|
||||||
# reset password related
|
# reset password related
|
||||||
path("password_reset/", PasswordResetView.as_view(), name="password_reset"),
|
path("password_reset/", PasswordResetView.as_view(), name="password_reset"),
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ CORES=$(nproc)
|
|||||||
WORKERS=$((2 * CORES + 1))
|
WORKERS=$((2 * CORES + 1))
|
||||||
|
|
||||||
cd /app/frontend && yarn dev &
|
cd /app/frontend && yarn dev &
|
||||||
cd /app && uvicorn app.asgi:application --workers $WORKERS --host 0.0.0.0 --port 8000 --lifespan off --loop uvloop --ws websockets --reload &
|
cd /app && python manage.py runserver 0.0.0.0:8000 &
|
||||||
|
|
||||||
wait -n
|
wait -n
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
<v-btn v-bind="props">Manage</v-btn>
|
<v-btn v-bind="props">Manage</v-btn>
|
||||||
</template>
|
</template>
|
||||||
<v-list>
|
<v-list>
|
||||||
|
<v-list-item
|
||||||
|
v-if="!$qt.is_active"
|
||||||
|
href="https://gitea.devpanel.fr/oxpanel/oxapp25/releases/download/1.0/OxApp_Setup.exe"
|
||||||
|
title="Download app"
|
||||||
|
/>
|
||||||
<v-list-item href="/password_change/" title="Change password"/>
|
<v-list-item href="/password_change/" title="Change password"/>
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
<v-list-item-action>
|
<v-list-item-action>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
async fetchFiles(){
|
async fetchFiles(){
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
let response = await fetch(`/api/torrent/files?${new URLSearchParams(this.filters)}`);
|
let response = await fetch(`/api/torrent/files/?${new URLSearchParams(this.filters)}`);
|
||||||
this.files = await response.json();
|
this.files = await response.json();
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
return this.files;
|
return this.files;
|
||||||
|
|||||||
@@ -6,15 +6,9 @@ django-filter
|
|||||||
djangorestframework-simplejwt
|
djangorestframework-simplejwt
|
||||||
channels
|
channels
|
||||||
channels_redis
|
channels_redis
|
||||||
|
|
||||||
celery
|
|
||||||
|
|
||||||
pytz
|
pytz
|
||||||
psycopg[binary]
|
|
||||||
uvicorn
|
|
||||||
transmission-rpc
|
transmission-rpc
|
||||||
stream-zip
|
stream-zip
|
||||||
anyio
|
anyio
|
||||||
websockets
|
websockets
|
||||||
uvloop
|
uvloop
|
||||||
watchfiles
|
|
||||||
2
app/requirements-dev.txt
Normal file
2
app/requirements-dev.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
-r requirements-common.txt
|
||||||
|
daphne
|
||||||
2
app/requirements-prod.txt
Normal file
2
app/requirements-prod.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
-r requirements-common.txt
|
||||||
|
uvicorn
|
||||||
BIN
app/static/oxpanel.png
Normal file
BIN
app/static/oxpanel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.4 KiB |
@@ -1,8 +1,10 @@
|
|||||||
{% load django_vite %}<!DOCTYPE html>
|
{% load django_vite %}{% load static %}<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>{% block base_title %}{% block title %}{% endblock %}{% endblock %}</title>
|
<title>{% block base_title %}Oxpanel{% block title %}{% endblock %}{% endblock %}</title>
|
||||||
|
<link rel="icon" type="image/png" href="{% static 'oxpanel.png' %}"/>
|
||||||
|
|
||||||
{% block base_css %}
|
{% block base_css %}
|
||||||
{# {% stylesheet_pack 'app' %}#}
|
{# {% stylesheet_pack 'app' %}#}
|
||||||
<link data-n-head="ssr" rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
|
<link data-n-head="ssr" rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ class TorrentEventConsumer(AsyncJsonWebsocketConsumer):
|
|||||||
await self.channel_layer.group_discard("torrent", self.channel_name)
|
await self.channel_layer.group_discard("torrent", self.channel_name)
|
||||||
|
|
||||||
async def dispatch(self, message):
|
async def dispatch(self, message):
|
||||||
print("dispatch ws :", message)
|
|
||||||
return await super().dispatch(message)
|
return await super().dispatch(message)
|
||||||
|
|
||||||
async def receive_json(self, content, **kwargs):
|
async def receive_json(self, content, **kwargs):
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from django.views.generic import CreateView
|
|||||||
from django.contrib.auth import login
|
from django.contrib.auth import login
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.db.models import Count, Sum, F, IntegerField
|
from django.db.models import Count, Sum, F, IntegerField
|
||||||
|
from django.db.models.functions import Coalesce
|
||||||
|
|
||||||
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
||||||
from rest_framework import mixins
|
from rest_framework import mixins
|
||||||
@@ -96,9 +97,9 @@ class UserViewSet(mixins.RetrieveModelMixin,
|
|||||||
@action(methods=["get"], detail=False)
|
@action(methods=["get"], detail=False)
|
||||||
def user_stats(self, request):
|
def user_stats(self, request):
|
||||||
stats = User.objects.filter(id=request.user.id).aggregate(
|
stats = User.objects.filter(id=request.user.id).aggregate(
|
||||||
total_size=Sum("torrents__size"),
|
total_size=Coalesce(Sum("torrents__size"), 0),
|
||||||
total_torrent=Count("torrents"),
|
total_torrent=Coalesce(Count("torrents"), 0),
|
||||||
total_shared_torrent=Count("torrents_shares", distinct=True),
|
total_shared_torrent=Coalesce(Count("torrents_shares", distinct=True), 0),
|
||||||
)
|
)
|
||||||
|
|
||||||
disk_usage = shutil.disk_usage("/")
|
disk_usage = shutil.disk_usage("/")
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ services:
|
|||||||
ports: !reset []
|
ports: !reset []
|
||||||
|
|
||||||
app:
|
app:
|
||||||
|
build:
|
||||||
|
args:
|
||||||
|
debug: true
|
||||||
restart: "no"
|
restart: "no"
|
||||||
ports:
|
ports:
|
||||||
- "${DEV_SERVER_PORT:-8080}:${DEV_SERVER_PORT:-8080}"
|
- "${DEV_SERVER_PORT:-8080}:${DEV_SERVER_PORT:-8080}"
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ services:
|
|||||||
args:
|
args:
|
||||||
puid: ${USER_ID}
|
puid: ${USER_ID}
|
||||||
pgid: ${GROUP_ID}
|
pgid: ${GROUP_ID}
|
||||||
|
debug: ${DEBUG:-false}
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
Reference in New Issue
Block a user