<commit_before>import dbus

from gabbletest import exec_test, make_result_iq
from servicetest import call_async, EventPattern, assertEquals, assertLength

from twisted.words.xish import xpath
import constants as cs
import ns

Rich_Presence_Access_Control_Type_Publish_List = 1

def test(q, bus, conn, stream):
    conn.Connect()

    # discard activities request and status change
    q.expect_many(
        EventPattern('stream-iq', iq_type='set',
            query_ns=ns.PUBSUB),
        EventPattern('dbus-signal', signal='StatusChanged',
            args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]),
        )

    # check location properties

    access_control_types = conn.Get(
            cs.CONN_IFACE_LOCATION, "LocationAccessControlTypes",
            dbus_interface=cs.PROPERTIES_IFACE)
    # only one access control is implemented in Gabble at the moment:
    assert len(access_control_types) == 1, access_control_types
    assert access_control_types[0] == \
        Rich_Presence_Access_Control_Type_Publish_List

    access_control = conn.Get(
            cs.CONN_IFACE_LOCATION, "LocationAccessControl",
            dbus_interface=cs.PROPERTIES_IFACE)
    assert len(access_control) == 2, access_control
    assert access_control[0] == \
        Rich_Presence_Access_Control_Type_Publish_List

    properties = conn.GetAll(
            cs.CONN_IFACE_LOCATION,
            dbus_interface=cs.PROPERTIES_IFACE)

    assert properties.get('LocationAccessControlTypes') == access_control_types
    assert properties.get('LocationAccessControl') == access_control

    # Test setting the properties

    # Enum out of range
    bad_access_control = dbus.Struct([dbus.UInt32(99),
            dbus.UInt32(0, variant_level=1)],
            signature=dbus.Signature('uv'))
    try:
        conn.Set (cs.CONN_IFACE_LOCATION, 'LocationAccessControl', bad_access_control,
            dbus_interface =cs.PROPERTIES_IFACE)
    except dbus.DBusException, e:
        pass
    else:
        assert False, "Should have had an error!"

    # Bad type
    bad_access_control = dbus.String("This should not be a string")
    try:
        conn.Set (cs.CONN_IFACE_LOCATION, 'LocationAccessControl', bad_access_control,
            dbus_interface =cs.PROPERTIES_IFACE)
    except dbus.DBusException, e:
        assert e.get_dbus_name() == cs.INVALID_ARGUMENT, e.get_dbus_name()
    else:
        assert False, "Should have had an error!"

    # Bad type
    bad_access_control = dbus.Struct([dbus.String("bad"), dbus.String("!"),
            dbus.UInt32(0, variant_level=1)],
            signature=dbus.Signature('ssv'))
    try:
        conn.Set (cs.CONN_IFACE_LOCATION, 'LocationAccessControl', bad_access_control,
            dbus_interface =cs.PROPERTIES_IFACE)
    except dbus.DBusException, e:
        assert e.get_dbus_name() == cs.INVALID_ARGUMENT, e.get_dbus_name()
    else:
        assert False, "Should have had an error!"

    # Correct
    conn.Set (cs.CONN_IFACE_LOCATION, 'LocationAccessControl', access_control,
        dbus_interface =cs.PROPERTIES_IFACE)

    # LocationAccessControlTypes is read-only, check Gabble return the
    # PermissionDenied error
    try:
        conn.Set (cs.CONN_IFACE_LOCATION, 'LocationAccessControlTypes',
            access_control_types,
            dbus_interface =cs.PROPERTIES_IFACE)
    except dbus.DBusException, e:
        assert e.get_dbus_name() == cs.PERMISSION_DENIED, e.get_dbus_name()
    else:
        assert False, "Should have had an error!"

    # set a Location
    conn.Location.SetLocation({
        'lat': dbus.Double(0.0, variant_level=1),
        'lon': 0.0,
        'language': 'en',
        # Gabble silently ignores unknown keys
        'badger': 'mushroom'})

    geoloc_iq_set_event = EventPattern('stream-iq', predicate=lambda x:
        xpath.queryForNodes("/iq/pubsub/publish/item/geoloc", x.stanza))

    event = q.expect_many(geoloc_iq_set_event)[0]
    geoloc = xpath.queryForNodes("/iq/pubsub/publish/item/geoloc", event.stanza)[0]
    assertEquals(geoloc.getAttribute((ns.XML, 'lang')), 'en')
    lon = xpath.queryForNodes('/geoloc/lon', geoloc)[0]
    assertEquals(float(str(lon)), 0.0)
    lat = xpath.queryForNodes('/geoloc/lat', geoloc)[0]
    assertEquals(float(str(lat)), 0.0)

    # Request Bob's location
    bob_handle = conn.RequestHandles(1, ['bob@foo.com'])[0]
    call_async(q, conn.Location, 'GetLocations', [bob_handle])

    # Gabble sends a pubsub query
    event = q.expect('stream-iq', iq_type='get',
        query_ns=ns.PUBSUB)

    # GetLocations doesn't wait for the reply
    e = q.expect('dbus-return', method='GetLocations')
    locations = e.value[0]
    # Location isn't known yet
    assertLength(0, locations)

    # reply with Bob's location
    result = make_result_iq(stream, event.stanza)
    result['from'] = 'bob@foo.com'
    query = result.firstChildElement()
    geoloc = query.addElement((ns.GEOLOC, 'geoloc'))
    geoloc['xml:lang'] = 'en'
    geoloc.addElement('lat', content='1.234')
    geoloc.addElement('lon', content='5.678')
    # invalid element, will be discarded by Gabble
    geoloc.addElement('badger', content='mushroom')
    stream.send(result)

    update_event = q.expect('dbus-signal', signal='LocationUpdated')

    handle, location = update_event.args
    assertEquals(handle, bob_handle)

    assertLength(3, location)
    assertEquals(location['language'], 'en')
    assertEquals(location['lat'], 1.234)
    assertEquals(location['lon'], 5.678)

    q.forbid_events([geoloc_iq_set_event])

    # Get location again, Gabble doesn't send a query any more and return the known
    # location
    locations = conn.Location.GetLocations([bob_handle])
    assertLength(1, locations)
    assertEquals(locations[bob_handle], location)

    # Try to set our location by passing a valid with an invalid type (lat is
    # supposed to be a double)
    try:
        conn.Location.SetLocation({'lat': 'pony'})
    except dbus.DBusException, e:
        assertEquals(e.get_dbus_name(), cs.INVALID_ARGUMENT)
    else:
        assert False

if __name__ == '__main__':
    exec_test(test)
<commit_msg>test-location.py: test more location key types<commit_after>import dbus
import time
import datetime

from gabbletest import exec_test, make_result_iq
from servicetest import call_async, EventPattern, assertEquals, assertLength

from twisted.words.xish import xpath
import constants as cs
import ns

Rich_Presence_Access_Control_Type_Publish_List = 1

def test(q, bus, conn, stream):
    conn.Connect()

    # discard activities request and status change
    q.expect_many(
        EventPattern('stream-iq', iq_type='set',
            query_ns=ns.PUBSUB),
        EventPattern('dbus-signal', signal='StatusChanged',
            args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]),
        )

    # check location properties

    access_control_types = conn.Get(
            cs.CONN_IFACE_LOCATION, "LocationAccessControlTypes",
            dbus_interface=cs.PROPERTIES_IFACE)
    # only one access control is implemented in Gabble at the moment:
    assert len(access_control_types) == 1, access_control_types
    assert access_control_types[0] == \
        Rich_Presence_Access_Control_Type_Publish_List

    access_control = conn.Get(
            cs.CONN_IFACE_LOCATION, "LocationAccessControl",
            dbus_interface=cs.PROPERTIES_IFACE)
    assert len(access_control) == 2, access_control
    assert access_control[0] == \
        Rich_Presence_Access_Control_Type_Publish_List

    properties = conn.GetAll(
            cs.CONN_IFACE_LOCATION,
            dbus_interface=cs.PROPERTIES_IFACE)

    assert properties.get('LocationAccessControlTypes') == access_control_types
    assert properties.get('LocationAccessControl') == access_control

    # Test setting the properties

    # Enum out of range
    bad_access_control = dbus.Struct([dbus.UInt32(99),
            dbus.UInt32(0, variant_level=1)],
            signature=dbus.Signature('uv'))
    try:
        conn.Set (cs.CONN_IFACE_LOCATION, 'LocationAccessControl', bad_access_control,
            dbus_interface =cs.PROPERTIES_IFACE)
    except dbus.DBusException, e:
        pass
    else:
        assert False, "Should have had an error!"

    # Bad type
    bad_access_control = dbus.String("This should not be a string")
    try:
        conn.Set (cs.CONN_IFACE_LOCATION, 'LocationAccessControl', bad_access_control,
            dbus_interface =cs.PROPERTIES_IFACE)
    except dbus.DBusException, e:
        assert e.get_dbus_name() == cs.INVALID_ARGUMENT, e.get_dbus_name()
    else:
        assert False, "Should have had an error!"

    # Bad type
    bad_access_control = dbus.Struct([dbus.String("bad"), dbus.String("!"),
            dbus.UInt32(0, variant_level=1)],
            signature=dbus.Signature('ssv'))
    try:
        conn.Set (cs.CONN_IFACE_LOCATION, 'LocationAccessControl', bad_access_control,
            dbus_interface =cs.PROPERTIES_IFACE)
    except dbus.DBusException, e:
        assert e.get_dbus_name() == cs.INVALID_ARGUMENT, e.get_dbus_name()
    else:
        assert False, "Should have had an error!"

    # Correct
    conn.Set (cs.CONN_IFACE_LOCATION, 'LocationAccessControl', access_control,
        dbus_interface =cs.PROPERTIES_IFACE)

    # LocationAccessControlTypes is read-only, check Gabble return the
    # PermissionDenied error
    try:
        conn.Set (cs.CONN_IFACE_LOCATION, 'LocationAccessControlTypes',
            access_control_types,
            dbus_interface =cs.PROPERTIES_IFACE)
    except dbus.DBusException, e:
        assert e.get_dbus_name() == cs.PERMISSION_DENIED, e.get_dbus_name()
    else:
        assert False, "Should have had an error!"

    date = dbus.Int64(time.time())
    date_str = datetime.datetime.utcfromtimestamp(date).strftime('%FT%H:%M:%SZ')

    # set a Location
    conn.Location.SetLocation({
        'lat': dbus.Double(0.0, variant_level=1),
        'lon': 0.0,
        'language': 'en',
        'timestamp': date,
        'country': 'Congo',
        # Gabble silently ignores unknown keys
        'badger': 'mushroom'})

    geoloc_iq_set_event = EventPattern('stream-iq', predicate=lambda x:
        xpath.queryForNodes("/iq/pubsub/publish/item/geoloc", x.stanza))

    event = q.expect_many(geoloc_iq_set_event)[0]
    geoloc = xpath.queryForNodes("/iq/pubsub/publish/item/geoloc", event.stanza)[0]
    assertEquals(geoloc.getAttribute((ns.XML, 'lang')), 'en')
    lon = xpath.queryForNodes('/geoloc/lon', geoloc)[0]
    assertEquals(float(str(lon)), 0.0)
    lat = xpath.queryForNodes('/geoloc/lat', geoloc)[0]
    assertEquals(float(str(lat)), 0.0)
    timestamp = xpath.queryForNodes('/geoloc/timestamp', geoloc)[0]
    assertEquals(str(timestamp), date_str)
    country = xpath.queryForNodes('/geoloc/country', geoloc)[0]
    assertEquals(str(country), 'Congo')

    # Request Bob's location
    bob_handle = conn.RequestHandles(1, ['bob@foo.com'])[0]
    call_async(q, conn.Location, 'GetLocations', [bob_handle])

    # Gabble sends a pubsub query
    event = q.expect('stream-iq', iq_type='get',
        query_ns=ns.PUBSUB)

    # GetLocations doesn't wait for the reply
    e = q.expect('dbus-return', method='GetLocations')
    locations = e.value[0]
    # Location isn't known yet
    assertLength(0, locations)

    # reply with Bob's location
    result = make_result_iq(stream, event.stanza)
    result['from'] = 'bob@foo.com'
    query = result.firstChildElement()
    geoloc = query.addElement((ns.GEOLOC, 'geoloc'))
    geoloc['xml:lang'] = 'en'
    geoloc.addElement('lat', content='1.234')
    geoloc.addElement('lon', content='5.678')
    geoloc.addElement('country', content='Belgium')
    geoloc.addElement('timestamp', content=date_str)
    # invalid element, will be discarded by Gabble
    geoloc.addElement('badger', content='mushroom')
    stream.send(result)

    update_event = q.expect('dbus-signal', signal='LocationUpdated')

    handle, location = update_event.args
    assertEquals(handle, bob_handle)

    assertLength(5, location)
    assertEquals(location['language'], 'en')
    assertEquals(location['lat'], 1.234)
    assertEquals(location['lon'], 5.678)
    assertEquals(location['country'], 'Belgium')
    assertEquals(location['timestamp'], date)

    q.forbid_events([geoloc_iq_set_event])

    # Get location again, Gabble doesn't send a query any more and return the known
    # location
    locations = conn.Location.GetLocations([bob_handle])
    assertLength(1, locations)
    assertEquals(locations[bob_handle], location)

    # Try to set our location by passing a valid with an invalid type (lat is
    # supposed to be a double)
    try:
        conn.Location.SetLocation({'lat': 'pony'})
    except dbus.DBusException, e:
        assertEquals(e.get_dbus_name(), cs.INVALID_ARGUMENT)
    else:
        assert False

if __name__ == '__main__':
    exec_test(test)
<|endoftext|>


<commit_before>import re
import urlparse
from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
# Avoid shadowing the login() view below.
from django.contrib.auth import login as auth_login
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm, PasswordChangeForm
from django.contrib.auth.tokens import default_token_generator
from django.views.decorators.csrf import csrf_protect
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib.sites.models import get_current_site
from django.http import HttpResponseRedirect, Http404, QueryDict
from django.template import RequestContext
from django.utils.http import base36_to_int
from django.utils.translation import ugettext as _
from django.contrib.auth.models import User
from django.views.decorators.cache import never_cache

@csrf_protect
@never_cache
def login(request, template_name='registration/login.html',
          redirect_field_name=REDIRECT_FIELD_NAME,
          authentication_form=AuthenticationForm):
    """Displays the login form and handles the login action."""

    redirect_to = request.REQUEST.get(redirect_field_name, '')

    if request.method == "POST":
        form = authentication_form(data=request.POST)
        if form.is_valid():
            netloc = urlparse.urlparse(redirect_to)[1]

            # Light security check -- make sure redirect_to isn't garbage.
            if not redirect_to or ' ' in redirect_to:
                redirect_to = settings.LOGIN_REDIRECT_URL

            # Heavier security check -- don't allow redirection to a different
            # host.
            elif netloc and netloc != request.get_host():
                redirect_to = settings.LOGIN_REDIRECT_URL

            # Okay, security checks complete. Log the user in.
            auth_login(request, form.get_user())

            if request.session.test_cookie_worked():
                request.session.delete_test_cookie()

            return HttpResponseRedirect(redirect_to)

    else:
        form = authentication_form(request)

    request.session.set_test_cookie()

    current_site = get_current_site(request)

    return render_to_response(template_name, {
        'form': form,
        redirect_field_name: redirect_to,
        'site': current_site,
        'site_name': current_site.name,
    }, context_instance=RequestContext(request))

def logout(request, next_page=None, template_name='registration/logged_out.html', redirect_field_name=REDIRECT_FIELD_NAME):
    "Logs out the user and displays 'You are logged out' message."
    from django.contrib.auth import logout
    logout(request)
    if next_page is None:
        redirect_to = request.REQUEST.get(redirect_field_name, '')
        if redirect_to:
            return HttpResponseRedirect(redirect_to)
        else:
            current_site = get_current_site(request)
            return render_to_response(template_name, {
                'site': current_site,
                'site_name': current_site.name,
                'title': _('Logged out')
            }, context_instance=RequestContext(request))
    else:
        # Redirect to this page until the session has been cleared.
        return HttpResponseRedirect(next_page or request.path)

def logout_then_login(request, login_url=None):
    "Logs out the user if he is logged in. Then redirects to the log-in page."
    if not login_url:
        login_url = settings.LOGIN_URL
    return logout(request, login_url)

def redirect_to_login(next, login_url=None,
                      redirect_field_name=REDIRECT_FIELD_NAME):
    "Redirects the user to the login page, passing the given 'next' page"
    if not login_url:
        login_url = settings.LOGIN_URL

    login_url_parts = list(urlparse.urlparse(login_url))
    if redirect_field_name:
        querystring = QueryDict(login_url_parts[4], mutable=True)
        querystring[redirect_field_name] = next
        login_url_parts[4] = querystring.urlencode(safe='/')

    return HttpResponseRedirect(urlparse.urlunparse(login_url_parts))

# 4 views for password reset:
# - password_reset sends the mail
# - password_reset_done shows a success message for the above
# - password_reset_confirm checks the link the user clicked and
#   prompts for a new password
# - password_reset_complete shows a success message for the above

@csrf_protect
def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html',
        email_template_name='registration/password_reset_email.html',
        password_reset_form=PasswordResetForm, token_generator=default_token_generator,
        post_reset_redirect=None, from_email=None):
    if post_reset_redirect is None:
        post_reset_redirect = reverse('django.contrib.auth.views.password_reset_done')
    if request.method == "POST":
        form = password_reset_form(request.POST)
        if form.is_valid():
            opts = {}
            opts['use_https'] = request.is_secure()
            opts['token_generator'] = token_generator
            opts['from_email'] = from_email
            opts['email_template_name'] = email_template_name
            opts['request'] = request
            if is_admin_site:
                opts['domain_override'] = request.META['HTTP_HOST']
            form.save(**opts)
            return HttpResponseRedirect(post_reset_redirect)
    else:
        form = password_reset_form()
    return render_to_response(template_name, {
        'form': form,
    }, context_instance=RequestContext(request))

def password_reset_done(request, template_name='registration/password_reset_done.html'):
    return render_to_response(template_name, context_instance=RequestContext(request))

# Doesn't need csrf_protect since no-one can guess the URL
def password_reset_confirm(request, uidb36=None, token=None, template_name='registration/password_reset_confirm.html',
                           token_generator=default_token_generator, set_password_form=SetPasswordForm,
                           post_reset_redirect=None):
    """
    View that checks the hash in a password reset link and presents a
    form for entering a new password.
    """
    assert uidb36 is not None and token is not None # checked by URLconf
    if post_reset_redirect is None:
        post_reset_redirect = reverse('django.contrib.auth.views.password_reset_complete')
    try:
        uid_int = base36_to_int(uidb36)
        user = User.objects.get(id=uid_int)
    except (ValueError, User.DoesNotExist):
        user = None

    context_instance = RequestContext(request)

    if user is not None and token_generator.check_token(user, token):
        context_instance['validlink'] = True
        if request.method == 'POST':
            form = set_password_form(user, request.POST)
            if form.is_valid():
                form.save()
                return HttpResponseRedirect(post_reset_redirect)
        else:
            form = set_password_form(None)
    else:
        context_instance['validlink'] = False
        form = None
    context_instance['form'] = form
    return render_to_response(template_name, context_instance=context_instance)

def password_reset_complete(request, template_name='registration/password_reset_complete.html'):
    return render_to_response(template_name, context_instance=RequestContext(request,
                                                                             {'login_url': settings.LOGIN_URL}))

@csrf_protect
@login_required
def password_change(request, template_name='registration/password_change_form.html',
                    post_change_redirect=None, password_change_form=PasswordChangeForm):
    if post_change_redirect is None:
        post_change_redirect = reverse('django.contrib.auth.views.password_change_done')
    if request.method == "POST":
        form = password_change_form(user=request.user, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(post_change_redirect)
    else:
        form = password_change_form(user=request.user)
    return render_to_response(template_name, {
        'form': form,
    }, context_instance=RequestContext(request))

def password_change_done(request, template_name='registration/password_change_done.html'):
    return render_to_response(template_name, context_instance=RequestContext(request))
<commit_msg>Fixed #5298 -- Added extra_context to contrib auth views.<commit_after>import re
import urlparse
from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
# Avoid shadowing the login() view below.
from django.contrib.auth import login as auth_login
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm, PasswordChangeForm
from django.contrib.auth.tokens import default_token_generator
from django.views.decorators.csrf import csrf_protect
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib.sites.models import get_current_site
from django.http import HttpResponseRedirect, Http404, QueryDict
from django.template import RequestContext
from django.utils.http import base36_to_int
from django.utils.translation import ugettext as _
from django.contrib.auth.models import User
from django.views.decorators.cache import never_cache

@csrf_protect
@never_cache
def login(request, template_name='registration/login.html',
          redirect_field_name=REDIRECT_FIELD_NAME,
          authentication_form=AuthenticationForm,
          extra_context=None):
    """Displays the login form and handles the login action."""

    redirect_to = request.REQUEST.get(redirect_field_name, '')

    if request.method == "POST":
        form = authentication_form(data=request.POST)
        if form.is_valid():
            netloc = urlparse.urlparse(redirect_to)[1]

            # Light security check -- make sure redirect_to isn't garbage.
            if not redirect_to or ' ' in redirect_to:
                redirect_to = settings.LOGIN_REDIRECT_URL

            # Heavier security check -- don't allow redirection to a different
            # host.
            elif netloc and netloc != request.get_host():
                redirect_to = settings.LOGIN_REDIRECT_URL

            # Okay, security checks complete. Log the user in.
            auth_login(request, form.get_user())

            if request.session.test_cookie_worked():
                request.session.delete_test_cookie()

            return HttpResponseRedirect(redirect_to)
    else:
        form = authentication_form(request)

    request.session.set_test_cookie()

    current_site = get_current_site(request)

    context = {
        'form': form,
        redirect_field_name: redirect_to,
        'site': current_site,
        'site_name': current_site.name,
    }
    context.update(extra_context or {})
    return render_to_response(template_name, context,
                              context_instance=RequestContext(request))

def logout(request, next_page=None,
           template_name='registration/logged_out.html',
           redirect_field_name=REDIRECT_FIELD_NAME,
           extra_context=None):
    "Logs out the user and displays 'You are logged out' message."
    from django.contrib.auth import logout
    logout(request)
    if next_page is None:
        redirect_to = request.REQUEST.get(redirect_field_name, '')
        if redirect_to:
            return HttpResponseRedirect(redirect_to)
        else:
            current_site = get_current_site(request)
            context = {
                'site': current_site,
                'site_name': current_site.name,
                'title': _('Logged out')
            }
            context.update(extra_context or {})
            return render_to_response(template_name, context,
                                      context_instance=RequestContext(request))
    else:
        # Redirect to this page until the session has been cleared.
        return HttpResponseRedirect(next_page or request.path)

def logout_then_login(request, login_url=None, extra_context=None):
    "Logs out the user if he is logged in. Then redirects to the log-in page."
    if not login_url:
        login_url = settings.LOGIN_URL
    return logout(request, login_url, extra_context=extra_context)

def redirect_to_login(next, login_url=None,
                      redirect_field_name=REDIRECT_FIELD_NAME):
    "Redirects the user to the login page, passing the given 'next' page"
    if not login_url:
        login_url = settings.LOGIN_URL

    login_url_parts = list(urlparse.urlparse(login_url))
    if redirect_field_name:
        querystring = QueryDict(login_url_parts[4], mutable=True)
        querystring[redirect_field_name] = next
        login_url_parts[4] = querystring.urlencode(safe='/')

    return HttpResponseRedirect(urlparse.urlunparse(login_url_parts))

# 4 views for password reset:
# - password_reset sends the mail
# - password_reset_done shows a success message for the above
# - password_reset_confirm checks the link the user clicked and
#   prompts for a new password
# - password_reset_complete shows a success message for the above

@csrf_protect
def password_reset(request, is_admin_site=False,
                   template_name='registration/password_reset_form.html',
                   email_template_name='registration/password_reset_email.html',
                   password_reset_form=PasswordResetForm,
                   token_generator=default_token_generator,
                   post_reset_redirect=None,
                   from_email=None,
                   extra_context=None):
    if post_reset_redirect is None:
        post_reset_redirect = reverse('django.contrib.auth.views.password_reset_done')
    if request.method == "POST":
        form = password_reset_form(request.POST)
        if form.is_valid():
            opts = {
                'use_https': request.is_secure(),
                'token_generator': token_generator,
                'from_email': from_email,
                'email_template_name': email_template_name,
                'request': request,
            }
            if is_admin_site:
                opts = dict(opts, domain_override=request.META['HTTP_HOST'])
            form.save(**opts)
            return HttpResponseRedirect(post_reset_redirect)
    else:
        form = password_reset_form()
    context = {
        'form': form,
    }
    context.update(extra_context or {})
    return render_to_response(template_name, context,
                              context_instance=RequestContext(request))

def password_reset_done(request,
                        template_name='registration/password_reset_done.html',
                        extra_context=None):
    context = {}
    context.update(extra_context or {})
    return render_to_response(template_name, context,
                              context_instance=RequestContext(request))

# Doesn't need csrf_protect since no-one can guess the URL
def password_reset_confirm(request, uidb36=None, token=None,
                           template_name='registration/password_reset_confirm.html',
                           token_generator=default_token_generator,
                           set_password_form=SetPasswordForm,
                           post_reset_redirect=None,
                           extra_context=None):
    """
    View that checks the hash in a password reset link and presents a
    form for entering a new password.
    """
    assert uidb36 is not None and token is not None # checked by URLconf
    if post_reset_redirect is None:
        post_reset_redirect = reverse('django.contrib.auth.views.password_reset_complete')
    try:
        uid_int = base36_to_int(uidb36)
        user = User.objects.get(id=uid_int)
    except (ValueError, User.DoesNotExist):
        user = None

    if user is not None and token_generator.check_token(user, token):
        validlink = True
        if request.method == 'POST':
            form = set_password_form(user, request.POST)
            if form.is_valid():
                form.save()
                return HttpResponseRedirect(post_reset_redirect)
        else:
            form = set_password_form(None)
    else:
        validlink = False
        form = None
    context = {
        'form': form,
        'validlink': validlink,
    }
    context.update(extra_context or {})
    return render_to_response(template_name, context,
                              context_instance=RequestContext(request))

def password_reset_complete(request,
                            template_name='registration/password_reset_complete.html',
                            extra_context=None):
    context = {
        'login_url': settings.LOGIN_URL
    }
    context.update(extra_context or {})
    return render_to_response(template_name, context,
                              context_instance=RequestContext(request))

@csrf_protect
@login_required
def password_change(request,
                    template_name='registration/password_change_form.html',
                    post_change_redirect=None,
                    password_change_form=PasswordChangeForm,
                    extra_context=None):
    if post_change_redirect is None:
        post_change_redirect = reverse('django.contrib.auth.views.password_change_done')
    if request.method == "POST":
        form = password_change_form(user=request.user, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(post_change_redirect)
    else:
        form = password_change_form(user=request.user)
    context = {
        'form': form,
    }
    context.update(extra_context or {})
    return render_to_response(template_name, context,
                              context_instance=RequestContext(request))

def password_change_done(request,
                         template_name='registration/password_change_done.html',
                         extra_context=None):
    context = {}
    context.update(extra_context or {})
    return render_to_response(template_name, context,
                              context_instance=RequestContext(request))
<|endoftext|>


<commit_before>from __future__ import division
import numpy as np
import pylab as pl
from mpl_toolkits.axes_grid1 import make_axes_locatable

import fastfit

# Set for our camera
sx, sy, pixelsize = 640, 480, 5.6

def sizetext(sx, sy):
    """
    Check if the difference between the two axes are similar or different
    Returns displayable text
    """
    if abs(sx - sy)/(sx+sy) < 0.05:
        csign = '~'
    elif (sx > sy):
        csign = '>'
    else:
        csign = '<'
    ctext = "wx  |  wy\n%.1f %s %.1f" %(sx, csign, sy)
    return ctext

def limits(centre, out, valid):
    """ Calculate matrix borders with limits """
    bottom = max(valid[0], centre-out)
    top = min(valid[1], centre+out)
    return bottom, top

def gauss(x, x0, sx, scale):
    """ Simple gaussian """
    return np.exp(-(x-x0)**2 / (2 * sx**2)) * scale

def preparedata(data):
    """ Prepare data for processing by cutting down on the area for D4s

    Input:
    ------
    data: original reading values in numpy array from

    Output:
    ------
    prepared: data in the cropped area
    (xbottom, ybottom): value of the starting corner in two dimension
    """
    dh, dw = data.shape
    border = np.array([])
    border = np.append(border, np.ravel(data[:-1, 0]))
    border = np.append(border, np.ravel(data[0, 1:]))
    border = np.append(border, np.ravel(data[1:, -1]))
    border = np.append(border, np.ravel(data[-1, :-1]))
    borderavg, bordervar = np.mean(border), np.var(border)
    slimdata = np.copy(data) - borderavg
    maxy, maxx = np.unravel_index(np.argmax(slimdata), slimdata.shape)
    # Find the number of points in the x/y direction that are above the background noise
    xl = slimdata[:, maxx]
    xdim = sum(sum([xl > 10*bordervar]))
    yl = slimdata[maxy, :]
    ydim = sum(sum([yl > 10*bordervar]))
    dim = 2 * max(xdim, ydim)
    xbottom, xtop = limits(maxx, dim, (0, dw))
    ybottom, ytop = limits(maxy, dim, (0, dh))
    testdata = slimdata[ybottom:ytop, xbottom:xtop]
    xx, yy, dx, dy, angle = fastfit.d4s(testdata)

    xc = int(xbottom+xx)
    yc = int(ybottom+yy)
    limr = 0.69
    limx = int(dx * limr)
    limy = int(dy * limr)
    xbottom, xtop = limits(xc, limx, (0, dw))
    ybottom, ytop = limits(yc, limy, (0, dh))
    prepared = slimdata[ybottom:ytop, xbottom:xtop]
    return prepared, (xbottom, ybottom)

def analyze(data):
    """ Do all the analysis that's needed to create the interface """
    prepared, centre = preparedata(data)
    xx, yy, dx, dy, angle = fastfit.d4s(prepared)
    xx += centre[0]
    yy += centre[1]
    xr, yr = fastfit.getellipse(xx, yy, dx, dy, angle)
    # fix axes calculation so no more -1 is needed
    angle *= -1
    adeg = "%.1f deg" %(angle / np.pi * 180)
    xxx = [xx - dx/2*np.cos(angle), xx + dx/2*np.cos(angle)]
    xxy = [yy + dx/2*np.sin(angle), yy - dx/2*np.sin(angle)]
    yyx = [xx + dy/2*np.sin(angle), xx - dy/2*np.sin(angle)]
    yyy = [yy + dy/2*np.cos(angle), yy - dy/2*np.cos(angle)]
    xwidth = (dx*np.cos(angle)**2 + dy*np.sin(angle)**2)/4.0
    ywidth = (dx*np.sin(angle)**2 + dy*np.cos(angle)**2)/4.0

    try:
        xc = int(np.round(xx))
        yc = int(np.round(yy))
    except ValueError:
        xc = 320
        yc = 240
    sy, sx = data.shape
    xcut = data[yc, :]
    ycut = data[:, xc]
    xline = range(0, sx)
    yline = range(0, sy)
    xcutg = gauss(xline, xx, xwidth, max(xcut))
    ycutg = gauss(yline, yy, ywidth, max(ycut))
    return (xx, yy, dx, dy, angle, xr, yr, adeg, xxx, xxy, yyx, yyy, xwidth, ywidth, xc, yc, xcut, ycut, xcutg, ycutg)

def createiface(data):
    (xx, yy, dx, dy, angle, xr, yr, adeg, xxx, xxy, yyx, yyy, xwidth, ywidth, xc, yc, xcut, ycut, xcutg, ycutg) = analyze(data)
    sy, sx = data.shape

    st = sizetext(dx/2*pixelsize, dy/2*pixelsize)
    text = "Data range: %d - %d" %(np.min(data), np.max(data))

    fs = 12.5
    fig = pl.figure(num=1, figsize=(fs, fs))

    axImg = pl.subplot(111)
    img = axImg.imshow(data, vmin=0, vmax=256, cmap='Paired')
    centre, = axImg.plot(xx, yy, '+', markersize=10)
    ellipse, = axImg.plot(xr, yr, 'k-', linewidth=3)
    ax1, ax2, = axImg.plot(xxx, xxy, 'k-', yyx, yyy, 'k-', linewidth=2)

    divider = make_axes_locatable(axImg)

    xline = range(0, sx)
    yline = range(0, sy)

    cutlinewidth=3
    fitlinewidth=2
    axCuty = divider.append_axes("right", size=1.4, pad=0.1, sharey=axImg)
    yl, = axCuty.plot(ycut, yline, 'k-', linewidth=cutlinewidth)
    yg, = axCuty.plot(ycutg, yline, 'r-', linewidth=fitlinewidth)

    axCutx = divider.append_axes("bottom", size=1.4, pad=0.1, sharex=axImg)
    xl, = axCutx.plot(xline, xcut, 'k-', linewidth=cutlinewidth)
    xg, = axCutx.plot(xline, xcutg, 'r-', linewidth=fitlinewidth)

    # Setting up limits
    axImg.set_xlim([0, sx])
    axImg.set_ylim([sy, 0])
    axImg.set_xticks([])
    axImg.set_yticks([])

    axCuty.set_xlim([-10, 256])
    axCuty.set_xticks([0, 128, 256])

    axCutx.set_ylim([256, -10])
    axCutx.set_yticks([0, 128, 256])

    htext = fig.text(0.5, 0.975, 'wx/wy = D4s/2*pixelsize [um] along principal axes\n = beam waist for Gaussian beam', horizontalalignment='center', fontsize=20)
    sztext = fig.text(0.5, 0.81, st, horizontalalignment='center', fontsize=67)
    atext = fig.text(0.5, 0.10, adeg, horizontalalignment='center', fontsize=65)
    uptext = fig.text(0.5, 0.05, text, horizontalalignment='center', fontsize=25)

    ret = (fig, img, centre, ellipse, ax1, ax2, xl, xg, yl, yg, sztext, uptext, atext)
    return ret

def updateiface(data, elements):
    """
    Run only updates of data on the interface

    data : input data
    elements : output of createiface(data)
    """
    (xx, yy, dx, dy, angle, xr, yr, adeg, xxx, xxy, yyx, yyy, xwidth, ywidth, xc, yc, xcut, ycut, xcutg, ycutg) = analyze(data)
    (fig, img, centre, ellipse, ax1, ax2, xl, xg, yl, yg, sztext, uptext, atext) = elements
    xline = range(0, sx)
    yline = range(0, sy)

    img.set_data(data)
    centre.set_xdata(xx)
    centre.set_ydata(yy)

    ellipse.set_xdata(xr)
    ellipse.set_ydata(yr)
    ax1.set_xdata(xxx)
    ax1.set_ydata(xxy)
    ax2.set_xdata(yyx)
    ax2.set_ydata(yyy)

    xl.set_ydata(xcut)
    xg.set_ydata(xcutg)

    yl.set_xdata(ycut)
    yg.set_xdata(ycutg)

    st = sizetext(dx/2*pixelsize, dy/2*pixelsize)
    text = "Data range: %d - %d" %(np.min(data), np.max(data))

    uptext.set_text(text)
    sztext.set_text(st)
    atext.set_text(adeg)

if __name__ == "__main__":
    filename = "test.txt"
    data = np.loadtxt(filename)

    elements = createiface(data)
    updateiface(data, elements)

    pl.show()
<commit_msg>fix crash in case there's no signal<commit_after>from __future__ import division
import numpy as np
import pylab as pl
from mpl_toolkits.axes_grid1 import make_axes_locatable

import fastfit

# Set for our camera
sx, sy, pixelsize = 640, 480, 5.6

def sizetext(sx, sy):
    """
    Check if the difference between the two axes are similar or different
    Returns displayable text
    """
    if abs(sx - sy)/(sx+sy) < 0.05:
        csign = '~'
    elif (sx > sy):
        csign = '>'
    else:
        csign = '<'
    ctext = "wx  |  wy\n%.1f %s %.1f" %(sx, csign, sy)
    return ctext

def limits(centre, out, valid):
    """ Calculate matrix borders with limits """
    bottom = max(valid[0], centre-out)
    top = min(valid[1], centre+out)
    return bottom, top

def gauss(x, x0, sx, scale):
    """ Simple gaussian """
    return np.exp(-(x-x0)**2 / (2 * sx**2)) * scale

def preparedata(data):
    """ Prepare data for processing by cutting down on the area for D4s

    Input:
    ------
    data: original reading values in numpy array from

    Output:
    ------
    prepared: data in the cropped area
    (xbottom, ybottom): value of the starting corner in two dimension
    """
    dh, dw = data.shape
    border = np.array([])
    border = np.append(border, np.ravel(data[:-1, 0]))
    border = np.append(border, np.ravel(data[0, 1:]))
    border = np.append(border, np.ravel(data[1:, -1]))
    border = np.append(border, np.ravel(data[-1, :-1]))
    borderavg, bordervar = np.mean(border), np.var(border)
    slimdata = np.copy(data) - borderavg
    maxy, maxx = np.unravel_index(np.argmax(slimdata), slimdata.shape)
    # Find the number of points in the x/y direction that are above the background noise
    xl = slimdata[:, maxx]
    xdim = sum(sum([xl > 10*bordervar]))
    yl = slimdata[maxy, :]
    ydim = sum(sum([yl > 10*bordervar]))
    dim = 2 * max(xdim, ydim)
    if dim < 5:
        # In this case, most likely we don't have a peak, just noise, since
        # very few points are over the noiselevel
        return data, (0, 0)
    xbottom, xtop = limits(maxx, dim, (0, dw))
    ybottom, ytop = limits(maxy, dim, (0, dh))
    testdata = slimdata[ybottom:ytop, xbottom:xtop]
    xx, yy, dx, dy, angle = fastfit.d4s(testdata)

    xc = int(xbottom+xx)
    yc = int(ybottom+yy)
    limr = 0.69
    limx = int(dx * limr)
    limy = int(dy * limr)
    xbottom, xtop = limits(xc, limx, (0, dw))
    ybottom, ytop = limits(yc, limy, (0, dh))
    prepared = slimdata[ybottom:ytop, xbottom:xtop]
    return prepared, (xbottom, ybottom)

def analyze(data):
    """ Do all the analysis that's needed to create the interface """
    prepared, centre = preparedata(data)
    xx, yy, dx, dy, angle = fastfit.d4s(prepared)
    xx += centre[0]
    yy += centre[1]
    xr, yr = fastfit.getellipse(xx, yy, dx, dy, angle)
    # fix axes calculation so no more -1 is needed
    angle *= -1
    adeg = "%.1f deg" %(angle / np.pi * 180)
    xxx = [xx - dx/2*np.cos(angle), xx + dx/2*np.cos(angle)]
    xxy = [yy + dx/2*np.sin(angle), yy - dx/2*np.sin(angle)]
    yyx = [xx + dy/2*np.sin(angle), xx - dy/2*np.sin(angle)]
    yyy = [yy + dy/2*np.cos(angle), yy - dy/2*np.cos(angle)]
    xwidth = (dx*np.cos(angle)**2 + dy*np.sin(angle)**2)/4.0
    ywidth = (dx*np.sin(angle)**2 + dy*np.cos(angle)**2)/4.0

    try:
        xc = int(np.round(xx))
        yc = int(np.round(yy))
    except ValueError:
        xc = 320
        yc = 240
    sy, sx = data.shape
    xcut = data[yc, :]
    ycut = data[:, xc]
    xline = range(0, sx)
    yline = range(0, sy)
    xcutg = gauss(xline, xx, xwidth, max(xcut))
    ycutg = gauss(yline, yy, ywidth, max(ycut))
    return (xx, yy, dx, dy, angle, xr, yr, adeg, xxx, xxy, yyx, yyy, xwidth, ywidth, xc, yc, xcut, ycut, xcutg, ycutg)

def createiface(data):
    (xx, yy, dx, dy, angle, xr, yr, adeg, xxx, xxy, yyx, yyy, xwidth, ywidth, xc, yc, xcut, ycut, xcutg, ycutg) = analyze(data)
    sy, sx = data.shape

    st = sizetext(dx/2*pixelsize, dy/2*pixelsize)
    text = "Data range: %d - %d" %(np.min(data), np.max(data))

    fs = 12.5
    fig = pl.figure(num=1, figsize=(fs, fs))

    axImg = pl.subplot(111)
    img = axImg.imshow(data, vmin=0, vmax=256, cmap='Paired')
    centre, = axImg.plot(xx, yy, '+', markersize=10)
    ellipse, = axImg.plot(xr, yr, 'k-', linewidth=3)
    ax1, ax2, = axImg.plot(xxx, xxy, 'k-', yyx, yyy, 'k-', linewidth=2)

    divider = make_axes_locatable(axImg)

    xline = range(0, sx)
    yline = range(0, sy)

    cutlinewidth=3
    fitlinewidth=2
    axCuty = divider.append_axes("right", size=1.4, pad=0.1, sharey=axImg)
    yl, = axCuty.plot(ycut, yline, 'k-', linewidth=cutlinewidth)
    yg, = axCuty.plot(ycutg, yline, 'r-', linewidth=fitlinewidth)

    axCutx = divider.append_axes("bottom", size=1.4, pad=0.1, sharex=axImg)
    xl, = axCutx.plot(xline, xcut, 'k-', linewidth=cutlinewidth)
    xg, = axCutx.plot(xline, xcutg, 'r-', linewidth=fitlinewidth)

    # Setting up limits
    axImg.set_xlim([0, sx])
    axImg.set_ylim([sy, 0])
    axImg.set_xticks([])
    axImg.set_yticks([])

    axCuty.set_xlim([-10, 256])
    axCuty.set_xticks([0, 128, 256])

    axCutx.set_ylim([256, -10])
    axCutx.set_yticks([0, 128, 256])

    htext = fig.text(0.5, 0.975, 'wx/wy = D4s/2*pixelsize [um] along principal axes\n = beam waist for Gaussian beam', horizontalalignment='center', fontsize=20)
    sztext = fig.text(0.5, 0.81, st, horizontalalignment='center', fontsize=67)
    atext = fig.text(0.5, 0.10, adeg, horizontalalignment='center', fontsize=65)
    uptext = fig.text(0.5, 0.05, text, horizontalalignment='center', fontsize=25)

    ret = (fig, img, centre, ellipse, ax1, ax2, xl, xg, yl, yg, sztext, uptext, atext)
    return ret

def updateiface(data, elements):
    """
    Run only updates of data on the interface

    data : input data
    elements : output of createiface(data)
    """
    (xx, yy, dx, dy, angle, xr, yr, adeg, xxx, xxy, yyx, yyy, xwidth, ywidth, xc, yc, xcut, ycut, xcutg, ycutg) = analyze(data)
    (fig, img, centre, ellipse, ax1, ax2, xl, xg, yl, yg, sztext, uptext, atext) = elements
    xline = range(0, sx)
    yline = range(0, sy)

    img.set_data(data)
    centre.set_xdata(xx)
    centre.set_ydata(yy)

    ellipse.set_xdata(xr)
    ellipse.set_ydata(yr)
    ax1.set_xdata(xxx)
    ax1.set_ydata(xxy)
    ax2.set_xdata(yyx)
    ax2.set_ydata(yyy)

    xl.set_ydata(xcut)
    xg.set_ydata(xcutg)

    yl.set_xdata(ycut)
    yg.set_xdata(ycutg)

    st = sizetext(dx/2*pixelsize, dy/2*pixelsize)
    text = "Data range: %d - %d" %(np.min(data), np.max(data))

    uptext.set_text(text)
    sztext.set_text(st)
    atext.set_text(adeg)

if __name__ == "__main__":
    filename = "test.txt"
    data = np.loadtxt(filename)

    elements = createiface(data)
    updateiface(data, elements)

    pl.show()
<|endoftext|>


<commit_before>"""
 Imports the SpatialRefSys and GeometryColumns models dependent on the
 spatial database backend.
"""
import re
from django.conf import settings

# Checking for the presence of GDAL (needed for the SpatialReference object)
from django.contrib.gis.gdal import HAS_GDAL, PYTHON23
if HAS_GDAL:
    from django.contrib.gis.gdal import SpatialReference

class SpatialRefSysMixin(object):
    """
    The SpatialRefSysMixin is a class used by the database-dependent
    SpatialRefSys objects to reduce redundnant code.
    """
    # For pulling out the spheroid from the spatial reference string. This
    # regular expression is used only if the user does not have GDAL installed.
    # TODO: Flattening not used in all ellipsoids, could also be a minor axis,
    # or 'b' parameter.
    spheroid_regex = re.compile(r'.+SPHEROID\[\"(?P<name>.+)\",(?P<major>\d+(\.\d+)?),(?P<flattening>\d{3}\.\d+),')

    # For pulling out the units on platforms w/o GDAL installed.
    # TODO: Figure out how to pull out angular units of projected coordinate system and
    # fix for LOCAL_CS types.  GDAL should be highly recommended for performing
    # distance queries.
    units_regex = re.compile(r'.+UNIT ?\["(?P<unit_name>[\w \'\(\)]+)", ?(?P<unit>[\d\.]+)(,AUTHORITY\["(?P<unit_auth_name>[\w \'\(\)]+)","(?P<unit_auth_val>\d+)"\])?\]([\w ]+)?(,AUTHORITY\["(?P<auth_name>[\w \'\(\)]+)","(?P<auth_val>\d+)"\])?\]$')

    def srs(self):
        """
        Returns a GDAL SpatialReference object, if GDAL is installed.
        """
        if HAS_GDAL:
            # TODO: Is caching really necessary here?  Is complexity worth it?
            if hasattr(self, '_srs'):
                # Returning a clone of the cached SpatialReference object.
                return self._srs.clone()
            else:
                # Attempting to cache a SpatialReference object.

                # Trying to get from WKT first.
                try:
                    self._srs = SpatialReference(self.wkt)
                    return self.srs
                except Exception, msg:
                    pass

                try:
                    self._srs = SpatialReference(self.proj4text)
                    return self.srs
                except Exception, msg:
                    pass

                raise Exception('Could not get OSR SpatialReference from WKT: %s\nError:\n%s' % (self.wkt, msg))
        else:
            raise Exception('GDAL is not installed.')
    srs = property(srs)

    def ellipsoid(self):
        """
        Returns a tuple of the ellipsoid parameters:
        (semimajor axis, semiminor axis, and inverse flattening).
        """
        if HAS_GDAL:
            return self.srs.ellipsoid
        else:
            m = self.spheroid_regex.match(self.wkt)
            if m: return (float(m.group('major')), float(m.group('flattening')))
            else: return None
    ellipsoid = property(ellipsoid)

    def name(self):
        "Returns the projection name."
        return self.srs.name
    name = property(name)

    def spheroid(self):
        "Returns the spheroid name for this spatial reference."
        return self.srs['spheroid']
    spheroid = property(spheroid)

    def datum(self):
        "Returns the datum for this spatial reference."
        return self.srs['datum']
    datum = property(datum)

    def projected(self):
        "Is this Spatial Reference projected?"
        if HAS_GDAL:
            return self.srs.projected
        else:
            return self.wkt.startswith('PROJCS')
    projected = property(projected)

    def local(self):
        "Is this Spatial Reference local?"
        if HAS_GDAL:
            return self.srs.local
        else:
            return self.wkt.startswith('LOCAL_CS')
    local = property(local)

    def geographic(self):
        "Is this Spatial Reference geographic?"
        if HAS_GDAL:
            return self.srs.geographic
        else:
            return self.wkt.startswith('GEOGCS')
    geographic = property(geographic)

    def linear_name(self):
        "Returns the linear units name."
        if HAS_GDAL:
            return self.srs.linear_name
        elif self.geographic:
            return None
        else:
            m = self.units_regex.match(self.wkt)
            return m.group('unit_name')
    linear_name = property(linear_name)

    def linear_units(self):
        "Returns the linear units."
        if HAS_GDAL:
            return self.srs.linear_units
        elif self.geographic:
            return None
        else:
            m = self.units_regex.match(self.wkt)
            return m.group('unit')
    linear_units = property(linear_units)

    def angular_name(self):
        "Returns the name of the angular units."
        if HAS_GDAL:
            return self.srs.angular_name
        elif self.projected:
            return None
        else:
            m = self.units_regex.match(self.wkt)
            return m.group('unit_name')
    angular_name = property(angular_name)

    def angular_units(self):
        "Returns the angular units."
        if HAS_GDAL:
            return self.srs.angular_units
        elif self.projected:
            return None
        else:
            m = self.units_regex.match(self.wkt)
            return m.group('unit')
    angular_units = property(angular_units)

    def units(self):
        "Returns a tuple of the units and the name."
        if self.projected or self.local:
            return (self.linear_units, self.linear_name)
        elif self.geographic:
            return (self.angular_units, self.angular_name)
        else:
            return (None, None)
    units = property(units)

    def get_units(cls, wkt):
        """
        Class method used by GeometryField on initialization to
        retrive the units on the given WKT, without having to use
        any of the database fields.
        """
        if HAS_GDAL:
            return SpatialReference(wkt).units
        else:
            m = cls.units_regex.match(wkt)
            return m.group('unit'), m.group('unit_name')
    get_units = classmethod(get_units)

    def get_spheroid(cls, wkt, string=True):
        """
        Class method used by GeometryField on initialization to
        retrieve the `SPHEROID[..]` parameters from the given WKT.
        """
        if HAS_GDAL:
            srs = SpatialReference(wkt)
            sphere_params = srs.ellipsoid
            sphere_name = srs['spheroid']
        else:
            m = cls.spheroid_regex.match(wkt)
            if m:
                sphere_params = (float(m.group('major')), float(m.group('flattening')))
                sphere_name = m.group('name')
            else:
                return None

        if not string:
            return sphere_name, sphere_params
        else:
            # `string` parameter used to place in format acceptable by PostGIS
            if len(sphere_params) == 3:
                radius, flattening = sphere_params[0], sphere_params[2]
            else:
                radius, flattening = sphere_params
            return 'SPHEROID["%s",%s,%s]' % (sphere_name, radius, flattening)
    get_spheroid = classmethod(get_spheroid)

    def __unicode__(self):
        """
        Returns the string representation.  If GDAL is installed,
        it will be 'pretty' OGC WKT.
        """
        try:
            return unicode(self.srs)
        except:
            return unicode(self.wkt)

# Defining dummy default first; if spatial db, will overrride.
def get_srid_info(srid):
    """
    Dummy routine for the backends that do not have the OGC required
    spatial metadata tables (like MySQL).
    """
    return None, None, None

# Django test suite on 2.3 platforms will choke on code inside this
# conditional.
if not PYTHON23:
    try:
        # try/except'ing the importation of SpatialBackend.  Have to fail
        # silently because this module may be inadvertently invoked by
        # non-GeoDjango users (e.g., when the Django test suite executes
        # the models.py of all contrib apps).
        from django.contrib.gis.db.backend import SpatialBackend
        if SpatialBackend.mysql: raise Exception

        # Exposing the SpatialRefSys and GeometryColumns models.
        class SpatialRefSys(SpatialBackend.SpatialRefSys, SpatialRefSysMixin):
            pass
        GeometryColumns = SpatialBackend.GeometryColumns

        # Override `get_srid_info` with something real thing.
        def get_srid_info(srid):
            """
            Returns the units, unit name, and spheroid WKT associated with the
            given SRID from the `spatial_ref_sys` (or equivalent) spatial database
            table.  We use a database cursor to execute the query because this
            function is used when it is not possible to use the ORM (for example,
            during field initialization).
            """
            # SRID=-1 is a common convention for indicating the geometry has no
            # spatial reference information associated with it.  Thus, we will
            # return all None values without raising an exception.
            if srid == -1: return None, None, None

            # Getting the spatial reference WKT associated with the SRID from the
            # `spatial_ref_sys` (or equivalent) spatial database table. This query
            # cannot be executed using the ORM because this information is needed
            # when the ORM cannot be used (e.g., during the initialization of
            # `GeometryField`).
            from django.db import connection
            cur = connection.cursor()
            qn = connection.ops.quote_name
            stmt = 'SELECT %(table)s.%(wkt_col)s FROM %(table)s WHERE (%(table)s.%(srid_col)s = %(srid)s)'
            params = {'table' : qn(SpatialRefSys._meta.db_table),
                      'srid_col' : qn('srid'),
                      'srid' : srid,
                      }
            if SpatialBackend.spatialite:
                if not HAS_GDAL: raise Exception('GDAL is required to use the SpatiaLite backend.')
                params['wkt_col'] = 'proj4text'
            else:
                params['wkt_col'] = qn(SpatialRefSys.wkt_col())

            # Executing the SQL statement.
            cur.execute(stmt % params)

            # Fetching the WKT from the cursor; if the query failed raise an Exception.
            fetched = cur.fetchone()
            if not fetched:
                raise ValueError('Failed to find spatial reference entry in "%s" corresponding to SRID=%s.' %
                                 (SpatialRefSys._meta.db_table, srid))

            if SpatialBackend.spatialite:
                # Because the `spatial_ref_sys` table does _not_ contain a WKT column,
                # we have to use GDAL to determine the units from the PROJ.4 string.
                srs_wkt = SpatialReference(fetched[0]).wkt
            else:
                srs_wkt = fetched[0]

            # Getting metadata associated with the spatial reference system identifier.
            # Specifically, getting the unit information and spheroid information
            # (both required for distance queries).
            unit, unit_name = SpatialRefSys.get_units(srs_wkt)
            spheroid = SpatialRefSys.get_spheroid(srs_wkt)
            return unit, unit_name, spheroid
    except:
        pass
<commit_msg>Fixed #9437 -- Now close database connection within `get_srid_info`.  Thanks, mattxbart.<commit_after>"""
 Imports the SpatialRefSys and GeometryColumns models dependent on the
 spatial database backend.
"""
import re
from django.conf import settings

# Checking for the presence of GDAL (needed for the SpatialReference object)
from django.contrib.gis.gdal import HAS_GDAL, PYTHON23
if HAS_GDAL:
    from django.contrib.gis.gdal import SpatialReference

class SpatialRefSysMixin(object):
    """
    The SpatialRefSysMixin is a class used by the database-dependent
    SpatialRefSys objects to reduce redundnant code.
    """
    # For pulling out the spheroid from the spatial reference string. This
    # regular expression is used only if the user does not have GDAL installed.
    # TODO: Flattening not used in all ellipsoids, could also be a minor axis,
    # or 'b' parameter.
    spheroid_regex = re.compile(r'.+SPHEROID\[\"(?P<name>.+)\",(?P<major>\d+(\.\d+)?),(?P<flattening>\d{3}\.\d+),')

    # For pulling out the units on platforms w/o GDAL installed.
    # TODO: Figure out how to pull out angular units of projected coordinate system and
    # fix for LOCAL_CS types.  GDAL should be highly recommended for performing
    # distance queries.
    units_regex = re.compile(r'.+UNIT ?\["(?P<unit_name>[\w \'\(\)]+)", ?(?P<unit>[\d\.]+)(,AUTHORITY\["(?P<unit_auth_name>[\w \'\(\)]+)","(?P<unit_auth_val>\d+)"\])?\]([\w ]+)?(,AUTHORITY\["(?P<auth_name>[\w \'\(\)]+)","(?P<auth_val>\d+)"\])?\]$')

    def srs(self):
        """
        Returns a GDAL SpatialReference object, if GDAL is installed.
        """
        if HAS_GDAL:
            # TODO: Is caching really necessary here?  Is complexity worth it?
            if hasattr(self, '_srs'):
                # Returning a clone of the cached SpatialReference object.
                return self._srs.clone()
            else:
                # Attempting to cache a SpatialReference object.

                # Trying to get from WKT first.
                try:
                    self._srs = SpatialReference(self.wkt)
                    return self.srs
                except Exception, msg:
                    pass

                try:
                    self._srs = SpatialReference(self.proj4text)
                    return self.srs
                except Exception, msg:
                    pass

                raise Exception('Could not get OSR SpatialReference from WKT: %s\nError:\n%s' % (self.wkt, msg))
        else:
            raise Exception('GDAL is not installed.')
    srs = property(srs)

    def ellipsoid(self):
        """
        Returns a tuple of the ellipsoid parameters:
        (semimajor axis, semiminor axis, and inverse flattening).
        """
        if HAS_GDAL:
            return self.srs.ellipsoid
        else:
            m = self.spheroid_regex.match(self.wkt)
            if m: return (float(m.group('major')), float(m.group('flattening')))
            else: return None
    ellipsoid = property(ellipsoid)

    def name(self):
        "Returns the projection name."
        return self.srs.name
    name = property(name)

    def spheroid(self):
        "Returns the spheroid name for this spatial reference."
        return self.srs['spheroid']
    spheroid = property(spheroid)

    def datum(self):
        "Returns the datum for this spatial reference."
        return self.srs['datum']
    datum = property(datum)

    def projected(self):
        "Is this Spatial Reference projected?"
        if HAS_GDAL:
            return self.srs.projected
        else:
            return self.wkt.startswith('PROJCS')
    projected = property(projected)

    def local(self):
        "Is this Spatial Reference local?"
        if HAS_GDAL:
            return self.srs.local
        else:
            return self.wkt.startswith('LOCAL_CS')
    local = property(local)

    def geographic(self):
        "Is this Spatial Reference geographic?"
        if HAS_GDAL:
            return self.srs.geographic
        else:
            return self.wkt.startswith('GEOGCS')
    geographic = property(geographic)

    def linear_name(self):
        "Returns the linear units name."
        if HAS_GDAL:
            return self.srs.linear_name
        elif self.geographic:
            return None
        else:
            m = self.units_regex.match(self.wkt)
            return m.group('unit_name')
    linear_name = property(linear_name)

    def linear_units(self):
        "Returns the linear units."
        if HAS_GDAL:
            return self.srs.linear_units
        elif self.geographic:
            return None
        else:
            m = self.units_regex.match(self.wkt)
            return m.group('unit')
    linear_units = property(linear_units)

    def angular_name(self):
        "Returns the name of the angular units."
        if HAS_GDAL:
            return self.srs.angular_name
        elif self.projected:
            return None
        else:
            m = self.units_regex.match(self.wkt)
            return m.group('unit_name')
    angular_name = property(angular_name)

    def angular_units(self):
        "Returns the angular units."
        if HAS_GDAL:
            return self.srs.angular_units
        elif self.projected:
            return None
        else:
            m = self.units_regex.match(self.wkt)
            return m.group('unit')
    angular_units = property(angular_units)

    def units(self):
        "Returns a tuple of the units and the name."
        if self.projected or self.local:
            return (self.linear_units, self.linear_name)
        elif self.geographic:
            return (self.angular_units, self.angular_name)
        else:
            return (None, None)
    units = property(units)

    def get_units(cls, wkt):
        """
        Class method used by GeometryField on initialization to
        retrive the units on the given WKT, without having to use
        any of the database fields.
        """
        if HAS_GDAL:
            return SpatialReference(wkt).units
        else:
            m = cls.units_regex.match(wkt)
            return m.group('unit'), m.group('unit_name')
    get_units = classmethod(get_units)

    def get_spheroid(cls, wkt, string=True):
        """
        Class method used by GeometryField on initialization to
        retrieve the `SPHEROID[..]` parameters from the given WKT.
        """
        if HAS_GDAL:
            srs = SpatialReference(wkt)
            sphere_params = srs.ellipsoid
            sphere_name = srs['spheroid']
        else:
            m = cls.spheroid_regex.match(wkt)
            if m:
                sphere_params = (float(m.group('major')), float(m.group('flattening')))
                sphere_name = m.group('name')
            else:
                return None

        if not string:
            return sphere_name, sphere_params
        else:
            # `string` parameter used to place in format acceptable by PostGIS
            if len(sphere_params) == 3:
                radius, flattening = sphere_params[0], sphere_params[2]
            else:
                radius, flattening = sphere_params
            return 'SPHEROID["%s",%s,%s]' % (sphere_name, radius, flattening)
    get_spheroid = classmethod(get_spheroid)

    def __unicode__(self):
        """
        Returns the string representation.  If GDAL is installed,
        it will be 'pretty' OGC WKT.
        """
        try:
            return unicode(self.srs)
        except:
            return unicode(self.wkt)

# Defining dummy default first; if spatial db, will overrride.
def get_srid_info(srid):
    """
    Dummy routine for the backends that do not have the OGC required
    spatial metadata tables (like MySQL).
    """
    return None, None, None

# Django test suite on 2.3 platforms will choke on code inside this
# conditional.
if not PYTHON23:
    try:
        # try/except'ing the importation of SpatialBackend.  Have to fail
        # silently because this module may be inadvertently invoked by
        # non-GeoDjango users (e.g., when the Django test suite executes
        # the models.py of all contrib apps).
        from django.contrib.gis.db.backend import SpatialBackend
        if SpatialBackend.mysql: raise Exception

        # Exposing the SpatialRefSys and GeometryColumns models.
        class SpatialRefSys(SpatialBackend.SpatialRefSys, SpatialRefSysMixin):
            pass
        GeometryColumns = SpatialBackend.GeometryColumns

        # Override `get_srid_info` with something real thing.
        def get_srid_info(srid):
            """
            Returns the units, unit name, and spheroid WKT associated with the
            given SRID from the `spatial_ref_sys` (or equivalent) spatial database
            table.  We use a database cursor to execute the query because this
            function is used when it is not possible to use the ORM (for example,
            during field initialization).
            """
            # SRID=-1 is a common convention for indicating the geometry has no
            # spatial reference information associated with it.  Thus, we will
            # return all None values without raising an exception.
            if srid == -1: return None, None, None

            # Getting the spatial reference WKT associated with the SRID from the
            # `spatial_ref_sys` (or equivalent) spatial database table. This query
            # cannot be executed using the ORM because this information is needed
            # when the ORM cannot be used (e.g., during the initialization of
            # `GeometryField`).
            from django.db import connection
            cur = connection.cursor()
            qn = connection.ops.quote_name
            stmt = 'SELECT %(table)s.%(wkt_col)s FROM %(table)s WHERE (%(table)s.%(srid_col)s = %(srid)s)'
            params = {'table' : qn(SpatialRefSys._meta.db_table),
                      'srid_col' : qn('srid'),
                      'srid' : srid,
                      }
            if SpatialBackend.spatialite:
                if not HAS_GDAL: raise Exception('GDAL is required to use the SpatiaLite backend.')
                params['wkt_col'] = 'proj4text'
            else:
                params['wkt_col'] = qn(SpatialRefSys.wkt_col())

            # Executing the SQL statement.
            cur.execute(stmt % params)

            # Fetching the WKT from the cursor; if the query failed raise an Exception.
            fetched = cur.fetchone()
            if not fetched:
                raise ValueError('Failed to find spatial reference entry in "%s" corresponding to SRID=%s.' %
                                 (SpatialRefSys._meta.db_table, srid))

            if SpatialBackend.spatialite:
                # Because the `spatial_ref_sys` table does _not_ contain a WKT column,
                # we have to use GDAL to determine the units from the PROJ.4 string.
                srs_wkt = SpatialReference(fetched[0]).wkt
            else:
                srs_wkt = fetched[0]
            connection.close()

            # Getting metadata associated with the spatial reference system identifier.
            # Specifically, getting the unit information and spheroid information
            # (both required for distance queries).
            unit, unit_name = SpatialRefSys.get_units(srs_wkt)
            spheroid = SpatialRefSys.get_spheroid(srs_wkt)
            return unit, unit_name, spheroid
    except:
        pass
<|endoftext|>


<commit_before>from django.core.handlers.base import BaseHandler
from django.core import signals
from django.dispatch import dispatcher
from django.utils import datastructures
from django.utils.encoding import force_unicode
from django import http
from pprint import pformat
from shutil import copyfileobj
from threading import Lock
try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO

# See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
STATUS_CODE_TEXT = {
    100: 'CONTINUE',
    101: 'SWITCHING PROTOCOLS',
    200: 'OK',
    201: 'CREATED',
    202: 'ACCEPTED',
    203: 'NON-AUTHORITATIVE INFORMATION',
    204: 'NO CONTENT',
    205: 'RESET CONTENT',
    206: 'PARTIAL CONTENT',
    300: 'MULTIPLE CHOICES',
    301: 'MOVED PERMANENTLY',
    302: 'FOUND',
    303: 'SEE OTHER',
    304: 'NOT MODIFIED',
    305: 'USE PROXY',
    306: 'RESERVED',
    307: 'TEMPORARY REDIRECT',
    400: 'BAD REQUEST',
    401: 'UNAUTHORIZED',
    402: 'PAYMENT REQUIRED',
    403: 'FORBIDDEN',
    404: 'NOT FOUND',
    405: 'METHOD NOT ALLOWED',
    406: 'NOT ACCEPTABLE',
    407: 'PROXY AUTHENTICATION REQUIRED',
    408: 'REQUEST TIMEOUT',
    409: 'CONFLICT',
    410: 'GONE',
    411: 'LENGTH REQUIRED',
    412: 'PRECONDITION FAILED',
    413: 'REQUEST ENTITY TOO LARGE',
    414: 'REQUEST-URI TOO LONG',
    415: 'UNSUPPORTED MEDIA TYPE',
    416: 'REQUESTED RANGE NOT SATISFIABLE',
    417: 'EXPECTATION FAILED',
    500: 'INTERNAL SERVER ERROR',
    501: 'NOT IMPLEMENTED',
    502: 'BAD GATEWAY',
    503: 'SERVICE UNAVAILABLE',
    504: 'GATEWAY TIMEOUT',
    505: 'HTTP VERSION NOT SUPPORTED',
}

def safe_copyfileobj(fsrc, fdst, length=16*1024, size=0):
    """
    A version of shutil.copyfileobj that will not read more than 'size' bytes.
    This makes it safe from clients sending more than CONTENT_LENGTH bytes of
    data in the body.
    """
    if not size:
        return
    while size > 0:
        buf = fsrc.read(min(length, size))
        if not buf:
            break
        fdst.write(buf)
        size -= len(buf)

class WSGIRequest(http.HttpRequest):
    def __init__(self, environ):
        self.environ = environ
        self.path = force_unicode(environ['PATH_INFO'])
        self.META = environ
        self.method = environ['REQUEST_METHOD'].upper()

    def __repr__(self):
        # Since this is called as part of error handling, we need to be very
        # robust against potentially malformed input.
        try:
            get = pformat(self.GET)
        except:
            get = '<could not parse>'
        try:
            post = pformat(self.POST)
        except:
            post = '<could not parse>'
        try:
            cookies = pformat(self.COOKIES)
        except:
            cookies = '<could not parse>'
        try:
            meta = pformat(self.META)
        except:
            meta = '<could not parse>'
        return '<WSGIRequest\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % \
            (get, post, cookies, meta)

    def get_full_path(self):
        return '%s%s' % (self.path, self.environ.get('QUERY_STRING', '') and ('?' + self.environ.get('QUERY_STRING', '')) or '')

    def is_secure(self):
        return 'wsgi.url_scheme' in self.environ \
            and self.environ['wsgi.url_scheme'] == 'https'

    def _load_post_and_files(self):
        # Populates self._post and self._files
        if self.method == 'POST':
            if self.environ.get('CONTENT_TYPE', '').startswith('multipart'):
                header_dict = dict([(k, v) for k, v in self.environ.items() if k.startswith('HTTP_')])
                header_dict['Content-Type'] = self.environ.get('CONTENT_TYPE', '')
                self._post, self._files = http.parse_file_upload(header_dict, self.raw_post_data)
            else:
                self._post, self._files = http.QueryDict(self.raw_post_data, encoding=self._encoding), datastructures.MultiValueDict()
        else:
            self._post, self._files = http.QueryDict('', encoding=self._encoding), datastructures.MultiValueDict()

    def _get_request(self):
        if not hasattr(self, '_request'):
            self._request = datastructures.MergeDict(self.POST, self.GET)
        return self._request

    def _get_get(self):
        if not hasattr(self, '_get'):
            # The WSGI spec says 'QUERY_STRING' may be absent.
            self._get = http.QueryDict(self.environ.get('QUERY_STRING', ''), encoding=self._encoding)
        return self._get

    def _set_get(self, get):
        self._get = get

    def _get_post(self):
        if not hasattr(self, '_post'):
            self._load_post_and_files()
        return self._post

    def _set_post(self, post):
        self._post = post

    def _get_cookies(self):
        if not hasattr(self, '_cookies'):
            self._cookies = http.parse_cookie(self.environ.get('HTTP_COOKIE', ''))
        return self._cookies

    def _set_cookies(self, cookies):
        self._cookies = cookies

    def _get_files(self):
        if not hasattr(self, '_files'):
            self._load_post_and_files()
        return self._files

    def _get_raw_post_data(self):
        try:
            return self._raw_post_data
        except AttributeError:
            buf = StringIO()
            try:
                # CONTENT_LENGTH might be absent if POST doesn't have content at all (lighttpd)
                content_length = int(self.environ.get('CONTENT_LENGTH', 0))
            except ValueError: # if CONTENT_LENGTH was empty string or not an integer
                content_length = 0
            safe_copyfileobj(self.environ['wsgi.input'], buf, size=content_length)
            self._raw_post_data = buf.getvalue()
            buf.close()
            return self._raw_post_data

    GET = property(_get_get, _set_get)
    POST = property(_get_post, _set_post)
    COOKIES = property(_get_cookies, _set_cookies)
    FILES = property(_get_files)
    REQUEST = property(_get_request)
    raw_post_data = property(_get_raw_post_data)

class WSGIHandler(BaseHandler):
    initLock = Lock()

    def __call__(self, environ, start_response):
        from django.conf import settings

        # Set up middleware if needed. We couldn't do this earlier, because
        # settings weren't available.
        if self._request_middleware is None:
            self.initLock.acquire()
            # Check that middleware is still uninitialised.
            if self._request_middleware is None:
                self.load_middleware()
            self.initLock.release()

        dispatcher.send(signal=signals.request_started)
        try:
            request = WSGIRequest(environ)
            response = self.get_response(request)

            # Apply response middleware
            for middleware_method in self._response_middleware:
                response = middleware_method(request, response)

        finally:
            dispatcher.send(signal=signals.request_finished)

        try:
            status_text = STATUS_CODE_TEXT[response.status_code]
        except KeyError:
            status_text = 'UNKNOWN STATUS CODE'
        status = '%s %s' % (response.status_code, status_text)
        response_headers = [(str(k), str(v)) for k, v in response.items()]
        for c in response.cookies.values():
            response_headers.append(('Set-Cookie', str(c.output(header=''))))
        start_response(status, response_headers)
        return response
<commit_msg>Removed unused import, unneeded due to [4144].<commit_after>from django.core.handlers.base import BaseHandler
from django.core import signals
from django.dispatch import dispatcher
from django.utils import datastructures
from django.utils.encoding import force_unicode
from django import http
from pprint import pformat
from threading import Lock
try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO

# See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
STATUS_CODE_TEXT = {
    100: 'CONTINUE',
    101: 'SWITCHING PROTOCOLS',
    200: 'OK',
    201: 'CREATED',
    202: 'ACCEPTED',
    203: 'NON-AUTHORITATIVE INFORMATION',
    204: 'NO CONTENT',
    205: 'RESET CONTENT',
    206: 'PARTIAL CONTENT',
    300: 'MULTIPLE CHOICES',
    301: 'MOVED PERMANENTLY',
    302: 'FOUND',
    303: 'SEE OTHER',
    304: 'NOT MODIFIED',
    305: 'USE PROXY',
    306: 'RESERVED',
    307: 'TEMPORARY REDIRECT',
    400: 'BAD REQUEST',
    401: 'UNAUTHORIZED',
    402: 'PAYMENT REQUIRED',
    403: 'FORBIDDEN',
    404: 'NOT FOUND',
    405: 'METHOD NOT ALLOWED',
    406: 'NOT ACCEPTABLE',
    407: 'PROXY AUTHENTICATION REQUIRED',
    408: 'REQUEST TIMEOUT',
    409: 'CONFLICT',
    410: 'GONE',
    411: 'LENGTH REQUIRED',
    412: 'PRECONDITION FAILED',
    413: 'REQUEST ENTITY TOO LARGE',
    414: 'REQUEST-URI TOO LONG',
    415: 'UNSUPPORTED MEDIA TYPE',
    416: 'REQUESTED RANGE NOT SATISFIABLE',
    417: 'EXPECTATION FAILED',
    500: 'INTERNAL SERVER ERROR',
    501: 'NOT IMPLEMENTED',
    502: 'BAD GATEWAY',
    503: 'SERVICE UNAVAILABLE',
    504: 'GATEWAY TIMEOUT',
    505: 'HTTP VERSION NOT SUPPORTED',
}

def safe_copyfileobj(fsrc, fdst, length=16*1024, size=0):
    """
    A version of shutil.copyfileobj that will not read more than 'size' bytes.
    This makes it safe from clients sending more than CONTENT_LENGTH bytes of
    data in the body.
    """
    if not size:
        return
    while size > 0:
        buf = fsrc.read(min(length, size))
        if not buf:
            break
        fdst.write(buf)
        size -= len(buf)

class WSGIRequest(http.HttpRequest):
    def __init__(self, environ):
        self.environ = environ
        self.path = force_unicode(environ['PATH_INFO'])
        self.META = environ
        self.method = environ['REQUEST_METHOD'].upper()

    def __repr__(self):
        # Since this is called as part of error handling, we need to be very
        # robust against potentially malformed input.
        try:
            get = pformat(self.GET)
        except:
            get = '<could not parse>'
        try:
            post = pformat(self.POST)
        except:
            post = '<could not parse>'
        try:
            cookies = pformat(self.COOKIES)
        except:
            cookies = '<could not parse>'
        try:
            meta = pformat(self.META)
        except:
            meta = '<could not parse>'
        return '<WSGIRequest\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % \
            (get, post, cookies, meta)

    def get_full_path(self):
        return '%s%s' % (self.path, self.environ.get('QUERY_STRING', '') and ('?' + self.environ.get('QUERY_STRING', '')) or '')

    def is_secure(self):
        return 'wsgi.url_scheme' in self.environ \
            and self.environ['wsgi.url_scheme'] == 'https'

    def _load_post_and_files(self):
        # Populates self._post and self._files
        if self.method == 'POST':
            if self.environ.get('CONTENT_TYPE', '').startswith('multipart'):
                header_dict = dict([(k, v) for k, v in self.environ.items() if k.startswith('HTTP_')])
                header_dict['Content-Type'] = self.environ.get('CONTENT_TYPE', '')
                self._post, self._files = http.parse_file_upload(header_dict, self.raw_post_data)
            else:
                self._post, self._files = http.QueryDict(self.raw_post_data, encoding=self._encoding), datastructures.MultiValueDict()
        else:
            self._post, self._files = http.QueryDict('', encoding=self._encoding), datastructures.MultiValueDict()

    def _get_request(self):
        if not hasattr(self, '_request'):
            self._request = datastructures.MergeDict(self.POST, self.GET)
        return self._request

    def _get_get(self):
        if not hasattr(self, '_get'):
            # The WSGI spec says 'QUERY_STRING' may be absent.
            self._get = http.QueryDict(self.environ.get('QUERY_STRING', ''), encoding=self._encoding)
        return self._get

    def _set_get(self, get):
        self._get = get

    def _get_post(self):
        if not hasattr(self, '_post'):
            self._load_post_and_files()
        return self._post

    def _set_post(self, post):
        self._post = post

    def _get_cookies(self):
        if not hasattr(self, '_cookies'):
            self._cookies = http.parse_cookie(self.environ.get('HTTP_COOKIE', ''))
        return self._cookies

    def _set_cookies(self, cookies):
        self._cookies = cookies

    def _get_files(self):
        if not hasattr(self, '_files'):
            self._load_post_and_files()
        return self._files

    def _get_raw_post_data(self):
        try:
            return self._raw_post_data
        except AttributeError:
            buf = StringIO()
            try:
                # CONTENT_LENGTH might be absent if POST doesn't have content at all (lighttpd)
                content_length = int(self.environ.get('CONTENT_LENGTH', 0))
            except ValueError: # if CONTENT_LENGTH was empty string or not an integer
                content_length = 0
            safe_copyfileobj(self.environ['wsgi.input'], buf, size=content_length)
            self._raw_post_data = buf.getvalue()
            buf.close()
            return self._raw_post_data

    GET = property(_get_get, _set_get)
    POST = property(_get_post, _set_post)
    COOKIES = property(_get_cookies, _set_cookies)
    FILES = property(_get_files)
    REQUEST = property(_get_request)
    raw_post_data = property(_get_raw_post_data)

class WSGIHandler(BaseHandler):
    initLock = Lock()

    def __call__(self, environ, start_response):
        from django.conf import settings

        # Set up middleware if needed. We couldn't do this earlier, because
        # settings weren't available.
        if self._request_middleware is None:
            self.initLock.acquire()
            # Check that middleware is still uninitialised.
            if self._request_middleware is None:
                self.load_middleware()
            self.initLock.release()

        dispatcher.send(signal=signals.request_started)
        try:
            request = WSGIRequest(environ)
            response = self.get_response(request)

            # Apply response middleware
            for middleware_method in self._response_middleware:
                response = middleware_method(request, response)

        finally:
            dispatcher.send(signal=signals.request_finished)

        try:
            status_text = STATUS_CODE_TEXT[response.status_code]
        except KeyError:
            status_text = 'UNKNOWN STATUS CODE'
        status = '%s %s' % (response.status_code, status_text)
        response_headers = [(str(k), str(v)) for k, v in response.items()]
        for c in response.cookies.values():
            response_headers.append(('Set-Cookie', str(c.output(header=''))))
        start_response(status, response_headers)
        return response
<|endoftext|>


<commit_before>'''
synbiochem (c) University of Manchester 2016

synbiochem is licensed under the MIT License.

To view a copy of this license, visit <http://opensource.org/licenses/MIT/>.

@author:  neilswainston
'''
# pylint: disable=no-member
from synbiochem.utils import dna_utils
from synbiochem.utils.ice_utils import ICEClient, ICEEntry

class ICEInterface(object):
    '''Class to inferface with ICE.'''

    def __init__(self, url, username, psswrd):
        self.__ice_client = ICEClient(url, username, psswrd)

    def get_dna(self, ice_id):
        '''Gets DNA object from ICE.'''
        return self.__ice_client.get_dna(ice_id)

    def submit(self, designs):
        '''Writes plasmids and dominoes to ICE.'''
        for design in designs:
            self.__write_plasmid(design)
            self.__write_dominoes(design)

    def __write_plasmid(self, design):
        '''Writes plasmids to ICE.'''
        ice_entry = ICEEntry(typ='PLASMID')
        self.__ice_client.set_ice_entry(ice_entry)
        design['ice_id'] = ice_entry.get_ice_id()

        _set_metadata(ice_entry, design['name'], ' '.join(design['design']),
                      'PLASMID')

        ice_entry.set_dna(design['plasmid'])
        self.__ice_client.set_ice_entry(ice_entry)

    def __write_dominoes(self, design):
        '''Writes dominoes to ICE, or retrieves them if pre-existing.'''
        seq_entries = {}

        for domino in design['dominoes']:
            seq = domino[1][0][0] + domino[1][1][0]

            if seq in seq_entries:
                ice_entry = seq_entries[seq]
            else:
                ice_entries = self.__ice_client.get_ice_entries_by_seq(seq)

                if len(ice_entries) == 0:
                    dna = _get_domino_dna('name', seq, domino[1][0][0],
                                          domino[1][1][0])
                    ice_entry = ICEEntry(dna, 'PART')
                else:
                    ice_entry = ice_entries[0]

            name, description = self.__get_metadata(ice_entry, domino[0])
            _set_metadata(ice_entry, name, description, 'DOMINO')
            self.__ice_client.set_ice_entry(ice_entry)

            self.__ice_client.add_link(
                design['ice_id'], ice_entry.get_ice_id())

            seq_entries[seq] = ice_entry

    def __get_metadata(self, ice_entry, part_ids):
        '''Gets metadata for a domino.'''
        metadata = ice_entry.get_metadata()

        # Set name if necessary:
        name = metadata['name'] if 'name' in metadata \
            else ' - '.join([self.__ice_client.get_ice_entry(prt_id).get_name()
                             for prt_id in part_ids])

        # Update Designs and Pairs in description:
        pairs = metadata['shortDescription'].split(', ') \
            if 'shortDescription' in metadata else []
        pairs.append('_'.join(part_ids))
        description = ', '.join(list(set(pairs)))

        return name, description

def _get_domino_dna(name, seq, left_subseq, right_subseq):
    '''Creates a DNA object representing a domino.'''
    dna = dna_utils.DNA(name=name, seq=seq)

    # Add annotations:
    dna.features.append(dna_utils.DNA(name='Left', start=1,
                                      end=len(left_subseq), forward=True))

    dna.features.append(dna_utils.DNA(name='Right', start=len(left_subseq) + 1,
                                      end=len(left_subseq) + len(right_subseq),
                                      forward=True))

    return dna

def _set_metadata(ice_entry, name, description, typ):
    '''Sets key metadata values for ICE entry.'''
    ice_entry.set_value('name', name)
    ice_entry.set_value('status', 'Complete')
    ice_entry.set_value('creator', 'SYNBIOCHEM')
    ice_entry.set_value('creatorEmail', 'support@synbiochem.co.uk')
    ice_entry.set_value('principalInvestigator', 'SYNBIOCHEM')
    ice_entry.set_value(
        'principalInvestigatorEmail', 'support@synbiochem.co.uk')
    ice_entry.set_value('shortDescription', description)
    ice_entry.set_value('parameters', [{'name': 'Type',
                                        'value': typ}])
<commit_msg>Added links between plasmids and parts.<commit_after>'''
synbiochem (c) University of Manchester 2016

synbiochem is licensed under the MIT License.

To view a copy of this license, visit <http://opensource.org/licenses/MIT/>.

@author:  neilswainston
'''
# pylint: disable=no-member
from synbiochem.utils import dna_utils
from synbiochem.utils.ice_utils import ICEClient, ICEEntry

class ICEInterface(object):
    '''Class to inferface with ICE.'''

    def __init__(self, url, username, psswrd):
        self.__ice_client = ICEClient(url, username, psswrd)

    def get_dna(self, ice_id):
        '''Gets DNA object from ICE.'''
        return self.__ice_client.get_dna(ice_id)

    def submit(self, designs):
        '''Writes plasmids and dominoes to ICE.'''
        for design in designs:
            self.__write_plasmid(design)
            self.__write_dominoes(design)

    def __write_plasmid(self, design):
        '''Writes plasmids to ICE.'''
        ice_entry = ICEEntry(typ='PLASMID')
        self.__ice_client.set_ice_entry(ice_entry)
        design['ice_id'] = ice_entry.get_ice_id()

        _set_metadata(ice_entry, design['name'], ' '.join(design['design']),
                      'PLASMID')

        ice_entry.set_dna(design['plasmid'])
        self.__ice_client.set_ice_entry(ice_entry)

        # Add link from plasmid -> parts:
        for part_id in design['design']:
            self.__ice_client.add_link(design['ice_id'], part_id)

    def __write_dominoes(self, design):
        '''Writes dominoes to ICE, or retrieves them if pre-existing.'''
        seq_entries = {}

        for domino in design['dominoes']:
            seq = domino[1][0][0] + domino[1][1][0]

            if seq in seq_entries:
                ice_entry = seq_entries[seq]
            else:
                ice_entries = self.__ice_client.get_ice_entries_by_seq(seq)

                if len(ice_entries) == 0:
                    dna = _get_domino_dna('name', seq, domino[1][0][0],
                                          domino[1][1][0])
                    ice_entry = ICEEntry(dna, 'PART')
                else:
                    ice_entry = ice_entries[0]

            name, description = self.__get_metadata(ice_entry, domino[0])
            _set_metadata(ice_entry, name, description, 'DOMINO')
            self.__ice_client.set_ice_entry(ice_entry)

            # Add link from plasmid -> domino:
            self.__ice_client.add_link(
                design['ice_id'], ice_entry.get_ice_id())

            seq_entries[seq] = ice_entry

    def __get_metadata(self, ice_entry, part_ids):
        '''Gets metadata for a domino.'''
        metadata = ice_entry.get_metadata()

        # Set name if necessary:
        name = metadata['name'] if 'name' in metadata \
            else ' - '.join([self.__ice_client.get_ice_entry(prt_id).get_name()
                             for prt_id in part_ids])

        # Update Designs and Pairs in description:
        pairs = metadata['shortDescription'].split(', ') \
            if 'shortDescription' in metadata else []
        pairs.append('_'.join(part_ids))
        description = ', '.join(list(set(pairs)))

        return name, description

def _get_domino_dna(name, seq, left_subseq, right_subseq):
    '''Creates a DNA object representing a domino.'''
    dna = dna_utils.DNA(name=name, seq=seq)

    # Add annotations:
    dna.features.append(dna_utils.DNA(name='Left', start=1,
                                      end=len(left_subseq), forward=True))

    dna.features.append(dna_utils.DNA(name='Right', start=len(left_subseq) + 1,
                                      end=len(left_subseq) + len(right_subseq),
                                      forward=True))

    return dna

def _set_metadata(ice_entry, name, description, typ):
    '''Sets key metadata values for ICE entry.'''
    ice_entry.set_value('name', name)
    ice_entry.set_value('status', 'Complete')
    ice_entry.set_value('creator', 'SYNBIOCHEM')
    ice_entry.set_value('creatorEmail', 'support@synbiochem.co.uk')
    ice_entry.set_value('principalInvestigator', 'SYNBIOCHEM')
    ice_entry.set_value(
        'principalInvestigatorEmail', 'support@synbiochem.co.uk')
    ice_entry.set_value('shortDescription', description)
    ice_entry.set_value('parameters', [{'name': 'Type',
                                        'value': typ}])
<|endoftext|>