2022-06-16 10:12:37 +09:00
|
|
|
# SPDX-FileCopyrightText: 2022 n9k <https://git.076.ne.jp/ninya9k>
|
2022-03-07 23:51:59 +09:00
|
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
|
2022-02-17 09:20:51 +09:00
|
|
|
import hashlib
|
|
|
|
import base64
|
2022-05-28 14:37:41 +09:00
|
|
|
from collections import deque, OrderedDict
|
2022-02-17 09:20:51 +09:00
|
|
|
from math import inf
|
|
|
|
|
|
|
|
from quart import current_app
|
|
|
|
|
2022-02-17 21:51:09 +09:00
|
|
|
from anonstream.utils.colour import generate_colour, colour_to_color
|
2022-02-27 10:01:32 +09:00
|
|
|
from anonstream.utils.user import Presence
|
2022-02-17 21:51:09 +09:00
|
|
|
|
2022-02-17 09:20:51 +09:00
|
|
|
CONFIG = current_app.config
|
|
|
|
|
2022-02-22 18:30:23 +09:00
|
|
|
def generate_token_hash_and_tag(token):
|
2022-02-17 09:20:51 +09:00
|
|
|
parts = CONFIG['SECRET_KEY'] + b'token-hash\0' + token.encode()
|
|
|
|
digest = hashlib.sha256(parts).digest()
|
2022-02-22 18:30:23 +09:00
|
|
|
|
|
|
|
token_hash = base64.b32encode(digest)[:26].lower().decode()
|
|
|
|
tag = f'#{digest.hex()[:3]}'
|
|
|
|
|
|
|
|
return token_hash, tag
|
2022-02-17 09:20:51 +09:00
|
|
|
|
2022-02-27 10:01:32 +09:00
|
|
|
def generate_user(timestamp, token, broadcaster, presence):
|
2022-02-17 21:51:09 +09:00
|
|
|
colour = generate_colour(
|
|
|
|
seed='name\0' + token,
|
|
|
|
bg=CONFIG['CHAT_BACKGROUND_COLOUR'],
|
2022-06-14 14:58:57 +09:00
|
|
|
min_contrast=4.53,
|
2022-02-17 21:51:09 +09:00
|
|
|
)
|
2022-02-22 18:30:23 +09:00
|
|
|
token_hash, tag = generate_token_hash_and_tag(token)
|
2022-02-17 09:20:51 +09:00
|
|
|
return {
|
|
|
|
'token': token,
|
2022-02-22 18:30:23 +09:00
|
|
|
'token_hash': token_hash,
|
|
|
|
'tag': tag,
|
2022-02-17 09:20:51 +09:00
|
|
|
'broadcaster': broadcaster,
|
2022-02-20 13:23:32 +09:00
|
|
|
'verified': broadcaster,
|
2022-04-02 13:46:24 +09:00
|
|
|
'websockets': {},
|
2022-02-17 09:20:51 +09:00
|
|
|
'name': None,
|
2022-02-17 21:51:09 +09:00
|
|
|
'color': colour_to_color(colour),
|
2022-02-17 09:20:51 +09:00
|
|
|
'tripcode': None,
|
2022-02-20 13:23:32 +09:00
|
|
|
'state': OrderedDict(),
|
2022-02-19 09:35:42 +09:00
|
|
|
'last': {
|
|
|
|
'seen': timestamp,
|
|
|
|
'watching': -inf,
|
2022-06-14 12:33:09 +09:00
|
|
|
'eyes': -inf,
|
2022-02-17 09:20:51 +09:00
|
|
|
},
|
2022-02-27 10:01:32 +09:00
|
|
|
'presence': presence,
|
2022-05-28 14:37:41 +09:00
|
|
|
'linespan': deque(),
|
2022-06-14 09:36:36 +09:00
|
|
|
'eyes': {
|
|
|
|
'total': 0,
|
|
|
|
'current': {},
|
|
|
|
},
|
2022-02-17 09:20:51 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
def get_default_name(user):
|
|
|
|
return (
|
|
|
|
CONFIG['DEFAULT_HOST_NAME']
|
|
|
|
if user['broadcaster'] else
|
|
|
|
CONFIG['DEFAULT_ANON_NAME']
|
|
|
|
)
|
|
|
|
|
2022-02-19 09:35:42 +09:00
|
|
|
def get_presence(timestamp, user):
|
|
|
|
last_watching_ago = timestamp - user['last']['watching']
|
2022-06-17 08:43:28 +09:00
|
|
|
if last_watching_ago < CONFIG['PRESENCE_NOTWATCHING']:
|
2022-02-19 09:35:42 +09:00
|
|
|
return Presence.WATCHING
|
|
|
|
|
|
|
|
last_seen_ago = timestamp - user['last']['seen']
|
2022-06-17 08:43:28 +09:00
|
|
|
if last_seen_ago < CONFIG['PRESENCE_TENTATIVE']:
|
2022-02-19 09:35:42 +09:00
|
|
|
return Presence.NOTWATCHING
|
|
|
|
if user['websockets']:
|
|
|
|
return Presence.NOTWATCHING
|
2022-02-17 09:20:51 +09:00
|
|
|
|
2022-06-17 08:43:28 +09:00
|
|
|
if last_seen_ago < CONFIG['PRESENCE_ABSENT']:
|
2022-02-19 09:35:42 +09:00
|
|
|
return Presence.TENTATIVE
|
2022-02-17 09:20:51 +09:00
|
|
|
|
2022-02-19 09:35:42 +09:00
|
|
|
return Presence.ABSENT
|