Skip to content

Commit 04fc790

Browse files
authored
feature-9004: Implement backend for additional Rocket Chat rooms (#9014)
* feature-8987 - Implement dedicated Rocket Chat rooms for each video room and make them ready for mobile view * feature-8987 + feature-9004 * fix python deepsource scan * fix issue create chat room for disabled location * fix mutiple migration head
1 parent 9b40fad commit 04fc790

File tree

5 files changed

+120
-12
lines changed

5 files changed

+120
-12
lines changed

app/api/chat/rocket_chat.py

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from app.api.helpers.db import get_new_identifier, get_or_create
1010
from app.models import db
1111
from app.models.event import Event
12+
from app.models.microlocation import Microlocation
1213
from app.models.user import User
1314
from app.settings import get_settings
1415

@@ -96,14 +97,20 @@ def register(
9697
)
9798
raise RocketChatException('Error while registration', response=res)
9899

99-
def get_token(self, user: User, event: Optional[Event] = None, retried=False):
100+
def get_token(
101+
self,
102+
user: User,
103+
event: Optional[Event] = None,
104+
retried=False,
105+
microlocation: Optional[Microlocation] = None,
106+
):
100107
if user.rocket_chat_token:
101108
res = requests.post(self.login_url, json=dict(resume=user.rocket_chat_token))
102109

103110
data = res.json()
104111
if res.status_code == 200:
105112
if event:
106-
self.add_in_room(event, data['data']['userId'])
113+
self.add_in_room(event, data['data']['userId'], microlocation)
107114
return dict(method='resumed', token=user.rocket_chat_token, res=data)
108115
elif res.status_code == 401:
109116
# Token Expired. Login again
@@ -145,14 +152,18 @@ def check_or_create_bot(self):
145152

146153
return bot_user
147154

148-
def create_room(self, event: Event, data):
155+
def create_room(self, event: Event, microlocation: Optional[Microlocation], data):
149156
bot_token = data['token']
150157
bot_id = data['res']['data']['userId']
158+
if microlocation:
159+
chat_room_name = microlocation.chat_room_name
160+
else:
161+
chat_room_name = event.chat_room_name
151162

152163
res = requests.post(
153164
self.api_url + '/api/v1/groups.create',
154165
json=dict(
155-
name=event.chat_room_name,
166+
name=chat_room_name,
156167
members=[bot_id],
157168
),
158169
headers={
@@ -165,20 +176,31 @@ def create_room(self, event: Event, data):
165176
raise RocketChatException('Error while creating room', response=res)
166177
else:
167178
group_data = res.json()
168-
event.chat_room_id = group_data['group']['_id']
169-
db.session.add(event)
179+
if microlocation:
180+
microlocation.chat_room_id = group_data['group']['_id']
181+
db.session.add(microlocation)
182+
else:
183+
event.chat_room_id = group_data['group']['_id']
184+
db.session.add(event)
170185
db.session.commit()
171186

172-
def add_in_room(self, event: Event, rocket_user_id):
187+
def add_in_room(
188+
self, event: Event, rocket_user_id, microlocation: Optional[Microlocation] = None
189+
):
173190
bot = self.check_or_create_bot()
174191
data = self.get_token(bot)
175192

176-
if not event.chat_room_id:
177-
self.create_room(event, data)
193+
if (not event.chat_room_id) or (microlocation and not microlocation.chat_room_id):
194+
self.create_room(event=event, microlocation=microlocation, data=data)
195+
196+
if microlocation is not None:
197+
chat_room_id = microlocation.chat_room_id
198+
else:
199+
chat_room_id = event.chat_room_id
178200

179201
bot_token = data['token']
180202
bot_id = data['res']['data']['userId']
181-
room_info = {'roomId': event.chat_room_id, 'userId': rocket_user_id}
203+
room_info = {'roomId': chat_room_id, 'userId': rocket_user_id}
182204

183205
res = requests.post(
184206
self.api_url + '/api/v1/groups.invite',
@@ -198,15 +220,19 @@ def generate_pass(size=10, chars=string.ascii_lowercase + string.digits):
198220
return ''.join(random.choice(chars) for _ in range(size))
199221

200222

201-
def get_rocket_chat_token(user: User, event: Optional[Event] = None):
223+
def get_rocket_chat_token(
224+
user: User,
225+
event: Optional[Event] = None,
226+
microlocation: Optional[Microlocation] = None,
227+
):
202228
settings = get_settings()
203229
if not (api_url := settings['rocket_chat_url']):
204230
raise RocketChatException(
205231
'Rocket Chat Integration is not enabled', RocketChatException.CODES.DISABLED
206232
)
207233

208234
rocket_chat = RocketChat(api_url)
209-
return rocket_chat.get_token(user, event)
235+
return rocket_chat.get_token(user, event, microlocation=microlocation)
210236

211237

212238
def rename_rocketchat_room(event: Event):

app/api/events.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,45 @@ def get_chat_token(event_id: int):
123123
)
124124

125125

126+
@events_blueprint.route(
127+
'/<string:event_identifier>/room/<string:microlocation_id>/chat-token',
128+
)
129+
@jwt_required
130+
@to_event_id
131+
def get_room_chat_token(event_id: int, microlocation_id: int):
132+
"""
133+
Get room chat token for specific room
134+
@param event_id: event identifier
135+
@param microlocation_id: microlocation id
136+
@return: room chat token
137+
"""
138+
event = Event.query.get_or_404(event_id)
139+
microlocation = Microlocation.query.get_or_404(microlocation_id)
140+
141+
if not VideoStream(event_id=event.id).user_can_access:
142+
raise NotFoundError({'source': ''}, 'Video Stream Not Found')
143+
144+
if not event.is_chat_enabled:
145+
raise NotFoundError({'source': ''}, 'Chat Not Enabled')
146+
147+
if not microlocation.is_chat_enabled and not microlocation.is_global_event_room:
148+
raise NotFoundError({'source': ''}, 'Chat Not Enabled For This Room')
149+
150+
try:
151+
data = get_rocket_chat_token(current_user, event, microlocation)
152+
return jsonify({'success': True, 'token': data['token']})
153+
except RocketChatException as rce:
154+
if rce.code == RocketChatException.CODES.DISABLED:
155+
return jsonify({'success': False, 'code': rce.code})
156+
return jsonify(
157+
{
158+
'success': False,
159+
'code': rce.code,
160+
'response': rce.response is not None and rce.response.json(),
161+
}
162+
)
163+
164+
126165
def validate_event(user, data):
127166
if not user.can_create_event():
128167
raise ForbiddenError({'source': ''}, "Please verify your Email")

app/api/schema/microlocations.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ class Meta:
2727
longitude = fields.Float(validate=lambda n: -180 <= n <= 180, allow_none=True)
2828
floor = fields.Integer(allow_none=True)
2929
hidden_in_scheduler = fields.Boolean(default=False)
30+
chat_room_name = fields.Str(dump_only=True)
31+
is_chat_enabled = fields.Boolean(default=False, allow_none=True)
32+
is_global_event_room = fields.Boolean(default=False, allow_none=True)
3033
position = fields.Integer(allow_none=True, default=0)
3134
room = fields.Str(allow_none=True)
3235
sessions = Relationship(

app/models/microlocation.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import re
2+
13
from app.models import db
24
from app.models.base import SoftDeletionModel
35

@@ -14,6 +16,9 @@ class Microlocation(SoftDeletionModel):
1416
hidden_in_scheduler = db.Column(db.Boolean, default=False, nullable=False)
1517
position = db.Column(db.Integer, default=0, nullable=False)
1618
room = db.Column(db.String)
19+
is_chat_enabled = db.Column(db.Boolean, default=False, nullable=True)
20+
is_global_event_room = db.Column(db.Boolean, default=False, nullable=True)
21+
chat_room_id = db.Column(db.String, nullable=True)
1722
session = db.relationship('Session', backref="microlocation")
1823
event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE'))
1924
video_stream_id = db.Column(
@@ -38,3 +43,7 @@ def safe_video_stream(self):
3843
@safe_video_stream.setter
3944
def safe_video_stream(self, value):
4045
self.video_stream = value
46+
47+
@property
48+
def chat_room_name(self):
49+
return re.sub('[^0-9a-zA-Z!]', '-', self.name) + '-' + str(self.id)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""empty message
2+
3+
Revision ID: c4100d6a5609
4+
Revises: 8bd9e8e80517
5+
Create Date: 2023-07-26 16:32:01.697408
6+
7+
"""
8+
9+
from alembic import op
10+
import sqlalchemy as sa
11+
12+
13+
# revision identifiers, used by Alembic.
14+
revision = 'c4100d6a5609'
15+
down_revision = '8bd9e8e80517'
16+
17+
18+
def upgrade():
19+
# ### commands auto generated by Alembic - please adjust! ###
20+
op.add_column('microlocations', sa.Column('is_chat_enabled', sa.Boolean(), nullable=True))
21+
op.add_column('microlocations', sa.Column('is_global_event_room', sa.Boolean(), nullable=True))
22+
op.add_column('microlocations', sa.Column('chat_room_id', sa.String(), nullable=True))
23+
# ### end Alembic commands ###
24+
25+
26+
def downgrade():
27+
# ### commands auto generated by Alembic - please adjust! ###
28+
op.drop_column('microlocations', 'chat_room_id')
29+
op.drop_column('microlocations', 'is_global_event_room')
30+
op.drop_column('microlocations', 'is_chat_enabled')
31+
# ### end Alembic commands ###

0 commit comments

Comments
 (0)