Skip to content

Commit

Permalink
Added worker slack_ids. Datamigration to port ids for existing users
Browse files Browse the repository at this point in the history
  • Loading branch information
kkamalov committed Apr 29, 2016
1 parent f4ab126 commit 8024ed9
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 3 deletions.
20 changes: 19 additions & 1 deletion orchestra/accounts/forms.py
Expand Up @@ -6,6 +6,7 @@
from orchestra.accounts.bitformfield import BitFormField
from orchestra.models import CommunicationPreference
from orchestra.models import Worker
from orchestra.utils.slack import get_slack_user_id

UserModel = get_user_model()

Expand All @@ -28,7 +29,24 @@ class WorkerForm(forms.ModelForm):
class Meta:
model = Worker
fields = ('slack_username', 'phone')
exclude = ('user', 'start_datetime')
exclude = ('user', 'start_datetime', 'slack_user_id')

def clean_slack_username(self):
slack_username = self.cleaned_data.get('slack_username')
if slack_username:
slack_user_id = get_slack_user_id(slack_username)
if slack_user_id is None:
raise forms.ValidationError(
'Incorrect slack username provided')
self.cleaned_data['slack_user_id'] = slack_user_id
return self.cleaned_data['slack_username']

def save(self, commit=True):
instance = super().save(commit=False)
instance.slack_user_id = self.cleaned_data.get('slack_user_id')
if commit:
instance.save()
return instance


class CommunicationPreferenceForm(forms.ModelForm):
Expand Down
12 changes: 10 additions & 2 deletions orchestra/accounts/tests/test_views.py
@@ -1,4 +1,5 @@
from django.core.urlresolvers import reverse
from unittest.mock import patch

from orchestra.tests.helpers import OrchestraAuthenticatedTestCase
from orchestra.models import CommunicationPreference
Expand Down Expand Up @@ -28,7 +29,10 @@ def test_get_form(self):
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'accounts/settings.html')

def test_change_all_fields(self):
@patch('orchestra.accounts.forms.get_slack_user_id')
def test_change_all_fields(self, mock_get_slack_user_id):
mock_get_slack_user_id.return_value = 'test_id'

data = self._get_account_settings_mock_data()
response = self.request_client.post(self.url, data)
self.assertTrue(response.context['success'])
Expand All @@ -40,8 +44,12 @@ def test_change_all_fields(self):
self.worker.refresh_from_db()
self.assertEqual(self.worker.slack_username, data['slack_username'])
self.assertEqual(self.worker.phone, data['phone_0'] + data['phone_1'])
self.assertEqual(self.worker.slack_user_id, 'test_id')

@patch('orchestra.accounts.forms.get_slack_user_id')
def test_missing_fields(self, mock_get_slack_user_id):
mock_get_slack_user_id.return_value = 'test_id'

def test_missing_fields(self):
required_fields = self._get_account_settings_mock_data().keys()
for field in required_fields:
data = self._get_account_settings_mock_data()
Expand Down
20 changes: 20 additions & 0 deletions orchestra/migrations/0053_worker_slack_user_id.py
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-04-29 16:42
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('orchestra', '0052_auto_20160428_2142'),
]

operations = [
migrations.AddField(
model_name='worker',
name='slack_user_id',
field=models.CharField(blank=True, max_length=200, null=True),
),
]
3 changes: 3 additions & 0 deletions orchestra/models/core/models.py
Expand Up @@ -185,12 +185,15 @@ class Worker(WorkerMixin, models.Model):
The time the worker was created.
slack_username (str):
The worker's Slack username if Slack integration is enabled.
slack_user_id (str):
The worker's Slack id if Slack integration is enabled.
phone (str):
The worker's phone number
"""
user = models.OneToOneField(settings.AUTH_USER_MODEL)
start_datetime = models.DateTimeField(default=timezone.now)
slack_username = models.CharField(max_length=200, blank=True, null=True)
slack_user_id = models.CharField(max_length=200, blank=True, null=True)
phone = PhoneNumberField(null=True)

class Meta:
Expand Down
45 changes: 45 additions & 0 deletions orchestra/scripts/add_slack_user_ids.py
@@ -0,0 +1,45 @@
from annoying.functions import get_object_or_None
from django.conf import settings
from slacker import Slacker

from orchestra.models import Worker

import logging
logger = logging.getLogger(__name__)


def add_worker_slack_ids():
slack = Slacker(getattr(settings, 'SLACK_EXPERTS_API_KEY', None))
slack_response = slack.users.list()
if not slack_response.successful:
logger.warning('Slack could not be reached.')
return

members = slack_response.body.get('members')
for member in members:
if member.get('is_bot'):
continue
worker = get_object_or_None(Worker,
slack_username=member['name'])
if worker is None:

# Try to match user by first name and last name.
if (member['profile'].get('first_name') is None or
member['profile'].get('last_name') is None):
continue

workers = Worker.objects.filter(
user__first_name=member['profile']['first_name'],
user__last_name=member['profile']['last_name'])
if workers.count() == 1:
worker = workers.first()

if worker:
logger.info('Username {} has slack id {}'.format(
member['name'], member['id']))
worker.slack_id = member['id']
worker.slack_username = member['name']
worker.save()
else:
logger.info('Could not find worker for username {}'.format(
member['name']))
13 changes: 13 additions & 0 deletions orchestra/utils/slack.py
@@ -0,0 +1,13 @@
from django.conf import settings
from slacker import Slacker as _Slacker


class Slacker(_Slacker):
def __init__(self):
super().__init__(settings.SLACK_EXPERTS_API_KEY)


def get_slack_user_id(slack_username):
slack = Slacker()
slack_user_id = slack.users.get_user_id(slack_username)
return slack_user_id

0 comments on commit 8024ed9

Please sign in to comment.