Skip to content

Instantly share code, notes, and snippets.

@jeann2013
Created June 4, 2019 17:09
Show Gist options
  • Save jeann2013/860a40718857eddfc74e9ac98ca75fdd to your computer and use it in GitHub Desktop.
Save jeann2013/860a40718857eddfc74e9ac98ca75fdd to your computer and use it in GitHub Desktop.
from __future__ import division
import datetime
from ..logger import get_logger
from ..models import LocationStats, Review, LocationMediaCustomers, Protocols
from firebase_admin import db as firebase_db
import arrow
from .. import celery
from datetime import datetime
from app.account import service as account_service
from app.google import google_service
from app import get_app
app = get_app()
logger = get_logger(__name__)
def get_top_metrics(path, gid):
listMetrics = ['ACTIONS_WEBSITE',
'ACTIONS_PHONE',
'QUERIES_INDIRECT',
'VIEWS_SEARCH',
'ACTIONS_DRIVING_DIRECTIONS',
'QUERIES_DIRECT',
'VIEWS_SEARCH',
'VIEWS_MAPS']
arrMetrics = dict()
for metric in listMetrics:
name = 'metrics.' + metric
query = {
'gid': gid,
'path': path,
name: {'$gt': 0}
}
metrics = list(LocationStats.objects().filter(__raw__=query).order_by('-' + name).limit(5))
arr = []
for mt in metrics:
if '_id' in mt:
mt['_id'] = str(mt['_id'])
if 'metrics' in mt:
mm = mt['metrics']
value = mm[metric]
date = mt['date'].strftime('%Y-%m-%d %H:%M:%S')
arr.append({'date': date, 'value': value})
arrMetrics[metric] = arr
return arrMetrics
def save_observations(gid, account_id, location_id, data):
path = '{}/accounts/{}/locations/{}'.format(gid, account_id, location_id)
observations = []
# Media in the last 30 days?
if data.get('media', {}).get('mediaItems', None) is not None:
last_media = arrow.get(data['media']['mediaItems'][0]['createTime']).datetime
if (arrow.utcnow() - last_media).days >= 30:
observations.append({"key": "no_media_30",
"message": "Try adding at least 5 new photos every month \
and also upload images to photo categories that do not have \
any content currently. "})
# Posts in the last 30 days?
if data.get('posts', {}).get('localPosts', None) is not None:
last_post = arrow.get(data['posts']['localPosts'][0]['createTime']).datetime
if (arrow.utcnow() - last_post).days >= 30:
observations.append({"key": "no_posts_30",
"message": "Try adding at least 1 new post every month and \
to focus on creating content that will increase engagement on \
your listing like an Offer or Event. "})
# Reviews in the last 30 days?
if data.get('reviews', {}).get('reviews', None) is not None:
last_review = arrow.get(data['reviews']['reviews'][0]['createTime']).datetime
if (arrow.utcnow() - last_review).days >= 30:
observations.append({"key": "no_reviews_30",
"message": "Try creating a review generation campaign by sending\
a 'review link' to customers via email or text to make it easier \
to leave a comment on your listing. Also try to train your staff \
to request reviews when customers share positive experiences in person."})
# Reviews ratios > 10% unreplied
unreplied = len(Review.get_all([account_id], [location_id], False))
replied = len(Review.get_all([account_id], [location_id], True))
total_reviews = replied + unreplied
if total_reviews is not 0:
unreplied_ratio = 100 - ((replied / total_reviews) * 100)
if unreplied_ratio >= 10:
observations.append({"key": "unreplied_ratio_10",
"message": "Make sure you are responding to customer\
reviews of all ratings, not just negative or positive\
reviews. Reviews with responses tend to appear higher\
in your \"most relevant\" reviews that Google shows\
users. If you can't manually respond to reviews,\
set up an Auto Responder campaign so that customers \
get feedback quicker and shows Google that you're\
an engaged business owner."})
# Location has menu/services?
ref = firebase_db.reference('saved_locations')
location_data = ref.child(path).get()
services = location_data.get('priceLists', None)
if services is None:
observations.append({"key": "no_services",
"message": "Make sure you upload a list of all your \
services / menu items to your business listing. Google \
indexes this content and shows it in \"Rich snippets\" \
in relevant searches. By adding your menu / services \
you are increasing the likelihood that Google will \
present your listing to users when searching for keywords \
related to your services / menu items. "})
path = '{}/accounts/{}/locations/{}'.format(gid, account_id, location_id)
ref = firebase_db.reference('observations')
obs = ref.child(path).get()
# TODO: Bad... need to keep records, not delete them.
if obs is not None:
for ob in obs:
ref.child(path + '/' + ob).delete()
for ob in observations:
ref.child(path).push({
'key': ob['key'],
'message': ob['message'],
'date_sent': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
})
return observations
def grader(gid, account_id, location_id):
grade = {}
data = google_service.verification_location_to_google(gid, None, account_id, location_id)
# Media in the last N days
if data.get('media', {}).get('mediaItems', None) is not None:
last_media = arrow.get(data['media']['mediaItems'][0]['createTime']).datetime
if (arrow.utcnow() - last_media).days <= 30:
media_points = 3
elif (arrow.utcnow() - last_media).days >= 30:
media_points = 2
elif (arrow.utcnow() - last_media).days >= 60:
media_points = 1
elif (arrow.utcnow() - last_media).days >= 90:
media_points = 0
else:
media_points = 0
grade.update({
'posted_media': {
'denominator_max': 3,
'score': media_points
}
})
return grade
@celery.task
def observations_for_all_locations():
with app.app_context():
active_groups = account_service.get_active_groups()
all_locations = account_service.get_all_locations_for_groups(active_groups)
for al in all_locations:
uid = al.get('uid')
gid = al.get('gid')
location_id = al.get('location_id')
account_id = al.get('account_id')
schedule_observations.delay(
**{'gid': gid, 'uid': uid, 'account_id': account_id, 'location_id': location_id})
@celery.task
def schedule_observations(gid, uid, account_id, location_id):
auth_data = google_service.verification_location_to_google(gid, uid, account_id, location_id)
observations = save_observations(gid, account_id, location_id, auth_data)
logger.debug('Completed task observation for account: {} locatiob: {}'.format(account_id, location_id))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment