import sys import time import traceback from aiohttp import web from sqlalchemy import select from api.model.toolkit_ui.conversation import ConversationHelper from api.model.toolkit_ui.page_title import PageTitleHelper from service.database import DatabaseService from service.event import EventService from service.mediawiki_api import MediaWikiApi, MediaWikiApiException, MediaWikiPageNotFoundException import utils.web class Index: @staticmethod @utils.web.token_auth async def update_title_info(request: web.Request): params = await utils.web.get_param(request, { "title": { "required": True, } }) title = params.get("title") mwapi = MediaWikiApi.create() db = await DatabaseService.create(request.app) async with PageTitleHelper(db) as page_title_helper: title_info = await page_title_helper.find_by_title(title) if title_info is not None and time.time() - title_info.updated_at < 60: return await utils.web.api_response(1, { "cached": True, "title": title_info.title, "page_id": title_info.page_id, }, request=request) # Load page info from MediaWiki API try: page_info = await mwapi.get_page_info(title) page_id = page_info.get("pageid") real_title = page_info.get("title") if title_info is None: title_info = await page_title_helper.add(page_id, real_title) else: title_info.page_id = page_id title_info.title = real_title await page_title_helper.update(title_info) return await utils.web.api_response(1, { "cached": False, "title": real_title, "page_id": page_id }, request=request) except MediaWikiPageNotFoundException: error_msg = "Page \"%s\" not found." % title return await utils.web.api_response(-2, error={ "code": "page-not-found", "message": error_msg }, request=request, http_status=404) except MediaWikiApiException as e: error_msg = "MediaWiki API error: %s" % e.info print(error_msg, file=sys.stderr) traceback.print_exc() return await utils.web.api_response(-3, error={ "code": "mediawiki-api-error", "message": error_msg }, request=request, http_status=500) except Exception as e: error_msg = str(e) print(error_msg, file=sys.stderr) traceback.print_exc() return await utils.web.api_response(-1, error={ "code": "internal-server-error", "message": error_msg }, request=request, http_status=500) @staticmethod @utils.web.token_auth async def get_conversation_list(request: web.Request): params = await utils.web.get_param(request, { "user_id": { "required": False, "type": int }, "title": { "required": True, }, "module": { "required": False } }) if request.get("caller") == "user": user_id = request.get("user") else: user_id = params.get("user_id") page_title = params.get("title") module = params.get("module") db = await DatabaseService.create(request.app) async with PageTitleHelper(db) as page_title_helper, ConversationHelper(db) as conversation_helper: page_id = await page_title_helper.get_page_id_by_title(page_title) if page_id is None: return await utils.web.api_response(-2, error={ "code": "page-not-found", "message": "Page not found.", }, request=request, http_status=404) conversation_list = await conversation_helper.get_conversation_list(user_id, module=module, page_id=page_id) conversation_result = [] for result in conversation_list: conversation_result.append({ "id": result.id, "module": result.module, "title": result.title, "thumbnail": result.thumbnail, "rev_id": result.rev_id, "updated_at": result.updated_at, "pinned": result.pinned, "extra": result.extra, }) return await utils.web.api_response(1, { "conversations": conversation_result }, request=request) @staticmethod @utils.web.token_auth async def get_conversation_info(request: web.Request): params = await utils.web.get_param(request, { "id": { "required": True, "type": int } }) conversation_id = params.get("id") db = await DatabaseService.create(request.app) async with ConversationHelper(db) as conversation_helper: conversation_info = await conversation_helper.find_by_id(conversation_id) if conversation_info is None: return await utils.web.api_response(-2, error={ "code": "conversation-not-found", "message": "Conversation not found.", }, request=request, http_status=404) if request.get("caller") == "user" and int(request.get("user")) != conversation_info.user_id: return await utils.web.api_response(-3, error={ "code": "permission-denied", "message": "Permission denied." }, request=request, http_status=403) conversation_result = { "id": conversation_info.id, "module": conversation_info.module, "title": conversation_info.title, "thumbnail": conversation_info.thumbnail, "rev_id": conversation_info.rev_id, "updated_at": conversation_info.updated_at, "pinned": conversation_info.pinned, "extra": conversation_info.extra, } return await utils.web.api_response(1, conversation_result, request=request) @staticmethod @utils.web.token_auth async def remove_conversation(request: web.Request): params = await utils.web.get_param(request, { "id": { "required": True, "type": int } }) conversation_id = params.get("id") db = await DatabaseService.create(request.app) async with ConversationHelper(db) as conversation_helper: conversation_info = await conversation_helper.find_by_id(conversation_id) if conversation_info is None: return await utils.web.api_response(-2, error={ "code": "conversation-not-found", "message": "Conversation not found." }, request=request, http_status=404) if request.get("caller") == "user" and int(request.get("user")) != conversation_info.user_id: return await utils.web.api_response(-3, error={ "code": "permission-denied", "message": "Permission denied." }, request=request, http_status=403) await conversation_helper.remove(conversation_info) # 通知其他模块删除 events = EventService.create() events.emit("conversation/removed", { "conversation": conversation_info, "dbs": db, "app": request.app, }) events.emit("conversation/removed/" + conversation_info.module, { "conversation": conversation_info, "dbs": db, "app": request.app, }) return await utils.web.api_response(1, request=request) @staticmethod @utils.web.token_auth async def set_conversation_pinned(request: web.Request): params = await utils.web.get_param(request, { "id": { "required": True, "type": int }, "pinned": { "required": True, "type": bool } }) conversation_id = params.get("id") pinned = params.get("pinned") db = await DatabaseService.create(request.app) async with ConversationHelper(db) as conversation_helper: conversation_info = await conversation_helper.find_by_id(conversation_id) if conversation_info is None: return await utils.web.api_response(-2, error={ "code": "conversation-not-found", "message": "Conversation not found." }, request=request, http_status=404) if request.get("caller") == "user" and int(request.get("user")) != conversation_info.user_id: return await utils.web.api_response(-3, error={ "code": "permission-denied", "message": "Permission denied." }, request=request, http_status=403) conversation_info.pinned = pinned await conversation_helper.update(conversation_info) return await utils.web.api_response(1, request=request) @staticmethod @utils.web.token_auth async def get_user_info(request: web.Request): params = await utils.web.get_param(request, { "user_id": { "required": False, "type": int } }) if request.get("caller") == "user": user_id = request.get("user") else: user_id = params.get("user_id") mwapi = MediaWikiApi.create() try: user_info = await mwapi.chat_complete_user_info(user_id) return await utils.web.api_response(1, user_info, request=request) except MediaWikiPageNotFoundException as e: return await utils.web.api_response(-2, error={ "code": "user-not-found", "message": "User not found." }, request=request, http_status=403) except MediaWikiApiException as e: err_str = "MediaWiki API error: %s" % e.info print(err_str, file=sys.stderr) traceback.print_exc() return await utils.web.api_response(-3, error={ "code": "mediawiki-api-error", "info": e.info, "message": err_str }, request=request, http_status=500) except Exception as e: err_str = str(e) print(err_str, file=sys.stderr) traceback.print_exc() return await utils.web.api_response(-1, error={ "code": "internal-server-error", "message": err_str }, request=request, http_status=500)