from time import time
from typing import Any, Callable, Tuple, AsyncIterator
from .account import extract_channel
from .interfaces.AioHttpHelper import AioHttpHelperInterface
from .kwargs import extract_common_kwargs
from .submit import SubmissionWSResult
# return (end watch?, transform result)
[docs]def display_ws(result: Any) -> Tuple[bool, Any]:
print(result)
return False, result
# # {'id': 1, 'channel': '34f1ec4b729022e4b48f8d24b65c857805a90469', 'text': {'t': 's', 'd': [5973356517882654806, 200631363, 1777, 1746206, 'TESTS', None, 'OK', 86, 86, 3198, 7884800, 148217099, '21220', '04.04.2023 5:57:08', '04.04.2023 5:57:08', 2147483647, 73, 0]}}
# # 总的ws, 无法获得当前题目的 通过百分比
# def create_ws_task(http: AioHttpHelperInterface, ws_handler: Callable[[Any], Tuple[bool, Any]]) -> asyncio.Task:
# """
# This method will use ``http`` to create common websocket, and ``ws_handler`` to handle each ws message
#
# this websocket cannot receive a submission running percentage, use :py:func:`create_contest_ws_task()` instead
#
# :param http: AioHttpHelperInterface
# :param ws_handler: function to handler messages
#
# :returns: the task which run ws
#
# Examples:
#
# .. code-block::
#
# import asyncio
# from codeforces_core.httphelper import HttpHelper
# from codeforces_core.account import async_login
# from codeforces_core.websocket import create_ws_task, display_ws
# from codeforces_core.submit import async_submit
#
# async def demo():
# # http = HttpHelper(token_path='/tmp/cache_token', cookie_jar_path='/tmp/cache_cookie_jar')
# http = HttpHelper(token_path='', cookie_jar_path='')
# await http.open_session()
# result = await async_login(http=http, handle='<handle>', password='<password>')
# assert(result.success)
# task = create_ws_task(http, ws_handler=display_ws)
# # submit code in webpage
# try:
# result = await asyncio.wait_for(task, timeout=60)
# print("ws is done, result:", task.result())
# except asyncio.TimeoutError:
# pass
# await http.close_session()
#
# asyncio.run(demo())
# """
# epoch = int(time() * 1000) # s -> ms
# token = http.get_tokens()
# ws_url = f"wss://pubsub.codeforces.com/ws/{token['uc']}/{token['usmc']}?_={epoch}&tag=&time=&eventid="
# print(ws_url)
# return asyncio.create_task(http.websockets(ws_url, ws_handler))
# https://codeforces.com/contest/<contest_id>/my 会多出两个 meta
# <meta name="cc" content="xxx"/>
# <meta name="pc" content="yyy"/>
# TODO 设计上不太对, handler处理了数据, 结果也抛给了使用者, 应该handler 只关心是否停止, 而transform不应该在handler里处理
# 这两个可以监听 题目测试时 的通过 百分比 变化
[docs]async def create_contest_ws_task_yield(http: AioHttpHelperInterface, contest_id: str,
ws_handler: Callable[[Any], Tuple[bool, Any]],
**kw) -> AsyncIterator[SubmissionWSResult]:
"""
This method will use ``http`` to create contest specific websocket, and ``ws_handler`` to handle each ws message
:param http: AioHttpHelperInterface
:param contest_id: contest id in the url
:param ws_handler: function to handler messages
:returns: the task which run ws
Examples:
See docstring of :py:func:`codeforces_core.submit.async_submit()`
"""
logger = extract_common_kwargs(**kw).logger
epoch = int(time() * 1000) # s -> ms
html_data = await http.async_get(f"/contest/{contest_id}/my")
cc, pc = extract_channel(html_data, logger)[2:4]
assert cc and pc
ws_url = f"wss://pubsub.codeforces.com/ws/s_{pc}/s_{cc}?_={epoch}&tag=&time=&eventid="
logger.debug(f"pc = {pc}") # 似乎和场次有关, 可能包含别人的?
logger.debug(f"cc = {cc}") # 似乎只会包含自己的
logger.debug(f"ws_url = {ws_url}")
async for data in http.websockets(ws_url, ws_handler):
yield data