<commit_before>"""
Thorough tests of the Location class
"""
import ddt

from unittest import TestCase
from opaque_keys import InvalidKeyError
from opaque_keys.edx.locations import Location, AssetLocation, SlashSeparatedCourseKey
from opaque_keys.edx.keys import UsageKey, CourseKey, AssetKey

# Pairs for testing the clean* functions.
# The first item in the tuple is the input string.
# The second item in the tuple is what the result of
# replacement should be.
GENERAL_PAIRS = [
    ('', ''),
    (' ', '_'),
    ('abc,', 'abc_'),
    ('ab    fg!@//\\aj', 'ab_fg_aj'),
    (u"ab\xA9", "ab_"),  # no unicode allowed for now
]

@ddt.ddt
class TestLocations(TestCase):
    """
    Tests of :class:`.Location`
    """
    @ddt.data(
        "location:org+course+run+category+name",
        "location:org+course+run+category+name@revision",
        "i4x://org/course/category/name",
        "i4x://org/course/category/name@draft",
        # now try the extended char sets
        "location:org.dept%sub-prof+course.num%section-4+run.hour%min-99+category+name:12%33-44",
        "i4x://org.dept%sub-prof/course.num%section-4/category/name:12%33-44",
    )
    def test_string_roundtrip(self, url):
        self.assertEquals(url, unicode(UsageKey.from_string(url)))

    @ddt.data(
        "i4x://org/course/category/name",
        "i4x://org/course/category/name@revision"
    )
    def test_deprecated_roundtrip(self, url):
        self.assertEquals(
            url,
            unicode(UsageKey.from_string(url))
        )

    @ddt.data(
        "foo/bar/baz",
    )
    def test_deprecated_roundtrip_for_ssck(self, course_id):
        self.assertEquals(
            course_id,
            unicode(CourseKey.from_string(course_id))
        )

    @ddt.data(
        "foo+bar+baz",
    )
    def test_new_roundtrip_for_ssck(self, course_id):
        course_key = SlashSeparatedCourseKey("foo", "bar", "baz")
        self.assertEquals(
            course_id,
            course_key._to_string()  # pylint: disable=protected-access
        )

    @ddt.data(
        "/c4x/org/course/asset/path",
    )
    def test_deprecated_round_trip_asset_location(self, path):
        self.assertEquals(
            path,
            unicode(AssetKey.from_string(path)),
        )

    def test_invalid_chars_ssck(self):
        """
        Test that the ssck constructor fails if given invalid chars
        """
        valid_base = SlashSeparatedCourseKey(u'org.dept-1%2', u'course.sub-2%3', u'run.faster-4%5')
        for key in SlashSeparatedCourseKey.KEY_FIELDS:
            with self.assertRaises(InvalidKeyError):
                # this ends up calling the constructor where the legality check should occur
                valid_base.replace(**{key: u'funny thing'})

    def test_invalid_chars_location(self):
        """
        Test that the location constructor fails if given invalid chars
        """
        course_key = SlashSeparatedCourseKey(u'org.dept-1%2', u'course.sub-2%3', u'run.faster-4%5')
        valid_base = course_key.make_usage_key('tomato-again%9', 'block-head:sub-4%9')
        for key in SlashSeparatedCourseKey.KEY_FIELDS:
            with self.assertRaises(InvalidKeyError):
                # this ends up calling the constructor where the legality check should occur
                valid_base.replace(**{key: u'funny thing'})

    @ddt.data(
        ((), {
            'org': 'org',
            'course': 'course',
            'run': 'run',
            'category': 'category',
            'name': 'name',
        }, 'org', 'course', 'run', 'category', 'name', None),
        ((), {
            'org': 'org',
            'course': 'course',
            'run': 'run',
            'category': 'category',
            'name': 'name:more_name',
        }, 'org', 'course', 'run', 'category', 'name:more_name', None),
        (['org', 'course', 'run', 'category', 'name'], {}, 'org', 'course', 'run', 'category', 'name', None),
    )
    @ddt.unpack
    def test_valid_locations(self, args, kwargs, org, course, run, category, name, revision):
        location = Location(*args, **kwargs)
        self.assertEquals(org, location.org)
        self.assertEquals(course, location.course)
        self.assertEquals(run, location.run)
        self.assertEquals(category, location.category)
        self.assertEquals(name, location.name)
        self.assertEquals(revision, location.revision)

    @ddt.data(
        (("foo",), {}),
        (["foo", "bar"], {}),
        (["foo", "bar", "baz", "blat/blat", "foo"], {}),
        (["foo", "bar", "baz", "blat", "foo/bar"], {}),
        (["foo", "bar", "baz", "blat:blat", "foo:bar"], {}),  # ':' ok in name, not in category
        (('org', 'course', 'run', 'category', 'name with spaces', 'revision'), {}),
        (('org', 'course', 'run', 'category', 'name/with/slashes', 'revision'), {}),
        (('org', 'course', 'run', 'category', 'name', u'\xae'), {}),
        (('org', 'course', 'run', 'category', u'\xae', 'revision'), {}),
        ((), {
            'tag': 'tag',
            'course': 'course',
            'category': 'category',
            'name': 'name@more_name',
            'org': 'org'
        }),
        ((), {
            'tag': 'tag',
            'course': 'course',
            'category': 'category',
            'name': 'name ',   # extra space
            'org': 'org'
        }),
    )
    @ddt.unpack
    def test_invalid_locations(self, *args, **kwargs):
        with self.assertRaises(TypeError):
            Location(*args, **kwargs)

    def test_equality(self):
        self.assertEquals(
            Location('tag', 'org', 'course', 'run', 'category', 'name'),
            Location('tag', 'org', 'course', 'run', 'category', 'name')
        )

        self.assertNotEquals(
            Location('tag', 'org', 'course', 'run', 'category', 'name1'),
            Location('tag', 'org', 'course', 'run', 'category', 'name')
        )

    @ddt.data(
        ('a:b', 'a_b'),  # no colons in non-name components
        ('a-b', 'a-b'),  # dashes ok
        ('a.b', 'a.b'),  # dot ok
        *GENERAL_PAIRS
    )
    def test_clean(self, pair):
        self.assertEquals(Location.clean(pair[0]), pair[1])

    @ddt.data(
        ('a:b', 'a:b'),  # colons ok in names
        ('a-b', 'a-b'),  # dashes ok in names
        ('a.b', 'a.b'),  # dot ok in names
        *GENERAL_PAIRS
    )
    def test_clean_for_url_name(self, pair):
        self.assertEquals(Location.clean_for_url_name(pair[0]), pair[1])

    @ddt.data(
        ("a:b", "a_b"),   # no colons for html use
        ("a-b", "a-b"),   # dashes ok (though need to be replaced in various use locations. ugh.)
        ('a.b', 'a_b'),   # no dots.
        *GENERAL_PAIRS
    )
    def test_clean_for_html(self, pair):
        self.assertEquals(Location.clean_for_html(pair[0]), pair[1])

    def test_html_id(self):
        loc = Location('org', 'course', 'run', 'cat', 'name:more_name', 'rev')
        self.assertEquals(loc.html_id(), "location:org+course+run+cat+name:more_name@rev")

    def test_deprecated_html_id(self):
        loc = Location('org', 'course', 'run', 'cat', 'name:more_name', 'rev', deprecated=True)
        self.assertEquals(loc.html_id(), "i4x-org-course-cat-name_more_name-rev")

    def test_replacement(self):
        # pylint: disable=protected-access

        self.assertEquals(
            Location('o', 'c', 'r', 'c', 'n', 'r').replace(name='new_name'),
            Location('o', 'c', 'r', 'c', 'new_name', 'r'),
        )

        with self.assertRaises(InvalidKeyError):
            Location('o', 'c', 'r', 'c', 'n', 'r').replace(name=u'name\xae')

    @ddt.data('org', 'course', 'category', 'name', 'revision')
    def test_immutable(self, attr):
        loc = Location('o', 'c', 'r', 'c', 'n', 'r')
        with self.assertRaises(AttributeError):
            setattr(loc, attr, attr)

    def test_map_into_course_location(self):
        loc = Location('org', 'course', 'run', 'cat', 'name:more_name', 'rev')
        course_key = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")
        self.assertEquals(
            Location("edX", "toy", "2012_Fall", 'cat', 'name:more_name', 'rev'),
            loc.map_into_course(course_key)
        )

    def test_map_into_course_asset_location(self):
        loc = AssetLocation('org', 'course', 'run', 'asset', 'foo.bar')
        course_key = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")
        self.assertEquals(
            AssetLocation("edX", "toy", "2012_Fall", 'asset', 'foo.bar'),
            loc.map_into_course(course_key)
        )
<commit_msg>Add tests of Location deprecated son code<commit_after>"""
Thorough tests of the Location class
"""
import ddt

from unittest import TestCase
from opaque_keys import InvalidKeyError
from opaque_keys.edx.locations import Location, AssetLocation, SlashSeparatedCourseKey
from opaque_keys.edx.keys import UsageKey, CourseKey, AssetKey

# Pairs for testing the clean* functions.
# The first item in the tuple is the input string.
# The second item in the tuple is what the result of
# replacement should be.
GENERAL_PAIRS = [
    ('', ''),
    (' ', '_'),
    ('abc,', 'abc_'),
    ('ab    fg!@//\\aj', 'ab_fg_aj'),
    (u"ab\xA9", "ab_"),  # no unicode allowed for now
]

@ddt.ddt
class TestLocations(TestCase):
    """
    Tests of :class:`.Location`
    """
    @ddt.data(
        "location:org+course+run+category+name",
        "location:org+course+run+category+name@revision",
        "i4x://org/course/category/name",
        "i4x://org/course/category/name@draft",
        # now try the extended char sets
        "location:org.dept%sub-prof+course.num%section-4+run.hour%min-99+category+name:12%33-44",
        "i4x://org.dept%sub-prof/course.num%section-4/category/name:12%33-44",
    )
    def test_string_roundtrip(self, url):
        self.assertEquals(url, unicode(UsageKey.from_string(url)))

    @ddt.data(
        "i4x://org/course/category/name",
        "i4x://org/course/category/name@revision"
    )
    def test_deprecated_roundtrip(self, url):
        self.assertEquals(
            url,
            unicode(UsageKey.from_string(url))
        )

    @ddt.data(
        "foo/bar/baz",
    )
    def test_deprecated_roundtrip_for_ssck(self, course_id):
        self.assertEquals(
            course_id,
            unicode(CourseKey.from_string(course_id))
        )

    @ddt.data(
        "foo+bar+baz",
    )
    def test_new_roundtrip_for_ssck(self, course_id):
        course_key = SlashSeparatedCourseKey("foo", "bar", "baz")
        self.assertEquals(
            course_id,
            course_key._to_string()  # pylint: disable=protected-access
        )

    @ddt.data(
        "/c4x/org/course/asset/path",
    )
    def test_deprecated_round_trip_asset_location(self, path):
        self.assertEquals(
            path,
            unicode(AssetKey.from_string(path)),
        )

    def test_invalid_chars_ssck(self):
        """
        Test that the ssck constructor fails if given invalid chars
        """
        valid_base = SlashSeparatedCourseKey(u'org.dept-1%2', u'course.sub-2%3', u'run.faster-4%5')
        for key in SlashSeparatedCourseKey.KEY_FIELDS:
            with self.assertRaises(InvalidKeyError):
                # this ends up calling the constructor where the legality check should occur
                valid_base.replace(**{key: u'funny thing'})

    def test_invalid_chars_location(self):
        """
        Test that the location constructor fails if given invalid chars
        """
        course_key = SlashSeparatedCourseKey(u'org.dept-1%2', u'course.sub-2%3', u'run.faster-4%5')
        valid_base = course_key.make_usage_key('tomato-again%9', 'block-head:sub-4%9')
        for key in SlashSeparatedCourseKey.KEY_FIELDS:
            with self.assertRaises(InvalidKeyError):
                # this ends up calling the constructor where the legality check should occur
                valid_base.replace(**{key: u'funny thing'})

    @ddt.data(
        ((), {
            'org': 'org',
            'course': 'course',
            'run': 'run',
            'category': 'category',
            'name': 'name',
        }, 'org', 'course', 'run', 'category', 'name', None),
        ((), {
            'org': 'org',
            'course': 'course',
            'run': 'run',
            'category': 'category',
            'name': 'name:more_name',
        }, 'org', 'course', 'run', 'category', 'name:more_name', None),
        (['org', 'course', 'run', 'category', 'name'], {}, 'org', 'course', 'run', 'category', 'name', None),
    )
    @ddt.unpack
    def test_valid_locations(self, args, kwargs, org, course, run, category, name, revision):
        location = Location(*args, **kwargs)
        self.assertEquals(org, location.org)
        self.assertEquals(course, location.course)
        self.assertEquals(run, location.run)
        self.assertEquals(category, location.category)
        self.assertEquals(name, location.name)
        self.assertEquals(revision, location.revision)

    @ddt.data(
        (("foo",), {}),
        (["foo", "bar"], {}),
        (["foo", "bar", "baz", "blat/blat", "foo"], {}),
        (["foo", "bar", "baz", "blat", "foo/bar"], {}),
        (["foo", "bar", "baz", "blat:blat", "foo:bar"], {}),  # ':' ok in name, not in category
        (('org', 'course', 'run', 'category', 'name with spaces', 'revision'), {}),
        (('org', 'course', 'run', 'category', 'name/with/slashes', 'revision'), {}),
        (('org', 'course', 'run', 'category', 'name', u'\xae'), {}),
        (('org', 'course', 'run', 'category', u'\xae', 'revision'), {}),
        ((), {
            'tag': 'tag',
            'course': 'course',
            'category': 'category',
            'name': 'name@more_name',
            'org': 'org'
        }),
        ((), {
            'tag': 'tag',
            'course': 'course',
            'category': 'category',
            'name': 'name ',   # extra space
            'org': 'org'
        }),
    )
    @ddt.unpack
    def test_invalid_locations(self, *args, **kwargs):
        with self.assertRaises(TypeError):
            Location(*args, **kwargs)

    def test_equality(self):
        self.assertEquals(
            Location('tag', 'org', 'course', 'run', 'category', 'name'),
            Location('tag', 'org', 'course', 'run', 'category', 'name')
        )

        self.assertNotEquals(
            Location('tag', 'org', 'course', 'run', 'category', 'name1'),
            Location('tag', 'org', 'course', 'run', 'category', 'name')
        )

    @ddt.data(
        ('a:b', 'a_b'),  # no colons in non-name components
        ('a-b', 'a-b'),  # dashes ok
        ('a.b', 'a.b'),  # dot ok
        *GENERAL_PAIRS
    )
    def test_clean(self, pair):
        self.assertEquals(Location.clean(pair[0]), pair[1])

    @ddt.data(
        ('a:b', 'a:b'),  # colons ok in names
        ('a-b', 'a-b'),  # dashes ok in names
        ('a.b', 'a.b'),  # dot ok in names
        *GENERAL_PAIRS
    )
    def test_clean_for_url_name(self, pair):
        self.assertEquals(Location.clean_for_url_name(pair[0]), pair[1])

    @ddt.data(
        ("a:b", "a_b"),   # no colons for html use
        ("a-b", "a-b"),   # dashes ok (though need to be replaced in various use locations. ugh.)
        ('a.b', 'a_b'),   # no dots.
        *GENERAL_PAIRS
    )
    def test_clean_for_html(self, pair):
        self.assertEquals(Location.clean_for_html(pair[0]), pair[1])

    def test_html_id(self):
        loc = Location('org', 'course', 'run', 'cat', 'name:more_name', 'rev')
        self.assertEquals(loc.html_id(), "location:org+course+run+cat+name:more_name@rev")

    def test_deprecated_html_id(self):
        loc = Location('org', 'course', 'run', 'cat', 'name:more_name', 'rev', deprecated=True)
        self.assertEquals(loc.html_id(), "i4x-org-course-cat-name_more_name-rev")

    def test_replacement(self):
        # pylint: disable=protected-access

        self.assertEquals(
            Location('o', 'c', 'r', 'c', 'n', 'r').replace(name='new_name'),
            Location('o', 'c', 'r', 'c', 'new_name', 'r'),
        )

        with self.assertRaises(InvalidKeyError):
            Location('o', 'c', 'r', 'c', 'n', 'r').replace(name=u'name\xae')

    @ddt.data('org', 'course', 'category', 'name', 'revision')
    def test_immutable(self, attr):
        loc = Location('o', 'c', 'r', 'c', 'n', 'r')
        with self.assertRaises(AttributeError):
            setattr(loc, attr, attr)

    def test_map_into_course_location(self):
        loc = Location('org', 'course', 'run', 'cat', 'name:more_name', 'rev')
        course_key = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")
        self.assertEquals(
            Location("edX", "toy", "2012_Fall", 'cat', 'name:more_name', 'rev'),
            loc.map_into_course(course_key)
        )

    def test_map_into_course_asset_location(self):
        loc = AssetLocation('org', 'course', 'run', 'asset', 'foo.bar')
        course_key = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")
        self.assertEquals(
            AssetLocation("edX", "toy", "2012_Fall", 'asset', 'foo.bar'),
            loc.map_into_course(course_key)
        )

    SON_KEYS = ('tag', 'org', 'course', 'category', 'name', 'revision')

    @ddt.data(
        (Location, '_id.', 'i4x', ('o', 'c', 'r', 'ct', 'n', 'v')),
        (Location, '', 'i4x', ('o', 'c', 'r', 'ct', 'n', 'v')),
        (AssetLocation, '_id.', 'c4x', ('o', 'c', 'r', 'ct', 'n', 'v')),
    )
    @ddt.unpack
    def test_to_deprecated_son(self, key_cls, prefix, tag, source):
        source_key = key_cls(*source)
        son = source_key.to_deprecated_son(prefix=prefix, tag=tag)
        self.assertEquals(son.keys(), [prefix + key for key in self.SON_KEYS])
        for key in self.SON_KEYS:
            if key == 'tag':
                self.assertEquals(son[prefix + key], tag)
            else:
                self.assertEquals(son[prefix + key], getattr(source_key, key))

    @ddt.data(
        Location('o', 'c', 'r', 'ct', 'n', None),
        Location('o', 'c', 'r', 'ct', 'n', 'v'),
        AssetLocation('o', 'c', 'r', 'ct', 'n', None),
        AssetLocation('o', 'c', 'r', 'ct', 'n', 'v'),
    )
    def test_deprecated_son_roundtrip(self, key):
        self.assertEquals(key, key.__class__._from_deprecated_son(key.to_deprecated_son(), key.run))<|endoftext|>


<commit_before># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 OpenStack, LLC
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import testtools

class TempestException(Exception):
    """
    Base Tempest Exception

    To correctly use this class, inherit from it and define
    a 'message' property. That message will get printf'd
    with the keyword arguments provided to the constructor.
    """
    message = "An unknown exception occurred"

    def __init__(self, *args, **kwargs):
        super(TempestException, self).__init__()
        try:
            self._error_string = self.message % kwargs
        except Exception:
            # at least get the core message out if something happened
            self._error_string = self.message
        if len(args) > 0:
            # If there is a non-kwarg parameter, assume it's the error
            # message or reason description and tack it on to the end
            # of the exception message
            # Convert all arguments into their string representations...
            args = ["%s" % arg for arg in args]
            self._error_string = (self._error_string +
                                  "\nDetails: %s" % '\n'.join(args))

    def __str__(self):
        return self._error_string

class InvalidConfiguration(TempestException):
    message = "Invalid Configuration"

class RestClientException(TempestException,
                          testtools.TestCase.failureException):
    pass

class NotFound(RestClientException):
    message = "Object not found"

class Unauthorized(RestClientException):
    message = 'Unauthorized'

class TimeoutException(TempestException):
    message = "Request timed out"

class BuildErrorException(TempestException):
    message = "Server %(server_id)s failed to build and is in ERROR status"

class AddImageException(TempestException):
    message = "Image %(image_id)s failed to become ACTIVE in the allotted time"

class EC2RegisterImageException(TempestException):
    message = ("Image %(image_id)s failed to become 'available' "
               "in the allotted time")

class VolumeBuildErrorException(TempestException):
    message = "Volume %(volume_id)s failed to build and is in ERROR status"

class SnapshotBuildErrorException(TempestException):
    message = "Snapshot %(snapshot_id)s failed to build and is in ERROR status"

class BadRequest(RestClientException):
    message = "Bad request"

class UnprocessableEntity(RestClientException):
    message = "Unprocessable entity"

class AuthenticationFailure(RestClientException):
    message = ("Authentication with user %(user)s and password "
               "%(password)s failed")

class EndpointNotFound(TempestException):
    message = "Endpoint not found"

class RateLimitExceeded(TempestException):
    message = ("Rate limit exceeded.\nMessage: %(message)s\n"
               "Details: %(details)s")

class OverLimit(TempestException):
    message = "Quota exceeded"

class ComputeFault(TempestException):
    message = "Got compute fault"

class ImageFault(TempestException):
    message = "Got image fault"

class IdentityError(TempestException):
    message = "Got identity error"

class Duplicate(RestClientException):
    message = "An object with that identifier already exists"

class SSHTimeout(TempestException):
    message = ("Connection to the %(host)s via SSH timed out.\n"
               "User: %(user)s, Password: %(password)s")

class SSHExecCommandFailed(TempestException):
    """Raised when remotely executed command returns nonzero status."""
    message = ("Command '%(command)s', exit status: %(exit_status)d, "
               "Error:\n%(strerror)s")

class ServerUnreachable(TempestException):
    message = "The server is not reachable via the configured network"

class SQLException(TempestException):
    message = "SQL error: %(message)s"

class TearDownException(TempestException):
    message = "%(num)d cleanUp operation failed"

class RFCViolation(RestClientException):
    message = "RFC Violation"

class ResponseWithNonEmptyBody(RFCViolation):
    message = ("RFC Violation! Response with %(status)d HTTP Status Code "
               "MUST NOT have a body")

class ResponseWithEntity(RFCViolation):
    message = ("RFC Violation! Response with 205 HTTP Status Code "
               "MUST NOT have an entity")
<commit_msg>A Heat client which does basic stack operations.<commit_after># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 OpenStack, LLC
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import testtools

class TempestException(Exception):
    """
    Base Tempest Exception

    To correctly use this class, inherit from it and define
    a 'message' property. That message will get printf'd
    with the keyword arguments provided to the constructor.
    """
    message = "An unknown exception occurred"

    def __init__(self, *args, **kwargs):
        super(TempestException, self).__init__()
        try:
            self._error_string = self.message % kwargs
        except Exception:
            # at least get the core message out if something happened
            self._error_string = self.message
        if len(args) > 0:
            # If there is a non-kwarg parameter, assume it's the error
            # message or reason description and tack it on to the end
            # of the exception message
            # Convert all arguments into their string representations...
            args = ["%s" % arg for arg in args]
            self._error_string = (self._error_string +
                                  "\nDetails: %s" % '\n'.join(args))

    def __str__(self):
        return self._error_string

class InvalidConfiguration(TempestException):
    message = "Invalid Configuration"

class RestClientException(TempestException,
                          testtools.TestCase.failureException):
    pass

class NotFound(RestClientException):
    message = "Object not found"

class Unauthorized(RestClientException):
    message = 'Unauthorized'

class TimeoutException(TempestException):
    message = "Request timed out"

class BuildErrorException(TempestException):
    message = "Server %(server_id)s failed to build and is in ERROR status"

class AddImageException(TempestException):
    message = "Image %(image_id)s failed to become ACTIVE in the allotted time"

class EC2RegisterImageException(TempestException):
    message = ("Image %(image_id)s failed to become 'available' "
               "in the allotted time")

class VolumeBuildErrorException(TempestException):
    message = "Volume %(volume_id)s failed to build and is in ERROR status"

class SnapshotBuildErrorException(TempestException):
    message = "Snapshot %(snapshot_id)s failed to build and is in ERROR status"

class StackBuildErrorException(TempestException):
    message = ("Stack %(stack_identifier)s is in %(stack_status)s status "
               "due to '%(stack_status_reason)s'")

class BadRequest(RestClientException):
    message = "Bad request"

class UnprocessableEntity(RestClientException):
    message = "Unprocessable entity"

class AuthenticationFailure(RestClientException):
    message = ("Authentication with user %(user)s and password "
               "%(password)s failed")

class EndpointNotFound(TempestException):
    message = "Endpoint not found"

class RateLimitExceeded(TempestException):
    message = ("Rate limit exceeded.\nMessage: %(message)s\n"
               "Details: %(details)s")

class OverLimit(TempestException):
    message = "Quota exceeded"

class ComputeFault(TempestException):
    message = "Got compute fault"

class ImageFault(TempestException):
    message = "Got image fault"

class IdentityError(TempestException):
    message = "Got identity error"

class Duplicate(RestClientException):
    message = "An object with that identifier already exists"

class SSHTimeout(TempestException):
    message = ("Connection to the %(host)s via SSH timed out.\n"
               "User: %(user)s, Password: %(password)s")

class SSHExecCommandFailed(TempestException):
    """Raised when remotely executed command returns nonzero status."""
    message = ("Command '%(command)s', exit status: %(exit_status)d, "
               "Error:\n%(strerror)s")

class ServerUnreachable(TempestException):
    message = "The server is not reachable via the configured network"

class SQLException(TempestException):
    message = "SQL error: %(message)s"

class TearDownException(TempestException):
    message = "%(num)d cleanUp operation failed"

class RFCViolation(RestClientException):
    message = "RFC Violation"

class ResponseWithNonEmptyBody(RFCViolation):
    message = ("RFC Violation! Response with %(status)d HTTP Status Code "
               "MUST NOT have a body")

class ResponseWithEntity(RFCViolation):
    message = ("RFC Violation! Response with 205 HTTP Status Code "
               "MUST NOT have an entity")
<|endoftext|>


<commit_before># Create your views here.
from django.views.generic import DetailView
from cbv.models import Klass, Module, ProjectVersion
from django.http import HttpResponse,HttpResponseRedirect
from pprint import pformat,pprint

class KlassDetailView(DetailView):
    model = Klass

    def get_queryset(self):
        return super(DetailView, self).get_queryset().select_related()

    def get_object(self):
        return self.model.objects.get(
            name__iexact=self.kwargs['klass'],
            module__name__iexact=self.kwargs['module'],
            module__project_version__version_number__iexact=self.kwargs['version'],
            module__project_version__project__name__iexact=self.kwargs['package'],
        )

class ModuleDetailView(DetailView):
    model = Module
    push_state_url = None

    def get_object(self):
        try:
            return self.model.objects.get(
                name=self.kwargs['module'],
                project_version__version_number=self.kwargs['version'],
                project_version__project__name=self.kwargs['package'],
            )
        except self.model.DoesNotExist:
            obj = self.model.objects.get(
                name__iexact=self.kwargs['module'],
                project_version__version_number__iexact=self.kwargs['version'],
                project_version__project__name__iexact=self.kwargs['package'],
            )
            self.push_state_url = obj.get_absolute_url()
            return obj

    def get_context_data(self, **kwargs):
        context = super(ModuleDetailView, self).get_context_data(**kwargs)
        context['push_state_url'] = self.push_state_url
        return context

class VersionDetailView(DetailView):
    model = ProjectVersion

    def get_object(self):
        return self.model.objects.get(
            version_number__iexact=self.kwargs['version'],
            project__name__iexact=self.kwargs['package'],
        )
<commit_msg>Separate the fuzzy matching into a mixin.<commit_after># Create your views here.
from django.views.generic import DetailView
from cbv.models import Klass, Module, ProjectVersion
from django.http import HttpResponse,HttpResponseRedirect
from pprint import pformat,pprint

class FuzzySingleObjectMixin(SingleObjectMixin):

    def get_object(self, queryset=None):
        try:
            return self.get_precise_object(queryset)
        except self.model.DoesNotExist:
            obj = self.get_fuzzy_object(queryset)
            self.push_state_url = obj.get_absolute_url()
            return obj

    def get_context_data(self, **kwargs):
        context = super(ModuleDetailView, self).get_context_data(**kwargs)
        context['push_state_url'] = self.push_state_url
        return context

class KlassDetailView(DetailView):
    model = Klass

    def get_queryset(self):
        return super(DetailView, self).get_queryset().select_related()

    def get_object(self):
        return self.model.objects.get(
            name__iexact=self.kwargs['klass'],
            module__name__iexact=self.kwargs['module'],
            module__project_version__version_number__iexact=self.kwargs['version'],
            module__project_version__project__name__iexact=self.kwargs['package'],
        )

class ModuleDetailView(FuzzySingleObjectMixin, DetailView):
    model = Module
    push_state_url = None

    def get_precise_object(self, queryset=None):
        return self.model.objects.get(
            name=self.kwargs['module'],
            project_version__version_number=self.kwargs['version'],
            project_version__project__name=self.kwargs['package'],
        )

    def get_fuzzy_object(self, queryset=None):
        return self.model.objects.get(
            name__iexact=self.kwargs['module'],
            project_version__version_number__iexact=self.kwargs['version'],
            project_version__project__name__iexact=self.kwargs['package'],
        )

class VersionDetailView(DetailView):
    model = ProjectVersion

    def get_object(self):
        return self.model.objects.get(
            version_number__iexact=self.kwargs['version'],
            project__name__iexact=self.kwargs['package'],
        )
<|endoftext|>


<commit_before>from AppKit import *

import os

import vanilla.dialogs as dialogs
import vanilla

from mojo.events import addObserver
from mojo.UI import OpenGlyphWindow, OpenSpaceCenter, CurrentSpaceCenterWindow, OutputWindow

from lib.scripting.scriptTools import ScriptRunner
from lib.scripting.codeEditor import CodeEditor
from lib.baseObjects import CallbackWrapper

from plistlib import readPlist, writePlist

def OpenRoboFontProject(path):
    root = os.path.dirname(path)
    project = readPlist(path)

    documentController = NSDocumentController.sharedDocumentController()
    delegate = NSApp().delegate()

    openFileNames = [window.representedFilename() for window in NSApp().windows()]

    for fileName, data in project["documents"].items():

        isUntitled = fileName == "untitled"

        if not isUntitled:
            if not os.path.exists(fileName):
                fileName = os.path.abspath(os.path.join(root, fileName))

            if not os.path.exists(fileName):
                continue

            if fileName in openFileNames:
                continue

        data.sort(key=lambda item: item.get("name") != "FontWindow")

        for windowData in data:
            name = windowData["windowName"]
            x, y, w, h = windowData["frame"]

            if isUntitled:
                if name == "FontWindow":
                    RFont()
                elif name == "ScriptingWindow":
                    delegate.scriptingWindow_(None)
                elif name == "FeatureWindow":
                    delegate.newFeature_(None)

            else:
                url = NSURL.fileURLWithPath_(fileName)
                doc, error = documentController.openDocumentWithContentsOfURL_display_error_(url, True, None)
                if error:
                    delegate.application_openFile_(NSApp(), fileName)

            window = NSApp().mainWindow()

            vanillaWrapper = None
            if hasattr(window.delegate(), "vanillaWrapper"):
                vanillaWrapper = window.delegate().vanillaWrapper()

            if vanillaWrapper:
                font = CurrentFont()
                if name == "GlyphWindow":
                    window = OpenGlyphWindow(font[windowData["glyphName"]], newWindow=True)
                    window.w.getNSWindow().setFrame_display_animate_(((x, y), (w, h)), True, False)
                    continue

                elif name == "SpaceCenter":
                    spaceCenter = OpenSpaceCenter(font)
                    spaceCenter.setPointSize(windowData["pointSize"])
                    spaceCenter.setPre(windowData["pre"])
                    spaceCenter.setAfter(windowData["after"])
                    spaceCenter.set(windowData["input"])

                    window = CurrentSpaceCenterWindow()
                    window.w.getNSWindow().setFrame_display_animate_(((x, y), (w, h)), True, False)
                    continue

            window.setFrame_display_animate_(((x, y), (w, h)), True, False)

    for windowData in project["toolWindows"]:
        name = windowData["windowName"]
        x, y, w, h = windowData["frame"]

        if name == "DebugWindow":
            window = OutputWindow()
            window.show()
            window.w.getNSWindow().setFrame_display_animate_(((x, y), (w, h)), True, False)

        elif name == "InspectorWindow":
            try:
                # a little bit hacky
                # will move to mojo.UI in the upcoming releases
                window = delegate._inspectorWindow.w.getNSWindow()
            except:
                window = None
            if window is None:
                delegate.openInspector_(None)
                window = delegate._inspectorWindow.w.getNSWindow()
            window.setFrame_display_animate_(((x, y), (w, h)), True, False)

    if "execute" in project:
        try:
            ScriptRunner(text=project["execute"])
        except:
            import traceback
            print(traceback.format_exc(5))

class SaveRoboFontProject(object):

    def __init__(self):
        w, h = 550, 250
        self.view = vanilla.Group((0, 0, w, h))
        self.view.relative = vanilla.CheckBox((0, 3, 300, 22), "Use Relative Paths")
        self.view.info = vanilla.TextBox((0, 33, 300, 22), "Execute on load:")
        self.view.editor = CodeEditor((0, 60, w, h-70))

        view = self.view.getNSView()
        view.setFrame_(((0, 0), (w, h)))

        path = dialogs.putFile("Save RoboFont Project..", fileTypes=["roboFontProject"], accessoryView=view)

        if path:
            data = self.getData(path)

            writePlist(data, path)

            icon = NSImage.alloc().initByReferencingFile_(os.path.join(os.path.dirname(__file__), "roboFontProjectIcon.png"))
            ws = NSWorkspace.sharedWorkspace()
            ws.setIcon_forFile_options_(icon, path, 0)

    def getData(self, path):
        toolWindows = list()
        documents = dict()
        untitled = list()

        relativePaths = self.view.relative.get()

        for document in NSApp().orderedDocuments():
            url = document.fileURL()
            fileName = None
            if url:
                fileName = url.path()
                if relativePaths and path:
                    fileName = os.path.relpath(fileName, os.path.dirname(path))
                if fileName not in documents:
                    documents[fileName] = []

            for windowController in document.windowControllers():
                window = windowController.window()
                (x, y), (w, h) =  window.frame()
                data = dict()
                data["frame"] = x, y, w, h
                data["windowName"] = window.windowName()

                vanillaWrapper = None
                if hasattr(window.delegate(), "vanillaWrapper"):
                    vanillaWrapper = window.delegate().vanillaWrapper()

                if vanillaWrapper:
                    if data["windowName"] == "GlyphWindow":
                        data["glyphName"] = vanillaWrapper.getGlyph().name
                    elif data["windowName"] == "SpaceCenter":
                            spaceCenter = vanillaWrapper.getSpaceCenter()
                            data["input"] = spaceCenter.get()
                            data["pre"] = spaceCenter.getPre()
                            data["after"] = spaceCenter.getAfter()
                            data["pointSize"] = spaceCenter.getPointSize()

                if fileName:
                    documents[fileName].append(data)
                else:
                    untitled.append(data)

        for window in NSApp().windows():
            if hasattr(window, "windowName"):
                if window.windowName() in ["DebugWindow", "InspectorWindow"]:
                    (x, y), (w, h) =  window.frame()
                    data = dict()
                    data["frame"] = x, y, w, h
                    data["windowName"] = window.windowName()
                    toolWindows.append(data)

        documents["untitled"] = untitled
        info = dict(toolWindows=toolWindows, documents=documents)
        code = self.view.editor.get()
        if code:
            info["execute"] = code
        return info

# file handler

class ReadRoboFontProjectFile(object):

    def __init__(self):
        addObserver(self, "applicationOpenFile", "applicationOpenFile")

    def applicationOpenFile(self, notification):
        path = notification["path"]
        ext = notification["ext"]
        fileHandler = notification["fileHandler"]
        if ext.lower() == ".robofontproject":
            try:
                OpenRoboFontProject(path)
            except:
                import traceback
                print(traceback.format_exc(5))
            fileHandler["opened"] = True

ReadRoboFontProjectFile()

# add to menu

class RoboFontProjectMenu(object):

    def __init__(self):
        title = "Save Project..."
        mainMenu = NSApp().mainMenu()
        fileMenu = mainMenu.itemWithTitle_("File")

        if not fileMenu:
            return

        fileMenu = fileMenu.submenu()

        if fileMenu.itemWithTitle_(title):
            return

        index = fileMenu.indexOfItemWithTitle_("Revert to Saved")
        self.target = CallbackWrapper(self.callback)

        newItem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(title, "action:", "")
        newItem.setTarget_(self.target)

        fileMenu.insertItem_atIndex_(newItem, index+1)

    def callback(self, sender):
        SaveRoboFontProject()

RoboFontProjectMenu()
<commit_msg>remove deprecated warning<commit_after>from AppKit import *

import os

import vanilla.dialogs as dialogs
import vanilla

from mojo.events import addObserver
from mojo.UI import OpenGlyphWindow, OpenSpaceCenter, CurrentSpaceCenterWindow, OutputWindow

from lib.scripting.scriptTools import ScriptRunner
from lib.scripting.codeEditor import CodeEditor
from mojo.tools import CallbackWrapper

from plistlib import readPlist, writePlist

def OpenRoboFontProject(path):
    root = os.path.dirname(path)
    project = readPlist(path)

    documentController = NSDocumentController.sharedDocumentController()
    delegate = NSApp().delegate()

    openFileNames = [window.representedFilename() for window in NSApp().windows()]

    for fileName, data in project["documents"].items():

        isUntitled = fileName == "untitled"

        if not isUntitled:
            if not os.path.exists(fileName):
                fileName = os.path.abspath(os.path.join(root, fileName))

            if not os.path.exists(fileName):
                continue

            if fileName in openFileNames:
                continue

        data.sort(key=lambda item: item.get("name") != "FontWindow")

        for windowData in data:
            name = windowData["windowName"]
            x, y, w, h = windowData["frame"]

            if isUntitled:
                if name == "FontWindow":
                    RFont()
                elif name == "ScriptingWindow":
                    delegate.scriptingWindow_(None)
                elif name == "FeatureWindow":
                    delegate.newFeature_(None)

            else:
                url = NSURL.fileURLWithPath_(fileName)
                doc, error = documentController.openDocumentWithContentsOfURL_display_error_(url, True, None)
                if error:
                    delegate.application_openFile_(NSApp(), fileName)

            window = NSApp().mainWindow()

            vanillaWrapper = None
            if hasattr(window.delegate(), "vanillaWrapper"):
                vanillaWrapper = window.delegate().vanillaWrapper()

            if vanillaWrapper:
                font = CurrentFont()
                if name == "GlyphWindow":
                    window = OpenGlyphWindow(font[windowData["glyphName"]], newWindow=True)
                    window.w.getNSWindow().setFrame_display_animate_(((x, y), (w, h)), True, False)
                    continue

                elif name == "SpaceCenter":
                    spaceCenter = OpenSpaceCenter(font)
                    spaceCenter.setPointSize(windowData["pointSize"])
                    spaceCenter.setPre(windowData["pre"])
                    spaceCenter.setAfter(windowData["after"])
                    spaceCenter.set(windowData["input"])

                    window = CurrentSpaceCenterWindow()
                    window.w.getNSWindow().setFrame_display_animate_(((x, y), (w, h)), True, False)
                    continue

            window.setFrame_display_animate_(((x, y), (w, h)), True, False)

    for windowData in project["toolWindows"]:
        name = windowData["windowName"]
        x, y, w, h = windowData["frame"]

        if name == "DebugWindow":
            window = OutputWindow()
            window.show()
            window.w.getNSWindow().setFrame_display_animate_(((x, y), (w, h)), True, False)

        elif name == "InspectorWindow":
            try:
                # a little bit hacky
                # will move to mojo.UI in the upcoming releases
                window = delegate._inspectorWindow.w.getNSWindow()
            except:
                window = None
            if window is None:
                delegate.openInspector_(None)
                window = delegate._inspectorWindow.w.getNSWindow()
            window.setFrame_display_animate_(((x, y), (w, h)), True, False)

    if "execute" in project:
        try:
            ScriptRunner(text=project["execute"])
        except:
            import traceback
            print(traceback.format_exc(5))

class SaveRoboFontProject(object):

    def __init__(self):
        w, h = 550, 250
        self.view = vanilla.Group((0, 0, w, h))
        self.view.relative = vanilla.CheckBox((0, 3, 300, 22), "Use Relative Paths")
        self.view.info = vanilla.TextBox((0, 33, 300, 22), "Execute on load:")
        self.view.editor = CodeEditor((0, 60, w, h-70))

        view = self.view.getNSView()
        view.setFrame_(((0, 0), (w, h)))

        path = dialogs.putFile("Save RoboFont Project..", fileTypes=["roboFontProject"], accessoryView=view)

        if path:
            data = self.getData(path)

            writePlist(data, path)

            icon = NSImage.alloc().initByReferencingFile_(os.path.join(os.path.dirname(__file__), "roboFontProjectIcon.png"))
            ws = NSWorkspace.sharedWorkspace()
            ws.setIcon_forFile_options_(icon, path, 0)

    def getData(self, path):
        toolWindows = list()
        documents = dict()
        untitled = list()

        relativePaths = self.view.relative.get()

        for document in NSApp().orderedDocuments():
            url = document.fileURL()
            fileName = None
            if url:
                fileName = url.path()
                if relativePaths and path:
                    fileName = os.path.relpath(fileName, os.path.dirname(path))
                if fileName not in documents:
                    documents[fileName] = []

            for windowController in document.windowControllers():
                window = windowController.window()
                (x, y), (w, h) =  window.frame()
                data = dict()
                data["frame"] = x, y, w, h
                data["windowName"] = window.windowName()

                vanillaWrapper = None
                if hasattr(window.delegate(), "vanillaWrapper"):
                    vanillaWrapper = window.delegate().vanillaWrapper()

                if vanillaWrapper:
                    if data["windowName"] == "GlyphWindow":
                        data["glyphName"] = vanillaWrapper.getGlyph().name
                    elif data["windowName"] == "SpaceCenter":
                            spaceCenter = vanillaWrapper.getSpaceCenter()
                            data["input"] = spaceCenter.get()
                            data["pre"] = spaceCenter.getPre()
                            data["after"] = spaceCenter.getAfter()
                            data["pointSize"] = spaceCenter.getPointSize()

                if fileName:
                    documents[fileName].append(data)
                else:
                    untitled.append(data)

        for window in NSApp().windows():
            if hasattr(window, "windowName"):
                if window.windowName() in ["DebugWindow", "InspectorWindow"]:
                    (x, y), (w, h) =  window.frame()
                    data = dict()
                    data["frame"] = x, y, w, h
                    data["windowName"] = window.windowName()
                    toolWindows.append(data)

        documents["untitled"] = untitled
        info = dict(toolWindows=toolWindows, documents=documents)
        code = self.view.editor.get()
        if code:
            info["execute"] = code
        return info

# file handler

class ReadRoboFontProjectFile(object):

    def __init__(self):
        addObserver(self, "applicationOpenFile", "applicationOpenFile")

    def applicationOpenFile(self, notification):
        path = notification["path"]
        ext = notification["ext"]
        fileHandler = notification["fileHandler"]
        if ext.lower() == ".robofontproject":
            try:
                OpenRoboFontProject(path)
            except:
                import traceback
                print(traceback.format_exc(5))
            fileHandler["opened"] = True

ReadRoboFontProjectFile()

# add to menu

class RoboFontProjectMenu(object):

    def __init__(self):
        title = "Save Project..."
        mainMenu = NSApp().mainMenu()
        fileMenu = mainMenu.itemWithTitle_("File")

        if not fileMenu:
            return

        fileMenu = fileMenu.submenu()

        if fileMenu.itemWithTitle_(title):
            return

        index = fileMenu.indexOfItemWithTitle_("Revert to Saved")
        self.target = CallbackWrapper(self.callback)

        newItem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(title, "action:", "")
        newItem.setTarget_(self.target)

        fileMenu.insertItem_atIndex_(newItem, index+1)

    def callback(self, sender):
        SaveRoboFontProject()

RoboFontProjectMenu()
<|endoftext|>


<commit_before>
# -------------------------------------------------------------------
# Copyright (c) 2017-2018 Denys Bortovets
# This file is part of the extensive testing project
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
# -------------------------------------------------------------------

"""
This is a setup.py script generated by py2applet

For building mac app run app-client/Scripts/qt5/MakeMacAppDMG.sh

"""

from setuptools import setup
from Main import __VERSION__

APP = ['../../Main.py']
APP_NAME = "ExtensiveTestingClient_%s" % __VERSION__
DATA_FILES = ['../../Files']

OPTIONS = {
    'argv_emulation': True,
    'iconfile': '../../Resources/ExtensiveTestingClient2.icns',
    'includes': ['sip', 'PyQt5', 'QScintilla'],
    'plist': {
        'CFBundleName': APP_NAME,
        'CFBundleDisplayName': APP_NAME,
        'CFBundleGetInfoString': "ET Client",
        'CFBundleVersion': "%s" % __VERSION__,
        'CFBundleShortVersionString': "%s" % __VERSION__,
        'NSHumanReadableCopyright': u"Copyright © 2017, Denys Bortovets, All Rights Reserved"
    }
}

setup(
    name=APP_NAME,
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)
<commit_msg>Mac Client<commit_after>
# -------------------------------------------------------------------
# Copyright (c) 2018 Denys Bortovets
# This file is part of the extensive testing project
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
# -------------------------------------------------------------------

"""
This is a setup.py script generated by py2applet

For building mac app run app-client/Scripts/qt5/MakeMacAppDMG.sh

"""

from setuptools import setup
from Main import __VERSION__

APP = ['../../Main.py']
APP_NAME = "ExtensiveTestingClient_%s" % __VERSION__
DATA_FILES = ['../../Files']

OPTIONS = {
    'argv_emulation': True,
    'iconfile': '../../Resources/ExtensiveTestingClient2.icns',
    'includes': ['sip', 'PyQt5', 'QScintilla'],
    'plist': {
        'CFBundleName': APP_NAME,
        'CFBundleDisplayName': APP_NAME,
        'CFBundleGetInfoString': "ET Client",
        'CFBundleVersion': "%s" % __VERSION__,
        'CFBundleShortVersionString': "%s" % __VERSION__,
        'NSHumanReadableCopyright': u"Copyright © 2018, Denys Bortovets, All Rights Reserved"
    }
}

setup(
    name=APP_NAME,
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Generated by Django 1.9.1 on 2016-01-24 09:31
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion

class Migration(migrations.Migration):

    dependencies = [
        ('sessions_', '0003_auto_20160112_0003'),
    ]

    operations = [
        migrations.CreateModel(
            name='SessionImage',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(help_text='Name of the Docker image', max_length=128)),
                ('tag', models.CharField(default='latest', help_text='Tag on the Docker image', max_length=128)),
                ('display_name', models.CharField(help_text='Name of the image as displayed', max_length=128)),
            ],
        ),
        migrations.CreateModel(
            name='SessionType',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(help_text='Name of the session type', max_length=128)),
                ('description', models.TextField(help_text='A short description of the session type')),
                ('ram', models.FloatField(default=0, help_text='Gigabytes (GB) of RAM allocated')),
                ('cpu', models.FloatField(default=0, help_text='Gigahertz (GHz) of CPU allocated to the session')),
                ('network', models.FloatField(default=0, help_text='Gigabytes (GB) of netwrk transfer allocated to the session')),
                ('timeout', models.FloatField(default=0, help_text='Minutes of inactivity before the session is terminated')),
            ],
        ),
        migrations.AlterField(
            model_name='session',
            name='image',
            field=models.CharField(help_text='Image name string for this session. Redundant given image_model', max_length=64),
        ),
        migrations.AddField(
            model_name='session',
            name='image_model',
            field=models.ForeignKey(default=1, help_text='SessionImage for this session', on_delete=django.db.models.deletion.CASCADE, related_name='sessions', to='sessions_.SessionImage'),
            preserve_default=False,
        ),
        migrations.AddField(
            model_name='session',
            name='type',
            field=models.ForeignKey(default=1, help_text='SessionType for this session', on_delete=django.db.models.deletion.CASCADE, related_name='sessions', to='sessions_.SessionType'),
            preserve_default=False,
        ),
    ]
<commit_msg>Fix migration<commit_after># -*- coding: utf-8 -*-
# Generated by Django 1.9.1 on 2016-01-24 09:31
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion

# Necessary to create default model instances for
# existing sessions to link to

def create_sessionimage_default(apps, schema_editor):
    SessionImage = apps.get_model("sessions_", "SessionImage")
    SessionImage.objects.create(
        id=1,
        name='',
        tag='',
        display_name=''
    )

def create_sessiontype_default(apps, schema_editor):
    SessionType = apps.get_model("sessions_", "SessionType")
    SessionType.objects.create(
        id=1,
        name='',
        description='',
        ram=0,
        cpu=0,
        network=0,
        timeout=0,
    )

class Migration(migrations.Migration):

    dependencies = [
        ('sessions_', '0003_auto_20160112_0003'),
    ]

    operations = [
        migrations.CreateModel(
            name='SessionImage',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(help_text='Name of the Docker image', max_length=128)),
                ('tag', models.CharField(default='latest', help_text='Tag on the Docker image', max_length=128)),
                ('display_name', models.CharField(help_text='Name of the image as displayed', max_length=128)),
            ],
        ),
        migrations.RunPython(create_sessionimage_default),
        migrations.CreateModel(
            name='SessionType',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(help_text='Name of the session type', max_length=128)),
                ('description', models.TextField(help_text='A short description of the session type')),
                ('ram', models.FloatField(default=0, help_text='Gigabytes (GB) of RAM allocated')),
                ('cpu', models.FloatField(default=0, help_text='Gigahertz (GHz) of CPU allocated to the session')),
                ('network', models.FloatField(default=0, help_text='Gigabytes (GB) of netwrk transfer allocated to the session')),
                ('timeout', models.FloatField(default=0, help_text='Minutes of inactivity before the session is terminated')),
            ],
        ),
        migrations.RunPython(create_sessiontype_default),
        migrations.AlterField(
            model_name='session',
            name='image',
            field=models.CharField(help_text='Image name string for this session. Redundant given image_model', max_length=64),
        ),
        migrations.AddField(
            model_name='session',
            name='image_model',
            field=models.ForeignKey(default=1, help_text='SessionImage for this session', on_delete=django.db.models.deletion.CASCADE, related_name='sessions', to='sessions_.SessionImage'),
            preserve_default=False,
        ),
        migrations.AddField(
            model_name='session',
            name='type',
            field=models.ForeignKey(default=1, help_text='SessionType for this session', on_delete=django.db.models.deletion.CASCADE, related_name='sessions', to='sessions_.SessionType'),
            preserve_default=False,
        ),
    ]
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################
#
# ChriCar Beteiligungs- und Beratungs- GmbH
# Copyright (C) ChriCar Beteiligungs- und Beratungs- GmbH
# all rights reserved
# created 2009-08-18 23:44:30+02
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs.
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/> or
# write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
###############################################
from osv import fields,osv

class act_window(osv.osv):
    _inherit = "ir.actions.act_window"

    _autosearch_check_limit = 80

    def run_auto_search_check(self, cr, uid):
        window_obj = self.pool.get('ir.actions.act_window')
        window_ids = window_obj.search \
            ( cr, uid
            , [('auto_search_check', '=', True), ('type', '=', 'ir.actions.act_window')]
            )
        for act_window in window_obj.browse(cr, uid, window_ids) :
            # FIXME add domain to get realistic results ??
            sql = """SELECT count(*) FROM %s;""" % self.pool.get(act_window.res_model)._table
            import sys ###################
            print >>sys.stderr, ">>>>>>>>>>>>>>>>", sql, ###################
            cr.execute(sql)
            count = cr.fetchone()
            print >>sys.stderr, count, act_window.id ####################
            if count > self._autosearch_check_limit :
                try :
                    window_obj.write(cr, uid, [act_window.id], {'auto_search' : False})
                except exc :
                    print  >>sys.stderr, "!!!!!", " could not write ir.actions.act_window,", act_window.id, str(exc)
    # end def run_auto_search_check

    _columns = \
        { 'auto_search_check': fields.boolean
            ('Auto Search Check'
            , help="If selected, the number of records will be checked periodically and autosearch will be turned off for big tables"
            )
        }
    _defaults = {'auto_search_check' : lambda *a : True}
act_window()
<commit_msg>c2c_autosearch_check: small bug fix<commit_after># -*- coding: utf-8 -*-
##############################################
#
# ChriCar Beteiligungs- und Beratungs- GmbH
# Copyright (C) ChriCar Beteiligungs- und Beratungs- GmbH
# all rights reserved
# created 2009-08-18 23:44:30+02
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs.
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/> or
# write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
###############################################
from osv import fields,osv

class act_window(osv.osv):
    _inherit = "ir.actions.act_window"

    _autosearch_check_limit = 80

    def run_auto_search_check(self, cr, uid):
        window_obj = self.pool.get('ir.actions.act_window')
        window_ids = window_obj.search \
            ( cr, uid
            , [('auto_search_check', '=', True), ('type', '=', 'ir.actions.act_window')]
            )
        for act_window in window_obj.browse(cr, uid, window_ids) :
            # FIXME add domain to get realistic results ??
            sql = """SELECT count(*) FROM %s;""" % self.pool.get(act_window.res_model)._table
            import sys ###################
            print >>sys.stderr, ">>>>>>>>>>>>>>>>", sql, ###################
            cr.execute(sql)
            count = cr.fetchone()
            print >>sys.stderr, count, act_window.id ####################
            if count > self._autosearch_check_limit :
                try :
                    window_obj.write(cr, uid, [act_window.id], {'auto_search' : False})
                except :
                    print  >>sys.stderr, "!!!!!", " could not write ir.actions.act_window,", act_window.id
    # end def run_auto_search_check

    _columns = \
        { 'auto_search_check': fields.boolean
            ('Auto Search Check'
            , help="If selected, the number of records will be checked periodically and autosearch will be turned off for big tables"
            )
        }
    _defaults = {'auto_search_check' : lambda *a : True}
act_window()
<|endoftext|>


<commit_before>from django.conf.urls import patterns, include, url
from tastypie.api import Api
from django.views.generic.base import RedirectView
from calaccess_campaign_browser.api import FilerResource
from calaccess_campaign_browser import views
from calaccess_campaign_browser.views import search

v1_api = Api(api_name='v1')
v1_api.register(FilerResource())

urlpatterns = patterns(
    '',
    url(r'^$', RedirectView.as_view(url='/latest/', permanent=False)),
    url(
        r'^latest/$',
        views.LatestFilingView.as_view(),
        name='latest_list'
    ),
    url(
        r'^filers/$',
        RedirectView.as_view(url='/filers/1/', permanent=False),
        name="filer_list"
    ),
    url(
        r'^filers/(?P<page>[\d+]+)/$',
        views.FilerListView.as_view(),
        name='filer_page'
    ),
    url(
        r'^filer/(?P<pk>\d+)/$',
        views.FilerDetailView.as_view(),
        name='filer_detail'
    ),
    url(
        r'^committee/(?P<pk>\d+)/contributions/(?P<page>[\d+]+)/$',
        views.CommitteeContributionView.as_view(),
        name='committee_contribution_list',
    ),
    url(
        r'^committee/(?P<pk>\d+)/expenditures/(?P<page>[\d+]+)/$',
        views.CommitteeExpenditureView.as_view(),
        name='committee_expenditure_list',
    ),
    url(
        r'^committee/(?P<pk>\d+)/filings/(?P<page>[\d+]+)/$',
        views.CommitteeFilingView.as_view(),
        name='committee_filing_list',
    ),
    url(
        r'^committee/(?P<pk>\d+)/$',
        views.CommitteeDetailView.as_view(),
        name='committee_detail'
    ),
    url(
        r'^filing/(?P<pk>\d+)/$',
        views.FilingDetailView.as_view(),
        name='filing_detail'
    ),
    url(
        r'^contribution/(?P<pk>\d+)/$',
        views.ContributionDetailView.as_view(),
        name='contribution_detail'
    ),
    url(
        r'^expenditure/(?P<pk>\d+)/$',
        views.ExpenditureDetailView.as_view(),
        name='expenditure_detail',
    ),
    url(r'^search/$', search.SearchList.as_view(), name='search-list'),
    url(
        r'^search/contribs-by-name/$',
        search.search_contribs_by_name,
        name='search-contribs-by-name'
    ),
    url(
        r'^parties/$',
        views.PartyListView.as_view(),
        name='party_list'
    ),

    # API
    url(r'^api/', include(v1_api.urls)),
)
<commit_msg>add robots.txt, closes #168<commit_after>from django.conf.urls import patterns, include, url
from tastypie.api import Api
from django.views.generic.base import RedirectView
from calaccess_campaign_browser.api import FilerResource
from calaccess_campaign_browser import views
from calaccess_campaign_browser.views import search
from django.views.generic import TemplateView

v1_api = Api(api_name='v1')
v1_api.register(FilerResource())

urlpatterns = patterns(
    '',
    url(r'^$', RedirectView.as_view(url='/latest/', permanent=False)),
    url(
        r'^latest/$',
        views.LatestFilingView.as_view(),
        name='latest_list'
    ),
    url(
        r'^filers/$',
        RedirectView.as_view(url='/filers/1/', permanent=False),
        name="filer_list"
    ),
    url(
        r'^filers/(?P<page>[\d+]+)/$',
        views.FilerListView.as_view(),
        name='filer_page'
    ),
    url(
        r'^filer/(?P<pk>\d+)/$',
        views.FilerDetailView.as_view(),
        name='filer_detail'
    ),
    url(
        r'^committee/(?P<pk>\d+)/contributions/(?P<page>[\d+]+)/$',
        views.CommitteeContributionView.as_view(),
        name='committee_contribution_list',
    ),
    url(
        r'^committee/(?P<pk>\d+)/expenditures/(?P<page>[\d+]+)/$',
        views.CommitteeExpenditureView.as_view(),
        name='committee_expenditure_list',
    ),
    url(
        r'^committee/(?P<pk>\d+)/filings/(?P<page>[\d+]+)/$',
        views.CommitteeFilingView.as_view(),
        name='committee_filing_list',
    ),
    url(
        r'^committee/(?P<pk>\d+)/$',
        views.CommitteeDetailView.as_view(),
        name='committee_detail'
    ),
    url(
        r'^filing/(?P<pk>\d+)/$',
        views.FilingDetailView.as_view(),
        name='filing_detail'
    ),
    url(
        r'^contribution/(?P<pk>\d+)/$',
        views.ContributionDetailView.as_view(),
        name='contribution_detail'
    ),
    url(
        r'^expenditure/(?P<pk>\d+)/$',
        views.ExpenditureDetailView.as_view(),
        name='expenditure_detail',
    ),
    url(r'^search/$', search.SearchList.as_view(), name='search-list'),
    url(
        r'^search/contribs-by-name/$',
        search.search_contribs_by_name,
        name='search-contribs-by-name'
    ),
    url(
        r'^parties/$',
        views.PartyListView.as_view(),
        name='party_list'
    ),

    # API
    url(r'^api/', include(v1_api.urls)),

    url(
        r'^robots\.txt$',
        TemplateView.as_view(template_name='robots.txt', content_type='text/plain')),

)
<|endoftext|>


<commit_before>from django.db.backends.postgresql_psycopg2.schema import DatabaseSchemaEditor as DSE

class DatabaseSchemaEditor(DSE):
    sql_create_fk = (
        "ALTER TABLE %(table)s ADD CONSTRAINT %(name)s FOREIGN KEY (%(column)s) "
        "REFERENCES %(to_table)s (%(to_column)s)%(cascade)s%(deferrable)s"
    )

<commit_msg>db schema set up to work on custom or base foreign key<commit_after>from django.db.backends.postgresql_psycopg2.schema import DatabaseSchemaEditor as DSE

class DatabaseSchemaEditor(DSE):

    sql_cascade = "ON DELETE CASCADE"

    sql_create_fk = (
        "ALTER TABLE %(table)s ADD CONSTRAINT %(name)s FOREIGN KEY (%(column)s) "
        "REFERENCES %(to_table)s (%(to_column)s)%(cascade)s%(deferrable)s"
    )

    def _create_fk_sql(self, model, field, suffix):
        from_table = model._meta.db_table
        from_column = field.column
        to_table = field.target_field.model._meta.db_table
        to_column = field.target_field.column
        suffix = suffix % {
            "to_table": to_table,
            "to_column": to_column,
        }

        return self.sql_create_fk % {
            "table": self.quote_name(from_table),
            "name": self.quote_name(self._create_index_name(model, [from_column], suffix=suffix)),
            "column": self.quote_name(from_column),
            "to_table": self.quote_name(to_table),
            "to_column": self.quote_name(to_column),
            "deferrable": self.connection.ops.deferrable_sql(),
            "cascade": self.sql_cascade if getattr(field, 'db_cascade', False) else ""
        }
<|endoftext|>


<commit_before># coding=utf-8
import os
import sys
import zipfile
import time
import re
from distutils.sysconfig import get_python_lib
from django.conf import settings
from django.core.management.base import NoArgsCommand
from django_extensions.management.commands import clean_pyc, compile_pyc

def zip_folder(folder_path, zip_name, include_empty_folder=True, check_root=None, check_file=None):
    root_length = len(folder_path) + 1
    zip_file = zipfile.ZipFile(zip_name, "w", zipfile.ZIP_DEFLATED)
    for root, folders, files in os.walk(folder_path):
        short_root = root[root_length:]
        if check_root is None or check_root(short_root):
            empty_folders = [folder for folder in folders if os.listdir(os.path.join(root, folder)) == []]
            for f in files:
                if check_file is None or check_file(short_root, f):
                    file_name = os.path.join(root, f)
                    zip_file.write(file_name, file_name[root_length:])
            if include_empty_folder:
                for folder in empty_folders:
                    zif = zipfile.ZipInfo(os.path.join(root, folder) + "/")
                    zip_file.writestr(zif, "")
    zip_file.close()

class Command(NoArgsCommand):
    help = "Compress site-packages folder to a zip file."
    usage_str = "Usage: ./manage.py compress_site_packages"
    filter_modules = ("_markerlib", "pip", "setuptools", "sae", "MySQLdb", "lxml", "PIL",
                      "werkzeug", "prettytable", "yaml", "argparse", "grizzled", "sqlcmd", "enum",
                      "test", "tests", "_mysql", "_mysql_exceptions", "_mysql",
                      "easy_install", "pkg_resources")

    @classmethod
    def check_root(cls, root):
        module_name = root.split(os.path.sep)[0]
        if module_name in cls.filter_modules or "." in module_name:
            return False
        return True

    @classmethod
    def check_file(cls, root, f):
        if not root:
            file_name, extend_name = os.path.splitext(f)
            if file_name in cls.filter_modules or extend_name in ['.egg', '.txt', '.pth']:
                return False
        return True

    @staticmethod
    def get_wsgi_file():
        return os.path.join(settings.BASE_DIR, 'index.wsgi')

    @staticmethod
    def replace_site_packages(path, name):
        if os.path.exists(path):
            with open(path) as rf:
                text = rf.read()
                m = re.search("sys.path.insert\(0, os.path.join\(root, '(?P<name>.+)'\)\)", text)
                if m:
                    with open(path, 'w') as wf:
                        wf.write(text.replace(m.group('name'), name))

    def handle(self, path=None, name=None, **options):
        if path is None:
            path = get_python_lib()
        if name is None:
            name = "site-packages%s.zip" % int(time.time())

        # 用户可以上传和使用 .pyc 文件，注意 .pyc 文件必须是python2.7.3生成的，否则无效。
        # http://sae.sina.com.cn/doc/python/runtime.html#id3
        if options.get("clean_pyc", sys.version_info[0:3] != (2, 7, 3)):
            clean_pyc.Command().execute(path=path, verbosity=1)
        else:
            compile_pyc.Command().execute(path=path, verbosity=1)

        zip_folder(path, name, True, self.check_root, self.check_file)
        self.replace_site_packages(self.get_wsgi_file(), name)
        self.stdout.write("compressed success:%s" % name)<commit_msg>修改verbosity默认值<commit_after># coding=utf-8
import os
import sys
import zipfile
import time
import re
from distutils.sysconfig import get_python_lib
from django.conf import settings
from django.core.management.base import NoArgsCommand
from django_extensions.management.commands import clean_pyc, compile_pyc

def zip_folder(folder_path, zip_name, include_empty_folder=True, check_root=None, check_file=None):
    root_length = len(folder_path) + 1
    zip_file = zipfile.ZipFile(zip_name, "w", zipfile.ZIP_DEFLATED)
    for root, folders, files in os.walk(folder_path):
        short_root = root[root_length:]
        if check_root is None or check_root(short_root):
            empty_folders = [folder for folder in folders if os.listdir(os.path.join(root, folder)) == []]
            for f in files:
                if check_file is None or check_file(short_root, f):
                    file_name = os.path.join(root, f)
                    zip_file.write(file_name, file_name[root_length:])
            if include_empty_folder:
                for folder in empty_folders:
                    zif = zipfile.ZipInfo(os.path.join(root, folder) + "/")
                    zip_file.writestr(zif, "")
    zip_file.close()

class Command(NoArgsCommand):
    help = "Compress site-packages folder to a zip file."
    usage_str = "Usage: ./manage.py compress_site_packages"
    filter_modules = ("_markerlib", "pip", "setuptools", "sae", "MySQLdb", "lxml", "PIL",
                      "werkzeug", "prettytable", "yaml", "argparse", "grizzled", "sqlcmd", "enum",
                      "test", "tests", "_mysql", "_mysql_exceptions", "_mysql",
                      "easy_install", "pkg_resources")

    @classmethod
    def check_root(cls, root):
        module_name = root.split(os.path.sep)[0]
        if module_name in cls.filter_modules or "." in module_name:
            return False
        return True

    @classmethod
    def check_file(cls, root, f):
        if not root:
            file_name, extend_name = os.path.splitext(f)
            if file_name in cls.filter_modules or extend_name in ['.egg', '.txt', '.pth']:
                return False
        return True

    @staticmethod
    def get_wsgi_file():
        return os.path.join(settings.BASE_DIR, 'index.wsgi')

    @staticmethod
    def replace_site_packages(path, name):
        if os.path.exists(path):
            with open(path) as rf:
                text = rf.read()
                m = re.search("sys.path.insert\(0, os.path.join\(root, '(?P<name>.+)'\)\)", text)
                if m:
                    with open(path, 'w') as wf:
                        wf.write(text.replace(m.group('name'), name))

    def handle(self, path=None, name=None, **options):
        if path is None:
            path = get_python_lib()
        if name is None:
            name = "site-packages%s.zip" % int(time.time())

        # 用户可以上传和使用 .pyc 文件，注意 .pyc 文件必须是python2.7.3生成的，否则无效。
        # http://sae.sina.com.cn/doc/python/runtime.html#id3
        if options.get("clean_pyc", sys.version_info[0:3] != (2, 7, 3)):
            clean_pyc.Command().execute(path=path, verbosity=0)
        else:
            compile_pyc.Command().execute(path=path, verbosity=0)

        zip_folder(path, name, True, self.check_root, self.check_file)
        self.replace_site_packages(self.get_wsgi_file(), name)
        self.stdout.write("compressed success:%s" % name)<|endoftext|>


<commit_before>from django.conf.urls import patterns, url, include
from tasks import views as task_views
from sprints import views as sprint_views
from rest_framework.routers import DefaultRouter

# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'tasks', task_views.TaskViewSet)
router.register(r'categories', task_views.CategoryViewSet)
router.register(r'sprints', sprint_views.SprintViewSet)
#router.register(r'users', views.UserViewSet)

# The API URLs are now determined automatically by the router.
# Additionally, we include the login URLs for the browseable API.
urlpatterns = patterns('',
    url(r'^', include(router.urls)),
)<commit_msg>added base names to api<commit_after>from django.conf.urls import patterns, url, include
from tasks import views as task_views
from sprints import views as sprint_views
from rest_framework.routers import DefaultRouter

# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'tasks', task_views.TaskViewSet, 'tasks')
router.register(r'categories', task_views.CategoryViewSet, 'categories')
router.register(r'sprints', sprint_views.SprintViewSet, 'sprints')
#router.register(r'users', views.UserViewSet)

# The API URLs are now determined automatically by the router.
# Additionally, we include the login URLs for the browseable API.
urlpatterns = patterns('',
    url(r'^', include(router.urls)),
)<|endoftext|>


<commit_before>import os
import unittest
import tempfile
import httpretty

import certificator
from certificator.main import create_app

class CertificatorTestCase(unittest.TestCase):

    def setUp(self):
        self.application = create_app()
        self.db_fd, self.application.config['DATABASE'] = tempfile.mkstemp()
        self.application.config['TESTING'] = True
        self.app = self.application.test_client()
        from certificator.db import db as sqla
        sqla.create_all()

    def tearDown(self):
        os.close(self.db_fd)
        os.unlink(self.application.config['DATABASE'])

    def login(self):
        # Mock the response from persona.org for success.
        persona = ('{"audience":"http://localhost/",'
                   '"expires":9377394697781,'
                   '"issuer":"gmail.login.persona.org",'
                   '"email":"example@gmail.com",'
                   '"status":"okay"}')
        httpretty.register_uri(httpretty.POST,
                               "https://verifier.login.persona.org/verify",
                               body=persona,
                               content_type="application/json")

        self.app.post('/api/login', data=dict(assertion="asdf"))

    def test_not_logged_in_redirect(self):
        '''When a user is not logged in, redirect to the landing page.'''
        rv = self.app.get('/')
        print repr(rv.headers)
        assert rv.status_code == 302
        assert rv.headers['Location'] == 'http://localhost/greetings'

    @httpretty.activate
    def test_log_in(self):
        '''A user has clicked the login button.'''

        # Shouldn't be able to see the available quizzes without logging in
        rv = self.app.get('/list')
        assert "Available Quizzes" not in rv.data

        self.login()

        # Should be able to see the available quizzes now.
        rv = self.app.get('/list')
        assert "Available Quizzes" in rv.data

if __name__ == '__main__':
    unittest.main()
<commit_msg>Put httpretty in the right spot.<commit_after>import os
import unittest
import tempfile
import httpretty

from certificator.main import create_app

class CertificatorTestCase(unittest.TestCase):

    def setUp(self):
        self.application = create_app()
        self.db_fd, self.application.config['DATABASE'] = tempfile.mkstemp()
        self.application.config['TESTING'] = True
        self.app = self.application.test_client()
        from certificator.db import db as sqla
        sqla.create_all()

    def tearDown(self):
        os.close(self.db_fd)
        os.unlink(self.application.config['DATABASE'])

    @httpretty.activate
    def login(self):
        # Mock the response from persona.org for success.
        persona = ('{"audience":"http://localhost/",'
                   '"expires":9377394697781,'
                   '"issuer":"gmail.login.persona.org",'
                   '"email":"example@gmail.com",'
                   '"status":"okay"}')
        httpretty.register_uri(httpretty.POST,
                               "https://verifier.login.persona.org/verify",
                               body=persona,
                               content_type="application/json")

        self.app.post('/api/login', data=dict(assertion="asdf"))

    def test_not_logged_in_redirect(self):
        '''When a user is not logged in, redirect to the landing page.'''
        rv = self.app.get('/')
        print repr(rv.headers)
        assert rv.status_code == 302
        assert rv.headers['Location'] == 'http://localhost/greetings'

    def test_log_in(self):
        '''A user has clicked the login button.'''

        # Shouldn't be able to see the available quizzes without logging in
        rv = self.app.get('/list')
        assert "Available Quizzes" not in rv.data

        self.login()

        # Should be able to see the available quizzes now.
        rv = self.app.get('/list')
        assert "Available Quizzes" in rv.data

if __name__ == '__main__':
    unittest.main()
<|endoftext|>