自定义头衔
This commit is contained in:
5
clear_redis.py
Normal file
5
clear_redis.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# 每次重置时执行
|
||||||
|
from utils import rds, RDS_KEY_TITLE, RDS_KEY_BLOCKED_COUNT
|
||||||
|
|
||||||
|
rds.delete(RDS_KEY_BLOCKED_COUNT)
|
||||||
|
rds.delete(RDS_KEY_TITLE)
|
||||||
45
hole.py
45
hole.py
@@ -10,7 +10,7 @@ from sqlalchemy.sql.expression import func
|
|||||||
|
|
||||||
from mastodon import Mastodon
|
from mastodon import Mastodon
|
||||||
from models import db, User, Post, Comment, Attention, TagRecord, Syslog
|
from models import db, User, Post, Comment, Attention, TagRecord, Syslog
|
||||||
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, rds, RDS_KEY_POLL_OPTS, RDS_KEY_POLL_VOTES, gen_poll_dict, name_with_tmp_limit, RDS_KEY_BLOCK_SET, RDS_KEY_BLOCKED_COUNT, RDS_KEY_DANGEROUS_USERS
|
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, rds, RDS_KEY_POLL_OPTS, RDS_KEY_POLL_VOTES, gen_poll_dict, name_with_tmp_limit, RDS_KEY_BLOCK_SET, RDS_KEY_BLOCKED_COUNT, RDS_KEY_DANGEROUS_USERS, RDS_KEY_TITLE
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///hole.db'
|
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///hole.db'
|
||||||
@@ -24,7 +24,6 @@ app.config.from_pyfile('config.py')
|
|||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
migrate = Migrate(app, db)
|
migrate = Migrate(app, db)
|
||||||
|
|
||||||
|
|
||||||
CS_LOGIN_URL = Mastodon(api_base_url=app.config['MASTODON_URL']) \
|
CS_LOGIN_URL = Mastodon(api_base_url=app.config['MASTODON_URL']) \
|
||||||
.auth_request_url(
|
.auth_request_url(
|
||||||
client_id=app.config['CLIENT_ID'],
|
client_id=app.config['CLIENT_ID'],
|
||||||
@@ -41,9 +40,6 @@ limiter = Limiter(
|
|||||||
PER_PAGE = 50
|
PER_PAGE = 50
|
||||||
DANGEROUS_USER_THRESHOLD = 10
|
DANGEROUS_USER_THRESHOLD = 10
|
||||||
|
|
||||||
# 重置后旧的被拉黑次数可以丢弃了,但其他仍需要保留
|
|
||||||
rds.delete(RDS_KEY_BLOCKED_COUNT)
|
|
||||||
|
|
||||||
|
|
||||||
class APIError(Exception):
|
class APIError(Exception):
|
||||||
msg = '未知错误'
|
msg = '未知错误'
|
||||||
@@ -138,6 +134,7 @@ def get_list():
|
|||||||
return {
|
return {
|
||||||
'code': 0,
|
'code': 0,
|
||||||
'tmp_token': tmp_token(),
|
'tmp_token': tmp_token(),
|
||||||
|
'custom_title': rds.hget(RDS_KEY_TITLE, hash_name(username)),
|
||||||
'count': len(data),
|
'count': len(data),
|
||||||
'data': data
|
'data': data
|
||||||
}
|
}
|
||||||
@@ -185,8 +182,6 @@ def get_multi():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/_api/v1/search')
|
@app.route('/_api/v1/search')
|
||||||
def search():
|
def search():
|
||||||
username = get_current_username()
|
username = get_current_username()
|
||||||
@@ -248,6 +243,7 @@ def do_post():
|
|||||||
post_type = request.form.get('type')
|
post_type = request.form.get('type')
|
||||||
cw = request.form.get('cw', '').strip()
|
cw = request.form.get('cw', '').strip()
|
||||||
poll_options = request.form.getlist('poll_options')
|
poll_options = request.form.getlist('poll_options')
|
||||||
|
use_title = request.form.get('use_title')
|
||||||
|
|
||||||
if not content or len(content) > 4096 or len(cw) > 32:
|
if not content or len(content) > 4096 or len(cw) > 32:
|
||||||
raise APIError('无内容或超长')
|
raise APIError('无内容或超长')
|
||||||
@@ -263,8 +259,10 @@ def do_post():
|
|||||||
if max(map(len, poll_options)) > 32:
|
if max(map(len, poll_options)) > 32:
|
||||||
raise APIError('选项过长')
|
raise APIError('选项过长')
|
||||||
|
|
||||||
|
name_hash = hash_name(username)
|
||||||
p = Post(
|
p = Post(
|
||||||
name_hash=hash_name(username),
|
name_hash=name_hash,
|
||||||
|
author_title=rds.hget(RDS_KEY_TITLE, name_hash) if use_title else None,
|
||||||
content=content,
|
content=content,
|
||||||
search_text=search_text,
|
search_text=search_text,
|
||||||
post_type=post_type,
|
post_type=post_type,
|
||||||
@@ -351,14 +349,18 @@ def do_comment():
|
|||||||
if post.deleted and not check_can_del(username, post.name_hash):
|
if post.deleted and not check_can_del(username, post.name_hash):
|
||||||
abort(451)
|
abort(451)
|
||||||
|
|
||||||
content = request.form.get('text')
|
content = request.form.get('text', '').strip()
|
||||||
content = content.strip() if content else None
|
if username.startswith('tmp_'):
|
||||||
content = '[tmp]\n' + content if username[:4] == 'tmp_' else content
|
content = '[tmp]\n' + content
|
||||||
if not content or len(content) > 4096:
|
if not content or len(content) > 4096:
|
||||||
abort(422)
|
abort(422)
|
||||||
|
|
||||||
|
use_title = request.form.get('use_title')
|
||||||
|
|
||||||
|
name_hash = hash_name(username)
|
||||||
c = Comment(
|
c = Comment(
|
||||||
name_hash=hash_name(username),
|
name_hash=name_hash,
|
||||||
|
author_title=rds.hget(RDS_KEY_TITLE, name_hash) if use_title else None,
|
||||||
content=content,
|
content=content,
|
||||||
)
|
)
|
||||||
post.comments.append(c)
|
post.comments.append(c)
|
||||||
@@ -518,6 +520,7 @@ def system_log():
|
|||||||
'start_time': app.config['START_TIME'],
|
'start_time': app.config['START_TIME'],
|
||||||
'salt': look(app.config['SALT']),
|
'salt': look(app.config['SALT']),
|
||||||
'tmp_token': tmp_token(),
|
'tmp_token': tmp_token(),
|
||||||
|
'custom_title': rds.hget(RDS_KEY_TITLE, hash_name(username)),
|
||||||
'data': [map_syslog(s, username) for s in ss]
|
'data': [map_syslog(s, username) for s in ss]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -627,5 +630,23 @@ def block_user_by_target():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/_api/v1/title', methods=['POST'])
|
||||||
|
@limiter.limit("10 / hour; 1 / 2 second")
|
||||||
|
def set_title():
|
||||||
|
username = get_current_username()
|
||||||
|
|
||||||
|
title = request.form.get('title')
|
||||||
|
if not title:
|
||||||
|
rds.hdel(RDS_KEY_TITLE, hash_name(username))
|
||||||
|
else:
|
||||||
|
if len(title) > 10:
|
||||||
|
raise APIError('自定义头衔太长')
|
||||||
|
if title in rds.hvals(RDS_KEY_TITLE): # 如果未来量大还是另外用个set维护
|
||||||
|
raise APIError('已经被使用了')
|
||||||
|
rds.hset(RDS_KEY_TITLE, hash_name(username), title)
|
||||||
|
|
||||||
|
return {'code': 0}
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(debug=True)
|
app.run(debug=True)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ class Post(db.Model):
|
|||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
name_hash = db.Column(db.String(64))
|
name_hash = db.Column(db.String(64))
|
||||||
|
author_title = db.Column(db.String(10))
|
||||||
content = db.Column(db.String(4096))
|
content = db.Column(db.String(4096))
|
||||||
search_text = db.Column(db.String(4096), default='', index=True)
|
search_text = db.Column(db.String(4096), default='', index=True)
|
||||||
post_type = db.Column(db.String(8))
|
post_type = db.Column(db.String(8))
|
||||||
@@ -44,6 +45,7 @@ class Post(db.Model):
|
|||||||
class Comment(db.Model):
|
class Comment(db.Model):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
name_hash = db.Column(db.String(64))
|
name_hash = db.Column(db.String(64))
|
||||||
|
author_title = db.Column(db.String(10))
|
||||||
content = db.Column(db.String(4096))
|
content = db.Column(db.String(4096))
|
||||||
timestamp = db.Column(db.Integer)
|
timestamp = db.Column(db.Integer)
|
||||||
deleted = db.Column(db.Boolean, default=False)
|
deleted = db.Column(db.Boolean, default=False)
|
||||||
|
|||||||
8
utils.py
8
utils.py
@@ -14,6 +14,8 @@ RDS_KEY_BLOCK_SET = 'hole_thu:block_list:%s' # key的参数是name而非namehas
|
|||||||
RDS_KEY_BLOCKED_COUNT = 'hole_thu:blocked_count' # namehash -> 被拉黑次数
|
RDS_KEY_BLOCKED_COUNT = 'hole_thu:blocked_count' # namehash -> 被拉黑次数
|
||||||
RDS_KEY_DANGEROUS_USERS = 'hole_thu:dangerous_users'
|
RDS_KEY_DANGEROUS_USERS = 'hole_thu:dangerous_users'
|
||||||
|
|
||||||
|
RDS_KEY_TITLE = 'hole_thu:title' # 用户自己设置的专属头衔, namehash -> 头衔
|
||||||
|
|
||||||
rds = redis.Redis(**RDS_CONFIG)
|
rds = redis.Redis(**RDS_CONFIG)
|
||||||
|
|
||||||
|
|
||||||
@@ -31,7 +33,7 @@ def tmp_token():
|
|||||||
)[5:21]
|
)[5:21]
|
||||||
|
|
||||||
|
|
||||||
def get_current_username():
|
def get_current_username() -> str:
|
||||||
token = request.headers.get('User-Token') or request.args.get('user_token')
|
token = request.headers.get('User-Token') or request.args.get('user_token')
|
||||||
if not token:
|
if not token:
|
||||||
abort(401)
|
abort(401)
|
||||||
@@ -72,7 +74,8 @@ def map_post(p, name, mc=50):
|
|||||||
'attention': check_attention(name, p.id),
|
'attention': check_attention(name, p.id),
|
||||||
'can_del': check_can_del(name, p.name_hash),
|
'can_del': check_can_del(name, p.name_hash),
|
||||||
'allow_search': bool(p.search_text),
|
'allow_search': bool(p.search_text),
|
||||||
'poll': None if blocked else gen_poll_dict(p.id, name)
|
'poll': None if blocked else gen_poll_dict(p.id, name),
|
||||||
|
'author_title': p.author_title
|
||||||
}
|
}
|
||||||
if is_admin(name):
|
if is_admin(name):
|
||||||
r['hot_score'] = p.hot_score
|
r['hot_score'] = p.hot_score
|
||||||
@@ -134,6 +137,7 @@ def map_comment(p, name):
|
|||||||
'blocked': (blocked := is_blocked(c.name_hash, name)),
|
'blocked': (blocked := is_blocked(c.name_hash, name)),
|
||||||
'cid': c.id,
|
'cid': c.id,
|
||||||
'name_id': gen_name_id(c.name_hash),
|
'name_id': gen_name_id(c.name_hash),
|
||||||
|
'author_title': c.author_title,
|
||||||
'pid': p.id,
|
'pid': p.id,
|
||||||
'text': '' if blocked else c.content,
|
'text': '' if blocked else c.content,
|
||||||
'timestamp': c.timestamp,
|
'timestamp': c.timestamp,
|
||||||
|
|||||||
Reference in New Issue
Block a user