[WIP] Added dao method and rest endpoint for getting template

statistics by service.

Some cosmetic changes to imports.

Added fix for job rest not correctly returning errors.
This commit is contained in:
Adam Shimali
2016-04-04 12:21:38 +01:00
parent e2d0d39ea7
commit 0d06be05e1
10 changed files with 390 additions and 44 deletions

View File

@@ -56,6 +56,7 @@ def create_app(app_name=None):
from app.permission.rest import permission as permission_blueprint
from app.accept_invite.rest import accept_invite
from app.notifications_statistics.rest import notifications_statistics as notifications_statistics_blueprint
from app.template_statistics.rest import template_statistics as template_statistics_blueprint
application.register_blueprint(service_blueprint, url_prefix='/service')
application.register_blueprint(user_blueprint, url_prefix='/user')
@@ -67,6 +68,7 @@ def create_app(app_name=None):
application.register_blueprint(permission_blueprint, url_prefix='/permission')
application.register_blueprint(accept_invite, url_prefix='/invite')
application.register_blueprint(notifications_statistics_blueprint)
application.register_blueprint(template_statistics_blueprint)
return application

View File

@@ -25,6 +25,23 @@ from app.clients import (
STATISTICS_REQUESTED
)
from functools import wraps
def transactional(func):
@wraps(func)
def commit_or_rollback(*args, **kwargs):
from flask import current_app
from app import db
try:
func(*args, **kwargs)
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
raise
return commit_or_rollback
def dao_get_notification_statistics_for_service(service_id):
return NotificationStatistics.query.filter_by(
@@ -39,46 +56,55 @@ def dao_get_notification_statistics_for_service_and_day(service_id, day):
).order_by(desc(NotificationStatistics.day)).first()
def dao_get_template_statistics_for_service(service_id, limit_days=None):
filter = [TemplateStatistics.service_id == service_id]
if limit_days:
latest_stat = TemplateStatistics.query.filter_by(service_id=service_id).order_by(
desc(TemplateStatistics.day)).limit(1).first()
if latest_stat:
last_date_to_fetch = latest_stat.day - timedelta(days=limit_days)
else:
last_date_to_fetch = date.today() - timedelta(days=limit_days)
filter.append(TemplateStatistics.day > last_date_to_fetch)
return TemplateStatistics.query.filter(*filter).order_by(desc(TemplateStatistics.day)).all()
@transactional
def dao_create_notification(notification, notification_type):
try:
if notification.job_id:
db.session.query(Job).filter_by(
id=notification.job_id
).update({
Job.notifications_sent: Job.notifications_sent + 1,
Job.updated_at: datetime.utcnow()
})
if notification.job_id:
db.session.query(Job).filter_by(
id=notification.job_id
).update({
Job.notifications_sent: Job.notifications_sent + 1,
Job.updated_at: datetime.utcnow()
})
update_count = db.session.query(NotificationStatistics).filter_by(
update_count = db.session.query(NotificationStatistics).filter_by(
day=notification.created_at.strftime('%Y-%m-%d'),
service_id=notification.service_id
).update(update_query(notification_type, 'requested'))
if update_count == 0:
stats = NotificationStatistics(
day=notification.created_at.strftime('%Y-%m-%d'),
service_id=notification.service_id
).update(update_query(notification_type, 'requested'))
if update_count == 0:
stats = NotificationStatistics(
day=notification.created_at.strftime('%Y-%m-%d'),
service_id=notification.service_id,
sms_requested=1 if notification_type == TEMPLATE_TYPE_SMS else 0,
emails_requested=1 if notification_type == TEMPLATE_TYPE_EMAIL else 0
)
db.session.add(stats)
update_count = db.session.query(TemplateStatistics).filter_by(
day=date.today(),
service_id=notification.service_id,
template_id=notification.template_id
).update({'usage_count': TemplateStatistics.usage_count + 1})
sms_requested=1 if notification_type == TEMPLATE_TYPE_SMS else 0,
emails_requested=1 if notification_type == TEMPLATE_TYPE_EMAIL else 0
)
db.session.add(stats)
if update_count == 0:
template_stats = TemplateStatistics(template_id=notification.template_id,
service_id=notification.service_id)
db.session.add(template_stats)
update_count = db.session.query(TemplateStatistics).filter_by(
day=date.today(),
service_id=notification.service_id,
template_id=notification.template_id
).update({'usage_count': TemplateStatistics.usage_count + 1})
db.session.add(notification)
db.session.commit()
except:
db.session.rollback()
raise
if update_count == 0:
template_stats = TemplateStatistics(template_id=notification.template_id,
service_id=notification.service_id)
db.session.add(template_stats)
db.session.add(notification)
def update_query(notification_type, status):

View File

@@ -37,6 +37,8 @@ def get_job_by_service_and_job_id(service_id, job_id):
def get_jobs_by_service(service_id):
jobs = dao_get_jobs_by_service_id(service_id)
data, errors = job_schema.dump(jobs, many=True)
if errors:
return jsonify(result="error", message=errors), 400
return jsonify(data=data)

View File

@@ -357,7 +357,7 @@ class TemplateStatistics(db.Model):
id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
service_id = db.Column(UUID(as_uuid=True), db.ForeignKey('services.id'), index=True, unique=False, nullable=False)
service = db.relationship('Service', backref=db.backref('template_statics', lazy='dynamic'))
service = db.relationship('Service', backref=db.backref('template_statistics', lazy='dynamic'))
template_id = db.Column(db.BigInteger, db.ForeignKey('templates.id'), index=True, nullable=False, unique=False)
template = db.relationship('Template')
usage_count = db.Column(db.BigInteger, index=False, unique=False, nullable=False, default=1)

View File

@@ -1,15 +1,27 @@
from flask_marshmallow.fields import fields
from . import ma
from . import models
from app.dao.permissions_dao import permission_dao
from marshmallow import (post_load, ValidationError, validates, validates_schema, pre_load)
from marshmallow import (
post_load,
ValidationError,
validates,
validates_schema,
pre_load
)
from marshmallow_sqlalchemy import field_for
from utils.recipients import (
validate_email_address, InvalidEmailError,
validate_phone_number, InvalidPhoneError,
validate_email_address,
InvalidEmailError,
validate_phone_number,
InvalidPhoneError,
validate_and_format_phone_number
)
from app import ma
from app import models
from app.dao.permissions_dao import permission_dao
# TODO I think marshmallow provides a better integration and error handling.
# Would be better to replace functionality in dao with the marshmallow supported
@@ -19,7 +31,7 @@ from utils.recipients import (
class BaseSchema(ma.ModelSchema):
def __init__(self, *args, load_json=False, **kwargs):
def __init__(self, load_json=False, *args, **kwargs):
self.load_json = load_json
super(BaseSchema, self).__init__(*args, **kwargs)
@@ -241,6 +253,14 @@ class NotificationsFilterSchema(ma.Schema):
raise ValidationError("Not a positive integer")
class TemplateStatisticsSchema(BaseSchema):
template = fields.Nested(TemplateSchema, only=["id", "name", "template_type"], dump_only=True)
class Meta:
model = models.TemplateStatistics
user_schema = UserSchema()
user_schema_load_json = UserSchema(load_json=True)
service_schema = ServiceSchema()
@@ -264,3 +284,4 @@ permission_schema = PermissionSchema()
email_data_request_schema = EmailDataSchema()
notifications_statistics_schema = NotificationsStatisticsSchema()
notifications_filter_schema = NotificationsFilterSchema()
template_statistics_schema = TemplateStatisticsSchema()

View File

View File

@@ -0,0 +1,36 @@
from flask import (
Blueprint,
jsonify,
request,
current_app
)
from app.dao.notifications_dao import dao_get_template_statistics_for_service
from app.schemas import template_statistics_schema
template_statistics = Blueprint('template-statistics',
__name__,
url_prefix='/service/<service_id>/template-statistics')
from app.errors import register_errors
register_errors(template_statistics)
@template_statistics.route('')
def get_template_statistics_for_service(service_id):
if request.args.get('limit_days'):
try:
limit_days = int(request.args['limit_days'])
except ValueError as e:
error = 'Limit days {} is not an integer'.format(request.args['limit_days'])
current_app.logger.error(error)
return jsonify(result="error", message=[error]), 400
else:
limit_days = None
stats = dao_get_template_statistics_for_service(service_id, limit_days=limit_days)
data, errors = template_statistics_schema.dump(stats, many=True)
if errors:
return jsonify(result="error", message=errors), 400
return jsonify(data=data)