<commit_before>"""
Contains model class definitions.
"""
import json
import urllib2

from django.conf import settings
from django.contrib.gis.geos import Point
from django.utils.encoding import python_2_unicode_compatible
from django.utils.http import urlencode
from django.utils.translation import ugettext_lazy as _

from taggit.managers import TaggableManager
from wagtail.wagtailadmin.edit_handlers import FieldPanel
from wagtail.wagtailadmin.edit_handlers import MultiFieldPanel
from wagtail.wagtailadmin.edit_handlers import ObjectList
from wagtail.wagtailadmin.taggable import TagSearchable
from wagtail.wagtailsearch import index

from .app_settings import ADDRESS_ATTR_MAP
from .app_settings import ADDRESS_FORMAT
from .app_settings import ADDRESS_FORMAT_FIELDS
from .edit_handlers import AddressComponentChooserPanel


API_KEY = getattr(settings, 'GOOGLE_API_KEY', None)

# Test for GIS app - probably a better way to do this...
if 'django.contrib.gis' in settings.INSTALLED_APPS:
    # Use GIS-enabled classes.
    from django.contrib.gis.db import models
    GEO_ENABLED = True
    geom_field  = models.PointField(_('Geometry'), srid=4326, blank=True, null=True, editable=False)
    addr_mgr    = models.GeoManager
else:
    # Fall back to standard classes.
    from django.db import models
    GEO_ENABLED = False
    geom_field  = models.CharField(_(u'Geometry'), max_length=50, blank=True, null=True, editable=False)
    addr_mgr    = models.Manager

def get_address_data(addr_str):
    """
    Returns address data dictionary for specified string.

    :rtype: dict.
    """
    if API_KEY:
        url = 'https://maps.googleapis.com/maps/api/geocode/json?{0}'.format(
            urlencode({
                'key':      API_KEY,
                'address':  addr_str,
                'sensor':   False
            })
        )
    
        try:
            response    = urllib2.urlopen(url)
            data        = json.loads(response.read())
            return data['results'][0]
        except:
            return None

def get_geom_from_data(data):
    """
    Returns geometry value (point object or string) from data dictionary.

    :param data: the address data dictionary.
    :rtype: django.contrib.gis.geos.Point || str.
    """
    if GEO_ENABLED:
        # Set the address geometry with SRID = 4326.
        geom = Point(
            data['geometry']['location']['lng'],
            data['geometry']['location']['lat'],
            srid=4326
        )
    else:
        # Simply store the latitude and longitude.
        geom = '{0},{1}'.format(
            data['geometry']['location']['lat'],
            data['geometry']['location']['lng'],
        )

    return geom

class AddressManager(addr_mgr):
    """
    Custom address model manager.
    """
    def get_or_create_from_string(self, addr_str):
        """
        Returns address model for specified string value.

        :param addr_str: the address string.
        :rtype: tuple.
        """
        addr    = None
        comps   = {}
        data    = get_address_data(addr_str)

        if data:
            for comp in data['address_components']:
                type = comp['types'][0]
                if type in ADDRESS_ATTR_MAP:
                    comps[type] = AddressComponent.objects.get_or_create(
                        type        = ADDRESS_ATTR_MAP[type],
                        long_name   = comp['long_name'],
                        short_name  = comp['short_name']
                    )[0]

            # Add default geometry value and return the instance.
            defaults = {'geom': get_geom_from_data(data)}
            return Address.objects.get_or_create(
                defaults={'geom': get_geom_from_data(data)},
                **comps
            )
        else:
            raise ValueError('Unable to parse "{0}"'.format(addr_str))

@python_2_unicode_compatible
class AddressComponent(models.Model, TagSearchable):
    """
    Stores an address component record.
    """
    type        = models.CharField(_(u'Component Type'), max_length=50, db_index=True)<commit_msg>Modified get_or_create_from_string()<commit_after>"""
Contains model class definitions.
"""
import json
import urllib2

from django.conf import settings
from django.contrib.gis.geos import Point
from django.utils.encoding import python_2_unicode_compatible
from django.utils.http import urlencode
from django.utils.translation import ugettext_lazy as _

from taggit.managers import TaggableManager
from wagtail.wagtailadmin.edit_handlers import FieldPanel
from wagtail.wagtailadmin.edit_handlers import MultiFieldPanel
from wagtail.wagtailadmin.edit_handlers import ObjectList
from wagtail.wagtailadmin.taggable import TagSearchable
from wagtail.wagtailsearch import index

from .app_settings import ADDRESS_ATTR_MAP
from .app_settings import ADDRESS_FORMAT
from .app_settings import ADDRESS_FORMAT_FIELDS
from .edit_handlers import AddressComponentChooserPanel


API_KEY = getattr(settings, 'GOOGLE_API_KEY', None)

# Test for GIS app - probably a better way to do this...
if 'django.contrib.gis' in settings.INSTALLED_APPS:
    # Use GIS-enabled classes.
    from django.contrib.gis.db import models
    GEO_ENABLED = True
    geom_field  = models.PointField(_('Geometry'), srid=4326, blank=True, null=True, editable=False)
    addr_mgr    = models.GeoManager
else:
    # Fall back to standard classes.
    from django.db import models
    GEO_ENABLED = False
    geom_field  = models.CharField(_(u'Geometry'), max_length=50, blank=True, null=True, editable=False)
    addr_mgr    = models.Manager

def get_address_data(addr_str):
    """
    Returns address data dictionary for specified string.

    :rtype: dict.
    """
    if API_KEY:
        url = 'https://maps.googleapis.com/maps/api/geocode/json?{0}'.format(
            urlencode({
                'key':      API_KEY,
                'address':  addr_str,
                'sensor':   False
            })
        )
    
        try:
            response    = urllib2.urlopen(url)
            data        = json.loads(response.read())
            return data['results'][0]
        except:
            return None

def get_geom_from_data(data):
    """
    Returns geometry value (point object or string) from data dictionary.

    :param data: the address data dictionary.
    :rtype: django.contrib.gis.geos.Point || str.
    """
    if GEO_ENABLED:
        # Set the address geometry with SRID = 4326.
        geom = Point(
            data['geometry']['location']['lng'],
            data['geometry']['location']['lat'],
            srid=4326
        )
    else:
        # Simply store the latitude and longitude.
        geom = '{0},{1}'.format(
            data['geometry']['location']['lat'],
            data['geometry']['location']['lng'],
        )

    return geom

class AddressManager(addr_mgr):
    """
    Custom address model manager.
    """
    def get_or_create_from_string(self, addr_str):
        """
        Returns address model for specified string value.

        :param addr_str: the address string.
        :rtype: tuple.
        """
        addr    = None
        comps   = {}
        data    = get_address_data(addr_str)

        if data:
            for comp in data['address_components']:
                type = comp['types'][0]
                if type in ADDRESS_ATTR_MAP:
                    comps[type] = AddressComponent.objects.get_or_create(
                        type        = ADDRESS_ATTR_MAP[type],
                        long_name   = comp['long_name'],
                        short_name  = comp['short_name']
                    )[0]

            # Add default geometry value and return the instance.
            defaults = {'geom': get_geom_from_data(data)}
            return Address.objects.get_or_create(
                defaults={'geom': get_geom_from_data(data)},
                **comps
            )

        return (None, False)

@python_2_unicode_compatible
class AddressComponent(models.Model, TagSearchable):
    """
    Stores an address component record.
    """
    type        = models.CharField(_(u'Component Type'), max_length=50, db_index=True)
{'fraction_non_alphanumeric': 0.09654919236417034, 'fraction_numerical': 0.00648556045031816, 'mean_word_length': 2.4153781863769326, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3854909', 'n_tokens_mistral': 2392, 'n_tokens_neox': 2350, 'n_words': 579}