Create: views and templates
This commit is contained in:
parent
52a77a4b27
commit
96ae8647e1
@ -1,6 +1,6 @@
|
|||||||
# Generated by Django 4.2 on 2023-07-27 02:04
|
# Generated by Django 4.2 on 2023-07-28 14:40
|
||||||
|
|
||||||
import collector.models
|
import collector.utils
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import django.core.files.storage
|
import django.core.files.storage
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
@ -22,6 +22,7 @@ class Migration(migrations.Migration):
|
|||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('name', models.CharField(max_length=20)),
|
('name', models.CharField(max_length=20)),
|
||||||
|
('pretty_name', models.CharField(max_length=20)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
@ -41,7 +42,8 @@ class Migration(migrations.Migration):
|
|||||||
name='Archive',
|
name='Archive',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('file', models.FileField(blank=True, null=True, storage=django.core.files.storage.FileSystemStorage(base_url='/archives/', location=pathlib.PurePosixPath('/home/stepan/Documents/Dev/ISPsystem/logs-collector/logs_collector/archives')), upload_to=collector.models.logs_dir_path)),
|
('file', models.FileField(blank=True, null=True, storage=django.core.files.storage.FileSystemStorage(base_url='/archives/', location=pathlib.PurePosixPath('/home/stepan/Documents/Dev/ISPsystem/logs-collector/logs_collector/archives')), upload_to=collector.utils.logs_dir_path)),
|
||||||
|
('size', models.CharField(blank=True, max_length=50)),
|
||||||
('sha1', models.CharField(editable=False, max_length=1024)),
|
('sha1', models.CharField(editable=False, max_length=1024)),
|
||||||
('time_create', models.DateTimeField(auto_now_add=True)),
|
('time_create', models.DateTimeField(auto_now_add=True)),
|
||||||
('time_update', models.DateTimeField(auto_now=True)),
|
('time_update', models.DateTimeField(auto_now=True)),
|
||||||
|
@ -5,7 +5,9 @@ from django.contrib.auth.models import User
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.files.storage import FileSystemStorage
|
from django.core.files.storage import FileSystemStorage
|
||||||
from django.db.models import FileField
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from .utils import logs_dir_path, get_file_size
|
||||||
|
|
||||||
|
|
||||||
# Create a custom storage location, using a value from your settings file
|
# Create a custom storage location, using a value from your settings file
|
||||||
@ -14,13 +16,10 @@ sensitive_upload_storage = FileSystemStorage(
|
|||||||
base_url=settings.MEDIA_URL_FOR_SENSITIVE_FILES
|
base_url=settings.MEDIA_URL_FOR_SENSITIVE_FILES
|
||||||
)
|
)
|
||||||
# ... and a file field that will use the custom storage
|
# ... and a file field that will use the custom storage
|
||||||
AuthenticatedFileField = partial(FileField, storage=sensitive_upload_storage)
|
AuthenticatedFileField = partial(
|
||||||
|
models.FileField,
|
||||||
|
storage=sensitive_upload_storage
|
||||||
def logs_dir_path(instance, filename):
|
)
|
||||||
# file will be uploaded to
|
|
||||||
# MEDIA_ROOT_FOR_SENSITIVE_FILES/<ticket>/<filename>
|
|
||||||
return f'{instance.ticket}/{filename}'
|
|
||||||
|
|
||||||
|
|
||||||
class Archive(models.Model):
|
class Archive(models.Model):
|
||||||
@ -29,6 +28,7 @@ class Archive(models.Model):
|
|||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
|
size = models.CharField(max_length=50, blank=True, editable=False)
|
||||||
sha1 = models.CharField(max_length=1024, editable=False)
|
sha1 = models.CharField(max_length=1024, editable=False)
|
||||||
time_create = models.DateTimeField(auto_now_add=True)
|
time_create = models.DateTimeField(auto_now_add=True)
|
||||||
time_update = models.DateTimeField(auto_now=True)
|
time_update = models.DateTimeField(auto_now=True)
|
||||||
@ -42,15 +42,32 @@ class Archive(models.Model):
|
|||||||
for byte_block in iter(lambda: f.read(4096), b""):
|
for byte_block in iter(lambda: f.read(4096), b""):
|
||||||
sha1.update(byte_block)
|
sha1.update(byte_block)
|
||||||
self.sha1 = sha1.hexdigest()
|
self.sha1 = sha1.hexdigest()
|
||||||
|
# calculate size and write size field to db
|
||||||
|
try:
|
||||||
|
mr = settings.MEDIA_ROOT_FOR_SENSITIVE_FILES
|
||||||
|
unit = 'gb'
|
||||||
|
file_path = mr / self.ticket / self.file.replace(" ", "_")
|
||||||
|
file_size = get_file_size(file_path, unit)
|
||||||
|
self.size = f"{file_size} {unit.title()}"
|
||||||
|
except Exception as error:
|
||||||
|
print(error)
|
||||||
|
self.size = '?'
|
||||||
# Call the "real" save() method
|
# Call the "real" save() method
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse('download', kwargs={'path': self.file})
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.file)
|
return str(self.file)
|
||||||
|
|
||||||
|
|
||||||
class Platform(models.Model):
|
class Platform(models.Model):
|
||||||
name = models.CharField(max_length=20)
|
name = models.CharField(max_length=20)
|
||||||
|
pretty_name = models.CharField(max_length=20)
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse('platform', kwargs={'platform': self.name})
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -65,5 +82,11 @@ class Ticket(models.Model):
|
|||||||
platform = models.ForeignKey('Platform', on_delete=models.CASCADE)
|
platform = models.ForeignKey('Platform', on_delete=models.CASCADE)
|
||||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse(
|
||||||
|
'ticket',
|
||||||
|
kwargs={'platform': self.platform.name, 'ticket': self.number}
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.number)
|
return str(self.number)
|
||||||
|
26
logs_collector/collector/templates/collector/base.html
Normal file
26
logs_collector/collector/templates/collector/base.html
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link
|
||||||
|
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"
|
||||||
|
rel="stylesheet"
|
||||||
|
integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{% block content %}{% endblock content %}
|
||||||
|
<script
|
||||||
|
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"
|
||||||
|
integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
></script>
|
||||||
|
<script>
|
||||||
|
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
|
||||||
|
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
58
logs_collector/collector/templates/collector/navigation.html
Normal file
58
logs_collector/collector/templates/collector/navigation.html
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<header>
|
||||||
|
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand" href="{% url 'index' %}">Logs Collector</a>
|
||||||
|
<button
|
||||||
|
class="navbar-toggler"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#navbarSupportedContent"
|
||||||
|
aria-controls="navbarSupportedContent"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-label="Переключатель навигации"
|
||||||
|
>
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
<ul class="navbar-nav ml-auto mb-2 mb-lg-0">
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a
|
||||||
|
class="nav-link dropdown-toggle"
|
||||||
|
href="#"
|
||||||
|
role="button"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
>Tickets</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" href="{% url 'index' %}">All</a>
|
||||||
|
</li>
|
||||||
|
{% for platform in platforms %}
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="{{ platform.get_absolute_url }}"
|
||||||
|
>{{ platform.pretty_name}}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
<li><hr class="dropdown-divider" /></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Create ticket</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link disabled">Отключенная</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<form class="d-flex" role="search">
|
||||||
|
<input
|
||||||
|
class="form-control me-2"
|
||||||
|
type="search"
|
||||||
|
placeholder="Поиск"
|
||||||
|
aria-label="Поиск"
|
||||||
|
/>
|
||||||
|
<button class="btn btn-outline-success" type="submit">Поиск</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
95
logs_collector/collector/templates/collector/ticket.html
Normal file
95
logs_collector/collector/templates/collector/ticket.html
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
{% extends 'collector/base.html' %}
|
||||||
|
{% block content %}
|
||||||
|
{% include 'collector/navigation.html' %}
|
||||||
|
<main>
|
||||||
|
<section>
|
||||||
|
<div class="container mt-3">
|
||||||
|
<div class="row">
|
||||||
|
<div class="list-group mb-2">
|
||||||
|
<div class="list-group-item list-group-item-action disable" aria-current="true">
|
||||||
|
<div class="d-flex w-100 justify-content-between mb-2">
|
||||||
|
<h5 class="mb-1">Ticket: {{ ticket.number }}</h5>
|
||||||
|
<small>{{ ticket.time_create }}</small>
|
||||||
|
</div>
|
||||||
|
<div class="col-xl-6 mb-2">
|
||||||
|
<h6 class="mb-1">Platform: {{ ticket.platform.pretty_name }}</h6>
|
||||||
|
<h6 class="mb-1">Owner: {{ ticket.user.username }}</h6>
|
||||||
|
</div>
|
||||||
|
<div class="col-xl-6 mt-1 mb-2">
|
||||||
|
{% if ticket.note %}
|
||||||
|
<small><b>Note:</b></small>
|
||||||
|
<hr>
|
||||||
|
<p>{{ ticket.note }}</p>
|
||||||
|
<hr>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<!-- Logs -->
|
||||||
|
{% if ticket.archive_set.all %}
|
||||||
|
<small><b>Logs:</b></small>
|
||||||
|
<ul class="list-group mb-2 mt-2">
|
||||||
|
{% for archive in ticket.archive_set.all %}
|
||||||
|
<li class="list-group-item list-group-item-action">
|
||||||
|
<p style="word-wrap: break-word" ><b>File:</b> {{ archive.file }}</p>
|
||||||
|
<small>
|
||||||
|
<b>SHA1:</b>
|
||||||
|
<span style="word-wrap: break-word">{{ archive.sha1 }}</span>
|
||||||
|
</small>
|
||||||
|
<br>
|
||||||
|
<small>
|
||||||
|
<b>Size:</b>
|
||||||
|
<span style="word-wrap: break-word">{{ archive.size }}</span>
|
||||||
|
</small>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col" >
|
||||||
|
<a
|
||||||
|
class="btn btn-outline-success btn-sm mt-2"
|
||||||
|
href="{{ archive.get_absolute_url }}"
|
||||||
|
>GET</a>
|
||||||
|
<button
|
||||||
|
class="btn btn-outline-danger btn-sm ms-2 mt-2"
|
||||||
|
button type="button" data-bs-toggle="modal" data-bs-target="#{{ archive.id }}"
|
||||||
|
>DEL</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
<!-- Card buttons -->
|
||||||
|
<div class="d-flex w-100 justify-content-between">
|
||||||
|
<a
|
||||||
|
href="{{ ticket.get_absolute_url }}"
|
||||||
|
class="btn btn-outline-warning mb-1 mt-1"
|
||||||
|
>Edit</a>
|
||||||
|
<a
|
||||||
|
href="{{ ticket.get_absolute_url }}"
|
||||||
|
class="btn btn-outline-danger mb-1 mt-1"
|
||||||
|
>Delete</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
{% for archive in ticket.archive_set.all %}
|
||||||
|
<div class="modal fade" id="{{ archive.id }}" tabindex="-1" aria-labelledby="{{ archive.id }}_Label" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="{{ archive.id }}_Label">Delete this file?</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p style="word-wrap: break-word">{{ archive.file }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-danger">Delete</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
{% endblock content %}
|
97
logs_collector/collector/templates/collector/tickets.html
Normal file
97
logs_collector/collector/templates/collector/tickets.html
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
{% extends 'collector/base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% include 'collector/navigation.html' %}
|
||||||
|
<!-- Modal -->
|
||||||
|
<main>
|
||||||
|
<section>
|
||||||
|
<div class="container mt-3">
|
||||||
|
{% for ticket in tickets %}
|
||||||
|
<div class="row">
|
||||||
|
<!-- Ticket -->
|
||||||
|
<div class="list-group mb-2">
|
||||||
|
<div class="list-group-item list-group-item-action disable" aria-current="true">
|
||||||
|
<div class="d-flex w-100 justify-content-between mb-2">
|
||||||
|
<h5 class="mb-1">Ticket: {{ ticket.number }}</h5>
|
||||||
|
<small>{{ ticket.time_create }}</small>
|
||||||
|
</div>
|
||||||
|
<div class="col-xl-6 mb-2">
|
||||||
|
<!-- Info -->
|
||||||
|
<h6 class="mb-1">Platform: {{ ticket.platform.pretty_name }}</h6>
|
||||||
|
<h6 class="mb-1">Owner: {{ ticket.user.username }}</h6>
|
||||||
|
</div>
|
||||||
|
<div class="col-xl-6 mt-1 mb-2">
|
||||||
|
<div class="accordion" id="#archive_{{ ticket.number }}">
|
||||||
|
{% if ticket.note %}
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header">
|
||||||
|
<button
|
||||||
|
class="accordion-button collapsed"
|
||||||
|
type="button" data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#collapse_{{ ticket.number}}_note"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls="collapse_{{ ticket.number }}"
|
||||||
|
>Note</button>
|
||||||
|
</h2>
|
||||||
|
<div id="collapse_{{ ticket.number }}_note"
|
||||||
|
class="accordion-collapse collapse"
|
||||||
|
data-bs-parent="#archive_{{ ticket.number }}_note"
|
||||||
|
>
|
||||||
|
<div class="accordion-body">
|
||||||
|
<p class="mb-1">{{ ticket.note }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if ticket.archive_set.all %}
|
||||||
|
<!-- Logs -->
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h3 class="accordion-header">
|
||||||
|
<button
|
||||||
|
class="accordion-button collapsed"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#collapse_{{ ticket.number }}"
|
||||||
|
aria-expanded="true" aria-controls="collapse_{{ ticket.number }}"
|
||||||
|
>Logs</button>
|
||||||
|
</h3>
|
||||||
|
<div
|
||||||
|
id="collapse_{{ ticket.number }}"
|
||||||
|
class="accordion-collapse collapse"
|
||||||
|
data-bs-parent="#archive_{{ ticket.number }}"
|
||||||
|
>
|
||||||
|
<div class="accordion-body">
|
||||||
|
<ul class="list-group mb-2">
|
||||||
|
{% for archive in ticket.archive_set.all %}
|
||||||
|
<li class="list-group-item list-group-item-action">
|
||||||
|
<a
|
||||||
|
href="{{ archive.get_absolute_url }}"
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-placement="top"
|
||||||
|
data-bs-title="Size: {{ archive.size }}"
|
||||||
|
style="word-wrap: break-word"
|
||||||
|
>{{ archive.file }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex w-100 justify-content-between">
|
||||||
|
<a
|
||||||
|
href="{{ ticket.get_absolute_url }}"
|
||||||
|
class="btn btn-outline-primary mb-1 mt-1"
|
||||||
|
>Open</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
{% endblock content %}
|
@ -1,9 +1,28 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.index, name='index',),
|
path(
|
||||||
path('test/<str:path>/', views.test_page, name='test_page'),
|
'',
|
||||||
path('archives/<ticket>/<file>', views.download, name="download")
|
views.ListAllTickets.as_view(),
|
||||||
|
name='index'
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'tickets/',
|
||||||
|
views.ListAllTickets.as_view(),
|
||||||
|
name='index'
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'tickets/<slug:platform>/',
|
||||||
|
views.ListPlatformTickets.as_view(),
|
||||||
|
name='platform'
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
'tickets/<slug:platform>/<int:ticket>/',
|
||||||
|
views.DetailTicket.as_view(),
|
||||||
|
name='ticket'
|
||||||
|
),
|
||||||
|
path('archives/<path:path>', views.download, name="download")
|
||||||
]
|
]
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def logs_dir_path(instance, filename):
|
||||||
|
# file will be uploaded to
|
||||||
|
# MEDIA_ROOT_FOR_SENSITIVE_FILES/<ticket>/<filename>
|
||||||
|
return f'{instance.ticket}/{filename}'
|
||||||
|
|
||||||
|
|
||||||
|
def get_file_size(file_path, unit='bytes'):
|
||||||
|
file_size = os.path.getsize(file_path)
|
||||||
|
exponents_map = {'bytes': 0, 'kb': 1, 'mb': 2, 'gb': 3}
|
||||||
|
if unit not in exponents_map:
|
||||||
|
raise ValueError("Must select from \
|
||||||
|
['bytes', 'kb', 'mb', 'gb']")
|
||||||
|
else:
|
||||||
|
size = file_size / 1024 ** exponents_map[unit]
|
||||||
|
return round(size, 3)
|
@ -1,14 +1,14 @@
|
|||||||
# from django.shortcuts import render
|
# from django.shortcuts import render
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.http import FileResponse, HttpResponse, Http404
|
from django.http import FileResponse, Http404
|
||||||
from .models import Archive
|
from django.views import generic
|
||||||
|
|
||||||
|
from .models import Archive, Ticket, Platform
|
||||||
|
|
||||||
|
|
||||||
# Create your views here.
|
|
||||||
# handles the url "/archives/{PATH}"".
|
# handles the url "/archives/{PATH}"".
|
||||||
@login_required
|
@login_required
|
||||||
def download(request, ticket, file):
|
def download(request, path):
|
||||||
path = f'{ticket}/{file}'
|
|
||||||
try:
|
try:
|
||||||
file = Archive.objects.get(file=path)
|
file = Archive.objects.get(file=path)
|
||||||
except Archive.DoesNotExist:
|
except Archive.DoesNotExist:
|
||||||
@ -17,9 +17,43 @@ def download(request, ticket, file):
|
|||||||
return FileResponse(file.file)
|
return FileResponse(file.file)
|
||||||
|
|
||||||
|
|
||||||
def index(request):
|
class ListAllTickets(generic.ListView):
|
||||||
return HttpResponse('<h1>Index Page</h1>')
|
model = Ticket
|
||||||
|
template_name = 'collector/tickets.html'
|
||||||
|
context_object_name = 'tickets'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['platforms'] = Platform.objects.all()
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
def test_page(request, path):
|
class ListPlatformTickets(generic.ListView):
|
||||||
return HttpResponse(f'<h1>{path} Page</h1>')
|
model = Ticket
|
||||||
|
template_name = 'collector/tickets.html'
|
||||||
|
context_object_name = 'tickets'
|
||||||
|
allow_empty = False
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Ticket.objects.filter(
|
||||||
|
platform__name=self.kwargs.get('platform')
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['platforms'] = Platform.objects.all()
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class DetailTicket(generic.DetailView):
|
||||||
|
model = Ticket
|
||||||
|
template_name = 'collector/ticket.html'
|
||||||
|
context_object_name = 'ticket'
|
||||||
|
|
||||||
|
def get_object(self, queryset=None):
|
||||||
|
return Ticket.objects.get(number=self.kwargs.get('ticket'))
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['platforms'] = Platform.objects.all()
|
||||||
|
return context
|
||||||
|
Loading…
Reference in New Issue
Block a user