Fix tests to allow use of random, but not change each time

--- simplecoin/tests/__init__.py
+++ simplecoin/tests/__init__.py
@@ -1,6 +1,7 @@
 import simplecoin
 import unittest
 import datetime
+import random

 import simplecoin.models as m

@@ -12,6 +13,9 @@
     """ Represents a set of tests that only need the database iniailized, but
     no fixture data """
     def setUp(self, **kwargs):
+        # Set the random seed to a fixed number, causing all use of random
+        # to actually repeat exactly the same every time
+        random.seed(0)
         extra = dict()
         extra.update(kwargs)
         app = simplecoin.create_app('webserver', configs=['test.toml'], **extra)

<|original_code|>
import simplecoin
import unittest
import datetime

import simplecoin.models as m

from decimal import Decimal
from simplecoin import db

class UnitTest(unittest.TestCase):
    """ Represents a set of tests that only need the database iniailized, but
    no fixture data """
    def setUp(self, **kwargs):
        extra = dict()
        extra.update(kwargs)
        app = simplecoin.create_app('webserver', configs=['test.toml'], **extra)
        with app.app_context():
            self.db = simplecoin.db
            self.setup_db()

        self.app = app
        self._ctx = self.app.test_request_context()
        self._ctx.push()
        self.client = self.app.test_client()

    def tearDown(self):
        # dump the test elasticsearch index
        db.session.remove()
        db.drop_all()

    def setup_db(self):
        self.db.drop_all()
        self.db.create_all()
        db.session.commit()

    def make_block(self, **kwargs):
        vals = dict(currency="LTC",
                    height=1,
                    found_at=datetime.datetime.utcnow(),
                    time_started=datetime.datetime.utcnow(),
                    difficulty=12,
                    merged=False,
                    algo="scrypt",
                    total_value=Decimal("50"))
        vals.update(kwargs)
        blk = m.Block(**vals)
        db.session.add(blk)
        return blk

class RedisUnitTest(UnitTest):
    def setUp(self):
        UnitTest.setUp(self)
        self.app.redis.flushdb()

<|edits_diff|>
--- simplecoin/tests/__init__.py
+++ simplecoin/tests/__init__.py
@@ -1,6 +1,7 @@
 import simplecoin
 import unittest
 import datetime
+import random

 import simplecoin.models as m

<|current_version|>
import simplecoin
import unittest
import datetime
import random

import simplecoin.models as m

from decimal import Decimal
from simplecoin import db

class UnitTest(unittest.TestCase):
    """ Represents a set of tests that only need the database iniailized, but
    no fixture data """
    def setUp(self, **kwargs):
        extra = dict()
        extra.update(kwargs)
        app = simplecoin.create_app('webserver', configs=['test.toml'], **extra)
        with app.app_context():
            self.db = simplecoin.db
            self.setup_db()

        self.app = app
        self._ctx = self.app.test_request_context()
        self._ctx.push()
        self.client = self.app.test_client()

    def tearDown(self):
        # dump the test elasticsearch index
        db.session.remove()
        db.drop_all()

    def setup_db(self):
        self.db.drop_all()
        self.db.create_all()
        db.session.commit()

    def make_block(self, **kwargs):
        vals = dict(currency="LTC",
                    height=1,
                    found_at=datetime.datetime.utcnow(),
                    time_started=datetime.datetime.utcnow(),
                    difficulty=12,
                    merged=False,
                    algo="scrypt",
                    total_value=Decimal("50"))
        vals.update(kwargs)
        blk = m.Block(**vals)
        db.session.add(blk)
        return blk

class RedisUnitTest(UnitTest):
    def setUp(self):
        UnitTest.setUp(self)
        self.app.redis.flushdb()

<|next_version|>
import simplecoin
import unittest
import datetime
import random

import simplecoin.models as m

from decimal import Decimal
from simplecoin import db

class UnitTest(unittest.TestCase):
    """ Represents a set of tests that only need the database iniailized, but
    no fixture data """
    def setUp(self, **kwargs):
        # Set the random seed to a fixed number, causing all use of random
        # to actually repeat exactly the same every time
        random.seed(0)
        extra = dict()
        extra.update(kwargs)
        app = simplecoin.create_app('webserver', configs=['test.toml'], **extra)
        with app.app_context():
            self.db = simplecoin.db
            self.setup_db()

        self.app = app
        self._ctx = self.app.test_request_context()
        self._ctx.push()
        self.client = self.app.test_client()

    def tearDown(self):
        # dump the test elasticsearch index
        db.session.remove()
        db.drop_all()

    def setup_db(self):
        self.db.drop_all()
        self.db.create_all()
        db.session.commit()

    def make_block(self, **kwargs):
        vals = dict(currency="LTC",
                    height=1,
                    found_at=datetime.datetime.utcnow(),
                    time_started=datetime.datetime.utcnow(),
                    difficulty=12,
                    merged=False,
                    algo="scrypt",
                    total_value=Decimal("50"))
        vals.update(kwargs)
        blk = m.Block(**vals)
        db.session.add(blk)
        return blk

class RedisUnitTest(UnitTest):
    def setUp(self):
        UnitTest.setUp(self)
        self.app.redis.flushdb()


Add threading to allow for client and server to be run from a single script

--- echo_client.py
+++ echo_client.py
@@ -1,6 +1,8 @@
 #!/usr/bin/env python
 import socket
 import sys
+import echo_server
+from threading import Thread

 def main():
@@ -18,4 +20,6 @@
     return client_socket.recv(1024)

 if __name__ == '__main__':
+    t = Thread(target=echo_server.main)
+    t.start()
     print main()

<|original_code|>
#!/usr/bin/env python
import socket
import sys

def main():
    message = sys.argv[1]
    port = 50000
    address = '127.0.0.1'
    client_socket = socket.socket(
        socket.AF_INET,
        socket.SOCK_STREAM,
        socket.IPPROTO_IP)
    client_socket.connect((address, port))
    client_socket.sendall(message)
    client_socket.shutdown(socket.SHUT_WR)

    return client_socket.recv(1024)

if __name__ == '__main__':
    print main()

<|edits_diff|>
--- echo_client.py
+++ echo_client.py
@@ -1,6 +1,8 @@
 #!/usr/bin/env python
 import socket
 import sys
+import echo_server
+from threading import Thread

 def main():
<|current_version|>
#!/usr/bin/env python
import socket
import sys
import echo_server
from threading import Thread

def main():
    message = sys.argv[1]
    port = 50000
    address = '127.0.0.1'
    client_socket = socket.socket(
        socket.AF_INET,
        socket.SOCK_STREAM,
        socket.IPPROTO_IP)
    client_socket.connect((address, port))
    client_socket.sendall(message)
    client_socket.shutdown(socket.SHUT_WR)

    return client_socket.recv(1024)

if __name__ == '__main__':
    print main()

<|next_version|>
#!/usr/bin/env python
import socket
import sys
import echo_server
from threading import Thread

def main():
    message = sys.argv[1]
    port = 50000
    address = '127.0.0.1'
    client_socket = socket.socket(
        socket.AF_INET,
        socket.SOCK_STREAM,
        socket.IPPROTO_IP)
    client_socket.connect((address, port))
    client_socket.sendall(message)
    client_socket.shutdown(socket.SHUT_WR)

    return client_socket.recv(1024)

if __name__ == '__main__':
    t = Thread(target=echo_server.main)
    t.start()
    print main()


Add docstrings to mocked time methods

Add docstrings to mocked time methods

--- logintokens/tests/util.py
+++ logintokens/tests/util.py
@@ -1,13 +1,25 @@
+"""utility functions for testing logintokens app
+
+"""
 from time import time

 class MockTime:
+    """Provide mocked time and sleep methods to simulate the passage of time.
+
+    """
     time_passed = 0.0

     def time(self):
+        """Return current time with a consistent offset.
+
+        """
         return time() + self.time_passed

     def sleep(self, seconds):
+        """Increase the offset to make it seem as though time has passed.
+
+        """
         self.time_passed += seconds

 mock_time = MockTime()

<|original_code|>
from time import time

class MockTime:
    time_passed = 0.0

    def time(self):
        return time() + self.time_passed

    def sleep(self, seconds):
        self.time_passed += seconds

mock_time = MockTime()

<|edits_diff|>
--- logintokens/tests/util.py
+++ logintokens/tests/util.py
@@ -1,10 +1,19 @@
+"""utility functions for testing logintokens app
+
+"""
 from time import time

 class MockTime:
+    """Provide mocked time and sleep methods to simulate the passage of time.
+
+    """
     time_passed = 0.0

     def time(self):
+        """Return current time with a consistent offset.
+
+        """
         return time() + self.time_passed

     def sleep(self, seconds):
<|current_version|>
"""utility functions for testing logintokens app

"""
from time import time

class MockTime:
    """Provide mocked time and sleep methods to simulate the passage of time.

    """
    time_passed = 0.0

    def time(self):
        """Return current time with a consistent offset.

        """
        return time() + self.time_passed

    def sleep(self, seconds):
        self.time_passed += seconds

mock_time = MockTime()

<|next_version|>
"""utility functions for testing logintokens app

"""
from time import time

class MockTime:
    """Provide mocked time and sleep methods to simulate the passage of time.

    """
    time_passed = 0.0

    def time(self):
        """Return current time with a consistent offset.

        """
        return time() + self.time_passed

    def sleep(self, seconds):
        """Increase the offset to make it seem as though time has passed.

        """
        self.time_passed += seconds

mock_time = MockTime()


Throw 500 error on SQLAlchemy integrity error

--- canopus/views/__init__.py
+++ canopus/views/__init__.py
@@ -1,8 +1,10 @@
 import os
 from datetime import date

+from pyramid.httpexceptions import HTTPBadRequest
 from pyramid.response import FileResponse
 from pyramid.view import view_config
+from sqlalchemy.exc import IntegrityError

 @view_config(route_name='home', renderer='templates/index.html')
@@ -15,3 +17,8 @@
     here = os.path.abspath(os.path.dirname(__file__))
     response = FileResponse(here + '/../static/robots.txt', request=request)
     return response
+
+
+@view_config(context=IntegrityError)
+def bad_request(exc, request):
+    raise HTTPBadRequest()

<|original_code|>
import os
from datetime import date

from pyramid.response import FileResponse
from pyramid.view import view_config

@view_config(route_name='home', renderer='templates/index.html')
def index(request):
    return {'year': date.today().year}

@view_config(route_name='robots')
def robots(request):
    here = os.path.abspath(os.path.dirname(__file__))
    response = FileResponse(here + '/../static/robots.txt', request=request)
    return response

<|edits_diff|>
--- canopus/views/__init__.py
+++ canopus/views/__init__.py
@@ -1,8 +1,10 @@
 import os
 from datetime import date

+from pyramid.httpexceptions import HTTPBadRequest
 from pyramid.response import FileResponse
 from pyramid.view import view_config
+from sqlalchemy.exc import IntegrityError

 @view_config(route_name='home', renderer='templates/index.html')
<|current_version|>
import os
from datetime import date

from pyramid.httpexceptions import HTTPBadRequest
from pyramid.response import FileResponse
from pyramid.view import view_config
from sqlalchemy.exc import IntegrityError

@view_config(route_name='home', renderer='templates/index.html')
def index(request):
    return {'year': date.today().year}

@view_config(route_name='robots')
def robots(request):
    here = os.path.abspath(os.path.dirname(__file__))
    response = FileResponse(here + '/../static/robots.txt', request=request)
    return response

<|next_version|>
import os
from datetime import date

from pyramid.httpexceptions import HTTPBadRequest
from pyramid.response import FileResponse
from pyramid.view import view_config
from sqlalchemy.exc import IntegrityError

@view_config(route_name='home', renderer='templates/index.html')
def index(request):
    return {'year': date.today().year}

@view_config(route_name='robots')
def robots(request):
    here = os.path.abspath(os.path.dirname(__file__))
    response = FileResponse(here + '/../static/robots.txt', request=request)
    return response

@view_config(context=IntegrityError)
def bad_request(exc, request):
    raise HTTPBadRequest()


Add test for MotorAsyncIOReference await support

--- tests/dal/await_syntax.py
+++ tests/dal/await_syntax.py
@@ -1,4 +1,5 @@
 from umongo import Document
+from umongo.dal.motor_asyncio import MotorAsyncIOReference

 # Await syntax related tests are stored in a separate file in order to
 # catch a SyntaxError when Python doesn't support it
@@ -19,6 +20,8 @@
     doc = Doc()
     await doc.commit()

+    assert doc == await MotorAsyncIOReference(Doc, doc.id).fetch()
+
     cursor = Doc.find()
     await test_cursor(cursor)
     cursor = doc.find()

<|original_code|>
from umongo import Document

# Await syntax related tests are stored in a separate file in order to
# catch a SyntaxError when Python doesn't support it
async def test_await_syntax(db):

    class Doc(Document):

        class Meta:
            collection = db.doc

    async def test_cursor(cursor):
        await cursor.count()
        await cursor.to_list(length=10)
        cursor.rewind()
        await cursor.fetch_next
        _ = cursor.next_object()

    doc = Doc()
    await doc.commit()

    cursor = Doc.find()
    await test_cursor(cursor)
    cursor = doc.find()
    await test_cursor(cursor)
    await Doc.find_one()
    await doc.find_one()
    await Doc.ensure_indexes()
    await doc.ensure_indexes()
    await doc.reload()
    await doc.remove()

<|edits_diff|>
--- tests/dal/await_syntax.py
+++ tests/dal/await_syntax.py
@@ -1,4 +1,5 @@
 from umongo import Document
+from umongo.dal.motor_asyncio import MotorAsyncIOReference

 # Await syntax related tests are stored in a separate file in order to
 # catch a SyntaxError when Python doesn't support it
<|current_version|>
from umongo import Document
from umongo.dal.motor_asyncio import MotorAsyncIOReference

# Await syntax related tests are stored in a separate file in order to
# catch a SyntaxError when Python doesn't support it
async def test_await_syntax(db):

    class Doc(Document):

        class Meta:
            collection = db.doc

    async def test_cursor(cursor):
        await cursor.count()
        await cursor.to_list(length=10)
        cursor.rewind()
        await cursor.fetch_next
        _ = cursor.next_object()

    doc = Doc()
    await doc.commit()

    cursor = Doc.find()
    await test_cursor(cursor)
    cursor = doc.find()
    await test_cursor(cursor)
    await Doc.find_one()
    await doc.find_one()
    await Doc.ensure_indexes()
    await doc.ensure_indexes()
    await doc.reload()
    await doc.remove()

<|next_version|>
from umongo import Document
from umongo.dal.motor_asyncio import MotorAsyncIOReference

# Await syntax related tests are stored in a separate file in order to
# catch a SyntaxError when Python doesn't support it
async def test_await_syntax(db):

    class Doc(Document):

        class Meta:
            collection = db.doc

    async def test_cursor(cursor):
        await cursor.count()
        await cursor.to_list(length=10)
        cursor.rewind()
        await cursor.fetch_next
        _ = cursor.next_object()

    doc = Doc()
    await doc.commit()

    assert doc == await MotorAsyncIOReference(Doc, doc.id).fetch()

    cursor = Doc.find()
    await test_cursor(cursor)
    cursor = doc.find()
    await test_cursor(cursor)
    await Doc.find_one()
    await doc.find_one()
    await Doc.ensure_indexes()
    await doc.ensure_indexes()
    await doc.reload()
    await doc.remove()


Document classes in the perception handler module.

--- enactiveagents/model/perceptionhandler.py
+++ enactiveagents/model/perceptionhandler.py
@@ -7,6 +7,9 @@
 import structure

 class PerceptionHandler(object):
+    """
+    Abstract perception handler class.
+    """

     @abc.abstractmethod
     def perceive(self, agent, world):
@@ -20,11 +23,19 @@
         raise NotImplementedError("Should be implemented by child")

 class EmptyPerceptionHandler(PerceptionHandler):
+    """
+    A trivial perception handler that never perceives anything.
+    """

     def perceive(self, agent, world):
         return ""

 class BasicPerceptionHandler(PerceptionHandler):
+    """
+    A perception handler that perceives walls and blocks up to a given distance.
+    The perception indicates the type of structure that is seen, as well as its
+    distance.
+    """

     def perceive(self, agent_, world_):
         for delta in range(0, 10):

<|original_code|>
"""
Module that holds classes that represent an agent's perception handler.
"""

import abc
import world
import structure

class PerceptionHandler(object):

    @abc.abstractmethod
    def perceive(self, agent, world):
        """
        Generates a percept given an agent and a world.

        :param agent: The agent to generate the percept for.
        :param world: The world to generate the percept for.
        :return: The percept.
        """
        raise NotImplementedError("Should be implemented by child")

class EmptyPerceptionHandler(PerceptionHandler):

    def perceive(self, agent, world):
        return ""

class BasicPerceptionHandler(PerceptionHandler):

    def perceive(self, agent_, world_):
        for delta in range(0, 10):
            pos = world.Position(agent_.get_position())

            pos.add(agent_.get_move_delta(delta))

            entities = world_.get_entities_at(pos)
            for entity in entities:
                if entity == agent_:
                    continue
                if isinstance(entity, structure.Wall):
                    return "w%s" % delta
                elif isinstance(entity, structure.Block):
                    return "b%s" % delta

        return ""
<|edits_diff|>
--- enactiveagents/model/perceptionhandler.py
+++ enactiveagents/model/perceptionhandler.py
@@ -7,6 +7,9 @@
 import structure

 class PerceptionHandler(object):
+    """
+    Abstract perception handler class.
+    """

     @abc.abstractmethod
     def perceive(self, agent, world):
@@ -20,6 +23,9 @@
         raise NotImplementedError("Should be implemented by child")

 class EmptyPerceptionHandler(PerceptionHandler):
+    """
+    A trivial perception handler that never perceives anything.
+    """

     def perceive(self, agent, world):
         return ""
<|current_version|>
"""
Module that holds classes that represent an agent's perception handler.
"""

import abc
import world
import structure

class PerceptionHandler(object):
    """
    Abstract perception handler class.
    """

    @abc.abstractmethod
    def perceive(self, agent, world):
        """
        Generates a percept given an agent and a world.

        :param agent: The agent to generate the percept for.
        :param world: The world to generate the percept for.
        :return: The percept.
        """
        raise NotImplementedError("Should be implemented by child")

class EmptyPerceptionHandler(PerceptionHandler):
    """
    A trivial perception handler that never perceives anything.
    """

    def perceive(self, agent, world):
        return ""

class BasicPerceptionHandler(PerceptionHandler):

    def perceive(self, agent_, world_):
        for delta in range(0, 10):
            pos = world.Position(agent_.get_position())

            pos.add(agent_.get_move_delta(delta))

            entities = world_.get_entities_at(pos)
            for entity in entities:
                if entity == agent_:
                    continue
                if isinstance(entity, structure.Wall):
                    return "w%s" % delta
                elif isinstance(entity, structure.Block):
                    return "b%s" % delta

        return ""
<|next_version|>
"""
Module that holds classes that represent an agent's perception handler.
"""

import abc
import world
import structure

class PerceptionHandler(object):
    """
    Abstract perception handler class.
    """

    @abc.abstractmethod
    def perceive(self, agent, world):
        """
        Generates a percept given an agent and a world.

        :param agent: The agent to generate the percept for.
        :param world: The world to generate the percept for.
        :return: The percept.
        """
        raise NotImplementedError("Should be implemented by child")

class EmptyPerceptionHandler(PerceptionHandler):
    """
    A trivial perception handler that never perceives anything.
    """

    def perceive(self, agent, world):
        return ""

class BasicPerceptionHandler(PerceptionHandler):
    """
    A perception handler that perceives walls and blocks up to a given distance.
    The perception indicates the type of structure that is seen, as well as its
    distance.
    """

    def perceive(self, agent_, world_):
        for delta in range(0, 10):
            pos = world.Position(agent_.get_position())

            pos.add(agent_.get_move_delta(delta))

            entities = world_.get_entities_at(pos)
            for entity in entities:
                if entity == agent_:
                    continue
                if isinstance(entity, structure.Wall):
                    return "w%s" % delta
                elif isinstance(entity, structure.Block):
                    return "b%s" % delta

        return ""


Add comment about import in function.

Add comment about import in function.

--- oxyio/settings/__init__.py
+++ oxyio/settings/__init__.py
@@ -3,6 +3,7 @@
 # Desc: settings classmodule allowing for defaults + modules applied at runtime

 import sys
+

 from . import defaults

@@ -13,7 +14,9 @@
         self.apply_attrs(defaults)

     def load_module(self, name):
+        # The sys.modules hack below breaks the import
         from importlib import import_module
+
         settings_module = import_module(name)
         self.apply_attrs(settings_module)

<|original_code|>
# oxy.io
# File: oxyio/settings/__init__.py
# Desc: settings classmodule allowing for defaults + modules applied at runtime

import sys

from . import defaults

class OxyioSettings(object):
    def __init__(self):
        # Apply the defaults to this
        self.apply_attrs(defaults)

    def load_module(self, name):
        from importlib import import_module
        settings_module = import_module(name)
        self.apply_attrs(settings_module)

    def apply_attrs(self, module):
        for key in [name for name in dir(module) if name.isupper()]:
            setattr(self, key, getattr(module, key))

sys.modules[__name__] = OxyioSettings()

<|edits_diff|>
--- oxyio/settings/__init__.py
+++ oxyio/settings/__init__.py
@@ -3,6 +3,7 @@
 # Desc: settings classmodule allowing for defaults + modules applied at runtime

 import sys
+

 from . import defaults

@@ -13,6 +14,7 @@
         self.apply_attrs(defaults)

     def load_module(self, name):
+        # The sys.modules hack below breaks the import
         from importlib import import_module
         settings_module = import_module(name)
         self.apply_attrs(settings_module)
<|current_version|>
# oxy.io
# File: oxyio/settings/__init__.py
# Desc: settings classmodule allowing for defaults + modules applied at runtime

import sys

from . import defaults

class OxyioSettings(object):
    def __init__(self):
        # Apply the defaults to this
        self.apply_attrs(defaults)

    def load_module(self, name):
        # The sys.modules hack below breaks the import
        from importlib import import_module
        settings_module = import_module(name)
        self.apply_attrs(settings_module)

    def apply_attrs(self, module):
        for key in [name for name in dir(module) if name.isupper()]:
            setattr(self, key, getattr(module, key))

sys.modules[__name__] = OxyioSettings()

<|next_version|>
# oxy.io
# File: oxyio/settings/__init__.py
# Desc: settings classmodule allowing for defaults + modules applied at runtime

import sys

from . import defaults

class OxyioSettings(object):
    def __init__(self):
        # Apply the defaults to this
        self.apply_attrs(defaults)

    def load_module(self, name):
        # The sys.modules hack below breaks the import
        from importlib import import_module

        settings_module = import_module(name)
        self.apply_attrs(settings_module)

    def apply_attrs(self, module):
        for key in [name for name in dir(module) if name.isupper()]:
            setattr(self, key, getattr(module, key))

sys.modules[__name__] = OxyioSettings()


Add tests for env serialization

Add tests for env serialization

--- tests/changes/api/serializer/models/test_command.py
+++ tests/changes/api/serializer/models/test_command.py
@@ -17,6 +17,7 @@
             label='echo 1',
             jobstep_id=jobstep.id,
             cwd='/home/foobar',
+            env={'foo': 'bar'},
             script='echo 1',
             date_created=datetime(2013, 9, 19, 22, 15, 22),
             artifacts=['junit.xml'],
@@ -28,4 +29,5 @@
         assert result['id'] == command.id.hex
         assert result['dateCreated'] == '2013-09-19T22:15:22'
         assert result['cwd'] == command.cwd
+        assert result['env'] == {'foo': 'bar'}
         assert result['script'] == command.script

<|original_code|>
from datetime import datetime

from changes.api.serializer import serialize
from changes.config import db
from changes.models import Command
from changes.testutils import TestCase

class CommandSerializerTest(TestCase):
    def test_simple(self):
        project = self.create_project()
        build = self.create_build(project)
        job = self.create_job(build)
        jobphase = self.create_jobphase(job)
        jobstep = self.create_jobstep(jobphase)
        command = Command(
            label='echo 1',
            jobstep_id=jobstep.id,
            cwd='/home/foobar',
            script='echo 1',
            date_created=datetime(2013, 9, 19, 22, 15, 22),
            artifacts=['junit.xml'],
        )
        db.session.add(command)
        db.session.flush()

        result = serialize(command)
        assert result['id'] == command.id.hex
        assert result['dateCreated'] == '2013-09-19T22:15:22'
        assert result['cwd'] == command.cwd
        assert result['script'] == command.script

<|edits_diff|>
--- tests/changes/api/serializer/models/test_command.py
+++ tests/changes/api/serializer/models/test_command.py
@@ -17,6 +17,7 @@
             label='echo 1',
             jobstep_id=jobstep.id,
             cwd='/home/foobar',
+            env={'foo': 'bar'},
             script='echo 1',
             date_created=datetime(2013, 9, 19, 22, 15, 22),
             artifacts=['junit.xml'],
<|current_version|>
from datetime import datetime

from changes.api.serializer import serialize
from changes.config import db
from changes.models import Command
from changes.testutils import TestCase

class CommandSerializerTest(TestCase):
    def test_simple(self):
        project = self.create_project()
        build = self.create_build(project)
        job = self.create_job(build)
        jobphase = self.create_jobphase(job)
        jobstep = self.create_jobstep(jobphase)
        command = Command(
            label='echo 1',
            jobstep_id=jobstep.id,
            cwd='/home/foobar',
            env={'foo': 'bar'},
            script='echo 1',
            date_created=datetime(2013, 9, 19, 22, 15, 22),
            artifacts=['junit.xml'],
        )
        db.session.add(command)
        db.session.flush()

        result = serialize(command)
        assert result['id'] == command.id.hex
        assert result['dateCreated'] == '2013-09-19T22:15:22'
        assert result['cwd'] == command.cwd
        assert result['script'] == command.script

<|next_version|>
from datetime import datetime

from changes.api.serializer import serialize
from changes.config import db
from changes.models import Command
from changes.testutils import TestCase

class CommandSerializerTest(TestCase):
    def test_simple(self):
        project = self.create_project()
        build = self.create_build(project)
        job = self.create_job(build)
        jobphase = self.create_jobphase(job)
        jobstep = self.create_jobstep(jobphase)
        command = Command(
            label='echo 1',
            jobstep_id=jobstep.id,
            cwd='/home/foobar',
            env={'foo': 'bar'},
            script='echo 1',
            date_created=datetime(2013, 9, 19, 22, 15, 22),
            artifacts=['junit.xml'],
        )
        db.session.add(command)
        db.session.flush()

        result = serialize(command)
        assert result['id'] == command.id.hex
        assert result['dateCreated'] == '2013-09-19T22:15:22'
        assert result['cwd'] == command.cwd
        assert result['env'] == {'foo': 'bar'}
        assert result['script'] == command.script


Disable coverage test on python3.2

Disable coverage test on python3.2

--- nose2/tests/functional/test_coverage.py
+++ nose2/tests/functional/test_coverage.py
@@ -1,9 +1,14 @@
 import os.path
+import platform
+from nose2.compat import unittest

 from nose2.tests._common import FunctionalTestCase

 class TestCoverage(FunctionalTestCase):
+    @unittest.skipIf(
+        platform.python_version_tuple()[:2] == ('3', '2'),
+        'coverage package does not support python 3.2')
     def test_run(self):
         proc = self.runIn(
             'scenario/test_with_module',

<|original_code|>
import os.path

from nose2.tests._common import FunctionalTestCase

class TestCoverage(FunctionalTestCase):
    def test_run(self):
        proc = self.runIn(
            'scenario/test_with_module',
            '-v',
            '--with-coverage',
            '--coverage=lib/'
        )
        STATS = '           8      5    38%'

        stdout, stderr = proc.communicate()
        self.assertTestRunOutputMatches(
            proc,
            stderr=os.path.join('lib', 'mod1.py').replace('\\', r'\\') + STATS)
        self.assertTestRunOutputMatches(
            proc,
            stderr='TOTAL      ' + STATS)

<|edits_diff|>
--- nose2/tests/functional/test_coverage.py
+++ nose2/tests/functional/test_coverage.py
@@ -1,4 +1,6 @@
 import os.path
+import platform
+from nose2.compat import unittest

 from nose2.tests._common import FunctionalTestCase

<|current_version|>
import os.path
import platform
from nose2.compat import unittest

from nose2.tests._common import FunctionalTestCase

class TestCoverage(FunctionalTestCase):
    def test_run(self):
        proc = self.runIn(
            'scenario/test_with_module',
            '-v',
            '--with-coverage',
            '--coverage=lib/'
        )
        STATS = '           8      5    38%'

        stdout, stderr = proc.communicate()
        self.assertTestRunOutputMatches(
            proc,
            stderr=os.path.join('lib', 'mod1.py').replace('\\', r'\\') + STATS)
        self.assertTestRunOutputMatches(
            proc,
            stderr='TOTAL      ' + STATS)

<|next_version|>
import os.path
import platform
from nose2.compat import unittest

from nose2.tests._common import FunctionalTestCase

class TestCoverage(FunctionalTestCase):
    @unittest.skipIf(
        platform.python_version_tuple()[:2] == ('3', '2'),
        'coverage package does not support python 3.2')
    def test_run(self):
        proc = self.runIn(
            'scenario/test_with_module',
            '-v',
            '--with-coverage',
            '--coverage=lib/'
        )
        STATS = '           8      5    38%'

        stdout, stderr = proc.communicate()
        self.assertTestRunOutputMatches(
            proc,
            stderr=os.path.join('lib', 'mod1.py').replace('\\', r'\\') + STATS)
        self.assertTestRunOutputMatches(
            proc,
            stderr='TOTAL      ' + STATS)


Add uniform API for public body widgets

Add uniform API for public body widgets

--- froide/publicbody/forms.py
+++ froide/publicbody/forms.py
@@ -20,9 +20,19 @@
             data['cleaned_data'] = self.cleaned_data
         return data

+    def get_publicbodies(self):
+        if self.is_valid():
+            return [self.cleaned_data['publicbody']]
+        return []
+

 class MultiplePublicBodyForm(JSONMixin, forms.Form):
     publicbody = forms.ModelMultipleChoiceField(
             queryset=PublicBody.objects.all(),
             label=_("Search for a topic or a public body:")
     )
+
+    def get_publicbodies(self):
+        if self.is_valid():
+            return self.cleaned_data['publicbody']
+        return []

<|original_code|>
from django import forms
from django.utils.translation import ugettext_lazy as _

from froide.helper.form_utils import JSONMixin

from .models import PublicBody
from .widgets import PublicBodySelect

class PublicBodyForm(JSONMixin, forms.Form):
    publicbody = forms.ModelChoiceField(
            queryset=PublicBody.objects.all(),
            widget=PublicBodySelect,
            label=_("Search for a topic or a public body:")
    )

    def as_data(self):
        data = super(PublicBodyForm, self).as_data()
        if self.is_bound and self.is_valid():
            data['cleaned_data'] = self.cleaned_data
        return data

class MultiplePublicBodyForm(JSONMixin, forms.Form):
    publicbody = forms.ModelMultipleChoiceField(
            queryset=PublicBody.objects.all(),
            label=_("Search for a topic or a public body:")
    )

<|edits_diff|>
--- froide/publicbody/forms.py
+++ froide/publicbody/forms.py
@@ -20,6 +20,11 @@
             data['cleaned_data'] = self.cleaned_data
         return data

+    def get_publicbodies(self):
+        if self.is_valid():
+            return [self.cleaned_data['publicbody']]
+        return []
+

 class MultiplePublicBodyForm(JSONMixin, forms.Form):
     publicbody = forms.ModelMultipleChoiceField(
<|current_version|>
from django import forms
from django.utils.translation import ugettext_lazy as _

from froide.helper.form_utils import JSONMixin

from .models import PublicBody
from .widgets import PublicBodySelect

class PublicBodyForm(JSONMixin, forms.Form):
    publicbody = forms.ModelChoiceField(
            queryset=PublicBody.objects.all(),
            widget=PublicBodySelect,
            label=_("Search for a topic or a public body:")
    )

    def as_data(self):
        data = super(PublicBodyForm, self).as_data()
        if self.is_bound and self.is_valid():
            data['cleaned_data'] = self.cleaned_data
        return data

    def get_publicbodies(self):
        if self.is_valid():
            return [self.cleaned_data['publicbody']]
        return []

class MultiplePublicBodyForm(JSONMixin, forms.Form):
    publicbody = forms.ModelMultipleChoiceField(
            queryset=PublicBody.objects.all(),
            label=_("Search for a topic or a public body:")
    )

<|next_version|>
from django import forms
from django.utils.translation import ugettext_lazy as _

from froide.helper.form_utils import JSONMixin

from .models import PublicBody
from .widgets import PublicBodySelect

class PublicBodyForm(JSONMixin, forms.Form):
    publicbody = forms.ModelChoiceField(
            queryset=PublicBody.objects.all(),
            widget=PublicBodySelect,
            label=_("Search for a topic or a public body:")
    )

    def as_data(self):
        data = super(PublicBodyForm, self).as_data()
        if self.is_bound and self.is_valid():
            data['cleaned_data'] = self.cleaned_data
        return data

    def get_publicbodies(self):
        if self.is_valid():
            return [self.cleaned_data['publicbody']]
        return []

class MultiplePublicBodyForm(JSONMixin, forms.Form):
    publicbody = forms.ModelMultipleChoiceField(
            queryset=PublicBody.objects.all(),
            label=_("Search for a topic or a public body:")
    )

    def get_publicbodies(self):
        if self.is_valid():
            return self.cleaned_data['publicbody']
        return []


Add debugging to the repear script

Add debugging to the repear script

--- reaper.py
+++ reaper.py
@@ -13,6 +13,7 @@
     attributes = instance.get_attribute("userData")

     if attributes['userData'] == None:
+        print "Instance has no userdata"
         return False

     user_data = base64.b64decode(attributes['userData'])
@@ -20,12 +21,15 @@
     try:
         data = json.loads(user_data)
     except ValueError:
+        print "User Data isn't json"
         return False

     if not data.get("popfly"):
+        print "No key popfly"
         return False

     if instance.state != "running":
+        print "Instance isn't running"
         return False

     start = datetime.strptime(instance.launch_time, "%Y-%m-%dT%H:%M:%S.%fZ")

<|original_code|>
#!/usr/bin/env python
import boto
import base64
import json
from datetime import datetime

def seconds_from_hours(hours):
    return hours * 60 * 60

def should_kill(instance):
    attributes = instance.get_attribute("userData")

    if attributes['userData'] == None:
        return False

    user_data = base64.b64decode(attributes['userData'])

    try:
        data = json.loads(user_data)
    except ValueError:
        return False

    if not data.get("popfly"):
        return False

    if instance.state != "running":
        return False

    start = datetime.strptime(instance.launch_time, "%Y-%m-%dT%H:%M:%S.%fZ")
    end = datetime.utcnow()
    life = start - end

    return life.total_seconds() >= seconds_from_hours(data['duration'])

def kill(instance):
    instance.terminate()
    print "BOOM"

conn = boto.connect_ec2()
for reservation in conn.get_all_instances():
    for instance in reservation.instances:
        if should_kill(instance):
            kill(instance)
            print "Killing {}".format(instance.id)
        else:
            print "Sparing {}".format(instance.id)

<|edits_diff|>
--- reaper.py
+++ reaper.py
@@ -13,6 +13,7 @@
     attributes = instance.get_attribute("userData")

     if attributes['userData'] == None:
+        print "Instance has no userdata"
         return False

     user_data = base64.b64decode(attributes['userData'])
@@ -20,9 +21,11 @@
     try:
         data = json.loads(user_data)
     except ValueError:
+        print "User Data isn't json"
         return False

     if not data.get("popfly"):
+        print "No key popfly"
         return False

     if instance.state != "running":
<|current_version|>
#!/usr/bin/env python
import boto
import base64
import json
from datetime import datetime

def seconds_from_hours(hours):
    return hours * 60 * 60

def should_kill(instance):
    attributes = instance.get_attribute("userData")

    if attributes['userData'] == None:
        print "Instance has no userdata"
        return False

    user_data = base64.b64decode(attributes['userData'])

    try:
        data = json.loads(user_data)
    except ValueError:
        print "User Data isn't json"
        return False

    if not data.get("popfly"):
        print "No key popfly"
        return False

    if instance.state != "running":
        return False

    start = datetime.strptime(instance.launch_time, "%Y-%m-%dT%H:%M:%S.%fZ")
    end = datetime.utcnow()
    life = start - end

    return life.total_seconds() >= seconds_from_hours(data['duration'])

def kill(instance):
    instance.terminate()
    print "BOOM"

conn = boto.connect_ec2()
for reservation in conn.get_all_instances():
    for instance in reservation.instances:
        if should_kill(instance):
            kill(instance)
            print "Killing {}".format(instance.id)
        else:
            print "Sparing {}".format(instance.id)

<|next_version|>
#!/usr/bin/env python
import boto
import base64
import json
from datetime import datetime

def seconds_from_hours(hours):
    return hours * 60 * 60

def should_kill(instance):
    attributes = instance.get_attribute("userData")

    if attributes['userData'] == None:
        print "Instance has no userdata"
        return False

    user_data = base64.b64decode(attributes['userData'])

    try:
        data = json.loads(user_data)
    except ValueError:
        print "User Data isn't json"
        return False

    if not data.get("popfly"):
        print "No key popfly"
        return False

    if instance.state != "running":
        print "Instance isn't running"
        return False

    start = datetime.strptime(instance.launch_time, "%Y-%m-%dT%H:%M:%S.%fZ")
    end = datetime.utcnow()
    life = start - end

    return life.total_seconds() >= seconds_from_hours(data['duration'])

def kill(instance):
    instance.terminate()
    print "BOOM"

conn = boto.connect_ec2()
for reservation in conn.get_all_instances():
    for instance in reservation.instances:
        if should_kill(instance):
            kill(instance)
            print "Killing {}".format(instance.id)
        else:
            print "Sparing {}".format(instance.id)


Add user ID to member

Add user ID to member

--- src/sentry/api/serializers/models/organization_member.py
+++ src/sentry/api/serializers/models/organization_member.py
@@ -7,10 +7,16 @@
 @register(OrganizationMember)
 class OrganizationMemberSerializer(Serializer):
     def serialize(self, obj, attrs, user):
+        if obj.user:
+            user_data = {'id': obj.user.id}
+        else:
+            user_data = None
+
         d = {
             'id': str(obj.id),
             'email': obj.get_email(),
             'name': obj.user.get_display_name() if obj.user else obj.get_email(),
+            'user': user_data,
             'role': obj.role,
             'roleName': obj.get_role_display(),
             'pending': obj.is_pending,

<|original_code|>
from __future__ import absolute_import

from sentry.api.serializers import Serializer, register
from sentry.models import OrganizationMember

@register(OrganizationMember)
class OrganizationMemberSerializer(Serializer):
    def serialize(self, obj, attrs, user):
        d = {
            'id': str(obj.id),
            'email': obj.get_email(),
            'name': obj.user.get_display_name() if obj.user else obj.get_email(),
            'role': obj.role,
            'roleName': obj.get_role_display(),
            'pending': obj.is_pending,
            'flags': {
                'sso:linked': bool(getattr(obj.flags, 'sso:linked')),
                'sso:invalid': bool(getattr(obj.flags, 'sso:invalid')),
            },
            'dateCreated': obj.date_added,
        }
        return d

<|edits_diff|>
--- src/sentry/api/serializers/models/organization_member.py
+++ src/sentry/api/serializers/models/organization_member.py
@@ -7,6 +7,11 @@
 @register(OrganizationMember)
 class OrganizationMemberSerializer(Serializer):
     def serialize(self, obj, attrs, user):
+        if obj.user:
+            user_data = {'id': obj.user.id}
+        else:
+            user_data = None
+
         d = {
             'id': str(obj.id),
             'email': obj.get_email(),
<|current_version|>
from __future__ import absolute_import

from sentry.api.serializers import Serializer, register
from sentry.models import OrganizationMember

@register(OrganizationMember)
class OrganizationMemberSerializer(Serializer):
    def serialize(self, obj, attrs, user):
        if obj.user:
            user_data = {'id': obj.user.id}
        else:
            user_data = None

        d = {
            'id': str(obj.id),
            'email': obj.get_email(),
            'name': obj.user.get_display_name() if obj.user else obj.get_email(),
            'role': obj.role,
            'roleName': obj.get_role_display(),
            'pending': obj.is_pending,
            'flags': {
                'sso:linked': bool(getattr(obj.flags, 'sso:linked')),
                'sso:invalid': bool(getattr(obj.flags, 'sso:invalid')),
            },
            'dateCreated': obj.date_added,
        }
        return d

<|next_version|>
from __future__ import absolute_import

from sentry.api.serializers import Serializer, register
from sentry.models import OrganizationMember

@register(OrganizationMember)
class OrganizationMemberSerializer(Serializer):
    def serialize(self, obj, attrs, user):
        if obj.user:
            user_data = {'id': obj.user.id}
        else:
            user_data = None

        d = {
            'id': str(obj.id),
            'email': obj.get_email(),
            'name': obj.user.get_display_name() if obj.user else obj.get_email(),
            'user': user_data,
            'role': obj.role,
            'roleName': obj.get_role_display(),
            'pending': obj.is_pending,
            'flags': {
                'sso:linked': bool(getattr(obj.flags, 'sso:linked')),
                'sso:invalid': bool(getattr(obj.flags, 'sso:invalid')),
            },
            'dateCreated': obj.date_added,
        }
        return d


Mark feedback comments starting with a html tag as spammy

--- mzalendo/feedback/views.py
+++ mzalendo/feedback/views.py
@@ -4,6 +4,9 @@

 from models import Feedback
 from forms import FeedbackForm
+
+import re
+

 @csrf_protect
 def add(request):
@@ -23,6 +26,10 @@

             # if there is any content in the honeypot field then label this comment as spammy
             if form.cleaned_data['website']:
+                feedback.status = 'spammy'
+
+            # if the comment starts with an html tag it is probably spam
+            if re.search('\A\s*<\w+>', form.cleaned_data['comment']):
                 feedback.status = 'spammy'

             if request.user.is_authenticated():

<|original_code|>
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.decorators.csrf import csrf_protect

from models import Feedback
from forms import FeedbackForm

@csrf_protect
def add(request):
    """Gather feedback for a page, and if it is ok show a thanks message and link back to the page."""

    submit_was_success = False
    return_to_url      = None

    # If it is a post request try to create the feedback
    if request.method == 'POST':
        form = FeedbackForm( request.POST )
        if form.is_valid():
            feedback = Feedback()
            feedback.url      = form.cleaned_data['url']
            feedback.email    = form.cleaned_data['email']
            feedback.comment  = form.cleaned_data['comment']

            # if there is any content in the honeypot field then label this comment as spammy
            if form.cleaned_data['website']:
                feedback.status = 'spammy'

            if request.user.is_authenticated():
                feedback.user = request.user

            feedback.save()

            submit_was_success = True
            return_to_url = feedback.url or None

    else:
        # use GET to grab the url if set
        form = FeedbackForm(initial=request.GET)

    return render_to_response(
        'feedback/add.html',
        {
            'form':               form,
            'submit_was_success': submit_was_success,
            'return_to_url':      return_to_url,
        },
        context_instance=RequestContext(request)
    )

<|edits_diff|>
--- mzalendo/feedback/views.py
+++ mzalendo/feedback/views.py
@@ -4,6 +4,9 @@

 from models import Feedback
 from forms import FeedbackForm
+
+import re
+

 @csrf_protect
 def add(request):
<|current_version|>
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.decorators.csrf import csrf_protect

from models import Feedback
from forms import FeedbackForm

import re

@csrf_protect
def add(request):
    """Gather feedback for a page, and if it is ok show a thanks message and link back to the page."""

    submit_was_success = False
    return_to_url      = None

    # If it is a post request try to create the feedback
    if request.method == 'POST':
        form = FeedbackForm( request.POST )
        if form.is_valid():
            feedback = Feedback()
            feedback.url      = form.cleaned_data['url']
            feedback.email    = form.cleaned_data['email']
            feedback.comment  = form.cleaned_data['comment']

            # if there is any content in the honeypot field then label this comment as spammy
            if form.cleaned_data['website']:
                feedback.status = 'spammy'

            if request.user.is_authenticated():
                feedback.user = request.user

            feedback.save()

            submit_was_success = True
            return_to_url = feedback.url or None

    else:
        # use GET to grab the url if set
        form = FeedbackForm(initial=request.GET)

    return render_to_response(
        'feedback/add.html',
        {
            'form':               form,
            'submit_was_success': submit_was_success,
            'return_to_url':      return_to_url,
        },
        context_instance=RequestContext(request)
    )

<|next_version|>
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.decorators.csrf import csrf_protect

from models import Feedback
from forms import FeedbackForm

import re

@csrf_protect
def add(request):
    """Gather feedback for a page, and if it is ok show a thanks message and link back to the page."""

    submit_was_success = False
    return_to_url      = None

    # If it is a post request try to create the feedback
    if request.method == 'POST':
        form = FeedbackForm( request.POST )
        if form.is_valid():
            feedback = Feedback()
            feedback.url      = form.cleaned_data['url']
            feedback.email    = form.cleaned_data['email']
            feedback.comment  = form.cleaned_data['comment']

            # if there is any content in the honeypot field then label this comment as spammy
            if form.cleaned_data['website']:
                feedback.status = 'spammy'

            # if the comment starts with an html tag it is probably spam
            if re.search('\A\s*<\w+>', form.cleaned_data['comment']):
                feedback.status = 'spammy'

            if request.user.is_authenticated():
                feedback.user = request.user

            feedback.save()

            submit_was_success = True
            return_to_url = feedback.url or None

    else:
        # use GET to grab the url if set
        form = FeedbackForm(initial=request.GET)

    return render_to_response(
        'feedback/add.html',
        {
            'form':               form,
            'submit_was_success': submit_was_success,
            'return_to_url':      return_to_url,
        },
        context_instance=RequestContext(request)
    )


Fix url reversing in Python 3

Fix url reversing in Python 3

--- private_storage/storage.py
+++ private_storage/storage.py
@@ -3,6 +3,8 @@
 """
 from django.core.files.storage import FileSystemStorage
 from django.core.urlresolvers import reverse_lazy
+from django.utils.encoding import force_text
+
 from . import appconfig

 __all__ = (
@@ -31,6 +33,11 @@
             # the attribute is overwritten here to avoid breaking lazy evaluation.
             self.base_url = reverse_lazy('serve_private_file', kwargs={'path': ''})

+    def url(self, name):
+        # Make sure reverse_lazy() is evaluated, as Python 3 won't do this here.
+        self.base_url = force_text(self.base_url)
+        return super(PrivateStorage, self).url(name)
+

 # Singleton instance.
 private_storage = PrivateStorage()

<|original_code|>
"""
Django Storage interface
"""
from django.core.files.storage import FileSystemStorage
from django.core.urlresolvers import reverse_lazy
from . import appconfig

__all__ = (
    'private_storage',
    'PrivateStorage',
)

class PrivateStorage(FileSystemStorage):
    """
    Interface to the Django storage system,
    storing the files in a private folder.
    """
    def __init__(self, location=None, base_url=None, **kwargs):
        if location is None:
            location = appconfig.PRIVATE_STORAGE_ROOT

        super(PrivateStorage, self).__init__(
            location=location,
            base_url=base_url,
            **kwargs
        )
        if base_url is None:
            # When base_url is not given, it's autodetected.
            # However, as the super method checks for base_url.endswith('/'),
            # the attribute is overwritten here to avoid breaking lazy evaluation.
            self.base_url = reverse_lazy('serve_private_file', kwargs={'path': ''})

# Singleton instance.
private_storage = PrivateStorage()

<|edits_diff|>
--- private_storage/storage.py
+++ private_storage/storage.py
@@ -3,6 +3,8 @@
 """
 from django.core.files.storage import FileSystemStorage
 from django.core.urlresolvers import reverse_lazy
+from django.utils.encoding import force_text
+
 from . import appconfig

 __all__ = (
<|current_version|>
"""
Django Storage interface
"""
from django.core.files.storage import FileSystemStorage
from django.core.urlresolvers import reverse_lazy
from django.utils.encoding import force_text

from . import appconfig

__all__ = (
    'private_storage',
    'PrivateStorage',
)

class PrivateStorage(FileSystemStorage):
    """
    Interface to the Django storage system,
    storing the files in a private folder.
    """
    def __init__(self, location=None, base_url=None, **kwargs):
        if location is None:
            location = appconfig.PRIVATE_STORAGE_ROOT

        super(PrivateStorage, self).__init__(
            location=location,
            base_url=base_url,
            **kwargs
        )
        if base_url is None:
            # When base_url is not given, it's autodetected.
            # However, as the super method checks for base_url.endswith('/'),
            # the attribute is overwritten here to avoid breaking lazy evaluation.
            self.base_url = reverse_lazy('serve_private_file', kwargs={'path': ''})

# Singleton instance.
private_storage = PrivateStorage()

<|next_version|>
"""
Django Storage interface
"""
from django.core.files.storage import FileSystemStorage
from django.core.urlresolvers import reverse_lazy
from django.utils.encoding import force_text

from . import appconfig

__all__ = (
    'private_storage',
    'PrivateStorage',
)

class PrivateStorage(FileSystemStorage):
    """
    Interface to the Django storage system,
    storing the files in a private folder.
    """
    def __init__(self, location=None, base_url=None, **kwargs):
        if location is None:
            location = appconfig.PRIVATE_STORAGE_ROOT

        super(PrivateStorage, self).__init__(
            location=location,
            base_url=base_url,
            **kwargs
        )
        if base_url is None:
            # When base_url is not given, it's autodetected.
            # However, as the super method checks for base_url.endswith('/'),
            # the attribute is overwritten here to avoid breaking lazy evaluation.
            self.base_url = reverse_lazy('serve_private_file', kwargs={'path': ''})

    def url(self, name):
        # Make sure reverse_lazy() is evaluated, as Python 3 won't do this here.
        self.base_url = force_text(self.base_url)
        return super(PrivateStorage, self).url(name)

# Singleton instance.
private_storage = PrivateStorage()


Fix ES index setup in XFormManagementTest

--- corehq/apps/data_interfaces/tests/test_xform_management.py
+++ corehq/apps/data_interfaces/tests/test_xform_management.py
@@ -5,12 +5,15 @@
 from corehq.apps.data_interfaces.views import XFormManagementView
 from corehq.apps.domain.shortcuts import create_domain
 from corehq.apps.users.models import WebUser
+from corehq.pillows.mappings.xform_mapping import XFORM_INDEX_INFO
+from corehq.util.elastic import reset_es_index

 class XFormManagementTest(TestCase):

     @classmethod
     def setUpClass(cls):
+        reset_es_index(XFORM_INDEX_INFO)
         cls.domain = create_domain('xform-management-test')
         cls.web_user = WebUser.create('xform-management-test', 'test', 'test',
                                       is_superuser=True)

<|original_code|>
from django.contrib.sessions.middleware import SessionMiddleware
from django.http import HttpRequest, QueryDict
from django.test import TestCase, Client

from corehq.apps.data_interfaces.views import XFormManagementView
from corehq.apps.domain.shortcuts import create_domain
from corehq.apps.users.models import WebUser

class XFormManagementTest(TestCase):

    @classmethod
    def setUpClass(cls):
        cls.domain = create_domain('xform-management-test')
        cls.web_user = WebUser.create('xform-management-test', 'test', 'test',
                                      is_superuser=True)
        Client().force_login(cls.web_user.get_django_user())

    @classmethod
    def tearDownClass(cls):
        cls.web_user.delete()
        cls.domain.delete()

    def test_get_xform_ids__sanity_check(self):
        # This helper has to mock a request in a brittle way.
        # If permissions are wrong, instead of returning a list,
        # it will return an HttpResponse containing the permission error.
        # This can break when permissions change.
        # So, just test that we aren't hitting that situation and that the response is a list.
        request = HttpRequest()
        request.POST = QueryDict('select_all=')
        request.couch_user = self.web_user
        SessionMiddleware().process_request(request)
        view = XFormManagementView()
        view.args = (self.domain.name,)
        view.request = request
        assert isinstance(view.get_xform_ids(request), list)

<|edits_diff|>
--- corehq/apps/data_interfaces/tests/test_xform_management.py
+++ corehq/apps/data_interfaces/tests/test_xform_management.py
@@ -5,6 +5,8 @@
 from corehq.apps.data_interfaces.views import XFormManagementView
 from corehq.apps.domain.shortcuts import create_domain
 from corehq.apps.users.models import WebUser
+from corehq.pillows.mappings.xform_mapping import XFORM_INDEX_INFO
+from corehq.util.elastic import reset_es_index

 class XFormManagementTest(TestCase):
<|current_version|>
from django.contrib.sessions.middleware import SessionMiddleware
from django.http import HttpRequest, QueryDict
from django.test import TestCase, Client

from corehq.apps.data_interfaces.views import XFormManagementView
from corehq.apps.domain.shortcuts import create_domain
from corehq.apps.users.models import WebUser
from corehq.pillows.mappings.xform_mapping import XFORM_INDEX_INFO
from corehq.util.elastic import reset_es_index

class XFormManagementTest(TestCase):

    @classmethod
    def setUpClass(cls):
        cls.domain = create_domain('xform-management-test')
        cls.web_user = WebUser.create('xform-management-test', 'test', 'test',
                                      is_superuser=True)
        Client().force_login(cls.web_user.get_django_user())

    @classmethod
    def tearDownClass(cls):
        cls.web_user.delete()
        cls.domain.delete()

    def test_get_xform_ids__sanity_check(self):
        # This helper has to mock a request in a brittle way.
        # If permissions are wrong, instead of returning a list,
        # it will return an HttpResponse containing the permission error.
        # This can break when permissions change.
        # So, just test that we aren't hitting that situation and that the response is a list.
        request = HttpRequest()
        request.POST = QueryDict('select_all=')
        request.couch_user = self.web_user
        SessionMiddleware().process_request(request)
        view = XFormManagementView()
        view.args = (self.domain.name,)
        view.request = request
        assert isinstance(view.get_xform_ids(request), list)

<|next_version|>
from django.contrib.sessions.middleware import SessionMiddleware
from django.http import HttpRequest, QueryDict
from django.test import TestCase, Client

from corehq.apps.data_interfaces.views import XFormManagementView
from corehq.apps.domain.shortcuts import create_domain
from corehq.apps.users.models import WebUser
from corehq.pillows.mappings.xform_mapping import XFORM_INDEX_INFO
from corehq.util.elastic import reset_es_index

class XFormManagementTest(TestCase):

    @classmethod
    def setUpClass(cls):
        reset_es_index(XFORM_INDEX_INFO)
        cls.domain = create_domain('xform-management-test')
        cls.web_user = WebUser.create('xform-management-test', 'test', 'test',
                                      is_superuser=True)
        Client().force_login(cls.web_user.get_django_user())

    @classmethod
    def tearDownClass(cls):
        cls.web_user.delete()
        cls.domain.delete()

    def test_get_xform_ids__sanity_check(self):
        # This helper has to mock a request in a brittle way.
        # If permissions are wrong, instead of returning a list,
        # it will return an HttpResponse containing the permission error.
        # This can break when permissions change.
        # So, just test that we aren't hitting that situation and that the response is a list.
        request = HttpRequest()
        request.POST = QueryDict('select_all=')
        request.couch_user = self.web_user
        SessionMiddleware().process_request(request)
        view = XFormManagementView()
        view.args = (self.domain.name,)
        view.request = request
        assert isinstance(view.get_xform_ids(request), list)


Set the process title on posix systems

Set the process title on posix systems

--- tornado_srv.py
+++ tornado_srv.py
@@ -2,10 +2,16 @@
 import tornado.wsgi
 import tornado.httpserver
 import tornado.ioloop
+import os

 from mojibake.main import app
 from mojibake.settings import PORT

+if os.name == 'posix':
+    import setproctitle
+    setproctitle.setproctitle('mojibake')  # Set the process title to mojibake
+
+print('Starting Mojibake...')
 container = tornado.wsgi.WSGIContainer(app)
 http_server = tornado.httpserver.HTTPServer(container)
 http_server.listen(PORT)

<|original_code|>
import tornado.web
import tornado.wsgi
import tornado.httpserver
import tornado.ioloop

from mojibake.main import app
from mojibake.settings import PORT

container = tornado.wsgi.WSGIContainer(app)
http_server = tornado.httpserver.HTTPServer(container)
http_server.listen(PORT)
tornado.ioloop.IOLoop.instance().start()

<|edits_diff|>
--- tornado_srv.py
+++ tornado_srv.py
@@ -2,6 +2,7 @@
 import tornado.wsgi
 import tornado.httpserver
 import tornado.ioloop
+import os

 from mojibake.main import app
 from mojibake.settings import PORT
<|current_version|>
import tornado.web
import tornado.wsgi
import tornado.httpserver
import tornado.ioloop
import os

from mojibake.main import app
from mojibake.settings import PORT

container = tornado.wsgi.WSGIContainer(app)
http_server = tornado.httpserver.HTTPServer(container)
http_server.listen(PORT)
tornado.ioloop.IOLoop.instance().start()

<|next_version|>
import tornado.web
import tornado.wsgi
import tornado.httpserver
import tornado.ioloop
import os

from mojibake.main import app
from mojibake.settings import PORT

if os.name == 'posix':
    import setproctitle
    setproctitle.setproctitle('mojibake')  # Set the process title to mojibake

print('Starting Mojibake...')
container = tornado.wsgi.WSGIContainer(app)
http_server = tornado.httpserver.HTTPServer(container)
http_server.listen(PORT)
tornado.ioloop.IOLoop.instance().start()


Add passing test for default image

Add passing test for default image

--- imagersite/imagersite/tests.py
+++ imagersite/imagersite/tests.py
@@ -1,3 +1,6 @@
+"""Tests for project level urls and views."""
+from __future__ import unicode_literals
+from django.contrib.staticfiles import finders
 from django.test import Client, TestCase
 from django.contrib.auth.models import User

@@ -5,6 +8,7 @@
 REGISTER = '/accounts/register/'
 LOGIN = '/login'
 LOGOUT = '/logout'
+DEFAULT_IMAGE = finders.find('static/imagersite/images/default-image.jpg')

 class UnauthenticatedUser(TestCase):
@@ -37,3 +41,8 @@
     def test_register(self):
         """Test register can be reached."""
         self.assertEqual(self.register.status_code, 200)
+
+    def test_default_image(self):
+        """Test default image shows up."""
+        img_path = self.home.context['image']
+        self.assertEqual(img_path, DEFAULT_IMAGE)

<|original_code|>
from django.test import Client, TestCase
from django.contrib.auth.models import User

HOME = '/'
REGISTER = '/accounts/register/'
LOGIN = '/login'
LOGOUT = '/logout'

class UnauthenticatedUser(TestCase):
    """Create unauth user for testing."""

    def setUp(self):
        """Setup unauth user."""
        client = Client()
        self.home = client.get(HOME)
        self.login = client.get(LOGIN)
        self.logout = client.get(LOGOUT)
        self.register = client.get(REGISTER)

    def test_no_user_in_db(self):
        """No user i db."""
        self.assertFalse(User.objects.count())

    def test_homepage(self):
        """Test homepage can be reached."""
        self.assertEqual(self.home.status_code, 200)

    def test_login(self):
        """Test login cna be reached."""
        self.assertEqual(self.login.status_code, 200)

    def test_logout(self):
        """Test logout can be reached."""
        self.assertEqual(self.logout.status_code, 200)

    def test_register(self):
        """Test register can be reached."""
        self.assertEqual(self.register.status_code, 200)

<|edits_diff|>
--- imagersite/imagersite/tests.py
+++ imagersite/imagersite/tests.py
@@ -1,3 +1,6 @@
+"""Tests for project level urls and views."""
+from __future__ import unicode_literals
+from django.contrib.staticfiles import finders
 from django.test import Client, TestCase
 from django.contrib.auth.models import User

@@ -5,6 +8,7 @@
 REGISTER = '/accounts/register/'
 LOGIN = '/login'
 LOGOUT = '/logout'
+DEFAULT_IMAGE = finders.find('static/imagersite/images/default-image.jpg')

 class UnauthenticatedUser(TestCase):
<|current_version|>
"""Tests for project level urls and views."""
from __future__ import unicode_literals
from django.contrib.staticfiles import finders
from django.test import Client, TestCase
from django.contrib.auth.models import User

HOME = '/'
REGISTER = '/accounts/register/'
LOGIN = '/login'
LOGOUT = '/logout'
DEFAULT_IMAGE = finders.find('static/imagersite/images/default-image.jpg')

class UnauthenticatedUser(TestCase):
    """Create unauth user for testing."""

    def setUp(self):
        """Setup unauth user."""
        client = Client()
        self.home = client.get(HOME)
        self.login = client.get(LOGIN)
        self.logout = client.get(LOGOUT)
        self.register = client.get(REGISTER)

    def test_no_user_in_db(self):
        """No user i db."""
        self.assertFalse(User.objects.count())

    def test_homepage(self):
        """Test homepage can be reached."""
        self.assertEqual(self.home.status_code, 200)

    def test_login(self):
        """Test login cna be reached."""
        self.assertEqual(self.login.status_code, 200)

    def test_logout(self):
        """Test logout can be reached."""
        self.assertEqual(self.logout.status_code, 200)

    def test_register(self):
        """Test register can be reached."""
        self.assertEqual(self.register.status_code, 200)

<|next_version|>
"""Tests for project level urls and views."""
from __future__ import unicode_literals
from django.contrib.staticfiles import finders
from django.test import Client, TestCase
from django.contrib.auth.models import User

HOME = '/'
REGISTER = '/accounts/register/'
LOGIN = '/login'
LOGOUT = '/logout'
DEFAULT_IMAGE = finders.find('static/imagersite/images/default-image.jpg')

class UnauthenticatedUser(TestCase):
    """Create unauth user for testing."""

    def setUp(self):
        """Setup unauth user."""
        client = Client()
        self.home = client.get(HOME)
        self.login = client.get(LOGIN)
        self.logout = client.get(LOGOUT)
        self.register = client.get(REGISTER)

    def test_no_user_in_db(self):
        """No user i db."""
        self.assertFalse(User.objects.count())

    def test_homepage(self):
        """Test homepage can be reached."""
        self.assertEqual(self.home.status_code, 200)

    def test_login(self):
        """Test login cna be reached."""
        self.assertEqual(self.login.status_code, 200)

    def test_logout(self):
        """Test logout can be reached."""
        self.assertEqual(self.logout.status_code, 200)

    def test_register(self):
        """Test register can be reached."""
        self.assertEqual(self.register.status_code, 200)

    def test_default_image(self):
        """Test default image shows up."""
        img_path = self.home.context['image']
        self.assertEqual(img_path, DEFAULT_IMAGE)


Update to make sure we log an error with an invalid key

--- Bookie/bookie/lib/access.py
+++ Bookie/bookie/lib/access.py
@@ -1,5 +1,9 @@
 """Handle auth and authz activities in bookie"""
+import logging
 from pyramid.httpexceptions import HTTPForbidden
+
+
+LOG = logging.getLogger(__name__)

 class Authorize(object):
@@ -21,6 +25,8 @@
     def __enter__(self):
         """Verify api key set in constructor"""
         if self.api_key != self.check_key:
+            LOG.error('Invalid API Key! {0} v {1}'.format(self.api_key,
+                                                          self.check_key))
             raise HTTPForbidden('Invalid Authorization')

     def __exit__(self, exc_type, exc_value, traceback):

<|original_code|>
"""Handle auth and authz activities in bookie"""
from pyramid.httpexceptions import HTTPForbidden

class Authorize(object):
    """Context manager to check if the user is authorized

    use:
        with Authorize(some_key):
            # do work

    Will return NotAuthorized if it fails

    """

    def __init__(self, submitted_key, config_key):
        """Create the context manager"""
        self.api_key = config_key
        self.check_key = submitted_key

    def __enter__(self):
        """Verify api key set in constructor"""
        if self.api_key != self.check_key:
            raise HTTPForbidden('Invalid Authorization')

    def __exit__(self, exc_type, exc_value, traceback):
        """No cleanup work to do after usage"""
        pass

<|edits_diff|>
--- Bookie/bookie/lib/access.py
+++ Bookie/bookie/lib/access.py
@@ -1,5 +1,9 @@
 """Handle auth and authz activities in bookie"""
+import logging
 from pyramid.httpexceptions import HTTPForbidden
+
+
+LOG = logging.getLogger(__name__)

 class Authorize(object):
<|current_version|>
"""Handle auth and authz activities in bookie"""
import logging
from pyramid.httpexceptions import HTTPForbidden

LOG = logging.getLogger(__name__)

class Authorize(object):
    """Context manager to check if the user is authorized

    use:
        with Authorize(some_key):
            # do work

    Will return NotAuthorized if it fails

    """

    def __init__(self, submitted_key, config_key):
        """Create the context manager"""
        self.api_key = config_key
        self.check_key = submitted_key

    def __enter__(self):
        """Verify api key set in constructor"""
        if self.api_key != self.check_key:
            raise HTTPForbidden('Invalid Authorization')

    def __exit__(self, exc_type, exc_value, traceback):
        """No cleanup work to do after usage"""
        pass

<|next_version|>
"""Handle auth and authz activities in bookie"""
import logging
from pyramid.httpexceptions import HTTPForbidden

LOG = logging.getLogger(__name__)

class Authorize(object):
    """Context manager to check if the user is authorized

    use:
        with Authorize(some_key):
            # do work

    Will return NotAuthorized if it fails

    """

    def __init__(self, submitted_key, config_key):
        """Create the context manager"""
        self.api_key = config_key
        self.check_key = submitted_key

    def __enter__(self):
        """Verify api key set in constructor"""
        if self.api_key != self.check_key:
            LOG.error('Invalid API Key! {0} v {1}'.format(self.api_key,
                                                          self.check_key))
            raise HTTPForbidden('Invalid Authorization')

    def __exit__(self, exc_type, exc_value, traceback):
        """No cleanup work to do after usage"""
        pass


Select latest event when logged in.

admin_base: Select latest event when logged in.

--- Instanssi/admin_base/views.py
+++ Instanssi/admin_base/views.py
@@ -2,9 +2,14 @@

 from django.http import HttpResponseRedirect
 from django.contrib.auth.decorators import login_required
+from Instanssi.admin_base.misc.eventsel import get_selected_event

 @login_required(login_url='/control/auth/login/')
 def index(request):
+    # Select latest event as default
+    print get_selected_event(request)
+
+    # Redirect to events page
     return HttpResponseRedirect("/control/events/")

 @login_required(login_url='/control/auth/login/')

<|original_code|>
# -*- coding: utf-8 -*-

from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required

@login_required(login_url='/control/auth/login/')
def index(request):
    return HttpResponseRedirect("/control/events/")

@login_required(login_url='/control/auth/login/')
def eventchange(request, event_id):
    # Get redirect path
    if 'r' in request.GET:
        r = request.GET['r']
        if r[0] != "/":
            r = "/control/"
    else:
        r = "/control/"

    # Set session variable
    try:
        request.session['m_event_id'] = int(event_id)
    except:
        raise Http404

    # Redirect
    return HttpResponseRedirect(r)
<|edits_diff|>
--- Instanssi/admin_base/views.py
+++ Instanssi/admin_base/views.py
@@ -2,6 +2,7 @@

 from django.http import HttpResponseRedirect
 from django.contrib.auth.decorators import login_required
+from Instanssi.admin_base.misc.eventsel import get_selected_event

 @login_required(login_url='/control/auth/login/')
 def index(request):
<|current_version|>
# -*- coding: utf-8 -*-

from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from Instanssi.admin_base.misc.eventsel import get_selected_event

@login_required(login_url='/control/auth/login/')
def index(request):
    return HttpResponseRedirect("/control/events/")

@login_required(login_url='/control/auth/login/')
def eventchange(request, event_id):
    # Get redirect path
    if 'r' in request.GET:
        r = request.GET['r']
        if r[0] != "/":
            r = "/control/"
    else:
        r = "/control/"

    # Set session variable
    try:
        request.session['m_event_id'] = int(event_id)
    except:
        raise Http404

    # Redirect
    return HttpResponseRedirect(r)
<|next_version|>
# -*- coding: utf-8 -*-

from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from Instanssi.admin_base.misc.eventsel import get_selected_event

@login_required(login_url='/control/auth/login/')
def index(request):
    # Select latest event as default
    print get_selected_event(request)

    # Redirect to events page
    return HttpResponseRedirect("/control/events/")

@login_required(login_url='/control/auth/login/')
def eventchange(request, event_id):
    # Get redirect path
    if 'r' in request.GET:
        r = request.GET['r']
        if r[0] != "/":
            r = "/control/"
    else:
        r = "/control/"

    # Set session variable
    try:
        request.session['m_event_id'] = int(event_id)
    except:
        raise Http404

    # Redirect
    return HttpResponseRedirect(r)


Add people and music to the main URL configuration.

--- base/urls.py
+++ base/urls.py
@@ -11,7 +11,10 @@

     url(r'^', include('components.appearances.urls')),
     url(r'^', include('components.events.urls')),
+
     url(r'^', include('components.merchandise.goods.urls')),
+    url(r'^', include('components.merchandise.music.urls')),
+    url(r'^', include('components.people.urls')),

     # Examples:
     # url(r'^$', 'base.views.home', name='home'),

<|original_code|>
from django.conf.urls import patterns, include, url
from django.contrib import admin

from components.views import SiteView

# Uncomment the next two lines to enable the admin:
# admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$', name='site-home', view=SiteView.as_view()),

    url(r'^', include('components.appearances.urls')),
    url(r'^', include('components.events.urls')),
    url(r'^', include('components.merchandise.goods.urls')),

    # Examples:
    # url(r'^$', 'base.views.home', name='home'),
    # url(r'^base/', include('base.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
)

<|edits_diff|>
--- base/urls.py
+++ base/urls.py
@@ -11,6 +11,7 @@

     url(r'^', include('components.appearances.urls')),
     url(r'^', include('components.events.urls')),
+
     url(r'^', include('components.merchandise.goods.urls')),

     # Examples:
<|current_version|>
from django.conf.urls import patterns, include, url
from django.contrib import admin

from components.views import SiteView

# Uncomment the next two lines to enable the admin:
# admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$', name='site-home', view=SiteView.as_view()),

    url(r'^', include('components.appearances.urls')),
    url(r'^', include('components.events.urls')),

    url(r'^', include('components.merchandise.goods.urls')),

    # Examples:
    # url(r'^$', 'base.views.home', name='home'),
    # url(r'^base/', include('base.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
)

<|next_version|>
from django.conf.urls import patterns, include, url
from django.contrib import admin

from components.views import SiteView

# Uncomment the next two lines to enable the admin:
# admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$', name='site-home', view=SiteView.as_view()),

    url(r'^', include('components.appearances.urls')),
    url(r'^', include('components.events.urls')),

    url(r'^', include('components.merchandise.goods.urls')),
    url(r'^', include('components.merchandise.music.urls')),
    url(r'^', include('components.people.urls')),

    # Examples:
    # url(r'^$', 'base.views.home', name='home'),
    # url(r'^base/', include('base.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
)


Check for empty files when merging benchmarks

--- scripts/merge_benchmarks.py
+++ scripts/merge_benchmarks.py
@@ -22,6 +22,11 @@

     res_list = []
     for file in bench_files:
+
+        if os.stat(file).st_size == 0:
+            print(f'{file} is empty and will be skipped')
+            continue
+
         clean_name = file.replace(args.root, "").replace(".benchmark", "")
         res = pd.read_csv(file, sep='\t')
         res.rename(columns={res.columns[1]: 'h_m_s'}, inplace=True)
@@ -31,3 +36,4 @@

     results = pd.concat(res_list)
     results.to_csv(args.output, index_label='scenario')
+

<|original_code|>
import pandas as pd
import argparse
import os

if __name__=='__main__':
    """
    Merge benchmark output for all scenarios, methods and settings
    """

    parser = argparse.ArgumentParser(description='Collect all benchmarks')

    parser.add_argument('-o', '--output', required=True, help='output file')
    parser.add_argument('-r', '--root', required=True,
                        help='root directory for scIB output')
    args = parser.parse_args()

    bench_files = []
    for path, dirs, files in os.walk(args.root):
        for file in files:
            if 'integration' in path and file.endswith('.benchmark'):
                bench_files.append(os.path.join(path, file))

    res_list = []
    for file in bench_files:
        clean_name = file.replace(args.root, "").replace(".benchmark", "")
        res = pd.read_csv(file, sep='\t')
        res.rename(columns={res.columns[1]: 'h_m_s'}, inplace=True)
        res['scenario'] = clean_name
        res.set_index('scenario', inplace=True)
        res_list.append(res)

    results = pd.concat(res_list)
    results.to_csv(args.output, index_label='scenario')

<|edits_diff|>
--- scripts/merge_benchmarks.py
+++ scripts/merge_benchmarks.py
@@ -22,6 +22,11 @@

     res_list = []
     for file in bench_files:
+
+        if os.stat(file).st_size == 0:
+            print(f'{file} is empty and will be skipped')
+            continue
+
         clean_name = file.replace(args.root, "").replace(".benchmark", "")
         res = pd.read_csv(file, sep='\t')
         res.rename(columns={res.columns[1]: 'h_m_s'}, inplace=True)
<|current_version|>
import pandas as pd
import argparse
import os

if __name__=='__main__':
    """
    Merge benchmark output for all scenarios, methods and settings
    """

    parser = argparse.ArgumentParser(description='Collect all benchmarks')

    parser.add_argument('-o', '--output', required=True, help='output file')
    parser.add_argument('-r', '--root', required=True,
                        help='root directory for scIB output')
    args = parser.parse_args()

    bench_files = []
    for path, dirs, files in os.walk(args.root):
        for file in files:
            if 'integration' in path and file.endswith('.benchmark'):
                bench_files.append(os.path.join(path, file))

    res_list = []
    for file in bench_files:

        if os.stat(file).st_size == 0:
            print(f'{file} is empty and will be skipped')
            continue

        clean_name = file.replace(args.root, "").replace(".benchmark", "")
        res = pd.read_csv(file, sep='\t')
        res.rename(columns={res.columns[1]: 'h_m_s'}, inplace=True)
        res['scenario'] = clean_name
        res.set_index('scenario', inplace=True)
        res_list.append(res)

    results = pd.concat(res_list)
    results.to_csv(args.output, index_label='scenario')

<|next_version|>
import pandas as pd
import argparse
import os

if __name__=='__main__':
    """
    Merge benchmark output for all scenarios, methods and settings
    """

    parser = argparse.ArgumentParser(description='Collect all benchmarks')

    parser.add_argument('-o', '--output', required=True, help='output file')
    parser.add_argument('-r', '--root', required=True,
                        help='root directory for scIB output')
    args = parser.parse_args()

    bench_files = []
    for path, dirs, files in os.walk(args.root):
        for file in files:
            if 'integration' in path and file.endswith('.benchmark'):
                bench_files.append(os.path.join(path, file))

    res_list = []
    for file in bench_files:

        if os.stat(file).st_size == 0:
            print(f'{file} is empty and will be skipped')
            continue

        clean_name = file.replace(args.root, "").replace(".benchmark", "")
        res = pd.read_csv(file, sep='\t')
        res.rename(columns={res.columns[1]: 'h_m_s'}, inplace=True)
        res['scenario'] = clean_name
        res.set_index('scenario', inplace=True)
        res_list.append(res)

    results = pd.concat(res_list)
    results.to_csv(args.output, index_label='scenario')


Add monkeypatch to prevent connection closing for memcachier

--- standup/wsgi.py
+++ standup/wsgi.py
@@ -9,11 +9,16 @@

 import os

+from django.core.cache.backends.memcached import BaseMemcachedCache
 from django.core.wsgi import get_wsgi_application

 from raven.contrib.django.raven_compat.middleware.wsgi import Sentry

+# Fix django closing connection to MemCachier after every request (#11331)
+# per the MemCachier docs.
+BaseMemcachedCache.close = lambda self, **kwargs: None
+
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "standup.settings")

 application = Sentry(get_wsgi_application())

<|original_code|>
"""
WSGI config for standup project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application

from raven.contrib.django.raven_compat.middleware.wsgi import Sentry

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "standup.settings")

application = Sentry(get_wsgi_application())

<|edits_diff|>
--- standup/wsgi.py
+++ standup/wsgi.py
@@ -9,6 +9,7 @@

 import os

+from django.core.cache.backends.memcached import BaseMemcachedCache
 from django.core.wsgi import get_wsgi_application

 from raven.contrib.django.raven_compat.middleware.wsgi import Sentry
<|current_version|>
"""
WSGI config for standup project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
"""

import os

from django.core.cache.backends.memcached import BaseMemcachedCache
from django.core.wsgi import get_wsgi_application

from raven.contrib.django.raven_compat.middleware.wsgi import Sentry

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "standup.settings")

application = Sentry(get_wsgi_application())

<|next_version|>
"""
WSGI config for standup project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
"""

import os

from django.core.cache.backends.memcached import BaseMemcachedCache
from django.core.wsgi import get_wsgi_application

from raven.contrib.django.raven_compat.middleware.wsgi import Sentry

# Fix django closing connection to MemCachier after every request (#11331)
# per the MemCachier docs.
BaseMemcachedCache.close = lambda self, **kwargs: None

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "standup.settings")

application = Sentry(get_wsgi_application())


Revert "Don't check INTEGRATION_TESTS env var in external libs test"

This reverts commit 648d02fbfca79241a65902f6dd9a7a767a0f633d.

--- test/test_external_libs.py
+++ test/test_external_libs.py
@@ -1,7 +1,10 @@
 import unittest
+import os
 from test.util import ykman_cli

+@unittest.skipIf(
+    os.environ.get('INTEGRATION_TESTS') != 'TRUE', 'INTEGRATION_TESTS != TRUE')
 class TestExternalLibraries(unittest.TestCase):

     def test_ykman_version(self):

<|original_code|>
import unittest
from test.util import ykman_cli

class TestExternalLibraries(unittest.TestCase):

    def test_ykman_version(self):
        output = ykman_cli('-v')
        # Test that major version is 1 on all libs
        self.assertIn('libykpers 1', output)
        self.assertIn('libu2f-host 1', output)
        self.assertIn('libusb 1', output)

    def test_ykman_version_not_found(self):
        output = ykman_cli('-v')
        self.assertNotIn('not found!', output)
        self.assertNotIn('<pyusb backend missing>', output)

<|edits_diff|>
--- test/test_external_libs.py
+++ test/test_external_libs.py
@@ -1,4 +1,5 @@
 import unittest
+import os
 from test.util import ykman_cli

<|current_version|>
import unittest
import os
from test.util import ykman_cli

class TestExternalLibraries(unittest.TestCase):

    def test_ykman_version(self):
        output = ykman_cli('-v')
        # Test that major version is 1 on all libs
        self.assertIn('libykpers 1', output)
        self.assertIn('libu2f-host 1', output)
        self.assertIn('libusb 1', output)

    def test_ykman_version_not_found(self):
        output = ykman_cli('-v')
        self.assertNotIn('not found!', output)
        self.assertNotIn('<pyusb backend missing>', output)

<|next_version|>
import unittest
import os
from test.util import ykman_cli

@unittest.skipIf(
    os.environ.get('INTEGRATION_TESTS') != 'TRUE', 'INTEGRATION_TESTS != TRUE')
class TestExternalLibraries(unittest.TestCase):

    def test_ykman_version(self):
        output = ykman_cli('-v')
        # Test that major version is 1 on all libs
        self.assertIn('libykpers 1', output)
        self.assertIn('libu2f-host 1', output)
        self.assertIn('libusb 1', output)

    def test_ykman_version_not_found(self):
        output = ykman_cli('-v')
        self.assertNotIn('not found!', output)
        self.assertNotIn('<pyusb backend missing>', output)


Add proper css classes to action buttons

--- nazs/web/core/blocks.py
+++ nazs/web/core/blocks.py
@@ -30,15 +30,18 @@
         columns=(
             ('install', tables.ActionColumn(verbose_name=_('Install'),
                                             action='core:install_module',
+                                            classes='btn btn-sm btn-primary',
                                             visible=lambda m: not m.installed)),

             ('enable', tables.ActionColumn(verbose_name=_('Enable'),
                                            action='core:enable_module',
+                                           classes='btn btn-sm btn-success',
                                            visible=lambda m: m.installed and
                                            not m.enabled)),

             ('disable', tables.ActionColumn(verbose_name=_('Disable'),
                                             action='core:disable_module',
+                                            classes='btn btn-sm btn-danger',
                                             visible=lambda m: m.installed and
                                             m.enabled)),
         )

<|original_code|>
from django.utils.translation import ugettext as _
from achilles import blocks, tables

import nazs

register = blocks.Library('core')

@register.block(template_name='web/core/welcome.html')
def home():
    return {'version': nazs.__version__}

@register.block(template_name='web/core/apply_button.html')
def apply_button():
    return {'active': nazs.changed()}

@register.block('modules')
class Modules(tables.Table):

    id_field = 'name'

    # Module name
    name = tables.Column(verbose_name=_('Module'))

    # Module status
    status = tables.MergeColumn(
        verbose_name=_('Status'),
        columns=(
            ('install', tables.ActionColumn(verbose_name=_('Install'),
                                            action='core:install_module',
                                            visible=lambda m: not m.installed)),

            ('enable', tables.ActionColumn(verbose_name=_('Enable'),
                                           action='core:enable_module',
                                           visible=lambda m: m.installed and
                                           not m.enabled)),

            ('disable', tables.ActionColumn(verbose_name=_('Disable'),
                                            action='core:disable_module',
                                            visible=lambda m: m.installed and
                                            m.enabled)),
        )
    )

    def objects(self):
        return nazs.modules()

    def get_object(self, name):
        for module in nazs.modules():
            if module.name == name:
                return module

        raise KeyError('Module %s not found' % name)

<|edits_diff|>
--- nazs/web/core/blocks.py
+++ nazs/web/core/blocks.py
@@ -30,10 +30,12 @@
         columns=(
             ('install', tables.ActionColumn(verbose_name=_('Install'),
                                             action='core:install_module',
+                                            classes='btn btn-sm btn-primary',
                                             visible=lambda m: not m.installed)),

             ('enable', tables.ActionColumn(verbose_name=_('Enable'),
                                            action='core:enable_module',
+                                           classes='btn btn-sm btn-success',
                                            visible=lambda m: m.installed and
                                            not m.enabled)),

<|current_version|>
from django.utils.translation import ugettext as _
from achilles import blocks, tables

import nazs

register = blocks.Library('core')

@register.block(template_name='web/core/welcome.html')
def home():
    return {'version': nazs.__version__}

@register.block(template_name='web/core/apply_button.html')
def apply_button():
    return {'active': nazs.changed()}

@register.block('modules')
class Modules(tables.Table):

    id_field = 'name'

    # Module name
    name = tables.Column(verbose_name=_('Module'))

    # Module status
    status = tables.MergeColumn(
        verbose_name=_('Status'),
        columns=(
            ('install', tables.ActionColumn(verbose_name=_('Install'),
                                            action='core:install_module',
                                            classes='btn btn-sm btn-primary',
                                            visible=lambda m: not m.installed)),

            ('enable', tables.ActionColumn(verbose_name=_('Enable'),
                                           action='core:enable_module',
                                           classes='btn btn-sm btn-success',
                                           visible=lambda m: m.installed and
                                           not m.enabled)),

            ('disable', tables.ActionColumn(verbose_name=_('Disable'),
                                            action='core:disable_module',
                                            visible=lambda m: m.installed and
                                            m.enabled)),
        )
    )

    def objects(self):
        return nazs.modules()

    def get_object(self, name):
        for module in nazs.modules():
            if module.name == name:
                return module

        raise KeyError('Module %s not found' % name)

<|next_version|>
from django.utils.translation import ugettext as _
from achilles import blocks, tables

import nazs

register = blocks.Library('core')

@register.block(template_name='web/core/welcome.html')
def home():
    return {'version': nazs.__version__}

@register.block(template_name='web/core/apply_button.html')
def apply_button():
    return {'active': nazs.changed()}

@register.block('modules')
class Modules(tables.Table):

    id_field = 'name'

    # Module name
    name = tables.Column(verbose_name=_('Module'))

    # Module status
    status = tables.MergeColumn(
        verbose_name=_('Status'),
        columns=(
            ('install', tables.ActionColumn(verbose_name=_('Install'),
                                            action='core:install_module',
                                            classes='btn btn-sm btn-primary',
                                            visible=lambda m: not m.installed)),

            ('enable', tables.ActionColumn(verbose_name=_('Enable'),
                                           action='core:enable_module',
                                           classes='btn btn-sm btn-success',
                                           visible=lambda m: m.installed and
                                           not m.enabled)),

            ('disable', tables.ActionColumn(verbose_name=_('Disable'),
                                            action='core:disable_module',
                                            classes='btn btn-sm btn-danger',
                                            visible=lambda m: m.installed and
                                            m.enabled)),
        )
    )

    def objects(self):
        return nazs.modules()

    def get_object(self, name):
        for module in nazs.modules():
            if module.name == name:
                return module

        raise KeyError('Module %s not found' % name)