Browse Source

Add admin tool for removing topics

merge-requests/34/head
Deimos 6 years ago
parent
commit
e87ba0d2a9
  1. 36
      tildes/alembic/versions/bcf1406bb6c5_add_admin_tool_for_removing_topics.py
  2. 2
      tildes/tildes/enums.py
  3. 5
      tildes/tildes/models/log/log.py
  4. 2
      tildes/tildes/models/topic/topic.py
  5. 1
      tildes/tildes/routes.py
  6. 26
      tildes/tildes/templates/topic.jinja2
  7. 22
      tildes/tildes/views/api/web/topic.py
  8. 2
      tildes/tildes/views/topic.py

36
tildes/alembic/versions/bcf1406bb6c5_add_admin_tool_for_removing_topics.py

@ -0,0 +1,36 @@
"""Add admin tool for removing topics
Revision ID: bcf1406bb6c5
Revises: 50c251c4a19c
Create Date: 2018-08-22 23:56:41.733065
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "bcf1406bb6c5"
down_revision = "50c251c4a19c"
branch_labels = None
depends_on = None
def upgrade():
# ALTER TYPE doesn't work from inside a transaction, disable it
connection = None
if not op.get_context().as_sql:
connection = op.get_bind()
connection.execution_options(isolation_level="AUTOCOMMIT")
op.execute("ALTER TYPE logeventtype ADD VALUE IF NOT EXISTS 'TOPIC_REMOVE'")
op.execute("ALTER TYPE logeventtype ADD VALUE IF NOT EXISTS 'TOPIC_UNREMOVE'")
# re-activate the transaction for any future migrations
if connection is not None:
connection.execution_options(isolation_level="READ_COMMITTED")
def downgrade():
# no way to remove enum values, just do nothing
pass

2
tildes/tildes/enums.py

@ -51,9 +51,11 @@ class LogEventType(enum.Enum):
TOPIC_LOCK = enum.auto()
TOPIC_MOVE = enum.auto()
TOPIC_POST = enum.auto()
TOPIC_REMOVE = enum.auto()
TOPIC_TAG = enum.auto()
TOPIC_TITLE_EDIT = enum.auto()
TOPIC_UNLOCK = enum.auto()
TOPIC_UNREMOVE = enum.auto()
class TopicSortOption(enum.Enum):

5
tildes/tildes/models/log/log.py

@ -112,6 +112,7 @@ class LogTopic(DatabaseModel, BaseLog):
def __str__(self) -> str:
"""Return a string representation of the log event."""
# pylint: disable=too-many-return-statements
if self.event_type == LogEventType.TOPIC_TAG:
return self._tag_event_description()
elif self.event_type == LogEventType.TOPIC_MOVE:
@ -120,8 +121,12 @@ class LogTopic(DatabaseModel, BaseLog):
return f"moved from ~{old_group} to ~{new_group}"
elif self.event_type == LogEventType.TOPIC_LOCK:
return "locked comments"
elif self.event_type == LogEventType.TOPIC_REMOVE:
return "removed"
elif self.event_type == LogEventType.TOPIC_UNLOCK:
return "unlocked comments"
elif self.event_type == LogEventType.TOPIC_UNREMOVE:
return "un-removed"
elif self.event_type == LogEventType.TOPIC_TITLE_EDIT:
old_title = self.info["old"] # noqa
new_title = self.info["new"] # noqa

2
tildes/tildes/models/topic/topic.py

@ -282,6 +282,8 @@ class Topic(DatabaseModel):
# tools that require specifically granted permissions
acl.append((Allow, "admin", "lock"))
acl.append((Allow, "admin", "remove"))
acl.append((Allow, "admin", "move"))
acl.append((Allow, "topic.move", "move"))

1
tildes/tildes/routes.py

@ -115,6 +115,7 @@ def add_intercooler_routes(config: Configurator) -> None:
)
add_ic_route("topic_group", "/topics/{topic_id36}/group", factory=topic_by_id36)
add_ic_route("topic_lock", "/topics/{topic_id36}/lock", factory=topic_by_id36)
add_ic_route("topic_remove", "/topics/{topic_id36}/remove", factory=topic_by_id36)
add_ic_route("topic_title", "/topics/{topic_id36}/title", factory=topic_by_id36)
add_ic_route("topic_vote", "/topics/{topic_id36}/vote", factory=topic_by_id36)
add_ic_route("topic_tags", "/topics/{topic_id36}/tags", factory=topic_by_id36)

26
tildes/tildes/templates/topic.jinja2

@ -56,7 +56,7 @@
{% endif %}
{% endif %}
{% if request.has_any_permission(('edit', 'delete', 'tag', 'lock', 'move', 'edit_title'), topic) %}
{% if request.has_any_permission(('edit', 'delete', 'tag', 'lock', 'move', 'edit_title', 'remove'), topic) %}
<menu class="post-buttons">
{% if request.has_permission('edit', topic) %}
<li><a class="post-button" name="edit"
@ -135,6 +135,30 @@
{% endif %}
</li>
{% endif %}
{% if request.has_permission("remove", topic) %}
<li>
{% if not topic.is_removed %}
<a class="post-button"
data-ic-put-to="{{ request.route_url(
'ic_topic_remove',
topic_id36=topic.topic_id36,
) }}"
data-ic-replace-target="true"
data-ic-confirm="Remove this topic?"
>Remove</a>
{% else %}
<a class="post-button"
data-ic-delete-from="{{ request.route_url(
'ic_topic_remove',
topic_id36=topic.topic_id36,
) }}"
data-ic-replace-target="true"
data-ic-confirm="Un-remove this topic?"
>Un-remove</a>
{% endif %}
</li>
{% endif %}
</menu>
{% endif %}

22
tildes/tildes/views/api/web/topic.py

@ -230,6 +230,28 @@ def patch_move_topic(request: Request, path: str) -> dict:
return Response("Moved")
@ic_view_config(route_name="topic_remove", request_method="PUT", permission="remove")
def put_topic_remove(request: Request) -> Response:
"""Remove a topic with Intercooler."""
topic = request.context
topic.is_removed = True
request.db_session.add(LogTopic(LogEventType.TOPIC_REMOVE, request, topic))
return Response("Removed")
@ic_view_config(route_name="topic_remove", request_method="DELETE", permission="remove")
def delete_topic_remove(request: Request) -> Response:
"""Un-remove a topic with Intercooler."""
topic = request.context
topic.is_removed = False
request.db_session.add(LogTopic(LogEventType.TOPIC_UNREMOVE, request, topic))
return Response("Un-removed")
@ic_view_config(route_name="topic_lock", request_method="PUT", permission="lock")
def put_topic_lock(request: Request) -> Response:
"""Lock a topic with Intercooler."""

2
tildes/tildes/views/topic.py

@ -253,9 +253,11 @@ def get_topic(request: Request, comment_order: CommentSortOption) -> dict:
visible_events = (
LogEventType.TOPIC_LOCK,
LogEventType.TOPIC_MOVE,
LogEventType.TOPIC_REMOVE,
LogEventType.TOPIC_TAG,
LogEventType.TOPIC_TITLE_EDIT,
LogEventType.TOPIC_UNLOCK,
LogEventType.TOPIC_UNREMOVE,
)
log = (
request.query(LogTopic)

Loading…
Cancel
Save