# Path: app/models.py
# class Respondent(db.Model):
#     """
#     ORM Model for the decision makers data.
#     """
#     id = db.Column(db.Integer(), primary_key=True)
#     name = db.Column(db.String(128))
#     phone = db.Column(db.String(32))
#     email = db.Column(db.String(64))
#     url = db.Column(db.String(256))
#     nation = db.Column(db.String(128))
#     group = db.Column(db.String(128))
#     party = db.Column(db.String(128))
#     license = db.Column(db.String(128))
#     image = db.Column(db.String(64))
# 
# class Campaign(db.Model):
#     """
#     ORM model for Calling Campaigns.
#     """
#     id = db.Column(db.Integer(), primary_key=True)
#     name = db.Column(db.String(128))
#     description = db.Column(db.String(1024))
#     id_audience = db.Column(db.Integer)
#     target_minutes = db.Column(db.Integer())
#     minutes_talked = db.Column(db.Integer())
#     id_owner = db.Column(db.Integer())
#     campaign_text = db.Column(db.String(2048))
#     campaign_text_html = db.Column(db.String(8192))
# 
# class Audience(db.Model):
#     """
#     ORM model for different groups of decision makers to be addressed by a campaign.
#     """
#     id = db.Column(db.Integer(), primary_key=True)
#     name = db.Column(db.String(128))
#     respondents = db.relationship('Respondent',
#                                   secondary=audience_respondent,
#                                   backref=db.backref('respondents', lazy='dynamic'))
# 
# Path: app/forms.py
# class CallForm(Form):
#     """
#     WTForm to validate Phonenumber and csrf-token
#     """
#     id_mdb = IntegerField(validators=[DataRequired()])
#     phone_number = StringField(validators=[DataRequired(message=u'Dieses Feld ist erforderlich.'), Length(1, 64)])
#     captcha = StringField()
#     captcha_hash = StringField()
# 
#     def __init__(self, *args, **kwargs):
#         super(CallForm, self).__init__(*args, **kwargs)
# 
#     def validate(self):
#         from app.callwidget.phone_number import PhoneNumber
#         initial_validation = super(CallForm, self).validate()
#         if not initial_validation:
#             return False
#         if current_app.config['CAPTCHA_ACTIVATED'] and \
#            not CaptchaStore.validate(hashkey=self.captcha_hash.data,
#                                      response=str(self.captcha.data).strip().lower()):
#             self.captcha.errors.append('Bitte versuchen sie es erneut.')
#             return False
#         if not PhoneNumber(self.phone_number).is_from(49):
#             self.phone_number.errors.append('Dies ist keine deutsche Rufnummer.')
#             return False
# 
#         self.phone_number.data = PhoneNumber(self.phone_number).get_e164_format()
#         return True
# 
# Path: app/abuse/calls.py
# def abuse_detected(phone_number, duration=None, persist=False):
#     """
#     :param phone_number: a phone number to add to the abuse tracker.
#     :param duration: the duration of the call.
#     :param persist: iff persist is set to True abuse flag will be set permanently
#     :return: true iff abuse is likely
#     """
# 
#     hashed_phone_number = sha256(bytes(str(phone_number), 'utf-8')).hexdigest()
#     short_calls = 0
#     if duration is not None and int(duration) <= current_app.config['SHORT_CALL_THRESHOLD']:
#         short_calls = 1
# 
#     abuse_case = PossibleAbuses().query.filter_by(id=hashed_phone_number).first()
#     if abuse_case is None:
#         abuse_case = PossibleAbuses()
#         abuse_case.id = hashed_phone_number
#         abuse_case.short_calls = 0 + short_calls
#         abuse_case.date = date.today()
#         abuse_case.persistent = persist
#         db.session.add(abuse_case)
#     elif abuse_case.date == date.today():
#         abuse_case.short_calls += short_calls
#     else:
#         abuse_case.date = date.today()
#         abuse_case.short_calls = short_calls
#     if persist:
#         abuse_case.persistent = True
#     db.session.commit()
# 
#     if abuse_case.persistent or \
#        abuse_case.short_calls >= current_app.config['SHORT_CALL_MAX_AMOUNT']:
#         return True
#     return False


from flask import render_template, flash, url_for, current_app, abort
from app.models import Respondent, Campaign, Audience
from app.forms import CallForm
from app.abuse.calls import abuse_detected
from twilio import twiml
from twilio.rest import TwilioRestClient
from operator import attrgetter
        template = 'callform/callform.html'
    if form.validate_on_submit():
        record = Respondent().query.filter_by(id=form.id_mdb.data).first()
        tel_mdb = record.phone
        tel_caller = form.phone_number.data
        if abuse_detected(phone_number=tel_caller):
            flash('I’m sorry Dave, I’m afraid I can’t do that.', category='warning')
            return render_template(template, record=record, form=form, campaign=campaign)
        if not initiate_call(record_id=form.id_mdb.data,
                             tel_caller=tel_caller,
                             audience_id=campaign.id_audience,
                             campaign_id=id_campaign):
            flash('something went wrong', category='warning')
            return render_template(template, record=record, form=form, campaign=campaign)
        else:
            flash('dispatching call from ' + tel_caller + ' to ' + tel_mdb, category='info')
            return render_template(template, record=record, form=form, campaign=campaign)
    else:
        record = Respondent().query.filter_by(id=form.id_mdb.data).first()
        return render_template(template, record=record, form=form, campaign=campaign)


def get_call_widget(request, id_campaign=1, embedded=False):
    """
    Render a call page due to a get request.
    :param request: a flask request object.
    :param id_campaign: an campaign id.
    :param embedded: True if embed template is supposed to be rendered.
    :return: flask response.
    """

# Path: app/models.py
# class Respondent(db.Model):
#     """
#     ORM Model for the decision makers data.
#     """
#     id = db.Column(db.Integer(), primary_key=True)
#     name = db.Column(db.String(128))
#     phone = db.Column(db.String(32))
#     email = db.Column(db.String(64))
#     url = db.Column(db.String(256))
#     nation = db.Column(db.String(128))
#     group = db.Column(db.String(128))
#     party = db.Column(db.String(128))
#     license = db.Column(db.String(128))
#     image = db.Column(db.String(64))
# 
# class Campaign(db.Model):
#     """
#     ORM model for Calling Campaigns.
#     """
#     id = db.Column(db.Integer(), primary_key=True)
#     name = db.Column(db.String(128))
#     description = db.Column(db.String(1024))
#     id_audience = db.Column(db.Integer)
#     target_minutes = db.Column(db.Integer())
#     minutes_talked = db.Column(db.Integer())
#     id_owner = db.Column(db.Integer())
#     campaign_text = db.Column(db.String(2048))
#     campaign_text_html = db.Column(db.String(8192))
# 
# class Audience(db.Model):
#     """
#     ORM model for different groups of decision makers to be addressed by a campaign.
#     """
#     id = db.Column(db.Integer(), primary_key=True)
#     name = db.Column(db.String(128))
#     respondents = db.relationship('Respondent',
#                                   secondary=audience_respondent,
#                                   backref=db.backref('respondents', lazy='dynamic'))
# 
# Path: app/forms.py
# class CallForm(Form):
#     """
#     WTForm to validate Phonenumber and csrf-token
#     """
#     id_mdb = IntegerField(validators=[DataRequired()])
#     phone_number = StringField(validators=[DataRequired(message=u'Dieses Feld ist erforderlich.'), Length(1, 64)])
#     captcha = StringField()
#     captcha_hash = StringField()
# 
#     def __init__(self, *args, **kwargs):
#         super(CallForm, self).__init__(*args, **kwargs)
# 
#     def validate(self):
#         from app.callwidget.phone_number import PhoneNumber
#         initial_validation = super(CallForm, self).validate()
#         if not initial_validation:
#             return False
#         if current_app.config['CAPTCHA_ACTIVATED'] and \
#            not CaptchaStore.validate(hashkey=self.captcha_hash.data,
#                                      response=str(self.captcha.data).strip().lower()):
#             self.captcha.errors.append('Bitte versuchen sie es erneut.')
#             return False
#         if not PhoneNumber(self.phone_number).is_from(49):
#             self.phone_number.errors.append('Dies ist keine deutsche Rufnummer.')
#             return False
# 
#         self.phone_number.data = PhoneNumber(self.phone_number).get_e164_format()
#         return True
# 
# Path: app/abuse/calls.py
# def abuse_detected(phone_number, duration=None, persist=False):
#     """
#     :param phone_number: a phone number to add to the abuse tracker.
#     :param duration: the duration of the call.
#     :param persist: iff persist is set to True abuse flag will be set permanently
#     :return: true iff abuse is likely
#     """
# 
#     hashed_phone_number = sha256(bytes(str(phone_number), 'utf-8')).hexdigest()
#     short_calls = 0
#     if duration is not None and int(duration) <= current_app.config['SHORT_CALL_THRESHOLD']:
#         short_calls = 1
# 
#     abuse_case = PossibleAbuses().query.filter_by(id=hashed_phone_number).first()
#     if abuse_case is None:
#         abuse_case = PossibleAbuses()
#         abuse_case.id = hashed_phone_number
#         abuse_case.short_calls = 0 + short_calls
#         abuse_case.date = date.today()
#         abuse_case.persistent = persist
#         db.session.add(abuse_case)
#     elif abuse_case.date == date.today():
#         abuse_case.short_calls += short_calls
#     else:
#         abuse_case.date = date.today()
#         abuse_case.short_calls = short_calls
#     if persist:
#         abuse_case.persistent = True
#     db.session.commit()
# 
#     if abuse_case.persistent or \
#        abuse_case.short_calls >= current_app.config['SHORT_CALL_MAX_AMOUNT']:
#         return True
#     return False


# Path: app/callwidget/calls.py
from flask import render_template, flash, url_for, current_app, abort
from app.models import Respondent, Campaign, Audience
from app.forms import CallForm
from app.abuse.calls import abuse_detected
from twilio import twiml
from twilio.rest import TwilioRestClient
from operator import attrgetter

        template = 'callform/callform.html'
    if form.validate_on_submit():
        record = Respondent().query.filter_by(id=form.id_mdb.data).first()
        tel_mdb = record.phone
        tel_caller = form.phone_number.data
        if abuse_detected(phone_number=tel_caller):
            flash('I’m sorry Dave, I’m afraid I can’t do that.', category='warning')
            return render_template(template, record=record, form=form, campaign=campaign)
        if not initiate_call(record_id=form.id_mdb.data,
                             tel_caller=tel_caller,
                             audience_id=campaign.id_audience,
                             campaign_id=id_campaign):
            flash('something went wrong', category='warning')
            return render_template(template, record=record, form=form, campaign=campaign)
        else:
            flash('dispatching call from ' + tel_caller + ' to ' + tel_mdb, category='info')
            return render_template(template, record=record, form=form, campaign=campaign)
    else:
        record = Respondent().query.filter_by(id=form.id_mdb.data).first()
        return render_template(template, record=record, form=form, campaign=campaign)


def get_call_widget(request, id_campaign=1, embedded=False):
    """
    Render a call page due to a get request.
    :param request: a flask request object.
    :param id_campaign: an campaign id.
    :param embedded: True if embed template is supposed to be rendered.
    :return: flask response.
    """

    form = CallForm(request.form)