Skip to content

Commit

Permalink
Make site logo configurable in misc_config
Browse files Browse the repository at this point in the history
  • Loading branch information
magnified103 authored and hieplpvip committed Sep 29, 2024
1 parent 50f7271 commit 9aa08ff
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 3 deletions.
3 changes: 3 additions & 0 deletions dmoj/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,9 @@
SUBMISSION_FILE_UPLOAD_URL_PREFIX = '/submission_file'
SUBMISSION_FILE_UPLOAD_MEDIA_DIR = 'submission_file'

STATIC_UPLOAD_URL_PREFIX = '/static-upload'
STATIC_UPLOAD_MEDIA_DIR = 'static-upload'

# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

Expand Down
3 changes: 3 additions & 0 deletions dmoj/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from judge.views import TitledTemplateView, api, blog, comment, contests, language, license, mailgun, organization, \
preview, problem, problem_manage, ranked_submission, register, stats, status, submission, tag, tasks, ticket, \
two_factor, user, widgets
from judge.views.misc_config import MiscConfigEdit
from judge.views.magazine import MagazinePage
from judge.views.problem_data import ProblemDataView, ProblemSubmissionDiff, \
problem_data_file, problem_init_view
Expand Down Expand Up @@ -421,6 +422,8 @@ def paged_list_view(view, name):
])),

path('magazine/', MagazinePage.as_view(), name='magazine'),

path('misc_config/', MiscConfigEdit.as_view(), name='misc_config'),
]

favicon_paths = ['apple-touch-icon-180x180.png', 'apple-touch-icon-114x114.png', 'android-chrome-72x72.png',
Expand Down
18 changes: 18 additions & 0 deletions judge/migrations/0203_unique_miscconfig_key.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.23 on 2024-01-12 10:16

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('judge', '0202_import_polygon_package'),
]

operations = [
migrations.AlterField(
model_name='miscconfig',
name='key',
field=models.CharField(max_length=30, unique=True, verbose_name='key'),
),
]
2 changes: 1 addition & 1 deletion judge/models/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


class MiscConfig(models.Model):
key = models.CharField(max_length=30, verbose_name=_('key'), db_index=True)
key = models.CharField(max_length=30, verbose_name=_('key'), unique=True)
value = models.TextField(verbose_name=_('value'), blank=True)

def __str__(self):
Expand Down
37 changes: 37 additions & 0 deletions judge/views/misc_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from django import forms
from django.db import transaction
from django.http import Http404
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django.views.generic import FormView

from judge.models import MiscConfig
from judge.utils.views import TitleMixin
from judge.views.widgets import static_uploader


class MiscConfigForm(forms.Form):
logo = forms.FileField(help_text='The site logo e.g. the image in the top left corner.')


class MiscConfigEdit(TitleMixin, FormView):
template_name = 'misc_config/edit.html'
form_class = MiscConfigForm
title = _('Site settings')

def get_success_url(self):
return reverse('home')

def form_valid(self, form):
with transaction.atomic():
logo = form.files.get('logo', default=None)
if logo is not None:
logo_url = static_uploader(logo)
config, _ = MiscConfig.objects.update_or_create(key='site_logo', defaults={'value': logo_url})
config.save()
return super().form_valid(form)

def dispatch(self, request, *args, **kwargs):
if not request.user.is_superuser:
raise Http404
return super().dispatch(request, *args, **kwargs)
11 changes: 11 additions & 0 deletions judge/views/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ def martor_image_uploader(request):
return HttpResponse(data, content_type='application/json')


def static_uploader(static_file):
ext = os.path.splitext(static_file.name)[1]
name = str(uuid.uuid4()) + ext
default_storage.save(os.path.join(settings.STATIC_UPLOAD_MEDIA_DIR, name), static_file)
url_base = getattr(settings, 'STATIC_UPLOAD_URL_PREFIX',
urljoin(settings.MEDIA_URL, settings.STATIC_UPLOAD_MEDIA_DIR))
if not url_base.endswith('/'):
url_base += '/'
return urljoin(url_base, name)


def csrf_failure(request: HttpRequest, reason=''):
# Redirect to the same page in case of CSRF failure
# So that we can turn on cloudflare DDOS protection without
Expand Down
7 changes: 7 additions & 0 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,13 @@
</ul>

<span id="user-links">
{% if request.user.is_superuser %}
<a href="{{ url('misc_config') }}" style="margin-right: 5px;">
<span title="{{ _('Site settings') }}">
<i class="fa fa-gear" style="color: rgb(200,200,200) ; font-size: 1.15em"></i>
</span>
</a>
{% endif %}
<a href=
{% if request.resolver_match.view_name == "problem_detail" and problem %}
"{{ url('new_problem_ticket', problem.code) }}"
Expand Down
38 changes: 38 additions & 0 deletions templates/misc_config/edit.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{% extends "base.html" %}

{% block js_media %}
{{ form.media.js }}
{% endblock %}

{% block media %}
{{ form.media.css }}
<link rel="stylesheet" type="text/css" href="{{ static('ui_form.css') }}">
<style>
.hidden {
display: none;
}
</style>
{% endblock %}

{% block body %}
<div>
{% if request.user.is_staff %}
<div class="alert alert-warning alert-dismissable">
<a class="close">x</a>
<a href="{{ url('admin:judge_miscconfig_changelist') }}">{{ _('Configure in admin panel for more options') }}</a>
</div>
{% endif %}
<form action="" method="post" class="form-area" enctype="multipart/form-data" style="display: flex; justify-content: center; flex-direction: column;">
{% if form.errors %}
<p class="errornote"> {{ _('Please correct the error below.') }}</p>
{% endif %}
{% csrf_token %}
<table class="django-as-table">{{ form.as_table() }}</table>
<table>
<tr><td style="float: left;">
<td style="float: right;"><input type="submit" value="{{ _('Update') }}" class="button"></td></tr>
</table>
</form>
</div>
{% endblock %}

6 changes: 4 additions & 2 deletions templates/site-logo-fragment.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
{% elif logo_override_image is defined and logo_override_image %}
<img src="{{ logo_override_image|camo }}" alt="{{ SITE_NAME }}" height="40" style="border: none; padding-top: 4px">
{% else %}
<img src="{{ static('icons/logo.svg') }}" alt="{{ SITE_NAME }}" width="130" height="40"
onerror="this.src=&quot;{{ static('icons/logo.png') }}&quot;; this.onerror=null" style="border: none; padding-top: 4px">
{% with logo_url=misc_config.site_logo|default(static('icons/logo.svg'), true) %}
<img src="{{ logo_url }}" alt="{{ SITE_NAME }}" width="130" height="40"
onerror="this.src=&quot;{{ logo_url }}&quot;; this.onerror=null" style="border: none; padding-top: 4px">
{% endwith %}
{% endif %}

0 comments on commit 9aa08ff

Please sign in to comment.