forked from newthuhole/hole_thu_backend
实现删除与封禁
This commit is contained in:
67
hole.py
67
hole.py
@@ -6,8 +6,8 @@ from flask_limiter.util import get_remote_address
|
||||
from mastodon import Mastodon
|
||||
import time, re, random, string, datetime, hashlib
|
||||
|
||||
from models import db, User, Post, Comment, Attention
|
||||
from utils import require_token, map_post, map_comment, check_attention
|
||||
from models import db, User, Post, Comment, Attention, Syslog
|
||||
from utils import require_token, map_post, map_comment, check_attention, hash_name
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///hole.db'
|
||||
@@ -26,10 +26,7 @@ CS_LOGIN_URL = Mastodon(api_base_url=app.config['MASTODON_URL']) \
|
||||
redirect_uris = app.config['REDIRECT_URI'],
|
||||
scopes = ['read:accounts']
|
||||
)
|
||||
PER_PAGE = 25
|
||||
|
||||
def hash_name(name):
|
||||
return hashlib.sha256((app.config['SALT'] + name).encode('utf-8')).hexdigest()
|
||||
PER_PAGE = 50
|
||||
|
||||
@app.route('/_login')
|
||||
def login():
|
||||
@@ -76,10 +73,10 @@ def get_list():
|
||||
p = request.args.get('p')
|
||||
p = int(p) if p and p.isdigit() else -1
|
||||
|
||||
posts = Post.query.filter_by(deleted=False).order_by(db.desc('timestamp')).paginate(page=p, per_page=PER_PAGE)
|
||||
posts = Post.query.filter_by(deleted=False).order_by(db.desc('timestamp')).paginate(p, PER_PAGE)
|
||||
|
||||
|
||||
data =list(map(map_post, posts.items, [hash_name(u.name)] * len(posts.items)))
|
||||
data =list(map(map_post, posts.items, [u.name] * len(posts.items)))
|
||||
|
||||
return {
|
||||
'code': 0,
|
||||
@@ -97,7 +94,7 @@ def get_one():
|
||||
if not post: abort(404)
|
||||
if post.deleted: abort(451)
|
||||
|
||||
data = map_post(post, name_hash=hash_name(u.name))
|
||||
data = map_post(post, u.name)
|
||||
|
||||
return {
|
||||
'code': 0,
|
||||
@@ -161,8 +158,9 @@ def get_comment():
|
||||
|
||||
post = Post.query.get(pid)
|
||||
if not post: abort(404)
|
||||
|
||||
data = map_comment(post)
|
||||
if post.deleted: abort(451)
|
||||
|
||||
data = map_comment(post, u.name)
|
||||
|
||||
return {
|
||||
'code': 0,
|
||||
@@ -182,6 +180,7 @@ def do_comment():
|
||||
|
||||
post = Post.query.get(pid)
|
||||
if not post: abort(404)
|
||||
if post.deleted: abort(451)
|
||||
|
||||
content = request.form.get('text')
|
||||
content = content.strip() if content else None
|
||||
@@ -237,7 +236,7 @@ def get_attention():
|
||||
|
||||
posts = [Post.query.get(at.pid) for at in ats.all()]
|
||||
print(posts)
|
||||
data = [ map_post(post, hash_name(u.name), 10)
|
||||
data = [ map_post(post, u.name, 10)
|
||||
for post in posts[::-1]
|
||||
if post and not post.deleted
|
||||
]
|
||||
@@ -248,6 +247,50 @@ def get_attention():
|
||||
'data': data
|
||||
}
|
||||
|
||||
@app.route('/_api/v1/delete', methods=['POST'])
|
||||
def delete():
|
||||
u = require_token()
|
||||
|
||||
obj_type = request.form.get('type')
|
||||
obj_id = request.form.get('id')
|
||||
note = request.form.get('note')
|
||||
|
||||
if obj_id and obj_id.isdigit():
|
||||
obj_id = int(obj_id)
|
||||
else:
|
||||
abort(422)
|
||||
|
||||
if note and len(note)>100: abort(422)
|
||||
|
||||
obj = None
|
||||
if obj_type == 'pid':
|
||||
obj = Post.query.get(obj_id)
|
||||
if len(obj.comments): abort(403)
|
||||
elif obj_type == 'cid':
|
||||
obj = Comment.query.get(obj_id)
|
||||
if not obj: abort(404)
|
||||
|
||||
if obj.name_hash == hash_name(u.name):
|
||||
db.session.delete(obj)
|
||||
elif u.name in app.config.get('ADMINS'):
|
||||
obj.deleted = True
|
||||
db.session.add(Syslog(
|
||||
log_type='ADMIN DELETE',
|
||||
log_detail=f"{type}={obj_id}\nnote",
|
||||
name_hash=hash_name(u.name)
|
||||
))
|
||||
if note.startswith('!ban'):
|
||||
db.session.add(Syslog(
|
||||
log_type='BANNED',
|
||||
log_detail=f"{type}={obj_id}\nnote",
|
||||
name_hash=obj.name_hash
|
||||
))
|
||||
|
||||
else:
|
||||
abort(403)
|
||||
|
||||
db.session.commit()
|
||||
return {'code': 0}
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
|
||||
@@ -44,4 +44,10 @@ class Attention(db.Model):
|
||||
name_hash = db.Column(db.String(64))
|
||||
pid = db.Column(db.Integer)
|
||||
disabled = db.Column(db.Boolean, default=False)
|
||||
|
||||
class Syslog(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
log_type = db.Column(db.String(16))
|
||||
log_detail = db.Column(db.String(128))
|
||||
name_hash = db.Column(db.String(64))
|
||||
|
||||
|
||||
31
utils.py
31
utils.py
@@ -1,13 +1,20 @@
|
||||
import hashlib
|
||||
from flask import request, abort
|
||||
from models import User, Attention
|
||||
from flask import request, abort, current_app
|
||||
from models import User, Attention, Syslog
|
||||
|
||||
def get_config(key):
|
||||
return current_app.config.get(key)
|
||||
|
||||
def require_token():
|
||||
token = request.args.get('user_token')
|
||||
u = User.query.filter_by(token=token).first() if token else None
|
||||
if Syslog.query.filter_by(log_type='BANNED', name_hash=hash_name(u.name)).first(): abort(403)
|
||||
return u if u else abort(401)
|
||||
|
||||
def map_post(p, name_hash, mc=50):
|
||||
def hash_name(name):
|
||||
return hashlib.sha256((get_config('SALT') + name).encode('utf-8')).hexdigest()
|
||||
|
||||
def map_post(p, name, mc=50):
|
||||
return {
|
||||
'pid': p.id,
|
||||
'likenum': p.likenum,
|
||||
@@ -17,11 +24,12 @@ def map_post(p, name_hash, mc=50):
|
||||
'type' : p.post_type,
|
||||
'url' : p.file_url,
|
||||
'reply': len(p.comments),
|
||||
'comments': map_comment(p) if len(p.comments) < mc else None,
|
||||
'attention': check_attention(name_hash, p.id)
|
||||
'comments': map_comment(p, name) if len(p.comments) < mc else None,
|
||||
'attention': check_attention(name, p.id),
|
||||
'can_del': check_can_del(name, p.name_hash)
|
||||
}
|
||||
|
||||
def map_comment(p):
|
||||
def map_comment(p, name):
|
||||
|
||||
names = {p.name_hash: 0}
|
||||
|
||||
@@ -36,10 +44,13 @@ def map_comment(p):
|
||||
'pid': p.id,
|
||||
'text': c.content,
|
||||
'timestamp': c.timestamp,
|
||||
#'cw': None # comments may have cw in future
|
||||
} for c in p.comments
|
||||
'can_del': check_can_del(name, c.name_hash)
|
||||
} for c in p.comments if not c.deleted
|
||||
]
|
||||
|
||||
def check_attention(name_hash, pid):
|
||||
at = Attention.query.filter_by(name_hash=name_hash, pid=pid, disabled=False).first()
|
||||
def check_attention(name, pid):
|
||||
at = Attention.query.filter_by(name_hash=hash_name(name), pid=pid, disabled=False).first()
|
||||
return 1 if at else 0
|
||||
|
||||
def check_can_del(name, author_hash):
|
||||
return 1 if hash_name(name) == author_hash or name in get_config('ADMINS') else 0
|
||||
|
||||
Reference in New Issue
Block a user