|
|
|
@ -10,12 +10,15 @@ from sqlalchemy.sql.expression import func
|
|
|
|
|
|
|
|
|
|
from mastodon import Mastodon |
|
|
|
|
from models import db, User, Post, Comment, Attention, TagRecord, Syslog |
|
|
|
|
from utils import get_current_user, map_post, map_comment, map_syslog, check_attention, hash_name, look, get_num, tmp_token, is_admin |
|
|
|
|
from utils import get_current_username, map_post, map_comment, map_syslog, check_attention, hash_name, look, get_num, tmp_token, is_admin, check_can_del |
|
|
|
|
|
|
|
|
|
app = Flask(__name__) |
|
|
|
|
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///hole.db' |
|
|
|
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False |
|
|
|
|
app.config['JSON_AS_ASCII'] = False |
|
|
|
|
app.config['SALT'] = ''.join(random.choices( |
|
|
|
|
string.ascii_letters + string.digits, k=32 |
|
|
|
|
)) |
|
|
|
|
app.config.from_pyfile('config.py') |
|
|
|
|
|
|
|
|
|
db.init_app(app) |
|
|
|
@ -86,7 +89,7 @@ def auth():
|
|
|
|
|
|
|
|
|
|
@app.route('/_api/v1/getlist') |
|
|
|
|
def get_list(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
username = get_current_username() |
|
|
|
|
|
|
|
|
|
p = request.args.get('p', type=int, default=1) |
|
|
|
|
order_mode = request.args.get('order_mode', type=int, default=0) |
|
|
|
@ -111,7 +114,7 @@ def get_list():
|
|
|
|
|
|
|
|
|
|
posts = query.order_by(order).paginate(p, PER_PAGE) |
|
|
|
|
|
|
|
|
|
data = list(map(map_post, posts.items, [u.name] * len(posts.items))) |
|
|
|
|
data = list(map(map_post, posts.items, [username] * len(posts.items))) |
|
|
|
|
|
|
|
|
|
return { |
|
|
|
|
'code': 0, |
|
|
|
@ -123,15 +126,17 @@ def get_list():
|
|
|
|
|
|
|
|
|
|
@app.route('/_api/v1/getone') |
|
|
|
|
def get_one(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
username = get_current_username() |
|
|
|
|
|
|
|
|
|
pid = request.args.get('pid', type=int) |
|
|
|
|
|
|
|
|
|
post = Post.query.get_or_404(pid) |
|
|
|
|
if post.deleted or post.is_reported: |
|
|
|
|
if post.deleted or post.is_reported and not ( |
|
|
|
|
check_can_del(username, post.name_hash) |
|
|
|
|
): |
|
|
|
|
abort(451) |
|
|
|
|
|
|
|
|
|
data = map_post(post, u.name) |
|
|
|
|
data = map_post(post, username) |
|
|
|
|
|
|
|
|
|
return { |
|
|
|
|
'code': 0, |
|
|
|
@ -141,7 +146,7 @@ def get_one():
|
|
|
|
|
|
|
|
|
|
@app.route('/_api/v1/search') |
|
|
|
|
def search(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
username = get_current_username() |
|
|
|
|
|
|
|
|
|
page = request.args.get('page', type=int, default=1) |
|
|
|
|
pagesize = min(request.args.get('pagesize', type=int, default=200), 200) |
|
|
|
@ -155,7 +160,8 @@ def search():
|
|
|
|
|
tag=keywords |
|
|
|
|
).all() |
|
|
|
|
|
|
|
|
|
tag_pids = [tag_pid for tag_pid, in tag_pids] or [0] # sql not allowed empty in |
|
|
|
|
tag_pids = [ |
|
|
|
|
tag_pid for tag_pid, in tag_pids] or [0] # sql not allowed empty in |
|
|
|
|
|
|
|
|
|
posts = Post.query.filter( |
|
|
|
|
Post.search_text.like("%{}%".format(keywords)) |
|
|
|
@ -177,7 +183,7 @@ def search():
|
|
|
|
|
).all() + posts |
|
|
|
|
|
|
|
|
|
data = [ |
|
|
|
|
map_post(post, u.name) |
|
|
|
|
map_post(post, username) |
|
|
|
|
for post in posts |
|
|
|
|
] |
|
|
|
|
|
|
|
|
@ -191,27 +197,23 @@ def search():
|
|
|
|
|
@app.route('/_api/v1/dopost', methods=['POST']) |
|
|
|
|
@limiter.limit("50 / hour; 1 / 3 second") |
|
|
|
|
def do_post(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
username = get_current_username() |
|
|
|
|
|
|
|
|
|
allow_search = request.form.get('allow_search') |
|
|
|
|
print(allow_search) |
|
|
|
|
content = request.form.get('text') |
|
|
|
|
content = content.strip() if content else None |
|
|
|
|
content = '[tmp]\n' + content if u.name[:4] == 'tmp_' else content |
|
|
|
|
content = request.form.get('text', '').strip() |
|
|
|
|
content = ('[tmp]\n' if username[:4] == 'tmp_' else '') + content |
|
|
|
|
post_type = request.form.get('type') |
|
|
|
|
cw = request.form.get('cw') |
|
|
|
|
cw = cw.strip() if cw else None |
|
|
|
|
cw = request.form.get('cw', '').strip() |
|
|
|
|
|
|
|
|
|
if not content or len(content) > 4096: |
|
|
|
|
abort(422) |
|
|
|
|
if cw and len(cw) > 32: |
|
|
|
|
if not content or len(content) > 4096 or len(cw) > 32: |
|
|
|
|
abort(422) |
|
|
|
|
|
|
|
|
|
search_text = content.replace( |
|
|
|
|
'\n', '') if allow_search else '' |
|
|
|
|
|
|
|
|
|
p = Post( |
|
|
|
|
name_hash=hash_name(u.name), |
|
|
|
|
name_hash=hash_name(username), |
|
|
|
|
content=content, |
|
|
|
|
search_text=search_text, |
|
|
|
|
post_type=post_type, |
|
|
|
@ -238,7 +240,7 @@ def do_post():
|
|
|
|
|
if not re.match('\\d+', tag): |
|
|
|
|
db.session.add(TagRecord(tag=tag, pid=p.id)) |
|
|
|
|
|
|
|
|
|
db.session.add(Attention(name_hash=hash_name(u.name), pid=p.id)) |
|
|
|
|
db.session.add(Attention(name_hash=hash_name(username), pid=p.id)) |
|
|
|
|
db.session.commit() |
|
|
|
|
|
|
|
|
|
return { |
|
|
|
@ -250,7 +252,7 @@ def do_post():
|
|
|
|
|
@app.route('/_api/v1/editcw', methods=['POST']) |
|
|
|
|
@limiter.limit("50 / hour; 1 / 2 second") |
|
|
|
|
def edit_cw(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
username = get_current_username() |
|
|
|
|
|
|
|
|
|
cw = request.form.get('cw') |
|
|
|
|
pid = get_num(request.form.get('pid')) |
|
|
|
@ -260,11 +262,8 @@ def edit_cw():
|
|
|
|
|
abort(422) |
|
|
|
|
|
|
|
|
|
post = Post.query.get_or_404(pid) |
|
|
|
|
if post.deleted: |
|
|
|
|
abort(451) |
|
|
|
|
|
|
|
|
|
if not (u.name in app.config.get('ADMINS') |
|
|
|
|
or hash_name(u.name) == post.name_hash): |
|
|
|
|
if not check_can_del(username, post.name_hash): |
|
|
|
|
abort(403) |
|
|
|
|
|
|
|
|
|
post.cw = cw |
|
|
|
@ -275,21 +274,19 @@ def edit_cw():
|
|
|
|
|
|
|
|
|
|
@app.route('/_api/v1/getcomment') |
|
|
|
|
def get_comment(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
username = get_current_username() |
|
|
|
|
|
|
|
|
|
pid = get_num(request.args.get('pid')) |
|
|
|
|
|
|
|
|
|
post = Post.query.get(pid) |
|
|
|
|
if not post: |
|
|
|
|
abort(404) |
|
|
|
|
if post.deleted: |
|
|
|
|
post = Post.query.get_or_404(pid) |
|
|
|
|
if post.deleted and not check_can_del(username, post.name_hash): |
|
|
|
|
abort(451) |
|
|
|
|
|
|
|
|
|
data = map_comment(post, u.name) |
|
|
|
|
data = map_comment(post, username) |
|
|
|
|
|
|
|
|
|
return { |
|
|
|
|
'code': 0, |
|
|
|
|
'attention': check_attention(u.name, pid), |
|
|
|
|
'attention': check_attention(username, pid), |
|
|
|
|
'likenum': post.likenum, |
|
|
|
|
'data': data |
|
|
|
|
} |
|
|
|
@ -298,24 +295,24 @@ def get_comment():
|
|
|
|
|
@app.route('/_api/v1/docomment', methods=['POST']) |
|
|
|
|
@limiter.limit("50 / hour; 1 / 3 second") |
|
|
|
|
def do_comment(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
username = get_current_username() |
|
|
|
|
|
|
|
|
|
pid = get_num(request.form.get('pid')) |
|
|
|
|
|
|
|
|
|
post = Post.query.get(pid) |
|
|
|
|
if not post: |
|
|
|
|
abort(404) |
|
|
|
|
if post.deleted: |
|
|
|
|
if post.deleted and not check_can_del(username, post.name_hash): |
|
|
|
|
abort(451) |
|
|
|
|
|
|
|
|
|
content = request.form.get('text') |
|
|
|
|
content = content.strip() if content else None |
|
|
|
|
content = '[tmp]\n' + content if u.name[:4] == 'tmp_' else content |
|
|
|
|
content = '[tmp]\n' + content if username[:4] == 'tmp_' else content |
|
|
|
|
if not content or len(content) > 4096: |
|
|
|
|
abort(422) |
|
|
|
|
|
|
|
|
|
c = Comment( |
|
|
|
|
name_hash=hash_name(u.name), |
|
|
|
|
name_hash=hash_name(username), |
|
|
|
|
content=content, |
|
|
|
|
) |
|
|
|
|
post.comments.append(c) |
|
|
|
@ -325,11 +322,11 @@ def do_comment():
|
|
|
|
|
post.hot_score += 1 |
|
|
|
|
|
|
|
|
|
at = Attention.query.filter_by( |
|
|
|
|
name_hash=hash_name(u.name), pid=pid |
|
|
|
|
name_hash=hash_name(username), pid=pid |
|
|
|
|
).first() |
|
|
|
|
|
|
|
|
|
if not at: |
|
|
|
|
at = Attention(name_hash=hash_name(u.name), pid=pid, disabled=False) |
|
|
|
|
at = Attention(name_hash=hash_name(username), pid=pid, disabled=False) |
|
|
|
|
db.session.add(at) |
|
|
|
|
post.likenum += 1 |
|
|
|
|
if post.hot_score != -1: |
|
|
|
@ -350,8 +347,8 @@ def do_comment():
|
|
|
|
|
@app.route('/_api/v1/attention', methods=['POST']) |
|
|
|
|
@limiter.limit("200 / hour; 1 / second") |
|
|
|
|
def attention(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
if u.name[:4] == 'tmp_': |
|
|
|
|
username = get_current_username() |
|
|
|
|
if username[:4] == 'tmp_': |
|
|
|
|
abort(403) |
|
|
|
|
|
|
|
|
|
s = request.form.get('switch') |
|
|
|
@ -365,11 +362,11 @@ def attention():
|
|
|
|
|
abort(404) |
|
|
|
|
|
|
|
|
|
at = Attention.query.filter_by( |
|
|
|
|
name_hash=hash_name(u.name), pid=pid |
|
|
|
|
name_hash=hash_name(username), pid=pid |
|
|
|
|
).first() |
|
|
|
|
|
|
|
|
|
if not at: |
|
|
|
|
at = Attention(name_hash=hash_name(u.name), pid=pid, disabled=True) |
|
|
|
|
at = Attention(name_hash=hash_name(username), pid=pid, disabled=True) |
|
|
|
|
db.session.add(at) |
|
|
|
|
if post.hot_score != -1: |
|
|
|
|
post.hot_score += 2 |
|
|
|
@ -389,12 +386,12 @@ def attention():
|
|
|
|
|
|
|
|
|
|
@app.route('/_api/v1/getattention') |
|
|
|
|
def get_attention(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
username = get_current_username() |
|
|
|
|
|
|
|
|
|
ats = Attention.query.with_entities( |
|
|
|
|
Attention.pid |
|
|
|
|
).filter_by( |
|
|
|
|
name_hash=hash_name(u.name), disabled=False |
|
|
|
|
name_hash=hash_name(username), disabled=False |
|
|
|
|
).all() |
|
|
|
|
|
|
|
|
|
pids = [pid for pid, in ats] or [0] # sql not allow empty in |
|
|
|
@ -405,7 +402,7 @@ def get_attention():
|
|
|
|
|
).order_by(Post.id.desc()).all() |
|
|
|
|
|
|
|
|
|
data = [ |
|
|
|
|
map_post(post, u.name, 10) |
|
|
|
|
map_post(post, username, 10) |
|
|
|
|
for post in posts |
|
|
|
|
] |
|
|
|
|
|
|
|
|
@ -419,7 +416,7 @@ def get_attention():
|
|
|
|
|
@app.route('/_api/v1/delete', methods=['POST']) |
|
|
|
|
@limiter.limit("50 / hour; 1 / 3 second") |
|
|
|
|
def delete(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
username = get_current_username() |
|
|
|
|
|
|
|
|
|
obj_type = request.form.get('type') |
|
|
|
|
obj_id = get_num(request.form.get('id')) |
|
|
|
@ -436,7 +433,7 @@ def delete():
|
|
|
|
|
if not obj: |
|
|
|
|
abort(404) |
|
|
|
|
|
|
|
|
|
if obj.name_hash == hash_name(u.name): |
|
|
|
|
if obj.name_hash == hash_name(username): |
|
|
|
|
if obj_type == 'pid': |
|
|
|
|
if len(obj.comments): |
|
|
|
|
abort(403) |
|
|
|
@ -445,12 +442,12 @@ def delete():
|
|
|
|
|
db.session.delete(obj) |
|
|
|
|
else: |
|
|
|
|
obj.deleted = True |
|
|
|
|
elif u.name in app.config.get('ADMINS'): |
|
|
|
|
elif username in app.config.get('ADMINS'): |
|
|
|
|
obj.deleted = True |
|
|
|
|
db.session.add(Syslog( |
|
|
|
|
log_type='ADMIN DELETE', |
|
|
|
|
log_detail=f"{obj_type}={obj_id}\n{note}", |
|
|
|
|
name_hash=hash_name(u.name) |
|
|
|
|
name_hash=hash_name(username) |
|
|
|
|
)) |
|
|
|
|
if note.startswith('!ban'): |
|
|
|
|
db.session.add(Syslog( |
|
|
|
@ -467,7 +464,7 @@ def delete():
|
|
|
|
|
|
|
|
|
|
@app.route('/_api/v1/systemlog') |
|
|
|
|
def system_log(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
username = get_current_username() |
|
|
|
|
|
|
|
|
|
ss = Syslog.query.order_by(db.desc('timestamp')).limit(100).all() |
|
|
|
|
|
|
|
|
@ -475,14 +472,14 @@ def system_log():
|
|
|
|
|
'start_time': app.config['START_TIME'], |
|
|
|
|
'salt': look(app.config['SALT']), |
|
|
|
|
'tmp_token': tmp_token(), |
|
|
|
|
'data': [map_syslog(s, u) for s in ss] |
|
|
|
|
'data': [map_syslog(s, username) for s in ss] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/_api/v1/report', methods=['POST']) |
|
|
|
|
@limiter.limit("10 / hour; 1 / 3 second") |
|
|
|
|
def report(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
username = get_current_username() |
|
|
|
|
|
|
|
|
|
pid = get_num(request.form.get('pid')) |
|
|
|
|
|
|
|
|
@ -491,7 +488,7 @@ def report():
|
|
|
|
|
db.session.add(Syslog( |
|
|
|
|
log_type='REPORT', |
|
|
|
|
log_detail=f"pid={pid}\n{reason}", |
|
|
|
|
name_hash=hash_name(u.name) |
|
|
|
|
name_hash=hash_name(username) |
|
|
|
|
)) |
|
|
|
|
|
|
|
|
|
post = Post.query.get(pid) |
|
|
|
@ -505,9 +502,8 @@ def report():
|
|
|
|
|
|
|
|
|
|
@app.route('/_api/v1/update_score', methods=['POST']) |
|
|
|
|
def edit_hot_score(): |
|
|
|
|
u = get_current_user() |
|
|
|
|
if not is_admin(u.name): |
|
|
|
|
print(u.name) |
|
|
|
|
username = get_current_username() |
|
|
|
|
if not is_admin(username): |
|
|
|
|
abort(403) |
|
|
|
|
|
|
|
|
|
pid = request.form.get('pid', type=int) |
|
|
|
|