Add post modify view
This allows moderators to modify posts (add sticky, etc). Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -115,3 +115,17 @@ class BanForm(ModelForm):
|
||||
else:
|
||||
expires = None
|
||||
self.instance.expires = expires
|
||||
|
||||
|
||||
class PostModifyForm(ModelForm):
|
||||
"""
|
||||
A form used to modify the attributes of a post (sticky, locked, sink, etc)
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Post
|
||||
fields = ["bump", "sticky"]
|
||||
|
||||
def clean(self):
|
||||
super(PostModifyForm, self).clean()
|
||||
print(self.fields["sticky"])
|
||||
|
||||
@@ -68,7 +68,7 @@ class Board(models.Model):
|
||||
return self.max_pages * self.threads_per_page
|
||||
|
||||
def prune_threads(self):
|
||||
to_remove = self.threads.order_by("-last_bump")[self.max_threads :]
|
||||
to_remove = self.threads.order_by("-sticky", "-last_bump")[self.max_threads :]
|
||||
for thread in to_remove:
|
||||
thread.delete()
|
||||
|
||||
@@ -93,6 +93,8 @@ class Post(models.Model):
|
||||
ip = models.GenericIPAddressField()
|
||||
# Capcode
|
||||
capcode = models.ForeignKey("Capcode", null=True, blank=True, on_delete=SET_NULL)
|
||||
# Post is stickied
|
||||
sticky = models.BooleanField(default=False, blank=True)
|
||||
# Creation time
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
# Last bump time
|
||||
@@ -116,6 +118,9 @@ class Post(models.Model):
|
||||
image_width = models.IntegerField(null=True)
|
||||
image_height = models.IntegerField(null=True)
|
||||
|
||||
class Meta:
|
||||
permissions = [("set_sticky", "Can sticky post")]
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.image:
|
||||
self.original_image_name = Path(self.image.name).parts[-1]
|
||||
|
||||
@@ -4,6 +4,18 @@ if (typeof window.banWindowName === "undefined") {
|
||||
window.banWindowName = "ban-window";
|
||||
}
|
||||
|
||||
if (typeof window.menuItemFactories !== "undefined") {
|
||||
window.menuItemFactories.push(
|
||||
(postElement) => $("<a>")
|
||||
.text("Ban")
|
||||
.attr("href", "#")
|
||||
.on("click", (e) => {
|
||||
e.preventDefault();
|
||||
openBanWindow($(postElement).attr("data-ban-url"));
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function getBanWindow() {
|
||||
return window.top.jsFrame.getWindowByName(banWindowName);
|
||||
}
|
||||
@@ -20,4 +32,4 @@ function openBanWindow(banUrl) {
|
||||
url: banUrl,
|
||||
});
|
||||
banWindow.show();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
if (typeof window.menuItemFactories !== "undefined") {
|
||||
window.menuItemFactories.push(
|
||||
(postElement) => $("<a>")
|
||||
.text("Ban")
|
||||
.attr("href", "#")
|
||||
.on("click", (e) => {
|
||||
e.preventDefault();
|
||||
openBanWindow($(postElement).attr("data-ban-url"));
|
||||
})
|
||||
)
|
||||
}
|
||||
36
board/static/board/modify.js
Normal file
36
board/static/board/modify.js
Normal file
@@ -0,0 +1,36 @@
|
||||
if (typeof window.menuItemFactories !== "undefined") {
|
||||
window.menuItemFactories.push(
|
||||
(postElement) => $("<a>")
|
||||
.text("Modify post")
|
||||
.attr("href", "#")
|
||||
.on("click", (e) => {
|
||||
e.preventDefault();
|
||||
openModifyWindow($(postElement).attr("data-modify-url"));
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// HACK: this should be a const, but it will cause an error if included twice in
|
||||
// the same page (like an iframe).
|
||||
if (typeof window.modifyWindowName === "undefined") {
|
||||
window.modifyWindowName = "modify-window";
|
||||
}
|
||||
|
||||
function getModifyWindow() {
|
||||
return window.top.jsFrame.getWindowByName(modifyWindowName);
|
||||
}
|
||||
|
||||
function openModifyWindow(modifyUrl) {
|
||||
if (window.top.jsFrame.containsWindowName(modifyWindowName)) {
|
||||
getModifyWindow().closeFrame();
|
||||
}
|
||||
|
||||
let modifyWindow = window.top.jsFrame.create({
|
||||
title: "Modifying post",
|
||||
name: modifyWindowName,
|
||||
width: 475,
|
||||
height: 475,
|
||||
url: modifyUrl,
|
||||
});
|
||||
modifyWindow.show();
|
||||
}
|
||||
@@ -85,6 +85,10 @@ th {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.post_sticky {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.post_id {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
{{block.super}}
|
||||
<script src="{% static 'board/jquery.js' %}"></script>
|
||||
<script src="{% static 'board/jsframe.min.js' %}"></script>
|
||||
<script src="{% static 'board/ban_window.js' %}"></script>
|
||||
<script src="{% static 'board/ban.js' %}"></script>
|
||||
{% endblock extrahead %}
|
||||
|
||||
{% block footer %}
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
{% load i18n static %}
|
||||
{# Title #}
|
||||
{% block title %}{% translate "Ban success" %}{% endblock %}
|
||||
{# Extra JS #}
|
||||
{% block extrajs %}
|
||||
<script src="{% static 'board/ban_window.js' %}"></script>
|
||||
{% endblock extrajs %}
|
||||
{# Body #}
|
||||
{% block content %}
|
||||
<div class="row" id="message">
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>{% block title %}{% if title %}{{title}}{% else %}Index{% endif %}{% endblock %}</title>
|
||||
<link rel="stylesheet" href="{% static 'board/style.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'board/font-awesome/css/font-awesome.min.css' %}">
|
||||
{% block extrastyle %}{% endblock %}
|
||||
<script src="{% static 'board/jquery.js' %}"></script>
|
||||
<script src="{% static 'board/jsframe.min.js' %}"></script>
|
||||
<script src="{% static 'board/post.js' %}"></script>
|
||||
{% if perms.board.create_ban %}
|
||||
<script src="{% static 'board/ban_window.js' %}"></script>
|
||||
<script src="{% static 'board/ban_menu.js' %}"></script>
|
||||
{% endif %}
|
||||
{% block extrajs %}{% endblock %}
|
||||
</head>
|
||||
|
||||
17
board/templates/board/post_modify_view.html
Normal file
17
board/templates/board/post_modify_view.html
Normal file
@@ -0,0 +1,17 @@
|
||||
{% extends "board/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post" action="{% url 'board:post_modify' post.id %}">
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
{% if perms.board.can_sticky %}
|
||||
<tr>
|
||||
<th>{{form.sticky.label_tag}}</th>
|
||||
<td>{{form.sticky}}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr><td> </td><td><input type="submit" value="Modify post" /></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
{% endblock content %}
|
||||
@@ -6,6 +6,9 @@
|
||||
{% if perms.board.create_ban %}
|
||||
data-ban-url="{% url 'board:ban_create' board.url post.id %}"
|
||||
{% endif %}
|
||||
{% if perms.board.can_sticky %}
|
||||
data-modify-url="{% url 'board:post_modify' post.id %}"
|
||||
{% endif %}
|
||||
>
|
||||
{# Image #}
|
||||
{% if post.thumbnail %}
|
||||
@@ -24,7 +27,10 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Post ID, username, time #}
|
||||
{# Post ID, sticky, username, time #}
|
||||
{% if post.sticky and not post.op %}
|
||||
<span title="Stickied" class="fa fa-sticky-note"></span>
|
||||
{% endif %}
|
||||
<a href="#p{{post.id}}">#.</a>
|
||||
<span class="post_id">{{post.id}}</span>
|
||||
{% if post.subject %}
|
||||
|
||||
@@ -20,6 +20,8 @@ urlpatterns = [
|
||||
path("ban/<slug:url>/<int:id>/", BanCreateView.as_view(), name="ban_create"),
|
||||
path("ban/success/", BanSuccessView.as_view(), name="ban_success"),
|
||||
path("banned", BannedView.as_view(), name="banned"),
|
||||
# Other moderation pages
|
||||
path("modify/<int:pk>/", PostModifyView.as_view(), name="post_modify"),
|
||||
]
|
||||
# TODO - make this conditional so we can serve images up with whatever server we want
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
@@ -13,7 +13,7 @@ from django.utils import timezone
|
||||
|
||||
from guardian.shortcuts import get_objects_for_user
|
||||
|
||||
from board.forms import BanForm, PostForm, ReplyForm, ReportForm
|
||||
from board.forms import *
|
||||
from board.models import Ban, BanTemplate, Board, Post, Report
|
||||
from board.utils import *
|
||||
|
||||
@@ -23,6 +23,7 @@ __all__ = (
|
||||
"BannedView",
|
||||
"BoardView",
|
||||
"PostCreateView",
|
||||
"PostModifyView",
|
||||
"PostView",
|
||||
"PostSuccessView",
|
||||
"ReplyCreateView",
|
||||
@@ -109,7 +110,9 @@ class BoardView(TemplateView):
|
||||
last_page = (thread_count // threads_per_page) + 1
|
||||
|
||||
kwargs["board"] = self.board
|
||||
kwargs["threads"] = self.board.threads.order_by("-last_bump")[start:end]
|
||||
kwargs["threads"] = self.board.threads.order_by("-sticky", "-last_bump")[
|
||||
start:end
|
||||
]
|
||||
kwargs["current_page"] = page
|
||||
kwargs["pages"] = range(1, last_page + 1)
|
||||
kwargs["last_page"] = last_page
|
||||
@@ -145,6 +148,24 @@ class PostCreateView(CreateView):
|
||||
return reverse("board:post_success") + "?" + query.urlencode()
|
||||
|
||||
|
||||
class PostModifyView(PermissionRequiredMixin, edit.UpdateView):
|
||||
model = Post
|
||||
form_class = PostModifyForm
|
||||
template_name = "board/post_modify_view.html"
|
||||
|
||||
def has_permission(self) -> bool:
|
||||
user = self.request.user
|
||||
if not user:
|
||||
return False
|
||||
# TODO add more permissions as required
|
||||
return user.has_perm("board.can_sticky")
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.post_obj = get_object_or_404(Post, id=kwargs["pk"])
|
||||
self.board = self.post_obj.board
|
||||
return super(PostModifyView, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
|
||||
class ReplyCreateView(CreateView):
|
||||
model = Post
|
||||
form_class = ReplyForm
|
||||
|
||||
Reference in New Issue
Block a user