utils.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import numpy as np
  2. from django.utils import timezone
  3. from review.models import Review
  4. from django.db.models import Count
  5. from django.db import connection
  6. def last_month_reviews(location_id):
  7. now = timezone.now()
  8. date = now.replace(day=1)
  9. day = (date - timezone.timedelta(days=1)).day + 1
  10. prev_date = date - timezone.timedelta(days=day)
  11. res = Review.objects.filter(create_time__range=(prev_date, date), location_id=location_id).\
  12. values('star_rating').annotate(total=Count('star_rating')).order_by('star_rating')
  13. ratings = [0] * 5
  14. for r in res:
  15. ratings[r.get('star_rating') - 1] = r.get('total')
  16. return ratings
  17. def weekly_reviews_summary(location_id):
  18. now = timezone.now()
  19. date = now - timezone.timedelta(days=7)
  20. reviews = Review.objects.filter(
  21. create_time__gte=date,
  22. location_id=location_id
  23. )
  24. ratings = reviews.values('star_rating')\
  25. .annotate(total=Count('star_rating'))\
  26. .order_by('-star_rating')
  27. return reviews, ratings
  28. def last_data(date, location_id):
  29. res = Review.objects.filter(create_time__gte=date, location_id=location_id).values('star_rating')\
  30. .annotate(total=Count('star_rating')).order_by('star_rating')
  31. ratings = [0] * 5
  32. for r in res:
  33. ratings[r.get('star_rating')-1] = r.get('total')
  34. return ratings
  35. def get_review_count_by_week(location_id):
  36. now = timezone.now()
  37. day = 6 - now.weekday()
  38. first_day_week = now - timezone.timedelta(days=(now.weekday()+1))
  39. this_week = last_data(first_day_week, location_id)
  40. sql = f'''
  41. SELECT WEEK(create_time) as month, star_rating, COALESCE(COUNT(*), 0) as total_review
  42. FROM review_review
  43. WHERE DATE_ADD(DATE_ADD(CURRENT_TIMESTAMP(),
  44. INTERVAL -1 YEAR), INTERVAL {day} DAY) <= create_time and location_id={location_id}
  45. GROUP BY WEEK(create_time), star_rating
  46. ORDER BY create_time;
  47. '''
  48. with connection.cursor() as cursor:
  49. cursor.execute(sql)
  50. rows = cursor.fetchall()
  51. # It will transform a cursor like ((3, 5, 26), (43, 3, 21), ...)
  52. # to a dict like this {(3, 5): 26, (43, 3): 21), ...}
  53. # Here key tuple (3, 5) means 5 star ratings in 3rd week of the year and value is the number of star count.
  54. row_dict = {(row[0], row[1]): row[2] for row in rows}
  55. # Get all week names for graph label
  56. labels = []
  57. for row in rows:
  58. if row[0] not in labels:
  59. labels.append(row[0])
  60. star_ratings = []
  61. for i in range(1, 6):
  62. row = [row_dict.get((w, i), 0) for w in labels]
  63. star_ratings.append(row)
  64. total_review = list(np.sum(star_ratings, axis=0))
  65. response = {
  66. 'label': labels,
  67. 'total_reviews': total_review,
  68. 'one_star': star_ratings[0],
  69. 'two_star': star_ratings[1],
  70. 'three_star': star_ratings[2],
  71. 'four_star': star_ratings[3],
  72. 'five_star': star_ratings[4],
  73. 'this': this_week
  74. }
  75. return response
  76. def get_review_count_by_month(location_id):
  77. now = timezone.now()
  78. date = now.replace(day=1) - timezone.timedelta(days=1)
  79. day = date.day - now.day
  80. first_day_month = now - timezone.timedelta(days=now.day)
  81. this_month = last_data(first_day_month, location_id)
  82. sql = f'''
  83. SELECT MONTHNAME(create_time) as month, star_rating, COALESCE(COUNT(*), 0) as total_review
  84. FROM review_review
  85. WHERE DATE_ADD(DATE_ADD(CURRENT_TIMESTAMP(),
  86. INTERVAL -1 YEAR), INTERVAL {day} DAY) <= create_time and location_id={location_id}
  87. GROUP BY MONTHNAME(create_time), star_rating
  88. ORDER BY create_time;
  89. '''
  90. with connection.cursor() as cursor:
  91. cursor.execute(sql)
  92. rows = cursor.fetchall()
  93. # It will transform a cursor like (('September', 5, 26), ('October', 3, 21), ...)
  94. # to a dict like this {('September', 5): 26, ('October', 3): 21), ...}
  95. # Here key tuple ('September', 5) means 5 star ratings in September month and value is the number of star count.
  96. row_dict = {(row[0], row[1]): row[2] for row in rows}
  97. # Get all month names for graph label
  98. labels = []
  99. for row in rows:
  100. if row[0] not in labels:
  101. labels.append(row[0])
  102. star_ratings = []
  103. for i in range(1, 6):
  104. row = [row_dict.get((m, i), 0) for m in labels]
  105. star_ratings.append(row)
  106. total_review = list(np.sum(star_ratings, axis=0))
  107. response = {
  108. 'label': labels,
  109. 'total_reviews': total_review,
  110. 'one_star': star_ratings[0],
  111. 'two_star': star_ratings[1],
  112. 'three_star': star_ratings[2],
  113. 'four_star': star_ratings[3],
  114. 'five_star': star_ratings[4],
  115. 'this': this_month
  116. }
  117. return response
  118. def get_list_of_reviews(google_reviews, facebook_reviews, yelp_reviews):
  119. google_review_list = list(google_reviews.exclude(star_rating__range=(3, 4)).
  120. values('comment', 'star_rating', 'create_time', 'reviewer_name'))
  121. facebook_review_list = list(facebook_reviews.
  122. values('id', 'recommendation_type', 'review_text', 'create_time'))
  123. yelp_review_list = list(yelp_reviews.exclude(rating__range=(3, 4)).
  124. values('comment', 'reviewer_name', 'rating', 'date_posted'))
  125. all_revs = []
  126. for rev in google_review_list:
  127. if not rev['comment']:
  128. continue
  129. # if rev['star_rating'] == 5 and len(rev['comment']) < 100:
  130. # continue
  131. rev['create_time'] = str(rev['create_time']).split()[0]
  132. rev['platform'] = 'Google'
  133. if rev['star_rating'] < 3:
  134. rev['positive'] = False
  135. else:
  136. rev['positive'] = True
  137. all_revs.append(rev)
  138. # Adding the facebook reviews
  139. for rev in facebook_review_list:
  140. if not rev['review_text']:
  141. continue
  142. rev['platform'] = 'Facebook'
  143. rev['create_time'] = str(rev['create_time']).split()[0]
  144. recommendation_type = rev.pop('recommendation_type')
  145. comment = rev.pop('review_text')
  146. reviewer = rev.pop('id')
  147. if recommendation_type:
  148. rev['positive'] = True
  149. else:
  150. rev['positive'] = False
  151. rev['comment'] = comment
  152. rev['reviewer_name'] = reviewer
  153. all_revs.append(rev)
  154. # Adding the yelp reviews
  155. for rev in yelp_review_list:
  156. if not rev['comment']:
  157. continue
  158. rev['platform'] = 'Yelp'
  159. date_posted = rev.pop('date_posted')
  160. rev['create_time'] = str(date_posted).split()[0]
  161. if rev['rating'] < 3:
  162. rev['positive'] = False
  163. else:
  164. rev['positive'] = True
  165. all_revs.append(rev)
  166. return all_revs