Verified Commit aee6738b authored by guglielmo's avatar guglielmo

slack notifications implemented; taskmanager added to requirements and settings

parent bc342f58
......@@ -193,7 +193,6 @@ SHARED_APPS = (
# 'django.contrib.admindocs',
# Django helper
"django_extensions",
"django_slack",
# Customers or tenants
"project.tenants",
)
......@@ -212,12 +211,15 @@ TENANT_APPS = (
# admin enhancers apps
"django_object_actions",
"django_admin_row_actions",
"django_slack",
# The app
"project.webapp",
# Live settings
"constance",
"constance.backends.database",
# task management
"taskmanager",
"django_uwsgi",
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
......@@ -320,11 +322,7 @@ CONSTANCE_CONFIG = {
'USE_SLACK': (False, "Enable notifications to slack channel. If False, then email is used", bool),
'SLACK_TOKEN': ("", "The token for slack integration, as read from slack"),
'SLACK_CHANNEL': ("", "The channel used for automatic notifications"),
'SLACK_USERNAME': ("", "The username sending automatic notifications"),
'SLACK_FAIL_SILENTLY': (True, "Whether to allow slack to silently fail", bool),
'SLACK_ICON_URL': ("", "The URL of an icon for this channel"),
'SLACK_ENDPOINT_URL': ("", "The slack app endpoint url. for example: https://hooks.slack.com/services/<TXXXX>/<GIBBERISH>")
}
}
CONSTANCE_IGNORE_ADMIN_VERSION_CHECK = True
CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend'
......
{% extends django_slack %}
{% block text %}
Cambiamenti ed errori nei siti sotto controllo
*Dominio*: {{ domain }}
*Cambiamenti*
{% for content in modified_contents %}
• <http://{{domain}}/sitescheck/content/{{content.id}}|{{ content.title }}> (<http://{{domain}}/diff/{{content.id}}"|diff>)
{% endfor %}
*Errori*
{% for content in failed_contents %}
• <http://{{domain}}/sitescheck/content/{{content.id}}|{{ content.title }}> (<http://{{domain}}/diff/{{content.id}}"|diff>)
{% endfor %}
{% endblock %}
{% block endpoint_url %}{{ config.SLACK_ENDPOINT_URL }}{% endblock %}
{% block channel %}{{ config.SLACK_CHANNEL }}{% endblock %}
{% block username %}{{ config.SLACK_USERNAME }}{% endblock %}
{% block token %}{{ config.SLACK_TOKEN }}{% endblock %}
import slack
from django.contrib.sites.models import Site
from django.core.management.base import BaseCommand
from django.core.mail import EmailMultiAlternatives
from django.conf import settings
from constance import config
from project.webapp.models import Content, Recipient
......@@ -9,23 +12,107 @@ class Command(BaseCommand):
help = 'Notify variations, if necessary, to all recipients'
def add_arguments(self, parser):
parser.add_argument('--dryrun',
action='store_true',
dest='dryrun',
default=False,
help='Execute a dry run: no db is written.'
)
parser.add_argument(
'--dryrun',
action='store_true',
dest='dryrun',
default=False,
help='Execute a dry run: no db is written.'
)
parser.add_argument(
'--notification-method',
dest='notification_method',
default="slack",
help='How notifications are sent.'
)
parser.add_argument(
'--slack-engine',
dest='slack_engine',
default="RequestsBackend",
help='The slack engine to be used: use ConsoleBackend to test.'
)
def handle(self, *args, **options):
"""
:param args:
:param options:
:return:
"""
context = {
'domain': Site.objects.get_current().domain,
'n_analysed_contents': Content.objects.count(),
'modified_contents': Content.objects.filter(verification_status=Content.STATUS_CHANGED),
'failed_contents': Content.objects.filter(verification_status=Content.STATUS_ERROR),
'n_modified_contents': Content.objects.filter(verification_status=Content.STATUS_CHANGED).count(),
'n_failed_contents': Content.objects.filter(verification_status=Content.STATUS_ERROR).count(),
}
if options['notification_method'] == 'slack':
self.handle_slack(context=context, **options)
else:
self.handle_email(context=context, **options)
@staticmethod
def handle_slack(**kwargs):
"""
:param kwargs:
:return:
"""
context = kwargs.get('context')
context['config'] = config
summary_txt = \
f"Trovati {context['n_modified_contents']} siti con variazioni e " \
f"{context['n_failed_contents']} con errori."
linked_txt = \
f"Trovati *{context['n_modified_contents']}* " \
f"<http://opdm.opsv.io:8000/admin/webapp/content/?verification_status__exact=1|siti con variazioni> e " \
f"*{context['n_failed_contents']}* " \
f"<http://opdm.opsv.io:8000/admin/webapp/content/?verification_status__exact=2|siti con errori>."
domain = Site.objects.get_current().domain
msg_blocks = [
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": f"Verificafonti ha analizzato *{context['n_analysed_contents']}* siti."
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": linked_txt
}
},
]
client = slack.WebClient(token=config.SLACK_TOKEN)
client.chat_postMessage(
channel=config.SLACK_CHANNEL,
text=summary_txt,
blocks=msg_blocks
)
@staticmethod
def handle_email(**kwargs):
"""
:param kwargs:
:return:
"""
context = kwargs.get('context')
domain = context['domain']
modified_contents = context['modified_contents']
failed_contents = context['failed_contents']
msg_txt = ""
msg_html = ""
modified_contents = Content.objects.filter(verification_status=Content.STATUS_CHANGED)
failed_contents = Content.objects.filter(verification_status=Content.STATUS_ERROR)
if modified_contents.count():
msg_txt += "Cambiamenti:\n"
msg_html += "Questo l'elenco dei siti cambiati: <br/><ul " \
......@@ -58,7 +145,7 @@ class Command(BaseCommand):
recipients.append(recipient.email)
print("recipients: " + "; ".join(recipients))
if options['dryrun'] is False:
if kwargs.get('dryrun', False) is False:
try:
subject = '[Openpolis] Cambiamento nei siti sotto controllo!'
msg = EmailMultiAlternatives(subject, msg_txt, settings.DEFAULT_FROM_EMAIL, recipients)
......
from django.core.management.base import BaseCommand
from django_slack import slack_message
from constance import config
from django.core.management.base import BaseCommand, CommandError
import slack
from django.conf import settings
from django.db import connection
from django_tenants.utils import get_tenant_model, get_public_schema_name
from constance import config
from project.webapp.models import Content
class Command(BaseCommand):
help = 'Test slack message'
def get_tenant(self, schema='public'):
"""Return the Tenant for the given schema"""
TenantModel = get_tenant_model()
all_tenants = TenantModel.objects.all()
if not all_tenants:
raise CommandError("""There are no tenants in the system.
To learn how create a tenant, see:
https://django-tenants.readthedocs.org/en/latest/use.html#creating-a-tenant""")
return TenantModel.objects.get(schema_name=schema)
def handle(self, *args, **options):
settings.DEGUG = False
slack_message('slack/test.slack', context={'config': config}, backend="django_slack.backends.UrllibBackend")
print(f"Message sent to channel {config.SLACK_CHANNEL} by {config.SLACK_USERNAME}")
\ No newline at end of file
@slack.RTMClient.run_on(event='message')
def say_hello(**payload):
connection.set_tenant(self.get_tenant(schema='opdm'))
data = payload['data']
web_client = payload['web_client']
rtm_client = payload['rtm_client']
if 'Hello' in data.get('text', None):
channel_id = data['channel']
thread_ts = data['ts']
user = data.get('user', 'ND')
n_content = Content.objects.count()
web_client.chat_postMessage(
channel=channel_id,
text=f"Hi <@{user}>! There are {n_content} contents.",
thread_ts=thread_ts
)
slack_token = config.SLACK_TOKEN
rtm_client = slack.RTMClient(token=slack_token)
rtm_client.start()
print("I'm listening")
\ No newline at end of file
......@@ -16,9 +16,17 @@ django-tenants==2.2.3
django-constance==2.4.0
django-constance[database]
# slack notifications
slackclient==2.0.0
# App requirements
psycopg2-binary==2.7.5
#django-uwsgi-taskmanager
-e git+https://gitlab.depp.it/openpolis/op-task-manager-project.git@master#egg=django-uwsgi-taskmanager
django-uwsgi==0.2.2
file_read_backwards
html2text
requests
lxml
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment