This commit is contained in:
p23 2024-11-26 09:38:28 +00:00
parent a548599662
commit 34fe546cd6
6 changed files with 30 additions and 49 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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