From 34fe546cd6cd750e3315536f82abd52fb2da7857 Mon Sep 17 00:00:00 2001 From: p23 Date: Tue, 26 Nov 2024 09:38:28 +0000 Subject: [PATCH] 404 --- blueprints/admin.py | 13 ++++++------- blueprints/article.py | 20 +++++++++----------- protobuf_files/niming.proto | 4 +--- protobuf_files/niming_pb2.py | 12 ++++++------ utils/dbhelper.py | 18 ++++++++---------- utils/misc.py | 12 ------------ 6 files changed, 30 insertions(+), 49 deletions(-) diff --git a/blueprints/admin.py b/blueprints/admin.py index 3960654..cd61bb8 100644 --- a/blueprints/admin.py +++ b/blueprints/admin.py @@ -4,12 +4,12 @@ import math import json import jwt -from flask import Blueprint, request, jsonify, make_response, g +from flask import Blueprint, request, jsonify, make_response, g, abort from bcrypt import hashpw, gensalt, checkpw from functools import wraps from utils import pgclass, setting_loader, logger -from utils.misc import error, internal_json2protobuf, error_proto +from utils.misc import error, internal_json2protobuf from utils.dbhelper import db, solo_article_fetcher, multi_article_fetcher, solo_file_fetcher, solo_article_remover from utils.platform_consts import PLIST, PLIST_ROOT from protobuf_files import niming_pb2 @@ -204,7 +204,6 @@ def article_del(id:int): logger.logger("article.delete", "User:%s deleted post (id=%d): last_status=%s"%(opuser.user, result["id"], result["mark"])) return niming_pb2.FetchResponse( - status = niming_pb2.Status.Success, posts = [ niming_pb2.FetchResponse.Message(id = result["id"], mark = result["mark"]) ] ).SerializeToString(), 200 @@ -216,20 +215,20 @@ def article_pend(id:int): with db.getsession() as session: # 確保文章存在 res = session.query(table).filter(table.id==int(id)).first() - if res is None: return error_proto("fetch", "Post not found"), 404 + if res is None: return abort(404) # 如果文章已經公開 if res.mark == "visible": - return error_proto("fetch", "Post is already visible."), 400 + return abort(400) elif res.mark == "pending": res.mark = "visible" session.commit() # run IG Post - return niming_pb2.FetchResponse(status=niming_pb2.Status.Success).SerializeToString(), 200 + return abort(200) else: - return error_proto("fetch", "Post mark error"), 500 + return abort(500) #################### # Setting Area # diff --git a/blueprints/article.py b/blueprints/article.py index 5bec259..64be130 100644 --- a/blueprints/article.py +++ b/blueprints/article.py @@ -3,12 +3,12 @@ import hashlib import secrets import magic -from flask import Blueprint, request, jsonify +from flask import Blueprint, request, abort from google.protobuf.message import DecodeError from utils import logger, pgclass, setting_loader from utils.dbhelper import db, solo_article_fetcher, multi_article_fetcher, solo_file_fetcher, solo_article_remover -from utils.misc import error, error_proto, internal_json2protobuf +from utils.misc import error, internal_json2protobuf from protobuf_files import niming_pb2 """ @@ -62,7 +62,6 @@ def owner_getarticle(id:int): logger.logger("delpost", "Delete post (id=%d): last_status=%s" %(result["id"], str(result["mark"]))) return niming_pb2.FetchResponse( - status = niming_pb2.Status.Success, posts = [ niming_pb2.FetchResponse.Message(id = result["id"], mark = result["mark"]) ] ).SerializeToString(), 200 @@ -88,12 +87,12 @@ def posting(): # protobuf parse recv = niming_pb2.Post() try: recv.ParseFromString(request.data) - except DecodeError: return error_proto("post", "Protobuf decode error"), 400 + except DecodeError: return abort(400) # content and check ctx = str(recv.content) if len(ctx) == 0 or len(ctx) > maxword: # length check - return error_proto("post", "no content or too many words"), 400 + return abort(400) # hash seed = ctx + str(time.time()) + str(secrets.token_urlsafe(nbytes=16)) @@ -105,7 +104,7 @@ def posting(): # 檢查指向的文章是否也是留言 reftg, code = solo_article_fetcher(role="general", key=ref) if code != 200 or reftg["reference"]: - return error_proto("post", "Invalid Reference"), 400 + return abort(400) else: ref = None @@ -114,16 +113,16 @@ def posting(): # check - size atts = opt["Attachment_Count"] sizelimit = opt["Attachment_Size"] - if len(files) > atts: return error_proto("post", "Too many files"), 400 + if len(files) > atts: return abort(400) for f in files: - if len(f) <= 0 or len(f) > sizelimit: return error_proto("post", "File size error"), 400 + if len(f) <= 0 or len(f) > sizelimit: return abort(400) # check - mimetype allowed_mime = opt["Allowed_MIME"] fmimes = [] for f in files: mime = magic.Magic(mime=True) type = mime.from_buffer(f) - if not(type in allowed_mime): return error_proto("post", "File format error"), 400 + if not(type in allowed_mime): return abort(400) fmimes.append(type) # IP @@ -163,14 +162,13 @@ def posting(): session.commit() # second commit result_id = data.id except: - return error_proto("post", "Create new post failed"), 400 + return abort(400) # logger logger.logger("newpost", "New post (id=%d point to %s): %s"%(result_id, ref, mark)) # to protobuf & return proto_stres = niming_pb2.PostResponse( - status = niming_pb2.Status.Success, hash = hash, id = int(result_id) ).SerializeToString() diff --git a/protobuf_files/niming.proto b/protobuf_files/niming.proto index 0bb46c8..cfd0547 100644 --- a/protobuf_files/niming.proto +++ b/protobuf_files/niming.proto @@ -37,7 +37,5 @@ message FetchResponse { repeated uint64 comments_id = 9; } // Several post info - Status status = 1; - repeated Message posts = 2; - optional string failed_message = 3; + repeated Message posts = 1; } \ No newline at end of file diff --git a/protobuf_files/niming_pb2.py b/protobuf_files/niming_pb2.py index f7d19ae..5ccea46 100644 --- a/protobuf_files/niming_pb2.py +++ b/protobuf_files/niming_pb2.py @@ -13,21 +13,21 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cniming.proto\"@\n\x04Post\x12\x0f\n\x07\x63ontent\x18\x01 \x01(\t\x12\x10\n\x03ref\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\r\n\x05\x66iles\x18\x03 \x03(\x0c\x42\x06\n\x04_ref\"q\n\x0cPostResponse\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\x12\x0c\n\x04hash\x18\x02 \x01(\t\x12\n\n\x02id\x18\x03 \x01(\x04\x12\x1b\n\x0e\x66\x61iled_message\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x11\n\x0f_failed_message\"\xb9\x02\n\rFetchResponse\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\x12%\n\x05posts\x18\x02 \x03(\x0b\x32\x16.FetchResponse.Message\x12\x1b\n\x0e\x66\x61iled_message\x18\x03 \x01(\tH\x00\x88\x01\x01\x1a\xb7\x01\n\x07Message\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\t\x12\x10\n\x03ref\x18\x03 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x08\x66iles_id\x18\x04 \x03(\x04\x12\x11\n\x04hash\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x0c\n\x04igid\x18\x06 \x01(\t\x12\x0c\n\x04mark\x18\x07 \x01(\t\x12\x0f\n\x02ip\x18\x08 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x0b\x63omments_id\x18\t \x03(\x04\x42\x06\n\x04_refB\x07\n\x05_hashB\x05\n\x03_ipB\x11\n\x0f_failed_message*!\n\x06Status\x12\n\n\x06\x46\x61iled\x10\x00\x12\x0b\n\x07Success\x10\x01\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cniming.proto\"@\n\x04Post\x12\x0f\n\x07\x63ontent\x18\x01 \x01(\t\x12\x10\n\x03ref\x18\x02 \x01(\x03H\x00\x88\x01\x01\x12\r\n\x05\x66iles\x18\x03 \x03(\x0c\x42\x06\n\x04_ref\"q\n\x0cPostResponse\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\x12\x0c\n\x04hash\x18\x02 \x01(\t\x12\n\n\x02id\x18\x03 \x01(\x04\x12\x1b\n\x0e\x66\x61iled_message\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x11\n\x0f_failed_message\"\xf0\x01\n\rFetchResponse\x12%\n\x05posts\x18\x01 \x03(\x0b\x32\x16.FetchResponse.Message\x1a\xb7\x01\n\x07Message\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\t\x12\x10\n\x03ref\x18\x03 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x08\x66iles_id\x18\x04 \x03(\x04\x12\x11\n\x04hash\x18\x05 \x01(\tH\x01\x88\x01\x01\x12\x0c\n\x04igid\x18\x06 \x01(\t\x12\x0c\n\x04mark\x18\x07 \x01(\t\x12\x0f\n\x02ip\x18\x08 \x01(\tH\x02\x88\x01\x01\x12\x13\n\x0b\x63omments_id\x18\t \x03(\x04\x42\x06\n\x04_refB\x07\n\x05_hashB\x05\n\x03_ip*!\n\x06Status\x12\n\n\x06\x46\x61iled\x10\x00\x12\x0b\n\x07Success\x10\x01\x62\x06proto3') _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'niming_pb2', globals()) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None - _STATUS._serialized_start=513 - _STATUS._serialized_end=546 + _STATUS._serialized_start=440 + _STATUS._serialized_end=473 _POST._serialized_start=16 _POST._serialized_end=80 _POSTRESPONSE._serialized_start=82 _POSTRESPONSE._serialized_end=195 _FETCHRESPONSE._serialized_start=198 - _FETCHRESPONSE._serialized_end=511 - _FETCHRESPONSE_MESSAGE._serialized_start=309 - _FETCHRESPONSE_MESSAGE._serialized_end=492 + _FETCHRESPONSE._serialized_end=438 + _FETCHRESPONSE_MESSAGE._serialized_start=255 + _FETCHRESPONSE_MESSAGE._serialized_end=438 # @@protoc_insertion_point(module_scope) diff --git a/utils/dbhelper.py b/utils/dbhelper.py index a306871..bebb02c 100644 --- a/utils/dbhelper.py +++ b/utils/dbhelper.py @@ -1,11 +1,11 @@ from typing import Tuple, Dict, List -from flask import make_response, Response, jsonify +from flask import make_response, Response, abort from sqlalchemy.orm import sessionmaker, aliased from sqlalchemy import desc, func, literal, and_ from utils import pgclass -from utils.misc import error, error_proto +from utils.misc import error from protobuf_files import niming_pb2 class db: @@ -23,7 +23,7 @@ class db: # role (general) (owner) (admin) # 獲取單一文章 -def solo_article_fetcher(role:str, key) -> Tuple[Dict | bytes, int]: # admin, owner, general +def solo_article_fetcher(role:str, key) -> Tuple[Dict, int]: # admin, owner, general table = pgclass.SQLarticle # main table2 = aliased(table) # comment with db.getsession() as session: @@ -51,7 +51,7 @@ def solo_article_fetcher(role:str, key) -> Tuple[Dict | bytes, int]: # admin, ow res = res.group_by(table.id, table.content, table.reference, table.file_list, table.hash, table.igid, table.mark, table.ip).first() if res is None: - return error_proto("fetch", "Post not found"), 404 + return abort(404) # mapping one = { @@ -76,13 +76,11 @@ def solo_article_fetcher(role:str, key) -> Tuple[Dict | bytes, int]: # admin, ow def multi_article_fetcher(role:str, page:str, count:int) -> Tuple[bytes, int]: # general, admin # checker if page is None or not page.isdigit(): - return error_proto("fetch", "Arguments error"), 400 + return abort(400) page = int(page)*count table = pgclass.SQLarticle - resfn = niming_pb2.FetchResponse( - status = niming_pb2.Status.Success - ) + resfn = niming_pb2.FetchResponse() with db.getsession() as session: # query @@ -112,7 +110,7 @@ def multi_article_fetcher(role:str, page:str, count:int) -> Tuple[bytes, int]: # # 刪除文章 -def solo_article_remover(role:str, hash:str=None, id:int=None) -> Tuple[Dict | bytes, int]: # admin, owner +def solo_article_remover(role:str, hash:str=None, id:int=None) -> Tuple[Dict, int]: # admin, owner key = None if role == "admin": key = id elif role == "owner": key = (hash, id) @@ -125,7 +123,7 @@ def solo_article_remover(role:str, hash:str=None, id:int=None) -> Tuple[Dict | b elif role == "owner": res = session.query(table).filter(table.hash == key[0], table.id == key[1]).first() if res is None: # 檢查本體是否存在 - return error_proto("fetch", "Post not found!"), 404 + return abort(404) # 刪本體 session.delete(res) session.commit() diff --git a/utils/misc.py b/utils/misc.py index 65eb32a..dc0b01f 100644 --- a/utils/misc.py +++ b/utils/misc.py @@ -6,18 +6,6 @@ def error(message:str) -> Response: return jsonify({"error":message}) -def error_proto(type:str, message:str) -> Response: - if type == "post": - proto = niming_pb2.PostResponse() - proto.hash = "" - proto.id = 0 - elif type == "fetch": - proto = niming_pb2.FetchResponse() - proto.status = niming_pb2.Status.Failed - proto.failed_message = message - return proto.SerializeToString() - - def internal_json2protobuf(original:list|dict) -> bytes: if isinstance(original, dict): original = [original]