Got library sort of working
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.1.1 on 2021-05-05 05:10
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('interface', '0027_auto_20210322_1154'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='ensemble',
|
||||
name='details',
|
||||
field=models.TextField(blank=True),
|
||||
),
|
||||
]
|
||||
+4
-3
@@ -44,6 +44,7 @@ class Ensemble(models.Model):
|
||||
passphrase = models.CharField(max_length=100)
|
||||
admins = models.ManyToManyField('auth.User', related_name='ensembles')
|
||||
slug = models.SlugField(max_length=100, editable=False)
|
||||
details = models.TextField(blank=True)
|
||||
storage = models.ForeignKey('byostorage.UserStorage', null=True, on_delete=models.SET_NULL)
|
||||
|
||||
def active_projects(self):
|
||||
@@ -53,10 +54,10 @@ class Ensemble(models.Model):
|
||||
code = str(self.code)
|
||||
return "{}-{}-{}".format(code[:3], code[3:6], code[6:])
|
||||
|
||||
def save(self):
|
||||
def save(self, **kwargs):
|
||||
if not self.slug:
|
||||
self.slug = slugify(self.name)
|
||||
super(Ensemble, self).save()
|
||||
super(Ensemble, self).save(**kwargs)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
@@ -86,7 +87,7 @@ class Project(models.Model):
|
||||
|
||||
@property
|
||||
def has_happened(self):
|
||||
return self.event_date < timezone.now()
|
||||
return self.event_date < timezone.now().date()
|
||||
|
||||
def save(self):
|
||||
if not self.slug:
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
--border-color: #292929;
|
||||
--gray-blue: #667788;
|
||||
--light-blue: #c5eff7;
|
||||
--light-grey: #EEEEEE;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
@@ -36,7 +37,7 @@ BODY {
|
||||
}
|
||||
|
||||
.main {
|
||||
max-width: 1000px;
|
||||
max-width: 1280px;
|
||||
margin: 10px auto;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 5px;
|
||||
@@ -55,16 +56,30 @@ BODY {
|
||||
margin: 0px auto;
|
||||
}
|
||||
|
||||
.wide {
|
||||
width: 1200px;
|
||||
}
|
||||
|
||||
.collapse {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
@media all and (max-width: 1200px) {
|
||||
.wide {
|
||||
width: 900px;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 900px) {
|
||||
.mdhide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.wide {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 700px) {
|
||||
@@ -74,6 +89,9 @@ BODY {
|
||||
.collapse {
|
||||
flex-direction: column;
|
||||
}
|
||||
.wide {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -138,6 +156,16 @@ INPUT[type=checkbox] {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
border: 1px solid var(--gray-blue);
|
||||
font-weight: bold;
|
||||
font-size: 0.9em;
|
||||
border-radius: 10px;
|
||||
padding: 4px 10px 2px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background-color: var(--gray-blue);
|
||||
display: inline-block;
|
||||
@@ -232,10 +260,28 @@ H1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
TD {
|
||||
padding: 5px;
|
||||
TABLE {
|
||||
border-spacing: 0px;
|
||||
}
|
||||
|
||||
TD, TH {
|
||||
padding: 3px 6px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
TABLE THEAD TR {
|
||||
background-color: var(--gray-blue);
|
||||
color: var(--light-blue);
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
TABLE THEAD TH {
|
||||
padding: 5px 6px;
|
||||
}
|
||||
|
||||
TABLE.zebra TR:nth-child(even) {
|
||||
background-color: var(--light-grey);
|
||||
}
|
||||
|
||||
TABLE.horizontal TH {
|
||||
text-align: right;
|
||||
@@ -298,12 +344,12 @@ TABLE SELECT {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
TD.select-cell {
|
||||
padding: 0;
|
||||
padding: 0px !important;
|
||||
}
|
||||
|
||||
.select-cell SELECT {
|
||||
border: none;
|
||||
background-color: white;
|
||||
background-color: transparent;
|
||||
height: 30px;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{% block page %}
|
||||
<div>
|
||||
<h3>{{ title }}</h3>
|
||||
<h3>{% firstof title view.title %}</h3>
|
||||
<form class="vertical" method="POST" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
|
||||
@@ -1,22 +1,12 @@
|
||||
{% extends "interface/project_base.html" %}
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block page %}
|
||||
<div style="flex-grow: 1">
|
||||
<h1>Projects for {{ ensemble.name }}</h1>
|
||||
<div class="list-group narrow">
|
||||
{% for project in ensemble.active_projects %}
|
||||
<a class="" href="{% url 'project_detail' project=project.id %}">
|
||||
<h3>{{ project.name }}</h3>
|
||||
<p><small>
|
||||
{% if project.deadline %}In {{ project.deadline|timeuntil }}<br/>{% endif %}
|
||||
{% if project.works.count %}{{ project.works.count }} works<br/>{% endif %}
|
||||
{% if project.submissions.count %}{{ project.submissions.count }} submissions<br/>{% endif %}
|
||||
</small></p>
|
||||
</a>
|
||||
{% block content %}
|
||||
<h2>{{ ensemble.name }}</h2>
|
||||
<p>{{ ensemble.details }}</p>
|
||||
<h4>Administrators</h4>
|
||||
<ul>
|
||||
{% for admin in ensemble.admins.all %}
|
||||
<li><a href="mailto:{{ admin.email }}">{% firstof admin.get_full_name admin.get_username %}</a></li>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div style="float: right; margin-top: 10px; color: #999;">
|
||||
<small>{{ ensemble.ensemble_code }}</small>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{% extends "interface/project_base.html" %}
|
||||
|
||||
{% block page %}
|
||||
<div style="flex-grow: 1">
|
||||
<h1>Projects for {{ ensemble.name }}</h1>
|
||||
<div class="list-group narrow">
|
||||
{% for project in ensemble.active_projects %}
|
||||
<a class="" href="{% url 'project_detail' project=project.id %}">
|
||||
<h3>{{ project.name }}</h3>
|
||||
<p><small>
|
||||
{% if project.deadline %}In {{ project.deadline|timeuntil }}<br/>{% endif %}
|
||||
{% if project.works.count %}{{ project.works.count }} works<br/>{% endif %}
|
||||
{% if project.submissions.count %}{{ project.submissions.count }} submissions<br/>{% endif %}
|
||||
</small></p>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div style="float: right; margin-top: 10px; color: #999;">
|
||||
<small>{{ ensemble.ensemble_code }}</small>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -7,9 +7,9 @@
|
||||
{% if project.event_date %}
|
||||
<h3 class="text-center">
|
||||
{% if project.has_happened %}
|
||||
{{ project.event_date|timesince }}
|
||||
{{ project.event_date|timesince }} ago.
|
||||
{% else %}
|
||||
{{ project.event_date|}}
|
||||
In {{ project.event_date|timeuntil }}.
|
||||
{% endif %}
|
||||
</h3>
|
||||
{% endif %}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
from django import template
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def url_update(context, **kwargs):
|
||||
params = context.request.GET.copy()
|
||||
for k in kwargs:
|
||||
params[k] = kwargs[k]
|
||||
return "?" + params.urlencode()
|
||||
@@ -0,0 +1,6 @@
|
||||
from django.test import TestCase
|
||||
|
||||
class IntegrationTestCase(TestCase):
|
||||
|
||||
def test_runs(self):
|
||||
self.assertTrue(True)
|
||||
+3
-1
@@ -10,7 +10,9 @@ urlpatterns = [
|
||||
path('register', views.register, name="register"),
|
||||
path('manage', views.ManageView.as_view(), name="manage"),
|
||||
|
||||
path('', views.EnsembleDetailView.as_view(), name='ensemble_detail'),
|
||||
path('', views.EnsembleProjectListView.as_view(), name='ensemble_detail'),
|
||||
path('ensembles/<int:pk>', views.EnsembleDetailView.as_view(), name='ensemble_detail'),
|
||||
|
||||
path('projects/<int:project>', views.ProjectDetailView.as_view(), name="project_detail"),
|
||||
path('projects/<int:project>/submissions.mk', views.ProjectMakefileView.as_view(), name="project_makefile"),
|
||||
|
||||
|
||||
+9
-1
@@ -60,6 +60,10 @@ class EnsembleMixin(object):
|
||||
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
@property
|
||||
def ensemble(self):
|
||||
return models.Ensemble.objects.get(pk=self.request.ensemble_id)
|
||||
|
||||
class ProjectMixin(EnsembleMixin):
|
||||
|
||||
def get_project(self):
|
||||
@@ -195,7 +199,8 @@ def logout(request):
|
||||
return redirect('/')
|
||||
|
||||
|
||||
class EnsembleDetailView(EnsembleMixin, DetailView):
|
||||
class EnsembleProjectListView(EnsembleMixin, DetailView):
|
||||
template_name = 'interface/ensemble_project_list.html'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
# capture provided urls
|
||||
@@ -207,6 +212,9 @@ class EnsembleDetailView(EnsembleMixin, DetailView):
|
||||
def get_object(self):
|
||||
return models.Ensemble.objects.get(pk=self.request.ensemble_id)
|
||||
|
||||
class EnsembleDetailView(DetailView):
|
||||
model = models.Ensemble
|
||||
|
||||
class ProjectDetailView(ProjectMixin, DetailView):
|
||||
|
||||
def get_object(self):
|
||||
|
||||
Reference in New Issue
Block a user