|
@@ -0,0 +1,107 @@
|
|
|
+from requests import get
|
|
|
+from django.conf import settings
|
|
|
+from gauth.auth_utils import get_gmb_id
|
|
|
+from gauth.location_utils import get_all_location_ids
|
|
|
+from django.db.models import Max
|
|
|
+from .models import Review, Reply
|
|
|
+from gauth.models import Location
|
|
|
+
|
|
|
+
|
|
|
+ACCESS_TOKEN_URI = settings.HOST_URI + '/token'
|
|
|
+
|
|
|
+STAR_REVIEW_NUM = {'STAR_RATING_UNSPECIFIED': 0, 'ONE': 1, 'TWO': 2, 'THREE': 3, 'FOUR': 4, 'FIVE': 5}
|
|
|
+USER, GMB_ID = get_gmb_id()
|
|
|
+
|
|
|
+
|
|
|
+def get_review_list_url(loc_id, next_page_token=''):
|
|
|
+ # An helper function that make a url that need to consume GMB review api
|
|
|
+ return 'https://mybusiness.googleapis.com/v4/accounts/' + GMB_ID + '/locations/' + loc_id + '/reviews?pageToken='+next_page_token
|
|
|
+
|
|
|
+
|
|
|
+def get_max_date(loc_id):
|
|
|
+ # Function that takes a location id and return the latest updated review.
|
|
|
+ largest = Review.objects.filter(location_id=loc_id).aggregate(Max('create_time'))['create_time__max']
|
|
|
+ max_date = largest if largest else '1970-01-11 17:41:17.532740'
|
|
|
+ return max_date
|
|
|
+
|
|
|
+
|
|
|
+def get_auth_header():
|
|
|
+ access_token = get(ACCESS_TOKEN_URI).text
|
|
|
+ headers = {
|
|
|
+ 'authorization': 'Bearer ' + access_token,
|
|
|
+ 'content-type': 'application/json'
|
|
|
+ }
|
|
|
+ return headers
|
|
|
+
|
|
|
+
|
|
|
+def filter_unrecorded_review_by_date(reviews, max_date):
|
|
|
+ # A function that return only those reviews whose has larger value than
|
|
|
+ # the max create_time value in review database.
|
|
|
+ filtered_reviews = []
|
|
|
+ for rev in reviews:
|
|
|
+ if rev['createTime'] >= str(max_date):
|
|
|
+ filtered_reviews.append(rev)
|
|
|
+ return filtered_reviews
|
|
|
+
|
|
|
+
|
|
|
+def insert_review_into_database(unrecorded_reviews, loc):
|
|
|
+ for review in unrecorded_reviews:
|
|
|
+ review_id = review.get('reviewId')
|
|
|
+ # Check the review already in database then We don't need to store again.
|
|
|
+ rev = Review.objects.filter(pk=review_id).first()
|
|
|
+ if rev:
|
|
|
+ continue
|
|
|
+ comment = review.get('comment')
|
|
|
+ create_time = review.get('createTime')
|
|
|
+ update_time = review.get('updateTime')
|
|
|
+ star_rating = STAR_REVIEW_NUM[review.get('starRating')]
|
|
|
+ reviewer = review.get('reviewer')
|
|
|
+ reviewer_name = reviewer.get('displayName')
|
|
|
+ reviewer_photo = reviewer.get('profilePhotoUrl')
|
|
|
+ review_reply = review.get('reviewReply')
|
|
|
+ if review_reply:
|
|
|
+ replied_text = review_reply.get('comment')
|
|
|
+ create_time = review_reply.get('updateTime')
|
|
|
+ reply = Reply.objects.create(replied_text=replied_text, create_time=create_time)
|
|
|
+ else:
|
|
|
+ reply = None
|
|
|
+
|
|
|
+ review = Review(
|
|
|
+ review_id=review_id,
|
|
|
+ comment=comment,
|
|
|
+ create_time=create_time,
|
|
|
+ update_time=update_time,
|
|
|
+ star_rating=star_rating,
|
|
|
+ reviewer_name=reviewer_name,
|
|
|
+ reviewer_photo=reviewer_photo,
|
|
|
+ location=loc,
|
|
|
+ reply=reply
|
|
|
+ )
|
|
|
+ review.save()
|
|
|
+
|
|
|
+
|
|
|
+def fetch_all_review(loc_id):
|
|
|
+ loc = Location.objects.get(pk=loc_id)
|
|
|
+ max_date = get_max_date(loc_id)
|
|
|
+ next_page_token = ''
|
|
|
+ headers = get_auth_header()
|
|
|
+ while True:
|
|
|
+ url = get_review_list_url(loc_id, next_page_token)
|
|
|
+ res = get(url, headers=headers)
|
|
|
+ if res.status_code == 401:
|
|
|
+ headers = get_auth_header()
|
|
|
+ continue
|
|
|
+ data = res.json()
|
|
|
+ reviews = data['reviews']
|
|
|
+ unrecorded_reviews = filter_unrecorded_review_by_date(reviews, max_date)
|
|
|
+ if len(unrecorded_reviews) != 0:
|
|
|
+ insert_review_into_database(unrecorded_reviews, loc)
|
|
|
+ next_page_token = data.get('nextPageToken')
|
|
|
+ if next_page_token is None:
|
|
|
+ break
|
|
|
+
|
|
|
+
|
|
|
+def populate_reviews():
|
|
|
+ locations = get_all_location_ids()
|
|
|
+ for loc_id in locations:
|
|
|
+ fetch_all_review(loc_id)
|