various interface changes
This commit is contained in:
parent
7307ec3931
commit
2445fadf63
11
README.md
11
README.md
|
@ -5,15 +5,18 @@ A django app running on Docker. Replaces _Aus GLAM Blogs_.
|
|||
## Deploy
|
||||
|
||||
* `docker compose build`
|
||||
* `./glamr-dev createsuperuser`
|
||||
* `./glamr-dev makemigrations`
|
||||
* `./glamr-dev makemigrations` (may get a DB connection error here, ignore it or run again)
|
||||
* `./glamr-dev migrate`
|
||||
* `./glamr-dev createsuperuser`
|
||||
* `docker compose up`
|
||||
|
||||
* set up database backups (as cron jobs):
|
||||
|
||||
* `/usr/bin/docker exec -u root ausglamr-db-1 pg_dump -v -Fc -U ausglamr -d "ausglamr" -f /tmp/ausglamr_backup.dump`
|
||||
* `/usr/bin/docker cp ausglamr-db-1:/tmp/ausglamr_backup.dump /home/hugh/backups/`
|
||||
* `./glamr-dev backup`
|
||||
|
||||
* `/snap/bin/docker exec -u root ausglamr_db_1 pg_dump -v -Fc -U ausglamr -d "ausglamr" -f /tmp/ausglamr_backup.dump`
|
||||
* `/snap/bin/docker cp ausglamr_db_1:/tmp/ausglamr_backup.dump /home/hugh/backups/`
|
||||
* `mv /home/hugh/backups/ausglamr_backup.dump /home/hugh/backups/ausglamr_backup_$(date +'%a').dump`
|
||||
|
||||
* set up cron jobs for management commands as below
|
||||
|
||||
|
|
|
@ -32,11 +32,11 @@ SECRET_KEY = env("SECRET_KEY")
|
|||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = env("DEBUG")
|
||||
ALLOWED_HOSTS = [env("DOMAIN")]
|
||||
CSRF_COOKIE_SECURE=True
|
||||
SESSION_COOKIE_SECURE=True
|
||||
ALLOWED_HOSTS = ['.localhost', '127.0.0.1', '[::1]', env("DOMAIN")]
|
||||
CSRF_COOKIE_SECURE = True
|
||||
SESSION_COOKIE_SECURE = True
|
||||
CSRF_TRUSTED_ORIGINS = [f'https://{env("DOMAIN")}']
|
||||
CONN_MAX_AGE=None # persistent DB connection
|
||||
CONN_MAX_AGE = None # persistent DB connection
|
||||
|
||||
# Application definition
|
||||
|
||||
|
@ -180,4 +180,4 @@ LOGGING = {
|
|||
"handlers": ["console"],
|
||||
"level": "INFO",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,14 @@ urlpatterns = [
|
|||
path("contribute", views.Contribute.as_view(), name="contribute"),
|
||||
path("contact", views.Contact.as_view(), name="contact"),
|
||||
path("blogs", views.Blogs.as_view(), name="blogs"),
|
||||
path("blogs/<category>", views.Blogs.as_view(), name="blog-category "),
|
||||
path("events", views.Conferences.as_view(), name="events"),
|
||||
path("cfps", views.CallsForPapers.as_view(), name="cfps"),
|
||||
path("events/<category>", views.Conferences.as_view(), name="events-category"),
|
||||
re_path(r"^cfps/?$", views.CallsForPapers.as_view(), name="cfps"),
|
||||
path("groups", views.Groups.as_view(), name="groups"),
|
||||
path("groups/<category>", views.Groups.as_view(), name="group-category"),
|
||||
path("newsletters", views.Newsletters.as_view(), name="newsletters"),
|
||||
path("newsletters/<category>", views.Newsletters.as_view(), name="newsletters-category"),
|
||||
path("register-blog", views.RegisterBlog.as_view(), name="register-blog"),
|
||||
path(
|
||||
"submit-blog-registration",
|
||||
|
|
|
@ -20,9 +20,7 @@ def approve(modeladmin, request, queryset):
|
|||
|
||||
if hasattr(instance, "event"): # CFP
|
||||
recipient = instance.event.contact_email
|
||||
if hasattr(
|
||||
instance, "contact_email"
|
||||
): # overrides above in case needed in future
|
||||
if hasattr(instance, "contact_email"):
|
||||
recipient = instance.contact_email
|
||||
|
||||
if recipient:
|
||||
|
@ -32,7 +30,10 @@ def approve(modeladmin, request, queryset):
|
|||
title = instance.title
|
||||
|
||||
subject = f"✅ {title} has been approved on AusGLAMR!"
|
||||
message = f"<html><body><p>{title} has been approved on <a href='https://{settings.DOMAIN}'>AusGLAMR</a>. Hooray!</p></body></html>"
|
||||
message = f"<html><body><p>{title} has been approved on <a href='https://{settings.DOMAIN}'>AusGLAMR</a>. Hooray!</p>"
|
||||
if type(instance).__name__ == "Event":
|
||||
message += f"<p>You can now optionally <a href='https://{settings.DOMAIN}/register-cfp'>register a call for papers</a>.</p>"
|
||||
message += "</body></html>"
|
||||
|
||||
utilities.send_email(subject, message, recipient)
|
||||
|
||||
|
|
|
@ -28,7 +28,9 @@ class Command(BaseCommand):
|
|||
)
|
||||
|
||||
cutoff = timezone.now() - timedelta(days=7)
|
||||
blogs = models.Blog.objects.filter(approved=True, updateddate__gte=cutoff)
|
||||
blogs = models.Blog.objects.filter(
|
||||
approved=True, active=True, added__gte=cutoff
|
||||
)
|
||||
articles = models.Article.objects.filter(pubdate__gte=cutoff)
|
||||
events = models.Event.objects.filter(approved=True, pub_date__gte=cutoff)
|
||||
cfps = models.CallForPapers.objects.filter(
|
||||
|
|
|
@ -25,7 +25,7 @@ class BlogData(models.Model):
|
|||
"""Base bloggy data"""
|
||||
|
||||
title = models.CharField(max_length=2000)
|
||||
author_name = models.CharField(max_length=1000, null=True)
|
||||
author_name = models.CharField(max_length=1000, null=True, blank=True)
|
||||
url = models.URLField(max_length=2000, unique=True)
|
||||
description = models.TextField(null=True, blank=True)
|
||||
updateddate = models.DateTimeField()
|
||||
|
@ -55,6 +55,7 @@ class Blog(BlogData):
|
|||
|
||||
feed = models.URLField(max_length=2000)
|
||||
category = models.CharField(choices=Category.choices, max_length=4)
|
||||
added = models.DateTimeField()
|
||||
approved = models.BooleanField(default=False)
|
||||
announced = models.BooleanField(default=False)
|
||||
failing = models.BooleanField(default=False, blank=True, null=True)
|
||||
|
@ -66,6 +67,11 @@ class Blog(BlogData):
|
|||
)
|
||||
contact_email = models.EmailField(blank=True, null=True)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.added:
|
||||
self.added = timezone.now()
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def announce(self):
|
||||
"""queue announcement"""
|
||||
|
||||
|
@ -108,7 +114,7 @@ class Article(BlogData):
|
|||
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name="articles")
|
||||
pubdate = models.DateTimeField()
|
||||
guid = models.CharField(max_length=2000)
|
||||
tags = models.ManyToManyField("Tag", related_name="articles")
|
||||
tags = models.ManyToManyField("Tag", related_name="articles", null=True, blank=True)
|
||||
|
||||
# pylint: disable=undefined-variable
|
||||
def announce(self):
|
||||
|
|
|
@ -9,10 +9,10 @@ from .utils import Announcement, Category
|
|||
class Event(models.Model):
|
||||
"""a event"""
|
||||
|
||||
name = models.CharField(max_length=999)
|
||||
name = models.CharField(max_length=100)
|
||||
category = models.CharField(choices=Category.choices, max_length=4)
|
||||
url = models.URLField(max_length=400, unique=True)
|
||||
description = models.TextField(null=True, blank=True)
|
||||
description = models.TextField(null=True, blank=True, max_length=250)
|
||||
pub_date = models.DateTimeField() # for RSS feed
|
||||
start_date = models.DateField()
|
||||
announcements = models.IntegerField(null=True, blank=True, default=0)
|
||||
|
@ -55,9 +55,9 @@ class CallForPapers(models.Model):
|
|||
"""a event call for papers/presentations"""
|
||||
|
||||
name = models.CharField(
|
||||
max_length=999
|
||||
max_length=100
|
||||
) # "Call for papers", "call for participation" etc
|
||||
details = models.TextField(null=True, blank=True)
|
||||
details = models.TextField(null=True, blank=True, max_length=250)
|
||||
pub_date = models.DateTimeField(null=True, default=None)
|
||||
opening_date = models.DateField()
|
||||
closing_date = models.DateField()
|
||||
|
|
|
@ -9,12 +9,12 @@ from .utils import Announcement, Category, GroupType
|
|||
class Group(models.Model):
|
||||
"""a group on email, discord, slack etc"""
|
||||
|
||||
name = models.CharField(max_length=999)
|
||||
name = models.CharField(max_length=100)
|
||||
category = models.CharField(choices=Category.choices, max_length=4)
|
||||
type = models.CharField(choices=GroupType.choices, max_length=4)
|
||||
url = models.URLField(max_length=400, unique=True)
|
||||
registration_url = models.URLField(max_length=400, unique=True)
|
||||
description = models.TextField(null=True, blank=True)
|
||||
description = models.TextField(null=True, blank=True, max_length=250)
|
||||
contact_email = models.EmailField(blank=True, null=True)
|
||||
announced = models.BooleanField(default=False)
|
||||
approved = models.BooleanField(default=False)
|
||||
|
|
|
@ -9,12 +9,12 @@ from .utils import Announcement, Category
|
|||
class Newsletter(models.Model):
|
||||
"""a newsletter"""
|
||||
|
||||
name = models.CharField(max_length=999)
|
||||
author = models.CharField(max_length=999)
|
||||
name = models.CharField(max_length=100)
|
||||
author = models.CharField(max_length=100)
|
||||
category = models.CharField(choices=Category.choices, max_length=4)
|
||||
url = models.URLField(max_length=400, unique=True)
|
||||
|
||||
description = models.TextField(null=True, blank=True)
|
||||
description = models.TextField(null=True, blank=True, max_length=250)
|
||||
activitypub_account_name = models.CharField(max_length=200, blank=True, null=True)
|
||||
contact_email = models.EmailField(blank=True, null=True)
|
||||
announced = models.BooleanField(default=False)
|
||||
|
|
|
@ -1,20 +1,28 @@
|
|||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="listing l-three header">
|
||||
<div>Title</div>
|
||||
<div>Category</div>
|
||||
<div>Last updated</div>
|
||||
<div>
|
||||
<a href="{% url 'register-blog' %}"><button class="button button-first">Add a Blog</button></a>
|
||||
</div>
|
||||
<div class="listing l-three header">
|
||||
<div>Title</div>
|
||||
<div>Category</div>
|
||||
<div>Last updated</div>
|
||||
</div>
|
||||
<hr/>
|
||||
{% for blog in blogs %}
|
||||
<div class="listing l-three">
|
||||
<div>
|
||||
<p><a href="{{blog.url}}">{{blog.title}}</a></p>
|
||||
<p>{{blog.description}}</p>
|
||||
</div>
|
||||
<hr/>
|
||||
{% for blog in blogs %}
|
||||
<div class="listing l-three">
|
||||
<div><a href="{{blog.url}}">{{blog.title}}</a><p>{{blog.description}}</p></div>
|
||||
<div><div class="end badge badge_{{blog.category}}">{{blog.category_name}}</div></div>
|
||||
<div>{{ blog.updateddate|date:"D d M Y" }}
|
||||
</div>
|
||||
<div><div class="end badge badge_{{blog.category}}"><a href="/blogs/{{blog.category}}">{{blog.category_name}}</a></div></div>
|
||||
<div>{{ blog.updateddate|date:"D d M Y" }}
|
||||
</div>
|
||||
<hr/>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<hr/>
|
||||
{% empty %}
|
||||
<p>Oh no! There are no blogs currently registered. Try checking out <a href="{% url 'newsletters' %}">some newsletters</a>.</p>
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
|
@ -10,7 +10,7 @@
|
|||
<hr/>
|
||||
|
||||
{% for cfp in cfps %}
|
||||
<div class="listing l-three">
|
||||
<div class="listing l-three" id="cfp_{{cfp.id}}">
|
||||
<div>
|
||||
<p><strong>{{cfp.name}}</strong></p>
|
||||
<p>{{cfp.details}}</p>
|
||||
|
@ -19,7 +19,9 @@
|
|||
<span class="closing-date">{{cfp.closing_date}}</span>
|
||||
</div>
|
||||
<hr/>
|
||||
{% endfor %}
|
||||
{% empty %}
|
||||
<p>Oh no! There are no Calls for Papers currently open. Try checking out <a href="{% url 'newsletters' %}">some newsletters</a>.</p>
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{% endblock %}
|
|
@ -2,30 +2,33 @@
|
|||
|
||||
{% block content %}
|
||||
|
||||
<div class="listing l-four header">
|
||||
<span>Name</span>
|
||||
<span>Category</span>
|
||||
<span>Start Date</span>
|
||||
<span>Description</span>
|
||||
</div>
|
||||
<hr/>
|
||||
|
||||
|
||||
{% for con in cons %}
|
||||
<div>{{con.call_for_papers.closing_date}}</div>
|
||||
<div class="listing l-four">
|
||||
<span><a href="{{con.url}}">{{con.name}}</a></span>
|
||||
<span><span class="badge badge_{{con.category}}">{{con.category_name}}</span></span>
|
||||
<span class="start-date">{{con.start_date}}</span>
|
||||
<div>
|
||||
<div>{{con.description}}</div>
|
||||
{% if con.call_for_papers %}
|
||||
<div><em><a href="{% url 'cfps' %}">{{ con.call_for_papers }}</a></em></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
<a href="{% url 'register-event' %}"><button class="button button-first">Add an Event</button></a>
|
||||
<a href="{% url 'register-cfp' %}"><button class="button">Add a CFP</button></a>
|
||||
</div>
|
||||
<div class="listing l-three header">
|
||||
<span>Description</span>
|
||||
<span>Category</span>
|
||||
<span>Start Date</span>
|
||||
</div>
|
||||
<hr/>
|
||||
{% for con in cons %}
|
||||
<div class="listing l-three">
|
||||
<div>
|
||||
<p><a href="{{con.url}}">{{con.name}}</a></p>
|
||||
<div>
|
||||
<p>{{con.description}}</p>
|
||||
{% if con.call_for_papers %}
|
||||
<p><em><a href="/cfps/#cfp_{{con.call_for_papers.id}}">{{con.call_for_papers.name}} closes {{ con.call_for_papers.closing_date|date:"D d M" }}</a></em></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<hr/>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
<span><span class="badge badge_{{con.category}}"><a href="/events/{{con.category}}">{{con.category_name}}</a></span></span>
|
||||
<span class="start-date">{{con.start_date}}</span>
|
||||
</div>
|
||||
<hr/>
|
||||
{% empty %}
|
||||
<p>Oh no! There are no events currently registered. Try checking out <a href="{% url 'blogs' %}">some blogs</a>.</p>
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
|
@ -1,20 +1,26 @@
|
|||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="listing l-four header">
|
||||
<span>Name</span>
|
||||
<span>Category</span>
|
||||
<div>
|
||||
<a href="{% url 'register-group' %}"><button class="button button-first">Add a Group</button></a>
|
||||
</div>
|
||||
<div class="listing l-three header">
|
||||
<span>Description</span>
|
||||
<span>Category</span>
|
||||
<span>Registration Link</span>
|
||||
</div>
|
||||
<hr/>
|
||||
{% for group in groups %}
|
||||
<div class="listing l-four">
|
||||
<span><a href="{{group.url}}">{{group.name}}</a></span>
|
||||
<span><span class="badge badge_{{group.category}}">{{group.category_name}}</span></span>
|
||||
<span>{{group.description}}</span>
|
||||
<div class="listing l-three">
|
||||
<span>
|
||||
<p><a href="{{group.url}}">{{group.name}}</a></p>
|
||||
<p><span>{{group.description}}</span></p>
|
||||
</span>
|
||||
<span><span class="badge badge_{{group.category}}"><a href="/groups/{{group.category}}">{{group.category_name}}</a></span></span>
|
||||
<span><a href="{{group.registration_url}}">Join the {{group.reg_type}}</a></span>
|
||||
</div>
|
||||
<hr/>
|
||||
{% empty %}
|
||||
<p>Oh no! There are no groups currently registered. Try checking out <a href="{% url 'newsletters' %}">some newsletters</a>.</p>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
|
@ -1,6 +1,9 @@
|
|||
{% extends "layout.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div>
|
||||
<a href="{% url 'register-newsletter' %}"><button class="button button-first">Add a Newsletter</button></a>
|
||||
</div>
|
||||
<div class="listing l-three header">
|
||||
<span>Title</span>
|
||||
<span>Author</span>
|
||||
|
@ -11,8 +14,10 @@
|
|||
<div class="listing l-three">
|
||||
<span><a href="{{pub.url}}">{{pub.name}}</a></span>
|
||||
<span>{{pub.author}}</span>
|
||||
<span><span class="badge badge_{{pub.category}}">{{pub.category_name}}</span></span>
|
||||
<span><span class="badge badge_{{pub.category}}"><a href="/newsletters/{{pub.category}}">{{pub.category_name}}</a></span></span>
|
||||
</div>
|
||||
<hr/>
|
||||
{% empty %}
|
||||
<p>Oh no! There are no newsletter currently registered. Try checking out <a href="{% url 'blogs' %}">some blogs</a>.</p>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
|
@ -27,36 +27,7 @@
|
|||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="columns eight">
|
||||
{% if conf_name %}
|
||||
<input hidden type="text" name="event" value="{{ form.event.value }}">
|
||||
{% else %}
|
||||
<label for="{{ form.event.id_for_label }}">Event:</label>
|
||||
{% if errors %} {{ form.event.errors }} {% endif %}
|
||||
{{ form.event }}
|
||||
{% endif %}
|
||||
|
||||
<label for="{{ form.name.id_for_label }}">Name:</label>
|
||||
{% if errors %} {{ form.name.errors }} {% endif %}
|
||||
<p class="hint">e.g. "Call for Papers", "Request for submissions" etc</p>
|
||||
<input type="text" name="name" id="name" class="u-full-width" required="">
|
||||
{% if errors %} {{ form.details.errors }} {% endif %}
|
||||
<label for="{{ form.details.id_for_label }}">Details:</label>
|
||||
<textarea name="details" id="details" class="u-full-width"></textarea>
|
||||
|
||||
<div class="row">
|
||||
<span class="columns four">
|
||||
{% if errors %} {{ form.opening_date.errors }} {% endif %}
|
||||
<label for="{{ form.opening_date.id_for_label }}">opening_date:</label>
|
||||
{% if errors %} {{ form.opening_date.errors }} {% endif %}
|
||||
{{ form.opening_date }}
|
||||
</span>
|
||||
<span class="columns four">
|
||||
<label for="{{ form.closing_date.id_for_label }}">closing_date:</label>
|
||||
{% if errors %} {{ form.closing_date.errors }} {% endif %}
|
||||
{{ form.closing_date }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{{ form }}
|
||||
<input class="button-primary u-pull-right" type="submit" value="Register!">
|
||||
<a href="/"><button class="button u-pull-right button-first" type="button">No thanks</button></a>
|
||||
</div>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ title }}</title>
|
||||
<link rel="icon" type="image/svg" href="{% static 'favicon.svg' %}" />
|
||||
<link rel="stylesheet" href="{% static 'css/normalize.css' %}" type="text/css" />
|
||||
<link rel="stylesheet" href="{% static 'css/skeleton.css' %}" type="text/css" />
|
||||
<link rel="stylesheet" href="{% static 'css/custom.css' %}" type="text/css" />
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
{% if register_type == "email address" %}
|
||||
<p>Check your inbox to confirm your subscription. You can opt-out at any time by clicking the link at the bottom of the weekly emails.</p>
|
||||
{% elif register_type == "conference" %}
|
||||
<p>Once your conference is approved, you will be able to register a <a href="{% url 'cfps' %}">Call for Papers</a> if you would like to do so.</p>
|
||||
{% else %}
|
||||
<p>Your {{ register_type }} registration will be reviewed before being added to <em>Aus GLAMR</em>.</p>
|
||||
{% endif %}
|
||||
|
|
|
@ -205,7 +205,6 @@ class CommandsTestCase(TestCase):
|
|||
# should not be announced
|
||||
self.assertEqual(models.Announcement.objects.count(), 0)
|
||||
|
||||
|
||||
def test_check_feeds_exclude_tag(self):
|
||||
"""test parse a feed with exclude tag"""
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ from operator import attrgetter
|
|||
|
||||
from django.conf import settings
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.contrib.postgres.aggregates import ArrayAgg
|
||||
from django.contrib.postgres.search import SearchRank, SearchVector
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.core.mail import EmailMessage
|
||||
|
@ -34,12 +35,21 @@ class HomeFeed(View):
|
|||
class Blogs(View):
|
||||
"""browse the list of blogs"""
|
||||
|
||||
def get(self, request):
|
||||
def get(self, request, category=None):
|
||||
"""here they are"""
|
||||
|
||||
blogs = models.Blog.objects.filter(approved=True, active=True).order_by(
|
||||
"-updateddate"
|
||||
)
|
||||
if category:
|
||||
|
||||
blogs = models.Blog.objects.filter(approved=True, active=True, category=category).order_by(
|
||||
"-updateddate"
|
||||
)
|
||||
|
||||
else:
|
||||
|
||||
blogs = models.Blog.objects.filter(approved=True, active=True).order_by(
|
||||
"-updateddate"
|
||||
)
|
||||
|
||||
for blog in blogs:
|
||||
blog.category_name = models.Category(blog.category).label
|
||||
data = {"title": "Blogs and websites", "blogs": blogs}
|
||||
|
@ -49,18 +59,22 @@ class Blogs(View):
|
|||
class Conferences(View):
|
||||
"""browse the list of conferences"""
|
||||
|
||||
def get(self, request):
|
||||
def get(self, request, category=None):
|
||||
"""here they are"""
|
||||
now = timezone.now()
|
||||
cons = models.Event.objects.filter(approved=True, start_date__gte=now).order_by(
|
||||
"start_date"
|
||||
)
|
||||
|
||||
if category:
|
||||
cons = models.Event.objects.filter(approved=True, start_date__gte=now, category=category).order_by(
|
||||
"start_date"
|
||||
)
|
||||
else:
|
||||
cons = models.Event.objects.filter(approved=True, start_date__gte=now).order_by(
|
||||
"start_date"
|
||||
)
|
||||
|
||||
for con in cons:
|
||||
con.category_name = models.Category(con.category).label
|
||||
con.call_for_papers = con.cfp.all().last()
|
||||
if con.call_for_papers and (con.call_for_papers.closing_date > now.date()):
|
||||
date = con.call_for_papers.closing_date.strftime("%a %d %b %Y")
|
||||
con.call_for_papers = f"{con.call_for_papers.name} closes {date}"
|
||||
con.call_for_papers = con.cfp.filter(closing_date__gte=timezone.now()).order_by("-closing_date").last()
|
||||
|
||||
data = {"title": "Upcoming events", "cons": cons}
|
||||
return render(request, "browse/events.html", data)
|
||||
|
@ -82,9 +96,15 @@ class CallsForPapers(View):
|
|||
class Groups(View):
|
||||
"""browse the list of groups"""
|
||||
|
||||
def get(self, request):
|
||||
def get(self, request, category=None):
|
||||
"""here they are"""
|
||||
groups = models.Group.objects.filter(approved=True).order_by("name")
|
||||
|
||||
if category:
|
||||
groups = models.Group.objects.filter(approved=True, category=category).order_by("name")
|
||||
|
||||
else:
|
||||
groups = models.Group.objects.filter(approved=True).order_by("name")
|
||||
|
||||
for group in groups:
|
||||
group.category_name = models.Category(group.category).label
|
||||
group.reg_type = models.utils.GroupType(group.type).label
|
||||
|
@ -188,17 +208,7 @@ class RegisterConference(View):
|
|||
if form.is_valid():
|
||||
conf = form.save()
|
||||
send_email("event", conf)
|
||||
cfp_form = forms.RegisterCallForPapersForm({"event": conf.id})
|
||||
data = {
|
||||
"title": "Register your Call for Papers",
|
||||
"form": cfp_form,
|
||||
"conf_name": conf.name,
|
||||
}
|
||||
|
||||
return render(request, "events/cfp.html", data)
|
||||
|
||||
data = {"title": "Complete blog registration", "form": form, "errors": True}
|
||||
return render(request, "events/register.html", data)
|
||||
return redirect("/thankyou/conference")
|
||||
|
||||
|
||||
class RegisterCallForPapers(View):
|
||||
|
@ -292,13 +302,16 @@ class Search(View):
|
|||
query = request.GET.get("q")
|
||||
|
||||
article_vector = (
|
||||
SearchVector("tags__name", weight="A")
|
||||
SearchVector("tagnames", weight="A")
|
||||
+ SearchVector("title", weight="B")
|
||||
+ SearchVector("description", weight="C")
|
||||
)
|
||||
|
||||
articles = (
|
||||
models.Article.objects.annotate(rank=SearchRank(article_vector, query))
|
||||
models.Article.objects.annotate(
|
||||
tagnames=ArrayAgg("tags__name", distinct=True), # see above: this prevents many-to-many objects like tags causing the same article to appear in the results multiple times
|
||||
rank=SearchRank(article_vector, query)
|
||||
)
|
||||
.filter(rank__gte=0.1)
|
||||
.order_by("-rank")
|
||||
)
|
||||
|
@ -308,7 +321,8 @@ class Search(View):
|
|||
)
|
||||
|
||||
events = (
|
||||
models.Event.objects.filter(approved=True).annotate(rank=SearchRank(conference_vector, query))
|
||||
models.Event.objects.filter(approved=True)
|
||||
.annotate(rank=SearchRank(conference_vector, query))
|
||||
.filter(rank__gte=0.1)
|
||||
.order_by("-rank")
|
||||
)
|
||||
|
@ -318,7 +332,8 @@ class Search(View):
|
|||
)
|
||||
|
||||
cfps = (
|
||||
models.CallForPapers.objects.filter(approved=True).annotate(rank=SearchRank(cfp_vector, query))
|
||||
models.CallForPapers.objects.filter(approved=True)
|
||||
.annotate(rank=SearchRank(cfp_vector, query))
|
||||
.filter(rank__gte=0.1)
|
||||
.order_by("-rank")
|
||||
)
|
||||
|
@ -328,7 +343,8 @@ class Search(View):
|
|||
)
|
||||
|
||||
newsletters = (
|
||||
models.Newsletter.objects.filter(approved=True).annotate(rank=SearchRank(news_vector, query))
|
||||
models.Newsletter.objects.filter(approved=True)
|
||||
.annotate(rank=SearchRank(news_vector, query))
|
||||
.filter(rank__gte=0.1)
|
||||
.order_by("-rank")
|
||||
)
|
||||
|
@ -338,7 +354,8 @@ class Search(View):
|
|||
)
|
||||
|
||||
groups = (
|
||||
models.Event.objects.filter(approved=True).annotate(rank=SearchRank(group_vector, query))
|
||||
models.Group.objects.filter(approved=True)
|
||||
.annotate(rank=SearchRank(group_vector, query))
|
||||
.filter(rank__gte=0.1)
|
||||
.order_by("-rank")
|
||||
)
|
||||
|
|
|
@ -11,8 +11,8 @@ services:
|
|||
web:
|
||||
build: .
|
||||
env_file: .env
|
||||
# command: python manage.py runserver 0.0.0.0:8000
|
||||
command: gunicorn --env DJANGO_SETTINGS_MODULE=ausglamr.settings ausglamr.wsgi --workers=10 --threads=4 -b 0.0.0.0:8000
|
||||
command: python manage.py runserver 0.0.0.0:8000
|
||||
# command: gunicorn --env DJANGO_SETTINGS_MODULE=ausglamr.settings ausglamr.wsgi --workers=10 --threads=4 -b 0.0.0.0:8000
|
||||
volumes:
|
||||
- .:/app
|
||||
depends_on:
|
||||
|
|
|
@ -30,6 +30,11 @@ case "$CMD" in
|
|||
announce)
|
||||
runweb python manage.py announce
|
||||
;;
|
||||
backup)
|
||||
/snap/bin/docker exec -u root ausglamr_db_1 pg_dump -v -Fc -U ausglamr -d "ausglamr" -f /tmp/ausglamr_backup.dump
|
||||
/snap/bin/docker cp ausglamr_db_1:/tmp/ausglamr_backup.dump /home/hugh/backups/
|
||||
mv /home/hugh/backups/ausglamr_backup.dump /home/hugh/backups/ausglamr_backup_$(date +'%a').dump
|
||||
;;
|
||||
black)
|
||||
docker compose run --rm web black ausglamr blogs
|
||||
;;
|
||||
|
|
Loading…
Reference in a new issue