<commit_before># -*- coding: utf-8 -*-
'''
    :codeauthor: :email:`Jayesh Kariya <jayeshk@saltstack.com>`
'''

# Import Python Libs
from __future__ import absolute_import

# Import Salt Testing Libs
from salttesting import TestCase, skipIf
from salttesting.mock import (
    MagicMock,
    patch,
    NO_MOCK,
    NO_MOCK_REASON
)

from salttesting.helpers import ensure_in_syspath

ensure_in_syspath('../../')

# Import Salt Libs
from salt.modules import schedule

# Globals
schedule.__salt__ = {}
schedule.__opts__ = {}
schedule.__pillar__ = {}

JOB1 = {'function': 'test.ping', 'maxrunning': 1, 'name': 'job1',
        'jid_include': True}

@skipIf(NO_MOCK, NO_MOCK_REASON)
class ScheduleTestCase(TestCase):
    '''
    Test cases for salt.modules.schedule
    '''
    # 'list_' function tests: 1

    def test_list(self):
        '''
        Test if it list the jobs currently scheduled on the minion.
        '''
        with patch.dict(schedule.__opts__, {'schedule': {'_seconds': []}}):
            self.assertEqual(schedule.list_(), 'schedule:\n  _seconds: []\n')
            self.assertDictEqual(schedule.list_(True, False), {'_seconds': []})

        with patch.dict(schedule.__opts__, {'schedule': {}}):
            self.assertDictEqual(schedule.list_(), {'schedule': {}})

    # 'purge' function tests: 1

    def test_purge(self):
        '''
        Test if it purge all the jobs currently scheduled on the minion.
        '''
        with patch.dict(schedule.__opts__, {'schedule': {}}):
            self.assertDictEqual(schedule.purge(), {'comment': [],
                                                    'result': True})

    # 'delete' function tests: 1

    def test_delete(self):
        '''
        Test if it delete a job from the minion's schedule.
        '''
        with patch.dict(schedule.__opts__, {'schedule': {}}):
            self.assertDictEqual(schedule.delete('job1'),
                                 {'comment': 'Job job1 does not exist.',
                                  'result': False})

    # 'build_schedule_item' function tests: 1

    def test_build_schedule_item(self):
        '''
        Test if it build a schedule job.
        '''
        comment = ('Unable to use "seconds", "minutes", "hours",'
                   ' or "days" with "when" or "cron" options.')
        comment1 = ('Unable to use "when" and "cron"'
                    ' options together.  Ignoring.')
        with patch.dict(schedule.__opts__, {'job1': {}}):
            self.assertDictEqual(schedule.build_schedule_item(''),
                                 {'comment': 'Job name is required.',
                                  'result': False})

            self.assertDictEqual(schedule.build_schedule_item
                                 ('job1', function='test.ping'),
                                 {'function': 'test.ping', 'maxrunning': 1,
                                  'name': 'job1', 'jid_include': True})

            self.assertDictEqual(schedule.build_schedule_item
                                 ('job1', function='test.ping', seconds=3600,
                                  when='2400'),
                                 {'comment': comment, 'result': False})

            self.assertDictEqual(schedule.build_schedule_item
                                 ('job1', function='test.ping', when='2400',
                                  cron='2'),
                                 {'comment': comment1, 'result': False})

    # 'add' function tests: 1

    def test_add(self):
        '''
        Test if it add a job to the schedule.
        '''
        comm1 = 'Job job1 already exists in schedule.'
        comm2 = ('Error: Unable to use "seconds", "minutes", "hours",'
                 ' or "days" with "when" or "cron" options.')
        comm3 = 'Unable to use "when" and "cron" options together.  Ignoring.'
        comm4 = 'Job: job2 would be added to schedule.'
        with patch.dict(schedule.__opts__, {'schedule': {'job1': 'salt'}}):
            self.assertDictEqual(schedule.add('job1'),
                                 {'comment': comm1, 'result': True})

            self.assertDictEqual(schedule.add('job2', function='test.ping',
                                              seconds=3600, when='2400'),
                                 {'comment': comm2, 'result': False})

            self.assertDictEqual(schedule.add('job2', function='test.ping',
                                              when='2400', cron='2'),
                                 {'comment': comm3, 'result': False})

            self.assertDictEqual(schedule.add('job2', function='test.ping',
                                              test=True),
                                 {'comment': comm4, 'result': True})

    # 'modify' function tests: 1

    def test_modify(self):
        '''
        Test if it modify an existing job in the schedule.
        '''
        comm1 = ('Error: Unable to use "seconds", "minutes", "hours",'
                 ' or "days" with "when" option.')
        comm2 = 'Unable to use "when" and "cron" options together.  Ignoring.'
        comm3 = 'Job job2 does not exist in schedule.'
        chan = {'diff': ('--- \n+++ \n@@ -0,0 +1,4 @@\n+function:test.ping\n+'
                         'jid_include:True\n+maxrunning:1\n+name:job3\n')}
        comm4 = 'Job: job3 would be modified in schedule.'
        with patch.dict(schedule.__opts__, {'schedule': {'job1': JOB1,
                                                         'job3': {}}}):
            self.assertDictEqual(schedule.modify('job1', function='test.ping',
                                                 seconds=3600, when='2400'),
                                 {'changes': {}, 'comment': comm1,
                                  'result': False})

            self.assertDictEqual(schedule.modify('job1', function='test.ping',
                                                 when='2400', cron='2'),
                                 {'changes': {}, 'comment': comm2,
                                  'result': False})

            self.assertDictEqual(schedule.modify('job2'), {'changes': {},
                                                           'comment': comm3,
                                                           'result': False})

            self.assertDictEqual(schedule.modify('job1', function='test.ping'),
                                 {'changes': {},
                                  'comment': 'Job job1 in correct state',
                                  'result': True})

            self.assertDictEqual(schedule.modify('job3', function='test.ping',
                                                 test=True),
                                 {'changes': chan, 'comment': comm4,
                                  'result': True})

    # 'run_job' function tests: 1

    def test_run_job(self):
        '''
        Test if it run a scheduled job on the minion immediately.
        '''
        with patch.dict(schedule.__opts__, {'schedule': {}}):
            self.assertDictEqual(schedule.run_job('job1'),
                                 {'comment': 'Job job1 does not exist.',
                                  'result': False})

    # 'enable_job' function tests: 1

    def test_enable_job(self):
        '''
        Test if it enable a job in the minion's schedule.
        '''
        with patch.dict(schedule.__opts__, {'schedule': {}}):
            self.assertDictEqual(schedule.enable_job('job1'),
                                 {'comment': 'Job job1 does not exist.',
                                  'result': False})

    # 'disable_job' function tests: 1

    def test_disable_job(self):
        '''
        Test if it disable a job in the minion's schedule.
        '''
        with patch.dict(schedule.__opts__, {'schedule': {}}):
            self.assertDictEqual(schedule.disable_job('job1'),
                                 {'comment': 'Job job1 does not exist.',
                                  'result': False})

    # 'save' function tests: 1

    def test_save(self):
        '''
        Test if it save all scheduled jobs on the minion.
        '''
        comm1 = 'Schedule (non-pillar items) saved to ///schedule.conf.'
        with patch.dict(schedule.__opts__, {'config_dir': '', 'schedule': {},
                                            'default_include': '/tmp'}):
            self.assertDictEqual(schedule.save(),
                                 {'comment': comm1, 'result': True})

    # 'enable' function tests: 1

    def test_enable(self):
        '''
        Test if it enable all scheduled jobs on the minion.
        '''
        self.assertDictEqual(schedule.enable(test=True),
                             {'comment': 'Schedule would be enabled.',
                              'result': True})

    # 'disable' function tests: 1

    def test_disable(self):
        '''
        Test if it disable all scheduled jobs on the minion.
        '''
        self.assertDictEqual(schedule.disable(test=True),
                             {'comment': 'Schedule would be disabled.',
                              'result': True})

    # 'reload_' function tests: 1

    def test_reload_(self):
        '''
        Test if it reload saved scheduled jobs on the minion.
        '''
        mock = MagicMock(return_value=True)
        with patch.dict(schedule.__opts__, {'config_dir': '',
                                            'default_include': '/tmp'}):
            with patch.dict(schedule.__salt__, {'event.fire': mock}):
                self.assertDictEqual(schedule.reload_(),
                                     {'comment': [], 'result': True})

    # 'move' function tests: 1

    def test_move(self):
        '''
        Test if it move scheduled job to another minion or minions.
        '''
        comm1 = 'no servers answered the published schedule.add command'
        comm2 = 'the following minions return False'
        comm3 = 'Moved Job job1 from schedule.'
        with patch.dict(schedule.__opts__, {'schedule': {'job1': JOB1}}):
            mock = MagicMock(return_value={})
            with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                self.assertDictEqual(schedule.move('job1', 'minion1'),
                                     {'comment': comm1, 'result': True})

            mock = MagicMock(return_value={'minion1': ''})
            with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                self.assertDictEqual(schedule.move('job1', 'minion1'),
                                     {'comment': comm2, 'minions': ['minion1'],
                                      'result': True})

            mock = MagicMock(return_value={'minion1': 'job1'})
            with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                mock = MagicMock(return_value=True)
                with patch.dict(schedule.__salt__, {'event.fire': mock}):
                    self.assertDictEqual(schedule.move('job1', 'minion1'),
                                         {'comment': comm3,
                                          'minions': ['minion1'],
                                          'result': True})

            self.assertDictEqual(schedule.move('job3', 'minion1'),
                                 {'comment': 'Job job3 does not exist.',
                                  'result': False})

        mock = MagicMock(side_effect=[{}, {'job1': {}}])
        with patch.dict(schedule.__opts__, {'schedule': mock}):
            with patch.dict(schedule.__pillar__, {'schedule': {'job1': JOB1}}):
                mock = MagicMock(return_value={})
                with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                    self.assertDictEqual(schedule.move('job1', 'minion1'),
                                         {'comment': comm1,
                                          'result': True})

                mock = MagicMock(return_value={'minion1': ''})
                with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                    self.assertDictEqual(schedule.move('job1', 'minion1'),
                                         {'comment': comm2,
                                          'minions': ['minion1'],
                                          'result': True})

                mock = MagicMock(return_value={'minion1': 'job1'})
                with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                    mock = MagicMock(return_value=True)
                    with patch.dict(schedule.__salt__, {'event.fire': mock}):
                        self.assertDictEqual(schedule.move('job1', 'minion1'),
                                             {'comment': comm3,
                                              'minions': ['minion1'],
                                              'result': True})

    # 'copy' function tests: 1

    def test_copy(self):
        '''
        Test if it copy scheduled job to another minion or minions.
        '''
        comm1 = 'no servers answered the published schedule.add command'
        comm2 = 'the following minions return False'
        comm3 = 'Copied Job job1 from schedule to minion(s).'
        with patch.dict(schedule.__opts__, {'schedule': {'job1': JOB1}}):
            mock = MagicMock(return_value={})
            with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                self.assertDictEqual(schedule.copy('job1', 'minion1'),
                                     {'comment': comm1, 'result': True})

            mock = MagicMock(return_value={'minion1': ''})
            with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                self.assertDictEqual(schedule.copy('job1', 'minion1'),
                                     {'comment': comm2, 'minions': ['minion1'],
                                      'result': True})

            mock = MagicMock(return_value={'minion1': 'job1'})
            with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                mock = MagicMock(return_value=True)
                with patch.dict(schedule.__salt__, {'event.fire': mock}):
                    self.assertDictEqual(schedule.copy('job1', 'minion1'),
                                         {'comment': comm3,
                                          'minions': ['minion1'],
                                          'result': True})

            self.assertDictEqual(schedule.copy('job3', 'minion1'),
                                 {'comment': 'Job job3 does not exist.',
                                  'result': False})

        mock = MagicMock(side_effect=[{}, {'job1': {}}])
        with patch.dict(schedule.__opts__, {'schedule': mock}):
            with patch.dict(schedule.__pillar__, {'schedule': {'job1': JOB1}}):
                mock = MagicMock(return_value={})
                with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                    self.assertDictEqual(schedule.copy('job1', 'minion1'),
                                         {'comment': comm1, 'result': True})

                mock = MagicMock(return_value={'minion1': ''})
                with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                    self.assertDictEqual(schedule.copy('job1', 'minion1'),
                                         {'comment': comm2,
                                          'minions': ['minion1'],
                                          'result': True})

                mock = MagicMock(return_value={'minion1': 'job1'})
                with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                    mock = MagicMock(return_value=True)
                    with patch.dict(schedule.__salt__, {'event.fire': mock}):
                        self.assertDictEqual(schedule.copy('job1', 'minion1'),
                                             {'comment': comm3,
                                              'minions': ['minion1'],
                                              'result': True})

if __name__ == '__main__':
    from integration import run_tests
    run_tests(ScheduleTestCase, needs_daemon=False)
<commit_msg>decrease specificity in schedule.modify unit test<commit_after># -*- coding: utf-8 -*-
'''
    :codeauthor: :email:`Jayesh Kariya <jayeshk@saltstack.com>`
'''

# Import Python Libs
from __future__ import absolute_import

# Import Salt Testing Libs
from salttesting import TestCase, skipIf
from salttesting.mock import (
    MagicMock,
    patch,
    NO_MOCK,
    NO_MOCK_REASON
)

from salttesting.helpers import ensure_in_syspath

ensure_in_syspath('../../')

# Import Salt Libs
from salt.modules import schedule

# Globals
schedule.__salt__ = {}
schedule.__opts__ = {}
schedule.__pillar__ = {}

JOB1 = {'function': 'test.ping', 'maxrunning': 1, 'name': 'job1',
        'jid_include': True}

@skipIf(NO_MOCK, NO_MOCK_REASON)
class ScheduleTestCase(TestCase):
    '''
    Test cases for salt.modules.schedule
    '''
    # 'list_' function tests: 1

    def test_list(self):
        '''
        Test if it list the jobs currently scheduled on the minion.
        '''
        with patch.dict(schedule.__opts__, {'schedule': {'_seconds': []}}):
            self.assertEqual(schedule.list_(), 'schedule:\n  _seconds: []\n')
            self.assertDictEqual(schedule.list_(True, False), {'_seconds': []})

        with patch.dict(schedule.__opts__, {'schedule': {}}):
            self.assertDictEqual(schedule.list_(), {'schedule': {}})

    # 'purge' function tests: 1

    def test_purge(self):
        '''
        Test if it purge all the jobs currently scheduled on the minion.
        '''
        with patch.dict(schedule.__opts__, {'schedule': {}}):
            self.assertDictEqual(schedule.purge(), {'comment': [],
                                                    'result': True})

    # 'delete' function tests: 1

    def test_delete(self):
        '''
        Test if it delete a job from the minion's schedule.
        '''
        with patch.dict(schedule.__opts__, {'schedule': {}}):
            self.assertDictEqual(schedule.delete('job1'),
                                 {'comment': 'Job job1 does not exist.',
                                  'result': False})

    # 'build_schedule_item' function tests: 1

    def test_build_schedule_item(self):
        '''
        Test if it build a schedule job.
        '''
        comment = ('Unable to use "seconds", "minutes", "hours",'
                   ' or "days" with "when" or "cron" options.')
        comment1 = ('Unable to use "when" and "cron"'
                    ' options together.  Ignoring.')
        with patch.dict(schedule.__opts__, {'job1': {}}):
            self.assertDictEqual(schedule.build_schedule_item(''),
                                 {'comment': 'Job name is required.',
                                  'result': False})

            self.assertDictEqual(schedule.build_schedule_item
                                 ('job1', function='test.ping'),
                                 {'function': 'test.ping', 'maxrunning': 1,
                                  'name': 'job1', 'jid_include': True})

            self.assertDictEqual(schedule.build_schedule_item
                                 ('job1', function='test.ping', seconds=3600,
                                  when='2400'),
                                 {'comment': comment, 'result': False})

            self.assertDictEqual(schedule.build_schedule_item
                                 ('job1', function='test.ping', when='2400',
                                  cron='2'),
                                 {'comment': comment1, 'result': False})

    # 'add' function tests: 1

    def test_add(self):
        '''
        Test if it add a job to the schedule.
        '''
        comm1 = 'Job job1 already exists in schedule.'
        comm2 = ('Error: Unable to use "seconds", "minutes", "hours",'
                 ' or "days" with "when" or "cron" options.')
        comm3 = 'Unable to use "when" and "cron" options together.  Ignoring.'
        comm4 = 'Job: job2 would be added to schedule.'
        with patch.dict(schedule.__opts__, {'schedule': {'job1': 'salt'}}):
            self.assertDictEqual(schedule.add('job1'),
                                 {'comment': comm1, 'result': True})

            self.assertDictEqual(schedule.add('job2', function='test.ping',
                                              seconds=3600, when='2400'),
                                 {'comment': comm2, 'result': False})

            self.assertDictEqual(schedule.add('job2', function='test.ping',
                                              when='2400', cron='2'),
                                 {'comment': comm3, 'result': False})

            self.assertDictEqual(schedule.add('job2', function='test.ping',
                                              test=True),
                                 {'comment': comm4, 'result': True})

    # 'modify' function tests: 1

    def test_modify(self):
        '''
        Test if it modify an existing job in the schedule.
        '''
        comm1 = ('Error: Unable to use "seconds", "minutes", "hours",'
                 ' or "days" with "when" option.')
        comm2 = 'Unable to use "when" and "cron" options together.  Ignoring.'
        comm3 = 'Job job2 does not exist in schedule.'
        comm4 = 'Job: job3 would be modified in schedule.'
        with patch.dict(schedule.__opts__, {'schedule': {'job1': JOB1,
                                                         'job3': {}}}):
            self.assertDictEqual(schedule.modify('job1', function='test.ping',
                                                 seconds=3600, when='2400'),
                                 {'changes': {}, 'comment': comm1,
                                  'result': False})

            self.assertDictEqual(schedule.modify('job1', function='test.ping',
                                                 when='2400', cron='2'),
                                 {'changes': {}, 'comment': comm2,
                                  'result': False})

            self.assertDictEqual(schedule.modify('job2'), {'changes': {},
                                                           'comment': comm3,
                                                           'result': False})

            self.assertDictEqual(schedule.modify('job1', function='test.ping'),
                                 {'changes': {},
                                  'comment': 'Job job1 in correct state',
                                  'result': True})

            ret = schedule.modify('job3', function='test.ping', test=True)
            del ret['changes']['diff']  # difflib formatting changes between 2.6 and 2.7
            self.assertDictEqual(ret, {'changes': {}, 'comment': comm4, 'result': True})

    # 'run_job' function tests: 1

    def test_run_job(self):
        '''
        Test if it run a scheduled job on the minion immediately.
        '''
        with patch.dict(schedule.__opts__, {'schedule': {}}):
            self.assertDictEqual(schedule.run_job('job1'),
                                 {'comment': 'Job job1 does not exist.',
                                  'result': False})

    # 'enable_job' function tests: 1

    def test_enable_job(self):
        '''
        Test if it enable a job in the minion's schedule.
        '''
        with patch.dict(schedule.__opts__, {'schedule': {}}):
            self.assertDictEqual(schedule.enable_job('job1'),
                                 {'comment': 'Job job1 does not exist.',
                                  'result': False})

    # 'disable_job' function tests: 1

    def test_disable_job(self):
        '''
        Test if it disable a job in the minion's schedule.
        '''
        with patch.dict(schedule.__opts__, {'schedule': {}}):
            self.assertDictEqual(schedule.disable_job('job1'),
                                 {'comment': 'Job job1 does not exist.',
                                  'result': False})

    # 'save' function tests: 1

    def test_save(self):
        '''
        Test if it save all scheduled jobs on the minion.
        '''
        comm1 = 'Schedule (non-pillar items) saved to ///schedule.conf.'
        with patch.dict(schedule.__opts__, {'config_dir': '', 'schedule': {},
                                            'default_include': '/tmp'}):
            self.assertDictEqual(schedule.save(),
                                 {'comment': comm1, 'result': True})

    # 'enable' function tests: 1

    def test_enable(self):
        '''
        Test if it enable all scheduled jobs on the minion.
        '''
        self.assertDictEqual(schedule.enable(test=True),
                             {'comment': 'Schedule would be enabled.',
                              'result': True})

    # 'disable' function tests: 1

    def test_disable(self):
        '''
        Test if it disable all scheduled jobs on the minion.
        '''
        self.assertDictEqual(schedule.disable(test=True),
                             {'comment': 'Schedule would be disabled.',
                              'result': True})

    # 'reload_' function tests: 1

    def test_reload_(self):
        '''
        Test if it reload saved scheduled jobs on the minion.
        '''
        mock = MagicMock(return_value=True)
        with patch.dict(schedule.__opts__, {'config_dir': '',
                                            'default_include': '/tmp'}):
            with patch.dict(schedule.__salt__, {'event.fire': mock}):
                self.assertDictEqual(schedule.reload_(),
                                     {'comment': [], 'result': True})

    # 'move' function tests: 1

    def test_move(self):
        '''
        Test if it move scheduled job to another minion or minions.
        '''
        comm1 = 'no servers answered the published schedule.add command'
        comm2 = 'the following minions return False'
        comm3 = 'Moved Job job1 from schedule.'
        with patch.dict(schedule.__opts__, {'schedule': {'job1': JOB1}}):
            mock = MagicMock(return_value={})
            with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                self.assertDictEqual(schedule.move('job1', 'minion1'),
                                     {'comment': comm1, 'result': True})

            mock = MagicMock(return_value={'minion1': ''})
            with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                self.assertDictEqual(schedule.move('job1', 'minion1'),
                                     {'comment': comm2, 'minions': ['minion1'],
                                      'result': True})

            mock = MagicMock(return_value={'minion1': 'job1'})
            with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                mock = MagicMock(return_value=True)
                with patch.dict(schedule.__salt__, {'event.fire': mock}):
                    self.assertDictEqual(schedule.move('job1', 'minion1'),
                                         {'comment': comm3,
                                          'minions': ['minion1'],
                                          'result': True})

            self.assertDictEqual(schedule.move('job3', 'minion1'),
                                 {'comment': 'Job job3 does not exist.',
                                  'result': False})

        mock = MagicMock(side_effect=[{}, {'job1': {}}])
        with patch.dict(schedule.__opts__, {'schedule': mock}):
            with patch.dict(schedule.__pillar__, {'schedule': {'job1': JOB1}}):
                mock = MagicMock(return_value={})
                with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                    self.assertDictEqual(schedule.move('job1', 'minion1'),
                                         {'comment': comm1,
                                          'result': True})

                mock = MagicMock(return_value={'minion1': ''})
                with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                    self.assertDictEqual(schedule.move('job1', 'minion1'),
                                         {'comment': comm2,
                                          'minions': ['minion1'],
                                          'result': True})

                mock = MagicMock(return_value={'minion1': 'job1'})
                with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                    mock = MagicMock(return_value=True)
                    with patch.dict(schedule.__salt__, {'event.fire': mock}):
                        self.assertDictEqual(schedule.move('job1', 'minion1'),
                                             {'comment': comm3,
                                              'minions': ['minion1'],
                                              'result': True})

    # 'copy' function tests: 1

    def test_copy(self):
        '''
        Test if it copy scheduled job to another minion or minions.
        '''
        comm1 = 'no servers answered the published schedule.add command'
        comm2 = 'the following minions return False'
        comm3 = 'Copied Job job1 from schedule to minion(s).'
        with patch.dict(schedule.__opts__, {'schedule': {'job1': JOB1}}):
            mock = MagicMock(return_value={})
            with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                self.assertDictEqual(schedule.copy('job1', 'minion1'),
                                     {'comment': comm1, 'result': True})

            mock = MagicMock(return_value={'minion1': ''})
            with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                self.assertDictEqual(schedule.copy('job1', 'minion1'),
                                     {'comment': comm2, 'minions': ['minion1'],
                                      'result': True})

            mock = MagicMock(return_value={'minion1': 'job1'})
            with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                mock = MagicMock(return_value=True)
                with patch.dict(schedule.__salt__, {'event.fire': mock}):
                    self.assertDictEqual(schedule.copy('job1', 'minion1'),
                                         {'comment': comm3,
                                          'minions': ['minion1'],
                                          'result': True})

            self.assertDictEqual(schedule.copy('job3', 'minion1'),
                                 {'comment': 'Job job3 does not exist.',
                                  'result': False})

        mock = MagicMock(side_effect=[{}, {'job1': {}}])
        with patch.dict(schedule.__opts__, {'schedule': mock}):
            with patch.dict(schedule.__pillar__, {'schedule': {'job1': JOB1}}):
                mock = MagicMock(return_value={})
                with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                    self.assertDictEqual(schedule.copy('job1', 'minion1'),
                                         {'comment': comm1, 'result': True})

                mock = MagicMock(return_value={'minion1': ''})
                with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                    self.assertDictEqual(schedule.copy('job1', 'minion1'),
                                         {'comment': comm2,
                                          'minions': ['minion1'],
                                          'result': True})

                mock = MagicMock(return_value={'minion1': 'job1'})
                with patch.dict(schedule.__salt__, {'publish.publish': mock}):
                    mock = MagicMock(return_value=True)
                    with patch.dict(schedule.__salt__, {'event.fire': mock}):
                        self.assertDictEqual(schedule.copy('job1', 'minion1'),
                                             {'comment': comm3,
                                              'minions': ['minion1'],
                                              'result': True})

if __name__ == '__main__':
    from integration import run_tests
    run_tests(ScheduleTestCase, needs_daemon=False)
<|endoftext|>


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

import utility
from commands import Command

from json import JSONDecoder

class IMDbCommand(Command):
	usage = "Usage: .imdb <search term>"

	def __init__(self):
		pass

	def query(self, argument):
		decoder = JSONDecoder()
		argument = utility.escape(argument)
		api_url = u"http://www.imdbapi.com/?t=%(search_term)s&r=json&plot=short" % \
				{"search_term": argument}
		site_search_url = u"http://akas.imdb.com/find?s=all&q=" + argument
		response = utility.read_url(api_url)

		if not response:
			return u"Couldn't connect to the API :( | Manual search: " + site_search_url

		try:
			data = decoder.decode(response['data'])
		except Exception:
			return u"Couldn't parse the API output :( | Manual search: " + site_search_url

		if data.get(u"Response") != u"True":
			return u"No results found! Maybe you should try searching manually: " + \
					site_search_url

		return \
				(u"%(title)s (%(year)s) - Rating: %(rating)s out of 10 - Genre: %(genre)s - " + \
				u"http://akas.imdb.com/title/%(id)s/ | More results: %(site_search_url)s") % \
				{u"title": data.get(u"Title", u"Missing title :S"),
					u"year": data.get(u"Year", u"Unknown year"),
					u"rating": data.get(u"Rating", u"N/A"),
					u"genre": data.get(u"Genre", u"Unknown"),
					u"id": data.get(u"ID", u"tt0107838"),
					u"site_search_url": site_search_url}

	def trig_imdb(self, bot, source, target, trigger, argument):
		"""Command that queries IMDb - The Internet Movie Database."""

		argument = argument.strip()

		# Show usage
		if not argument:
			return "IMDb - The Internet Movie Database. " + self.usage

		# Query API
		else:
			return self.query(argument).encode("utf-8")

<commit_msg>Fixed the IMDb plugin slightly<commit_after># -*- coding: utf-8 -*-

import utility
from commands import Command

from json import JSONDecoder

class IMDbCommand(Command):
	usage = "Usage: .imdb <search term>"

	def __init__(self):
		pass

	def query(self, argument):
		decoder = JSONDecoder()
		argument = utility.escape(argument)
                api_url = u"http://www.omdbapi.com/?t=%(search_term)s&r=json&plot=short" % \
                                {"search_term": argument}
		site_search_url = u"http://akas.imdb.com/find?s=all&q=" + argument
		response = utility.read_url(api_url)

		if not response:
			return u"Couldn't connect to the API :( | Manual search: " + site_search_url

		try:
			data = decoder.decode(response['data'])
		except Exception:
			return u"Couldn't parse the API output :( | Manual search: " + site_search_url

		if data.get(u"Response") != u"True":
			return u"No results found! Maybe you should try searching manually: " + \
					site_search_url

		return \
				(u"%(title)s (%(year)s) - Rating: %(rating)s out of 10 - Genre: %(genre)s - " + \
				u"http://akas.imdb.com/title/%(id)s/ | More results: %(site_search_url)s") % \
				{u"title": data.get(u"Title", u"Missing title :S"),
					u"year": data.get(u"Year", u"Unknown year"),
					u"rating": data.get(u"imdbRating", u"N/A"),
					u"genre": data.get(u"Genre", u"Unknown"),
					u"id": data.get(u"imdbID", u"tt0107838"),
					u"site_search_url": site_search_url}

	def trig_imdb(self, bot, source, target, trigger, argument):
		"""Command that queries IMDb - The Internet Movie Database."""

		argument = argument.strip()

		# Show usage
		if not argument:
			return "IMDb - The Internet Movie Database. " + self.usage

		# Query API
		else:
			return self.query(argument).encode("utf-8")

<|endoftext|>


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

# Copyright(C) 2010  Romain Bignon, Christophe Benz
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

from datetime import datetime, timedelta

from .base import IBaseCap, CapBaseObject, NotLoaded

__all__ = ['BaseVideo', 'ICapVideo']

class VideoThumbnail(CapBaseObject):
    def __init__(self, url):
        CapBaseObject.__init__(self, url)
        self.add_field('url', basestring, url.replace(' ', '%20'))
        self.add_field('data', str)

    def __str__(self):
        return self.url

    def __repr__(self):
        return '<Thumbnail url="%s">' % self.url

    def __iscomplete__(self):
        return self.data is not NotLoaded

class BaseVideo(CapBaseObject):
    def __init__(self, _id, title=NotLoaded, url=NotLoaded, author=NotLoaded, duration=NotLoaded, date=NotLoaded,
                 rating=NotLoaded, rating_max=NotLoaded, thumbnail=NotLoaded, thumbnail_url=None, nsfw=False):
        CapBaseObject.__init__(self, unicode(_id))

        self.add_field('title', basestring, title)
        self.add_field('url', basestring, url)
        self.add_field('author', basestring, author)
        self.add_field('description', basestring)
        self.add_field('duration', (int,long,timedelta), duration)
        self.add_field('date', datetime, date)
        self.add_field('rating', (int,long,float), rating)
        self.add_field('rating_max', (int,long,float), rating_max)
        self.add_field('thumbnail', VideoThumbnail, thumbnail)
        self.add_field('nsfw', bool, nsfw)

        # XXX remove this and fix all backends
        if thumbnail_url is not None and self.thumbnail is NotLoaded:
            self.thumbnail = VideoThumbnail(thumbnail_url)

    @classmethod
    def id2url(cls, _id):
        """Overloaded in child classes provided by backends."""
        raise NotImplementedError()

    @property
    def page_url(self):
        return self.id2url(self.id)

class ICapVideo(IBaseCap):
    def iter_page_urls(self, mozaic_url):
        raise NotImplementedError()

    (SEARCH_RELEVANCE,
     SEARCH_RATING,
     SEARCH_VIEWS,
     SEARCH_DATE) = range(4)

    def iter_search_results(self, pattern=None, sortby=SEARCH_RELEVANCE, nsfw=False, max_results=None):
        """
        Iter results of a search on a pattern. Note that if pattern is None,
        it get the latest videos.

        @param pattern  [str] pattern to search on
        @param sortby  [enum] sort by...
        @param nsfw  [bool] include non-suitable for work videos if True
        @param max_results  [int] maximum number of results to return
        """
        raise NotImplementedError()

    def get_video(self, _id):
        """
        Get a Video from an ID.

        @param _id  the video id. It can be a numeric ID, or a page url, or so.
        @return a Video object
        """
        raise NotImplementedError()
<commit_msg>remove unused method<commit_after># -*- coding: utf-8 -*-

# Copyright(C) 2010  Romain Bignon, Christophe Benz
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

from datetime import datetime, timedelta

from .base import IBaseCap, CapBaseObject, NotLoaded

__all__ = ['BaseVideo', 'ICapVideo']

class VideoThumbnail(CapBaseObject):
    def __init__(self, url):
        CapBaseObject.__init__(self, url)
        self.add_field('url', basestring, url.replace(' ', '%20'))
        self.add_field('data', str)

    def __str__(self):
        return self.url

    def __repr__(self):
        return '<Thumbnail url="%s">' % self.url

    def __iscomplete__(self):
        return self.data is not NotLoaded

class BaseVideo(CapBaseObject):
    def __init__(self, _id, title=NotLoaded, url=NotLoaded, author=NotLoaded, duration=NotLoaded, date=NotLoaded,
                 rating=NotLoaded, rating_max=NotLoaded, thumbnail=NotLoaded, thumbnail_url=None, nsfw=False):
        CapBaseObject.__init__(self, unicode(_id))

        self.add_field('title', basestring, title)
        self.add_field('url', basestring, url)
        self.add_field('author', basestring, author)
        self.add_field('description', basestring)
        self.add_field('duration', (int,long,timedelta), duration)
        self.add_field('date', datetime, date)
        self.add_field('rating', (int,long,float), rating)
        self.add_field('rating_max', (int,long,float), rating_max)
        self.add_field('thumbnail', VideoThumbnail, thumbnail)
        self.add_field('nsfw', bool, nsfw)

        # XXX remove this and fix all backends
        if thumbnail_url is not None and self.thumbnail is NotLoaded:
            self.thumbnail = VideoThumbnail(thumbnail_url)

    @classmethod
    def id2url(cls, _id):
        """Overloaded in child classes provided by backends."""
        raise NotImplementedError()

    @property
    def page_url(self):
        return self.id2url(self.id)

class ICapVideo(IBaseCap):
    (SEARCH_RELEVANCE,
     SEARCH_RATING,
     SEARCH_VIEWS,
     SEARCH_DATE) = range(4)

    def iter_search_results(self, pattern=None, sortby=SEARCH_RELEVANCE, nsfw=False, max_results=None):
        """
        Iter results of a search on a pattern. Note that if pattern is None,
        it get the latest videos.

        @param pattern  [str] pattern to search on
        @param sortby  [enum] sort by...
        @param nsfw  [bool] include non-suitable for work videos if True
        @param max_results  [int] maximum number of results to return
        """
        raise NotImplementedError()

    def get_video(self, _id):
        """
        Get a Video from an ID.

        @param _id  the video id. It can be a numeric ID, or a page url, or so.
        @return a Video object
        """
        raise NotImplementedError()
<|endoftext|>


<commit_before><commit_msg>Changed quotes to match the convention. #2<commit_after><|endoftext|>


<commit_before><commit_msg>minor changes to the workfile update method<commit_after><|endoftext|>


<commit_before><commit_msg>redone Config.findFile with @classmethod<commit_after><|endoftext|>


<commit_before>from django.conf.urls import patterns, url,include
from django.views.generic import TemplateView
from django.views.generic.base import RedirectView
from events import views

urlpatterns = patterns('',
    url(r'^my_abstract_list/$', views.list_my_abstracts, name="list_my_abstracts"),
    url(r'^my_registration_list/$', views.list_my_registration, name="list_my_registration"),
    url(r'^barcode/$', views.show_barcode, name="show_my_barcode"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/barcode/(?P<user_pk>\d+)/$', views.show_barcode, name="show_barcode_privileged"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/barcode/(?P<user_pk>\d+)/pdf$', views.BarcodePDFView.as_view(cmd_options = {
                'margin-top': 20,
                'margin-right': 20,
                'margin-left': 20,
                'page-size': 'A7',
            }, template_name='events/partials/badge.html', filename='Badge.pdf'), name="show_badge_pdf_privileged"),
    url(r'^barcode/pdf$', views.BarcodePDFView.as_view(cmd_options = {
                'margin-top': 10,
                'margin-right': 10,
                'margin-left': 10,
                'page-size': 'A7',
            }, template_name='events/partials/badge.html', filename='Badge.pdf'), name="show_badge_pdf"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/barcode_list/$', views.list_barcodes, name="list_barcodes"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/$', views.redirect_home, name="redirect_home"),
    #URL already puplished (to be changed after the end of hpc2)
    url(r'^(?P<event_code_name>[\d\w_\-]+)/sessions/list/$', views.list_sessions_privileged, name="list_sessions_privileged"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/sessions/$', views.list_timeslots, name="list_timeslots"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/timeslots/(?P<pk>\d+)/$', views.list_sessions, name="list_sessions"),
    url(r'^sessions/ajax/group$', views.handle_ajax, name="handle_ajax"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/sessions/(?P<pk>\d+)/$', views.show_session, name="show_session"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/sessions/(?P<pk>\d+)/attendance/$', views.show_attendance_interface, name="show_attendance_interface"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/sessions/(?P<pk>\d+)/attendance/process$', views.process_barcode, name="process_barcode"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/sessions/(?P<pk>\d+)/review/$', views.review_registrations, name="review_registrations"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/$', views.introduce_registration, name="registration_introduction"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/user/$', views.user_registration, name="user_registration"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/list/$', views.list_registrations, name="list_registrations"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/list/(?P<pk>\d+)/$', views.show_session_privileged, name="show_session_privileged"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/nonuser/$', views.nonuser_registration, name="nonuser_registration"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/thanks/$', views.registration_completed, name="registration_completed"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/closed/$', views.registration_closed, name="registration_closed"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/already/$', views.registration_already, name="registration_already"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/$', views.submit_abstract, name="submit_abstract"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/list/$', views.list_abstracts, name="list_abstracts"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/(?P<pk>\d+)/$', views.show_abstract, name="show_abstract"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/(?P<pk>\d+)/upload/$', views.presntation_upload,name="presntation_upload"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/thanks/$', TemplateView.as_view(template_name='events/abstracts/abstract_submission_completed.html'), name="abstract_submision_completed"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/(?P<pk>\d+)/edit/$', views.edit_abstract, name="edit_abstract"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/(?P<pk>\d+)/delete/$', views.delete_abstract, name="delete_abstract"),
    url(r'^abstracts/img/$',views.upload_abstract_image, name="upload_abstract_image"),
    url(r'^ckeditor/', include('ckeditor_uploader.urls')),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/initiatives/$', views.submit_initiative, name="submit_initiative"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/initiatives/list/$', views.list_initiatives, name="list_initiatives"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/initiatives/(?P<pk>\d+)/$', views.show_initiative, name="show_initiative"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/initiatives/thanks/$', TemplateView.as_view(template_name='events/initiatives/initiatives_submission_completed.html'), name="initiative_submission_completed"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/casereports/$', views.submit_case_report,name="submit_case_report"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/casereports/(?P<pk>\d+)/$', views.show_casereport,name="show_casereport"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/casereports/(?P<pk>\d+)/delete/$', views.delete_casereport,name="delete_casereport"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/(?P<code_name>[\d\w\-]+)/$', views.show_session_group,name="show_session_group"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/(?P<pk>\d+)/evaluate/$', views.evaluate, name="evaluate"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/(?P<pk>\d+)/evaluate/(?P<evaluation_id>[\d\w\-]+)/$', views.edit_evaluation,name="edit_evaluation"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/evaluators/$', views.evaluators_homepage,name="evaluators_homepage"),
                       )
<commit_msg>Add login_required<commit_after>from django.conf.urls import patterns, url,include
from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView
from django.views.generic.base import RedirectView
from events import views

urlpatterns = patterns('',
    url(r'^my_abstract_list/$', views.list_my_abstracts, name="list_my_abstracts"),
    url(r'^my_registration_list/$', views.list_my_registration, name="list_my_registration"),
    url(r'^barcode/$', views.show_barcode, name="show_my_barcode"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/barcode/(?P<user_pk>\d+)/$', views.show_barcode, name="show_barcode_privileged"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/barcode/(?P<user_pk>\d+)/pdf$', login_required(views.BarcodePDFView.as_view(cmd_options = {
                'margin-top': 20,
                'margin-right': 20,
                'margin-left': 20,
                'page-size': 'A7',
            }, template_name='events/partials/badge.html', filename='Badge.pdf')), name="show_badge_pdf_privileged"),
    url(r'^barcode/pdf$', login_required(views.BarcodePDFView.as_view(cmd_options = {
                'margin-top': 10,
                'margin-right': 10,
                'margin-left': 10,
                'page-size': 'A7',
            }, template_name='events/partials/badge.html', filename='Badge.pdf')), name="show_badge_pdf"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/barcode_list/$', views.list_barcodes, name="list_barcodes"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/$', views.redirect_home, name="redirect_home"),
    #URL already puplished (to be changed after the end of hpc2)
    url(r'^(?P<event_code_name>[\d\w_\-]+)/sessions/list/$', views.list_sessions_privileged, name="list_sessions_privileged"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/sessions/$', views.list_timeslots, name="list_timeslots"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/timeslots/(?P<pk>\d+)/$', views.list_sessions, name="list_sessions"),
    url(r'^sessions/ajax/group$', views.handle_ajax, name="handle_ajax"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/sessions/(?P<pk>\d+)/$', views.show_session, name="show_session"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/sessions/(?P<pk>\d+)/attendance/$', views.show_attendance_interface, name="show_attendance_interface"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/sessions/(?P<pk>\d+)/attendance/process$', views.process_barcode, name="process_barcode"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/sessions/(?P<pk>\d+)/review/$', views.review_registrations, name="review_registrations"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/$', views.introduce_registration, name="registration_introduction"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/user/$', views.user_registration, name="user_registration"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/list/$', views.list_registrations, name="list_registrations"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/list/(?P<pk>\d+)/$', views.show_session_privileged, name="show_session_privileged"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/nonuser/$', views.nonuser_registration, name="nonuser_registration"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/thanks/$', views.registration_completed, name="registration_completed"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/closed/$', views.registration_closed, name="registration_closed"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/registration/already/$', views.registration_already, name="registration_already"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/$', views.submit_abstract, name="submit_abstract"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/list/$', views.list_abstracts, name="list_abstracts"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/(?P<pk>\d+)/$', views.show_abstract, name="show_abstract"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/(?P<pk>\d+)/upload/$', views.presntation_upload,name="presntation_upload"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/thanks/$', TemplateView.as_view(template_name='events/abstracts/abstract_submission_completed.html'), name="abstract_submision_completed"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/(?P<pk>\d+)/edit/$', views.edit_abstract, name="edit_abstract"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/(?P<pk>\d+)/delete/$', views.delete_abstract, name="delete_abstract"),
    url(r'^abstracts/img/$',views.upload_abstract_image, name="upload_abstract_image"),
    url(r'^ckeditor/', include('ckeditor_uploader.urls')),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/initiatives/$', views.submit_initiative, name="submit_initiative"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/initiatives/list/$', views.list_initiatives, name="list_initiatives"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/initiatives/(?P<pk>\d+)/$', views.show_initiative, name="show_initiative"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/initiatives/thanks/$', TemplateView.as_view(template_name='events/initiatives/initiatives_submission_completed.html'), name="initiative_submission_completed"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/casereports/$', views.submit_case_report,name="submit_case_report"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/casereports/(?P<pk>\d+)/$', views.show_casereport,name="show_casereport"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/casereports/(?P<pk>\d+)/delete/$', views.delete_casereport,name="delete_casereport"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/(?P<code_name>[\d\w\-]+)/$', views.show_session_group,name="show_session_group"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/(?P<pk>\d+)/evaluate/$', views.evaluate, name="evaluate"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/(?P<pk>\d+)/evaluate/(?P<evaluation_id>[\d\w\-]+)/$', views.edit_evaluation,name="edit_evaluation"),
    url(r'^(?P<event_code_name>[\d\w_\-]+)/abstracts/evaluators/$', views.evaluators_homepage,name="evaluators_homepage"),
                       )
<|endoftext|>


<commit_before>##############################################################################
#
# Copyright (c) 2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
##############################################################################

import time
import wizard

_form = '''<?xml version="1.0"?>
<form string="Select period">
	<separator string="Cost Legder for period" colspan="4"/>
	<field name="date1"/>
	<field name="date2"/>
	<separator string="and Journals" colspan="4"/>
	<field name="journal" colspan="4"/>
</form>'''

_fields = {
	'date1': {'string':'Start of period', 'type':'date', 'required':True, 'default': lambda *a: time.strftime('%Y-01-01')},
	'date2': {'string':'End of period', 'type':'date', 'required':True, 'default': lambda *a: time.strftime('%Y-%m-%d')},
	'journal': {'string':'Journals','type':'many2many', 'relation':'account.analytic.journal'},
}

class wizard_report(wizard.interface):
	states = {
		'init': {
			'actions': [],
			'result': {
				'type': 'form',
				'arch': _form,
				'fields': _fields,
				'state': [
					('end','Cancel'),
					('report','Print')
				]
			}
		},
		'report': {
			'actions': [],
			'result': {
				'type': 'print',
				'report': 'account.analytic.account.cost_ledger',
				'state': 'end'
			}
		},
	}

wizard_report('account.analytic.account.quantity_cost_ledger.report')
<commit_msg>Link wizard to the right report cost ledger (quantities)<commit_after>##############################################################################
#
# Copyright (c) 2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
##############################################################################

import time
import wizard

_form = '''<?xml version="1.0"?>
<form string="Select period">
	<separator string="Cost Legder for period" colspan="4"/>
	<field name="date1"/>
	<field name="date2"/>
	<separator string="and Journals" colspan="4"/>
	<field name="journal" colspan="4"/>
</form>'''

_fields = {
	'date1': {'string':'Start of period', 'type':'date', 'required':True, 'default': lambda *a: time.strftime('%Y-01-01')},
	'date2': {'string':'End of period', 'type':'date', 'required':True, 'default': lambda *a: time.strftime('%Y-%m-%d')},
	'journal': {'string':'Journals','type':'many2many', 'relation':'account.analytic.journal'},
}

class wizard_report(wizard.interface):
	states = {
		'init': {
			'actions': [],
			'result': {
				'type': 'form',
				'arch': _form,
				'fields': _fields,
				'state': [
					('end','Cancel'),
					('report','Print')
				]
			}
		},
		'report': {
			'actions': [],
			'result': {
				'type': 'print',
				'report': 'account.analytic.account.quantity_cost_ledger',
				'state': 'end'
			}
		},
	}

wizard_report('account.analytic.account.quantity_cost_ledger.report')
<|endoftext|>


<commit_before>from __future__ import division
import numpy as np
import multiprocessing as mp
import math

MAXIMUM_STAGE_NUMBER = 10

def error_norm(y1, y2, Atol, Rtol):
    tol = Atol + np.maximum(y1,y2)*Rtol
    return np.linalg.norm((y1-y2)/tol)/(len(y1)**0.5)

def adapt_step(method, f, tn_1, yn_1, y, y_hat, h, p, Atol, Rtol, pool):
    '''
        Checks if the step size is accepted. If not, computes a new step size
        and checks again. Repeats until step size is accepted

        **Inputs**:
            - method    -- the method on which the extrapolation is based
            - f         -- the right hand side function of the IVP.
                        Must output a non-scalar numpy.ndarray
            - tn_1, yn_1 -- y(tn_1) = yn_1 is the last accepted value of the
                        computed solution
            - y, y_hat  -- the computed values of y(tn_1 + h) of order p and
                        (p-1), respectively
            - h         -- the step size taken and to be tested
            - p         -- the order of the higher extrapolation method
                        Assumed to be greater than 1.
            - Atol, Rtol -- the absolute and relative tolerance of the local
                         error.

        **Outputs**:
            - y, y_hat  -- the computed solution of orders p and (p-1) at the
                        accepted step size
            - h         -- the accepted step taken to compute y and y_hat
            - h_new     -- the proposed next step size
            - fe        -- the number of f evaluations
    '''

    fe = 0
    facmax = 5
    facmin = 0.2
    fac = 0.8
    err = error_norm(y, y_hat, Atol, Rtol)
    h_new = h*min(facmax, max(facmin, fac*((1/err)**(1/p))))

    while err > 1:
        h = h_new
        y, y_hat, fe_ = method(f, tn_1, yn_1, h, p, pool)
        fe += fe_
        err = error_norm(y, y_hat, Atol, Rtol)
        h_new = h*min(facmax, max(facmin, fac*((1/err)**(1/p))))

    return (y, y_hat, h, h_new, fe)

def extrapolation_parallel(method, f, t0, tf, y0, adaptive="order", p=4,
        step_size=0.5, Atol=0, Rtol=0, exact=(lambda t: t)):
    '''
        Solves the system of IVPs y'(t) = f(y, t) with extrapolation of order
        p based on method provided. The implementation is parallel.

        **Inputs**:
            - method    -- the method on which the extrapolation is based
            - f         -- the right hand side function of the IVP
                        Must output a non-scalar numpy.ndarray
            - [t0, tf]  -- the interval of integration
            - y0        -- the value of y(t0). Must be a non-scalar numpy.ndarray
            - adaptive  -- can be either of three values:
                            "fixed" = use fixed step size and order.
                            "step"  = use adaptive step size but fixed order.
                            "order" = use adaptive step size and adaptive order.
                        optional; defaults to "order"
            - p         -- the order of extrapolation if adaptive is not "order",
                        and the starting order otherwise. optional; defaults to 4
            - step_size -- the fixed step size when adaptive="fixed", and the
                        starting step size otherwise. optional; defaults to 0.5
            - Atol, Rtol -- the absolute and relative tolerance of the local
                         error. optional; both default to 0
            - exact     -- the exact solution to the IVP. Only used for
                        debugging. optional; defaults to (lambda t: t).
                        Must output a non-scalar numpy.ndarray

        **Outputs**:
            - ts, ys    -- the computed solution y for the IVP. y(ts[i]) = ys[i]
            - fe        -- the number of f evaluations
    '''

    processes = int((MAXIMUM_STAGE_NUMBER + 1)/2) + 1

    pool = mp.Pool(processes)

    fe = 0
    if adaptive == "fixed":
        ts, h = np.linspace(t0, tf, (tf-t0)/step_size + 1, retstep=True)
        ys = np.zeros((len(ts), len(y0)), dtype=(type(y0[0])))
        ys_hat = np.zeros((len(ts), len(y0)), dtype=(type(y0[0])))
        ys[0] = y0

        for i in range(len(ts) - 1):
            ys[i+1], ys_hat[i+1], fe_ = method(f, ts[i], ys[i], h, p, pool)
            fe += fe_

    elif adaptive == "step":
        assert p > 1, "order of method must be greater than 1 if adaptive=True"
        ts = np.zeros((1, len(y0)), dtype=(type(y0[0])))
        ys = np.zeros((1, len(y0)), dtype=(type(y0[0])))
        ys_hat = np.zeros((1, len(y0)), dtype=(type(y0[0])))
        ts[0] = t0
        ys[0] = y0
        ys_hat[0] = y0
        h = min(step_size, tf-t0)

        t, i = t0, 0
        while t < tf:
            y, y_hat, fe_ = method(f, ts[i], ys[i], h, p, pool)
            fe += fe_
            y, y_hat, h, h_new, fe_ = adapt_step(method, f, ts[i], ys[i],
                y, y_hat, h, p, Atol, Rtol, pool)
            t, i, fe = t + h, i+1, fe + fe_
            ts = np.append(ts, t)
            ys = np.vstack((ys, y))
            ys_hat = np.vstack((ys_hat, y_hat))
            h = min(h_new, tf - t)

    elif adaptive == "order":
        ts = np.zeros((1, len(y0)), dtype=(type(y0[0])))
        ys = np.zeros((1, len(y0)), dtype=(type(y0[0])))
        ts[0] = t0
        ys[0] = y0
        h = min(step_size, tf-t0)

        h_acc = []
        k_acc = []
        h_rej = []
        k_rej = []

        t, i, k = t0, 0, p
        while t < tf:
            y, h, k, h_new, k_new, h_rej_, k_rej_, fe_ = method(f, ts[i], ys[i],
                h, k, Atol, Rtol, pool)
            t, i, fe = t + h, i+1, fe + fe_
            ts = np.append(ts, t)
            ys = np.vstack((ys, y))
            h_acc.append(h)
            k_acc.append(k)
            h_rej.append(h_rej_)
            k_rej.append(k_rej_)
            h = min(h_new, tf - t)
            k = k_new

        return (ts, ys, fe, h_acc, k_acc, h_rej, k_rej)
    else:
        raise Exception("\'" + str(adaptive) +
            "\' is not a valid value for the argument \'adaptive\'")

    pool.close()
    return (ts, ys, fe)

def compute_stages((f, tn, yn, h, k_lst)):
    res = []
    for k in k_lst:
        k = int(k)
        Y = np.zeros((2*k+1, len(yn)), dtype=(type(yn[0])))
        fe = 0
        Y[0] = yn
        Y[1] = Y[0] + h/(2*k)*f(Y[0], tn)
        for j in range(2,2*k+1):
            Y[j] = Y[j-2] + (h/k)*f(Y[j-1], tn + (j-1)*(h/(2*k)))
            fe += 1
        res += [(k, Y[2*k], fe)]

    return res

def compute_ex_table(f, tn, yn, h, k, pool):
    T = np.zeros((k+1,k+1, len(yn)), dtype=(type(yn[0])))
    fe = 0

    if k % 2 == 1:
        ks = [[k]] + [[i, k - i] for i in range(1, int(k/2)+1)]
    else:
        ks = [[k]] + [[i, k - i] for i in range(1, int(k/2))] + [[k/2]]

    jobs = [(f, tn, yn, h, k_lst) for k_lst in ks]

    results = pool.map(compute_stages, jobs, chunksize=1)

    # process the returned results from the pool
    for res in results:
        for (k_, Tk_, fe_) in res:
            fe += fe_
            T[k_, 1] = Tk_

    # compute extrapolation table
    for i in range(2, k+1):
        for j in range(i, k+1):
            T[j,i] = T[j,i-1] + (T[j,i-1] - T[j-1,i-1])/((j/(j-i+1))**2 - 1)

    return (T, fe)

def midpoint_fixed_step(f, tn, yn, h, p, pool):
    r = int(round(p/2))
    T, fe = compute_ex_table(f, tn, yn, h, r, pool)
    return (T[r,r], T[r-1,r-1], fe)

def midpoint_adapt_order(f, tn, yn, h, k, Atol, Rtol, pool):
    k_max = MAXIMUM_STAGE_NUMBER
    k_min = 3
    k = min(k_max, max(k_min, k))
    A_k = lambda k: k*(k+1)
    H_k = lambda h, k, err_k: h*0.94*(0.65/err_k)**(1/(2*k-1))
    W_k = lambda Ak,Hk: Ak/Hk
    h_rej = []
    k_rej = []

    T, fe = compute_ex_table(f, tn, yn, h, k+1, pool)

    # compute the error and work function for the stages (k-2) to (k+1)
    err_k_2 = error_norm(T[k-2,k-3], T[k-2,k-2], Atol, Rtol)
    err_k_1 = error_norm(T[k-1,k-2], T[k-1,k-1], Atol, Rtol)
    err_k   = error_norm(T[k,k-1],   T[k,k],     Atol, Rtol)
    err_k1  = error_norm(T[k+1,k],   T[k+1,k+1], Atol, Rtol)
    h_k_2   = H_k(h, k-2, err_k_2)
    h_k_1   = H_k(h, k-1, err_k_1)
    h_k     = H_k(h, k,   err_k)
    h_k1    = H_k(h, k+1, err_k1)
    w_k_2   = W_k(A_k(k-2), h_k_2)
    w_k_1   = W_k(A_k(k-1), h_k_1)
    w_k     = W_k(A_k(k),   h_k)
    w_k1    = W_k(A_k(k+1), h_k1)

    if err_k_1 <= 1:
        # convergence in line k-1
        y = T[k-1,k-1]
        k_new = k if w_k_1 < 0.9*w_k_2 else k-1
        h_new = h_k_1 if k_new <= k-1 else h_k_1*A_k(k)/A_k(k-1)

    elif err_k <= 1:
        # convergence in line k
        y = T[k,k]
        k_new = k-1 if w_k_1 < 0.9*w_k else (
                k+1 if w_k < 0.9*w_k_1 else k)
        h_new = h_k_1 if k_new == k-1 else (
                h_k if k_new == k else h_k*A_k(k+1)/A_k(k))

    elif err_k1 <= 1:
        # convergence in line k+1
        y = T[k+1,k+1]
        if w_k_1 < 0.9*w_k:
            k_new = k+1 if w_k1 < 0.9*w_k_1 else k-1
        else:
            k_new = k+1 if w_k1 < 0.9*w_k else k

        h_new = h_k_1 if k_new == k-1 else (
                h_k if k_new == k else h_k1)

    elif err_k_1 > ((k+1)*k)**2:
        # convergence monitor
        # reject (h, k) and restart with new values accordingly
        k_new = k-1
        h_new = min(h_k_1, h)
        h_rej.append(h)
        k_rej.append(k)
        y, h, k, h_new, k_new, h_rej_, k_rej_, fe_ = midpoint_adapt_order(f, tn,
            yn, h_new, k_new, Atol, Rtol, pool)
        fe += fe_
        h_rej += h_rej_
        k_rej += k_rej_

    elif err_k > (k+1)**2:
        # second convergence monitor
        # reject (h, k) and restart with new values accordingly
        k_new = k-1 if w_k_1 < 0.9*w_k else k
        h_new = min(h_k_1 if k_new == k-1 else h_k, h)
        h_rej.append(h)
        k_rej.append(k)
        y, h, k, h_new, k_new, h_rej_, k_rej_, fe_ = midpoint_adapt_order(f,
            tn, yn, h_new, k_new, Atol, Rtol, pool)
        fe += fe_
        h_rej += h_rej_
        k_rej += k_rej_

    else:
        # no convergence
        # reject (h, k) and restart with new values accordingly
        k_new = k-1 if w_k_1 < 0.9*w_k else k
        h_new = min(h_k_1 if k_new == k-1 else h_k, h)
        h_rej.append(h)
        k_rej.append(k)
        y, h, k, h_new, k_new, h_rej_, k_rej_, fe_ = midpoint_adapt_order(f,
            tn, yn, h_new, k_new, Atol, Rtol, pool)
        fe += fe_
        h_rej += h_rej_
        k_rej += k_rej_

    return (y, h, k, h_new, k_new, h_rej, k_rej, fe)

def ex_midpoint_parallel(f, t0, tf, y0, adaptive="order", p=4, step_size=0.5, Atol=0,
        Rtol=0, exact=(lambda t: t)):
    '''
        An instantiation of extrapolation_serial() function with the midpoint method.
        For more details, refer to extrapolation_serial() function.
    '''

    method = midpoint_adapt_order if adaptive == "order" else midpoint_fixed_step

    return extrapolation_parallel(method, f, t0, tf, y0,
        adaptive=adaptive, p=p, step_size=step_size, Atol=Atol, Rtol=Rtol,
        exact=exact)<commit_msg>wrapped cpu_count() call with a try<commit_after>from __future__ import division
import numpy as np
import multiprocessing as mp
import math

def error_norm(y1, y2, Atol, Rtol):
    tol = Atol + np.maximum(y1,y2)*Rtol
    return np.linalg.norm((y1-y2)/tol)/(len(y1)**0.5)

def adapt_step(method, f, tn_1, yn_1, y, y_hat, h, p, Atol, Rtol, pool):
    '''
        Checks if the step size is accepted. If not, computes a new step size
        and checks again. Repeats until step size is accepted

        **Inputs**:
            - method    -- the method on which the extrapolation is based
            - f         -- the right hand side function of the IVP.
                        Must output a non-scalar numpy.ndarray
            - tn_1, yn_1 -- y(tn_1) = yn_1 is the last accepted value of the
                        computed solution
            - y, y_hat  -- the computed values of y(tn_1 + h) of order p and
                        (p-1), respectively
            - h         -- the step size taken and to be tested
            - p         -- the order of the higher extrapolation method
                        Assumed to be greater than 1.
            - Atol, Rtol -- the absolute and relative tolerance of the local
                         error.

        **Outputs**:
            - y, y_hat  -- the computed solution of orders p and (p-1) at the
                        accepted step size
            - h         -- the accepted step taken to compute y and y_hat
            - h_new     -- the proposed next step size
            - fe        -- the number of f evaluations
    '''

    fe = 0
    facmax = 5
    facmin = 0.2
    fac = 0.8
    err = error_norm(y, y_hat, Atol, Rtol)
    h_new = h*min(facmax, max(facmin, fac*((1/err)**(1/p))))

    while err > 1:
        h = h_new
        y, y_hat, fe_ = method(f, tn_1, yn_1, h, p, pool)
        fe += fe_
        err = error_norm(y, y_hat, Atol, Rtol)
        h_new = h*min(facmax, max(facmin, fac*((1/err)**(1/p))))

    return (y, y_hat, h, h_new, fe)

def extrapolation_parallel(method, f, t0, tf, y0, adaptive="order", p=4,
        step_size=0.5, Atol=0, Rtol=0, exact=(lambda t: t)):
    '''
        Solves the system of IVPs y'(t) = f(y, t) with extrapolation of order
        p based on method provided. The implementation is parallel.

        **Inputs**:
            - method    -- the method on which the extrapolation is based
            - f         -- the right hand side function of the IVP
                        Must output a non-scalar numpy.ndarray
            - [t0, tf]  -- the interval of integration
            - y0        -- the value of y(t0). Must be a non-scalar numpy.ndarray
            - adaptive  -- can be either of three values:
                            "fixed" = use fixed step size and order.
                            "step"  = use adaptive step size but fixed order.
                            "order" = use adaptive step size and adaptive order.
                        optional; defaults to "order"
            - p         -- the order of extrapolation if adaptive is not "order",
                        and the starting order otherwise. optional; defaults to 4
            - step_size -- the fixed step size when adaptive="fixed", and the
                        starting step size otherwise. optional; defaults to 0.5
            - Atol, Rtol -- the absolute and relative tolerance of the local
                         error. optional; both default to 0
            - exact     -- the exact solution to the IVP. Only used for
                        debugging. optional; defaults to (lambda t: t).
                        Must output a non-scalar numpy.ndarray

        **Outputs**:
            - ts, ys    -- the computed solution y for the IVP. y(ts[i]) = ys[i]
            - fe        -- the number of f evaluations
    '''

    try:
        processes = mp.cpu_count()
    except NotImplementedError:
        processes = 4

    pool = mp.Pool(processes)

    fe = 0
    if adaptive == "fixed":
        ts, h = np.linspace(t0, tf, (tf-t0)/step_size + 1, retstep=True)
        ys = np.zeros((len(ts), len(y0)), dtype=(type(y0[0])))
        ys_hat = np.zeros((len(ts), len(y0)), dtype=(type(y0[0])))
        ys[0] = y0

        for i in range(len(ts) - 1):
            ys[i+1], ys_hat[i+1], fe_ = method(f, ts[i], ys[i], h, p, pool)
            fe += fe_

    elif adaptive == "step":
        assert p > 1, "order of method must be greater than 1 if adaptive=True"
        ts = np.zeros((1, len(y0)), dtype=(type(y0[0])))
        ys = np.zeros((1, len(y0)), dtype=(type(y0[0])))
        ys_hat = np.zeros((1, len(y0)), dtype=(type(y0[0])))
        ts[0] = t0
        ys[0] = y0
        ys_hat[0] = y0
        h = min(step_size, tf-t0)

        t, i = t0, 0
        while t < tf:
            y, y_hat, fe_ = method(f, ts[i], ys[i], h, p, pool)
            fe += fe_
            y, y_hat, h, h_new, fe_ = adapt_step(method, f, ts[i], ys[i],
                y, y_hat, h, p, Atol, Rtol, pool)
            t, i, fe = t + h, i+1, fe + fe_
            ts = np.append(ts, t)
            ys = np.vstack((ys, y))
            ys_hat = np.vstack((ys_hat, y_hat))
            h = min(h_new, tf - t)

    elif adaptive == "order":
        ts = np.zeros((1, len(y0)), dtype=(type(y0[0])))
        ys = np.zeros((1, len(y0)), dtype=(type(y0[0])))
        ts[0] = t0
        ys[0] = y0
        h = min(step_size, tf-t0)

        h_acc = []
        k_acc = []
        h_rej = []
        k_rej = []

        t, i, k = t0, 0, p
        while t < tf:
            y, h, k, h_new, k_new, h_rej_, k_rej_, fe_ = method(f, ts[i], ys[i],
                h, k, Atol, Rtol, pool)
            t, i, fe = t + h, i+1, fe + fe_
            ts = np.append(ts, t)
            ys = np.vstack((ys, y))
            h_acc.append(h)
            k_acc.append(k)
            h_rej.append(h_rej_)
            k_rej.append(k_rej_)
            h = min(h_new, tf - t)
            k = k_new

        return (ts, ys, fe, h_acc, k_acc, h_rej, k_rej)
    else:
        raise Exception("\'" + str(adaptive) +
            "\' is not a valid value for the argument \'adaptive\'")

    pool.close()
    return (ts, ys, fe)

def compute_stages((f, tn, yn, h, k_lst)):
    res = []
    for k in k_lst:
        k = int(k)
        Y = np.zeros((2*k+1, len(yn)), dtype=(type(yn[0])))
        fe = 0
        Y[0] = yn
        Y[1] = Y[0] + h/(2*k)*f(Y[0], tn)
        for j in range(2,2*k+1):
            Y[j] = Y[j-2] + (h/k)*f(Y[j-1], tn + (j-1)*(h/(2*k)))
            fe += 1
        res += [(k, Y[2*k], fe)]

    return res

def compute_ex_table(f, tn, yn, h, k, pool):
    T = np.zeros((k+1,k+1, len(yn)), dtype=(type(yn[0])))
    fe = 0

    if k % 2 == 1:
        ks = [[k]] + [[i, k - i] for i in range(1, int(k/2)+1)]
    else:
        ks = [[k]] + [[i, k - i] for i in range(1, int(k/2))] + [[k/2]]

    jobs = [(f, tn, yn, h, k_lst) for k_lst in ks]

    results = pool.map(compute_stages, jobs, chunksize=1)

    # process the returned results from the pool
    for res in results:
        for (k_, Tk_, fe_) in res:
            fe += fe_
            T[k_, 1] = Tk_

    # compute extrapolation table
    for i in range(2, k+1):
        for j in range(i, k+1):
            T[j,i] = T[j,i-1] + (T[j,i-1] - T[j-1,i-1])/((j/(j-i+1))**2 - 1)

    return (T, fe)

def midpoint_fixed_step(f, tn, yn, h, p, pool):
    r = int(round(p/2))
    T, fe = compute_ex_table(f, tn, yn, h, r, pool)
    return (T[r,r], T[r-1,r-1], fe)

def midpoint_adapt_order(f, tn, yn, h, k, Atol, Rtol, pool):
    k_max = 10
    k_min = 3
    k = min(k_max, max(k_min, k))
    A_k = lambda k: k*(k+1)
    H_k = lambda h, k, err_k: h*0.94*(0.65/err_k)**(1/(2*k-1))
    W_k = lambda Ak,Hk: Ak/Hk
    h_rej = []
    k_rej = []

    T, fe = compute_ex_table(f, tn, yn, h, k+1, pool)

    # compute the error and work function for the stages (k-2) to (k+1)
    err_k_2 = error_norm(T[k-2,k-3], T[k-2,k-2], Atol, Rtol)
    err_k_1 = error_norm(T[k-1,k-2], T[k-1,k-1], Atol, Rtol)
    err_k   = error_norm(T[k,k-1],   T[k,k],     Atol, Rtol)
    err_k1  = error_norm(T[k+1,k],   T[k+1,k+1], Atol, Rtol)
    h_k_2   = H_k(h, k-2, err_k_2)
    h_k_1   = H_k(h, k-1, err_k_1)
    h_k     = H_k(h, k,   err_k)
    h_k1    = H_k(h, k+1, err_k1)
    w_k_2   = W_k(A_k(k-2), h_k_2)
    w_k_1   = W_k(A_k(k-1), h_k_1)
    w_k     = W_k(A_k(k),   h_k)
    w_k1    = W_k(A_k(k+1), h_k1)

    if err_k_1 <= 1:
        # convergence in line k-1
        y = T[k-1,k-1]
        k_new = k if w_k_1 < 0.9*w_k_2 else k-1
        h_new = h_k_1 if k_new <= k-1 else h_k_1*A_k(k)/A_k(k-1)

    elif err_k <= 1:
        # convergence in line k
        y = T[k,k]
        k_new = k-1 if w_k_1 < 0.9*w_k else (
                k+1 if w_k < 0.9*w_k_1 else k)
        h_new = h_k_1 if k_new == k-1 else (
                h_k if k_new == k else h_k*A_k(k+1)/A_k(k))

    elif err_k1 <= 1:
        # convergence in line k+1
        y = T[k+1,k+1]
        if w_k_1 < 0.9*w_k:
            k_new = k+1 if w_k1 < 0.9*w_k_1 else k-1
        else:
            k_new = k+1 if w_k1 < 0.9*w_k else k

        h_new = h_k_1 if k_new == k-1 else (
                h_k if k_new == k else h_k1)

    elif err_k_1 > ((k+1)*k)**2:
        # convergence monitor
        # reject (h, k) and restart with new values accordingly
        k_new = k-1
        h_new = min(h_k_1, h)
        h_rej.append(h)
        k_rej.append(k)
        y, h, k, h_new, k_new, h_rej_, k_rej_, fe_ = midpoint_adapt_order(f, tn,
            yn, h_new, k_new, Atol, Rtol, pool)
        fe += fe_
        h_rej += h_rej_
        k_rej += k_rej_

    elif err_k > (k+1)**2:
        # second convergence monitor
        # reject (h, k) and restart with new values accordingly
        k_new = k-1 if w_k_1 < 0.9*w_k else k
        h_new = min(h_k_1 if k_new == k-1 else h_k, h)
        h_rej.append(h)
        k_rej.append(k)
        y, h, k, h_new, k_new, h_rej_, k_rej_, fe_ = midpoint_adapt_order(f,
            tn, yn, h_new, k_new, Atol, Rtol, pool)
        fe += fe_
        h_rej += h_rej_
        k_rej += k_rej_

    else:
        # no convergence
        # reject (h, k) and restart with new values accordingly
        k_new = k-1 if w_k_1 < 0.9*w_k else k
        h_new = min(h_k_1 if k_new == k-1 else h_k, h)
        h_rej.append(h)
        k_rej.append(k)
        y, h, k, h_new, k_new, h_rej_, k_rej_, fe_ = midpoint_adapt_order(f,
            tn, yn, h_new, k_new, Atol, Rtol, pool)
        fe += fe_
        h_rej += h_rej_
        k_rej += k_rej_

    return (y, h, k, h_new, k_new, h_rej, k_rej, fe)

def ex_midpoint_parallel(f, t0, tf, y0, adaptive="order", p=4, step_size=0.5, Atol=0,
        Rtol=0, exact=(lambda t: t)):
    '''
        An instantiation of extrapolation_serial() function with the midpoint method.
        For more details, refer to extrapolation_serial() function.
    '''

    method = midpoint_adapt_order if adaptive == "order" else midpoint_fixed_step

    return extrapolation_parallel(method, f, t0, tf, y0,
        adaptive=adaptive, p=p, step_size=step_size, Atol=Atol, Rtol=Rtol,
        exact=exact)<|endoftext|>


<commit_before>#!/usr/bin/env python3
# Copyright 2021 The CFU-Playground Authors
#
# 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 argparse
import os
import re
import sys
import json
from importlib import import_module
from shutil import copy

sys.path.append((os.path.join(os.path.dirname(__file__),
                "..", "third_party", "python", "litex", "litex", "tools")))

litex_renode = import_module("litex_json2renode")

def generate_resc(target):
    result = """
using sysbus
mach create \"""" + target + """\"
machine LoadPlatformDescription $ORIGIN/""" + target + """.repl
machine StartGdbServer 10001
showAnalyzer sysbus.uart
showAnalyzer sysbus.uart Antmicro.Renode.Analyzers.LoggingUartAnalyzer

sysbus LoadELF $ORIGIN/../software.elf
"""
    return result

def generate_litex_renode_repl(conf_file, etherbone_peripherals, autoalign):

    with open(conf_file) as f:
        csr = json.load(f)

    result = litex_renode.generate_repl(csr, etherbone_peripherals, autoalign)

    return result

def generate_repl(target, path):
    result = "using \"" + str(path) + str(target) + "_generated.repl\""
    result += """

cpu:
    init:
        RegisterCustomCSR "BPM" 0xB04  User
        RegisterCustomCSR "BPM" 0xB05  User
        RegisterCustomCSR "BPM" 0xB06  User
        RegisterCustomCSR "BPM" 0xB07  User
        RegisterCustomCSR "BPM" 0xB08  User
        RegisterCustomCSR "BPM" 0xB09  User
        RegisterCustomCSR "BPM" 0xB0A  User
        RegisterCustomCSR "BPM" 0xB0B  User
        RegisterCustomCSR "BPM" 0xB0C  User
        RegisterCustomCSR "BPM" 0xB0D  User
        RegisterCustomCSR "BPM" 0xB0E  User
        RegisterCustomCSR "BPM" 0xB0F  User
        RegisterCustomCSR "BPM" 0xB10  User
        RegisterCustomCSR "BPM" 0xB11  User
        RegisterCustomCSR "BPM" 0xB12  User
        RegisterCustomCSR "BPM" 0xB13  User
        RegisterCustomCSR "BPM" 0xB14  User
        RegisterCustomCSR "BPM" 0xB15  User
"""
    return result

def generate_robot(robot_template_path, target):
    with open(robot_template_path, "r") as f:
        file_content = f.read()
        file_content = file_content.replace("TARGET", target)

    return file_content

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("conf_file",
                        help="JSON configuration generated by LiteX")
    parser.add_argument("target", help="Target name")
    parser.add_argument("build_path",
                        help="Output path for generated files")
    parser.add_argument("--repl", action="store",
                        help="Output platform definition file")
    parser.add_argument("--etherbone", action="append", dest="etherbone_peripherals",
                        default=[],
                        help="Peripheral to connect over etherbone bridge")
    parser.add_argument("--auto-align", action="append", dest="autoalign_memor_regions",
                        default=[],
                        help="List of memory regions to align automatically (necessary due to limitations in Renode)")
    args = parser.parse_args()

    return args

def main():
    args = parse_args()

    resc_filepath = args.build_path + args.target + ".resc"
    repl_filepath = args.build_path + args.target + ".repl"
    litex_renode_repl_filepath = args.build_path + args.target + "_generated.repl"
    robot_filepath = args.build_path + args.target + ".robot"

    proj_name = re.search("proj/(.*)/build", args.build_path)
    proj_name = proj_name.group(1)

    proj_path = os.path.abspath(os.path.join(args.build_path, "../.."))
    predefined_resc_path = os.path.join(proj_path, "renode", args.target + ".resc")
    predefined_repl_path = os.path.join(proj_path, "renode", args.target + ".repl")
    predefined_robot_path = os.path.join(proj_path, "renode", args.target + ".robot")
    robot_template_path = os.path.join(proj_path, proj_name + ".robot")

    if os.path.isfile(predefined_resc_path):
        copy(predefined_resc_path, args.build_path)
    else:
        with open(resc_filepath, "w") as f:
            f.write(generate_resc(args.target))

    etherbone_peripherals = litex_renode.check_etherbone_peripherals(args.etherbone_peripherals)

    # if there is a predefined Renode platform script for a target, copy it to build directory,
    # otherwise generate a new one with LiteX-Renode
    if os.path.isfile(predefined_repl_path):
        copy(predefined_repl_path, args.build_path)
    else:
        with open(litex_renode_repl_filepath, "w") as f:
            f.write(generate_litex_renode_repl(args.conf_file, etherbone_peripherals, args.autoalign_memor_regions))

        with open(repl_filepath, "w") as f:
            f.write(generate_repl(args.target, args.build_path))

    if os.path.isfile(predefined_robot_path):
        copy(predefined_robot_path, args.build_path)
    elif os.path.isfile(robot_template_path):
        with open(robot_filepath, "w") as f:
            f.write(generate_robot(robot_template_path, args.target))
    else:
        print("Warning: {} was not generated, could not find {}".format(proj_name + ".robot", robot_template_path))

if __name__ == "__main__":
    main()
<commit_msg>Generate Renode scripts with support for verilated CFU<commit_after>#!/usr/bin/env python3
# Copyright 2021 The CFU-Playground Authors
#
# 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 argparse
import os
import re
import sys
import json
from importlib import import_module
from shutil import copy

sys.path.append((os.path.join(os.path.dirname(__file__),
                "..", "third_party", "python", "litex", "litex", "tools")))

litex_renode = import_module("litex_json2renode")

def generate_resc(target, cfu_lib_filepath):
    result = """
using sysbus
mach create \"""" + target + """\"
machine LoadPlatformDescription $ORIGIN/""" + target + """.repl
machine StartGdbServer 10001
showAnalyzer sysbus.uart
showAnalyzer sysbus.uart Antmicro.Renode.Analyzers.LoggingUartAnalyzer
"""
    if cfu_lib_filepath:
        result += """
cpu.cfu0 SimulationFilePathLinux @""" + cfu_lib_filepath + """
"""

    result += """
sysbus LoadELF $ORIGIN/../software.elf
"""
    return result

def generate_litex_renode_repl(conf_file, etherbone_peripherals, autoalign):

    with open(conf_file) as f:
        csr = json.load(f)

    result = litex_renode.generate_repl(csr, etherbone_peripherals, autoalign)

    return result

def generate_repl(target, path, cfu_lib_filepath):
    result = "using \"" + str(path) + str(target) + "_generated.repl\""
    result += """

cpu:
    init:
        RegisterCustomCSR "BPM" 0xB04  User
        RegisterCustomCSR "BPM" 0xB05  User
        RegisterCustomCSR "BPM" 0xB06  User
        RegisterCustomCSR "BPM" 0xB07  User
        RegisterCustomCSR "BPM" 0xB08  User
        RegisterCustomCSR "BPM" 0xB09  User
        RegisterCustomCSR "BPM" 0xB0A  User
        RegisterCustomCSR "BPM" 0xB0B  User
        RegisterCustomCSR "BPM" 0xB0C  User
        RegisterCustomCSR "BPM" 0xB0D  User
        RegisterCustomCSR "BPM" 0xB0E  User
        RegisterCustomCSR "BPM" 0xB0F  User
        RegisterCustomCSR "BPM" 0xB10  User
        RegisterCustomCSR "BPM" 0xB11  User
        RegisterCustomCSR "BPM" 0xB12  User
        RegisterCustomCSR "BPM" 0xB13  User
        RegisterCustomCSR "BPM" 0xB14  User
        RegisterCustomCSR "BPM" 0xB15  User
"""
    if cfu_lib_filepath:
        result += """
cfu0: Verilated.CFUVerilatedPeripheral @ cpu 0
    frequency: 100000000
"""
    return result

def generate_robot(robot_template_path, target):
    with open(robot_template_path, "r") as f:
        file_content = f.read()
        file_content = file_content.replace("TARGET", target)

    return file_content

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("conf_file",
                        help="JSON configuration generated by LiteX")
    parser.add_argument("target", help="Target name")
    parser.add_argument("build_path",
                        help="Output path for generated files")
    parser.add_argument("--repl", action="store",
                        help="Output platform definition file")
    parser.add_argument("--etherbone", action="append", dest="etherbone_peripherals",
                        default=[],
                        help="Peripheral to connect over etherbone bridge")
    parser.add_argument("--auto-align", action="append", dest="autoalign_memor_regions",
                        default=[],
                        help="List of memory regions to align automatically (necessary due to limitations in Renode)")
    parser.add_argument("--sw-only", action="store_true", help="Generate script without simulating hardware CFU")
    args = parser.parse_args()

    return args

def main():
    args = parse_args()

    resc_filepath = args.build_path + args.target + ".resc"
    repl_filepath = args.build_path + args.target + ".repl"
    litex_renode_repl_filepath = args.build_path + args.target + "_generated.repl"
    robot_filepath = args.build_path + args.target + ".robot"

    proj_name = re.search("proj/(.*)/build", args.build_path)
    proj_name = proj_name.group(1)

    proj_path = os.path.abspath(os.path.join(args.build_path, "../.."))
    predefined_resc_path = os.path.join(proj_path, "renode", args.target + ".resc")
    predefined_repl_path = os.path.join(proj_path, "renode", args.target + ".repl")
    predefined_robot_path = os.path.join(proj_path, "renode", args.target + ".robot")
    robot_template_path = os.path.join(proj_path, proj_name + ".robot")

    cfu_lib_filepath = os.path.join(args.build_path, "libVtop.so")
    if not os.path.isfile(cfu_lib_filepath) or args.sw_only:
        cfu_lib_filepath = None

    if os.path.isfile(predefined_resc_path):
        copy(predefined_resc_path, args.build_path)
    else:
        with open(resc_filepath, "w") as f:
            f.write(generate_resc(args.target, cfu_lib_filepath))

    etherbone_peripherals = litex_renode.check_etherbone_peripherals(args.etherbone_peripherals)

    # if there is a predefined Renode platform script for a target, copy it to build directory,
    # otherwise generate a new one with LiteX-Renode
    if os.path.isfile(predefined_repl_path):
        copy(predefined_repl_path, args.build_path)
    else:
        with open(litex_renode_repl_filepath, "w") as f:
            f.write(generate_litex_renode_repl(args.conf_file, etherbone_peripherals, args.autoalign_memor_regions))

        with open(repl_filepath, "w") as f:
            f.write(generate_repl(args.target, args.build_path, cfu_lib_filepath))

    if os.path.isfile(predefined_robot_path):
        copy(predefined_robot_path, args.build_path)
    elif os.path.isfile(robot_template_path):
        with open(robot_filepath, "w") as f:
            f.write(generate_robot(robot_template_path, args.target))
    else:
        print("Warning: {} was not generated, could not find {}".format(proj_name + ".robot", robot_template_path))

if __name__ == "__main__":
    main()
<|endoftext|>


<commit_before>#!/usr/bin/env python

###
# Copyright (c) 2002, Jeremiah Fincher
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright notice,
#     this list of conditions, and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions, and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the author of this software nor the name of
#     contributors to this software may be used to endorse or promote products
#     derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###

from baseplugin import *

import callbacks

class Friendly(callbacks.PrivmsgRegexp):
    def greet(self, irc, msg, match):
        "(?:heya?|(?:w(?:hat'?s\b|as)s?up)|howdy|hi|hello)"
        if re.search(irc.nick, msg.args[1]):
            irc.queueMsg(ircmsgs.privmsg(msg.args[0], 'howdy :)'))

    def goodbye(self, irc, msg, match):
        "(?:good)?bye|adios|vale|ciao|au revoir|seeya|night"
        if re.search(irc.nick, msg.args[1]):
            self.reply('vale, amic(e|a)!')

    def exclaim(self, irc, msg, match):
        "([^\s]+)!"
        if match.group(1) == irc.nick:
            irc.queueMsg(ircmsgs.privmsg(msg.args[0], '%s!' % msg.nick))

# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
<commit_msg>Fixed a few bugs<commit_after>#!/usr/bin/env python

###
# Copyright (c) 2002, Jeremiah Fincher
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright notice,
#     this list of conditions, and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions, and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the author of this software nor the name of
#     contributors to this software may be used to endorse or promote products
#     derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###

from baseplugin import *

import re

import ircmsgs
import callbacks

class Friendly(callbacks.PrivmsgRegexp):
    def greet(self, irc, msg, match):
        "(?:heya?|(?:w(?:hat'?s\b|as)s?up)|howdy|hi|hello)"
        if re.search(irc.nick, msg.args[1]):
            irc.queueMsg(ircmsgs.privmsg(msg.args[0], 'howdy :)'))

    def goodbye(self, irc, msg, match):
        "(?:good)?bye|adios|vale|ciao|au revoir|seeya|night"
        if re.search(irc.nick, msg.args[1]):
            irc.queueMsg(ircmsgs.privmsg(msg.args[0], 'seeya, d00d!'))

    def exclaim(self, irc, msg, match):
        "([^\s]+)!"
        if match.group(1) == irc.nick:
            irc.queueMsg(ircmsgs.privmsg(msg.args[0], '%s!' % msg.nick))

Class = Friendly

# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
<|endoftext|>