mirror of https://github.com/zulip/zulip.git
zilencer: Move feedback code to zerver/lib/feedback.
This commit is contained in:
parent
1f9d93bc96
commit
ed5b76f566
|
@ -0,0 +1,75 @@
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from typing import Any, Dict, Optional, Text
|
||||||
|
|
||||||
|
from zerver.lib.actions import internal_send_message
|
||||||
|
from zerver.lib.redis_utils import get_redis_client
|
||||||
|
from zerver.models import get_realm, get_user_profile_by_email, \
|
||||||
|
get_realm_by_email_domain, UserProfile, Realm
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
client = get_redis_client()
|
||||||
|
|
||||||
|
def realm_for_email(email):
|
||||||
|
# type: (str) -> Optional[Realm]
|
||||||
|
try:
|
||||||
|
user = get_user_profile_by_email(email)
|
||||||
|
return user.realm
|
||||||
|
except UserProfile.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return get_realm_by_email_domain(email)
|
||||||
|
|
||||||
|
def has_enough_time_expired_since_last_message(sender_email, min_delay):
|
||||||
|
# type: (Text, float) -> bool
|
||||||
|
# This function returns a boolean, but it also has the side effect
|
||||||
|
# of noting that a new message was received.
|
||||||
|
key = 'zilencer:feedback:%s' % (sender_email,)
|
||||||
|
t = int(time.time())
|
||||||
|
last_time = client.getset(key, t)
|
||||||
|
if last_time is None:
|
||||||
|
return True
|
||||||
|
delay = t - int(last_time)
|
||||||
|
return delay > min_delay
|
||||||
|
|
||||||
|
def get_ticket_number():
|
||||||
|
# type: () -> int
|
||||||
|
num_file = '/var/tmp/.feedback-bot-ticket-number'
|
||||||
|
try:
|
||||||
|
ticket_number = int(open(num_file).read()) + 1
|
||||||
|
except Exception:
|
||||||
|
ticket_number = 1
|
||||||
|
open(num_file, 'w').write('%d' % (ticket_number,))
|
||||||
|
return ticket_number
|
||||||
|
|
||||||
|
def deliver_feedback_by_zulip(message):
|
||||||
|
# type: (Dict[str, Any]) -> None
|
||||||
|
subject = "%s" % (message["sender_email"],)
|
||||||
|
|
||||||
|
if len(subject) > 60:
|
||||||
|
subject = subject[:57].rstrip() + "..."
|
||||||
|
|
||||||
|
content = u''
|
||||||
|
sender_email = message['sender_email']
|
||||||
|
|
||||||
|
# We generate ticket numbers if it's been more than a few minutes
|
||||||
|
# since their last message. This avoids some noise when people use
|
||||||
|
# enter-send.
|
||||||
|
need_ticket = has_enough_time_expired_since_last_message(sender_email, 180)
|
||||||
|
|
||||||
|
if need_ticket:
|
||||||
|
ticket_number = get_ticket_number()
|
||||||
|
content += '\n~~~'
|
||||||
|
content += '\nticket Z%03d (@support please ack)' % (ticket_number,)
|
||||||
|
content += '\nsender: %s' % (message['sender_full_name'],)
|
||||||
|
content += '\nemail: %s' % (sender_email,)
|
||||||
|
if 'sender_domain' in message:
|
||||||
|
content += '\nrealm: %s' % (message['sender_domain'],)
|
||||||
|
content += '\n~~~'
|
||||||
|
content += '\n\n'
|
||||||
|
|
||||||
|
content += message['content']
|
||||||
|
|
||||||
|
internal_send_message(realm_for_email("feedback@zulip.com"), "feedback@zulip.com",
|
||||||
|
"stream", "support", subject, content)
|
|
@ -1,10 +1,12 @@
|
||||||
from django.conf.urls import url, include
|
from django.conf.urls import url, include
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from zerver.lib.rest import rest_dispatch
|
from zerver.lib.rest import rest_dispatch
|
||||||
|
|
||||||
import zilencer.views
|
import zilencer.views
|
||||||
import zerver.views.report
|
import zerver.views.report
|
||||||
|
|
||||||
i18n_urlpatterns = [
|
i18n_urlpatterns = [] # type: Any
|
||||||
]
|
|
||||||
|
|
||||||
# Zilencer views following the REST API style
|
# Zilencer views following the REST API style
|
||||||
v1_api_and_json_patterns = [
|
v1_api_and_json_patterns = [
|
||||||
|
|
|
@ -6,87 +6,19 @@ from django.http import HttpResponse, HttpRequest
|
||||||
from zilencer.models import Deployment
|
from zilencer.models import Deployment
|
||||||
|
|
||||||
from zerver.decorator import has_request_variables, REQ
|
from zerver.decorator import has_request_variables, REQ
|
||||||
from zerver.lib.actions import internal_send_message
|
|
||||||
from zerver.lib.error_notify import do_report_error
|
from zerver.lib.error_notify import do_report_error
|
||||||
from zerver.lib.redis_utils import get_redis_client
|
from zerver.lib.feedback import deliver_feedback_by_zulip
|
||||||
from zerver.lib.response import json_error, json_response
|
|
||||||
from zerver.lib.validator import check_dict
|
from zerver.lib.validator import check_dict
|
||||||
from zerver.models import get_realm, get_user_profile_by_email, \
|
|
||||||
get_realm_by_email_domain, UserProfile, Realm
|
|
||||||
|
|
||||||
import time
|
from typing import Any, Dict, Text
|
||||||
|
|
||||||
from typing import Dict, Optional, Any, Text
|
|
||||||
|
|
||||||
client = get_redis_client()
|
|
||||||
|
|
||||||
def has_enough_time_expired_since_last_message(sender_email, min_delay):
|
|
||||||
# type: (Text, float) -> bool
|
|
||||||
# This function returns a boolean, but it also has the side effect
|
|
||||||
# of noting that a new message was received.
|
|
||||||
key = 'zilencer:feedback:%s' % (sender_email,)
|
|
||||||
t = int(time.time())
|
|
||||||
last_time = client.getset(key, t)
|
|
||||||
if last_time is None:
|
|
||||||
return True
|
|
||||||
delay = t - int(last_time)
|
|
||||||
return delay > min_delay
|
|
||||||
|
|
||||||
def get_ticket_number():
|
|
||||||
# type: () -> int
|
|
||||||
num_file = '/var/tmp/.feedback-bot-ticket-number'
|
|
||||||
try:
|
|
||||||
ticket_number = int(open(num_file).read()) + 1
|
|
||||||
except Exception:
|
|
||||||
ticket_number = 1
|
|
||||||
open(num_file, 'w').write('%d' % (ticket_number,))
|
|
||||||
return ticket_number
|
|
||||||
|
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def submit_feedback(request, deployment, message=REQ(validator=check_dict([]))):
|
def submit_feedback(request, deployment, message=REQ(validator=check_dict([]))):
|
||||||
# type: (HttpRequest, Deployment, Dict[str, Text]) -> HttpResponse
|
# type: (HttpRequest, Deployment, Dict[str, Text]) -> HttpResponse
|
||||||
subject = "%s" % (message["sender_email"],)
|
deliver_feedback_by_zulip(message)
|
||||||
|
|
||||||
if len(subject) > 60:
|
|
||||||
subject = subject[:57].rstrip() + "..."
|
|
||||||
|
|
||||||
content = u''
|
|
||||||
sender_email = message['sender_email']
|
|
||||||
|
|
||||||
# We generate ticket numbers if it's been more than a few minutes
|
|
||||||
# since their last message. This avoids some noise when people use
|
|
||||||
# enter-send.
|
|
||||||
need_ticket = has_enough_time_expired_since_last_message(sender_email, 180)
|
|
||||||
|
|
||||||
if need_ticket:
|
|
||||||
ticket_number = get_ticket_number()
|
|
||||||
content += '\n~~~'
|
|
||||||
content += '\nticket Z%03d (@support please ack)' % (ticket_number,)
|
|
||||||
content += '\nsender: %s' % (message['sender_full_name'],)
|
|
||||||
content += '\nemail: %s' % (sender_email,)
|
|
||||||
if 'sender_domain' in message:
|
|
||||||
content += '\nrealm: %s' % (message['sender_domain'],)
|
|
||||||
content += '\n~~~'
|
|
||||||
content += '\n\n'
|
|
||||||
|
|
||||||
content += message['content']
|
|
||||||
|
|
||||||
internal_send_message(realm_for_email("feedback@zulip.com"), "feedback@zulip.com",
|
|
||||||
"stream", "support", subject, content)
|
|
||||||
|
|
||||||
return HttpResponse(message['sender_email'])
|
return HttpResponse(message['sender_email'])
|
||||||
|
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def report_error(request, deployment, type=REQ(), report=REQ(validator=check_dict([]))):
|
def report_error(request, deployment, type=REQ(), report=REQ(validator=check_dict([]))):
|
||||||
# type: (HttpRequest, Deployment, Text, Dict[str, Any]) -> HttpResponse
|
# type: (HttpRequest, Deployment, Text, Dict[str, Any]) -> HttpResponse
|
||||||
return do_report_error(deployment.name, type, report)
|
return do_report_error(deployment.name, type, report)
|
||||||
|
|
||||||
def realm_for_email(email):
|
|
||||||
# type: (str) -> Optional[Realm]
|
|
||||||
try:
|
|
||||||
user = get_user_profile_by_email(email)
|
|
||||||
return user.realm
|
|
||||||
except UserProfile.DoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return get_realm_by_email_domain(email)
|
|
||||||
|
|
Loading…
Reference in New Issue