Merge branch 'dev'
このコミットが含まれているのは:
コミット
b09c396d1c
|
@ -1,3 +1,6 @@
|
|||
# SPDX-FileCopyrightText: 2022 n9k <https://git.076.ne.jp/ninya9k>
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import argparse
|
||||
import os
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# SPDX-FileCopyrightText: 2022 n9k <https://git.076.ne.jp/ninya9k>
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import time
|
||||
|
||||
from quart import current_app
|
||||
|
|
|
@ -46,7 +46,7 @@ async def cmd_user_help():
|
|||
' user [show]...................show all users\' tokens\n'
|
||||
' user attr USER................show names of a user\'s attributes\n'
|
||||
' user get USER ATTR............show an attribute of a user\n'
|
||||
' user set USER ATTR............set an attribute of a user\n'
|
||||
' user set USER ATTR VALUE......set an attribute of a user\n'
|
||||
' user eyes USER [show].........show a user\'s active video responses\n'
|
||||
' user eyes USER delete EYES_ID.end a video response to a user\n'
|
||||
'Definitions:\n'
|
||||
|
@ -54,6 +54,7 @@ async def cmd_user_help():
|
|||
' TOKEN.........................a token, json string\n'
|
||||
' HASH..........................a token hash\n'
|
||||
' ATTR..........................a user attribute, re:[a-z0-9_]+\n'
|
||||
' VALUE.........................json value\n'
|
||||
' EYES_ID.......................a user\'s eyes_id, base 10 integer\n'
|
||||
)
|
||||
return normal, response
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import asyncio
|
||||
from quart import current_app, websocket
|
||||
|
||||
from anonstream.user import see, reading
|
||||
from anonstream.user import see
|
||||
from anonstream.websocket import websocket_outbound, websocket_inbound
|
||||
from anonstream.routes.wrappers import with_user_from
|
||||
|
||||
|
@ -18,7 +18,7 @@ async def live(timestamp, user_or_token):
|
|||
case dict() as user:
|
||||
queue = asyncio.Queue()
|
||||
user['websockets'][queue] = timestamp
|
||||
reading(user, timestamp=timestamp)
|
||||
user['last']['reading'] = timestamp
|
||||
|
||||
producer = websocket_outbound(queue, user)
|
||||
consumer = websocket_inbound(queue, user)
|
||||
|
|
|
@ -13,7 +13,6 @@ from werkzeug.exceptions import BadRequest, Unauthorized, Forbidden
|
|||
from werkzeug.security import check_password_hash
|
||||
|
||||
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
|
||||
|
@ -121,7 +120,9 @@ def with_user_from(context, fallback_to_token=False):
|
|||
raise Unauthorized(Markup(
|
||||
f"You are using the broadcaster's token but you are "
|
||||
f"not logged in. The broadcaster should "
|
||||
f"<a href=\"{url_for('login')}\">click here</a> "
|
||||
f"<a href=\"{url_for('login')}\" target=\"_top\">"
|
||||
f"click here"
|
||||
f"</a> "
|
||||
f"and log in with the credentials printed in their "
|
||||
f"terminal when they started anonstream."
|
||||
))
|
||||
|
@ -138,12 +139,14 @@ def with_user_from(context, fallback_to_token=False):
|
|||
else:
|
||||
raise Forbidden(Markup(
|
||||
f"You have not solved the access captcha. "
|
||||
f"<a href=\"{url_for('home', token=token)}\">"
|
||||
f"<a href=\"{url_for('home', token=token)}\" target=\"_top\">"
|
||||
f"Click here."
|
||||
f"</a>"
|
||||
))
|
||||
else:
|
||||
if user is None:
|
||||
if user is not None:
|
||||
user['last']['seen'] = timestamp
|
||||
else:
|
||||
user = generate_and_add_user(timestamp, token, broadcaster)
|
||||
response = await f(timestamp, user, *args, **kwargs)
|
||||
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
<title>{{ error.code }} {{ error.name }}</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #18181a;
|
||||
background-color: #232327;
|
||||
color: #ddd;
|
||||
font-family: sans-serif;
|
||||
font-size: 14pt;
|
||||
margin: 24pt 16pt;
|
||||
margin: 4pt 6pt;
|
||||
text-align: center;
|
||||
text-shadow: 2px 0px 1px orangered;
|
||||
}
|
||||
|
@ -19,6 +19,10 @@
|
|||
}
|
||||
h1 {
|
||||
font-size: 32pt;
|
||||
margin: 0 0 8pt;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
a {
|
||||
color: #42a5d7;
|
||||
|
@ -29,11 +33,32 @@
|
|||
border-radius: 2px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
@media (min-height: 128px) {
|
||||
body {
|
||||
margin: 18pt 16pt;
|
||||
}
|
||||
h1 {
|
||||
margin: revert;
|
||||
}
|
||||
p {
|
||||
margin: revert;
|
||||
}
|
||||
}
|
||||
@media (min-height: 192px) {
|
||||
body {
|
||||
margin: 24pt 16pt;
|
||||
}
|
||||
}
|
||||
@media (min-width: 400px) and (min-height: 128px;) {
|
||||
body {
|
||||
background-color: #18181a;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>{{ error.code }} {{ error.name }}</h1>
|
||||
<h1>{{ error.name }}</h1>
|
||||
{% if error.description != error.__class__.description %}
|
||||
<p>{{ error.description }}</p>
|
||||
{% endif %}
|
||||
|
|
|
@ -132,8 +132,9 @@ def change_tripcode(user, password, dry_run=False):
|
|||
def delete_tripcode(user):
|
||||
user['tripcode'] = None
|
||||
|
||||
@with_timestamp()
|
||||
def see(timestamp, user):
|
||||
def see(user, timestamp=None):
|
||||
if timestamp is None:
|
||||
timestamp = get_timestamp()
|
||||
user['last']['seen'] = timestamp
|
||||
|
||||
def watching(user, timestamp=None):
|
||||
|
@ -284,8 +285,8 @@ def create_eyes(timestamp, user, headers):
|
|||
def renew_eyes(timestamp, user, eyes_id, just_read_new_segment=False):
|
||||
try:
|
||||
eyes = user['eyes']['current'][eyes_id]
|
||||
except KeyError:
|
||||
raise DeletedEyes
|
||||
except KeyError as e:
|
||||
raise DeletedEyes from e
|
||||
|
||||
# Enforce expire_after (if the background task hasn't already)
|
||||
renewed_ago = timestamp - eyes['renewed']
|
||||
|
|
|
@ -10,7 +10,7 @@ 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, reading, verify, deverify, BadCaptcha, try_change_appearance
|
||||
from anonstream.wrappers import with_timestamp
|
||||
from anonstream.wrappers import with_timestamp, get_timestamp
|
||||
from anonstream.utils.chat import generate_nonce
|
||||
from anonstream.utils.user import identifying_string
|
||||
from anonstream.utils.websocket import parse_websocket_data, Malformed, WS
|
||||
|
@ -49,7 +49,8 @@ async def websocket_inbound(queue, user):
|
|||
except json.JSONDecodeError:
|
||||
receipt = None
|
||||
finally:
|
||||
see(user)
|
||||
timestamp = get_timestamp()
|
||||
see(user, timestamp=timestamp)
|
||||
try:
|
||||
receipt_type, parsed = parse_websocket_data(receipt)
|
||||
except Malformed as e:
|
||||
|
@ -68,25 +69,24 @@ async def websocket_inbound(queue, user):
|
|||
handle = handle_inbound_captcha
|
||||
case WS.PONG:
|
||||
handle = handle_inbound_pong
|
||||
payload = handle(queue, user, *parsed)
|
||||
payload = handle(timestamp, queue, user, *parsed)
|
||||
|
||||
if payload is not None:
|
||||
queue.put_nowait(payload)
|
||||
|
||||
@with_timestamp()
|
||||
def handle_inbound_pong(timestamp, queue, user):
|
||||
print(f'[pong] {identifying_string(user)}')
|
||||
reading(user, timestamp=timestamp)
|
||||
user['last']['reading'] = timestamp
|
||||
user['websockets'][queue] = timestamp
|
||||
return None
|
||||
|
||||
def handle_inbound_captcha(queue, user):
|
||||
def handle_inbound_captcha(timestamp, queue, user):
|
||||
return {
|
||||
'type': 'captcha',
|
||||
'digest': get_random_captcha_digest_for(user),
|
||||
}
|
||||
|
||||
def handle_inbound_appearance(queue, user, name, color, password, want_tripcode):
|
||||
def handle_inbound_appearance(timestamp, queue, user, name, color, password, want_tripcode):
|
||||
errors = try_change_appearance(user, name, color, password, want_tripcode)
|
||||
if errors:
|
||||
return {
|
||||
|
@ -102,7 +102,7 @@ def handle_inbound_appearance(queue, user, name, color, password, want_tripcode)
|
|||
#'tripcode': user['tripcode'],
|
||||
}
|
||||
|
||||
def handle_inbound_message(queue, user, nonce, comment, digest, answer):
|
||||
def handle_inbound_message(timestamp, queue, user, nonce, comment, digest, answer):
|
||||
try:
|
||||
verification_happened = verify(user, digest, answer)
|
||||
except BadCaptcha as e:
|
||||
|
|
読み込み中…
新しいイシューから参照