<commit_before>import unittest
import sys, os

from scipy_distutils.misc_util import add_grandparent_to_path, restore_path
from scipy_distutils.misc_util import add_local_to_path

add_grandparent_to_path(__name__)
from catalog import *
# not sure why, but was having problems with which catalog was being called.
import catalog
#catalog = catalog.catalog
restore_path()

add_local_to_path(__name__)
from weave_test_utils import *
restore_path()

class test_default_dir(unittest.TestCase):
    def check_is_writable(self):
        path = default_dir()
        name = os.path.join(path,'dummy_catalog')
        test_file = open(name,'w')
        try:
            test_file.write('making sure default location is writable\n')
        finally:
            test_file.close()
            os.remove(name)

class test_os_dependent_catalog_name(unittest.TestCase):
    pass

class test_catalog_path(unittest.TestCase):
    def check_default(self):
        in_path = default_dir()
        path = catalog_path(in_path)
        d,f = os.path.split(path)
        assert(d == in_path)
        assert(f == os_dependent_catalog_name())
    def check_current(self):
        in_path = '.'
        path = catalog_path(in_path)
        d,f = os.path.split(path)
        assert(d == os.path.abspath(in_path))
        assert(f == os_dependent_catalog_name())
    def check_user(path):
        if sys.platform != 'win32':
            in_path = '~'
            path = catalog_path(in_path)
            d,f = os.path.split(path)
            assert(d == os.path.expanduser(in_path))
            assert(f == os_dependent_catalog_name())
    def check_module(self):
        # hand it a module and see if it uses the parent directory
        # of the module.
        path = catalog_path(os.__file__)
        d,f = os.path.split(os.__file__)
        d2,f = os.path.split(path)
        assert (d2 == d)
    def check_path(self):
        # use os.__file__ to get a usable directory.
        in_path,f = os.path.split(os.__file__)
        path = catalog_path(in_path)
        d,f = os.path.split(path)
        assert (d == in_path)
    def check_bad_path(self):
        # stupid_path_name
        in_path = 'stupid_path_name'
        path = catalog_path(in_path)
        assert (path is None)

class test_get_catalog(unittest.TestCase):
    """ This only tests whether new catalogs are created correctly.
        And whether non-existent return None correctly with read mode.
        Putting catalogs in the right place is all tested with
        catalog_dir tests.
    """
    def get_test_dir(self,erase = 0):
        # make sure tempdir catalog doesn't exist
        import tempfile
        temp = tempfile.gettempdir()
        pardir = os.path.join(temp,'catalog_test'+tempfile.gettempprefix())
        if not os.path.exists(pardir):
            os.mkdir(pardir)
        catalog_file = os.path.join(pardir,os_dependent_catalog_name()+'.dat')
        if os.path.exists(catalog_file) and erase:
            os.remove(catalog_file)
        catalog_file = os.path.join(pardir,os_dependent_catalog_name()+'.dir')
        if os.path.exists(catalog_file) and erase:
            os.remove(catalog_file)
        catalog_file = os.path.join(pardir,os_dependent_catalog_name())
        if os.path.exists(catalog_file) and erase:
            os.remove(catalog_file)
        return pardir
    def check_nonexistent_catalog_is_none(self):
        pardir = self.get_test_dir(erase=1)
        catalog = get_catalog(pardir)
        assert(catalog is None)
    def check_create_catalog(self):
        pardir = self.get_test_dir(erase=1)
        catalog = get_catalog(pardir,'c')
        assert(catalog is not None)

class test_catalog(unittest.TestCase):

    def clear_environ(self):
        if os.environ.has_key('PYTHONCOMPILED'):
            self.old_PYTHONCOMPILED = os.environ['PYTHONCOMPILED']
            del os.environ['PYTHONCOMPILED']
        else:
            self.old_PYTHONCOMPILED = None
    def reset_environ(self):
        if self.old_PYTHONCOMPILED:
            os.environ['PYTHONCOMPILED'] = self.old_PYTHONCOMPILED
            self.old_PYTHONCOMPILED = None
    def setUp(self):
        self.clear_environ()
    def tearDown(self):
        self.reset_environ()

    def check_set_module_directory(self):
        q = catalog.catalog()
        q.set_module_directory('bob')
        r = q.get_module_directory()
        assert (r == 'bob')
    def check_clear_module_directory(self):
        q = catalog.catalog()
        r = q.get_module_directory()
        assert (r == None)
        q.set_module_directory('bob')
        r = q.clear_module_directory()
        assert (r == None)
    def check_get_environ_path(self):
        if sys.platform == 'win32': sep = ';'
        else: sep = ':'
        os.environ['PYTHONCOMPILED'] = sep.join(('path1','path2','path3'))
        q = catalog.catalog()
        path = q.get_environ_path()
        assert(path == ['path1','path2','path3'])
    def check_build_search_order1(self):
        """ MODULE in search path should be replaced by module_dir.
        """
        q = catalog.catalog(['first','MODULE','third'])
        q.set_module_directory('second')
        order = q.build_search_order()
        assert(order == ['first','second','third',default_dir()])
    def check_build_search_order2(self):
        """ MODULE in search path should be removed if module_dir==None.
        """
        q = catalog.catalog(['first','MODULE','third'])
        order = q.build_search_order()
        assert(order == ['first','third',default_dir()])
    def check_build_search_order3(self):
        """ If MODULE is absent, module_dir shouldn't be in search path.
        """
        q = catalog.catalog(['first','second'])
        q.set_module_directory('third')
        order = q.build_search_order()
        assert(order == ['first','second',default_dir()])
    def check_build_search_order4(self):
        """ Make sure environment variable is getting used.
        """
        q = catalog.catalog(['first','second'])
        if sys.platform == 'win32': sep = ';'
        else: sep = ':'
        os.environ['PYTHONCOMPILED'] = sep.join(('MODULE','fourth','fifth'))
        q.set_module_directory('third')
        order = q.build_search_order()
        assert(order == ['first','second','third','fourth','fifth',default_dir()])

    def check_catalog_files1(self):
        """ Be sure we get at least one file even without specifying the path.
        """
        q = catalog.catalog()
        files = q.get_catalog_files()
        assert(len(files) == 1)

    def check_catalog_files2(self):
        """ Ignore bad paths in the path.
        """
        q = catalog.catalog()
        os.environ['PYTHONCOMPILED'] = '_some_bad_path_'
        files = q.get_catalog_files()
        assert(len(files) == 1)

    def check_get_existing_files1(self):
        """ Shouldn't get any files when temp doesn't exist and no path set.
        """
        clear_temp_catalog()
        q = catalog.catalog()
        files = q.get_existing_files()
        restore_temp_catalog()
        assert(len(files) == 0)
    def check_get_existing_files2(self):
        """ Shouldn't get a single file from the temp dir.
        """
        clear_temp_catalog()
        q = catalog.catalog()
        # create a dummy file
        import os
        q.add_function('code', os.getpid)
        del q
        q = catalog.catalog()
        files = q.get_existing_files()
        restore_temp_catalog()
        print 'files:', files
        assert(len(files) == 1)

    def check_access_writable_file(self):
        """ There should always be a writable file -- even if it is in temp
        """
        q = catalog.catalog()
        file = q.get_writable_file()
        try:
            f = open(file,'w')
            f.write('bob')
        finally:
            f.close()
            os.remove(file)
    def check_writable_with_bad_path(self):
        """ There should always be a writable file -- even if search paths contain
            bad values.
        """
        if sys.platform == 'win32': sep = ';'
        else: sep = ':'
        os.environ['PYTHONCOMPILED'] = sep.join(('_bad_path_name_'))
        q = catalog.catalog()
        file = q.get_writable_file()
        try:
            f = open(file,'w')
            f.write('bob')
        finally:
            f.close()
        os.remove(file)
    def check_writable_dir(self):
        """ Check that we can create a file in the writable directory
        """
        q = catalog.catalog()
        d = q.get_writable_dir()
        file = os.path.join(d,'some_silly_file')
        try:
            f = open(file,'w')
            f.write('bob')
        finally:
            f.close()
            os.remove(file)
    def check_unique_module_name(self):
        """ Check that we can create a file in the writable directory
        """
        q = catalog.catalog()
        file = q.unique_module_name('bob')
        cfile1 = file+'.cpp'
        assert(not os.path.exists(cfile1))
        #make sure it is writable
        try:
            f = open(cfile1,'w')
            f.write('bob')
        finally:
            f.close()
        # try again with same code fragment -- should get unique name
        file = q.unique_module_name('bob')
        cfile2 = file+'.cpp'
        assert(not os.path.exists(cfile2+'.cpp'))
        os.remove(cfile1)
    def check_add_function_persistent1(self):
        """ Test persisting a function in the default catalog
        """
        clear_temp_catalog()
        q = catalog.catalog()
        mod_name = q.unique_module_name('bob')
        d,f = os.path.split(mod_name)
        module_name, funcs = simple_module(d,f,'f')
        for i in funcs:
            q.add_function_persistent('code',i)
        pfuncs = q.get_cataloged_functions('code')
        os.remove(module_name)
        # any way to clean modules???
        restore_temp_catalog()
        for i in funcs:
            assert(i in pfuncs)

    def not_sure_about_this_check_add_function_persistent2(self):
        """ Test ordering of persistent functions
        """
        clear_temp_catalog()
        q = catalog.catalog()

        mod_name = q.unique_module_name('bob')
        d,f = os.path.split(mod_name)
        module_name1, funcs1 = simple_module(d,f,'f')
        for i in funcs1:
            q.add_function_persistent('code',i)

        d = empty_temp_dir()
        q = catalog(d)
        mod_name = q.unique_module_name('bob')
        d,f = os.path.split(mod_name)
        module_name2, funcs2 = simple_module(d,f,'f')
        for i in funcs2:
            q.add_function_persistent('code',i)
        pfuncs = q.get_cataloged_functions('code')

        os.remove(module_name1)
        os.remove(module_name2)
        cleanup_temp_dir(d)
        restore_temp_catalog()
        # any way to clean modules???
        for i in funcs1:
            assert(i in pfuncs)
        for i in funcs2:
            assert(i in pfuncs)
        # make sure functions occur in correct order for
        # lookup
        all_funcs = zip(funcs1,funcs2)
        print all_funcs
        for a,b in all_funcs:
            assert(pfuncs.index(a) > pfuncs.index(b))

        assert(len(pfuncs) == 4)

    def check_add_function_ordered(self):
        clear_temp_catalog()
        q = catalog.catalog()
        import string

        q.add_function('f',string.upper)
        q.add_function('f',string.lower)
        q.add_function('ff',string.find)
        q.add_function('ff',string.replace)
        q.add_function('fff',string.atof)
        q.add_function('fff',string.atoi)
        del q

        # now we're gonna make a new catalog with same code
        # but different functions in a specified module directory
        env_dir = empty_temp_dir()
        r = catalog.catalog(env_dir)
        r.add_function('ff',os.abort)
        r.add_function('ff',os.chdir)
        r.add_function('fff',os.access)
        r.add_function('fff',os.open)
        del r
        # now we're gonna make a new catalog with same code
        # but different functions in a user specified directory
        user_dir = empty_temp_dir()
        s = catalog.catalog(user_dir)
        import re
        s.add_function('fff',re.match)
        s.add_function('fff',re.purge)
        del s

        # open new catalog and make sure it retreives the functions
        # from d catalog instead of the temp catalog (made by q)
        os.environ['PYTHONCOMPILED'] = env_dir
        t = catalog.catalog(user_dir)
        funcs1 = t.get_functions('f')
        funcs2 = t.get_functions('ff')
        funcs3 = t.get_functions('fff')
        restore_temp_catalog()
        # make sure everything is read back in the correct order
        assert(funcs1 == [string.lower,string.upper])
        assert(funcs2 == [os.chdir,os.abort,string.replace,string.find])
        assert(funcs3 == [re.purge,re.match,os.open,
                          os.access,string.atoi,string.atof])
        cleanup_temp_dir(user_dir)
        cleanup_temp_dir(env_dir)

def test_suite():
    suites = []
    suites.append( unittest.makeSuite(test_default_dir,'check_'))
    suites.append( unittest.makeSuite(test_os_dependent_catalog_name,'check_'))
    suites.append( unittest.makeSuite(test_catalog_path,'check_'))
    suites.append( unittest.makeSuite(test_get_catalog,'check_'))
    suites.append( unittest.makeSuite(test_catalog,'check_'))

    total_suite = unittest.TestSuite(suites)
    return total_suite

def test():
    all_tests = test_suite()
    runner = unittest.TextTestRunner()
    runner.run(all_tests)
    return runner

if __name__ == '__main__':
    test()
<commit_msg>got rid of from catalog import * in test code that forced restarts for testing to reflect code changes<commit_after>import unittest
import sys, os

from scipy_distutils.misc_util import add_grandparent_to_path, restore_path
from scipy_distutils.misc_util import add_local_to_path

add_grandparent_to_path(__name__)
from catalog import *
# not sure why, but was having problems with which catalog was being called.
import catalog
#catalog = catalog.catalog
restore_path()

add_local_to_path(__name__)
from weave_test_utils import *
restore_path()

class test_default_dir(unittest.TestCase):
    def check_is_writable(self):
        path = default_dir()
        name = os.path.join(path,'dummy_catalog')
        test_file = open(name,'w')
        try:
            test_file.write('making sure default location is writable\n')
        finally:
            test_file.close()
            os.remove(name)

class test_os_dependent_catalog_name(unittest.TestCase):
    pass

class test_catalog_path(unittest.TestCase):
    def check_default(self):
        in_path = default_dir()
        path = catalog.catalog_path(in_path)
        d,f = os.path.split(path)
        assert(d == in_path)
        assert(f == os_dependent_catalog_name())
    def check_current(self):
        in_path = '.'
        path = catalog.catalog_path(in_path)
        d,f = os.path.split(path)
        assert(d == os.path.abspath(in_path))
        assert(f == os_dependent_catalog_name())
    def check_user(path):
        if sys.platform != 'win32':
            in_path = '~'
            path = catalog_path(in_path)
            d,f = os.path.split(path)
            assert(d == os.path.expanduser(in_path))
            assert(f == catalog.os_dependent_catalog_name())
    def check_module(self):
        # hand it a module and see if it uses the parent directory
        # of the module.
        path = catalog.catalog_path(os.__file__)
        d,f = os.path.split(os.__file__)
        d2,f = os.path.split(path)
        assert (d2 == d)
    def check_path(self):
        # use os.__file__ to get a usable directory.
        in_path,f = os.path.split(os.__file__)
        path = catalog.catalog_path(in_path)
        d,f = os.path.split(path)
        assert (d == in_path)
    def check_bad_path(self):
        # stupid_path_name
        in_path = 'stupid_path_name'
        path = catalog.catalog_path(in_path)
        assert (path is None)

class test_get_catalog(unittest.TestCase):
    """ This only tests whether new catalogs are created correctly.
        And whether non-existent return None correctly with read mode.
        Putting catalogs in the right place is all tested with
        catalog_dir tests.
    """
    def get_test_dir(self,erase = 0):
        # make sure tempdir catalog doesn't exist
        import tempfile
        temp = tempfile.gettempdir()
        pardir = os.path.join(temp,'catalog_test'+tempfile.gettempprefix())
        if not os.path.exists(pardir):
            os.mkdir(pardir)
        catalog_file = os.path.join(pardir,
                                    catalog.os_dependent_catalog_name()+'.dat')
        if os.path.exists(catalog_file) and erase:
            os.remove(catalog_file)
        catalog_file = os.path.join(pardir,
                                    catalog.os_dependent_catalog_name()+'.dir')
        if os.path.exists(catalog_file) and erase:
            os.remove(catalog_file)
        catalog_file = os.path.join(pardir,
                                    catalog.os_dependent_catalog_name())
        if os.path.exists(catalog_file) and erase:
            os.remove(catalog_file)
        return pardir
    def check_nonexistent_catalog_is_none(self):
        pardir = self.get_test_dir(erase=1)
        cat = catalog.get_catalog(pardir)
        assert(cat is None)
    def check_create_catalog(self):
        pardir = self.get_test_dir(erase=1)
        cat = catalog.get_catalog(pardir,'c')
        assert(cat is not None)

class test_catalog(unittest.TestCase):

    def clear_environ(self):
        if os.environ.has_key('PYTHONCOMPILED'):
            self.old_PYTHONCOMPILED = os.environ['PYTHONCOMPILED']
            del os.environ['PYTHONCOMPILED']
        else:
            self.old_PYTHONCOMPILED = None
    def reset_environ(self):
        if self.old_PYTHONCOMPILED:
            os.environ['PYTHONCOMPILED'] = self.old_PYTHONCOMPILED
            self.old_PYTHONCOMPILED = None
    def setUp(self):
        self.clear_environ()
    def tearDown(self):
        self.reset_environ()

    def check_set_module_directory(self):
        q = catalog.catalog()
        q.set_module_directory('bob')
        r = q.get_module_directory()
        assert (r == 'bob')
    def check_clear_module_directory(self):
        q = catalog.catalog()
        r = q.get_module_directory()
        assert (r == None)
        q.set_module_directory('bob')
        r = q.clear_module_directory()
        assert (r == None)
    def check_get_environ_path(self):
        if sys.platform == 'win32': sep = ';'
        else: sep = ':'
        os.environ['PYTHONCOMPILED'] = sep.join(('path1','path2','path3'))
        q = catalog.catalog()
        path = q.get_environ_path()
        assert(path == ['path1','path2','path3'])
    def check_build_search_order1(self):
        """ MODULE in search path should be replaced by module_dir.
        """
        q = catalog.catalog(['first','MODULE','third'])
        q.set_module_directory('second')
        order = q.build_search_order()
        assert(order == ['first','second','third',default_dir()])
    def check_build_search_order2(self):
        """ MODULE in search path should be removed if module_dir==None.
        """
        q = catalog.catalog(['first','MODULE','third'])
        order = q.build_search_order()
        assert(order == ['first','third',default_dir()])
    def check_build_search_order3(self):
        """ If MODULE is absent, module_dir shouldn't be in search path.
        """
        q = catalog.catalog(['first','second'])
        q.set_module_directory('third')
        order = q.build_search_order()
        assert(order == ['first','second',default_dir()])
    def check_build_search_order4(self):
        """ Make sure environment variable is getting used.
        """
        q = catalog.catalog(['first','second'])
        if sys.platform == 'win32': sep = ';'
        else: sep = ':'
        os.environ['PYTHONCOMPILED'] = sep.join(('MODULE','fourth','fifth'))
        q.set_module_directory('third')
        order = q.build_search_order()
        assert(order == ['first','second','third','fourth','fifth',default_dir()])

    def check_catalog_files1(self):
        """ Be sure we get at least one file even without specifying the path.
        """
        q = catalog.catalog()
        files = q.get_catalog_files()
        assert(len(files) == 1)

    def check_catalog_files2(self):
        """ Ignore bad paths in the path.
        """
        q = catalog.catalog()
        os.environ['PYTHONCOMPILED'] = '_some_bad_path_'
        files = q.get_catalog_files()
        assert(len(files) == 1)

    def check_get_existing_files1(self):
        """ Shouldn't get any files when temp doesn't exist and no path set.
        """
        clear_temp_catalog()
        q = catalog.catalog()
        files = q.get_existing_files()
        restore_temp_catalog()
        assert(len(files) == 0)
    def check_get_existing_files2(self):
        """ Shouldn't get a single file from the temp dir.
        """
        clear_temp_catalog()
        q = catalog.catalog()
        # create a dummy file
        import os
        q.add_function('code', os.getpid)
        del q
        q = catalog.catalog()
        files = q.get_existing_files()
        restore_temp_catalog()
        print 'files:', files
        assert(len(files) == 1)

    def check_access_writable_file(self):
        """ There should always be a writable file -- even if it is in temp
        """
        q = catalog.catalog()
        file = q.get_writable_file()
        try:
            f = open(file,'w')
            f.write('bob')
        finally:
            f.close()
            os.remove(file)
    def check_writable_with_bad_path(self):
        """ There should always be a writable file -- even if search paths contain
            bad values.
        """
        if sys.platform == 'win32': sep = ';'
        else: sep = ':'
        os.environ['PYTHONCOMPILED'] = sep.join(('_bad_path_name_'))
        q = catalog.catalog()
        file = q.get_writable_file()
        try:
            f = open(file,'w')
            f.write('bob')
        finally:
            f.close()
        os.remove(file)
    def check_writable_dir(self):
        """ Check that we can create a file in the writable directory
        """
        q = catalog.catalog()
        d = q.get_writable_dir()
        file = os.path.join(d,'some_silly_file')
        try:
            f = open(file,'w')
            f.write('bob')
        finally:
            f.close()
            os.remove(file)
    def check_unique_module_name(self):
        """ Check that we can create a file in the writable directory
        """
        q = catalog.catalog()
        file = q.unique_module_name('bob')
        cfile1 = file+'.cpp'
        assert(not os.path.exists(cfile1))
        #make sure it is writable
        try:
            f = open(cfile1,'w')
            f.write('bob')
        finally:
            f.close()
        # try again with same code fragment -- should get unique name
        file = q.unique_module_name('bob')
        cfile2 = file+'.cpp'
        assert(not os.path.exists(cfile2+'.cpp'))
        os.remove(cfile1)
    def check_add_function_persistent1(self):
        """ Test persisting a function in the default catalog
        """
        clear_temp_catalog()
        q = catalog.catalog()
        mod_name = q.unique_module_name('bob')
        d,f = os.path.split(mod_name)
        module_name, funcs = simple_module(d,f,'f')
        for i in funcs:
            q.add_function_persistent('code',i)
        pfuncs = q.get_cataloged_functions('code')
        os.remove(module_name)
        # any way to clean modules???
        restore_temp_catalog()
        for i in funcs:
            assert(i in pfuncs)

    def not_sure_about_this_check_add_function_persistent2(self):
        """ Test ordering of persistent functions
        """
        clear_temp_catalog()
        q = catalog.catalog()

        mod_name = q.unique_module_name('bob')
        d,f = os.path.split(mod_name)
        module_name1, funcs1 = simple_module(d,f,'f')
        for i in funcs1:
            q.add_function_persistent('code',i)

        d = empty_temp_dir()
        q = catalog.catalog(d)
        mod_name = q.unique_module_name('bob')
        d,f = os.path.split(mod_name)
        module_name2, funcs2 = simple_module(d,f,'f')
        for i in funcs2:
            q.add_function_persistent('code',i)
        pfuncs = q.get_cataloged_functions('code')

        os.remove(module_name1)
        os.remove(module_name2)
        cleanup_temp_dir(d)
        restore_temp_catalog()
        # any way to clean modules???
        for i in funcs1:
            assert(i in pfuncs)
        for i in funcs2:
            assert(i in pfuncs)
        # make sure functions occur in correct order for
        # lookup
        all_funcs = zip(funcs1,funcs2)
        print all_funcs
        for a,b in all_funcs:
            assert(pfuncs.index(a) > pfuncs.index(b))

        assert(len(pfuncs) == 4)

    def check_add_function_ordered(self):
        clear_temp_catalog()
        q = catalog.catalog()
        import string

        q.add_function('f',string.upper)
        q.add_function('f',string.lower)
        q.add_function('ff',string.find)
        q.add_function('ff',string.replace)
        q.add_function('fff',string.atof)
        q.add_function('fff',string.atoi)
        del q

        # now we're gonna make a new catalog with same code
        # but different functions in a specified module directory
        env_dir = empty_temp_dir()
        r = catalog.catalog(env_dir)
        r.add_function('ff',os.abort)
        r.add_function('ff',os.chdir)
        r.add_function('fff',os.access)
        r.add_function('fff',os.open)
        del r
        # now we're gonna make a new catalog with same code
        # but different functions in a user specified directory
        user_dir = empty_temp_dir()
        s = catalog.catalog(user_dir)
        import re
        s.add_function('fff',re.match)
        s.add_function('fff',re.purge)
        del s

        # open new catalog and make sure it retreives the functions
        # from d catalog instead of the temp catalog (made by q)
        os.environ['PYTHONCOMPILED'] = env_dir
        t = catalog.catalog(user_dir)
        funcs1 = t.get_functions('f')
        funcs2 = t.get_functions('ff')
        funcs3 = t.get_functions('fff')
        restore_temp_catalog()
        # make sure everything is read back in the correct order
        assert(funcs1 == [string.lower,string.upper])
        assert(funcs2 == [os.chdir,os.abort,string.replace,string.find])
        assert(funcs3 == [re.purge,re.match,os.open,
                          os.access,string.atoi,string.atof])
        cleanup_temp_dir(user_dir)
        cleanup_temp_dir(env_dir)

def test_suite():
    suites = []
    suites.append( unittest.makeSuite(test_default_dir,'check_'))
    suites.append( unittest.makeSuite(test_os_dependent_catalog_name,'check_'))
    suites.append( unittest.makeSuite(test_catalog_path,'check_'))
    suites.append( unittest.makeSuite(test_get_catalog,'check_'))
    suites.append( unittest.makeSuite(test_catalog,'check_'))

    total_suite = unittest.TestSuite(suites)
    return total_suite

def test():
    all_tests = test_suite()
    runner = unittest.TextTestRunner()
    runner.run(all_tests)
    return runner

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


<commit_before>from config import credentials
import requests
import time
import datetime

class NextBusChecker:
    def __init__(self):
        self.last_data_updated_at = None
        self.last_data_minutes_to_next_bus = None
        self.minutes_to_next_bus = None

    def get_data_from_api(self):
        """
        Gets data from Trafiklab Api

        Api call format:
        https://api.sl.se/api2/realtimedepartures.json?key=<TRAFIKLAB_API_KEY>&siteid=<SITEID>&timewindow=<TIMEWINDOW>
        SITEID for Ekensberg is 1600 (2015-02-07)
        TIMEWINDOW is integer for minutes from now, max is 60.

        Api call for Ekensberg for 60 minutes:
        https://api.sl.se/api2/realtimedepartures.json?key=<TRAFIKLAB_API_KEY>&siteid=1600&timewindow=60

        Example response:
        {
            "StatusCode": 0,
            "Message": null,
            "ExecutionTime": 50,
            "ResponseData": {
                "LatestUpdate": "2015-02-07T22:35:44",
                "DataAge": 15,
                "Metros": [],
                "Buses": [
                    {
                        "JourneyDirection": 2,
                        "GroupOfLine": null,
                        "StopAreaName": "Ekensberg",
                        "StopAreaNumber": 14066,
                        "StopPointNumber": 14066,
                        "StopPointDesignation": null,
                        "TimeTabledDateTime": "2015-02-07T23:00:00",
                        "ExpectedDateTime": "2015-02-07T23:00:00",
                        "DisplayTime": "24 min",
                        "Deviations": null,
                        "TransportMode": "BUS",
                        "LineNumber": "133",
                        "Destination": "Liljeholmen",
                        "SiteId": 1600
                    },
                    {
                        "JourneyDirection": 2,
                        "GroupOfLine": null,
                        "StopAreaName": "Ekensberg",
                        "StopAreaNumber": 14066,
                        "StopPointNumber": 14066,
                        "StopPointDesignation": null,
                        "TimeTabledDateTime": "2015-02-07T23:30:00",
                        "ExpectedDateTime": "2015-02-07T23:30:00",
                        "DisplayTime": "23:30",
                        "Deviations": null,
                        "TransportMode": "BUS",
                        "LineNumber": "133",
                        "Destination": "Liljeholmen",
                        "SiteId": 1600
                    }
                ],
                "Trains": [],
                "Trams": [],
                "Ships": [],
                "StopPointDeviations": []
            }
        }
        """

        api_url = "https://api.sl.se/api2/realtimedepartures.json?key=%s&siteid=1600&timewindow=60" % credentials.TRAFIKLAB_API_KEY

        try:
            api_request = requests.get(api_url, timeout=10)
        except:
            api_result = "No data"
        else:
            api_result = api_request.json()

        return api_result

    def get_minutes_to_next_bus(self):
        """
        Gets minutes to next bus
        """
        api_result = self.get_data_from_api()
        print api_result
        try:
            expected_time = api_result["ResponseData"]["Buses"][0]["ExpectedDateTime"]
            sl_time = api_result["ResponseData"]["LatestUpdate"]
        except (KeyError, TypeError):
            return "No data"
        expected_time = datetime.datetime.strptime(expected_time, "%Y-%m-%dT%H:%M:%S")
        sl_time = datetime.datetime.strptime(sl_time, "%Y-%m-%dT%H:%M:%S")
        minutes = (expected_time - sl_time).seconds / 60
        return minutes

    def print_next_bus(self):
        print "Next bus leaves in: %s" % self.get_minutes_to_next_bus()
        return

    def tick(self):
        now = datetime.datetime.now()
        if self.last_data_updated_at is not None:
            if (now - self.last_data_updated_at).seconds < 30:
                return

        # TODO: if no bus until time X, don't get new data until time X - 15 minutes

        data = self.get_minutes_to_next_bus()
        if data == "No data":
            return

        self.last_data_updated_at = now
        self.last_data_minutes_to_next_bus = data

        self.print_next_bus()

    def loop(self):
        while True:
            # tick every second
            self.tick()
            time.sleep(1)

if __name__ == "__main__":
    next_bus_checker = NextBusChecker()
    next_bus_checker.loop()<commit_msg>updated print_next_bus<commit_after>from config import credentials
import requests
import time
import datetime

class NextBusChecker:
    def __init__(self):
        self.last_data_updated_at = None
        self.last_data_minutes_to_next_bus = None
        self.minutes_to_next_bus = None

    def get_data_from_api(self):
        """
        Gets data from Trafiklab Api

        Api call format:
        https://api.sl.se/api2/realtimedepartures.json?key=<TRAFIKLAB_API_KEY>&siteid=<SITEID>&timewindow=<TIMEWINDOW>
        SITEID for Ekensberg is 1600 (2015-02-07)
        TIMEWINDOW is integer for minutes from now, max is 60.

        Api call for Ekensberg for 60 minutes:
        https://api.sl.se/api2/realtimedepartures.json?key=<TRAFIKLAB_API_KEY>&siteid=1600&timewindow=60

        Example response:
        {
            "StatusCode": 0,
            "Message": null,
            "ExecutionTime": 50,
            "ResponseData": {
                "LatestUpdate": "2015-02-07T22:35:44",
                "DataAge": 15,
                "Metros": [],
                "Buses": [
                    {
                        "JourneyDirection": 2,
                        "GroupOfLine": null,
                        "StopAreaName": "Ekensberg",
                        "StopAreaNumber": 14066,
                        "StopPointNumber": 14066,
                        "StopPointDesignation": null,
                        "TimeTabledDateTime": "2015-02-07T23:00:00",
                        "ExpectedDateTime": "2015-02-07T23:00:00",
                        "DisplayTime": "24 min",
                        "Deviations": null,
                        "TransportMode": "BUS",
                        "LineNumber": "133",
                        "Destination": "Liljeholmen",
                        "SiteId": 1600
                    },
                    {
                        "JourneyDirection": 2,
                        "GroupOfLine": null,
                        "StopAreaName": "Ekensberg",
                        "StopAreaNumber": 14066,
                        "StopPointNumber": 14066,
                        "StopPointDesignation": null,
                        "TimeTabledDateTime": "2015-02-07T23:30:00",
                        "ExpectedDateTime": "2015-02-07T23:30:00",
                        "DisplayTime": "23:30",
                        "Deviations": null,
                        "TransportMode": "BUS",
                        "LineNumber": "133",
                        "Destination": "Liljeholmen",
                        "SiteId": 1600
                    }
                ],
                "Trains": [],
                "Trams": [],
                "Ships": [],
                "StopPointDeviations": []
            }
        }
        """

        api_url = "https://api.sl.se/api2/realtimedepartures.json?key=%s&siteid=1600&timewindow=60" % credentials.TRAFIKLAB_API_KEY

        try:
            api_request = requests.get(api_url, timeout=10)
        except:
            api_result = "No data"
        else:
            api_result = api_request.json()

        return api_result

    def get_minutes_to_next_bus(self):
        """
        Gets minutes to next bus
        """
        api_result = self.get_data_from_api()
        print api_result
        try:
            expected_time = api_result["ResponseData"]["Buses"][0]["ExpectedDateTime"]
            sl_time = api_result["ResponseData"]["LatestUpdate"]
        except (KeyError, TypeError):
            return "No data"
        expected_time = datetime.datetime.strptime(expected_time, "%Y-%m-%dT%H:%M:%S")
        sl_time = datetime.datetime.strptime(sl_time, "%Y-%m-%dT%H:%M:%S")
        minutes = (expected_time - sl_time).seconds / 60
        return minutes

    def print_next_bus(self):
        print "Next bus leaves in: %s" % self.minutes_to_next_bus
        return

    def tick(self):
        now = datetime.datetime.now()

        # TODO: update minutes_to_next_bus using now, last_data_minutes_to_next_bus and last_data_updated_at

        if self.last_data_updated_at is not None:
            if (now - self.last_data_updated_at).seconds < 30:
                return

        # TODO: if no bus until time X, don't get new data until time X - 15 minutes

        data = self.get_minutes_to_next_bus()
        if data == "No data":
            return

        self.last_data_updated_at = now
        self.last_data_minutes_to_next_bus = data
        self.minutes_to_next_bus = self.last_data_minutes_to_next_bus
        self.print_next_bus()

    def loop(self):
        while True:
            # tick every second
            self.tick()
            time.sleep(1)

if __name__ == "__main__":
    next_bus_checker = NextBusChecker()
    next_bus_checker.loop()<|endoftext|>


<commit_before>import numpy as np
from game.displays.null_display import NullDisplay

"""The simple rule AI - if oponent has 2 in a row - block it"""
class RulePlayerV1:
  def __init__(self, player_no):
    self.player_no = player_no
    if player_no == 1:
      self.other_player = 2
    else:
      self.other_player = 1

  def get_input(self, board):
    for i in range(0, board.shape[0]):                     # rows
      if self.two_in_a_row(board[i, :]):
        # print('Found two in row ', i)
        y = np.where(board[i, :] == 0)[0][0]
        return [i, y]

    for i in range(0, board.shape[1]):                     # columns
      if self.two_in_a_row(board[:, i]):
        # print('Found two in col ', i)
        x = np.where(board[:, i] == 0)[0][0]
        return [x, i]

    if self.two_in_a_row(np.diag(board)): # diagonal
      # print('Found two on diag ')
      diag_pos = np.where(np.diag(board) == 0)[0][0]
      return [diag_pos, diag_pos]

    if self.two_in_a_row(np.diag(np.flipud(board))): # anty-diagonal
      # print('Found two on anty-diag ')
      anyy_diag_pos = np.where(np.diag(np.flipud(board)) == 0)[0][0]
      return [board.shape[0] - 1 - anty_diag_pos, anty_diag_pos]
    # print('not found - falling back to random')
    return self.random_input(board)

  def random_input(self, board):
    empty_indexes = np.where(board == 0)
    zipped = np.column_stack(empty_indexes)
    np.random.shuffle(zipped)
    return zipped[0]

  def two_in_a_row(self, row):
    row = row.copy()
    row.sort()
    if row[0] == 0 and row[1] == self.other_player and row[2] == self.other_player: return True
    return False

  def display_class(self):
    return NullDisplay<commit_msg>Fix another bug (typo)<commit_after>import numpy as np
from game.displays.null_display import NullDisplay

"""The simple rule AI - if oponent has 2 in a row - block it"""
class RulePlayerV1:
  def __init__(self, player_no):
    self.player_no = player_no
    if player_no == 1:
      self.other_player = 2
    else:
      self.other_player = 1

  def get_input(self, board):
    for i in range(0, board.shape[0]):                     # rows
      if self.two_in_a_row(board[i, :]):
        # print('Found two in row ', i)
        y = np.where(board[i, :] == 0)[0][0]
        return [i, y]

    for i in range(0, board.shape[1]):                     # columns
      if self.two_in_a_row(board[:, i]):
        # print('Found two in col ', i)
        x = np.where(board[:, i] == 0)[0][0]
        return [x, i]

    if self.two_in_a_row(np.diag(board)): # diagonal
      # print('Found two on diag ')
      diag_pos = np.where(np.diag(board) == 0)[0][0]
      return [diag_pos, diag_pos]

    if self.two_in_a_row(np.diag(np.flipud(board))): # anty-diagonal
      # print('Found two on anty-diag ')
      anty_diag_pos = np.where(np.diag(np.flipud(board)) == 0)[0][0]
      return [board.shape[0] - 1 - anty_diag_pos, anty_diag_pos]
    # print('not found - falling back to random')
    return self.random_input(board)

  def random_input(self, board):
    empty_indexes = np.where(board == 0)
    zipped = np.column_stack(empty_indexes)
    np.random.shuffle(zipped)
    return zipped[0]

  def two_in_a_row(self, row):
    row = row.copy()
    row.sort()
    if row[0] == 0 and row[1] == self.other_player and row[2] == self.other_player: return True
    return False

  def display_class(self):
    return NullDisplay<|endoftext|>


<commit_before>from __future__ import absolute_import, division, print_function

from collections import Iterator
from contextlib import contextmanager
import os
import gzip
import tempfile

from .compatibility import unicode

def raises(err, lamda):
    try:
        lamda()
        return False
    except err:
        return True

def deepmap(func, *seqs):
    """ Apply function inside nested lists

    >>> inc = lambda x: x + 1
    >>> deepmap(inc, [[1, 2], [3, 4]])
    [[2, 3], [4, 5]]

    >>> add = lambda x, y: x + y
    >>> deepmap(add, [[1, 2], [3, 4]], [[10, 20], [30, 40]])
    [[11, 22], [33, 44]]
    """
    if isinstance(seqs[0], (list, Iterator)):
        return [deepmap(func, *items) for items in zip(*seqs)]
    else:
        return func(*seqs)

@contextmanager
def ignoring(*exceptions):
    try:
        yield
    except exceptions:
        pass

@contextmanager
def tmpfile(extension=''):
    extension = '.' + extension.lstrip('.')
    handle, filename = tempfile.mkstemp(extension)
    os.close(handle)
    os.remove(filename)

    try:
        yield filename
    finally:
        if os.path.exists(filename):
            if os.path.isdir(filename):
                shutil.rmtree(filename)
            else:
                os.remove(filename)

@contextmanager
def filetext(text, extension='', open=open, mode='w'):
    with tmpfile(extension=extension) as filename:
        f = open(filename, mode=mode)
        try:
            f.write(text)
        finally:
            try:
                f.close()
            except AttributeError:
                pass

        yield filename

def repr_long_list(seq):
    """

    >>> repr_long_list(list(range(100)))
    '[0, 1, 2, ..., 98, 99]'
    """
    if len(seq) < 8:
        return repr(seq)
    else:
        return repr(seq[:3])[:-1] + ', ..., ' + repr(seq[-2:])[1:]

class IndexCallable(object):
    """ Provide getitem syntax for functions

    >>> def inc(x):
    ...     return x + 1

    >>> I = IndexCallable(inc)
    >>> I[3]
    4
    """
    __slots__ = 'fn',
    def __init__(self, fn):
        self.fn = fn

    def __getitem__(self, key):
        return self.fn(key)

@contextmanager
def filetexts(d, open=open):
    """ Dumps a number of textfiles to disk

    d - dict
        a mapping from filename to text like {'a.csv': '1,1\n2,2'}
    """
    for filename, text in d.items():
        f = open(filename, 'wt')
        try:
            f.write(text)
        finally:
            try:
                f.close()
            except AttributeError:
                pass

    yield list(d)

    for filename in d:
        if os.path.exists(filename):
            os.remove(filename)

opens = {'gzip': gzip.open}

def textblock(file, start, stop, compression=None):
    """ Pull out a block of text from a file given start and stop bytes

    This gets data starting/ending from the next newline delimiter

    Example
    -------

    >>> with open('myfile.txt', 'w') as f:
    ...     f.write('123\n456\n789\nabc')

    >>> f = open('myfile.txt')
    >>> textblock(f, 1, 10)  # Note that 1 and 10 don't line up with endlines
    '456\n789\n'
    """
    if isinstance(file, (str, unicode)):
        myopen = opens.get(compression, open)
        f = myopen(file)
        try:
            result = textblock(f, start, stop)
        finally:
            f.close()
        return result
    file.seek(start)
    if start:
        char = file.read(1)
        while char and char != '\n':
            char = file.read(1)
            start += 1
        start += 1

    if stop is None:
        file.seek(start)
        return file.read()

    file.seek(stop)
    char = file.read(1)
    while char and char != '\n':
        char = file.read(1)
        stop += 1

    file.seek(start)
    return file.read(stop - start + 1)
<commit_msg>comment out doctest with endlines<commit_after>from __future__ import absolute_import, division, print_function

from collections import Iterator
from contextlib import contextmanager
import os
import gzip
import tempfile

from .compatibility import unicode

def raises(err, lamda):
    try:
        lamda()
        return False
    except err:
        return True

def deepmap(func, *seqs):
    """ Apply function inside nested lists

    >>> inc = lambda x: x + 1
    >>> deepmap(inc, [[1, 2], [3, 4]])
    [[2, 3], [4, 5]]

    >>> add = lambda x, y: x + y
    >>> deepmap(add, [[1, 2], [3, 4]], [[10, 20], [30, 40]])
    [[11, 22], [33, 44]]
    """
    if isinstance(seqs[0], (list, Iterator)):
        return [deepmap(func, *items) for items in zip(*seqs)]
    else:
        return func(*seqs)

@contextmanager
def ignoring(*exceptions):
    try:
        yield
    except exceptions:
        pass

@contextmanager
def tmpfile(extension=''):
    extension = '.' + extension.lstrip('.')
    handle, filename = tempfile.mkstemp(extension)
    os.close(handle)
    os.remove(filename)

    try:
        yield filename
    finally:
        if os.path.exists(filename):
            if os.path.isdir(filename):
                shutil.rmtree(filename)
            else:
                os.remove(filename)

@contextmanager
def filetext(text, extension='', open=open, mode='w'):
    with tmpfile(extension=extension) as filename:
        f = open(filename, mode=mode)
        try:
            f.write(text)
        finally:
            try:
                f.close()
            except AttributeError:
                pass

        yield filename

def repr_long_list(seq):
    """

    >>> repr_long_list(list(range(100)))
    '[0, 1, 2, ..., 98, 99]'
    """
    if len(seq) < 8:
        return repr(seq)
    else:
        return repr(seq[:3])[:-1] + ', ..., ' + repr(seq[-2:])[1:]

class IndexCallable(object):
    """ Provide getitem syntax for functions

    >>> def inc(x):
    ...     return x + 1

    >>> I = IndexCallable(inc)
    >>> I[3]
    4
    """
    __slots__ = 'fn',
    def __init__(self, fn):
        self.fn = fn

    def __getitem__(self, key):
        return self.fn(key)

@contextmanager
def filetexts(d, open=open):
    """ Dumps a number of textfiles to disk

    d - dict
        a mapping from filename to text like {'a.csv': '1,1\n2,2'}
    """
    for filename, text in d.items():
        f = open(filename, 'wt')
        try:
            f.write(text)
        finally:
            try:
                f.close()
            except AttributeError:
                pass

    yield list(d)

    for filename in d:
        if os.path.exists(filename):
            os.remove(filename)

opens = {'gzip': gzip.open}

def textblock(file, start, stop, compression=None):
    """ Pull out a block of text from a file given start and stop bytes

    This gets data starting/ending from the next newline delimiter

    Example
    -------

    >> with open('myfile.txt', 'w') as f:
    ..     f.write('123\n456\n789\nabc')

    >> f = open('myfile.txt')

    In the example below, 1 and 10 don't line up with endlines

    >> textblock(f, 1, 10)
    '456\n789\n'
    """
    if isinstance(file, (str, unicode)):
        myopen = opens.get(compression, open)
        f = myopen(file)
        try:
            result = textblock(f, start, stop)
        finally:
            f.close()
        return result
    file.seek(start)
    if start:
        char = file.read(1)
        while char and char != '\n':
            char = file.read(1)
            start += 1
        start += 1

    if stop is None:
        file.seek(start)
        return file.read()

    file.seek(stop)
    char = file.read(1)
    while char and char != '\n':
        char = file.read(1)
        stop += 1

    file.seek(start)
    return file.read(stop - start + 1)
<|endoftext|>


<commit_before>from sqlalchemy import ForeignKey
from werkzeug.security import generate_password_hash, check_password_hash

from app import db

class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key = True)
    email = db.Column(db.String(120), unique = True)
    pwdhash = db.Column(db.String(54))

    def __init__(self, email, password):
        self.email = email.lower()
        self.pwdhash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.pwdhash, password)

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return unicode(self.id)

    def __repr__(self):
        return '<User %r>' % (self.username)

# class with name URL does not work (URL - Uniform Resource Locator)
class Locator(db.Model):
    __tablename__ = 'locator'
    id = db.Column(db.Integer, primary_key = True)
    url = db.Column(db.String(500))
    title = db.Column(db.String(500))
    groupname = db.Column(db.String(25))
    date = db.Column(db.Date)
    email = db.Column(db.String(64), ForeignKey('user.email'))

    def __repr__(self):
        return '<URL %r>' % (self.url)<commit_msg>small change<commit_after>from sqlalchemy import ForeignKey
from werkzeug.security import generate_password_hash, check_password_hash

from app import db

class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key = True)
    email = db.Column(db.String(120), unique = True)
    pwdhash = db.Column(db.String(54))

    def __init__(self, email, password):
        self.email = email.lower()
        self.pwdhash = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.pwdhash, password)

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return unicode(self.id)

    def __repr__(self):
        return '<User %r>' % (self.email)

# class with name URL does not work (URL - Uniform Resource Locator)
class Locator(db.Model):
    __tablename__ = 'locator'
    id = db.Column(db.Integer, primary_key = True)
    url = db.Column(db.String(500))
    title = db.Column(db.String(500))
    groupname = db.Column(db.String(25))
    date = db.Column(db.Date)
    email = db.Column(db.String(64), ForeignKey('user.email'))

    def __repr__(self):
        return '<URL %r>' % (self.url)<|endoftext|>


<commit_before>class InProgress(Exception):
	def __rep__(self):
		return "inprogress"

	def __str__(self):
		return "inprogress"

class Unknown(Exception):
	def __rep__(self):
		return "unknwown"

	def __str__(self):
		return "unknwown"
<commit_msg>Clean code<commit_after>class InProgress(Exception):
        pass

class Unknown(Exception):
        pass
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from twisted.internet import reactor
from twisted.web import client
from twisted.web.client import Agent, RedirectAgent
client._HTTP11ClientFactory.noisy = False

class ResolverAgent(RedirectAgent):

    def __init__(self, uri, connectTimeout=15, redirectLimit=20):
        self.lastURI = uri
        RedirectAgent.__init__(self, Agent(reactor, connectTimeout=connectTimeout), redirectLimit=redirectLimit)

    def resolve(self):
        return self.request('HEAD', self.lastURI)

    def _handleRedirect(self, response, method, uri, headers, redirectCount):
        if redirectCount >= self._redirectLimit:
            # Infinite redirection detected, keep lastURI
            return response
        locationHeaders = response.headers.getRawHeaders('location', [])
        if not locationHeaders:
            err = error.RedirectWithNoLocation(
                response.code, 'No location header field', uri)
            raise ResponseFailed([failure.Failure(err)], response)
        self.lastURI = locationHeaders[0]
        deferred = self._agent.request(method, self.lastURI, headers)
        return deferred.addCallback(self._handleResponse, method, uri, headers, redirectCount + 1)

<commit_msg>fix redirects with relative location<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from twisted.internet import reactor
from twisted.web import client
from twisted.web.client import Agent, RedirectAgent
client._HTTP11ClientFactory.noisy = False

class ResolverAgent(RedirectAgent):

    def __init__(self, uri, connectTimeout=15, redirectLimit=20):
        self.lastURI = uri
        RedirectAgent.__init__(self, Agent(reactor, connectTimeout=connectTimeout), redirectLimit=redirectLimit)

    def resolve(self):
        return self.request('HEAD', self.lastURI)

    def _handleRedirect(self, response, method, uri, headers, redirectCount):
        if redirectCount >= self._redirectLimit:
            # Infinite redirection detected, keep lastURI
            return response
        locationHeaders = response.headers.getRawHeaders('location', [])
        if not locationHeaders:
            err = error.RedirectWithNoLocation(
                response.code, 'No location header field', uri)
            raise ResponseFailed([failure.Failure(err)], response)
        try:
            host = self.lastURI[:(self.lastURI+"/").index('/', 8)]
        except:
            host = "http:/"
        self.lastURI = locationHeaders[0].lstrip('/')
        if not self.lastURI.startswith('http'):
            self.lastURI = "%s/%s" % (host, self.lastURI)
        deferred = self._agent.request(method, self.lastURI, headers)
        return deferred.addCallback(self._handleResponse, method, uri, headers, redirectCount + 1)

<|endoftext|>


<commit_before># gaussfitter.py
# created by Adam Ginsburg (adam.ginsburg@colorado.edu or keflavich@gmail.com) 3/17/08)
import numpy
from scipy import optimize
from scipy import stats
from mpfit import mpfit

def moments(data,circle,rotate,vheight):
    """Returns (height, amplitude, x, y, width_x, width_y, rotation angle)
    the gaussian parameters of a 2D distribution by calculating its
    moments.  Depending on the input parameters, will only output
    a subset of the above"""
    total = numpy.abs(data).sum()
    Y, X = numpy.indices(data.shape) # python convention: reverse x,y numpy.indices
    x = (X*numpy.abs(data)).sum()/total
    y = (Y*numpy.abs(data)).sum()/total
    col = data[:, int(y)]
    width_x = numpy.sqrt(numpy.abs((numpy.arange(col.size)-y)**2*col).sum()/numpy.abs(col).sum())
    row = data[int(x), :]
    width_y = numpy.sqrt(numpy.abs((numpy.arange(row.size)-x)**2*row).sum()/numpy.abs(row).sum())
    width = ( width_x + width_y ) / 2.
    height = stats.mode(data.ravel())[0][0]
    amplitude = data.max()-height
    mylist = [amplitude,x,y]
    if numpy.isnan(width_y) or numpy.isnan(width_x) or numpy.isnan(height) or numpy.isnan(amplitude):
        raise ValueError("something is nan")
    if vheight==1:
        mylist = [height] + mylist
    if circle==0:
        mylist = mylist + [width_x,width_y]
    else:
        mylist = mylist + [width]
    if rotate==1:
        mylist = mylist + [0.] #rotation "moment" is just zero...
    return tuple(mylist)

def twodgaussian(inpars, circle=0, rotate=1, vheight=1):
    """Returns a 2d gaussian function of the form:
        x' = numpy.cos(rota) * x - numpy.sin(rota) * y
        y' = numpy.sin(rota) * x + numpy.cos(rota) * y
        (rota should be in degrees)
        g = b + a numpy.exp ( - ( ((x-center_x)/width_x)**2 +
        ((y-center_y)/width_y)**2 ) / 2 )

        where x and y are the input parameters of the returned function,
        and all other parameters are specified by this function

        However, the above values are passed by list.  The list should be:
        inpars = (height,amplitude,center_x,center_y,width_x,width_y,rota)

        You can choose to ignore / neglect some of the above input parameters
            unumpy.sing the following options:
            circle=0 - default is an elliptical gaussian (different x, y
                widths), but can reduce the input by one parameter if it's a
                circular gaussian
            rotate=1 - default allows rotation of the gaussian ellipse.  Can
                remove last parameter by setting rotate=0
            vheight=1 - default allows a variable height-above-zero, i.e. an
                additive constant for the Gaussian function.  Can remove first
                parameter by setting this to 0
        """
    inpars_old = inpars
    inpars = list(inpars)
    if vheight == 1:
        height = inpars.pop(0)
        height = float(height)
    else:
        height = float(0)
    amplitude, center_x, center_y = inpars.pop(0),inpars.pop(0),inpars.pop(0)
    amplitude = float(amplitude)
    center_x = float(center_x)
    center_y = float(center_y)
    if circle == 1:
        width = inpars.pop(0)
        width_x = float(width)
        width_y = float(width)
    else:
        width_x, width_y = inpars.pop(0),inpars.pop(0)
        width_x = float(width_x)
        width_y = float(width_y)
    if rotate == 1:
        rota = inpars.pop(0)
        rota = pi/180. * float(rota)
        rcen_x = center_x * numpy.cos(rota) - center_y * numpy.sin(rota)
        rcen_y = center_x * numpy.sin(rota) + center_y * numpy.cos(rota)
    else:
        rcen_x = center_x
        rcen_y = center_y
    if len(inpars) > 0:
        raise ValueError("There are still input parameters:" + str(inpars) + \
                " and you've input: " + str(inpars_old) + \
                " circle=%d, rotate=%d, vheight=%d" % (circle,rotate,vheight) )

    def rotgauss(x,y):
        if rotate==1:
            xp = x * numpy.cos(rota) - y * numpy.sin(rota)
            yp = x * numpy.sin(rota) + y * numpy.cos(rota)
        else:
            xp = x
            yp = y
        g = height+amplitude*numpy.exp(
            -(((rcen_x-xp)/width_x)**2+
            ((rcen_y-yp)/width_y)**2)/2.)
        return g
    return rotgauss

def gaussfit(data,err=None,params=[],autoderiv=1,return_all=0,circle=0,
        fixed=repeat(False,7),limitedmin=[False,False,False,False,True,True,True],
        limitedmax=[False,False,False,False,False,False,True],
        minpars=repeat(0,7),maxpars=[0,0,0,0,0,0,360],
        rotate=1,vheight=1,quiet=True):
    """
    Gaussian fitter with the ability to fit a variety of different forms of
    2-dimensional gaussian.

    Input Parameters:
        data - 2-dimensional data array
        err=None - error array with same size as data array
        params=[] - initial input parameters for Gaussian function.
            (height, amplitude, x, y, width_x, width_y, rota)
            if not input, these will be determined from the moments of the system,
            assuming no rotation
        autoderiv=1 - use the autoderiv provided in the lmder.f function (the
            alternative is to us an analytic derivative with lmdif.f: this method
            is less robust)
        return_all=0 - Default is to return only the Gaussian parameters.  See
            below for detail on output
        circle=0 - default is an elliptical gaussian (different x, y widths),
            but can reduce the input by one parameter if it's a circular gaussian
        rotate=1 - default allows rotation of the gaussian ellipse.  Can remove
            last parameter by setting rotate=0.  numpy.expects angle in DEGREES
        vheight=1 - default allows a variable height-above-zero, i.e. an
            additive constant for the Gaussian function.  Can remove first
            parameter by setting this to 0

    Output:
        Default output is a set of Gaussian parameters with the same shape as
            the input parameters

        Can also output the covariance matrix, 'infodict' that contains a lot
            more detail about the fit (see scipy.optimize.leastsq), and a message
            from leastsq telling what the exit status of the fitting routine was

        Warning: Does NOT necessarily output a rotation angle between 0 and 360 degrees.
    """
    if params == []:
        params = (moments(data,circle,rotate,vheight))
    if err == None:
        errorfunction = lambda p: numpy.ravel((twodgaussian(p,circle,rotate,vheight)\
                (*numpy.indices(data.shape)) - data))
    else:
        errorfunction = lambda p: numpy.ravel((twodgaussian(p,circle,rotate,vheight)\
                (*numpy.indices(data.shape)) - data)/err)
    def mpfitfun(data,err):
        if err == None:
            def f(p,fjac=None): return [0,numpy.ravel(data-twodgaussian(p,circle,rotate,vheight)\
                    (*numpy.indices(data.shape)))]
        else:
            def f(p,fjac=None): return [0,numpy.ravel((data-twodgaussian(p,circle,rotate,vheight)\
                    (*numpy.indices(data.shape)))/err)]
        return f
    if rotate == 0:
        params[6] = 0
        fixed[6] = True
    if vheight == 0:
        params[0] = 0
        fixed[0] = True
    if circle == 1:
        params[5] = 0
        fixed[5] = True

    parinfo = [ {'n':0,'value':params[0],'limits':[minpars[0],maxpars[0]],'limited':[limitedmin[0],limitedmax[0]],'fixed':fixed[0],'parname':"HEIGHT",'error':0} ,
                {'n':1,'value':params[1],'limits':[minpars[1],maxpars[1]],'limited':[limitedmin[1],limitedmax[1]],'fixed':fixed[1],'parname':"AMPLITUDE",'error':0},
                {'n':2,'value':params[2],'limits':[minpars[2],maxpars[2]],'limited':[limitedmin[2],limitedmax[2]],'fixed':fixed[2],'parname':"XSHIFT",'error':0},
                {'n':3,'value':params[3],'limits':[minpars[3],maxpars[3]],'limited':[limitedmin[3],limitedmax[3]],'fixed':fixed[3],'parname':"YSHIFT",'error':0},
                {'n':4,'value':params[4],'limits':[minpars[4],maxpars[4]],'limited':[limitedmin[4],limitedmax[4]],'fixed':fixed[4],'parname':"XWIDTH",'error':0},
                {'n':5,'value':params[5],'limits':[minpars[5],maxpars[5]],'limited':[limitedmin[5],limitedmax[5]],'fixed':fixed[5],'parname':"YWIDTH",'error':0},
                {'n':6,'value':params[6],'limits':[minpars[6],maxpars[6]],'limited':[limitedmin[6],limitedmax[6]],'fixed':fixed[6],'parname':"ROTATION",'error':0}]

    if autoderiv == 0:
        # the analytic derivative, while not terribly difficult, is less
        # efficient and useful.  I only bothered putting it here because I was
        # instructed to do so for a class project - please ask if you would
        # like this feature implemented
        raise ValueError("I'm sorry, I haven't implemented this feature yet.")
    else:
#        p, cov, infodict, errmsg, success = optimize.leastsq(errorfunction,\
#                params, full_output=1)
        mp = mpfit(mpfitfun(data,err),parinfo=parinfo,quiet=quiet)
    if  return_all == 0:
        return mp.params
    elif return_all == 1:
        return mp.params,mp.perror

def onedgaussfit(xax,data,err=None,params=[0,1,0,1],fixed=[False,False,False,False],limitedmin=[False,False,False,False],
        limitedmax=[False,False,False,False],minpars=[0,0,0,0],maxpars=[0,0,0,0],
        quiet=True,shh=True):
    """
    Inputs:
       xax - x axis
       data - y axis
       err - error corresponding to data

       params - Fit parameters: Height of background, Amplitude, Shift, Width
       fixed - Is parameter fixed?
       limitedmin/minpars - set lower limits on each parameter
       limitedmax/maxpars - set upper limits on each parameter
       quiet - should MPFIT output each iteration?
       shh - output final parameters?

    Returns:
       Fit parameters
       Model
       Fit errors
       chi2
    """

    def onedgauss(x,H,A,dx,w):
        return H+A*numpy.exp(-(x-dx)**2/(2*w**2))

    def mpfitfun(x,y,err):
        if err == None:
            def f(p,fjac=None): return [0,(y-onedgauss(x,*p))]
        else:
            def f(p,fjac=None): return [0,(y-onedgauss(x,*p))/err]
        return f

    if xax == None:
        xax = numpy.arange(len(data))

    parinfo = [ {'n':0,'value':params[0],'limits':[minpars[0],maxpars[0]],'limited':[limitedmin[0],limitedmax[0]],'fixed':fixed[0],'parname':"HEIGHT",'error':0} ,
                {'n':1,'value':params[1],'limits':[minpars[1],maxpars[1]],'limited':[limitedmin[1],limitedmax[1]],'fixed':fixed[1],'parname':"AMPLITUDE",'error':0},
                {'n':2,'value':params[2],'limits':[minpars[2],maxpars[2]],'limited':[limitedmin[2],limitedmax[2]],'fixed':fixed[2],'parname':"SHIFT",'error':0},
                {'n':3,'value':params[3],'limits':[minpars[3],maxpars[3]],'limited':[limitedmin[3],limitedmax[3]],'fixed':fixed[3],'parname':"WIDTH",'error':0}]

    mp = mpfit(mpfitfun(xax,data,err),parinfo=parinfo,quiet=quiet)
    mpp = mp.params
    mpperr = mp.perror
    chi2 = mp.fnorm

    if not shh:
        for i,p in enumerate(mpp):
            parinfo[i]['value'] = p
            print parinfo[i]['parname'],p," +/- ",mpperr[i]
        print "Chi2: ",mp.fnorm," Reduced Chi2: ",mp.fnorm/len(data)," DOF:",len(data)-len(mpp)

    return mpp,onedgauss(xax,*mpp),mpperr,chi2

<commit_msg>fixed numpy.repeat in gaussfitter<commit_after># gaussfitter.py
# created by Adam Ginsburg (adam.ginsburg@colorado.edu or keflavich@gmail.com) 3/17/08)
import numpy
from scipy import optimize
from scipy import stats
from mpfit import mpfit

def moments(data,circle,rotate,vheight):
    """Returns (height, amplitude, x, y, width_x, width_y, rotation angle)
    the gaussian parameters of a 2D distribution by calculating its
    moments.  Depending on the input parameters, will only output
    a subset of the above"""
    total = numpy.abs(data).sum()
    Y, X = numpy.indices(data.shape) # python convention: reverse x,y numpy.indices
    x = (X*numpy.abs(data)).sum()/total
    y = (Y*numpy.abs(data)).sum()/total
    col = data[:, int(y)]
    width_x = numpy.sqrt(numpy.abs((numpy.arange(col.size)-y)**2*col).sum()/numpy.abs(col).sum())
    row = data[int(x), :]
    width_y = numpy.sqrt(numpy.abs((numpy.arange(row.size)-x)**2*row).sum()/numpy.abs(row).sum())
    width = ( width_x + width_y ) / 2.
    height = stats.mode(data.ravel())[0][0]
    amplitude = data.max()-height
    mylist = [amplitude,x,y]
    if numpy.isnan(width_y) or numpy.isnan(width_x) or numpy.isnan(height) or numpy.isnan(amplitude):
        raise ValueError("something is nan")
    if vheight==1:
        mylist = [height] + mylist
    if circle==0:
        mylist = mylist + [width_x,width_y]
    else:
        mylist = mylist + [width]
    if rotate==1:
        mylist = mylist + [0.] #rotation "moment" is just zero...
    return tuple(mylist)

def twodgaussian(inpars, circle=0, rotate=1, vheight=1):
    """Returns a 2d gaussian function of the form:
        x' = numpy.cos(rota) * x - numpy.sin(rota) * y
        y' = numpy.sin(rota) * x + numpy.cos(rota) * y
        (rota should be in degrees)
        g = b + a numpy.exp ( - ( ((x-center_x)/width_x)**2 +
        ((y-center_y)/width_y)**2 ) / 2 )

        where x and y are the input parameters of the returned function,
        and all other parameters are specified by this function

        However, the above values are passed by list.  The list should be:
        inpars = (height,amplitude,center_x,center_y,width_x,width_y,rota)

        You can choose to ignore / neglect some of the above input parameters
            unumpy.sing the following options:
            circle=0 - default is an elliptical gaussian (different x, y
                widths), but can reduce the input by one parameter if it's a
                circular gaussian
            rotate=1 - default allows rotation of the gaussian ellipse.  Can
                remove last parameter by setting rotate=0
            vheight=1 - default allows a variable height-above-zero, i.e. an
                additive constant for the Gaussian function.  Can remove first
                parameter by setting this to 0
        """
    inpars_old = inpars
    inpars = list(inpars)
    if vheight == 1:
        height = inpars.pop(0)
        height = float(height)
    else:
        height = float(0)
    amplitude, center_x, center_y = inpars.pop(0),inpars.pop(0),inpars.pop(0)
    amplitude = float(amplitude)
    center_x = float(center_x)
    center_y = float(center_y)
    if circle == 1:
        width = inpars.pop(0)
        width_x = float(width)
        width_y = float(width)
    else:
        width_x, width_y = inpars.pop(0),inpars.pop(0)
        width_x = float(width_x)
        width_y = float(width_y)
    if rotate == 1:
        rota = inpars.pop(0)
        rota = pi/180. * float(rota)
        rcen_x = center_x * numpy.cos(rota) - center_y * numpy.sin(rota)
        rcen_y = center_x * numpy.sin(rota) + center_y * numpy.cos(rota)
    else:
        rcen_x = center_x
        rcen_y = center_y
    if len(inpars) > 0:
        raise ValueError("There are still input parameters:" + str(inpars) + \
                " and you've input: " + str(inpars_old) + \
                " circle=%d, rotate=%d, vheight=%d" % (circle,rotate,vheight) )

    def rotgauss(x,y):
        if rotate==1:
            xp = x * numpy.cos(rota) - y * numpy.sin(rota)
            yp = x * numpy.sin(rota) + y * numpy.cos(rota)
        else:
            xp = x
            yp = y
        g = height+amplitude*numpy.exp(
            -(((rcen_x-xp)/width_x)**2+
            ((rcen_y-yp)/width_y)**2)/2.)
        return g
    return rotgauss

def gaussfit(data,err=None,params=[],autoderiv=1,return_all=0,circle=0,
        fixed=numpy.repeat(False,7),limitedmin=[False,False,False,False,True,True,True],
        limitedmax=[False,False,False,False,False,False,True],
        minpars=numpy.repeat(0,7),maxpars=[0,0,0,0,0,0,360],
        rotate=1,vheight=1,quiet=True):
    """
    Gaussian fitter with the ability to fit a variety of different forms of
    2-dimensional gaussian.

    Input Parameters:
        data - 2-dimensional data array
        err=None - error array with same size as data array
        params=[] - initial input parameters for Gaussian function.
            (height, amplitude, x, y, width_x, width_y, rota)
            if not input, these will be determined from the moments of the system,
            assuming no rotation
        autoderiv=1 - use the autoderiv provided in the lmder.f function (the
            alternative is to us an analytic derivative with lmdif.f: this method
            is less robust)
        return_all=0 - Default is to return only the Gaussian parameters.  See
            below for detail on output
        circle=0 - default is an elliptical gaussian (different x, y widths),
            but can reduce the input by one parameter if it's a circular gaussian
        rotate=1 - default allows rotation of the gaussian ellipse.  Can remove
            last parameter by setting rotate=0.  numpy.expects angle in DEGREES
        vheight=1 - default allows a variable height-above-zero, i.e. an
            additive constant for the Gaussian function.  Can remove first
            parameter by setting this to 0

    Output:
        Default output is a set of Gaussian parameters with the same shape as
            the input parameters

        Can also output the covariance matrix, 'infodict' that contains a lot
            more detail about the fit (see scipy.optimize.leastsq), and a message
            from leastsq telling what the exit status of the fitting routine was

        Warning: Does NOT necessarily output a rotation angle between 0 and 360 degrees.
    """
    if params == []:
        params = (moments(data,circle,rotate,vheight))
    if err == None:
        errorfunction = lambda p: numpy.ravel((twodgaussian(p,circle,rotate,vheight)\
                (*numpy.indices(data.shape)) - data))
    else:
        errorfunction = lambda p: numpy.ravel((twodgaussian(p,circle,rotate,vheight)\
                (*numpy.indices(data.shape)) - data)/err)
    def mpfitfun(data,err):
        if err == None:
            def f(p,fjac=None): return [0,numpy.ravel(data-twodgaussian(p,circle,rotate,vheight)\
                    (*numpy.indices(data.shape)))]
        else:
            def f(p,fjac=None): return [0,numpy.ravel((data-twodgaussian(p,circle,rotate,vheight)\
                    (*numpy.indices(data.shape)))/err)]
        return f
    if rotate == 0:
        params[6] = 0
        fixed[6] = True
    if vheight == 0:
        params[0] = 0
        fixed[0] = True
    if circle == 1:
        params[5] = 0
        fixed[5] = True

    parinfo = [ {'n':0,'value':params[0],'limits':[minpars[0],maxpars[0]],'limited':[limitedmin[0],limitedmax[0]],'fixed':fixed[0],'parname':"HEIGHT",'error':0} ,
                {'n':1,'value':params[1],'limits':[minpars[1],maxpars[1]],'limited':[limitedmin[1],limitedmax[1]],'fixed':fixed[1],'parname':"AMPLITUDE",'error':0},
                {'n':2,'value':params[2],'limits':[minpars[2],maxpars[2]],'limited':[limitedmin[2],limitedmax[2]],'fixed':fixed[2],'parname':"XSHIFT",'error':0},
                {'n':3,'value':params[3],'limits':[minpars[3],maxpars[3]],'limited':[limitedmin[3],limitedmax[3]],'fixed':fixed[3],'parname':"YSHIFT",'error':0},
                {'n':4,'value':params[4],'limits':[minpars[4],maxpars[4]],'limited':[limitedmin[4],limitedmax[4]],'fixed':fixed[4],'parname':"XWIDTH",'error':0},
                {'n':5,'value':params[5],'limits':[minpars[5],maxpars[5]],'limited':[limitedmin[5],limitedmax[5]],'fixed':fixed[5],'parname':"YWIDTH",'error':0},
                {'n':6,'value':params[6],'limits':[minpars[6],maxpars[6]],'limited':[limitedmin[6],limitedmax[6]],'fixed':fixed[6],'parname':"ROTATION",'error':0}]

    if autoderiv == 0:
        # the analytic derivative, while not terribly difficult, is less
        # efficient and useful.  I only bothered putting it here because I was
        # instructed to do so for a class project - please ask if you would
        # like this feature implemented
        raise ValueError("I'm sorry, I haven't implemented this feature yet.")
    else:
#        p, cov, infodict, errmsg, success = optimize.leastsq(errorfunction,\
#                params, full_output=1)
        mp = mpfit(mpfitfun(data,err),parinfo=parinfo,quiet=quiet)
    if  return_all == 0:
        return mp.params
    elif return_all == 1:
        return mp.params,mp.perror

def onedgaussfit(xax,data,err=None,params=[0,1,0,1],fixed=[False,False,False,False],limitedmin=[False,False,False,False],
        limitedmax=[False,False,False,False],minpars=[0,0,0,0],maxpars=[0,0,0,0],
        quiet=True,shh=True):
    """
    Inputs:
       xax - x axis
       data - y axis
       err - error corresponding to data

       params - Fit parameters: Height of background, Amplitude, Shift, Width
       fixed - Is parameter fixed?
       limitedmin/minpars - set lower limits on each parameter
       limitedmax/maxpars - set upper limits on each parameter
       quiet - should MPFIT output each iteration?
       shh - output final parameters?

    Returns:
       Fit parameters
       Model
       Fit errors
       chi2
    """

    def onedgauss(x,H,A,dx,w):
        return H+A*numpy.exp(-(x-dx)**2/(2*w**2))

    def mpfitfun(x,y,err):
        if err == None:
            def f(p,fjac=None): return [0,(y-onedgauss(x,*p))]
        else:
            def f(p,fjac=None): return [0,(y-onedgauss(x,*p))/err]
        return f

    if xax == None:
        xax = numpy.arange(len(data))

    parinfo = [ {'n':0,'value':params[0],'limits':[minpars[0],maxpars[0]],'limited':[limitedmin[0],limitedmax[0]],'fixed':fixed[0],'parname':"HEIGHT",'error':0} ,
                {'n':1,'value':params[1],'limits':[minpars[1],maxpars[1]],'limited':[limitedmin[1],limitedmax[1]],'fixed':fixed[1],'parname':"AMPLITUDE",'error':0},
                {'n':2,'value':params[2],'limits':[minpars[2],maxpars[2]],'limited':[limitedmin[2],limitedmax[2]],'fixed':fixed[2],'parname':"SHIFT",'error':0},
                {'n':3,'value':params[3],'limits':[minpars[3],maxpars[3]],'limited':[limitedmin[3],limitedmax[3]],'fixed':fixed[3],'parname':"WIDTH",'error':0}]

    mp = mpfit(mpfitfun(xax,data,err),parinfo=parinfo,quiet=quiet)
    mpp = mp.params
    mpperr = mp.perror
    chi2 = mp.fnorm

    if not shh:
        for i,p in enumerate(mpp):
            parinfo[i]['value'] = p
            print parinfo[i]['parname'],p," +/- ",mpperr[i]
        print "Chi2: ",mp.fnorm," Reduced Chi2: ",mp.fnorm/len(data)," DOF:",len(data)-len(mpp)

    return mpp,onedgauss(xax,*mpp),mpperr,chi2

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import json

from bottle import default_app, route, response, run

app = default_app()

data = {
    'api': '0.13',
    'space': 'coredump',
    'logo': 'https://www.coredump.ch/logo.png',
    'url': 'https://www.coredump.ch/',
    'location': {
        'address': 'Spinnereistrasse 2, 8640 Rapperswil, Switzerland',
        'lat': 47.22936,
        'lon': 8.82949
    },
    'spacefed': {
        'spacenet': False,
        'spacesaml': False,
        'spacephone': False
    },
    'state': {
        'open': None,
        'message': 'Open every monday from 19:30',
    },
    'contact': {
        'irc': 'irc://freenode.net/#coredump',
        'twitter': '@coredump_ch',
        'foursquare': '525c20e5498e875d8231b1e5',
        'email': 'danilo@coredump.ch',
    },
    'issue_report_channels': ['email', 'twitter'],
    'feeds': {
        'blog': {
            'type': 'rss',
            'url': 'https://www.coredump.ch/feed/',
        },
    },
    'cache': {
        'schedule': 'h.02',
    },
    'projects': ['https://github.com/coredump-ch/'],
}

@route('/')
def json_out():
    response.set_header('Access-Control-Allow-Origin', '*')
    response.set_header('Cache-Control', 'no-cache')
    response.set_header('Content-Type', 'application/json')
    return json.dumps(data)

if __name__ == '__main__':
    run(host='localhost', port=8080)
<commit_msg>Added more project URLs<commit_after># -*- coding: utf-8 -*-
import json

from bottle import default_app, route, response, run

app = default_app()

data = {
    'api': '0.13',
    'space': 'coredump',
    'logo': 'https://www.coredump.ch/logo.png',
    'url': 'https://www.coredump.ch/',
    'location': {
        'address': 'Spinnereistrasse 2, 8640 Rapperswil, Switzerland',
        'lat': 47.22936,
        'lon': 8.82949
    },
    'spacefed': {
        'spacenet': False,
        'spacesaml': False,
        'spacephone': False
    },
    'state': {
        'open': None,
        'message': 'Open every monday from 19:30',
    },
    'contact': {
        'irc': 'irc://freenode.net/#coredump',
        'twitter': '@coredump_ch',
        'foursquare': '525c20e5498e875d8231b1e5',
        'email': 'danilo@coredump.ch',
    },
    'issue_report_channels': ['email', 'twitter'],
    'feeds': {
        'blog': {
            'type': 'rss',
            'url': 'https://www.coredump.ch/feed/',
        },
    },
    'cache': {
        'schedule': 'h.02',
    },
    'projects': [
        'https://github.com/coredump-ch/',
        'https://www.coredump.ch/projekte/',
    ],
}

@route('/')
def json_out():
    response.set_header('Access-Control-Allow-Origin', '*')
    response.set_header('Cache-Control', 'no-cache')
    response.set_header('Content-Type', 'application/json')
    return json.dumps(data)

if __name__ == '__main__':
    run(host='localhost', port=8080)
<|endoftext|>


<commit_before>from datetime import timedelta

from django.core.management import call_command
from django.utils.timezone import now

from decisions.celery import app
from decisions.ahjo import fetch as ahjo_fetch
from decisions.subscriptions.process import process_subscriptions
from decisions.ahjo.models import AgendaItem

@app.task()
def fetch_index(limit=50):
    # Fetch all sorts of new data
    # Fetchers should give a date after which all new entries are
    # We will always re-index at least two hours (this is supposed to be run every hour)
    earliest_dates = [now() - timedelta(hours=2)]

    if AgendaItem.objects.count():
        earliest_dates.append(AgendaItem.objects.latest().last_modified_time)

    ahjo_fetch.import_latest(limit)

    # Reindex Haystack
    call_command("update_index",
                 interactive=False,
                 after=min(earliest_dates).isoformat())

@app.task()
def process():
    # Send mail about saved searches
    process_subscriptions()
<commit_msg>actually speed up indexing<commit_after>from datetime import timedelta

from django.core.management import call_command
from django.utils.timezone import now

from decisions.celery import app
from decisions.ahjo import fetch as ahjo_fetch
from decisions.subscriptions.process import process_subscriptions
from decisions.ahjo.models import AgendaItem

@app.task()
def fetch_index(limit=50):
    # Fetch all sorts of new data
    # Fetchers should give a date after which all new entries are
    # We will always re-index at least two hours (this is supposed to be run every hour)
    earliest_dates = [now() - timedelta(hours=2)]

    if AgendaItem.objects.count():
        earliest_dates.append(AgendaItem.objects.latest().last_modified_time)

    ahjo_fetch.import_latest(limit)

    start = min(earliest_dates).isoformat()

    # Reindex Haystack
    call_command("update_index",
                 interactive=False,
                 start_date=start.isoformat())

@app.task()
def process():
    # Send mail about saved searches
    process_subscriptions()
<|endoftext|>


<commit_before>from django.test import TestCase
from blti.validators import *
from blti.crypto import aes128cbc
from blti import BLTIException

class BLTIOAuthTest(TestCase):
    def test_get_consumer(self):
        with self.settings(LTI_CONSUMERS={'ABC': '12345'}):
            self.assertEquals(BLTIOauth().get_consumer('ABC').secret, '12345')
            self.assertEquals(None, BLTIOauth().get_consumer('XYZ'))

class BLTIRolesTest(TestCase):
    def test_has_admin_role(self):
        self.assertEquals(
            True, BLTIRoles().has_admin_role(['Faculty', 'Alumni']))
        self.assertEquals(False, BLTIRoles().has_admin_role(['Guest']))

    def test_has_instructor_role(self):
        self.assertEquals(
            True, BLTIRoles().has_instructor_role(['TeachingAssistant']))
        self.assertEquals(
            False, BLTIRoles().has_instructor_role(['Faculty', 'Alumni']))

    def test_has_learner_role(self):
        self.assertEquals(
            True, BLTIRoles().has_learner_role(['Member']))
        self.assertEquals(
            False, BLTIRoles().has_learner_role(['Faculty', 'Staff']))

    def test_validate(self):
        blti = {'roles': 'Member'}
        self.assertEquals(None, BLTIRoles().validate(blti, 'member'))
        self.assertRaises(
            BLTIException, BLTIRoles().validate, blti, 'admin')

        blti = {'roles': 'Faculty,Staff'}
        self.assertEquals(None, BLTIRoles().validate(blti, 'member'))
        self.assertEquals(None, BLTIRoles().validate(blti, 'admin'))

class CryptoTest(TestCase):
    test_key = 'DUMMY_KEY_FOR_TESTING_1234567890'
    test_iv = 'DUMMY_IV_TESTING'
    msg = ('LTI provides a framework through which an LMS can send some '
           'verifiable information about a user to a third party.')
    padded = ('LTI provides a framework through which an LMS can send '
              'some verifiable information about a user to a third party.'
              '\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f')
    encrypted = ('\xff\xf7\xe1\xed\xeen\xd3\x1a\x01\xe9\xd2\x06\xf7\x14v!'
                 '\xbf\xe5\x11\x0e+\xa6\xf5\xf8\xe7\xc8\xcd\xae\xf6;j$\x00'
                 '\x9c#\xc1\xa7\x1cz;\xcdp\x97\x86\xbef\x9fl\xfb\xbcz\x9eP'
                 '\x91\xa4RltA\xe8\xf1\rb\xbd.+\x97\x8b\xf1\xc9<?7\xabF/'
                 '\x0e\xef\xd7\xc7y\xcb\xbd\x9c\xb7\xa0\x95\x0ciKI\xe1\x08'
                 '\xf7\x1a\x90c\xf1\x7f\xe4\x93\xb11=\xd6\xe2\xc1G\xd15\x05'
                 '\x1b\xab\x07\x1c\xf6H\n\xaa3\xc6\x01H\xcc\xea\xbeh\xd5')

    def test_encrypt(self):
        aes = aes128cbc(self.test_key, self.test_iv)
        self.assertEquals(aes.encrypt(aes.pad(self.msg)), self.encrypted)

    def test_decrypt(self):
        aes = aes128cbc(self.test_key, self.test_iv)
        self.assertEquals(aes.unpad(aes.decrypt(self.encrypted)), self.msg)

    def test_pad(self):
        aes = aes128cbc(self.test_key, self.test_iv)
        self.assertEquals(aes.pad(self.msg), self.padded)

    def test_unpad(self):
        aes = aes128cbc(self.test_key, self.test_iv)
        self.assertEquals(aes.unpad(self.padded), self.msg)
<commit_msg>adds tests for pad/unpad<commit_after>from django.test import TestCase
from blti.validators import *
from blti.crypto import aes128cbc
from blti import BLTIException

class BLTIOAuthTest(TestCase):
    def test_get_consumer(self):
        with self.settings(LTI_CONSUMERS={'ABC': '12345'}):
            self.assertEquals(BLTIOauth().get_consumer('ABC').secret, '12345')
            self.assertEquals(None, BLTIOauth().get_consumer('XYZ'))

class BLTIRolesTest(TestCase):
    def test_has_admin_role(self):
        self.assertEquals(
            True, BLTIRoles().has_admin_role(['Faculty', 'Alumni']))
        self.assertEquals(False, BLTIRoles().has_admin_role(['Guest']))

    def test_has_instructor_role(self):
        self.assertEquals(
            True, BLTIRoles().has_instructor_role(['TeachingAssistant']))
        self.assertEquals(
            False, BLTIRoles().has_instructor_role(['Faculty', 'Alumni']))

    def test_has_learner_role(self):
        self.assertEquals(
            True, BLTIRoles().has_learner_role(['Member']))
        self.assertEquals(
            False, BLTIRoles().has_learner_role(['Faculty', 'Staff']))

    def test_validate(self):
        blti = {'roles': 'Member'}
        self.assertEquals(None, BLTIRoles().validate(blti, 'member'))
        self.assertRaises(
            BLTIException, BLTIRoles().validate, blti, 'admin')

        blti = {'roles': 'Faculty,Staff'}
        self.assertEquals(None, BLTIRoles().validate(blti, 'member'))
        self.assertEquals(None, BLTIRoles().validate(blti, 'admin'))

class CryptoTest(TestCase):
    test_key = 'DUMMY_KEY_FOR_TESTING_1234567890'
    test_iv = 'DUMMY_IV_TESTING'
    msg = ('LTI provides a framework through which an LMS can send some '
           'verifiable information about a user to a third party.')
    padded = ('LTI provides a framework through which an LMS can send '
              'some verifiable information about a user to a third party.'
              '\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f')
    encrypted = ('\xff\xf7\xe1\xed\xeen\xd3\x1a\x01\xe9\xd2\x06\xf7\x14v!'
                 '\xbf\xe5\x11\x0e+\xa6\xf5\xf8\xe7\xc8\xcd\xae\xf6;j$\x00'
                 '\x9c#\xc1\xa7\x1cz;\xcdp\x97\x86\xbef\x9fl\xfb\xbcz\x9eP'
                 '\x91\xa4RltA\xe8\xf1\rb\xbd.+\x97\x8b\xf1\xc9<?7\xabF/'
                 '\x0e\xef\xd7\xc7y\xcb\xbd\x9c\xb7\xa0\x95\x0ciKI\xe1\x08'
                 '\xf7\x1a\x90c\xf1\x7f\xe4\x93\xb11=\xd6\xe2\xc1G\xd15\x05'
                 '\x1b\xab\x07\x1c\xf6H\n\xaa3\xc6\x01H\xcc\xea\xbeh\xd5')

    def test_pad(self):
        aes = aes128cbc(self.test_key, self.test_iv)
        self.assertEquals(aes.pad(self.msg), self.padded)

    def test_unpad(self):
        aes = aes128cbc(self.test_key, self.test_iv)
        self.assertEquals(aes.unpad(self.padded), self.msg)

    def test_encrypt(self):
        aes = aes128cbc(self.test_key, self.test_iv)
        self.assertEquals(aes.encrypt(aes.pad(self.msg)), self.encrypted)

    def test_decrypt(self):
        aes = aes128cbc(self.test_key, self.test_iv)
        self.assertEquals(aes.unpad(aes.decrypt(self.encrypted)), self.msg)
<|endoftext|>


<commit_before>#!/usr/bin/python
import ConfigParser
import getopt
import sys
import ipaddress
import random
import tor
import nmap
import time
import pycurl
import io
__author__ = 'jbollin'

hostlist = []
num_targets = 0
num_hosts = 0
first_run = True
sleep_time = 10

config = ConfigParser.ConfigParser()
config.read('scanner.cfg')
source_port = int(config.get("Scanner", "source_port"))

# helper functions
def refine_targetlist(targets):
    """
    Extract host ips from network blocks and randomize host scan order
    """
    global num_hosts
    outputlist = []
    for target_line in targets:
        target_line = target_line.rstrip()
        if "/" in target_line:
            try:
                for address in (ipaddress.ip_network(unicode(target_line)).hosts()):
                    outputlist.append(str(address))
            except ValueError:
                sys.exit("Invalid address or netmask: " + target_line)
        else:
            outputlist.append(target_line)
    random.shuffle(outputlist)
    return outputlist

def query(url):
    """
    Uses pycurl to fetch a site using the proxy on the SOCKS_PORT.
    """
    socks_port = 9050
    output = io.BytesIO()

    curl_query = pycurl.Curl()
    curl_query.setopt(pycurl.URL, url)
    curl_query.setopt(pycurl.PROXY, 'localhost')
    curl_query.setopt(pycurl.PROXYPORT, socks_port)
    curl_query.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5_HOSTNAME)
    curl_query.setopt(pycurl.WRITEFUNCTION, output.write)

    try:
        curl_query.perform()
        return output.getvalue()
    except pycurl.error as exc:
        return "Unable to reach %s (%s)" % (url, exc)

def printhelp():
    print'    usage: ./nmap-tor.py <options>'
    print'    options:'
    print'      -h, --help        Display this message'
    print'      -t, --target      Specify single IP address or network of target'
    print'      -f, --targetlist  Specify file of IP addresses and/or networks to use as target'
    print'      -p, --portlist    Specify file of ports to be used on target'
    print'      -s, --sleep       Specify time in seconds to sleep between Nmap requests (default:10)'

# System arguments for input and output files
try:
    opts, args = getopt.getopt(sys.argv[1:], "hf:t:p:s:", ["help", "target=", "targetlist=", "portlist=", "sleep="])
except getopt.GetoptError:
    print printhelp()
    sys.exit(2)
if len(args) < 0:
    printhelp()
    sys.exit("There are no arguments listed")
for opt, arg in opts:
    if opt == '-h':
        print printhelp()
        sys.exit(2)
    elif opt in ("-f", "--targetlist"):
        inputfile = arg
        try:
            with open(inputfile) as hostfile:
                hostlist = []
                for host in hostfile:
                    hostlist.append(host)
                num_hosts = len(hostlist)
        except:
            sys.exit("Input file for hosts is not valid")
    elif opt in ("-p", "--portlist"):
        inputfile = arg
        try:
            with open(inputfile) as portfile:
                targetports = []
                for port in portfile:
                    targetports.append(port.strip('\r\n'))
                num_ports = len(targetports)
        except:
            sys.exit("Input file for ports is not valid")
    elif opt in ("-t", "--target"):
        try:
            arg_ucode = unicode(arg)
            target_subnet = ipaddress.IPv4Network(arg_ucode)
            iplist = list(ipaddress.ip_network(target_subnet).hosts())
            for ip in iplist:
                hostlist.append(str(ip.compressed))
        except ipaddress.AddressValueError:
            sys.exit('Invalid IP address')
        except ipaddress.NetmaskValueError:
            sys.exit('Invalid subnet mask')
    elif opt in "-n":
        num_hosts = int(arg)
    elif opt in ("-s", "--sleep"):
        sleep_time = float(arg)

print "[+] Nmap-Tor-Scanner starting up...\n"
targetlist = refine_targetlist(hostlist)

for target in targetlist:
    for dest_port in targetports:
        if not first_run:
            print "\n[+] Sleeping for " + str(sleep_time) + " seconds..."
            time.sleep(sleep_time)
            tor.changeIP()
        else:
            first_run = False
        print(query("https://www.atagar.com/echo.php"))
        print "trying {0:s} on {1:s}".format(target, dest_port)
        nmap.print_scan(nmap.do_scan(target, '-sT -p ' + str(dest_port)))
<commit_msg>added a progress indicator<commit_after>#!/usr/bin/python
import ConfigParser
import getopt
import sys
import ipaddress
import random
import tor
import nmap
import time
import pycurl
import io
__author__ = 'jbollin'

hostlist = []
num_targets = 0
num_hosts = 0
targets_scanned = 0
first_run = True
sleep_time = 10

config = ConfigParser.ConfigParser()
config.read('scanner.cfg')
source_port = int(config.get("Scanner", "source_port"))

# helper functions
def refine_targetlist(targets):
    """
    Extract host ips from network blocks and randomize host scan order
    """
    global num_hosts
    outputlist = []
    for target_line in targets:
        target_line = target_line.rstrip()
        if "/" in target_line:
            try:
                for address in (ipaddress.ip_network(unicode(target_line)).hosts()):
                    outputlist.append(str(address))
            except ValueError:
                sys.exit("Invalid address or netmask: " + target_line)
        else:
            outputlist.append(target_line)
    random.shuffle(outputlist)
    return outputlist

def query(url):
    """
    Uses pycurl to fetch a site using the proxy on the SOCKS_PORT.
    """
    socks_port = 9050
    output = io.BytesIO()

    curl_query = pycurl.Curl()
    curl_query.setopt(pycurl.URL, url)
    curl_query.setopt(pycurl.PROXY, 'localhost')
    curl_query.setopt(pycurl.PROXYPORT, socks_port)
    curl_query.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5_HOSTNAME)
    curl_query.setopt(pycurl.WRITEFUNCTION, output.write)

    try:
        curl_query.perform()
        return output.getvalue()
    except pycurl.error as exc:
        return "Unable to reach %s (%s)" % (url, exc)

def printhelp():
    print'    usage: ./nmap-tor.py <options>'
    print'    options:'
    print'      -h, --help        Display this message'
    print'      -t, --target      Specify single IP address or network of target'
    print'      -f, --targetlist  Specify file of IP addresses and/or networks to use as target'
    print'      -p, --portlist    Specify file of ports to be used on target'
    print'      -s, --sleep       Specify time in seconds to sleep between Nmap requests (default:10)'

# System arguments for input and output files
try:
    opts, args = getopt.getopt(sys.argv[1:], "hf:t:p:s:", ["help", "target=", "targetlist=", "portlist=", "sleep="])
except getopt.GetoptError:
    print printhelp()
    sys.exit(2)
if len(args) < 0:
    printhelp()
    sys.exit("There are no arguments listed")
for opt, arg in opts:
    if opt == '-h':
        print printhelp()
        sys.exit(2)
    elif opt in ("-f", "--targetlist"):
        inputfile = arg
        try:
            with open(inputfile) as hostfile:
                hostlist = []
                for host in hostfile:
                    hostlist.append(host)
                num_hosts = len(hostlist)
        except:
            sys.exit("Input file for hosts is not valid")
    elif opt in ("-p", "--portlist"):
        inputfile = arg
        try:
            with open(inputfile) as portfile:
                targetports = []
                for port in portfile:
                    targetports.append(port.strip('\r\n'))
                num_ports = len(targetports)
        except:
            sys.exit("Input file for ports is not valid")
    elif opt in ("-t", "--target"):
        try:
            arg_ucode = unicode(arg)
            target_subnet = ipaddress.IPv4Network(arg_ucode)
            iplist = list(ipaddress.ip_network(target_subnet).hosts())
            for ip in iplist:
                hostlist.append(str(ip.compressed))
        except ipaddress.AddressValueError:
            sys.exit('Invalid IP address')
        except ipaddress.NetmaskValueError:
            sys.exit('Invalid subnet mask')
    elif opt in "-n":
        num_hosts = int(arg)
    elif opt in ("-s", "--sleep"):
        sleep_time = float(arg)

print "[+] Nmap-Tor-Scanner starting up...\n"
targetlist = refine_targetlist(hostlist)

for target in targetlist:
    for dest_port in targetports:
        if not first_run:
            print "[+] Sleeping for " + str(sleep_time) + " seconds..."
            time.sleep(sleep_time)
            tor.changeIP()
        else:
            first_run = False
        print(query("https://www.atagar.com/echo.php"))
        print "trying {0:s} on {1:s}".format(target, dest_port)
        nmap.print_scan(nmap.do_scan(target, '-sT -p ' + str(dest_port)))
        targets_scanned += 1
        print "\n[+] (" + str(targets_scanned) + "/" + str(len(targetlist)) + ") " + \
              str(round((targets_scanned/float(len(targetlist)))*100, 1)) + "% targets scanned"
<|endoftext|>