예제 #1
0
    def get(self, request):
        if not admin_work_weixin_departments_check():
            error_msg = 'Feature is not enabled.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        access_token = get_work_weixin_access_token()
        if not access_token:
            logger.error('can not get work weixin access_token')
            error_msg = '获取企业微信组织架构失败'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        data = {
            'access_token': access_token,
        }
        department_id = request.GET.get('department_id', None)
        if department_id:
            data['id'] = department_id

        api_response = requests.get(WORK_WEIXIN_DEPARTMENTS_URL, params=data)
        api_response_dic = handler_work_weixin_api_response(api_response)
        if not api_response_dic:
            logger.error('can not get work weixin departments response')
            error_msg = '获取企业微信组织架构失败'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if WORK_WEIXIN_DEPARTMENT_FIELD not in api_response_dic:
            logger.error(json.dumps(api_response_dic))
            logger.error(
                'can not get department list in work weixin departments response'
            )
            error_msg = '获取企业微信组织架构失败'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        return Response(api_response_dic)
예제 #2
0
def work_weixin_oauth_connect_callback(request):
    if not work_weixin_oauth_check():
        return render_error(request, _('Feature is not enabled.'))

    code = request.GET.get('code', None)
    state = request.GET.get('state', None)
    if state != request.session.get('work_weixin_oauth_connect_state', None) or not code:
        logger.error('can not get right code or state from work weixin request')
        return render_error(request, _('Error, please contact administrator.'))

    access_token = get_work_weixin_access_token()
    if not access_token:
        logger.error('can not get work weixin access_token')
        return render_error(request, _('Error, please contact administrator.'))

    data = {
        'access_token': access_token,
        'code': code,
    }
    api_response = requests.get(WORK_WEIXIN_GET_USER_INFO_URL, params=data)
    api_response_dic = handler_work_weixin_api_response(api_response)
    if not api_response_dic:
        logger.error('can not get work weixin user info')
        return render_error(request, _('Error, please contact administrator.'))

    if not api_response_dic.get('UserId', None):
        logger.error('can not get UserId in work weixin user info response')
        return render_error(request, _('Error, please contact administrator.'))

    user_id = api_response_dic.get('UserId')
    uid = WORK_WEIXIN_UID_PREFIX + user_id
    email = request.user.username

    work_weixin_user = SocialAuthUser.objects.get_by_provider_and_uid(WORK_WEIXIN_PROVIDER, uid)
    if work_weixin_user:
        logger.error('work weixin account already exists %s' % user_id)
        return render_error(request, '出错了,此企业微信账号已被绑定')

    SocialAuthUser.objects.add(email, WORK_WEIXIN_PROVIDER, uid)

    # update user info
    if WORK_WEIXIN_USER_INFO_AUTO_UPDATE:
        user_info_data = {
            'access_token': access_token,
            'userid': user_id,
        }
        user_info_api_response = requests.get(WORK_WEIXIN_GET_USER_PROFILE_URL, params=user_info_data)
        user_info_api_response_dic = handler_work_weixin_api_response(user_info_api_response)
        if user_info_api_response_dic:
            api_user = user_info_api_response_dic
            api_user['username'] = email
            api_user['contact_email'] = api_user['email']
            update_work_weixin_user_info(api_user)

    # redirect user to page
    response = HttpResponseRedirect(request.session.get('work_weixin_oauth_connect_redirect', '/'))
    return response
예제 #3
0
    def get(self, request, department_id):
        if not admin_work_weixin_departments_check():
            error_msg = 'Feature is not enabled.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        if not request.user.admin_permissions.can_manage_user():
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        access_token = get_work_weixin_access_token()
        if not access_token:
            logger.error('can not get work weixin access_token')
            error_msg = '获取企业微信组织架构成员失败'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        data = {
            'access_token': access_token,
            'department_id': department_id,
        }
        fetch_child = request.GET.get('fetch_child', None)
        if fetch_child:
            if fetch_child not in ('true', 'false'):
                error_msg = 'fetch_child invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
            data['fetch_child'] = 1 if fetch_child == 'true' else 0

        api_response = requests.get(WORK_WEIXIN_DEPARTMENT_MEMBERS_URL,
                                    params=data)
        api_response_dic = handler_work_weixin_api_response(api_response)
        if not api_response_dic:
            logger.error('can not get work weixin department members response')
            error_msg = '获取企业微信组织架构成员失败'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if WORK_WEIXIN_DEPARTMENT_MEMBERS_FIELD not in api_response_dic:
            logger.error(json.dumps(api_response_dic))
            logger.error(
                'can not get userlist in work weixin department members response'
            )
            error_msg = '获取企业微信组织架构成员失败'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        api_user_list = api_response_dic[WORK_WEIXIN_DEPARTMENT_MEMBERS_FIELD]
        # todo filter ccnet User database
        social_auth_queryset = SocialAuthUser.objects.filter(
            provider=WORK_WEIXIN_PROVIDER,
            uid__contains=WORK_WEIXIN_UID_PREFIX)
        for api_user in api_user_list:
            uid = WORK_WEIXIN_UID_PREFIX + api_user.get('userid', '')
            api_user['contact_email'] = api_user['email']
            # #  determine the user exists
            if social_auth_queryset.filter(uid=uid).exists():
                api_user['email'] = social_auth_queryset.get(uid=uid).username
            else:
                api_user['email'] = ''

        return Response(api_response_dic)
    def do_action(self):
        # work weixin check
        if not admin_work_weixin_departments_check():
            self.log_error('Feature is not enabled.')
            return

        access_token = get_work_weixin_access_token()
        if not access_token:
            self.log_error('can not get work weixin access_token')
            return

        # list departments from work weixin
        api_department_list = self.list_departments_from_work_weixin(
            access_token)
        if api_department_list is None:
            self.log_error('获取企业微信组织架构失败')
            return
        api_department_list = sorted(api_department_list,
                                     key=lambda x: x['id'])

        self.log_debug('Total %d work-weixin departments.' %
                       len(api_department_list))

        # main
        count = 0
        exists_count = 0
        for department_obj in api_department_list:
            # check department argument
            group_name = department_obj.get('name')
            department_obj_id = department_obj.get('id')
            if department_obj_id is None or not group_name:
                continue

            # check department exist
            exist_department = ExternalDepartment.objects.get_by_provider_and_outer_id(
                WORK_WEIXIN_PROVIDER, department_obj_id)
            if exist_department:
                exists_count += 1
                continue

            # sync to db
            group = self.get_group_by_name(group_name)
            if group:
                ExternalDepartment.objects.create(
                    group_id=group.id,
                    provider=WORK_WEIXIN_PROVIDER,
                    outer_id=department_obj_id,
                )
                count += 1

        self.log_debug('%d work-weixin departments exists in db.' %
                       exists_count)
        self.log_debug('Sync %d work-weixin departments to db.' % count)
예제 #5
0
    def post(self, request):
        """import department from work weixin

        permission: IsProVersion
        """

        if not request.user.admin_permissions.can_manage_user():
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        # argument check
        department_id = request.data.get('work_weixin_department_id')
        try:
            department_id = int(department_id)
        except Exception as e:
            logger.error(e)
            error_msg = 'work_weixin_department_ids invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # is pro version and work weixin check
        if not IsProVersion or not admin_work_weixin_departments_check():
            error_msg = 'Feature is not enabled.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        access_token = get_work_weixin_access_token()
        if not access_token:
            logger.error('can not get work weixin access_token')
            error_msg = '获取企业微信组织架构失败'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # list departments from work weixin
        api_department_list = self._list_departments_from_work_weixin(
            access_token, department_id)
        if api_department_list is None:
            error_msg = '获取企业微信组织架构失败'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # list department members from work weixin
        api_user_list = self._list_department_members_from_work_weixin(
            access_token, department_id)
        if api_user_list is None:
            error_msg = '获取企业微信组织架构成员失败'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # main
        success = list()
        failed = list()
        department_map_to_group_dict = dict()

        for index, department_obj in enumerate(api_department_list):
            # check department argument
            new_group_name = department_obj.get('name')
            department_obj_id = department_obj.get('id')
            if department_obj_id is None or not new_group_name or not validate_group_name(
                    new_group_name):
                failed_msg = self._api_department_failed_msg(
                    department_obj_id, new_group_name, '部门参数错误')
                failed.append(failed_msg)
                continue

            # check parent group
            if index == 0:
                parent_group_id = -1
            else:
                parent_department_id = department_obj.get('parentid')
                parent_group_id = department_map_to_group_dict.get(
                    parent_department_id)

            if parent_group_id is None:
                failed_msg = self._api_department_failed_msg(
                    department_obj_id, new_group_name, '父级部门不存在')
                failed.append(failed_msg)
                continue

            # check department exist by group name
            exist, exist_group = self._admin_check_group_name_conflict(
                new_group_name)
            if exist:
                department_map_to_group_dict[
                    department_obj_id] = exist_group.id
                failed_msg = self._api_department_failed_msg(
                    department_obj_id, new_group_name, '部门已存在')
                failed.append(failed_msg)
                continue

            # import department
            try:
                group_id = ccnet_api.create_group(
                    new_group_name,
                    DEPARTMENT_OWNER,
                    parent_group_id=parent_group_id)

                seafile_api.set_group_quota(group_id, -2)

                department_map_to_group_dict[department_obj_id] = group_id
                success_msg = self._api_department_success_msg(
                    department_obj_id, new_group_name, group_id)
                success.append(success_msg)
            except Exception as e:
                logger.error(e)
                failed_msg = self._api_department_failed_msg(
                    department_obj_id, new_group_name, '部门导入失败')
                failed.append(failed_msg)

        # todo filter ccnet User database
        social_auth_queryset = SocialAuthUser.objects.filter(
            provider=WORK_WEIXIN_PROVIDER,
            uid__contains=WORK_WEIXIN_UID_PREFIX)

        # import api_user
        for api_user in api_user_list:
            uid = WORK_WEIXIN_UID_PREFIX + api_user.get('userid', '')
            api_user['contact_email'] = api_user['email']
            api_user_name = api_user.get('name')

            #  determine the user exists
            if social_auth_queryset.filter(uid=uid).exists():
                email = social_auth_queryset.get(uid=uid).username
            else:
                # create user
                email = gen_user_virtual_id()
                create_user_success = _import_user_from_work_weixin(
                    email, api_user)
                if not create_user_success:
                    failed_msg = self._api_user_failed_msg(
                        '', api_user_name, department_id, '导入用户失败')
                    failed.append(failed_msg)
                    continue

            # bind user to department
            api_user_department_list = api_user.get('department')
            for department_obj_id in api_user_department_list:
                group_id = department_map_to_group_dict.get(department_obj_id)
                if group_id is None:
                    # the api_user also exist in the brother department which not import
                    continue

                if ccnet_api.is_group_user(group_id, email):
                    failed_msg = self._api_user_failed_msg(
                        email, api_user_name, department_obj_id, '部门成员已存在')
                    failed.append(failed_msg)
                    continue

                try:
                    ccnet_api.group_add_member(group_id, DEPARTMENT_OWNER,
                                               email)
                    success_msg = self._api_user_success_msg(
                        email, api_user_name, department_obj_id, group_id)
                    success.append(success_msg)
                except Exception as e:
                    logger.error(e)
                    failed_msg = self._api_user_failed_msg(
                        email, api_user_name, department_id, '导入部门成员失败')
                    failed.append(failed_msg)

        return Response({
            'success': success,
            'failed': failed,
        })
예제 #6
0
def work_weixin_oauth_callback(request):
    if not work_weixin_oauth_check():
        return render_error(request, _('Feature is not enabled.'))

    code = request.GET.get('code', None)
    state = request.GET.get('state', None)
    if state != request.session.get('work_weixin_oauth_state',
                                    None) or not code:
        logger.error(
            'can not get right code or state from work weixin request')
        return render_error(request, _('Error, please contact administrator.'))

    access_token = get_work_weixin_access_token()
    if not access_token:
        logger.error('can not get work weixin access_token')
        return render_error(request, _('Error, please contact administrator.'))

    data = {
        'access_token': access_token,
        'code': code,
    }
    api_response = requests.get(WORK_WEIXIN_GET_USER_INFO_URL, params=data)
    api_response_dic = handler_work_weixin_api_response(api_response)
    if not api_response_dic:
        logger.error('can not get work weixin user info')
        return render_error(request, _('Error, please contact administrator.'))

    if not api_response_dic.get('UserId', None):
        logger.error('can not get UserId in work weixin user info response')
        return render_error(request, _('Error, please contact administrator.'))

    user_id = api_response_dic.get('UserId')
    uid = WORK_WEIXIN_UID_PREFIX + user_id

    work_weixin_user = SocialAuthUser.objects.get_by_provider_and_uid(
        WORK_WEIXIN_PROVIDER, uid)
    if work_weixin_user:
        email = work_weixin_user.username
        is_new_user = False
    else:
        email = gen_user_virtual_id()
        SocialAuthUser.objects.add(email, WORK_WEIXIN_PROVIDER, uid)
        is_new_user = True

    try:
        user = auth.authenticate(remote_user=email)
    except User.DoesNotExist:
        user = None

    if not user:
        return render_error(
            request,
            _('Error, new user registration is not allowed, please contact administrator.'
              ))

    # update user info
    if is_new_user or WORK_WEIXIN_USER_INFO_AUTO_UPDATE:
        user_info_data = {
            'access_token': access_token,
            'userid': user_id,
        }
        user_info_api_response = requests.get(WORK_WEIXIN_GET_USER_PROFILE_URL,
                                              params=user_info_data)
        user_info_api_response_dic = handler_work_weixin_api_response(
            user_info_api_response)
        if user_info_api_response_dic:
            api_user = user_info_api_response_dic
            api_user['username'] = email
            api_user['contact_email'] = api_user['email']
            update_work_weixin_user_info(api_user)

    if not user.is_active:
        return render_error(
            request,
            _('Your account is created successfully, please wait for administrator to activate your account.'
              ))

    # User is valid.  Set request.user and persist user in the session
    # by logging the user in.
    request.user = user
    auth.login(request, user)

    # generate auth token for Seafile client
    api_token = get_api_token(request)

    # redirect user to page
    response = HttpResponseRedirect(
        request.session.get('work_weixin_oauth_redirect', '/'))
    response.set_cookie('seahub_auth', user.username + '@' + api_token.key)
    return response
예제 #7
0
    def do_action(self):
        # check before start
        if not work_weixin_notifications_check():
            self.log_error('work weixin notifications settings check failed')
            return

        access_token = get_work_weixin_access_token()
        if not access_token:
            self.log_error('can not get access_token')
            return

        notice_url = WORK_WEIXIN_NOTIFICATIONS_URL + '?access_token=' + access_token
        detail_url = DTABLE_WEB_SERVICE_URL

        # start
        now = datetime.utcnow()
        today = datetime.utcnow().replace(hour=0).replace(minute=0). \
            replace(second=0).replace(microsecond=0)

        # 1. get all users who are connected work weixin
        socials = SocialAuthUser.objects.filter(
            provider=WORK_WEIXIN_PROVIDER,
            uid__contains=WORK_WEIXIN_UID_PREFIX)
        users = [(x.username, x.uid[len(WORK_WEIXIN_UID_PREFIX):])
                 for x in socials]
        self.log_info('Found %d users' % len(users))
        if not users:
            return

        user_uid_map = dict()
        for username, uid in users:
            user_uid_map[username] = uid

        # 2. get previous time that command last runs
        try:
            cmd_last_check = CommandsLastCheck.objects.get(
                command_type=self.label)
            self.log_debug('Last check time is %s' % cmd_last_check.last_check)

            last_check_dt = cmd_last_check.last_check

            cmd_last_check.last_check = now
            cmd_last_check.save()
        except CommandsLastCheck.DoesNotExist:
            last_check_dt = today
            self.log_debug('Create new last check time: %s' % now)
            CommandsLastCheck(command_type=self.label, last_check=now).save()

        # 3. get all unseen row comments for those users
        user_list = list(user_uid_map.keys())
        with connection.cursor() as cursor:
            cursor.execute(
                "SELECT * FROM dtable_notifications WHERE created_at > %s"
                "AND seen = FALSE AND username IN %s",
                [last_check_dt, user_list])
            rows = cursor.fetchall()

        if len(rows) == 0:
            return
        user_notices = {}
        for row in rows:
            if row[1] not in user_notices:
                user_notices[row[1]] = [row]
            else:
                user_notices[row[1]].append(row)

        cur_language = translation.get_language()
        translation.activate('zh-cn')  # set language to zh-cn
        self.log_info('Set language to zh-cn')

        # 4. send msg to users
        site_name = get_site_name()
        for username, uid in users:
            notices = user_notices.get(username, [])
            count = len(notices)
            if count == 0:
                continue

            title = ungettext(
                "\n"
                "You've got 1 new notice on %(site_name)s:\n", "\n"
                "You've got %(num)s new notices on %(site_name)s:\n",
                count) % {
                    'num': count,
                    'site_name': site_name,
                }
            content = '\n'.join([format_notice(x) for x in notices])
            self.send_work_weixin_msg(uid, title, content, detail_url,
                                      notice_url)

        translation.activate(cur_language)  # reset language
        self.log_info('Reset language success')
예제 #8
0
    def do_action(self):
        # check before start
        if not work_weixin_notifications_check():
            self.log_error('work weixin notifications settings check failed')
            return

        access_token = get_work_weixin_access_token()
        if not access_token:
            self.log_error('can not get access_token')

        self.work_weixin_notifications_url = WORK_WEIXIN_NOTIFICATIONS_URL + '?access_token=' + access_token
        self.detail_url = get_site_scheme_and_netloc().rstrip('/') + reverse(
            'user_notification_list')
        site_name = get_site_name()

        # start
        now = datetime.now()
        today = datetime.now().replace(hour=0).replace(minute=0).replace(
            second=0).replace(microsecond=0)

        # 1. get all users who are connected work weixin
        socials = SocialAuthUser.objects.filter(
            provider=WORK_WEIXIN_PROVIDER,
            uid__contains=WORK_WEIXIN_UID_PREFIX)
        users = [(x.username, x.uid[len(WORK_WEIXIN_UID_PREFIX):])
                 for x in socials]
        self.log_info('Found %d users' % len(users))
        if not users:
            return

        user_uid_map = {}
        for username, uid in users:
            user_uid_map[username] = uid

        # 2. get previous time that command last runs
        try:
            cmd_last_check = CommandsLastCheck.objects.get(
                command_type=self.label)
            self.log_debug('Last check time is %s' % cmd_last_check.last_check)

            last_check_dt = cmd_last_check.last_check

            cmd_last_check.last_check = now
            cmd_last_check.save()
        except CommandsLastCheck.DoesNotExist:
            last_check_dt = today
            self.log_debug('Create new last check time: %s' % now)
            CommandsLastCheck(command_type=self.label, last_check=now).save()

        # 3. get all unseen notices for those users
        qs = UserNotification.objects.filter(
            timestamp__gt=last_check_dt).filter(seen=False).filter(
                to_user__in=list(user_uid_map.keys()))
        self.log_info('Found %d notices' % qs.count())
        if qs.count() == 0:
            return

        user_notices = {}
        for q in qs:
            if q.to_user not in user_notices:
                user_notices[q.to_user] = [q]
            else:
                user_notices[q.to_user].append(q)

        # save current language
        cur_language = translation.get_language()
        # active zh-cn
        translation.activate('zh-cn')
        self.log_info('the language is set to zh-cn')

        # 4. send msg to users
        for username, uid in users:
            notices = user_notices.get(username, [])
            count = len(notices)
            if count == 0:
                continue

            title = ungettext(
                "\n"
                "You've got 1 new notice on %(site_name)s:\n", "\n"
                "You've got %(num)s new notices on %(site_name)s:\n",
                count) % {
                    'num': count,
                    'site_name': site_name,
                }

            content = ''.join([wrap_div(x.format_msg()) for x in notices])
            self.send_work_weixin_msg(uid, title, content)

        # reset language
        translation.activate(cur_language)
        self.log_info('reset language success')
    def do_action(self):

        if not ENABLE_DINGTALK and not ENABLE_WORK_WEIXIN:
            self.log_info('No social account enabled')
            return

        dingtalk_access_token = ''
        work_weixin_access_token = ''

        if ENABLE_DINGTALK:

            dingtalk_access_token = dingtalk_get_access_token()
            if not dingtalk_access_token:
                self.log_error('can not get access token for dingtalk')
            else:
                self.dingtalk_message_send_to_conversation_url = DINGTALK_MESSAGE_SEND_TO_CONVERSATION_URL + \
                        '?access_token=' + dingtalk_access_token
                self.detail_url = get_site_scheme_and_netloc().rstrip(
                    '/') + reverse('user_notification_list')

        if ENABLE_WORK_WEIXIN:

            work_weixin_access_token = get_work_weixin_access_token()
            if not work_weixin_access_token:
                self.log_error('can not get access token for work weixin')
            else:
                self.work_weixin_notifications_url = WORK_WEIXIN_NOTIFICATIONS_URL + \
                        '?access_token=' + work_weixin_access_token
                self.detail_url = get_site_scheme_and_netloc().rstrip(
                    '/') + reverse('user_notification_list')

        if not dingtalk_access_token and not work_weixin_access_token:
            return

        # save current language
        cur_language = translation.get_language()
        # active zh-cn
        translation.activate('zh-cn')
        self.log_info('the language is set to zh-cn')

        # 1. get previous time that command last runs
        now = datetime.now()
        today = datetime.now().replace(hour=0).replace(minute=0).replace(
            second=0).replace(microsecond=0)

        try:
            cmd_last_check = CommandsLastCheck.objects.get(
                command_type=self.label)
            self.log_debug('Last check time is %s' % cmd_last_check.last_check)

            last_check_dt = cmd_last_check.last_check

            cmd_last_check.last_check = now
            cmd_last_check.save()
        except CommandsLastCheck.DoesNotExist:
            last_check_dt = today
            self.log_debug('Create new last check time: %s' % now)
            CommandsLastCheck(command_type=self.label, last_check=now).save()

        # 2. get all unseen notices
        user_notifications = UserNotification.objects.filter(
            timestamp__gt=last_check_dt).filter(seen=False)
        self.log_info('Found %d notices' % user_notifications.count())
        if user_notifications.count() == 0:
            return

        # 3. get all users should send notice to
        user_email_list = list(
            set([item.to_user for item in user_notifications]))

        dingtail_socials = SocialAuthUser.objects.filter(
            provider='dingtalk').filter(username__in=user_email_list)
        dingtalk_email_list = [item.username for item in dingtail_socials]
        dingtalk_email_uid_dict = {}
        for item in dingtail_socials:
            dingtalk_email_uid_dict[
                item.username] = dingtalk_get_userid_by_unionid(item.uid)

        work_weixin_socials = SocialAuthUser.objects.filter(provider=WORK_WEIXIN_PROVIDER, \
                uid__contains=WORK_WEIXIN_UID_PREFIX).filter(username__in=user_email_list)
        work_weixin_email_list = [
            item.username for item in work_weixin_socials
        ]
        work_weixin_email_uid_dict = {}
        for item in work_weixin_socials:
            work_weixin_email_uid_dict[
                item.username] = item.uid[len(WORK_WEIXIN_UID_PREFIX):]

        # 4. send msg
        site_name = get_site_name()

        for email in list(set(dingtalk_email_list + work_weixin_email_list)):

            should_send = []
            for notification in user_notifications:
                if email == notification.to_user:
                    should_send.append(notification)

            title = _("You've got %(num)s new notices on %(site_name)s:\n") % \
                    {'num': len(should_send), 'site_name': site_name, }

            has_sent = False

            if not has_sent and email in dingtalk_email_list and ENABLE_DINGTALK:
                content = '  \n  '.join([
                    remove_html_a_element_for_dingtalk(x.format_msg())
                    for x in should_send
                ])
                self.send_dingtalk_msg(dingtalk_email_uid_dict[email], title,
                                       content)
                has_sent = True

            if not has_sent and email in work_weixin_email_list and ENABLE_WORK_WEIXIN:
                content = ''.join([
                    wrap_div_for_work_weixin(x.format_msg())
                    for x in should_send
                ])
                self.send_work_weixin_msg(work_weixin_email_uid_dict[email],
                                          title, content)
                has_sent = True

        translation.activate(cur_language)
        self.log_info('reset language success')
        return