mirror of
https://github.com/lucaspalomodevelop/indico-plugins.git
synced 2026-03-13 07:29:39 +00:00
VC/Zoom: Better notifications, rename owner -> host
This commit is contained in:
parent
5e65555855
commit
6525135348
@ -10,10 +10,10 @@ from indico.modules.vc.exceptions import VCRoomError
|
||||
from indico.util.i18n import _
|
||||
|
||||
|
||||
class RHRoomOwner(RHVCSystemEventBase):
|
||||
class RHRoomHost(RHVCSystemEventBase):
|
||||
def _process(self):
|
||||
result = {}
|
||||
self.vc_room.data['owner'] = session.user.identifier
|
||||
self.vc_room.data['host'] = session.user.identifier
|
||||
try:
|
||||
self.plugin.update_room(self.vc_room, self.event)
|
||||
except VCRoomError as err:
|
||||
@ -21,6 +21,6 @@ class RHRoomOwner(RHVCSystemEventBase):
|
||||
result['success'] = False
|
||||
db.session.rollback()
|
||||
else:
|
||||
flash(_("You are now the owner of the room '{room.name}'".format(room=self.vc_room)), 'success')
|
||||
flash(_("You are now the host of room '{room.name}'".format(room=self.vc_room)), 'success')
|
||||
result['success'] = True
|
||||
return jsonify(result)
|
||||
|
||||
@ -15,9 +15,7 @@ from indico.web.forms.widgets import SwitchWidget
|
||||
from indico_vc_zoom import _
|
||||
|
||||
|
||||
class ZoomAdvancedFormMixin(object):
|
||||
# Advanced options (per event)
|
||||
|
||||
class VCRoomAttachForm(VCRoomAttachFormBase):
|
||||
password_visibility = IndicoRadioField(_("Password visibility"),
|
||||
description=_("Who should be able to know this meeting's password"),
|
||||
orientation='horizontal',
|
||||
@ -27,24 +25,26 @@ class ZoomAdvancedFormMixin(object):
|
||||
('no_one', _("No one"))])
|
||||
|
||||
|
||||
class VCRoomAttachForm(VCRoomAttachFormBase, ZoomAdvancedFormMixin):
|
||||
pass
|
||||
|
||||
|
||||
class VCRoomForm(VCRoomFormBase, ZoomAdvancedFormMixin):
|
||||
class VCRoomForm(VCRoomFormBase):
|
||||
"""Contains all information concerning a Zoom booking."""
|
||||
|
||||
advanced_fields = {'mute_audio', 'mute_host_video', 'mute_participant_video'} | VCRoomFormBase.advanced_fields
|
||||
|
||||
skip_fields = advanced_fields | VCRoomFormBase.conditional_fields
|
||||
|
||||
description = TextAreaField(_('Description'), description=_('The description of the room'))
|
||||
host_choice = IndicoRadioField(_("Meeting Host"), [DataRequired()],
|
||||
choices=[('myself', _("Myself")), ('someone_else', _("Someone else"))])
|
||||
|
||||
owner_choice = IndicoRadioField(_("Owner of Room"), [DataRequired()],
|
||||
choices=[('myself', _("Myself")), ('someone_else', _("Someone else"))])
|
||||
host_user = PrincipalField(_("User"),
|
||||
[HiddenUnless('host_choice', 'someone_else'), DataRequired()])
|
||||
|
||||
owner_user = PrincipalField(_("User"),
|
||||
[HiddenUnless('owner_choice', 'someone_else'), DataRequired()])
|
||||
password_visibility = IndicoRadioField(_("Password visibility"),
|
||||
description=_("Who should be able to know this meeting's password"),
|
||||
orientation='horizontal',
|
||||
choices=[
|
||||
('everyone', _('Everyone')),
|
||||
('logged_in', _('Logged-in users')),
|
||||
('no_one', _("No one"))])
|
||||
|
||||
mute_audio = BooleanField(_('Mute audio'),
|
||||
widget=SwitchWidget(),
|
||||
@ -62,18 +62,20 @@ class VCRoomForm(VCRoomFormBase, ZoomAdvancedFormMixin):
|
||||
widget=SwitchWidget(),
|
||||
description=_('Participants may be kept in a waiting room by the host'))
|
||||
|
||||
description = TextAreaField(_('Description'), description=_('The description of the room'))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
defaults = kwargs['obj']
|
||||
if defaults.owner_user is None and defaults.owner is not None:
|
||||
owner = principal_from_identifier(defaults.owner)
|
||||
defaults.owner_choice = 'myself' if owner == session.user else 'someone_else'
|
||||
defaults.owner_user = None if owner == session.user else owner
|
||||
if defaults.host_user is None and defaults.host is not None:
|
||||
host = principal_from_identifier(defaults.host)
|
||||
defaults.host_choice = 'myself' if host == session.user else 'someone_else'
|
||||
defaults.host_user = None if host == session.user else host
|
||||
super(VCRoomForm, self).__init__(*args, **kwargs)
|
||||
|
||||
@generated_data
|
||||
def owner(self):
|
||||
return session.user.identifier if self.owner_choice.data == 'myself' else self.owner_user.data.identifier
|
||||
def host(self):
|
||||
return session.user.identifier if self.host_choice.data == 'myself' else self.host_user.data.identifier
|
||||
|
||||
def validate_owner_user(self, field):
|
||||
def validate_host_user(self, field):
|
||||
if not field.data:
|
||||
raise ValidationError(_("Unable to find this user in Indico."))
|
||||
|
||||
37
indico_vc_zoom/notifications.py
Normal file
37
indico_vc_zoom/notifications.py
Normal file
@ -0,0 +1,37 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from indico.web.flask.templating import get_template_module
|
||||
from indico.core.notifications import make_email, send_email
|
||||
from indico.util.user import principal_from_identifier
|
||||
|
||||
|
||||
def notify_host_start_url(vc_room):
|
||||
from indico_vc_zoom.plugin import ZoomPlugin
|
||||
|
||||
user = principal_from_identifier(vc_room.data['host'])
|
||||
to_list = {user.email}
|
||||
|
||||
template_module = get_template_module(
|
||||
'vc_zoom:emails/notify_start_url.html',
|
||||
plugin=ZoomPlugin.instance,
|
||||
vc_room=vc_room,
|
||||
user=user
|
||||
)
|
||||
|
||||
email = make_email(to_list, template=template_module, html=True)
|
||||
send_email(email, None, 'Zoom')
|
||||
|
||||
|
||||
def notify_new_host(actor, vc_room):
|
||||
from indico_vc_zoom.plugin import ZoomPlugin
|
||||
|
||||
template_module = get_template_module(
|
||||
'vc_zoom:emails/notify_new_host.html',
|
||||
plugin=ZoomPlugin.instance,
|
||||
vc_room=vc_room,
|
||||
actor=actor
|
||||
)
|
||||
|
||||
new_host = principal_from_identifier(vc_room.data['host'])
|
||||
email = make_email({new_host.email}, cc_list={actor.email}, template=template_module, html=True)
|
||||
send_email(email, None, 'Zoom')
|
||||
@ -3,7 +3,7 @@ from __future__ import unicode_literals
|
||||
import random
|
||||
import string
|
||||
|
||||
from flask import flash
|
||||
from flask import flash, session
|
||||
from requests.exceptions import HTTPError
|
||||
from sqlalchemy.orm.attributes import flag_modified
|
||||
from werkzeug.exceptions import Forbidden, NotFound
|
||||
@ -11,13 +11,8 @@ from wtforms.fields.core import BooleanField
|
||||
from wtforms.fields import IntegerField, TextAreaField
|
||||
from wtforms.fields.html5 import EmailField, URLField
|
||||
from wtforms.fields.simple import StringField
|
||||
|
||||
from indico.web.forms.fields.simple import IndicoPasswordField
|
||||
from indico.web.forms.widgets import SwitchWidget
|
||||
|
||||
from indico.web.flask.templating import get_template_module
|
||||
from wtforms.validators import DataRequired, NumberRange
|
||||
from indico.core.notifications import make_email, send_email
|
||||
|
||||
from indico.core import signals
|
||||
from indico.core.config import config
|
||||
from indico.core.plugins import IndicoPlugin, url_for_plugin
|
||||
@ -27,7 +22,8 @@ from indico.modules.vc.exceptions import VCRoomError, VCRoomNotFoundError
|
||||
from indico.modules.vc.models.vc_rooms import VCRoom
|
||||
from indico.modules.vc.views import WPVCEventPage, WPVCManageEvent
|
||||
from indico.util.user import principal_from_identifier
|
||||
from indico.web.forms.widgets import CKEditorWidget
|
||||
from indico.web.forms.fields.simple import IndicoPasswordField
|
||||
from indico.web.forms.widgets import CKEditorWidget, SwitchWidget
|
||||
from indico.web.http_api.hooks.base import HTTPAPIHook
|
||||
|
||||
from indico_vc_zoom import _
|
||||
@ -36,6 +32,7 @@ from indico_vc_zoom.blueprint import blueprint
|
||||
from indico_vc_zoom.cli import cli
|
||||
from indico_vc_zoom.forms import VCRoomAttachForm, VCRoomForm
|
||||
from indico_vc_zoom.http_api import DeleteVCRoomAPI
|
||||
from indico_vc_zoom.notifications import notify_new_host, notify_host_start_url
|
||||
from indico_vc_zoom.util import find_enterprise_email
|
||||
|
||||
|
||||
@ -206,7 +203,7 @@ class ZoomPlugin(VCPluginMixin, IndicoPlugin):
|
||||
def update_data_vc_room(self, vc_room, data):
|
||||
super(ZoomPlugin, self).update_data_vc_room(vc_room, data)
|
||||
|
||||
for key in {'description', 'owner', 'mute_audio', 'mute_participant_video', 'mute_host_video',
|
||||
for key in {'description', 'host', 'mute_audio', 'mute_participant_video', 'mute_host_video',
|
||||
'join_before_host', 'waiting_room'}:
|
||||
if key in data:
|
||||
vc_room.data[key] = data.pop(key)
|
||||
@ -239,8 +236,8 @@ class ZoomPlugin(VCPluginMixin, IndicoPlugin):
|
||||
:param event: the event to the Zoom room will be attached
|
||||
"""
|
||||
client = ZoomIndicoClient()
|
||||
owner = principal_from_identifier(vc_room.data['owner'])
|
||||
owner_id = find_enterprise_email(owner)
|
||||
host = principal_from_identifier(vc_room.data['host'])
|
||||
host_id = find_enterprise_email(host)
|
||||
|
||||
# get the object that this booking is linked to
|
||||
vc_room_assoc = vc_room.events[0]
|
||||
@ -248,7 +245,7 @@ class ZoomPlugin(VCPluginMixin, IndicoPlugin):
|
||||
|
||||
scheduling_args = _get_schedule_args(link_obj) if link_obj.start_dt else {}
|
||||
|
||||
self._check_indico_is_assistant(owner_id)
|
||||
self._check_indico_is_assistant(host_id)
|
||||
|
||||
try:
|
||||
settings = {
|
||||
@ -262,7 +259,7 @@ class ZoomPlugin(VCPluginMixin, IndicoPlugin):
|
||||
type=2 if scheduling_args else 3, # scheduled vs. recurring meeting
|
||||
topic=vc_room.name,
|
||||
password=_gen_random_password(),
|
||||
schedule_for=owner_id,
|
||||
schedule_for=host_id,
|
||||
timezone=event.timezone,
|
||||
settings=settings,
|
||||
**scheduling_args)
|
||||
@ -276,21 +273,21 @@ class ZoomPlugin(VCPluginMixin, IndicoPlugin):
|
||||
'public_url': meeting_obj['join_url'].split('?')[0],
|
||||
'start_url': meeting_obj['start_url'],
|
||||
'password': meeting_obj['password'],
|
||||
'owner': owner.identifier
|
||||
'host': host.identifier
|
||||
})
|
||||
|
||||
flag_modified(vc_room, 'data')
|
||||
|
||||
# e-mail Host URL to meeting host
|
||||
if self.settings.get('send_host_url'):
|
||||
self.notify_owner_start_url(vc_room)
|
||||
notify_host_start_url(vc_room)
|
||||
|
||||
def update_room(self, vc_room, event):
|
||||
client = ZoomIndicoClient()
|
||||
zoom_meeting = _fetch_zoom_meeting(vc_room, client=client)
|
||||
changes = {}
|
||||
|
||||
owner = principal_from_identifier(vc_room.data['owner'])
|
||||
host = principal_from_identifier(vc_room.data['host'])
|
||||
host_id = zoom_meeting['host_id']
|
||||
|
||||
try:
|
||||
@ -299,15 +296,16 @@ class ZoomPlugin(VCPluginMixin, IndicoPlugin):
|
||||
self.logger.exception("Error retrieving user '%s': %s", host_id, e.response.content)
|
||||
raise VCRoomError(_("Can't get information about user. Please contact support if the error persists."))
|
||||
|
||||
# owner changed
|
||||
if host_data['email'] not in owner.all_emails:
|
||||
email = find_enterprise_email(owner)
|
||||
# host changed
|
||||
if host_data['email'] not in host.all_emails:
|
||||
email = find_enterprise_email(host)
|
||||
|
||||
if not email:
|
||||
raise Forbidden(_("This user doesn't seem to have an associated Zoom account"))
|
||||
|
||||
changes['schedule_for'] = email
|
||||
self._check_indico_is_assistant(email)
|
||||
notify_new_host(session.user, vc_room)
|
||||
|
||||
if vc_room.name != zoom_meeting['topic']:
|
||||
changes['topic'] = vc_room.name
|
||||
@ -356,8 +354,8 @@ class ZoomPlugin(VCPluginMixin, IndicoPlugin):
|
||||
'mute_host_video': self.settings.get('mute_host_video'),
|
||||
'mute_participant_video': self.settings.get('mute_participant_video'),
|
||||
'waiting_room': self.settings.get('waiting_room'),
|
||||
'owner_choice': 'myself',
|
||||
'owner_user': None,
|
||||
'host_choice': 'myself',
|
||||
'host_user': None,
|
||||
'password_visibility': 'logged_in'
|
||||
})
|
||||
return defaults
|
||||
@ -369,36 +367,20 @@ class ZoomPlugin(VCPluginMixin, IndicoPlugin):
|
||||
|
||||
def can_manage_vc_room(self, user, room):
|
||||
return (
|
||||
user == principal_from_identifier(room.data['owner']) or
|
||||
user == principal_from_identifier(room.data['host']) or
|
||||
super(ZoomPlugin, self).can_manage_vc_room(user, room)
|
||||
)
|
||||
|
||||
def _merge_users(self, target, source, **kwargs):
|
||||
super(ZoomPlugin, self)._merge_users(target, source, **kwargs)
|
||||
for room in VCRoom.query.filter(
|
||||
VCRoom.type == self.service_name, VCRoom.data.contains({'owner': source.identifier})
|
||||
VCRoom.type == self.service_name, VCRoom.data.contains({'host': source.identifier})
|
||||
):
|
||||
room.data['owner'] = target.id
|
||||
room.data['host'] = target.id
|
||||
flag_modified(room, 'data')
|
||||
|
||||
def get_notification_cc_list(self, action, vc_room, event):
|
||||
return {principal_from_identifier(vc_room.data['owner']).email}
|
||||
|
||||
def notify_owner_start_url(self, vc_room):
|
||||
user = principal_from_identifier(vc_room.data['owner'])
|
||||
to_list = {user.email}
|
||||
|
||||
template_module = get_template_module(
|
||||
'vc_zoom:emails/notify_start_url.html',
|
||||
plugin=ZoomPlugin.instance,
|
||||
vc_room=vc_room,
|
||||
event=None,
|
||||
vc_room_event=None,
|
||||
user=user
|
||||
)
|
||||
|
||||
email = make_email(to_list, template=template_module, html=True)
|
||||
send_email(email, None, 'Zoom')
|
||||
return {principal_from_identifier(vc_room.data['host']).email}
|
||||
|
||||
def _times_changed(self, sender, obj, **kwargs):
|
||||
from indico.modules.events.models.events import Event
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
{% block plugin_specific_info %}
|
||||
<li>
|
||||
<strong>Host</strong>:
|
||||
<span>{{ (vc_room.data.owner|decodeprincipal).full_name }}</span>
|
||||
<span>{{ (vc_room.data.host|decodeprincipal).full_name }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Zoom URL</strong>:
|
||||
|
||||
25
indico_vc_zoom/templates/emails/notify_new_host.html
Normal file
25
indico_vc_zoom/templates/emails/notify_new_host.html
Normal file
@ -0,0 +1,25 @@
|
||||
{% extends 'emails/base.html' %}
|
||||
|
||||
{% block subject -%}
|
||||
[{{ plugin.friendly_name }}] You are now hosting '{{ vc_room.name }}'
|
||||
{%- endblock %}
|
||||
|
||||
{% block header -%}
|
||||
<p>
|
||||
<strong>{{ actor.full_name }}</strong> has just made you the host of Zoom Meeting '{{ vc_room.name }}'.
|
||||
</p>
|
||||
{% if plugin.settings.get('send_host_url') %}
|
||||
<p>
|
||||
<strong>ATTENTION:</strong>
|
||||
You should not share this URL with anyone, since it will allow them to become meeting hosts!
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Host URL</strong>:
|
||||
<a href="{{ vc_room.data.start_url }}">{{ vc_room.data.start_url }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% block custom_footer %}{% endblock %}
|
||||
{%- endblock %}
|
||||
@ -1,7 +1,7 @@
|
||||
{% extends 'emails/base.html' %}
|
||||
|
||||
{% block subject -%}
|
||||
Zoom Host URL - {{ vc_room.name }}
|
||||
[{{ plugin.friendly_name }}] Host URL - {{ vc_room.name }}
|
||||
{%- endblock %}
|
||||
|
||||
{% block header -%}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
{% from '_clipboard_input.html' import clipboard_input %}
|
||||
{% set owner = vc_room.data.owner %}
|
||||
{% set host = vc_room.data.host %}
|
||||
{% set phone_link = settings.get('zoom_phone_link') %}
|
||||
<dl>
|
||||
<dt>{% trans %}Meeting ID{% endtrans %}</dt>
|
||||
<dd>{{ vc_room.data.zoom_id }}</dd>
|
||||
{% if owner %}
|
||||
<dt>{% trans %}Owner{% endtrans %}</dt>
|
||||
<dd>{{ (owner|decodeprincipal).full_name }}</dd>
|
||||
{% if host %}
|
||||
<dt>{% trans %}Host{% endtrans %}</dt>
|
||||
<dd>{{ (host|decodeprincipal).full_name }}</dd>
|
||||
{% endif %}
|
||||
{% if event_vc_room.data.password_visibility == 'everyone' or is_manager or
|
||||
(session.user and event_vc_room.data.password_visibility == 'logged_in') %}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
{% from '_password.html' import password %}
|
||||
{% from '_clipboard_input.html' import clipboard_input %}
|
||||
{% set owner = vc_room.data.owner %}
|
||||
{% set host = vc_room.data.host %}
|
||||
{% set phone_link = settings.get('zoom_phone_link') %}
|
||||
<dl class="details-container">
|
||||
<dt>{% trans %}Zoom Meeting ID{% endtrans %}</dt>
|
||||
<dd>{{ vc_room.data.zoom_id }}</dd>
|
||||
<dt>{% trans %}Owner{% endtrans %}</dt>
|
||||
<dt>{% trans %}Host{% endtrans %}</dt>
|
||||
<dd>
|
||||
{{ (owner|decodeprincipal).full_name }}
|
||||
{{ (host|decodeprincipal).full_name }}
|
||||
</dd>
|
||||
<dt>{% trans %}Linked to{% endtrans %}</dt>
|
||||
<dd>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user