From 40ed9bb497ccfeefab1c48c0b70597a6009dae0c Mon Sep 17 00:00:00 2001
From: David Huss <dh@atoav.com>
Date: Wed, 30 Jun 2021 16:10:45 +0200
Subject: [PATCH] Fix module structure

---
 bbbmeetings/__init__.py    |   2 +-
 bbbmeetings/bbbmeetings.py | 374 ++++++++++++++++++++++++++++++++++++-
 bbbmeetings/classes.py     | 372 ------------------------------------
 bbbmeetings/connection.py  |   6 +-
 pyproject.toml             |   2 +-
 5 files changed, 372 insertions(+), 384 deletions(-)
 delete mode 100644 bbbmeetings/classes.py

diff --git a/bbbmeetings/__init__.py b/bbbmeetings/__init__.py
index b794fd4..c12f34c 100644
--- a/bbbmeetings/__init__.py
+++ b/bbbmeetings/__init__.py
@@ -1 +1 @@
-__version__ = '0.1.0'
+__version__ = '0.1.1'
\ No newline at end of file
diff --git a/bbbmeetings/bbbmeetings.py b/bbbmeetings/bbbmeetings.py
index de9e97b..25a460b 100644
--- a/bbbmeetings/bbbmeetings.py
+++ b/bbbmeetings/bbbmeetings.py
@@ -1,12 +1,372 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
-
-from typing import NewType, Optional, Tuple, Iterable, List
-from collections import OrderedDict
 from datetime import datetime, timedelta
-import hashlib
-import requests
-import xmltodict
+from typing import NewType, Optional, Tuple, Iterable, List, Union
+import itertools
+
+from bbbmeetings.helpers import timestamp_to_datetime, seconds_to_timedelta
+from bbbmeetings.connection import get_meetings
+from bbbmeetings.types import *
+
+
+
+class BBBServers():
+    """
+    Multiple servers represented as one
+    """
+    def __init__(self, servers: List['BBBServer']):
+        self.servers = servers
+
+    @classmethod
+    def from_list(cls, servers: List['BBBServer']) -> 'Self':
+        if not isinstance(servers, list):
+            servers = list(servers)
+        return cls(servers)
+
+    def add(cls, servers: Union['BBBServer', List['BBBServer']]) -> 'Self':
+        if not isinstance(servers, list):
+            servers = list(servers)
+        for server in servers:
+            self.servers.append(server)
+        return self
+
+    def update_meetings(self) -> 'Self':
+        """
+        Update the meeting details by sendign a request to the BBBServers BBB-API
+        """
+        for server in self.servers:
+            server.update_meetings()
+        return self
+
+    @property
+    def meetings(self) -> List['Meeting']:
+        """
+        Return a flat list of all meetings on all servers
+        """
+        if any([s.last_update is None for s in self.servers]):
+            for server in self.servers:
+                server.update_meetings()
+
+        return list(itertools.chain.from_iterable([s.meetings for s in self.servers]))
+
+    @property
+    def people(self) -> int:
+        """
+        Returns the count of participants of a meeting
+        """
+        return sum([m.participantCount for m in self.meetings])
+
+    @property
+    def biggest_meeting(self) -> Optional['Meeting']:
+        return max(self.meetings, key=lambda m: m.people)
+
+    @property
+    def smallest_meeting(self) -> Optional['Meeting']:
+        return min(self.meetings, key=lambda m: m.people)
+
+    @property
+    def n_meetings(self) -> int:
+        return len(self.meetings)
+
+    @property
+    def listeners(self) -> int:
+        return sum([m.listenerCount for m in self.meetings])
+
+    @property
+    def connected_with_mic(self) -> int:
+        return sum([m.voiceParticipantCount for m in self.meetings])
+
+    @property
+    def video_active(self) -> int:
+        return sum([m.videoCount for m in self.meetings])
+
+    @property
+    def moderators(self) -> int:
+        return sum([m.moderatorCount for m in self.meetings])
+
+    @property
+    def longest_duration(self) -> Optional['Meeting']:
+        return max(self.meetings, key=lambda m: m.duration)
+
+    @property
+    def most_listeners(self) -> Optional['Meeting']:
+        return max(self.meetings, key=lambda m: m.listeners)
+
+    @property
+    def most_video_active(self) -> Optional['Meeting']:
+        return max(self.meetings, key=lambda m: m.video_active)
+
+    @property
+    def most_moderators(self) -> Optional['Meeting']:
+        return max(self.meetings, key=lambda m: m.moderators)
+
+    @property
+    def attendees(self) -> List['Attendees']:
+        return list(itertools.chain.from_iterable([m.attendees for m in self.meetings]))
+
+
+
+
+class BBBServer():
+    """
+    Represents a single Endpoint of the BBB-API (with a host address and a secret)
+    The hostname could be something like "https://bbb.example.org/" while the secret
+    is bascially a random string
+    """
+    def __init__(self, host, secret):
+        self.host = host
+        self.secret = secret
+        self._meetings = []
+        self.last_update = None
+
+    @classmethod
+    def from_dict(cls, d: dict):
+        """
+        Allows things like:
+        ```
+        s = BBBServer.from_dict({"host":"https://bbb.example.org", "secret":"12345"})
+        ```
+        """
+        host   = d["host"]
+        secret = d["secret"]
+        return cls(host, secret)
+
+    def update_meetings(self) -> 'Self':
+        """
+        Update the meeting details by sendign a request to the BBBServers BBB-API
+        """
+        self._meetings = get_meetings(self.host, self.secret)
+        self.last_update = datetime.now()
+        return self
+
+    @property
+    def meetings(self) -> List['Meeting']:
+        if self.last_update is None:
+            self.update_meetings()
+        return self._meetings
+
+    @property
+    def people(self) -> int:
+        """
+        Returns the count of participants of a meeting
+        """
+        return sum([m.people for m in self.meetings])
+
+    @property
+    def biggest_meeting(self) -> Optional['Meeting']:
+        return max(self.meetings, key=lambda m: m.people)
+
+    @property
+    def smallest_meeting(self) -> Optional['Meeting']:
+        return min(self.meetings, key=lambda m: m.people)
+
+    @property
+    def n_meetings(self) -> int:
+        return len(self.meetings)
+
+    @property
+    def listeners(self) -> int:
+        return sum([m.listeners for m in self.meetings])
+
+    @property
+    def connected_with_mic(self) -> int:
+        return sum([m.connected_with_mic for m in self.meetings])
+
+    @property
+    def video_active(self) -> int:
+        return sum([m.cideo_active for m in self.meetings])
+
+    @property
+    def moderators(self) -> int:
+        return sum([m.moderators for m in self.meetings])
+
+    @property
+    def longest_duration(self) -> Optional['Meeting']:
+        return max(self.meetings, key=lambda m: m.duration)
+
+    @property
+    def most_listeners(self) -> Optional['Meeting']:
+        return max(self.meetings, key=lambda m: m.listeners)
+
+    @property
+    def most_video_active(self) -> Optional['Meeting']:
+        return max(self.meetings, key=lambda m: m.video_active)
+
+    @property
+    def most_moderators(self) -> Optional['Meeting']:
+        return max(self.meetings, key=lambda m: m.moderators)
+
+    @property
+    def attendees(self) -> List['Attendees']:
+        return list(itertools.chain.from_iterable([m.attendees for m in self.meetings]))
+
+
+
+
+
+class Meeting():
+    """
+    A Meeting represents all the data the BBB-API returns about a Meeting
+    """
+    def __init__(self, name, meetingID, internalMeetingID, createTime, voiceBridge, dialNumber, attendeePW, moderatorPW, running, hasUserJoined, recording, hasBeenForciblyEnded, startTime, endTime, participantCount, listenerCount, voiceParticipantCount, videoCount, maxUsers, moderatorCount, attendees, isBreakout, parentRoom, breakoutRooms):
+        self.name              = name
+        self.meetingID         = meetingID
+        self.internalMeetingID = internalMeetingID
+        self.createTime        = createTime
+        self.voiceBridge       = voiceBridge
+        self.dialNumber        = dialNumber
+        self.attendeePW        = attendeePW
+        self.moderatorPW       = moderatorPW
+        self.running           = running
+        self.hasUserJoined     = hasUserJoined
+        self.recording         = recording
+        self.hasBeenForciblyEnded = hasBeenForciblyEnded
+        self.startTime         = startTime
+        self.endTime           = endTime
+        self.participantCount  = participantCount
+        self.listenerCount     = listenerCount
+        self.voiceParticipantCount = voiceParticipantCount
+        self.videoCount        = videoCount
+        self.maxUsers          = maxUsers
+        self.moderatorCount    = moderatorCount
+        self.attendees         = attendees
+        self.isBreakout        = isBreakout
+        self.parentRoom        = parentRoom
+        self.breakoutRooms     = breakoutRooms
+
+    @classmethod
+    def from_dict(cls, d: dict):
+        name                   = d["meetingName"]
+        meetingID              = d["meetingID"]
+        internalMeetingID      = d["internalMeetingID"]
+        createTime             = timestamp_to_datetime(d["createTime"])
+        voiceBridge            = d["voiceBridge"]
+        dialNumber             = d["dialNumber"]
+        attendeePW             = d["attendeePW"]
+        moderatorPW            = d["moderatorPW"]
+        running                = d["running"] == "true"
+        hasUserJoined          = d["hasUserJoined"] == "true"
+        recording              = d["recording"] == "true"
+        hasBeenForciblyEnded   = d["hasBeenForciblyEnded"] == "true"
+        startTime              = timestamp_to_datetime(d["startTime"])
+        endTime                = timestamp_to_datetime(d["endTime"])
+        participantCount       = int(d["participantCount"])
+        listenerCount          = int(d["listenerCount"])
+        voiceParticipantCount  = int(d["voiceParticipantCount"])
+        videoCount             = int(d["videoCount"])
+        maxUsers               = int(d["maxUsers"])
+        moderatorCount         = int(d["moderatorCount"])
+        attendees              = []
+        if d["attendees"] is not None:
+            for x in d["attendees"].values():
+                if isinstance(x, list):
+                    for i in x:
+                        attendees.append(Attendee.from_dict(i))
+                else:
+                    attendees.append(Attendee.from_dict(x))
+
+        isBreakout             = d["isBreakout"] == "true"
+        parentRoom = None
+        breakoutRooms = []
+        if isBreakout:
+            parentRoom = d["parentMeetingID"]
+        elif "breakoutRooms" in d.keys():
+            for x in d["breakoutRooms"].values():
+                if isinstance(x, list):
+                    for i in x:
+                        breakoutRooms.append(i)
+                else:
+                    breakoutRooms.append(x)
+
+            
+        return cls(name, meetingID, internalMeetingID, createTime, voiceBridge, dialNumber, attendeePW, moderatorPW, running, hasUserJoined, recording, hasBeenForciblyEnded, startTime, endTime, participantCount, listenerCount, voiceParticipantCount, videoCount, maxUsers, moderatorCount, attendees, isBreakout, parentRoom, breakoutRooms)
+
+    def __str__(self):
+        s = f"""Meeting
+    name:                  {self.name}
+    meetingID:             {self.meetingID}
+    internalMeetingID:     {self.internalMeetingID}
+    createTime:            {self.createTime}
+    voiceBridge:           {self.voiceBridge}
+    dialNumber:            {self.dialNumber}
+    attendeePW:            {self.attendeePW}
+    moderatorPW:           {self.moderatorPW}
+    running:               {self.running}
+    duration:              {self.duration}
+    hasUserJoined:         {self.hasUserJoined}
+    recording:             {self.recording}
+    hasBeenForciblyEnded:  {self.hasBeenForciblyEnded}
+    startTime:             {self.startTime}
+    endTime:               {self.endTime}
+    participantCount:      {self.participantCount}
+    listenerCount:         {self.listenerCount}
+    voiceParticipantCount: {self.voiceParticipantCount}
+    videoCount:            {self.videoCount}
+    maxUsers:              {self.maxUsers}
+    moderatorCount:        {self.moderatorCount}
+    attendees:             {', '.join([a.fullName for a in self.attendees])}
+    isBreakout:            {self.isBreakout}
+    parentRoom:            {self.parentRoom}
+    breakoutRooms:         {', '.join([x for x in self.breakoutRooms])}
+    """
+        return s
+
+    def __repr__(self):
+        return str(self)
+
+    @property
+    def duration(self) -> timedelta:
+        return datetime.now() - self.startTime
+
+    @property
+    def people(self) -> int:
+        return self.participantCount
+
+    @property
+    def listeners(self) -> int:
+        return self.listenerCount
+
+    @property
+    def connected_with_mic(self) -> int:
+        return self.voiceParticipantCount
+
+    @property
+    def video_active(self) -> int:
+        return  self.videoCount
+
+    @property
+    def moderators(self) -> int:
+        return self.moderatorCount
+
+
+
+class Attendee():
+    """
+    An Attendee is someone who is joined to a Meeting, as represented by the BBB-API
+    """
+    def __init__(self, userID, fullName, role, isPresenter, isListeningOnly, hasJoinedVoice, hasVideo, clientType):
+        self.userID          = userID
+        self.fullName        = fullName
+        self.role            = role
+        self.isPresenter     = isPresenter
+        self.isListeningOnly = isListeningOnly
+        self.hasJoinedVoice  = hasJoinedVoice
+        self.hasVideo        = hasVideo
+        self.clientType      = clientType
+
+    @classmethod
+    def from_dict(cls, d: dict):
+        userID           = d["userID"]
+        fullName         = d["fullName"]
+        role             = d["role"]
+        isPresenter      = d["isPresenter"] == "true"
+        isListeningOnly  = d["isListeningOnly"] == "true"
+        hasJoinedVoice   = d["hasJoinedVoice"] == "true"
+        hasVideo         = d["hasVideo"] == "true"
+        clientType       = d["clientType"]
 
-from bbbmeetings.classes import BBBServers, BBBServer
+        return cls(userID, fullName, role, isPresenter, isListeningOnly, hasJoinedVoice, hasVideo, clientType)
 
+    @property
+    def name(self) -> Optional[str]:
+        return self.fullName
diff --git a/bbbmeetings/classes.py b/bbbmeetings/classes.py
deleted file mode 100644
index 25a460b..0000000
--- a/bbbmeetings/classes.py
+++ /dev/null
@@ -1,372 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-from datetime import datetime, timedelta
-from typing import NewType, Optional, Tuple, Iterable, List, Union
-import itertools
-
-from bbbmeetings.helpers import timestamp_to_datetime, seconds_to_timedelta
-from bbbmeetings.connection import get_meetings
-from bbbmeetings.types import *
-
-
-
-class BBBServers():
-    """
-    Multiple servers represented as one
-    """
-    def __init__(self, servers: List['BBBServer']):
-        self.servers = servers
-
-    @classmethod
-    def from_list(cls, servers: List['BBBServer']) -> 'Self':
-        if not isinstance(servers, list):
-            servers = list(servers)
-        return cls(servers)
-
-    def add(cls, servers: Union['BBBServer', List['BBBServer']]) -> 'Self':
-        if not isinstance(servers, list):
-            servers = list(servers)
-        for server in servers:
-            self.servers.append(server)
-        return self
-
-    def update_meetings(self) -> 'Self':
-        """
-        Update the meeting details by sendign a request to the BBBServers BBB-API
-        """
-        for server in self.servers:
-            server.update_meetings()
-        return self
-
-    @property
-    def meetings(self) -> List['Meeting']:
-        """
-        Return a flat list of all meetings on all servers
-        """
-        if any([s.last_update is None for s in self.servers]):
-            for server in self.servers:
-                server.update_meetings()
-
-        return list(itertools.chain.from_iterable([s.meetings for s in self.servers]))
-
-    @property
-    def people(self) -> int:
-        """
-        Returns the count of participants of a meeting
-        """
-        return sum([m.participantCount for m in self.meetings])
-
-    @property
-    def biggest_meeting(self) -> Optional['Meeting']:
-        return max(self.meetings, key=lambda m: m.people)
-
-    @property
-    def smallest_meeting(self) -> Optional['Meeting']:
-        return min(self.meetings, key=lambda m: m.people)
-
-    @property
-    def n_meetings(self) -> int:
-        return len(self.meetings)
-
-    @property
-    def listeners(self) -> int:
-        return sum([m.listenerCount for m in self.meetings])
-
-    @property
-    def connected_with_mic(self) -> int:
-        return sum([m.voiceParticipantCount for m in self.meetings])
-
-    @property
-    def video_active(self) -> int:
-        return sum([m.videoCount for m in self.meetings])
-
-    @property
-    def moderators(self) -> int:
-        return sum([m.moderatorCount for m in self.meetings])
-
-    @property
-    def longest_duration(self) -> Optional['Meeting']:
-        return max(self.meetings, key=lambda m: m.duration)
-
-    @property
-    def most_listeners(self) -> Optional['Meeting']:
-        return max(self.meetings, key=lambda m: m.listeners)
-
-    @property
-    def most_video_active(self) -> Optional['Meeting']:
-        return max(self.meetings, key=lambda m: m.video_active)
-
-    @property
-    def most_moderators(self) -> Optional['Meeting']:
-        return max(self.meetings, key=lambda m: m.moderators)
-
-    @property
-    def attendees(self) -> List['Attendees']:
-        return list(itertools.chain.from_iterable([m.attendees for m in self.meetings]))
-
-
-
-
-class BBBServer():
-    """
-    Represents a single Endpoint of the BBB-API (with a host address and a secret)
-    The hostname could be something like "https://bbb.example.org/" while the secret
-    is bascially a random string
-    """
-    def __init__(self, host, secret):
-        self.host = host
-        self.secret = secret
-        self._meetings = []
-        self.last_update = None
-
-    @classmethod
-    def from_dict(cls, d: dict):
-        """
-        Allows things like:
-        ```
-        s = BBBServer.from_dict({"host":"https://bbb.example.org", "secret":"12345"})
-        ```
-        """
-        host   = d["host"]
-        secret = d["secret"]
-        return cls(host, secret)
-
-    def update_meetings(self) -> 'Self':
-        """
-        Update the meeting details by sendign a request to the BBBServers BBB-API
-        """
-        self._meetings = get_meetings(self.host, self.secret)
-        self.last_update = datetime.now()
-        return self
-
-    @property
-    def meetings(self) -> List['Meeting']:
-        if self.last_update is None:
-            self.update_meetings()
-        return self._meetings
-
-    @property
-    def people(self) -> int:
-        """
-        Returns the count of participants of a meeting
-        """
-        return sum([m.people for m in self.meetings])
-
-    @property
-    def biggest_meeting(self) -> Optional['Meeting']:
-        return max(self.meetings, key=lambda m: m.people)
-
-    @property
-    def smallest_meeting(self) -> Optional['Meeting']:
-        return min(self.meetings, key=lambda m: m.people)
-
-    @property
-    def n_meetings(self) -> int:
-        return len(self.meetings)
-
-    @property
-    def listeners(self) -> int:
-        return sum([m.listeners for m in self.meetings])
-
-    @property
-    def connected_with_mic(self) -> int:
-        return sum([m.connected_with_mic for m in self.meetings])
-
-    @property
-    def video_active(self) -> int:
-        return sum([m.cideo_active for m in self.meetings])
-
-    @property
-    def moderators(self) -> int:
-        return sum([m.moderators for m in self.meetings])
-
-    @property
-    def longest_duration(self) -> Optional['Meeting']:
-        return max(self.meetings, key=lambda m: m.duration)
-
-    @property
-    def most_listeners(self) -> Optional['Meeting']:
-        return max(self.meetings, key=lambda m: m.listeners)
-
-    @property
-    def most_video_active(self) -> Optional['Meeting']:
-        return max(self.meetings, key=lambda m: m.video_active)
-
-    @property
-    def most_moderators(self) -> Optional['Meeting']:
-        return max(self.meetings, key=lambda m: m.moderators)
-
-    @property
-    def attendees(self) -> List['Attendees']:
-        return list(itertools.chain.from_iterable([m.attendees for m in self.meetings]))
-
-
-
-
-
-class Meeting():
-    """
-    A Meeting represents all the data the BBB-API returns about a Meeting
-    """
-    def __init__(self, name, meetingID, internalMeetingID, createTime, voiceBridge, dialNumber, attendeePW, moderatorPW, running, hasUserJoined, recording, hasBeenForciblyEnded, startTime, endTime, participantCount, listenerCount, voiceParticipantCount, videoCount, maxUsers, moderatorCount, attendees, isBreakout, parentRoom, breakoutRooms):
-        self.name              = name
-        self.meetingID         = meetingID
-        self.internalMeetingID = internalMeetingID
-        self.createTime        = createTime
-        self.voiceBridge       = voiceBridge
-        self.dialNumber        = dialNumber
-        self.attendeePW        = attendeePW
-        self.moderatorPW       = moderatorPW
-        self.running           = running
-        self.hasUserJoined     = hasUserJoined
-        self.recording         = recording
-        self.hasBeenForciblyEnded = hasBeenForciblyEnded
-        self.startTime         = startTime
-        self.endTime           = endTime
-        self.participantCount  = participantCount
-        self.listenerCount     = listenerCount
-        self.voiceParticipantCount = voiceParticipantCount
-        self.videoCount        = videoCount
-        self.maxUsers          = maxUsers
-        self.moderatorCount    = moderatorCount
-        self.attendees         = attendees
-        self.isBreakout        = isBreakout
-        self.parentRoom        = parentRoom
-        self.breakoutRooms     = breakoutRooms
-
-    @classmethod
-    def from_dict(cls, d: dict):
-        name                   = d["meetingName"]
-        meetingID              = d["meetingID"]
-        internalMeetingID      = d["internalMeetingID"]
-        createTime             = timestamp_to_datetime(d["createTime"])
-        voiceBridge            = d["voiceBridge"]
-        dialNumber             = d["dialNumber"]
-        attendeePW             = d["attendeePW"]
-        moderatorPW            = d["moderatorPW"]
-        running                = d["running"] == "true"
-        hasUserJoined          = d["hasUserJoined"] == "true"
-        recording              = d["recording"] == "true"
-        hasBeenForciblyEnded   = d["hasBeenForciblyEnded"] == "true"
-        startTime              = timestamp_to_datetime(d["startTime"])
-        endTime                = timestamp_to_datetime(d["endTime"])
-        participantCount       = int(d["participantCount"])
-        listenerCount          = int(d["listenerCount"])
-        voiceParticipantCount  = int(d["voiceParticipantCount"])
-        videoCount             = int(d["videoCount"])
-        maxUsers               = int(d["maxUsers"])
-        moderatorCount         = int(d["moderatorCount"])
-        attendees              = []
-        if d["attendees"] is not None:
-            for x in d["attendees"].values():
-                if isinstance(x, list):
-                    for i in x:
-                        attendees.append(Attendee.from_dict(i))
-                else:
-                    attendees.append(Attendee.from_dict(x))
-
-        isBreakout             = d["isBreakout"] == "true"
-        parentRoom = None
-        breakoutRooms = []
-        if isBreakout:
-            parentRoom = d["parentMeetingID"]
-        elif "breakoutRooms" in d.keys():
-            for x in d["breakoutRooms"].values():
-                if isinstance(x, list):
-                    for i in x:
-                        breakoutRooms.append(i)
-                else:
-                    breakoutRooms.append(x)
-
-            
-        return cls(name, meetingID, internalMeetingID, createTime, voiceBridge, dialNumber, attendeePW, moderatorPW, running, hasUserJoined, recording, hasBeenForciblyEnded, startTime, endTime, participantCount, listenerCount, voiceParticipantCount, videoCount, maxUsers, moderatorCount, attendees, isBreakout, parentRoom, breakoutRooms)
-
-    def __str__(self):
-        s = f"""Meeting
-    name:                  {self.name}
-    meetingID:             {self.meetingID}
-    internalMeetingID:     {self.internalMeetingID}
-    createTime:            {self.createTime}
-    voiceBridge:           {self.voiceBridge}
-    dialNumber:            {self.dialNumber}
-    attendeePW:            {self.attendeePW}
-    moderatorPW:           {self.moderatorPW}
-    running:               {self.running}
-    duration:              {self.duration}
-    hasUserJoined:         {self.hasUserJoined}
-    recording:             {self.recording}
-    hasBeenForciblyEnded:  {self.hasBeenForciblyEnded}
-    startTime:             {self.startTime}
-    endTime:               {self.endTime}
-    participantCount:      {self.participantCount}
-    listenerCount:         {self.listenerCount}
-    voiceParticipantCount: {self.voiceParticipantCount}
-    videoCount:            {self.videoCount}
-    maxUsers:              {self.maxUsers}
-    moderatorCount:        {self.moderatorCount}
-    attendees:             {', '.join([a.fullName for a in self.attendees])}
-    isBreakout:            {self.isBreakout}
-    parentRoom:            {self.parentRoom}
-    breakoutRooms:         {', '.join([x for x in self.breakoutRooms])}
-    """
-        return s
-
-    def __repr__(self):
-        return str(self)
-
-    @property
-    def duration(self) -> timedelta:
-        return datetime.now() - self.startTime
-
-    @property
-    def people(self) -> int:
-        return self.participantCount
-
-    @property
-    def listeners(self) -> int:
-        return self.listenerCount
-
-    @property
-    def connected_with_mic(self) -> int:
-        return self.voiceParticipantCount
-
-    @property
-    def video_active(self) -> int:
-        return  self.videoCount
-
-    @property
-    def moderators(self) -> int:
-        return self.moderatorCount
-
-
-
-class Attendee():
-    """
-    An Attendee is someone who is joined to a Meeting, as represented by the BBB-API
-    """
-    def __init__(self, userID, fullName, role, isPresenter, isListeningOnly, hasJoinedVoice, hasVideo, clientType):
-        self.userID          = userID
-        self.fullName        = fullName
-        self.role            = role
-        self.isPresenter     = isPresenter
-        self.isListeningOnly = isListeningOnly
-        self.hasJoinedVoice  = hasJoinedVoice
-        self.hasVideo        = hasVideo
-        self.clientType      = clientType
-
-    @classmethod
-    def from_dict(cls, d: dict):
-        userID           = d["userID"]
-        fullName         = d["fullName"]
-        role             = d["role"]
-        isPresenter      = d["isPresenter"] == "true"
-        isListeningOnly  = d["isListeningOnly"] == "true"
-        hasJoinedVoice   = d["hasJoinedVoice"] == "true"
-        hasVideo         = d["hasVideo"] == "true"
-        clientType       = d["clientType"]
-
-        return cls(userID, fullName, role, isPresenter, isListeningOnly, hasJoinedVoice, hasVideo, clientType)
-
-    @property
-    def name(self) -> Optional[str]:
-        return self.fullName
diff --git a/bbbmeetings/connection.py b/bbbmeetings/connection.py
index d989b45..42b8a74 100644
--- a/bbbmeetings/connection.py
+++ b/bbbmeetings/connection.py
@@ -7,7 +7,7 @@ import requests
 import xmltodict
 
 from bbbmeetings.types import *
-import bbbmeetings.classes as classes
+import bbbmeetings
 
 def generate_checksum(call_name: str, query_string: str, secret: Secret) -> str:
     """
@@ -68,7 +68,7 @@ def get_meetings(bbb_url: Url, secret: Secret) -> List['Meeting']:
         for d in checked_dict["meetings"].values():
             if isinstance(d, list):
                 for x in d:
-                    meetings.append(classes.Meeting.from_dict(x))
+                    meetings.append(bbbmeetings.Meeting.from_dict(x))
             else:
-                meetings.append(classes.Meeting.from_dict(d))
+                meetings.append(bbbmeetings.Meeting.from_dict(d))
         return meetings
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index 6a12337..478336a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "bbbmeetings"
-version = "0.1.0"
+version = "0.1.1"
 description = "A module for reading bbb meetings from bbb servers"
 authors = ["David Huss <david.huss@hfbk-hamburg.de>"]
 maintainers = ["David Huss <david.huss@hfbk-hamburg.de>"]
-- 
GitLab