Переглянути джерело

NLU staff has done and inference showed in dashboard

Mohidul Islam 5 роки тому
батько
коміт
682594a6e8

+ 5 - 0
dashboard/static/main.css

@@ -82,3 +82,8 @@ a.article-title:hover {
 .account-heading {
   font-size: 2.5rem;
 }
+
+.article-link {
+    text-decoration: none;
+    color: #2e333a;
+}

+ 8 - 0
dashboard/templates/_locationsidebar.html

@@ -0,0 +1,8 @@
+<div class="content-section">
+    <h3>ER Locations</h3>
+    <ul class="list-group">
+        {% for loc in locations %}
+        <li class="list-group-item list-group-item-light"><a href="{% url 'review-list-by-location' loc.location_id %}">{{ loc.care_name }}</a></li>
+        {% endfor %}
+    </ul>
+</div>

+ 33 - 0
dashboard/templates/_reportsidebar.html

@@ -0,0 +1,33 @@
+<div class="content-section" style="padding: 0px">
+<div class="card" >
+  <div class="card-body">
+    <h5 class="card-title">Intent Ranking</h5>
+    <hr>
+    {% for intent, confidence in intents.items %}
+      {{ intent }}
+      <div class="progress mb-2">
+          <div class="progress-bar" role="progressbar" style="width: {{ confidence }}%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100">{{ confidence }}%</div>
+      </div>
+    {% endfor %}
+  </div>
+</div>
+
+<div class="card">
+  <div class="card-body">
+    <h5 class="card-title">Replies</h5>
+    <hr>
+      {% for key, data in replies.items %}
+        <div class="card">
+          <h5 class="card-header">{{key}}</h5>
+          <div class="card-body" style="padding: 1px">
+            <ul class="list-group list-group-item-action">
+                {% for reply in data %}
+                  <li class="list-group-item" style="font-size: 14px"><p>{{ reply.reply }}</p></li>
+                {% endfor %}
+            </ul>
+          </div>
+        </div>
+      {% endfor %}
+  </div>
+</div>
+</div>

+ 7 - 10
dashboard/templates/base.html

@@ -43,19 +43,15 @@
     </header>
     <main role="main" class="container mb-5">
       <div class="row">
-        <div class="col-md-9">
+        <div class="col-md-8">
           {% block content %}{% endblock %}
         </div>
-        <div class="col-md-3">
+        <div class="col-md-4">
+        {% if intents %}
+          {% include '_reportsidebar.html' %}
+        {% endif %}
         {% if locations %}
-          <div class="content-section">
-            <h3>ER Locations</h3>
-              <ul class="list-group">
-                  {% for loc in locations %}
-                    <li class="list-group-item list-group-item-light"><a href="{% url 'review-list-by-location' loc.location_id %}">{{ loc.care_name }}</a></li>
-                  {% endfor %}
-              </ul>
-          </div>
+            {% include '_locationsidebar.html' %}
         {% endif %}
         </div>
       </div>
@@ -70,5 +66,6 @@
     <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
+
 </body>
 </html>

+ 6 - 8
dashboard/templates/dashboard.html

@@ -14,20 +14,18 @@
             <span style="color: #a41515; float: right">{% for star in "x"|ljust:review.star_rating %} &#9733; {% endfor %}</span>
         </div>
         {% if review.comment %}
-            <p class="article-content">{{ review.comment }}</p>
+            <a class="article-link" href="{% url 'predict' review.review_id %}" style="text-decoration: none; color: #232a31">
+                <p class="article-content">{{ review.comment }}</p>
+            </a>
         {% endif %}
-        <form method="post" class="form">
+        <form method="post" class="form" action="{% url 'un-replied-review' %}">
             {% csrf_token %}
                 {{ form|crispy }}
             <input type="hidden" value="{{ review.review_id }}" name="review_id">
-            <input class="btn btn-primary ml-5" style="float: right" type="submit", value="Submit"/>
+            <input class="btn btn-primary ml-2" style="float: right" type="submit", value="Submit"/>
         </form>
-<!--        <div class="row">-->
-<!--            <p class="mr-4">kid: <span class="ml-2" style="color: #0000FF;">{% for star in "x"|ljust:6 %} &#9899; {% endfor %}</span></p>-->
-<!--            <p class="mr-4">staff: <span class="ml-2" style="color: #0000FF;">{% for star in "x"|ljust:3 %} &#9899; {% endfor %}</span></p>-->
-<!--            <p class="mr-4">facility: <span class="ml-2" style="color: #0000FF;">{% for star in "x"|ljust:2 %} &#9899; {% endfor %}</span></p>-->
-<!--        </div>-->
         </div>
+
 </article>
 {% endfor %}
 {% endblock %}

+ 1 - 2
gauth/models.py

@@ -20,5 +20,4 @@ class Location(models.Model):
     owner = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
 
     def __str__(self):
-        return self.location_name
-
+        return self.care_name if self.care_name else self.location_name

+ 0 - 0
nlu_job/__init__.py


+ 3 - 0
nlu_job/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 5 - 0
nlu_job/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class NluJobConfig(AppConfig):
+    name = 'nlu_job'

+ 0 - 0
nlu_job/migrations/__init__.py


+ 3 - 0
nlu_job/models.py

@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.

+ 37 - 0
nlu_job/nlu_utils.py

@@ -0,0 +1,37 @@
+from django.conf import settings
+from requests import post
+import json
+
+nlu_server_url = settings.NLU_SERVER_URI
+
+
+def model_inference(text):
+    url = nlu_server_url + '/model/parse'
+    payload = {'text': text}
+    headers = {'content-type': 'application/json'}
+
+    response = post(url, data=json.dumps(payload), headers=headers)
+    if response.status_code == 200:
+        return response.json()
+    return response
+
+
+def analyze_inference(response):
+    '''
+    response has four property
+    ['intent', 'entities', 'intent_ranking', 'text']
+    we took all intents that has more than 10% of intent confident.
+    all the intents that has bellow confidence has been omitted.
+    :param response:
+    :return: dictionary with key of intent and value of it's confident.
+    '''
+
+    res_intents = response.get('intent_ranking')
+    intents = {}
+    for intent in res_intents:
+        key = intent.get('name')
+        values = intent.get('confidence')
+        if values > 0.1:
+            intents[key] = int(values*100)
+
+    return intents

+ 3 - 0
nlu_job/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 7 - 0
nlu_job/urls.py

@@ -0,0 +1,7 @@
+from django.urls import path
+from .views import predict_report
+
+
+urlpatterns = [
+    path('predict/<review_id>/', predict_report, name='predict'),
+]

+ 31 - 0
nlu_job/views.py

@@ -0,0 +1,31 @@
+from django.shortcuts import render
+from django.utils import timezone
+from django.shortcuts import redirect
+from review.forms import ReplyForm
+from review.models import Review, CustomReply
+
+from .nlu_utils import model_inference, analyze_inference
+
+
+def predict_report(request, review_id):
+    review = Review.objects.filter(review_id=review_id).first()
+    if review is None:
+        return redirect('un-replied-review')
+    text = review.comment.lower()
+    res = model_inference(text=text)
+    intents = analyze_inference(res)
+    now = timezone.now()
+    form = ReplyForm()
+    date = now - timezone.timedelta(days=30)
+    reviews = Review.objects.filter(reply=None, update_time__gte=date).order_by('-update_time')
+    replies = {}
+    for intent in intents.keys():
+        r = CustomReply.objects.filter(reply_category=intent)
+        replies[intent] = r
+    context = {
+        'reviews': reviews,
+        'form': form,
+        'intents': intents,
+        'replies': replies
+    }
+    return render(request, 'dashboard.html', context)

+ 1 - 1
review/forms.py

@@ -2,4 +2,4 @@ from django import forms
 
 
 class ReplyForm(forms.Form):
-    reply = forms.CharField(max_length=2000, widget=forms.Textarea(attrs={'rows': 3}))
+    reply = forms.CharField(max_length=2000, widget=forms.Textarea(attrs={'rows': 4}))

+ 0 - 1
review/models.py

@@ -1,5 +1,4 @@
 from django.db import models
-from django.contrib.auth.models import User
 from gauth.models import Location
 
 

+ 2 - 0
review_automation/settings.py

@@ -26,6 +26,7 @@ INSTALLED_APPS = [
     'gauth.apps.GauthConfig',
     'review.apps.ReviewConfig',
     'dashboard.apps.DashboardConfig',
+    'nlu_job.apps.NluJobConfig',
 
     'crispy_forms',
 ]
@@ -122,3 +123,4 @@ CLIENT_ID = "174657415928-0bt50gt42pslq47gf21ao67n15rom96r.apps.googleuserconten
 CLIENT_SECRET = "ZXYpt07Su0pW3y3jPGOXY_C_"
 TOKEN_URI = "https://oauth2.googleapis.com/token"
 HOST_URI = "http://127.0.0.1:8000"
+NLU_SERVER_URI = 'http://localhost:5005'

+ 2 - 1
review_automation/urls.py

@@ -6,6 +6,7 @@ from django.conf.urls.static import static
 urlpatterns = [
     path('admin/', admin.site.urls),
     path('', include('gauth.urls')),
+    path('nlu/', include('nlu_job.urls')),
     path('dashboard/', include('dashboard.urls')),
-]+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
+] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)