<commit_before>"""Defines various one-off helpers for the package."""
from functools import wraps
from sqlalchemy.exc import IntegrityError
from time import time
from .models import IPAddr, Installation, Package, Platform, PythonVersion, db
import requests


def configure_logging(app):
    """Send ERROR log to ADMINS emails."""
    ADMINS = ['<EMAIL>']
    if not app.debug:
        import logging
        from logging.handlers import SMTPHandler
        mail_handler = SMTPHandler(
            '127.0.0.1', '<EMAIL>',
            ADMINS, 'UpdateChecker Failed')
        mail_handler.setLevel(logging.ERROR)
        app.logger.addHandler(mail_handler)


def package_cache(function):
    """Memoize the wrapped function."""
    CACHE_TIME = 600
    stored = {}

    @wraps(function)
    def wrapped(package_name):
        now = time()
        if package_name in stored:
            updated, data = stored[package_name]
            if now < updated + CACHE_TIME:
                return data
        data = function(package_name)
        stored[package_name] = (now, data)
        return data
    return wrapped


@package_cache
def get_current_version(package):
    """Return information about the current version of package."""
    r = requests.get('http://pypi.python.org/pypi/{0}/json'.format(package))
    if r.status_code != 200:
        return {'success': False}
    upload_time = None
    json_data = r.json()
    for file_info in json_data['urls']:
        if file_info['packagetype'] == 'sdist':
            upload_time = file_info['upload_time']
    return {'success': True, 'data': {'upload_time': upload_time,
                                      'version': json_data['info']['version']}}


def record_check(name, version, platform_str, python_version_str, ip):
    """Record the update check."""
    package = Package.fetch_or_create(package_name=name,
                                      package_version=version)
    platform = Platform.fetch_or_create(value=platform_str)
    python_version = PythonVersion.fetch_or_create(value=python_version_str)
    ipaddr = IPAddr.fetch_or_create(value=ip)

    update = False
    if ipaddr.id and package.id and platform.id and python_version.id:
        update = Installation.query.filter_by(
            day=db.func.Date(db.func.now()), ipaddr=ipaddr, package=package,
            platform=platform, python_version=python_version).update(
                {Installation.count: Installation.count + 1},
                synchronize_session=False)
    if not update:
        installation = Installation(count=1, ipaddr=ipaddr, package=package,
                                    platform=platform,
                                    python_version=python_version)
        db.session.add(installation)

    try:
        db.session.commit()
    except IntegrityError:
        db.session.rollback()
        record_check(name, version, platform_str, python_version_str, ip, True)<commit_msg>Fix bug in recursive record check.<commit_after>"""Defines various one-off helpers for the package."""
from functools import wraps
from sqlalchemy.exc import IntegrityError
from time import time
from .models import IPAddr, Installation, Package, Platform, PythonVersion, db
import requests


def configure_logging(app):
    """Send ERROR log to ADMINS emails."""
    ADMINS = ['<EMAIL>']
    if not app.debug:
        import logging
        from logging.handlers import SMTPHandler
        mail_handler = SMTPHandler(
            '127.0.0.1', '<EMAIL>',
            ADMINS, 'UpdateChecker Failed')
        mail_handler.setLevel(logging.ERROR)
        app.logger.addHandler(mail_handler)


def package_cache(function):
    """Memoize the wrapped function."""
    CACHE_TIME = 600
    stored = {}

    @wraps(function)
    def wrapped(package_name):
        now = time()
        if package_name in stored:
            updated, data = stored[package_name]
            if now < updated + CACHE_TIME:
                return data
        data = function(package_name)
        stored[package_name] = (now, data)
        return data
    return wrapped


@package_cache
def get_current_version(package):
    """Return information about the current version of package."""
    r = requests.get('http://pypi.python.org/pypi/{0}/json'.format(package))
    if r.status_code != 200:
        return {'success': False}
    upload_time = None
    json_data = r.json()
    for file_info in json_data['urls']:
        if file_info['packagetype'] == 'sdist':
            upload_time = file_info['upload_time']
    return {'success': True, 'data': {'upload_time': upload_time,
                                      'version': json_data['info']['version']}}


def record_check(name, version, platform_str, python_version_str, ip):
    """Record the update check."""
    package = Package.fetch_or_create(package_name=name,
                                      package_version=version)
    platform = Platform.fetch_or_create(value=platform_str)
    python_version = PythonVersion.fetch_or_create(value=python_version_str)
    ipaddr = IPAddr.fetch_or_create(value=ip)

    update = False
    if ipaddr.id and package.id and platform.id and python_version.id:
        update = Installation.query.filter_by(
            day=db.func.Date(db.func.now()), ipaddr=ipaddr, package=package,
            platform=platform, python_version=python_version).update(
                {Installation.count: Installation.count + 1},
                synchronize_session=False)
    if not update:
        installation = Installation(count=1, ipaddr=ipaddr, package=package,
                                    platform=platform,
                                    python_version=python_version)
        db.session.add(installation)

    try:
        db.session.commit()
    except IntegrityError:
        db.session.rollback()
        record_check(name, version, platform_str, python_version_str, ip)
{'fraction_non_alphanumeric': 0.10198204302896832, 'fraction_numerical': 0.0050821616127392855, 'mean_word_length': 2.6354679802955663, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2336843', 'n_tokens_mistral': 1683, 'n_tokens_neox': 1638, 'n_words': 393}