niming_igapi/grpcServer/grpcServer.py

139 lines
4.7 KiB
Python
Raw Permalink Normal View History

2024-12-18 00:35:17 +08:00
# from concurrent import futures
2024-12-18 03:06:40 +08:00
import logging
2024-12-18 00:35:17 +08:00
import grpc
from cachetools import cached, TTLCache
from ig import IG
from db import dbhelper
from utils.const import GRPC_ACCINFO_CACHE, GRPC_RELOGIN_LIMIT
from grpcServer import anoth
from grpcServer.protobuf import igapi_pb2_grpc
from grpcServer.protobuf.igapi_pb2 import Request, Reply
2024-12-18 03:06:40 +08:00
# logging
grpclog = logging.getLogger("grpc")
grpclog.setLevel(level=logging.INFO)
2024-12-18 00:35:17 +08:00
# call account info / login
2024-12-22 21:00:25 +08:00
# may race condition
2024-12-18 00:35:17 +08:00
cache_accinfo = TTLCache(maxsize=1, ttl=GRPC_ACCINFO_CACHE)
@cached(cache_accinfo)
def call_IG_account_info():
result = IG.account_info()
return result
cache_login = TTLCache(maxsize=1, ttl=GRPC_RELOGIN_LIMIT)
@cached(cache_login)
def call_IG_login():
result = IG.login()
return result
# object
# 考慮一下如果同時發起多的請求asyncio可能會搞到被ban號(IG)
class IGAPI_Server(igapi_pb2_grpc.IGAPIServicer):
async def account_info(self, request: Request, context) -> Reply:
2024-12-18 03:06:40 +08:00
grpclog.info("Request: account_info")
2024-12-18 00:35:17 +08:00
account = call_IG_account_info()
if account:
result = {
"username":account["username"],
"full_name":account["full_name"],
"email":account["email"]
}
return Reply(err=0, result=result)
else:
return Reply(err=1, result={"error":"IG.account_info returned None"})
async def login(self, request: Request, context) -> Reply:
2024-12-18 03:06:40 +08:00
grpclog.info("Request: login")
2024-12-18 00:35:17 +08:00
if len(cache_login): # cache has not expired
2024-12-18 03:06:40 +08:00
grpclog.info("Login: Cooldown")
2024-12-18 00:35:17 +08:00
return Reply(err=1, result={"error":"Cooldown"})
else:
login = call_IG_login()
if login:
return Reply(err=0, result={"result":"Login Successed"})
else:
return Reply(err=1, result={"error":"Login Failed"})
async def upload(self, request: Request, context) -> Reply:
2024-12-18 03:06:40 +08:00
grpclog.info("Request: upload")
2024-12-18 00:35:17 +08:00
aid = request.code
# 檢查 - 可見
article, code = dbhelper.solo_article_fetcher(role="general", key=aid) # visible -> post
if code != 200:
return Reply(err=1, result={"error":"Post not found"})
# 檢查 - 已經在 Queue 內
if anoth.task["upload-"+str(aid)]:
return Reply(err=1, result={"error":"Request is already in queue"})
# 檢查 - Queue 內有請求刪除同目標
if anoth.task["delete-"+str(aid)]:
anoth.task.pop("delete-"+str(aid))
return Reply(err=0, result={"result":"Canceled delete post request"})
# 檢查 - 已經上傳過
if article["igid"]:
return Reply(err=1, result={"error":"Already Posted"})
# put into queue
anoth.task["upload-"+str(aid)] = {"aid":aid}
return Reply(err=0, result={"result":"Put into queue"})
async def delete(self, request: Request, context) -> Reply:
2024-12-18 03:06:40 +08:00
grpclog.info("Request: delete")
2024-12-18 00:35:17 +08:00
# article id
aid = request.code
# igid from args
if request.args:
igid = request.args[0]
else:
return Reply(err=1, result={"error":"Invalid Arguments"})
# 檢查 - 已經在 Queue 內
if anoth.task["delete-"+str(aid)]:
return Reply(err=1, result={"error":"Request is already in queue"})
# 檢查 - Queue 內有請求上傳同目標
if anoth.task["upload-"+str(aid)]:
anoth.task.pop("upload-"+str(aid))
return Reply(err=0, result={"result":"Canceled upload post request"})
# put into queue
anoth.task["delete-"+str(aid)] = {"aid":aid, "code":igid}
return Reply(err=0, result={"result":"Put into queue"})
async def queue(self, request:Request, context) -> Reply:
2024-12-18 03:06:40 +08:00
grpclog.info("Request: queue")
2024-12-18 00:35:17 +08:00
t = anoth.task.items()
reply = { _[0]:str(_[1]["aid"]) for _ in t }
return Reply(err=0, result=reply)
async def setting(self, request:Request, context) -> Reply:
# not done
2024-12-18 03:06:40 +08:00
grpclog.info("Request: setting")
2024-12-18 00:35:17 +08:00
return Reply(err=1, result={"error":"Not Done"})
# start server
async def serve() -> None:
server = grpc.aio.server()
igapi_pb2_grpc.add_IGAPIServicer_to_server(
IGAPI_Server(), server
)
server.add_insecure_port("[::]:50051")
await server.start()
2024-12-18 03:06:40 +08:00
grpclog.info("gRPC Server listening on 0.0.0.0:50051")
2024-12-18 00:35:17 +08:00
await server.wait_for_termination()