Merge remote-tracking branch 'origin/member-summary'

This commit is contained in:
Tanner Collin 2020-11-15 00:55:04 +00:00
commit 429a6c0354
9 changed files with 122 additions and 23 deletions

View File

@ -14,6 +14,8 @@ class Command(BaseCommand):
players = utils_stats.check_minecraft_server()
self.stdout.write('Found Minecraft players: ' + str(players))
users = utils_stats.check_mumble_server()
self.stdout.write('Found Mumble users: ' + str(users))
self.stdout.write('Completed tasks in {} s'.format(
str(time.time() - start)[:4]

View File

@ -22,6 +22,7 @@ DEFAULTS = {
'bay_108_temp': None,
'bay_110_temp': None,
'minecraft_players': [],
'mumble_users': [],
'card_scans': 0,
'track': {},
}
@ -114,6 +115,21 @@ def check_minecraft_server():
return []
def check_mumble_server():
if secrets.MUMBLE:
url = secrets.MUMBLE
try:
r = requests.get(url, timeout=5)
r.raise_for_status()
users = r.text.split()
cache.set('mumble_users', users)
return users
except BaseException as e:
logger.error('Problem checking Mumble: {} - {}'.format(e.__class__.__name__, str(e)))
return []
def calc_card_scans():
date = today_alberta_tz()
cards = models.Card.objects

View File

@ -60,6 +60,7 @@ DOOR_API_TOKEN = ''
DOOR_CODE = ''
WIFI_PASS = ''
MINECRAFT = ''
MUMBLE = ''
# Portal Email Credentials
# For sending password resets, etc.

View File

@ -221,7 +221,15 @@ export function AdminMemberCards(props) {
/>
</Form.Group>
<Form.Button loading={loading} error={error.non_field_errors}>
<Form.Checkbox
label='Confirmed that the member has been given a tour and knows the alarm code'
required
{...makeProps('given_tour')}
onChange={handleCheck}
checked={input.given_tour}
/>
<Form.Button disabled={!input.given_tour} loading={loading} error={error.non_field_errors}>
Submit
</Form.Button>
{success && <div>Success!</div>}

View File

@ -2,6 +2,7 @@ import React, { useState, useEffect, useReducer, useContext } from 'react';
import { BrowserRouter as Router, Switch, Route, Link, useParams, useHistory } from 'react-router-dom';
import './semantic-ui/semantic.min.css';
import './light.css';
import './dark.css';
import { Container, Divider, Dropdown, Form, Grid, Header, Icon, Image, Menu, Message, Segment, Table } from 'semantic-ui-react';
import Darkmode from 'darkmode-js';
import { isAdmin, requester } from './utils.js';

View File

@ -47,6 +47,25 @@ export function Charts(props) {
<Container>
<Header size='large'>Charts</Header>
<Header size='medium'>Summary</Header>
{memberCount && signupCount &&
<>
<p>
The total member count is {memberCount.slice().reverse()[0].member_count} members,
compared to {memberCount.slice().reverse()[30].member_count} members 30 days ago.
</p>
<p>
The green member count is {memberCount.slice().reverse()[0].green_count} members,
compared to {memberCount.slice().reverse()[30].green_count} members 30 days ago.
</p>
<p>
There were {signupCount.slice().reverse()[0].signup_count} signups so far this month,
and {signupCount.slice().reverse()[1].signup_count} signups last month.
</p>
</>
}
<Header size='medium'>Member Counts</Header>
<p>Daily since March 2nd, 2020.</p>

View File

@ -152,6 +152,7 @@ export function Home(props) {
const getDateStat = (x) => stats && stats[x] ? moment.utc(stats[x]).tz('America/Edmonton').format('ll') : '?';
const mcPlayers = stats && stats['minecraft_players'] ? stats['minecraft_players'] : [];
const mumbleUsers = stats && stats['mumble_users'] ? stats['mumble_users'] : [];
const getTrackStat = (x) => stats && stats.track && stats.track[x] ? moment().unix() - stats.track[x]['time'] > 60 ? 'Free' : 'In Use' : '?';
const getTrackLast = (x) => stats && stats.track && stats.track[x] ? moment.unix(stats.track[x]['time']).tz('America/Edmonton').format('llll') : 'Unknown';
@ -214,11 +215,10 @@ export function Home(props) {
<p>Next monthly clean: {getDateStat('next_clean')}</p>
<p>Member count: {getStat('member_count')} <Link to='/charts'>[more]</Link></p>
<p>Green members: {getStat('green_count')}</p>
<p>Old members: {getStat('paused_count')}</p>
<p>Card scans today: {getZeroStat('card_scans')}</p>
<p>
Minecraft players: {mcPlayers.length} <Popup content={
Minecraft players: {mcPlayers.length} {mcPlayers.length > 5 && '🔥'} <Popup content={
<React.Fragment>
<p>
Server IP:<br />
@ -233,6 +233,21 @@ export function Home(props) {
{' '}<a href='http://games.protospace.ca:8123/?worldname=world&mapname=flat&zoom=3&x=74&y=64&z=354' target='_blank'>[map]</a>
</p>
<p>
Mumble users: {mumbleUsers.length} <Popup content={
<React.Fragment>
<p>
Server IP:<br />
mumble.protospace.ca
</p>
<p>
Users:<br />
{mumbleUsers.length ? mumbleUsers.map(x => <React.Fragment>{x}<br /></React.Fragment>) : 'None'}
</p>
</React.Fragment>
} trigger={<a>[more]</a>} />
</p>
<p>
Trotec availability: {getTrackStat('TROTECS300')} <Popup content={
<React.Fragment>

57
webclient/src/dark.css Normal file
View File

@ -0,0 +1,57 @@
.darkmode-layer, .darkmode-toggle {
z-index: 500;
}
.darkmode--activated .ui.image {
mix-blend-mode: difference;
filter: brightness(75%);
}
.darkmode--activated i.green.circle.icon {
mix-blend-mode: difference;
color: #21ba4582 !important;
}
.darkmode--activated i.yellow.circle.icon {
mix-blend-mode: difference;
color: #fbbd0882 !important;
}
.darkmode--activated i.red.circle.icon {
mix-blend-mode: difference;
color: #db282882 !important;
}
.darkmode--activated .footer {
mix-blend-mode: difference;
}
.darkmode--activated .ql-toolbar.ql-snow,
.darkmode--activated .ql-container.ql-snow,
.darkmode--activated .ui.segment,
.darkmode--activated .ui.form .field input,
.darkmode--activated .ui.form .field .selection.dropdown,
.darkmode--activated .ui.form .field .ui.checkbox label::before,
.darkmode--activated .ui.form .field textarea {
border: 1px solid rgba(34,36,38,.50) !important;
}
.darkmode--activated .ui.basic.table tbody tr {
border-bottom: 1px solid rgba(34,36,38,.50) !important;
}
.darkmode--activated .ui.button {
background: #c9c9c9 !important;
}
.darkmode--activated .ui.red.button {
mix-blend-mode: difference;
background: #db282882 !important;
}
.darkmode--activated .ui.green.button,
.darkmode--activated .ui.button.toggle.active {
mix-blend-mode: difference;
background: #21ba4582 !important;
}

View File

@ -150,23 +150,3 @@ body {
margin-left: -3.5px;
margin-right: 0.5em;
}
.darkmode-layer, .darkmode-toggle {
z-index: 500;
}
.darkmode--activated .ui.image {
mix-blend-mode: difference;
filter: brightness(50%);
}
.darkmode--activated i.green.circle.icon,
.darkmode--activated i.yellow.circle.icon,
.darkmode--activated i.red.circle.icon {
mix-blend-mode: difference;
}
.darkmode--activated .footer {
mix-blend-mode: difference;
}