Track the last time users were sent chat messages

このコミットが含まれているのは:
n9k 2022-06-19 08:10:23 +00:00
コミット 1d5b446291
8個のファイルの変更31行の追加15行の削除

ファイルの表示

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