Track the last time users were sent chat messages
このコミットが含まれているのは:
コミット
1d5b446291
|
@ -44,6 +44,7 @@ def generate_user(timestamp, token, broadcaster, presence):
|
|||
'seen': timestamp,
|
||||
'watching': -inf,
|
||||
'eyes': -inf,
|
||||
'reading': -inf,
|
||||
},
|
||||
'presence': presence,
|
||||
'linespan': deque(),
|
||||
|
|
|
@ -9,7 +9,7 @@ from werkzeug.exceptions import TooManyRequests
|
|||
from anonstream.captcha import get_captcha_image
|
||||
from anonstream.segments import segments, StopSendingSegments
|
||||
from anonstream.stream import is_online, get_stream_uptime
|
||||
from anonstream.user import watched, create_eyes, renew_eyes, EyesException, RatelimitedEyes
|
||||
from anonstream.user import watching, create_eyes, renew_eyes, EyesException, RatelimitedEyes
|
||||
from anonstream.routes.wrappers import with_user_from, auth_required
|
||||
from anonstream.utils.security import generate_csp
|
||||
|
||||
|
@ -42,7 +42,7 @@ async def stream(user):
|
|||
except EyesException as e:
|
||||
raise StopSendingSegments(f'eyes {eyes_id} not allowed: {e!r}') from e
|
||||
print(f'{uri}: {eyes_id}~{user["token"]}')
|
||||
watched(user)
|
||||
watching(user)
|
||||
|
||||
generator = segments(segment_read_hook, token=user['token'])
|
||||
response = await make_response(generator)
|
||||
|
|
|
@ -6,7 +6,7 @@ from quart import current_app, request, render_template, redirect, url_for, esca
|
|||
from anonstream.captcha import get_random_captcha_digest_for
|
||||
from anonstream.chat import add_chat_message, Rejected
|
||||
from anonstream.stream import is_online, get_stream_title, get_stream_uptime_and_viewership
|
||||
from anonstream.user import add_state, pop_state, try_change_appearance, update_presence, get_users_by_presence, Presence, verify, deverify, BadCaptcha
|
||||
from anonstream.user import add_state, pop_state, try_change_appearance, update_presence, get_users_by_presence, Presence, verify, deverify, BadCaptcha, reading
|
||||
from anonstream.routes.wrappers import with_user_from, render_template_with_etag
|
||||
from anonstream.helpers.chat import get_scrollback
|
||||
from anonstream.helpers.user import get_default_name
|
||||
|
@ -46,6 +46,7 @@ async def nojs_info(user):
|
|||
@current_app.route('/chat/messages.html')
|
||||
@with_user_from(request)
|
||||
async def nojs_chat_messages(user):
|
||||
reading(user)
|
||||
return await render_template_with_etag(
|
||||
'nojs_chat_messages.html',
|
||||
{'csp': generate_csp()},
|
||||
|
|
|
@ -7,15 +7,16 @@ from math import inf
|
|||
|
||||
from quart import current_app, websocket
|
||||
|
||||
from anonstream.user import see
|
||||
from anonstream.user import see, reading
|
||||
from anonstream.websocket import websocket_outbound, websocket_inbound
|
||||
from anonstream.routes.wrappers import with_user_from
|
||||
|
||||
@current_app.websocket('/live')
|
||||
@with_user_from(websocket)
|
||||
async def live(user):
|
||||
queue = asyncio.Queue(maxsize=0)
|
||||
queue = asyncio.Queue()
|
||||
user['websockets'][queue] = -inf
|
||||
reading(user)
|
||||
|
||||
producer = websocket_outbound(queue, user)
|
||||
consumer = websocket_inbound(queue, user)
|
||||
|
|
|
@ -5,7 +5,6 @@ import hashlib
|
|||
import hmac
|
||||
import re
|
||||
import string
|
||||
import time
|
||||
from functools import wraps
|
||||
|
||||
from quart import current_app, request, abort, make_response, render_template, request
|
||||
|
@ -15,6 +14,7 @@ from anonstream.broadcast import broadcast
|
|||
from anonstream.user import see
|
||||
from anonstream.helpers.user import generate_user
|
||||
from anonstream.utils.user import generate_token, Presence
|
||||
from anonstream.wrappers import get_timestamp
|
||||
|
||||
CONFIG = current_app.config
|
||||
MESSAGES = current_app.messages
|
||||
|
@ -68,7 +68,7 @@ def with_user_from(context):
|
|||
def with_user_from_context(f):
|
||||
@wraps(f)
|
||||
async def wrapper(*args, **kwargs):
|
||||
timestamp = int(time.time())
|
||||
timestamp = get_timestamp()
|
||||
|
||||
# Check if broadcaster
|
||||
broadcaster = check_auth(context)
|
||||
|
|
|
@ -7,7 +7,7 @@ from math import inf
|
|||
|
||||
from quart import current_app
|
||||
|
||||
from anonstream.wrappers import try_except_log, with_timestamp
|
||||
from anonstream.wrappers import try_except_log, with_timestamp, get_timestamp
|
||||
from anonstream.helpers.user import get_default_name, get_presence, Presence
|
||||
from anonstream.helpers.captcha import check_captcha_digest, Answer
|
||||
from anonstream.helpers.tripcode import generate_tripcode
|
||||
|
@ -136,11 +136,18 @@ def delete_tripcode(user):
|
|||
def see(timestamp, user):
|
||||
user['last']['seen'] = timestamp
|
||||
|
||||
@with_timestamp()
|
||||
def watched(timestamp, user):
|
||||
def watching(user, timestamp=None):
|
||||
if timestamp is None:
|
||||
timestamp = get_timestamp()
|
||||
user['last']['seen'] = timestamp
|
||||
user['last']['watching'] = timestamp
|
||||
|
||||
def reading(user, timestamp=None):
|
||||
if timestamp is None:
|
||||
timestamp = get_timestamp()
|
||||
user['last']['seen'] = timestamp
|
||||
user['last']['reading'] = timestamp
|
||||
|
||||
@with_timestamp()
|
||||
def get_all_users_for_websocket(timestamp):
|
||||
return {
|
||||
|
|
|
@ -9,7 +9,7 @@ from quart import current_app, websocket
|
|||
from anonstream.stream import get_stream_title, get_stream_uptime_and_viewership
|
||||
from anonstream.captcha import get_random_captcha_digest_for
|
||||
from anonstream.chat import get_all_messages_for_websocket, add_chat_message, Rejected
|
||||
from anonstream.user import get_all_users_for_websocket, see, verify, deverify, BadCaptcha, try_change_appearance
|
||||
from anonstream.user import get_all_users_for_websocket, see, reading, verify, deverify, BadCaptcha, try_change_appearance
|
||||
from anonstream.wrappers import with_timestamp
|
||||
from anonstream.utils.chat import generate_nonce
|
||||
from anonstream.utils.websocket import parse_websocket_data, Malformed, WS
|
||||
|
@ -75,6 +75,7 @@ async def websocket_inbound(queue, user):
|
|||
@with_timestamp()
|
||||
def handle_inbound_pong(timestamp, queue, user):
|
||||
print(f'[pong] {user["token"]}')
|
||||
reading(user, timestamp=timestamp)
|
||||
user['websockets'][queue] = timestamp
|
||||
return None
|
||||
|
||||
|
|
|
@ -16,13 +16,18 @@ def with_function_call(fn, *fn_args, **fn_kwargs):
|
|||
def with_constant(x):
|
||||
return with_function_call(lambda: x)
|
||||
|
||||
def with_timestamp(monotonic=False, precise=False):
|
||||
def get_timestamp(monotonic=False, precise=False):
|
||||
n = 1_000_000_000
|
||||
if monotonic:
|
||||
fn = precise and time.monotonic or (lambda: time.monotonic_ns() // n)
|
||||
timestamp = precise and time.monotonic() or time.monotonic_ns() // n
|
||||
else:
|
||||
fn = precise and time.time or (lambda: time.time_ns() // n)
|
||||
return with_function_call(fn)
|
||||
timestamp = precise and time.time() or time.time_ns() // n
|
||||
return timestamp
|
||||
|
||||
def with_timestamp(monotonic=False, precise=False):
|
||||
def get_timestamp_specific():
|
||||
return get_timestamp(monotonic=monotonic, precise=precise)
|
||||
return with_function_call(get_timestamp_specific)
|
||||
|
||||
def try_except_log(errors, exception_class):
|
||||
def try_except_log_specific(f):
|
||||
|
|
読み込み中…
新しいイシューから参照