forked from MarseyWorld/MarseyWorld
add edit logs
parent
fa80540fc6
commit
18ba6becd3
|
@ -38,3 +38,5 @@ from .currency_logs import *
|
||||||
|
|
||||||
if FEATURES['IP_LOGGING']:
|
if FEATURES['IP_LOGGING']:
|
||||||
from .ip_logs import *
|
from .ip_logs import *
|
||||||
|
|
||||||
|
from .edit_logs import *
|
||||||
|
|
|
@ -232,6 +232,7 @@ class Comment(Base):
|
||||||
options = relationship("CommentOption", order_by="CommentOption.id")
|
options = relationship("CommentOption", order_by="CommentOption.id")
|
||||||
casino_game = relationship("CasinoGame")
|
casino_game = relationship("CasinoGame")
|
||||||
wall_user = relationship("User", primaryjoin="User.id==Comment.wall_user_id")
|
wall_user = relationship("User", primaryjoin="User.id==Comment.wall_user_id")
|
||||||
|
edits = relationship("CommentEdit", order_by="CommentEdit.id.desc()")
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
if "created_utc" not in kwargs:
|
if "created_utc" not in kwargs:
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
import time
|
||||||
|
|
||||||
|
from sqlalchemy import Column, ForeignKey
|
||||||
|
from sqlalchemy.sql.sqltypes import *
|
||||||
|
|
||||||
|
from files.classes import Base
|
||||||
|
|
||||||
|
class PostEdit(Base):
|
||||||
|
__tablename__ = "post_edits"
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
post_id = Column(Integer, ForeignKey("posts.id"))
|
||||||
|
old_body = Column(String)
|
||||||
|
old_body_html = Column(String)
|
||||||
|
old_title = Column(String)
|
||||||
|
old_title_html = Column(String)
|
||||||
|
created_utc = Column(Integer)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time())
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<{self.__class__.__name__}(id={self.id})>"
|
||||||
|
|
||||||
|
class CommentEdit(Base):
|
||||||
|
__tablename__ = "comment_edits"
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
comment_id = Column(Integer, ForeignKey("comments.id"))
|
||||||
|
old_body = Column(String)
|
||||||
|
old_body_html = Column(String)
|
||||||
|
created_utc = Column(Integer)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time())
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<{self.__class__.__name__}(id={self.id})>"
|
|
@ -85,6 +85,7 @@ class Post(Base):
|
||||||
comments = relationship("Comment", primaryjoin="Comment.parent_post==Post.id", back_populates="post")
|
comments = relationship("Comment", primaryjoin="Comment.parent_post==Post.id", back_populates="post")
|
||||||
hole_obj = relationship("Hole", primaryjoin="foreign(Post.hole)==remote(Hole.name)")
|
hole_obj = relationship("Hole", primaryjoin="foreign(Post.hole)==remote(Hole.name)")
|
||||||
options = relationship("PostOption", order_by="PostOption.id")
|
options = relationship("PostOption", order_by="PostOption.id")
|
||||||
|
edits = relationship("PostEdit", order_by="PostEdit.id.desc()")
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
if "created_utc" not in kwargs:
|
if "created_utc" not in kwargs:
|
||||||
|
|
|
@ -171,6 +171,7 @@ PERMS = { # Minimum admin_level to perform action.
|
||||||
'VIEW_ACTIVE_USERS': 1,
|
'VIEW_ACTIVE_USERS': 1,
|
||||||
'VIEW_ALT_VOTES': 1,
|
'VIEW_ALT_VOTES': 1,
|
||||||
'VIEW_LAST_ACTIVE': 1,
|
'VIEW_LAST_ACTIVE': 1,
|
||||||
|
'VIEW_EDITS': 1,
|
||||||
'ENABLE_VOTE_BUTTONS_ON_USER_PAGE': 1,
|
'ENABLE_VOTE_BUTTONS_ON_USER_PAGE': 1,
|
||||||
'NOTIFICATIONS_MODERATOR_ACTIONS': 1,
|
'NOTIFICATIONS_MODERATOR_ACTIONS': 1,
|
||||||
'EXEMPT_FROM_IP_LOGGING': 1,
|
'EXEMPT_FROM_IP_LOGGING': 1,
|
||||||
|
|
|
@ -2231,3 +2231,16 @@ def unmark_effortpost(pid, v):
|
||||||
send_repeatable_notification(p.author_id, f":marseyitsover: @{v.username} (a site admin) has unmarked {p.textlink} as an effortpost. {coins} coins have been deducted from you. :!marseyitsover:")
|
send_repeatable_notification(p.author_id, f":marseyitsover: @{v.username} (a site admin) has unmarked {p.textlink} as an effortpost. {coins} coins have been deducted from you. :!marseyitsover:")
|
||||||
|
|
||||||
return {"message": "Post has been unmarked as an effortpost!"}
|
return {"message": "Post has been unmarked as an effortpost!"}
|
||||||
|
|
||||||
|
@app.get("/edits/<link>")
|
||||||
|
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
|
||||||
|
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
|
||||||
|
@admin_level_required(PERMS['VIEW_EDITS'])
|
||||||
|
def view_edits(v, link):
|
||||||
|
try:
|
||||||
|
if "p_" in link: obj = get_post(int(link.split("p_")[1]), v=v)
|
||||||
|
elif "c_" in link: obj = get_comment(int(link.split("c_")[1]), v=v)
|
||||||
|
else: abort(400)
|
||||||
|
except: abort(400)
|
||||||
|
|
||||||
|
return render_template("edits.html", v=v, obj=obj)
|
||||||
|
|
|
@ -637,6 +637,13 @@ def edit_comment(cid, v):
|
||||||
if c.author.hieroglyphs and marseyaward_body_regex.search(body_html):
|
if c.author.hieroglyphs and marseyaward_body_regex.search(body_html):
|
||||||
abort(403, "You can only type marseys!")
|
abort(403, "You can only type marseys!")
|
||||||
|
|
||||||
|
edit_log = CommentEdit(
|
||||||
|
comment_id=c.id,
|
||||||
|
old_body=c.body,
|
||||||
|
old_body_html=c.body_html,
|
||||||
|
)
|
||||||
|
g.db.add(edit_log)
|
||||||
|
|
||||||
oldtext = c.body
|
oldtext = c.body
|
||||||
|
|
||||||
c.body = body
|
c.body = body
|
||||||
|
|
|
@ -1057,6 +1057,14 @@ def edit_post(pid, v):
|
||||||
|
|
||||||
changed = False
|
changed = False
|
||||||
|
|
||||||
|
edit_log = PostEdit(
|
||||||
|
post_id=p.id,
|
||||||
|
old_title=p.title,
|
||||||
|
old_title_html=p.title_html,
|
||||||
|
old_body=p.body,
|
||||||
|
old_body_html=p.body_html,
|
||||||
|
)
|
||||||
|
g.db.add(edit_log)
|
||||||
|
|
||||||
if title != p.title:
|
if title != p.title:
|
||||||
title_html = filter_emojis_only(title, golden=False, obj=p, author=p.author)
|
title_html = filter_emojis_only(title, golden=False, obj=p, author=p.author)
|
||||||
|
|
|
@ -233,9 +233,15 @@
|
||||||
|
|
||||||
<a class="vertical-align ml-1" href="{{c.permalink}}">#{{c.id}}</a>
|
<a class="vertical-align ml-1" href="{{c.permalink}}">#{{c.id}}</a>
|
||||||
|
|
||||||
<span class="{% if not c.edited_utc %}d-none{% endif %} font-italic" data-nonce="{{g.nonce}}" data-bs-toggle="tooltip" data-bs-placement="bottom" data-onmouseover="timestamp(this, '{{c.edited_utc}}')">
|
{% if c.edited_utc and v and v.admin_level >= PERMS['VIEW_EDITS'] %}
|
||||||
Edited <span id="comment-edited_string-{{c.id}}">{{c.edited_string}}</span>
|
<a href="/edits/{{c.fullname}}" class="font-italic" data-nonce="{{g.nonce}}" data-bs-toggle="tooltip" data-bs-placement="bottom" data-onmouseover="timestamp(this, '{{c.edited_utc}}')">
|
||||||
</span>
|
Edited <span id="comment-edited_string-{{c.id}}">{{c.edited_string}}</span>
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
<span class="{% if not c.edited_utc %}d-none{% endif %} font-italic" data-nonce="{{g.nonce}}" data-bs-toggle="tooltip" data-bs-placement="bottom" data-onmouseover="timestamp(this, '{{c.edited_utc}}')">
|
||||||
|
Edited <span id="comment-edited_string-{{c.id}}">{{c.edited_string}}</span>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if c.treasure_amount and c.treasure_amount != '0' %}
|
{% if c.treasure_amount and c.treasure_amount != '0' %}
|
||||||
{% if c.treasure_amount.startswith('l') %}
|
{% if c.treasure_amount.startswith('l') %}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
{% extends "default.html" %}
|
||||||
|
{% block pagetitle %}Edits on {{obj.shortlink}}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<h2>Edits on {{obj.textlink | safe}}</h2>
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{% if obj.fullname.startswith('p_') %}
|
||||||
|
<th>Title</th>
|
||||||
|
{% endif %}
|
||||||
|
<th>Body</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
{% for edit in obj.edits %}
|
||||||
|
<tr>
|
||||||
|
{% if obj.fullname.startswith('p_') %}
|
||||||
|
<td>{{edit.old_title_html | safe}}</td>
|
||||||
|
{% endif %}
|
||||||
|
<td>{{edit.old_body_html | safe}}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -125,7 +125,11 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if p.edited_utc %}
|
{% if p.edited_utc %}
|
||||||
<span class="ml-2 d-inline-block">Edited <span data-bs-toggle="tooltip" data-bs-placement="bottom" id="edited_timestamp-{{p.id}}" data-nonce="{{g.nonce}}" data-onmouseover="timestamp(this, '{{p.edited_utc}}')">{{p.edited_string}}</span></span>
|
{% if v and v.admin_level >= PERMS['VIEW_EDITS'] %}
|
||||||
|
<a href="/edits/{{p.fullname}}" class="ml-2 d-inline-block">Edited <span data-bs-toggle="tooltip" data-bs-placement="bottom" id="edited_timestamp-{{p.id}}" data-nonce="{{g.nonce}}" data-onmouseover="timestamp(this, '{{p.edited_utc}}')">{{p.edited_string}}</span></a>
|
||||||
|
{% else %}
|
||||||
|
<span class="ml-2 d-inline-block">Edited <span data-bs-toggle="tooltip" data-bs-placement="bottom" id="edited_timestamp-{{p.id}}" data-nonce="{{g.nonce}}" data-onmouseover="timestamp(this, '{{p.edited_utc}}')">{{p.edited_string}}</span></span>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span class="ml-2 d-inline-block">{{p.views}} thread views</span>
|
<span class="ml-2 d-inline-block">{{p.views}} thread views</span>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
create table post_edits (
|
||||||
|
id integer primary key,
|
||||||
|
post_id integer not null,
|
||||||
|
old_title character varying(500),
|
||||||
|
old_title_html character varying(1500),
|
||||||
|
old_body character varying(100000),
|
||||||
|
old_body_html character varying(200000),
|
||||||
|
created_utc integer NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.post_edits_id_seq
|
||||||
|
AS integer
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.post_edits_id_seq OWNED BY public.post_edits.id;
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.post_edits ALTER COLUMN id SET DEFAULT nextval('public.post_edits_id_seq'::regclass);
|
||||||
|
|
||||||
|
alter table only post_edits
|
||||||
|
add constraint post_edits_post_fkey foreign key (post_id) references public.posts(id);
|
||||||
|
|
||||||
|
|
||||||
|
create table comment_edits (
|
||||||
|
id integer primary key,
|
||||||
|
comment_id integer not null,
|
||||||
|
old_body character varying(100000),
|
||||||
|
old_body_html character varying(200000),
|
||||||
|
created_utc integer NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.comment_edits_id_seq
|
||||||
|
AS integer
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.comment_edits_id_seq OWNED BY public.comment_edits.id;
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.comment_edits ALTER COLUMN id SET DEFAULT nextval('public.comment_edits_id_seq'::regclass);
|
||||||
|
|
||||||
|
alter table only comment_edits
|
||||||
|
add constraint comment_edits_comment_fkey foreign key (comment_id) references public.comments(id);
|
Loading…
Reference in New Issue