소스 검색

added word cloud to manager review list page

Mohidul Islam 4 년 전
부모
커밋
cf6c505575
83개의 변경된 파일128개의 추가작업 그리고 4개의 파일을 삭제
  1. 2 0
      .gitignore
  2. 24 2
      manager/templates/manager-dashboard.html
  3. 28 1
      manager/templates/review-list-man.html
  4. 60 0
      manager/word_cloud.py
  5. BIN
      media/facebook/negative/12541597562633926366.png
  6. BIN
      media/facebook/negative/13486358490203335051.png
  7. BIN
      media/facebook/negative/14567670160750071148.png
  8. BIN
      media/facebook/negative/14748677429039074158.png
  9. BIN
      media/facebook/negative/14904078213800803294.png
  10. BIN
      media/facebook/negative/15979470999169074295.png
  11. BIN
      media/facebook/negative/16389487648212004696.png
  12. BIN
      media/facebook/negative/16590124370714063921.png
  13. BIN
      media/facebook/negative/16891069708558046635.png
  14. BIN
      media/facebook/negative/17394740196501090048.png
  15. BIN
      media/facebook/negative/17898197009688164559.png
  16. BIN
      media/facebook/negative/2077061009497551125.png
  17. BIN
      media/facebook/negative/2694018788013845459.png
  18. BIN
      media/facebook/negative/3272657195432704501.png
  19. BIN
      media/facebook/negative/3511292162159714121.png
  20. BIN
      media/facebook/negative/6521947413723274945.png
  21. BIN
      media/facebook/negative/8626688543755174284.png
  22. BIN
      media/facebook/negative/8679688254631342173.png
  23. BIN
      media/facebook/negative/8918455867446117794.png
  24. BIN
      media/facebook/positive/12541597562633926366.png
  25. BIN
      media/facebook/positive/13486358490203335051.png
  26. BIN
      media/facebook/positive/14567670160750071148.png
  27. BIN
      media/facebook/positive/14748677429039074158.png
  28. BIN
      media/facebook/positive/14904078213800803294.png
  29. BIN
      media/facebook/positive/15979470999169074295.png
  30. BIN
      media/facebook/positive/16389487648212004696.png
  31. BIN
      media/facebook/positive/16590124370714063921.png
  32. BIN
      media/facebook/positive/16891069708558046635.png
  33. BIN
      media/facebook/positive/17394740196501090048.png
  34. BIN
      media/facebook/positive/17898197009688164559.png
  35. BIN
      media/facebook/positive/2077061009497551125.png
  36. BIN
      media/facebook/positive/2694018788013845459.png
  37. BIN
      media/facebook/positive/3272657195432704501.png
  38. BIN
      media/facebook/positive/3511292162159714121.png
  39. BIN
      media/facebook/positive/6521947413723274945.png
  40. BIN
      media/facebook/positive/8626688543755174284.png
  41. BIN
      media/facebook/positive/8679688254631342173.png
  42. BIN
      media/facebook/positive/8918455867446117794.png
  43. BIN
      media/google/negative/12541597562633926366.png
  44. BIN
      media/google/negative/13486358490203335051.png
  45. BIN
      media/google/negative/14567670160750071148.png
  46. BIN
      media/google/negative/14748677429039074158.png
  47. BIN
      media/google/negative/14904078213800803294.png
  48. BIN
      media/google/negative/15979470999169074295.png
  49. BIN
      media/google/negative/16389487648212004696.png
  50. BIN
      media/google/negative/16590124370714063921.png
  51. BIN
      media/google/negative/16891069708558046635.png
  52. BIN
      media/google/negative/17394740196501090048.png
  53. BIN
      media/google/negative/17898197009688164559.png
  54. BIN
      media/google/negative/2077061009497551125.png
  55. BIN
      media/google/negative/2694018788013845459.png
  56. BIN
      media/google/negative/3272657195432704501.png
  57. BIN
      media/google/negative/3511292162159714121.png
  58. BIN
      media/google/negative/6521947413723274945.png
  59. BIN
      media/google/negative/8626688543755174284.png
  60. BIN
      media/google/negative/8679688254631342173.png
  61. BIN
      media/google/negative/8918455867446117794.png
  62. BIN
      media/google/positive/12541597562633926366.png
  63. BIN
      media/google/positive/13486358490203335051.png
  64. BIN
      media/google/positive/14567670160750071148.png
  65. BIN
      media/google/positive/14748677429039074158.png
  66. BIN
      media/google/positive/14904078213800803294.png
  67. BIN
      media/google/positive/15979470999169074295.png
  68. BIN
      media/google/positive/16389487648212004696.png
  69. BIN
      media/google/positive/16590124370714063921.png
  70. BIN
      media/google/positive/16891069708558046635.png
  71. BIN
      media/google/positive/17394740196501090048.png
  72. BIN
      media/google/positive/17898197009688164559.png
  73. BIN
      media/google/positive/2077061009497551125.png
  74. BIN
      media/google/positive/2694018788013845459.png
  75. BIN
      media/google/positive/3272657195432704501.png
  76. BIN
      media/google/positive/3511292162159714121.png
  77. BIN
      media/google/positive/6521947413723274945.png
  78. BIN
      media/google/positive/8626688543755174284.png
  79. BIN
      media/google/positive/8679688254631342173.png
  80. BIN
      media/google/positive/8918455867446117794.png
  81. 10 0
      requirements.txt
  82. 2 0
      review_automation/settings/base.py
  83. 2 1
      review_automation/urls.py

+ 2 - 0
.gitignore

@@ -1,4 +1,6 @@
 # Byte-compiled / optimized / DLL files
+
+d*.png
 __pycache__/
 *.py[cod]
 *$py.class

+ 24 - 2
manager/templates/manager-dashboard.html

@@ -10,14 +10,25 @@
       <div class="card-header"><h5 class="card-title">Google <span><i class="fa fa-google" aria-hidden="true"></i></span></h5></div>
         <div class="card-body">
           <table class="table">
-            <tr><td><i class="fa fa-pencil-square-o" aria-hidden="true"></i> Reviews</td> <td>Count</td></tr>
             <tr>
+              <td>
+                <i class="fa fa-pencil-square-o" aria-hidden="true"></i> Reviews
+              </td>
+              <td>
+                <i class="fa fa-thumbs-o-up" aria-hidden="true"></i> Positive
+              </td>
+              <td>
+                <i class="fa fa-thumbs-o-down" aria-hidden="true"></i> Negative
+              </td>
+              </tr>
               <td>This month (so far)</td>
               <td>{{ google_this_month }}</td>
+              <td>{{ google_this_month }}</td>
             </tr>
             <tr>
               <td>Last month</td>
               <td>{{ google_last_month }}</td>
+              <td>{{ google_last_month }}</td>
             </tr>
           </table>
         </div>
@@ -48,14 +59,25 @@
         <div class="card-body">
           <table class="table">
             <tr>
-              <td><i class="fa fa-pencil-square-o" aria-hidden="true"></i> Reviews</td> <td>Count</td></tr>
+              <td>
+                <i class="fa fa-pencil-square-o" aria-hidden="true"></i> Reviews
+              </td>
+              <td>
+                <i class="fa fa-thumbs-o-up" aria-hidden="true"></i> Positive
+              </td>
+              <td>
+                <i class="fa fa-thumbs-o-down" aria-hidden="true"></i> Negative
+              </td>
+            </tr>
             <tr>
               <td>This month (so far)</td>
               <td>{{ facebook_this_month }}</td>
+              <td>{{ facebook_this_month }}</td>
             </tr>
             <tr>
               <td>Last month</td>
               <td>{{ facebook_last_month }}</td>
+              <td>{{ facebook_last_month }}</td>
             </tr>
           </table>
         </div>

+ 28 - 1
manager/templates/review-list-man.html

@@ -1,4 +1,5 @@
 {% extends 'manager-base.html' %}
+{% load static %}
 
 {% block filter %}
   <div class="btn-toolbar mb-2 mb-md-0">
@@ -33,7 +34,33 @@
 
 
 {% block content %}
-<h2 style="text-align: center;">All reviews posted on {{ platform|title }}</h2>
+<!--<h2 style="text-align: center;">All reviews posted on {{ platform|title }}</h2>-->
+<div class="row" style="padding: 0rem 1rem 0rem 1rem;">
+  <div class="col-sm-6 col-md-6">
+    <div class="card">
+    <div class="card-header">
+      Word frequently found in {{ platform|title }} positive reviews.
+    </div>
+    <div class="card-body">
+    <blockquote class="blockquote mb-0">
+      <img src="/media/{{ platform }}/positive/{{ location.location_id }}.png" width="100%" alt="">
+    </blockquote>
+    </div>
+    </div>
+  </div>
+  <div class="col-sm-6 col-md-6">
+    <div class="card">
+      <div class="card-header">
+        <span style="text-align: center;">Word frequently found in {{ platform|title }} negative reviews.</span>
+      </div>
+      <div class="card-body">
+      <blockquote class="blockquote mb-0">
+        <img src="/media/{{ platform }}/negative/{{ location.location_id }}.png" width="100%" alt="">
+      </blockquote>
+      </div>
+    </div>
+  </div>
+</div>
 {% for review in reviews %}
   {% if platform == 'google' %}
     {% include '_google_review.html' %}

+ 60 - 0
manager/word_cloud.py

@@ -0,0 +1,60 @@
+import os
+import time
+from wordcloud import WordCloud, STOPWORDS
+
+from django.conf import settings
+from gauth.models import Location
+from review.models import Review
+from facebook_app.models import FacebookReview
+
+
+WC = WordCloud(
+    width=1200,
+    height=300,
+    background_color='white',
+    stopwords=STOPWORDS
+)
+GOOGLE_PATH = os.path.join(settings.BASE_DIR, 'media', 'google')
+FACEBOOK_PATH = os.path.join(settings.BASE_DIR, 'media', 'facebook')
+
+
+def create_wc_for_google(location_id):
+    reviews = Review.objects.filter(location_id=location_id).exclude(comment=None)
+    pos_reviews = reviews.filter(star_rating__gte=4)[:100]
+    neg_reviews = reviews.filter(star_rating__lte=3)[:100]
+    pos_text = ' '.join([review.comment for review in pos_reviews])
+    neg_text = ' '.join([review.comment for review in neg_reviews])
+    if len(pos_text) == 0:
+        pos_text = "No positive Review found."
+    if len(neg_text) == 0:
+        neg_text = "No negative Review found."
+    wc = WC.generate_from_text(pos_text)
+    wc.to_file(GOOGLE_PATH+'/positive/'+f'{location_id}.png')
+    wc = WC.generate_from_text(neg_text)
+    wc.to_file(GOOGLE_PATH+'/negative/'+f'{location_id}.png')
+
+
+def create_wc_for_facebook(location_id):
+    reviews = FacebookReview.objects.filter(page__location_id=location_id).exclude(review_text=None)
+    pos_reviews = reviews.filter(recommendation_type=True)[:100]
+    neg_reviews = reviews.filter(recommendation_type=False)[:100]
+    pos_text = ' '.join([review.review_text for review in pos_reviews])
+    neg_text = ' '.join([review.review_text for review in neg_reviews])
+    if len(pos_text) == 0:
+        pos_text = "Didn't found posted any positive Review."
+    if len(neg_text) == 0:
+        neg_text = "Didn't found posted any negative Review."
+    wc = WC.generate_from_text(pos_text)
+    wc.to_file(FACEBOOK_PATH+'/positive/'+f'{location_id}.png')
+    wc = WC.generate_from_text(neg_text)
+    wc.to_file(FACEBOOK_PATH+'/negative/'+f'{location_id}.png')
+
+
+def generate_word_clouds():
+    locations = Location.objects.all()
+    start = time.time()
+    for loc in locations:
+        create_wc_for_google(location_id=loc.location_id)
+        create_wc_for_facebook(location_id=loc.location_id)
+    end = time.time()
+    print('Elapsed time: ', end-start, 'millisecond.')

BIN
media/facebook/negative/12541597562633926366.png


BIN
media/facebook/negative/13486358490203335051.png


BIN
media/facebook/negative/14567670160750071148.png


BIN
media/facebook/negative/14748677429039074158.png


BIN
media/facebook/negative/14904078213800803294.png


BIN
media/facebook/negative/15979470999169074295.png


BIN
media/facebook/negative/16389487648212004696.png


BIN
media/facebook/negative/16590124370714063921.png


BIN
media/facebook/negative/16891069708558046635.png


BIN
media/facebook/negative/17394740196501090048.png


BIN
media/facebook/negative/17898197009688164559.png


BIN
media/facebook/negative/2077061009497551125.png


BIN
media/facebook/negative/2694018788013845459.png


BIN
media/facebook/negative/3272657195432704501.png


BIN
media/facebook/negative/3511292162159714121.png


BIN
media/facebook/negative/6521947413723274945.png


BIN
media/facebook/negative/8626688543755174284.png


BIN
media/facebook/negative/8679688254631342173.png


BIN
media/facebook/negative/8918455867446117794.png


BIN
media/facebook/positive/12541597562633926366.png


BIN
media/facebook/positive/13486358490203335051.png


BIN
media/facebook/positive/14567670160750071148.png


BIN
media/facebook/positive/14748677429039074158.png


BIN
media/facebook/positive/14904078213800803294.png


BIN
media/facebook/positive/15979470999169074295.png


BIN
media/facebook/positive/16389487648212004696.png


BIN
media/facebook/positive/16590124370714063921.png


BIN
media/facebook/positive/16891069708558046635.png


BIN
media/facebook/positive/17394740196501090048.png


BIN
media/facebook/positive/17898197009688164559.png


BIN
media/facebook/positive/2077061009497551125.png


BIN
media/facebook/positive/2694018788013845459.png


BIN
media/facebook/positive/3272657195432704501.png


BIN
media/facebook/positive/3511292162159714121.png


BIN
media/facebook/positive/6521947413723274945.png


BIN
media/facebook/positive/8626688543755174284.png


BIN
media/facebook/positive/8679688254631342173.png


BIN
media/facebook/positive/8918455867446117794.png


BIN
media/google/negative/12541597562633926366.png


BIN
media/google/negative/13486358490203335051.png


BIN
media/google/negative/14567670160750071148.png


BIN
media/google/negative/14748677429039074158.png


BIN
media/google/negative/14904078213800803294.png


BIN
media/google/negative/15979470999169074295.png


BIN
media/google/negative/16389487648212004696.png


BIN
media/google/negative/16590124370714063921.png


BIN
media/google/negative/16891069708558046635.png


BIN
media/google/negative/17394740196501090048.png


BIN
media/google/negative/17898197009688164559.png


BIN
media/google/negative/2077061009497551125.png


BIN
media/google/negative/2694018788013845459.png


BIN
media/google/negative/3272657195432704501.png


BIN
media/google/negative/3511292162159714121.png


BIN
media/google/negative/6521947413723274945.png


BIN
media/google/negative/8626688543755174284.png


BIN
media/google/negative/8679688254631342173.png


BIN
media/google/negative/8918455867446117794.png


BIN
media/google/positive/12541597562633926366.png


BIN
media/google/positive/13486358490203335051.png


BIN
media/google/positive/14567670160750071148.png


BIN
media/google/positive/14748677429039074158.png


BIN
media/google/positive/14904078213800803294.png


BIN
media/google/positive/15979470999169074295.png


BIN
media/google/positive/16389487648212004696.png


BIN
media/google/positive/16590124370714063921.png


BIN
media/google/positive/16891069708558046635.png


BIN
media/google/positive/17394740196501090048.png


BIN
media/google/positive/17898197009688164559.png


BIN
media/google/positive/2077061009497551125.png


BIN
media/google/positive/2694018788013845459.png


BIN
media/google/positive/3272657195432704501.png


BIN
media/google/positive/3511292162159714121.png


BIN
media/google/positive/6521947413723274945.png


BIN
media/google/positive/8626688543755174284.png


BIN
media/google/positive/8679688254631342173.png


BIN
media/google/positive/8918455867446117794.png


+ 10 - 0
requirements.txt

@@ -5,6 +5,7 @@ cachetools==4.0.0
 catalogue==1.0.0
 certifi==2019.11.28
 chardet==3.0.4
+cycler==0.10.0
 cymem==2.0.3
 Django==3.0.4
 django-crispy-forms==1.9.0
@@ -12,20 +13,28 @@ django-crontab==0.7.1
 django-tempus-dominus==5.1.2.13
 djangorestframework==3.11.0
 en-core-web-sm==2.3.1
+et-xmlfile==1.0.1
 facebook-sdk==3.1.0
 google-auth==1.11.2
 google-auth-oauthlib==0.4.1
 idna==2.9
 importlib-metadata==2.0.0
+jdcal==1.4.1
+kiwisolver==1.3.1
+matplotlib==3.3.4
 murmurhash==1.0.2
 mysqlclient==1.4.6
 nameparser==1.0.6
 numpy==1.19.1
 oauthlib==3.1.0
+openpyxl==3.0.6
+Pillow==8.1.0
 plac==1.1.3
 preshed==3.0.2
 pyasn1==0.4.8
 pyasn1-modules==0.2.8
+pyparsing==2.4.7
+python-dateutil==2.8.1
 pytz==2019.3
 requests==2.23.0
 requests-oauthlib==1.3.0
@@ -40,4 +49,5 @@ thinc==7.4.1
 tqdm==4.50.0
 urllib3==1.25.8
 wasabi==0.8.0
+wordcloud==1.8.1
 zipp==3.3.0

+ 2 - 0
review_automation/settings/base.py

@@ -85,6 +85,8 @@ USE_TZ = True
 
 STATIC_URL = '/static/'
 STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
+MEDIA_URL = '/media/'
+MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
 
 LOGIN_URL = '/user/login'
 LOGIN_REDIRECT_URL = 'login-redirect'

+ 2 - 1
review_automation/urls.py

@@ -16,7 +16,8 @@ urlpatterns = [
     path('facebook/', include('facebook_app.urls')),
     path('user/', include('user.urls')),
     path('managers/', include('manager.urls')),
-] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
+] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)\
+              + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
 
 
 admin.site.site_header = "Byte Trek Online Reputation Manager"