Browse Source

实现删除与封禁

master
hole-thu 5 years ago
parent
commit
44d1b26079
  1. 65
      hole.py
  2. 6
      models.py
  3. 31
      utils.py

65
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)
if post.deleted: abort(451)
data = map_comment(post)
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)

6
models.py

@ -45,3 +45,9 @@ class Attention(db.Model):
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

@ -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

Loading…
Cancel
Save