Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
B
bbbmon
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
bbb
bbbmon
Commits
7fe39038
Commit
7fe39038
authored
5 years ago
by
David Huss
Browse files
Options
Downloads
Patches
Plain Diff
Add a ton of CLI options, formatting fixes & fancy
parent
012ede87
Branches
Branches containing commit
Tags
v.0.1.9
Tags containing commit
No related merge requests found
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
README.md
+10
-1
10 additions, 1 deletion
README.md
bbbmon/bbbmon.py
+75
-35
75 additions, 35 deletions
bbbmon/bbbmon.py
bbbmon/configuration.py
+17
-0
17 additions, 0 deletions
bbbmon/configuration.py
pyproject.toml
+1
-1
1 addition, 1 deletion
pyproject.toml
with
103 additions
and
37 deletions
README.md
+
10
−
1
View file @
7fe39038
...
@@ -58,3 +58,12 @@ securitySalt=MY_SUPER_SECRET_SECRET2
...
@@ -58,3 +58,12 @@ securitySalt=MY_SUPER_SECRET_SECRET2
bigbluebutton.web.serverURL
=
https://bbb.foo.com/
bigbluebutton.web.serverURL
=
https://bbb.foo.com/
```
```
The section names in the square brackets will be used as display names (these support utf-8)
The section names in the square brackets will be used as display names (these support utf-8)
# Usage
For help run:
```
bash
bbbmon
--help
```
This diff is collapsed.
Click to expand it.
bbbmon/bbbmon.py
+
75
−
35
View file @
7fe39038
...
@@ -117,41 +117,67 @@ def format_duration(meeting: XmlDictConfig) -> str:
...
@@ -117,41 +117,67 @@ def format_duration(meeting: XmlDictConfig) -> str:
def
get_formated_presenter_name_id
(
meeting
:
XmlDictConfig
)
->
str
:
"""
Get the formated name of the presenter for a given meeting (with id)
"""
presenter
=
get_presenter
(
meeting
)
if
presenter
is
not
None
:
return
"
{:<30} ({})
"
.
format
(
presenter
[
"
fullName
"
],
presenter
[
"
userID
"
])
else
:
return
"
no Presenter
"
def
get_formated_presenter_name
(
meeting
:
XmlDictConfig
)
->
str
:
def
get_formated_presenter_name
(
meeting
:
XmlDictConfig
)
->
str
:
"""
"""
Get the formated name of the presenter for a given meeting
Get the formated name of the presenter for a given meeting
"""
"""
presenter
=
get_presenter
(
meeting
)
presenter
=
get_presenter
(
meeting
)
if
presenter
is
not
None
:
if
presenter
is
not
None
:
return
"
{:<30}
({})
"
.
format
(
presenter
[
"
fullName
"
]
,
presenter
[
"
userID
"
]
)
return
"
{:<30}
"
.
format
(
presenter
[
"
fullName
"
])
else
:
else
:
return
"
no Presenter
"
return
"
no Presenter
"
def
print_leaderboard
(
meetings
:
Iterable
[
XmlDictConfig
],
key
:
str
):
def
print_leaderboard
(
meetings
:
Iterable
[
XmlDictConfig
],
key
:
str
,
endpoint_name
:
str
,
presenter
:
bool
,
presenter_id
:
bool
,
fancy
:
bool
):
"""
"""
Print a leaderboard of all meetings sorted by a given key (e.g.
Print a leaderboard of all meetings sorted by a given key (e.g.
participantCount)
participantCount)
"""
"""
print
(
"
LEADERBOARD ({})
"
.
format
(
FRIENDLY_KEYNAMES
[
key
]))
print
_header
(
endpoint_name
,
"
LEADERBOARD ({})
"
.
format
(
FRIENDLY_KEYNAMES
[
key
])
,
fancy
)
sorted_by
=
sorted
([
m
for
m
in
meetings
],
key
=
lambda
x
:
int
(
x
[
key
]),
reverse
=
True
)
sorted_by
=
sorted
([
m
for
m
in
meetings
],
key
=
lambda
x
:
int
(
x
[
key
]),
reverse
=
True
)
for
m
in
sorted_by
:
for
m
in
sorted_by
:
if
presenter
:
if
presenter_id
:
print
(
"
{:>5} {:<45} {}
"
.
format
(
m
[
key
],
m
[
"
meetingName
"
],
get_formated_presenter_name_id
(
m
)))
else
:
print
(
"
{:>5} {:<45} {}
"
.
format
(
m
[
key
],
m
[
"
meetingName
"
],
get_formated_presenter_name
(
m
)))
print
(
"
{:>5} {:<45} {}
"
.
format
(
m
[
key
],
m
[
"
meetingName
"
],
get_formated_presenter_name
(
m
)))
else
:
print
(
"
{:>5} {}
"
.
format
(
m
[
key
],
m
[
"
meetingName
"
]))
def
print_duration_leaderboard
(
meetings
:
Iterable
[
XmlDictConfig
],
endpoint_name
:
str
,
presenter
:
bool
,
presenter_id
:
bool
,
fancy
:
bool
):
def
print_duration_leaderboard
(
meetings
:
Iterable
[
XmlDictConfig
]):
"""
"""
Print a leaderboard of all meetings sorted by a given key (e.g.
Print a leaderboard of all meetings sorted by a given key (e.g.
participantCount)
participantCount)
"""
"""
print
(
"
LEADERBOARD (Duration)
"
)
print
_header
(
endpoint_name
,
"
LEADERBOARD (Duration)
"
,
fancy
)
by_duration
=
sorted
([
m
for
m
in
meetings
],
key
=
lambda
x
:
int
(
get_duration
(
x
).
total_seconds
()),
reverse
=
True
)
by_duration
=
sorted
([
m
for
m
in
meetings
],
key
=
lambda
x
:
int
(
get_duration
(
x
).
total_seconds
()),
reverse
=
True
)
for
m
in
by_duration
:
for
m
in
by_duration
:
print
(
"
{:>12} {:<45} {}
"
.
format
(
format_duration
(
m
),
m
[
"
meetingName
"
],
get_formated_presenter_name
(
m
)))
if
presenter
:
if
presenter_id
:
print
(
"
{:>12} {:<38} {}
"
.
format
(
format_duration
(
m
),
m
[
"
meetingName
"
],
get_formated_presenter_name_id
(
m
)))
else
:
print
(
"
{:>12} {:<38} {}
"
.
format
(
format_duration
(
m
),
m
[
"
meetingName
"
],
get_formated_presenter_name
(
m
)))
else
:
print
(
"
{:>12} {}
"
.
format
(
format_duration
(
m
),
m
[
"
meetingName
"
]))
def
print_header
(
endpoint_name
:
str
,
text
:
str
,
fancy
=
True
):
if
fancy
:
click
.
echo
(
click
.
style
(
"
[{}] {}
"
.
format
(
endpoint_name
,
text
),
fg
=
'
black
'
,
bg
=
'
white
'
,
bold
=
True
))
else
:
print
(
"
[{}] {}
"
.
format
(
endpoint_name
,
text
))
def
print_overview
(
config
:
Config
):
def
print_overview
(
config
:
Config
,
leaderboards
:
bool
,
participants
:
bool
,
presenter
:
bool
,
presenter_id
:
bool
,
show_meetings
:
bool
,
fancy
:
bool
):
"""
"""
For each endpoint in the configuration get the active meetings and print
For each endpoint in the configuration get the active meetings and print
out an overview of the current bbb-usage
out an overview of the current bbb-usage
...
@@ -162,12 +188,14 @@ def print_overview(config: Config):
...
@@ -162,12 +188,14 @@ def print_overview(config: Config):
# Print divider if there is more than one endpoint
# Print divider if there is more than one endpoint
if
i
>
0
:
if
i
>
0
:
print
()
print
()
print
(
"
=
"
*
80
)
print
(
"
=
"
*
click
.
get_terminal_size
()[
0
]
)
print
()
print
()
# If there are no meetings, skip to next endpoint
# If there are no meetings, skip to next endpoint
if
len
(
meetings
)
==
0
:
if
len
(
meetings
)
==
0
:
print
(
"
MEETINGS on [{}]: None
"
.
format
(
endpoint
.
name
))
if
show_meetings
:
print_header
(
endpoint
.
name
,
"
MEETINGS
"
,
fancy
)
print
(
"
└─── Currently no active meetings.
"
)
continue
continue
n_running
=
len
(
meetings
)
n_running
=
len
(
meetings
)
...
@@ -178,25 +206,29 @@ def print_overview(config: Config):
...
@@ -178,25 +206,29 @@ def print_overview(config: Config):
n_video
=
sum
([
int
(
m
[
"
videoCount
"
])
for
m
in
meetings
])
n_video
=
sum
([
int
(
m
[
"
videoCount
"
])
for
m
in
meetings
])
n_moderator
=
sum
([
int
(
m
[
"
moderatorCount
"
])
for
m
in
meetings
])
n_moderator
=
sum
([
int
(
m
[
"
moderatorCount
"
])
for
m
in
meetings
])
print
(
"
MEETINGS on [{}]:
"
.
format
(
endpoint
.
name
))
if
show_meetings
:
print_header
(
endpoint
.
name
,
"
MEETINGS
"
,
fancy
)
print
(
"
├─── {:>4} running
"
.
format
(
n_running
))
print
(
"
├─── {:>4} running
"
.
format
(
n_running
))
print
(
"
└─── {:>4} recording
"
.
format
(
n_recording
))
print
(
"
└─── {:>4} recording
"
.
format
(
n_recording
))
print
()
print
()
print
(
"
PARTICIPANTS across all {} rooms
"
.
format
(
n_running
))
if
participants
:
print_header
(
endpoint
.
name
,
"
PARTICIPANTS across all {} rooms
"
.
format
(
n_running
),
fancy
)
print
(
"
└─┬─ {:>4} total
"
.
format
(
n_participants
))
print
(
"
└─┬─ {:>4} total
"
.
format
(
n_participants
))
print
(
"
├─ {:>4} listening only
"
.
format
(
n_listeners
))
print
(
"
├─ {:>4} listening only
"
.
format
(
n_listeners
))
print
(
"
├─ {:>4} mic on
"
.
format
(
n_voice
))
print
(
"
├─ {:>4} mic on
"
.
format
(
n_voice
))
print
(
"
├─ {:>4} video on
"
.
format
(
n_video
))
print
(
"
├─ {:>4} video on
"
.
format
(
n_video
))
print
(
"
└─ {:>4} moderators
"
.
format
(
n_moderator
))
print
(
"
└─ {:>4} moderators
"
.
format
(
n_moderator
))
if
leaderboards
:
print
()
print
()
print_leaderboard
(
meetings
,
"
participantCount
"
)
print_leaderboard
(
meetings
,
"
participantCount
"
,
endpoint
.
name
,
presenter
,
presenter_id
,
fancy
)
print
()
print
()
print_leaderboard
(
meetings
,
"
videoCount
"
)
print_leaderboard
(
meetings
,
"
videoCount
"
,
endpoint
.
name
,
presenter
,
presenter_id
,
fancy
)
print
()
print
()
print_leaderboard
(
meetings
,
"
voiceParticipantCount
"
)
print_leaderboard
(
meetings
,
"
voiceParticipantCount
"
,
endpoint
.
name
,
presenter
,
presenter_id
,
fancy
)
print
()
print
()
print_duration_leaderboard
(
meetings
)
print_duration_leaderboard
(
meetings
,
endpoint
.
name
,
presenter
,
presenter_id
,
fancy
)
def
init_config
()
->
Optional
[
Config
]:
def
init_config
()
->
Optional
[
Config
]:
...
@@ -227,10 +259,18 @@ def init_config() -> Optional[Config]:
...
@@ -227,10 +259,18 @@ def init_config() -> Optional[Config]:
exit
()
exit
()
@click.command
()
def
main
():
@click.option
(
'
--endpoint
'
,
'
-e
'
,
multiple
=
True
,
help
=
"
Filter by one or more endpoints as named in the user configuration. Order is respected.
"
)
Config
=
init_config
()
@click.option
(
'
--leaderboards/--no-leaderboards
'
,
default
=
True
,
show_default
=
True
,
help
=
"
Hide or show the meeting leaderboards
"
)
print_overview
(
Config
)
@click.option
(
'
--participants/--no-participants
'
,
default
=
True
,
show_default
=
True
,
help
=
"
Hide or show the participants
"
)
@click.option
(
'
--meetings/--no-meetings
'
,
default
=
True
,
show_default
=
True
,
help
=
"
Hide or show the meetings
"
)
@click.option
(
'
--presenter/--no-presenter
'
,
default
=
True
,
show_default
=
True
,
help
=
"
Hide or show the presenters
"
)
@click.option
(
'
--presenter-id/--no-presenter-id
'
,
default
=
True
,
show_default
=
True
,
help
=
"
Hide or show the presenter IDs
"
)
@click.option
(
'
--fancy/--no-fancy
'
,
default
=
True
,
show_default
=
True
,
help
=
"
Use fancy headers
"
)
def
main
(
leaderboards
,
participants
,
presenter
,
presenter_id
,
meetings
,
endpoint
,
fancy
):
config
=
init_config
()
config
.
filter_endpoints
(
endpoint
)
print_overview
(
config
,
leaderboards
,
participants
,
presenter
,
presenter_id
,
meetings
,
fancy
)
if
__name__
==
"
__main__
"
:
if
__name__
==
"
__main__
"
:
...
...
This diff is collapsed.
Click to expand it.
bbbmon/configuration.py
+
17
−
0
View file @
7fe39038
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
import
configparser
import
configparser
from
typing
import
NewType
,
Optional
,
Tuple
,
Iterable
,
List
from
typing
import
NewType
,
Optional
,
Tuple
,
Iterable
,
List
import
click
# Default path
# Default path
SERVER_PROPERTIES_FILE
=
"
/usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties
"
SERVER_PROPERTIES_FILE
=
"
/usr/share/bbb-web/WEB-INF/classes/bigbluebutton.properties
"
...
@@ -55,6 +56,22 @@ class Config():
...
@@ -55,6 +56,22 @@ class Config():
self
=
self
.
from_server
(
path
)
self
=
self
.
from_server
(
path
)
return
self
return
self
def
filter_endpoints
(
self
,
endpoint_options
:
List
[
str
])
->
'
Config
'
:
if
len
(
endpoint_options
)
==
0
:
return
self
else
:
existing_names
=
[
e
.
name
for
e
in
self
.
endpoints
]
filtered_endpoints
=
[]
for
endpoint_option
in
endpoint_options
:
if
not
endpoint_option
in
existing_names
:
click
.
echo
(
"
{} there is no endpoint called
\"
{}
\"
in the configuration. It will be ignored.
\n
"
.
format
(
click
.
style
(
'
Error:
'
,
fg
=
'
red
'
,
bold
=
True
),
click
.
style
(
endpoint_option
,
fg
=
'
red
'
,
bold
=
True
)))
else
:
filtered_endpoints
.
append
([
e
for
e
in
self
.
endpoints
if
e
.
name
==
endpoint_option
][
0
])
self
.
endpoints
=
filtered_endpoints
return
self
def
__len__
(
self
):
def
__len__
(
self
):
"""
"""
The length of a Config is represented by the number of endpoints
The length of a Config is represented by the number of endpoints
...
...
This diff is collapsed.
Click to expand it.
pyproject.toml
+
1
−
1
View file @
7fe39038
[tool.poetry]
[tool.poetry]
name
=
"bbbmon"
name
=
"bbbmon"
version
=
"0.1.
8
"
version
=
"0.1.
9
"
description
=
"A small CLI utility to monitor bbb usage"
description
=
"A small CLI utility to monitor bbb usage"
authors
=
[
"David Huss <david.huss@hfbk-hamburg.de>"
]
authors
=
[
"David Huss <david.huss@hfbk-hamburg.de>"
]
maintainers
=
[
"David Huss <david.huss@hfbk-hamburg.de>"
]
maintainers
=
[
"David Huss <david.huss@hfbk-hamburg.de>"
]
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment