feat: add Django project & VSCode config for enhanced development workflow
Introduce the initial Django project setup alongside necessary configurations for VSCode, laying the groundwork for a robust development environment. This includes project scaffolding (`coffeemachine` app), ASGI configuration for async support, and a model example for game servers, demonstrating Django's ORM capabilities. Additionally, we integrate Bootstrap for frontend styling and configure `.gitignore` for Python/Django standard exclusions, ensuring a cleaner repository state. The VSCode launch configuration is tailored for Django, facilitating debugging and enhancing the developer experience within the IDE. This structured approach not only accelerates the setup phase for new developers but also ensures consistency across environments, fostering a more collaborative and efficient development process.
This commit is contained in:
commit
9ff6278ba1
24 changed files with 541 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
venv/
|
||||||
|
*.pyc
|
||||||
|
__pycache__/
|
||||||
|
settings.ini
|
||||||
|
db.sqlite3
|
20
.vscode/launch.json
vendored
Normal file
20
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Python Debugger: Django",
|
||||||
|
"type": "debugpy",
|
||||||
|
"request": "launch",
|
||||||
|
"args": [
|
||||||
|
"runserver",
|
||||||
|
"8104"
|
||||||
|
],
|
||||||
|
"django": true,
|
||||||
|
"autoStartBrowser": false,
|
||||||
|
"program": "${workspaceFolder}/manage.py"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
0
coffeemachine/__init__.py
Normal file
0
coffeemachine/__init__.py
Normal file
16
coffeemachine/asgi.py
Normal file
16
coffeemachine/asgi.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
"""
|
||||||
|
ASGI config for coffeemachine project.
|
||||||
|
|
||||||
|
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'coffeemachine.settings')
|
||||||
|
|
||||||
|
application = get_asgi_application()
|
0
coffeemachine/servers/__init__.py
Normal file
0
coffeemachine/servers/__init__.py
Normal file
3
coffeemachine/servers/admin.py
Normal file
3
coffeemachine/servers/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
6
coffeemachine/servers/apps.py
Normal file
6
coffeemachine/servers/apps.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class ServersConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'coffeemachine.servers'
|
0
coffeemachine/servers/migrations/__init__.py
Normal file
0
coffeemachine/servers/migrations/__init__.py
Normal file
19
coffeemachine/servers/models.py
Normal file
19
coffeemachine/servers/models.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
class GameServer(models.Model):
|
||||||
|
STATUS_CHOICES = [
|
||||||
|
('stopped', 'Stopped'),
|
||||||
|
('running', 'Running'),
|
||||||
|
('installing', 'Installing'),
|
||||||
|
('updating', 'Updating'),
|
||||||
|
('error', 'Error'),
|
||||||
|
]
|
||||||
|
|
||||||
|
name = models.CharField(max_length=100)
|
||||||
|
game = models.CharField(max_length=100)
|
||||||
|
status = models.CharField(max_length=100, choices=STATUS_CHOICES, default='stopped')
|
||||||
|
installation_path = models.CharField(max_length=255)
|
||||||
|
custom_script_content = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
36
coffeemachine/servers/templates/servers/base.html
Normal file
36
coffeemachine/servers/templates/servers/base.html
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<!-- templates/base.html -->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{% block title %}CoffeeMachine{% endblock %}</title>
|
||||||
|
<link href="{% static "dist/css/bootstrap.min.css" %}" rel="stylesheet">
|
||||||
|
<script src="{% static "dist/js/bootstrap.bundle.min.js" %}"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a class="navbar-brand" href="{% url 'dashboard' %}">CoffeeMachine</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
|
<ul class="navbar-nav">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'dashboard' %}">Dashboard</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{% url 'install_server' %}">Install Server</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container mt-4">
|
||||||
|
{% block content %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
32
coffeemachine/servers/templates/servers/dashboard.html
Normal file
32
coffeemachine/servers/templates/servers/dashboard.html
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{% extends "servers/base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Dashboard{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Game Server Dashboard</h1>
|
||||||
|
<a href="{% url 'install_server' %}" class="btn btn-primary mb-3">Install New Server</a>
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Game</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for server in servers %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ server.name }}</td>
|
||||||
|
<td>{{ server.game }}</td>
|
||||||
|
<td>{{ server.get_status_display }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'manage_server' server.id 'start' %}" class="btn btn-success btn-sm">Start</a>
|
||||||
|
<a href="{% url 'manage_server' server.id 'stop' %}" class="btn btn-danger btn-sm">Stop</a>
|
||||||
|
<a href="{% url 'manage_server' server.id 'update' %}" class="btn btn-warning btn-sm">Update</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
22
coffeemachine/servers/templates/servers/install_server.html
Normal file
22
coffeemachine/servers/templates/servers/install_server.html
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{% extends "base.html" %} {% block title %}Install Game Server{% endblock %} {%
|
||||||
|
block content %}
|
||||||
|
<h1>Install Game Server</h1>
|
||||||
|
<form method="post" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="mb-3">{{ form.name.label_tag }} {{ form.name }}</div>
|
||||||
|
<div class="mb-3">{{ form.game.label_tag }} {{ form.game }}</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
{{ form.installation_path.label_tag }} {{ form.installation_path }}
|
||||||
|
</div>
|
||||||
|
<div class="mb-3 form-check">
|
||||||
|
{{ form.existing_server }} {{ form.existing_server.label_tag }}
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
{{ form.script_file.label_tag }} {{ form.script_file }}
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
{{ form.script_content.label_tag }} {{ form.script_content }}
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Install</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
3
coffeemachine/servers/tests.py
Normal file
3
coffeemachine/servers/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
12
coffeemachine/servers/urls.py
Normal file
12
coffeemachine/servers/urls.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
from django.urls import path
|
||||||
|
from .views import DashboardView, InstallServerView, ManageServerView
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path("", DashboardView.as_view(), name="dashboard"),
|
||||||
|
path("install/", InstallServerView.as_view(), name="install_server"),
|
||||||
|
path(
|
||||||
|
"manage/<int:server_id>/<str:action>/",
|
||||||
|
ManageServerView.as_view(),
|
||||||
|
name="manage_server",
|
||||||
|
),
|
||||||
|
]
|
161
coffeemachine/servers/views.py
Normal file
161
coffeemachine/servers/views.py
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
# servers/views.py
|
||||||
|
from django.shortcuts import render, redirect
|
||||||
|
from django.views import View
|
||||||
|
from .models import GameServer
|
||||||
|
from .forms import GameServerForm
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
|
||||||
|
class DashboardView(View):
|
||||||
|
template_name = "servers/dashboard.html"
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
servers = GameServer.objects.all()
|
||||||
|
for server in servers:
|
||||||
|
server.status = self.check_server_status(server)
|
||||||
|
server.save()
|
||||||
|
return render(request, self.template_name, {"servers": servers})
|
||||||
|
|
||||||
|
def check_server_status(self, server):
|
||||||
|
script_path = (
|
||||||
|
os.path.join(server.installation_path, "custom_script.sh")
|
||||||
|
if server.custom_script_content
|
||||||
|
else f"./{server.game}server"
|
||||||
|
)
|
||||||
|
result = subprocess.run(
|
||||||
|
[script_path, "status"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
cwd=server.installation_path,
|
||||||
|
)
|
||||||
|
if "is running" in result.stdout:
|
||||||
|
return "running"
|
||||||
|
else:
|
||||||
|
return "stopped"
|
||||||
|
|
||||||
|
|
||||||
|
class InstallServerView(View):
|
||||||
|
template_name = "servers/install_server.html"
|
||||||
|
form_class = GameServerForm
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
form = self.form_class()
|
||||||
|
return render(request, self.template_name, {"form": form})
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
form = self.form_class(request.POST, request.FILES)
|
||||||
|
if form.is_valid():
|
||||||
|
server = form.save(commit=False)
|
||||||
|
os.makedirs(server.installation_path, exist_ok=True)
|
||||||
|
|
||||||
|
if form.cleaned_data["existing_server"]:
|
||||||
|
# Handle existing server
|
||||||
|
script_path = self.handle_custom_script(form, server)
|
||||||
|
server.status = self.check_server_status(server)
|
||||||
|
else:
|
||||||
|
# Handle new server installation
|
||||||
|
script_path = self.handle_custom_script(form, server)
|
||||||
|
if not script_path:
|
||||||
|
script_path = self.download_lgsm_script(server.installation_path)
|
||||||
|
server.status = "installing"
|
||||||
|
server.save()
|
||||||
|
subprocess.run(
|
||||||
|
[script_path, server.game], cwd=server.installation_path
|
||||||
|
)
|
||||||
|
subprocess.run(
|
||||||
|
[f"./{server.game}server", "install"],
|
||||||
|
cwd=server.installation_path,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
server.status = "installing"
|
||||||
|
server.save()
|
||||||
|
subprocess.run(
|
||||||
|
[script_path, "install"], cwd=server.installation_path
|
||||||
|
)
|
||||||
|
|
||||||
|
server.status = self.check_server_status(server)
|
||||||
|
server.save()
|
||||||
|
return redirect("dashboard")
|
||||||
|
return render(request, self.template_name, {"form": form})
|
||||||
|
|
||||||
|
def handle_custom_script(self, form, server):
|
||||||
|
script_path = None
|
||||||
|
if form.cleaned_data["script_file"]:
|
||||||
|
script_file = form.cleaned_data["script_file"]
|
||||||
|
script_path = os.path.join(server.installation_path, "custom_script.sh")
|
||||||
|
with open(script_path, "wb+") as destination:
|
||||||
|
for chunk in script_file.chunks():
|
||||||
|
destination.write(chunk)
|
||||||
|
os.chmod(script_path, 0o755) # Make the script executable
|
||||||
|
elif form.cleaned_data["script_content"]:
|
||||||
|
script_content = form.cleaned_data["script_content"]
|
||||||
|
script_path = os.path.join(server.installation_path, "custom_script.sh")
|
||||||
|
with open(script_path, "w") as script_file:
|
||||||
|
script_file.write(script_content)
|
||||||
|
os.chmod(script_path, 0o755) # Make the script executable
|
||||||
|
server.custom_script_content = script_content
|
||||||
|
return script_path
|
||||||
|
|
||||||
|
def download_lgsm_script(self, installation_path):
|
||||||
|
url = "https://linuxgsm.sh"
|
||||||
|
script_path = os.path.join(installation_path, "linuxgsm.sh")
|
||||||
|
urllib.request.urlretrieve(url, script_path)
|
||||||
|
os.chmod(script_path, 0o755) # Make the script executable
|
||||||
|
return script_path
|
||||||
|
|
||||||
|
def check_server_status(self, server):
|
||||||
|
script_path = (
|
||||||
|
os.path.join(server.installation_path, "custom_script.sh")
|
||||||
|
if server.custom_script_content
|
||||||
|
else f"./{server.game}server"
|
||||||
|
)
|
||||||
|
result = subprocess.run(
|
||||||
|
[script_path, "status"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
cwd=server.installation_path,
|
||||||
|
)
|
||||||
|
if "is running" in result.stdout:
|
||||||
|
return "running"
|
||||||
|
else:
|
||||||
|
return "stopped"
|
||||||
|
|
||||||
|
|
||||||
|
class ManageServerView(View):
|
||||||
|
def post(self, request, server_id, action, *args, **kwargs):
|
||||||
|
server = GameServer.objects.get(id=server_id)
|
||||||
|
script_path = (
|
||||||
|
os.path.join(server.installation_path, "custom_script.sh")
|
||||||
|
if server.custom_script_content
|
||||||
|
else f"./{server.game}server"
|
||||||
|
)
|
||||||
|
command = [script_path, action]
|
||||||
|
server.status = (
|
||||||
|
"updating"
|
||||||
|
if action == "update"
|
||||||
|
else "running" if action == "start" else "stopped"
|
||||||
|
)
|
||||||
|
server.save()
|
||||||
|
subprocess.run(command, cwd=server.installation_path)
|
||||||
|
server.status = self.check_server_status(server)
|
||||||
|
server.save()
|
||||||
|
return redirect("dashboard")
|
||||||
|
|
||||||
|
def check_server_status(self, server):
|
||||||
|
script_path = (
|
||||||
|
os.path.join(server.installation_path, "custom_script.sh")
|
||||||
|
if server.custom_script_content
|
||||||
|
else f"./{server.game}server"
|
||||||
|
)
|
||||||
|
result = subprocess.run(
|
||||||
|
[script_path, "status"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
cwd=server.installation_path,
|
||||||
|
)
|
||||||
|
if "is running" in result.stdout:
|
||||||
|
return "running"
|
||||||
|
else:
|
||||||
|
return "stopped"
|
125
coffeemachine/settings.py
Normal file
125
coffeemachine/settings.py
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
"""
|
||||||
|
Django settings for coffeemachine project.
|
||||||
|
|
||||||
|
Generated by 'django-admin startproject' using Django 5.0.6.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/5.0/topics/settings/
|
||||||
|
|
||||||
|
For the full list of settings and their values, see
|
||||||
|
https://docs.djangoproject.com/en/5.0/ref/settings/
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from autosecretkey import AutoSecretKey
|
||||||
|
|
||||||
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
ASK = AutoSecretKey(BASE_DIR / 'settings.ini')
|
||||||
|
SECRET_KEY = ASK.secret_key
|
||||||
|
|
||||||
|
CONFIG = ASK.config
|
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG = CONFIG.getboolean("CoffeeMachine", "Debug", fallback=False)
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = CONFIG.get("CoffeeMachine", "Hostname", fallback="*").split(",")
|
||||||
|
|
||||||
|
|
||||||
|
# Application definition
|
||||||
|
|
||||||
|
INSTALLED_APPS = [
|
||||||
|
'django.contrib.admin',
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.staticfiles',
|
||||||
|
|
||||||
|
'coffeemachine.servers',
|
||||||
|
]
|
||||||
|
|
||||||
|
MIDDLEWARE = [
|
||||||
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
]
|
||||||
|
|
||||||
|
ROOT_URLCONF = 'coffeemachine.urls'
|
||||||
|
|
||||||
|
TEMPLATES = [
|
||||||
|
{
|
||||||
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
|
'DIRS': [],
|
||||||
|
'APP_DIRS': True,
|
||||||
|
'OPTIONS': {
|
||||||
|
'context_processors': [
|
||||||
|
'django.template.context_processors.debug',
|
||||||
|
'django.template.context_processors.request',
|
||||||
|
'django.contrib.auth.context_processors.auth',
|
||||||
|
'django.contrib.messages.context_processors.messages',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
WSGI_APPLICATION = 'coffeemachine.wsgi.application'
|
||||||
|
|
||||||
|
|
||||||
|
# Database
|
||||||
|
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
|
'NAME': BASE_DIR / 'db.sqlite3',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Password validation
|
||||||
|
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# Internationalization
|
||||||
|
# https://docs.djangoproject.com/en/5.0/topics/i18n/
|
||||||
|
|
||||||
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
|
USE_I18N = True
|
||||||
|
|
||||||
|
USE_TZ = True
|
||||||
|
|
||||||
|
|
||||||
|
# Static files (CSS, JavaScript, Images)
|
||||||
|
# https://docs.djangoproject.com/en/5.0/howto/static-files/
|
||||||
|
|
||||||
|
STATIC_URL = 'static/'
|
||||||
|
|
||||||
|
# Default primary key field type
|
||||||
|
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
|
||||||
|
|
||||||
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
6
coffeemachine/static/dist/css/bootstrap.min.css
vendored
Normal file
6
coffeemachine/static/dist/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
coffeemachine/static/dist/css/bootstrap.min.css.map
vendored
Normal file
1
coffeemachine/static/dist/css/bootstrap.min.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
coffeemachine/static/dist/js/bootstrap.bundle.min.js
vendored
Normal file
7
coffeemachine/static/dist/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
coffeemachine/static/dist/js/bootstrap.bundle.min.js.map
vendored
Normal file
1
coffeemachine/static/dist/js/bootstrap.bundle.min.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
23
coffeemachine/urls.py
Normal file
23
coffeemachine/urls.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
"""
|
||||||
|
URL configuration for coffeemachine project.
|
||||||
|
|
||||||
|
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||||
|
https://docs.djangoproject.com/en/5.0/topics/http/urls/
|
||||||
|
Examples:
|
||||||
|
Function views
|
||||||
|
1. Add an import: from my_app import views
|
||||||
|
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||||
|
Class-based views
|
||||||
|
1. Add an import: from other_app.views import Home
|
||||||
|
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||||
|
Including another URLconf
|
||||||
|
1. Import the include() function: from django.urls import include, path
|
||||||
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
|
"""
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import path, include
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('admin/', admin.site.urls),
|
||||||
|
|
||||||
|
]
|
16
coffeemachine/wsgi.py
Normal file
16
coffeemachine/wsgi.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
"""
|
||||||
|
WSGI config for coffeemachine project.
|
||||||
|
|
||||||
|
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'coffeemachine.settings')
|
||||||
|
|
||||||
|
application = get_wsgi_application()
|
22
manage.py
Executable file
22
manage.py
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""Django's command-line utility for administrative tasks."""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Run administrative tasks."""
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'coffeemachine.settings')
|
||||||
|
try:
|
||||||
|
from django.core.management import execute_from_command_line
|
||||||
|
except ImportError as exc:
|
||||||
|
raise ImportError(
|
||||||
|
"Couldn't import Django. Are you sure it's installed and "
|
||||||
|
"available on your PYTHONPATH environment variable? Did you "
|
||||||
|
"forget to activate a virtual environment?"
|
||||||
|
) from exc
|
||||||
|
execute_from_command_line(sys.argv)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
5
requirements.txt
Normal file
5
requirements.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
Django
|
||||||
|
psycopg2-binary
|
||||||
|
django-autosecretkey
|
||||||
|
celery
|
||||||
|
redis
|
Loading…
Reference in a new issue