WS: combine `uptime` and `viewership` into `stats`
If the stream is offline, `stats` is null, otherwise it contains uptime and viewership.
このコミットが含まれているのは:
コミット
7962de87e3
|
@ -2,7 +2,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 get_stream_title, get_stream_uptime, get_stream_viewership
|
||||
from anonstream.stream import get_stream_title, get_stream_uptime_and_viewership
|
||||
from anonstream.user import add_state, pop_state, try_change_appearance, get_users_by_presence, Presence, verify, deverify, BadCaptcha
|
||||
from anonstream.routes.wrappers import with_user_from, render_template_with_etag
|
||||
from anonstream.helpers.chat import get_scrollback
|
||||
|
@ -16,11 +16,12 @@ USERS_BY_TOKEN = current_app.users_by_token
|
|||
@current_app.route('/info.html')
|
||||
@with_user_from(request)
|
||||
async def nojs_info(user):
|
||||
uptime, viewership = get_stream_uptime_and_viewership()
|
||||
return await render_template(
|
||||
'nojs_info.html',
|
||||
user=user,
|
||||
viewership=get_stream_viewership(),
|
||||
uptime=get_stream_uptime(),
|
||||
viewership=viewership,
|
||||
uptime=uptime,
|
||||
title=await get_stream_title(),
|
||||
)
|
||||
|
||||
|
|
|
@ -159,6 +159,8 @@ const create_and_add_chat_message = (object) => {
|
|||
}
|
||||
|
||||
let users = {};
|
||||
let stats = null;
|
||||
let stats_received = null;
|
||||
let default_name = {true: "Broadcaster", false: "Anonymous"};
|
||||
let max_chat_scrollback = 256;
|
||||
const tidy_stylesheet = ({stylesheet, selector_regex, ignore_condition}) => {
|
||||
|
@ -370,20 +372,14 @@ const set_title = (title) => {
|
|||
info_title.innerHTML = element.outerHTML;
|
||||
}
|
||||
|
||||
let frozen_uptime = null;
|
||||
let frozen_uptime_received = null;
|
||||
const set_frozen_uptime = (x) => {
|
||||
frozen_uptime = x;
|
||||
frozen_uptime_received = new Date();
|
||||
}
|
||||
const update_uptime = () => {
|
||||
if (frozen_uptime_received === null) {
|
||||
if (stats_received === null) {
|
||||
return;
|
||||
} else if (frozen_uptime === null) {
|
||||
} else if (stats === null) {
|
||||
info_uptime.innerText = "";
|
||||
} else {
|
||||
const frozen_uptime_received_ago = (new Date() - frozen_uptime_received) / 1000;
|
||||
const uptime = Math.round(frozen_uptime + frozen_uptime_received_ago);
|
||||
const stats_received_ago = (new Date() - stats_received) / 1000;
|
||||
const uptime = Math.round(stats.uptime + stats_received_ago);
|
||||
|
||||
const s = Math.round(uptime % 60);
|
||||
const m = Math.floor(uptime / 60) % 60
|
||||
|
@ -400,8 +396,18 @@ const update_uptime = () => {
|
|||
}
|
||||
setInterval(update_uptime, 1000); // always update uptime
|
||||
|
||||
const set_viewership = (n) => {
|
||||
info_viewership.innerText = n === null ? "" : `${n} viewers`;
|
||||
const update_viewership = () => {
|
||||
info_viewership.innerText = stats === null ? "" : `${stats.viewership} viewers`;
|
||||
}
|
||||
|
||||
const update_stats = () => {
|
||||
if (stats === null) {
|
||||
update_viewership();
|
||||
update_uptime();
|
||||
} else {
|
||||
update_uptime();
|
||||
update_viewership();
|
||||
}
|
||||
}
|
||||
|
||||
const update_users_list = () => {
|
||||
|
@ -474,12 +480,10 @@ const on_websocket_message = (event) => {
|
|||
// set title
|
||||
set_title(receipt.title);
|
||||
|
||||
// set viewership
|
||||
set_viewership(receipt.viewership);
|
||||
|
||||
// set uptime
|
||||
set_frozen_uptime(receipt.uptime);
|
||||
update_uptime();
|
||||
// update stats (uptime/viewership)
|
||||
stats = receipt.stats;
|
||||
stats_received = new Date();
|
||||
update_stats();
|
||||
|
||||
// chat form nonce
|
||||
chat_form_nonce.value = receipt.nonce;
|
||||
|
@ -530,14 +534,10 @@ const on_websocket_message = (event) => {
|
|||
if (receipt.title !== undefined) {
|
||||
set_title(receipt.title);
|
||||
}
|
||||
if (receipt.uptime !== undefined) {
|
||||
set_frozen_uptime(receipt.uptime);
|
||||
update_uptime();
|
||||
}
|
||||
if (receipt.viewership === 0 && frozen_uptime === null) {
|
||||
set_viewership(null);
|
||||
} else if (receipt.viewership !== undefined) {
|
||||
set_viewership(receipt.viewership);
|
||||
if (receipt.stats !== undefined) {
|
||||
stats = receipt.stats;
|
||||
stats_received = new Date();
|
||||
update_stats();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -37,16 +37,26 @@ def get_stream_uptime(rounded=True):
|
|||
return uptime
|
||||
|
||||
@with_timestamp
|
||||
def get_stream_viewership(timestamp):
|
||||
def get_raw_viewership(timestamp):
|
||||
users = get_watching_users(timestamp)
|
||||
return max(
|
||||
map(operator.itemgetter(0), zip(itertools.count(1), users)),
|
||||
default=0,
|
||||
)
|
||||
|
||||
def get_stream_viewership_or_none(uptime):
|
||||
viewership = get_stream_viewership()
|
||||
return uptime and viewership
|
||||
def get_stream_uptime_and_viewership(for_websocket=False):
|
||||
uptime = get_stream_uptime()
|
||||
if not for_websocket:
|
||||
viewership = None if uptime is None else get_raw_viewership()
|
||||
result = (uptime, viewership)
|
||||
elif uptime is None:
|
||||
result = None
|
||||
else:
|
||||
result = {
|
||||
'uptime': uptime,
|
||||
'viewership': get_raw_viewership(),
|
||||
}
|
||||
return result
|
||||
|
||||
def is_online():
|
||||
try:
|
||||
|
|
|
@ -5,7 +5,7 @@ from functools import wraps
|
|||
from quart import current_app
|
||||
|
||||
from anonstream.broadcast import broadcast, broadcast_users_update
|
||||
from anonstream.stream import is_online, get_stream_title, get_stream_uptime, get_stream_viewership_or_none
|
||||
from anonstream.stream import is_online, get_stream_title, get_stream_uptime_and_viewership
|
||||
from anonstream.user import get_sunsettable_users
|
||||
from anonstream.wrappers import with_timestamp
|
||||
|
||||
|
@ -94,21 +94,22 @@ async def t_broadcast_users_update(iteration):
|
|||
async def t_broadcast_stream_info_update(iteration):
|
||||
if iteration == 0:
|
||||
title = await get_stream_title()
|
||||
uptime = get_stream_uptime()
|
||||
viewership = get_stream_viewership_or_none(uptime)
|
||||
uptime, viewership = get_stream_uptime_and_viewership()
|
||||
current_app.stream_title = title
|
||||
current_app.stream_uptime = uptime
|
||||
current_app.stream_viewership = viewership
|
||||
else:
|
||||
payload = {}
|
||||
|
||||
# Check if the stream title has changed
|
||||
title = await get_stream_title()
|
||||
uptime, viewership = get_stream_uptime_and_viewership()
|
||||
|
||||
# Check if the stream title has changed
|
||||
if current_app.stream_title != title:
|
||||
current_app.stream_title = title
|
||||
payload['title'] = title
|
||||
|
||||
# Check if the stream uptime has changed more or less than expected
|
||||
# Check if the stream uptime has changed unexpectedly
|
||||
if current_app.stream_uptime is None:
|
||||
expected_uptime = None
|
||||
else:
|
||||
|
@ -116,20 +117,27 @@ async def t_broadcast_stream_info_update(iteration):
|
|||
current_app.stream_uptime
|
||||
+ CONFIG['TASK_PERIOD_BROADCAST_STREAM_INFO_UPDATE']
|
||||
)
|
||||
uptime = get_stream_uptime()
|
||||
current_app.stream_uptime = uptime
|
||||
if uptime is None and expected_uptime is None:
|
||||
pass
|
||||
stats_changed = False
|
||||
elif uptime is None or expected_uptime is None:
|
||||
payload['uptime'] = uptime
|
||||
elif abs(uptime - expected_uptime) >= 0.0625:
|
||||
payload['uptime'] = uptime
|
||||
stats_changed = True
|
||||
else:
|
||||
stats_changed = abs(uptime - expected_uptime) >= 0.0625
|
||||
|
||||
# Check if viewership has changed
|
||||
viewership = get_stream_viewership_or_none(uptime)
|
||||
if current_app.stream_viewership != viewership:
|
||||
current_app.stream_viewership = viewership
|
||||
payload['viewership'] = viewership
|
||||
stats_changed = True
|
||||
|
||||
if stats_changed:
|
||||
if uptime is None:
|
||||
payload['stats'] = None
|
||||
else:
|
||||
payload['stats'] = {
|
||||
'uptime': uptime,
|
||||
'viewership': viewership,
|
||||
}
|
||||
|
||||
if payload:
|
||||
broadcast(USERS, payload={'type': 'info', **payload})
|
||||
|
|
|
@ -3,7 +3,7 @@ import json
|
|||
|
||||
from quart import current_app, websocket
|
||||
|
||||
from anonstream.stream import get_stream_title, get_stream_uptime, get_stream_viewership_or_none
|
||||
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
|
||||
|
@ -13,14 +13,11 @@ from anonstream.utils.websocket import parse_websocket_data, Malformed
|
|||
CONFIG = current_app.config
|
||||
|
||||
async def websocket_outbound(queue, user):
|
||||
uptime = get_stream_uptime()
|
||||
viewership = get_stream_viewership_or_none(uptime)
|
||||
payload = {
|
||||
'type': 'init',
|
||||
'nonce': generate_nonce(),
|
||||
'title': await get_stream_title(),
|
||||
'uptime': uptime,
|
||||
'viewership': viewership,
|
||||
'stats': get_stream_uptime_and_viewership(for_websocket=True),
|
||||
'messages': get_all_messages_for_websocket(),
|
||||
'users': get_all_users_for_websocket(),
|
||||
'default': {
|
||||
|
|
読み込み中…
新しいイシューから参照