def create(_ctxt, entity_type, entity_id): url = flask.request.form.get('url') public_id = flask.request.form.get('public_id') redirect_url = get_image_redirect_url(entity_type, entity_id) try: with models.transaction() as session: i = models.Image(image_url=url, public_id=public_id) session.add(i) with models.transaction() as session: if entity_type == 'user': ui = models.UserImage(image_id=i.id, user_id=entity_id) session.add(ui) elif entity_type == 'group': gi = models.GroupImage(image_id=i.id, group_id=entity_id) session.add(gi) elif entity_type == 'org': oi = models.OrganizationImage(image_id=i.id, organization_id=entity_id) session.add(oi) flask.flash("Image saved successfully", "success") except Exception: message = "Failed to save image, please try again later" LOG.exception(message) flask.flash(message, "danger") return flask.redirect(redirect_url)
def meeting_create(_ctxt, group_id): form = forms.GroupMeetingForm(flask.request.form) group = models.Group.get(group_id) if not group: flask.flash('Group not found, please try again.', 'danger') return flask.redirect(flask.url_for('index')) if not form.validate(): app_utils.flash_errors(form) else: try: with models.transaction() as session: cohosts = session.query(models.GroupMember).filter( models.GroupMember.group_id == group_id).filter( models.GroupMember.can_cohost_meeting == 1).all() zoom = meeting.ZoomMeetingDriver() meeting_info = { 'current_user': current_user, 'cohosts': cohosts, 'topic': form.topic.data, 'type': form.meeting_type.data, 'duration': form.duration.data, 'start_time': form.start_datetime.data } result = zoom.schedule_meeting(**meeting_info) utc_meeting_start = helper.get_utc_date_time( current_user.timezone, form.start_datetime.data) with models.transaction() as session: m = models.ZoomMeeting( meeting_id=result['id'], duration=form.duration.data, meeting_start=utc_meeting_start, repeat_type=form.meeting_type.data, topic=form.topic.data, start_url=result['start_url'], join_url=result['join_url'], repeat_end_date=form.repeat_end_date.data, user_id=current_user.id, group_id=group_id) session.add(m) flask.flash( "You successfully created your meeting! " "Your meeting ID is {}".format(m.meeting_id), 'success') except Exception: message = "Failed to create meeting for group {}".format( group.name) LOG.exception(message) flask.flash(message, 'danger') return flask.redirect(flask.url_for('.show', group_id=group_id))
def delete(_ctxt, image_id, entity_type): form = forms.ConfirmForm(flask.request.form) if not form.validate(): app_utils.flash_errors(form) else: try: with models.transaction() as session: if entity_type == 'user': ui = models.UserImage.get_by_image_id(image_id) session.delete(ui) elif entity_type == 'group': gi = models.GroupImage.get_by_image_id(image_id) session.delete(gi) elif entity_type == 'organization': oi = models.OrganizationImage.get_by_image_id(image_id) session.delete(oi) i = models.Image.get(image_id) session.delete(i) CloudinaryHandler().delete([i.public_id]) flask.flash("Image deleted successfully", "success") except Exception: message = "Failed to delete image, please try again later" LOG.exception(message) flask.flash(message, "danger") return flask.redirect(flask.request.referrer)
def create(_ctxt, group_id=None, organization_id=None): entity, entity_id, values = get_context(group_id, organization_id) form = forms.LinkForm(flask.request.form) can_edit_entity = getattr(current_user, 'can_edit_' + entity) if not can_edit_entity(entity_id) or not form.validate(): app_utils.flash_errors(form) else: try: with models.transaction() as session: link = models.Link(link_type_id=form.link_type.data.id, url=form.link.data, **(values if group_id else { 'organization_id': entity_id })) session.add(link) flask.flash( 'You successfully added %s %s link!' % ('a' if group_id else 'an', entity), 'success') except Exception: LOG.exception("Failed to create link for %s '%s'", entity, entity_id) flask.flash( """There was an error adding the %s link. Please try again later""" % entity, 'danger') return flask.redirect(flask.url_for('%ss.edit' % entity, **values))
def document_upload(group_id, form): if 'file' not in flask.request.files: flask.flash('Please provide a file', 'danger') return flask.redirect(flask.url_for('.show', group_id=group_id)) doc = flask.request.files['file'] try: doc_handler = filehandler.S3FileHandler(doc, form.filename.data) url = doc_handler.save() with models.transaction() as session: d = models.GroupDocument(group_id=group_id, friendly_name=doc_handler.filename, file_url=url) session.add(d) flask.flash('You successfully uploaded a document!', 'success') return flask.redirect(flask.url_for('.show', group_id=group_id)) except exc.InvalidFileExtensionException as e: LOG.exception("Invalid File Extension") flask.flash(str(e), 'danger') except exc.FileAlreadyExists as e: LOG.exception("File Already Exists") flask.flash(str(e), 'danger') except Exception: LOG.exception("Failed to save the document for group %s", str(group_id)) flask.flash( 'There was an error uploading the document. Please try' ' again later.', 'danger') return flask.redirect(flask.url_for('.show', group_id=group_id))
def handle_zoom_information(self, user): try: result = self._client.user.get_by_email( email=user.email, login_type=self.SNS_ZOOM_LOGIN_TYPE) LOG.debug("RESULT: get zoom client by email: %s", result.json()) if result.json().get('error'): result = self._client.user.cust_create( email=user.email, type=self.PRO_USER_TYPE, first_name=user.first_name, last_name=user.last_name) LOG.debug("RESULT: create zoom customer: %s", result.json()) except Exception: LOG.exception("Issue creating zoom customer for user: %s", user.full_name_and_email) raise try: # TODO: move database update out into flask route # means we need to detect user property in flask route, update # user and then call schedule_meeting with models.transaction() as session: user.zoom_user_id = result.json()['id'] session.add(user) except Exception: LOG.exception("Issue adding zoom_user_id to user: %s", user.full_name_and_email) raise
def user_delete(_ctxt, org_id, user_id): form = forms.ConfirmForm(flask.request.form) if not form.validate(): app_utils.flash_errors(form) else: try: with models.transaction() as session: ou = helper.get_member(org_id, user_id) LOG.debug("Removing user '%s' from org '%s'", user_id, org_id) session.delete(ou) if form.confirm_checkbox.data: org_groups = session.query( models.OrganizationGroup).filter( models.OrganizationGroup.organization_id == org_id).all() for og in org_groups: gu = session.query(models.GroupMember).filter( models.GroupMember.group_id == og.group_id).filter( models.GroupMember.user_id == user_id).first() if gu: LOG.debug("Removing user '%s' from group '%s'", user_id, og.group_id) session.delete(gu) flask.flash('Member removed successfully!', 'success') except Exception: LOG.exception("Failed to remove user '%s' from org '%s'", user_id, org_id) flask.flash('Failed to remove member.', 'danger') return flask.redirect(flask.url_for('.edit', org_id=org_id))
def view_all(_ctxt): with models.transaction() as session: cls = models.Organization query = session.query(cls).filter( cls.activated_at.isnot(None)).order_by(cls.name) context = dict(organizations=query.all(), contact_form=forms.ContactForm()) return flask.render_template('organization/all.html', **context)
def search(_ctxt): form = forms.OrgSearchForm(flask.request.form) context = dict(form=form) if flask.request.method == 'POST': if not form.validate(): app_utils.flash_errors(form) else: with models.transaction() as session: filters = [models.Organization.activated_at.isnot(None)] form_pairs = { "name": models.Organization.name, "city": models.Address.city, "state": models.Address.state, "zip_code": models.Address.zip_code } for form_field, model_field in form_pairs.items(): form_data = form[form_field].data if form_data: filters.append( model_field.like('{}%'.format(form_data))) query = session.query(models.Organization).join( models.Address, models.Address.id == models.Organization.address_id).filter(*filters).order_by( models.Organization.name) context['orgs'] = query.all() return flask.render_template('organization/search.html', **context) return flask.render_template('organization/search.html', **context)
def notify_join(self, user_to, org): try: with models.transaction() as session: nt = session.query(models.NotificationType).filter( models.NotificationType.description.like( '%Join Org%')).first() notification = models.Notification( notification_type_id=nt.id, user_to_id=user_to.id, user_from_id=current_user.id, organization_id=org.id) reminder = self.send_notification(notification) email_type = email.InviteExistingUserToOrgEmail() self.send_email(email_type, current_user.email, user_to.email, reminder, org=org) flask.flash( 'Notification sent to member for acceptance or' ' rejection.', 'success') except Exception: LOG.exception('Failed to invite member to org %s', org.id) flask.flash( 'There was an error adding the member. Please try' ' again later.', 'danger')
def notify_join(self, user_to, group): try: with models.transaction() as session: nt = session.query(models.NotificationType).filter( models.NotificationType.description.like( '%Join Group%')).first() notification = models.Notification( notification_type_id=nt.id, user_to_id=user_to.id, user_from_id=current_user.id, group_id=group.id) reminder = self.send_notification(notification) email_type = email.InviteExistingUserToGroupEmail() self.send_email(email_type, current_user.email, user_to.email, reminder, group=group) flask.flash( "Notification sent to member for acceptance or" " rejection.", "success") except Exception: LOG.exception("Failed to invite member to group %s", group.id) flask.flash( "There was an error adding the member. Please try" " again later.", "danger")
def group_leave(_ctxt, user_id, group_id): form = forms.ConfirmForm(flask.request.form) if not form.validate(): app_utils.flash_errors(form) else: group_member = models.Session.query(models.GroupMember).filter( models.GroupMember.group_id == group_id).filter( models.GroupMember.user_id == user_id).first() group_leaders = models.Session.query(models.User).join( models.GroupMember, models.User.id == models.GroupMember.user_id).join( models.Group, models.Group.id == models.GroupMember.group_id).join( models.GroupRole, models.GroupRole.id == models.GroupMember.role_id ).filter(models.Group.id == group_id).filter( models.GroupRole.description == 'Group Leader').all() if (group_member and group_leaders and len(group_leaders) == 1 and group_leaders[0].id == user_id): flask.flash( 'Unable to leave group when you are the last' ' group leader.', 'danger') elif group_member: with models.transaction() as session: session.delete(group_member) session.commit() flask.flash('You left group successfully!', 'success') else: flask.flash('Error leaving group.', 'danger') return flask.redirect(flask.url_for('.show', user_id=user_id))
def send_notification(notification): verified_notification = notification.prevent_duplicate() if verified_notification: with models.transaction() as session: session.add(verified_notification) else: return 'blocked' return bool(verified_notification != notification)
def google_doc_add(group_id, googledoc): with models.transaction() as session: d = models.GroupDocument(group_id=group_id, friendly_name=googledoc.filename.data, file_url=googledoc.link.data) session.add(d) flask.flash('Link Successfully Added!', 'success') return
def creation_workflow(self, form, org): with models.transaction() as session: if form.user_is_leader.data: leader = current_user else: address = models.User.get_email_from_full_name_and_email( form.owner.data) leader = models.User.get_by_email(address) group_leaders = org.group_leaders if (leader not in group_leaders) and not org.is_in_trial() and ( org.available_licenses < 1): return self.need_leaders(org.id) new_group = models.Group( name=form.name.data, description=form.description.data, member_limit=form.member_limit.data, privacy_setting_id=form.privacy_settings.data, anonymous=form.anonymous.data, gender_focus=form.gender_focus.data) if form.age_range.data: new_group.age_range_id = form.age_range.data.id if form.group_category.data: new_group.group_type_id = form.group_category.data.id session.add(new_group) with models.transaction() as session: organization_group = models.OrganizationGroup( organization_id=form.org.data, group_id=new_group.id) session.add(organization_group) new_group_meet_times = [] for group_meet_time_type in form.meet_times.data: new_group_meet_time = models.GroupMeetTime( group_id=new_group.id, meet_time_type_id=group_meet_time_type.id) new_group_meet_times.append(new_group_meet_time) if new_group_meet_times: session.add_all(new_group_meet_times) group_role = session.query(models.GroupRole).filter( models.GroupRole.description == 'Group Leader').first() group_member = models.GroupMember(group_id=new_group.id, user_id=leader.id, role_id=group_role.id) form.owner.default = current_user.id session.add(group_member) flask.flash("Group {} created successfully".format(form.name.data)) return flask.redirect(flask.url_for('.show', group_id=new_group.id))
def handle(self): LOG.debug("Handling acknowledge group join request") with models.transaction() as session: gr = models.GroupRole.get_by_description('Member') gm = models.GroupMember( user_id=self.notification.user_from_id, group_id=self.notification.group_id, role_id=gr.id) session.add(gm)
def handle(self): LOG.debug("Handling accept invitation to join group") with models.transaction() as session: gr = models.GroupRole.get_by_description('Member') gm = models.GroupMember( user_id=self.notification.user_to_id, group_id=self.notification.group_id, role_id=gr.id) session.add(gm)
def handle(self): LOG.debug("Handling accept organization join request") with models.transaction() as session: org_role = models.OrganizationRole.get_by_description('Member') om = models.OrganizationMember( user_id=self.notification.user_from_id, organization_id=self.notification.organization_id, role_id=org_role.id) session.add(om)
def get_org_groups(org_id): with models.transaction() as session: org_groups = session.query(models.Group).join( models.OrganizationGroup, models.OrganizationGroup.group_id == models.Group.id).join( models.Organization, models.Organization.id == models.OrganizationGroup.organization_id).filter( models.Organization.id == org_id) return org_groups.all()
def query_users_with_type(org_id): with models.transaction() as session: query = session.query(models.User).join( models.OrganizationMember, models.User.id == models.OrganizationMember.user_id).join( models.Organization, models.Organization.id == models.OrganizationMember.organization_id).join( models.OrganizationRole, models.OrganizationRole.id == models.OrganizationMember.role_id).filter( models.Organization.id == org_id) return query
def handle(self): LOG.debug("Handling accept organization creation request") with models.transaction() as session: o = models.Organization.get(self.notification.organization_id) o.activated_at = datetime.datetime.utcnow() org_role = models.OrganizationRole.get_by_description('Owner') om = models.OrganizationMember( user_id=self.notification.user_from_id, organization_id=self.notification.organization_id, role_id=org_role.id) session.add(om)
def request_new_organization_workflow(self, form): try: user = current_user LOG.debug("New organization owner: %s", user.full_name_and_email) org = models.Organization() self.populate_org(org, form) with models.transaction() as session: super_admins = session.query(models.User).filter( models.User.super_admin == sa.sql.expression.true()).all() if super_admins: LOG.debug( 'Super admins to be notified of org' ' creation request: %s', super_admins) session.add(org) session.commit() LOG.debug('Organization: %s:%s', org.id, org.name) ocr = models.NotificationType.get_by_description( 'Organization Creation Request') reminder = None for admin in super_admins: notification = models.Notification( user_to_id=admin.id, user_from_id=current_user.id, notification_type_id=ocr.id, organization_id=org.id) reminder = self.send_notification(notification) LOG.debug('Org creation notification sent to %s', admin.email) mail_to = ','.join([u.email for u in super_admins]) email_type = email.OrgCreationRequestEmail() self.send_email(email_type, current_user.email, mail_to, reminder, org=org) flask.flash( 'Organization creation request sent successfully.', 'success') else: LOG.debug( 'Unable to send organization request for %s due to no' ' super admins presnet. Organization name: %s', current_user.email, org.name) flask.flash( 'No super admins present, unable to send organization' ' creation request. Please try again later.', 'danger') return flask.redirect(flask.url_for('index')) except Exception: LOG.exception('Failed to request organization creation') flask.flash('There was an error requesting organization creation', 'danger') return flask.redirect(flask.url_for('index'))
def update(_ctxt, group_id): form = forms.GroupEditForm(flask.request.form) form.privacy_settings.choices = forms.privacy_setting_choices() if not form.validate(): app_utils.flash_errors(form) else: try: with models.transaction() as session: update_group = models.Group.get(group_id) if update_group: # TODO I wish form.populate_obj worked here, but it doesn't update_group.description = form.description.data update_group.member_limit = form.member_limit.data update_group.privacy_setting_id = form.privacy_settings.data update_group.anonymous = form.anonymous.data update_group.age_range_id = (form.age_range.data.id if form.age_range.data else None) update_group.gender_focus = form.gender_focus.data group_meet_times = [] for m in form.meet_times.data: group_meet_time = models.GroupMeetTime( group_id=group_id, meet_time_type_id=m.id) group_meet_times.append(group_meet_time) # NOTE: We can't just .clear(). It actually only sets # the group_id column to NULL on each record for this user, # then we issue N inserts after. Instead we can either # 1) delete then insert # 2) set math, delete if necessary, insert if necessary # Considering there's no downside to deleting, and it's # simpler, that's the approach below. for mt in update_group.meet_times: session.delete(mt) update_group.meet_times.extend(group_meet_times) update_group.group_type_id = (form.group_category.data.id if form.group_category.data else None) session.add(update_group) flask.flash('You successfully updated the group profile!', 'success') else: flask.flash('No group found to update', 'danger') return flask.redirect( flask.url_for('.show', group_id=group_id)) except Exception: LOG.exception("Failed to update group profile for group " "%s", group_id) flask.flash('There was an error updating the group profile!', 'danger') return flask.redirect(flask.url_for('.edit', group_id=group_id))
def query_users_with_phone(group_id): with models.transaction() as session: users_query = session.query(models.User).join( models.GroupMember, models.User.id == models.GroupMember.user_id).join( models.Group, models.Group.id == models.GroupMember.group_id).join( models.GroupRole, models.GroupMember.role_id == models.GroupRole.id).filter( sa.and_(models.Group.id == group_id, models.User.opt_in_texts == 1, models.User.phone_number.isnot(None))) return users_query
def autocomplete(_ctxt): prefix = flask.request.args.get('prefix') with models.transaction() as session: query = session.query(models.Organization).filter( sa.and_( sa.or_( models.Organization.description.like( '%{}%'.format(prefix)), models.Organization.name.like('%{}%'.format(prefix))), models.Organization.activated_at.isnot(None))).order_by( models.Organization.name) formatted_orgs = [dict(id=str(o.id), name=o.name) for o in query.all()] return flask.jsonify(formatted_orgs)
def query_users(group_id): with models.transaction() as session: users_query = session.query( models.User, models.GroupMember, models.GroupRole).join( models.GroupMember, models.User.id == models.GroupMember.user_id).join( models.Group, models.Group.id == models.GroupMember.group_id).join( models.GroupRole, models.GroupRole.id == models.GroupMember.role_id).filter( models.Group.id == group_id).order_by( models.GroupRole.priority) return users_query
def email_leaders(_ctxt, group_id): form = forms.GroupLeadersEmailForm(flask.request.form) if not form.validate(): app_utils.flash_errors(form) else: with models.transaction() as session: group_users = session.query(models.User).join( models.GroupMember, models.User.id == models.GroupMember.user_id).join( models.Group, models.Group.id == models.GroupMember.group_id).join( models.GroupRole, models.GroupRole.id == models.GroupMember.role_id).filter( sa.and_( models.Group.id == group_id, models.GroupRole.description == 'Group Leader')).all() subject = form.subject.data # TODO: need to wrap this data in a cleaner (NEVER TRUST USER INPUT) message = form.message.data group_leader_emails = [u.email for u in group_users] group_leader_emails = ','.join(group_leader_emails) if not group_leader_emails: flask.flash( 'There are not currently any group leaders for' ' this group. No message sent' ' Please try again shortly.', 'danger') else: try: group = models.Group.get(group_id) mail_content = { 'to': group_leader_emails, 'subject': subject, 'message': message, 'user': current_user, 'group': group } group_leaders_email = email.GroupLeadersEmail() group_leaders_email.send(current_user.email, group_leader_emails, **mail_content) flask.flash('You successfully sent your email message.', 'success') except Exception: LOG.exception("Error sending email to group leaders") flask.flash( 'There was a problem sending your message.' ' Sorry for the inconvenience.' ' We will fix this as soon as we can.' ' Please try again shortly.', 'danger') return flask.redirect(flask.url_for('.show', group_id=group_id))
def get_similar(notification): with models.transaction() as session: query = session.query( models.Notification).filter( sa.and_( models.Notification.notification_type_id == notification.notification_type_id, models.Notification.user_from_id == notification.user_from_id, models.Notification.group_id == notification.group_id, models.Notification.organization_id == notification.organization_id)) return query.all()
def join_request(_ctxt, org_id): form = forms.ConfirmForm(flask.request.form) if not form.validate(): return flask.redirect( flask.redirect(flask.url_for('.show', org_id=org_id))) try: with models.transaction() as session: existing_om = helper.get_member(org_id, current_user.id) if existing_om: flask.flash('You are already a member of this organization', 'danger') return flask.redirect(flask.url_for('.show', org_id=org_id)) org = models.Organization.get(org_id) if not org: flask.flash('No organization found', 'danger') return flask.redirect(flask.url_for('.show', org_id=org_id)) org_admins_and_owners = helper.get_leaders(org_id) if not org_admins_and_owners: flask.flash( 'There is not currently any organization' ' owners/administrators for this organization. No request' ' sent Please try again shortly.', 'danger') else: notification_type = session.query( models.NotificationType).filter( models.NotificationType.description == 'Organization Join Request').first() for user in org_admins_and_owners: notification = models.Notification( user_to_id=user.id, user_from_id=current_user.id, notification_type_id=notification_type.id, organization_id=org_id) reminder = helper.send_notification(notification) mail_to = ','.join([u.email for u in org_admins_and_owners]) email_type = email.OrgJoinRequestEmail() helper.send_email(email_type, current_user.email, mail_to, reminder, org=org) flask.flash('Request to join organization successfully sent!', 'success') except Exception: LOG.exception('Failed to send group join request to organization %s', org_id) flask.flash('There was an error sending your join request!', 'danger') return flask.redirect(flask.url_for('.show', org_id=org_id))
def groups_sort(org_id, group_ids): groups_order = {} for order, group_id in enumerate(group_ids): groups_order[group_id] = order organization_groups = models.Session.query( models.OrganizationGroup).filter_by(organization_id=org_id).filter( models.OrganizationGroup.group_id.in_( groups_order.keys())).all() with models.transaction() as session: for og in organization_groups: og.order = groups_order[str(og.group_id)] session.add(og) session.commit()