Skip to content
This repository was archived by the owner on Dec 5, 2023. It is now read-only.

Commit ddcfbb6

Browse files
authored
Merge pull request #648 from unfoldingWord-dev/develop
Develop
2 parents cd3b6a9 + 62f1a4a commit ddcfbb6

27 files changed

+609
-73
lines changed

td/gl_tracking/views.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.contrib import messages
12
from django.shortcuts import render
23
from django.views.generic import TemplateView, DetailView, CreateView
34
from django.views.generic.edit import FormView, UpdateView
@@ -122,6 +123,14 @@ def form_valid(self, form):
122123
class PartnerListView(LoginRequiredMixin, TemplateView):
123124
template_name = "gl_tracking/partner_list.html"
124125

126+
def get(self, request, *args, **kwargs):
127+
print "Something"
128+
messages.warning(request, "The ability to create and update Languages, WA Regions, Countries, Charters, Events,"
129+
" and Partners will be suspended for all users starting on Monday, Jan. 9, 2017."
130+
" These functions will be made available in the new system, which is launching in"
131+
" a couple of weeks. Please retain the information you want to enter until then.")
132+
return super(PartnerListView, self).get(request, *args, **kwargs)
133+
125134

126135
class PartnerDetailView(LoginRequiredMixin, DetailView):
127136
model = Partner

td/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ def codes_text(cls):
430430
@classmethod
431431
def names_text(cls):
432432
return "\n".join([
433-
"{}\t{}".format(x.code, x.name.encode("utf-8"))
433+
"{}\t{}".format(x.code.encode("utf-8"), x.name.encode("utf-8"))
434434
for x in cls.objects.all().order_by("code")
435435
])
436436

td/receivers.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from pinax.eventlog.models import log
1111

1212
from .models import Country, Language, LanguageAltName, AdditionalLanguage, TempLanguage, WARegion
13-
from .tasks import reset_langnames_cache, update_alt_names, create_comment_tag, delete_comment_tag
13+
from .tasks import reset_langnames_cache, update_alt_names, create_comment_tag, delete_comment_tag, notify_external_apps
1414
from .signals import languages_integrated
1515
from td.resources.tasks import notify_templanguage_created
1616

@@ -60,39 +60,50 @@ def handle_additionallanguage_delete(sender, instance, **kwargs):
6060

6161
@receiver(post_save, sender=Language)
6262
def handle_language_save(sender, instance=None, created=False, **kwargs):
63-
(instance and "code" in instance.tracker.changed().keys()) and create_comment_tag(instance)
63+
if instance is not None:
64+
notify_external_apps("CREATE" if created else "UPDATE", instance)
65+
if "code" in instance.tracker.changed().keys():
66+
create_comment_tag(instance)
6467
reset_langnames_cache.delay()
6568
cache.set("map_gateway_refresh", True)
6669

6770

6871
@receiver(post_delete, sender=Language)
6972
def handle_language_delete(sender, instance=None, **kwargs):
70-
instance and delete_comment_tag(instance)
73+
if instance is not None:
74+
# notify_external_apps("DELETE", instance)
75+
delete_comment_tag(instance)
7176
reset_langnames_cache.delay()
7277
cache.set("map_gateway_refresh", True)
7378

7479

7580
@receiver(post_save, sender=LanguageAltName)
76-
def handle_alt_name_save(sender, instance=None, **kwargs):
81+
def handle_alt_name_save(sender, instance=None, created=False, **kwargs):
7782
if instance is not None:
83+
# notify_external_apps("CREATE" if created else "UPDATE", instance)
7884
update_alt_names(instance.code)
7985

8086

8187
@receiver(post_delete, sender=LanguageAltName)
8288
def handle_alt_name_delete(sender, instance=None, **kwargs):
8389
if instance is not None:
90+
# notify_external_apps("DELETE", instance)
8491
update_alt_names(instance.code)
8592

8693

8794
@receiver(post_save, sender=Country)
8895
def handle_country_save(sender, instance=None, created=False, **kwargs):
89-
"code" in instance.tracker.changed().keys() and create_comment_tag(instance)
96+
if instance is not None:
97+
# notify_external_apps("CREATE" if created else "UPDATE", instance)
98+
"code" in instance.tracker.changed().keys() and create_comment_tag(instance)
9099
cache.set("map_gateway_refresh", True)
91100

92101

93102
@receiver(post_delete, sender=Country)
94103
def handle_country_delete(sender, instance=None, **kwargs):
95-
instance and delete_comment_tag(instance)
104+
if instance is not None:
105+
# notify_external_apps("DELETE", instance)
106+
delete_comment_tag(instance)
96107
cache.set("map_gateway_refresh", True)
97108

98109

td/resources/tests/test_models.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from django.test import TestCase
2+
23
from ..models import Resource, Media, Title, Publisher, Questionnaire
34
from td.models import Language
5+
from td.tests.models import NoSignalTestCase
46

57

68
class MediaTestCase(TestCase):
@@ -21,21 +23,20 @@ def test_string_representation(self):
2123
self.assertEquals(str(publisher), "Test Publisher")
2224

2325

24-
class ResourceTestCase(TestCase):
25-
@classmethod
26-
def setUpClass(cls):
27-
super(ResourceTestCase, cls).setUpClass()
28-
cls.publisher = Publisher(name="Test Publisher 1")
29-
cls.publisher.save()
30-
cls.publisher2 = Publisher(name="Test Publisher 2")
31-
cls.publisher2.save()
32-
cls.title = Title(name="Test Title", slug="test-title")
33-
cls.title.publisher = cls.publisher
34-
cls.title.save()
35-
cls.media = Media(name="Media Title", slug="test-media")
36-
cls.media.save()
37-
cls.language = Language(code="ztest", name="Z Language")
38-
cls.language.save()
26+
class ResourceTestCase(NoSignalTestCase):
27+
def setUp(self):
28+
super(ResourceTestCase, self).setUp()
29+
self.publisher = Publisher(name="Test Publisher 1")
30+
self.publisher.save()
31+
self.publisher2 = Publisher(name="Test Publisher 2")
32+
self.publisher2.save()
33+
self.title = Title(name="Test Title", slug="test-title")
34+
self.title.publisher = self.publisher
35+
self.title.save()
36+
self.media = Media(name="Media Title", slug="test-media")
37+
self.media.save()
38+
self.language = Language(code="ztest", name="Z Language")
39+
self.language.save()
3940

4041
def test_string_representation(self):
4142
resource = Resource(language=self.language, title=self.title)

td/settings.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,16 @@
267267
}
268268

269269
JP_API_KEY = os.environ.get("JP_API_KEY")
270+
271+
EXT_APP_PUSH = [
272+
{
273+
"name": "wa_ops_crm",
274+
"url": "http://wa-td-integration.azurewebsites.net/api/crm/update",
275+
"key": os.environ.get("CRM_API_KEY"),
276+
}
277+
]
278+
279+
HOMEPAGE_MESSAGE = "The ability to create and update Languages, WA Regions, Countries, Charters, Events, and Partners " \
280+
"will be suspended for all users starting on Monday, Jan. 9, 2017. These functions will be made " \
281+
"available in the new system, which is launching in a couple of weeks. Please retain the " \
282+
"information you want to enter until then."

td/tasks.py

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
from __future__ import absolute_import
22

33
import logging
4+
import json
5+
import requests
6+
import types
47

58
from django.contrib.contenttypes.models import ContentType
69
from django.core.cache import cache
7-
from django.db import connection, IntegrityError
10+
from django.core.mail import send_mail
11+
from django.db import connection, IntegrityError, models
812

913
from celery import task
1014
from pinax.eventlog.models import log
1115

16+
from td import settings
1217
from td.commenting.models import CommentTag
1318
from td.imports.models import (
1419
EthnologueLanguageCode,
@@ -27,6 +32,12 @@
2732
logger = logging.getLogger(__name__)
2833

2934

35+
class TaskStatus(object):
36+
def __init__(self, success=False):
37+
self.success = success
38+
self.message = []
39+
40+
3041
@task()
3142
def create_comment_tag(instance):
3243
try:
@@ -191,3 +202,87 @@ def integrate_imb_language_data():
191202
language.country = country
192203
language.source = imb
193204
language.save()
205+
206+
207+
@task()
208+
def notify_external_apps(action="", instance=None):
209+
""" Make a POST request based on action types to urls registered in EXT_APP_PUSH under settings """
210+
211+
task_status = TaskStatus()
212+
213+
if not isinstance(instance, models.Model):
214+
task_status.message.append("function is called with invalid 'instance'")
215+
return task_status
216+
if not isinstance(action, (str, unicode)) or action.strip() == "":
217+
task_status.message.append("function is called with invalid 'action'")
218+
return task_status
219+
if not isinstance(settings.EXT_APP_PUSH, types.ListType):
220+
task_status.message.append("settings.EXT_APP_PUSH is not a list")
221+
return task_status
222+
223+
data = None
224+
225+
if action == "CREATE":
226+
# If instance is created, serialize all concrete fields and assign them as data
227+
# serialized_instances = serializers.serialize('json', [instance])
228+
# serialized_data = json.loads(serialized_instances)[0]
229+
# data = serialized_data
230+
# data.update({"code": instance.code})
231+
task_status.message.append("%s is not supported at this moment" % action)
232+
return task_status
233+
elif action == "UPDATE":
234+
# If instance is edited, only pass the changed fields as data
235+
data = {
236+
"pk": instance.id,
237+
"code": instance.tracker.previous("code") if instance.tracker.has_changed("code") else instance.code,
238+
"fields": {key.replace("_id", ""): getattr(instance, key, "") for key in instance.tracker.changed().keys()}
239+
}
240+
elif action == "DELETE":
241+
# If instance is deleted, just pass the id
242+
# data = {
243+
# "pk": instance.id,
244+
# "code": instance.code,
245+
# }
246+
task_status.message.append("%s is not supported at this moment" % action)
247+
return task_status
248+
else:
249+
task_status.message.append("%s is not a valid option for 'action'" % action)
250+
return task_status
251+
252+
# Include model name and action type in data to meet the spec. If action is 'CREATE', 'model' will be overridden by
253+
# class name instead of what the serializer sets.
254+
# Also include (previous) code to help identify records, especially the ones created by outside apps.
255+
data.update({
256+
"model": instance.__class__.__name__,
257+
"action": action,
258+
})
259+
260+
data = [data]
261+
262+
# NOTE: Maybe this can be abstracted into a function for easier testing
263+
for app in settings.EXT_APP_PUSH:
264+
url = app.get("url")
265+
if "key" in app:
266+
key = app.get("key")
267+
url += "?key=" + key if key is not None else ""
268+
headers = {'Content-Type': 'application/json'}
269+
270+
post_to_ext_apps.delay(url, json.dumps(data), headers)
271+
272+
task_status.success = True
273+
return task_status
274+
275+
276+
@task()
277+
def post_to_ext_apps(url, data, headers):
278+
response = requests.post(url, data=data, headers=headers)
279+
if response.status_code == 202 and response.content == "":
280+
return
281+
else:
282+
message = "POST to %s has failed with code: %s and message: %s" % (url, response.status_code, response.content)
283+
send_mail(
284+
"Ops CRM shim rejects POST",
285+
message,
286+
"admin@unfoldingword.org",
287+
["vleong2332@gmail.com"],
288+
)

td/templates/gl_tracking/partner_list.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
<h1>{% blocktrans %}Translation Partners{% endblocktrans %}</h1>
1111
{% url "gl:partner_create_view" as partner_create %}
1212
{% if user.is_authenticated %}
13-
{% blocktrans %}
14-
<a href="{{ partner_create }}" class="btn btn-primary large">Add a Partner</a>
15-
{% endblocktrans %}
13+
{# {% blocktrans %}#}
14+
{# <a href="{{ partner_create }}" class="btn btn-primary large">Add a Partner</a>#}
15+
{# {% endblocktrans %}#}
1616
{% endif %}
1717
</div>
1818
</section>

td/templates/resources/_empty_div_overlay.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<h3 class="empty-div-msg">{{ msg }}</h3>
33
{% if action %}
44
{% if user.is_authenticated %}
5-
<a class="btn btn-primary btn-empty-div" href="{{ action_url }}">{{ action }}</a>
5+
{# <a class="btn btn-primary btn-empty-div" href="{{ action_url }}">{{ action }}</a>#}
66
{% else %}
77
<a class="btn btn-primary btn-empty-div" href="">Login</a>
88
{% endif %}

td/templates/resources/_project_detail.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<h4 class="section-header-title">Charter</h4>
77
<div class="section-header-line"></div>
88
<div class="section-header-actions">
9-
<a class="btn btn-icon" href="{% url "tracking:charter_update" charter.pk %}" title="Edit Charter"><i class="fa fa-pencil"></i></a>
9+
{# <a class="btn btn-icon" href="{% url "tracking:charter_update" charter.pk %}" title="Edit Charter"><i class="fa fa-pencil"></i></a>#}
1010
<button class="btn btn-icon" data-toggle="collapse" data-target=".charter-section"><i class="fa fa-compress"></i></button>
1111
</div>
1212
</div>
@@ -32,7 +32,7 @@ <h4 class="section-header-title">Charter</h4>
3232
</div>
3333
<div class="col-md-6">
3434
{% include "comments/custom_lists.html" with object=data prefix="ch" %}
35-
{% render_comment_form for data %}
35+
{# {% render_comment_form for data %}#}
3636
</div>
3737
</div>
3838
</div>
@@ -43,7 +43,7 @@ <h4 class="section-header-title">Charter</h4>
4343
<h4 class="section-header-title">Events</h4>
4444
<div class="section-header-line"></div>
4545
<div class="section-header-actions">
46-
<a class="btn btn-icon" href="{% url "tracking:event_add_specific" charter.pk %}"><i class="fa fa-plus"></i></a>
46+
{# <a class="btn btn-icon" href="{% url "tracking:event_add_specific" charter.pk %}"><i class="fa fa-plus"></i></a>#}
4747
<button class="btn btn-icon" data-toggle="collapse" data-target=".event-section"><i class="fa fa-compress"></i></button>
4848
</div>
4949
</div>

td/templates/resources/country_detail.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ <h2>Event Count</h2>
126126
<!-- COMMENTS VIEW -->
127127
<div id="comments-view" class="row tab-pane">
128128
<div class="col-md-12">
129-
{% render_comment_form for country %}
129+
{# {% render_comment_form for country %}#}
130130
{% include "comments/custom_lists.html" with object=country %}
131131
</div>
132132
</div>

0 commit comments

Comments
 (0)