Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

send sdoc notice #5797

Merged
merged 2 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 43 additions & 6 deletions seahub/notifications/management/commands/send_notices.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from django.utils.translation import gettext as _

from seaserv import seafile_api, ccnet_api
from seahub.notifications.models import UserNotification
from seahub.notifications.models import UserNotification, MSG_TYPE_FILE_COMMENT
from seahub.utils import send_html_email, get_site_scheme_and_netloc
from seahub.avatar.templatetags.avatar_tags import avatar
from seahub.avatar.util import get_default_avatar_url
Expand All @@ -25,6 +25,9 @@
from seahub.utils import get_site_name
from seahub.options.models import UserOptions, KEY_COLLABORATE_EMAIL_INTERVAL, \
KEY_COLLABORATE_LAST_EMAILED_TIME, DEFAULT_COLLABORATE_EMAIL_INTERVAL
from seahub.seadoc.models import SeadocNotification
from seahub.tags.models import FileUUIDMap
from seahub.notifications.utils import gen_sdoc_smart_link

# Get an instance of a logger
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -254,6 +257,22 @@ def format_repo_monitor_msg(self, notice):

return notice

def format_sdoc_msg(self, sdoc_queryset, sdoc_notice):
sdoc_obj = sdoc_queryset.filter(uuid=sdoc_notice.doc_uuid).first()
if not sdoc_obj:
return None
notice = UserNotification()
notice.msg_type = MSG_TYPE_FILE_COMMENT
notice.to_user = sdoc_notice.username
notice.timestamp = sdoc_notice.created_at
notice.file_url = gen_sdoc_smart_link(sdoc_notice.doc_uuid, with_service_url=False)
notice.file_name = str(sdoc_obj.filename)[:-5]
detail = json.loads(sdoc_notice.detail)
author = email2nickname(detail.get('author'))
notice.author = author
notice.avatar_src = self.get_avatar_src(author)
return notice

def get_user_language(self, username):
return Profile.objects.get_user_language(username)

Expand All @@ -267,14 +286,23 @@ def get_user_intervals_and_notices(self):

all_unseen_notices = UserNotification.objects.get_all_notifications(
seen=False, time_since=last_longest_interval_time).order_by('-timestamp')
all_unseen_sdoc_notices = SeadocNotification.objects.filter(
seen=False, created_at__gt=last_longest_interval_time).order_by('-created_at')
sdoc_queryset = FileUUIDMap.objects.filter(uuid__in=[item.doc_uuid for item in all_unseen_sdoc_notices])

results = {}
for notice in all_unseen_notices:
if notice.to_user not in results:
results[notice.to_user] = {'notices': [notice], 'interval': DEFAULT_COLLABORATE_EMAIL_INTERVAL}
results[notice.to_user] = {'notices': [notice], 'sdoc_notices': [] , 'interval': DEFAULT_COLLABORATE_EMAIL_INTERVAL}
else:
results[notice.to_user]['notices'].append(notice)

for sdoc_notice in all_unseen_sdoc_notices:
if sdoc_notice.username not in results:
results[sdoc_notice.username] = {'notices': [], 'sdoc_notices': [sdoc_notice], 'interval': DEFAULT_COLLABORATE_EMAIL_INTERVAL}
else:
results[sdoc_notice.username]['sdoc_notices'].append(sdoc_notice)

user_options = UserOptions.objects.filter(
email__in=results.keys(), option_key=KEY_COLLABORATE_EMAIL_INTERVAL)
for option in user_options:
Expand All @@ -289,7 +317,7 @@ def get_user_intervals_and_notices(self):
else:
results[email]['interval'] = interval

return [(key, value['interval'], value['notices']) for key, value in results.items()]
return [(key, value['interval'], value['notices'], value['sdoc_notices'], sdoc_queryset) for key, value in results.items()]

def do_action(self):

Expand All @@ -299,7 +327,7 @@ def do_action(self):

# check if to_user active
user_active_dict = {}
for (to_user, interval_val, notices) in user_interval_notices:
for (to_user, interval_val, notices, sdoc_notices, sdoc_queryset) in user_interval_notices:

if to_user in user_active_dict:
continue
Expand All @@ -314,7 +342,7 @@ def do_action(self):

# save current language
cur_language = translation.get_language()
for (to_user, interval_val, notices) in user_interval_notices:
for (to_user, interval_val, notices, sdoc_notices, sdoc_queryset) in user_interval_notices:

if not user_active_dict[to_user]:
continue
Expand All @@ -330,7 +358,8 @@ def do_action(self):
continue

user_notices = list(filter(lambda notice: notice.timestamp > last_emailed_time, notices))
if not user_notices:
user_sdoc_notices = list(filter(lambda sdoc_notice: sdoc_notice.created_at > last_emailed_time, sdoc_notices))
if not user_notices and not user_sdoc_notices:
continue

# get and active user language
Expand Down Expand Up @@ -392,6 +421,14 @@ def do_action(self):

notices.append(notice)

for sdoc_notice in user_sdoc_notices:
if sdoc_notice.username != to_user:
continue
notice = self.format_sdoc_msg(sdoc_queryset, sdoc_notice)
if notice is None:
continue
notices.append(notice)

if not notices:
continue

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
from seahub.notifications.models import UserNotification
from seahub.utils import get_site_scheme_and_netloc, get_site_name
from seahub.auth.models import SocialAuthUser
from seahub.seadoc.models import SeadocNotification
from seahub.tags.models import FileUUIDMap
from seahub.notifications.utils import format_sdoc_notice

from seahub.dingtalk.utils import dingtalk_get_access_token, dingtalk_get_userid_by_unionid
from seahub.dingtalk.utils import dingtalk_get_orgapp_token, dingtalk_get_userid_by_unionid_new
from seahub.dingtalk.settings import DINGTALK_MESSAGE_SEND_TO_CONVERSATION_URL, \
DINGTALK_AGENT_ID, ENABLE_DINGTALK

Expand Down Expand Up @@ -77,6 +80,7 @@ class Command(BaseCommand, CommandLogMixin):

help = "Send notices to user's social account if he/she has unseen notices every period of time."
label = "notifications_send_notices_to_social_account"
sdoc_label = "notifications_send_sdoc_notices_to_social_account"

def handle(self, *args, **options):

Expand Down Expand Up @@ -144,7 +148,7 @@ def do_action(self):

if ENABLE_DINGTALK:

dingtalk_access_token = dingtalk_get_access_token()
dingtalk_access_token = dingtalk_get_orgapp_token()
if not dingtalk_access_token:
self.log_error('can not get access token for dingtalk')
else:
Expand Down Expand Up @@ -188,20 +192,41 @@ def do_action(self):
self.log_debug('Create new last check time: %s' % now)
CommandsLastCheck(command_type=self.label, last_check=now).save()

# sdoc
try:
sdoc_cmd_last_check = CommandsLastCheck.objects.get(command_type=self.sdoc_label)
self.log_debug('Last sdoc check time is %s' % sdoc_cmd_last_check.last_check)

sdoc_last_check_dt = sdoc_cmd_last_check.last_check

sdoc_cmd_last_check.last_check = now
sdoc_cmd_last_check.save()
except CommandsLastCheck.DoesNotExist:
sdoc_last_check_dt = today
self.log_debug('Create new sodc last check time: %s' % now)
CommandsLastCheck(command_type=self.sdoc_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:

sdoc_notifications = SeadocNotification.objects.filter(created_at__gt=sdoc_last_check_dt).filter(seen=False)
self.log_info('Found %d sdoc notices' % sdoc_notifications.count())
sdoc_queryset = FileUUIDMap.objects.filter(uuid__in=[item.doc_uuid for item in sdoc_notifications])

if user_notifications.count() == 0 and sdoc_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]))
user_email_set = set([item.to_user for item in user_notifications])
sdoc_user_email_set = set([item.username for item in sdoc_notifications])
user_email_list = list(user_email_set | sdoc_user_email_set)

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)
dingtalk_email_uid_dict[item.username] = dingtalk_get_userid_by_unionid_new(item.uid)

work_weixin_socials = SocialAuthUser.objects.filter(provider=WORK_WEIXIN_PROVIDER, \
uid__contains=WORK_WEIXIN_UID_PREFIX).filter(username__in=user_email_list)
Expand All @@ -220,18 +245,27 @@ def do_action(self):
if email == notification.to_user:
should_send.append(notification)

sdoc_should_send = []
for sdoc_notification in sdoc_notifications:
if email == sdoc_notification.username:
sdoc_should_send.append(sdoc_notification)

title = _("You've got %(num)s new notices on %(site_name)s:\n") % \
{'num': len(should_send), 'site_name': site_name, }
{'num': len(should_send) + len(sdoc_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])
sdoc_content = ' \n '.join([remove_html_a_element_for_dingtalk(format_sdoc_notice(sdoc_queryset, item)) for item in sdoc_should_send])
content = ' \n '.join([content, sdoc_content])
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])
sdoc_content = ''.join([wrap_div_for_work_weixin(format_sdoc_notice(sdoc_queryset, item)) for item in sdoc_should_send])
content = ''.join([content, sdoc_content])
self.send_work_weixin_msg(work_weixin_email_uid_dict[email], title, content)
has_sent = True

Expand Down
49 changes: 49 additions & 0 deletions seahub/notifications/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import json
import logging
from django.core.cache import cache
from django.utils.html import escape
from django.utils.translation import gettext as _

from seaserv import ccnet_api, seafile_api
from seahub.notifications.models import Notification
from seahub.notifications.settings import NOTIFICATION_CACHE_TIMEOUT
from seahub.avatar.templatetags.avatar_tags import api_avatar_url
from seahub.base.templatetags.seahub_tags import email2nickname, email2contact_email
from seahub.utils import get_service_url

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -266,3 +269,49 @@ def update_notice_detail(request, notices):
logger.error(e)

return notices


def gen_sdoc_smart_link(doc_uuid, with_service_url=True):
service_url = get_service_url()
service_url = service_url.rstrip('/')
if with_service_url:
return '%s/smart-link/%s/' % (service_url, doc_uuid)
else:
return '/smart-link/%s/' % (doc_uuid,)


def add_a_element(con, href='#', style=''):
return '<a href="%s" style="%s">%s</a>' % (href, style, escape(con))


def format_sdoc_notice(sdoc_queryset, sdoc_notice, include_detail_link=False):
message = ''
sdoc_obj = sdoc_queryset.filter(uuid=sdoc_notice.doc_uuid).first()
if not sdoc_obj:
return ''
sdoc_name = str(sdoc_obj.filename)[:-5]
detail = json.loads(sdoc_notice.detail)
msg_type = sdoc_notice.msg_type
author = detail.get('author')

if msg_type == 'comment':
message = _("%(author)s added a new comment in document %(sdoc_name)s") % {
'author': escape(email2nickname(author)),
'sdoc_name': sdoc_name,
}
message = '%s "%s"' % (message, detail.get('comment', ''))
if include_detail_link:
sdoc_file_url = gen_sdoc_smart_link(sdoc_notice.doc_uuid)
message = '%s %s' % (message, add_a_element(_('Details'), sdoc_file_url))

if msg_type == 'reply':
message = _("%(author)s added a new reply in document %(sdoc_name)s") % {
'author': escape(email2nickname(author)),
'sdoc_name': sdoc_name,
}
message = '%s "%s"' % (message, detail.get('reply', ''))
if include_detail_link:
sdoc_file_url = gen_sdoc_smart_link(sdoc_notice.doc_uuid)
message = '%s %s' % (message, add_a_element(_('Details'), sdoc_file_url))

return message
2 changes: 1 addition & 1 deletion seahub/work_weixin/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def work_weixin_oauth_callback(request):
request, _('Error, new user registration is not allowed, please contact administrator.'))

if is_new_user:
SocialAuthUser.objects.add(email, WORK_WEIXIN_PROVIDER, uid)
SocialAuthUser.objects.add(user.username, WORK_WEIXIN_PROVIDER, uid)

# update user info
if is_new_user or WORK_WEIXIN_USER_INFO_AUTO_UPDATE:
Expand Down
Loading