<commit_before>"""Model classes for app_text

Customizing the templates for application specific needs can be done
at several levels.  This module houses tables used to generate
app specific strings.  Values are imported and exported through the
SitePersistence mechanism, and looked up in a template using the
`app_text(string)` method.

"""
from abc import ABCMeta, abstractmethod
from flask import current_app
from flask_babel import gettext
import requests
from requests.exceptions import MissingSchema
from urllib import urlencode
from urlparse import parse_qsl, urlparse

from ..database import db


class AppText(db.Model):
    """Model representing application specific strings for customization

    The portal (shared services) can be configured to support a number
    of specific sites.  This class provides a mechanism to store and lookup
    any text string needing to be customized.

    """
    __tablename__ = 'apptext'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Text, unique=True, nullable=False)
    custom_text = db.Column(db.Text, nullable=True)

    def __repr__(self):
        return "{} ({}, {})".format(self.__class__.__name__,
                                    self.name, str(self))

    def __str__(self):
        if self.custom_text:
            return self.custom_text
        return self.text

    def __unicode__(self):
        if self.custom_text:
            return self.custom_text
        return self.text

    @classmethod
    def from_json(cls, data):
        if 'name' not in data:
            raise ValueError("missing required 'name' field")
        app_text = AppText.query.filter_by(name=data['name']).first()
        if not app_text:
            app_text = cls()
            app_text.name = data['name']
            app_text.custom_text = data.get('custom_text')
            db.session.add(app_text)
        else:
            app_text.custom_text = data.get('custom_text')
        return app_text

    def as_json(self):
        d = {}
        d['resourceType'] = 'AppText'
        d['name'] = self.name
        if self.custom_text:
            d['custom_text'] = self.custom_text
        return d


class AppTextModelAdapter(object):
    """Several special purpose patterns used for lookups

    Make access consistent and easy for model classes where appropriate

    Abstract base class - defining methods each model adapter needs
    """
    __metaclass__ = ABCMeta

    @abstractmethod
    def name_key(**kwargs):
        """Return the named key as used by AppText for the type"""
        raise NotImplemented


class ConsentByOrg_ATMA(AppTextModelAdapter):
    """AppTextModelAdapter for Consent agreements - namely the URL per org"""

    @staticmethod
    def name_key(**kwargs):
        """Generate AppText name key for a consent agreement

        :param organization: for which the consent agreement applies
        :returns: string for AppText.name field

        """
        organization = kwargs.get('organization')
        if not organization:
            raise ValueError("required organization parameter not defined")
        return "{} organization consent URL".format(organization.name)


class WebsiteConsentTermsByOrg_ATMA(AppTextModelAdapter):
    @staticmethod
    def name_key(**kwargs):
        """Generate AppText name key for website consent terms presented at initial queries

        :param organization: for which the consent agreement applies
        :param role: for specific role selections, but only if
          it makes sense.  (i.e. on ePROMs, staff see different content)

        :returns: string for AppText.name field

        """
        organization = kwargs.get('organization')
        if not organization:
            raise ValueError("required organization parameter not defined")
        role = kwargs.get('role')
        if role:
            return "{} {} website consent URL".format(
                organization.name, role)
        return "{} organization website consent URL".format(organization.name)

class InitialConsent_ATMA(AppTextModelAdapter):
    """AppTextModelAdapter for Initial Consent Terms as presented at initial queries - namely the URL"""

    @staticmethod
    def name_key(**kwargs):
        """Generate AppText name key for a Initial Consent Terms

        Not expecting any args at this time - may specialize per study
        or organization in the future as needed.

        :returns: string for AppText.name field

        """
        return "Initial Consent Terms URL"

class Terms_ATMA(AppTextModelAdapter):
    """AppTextModelAdapter for New Terms Of Use agreements, used for /terms"""

    @staticmethod
    def name_key(**kwargs):
        """Generate AppText name key for a Terms and Conditions

        :param organization: optional, present in tandem to role parameter
        :param role: optional, role of the user
        :returns: string for AppText.name field

        """
        if kwargs.get('organization') and not kwargs.get('role'):
            raise ValueError("'role' parameter not defined")
        elif kwargs.get('role') and not kwargs.get('organization'):
            raise ValueError("'organization' parameter not defined")
        elif kwargs.get('organization') and kwargs.get('role'):
            return "{} {} terms and conditions URL".\
                    format(kwargs.get('organization').name, kwargs.get('role'))
        return "Terms and Conditions URL"

class WebsiteDeclarationForm_ATMA(AppTextModelAdapter):
    """AppTextModelAdapter for Website Declaraion Form"""

    @staticmethod
    def name_key(**kwargs):
        """Generate AppText name key for a Website Declaration Form

        :param organization: required
        :returns: string for AppText.name field

        """
        if not kwargs.get('organization'):
            raise ValueError("required 'organization' parameter not defined")
        else:<commit_msg>made a blanket for PEP8<commit_after>"""Model classes for app_text

Customizing the templates for application specific needs can be done
at several levels.  This module houses tables used to generate
app specific strings.  Values are imported and exported through the
SitePersistence mechanism, and looked up in a template using the
`app_text(string)` method.

"""
from abc import ABCMeta, abstractmethod
from flask import current_app
from flask_babel import gettext
import requests
from requests.exceptions import MissingSchema
from urllib import urlencode
from urlparse import parse_qsl, urlparse

from ..database import db


class AppText(db.Model):
    """Model representing application specific strings for customization

    The portal (shared services) can be configured to support a number
    of specific sites.  This class provides a mechanism to store and lookup
    any text string needing to be customized.

    """
    __tablename__ = 'apptext'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Text, unique=True, nullable=False)
    custom_text = db.Column(db.Text, nullable=True)

    def __repr__(self):
        return "{} ({}, {})".format(self.__class__.__name__,
                                    self.name, str(self))

    def __str__(self):
        if self.custom_text:
            return self.custom_text
        return self.text

    def __unicode__(self):
        if self.custom_text:
            return self.custom_text
        return self.text

    @classmethod
    def from_json(cls, data):
        if 'name' not in data:
            raise ValueError("missing required 'name' field")
        app_text = AppText.query.filter_by(name=data['name']).first()
        if not app_text:
            app_text = cls()
            app_text.name = data['name']
            app_text.custom_text = data.get('custom_text')
            db.session.add(app_text)
        else:
            app_text.custom_text = data.get('custom_text')
        return app_text

    def as_json(self):
        d = {}
        d['resourceType'] = 'AppText'
        d['name'] = self.name
        if self.custom_text:
            d['custom_text'] = self.custom_text
        return d


class AppTextModelAdapter(object):
    """Several special purpose patterns used for lookups

    Make access consistent and easy for model classes where appropriate

    Abstract base class - defining methods each model adapter needs
    """
    __metaclass__ = ABCMeta

    @abstractmethod
    def name_key(**kwargs):
        """Return the named key as used by AppText for the type"""
        raise NotImplemented


class ConsentByOrg_ATMA(AppTextModelAdapter):
    """AppTextModelAdapter for Consent agreements - namely the URL per org"""

    @staticmethod
    def name_key(**kwargs):
        """Generate AppText name key for a consent agreement

        :param organization: for which the consent agreement applies
        :returns: string for AppText.name field

        """
        organization = kwargs.get('organization')
        if not organization:
            raise ValueError("required organization parameter not defined")
        return "{} organization consent URL".format(organization.name)


class WebsiteConsentTermsByOrg_ATMA(AppTextModelAdapter):
    @staticmethod
    def name_key(**kwargs):
        """Generate AppText name key for website consent terms presented at initial queries

        :param organization: for which the consent agreement applies
        :param role: for specific role selections, but only if
          it makes sense.  (i.e. on ePROMs, staff see different content)

        :returns: string for AppText.name field

        """
        organization = kwargs.get('organization')
        if not organization:
            raise ValueError("required organization parameter not defined")
        role = kwargs.get('role')
        if role:
            return "{} {} website consent URL".format(
                organization.name, role)
        return "{} organization website consent URL".format(organization.name)

class InitialConsent_ATMA(AppTextModelAdapter):
    """AppTextModelAdapter for Initial Consent Terms as presented at initial queries - namely the URL"""

    @staticmethod
    def name_key(**kwargs):
        """Generate AppText name key for a Initial Consent Terms

        Not expecting any args at this time - may specialize per study
        or organization in the future as needed.

        :returns: string for AppText.name field

        """
        return "Initial Consent Terms URL"

class Terms_ATMA(AppTextModelAdapter):
    """AppTextModelAdapter for New Terms Of Use agreements, used for /terms"""

    @staticmethod
    def name_key(**kwargs):
        """Generate AppText name key for a Terms and Conditions

        :param organization: optional, present in tandem to role parameter
        :param role: optional, role of the user
        :returns: string for AppText.name field

        """
        if kwargs.get('organization') and not kwargs.get('role'):
            raise ValueError("'role' parameter not defined")
        elif kwargs.get('role') and not kwargs.get('organization'):
            raise ValueError("'organization' parameter not defined")
        elif kwargs.get('organization') and kwargs.get('role'):
            return "{} {} terms and conditions URL".\
                    format(kwargs.get('organization').name, kwargs.get('role'))
        return "Terms and Conditions URL"


class WebsiteDeclarationForm_ATMA(AppTextModelAdapter):
    """AppTextModelAdapter for Website Declaraion Form"""

    @staticmethod
    def name_key(**kwargs):
        """Generate AppText name key for a Website Declaration Form

        :param organization: required
        :returns: string for AppText.name field

        """
        if not kwargs.get('organization'):
            raise ValueError("required 'organization' parameter not defined")
        else:
{'fraction_non_alphanumeric': 0.08225656616839794, 'fraction_numerical': 8.445232666159953e-05, 'mean_word_length': 2.8101673101673104, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1847109', 'n_tokens_mistral': 3020, 'n_tokens_neox': 2922, 'n_words': 1081}