mirror of
https://codeberg.org/langfingaz/bbb-status
synced 2024-12-22 00:26:06 +01:00
add main.py; Dockerfile: build dependencies; TZ
This commit is contained in:
parent
32d8158921
commit
5afe6af136
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
/secret/*.txt
|
||||
/data/*.xml
|
||||
src/__pycache__/
|
||||
/src/__pycache__/
|
||||
/plot/*.png
|
||||
|
3
.idea/bbb-status.iml
generated
3
.idea/bbb-status.iml
generated
@ -7,4 +7,7 @@
|
||||
<orderEntry type="jdk" jdkName="Python 3.8 (xfconf-backup)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="PackageRequirementsSettings">
|
||||
<option name="versionSpecifier" value="Greater or equal (>=x.y.z)" />
|
||||
</component>
|
||||
</module>
|
36
Dockerfile
36
Dockerfile
@ -2,11 +2,39 @@ FROM python:3.8-alpine
|
||||
|
||||
WORKDIR /usr/src/
|
||||
|
||||
COPY requirements.txt ./
|
||||
RUN pip3 install --no-cache-dir -r requirements.txt
|
||||
RUN apk update && \
|
||||
apk add \
|
||||
tzdata \
|
||||
make automake gcc g++ subversion python3-dev \
|
||||
zlib-dev jpeg-dev freetype-dev lcms2-dev libwebp-dev tcl-dev tk-dev harfbuzz-dev \
|
||||
fribidi-dev libimagequant-dev libxcb-dev && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
# source: https://serverfault.com/a/683651/537998
|
||||
ENV TZ=Europe/Berlin
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
#COPY requirements.txt ./
|
||||
#RUN pip3 install --no-cache-dir -r requirements.txt
|
||||
|
||||
# LDFLAGS required for "pip install pillow"
|
||||
# otherwise this would be necessary:
|
||||
## RUN ln -s /usr/lib/x86_64-linux-gnu/libz.so /lib/
|
||||
## RUN ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /lib/
|
||||
# source: https://github.com/python-pillow/Pillow/issues/3103#issuecomment-382634946
|
||||
ENV LDFLAGS=-L/usr/lib/x86_64-linux-gnu/
|
||||
|
||||
RUN python3 -m pip install --no-cache-dir --upgrade pip
|
||||
RUN python3 -m pip install --no-cache-dir --upgrade requests
|
||||
RUN python3 -m pip install --no-cache-dir --upgrade setuptools
|
||||
RUN python3 -m pip install --no-cache-dir --upgrade numpy
|
||||
RUN python3 -m pip install --no-cache-dir --upgrade pillow
|
||||
RUN python3 -m pip install --no-cache-dir --upgrade matplotlib
|
||||
|
||||
COPY ./src/ ./
|
||||
RUN chmod +x ./langfingaz/logMeetingData.py
|
||||
RUN chmod +x ./langfingaz/main.py
|
||||
|
||||
# unbuffered output option otherwise script sleeps before any output appears
|
||||
CMD [ "python", "-u", "./langfingaz/logMeetingData.py" ]
|
||||
# python -u
|
||||
ENTRYPOINT [ "python", "-u", "./langfingaz/main.py" ]
|
||||
CMD [ "log-verbose" ]
|
||||
|
@ -2,9 +2,11 @@ version: '3.7'
|
||||
services:
|
||||
dk-gen:
|
||||
build: .
|
||||
command: ["log"] # see main.py for available commandline arguments
|
||||
environment:
|
||||
# pythonpath is required to import from self created modules (langfingaz)
|
||||
- PYTHONPATH=/usr/src/
|
||||
- PYTHONPATH=/usr/src/ # pythonpath is required to import from self created modules ("from langfingaz ...")
|
||||
- PYTHONUNBUFFERED=1
|
||||
volumes:
|
||||
- ./secret:/usr/secret
|
||||
- ./data:/usr/data
|
||||
- ./plot:/usr/plot
|
||||
|
@ -1 +1,2 @@
|
||||
requests>=2.25.0
|
||||
requests>=2.25.0
|
||||
matplotlib>=3.3.3
|
@ -1,5 +1,6 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
@ -13,6 +14,8 @@ def sleepFiveMin(verbose=False):
|
||||
|
||||
if verbose:
|
||||
print(">> Sleeping for five minutes <<")
|
||||
|
||||
sys.stdout.flush()
|
||||
time.sleep(fiveMinutes)
|
||||
|
||||
|
||||
@ -27,7 +30,7 @@ def v2(folder: Path = saveData.getDefaultFolder()):
|
||||
meetings = parseMeetings.parseMeetingsData(meetingsStr)
|
||||
bbbStatus = parseMeetings.BbbStatus(meetings)
|
||||
bbbStatusStr = str(bbbStatus)
|
||||
print(util.indentMultilineStr(bbbStatusStr))
|
||||
print(util.indentMultilineStr(bbbStatusStr), flush=True)
|
||||
|
||||
sleepFiveMin(verbose=True)
|
||||
|
||||
@ -35,7 +38,7 @@ def v2(folder: Path = saveData.getDefaultFolder()):
|
||||
def v1(folder: Path = saveData.getDefaultFolder()):
|
||||
while True:
|
||||
saveData.requestAndSaveMeetingData(folder)
|
||||
print('.', end='')
|
||||
print('.', end='', flush=True)
|
||||
sleepFiveMin()
|
||||
|
||||
|
||||
|
34
src/langfingaz/main.py
Executable file
34
src/langfingaz/main.py
Executable file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/python3
|
||||
from sys import argv
|
||||
|
||||
from langfingaz import plotMeetings
|
||||
from langfingaz import logMeetingData
|
||||
|
||||
|
||||
def main():
|
||||
print("=== bbb-status ===")
|
||||
print(">> given args: " + str(argv))
|
||||
print()
|
||||
|
||||
usageStr = 'Usage:\n' + argv[0] + ' [log|log-verbose|plot]\n' + \
|
||||
'\tlog: log BBB meeting data every 5 minutes;\n' + \
|
||||
'\t prints one dot after each successfully saved file\n' + \
|
||||
'\tlog-verbose: log BBB meeting every 5 minute and write current status to stdout\n' + \
|
||||
'\tplot: saves a plot of the saved BBB meeting data\n'
|
||||
|
||||
if len(argv) != 2:
|
||||
raise ValueError("Expected one commandline argument!")
|
||||
|
||||
if argv[1] == "log":
|
||||
logMeetingData.v1()
|
||||
elif argv[1] == "log-verbose":
|
||||
logMeetingData.v2()
|
||||
elif argv[1] == "plot":
|
||||
plotMeetings.plotMeetings()
|
||||
else:
|
||||
print(usageStr)
|
||||
exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,5 +1,6 @@
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
import numpy
|
||||
import matplotlib.pyplot as plt # TODO
|
||||
from datetime import datetime
|
||||
|
||||
@ -9,23 +10,28 @@ from langfingaz.parseMeetings import BbbStatus, Meeting
|
||||
from langfingaz.util import fileUtil
|
||||
|
||||
|
||||
def plotMeetings(folder: Path):
|
||||
def getDefaultPlotFolder() -> Path:
|
||||
return fileUtil.getProjectBaseDir().joinpath("plot")
|
||||
|
||||
|
||||
def plotMeetings(dataDir: Path = fileUtil.getProjectBaseDir().joinpath("data")):
|
||||
bbbStati: List[BbbStatus] = []
|
||||
|
||||
for file in folder.iterdir():
|
||||
for file in dataDir.iterdir():
|
||||
if file.name.endswith(".xml"):
|
||||
dataStr, t = loadData.loadData(file)
|
||||
meetings: List[Meeting] = parseMeetings.parseMeetingsData(dataStr)
|
||||
bbbStati.append(parseMeetings.BbbStatus(meetings, t))
|
||||
|
||||
doPlotMeetings(bbbStati)
|
||||
image: Path = doPlotMeetings(bbbStati)
|
||||
print("saved image at " + str(image))
|
||||
|
||||
|
||||
def doPlotMeetings(bbbStati: List[BbbStatus]):
|
||||
time = [] # x-axis: time
|
||||
participants = [] # yAxis (1)
|
||||
videos = [] # yAxis (2)
|
||||
voices = [] # yAxis (3)
|
||||
def doPlotMeetings(bbbStati: List[BbbStatus]) -> Path:
|
||||
time = [] # x-axis: time
|
||||
participants = [] # yAxis (1)
|
||||
videos = [] # yAxis (2)
|
||||
voices = [] # yAxis (3)
|
||||
|
||||
for bbbStatus in bbbStati:
|
||||
time.append(bbbStatus.pointOfTime)
|
||||
@ -33,7 +39,6 @@ def doPlotMeetings(bbbStati: List[BbbStatus]):
|
||||
videos.append(bbbStatus.videoCount)
|
||||
voices.append(bbbStatus.voiceParticipantCount)
|
||||
|
||||
|
||||
# Note that even in the OO-style, we use `.pyplot.figure` to create the figure.
|
||||
fig, ax = plt.subplots() # Create a figure and an axes.
|
||||
ax.plot(time, participants, label='participants') # Plot some data on the axes.
|
||||
@ -44,9 +49,14 @@ def doPlotMeetings(bbbStati: List[BbbStatus]):
|
||||
ax.set_title("BigBlueButton Statistics") # Add a title to the axes.
|
||||
ax.legend() # Add a legend.
|
||||
|
||||
fig.savefig(fileUtil.setDatetimePrefix(fileUtil.getProjectBaseDir().joinpath("plot"), datetime.now()))
|
||||
plt.show()
|
||||
image: Path = getDefaultPlotFolder().joinpath(
|
||||
"{}_until_{}".format(fileUtil.asString(time[0]), fileUtil.asString(time[-1]))
|
||||
)
|
||||
fig.savefig(image)
|
||||
# plt.show()
|
||||
|
||||
return image
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
plotMeetings(fileUtil.getProjectBaseDir().joinpath("data"))
|
||||
plotMeetings()
|
||||
|
@ -24,9 +24,13 @@ def __getDatetimePrefixLength() -> int:
|
||||
return len("20200101_120030") # 1st January 2020, 12:00 and 30 seconds
|
||||
|
||||
|
||||
def asString(t: datetime) -> str:
|
||||
return t.strftime('%Y%m%d_%H%M%S')
|
||||
|
||||
|
||||
def setDatetimePrefix(file: Path, t: datetime) -> Path:
|
||||
# filename = file.name
|
||||
prefix = t.strftime('%Y%m%d_%H%M%S')
|
||||
prefix = asString(t)
|
||||
filename = prefix + "_" + file.name
|
||||
return file.parent.joinpath(filename)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user