Compare commits
No commits in common. "c8f050531ed1c343e6999454b0a268bea30a0974" and "5ea6e75d0ac940b3e4863805b79c8e0079ba3077" have entirely different histories.
c8f050531e
...
5ea6e75d0a
7 changed files with 6 additions and 109 deletions
|
@ -38,7 +38,7 @@
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="flex-shrink-0" role="main">
|
<main class="flex-shrink-0" role="main">,
|
||||||
<div class="container">
|
<div class="container">
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
|
@ -63,7 +63,7 @@ class RaidResponseForm(ModelForm):
|
||||||
class RaidForm(ModelForm):
|
class RaidForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Raid
|
model = Raid
|
||||||
fields = ["title", "description", "is_optional", "date", "response_deadline"]
|
fields = ["title", "description", "date", "response_deadline"]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
@ -76,7 +76,6 @@ class RaidForm(ModelForm):
|
||||||
self.helper.layout = Layout(
|
self.helper.layout = Layout(
|
||||||
Field("title"),
|
Field("title"),
|
||||||
Field("description"),
|
Field("description"),
|
||||||
Field("is_optional"),
|
|
||||||
Row(
|
Row(
|
||||||
Column("date", css_class="form-group col-md-6"),
|
Column("date", css_class="form-group col-md-6"),
|
||||||
Column("response_deadline", css_class="form-group col-md-6"),
|
Column("response_deadline", css_class="form-group col-md-6"),
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Generated by Django 2.2.6 on 2019-11-20 22:36
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('raids', '0003_auto_20191119_0412'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='raid',
|
|
||||||
name='is_optional',
|
|
||||||
field=models.BooleanField(default=False, help_text='Designates whether this raid is optional. Optional raids are not included in attendance calculations.'),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -23,13 +23,6 @@ class Raid(models.Model):
|
||||||
help_text="Defaults to 24 hours before date and time of raid if not set."
|
help_text="Defaults to 24 hours before date and time of raid if not set."
|
||||||
)
|
)
|
||||||
|
|
||||||
is_optional = models.BooleanField(
|
|
||||||
default=False,
|
|
||||||
help_text=(
|
|
||||||
"Designates whether this raid is optional. Optional raids are not included in attendance calculations."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ["-date"]
|
ordering = ["-date"]
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,8 @@
|
||||||
{% if perms.raids.delete_raid %}<a class="btn text-danger btn-link btn-sm ml-2" role="button" href="{% url 'raid_delete' raid.id %}">Delete</a>{% endif %}
|
{% if perms.raids.delete_raid %}<a class="btn text-danger btn-link btn-sm ml-2" role="button" href="{% url 'raid_delete' raid.id %}">Delete</a>{% endif %}
|
||||||
</h4>
|
</h4>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p class="card-text">{{ raid.description | urlize | linebreaksbr | default:"<em>No description</em>" }}</p>
|
<p class="card-text">{{ raid.description | linebreaksbr | default:"<em>No description</em>" }}</p>
|
||||||
{% if raid.is_optional %}
|
<p class="card-text"><small class="text-muted">Response deadline: {{ raid.response_deadline }}</small></p>
|
||||||
<p class="card-text mb-0"><small class="text-muted">This raid is optional.</small></p>
|
|
||||||
{% endif %}
|
|
||||||
<p class="card-text"><small class="text-muted">Response deadline: {{ raid.response_deadline }}.</small></p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if response_form %}
|
{% if response_form %}
|
||||||
|
@ -32,34 +29,11 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="mb-4"></div>
|
<div class="mb-4"></div>
|
||||||
|
|
||||||
<div class="modal fade" id="exportModal" tabindex="-1" role="dialog" aria-labelledby="exportModalLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="exportModalLabel">Export</h5>
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<p>Export list of characters for automatic invitation using <a href="https://www.curseforge.com/wow/addons/exorsus-raid-tools">Exorsus Raid Tools</a>.</p>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="characters-textinput" class="col-form-label">Characters:</label>
|
|
||||||
<textarea readonly class="form-control" id="characters-textinput" onclick="this.select();"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% regroup responses by get_status_display as status_responses_list %}
|
{% regroup responses by get_status_display as status_responses_list %}
|
||||||
{% for status, status_responses in status_responses_list %}
|
{% for status, status_responses in status_responses_list %}
|
||||||
{% with status=status|default_if_none:"No Response" %}
|
{% with status=status|default_if_none:"No Response" %}
|
||||||
<div class="card mb-2">
|
<div class="card mb-2">
|
||||||
<h6 class="card-header d-flex response-status-{{ status | slugify }}-bg">
|
<h6 class="card-header response-status-{{ status | slugify }}-bg">{{ status }} ({{ status_responses | length }})</h6>
|
||||||
<span class="mr-auto">{{ status }} ({{ status_responses | length }})</span>
|
|
||||||
<span type="button" class="badge badge-dark" data-toggle="modal" data-target="#exportModal">Export</span>
|
|
||||||
</h6>
|
|
||||||
<div class="card-body mb-n4">
|
<div class="card-body mb-n4">
|
||||||
{% regroup status_responses by get_role_display as role_responses_list %}
|
{% regroup status_responses by get_role_display as role_responses_list %}
|
||||||
{% for role, role_responses in role_responses_list %}
|
{% for role, role_responses in role_responses_list %}
|
||||||
|
@ -73,6 +47,7 @@
|
||||||
{% for response in class_responses %}
|
{% for response in class_responses %}
|
||||||
<a class="btn response-character-button mb-1 btn-class-{{ response.character.klass }}" role="button" href="#">
|
<a class="btn response-character-button mb-1 btn-class-{{ response.character.klass }}" role="button" href="#">
|
||||||
{{ response.character.name }}
|
{{ response.character.name }}
|
||||||
|
{% if response.note is not None %}🗩{% endif %}
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -112,15 +87,3 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
|
|
||||||
{% block scripts %}
|
|
||||||
<script>
|
|
||||||
const charactersTextinput = document.querySelector("#characters-textinput");
|
|
||||||
$("#exportModal").on("show.bs.modal", function (event) {
|
|
||||||
charactersTextinput.textContent = $(event.relatedTarget).closest(".card").find(".response-character-button").map(function () {
|
|
||||||
return this.text.trim();
|
|
||||||
}).get().join("\n");
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
{% endblock scripts %}
|
|
|
@ -1,5 +1,4 @@
|
||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.contrib.auth.models import UserManager as DjangoUserManager
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.core.validators import RegexValidator, MinLengthValidator
|
from django.core.validators import RegexValidator, MinLengthValidator
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
|
@ -21,11 +20,6 @@ class Rank(models.Model):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class UserManager(DjangoUserManager):
|
|
||||||
def get_by_natural_key(self, username):
|
|
||||||
return super().get_by_natural_key(self.model.normalize_username(username))
|
|
||||||
|
|
||||||
|
|
||||||
class User(AbstractUser):
|
class User(AbstractUser):
|
||||||
first_name = None
|
first_name = None
|
||||||
last_name = None
|
last_name = None
|
||||||
|
@ -43,25 +37,15 @@ class User(AbstractUser):
|
||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
|
|
||||||
objects = UserManager()
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ["rank", "username"]
|
ordering = ["rank", "username"]
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
self.username = self.normalize_username(self.username)
|
|
||||||
if not hasattr(self, "rank"):
|
if not hasattr(self, "rank"):
|
||||||
self.rank = Rank.objects.last()
|
self.rank = Rank.objects.last()
|
||||||
if hasattr(self, "main") and self.main.user != self:
|
if hasattr(self, "main") and self.main.user != self:
|
||||||
raise ValidationError({"main": "Main character must be owned by user."})
|
raise ValidationError({"main": "Main character must be owned by user."})
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def normalize_username(cls, username):
|
|
||||||
"""
|
|
||||||
Make username case-insensitive.
|
|
||||||
"""
|
|
||||||
return super().normalize_username(username).lower()
|
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if not hasattr(self, "main"):
|
if not hasattr(self, "main"):
|
||||||
|
|
24
migrate.py
24
migrate.py
|
@ -1,24 +0,0 @@
|
||||||
import json
|
|
||||||
|
|
||||||
with open("data.json", "r") as file:
|
|
||||||
data = json.load(file)
|
|
||||||
for o in data:
|
|
||||||
print(o)
|
|
||||||
if o["model"] == "raids.raidresponse":
|
|
||||||
if o["fields"]["status"] >= 2: # SIGNED_UP
|
|
||||||
o["fields"]["attendance"] = 1.0
|
|
||||||
else:
|
|
||||||
o["fields"]["attendance"] = 0.0
|
|
||||||
if o["model"] == "users.user":
|
|
||||||
o["fields"]["rank"] = 3 # veteran
|
|
||||||
|
|
||||||
print("=============================================")
|
|
||||||
print("=============================================")
|
|
||||||
print("=============================================")
|
|
||||||
|
|
||||||
with open("new.json", "w") as file:
|
|
||||||
skip = ["contenttypes.contenttype", "auth.permission", "admin.logentry"]
|
|
||||||
thedump = [d for d in data if d["model"] not in skip]
|
|
||||||
for d in thedump:
|
|
||||||
print(d)
|
|
||||||
json.dump(thedump, file)
|
|
Loading…
Reference in a new issue