From aa7e4ea7706b25130031b7b8bfcce8085e9a634d Mon Sep 17 00:00:00 2001 From: jolheiser Date: Tue, 15 Feb 2022 23:01:37 +0000 Subject: [PATCH] Change questions (#19) This PR updates the questions per Discord. Reviewed-on: https://git.jojodev.com/Minecraft/minecraft_manager/pulls/19 Co-authored-by: jolheiser Co-committed-by: jolheiser --- admin.py | 2 +- api/admin.py | 2 +- api/views.py | 2 +- discord.py | 29 ++ external/urls.py | 12 +- middleware.py | 2 +- models.py | 6 +- static/minecraft_manager/css/external.css | 19 +- static/minecraft_manager/css/sakura.css | 249 ++++++++++++++++++ .../minecraft_manager/application_info.html | 4 +- .../minecraft_manager/external/apply.html | 3 +- .../minecraft_manager/external/base.html | 1 + templatetags/str_utils.py | 10 + urls.py | 42 +-- utils.py | 29 +- 15 files changed, 345 insertions(+), 67 deletions(-) create mode 100644 discord.py create mode 100644 static/minecraft_manager/css/sakura.css create mode 100644 templatetags/str_utils.py diff --git a/admin.py b/admin.py index 5de50b1..bffac2a 100644 --- a/admin.py +++ b/admin.py @@ -3,7 +3,7 @@ from __future__ import absolute_import from django.contrib import admin from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.models import User -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext as _ from minecraft_manager.models import Application, Note, Ticket, TicketNote, Player, IP, UserSettings, Alert, Attachment from minecraft_manager.api.admin import register as api_register diff --git a/api/admin.py b/api/admin.py index 4a89974..849b5cd 100644 --- a/api/admin.py +++ b/api/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext as _ from minecraft_manager.api.models import Token diff --git a/api/views.py b/api/views.py index fdba1eb..af4a8e1 100644 --- a/api/views.py +++ b/api/views.py @@ -314,7 +314,7 @@ class PluginAPI(View): warning.save() json['message'] = "Warning issued." link = mcm_utils.full_reverse('note_info', warning.id) - msg = mcm_utils.build_warning(warning, link) + msg = mcm_utils.build_note(warning, link) mcm_api.discord_mcm(embed=msg) except Exception as ex: json['status'] = False diff --git a/discord.py b/discord.py new file mode 100644 index 0000000..d6829ea --- /dev/null +++ b/discord.py @@ -0,0 +1,29 @@ +from enum import Enum +from datetime import datetime +from typing import Union + + +class TimestampStyle(Enum): + SHORT_TIME = "t" + """16:20""" + LONG_TIME = "T" + """16:20:30""" + SHORT_DATE = "d" + """20/04/2021""" + LONG_DATE = "D" + """20 April 2021""" + SHORT_DATETIME = "f" + """20 April 2021 16:20""" + LONG_DATETIME = "F" + """Tuesday, 20 April 2021 16:20""" + RELATIVE = "R" + """2 months ago""" + + +def format_timestamp(unix: Union[int, datetime], style: TimestampStyle = TimestampStyle.SHORT_DATETIME) -> str: + t = 0 + if isinstance(unix, int): + t = unix + elif isinstance(unix, datetime): + t = unix.timestamp() + return f"" diff --git a/external/urls.py b/external/urls.py index 07d2783..72a5575 100644 --- a/external/urls.py +++ b/external/urls.py @@ -1,10 +1,10 @@ -from django.conf.urls import url -from django.contrib.auth.decorators import login_required +from django.urls import path + import minecraft_manager.external.views as external urlpatterns = [ - url(r'^apply/$', external.Apply.as_view(), name="external-apply"), - url(r'^ticket/$', external.Ticket.as_view(), name="external-ticket"), - url(r'^stats/$', external.Stats.as_view(), name="external-stats"), - url(r'^stats/player/$', external.StatsPlayer.as_view(), name="external-stats-player"), + path('apply/', external.Apply.as_view(), name="external-apply"), + path('ticket/', external.Ticket.as_view(), name="external-ticket"), + path('stats/', external.Stats.as_view(), name="external-stats"), + path('stats/player/', external.StatsPlayer.as_view(), name="external-stats-player"), ] diff --git a/middleware.py b/middleware.py index 69fe329..c7727b9 100644 --- a/middleware.py +++ b/middleware.py @@ -13,4 +13,4 @@ class TimezoneMiddleware(MiddlewareMixin): try: timezone.activate(pytz.timezone(request.user.usersettings.default_timezone)) except: - timezone.deactivate() \ No newline at end of file + timezone.deactivate() diff --git a/models.py b/models.py index 4fc573a..bb6eaba 100644 --- a/models.py +++ b/models.py @@ -66,12 +66,12 @@ class UserSettings(models.Model): class Application(models.Model): username = models.CharField("Minecraft Username", max_length=20, unique=True) age = models.PositiveSmallIntegerField() - player_type = models.TextField("What type of player are you?", max_length=300) + player_type = models.TextField("What's your favorite thing to do in Minecraft?", max_length=300) ever_banned = models.BooleanField("Have you ever been banned?", default=False) ever_banned_explanation = models.TextField("If you were previously banned, will you share why?", max_length=300, blank=True, null=True) - reference = models.CharField("How did you find out about our server?", max_length=50, blank=True, null=True) + reference = models.CharField("How did you find out about us? Please give a website or player name, if applicable.", max_length=50, blank=True, null=True) read_rules = models.CharField("Have you read the rules?", max_length=10) - accepted = models.NullBooleanField() + accepted = models.BooleanField(null=True) date = models.DateTimeField(auto_now_add=True, blank=True, null=True) objects = models.Manager() diff --git a/static/minecraft_manager/css/external.css b/static/minecraft_manager/css/external.css index 8f3436b..e064267 100644 --- a/static/minecraft_manager/css/external.css +++ b/static/minecraft_manager/css/external.css @@ -3,22 +3,19 @@ min-height:100%; height:auto!important; position:fixed; - top:0px; - left:0px; + top:0; + left:0; overflow:hidden; - border:0px; + border:0; z-index:-9; float:left; } #form { - background: rgba(255, 255, 255, .9); - margin: auto; + background: rgba(0, 0, 0, .75); display: block; - width: 35%; - padding-top: 1em; - padding-bottom: 1em; - padding-left: 5em; + width: 75%; + padding: 1em 5em; border-radius: 1em; top: 50%; left: 50%; @@ -65,6 +62,10 @@ color: black; } +.sub { + margin-left: 1em; +} + .rule { margin-bottom: .5em; } diff --git a/static/minecraft_manager/css/sakura.css b/static/minecraft_manager/css/sakura.css new file mode 100644 index 0000000..817b45c --- /dev/null +++ b/static/minecraft_manager/css/sakura.css @@ -0,0 +1,249 @@ +/* Sakura.css v1.3.1 + * ================ + * Minimal css theme. + * Project: https://github.com/oxalorg/sakura/ + */ + +/* Default Sakura Theme */ +:root { + --color-blossom: #1d7484; + --color-fade: #982c61; + --color-bg: #f9f9f9; + --color-bg-alt: #f1f1f1; + --color-text: #4a4a4a; +} + +/* Sakura Dark Theme */ +@media (prefers-color-scheme: dark) { + :root { + --color-blossom: #ffffff; + --color-fade: #c9c9c9; + --color-bg: #222222; + --color-bg-alt: #4a4a4a; + --color-text: #c9c9c9; + } +} + +html { + font-size: 62.5%; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; +} + +body { + font-size: 1.8rem; + line-height: 1.618; + max-width: 38em; + margin: auto; + color: var(--color-text); + background-color: var(--color-bg); + padding: 13px; +} + +@media (max-width: 684px) { + body { + font-size: 1.53rem; + } +} + +@media (max-width: 382px) { + body { + font-size: 1.35rem; + } +} + +h1, h2, h3, h4, h5, h6 { + line-height: 1.1; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-weight: 700; + margin-top: 3rem; + margin-bottom: 1.5rem; + overflow-wrap: break-word; + word-wrap: break-word; + -ms-word-break: break-all; + word-break: break-word; +} + +h1 { + font-size: 2.35em; +} + +h2 { + font-size: 2.00em; +} + +h3 { + font-size: 1.75em; +} + +h4 { + font-size: 1.5em; +} + +h5 { + font-size: 1.25em; +} + +h6 { + font-size: 1em; +} + +p { + margin-top: 0px; + margin-bottom: 2.5rem; +} + +small, sub, sup { + font-size: 75%; +} + +hr { + border-color: var(--color-blossom); +} + +a { + text-decoration: none; + color: var(--color-blossom); +} + +a:hover { + color: var(--color-fade); + border-bottom: 2px solid var(--color-text); +} + +a:visited { + color: var(--color-blossom); +} + +ul { + padding-left: 1.4em; + margin-top: 0px; + margin-bottom: 2.5rem; +} + +li { + margin-bottom: 0.4em; +} + +blockquote { + margin-left: 0px; + margin-right: 0px; + padding-left: 1em; + padding-top: 0.8em; + padding-bottom: 0.8em; + padding-right: 0.8em; + border-left: 5px solid var(--color-blossom); + margin-bottom: 2.5rem; + background-color: var(--color-bg-alt); +} + +blockquote p { + margin-bottom: 0; +} + +img, video { + height: auto; + max-width: 100%; + margin-top: 0px; + margin-bottom: 2.5rem; +} + +/* Pre and Code */ +pre { + background-color: var(--color-bg-alt); + display: block; + padding: 1em; + overflow-x: auto; + margin-top: 0px; + margin-bottom: 2.5rem; +} + +code { + font-size: 0.9em; + padding: 0 0.5em; + background-color: var(--color-bg-alt); + white-space: pre-wrap; +} + +pre > code { + padding: 0; + background-color: transparent; + white-space: pre; +} + +/* Tables */ +table { + text-align: justify; + width: 100%; + border-collapse: collapse; +} + +td, th { + padding: 0.5em; + border-bottom: 1px solid var(--color-bg-alt); +} + +/* Buttons, forms and input */ +input, textarea { + border: 1px solid var(--color-text); +} + +input:focus, textarea:focus { + border: 1px solid var(--color-blossom); +} + +textarea { + width: 100%; +} + +.button, button, input[type="submit"], input[type="reset"], input[type="button"] { + display: inline-block; + padding: 5px 10px; + text-align: center; + text-decoration: none; + white-space: nowrap; + background-color: var(--color-blossom); + color: var(--color-bg); + border-radius: 1px; + border: 1px solid var(--color-blossom); + cursor: pointer; + box-sizing: border-box; +} + +.button[disabled], button[disabled], input[type="submit"][disabled], input[type="reset"][disabled], input[type="button"][disabled] { + cursor: default; + opacity: .5; +} + +.button:focus:enabled, .button:hover:enabled, button:focus:enabled, button:hover:enabled, input[type="submit"]:focus:enabled, input[type="submit"]:hover:enabled, input[type="reset"]:focus:enabled, input[type="reset"]:hover:enabled, input[type="button"]:focus:enabled, input[type="button"]:hover:enabled { + background-color: var(--color-fade); + border-color: var(--color-fade); + color: var(--color-bg); + outline: 0; +} + +textarea, select, input { + color: var(--color-text); + padding: 6px 10px; + /* The 6px vertically centers text on FF, ignored by Webkit */ + margin-bottom: 10px; + background-color: var(--color-bg-alt); + border: 1px solid var(--color-bg-alt); + border-radius: 4px; + box-shadow: none; + box-sizing: border-box; +} + +textarea:focus, select:focus, input:focus { + border: 1px solid var(--color-blossom); + outline: 0; +} + +input[type="checkbox"]:focus { + outline: 1px dotted var(--color-blossom); +} + +label, legend, fieldset { + display: block; + margin-bottom: .5rem; + font-weight: 600; +} \ No newline at end of file diff --git a/templates/minecraft_manager/application_info.html b/templates/minecraft_manager/application_info.html index 5b80d8e..8bdbf6f 100644 --- a/templates/minecraft_manager/application_info.html +++ b/templates/minecraft_manager/application_info.html @@ -9,7 +9,7 @@

Age: {{ application.age }}

Application Date: {{ application.date }}

-

Type Of Player:

+

Favorite Activity:

{{ application.player_type }}

{% if application.accepted is not null %}

Status: {{ application.status }}

@@ -26,7 +26,7 @@

Explanation: {{ application.ever_banned_explanation }}

{% endif %} {% if application.reference %} -

Reference: {{ application.reference }}

+

Referral: {{ application.reference }}

{% endif %}

Read The Rules: {{ application.read_rules }}

diff --git a/templates/minecraft_manager/external/apply.html b/templates/minecraft_manager/external/apply.html index d376524..be61f11 100644 --- a/templates/minecraft_manager/external/apply.html +++ b/templates/minecraft_manager/external/apply.html @@ -1,4 +1,5 @@ {% extends 'minecraft_manager/external/base.html' %} +{% load str_utils %} {% block title %}Application Form{% endblock %} @@ -7,7 +8,7 @@ {% block form_top %}

Rules

{% for rule in rules %} -
{{ rule }}
+
{{ rule }}
{% endfor %} {% endblock %} diff --git a/templates/minecraft_manager/external/base.html b/templates/minecraft_manager/external/base.html index 74197ad..5dca320 100644 --- a/templates/minecraft_manager/external/base.html +++ b/templates/minecraft_manager/external/base.html @@ -10,6 +10,7 @@ {% endif %} + diff --git a/templatetags/str_utils.py b/templatetags/str_utils.py new file mode 100644 index 0000000..8d2f834 --- /dev/null +++ b/templatetags/str_utils.py @@ -0,0 +1,10 @@ +from django import template + +register = template.Library() + + +def has_prefix(value: str, arg: str) -> bool: + return value.startswith(arg) + + +register.filter('has_prefix', has_prefix) diff --git a/urls.py b/urls.py index 02e686d..ed53ee2 100644 --- a/urls.py +++ b/urls.py @@ -1,47 +1,47 @@ -from django.conf.urls import url +from django.urls import path from django.views.generic import RedirectView from django.contrib.auth.decorators import login_required, permission_required import minecraft_manager.views as mcm urlpatterns = [ - url(r'^$', RedirectView.as_view(pattern_name='overview')), + path('', RedirectView.as_view(pattern_name='overview')), # Dashboard - url(r'^overview/$', login_required(mcm.Overview.as_view()), name="overview"), - url(r'^ban/$', login_required(mcm.Ban.as_view()), name="ban"), + path('overview/', login_required(mcm.Overview.as_view()), name="overview"), + path('ban/', login_required(mcm.Ban.as_view()), name="ban"), # Alerts - url(r'^alert/$', login_required(mcm.Alert.as_view()), name="alert"), - url(r'^alert/(?P[0-9]{1,5})/$', login_required(mcm.AlertInfo.as_view()), name="alert_info"), + path('alert/', login_required(mcm.Alert.as_view()), name="alert"), + path('alert//', login_required(mcm.AlertInfo.as_view()), name="alert_info"), # Applications - url(r'^application/$', login_required(mcm.Application.as_view()), name="application"), - url(r'^reference/$', login_required(mcm.Reference.as_view()), name="reference"), - url(r'^application/(?P[0-9]{1,5})/$', login_required(mcm.ApplicationInfo.as_view()), name="application_info"), + path('application/', login_required(mcm.Application.as_view()), name="application"), + path('reference/', login_required(mcm.Reference.as_view()), name="reference"), + path('application//', login_required(mcm.ApplicationInfo.as_view()), name="application_info"), # Players - url(r'^player/$', login_required(mcm.Player.as_view()), name="player"), - url(r'^player/(?P[0-9]{1,5})/$', login_required(mcm.PlayerInfo.as_view()), name="player_info"), + path('player/', login_required(mcm.Player.as_view()), name="player"), + path('player//', login_required(mcm.PlayerInfo.as_view()), name="player_info"), # Tickets - url(r'^ticket/$', login_required(mcm.Ticket.as_view()), name="ticket"), - url(r'^ticket/(?P[0-9]{1,5})/$', login_required(mcm.TicketInfo.as_view()), name="ticket_info"), + path('ticket/', login_required(mcm.Ticket.as_view()), name="ticket"), + path('ticket//', login_required(mcm.TicketInfo.as_view()), name="ticket_info"), # Notes - url(r'^note/$', login_required(mcm.Note.as_view()), name="note"), - url(r'^note/(?P[0-9]{1,5})/$', login_required(mcm.NoteInfo.as_view()), name='note_info'), - url(r'^note/add$', login_required(mcm.NoteAdd.as_view()), name="note_add"), + path('note/', login_required(mcm.Note.as_view()), name="note"), + path('note//', login_required(mcm.NoteInfo.as_view()), name='note_info'), + path('note/add', login_required(mcm.NoteAdd.as_view()), name="note_add"), # Attachments - url(r'^attachment/(?P[0-9]{1,5})/$', login_required(mcm.Attachment.as_view()), name="attachment"), - url(r'attachment/(?P[A-Za-z])/(?P[0-9]{1,5})/$', login_required(mcm.AddAttachment.as_view()), name='attachment_add'), + path('attachment//', login_required(mcm.Attachment.as_view()), name="attachment"), + path('attachment///', login_required(mcm.AddAttachment.as_view()), name='attachment_add'), # IP - url(r'^ip/(?P[0-9]{1,5})/$', login_required(mcm.IP.as_view()), name="ip"), + path('ip//', login_required(mcm.IP.as_view()), name="ip"), # Report - url(r'^report/$', login_required(mcm.Report.as_view()), name="report"), + path('report/', login_required(mcm.Report.as_view()), name="report"), # Chat - url(r'^chat/$', permission_required('minecraft_manager.chat')(mcm.Chat.as_view()), name="chat"), + path('chat/', permission_required('minecraft_manager.chat')(mcm.Chat.as_view()), name="chat"), ] diff --git a/utils.py b/utils.py index 74a472f..4df443b 100644 --- a/utils.py +++ b/utils.py @@ -30,20 +30,20 @@ def build_application(application): embed = discord.Embed(colour=discord.Colour(0x417505)) embed.title = "Application" embed.set_thumbnail( - url="https://minotar.net/helm/{0}/100.png".format(application.username)) + url=f"https://minotar.net/helm/{application.username}/100.png") embed.add_field(name="Application ID", value=application.id) embed.add_field(name="Username", value=application.username.replace("_", "\\_")) embed.add_field(name="Age", value=application.age) - embed.add_field(name="Type of Player", value=application.player_type) + embed.add_field(name="Favorite Activity", value=application.player_type) embed.add_field(name="Ever been banned", value=application.ever_banned) if application.ever_banned and application.ever_banned_explanation: embed.add_field(name="Reason for being banned", value=application.ever_banned_explanation) if application.reference: - embed.add_field(name="Reference", value=application.reference) + embed.add_field(name="Referral", value=application.reference) embed.add_field(name="Read the Rules", value=application.read_rules) embed.timestamp = application.date embed.add_field(name="Status", value=application.status) - embed.add_field(name="Link", value=full_reverse('application_info', application.id)) + embed.add_field(name="Link", value=full_reverse('application_info', application.id), inline=False) return embed @@ -57,19 +57,7 @@ def build_ticket(ticket, link): if ticket.x and ticket.y and ticket.z and ticket.world: embed.add_field(name="Location", value=ticket.location) embed.add_field(name="Message", value=ticket.message) - embed.add_field(name="Link", value=link) - return embed - - -def build_warning(warning, link): - embed = discord.Embed(colour=discord.Colour(0x417505)) - embed.title = "Warning" - embed.set_thumbnail(url=full_static("favicon.png")) - embed.timestamp = warning.date - embed.add_field(name="Player", value=warning.player.username.replace("_", "\\_")) - embed.add_field(name="Importance", value=warning.importance_display) - embed.add_field(name="Message", value=warning.message) - embed.add_field(name="Link", value=link) + embed.add_field(name="Link", value=link, inline=False) return embed @@ -78,16 +66,15 @@ def build_note(note, link): embed.title = "Note" embed.set_thumbnail(url=full_static("favicon.png")) embed.timestamp = note.date - embed.add_field(name="Date", value=note.date_display) embed.add_field(name="Player", value=note.player.username.replace("_", "\\_")) embed.add_field(name="Importance", value=note.importance_display) embed.add_field(name="Message", value=note.message) - embed.add_field(name="Link", value=link) + embed.add_field(name="Link", value=link, inline=False) return embed def validate_username(username): - response = requests.get("https://api.mojang.com/users/profiles/minecraft/{}".format(username)) + response = requests.get(f"https://api.mojang.com/users/profiles/minecraft/{username}") if response.status_code == 200: return True return False @@ -137,4 +124,4 @@ class Captcha: def add_error(self, error): if error not in self.errors: - self.errors.append(error) \ No newline at end of file + self.errors.append(error)