text:
'''
Created on July 1, 2014

@author: cmills
'''

from tasr_test import TASRTestCase
from tasr.headers import SchemaHeaderBot, SubjectHeaderBot

import unittest
from webtest import TestApp
import tasr.app
import json
import StringIO
import requests

APP = tasr.app.TASR_APP
APP.set_config_mode('local')

class TestTASRSubjectApp(TASRTestCase):
    '''These tests check that the TASR S+V REST API, expected by the Avro-1124
    repo code.  This does not check the TASR native API calls.
    '''

    def setUp(self):
        self.event_type = "gold"
        fix_rel_path = "schemas/%s.avsc" % (self.event_type)
        self.avsc_file = TASRTestCase.get_fixture_file(fix_rel_path, "r")
        self.schema_str = self.avsc_file.read()
        self.tasr_app = TestApp(APP)
        self.url_prefix = 'http://%s:%s/tasr' % (APP.config.host,
                                                 APP.config.port)
        self.subject_url = '%s/subject/%s' % (self.url_prefix, self.event_type)
        self.content_type = 'application/json; charset=utf8'
        # clear out all the keys before beginning -- careful!
        APP.ASR.redis.flushdb()

    def tearDown(self):
        # this clears out redis after each test -- careful!
        APP.ASR.redis.flushdb()

    def abort_diff_status(self, resp, code):
        self.assertEqual(code, resp.status_code,
                         u'Non-%s status code: %s' % (code, resp.status_code))

    def register_subject(self, subject_name):
        url = '%s/subject/%s' % (self.url_prefix, subject_name)
        return self.tasr_app.put(url, {'subject_name': subject_name})

    def register_schema(self, subject_name, schema_str, expect_errors=False):
        reg_url = '%s/subject/%s/register' % (self.url_prefix, subject_name)
        return self.tasr_app.request(reg_url, method='PUT',
                                     content_type=self.content_type,
                                     expect_errors=expect_errors,
                                     body=schema_str)

    ###########################################################################
    # subject tests
    ###########################################################################
    def test_all_subject_names(self):
        '''GET /tasr/subject - gets _all_ current subjects, as expected'''
        # reg two vers for target subject and one for an alt subject
        self.register_subject(self.event_type)
        alt_subject_name = 'bob'
        self.register_subject(alt_subject_name)
        # now get all and check the headers
        resp = self.tasr_app.request('%s/subject' % self.url_prefix,
                                     method='GET')
        self.abort_diff_status(resp, 200)
        meta_dict = SubjectHeaderBot.extract_metadata(resp)

        self.assertIn(self.event_type, meta_dict.keys(), 'missing subject')
        subj = meta_dict[self.event_type]
        self.assertEqual(self.event_type, subj.name, 'bad subject name')

        self.assertIn(alt_subject_name, meta_dict.keys(), 'missing subject')
        alt_subj = meta_dict[alt_subject_name]
        self.assertEqual(alt_subject_name, alt_subj.name, 'bad subject name')

        # lastly check the body
        buff = StringIO.StringIO(resp.body)
        group_names = []
        for topic_line in buff:
            group_names.append(topic_line.strip())
        buff.close()
        self.assertListEqual(sorted(group_names), sorted(meta_dict.keys()),
                             'Expected group_names in body to match headers.')

    def test_lookup_subject(self):
        '''GET /tasr/subject/<subject> - lookup the subject by name'''
        self.register_subject(self.event_type)
        resp = self.tasr_app.request(self.subject_url, method='GET')
        self.abort_diff_status(resp, 200)
        metas = SubjectHeaderBot.extract_metadata(resp)
        self.assertEqual(self.event_type, metas[self.event_type].name,
                         'unexpected subject name')

    def test_lookup_subject__accept_json(self):
        '''GET /tasr/subject/<subject> - lookup the subject by name'''
        self.register_subject(self.event_type)
        resp = self.tasr_app.request(self.subject_url, method='GET',
                                     accept='text/json')
        self.abort_diff_status(resp, 200)
        metas = SubjectHeaderBot.extract_metadata(resp)
        self.assertEqual(self.event_type, metas[self.event_type].name,
                         'unexpected subject name')

    def test_lookup_missing_subject(self):
        '''GET /tasr/subject/<subject> - lookup the subject by name'''
        missing_subject_name = 'bob'
        url = '%s/%s' % (self.url_prefix, missing_subject_name)
        resp = self.tasr_app.request(url, method='GET', expect_errors=True)
        self.abort_diff_status(resp, 404)

    def test_lookup_missing_subject__accept_json(self):
        '''GET /tasr/subject/<subject> - lookup the subject by name'''
        missing_subject_name = 'bob'
        url = '%s/%s' % (self.url_prefix, missing_subject_name)
        resp = self.tasr_app.request(url, method='GET',
                                     accept='text/json',
                                     expect_errors=True)
        self.abort_diff_status(resp, 404)
        # we expect a JSON error back, so check that we got it
        json_error = json.loads(resp.body)  # body is parseable JSON
        self.assertEqual(404, json_error["status_code"], "expected a 404")

    def test_register_subject(self):
        '''PUT /tasr/subject - registers the subject (not the schema)'''
        resp = self.register_subject(self.event_type)
        self.abort_diff_status(resp, 201)
        metas = SubjectHeaderBot.extract_metadata(resp)
        self.assertEqual(self.event_type, metas[self.event_type].name,
                         'unexpected subject name')

    def test_delete_subject(self):
        '''DELETE /tasr/subject/<subject> - delete the subject'''
        # ensure expose_delete is True
        mode = APP.config.mode
        orig_val = APP.config.config.get(mode, 'expose_delete')
        APP.config.config.set(mode, 'expose_delete', 'True')
        try:
            self.register_subject(self.event_type)
            resp = self.tasr_app.request(self.subject_url, method='GET')
            self.abort_diff_status(resp, 200)
            resp = self.tasr_app.request(self.subject_url, method='DELETE',
                                         expect_errors=False)
            self.abort_diff_status(resp, 200)
        finally:
            # reset expose_delete to its original value
            APP.config.config.set(mode, 'expose_delete', orig_val)

    def test_delete_missing_subject(self):
        '''DELETE /tasr/subject/<subject> - delete a missing subject'''
        mode = APP.config.mode
        orig_val = APP.config.config.get(mode, 'expose_delete')
        APP.config.config.set(mode, 'expose_delete', 'True')
        try:
            resp = self.tasr_app.request(self.subject_url, method='DELETE',
                                         expect_errors=True)
            self.abort_diff_status(resp, 404)
        finally:
            # reset expose_delete to its original value
            APP.config.config.set(mode, 'expose_delete', orig_val)

    def test_unexposed_delete_subject(self):
        '''DELETE /tasr/subject/<subject> - delete when not allowed'''
        mode = APP.config.mode
        orig_val = APP.config.config.get(mode, 'expose_delete')
        APP.config.config.set(mode, 'expose_delete', 'False')
        try:
            resp = self.tasr_app.request(self.subject_url, method='DELETE',
                                         expect_errors=True)
            self.abort_diff_status(resp, 403)
        finally:
            # reset expose_delete to its original value
            APP.config.config.set(mode, 'expose_delete', orig_val)

    def test_register_subject__accept_json(self):
        '''PUT /tasr/subject - registers the subject (not the schema)'''
        url = '%s/subject/%s' % (self.url_prefix, self.event_type)
        dummy_config = {'dummy_config_key': 'dummy_config_val'}
        resp = self.tasr_app.put(url, dummy_config, {'Accept': 'text/json'})
        self.abort_diff_status(resp, 201)
        metas = SubjectHeaderBot.extract_metadata(resp)
        self.assertEqual(self.event_type, metas[self.event_type].name,
                         'unexpected subject name')
        # check the returned JSON to ensure it worked
        json_sub = json.loads(resp.body)
        self.assertEqual(self.event_type, json_sub["subject_name"],
                         "bad subject name")
        self.assertEqual(dummy_config, json_sub["config"], "bad config")

    def test_register_subject_with_no_config(self):
        '''PUT /tasr/subject/<subject> - missing body should be OK'''
        resp = self.tasr_app.request(self.subject_url, method='PUT',
                                     body=None,
                                     expect_errors=False)
        self.abort_diff_status(resp, 201)

    def test_register_subject_with_config_with_empty_field_val(self):
        '''PUT /tasr/subject - empty subject name should be OK'''
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': ''},
                                 expect_errors=False)
        self.abort_diff_status(resp, 201)

    def test_register_subject_with_config_with_colliding_fields(self):
        '''PUT /tasr/subject - empty subject name should return a 400'''
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': ['alice', 'bob']},
                                 expect_errors=True)
        self.abort_diff_status(resp, 400)

    def test_rereg_subject_with_non_conflicting_config(self):
        '''PUT /tasr/subject -  configs match, so no problem'''
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': 'bob'},
                                 expect_errors=False)
        self.abort_diff_status(resp, 201)
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': 'bob'},
                                 expect_errors=False)
        self.abort_diff_status(resp, 200)

    def test_rereg_subject_with_conflicting_config(self):
        '''PUT /tasr/subject -  conflict with preexisting config should 409'''
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': 'bob'},
                                 expect_errors=False)
        self.abort_diff_status(resp, 201)
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': 'alice'},
                                 expect_errors=True)
        self.abort_diff_status(resp, 409)

    def test_reg_and_rereg_subject(self):
        '''PUT /tasr/subject - registers the subject (not the schema), then
        re-registers the same subject.  The second reg should return a 200.'''
        resp = self.register_subject(self.event_type)
        self.abort_diff_status(resp, 201)
        resp = self.register_subject(self.event_type)
        self.abort_diff_status(resp, 200)
        metas = SubjectHeaderBot.extract_metadata(resp)
        self.assertEqual(self.event_type, metas[self.event_type].name,
                         'unexpected subject name')

    def test_get_subject_config(self):
        '''GET /tasr/subject/<subject>/config - get the config map'''
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': self.event_type},
                                 expect_errors=False)
        self.abort_diff_status(resp, 201)
        url = '%s/config' % self.subject_url
        resp = self.tasr_app.request(url, method='GET')
        self.assertEqual('subject_name=%s' % self.event_type,
                         resp.body.strip(), 'Bad response body.')

    def test_update_subject_config(self):
        '''GET /tasr/subject/<subject>/config - get the config map'''
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': self.event_type})
        self.abort_diff_status(resp, 201)
        url = '%s/config' % self.subject_url
        resp = self.tasr_app.request(url, method='GET')
        self.abort_diff_status(resp, 200)
        self.assertEqual('subject_name=%s' % self.event_type,
                         resp.body.strip(), 'Bad response body.')
        resp = self.tasr_app.post(url, {'subject_name': 'alice'})
        self.abort_diff_status(resp, 200)
        resp = self.tasr_app.request(url, method='GET')
        self.abort_diff_status(resp, 200)
        self.assertEqual('subject_name=alice', resp.body.strip(),
                         'Bad response body.')

    def test_get_subject_config_entry(self):
        '''GET /tasr/subject/<subject>/config/<key> - get a config value'''
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': self.event_type},
                                 expect_errors=False)
        self.abort_diff_status(resp, 201)
        url = '%s/config/%s' % (self.subject_url, 'subject_name')
        resp = self.tasr_app.request(url, method='GET')
        self.abort_diff_status(resp, 200)
        self.assertEqual(resp.body.strip(), self.event_type, 'value mismatch')

    def test_get_subject_config_entry_as_json(self):
        '''GET /tasr/subject/<subject>/config/<key> - get as JSON'''
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': self.event_type},
                                 expect_errors=False)
        self.abort_diff_status(resp, 201)
        url = '%s/config/%s' % (self.subject_url, 'subject_name')
        resp = self.tasr_app.request(url, headers={'Accept': 'text/json'},
                                     method='GET')
        self.abort_diff_status(resp, 200)
        expected_dict = {'subject_name': self.event_type}
        json_dict = json.loads(resp.body.strip())
        self.assertDictEqual(json_dict, expected_dict, 'mismatch')

    def test_set_subject_config_entry_overwrite(self):
        '''POST /tasr/subject/<subject>/config/<key> - get a config value'''
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': self.event_type},
                                 expect_errors=False)
        self.abort_diff_status(resp, 201)
        # check that the original value is right
        url = '%s/config/%s' % (self.subject_url, 'subject_name')
        resp = self.tasr_app.request(url, method='GET')
        self.abort_diff_status(resp, 200)
        self.assertEqual(resp.body.strip(), self.event_type, 'value mismatch')

        # set a new entry -- key is part of the URL, the POST body is the value
        val = 'ALICE_VAL'
        resp = self.tasr_app.post(url, val)
        self.abort_diff_status(resp, 200)
        # now grab the value for the new entry and check it is what we sent
        resp = self.tasr_app.request(url, method='GET')
        self.abort_diff_status(resp, 200)
        rval = resp.body.strip()
        self.assertEqual(rval, val, 'value mismatch (%s != %s)' % (rval, val))

    def test_set_subject_config_entry_new(self):
        '''POST /tasr/subject/<subject>/config/<key> - get a config value'''
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': self.event_type},
                                 expect_errors=False)
        self.abort_diff_status(resp, 201)
        # check that the original value is right
        url = '%s/config/%s' % (self.subject_url, 'subject_name')
        resp = self.tasr_app.request(url, method='GET')
        self.abort_diff_status(resp, 200)
        self.assertEqual(resp.body.strip(), self.event_type, 'value mismatch')

        # set a new entry -- key is part of the URL, the POST body is the value
        key = 'alice_key'
        val = 'ALICE_VAL'
        url = '%s/config/%s' % (self.subject_url, key)
        resp = self.tasr_app.post(url, val)
        self.abort_diff_status(resp, 200)
        # now grab the value for the new entry and check it is what we sent
        resp = self.tasr_app.request(url, method='GET')
        self.abort_diff_status(resp, 200)
        rval = resp.body.strip()
        self.assertEqual(rval, val, 'value mismatch (%s != %s)' % (rval, val))

    def test_delete_subject_config_entry(self):
        '''POST /tasr/subject/<subject>/config/<key> - get a config value'''
        resp = self.tasr_app.put(self.subject_url,
                                 {'subject_name': self.event_type},
                                 expect_errors=False)
        self.abort_diff_status(resp, 201)
        # add a new entry
        # set a new entry -- key is part of the URL, the POST body is the value
        key = 'alice_key'
        val = 'ALICE_VAL'
        url = '%s/config/%s' % (self.subject_url, key)
        resp = self.tasr_app.post(url, val)
        self.abort_diff_status(resp, 200)

        # check that both entries are present and correct
        url = '%s/config/%s' % (self.subject_url, 'subject_name')
        resp = self.tasr_app.request(url, method='GET')
        self.abort_diff_status(resp, 200)
        self.assertEqual(resp.body.strip(), self.event_type, 'value mismatch')
        url = '%s/config/%s' % (self.subject_url, key)
        resp = self.tasr_app.request(url, method='GET')
        self.abort_diff_status(resp, 200)
        self.assertEqual(resp.body.strip(), val, 'value mismatch')

        # delete the new entry
        resp = self.tasr_app.delete(url)
        self.abort_diff_status(resp, 200)

        # now check that the new entry is gone...
        resp = self.tasr_app.request(url, method='GET', expect_errors=True)
        self.abort_diff_status(resp, 404)
        # ...and that the original entry is unaffected
        url = '%s/config/%s' % (self.subject_url, 'subject_name')
        resp = self.tasr_app.request(url, method='GET')
        self.abort_diff_status(resp, 200)
        self.assertEqual(resp.body.strip(), self.event_type, 'value mismatch')

    def test_subject_integral(self):
        '''GET /tasr/subject/<subject_name>/integral - should always return
        False as our IDs are not integers (though our version numbers are).
        '''
        self.register_subject(self.event_type)
        url = '%s/integral' % self.subject_url
        resp = self.tasr_app.request(url, method='GET')
        self.abort_diff_status(resp, 200)
        self.assertEqual(u'False', resp.body.strip(), 'Bad response body.')

    def test_missing_subject_integral(self):
        '''GET /tasr/subject/<subject_name>/integral - for a bad subject'''
        url = '%s/integral' % self.subject_url
        resp = self.tasr_app.request(url, method='GET', expect_errors=True)
        self.abort_diff_status(resp, 404)

    def test_all_subject_ids(self):
        '''GET /tasr/subject/<subject>/all_ids - gets schema IDs for all
        versions of the subject, in order, one per line in the response body.
        '''
        sha256_ids = []
        # add a bunch of versions for our subject
        for v in range(1, 50):
            ver_schema_str = self.get_schema_permutation(self.schema_str,
                                                         "fn_%s" % v)
            resp = self.register_schema(self.event_type, ver_schema_str)
            self.abort_diff_status(resp, 201)
            meta = SchemaHeaderBot.extract_metadata(resp)
            sha256_ids.append(meta.sha256_id)

        url = '%s/all_ids' % self.subject_url
        resp = self.tasr_app.get(url)
        buff = StringIO.StringIO(resp.body)
        all_ids = []
        for topic_line in buff:
            all_ids.append(topic_line.strip())
        buff.close()
        self.assertListEqual(sha256_ids, all_ids, 'Bad ID list.')

    def test_all_subject_schemas(self):
        '''GET /tasr/subject/<subject>/all_schemas - gets schemas for all
        versions of the subject, in order, one per line in the response body.
        '''
        versions = []
        # add a bunch of versions for our subject
        for v in range(1, 50):
            ver_schema_str = self.get_schema_permutation(self.schema_str,
                                                         "fn_%s" % v)
            resp = self.register_schema(self.event_type, ver_schema_str)
            self.abort_diff_status(resp, 201)
            versions.append(resp.body.strip())

        url = '%s/all_schemas' % self.subject_url
        resp = self.tasr_app.get(url)
        buff = StringIO.StringIO(resp.body)
        all_vers = []
        for topic_line in buff:
            all_vers.append(topic_line.strip())
        buff.close()
        self.assertListEqual(versions, all_vers, 'Bad versions list.')

    ###########################################################################
    # schema tests
    ###########################################################################
    def test_register_schema(self):
        '''PUT /tasr/subject/<subject>/register - as expected'''
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)

    def test_reg_fail_on_empty_schema(self):
        '''PUT /tasr/subject/<subject>/register - empty schema'''
        resp = self.register_schema(self.event_type, None, True)
        self.abort_diff_status(resp, 400)

    def test_reg_fail_on_invalid_schema(self):
        '''PUT /tasr/subject/<subject>/register - bad schema'''
        bad_schema_str = "%s }" % self.schema_str
        resp = self.register_schema(self.event_type, bad_schema_str, True)
        self.abort_diff_status(resp, 400)

    def test_reg_fail_on_bad_content_type(self):
        '''PUT /tasr/subject/<subject>/register - bad content type'''
        reg_url = '%s/register' % self.subject_url
        resp = self.tasr_app.request(reg_url, method='PUT',
                                     content_type='text/plain; charset=utf8',
                                     expect_errors=True,
                                     body=self.schema_str)
        self.abort_diff_status(resp, 406)

    def test_reg_and_rereg(self):
        '''PUT /tasr/subject/<subject>/register - multiple calls, one schema'''
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)
        meta = SchemaHeaderBot.extract_metadata(resp)
        self.assertEqual(1, meta.group_version(self.event_type), 'bad ver')
        resp1 = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp1, 200)
        meta1 = SchemaHeaderBot.extract_metadata(resp1)
        self.assertEqual(1, meta1.group_version(self.event_type), 'bad ver')

    def test_fail_rereg_with_incompatible_schema(self):
        '''PUT /tasr/subject/<subject>/register - incompatible schemas'''
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)
        meta = SchemaHeaderBot.extract_metadata(resp)
        self.assertEqual(1, meta.group_version(self.event_type), 'bad ver')
        # swap long for int, an incompatible change
        targ = '{"name": "source__timestamp", "type": "long"}'
        replacement = '{"name": "source__timestamp", "type": "int"}'
        incompat_schema_str = self.schema_str.replace(targ, replacement, 1)
        # now registering the schema should return a 409
        reg_url = '%s/register' % self.subject_url
        resp1 = self.tasr_app.request(reg_url, method='PUT',
                                      content_type=self.content_type,
                                      expect_errors=True,
                                      body=incompat_schema_str)
        self.abort_diff_status(resp1, 409)

    def test_force_rereg_with_incompatible_schema(self):
        '''PUT /tasr/subject/<subject>/force_register - incompatible schemas'''
        mode = APP.config.mode
        orig_val = APP.config.config.get(mode, 'expose_force_register')
        APP.config.config.set(mode, 'expose_force_register', 'True')
        try:
            resp = self.register_schema(self.event_type, self.schema_str)
            self.abort_diff_status(resp, 201)
            meta = SchemaHeaderBot.extract_metadata(resp)
            self.assertEqual(1, meta.group_version(self.event_type), 'bad ver')
            # swap long for int, an incompatible change
            targ = '{"name": "source__timestamp", "type": "long"}'
            replacement = '{"name": "source__timestamp", "type": "int"}'
            incompat_schema_str = self.schema_str.replace(targ, replacement, 1)
            # now forcibly registering the schema should return a 201
            reg_url = '%s/force_register' % self.subject_url
            resp1 = self.tasr_app.request(reg_url, method='PUT',
                                          content_type=self.content_type,
                                          expect_errors=False,
                                          body=incompat_schema_str)
            self.abort_diff_status(resp1, 201)
            meta = SchemaHeaderBot.extract_metadata(resp1)
            self.assertEqual(2, meta.group_version(self.event_type), 'bad ver')
        finally:
            # reset expose_force_register to its original value
            APP.config.config.set(mode, 'expose_force_register', orig_val)

    def test_unexposed_force_rereg_with_incompatible_schema(self):
        '''PUT /tasr/subject/<subject>/force_register - incompatible schemas'''
        mode = APP.config.mode
        orig_val = APP.config.config.get(mode, 'expose_force_register')
        APP.config.config.set(mode, 'expose_force_register', 'False')
        try:
            resp = self.register_schema(self.event_type, self.schema_str)
            self.abort_diff_status(resp, 201)
            meta = SchemaHeaderBot.extract_metadata(resp)
            self.assertEqual(1, meta.group_version(self.event_type), 'bad ver')
            # swap long for int, an incompatible change
            targ = '{"name": "source__timestamp", "type": "long"}'
            replacement = '{"name": "source__timestamp", "type": "int"}'
            incompat_schema_str = self.schema_str.replace(targ, replacement, 1)
            # now forcibly registering the schema should return a 201
            reg_url = '%s/force_register' % self.subject_url
            resp1 = self.tasr_app.request(reg_url, method='PUT',
                                          content_type=self.content_type,
                                          expect_errors=True,
                                          body=incompat_schema_str)
            self.abort_diff_status(resp1, 403)
        finally:
            # reset expose_force_register to its original value
            APP.config.config.set(mode, 'expose_force_register', orig_val)

    def test_multi_subject_reg(self):
        '''PUT /tasr/subject/<subject>/register - multi subjects, one schema'''
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)
        meta = SchemaHeaderBot.extract_metadata(resp)
        self.assertEqual(1, meta.group_version(self.event_type), 'bad ver')

        alt_subject = 'bob'
        resp2 = self.register_schema(alt_subject, self.schema_str)
        self.abort_diff_status(resp2, 201)
        meta2 = SchemaHeaderBot.extract_metadata(resp2)
        self.assertEqual(1, meta2.group_version(alt_subject), 'bad ver')

        # check that first association still holds
        resp3 = self.tasr_app.get('%s/latest' % self.subject_url)
        meta3 = SchemaHeaderBot.extract_metadata(resp3)
        self.assertEqual(1, meta3.group_version(self.event_type), 'lost reg')

    def test_reg_if_latest(self):
        '''PUT /tasr/subject/<subject name>/register_if_latest/<version>
        As expected, we reference the version number of the latest version.
        '''
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)
        meta = SchemaHeaderBot.extract_metadata(resp)
        cur_ver = meta.group_version(self.event_type)
        schema_str_2 = self.get_schema_permutation(self.schema_str)
        url = '%s/register_if_latest/%s' % (self.subject_url, cur_ver)
        resp = self.tasr_app.request(url, method='PUT',
                                     content_type=self.content_type,
                                     body=schema_str_2)
        self.abort_diff_status(resp, 201)

    def test_fail_reg_if_latest_bad_ver(self):
        '''PUT /tasr/subject/<subject name>/register_if_latest/<version>
        Should fail as version number is non-existent.
        '''
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)
        meta = SchemaHeaderBot.extract_metadata(resp)
        bad_ver = meta.group_version(self.event_type) + 1
        schema_str_2 = self.get_schema_permutation(self.schema_str)
        url = '%s/register_if_latest/%s' % (self.subject_url, bad_ver)
        resp = self.tasr_app.request(url, method='PUT',
                                     content_type=self.content_type,
                                     expect_errors=True,
                                     body=schema_str_2)
        self.abort_diff_status(resp, 409)

    def test_fail_reg_if_latest_old_ver(self):
        '''PUT /tasr/subject/<subject name>/register_if_latest/<version>
        Should fail as version number exists but is not the latest.
        '''
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)
        schema_str_2 = self.get_schema_permutation(self.schema_str)
        resp = self.register_schema(self.event_type, schema_str_2)
        self.abort_diff_status(resp, 201)
        meta = SchemaHeaderBot.extract_metadata(resp)
        old_ver = meta.group_version(self.event_type) - 1
        url = '%s/register_if_latest/%s' % (self.subject_url, old_ver)
        resp = self.tasr_app.request(url, method='PUT',
                                     content_type=self.content_type,
                                     expect_errors=True,
                                     body=self.schema_str)
        self.abort_diff_status(resp, 409)

    # retrieval
    def test_lookup_by_schema_str(self):
        '''POST /tasr/subject/<subject>/schema - as expected'''
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)
        # canonicalized schema string is passed back on registration
        canonicalized_schema_str = resp.body
        meta_1 = SchemaHeaderBot.extract_metadata(resp)
        self.assertEqual(1, meta_1.group_version(self.event_type), 'bad ver')
        schema_str_2 = self.get_schema_permutation(self.schema_str)
        resp = self.register_schema(self.event_type, schema_str_2)
        self.abort_diff_status(resp, 201)
        # get by POSTed schema
        post_url = "%s/schema" % self.subject_url
        post_resp = self.tasr_app.request(post_url, method='POST',
                                          content_type=self.content_type,
                                          body=self.schema_str)
        meta_2 = SchemaHeaderBot.extract_metadata(post_resp)
        self.assertEqual(1, meta_2.group_version(self.event_type), 'bad ver')
        self.assertEqual(meta_1.sha256_id, meta_2.sha256_id, 'SHA mismatch')
        self.assertEqual(meta_1.md5_id, meta_2.md5_id, 'MD5 mismatch')
        self.assertEqual(canonicalized_schema_str, post_resp.body,
                         u'Unexpected body: %s' % post_resp.body)

    def test_fail_lookup_by_schema_str_on_empty_schema_str(self):
        '''POST /tasr/subject/<subject>/schema - fail on empty schema string'''
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)
        post_url = "%s/schema" % self.subject_url
        resp = self.tasr_app.request(post_url, method='POST',
                                     content_type=self.content_type,
                                     expect_errors=True,
                                     body=None)
        self.abort_diff_status(resp, 400)

    def test_fail_lookup_by_schema_str_on_invalid_schema_str(self):
        '''POST /tasr/subject/<subject>/schema - fail on bad schema string'''
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)
        post_url = "%s/schema" % self.subject_url
        resp = self.tasr_app.request(post_url, method='POST',
                                     content_type=self.content_type,
                                     expect_errors=True,
                                     body="%s }" % self.schema_str)
        self.abort_diff_status(resp, 400)

    def test_fail_lookup_by_schema_str_on_unregistered_schema_str(self):
        '''POST /tasr/subject/<subject>/schema - fail on new schema string'''
        post_url = "%s/schema" % self.subject_url
        resp = self.tasr_app.request(post_url, method='POST',
                                     content_type=self.content_type,
                                     expect_errors=True,
                                     body=self.schema_str)
        self.assertEqual(404, resp.status_int,
                         u'Unexpected status: %s' % resp.status_int)
        meta = SchemaHeaderBot.extract_metadata(resp)
        self.assertTrue(meta.sha256_id, 'SHA missing')
        self.assertTrue(meta.md5_id, 'MD5 missing')

    def test_lookup_by_subject_and_version(self):
        '''GET /tasr/subject/<subject>/version/<version> - as expected'''
        schemas = []
        # add a bunch of versions for our subject
        for v in range(1, 50):
            ver_schema_str = self.get_schema_permutation(self.schema_str,
                                                         "fn_%s" % v)
            resp = self.register_schema(self.event_type, ver_schema_str)
            self.abort_diff_status(resp, 201)
            # schema str with canonicalized whitespace returned
            canonicalized_schema_str = resp.body
            schemas.append(canonicalized_schema_str)

        # step through and request each version by version number
        for v in range(1, 50):
            get_url = '%s/version/%s' % (self.subject_url, v)
            get_resp = self.tasr_app.request(get_url, method='GET')
            self.abort_diff_status(get_resp, 200)
            meta = SchemaHeaderBot.extract_metadata(get_resp)
            self.assertEqual(v, meta.group_version(self.event_type), 'bad ver')
            self.assertEqual(schemas[v - 1], get_resp.body,
                             u'Unexpected body: %s' % get_resp.body)

    def test_fail_lookup_for_subject_and_version_on_bad_version(self):
        '''GET /tasr/subject/<subject>/version/<version> - fail on bad ver'''
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)
        meta = SchemaHeaderBot.extract_metadata(resp)
        bad_version = meta.group_version(self.event_type) + 1
        get_url = '%s/version/%s' % (self.subject_url, bad_version)
        get_resp = self.tasr_app.request(get_url, method='GET',
                                         expect_errors=True)
        self.abort_diff_status(get_resp, 404)

    def test_lookup_for_subject_and_version_on_stale_version(self):
        '''GET /tasr/subject/<subject>/version/<version> - 1 schema, 2 vers'''
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)
        schema_str_2 = self.get_schema_permutation(self.schema_str)
        resp = self.register_schema(self.event_type, schema_str_2)
        self.abort_diff_status(resp, 201)
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)
        # get the latest version, which should be 3
        resp = self.tasr_app.get('%s/latest' % self.subject_url)
        self.abort_diff_status(resp, 200)
        meta_v3 = SchemaHeaderBot.extract_metadata(resp)
        self.assertEqual(3, meta_v3.group_version(self.event_type), 'bad ver')
        # now get ver 1, which should have the same body as ver 3
        get_url = '%s/version/%s' % (self.subject_url, 1)
        get_resp = self.tasr_app.request(get_url, method='GET')
        self.abort_diff_status(get_resp, 200)
        meta_v1 = SchemaHeaderBot.extract_metadata(get_resp)
        self.assertEqual(1, meta_v1.group_version(self.event_type), 'bad ver')
        self.assertEqual(resp.body, get_resp.body, 'schema body mismatch')

    def test_lookup_by_subject_and_sha256_id_str(self):
        '''GET /tasr/subject/<subject>/id/<id_str> - as expected'''
        sha256_ids = []
        schemas = []
        # add a bunch of versions for our subject
        for v in range(1, 50):
            ver_schema_str = self.get_schema_permutation(self.schema_str,
                                                         "fn_%s" % v)
            resp = self.register_schema(self.event_type, ver_schema_str)
            self.abort_diff_status(resp, 201)
            ver_meta = SchemaHeaderBot.extract_metadata(resp)
            sha256_ids.append(ver_meta.sha256_id)
            # schema str with canonicalized whitespace returned
            canonicalized_schema_str = resp.body
            schemas.append(canonicalized_schema_str)

        # step through and request each version by version number
        for v in range(1, 50):
            get_url = '%s/id/%s' % (self.subject_url, sha256_ids[v - 1])
            get_resp = self.tasr_app.request(get_url, method='GET')
            self.abort_diff_status(get_resp, 200)
            meta = SchemaHeaderBot.extract_metadata(get_resp)
            self.assertEqual(sha256_ids[v - 1], meta.sha256_id, 'bad ID')
            self.assertEqual(schemas[v - 1], get_resp.body,
                             u'Unexpected body: %s' % get_resp.body)

    def test_lookup_by_subject_and_md5_id_str(self):
        '''GET /tasr/subject/<subject>/id/<id_str> - as expected'''
        md5_ids = []
        schemas = []
        # add a bunch of versions for our subject
        for v in range(1, 50):
            ver_schema_str = self.get_schema_permutation(self.schema_str,
                                                         "fn_%s" % v)
            resp = self.register_schema(self.event_type, ver_schema_str)
            self.abort_diff_status(resp, 201)
            ver_meta = SchemaHeaderBot.extract_metadata(resp)
            md5_ids.append(ver_meta.md5_id)
            # schema str with canonicalized whitespace returned
            canonicalized_schema_str = resp.body
            schemas.append(canonicalized_schema_str)

        # step through and request each version by version number
        for v in range(1, 50):
            get_url = '%s/id/%s' % (self.subject_url, md5_ids[v - 1])
            get_resp = self.tasr_app.request(get_url, method='GET')
            self.abort_diff_status(get_resp, 200)
            meta = SchemaHeaderBot.extract_metadata(get_resp)
            self.assertEqual(md5_ids[v - 1], meta.md5_id, 'bad ID')
            self.assertEqual(schemas[v - 1], get_resp.body,
                             u'Unexpected body: %s' % get_resp.body)

    def test_lookup_latest(self):
        '''GET  /tasr/subject/<subject name>/latest'''
        # should be nothing there to start with
        resp = self.tasr_app.request('%s/latest' % self.subject_url,
                                     method='GET', expect_errors=True)
        self.abort_diff_status(resp, 404)

        # reg a schema so we'll have something to lookup
        resp = self.register_schema(self.event_type, self.schema_str)
        self.abort_diff_status(resp, 201)

        # reg a second schema so we could get a stale version
        schema_str_2 = self.get_schema_permutation(self.schema_str)
        resp = self.register_schema(self.event_type, schema_str_2)
        self.abort_diff_status(resp, 201)

        # check that lookup gets the _latest_ schema
        resp = self.tasr_app.get('%s/latest' % self.subject_url)
        self.abort_diff_status(resp, 200)
        meta = SchemaHeaderBot.extract_metadata(resp)
        self.assertEqual(2, meta.group_version(self.event_type), 'bad ver')

    def test_master_schema_for_subject(self):
        '''GET /tasr/subject/<subject>/master - as expected'''
        schemas = []
        # add a bunch of versions for our subject
        for v in range(1, 4):
            ver_schema_str = self.get_schema_permutation(self.schema_str,
                                                         "fn_%s" % v)
            resp = self.register_schema(self.event_type, ver_schema_str)
            self.abort_diff_status(resp, 201)
            # schema str with canonicalized whitespace returned
            canonicalized_schema_str = resp.body
            schemas.append(canonicalized_schema_str)

        # grab the master and check that all the expected fields are there
        resp = self.tasr_app.get('%s/master' % self.subject_url)
        self.abort_diff_status(resp, 200)
        master_fnames = []
        for mfield in json.loads(resp.body)['fields']:
            master_fnames.append(mfield['name'])
        # check the original fields
        for ofield in json.loads(self.schema_str)['fields']:
            if not ofield['name'] in master_fnames:
                self.fail('missing original field %s' % ofield['name'])
        # now check all of the extra fields from the version permutations
        for v in range(1, 4):
            fname = "fn_%s" % v
            if not fname in master_fnames:
                self.fail('missing field %s' % fname)

    def test_incompat_master_schema_for_subject(self):
        '''GET /tasr/subject/<subject>/master - as expected'''
        mode = APP.config.mode
        orig_val = APP.config.config.get(mode, 'expose_force_register')
        APP.config.config.set(mode, 'expose_force_register', 'True')
        try:
            # first add a version that will not be compatible
            targ = '{"name": "source__timestamp", "type": "long"}'
            replacement = '{"name": "source__timestamp", "type": "int"}'
            incompat_schema_str = self.schema_str.replace(targ, replacement, 1)
            resp = self.register_schema(self.event_type, incompat_schema_str)
            self.abort_diff_status(resp, 201)
            # now force register a set of compatible schemas
            schemas = []
            for v in range(1, 4):
                ver_schema_str = self.get_schema_permutation(self.schema_str,
                                                             "fn_%s" % v)
                reg_url = '%s/force_register' % self.subject_url
                resp1 = self.tasr_app.request(reg_url, method='PUT',
                                              content_type=self.content_type,
                                              expect_errors=False,
                                              body=ver_schema_str)
                self.abort_diff_status(resp1, 201)
                # schema str with canonicalized whitespace returned
                canonicalized_schema_str = resp1.body
                schemas.append(canonicalized_schema_str)
            # grab the master and check that all the expected fields are there
            reg_url = '%s/master' % self.subject_url
            resp2 = self.tasr_app.request(reg_url, method='GET',
                                          content_type=self.content_type,
                                          expect_errors=True,
                                          body=None)
            self.abort_diff_status(resp2, 409)
            master_fnames = []
            for mfield in json.loads(resp2.body)['fields']:
                master_fnames.append(mfield['name'])
            # check the original fields
            for ofield in json.loads(self.schema_str)['fields']:
                if not ofield['name'] in master_fnames:
                    self.fail('missing original field %s' % ofield['name'])
            # now check all of the extra fields from the version permutations
            for v in range(1, 4):
                fname = "fn_%s" % v
                if not fname in master_fnames:
                    self.fail('missing field %s' % fname)
        finally:
            # reset expose_force_register to its original value
            APP.config.config.set(mode, 'expose_force_register', orig_val)

    def test_hdfs_master_schema_for_subject(self):
        '''GET /tasr/subject/<subject>/master - as expected, check hdfs'''
        mode = APP.config.mode
        orig_val = APP.config.config.get(mode, 'push_masters_to_hdfs')
        APP.config.config.set(mode, 'push_masters_to_hdfs', 'True')
        try:
            resp = None
            schemas = []
            # add a bunch of versions for our subject
            for v in range(1, 4):
                ver_schema_str = self.get_schema_permutation(self.schema_str,
                                                             "fn_%s" % v)
                resp = self.register_schema(self.event_type, ver_schema_str)
                self.abort_diff_status(resp, 201)
                # schema str with canonicalized whitespace returned
                canonicalized_schema_str = resp.body
                schemas.append(canonicalized_schema_str)

            # grab the master FROM HDFS, check that all the expected fields
            hdfs_path = resp.headers['X-Tasr-Hdfs-Master-Path']
            hdfs_user = APP.config.config.get(mode, 'webhdfs_user')
            # first get the current master from HDFS
            resp = requests.get('%s?user.name=%s&op=OPEN' % (hdfs_path,
                                                             hdfs_user))
            self.abort_diff_status(resp, 200)
            master_fnames = []
            for mfield in json.loads(resp.content)['fields']:
                master_fnames.append(mfield['name'])
            # check the original fields
            for ofield in json.loads(self.schema_str)['fields']:
                if not ofield['name'] in master_fnames:
                    self.fail('missing original field %s' % ofield['name'])
            # now check all of the extra fields from the version permutations
            for v in range(1, 4):
                fname = "fn_%s" % v
                if not fname in master_fnames:
                    self.fail('missing field %s' % fname)
        finally:
            # reset expose_force_register to its original value
            APP.config.config.set(mode, 'push_masters_to_hdfs', orig_val)

if __name__ == "__main__":
    SUITE = unittest.TestLoader().loadTestsFromTestCase(TestTASRSubjectApp)
    unittest.TextTestRunner(verbosity=2).run(SUITE)


text:
blog tour & review of chasing the dragon by t.k. leigh
He's trying to protect his heart… She's a shell of the girl she once was… Can he chase away the demons threatening to destroy her?
Mackenzie Delano craves control. After tragedy strikes during her freshman year of college, she compensates for the helplessness she felt by micro-managing every aspect of her life, from her business life to her social life…to her love life. But she wasn't expecting to cross paths with a mysterious man who seems to invade her every thought. Tyler Burnham has been living his life with one rule in mind…never fall in love. Focusing solely on his career, he is able to remain a detached observer of life… Until a case is dropped in his lap, forcing him to form an intimate relationship with a sharp-tongued woman in order to obtain the location of a man deemed an enemy of the State. When Tyler finds himself falling for Mackenzie, will he be able push his feelings aside and recover the information he needs? Or will he put the mission and their lives at risk to follow his heart? Chasing The Dragon is the first installment of a two part series of deception and betrayal where nothing is as it seems. ***Note - Chasing The Dragon is the first book in a two-book duet and is a spin-off of T.K. Leigh's USA Today Best Selling Beautiful Mess series. It is not necessary to have read that series in order to read this duet, but it will contain a mild spoiler from the third book in the Beautiful Mess series, Gorgeous Chaos.***
"Dance with me, Mackenzie," he said, holding my hand in his, sensually placing the other just below my hip bone. "What are you−" "Shhh…," he admonished, expertly leading me in our dance, the band playing Cole Porter's Every Time We Say Goodbye. "Just enjoy it and don't think." I simply nodded, turning my head to scan the restaurant. "Mackenzie, eyes on me. I need to know you're with me." I snapped my eyes back to his, my mouth slightly agape as my heart pounded in my chest. He was warm and spellbinding. The way he held me in his arms comforted me and made me feel as if they were made to hold me. "Are you with me?" he asked, raising his eyebrows. "Yes," I said, my voice soft. He leaned toward me and the bit of stubble on his chin brushed my skin. "Yes what?" he whispered. "I'm with you." The corners of his lips turned up slightly and there was a spark about him that wasn't present yesterday. "I like the sound of that, Miss Delano." He pulled me closer and I tilted my head to peer into his striking eyes, needing the connection I felt at that moment. It was unlike anything I had ever experienced, all because of a well-placed hand, a sinfully sexy voice, eyes that made me want to melt, and arms that felt like home. "Who would have thought that the Mackenzie whose lips I couldn't stop seeing in my dreams last night would turn out to be Mackenzie Delano, proprietor of South Padre's hottest new spot?" "How did−" "Shhh," he said once more. "You think too much. Just enjoy the moment because it's over once the band plays the final note to this melody." I snapped my mouth shut, a strange awareness of loss washing over me at the prospect of this complete stranger walking away from me once the song came to an end, wondering if I would ever see him again. "You're a lovely dancer, Miss Delano," he commented. "Thank you," I answered, unsure of whether to say anything further. He seemed to be in complete control of the dance, of his words…and of mine. And, for the first time, I was okay with someone else calling the shots. "You have a dancer's body. I'm confident you've bewitched quite a few men with the way you can seamlessly navigate the dance floor." He leaned toward me and whispered, "I must confess… You've bewitched me." His voice was sweet as it crooned in my ear, and I was left a silent, blubbering mute, the sincerity in his declaration sparking a renewed sense of longing I had ignored for years. My breathing grew ragged, and I was unable to formulate any response. I simply lost myself in the moment of our dance, wanting his sensual words to ring in the recesses of my mind for all eternity. I wished I could have recorded his voice murmuring those endearing words to me so I could replay them over and over again when I needed to feel something I didn't think I would ever feel again. He molded my frame to his, our bodies swaying to the classic tune, and began to sing along with the band. I imagined he was singing to me, and me alone. His voice was deep and guttural, but sweet as he leaned toward my neck and crooned the last verse into my ear. I closed my eyes, losing myself in his warmth, his voice, his everything. All too soon, the final note rang out, silence encompassing the room, but we continued to sway to the music in our heads, our rhythm perfectly in tune to each other. A loud drum kick echoed, startling me, and I opened my eyes, almost expecting it all to be a dream. But it wasn't, and I was met with my mysterious stranger's strong face. Time stood still as we simply stared at each other, neither one of us moving. I licked my dry lips, nerves causing my breathing to grow more intense and labored. He grabbed my hand and brought it to his soft lips, placing a kiss on it. The contact caused a rush of adrenaline to run through me. Before I could ask his name, he was gone, leaving me stunned and alone once more.
AMAZON US I AMAZON UK I NOOK I iBOOKS I KOBO I GOOGLE PLAY
T.K. Leigh, otherwise known as Tracy Leigh Kellam, is the USA Today Best Selling author of the Beautiful Mess series. Originally from New England, she now resides in sunny Southern California with her husband, dog and three cats, all of which she has rescued (including the husband). She always had a knack for writing, but mostly in the legal field. It wasn't until recently that she decided to try her hand at creative writing and is now addicted to creating different characters and new and unique story lines in the Contemporary Romantic Suspense genre.
When she's not planted in front of her computer, writing away, she can be found running and training for her next marathon (of which she has run over fifteen fulls and far too many halfs to recall). Unlike Olivia, the main character in her Beautiful Mess series, she has yet to qualify for the Boston Marathon.
FACEBOOK * TWITTER * GOOGLE+ * PINTEREST * INSTAGRAM * GOODREADS
blog tour of untouch me by dawn martens
Angels Warriors Series
Cover Designer: Sara Eirew Photography
The truth always comes out, no matter how deep you try to bury it. Secrets never make their way to the grave.
Lilly Mayer has always lived a simple life. She's loyal—maybe too loyal since faithfulness cost her the love of her life. Keeping Eden's whereabouts a secret from everyone, including Vinny, has ripped away Lilly's future.
Vincent "Zippo" Torino knows he's a goddamn bastard. And he's willing to use Lilly's loyalty to Eden as his own escape from a hell he created. He doesn't give a damn that he's leaving the woman pregnant with his child behind—not when he has to protect his own destructive secret. And not when he's sure she's going to beat him to the punch and leave first.
As the dangers to the club escalate, nobody's hearts—or lives—are safe.
*All books in this series are 50K words, all to be combined into ONE paperback titled UnLove Me*
Amazon US Amazon UK Amazon CA Amazon AU
B&N &nbs p;Kobo iTunes
(INSERT YOUR REVIEW HERE)
Dawn Martens is a young, spunky Canadian Author.
Being a wife to Colin, and a mother to three beautiful little girls (Sarah (2007), Grace (2010), and Ava (2014)) hasn't stopped this Canadian Firecracker from pursuing her dreams of becoming a writer!
Dawn's number one passion in life is the written word, and she's extremely thankful that she has the ability to share the ramblings from the characters inside of her head with the rest of the world!
She also may or may not have the hugest girl crush on Author Kristen Ashley, who is her personal idol and helped inspire Dawn in the beginning of her Indie career.
Facebook Website Twitter Amazon
#Oneclick UnKiss Me (Angels Warriors Book #1)
B&N Itunes Kobo Amazon USA Amazon AUS Amazon UK Amazon CAN

redpajama_set_name: RedPajamaCommonCrawl


Mohammed Asab, the ring-leader of a Pakistani cockfighting gang based in Ilford, East London, was found guilty of causing an animal fight to take place, keeping and training an animal for use in connection with an animal fight, and keeping premises for use for an animal fight.
Mohammed Arif, Akhtar Hussain, Mehtab Ahmed and Altaf Hussain were all found guilty of being present at an animal fight involving cockerels.
Disturbing footage seized by police and produced in court showed bloodied birds being trained by the gang. In the video, shown below, Asab is seen training and breeding cockerels to fight and even referred to one of his hens as a producer of 'champions'.
Cockerels armed with sharpened spurs were pitched against one another in an outbuilding where the group had specifically designed a ring compete with seats around the edge and fake grass in the centre.
When police raided the fighting pit they found fresh cockerel blood splattered across white walls and found several distressed birds flapping around inside.
A blood-stained towel was also found and the cockerels were found to have wounds including one deep cut to the neck which someone had attempted to stitch up.
A total of ten cockerels and two hens were seized by police and animal welfare officers during the raid in January 2017.
Mohammed Asab: given a 22-week suspended sentence and ordered to pay £10,000 for the long-term care of his former cockerels, now forfeited to the RSPCA, and £2,000 in legal costs. He must also pay a £150 victim surcharge, complete 200 hours community service in 12 months, and forfeit his cockfighting paraphernalia. Lifetime bird-keeping ban.
Mohammed Arif, Akhtar Hussain, Mehtab Ahmed and Altaf Hussain were each fined £1,500, plus a £85 victim surcharge, and granted community orders of 200 hours community service to be completed in 12 months.
A 17-year-old was granted conditional discharge and a fine of £180.
#TheList Aaron Jay Barker (DoB 01/07/1991) of Flat 2, Cherry House, 23 Redhill Road, Arnold, Nottingham NG5 8GT – beat to death two kittens he'd adopted 10 days previously from Cats Protection League.
Kitten killer Aaron Jay Barker of Basford, Nottingham. Photo on right shows Barker with one of the kittens he later killed.
Barker pinned 4mo kittens Panther and Baby to the floor and beat them to death.
A post-mortem showed the kittens suffered multiple injuries including fractured skull, broken ribs, brain haemorrhages, ruptured liver and blood clots. Vets believed these were caused by blunt force trauma and contacted the RSPCA.
Barker claim a burglar attacked the kittens. He said he tried to give them a bath to wash away blood and faeces, but as he did so Panther jumped out of his arms, hit the bottom of the bath and died. Panther's injuries were not consistent with this, however, and the evidence pointed to the injuries being inflicted when Barker was at home alone.
Sentence: 20 weeks in prison. Life ban on keeping pets.
Violent dog abuser Jake Griffiths, who's now banned from keeping animals for life.
Griffiths assaulted his dog in such a shocking way that people walking past the attack on Gloucester Road in July 2017 stepped in and tried to stop him.
They held him until police arrived, and Griffith was arrested.
It appeared Griffiths was trying to train his brindle-coloured Staffordshire bull terrier, who was just nine months old at the time. He was picking up the dog, Buddy, and throwing him to the ground.
"Witnesses saw Griffiths lift the dog up by his lead which was tied around his neck, so it was almost like a noose," said RSPCA Inspector Simon Coombs.
"Then they saw him kick the dog a couple of times, before dragging him up the road.
"They intervened and called the police, who then arrested Griffiths and contacted ourselves," he added.
At Bristol Magistrates Court, Griffiths admitted two offences under the Animal Welfare Act.
He was given a lifetime ban on keeping all animals for causing unnecessary suffering to Buddy, as well as using frightening, harmful and potentially painful training methods.
In his defence, Griffiths told magistrates that he has an alcohol problem that made him short-tempered and he had taken it out on Buddy, despite saying he loved the dog.
"That is still no excuse for treating an animal so badly and I'm really pleased with the sentence," said Insp Coombs.
"Griffiths signed Buddy over to us as soon as we became involved and I'm pleased to say that he was rehomed soon after," he added.
Magistrates commended the two witnesses who saw the incident and intervened.
Griffiths was told by the court that he cannot appeal his lifetime animal ban for ten years.
Sentence: one-year community order, which includes 20 days of rehabilitation activity and a six-month alcohol treatment requirement; £300 in costs and £85 victim surcharge; banned from keeping animals for life.
Prince pleaded guilty to causing unnecessary suffering to her black Labrador called Roxy.
The court heard that Roxy almost died after losing 10 kilogrammes of weight in just four months. She had been diagnosed with irritable bowel syndrome (IBS) earlier in 2017, and her rapid weight loss was said to be a result of the illness.
RSPCA Inspector Nicola Johnson said: "Roxy was unable to digest food properly because of the IBS, which would have left her in a lot of pain most days.
Roxy was skin and bone by the time she was rescued by the RSPCA from her neglectful owner Leah Prince from Swadlincote, Derbyshire. Happily she recovered and has been rehomed.
Roxy was taken to a vet by Prince, where she was diagnosed with IBS, but was not taken back to the vets again to receive an offer of surgery to help treat the condition.
Inspector Johnson said: "Instead, Prince went on the internet and searched for ways to treat it herself.
"She believed that eventually she would find the right food for Roxy, but in the meantime Roxy was drastically losing weight.
"She was eating food which would come straight out again – she just wasn't able to digest it properly. This went on for four months, during which time Roxy had been left to suffer.
The RSPCA was contacted by a member of the public after concerns were raised about the dog's welfare and health.
Inspector Johnson added: "I took Roxy to a vet and we weighed her in at 13kg, which is far below the 25kg a female Labrador should weigh.
"Her road to recovery was a long one and she was so poorly that we nearly lost her a couple of times. It really was touch and go.
"I'd like to give a huge thanks to the staff at the RSPCA's Burton branch, and staff at Springwood Vets and Swadlincote's vets for their part in saving Roxy's life. Without them she might not be here today.
"The good news is that Roxy has been happily re-homed with a lovely family, and she is a very happy dog today.
Sentencing: two-year conditional discharge; £200 costs. Lifetime ban on keeping animals.
Horrifying footage filmed by a concerned passer-by shows the tiny dog being kicked in the face while being walked by Doolan down a busy street in Dingle on August 16, 2017.
Such was the force of the attack, the dog was lifted into the air before flinching every time Doolan lashed out at concerned members of the public trying to protect the animal.
In court, Doolan admitted causing unnecessary suffering to a protected animal and using threatening words or behaviour likely to cause alarm or distress.
After leaving court, local newspaper the ECHO confronted Doolan to ask if he'd like to comment on the incident, but he showed very little remorse and claimed he beat the dog because it had bitten him and his brother.
He told our reporter: "I didn't beat up a dog, go away … I didn't beat up a dog. I kicked a dog, so what?
"I kicked a dog, it f*g ripped the end of my finger off so I kicked it.
Visibly angry, Doolan then went on to claim people "shouldn't be concerned about animals".
He added: "I am remorseful. I shouldn't have kicked the dog okay, what more do you want me to do? When a dog is hanging off your finger you might think differently.
"There was a six month old baby killed by a dog because the father was p****d on the couch. Not my dog, but people shouldn't be concerned about animals.
"Animals are like secondary, you should consider children more than animals.
The court heard that Doolan had 31 previous convictions for unrelated offences and was last convicted in March 2017 of theft and battery.
Doolan was handed a 12-month community order and a home curfew on that occasion, meaning he was in breach of the order at the time of this incident.
Doolan told the court he had mental health issues and had been "unwell", so had not seen the probation service since August or completed a thinking skills course.
Ms Fletcher requested further information from the probation service and an adjournment for a pre-sentence report, which was granted by magistrates.
Doolan was due to be sentenced in 22 January 2018 but no details were ever published in the press.
The dog, initially renamed Sconehead then Buster, recovered from his ordeal and was rehomed.
Greedy puppy farmer Rocky Knight from Farnworth in Bolton kept puppies in inhumane conditions before selling them on to unsuspecting families.
Irish traveller Knight, who was previously based at the notorious Hall Lane caravan site in Farnworth, admitted six counts of causing unnecessary suffering to a protected animal.
The RSPCA launched an investigation in 2016 following a number of complaints from members of the public who had bought puppies that had fallen ill and, in some cases, had died.
Phoebe the pug lived in disgusting conditions. She has since recovered from her ordeal and been rehomed.
During one raid, officers found two female dogs, a pug and a dachshund-cross, being kept in makeshift pens in an outbuilding in the rear garden.
Inspector Pippa Boyd said: "We found a crossbreed called Patsy and pug called Phoebe living in horrendous conditions in dark, dank and cold pens with no warm bedding or dry areas off the floor. It was a completely inhumane environment to keep dogs.
"Thankfully, we got to them in time and removed them. They were incredibly itchy and Phoebe had serious breathing problems. But they've been doing well in our care since and we have lovely new homes lined up for them.
Knight advertised the dogs online and passed himself off as a responsible, reputable breeder.
He offered to deliver puppies to new owners or arranged to meet them in car parks away from his home.
Knight's lawyer said her client was 'remorseful' and accepted responsibility for his actions.
She said: "You probably have little in terms of positive feelings towards Mr Knight. He is remorseful and, in his words, he wishes he could turn the clocks back.
"He accepts his culpability. He did not go out there to intentionally sell families sick puppies. Hindsight is a wonderful thing.
The dogs that were cared for by staff at the RSPCA's Warrington branch have already found new homes.
Insp Boyd said: "This should be a major flag to anybody looking into buying a puppy.
"A genuinely responsible breeder who has the best interests of their dogs in mind will be happy for you to visit the puppies in the environment they were born and see them interacting with their mother, siblings and people.
16-week jail term; £150 victim surcharge. Disqualified from keeping animals for life.
#TheList Aimie Louise Bennett, born 19/07/1991, of 22 St Leonard Crescent, Thornley, Durham DH6 3GA – starved a Dalmatian and left her to suffer with an agonising skin condition.
Six-year-old Bella was left to starve and suffer a painful skin condition. She later died as a result of the neglect she'd been subjected to by Aimie Louise Bennett of Thornley, Durham.
Six-year-old Dalmatian Bella was taken in by the Dalmatian Adoption Society and Rescue after a member was tipped off about the appalling condition she was in.
The charity's founder Sue Bell said Bella's skin condition was so bad that she was biting and scratching herself to get a little bit of relief. She said Bella was also emaciated with her bones clearly visible through her skin.
Sadly, a few days after being rescued Bella died in the night from a condition called bloat, or gastric dilatation-volvulus, which is when a dog's stomach fills with gas, food, or fluid, making it expand and twist.
The rescue contacted the RSPCA about Bella's condition, who prosecuted her owner, mother-of-three Aimie Louise Bennett.
Bennett admitted causing unnecessary suffering to Bella between March and June 2017 by failing to explore and address her deteriorating physical condition.
Speaking about the case RSPCA inspector Nick Jones said: "This poor dog was in a shocking state.
"She was emaciated and had a terrible skin infection which had caused her to self-harm.
Bennett said she had taken Bella on after her previous owner moved away and that she had issues with her skin from the start which she had treated herself when they escalated.
RSPCA inspector Jones said: "It is every owner's responsibility to provide vet treatment for their pets when they need it.
Sentencing: £150 costs. Disqualified from keeping dogs for five years (expires December 2022).
#TheList John Michael Donaldson, born 25/05/1969, of 12 Oak Grove, Hartlepool TS24 8JG – left two dogs to starve to death.
Donaldson left a female white and black terrier-type dog called Bess and a male black terrier named Whiskey at a house in Straker Street, Hartlepool, without food.
The dogs were found dead on May 23, 2017, by the landlord of the house that Donaldson rented.
RSPCA inspector Lucy Hoehne said: "The smell was overwhelming and there was faeces, urine and bits of chewed up foam from a sofa all over the floor.
"The dogs were in the upstairs back bedroom.
"It was an absolutely heartbreaking scene, they were snuggled together in a corner where there was a duvet on the floor.
"If it hadn't been for the smell, at first glance you might have thought they were sleeping.
The court earlier heard that Donaldson had previously lived at the house but left the dogs there when he moved to another address.
Donaldson refused to cooperate with the RSPCA investigation. He was convicted in his absence of two offences of causing unnecessary suffering to an animal between April and May 2017.
Donaldson was eventually arrested after a third warrant was issued when he failed to turn up at court.
Sentencing: 24 weeks in jail. Total of £415 costs and charges. Lifetime ban on keeping animals.


It is our mission to help our clients define their place in the community and to enhance their surrounding built environment. We accomplish this by understanding their needs, aspirations and resources.
Our core values are based on communication, inspiration, and collaboration.
We believe that talking, and more importantly, listening to the client is the foundation for creating lasting relationships and architecture. Our philosophy is that the client understands what they want and we provide the conduit for their ideas to be expressed.
We are truly inspired by each client and project. Every project is different and requires a unique solution. The R2 Design Group looks at each project from all viewpoints which helps create the right solution to the problem. We strive for unique solutions that celebrate the site, surrounding environment, and intended use all within budget.
We believe in a process that creates innovative architectural solutions within the project constraints. To do this, there must be interdisciplinary integration where there is an atmosphere of trust and collaboration. The process of architecture and design must be interactive and include the client and all members of the design team.
A commitment to architecture and design that incorporates these values has earned the R2 Design Group high praise from our clients.


Timeout in milli seconds to find an initial solution for the local search.
Timeout in milli seconds to find the next solution in the iteration.
Sub-solver used to find the initial solution and the next solution.
Constructs a random-walk solver for the given network.
Constructs a random-walk solver for the given network and option.
Constructs a random-walk solver for the given network, option, and name.
Constructs a random-walk solver for the given network and name.
Returns the candidate solution for the next iteration.
Returns the solution exchange rate for ParallelSolver.
The body of the solver.
Sets a candidate solution for the next iteration.
Sets the solution exchange rate used for ParallelSolver.
Stops the execution of the solver.
Timeout in milli seconds to find an initial solution for the local search. The initial solution is searched by the Solver.findFirst(long) method. The default value is 0 (no timeout).
Timeout in milli seconds to find the next solution in the iteration. The next solution is searched by the Solver.findBest(long) method. The default value is 5000 (5 seconds).
Constructs a random-walk solver for the given network. This constructor is equivalent to LocalSearch(network, DEFAULT, null).
Constructs a random-walk solver for the given network and option. This constructor is equivalent to LocalSearch(network, option, null).
Constructs a random-walk solver for the given network and name. This constructor is equivalent to LocalSearch(network, DEFAULT, name).
The body of the solver. This method is called from Solver.start() methods.


Kodi 18.0 Has Been Finally Released - You Can Update Your Kodi NOW! Kodi 18.0 Has Been Finally Released - You Can Update Your Kodi NOW!
Kodi 18.0 Has Been Finally Released – Bringing Android Leanback, Retro Gaming & More!
Long-awaited Kodi 18.0 release is finally here; You can download it right now.
The latest Kodi version has been in development for close to two years, with half a million lines of code being added in the meantime.
Kodi 18.0 brings numerous notable features that should make the software easier to use, while also improving its performance.
Two weeks after the fifth and final RC version, Kodi 18.0 is finally ready to be used by millions of loyal fans and users from all over the world. The latest Kodi version has been under development for close to two years now, and it brings plenty of under-the-hood improvements as well as a few notable changes to its interface.
We've been following the development of the newest version for quite some time now, and we already have a dedicated article on all the new features of Kodi 18.0 'Leia'. Make sure to click on the provided link to get in-depth and hands-on information about what to expect and how to get the most out of your brand-new Kodi. However, we're going to bring you up to speed by listing some of the most notable changes below, so take a quick look.
Retro Gaming: Thanks to built-in support for emulators, it's now possible to play retro games via Kodi. You can control different types of ROMs and inputs, and Kodi's developers are promising to expand this feature in the future.
Android TV Support: Kodi 18.0 now fully supports Android 'Leanback' which 'pulls' your Kodi content onto the Home Screen of Android TV. In addition, you can now use Google Assistant to control Kodi via your voice.
Digital Rights Implementation: This is a brand-new and still young feature that needs to be expanded on in the future. However, Kodi 18.0 now supports digital rights by allowing subscription-based services to work from within this application.
Music Library Overhaul: We're sure you'll want to import your music collection to Kodi since the application now brings a streamlined interface. You can use better filtering options, check out new artwork, and plenty more.
Playback Improvements: The latest video formats should now play better within Kodi, which includes 4K and 8K video (HDR included). No matter what kind of device you use, Kodi will now be able to use your CPU and GPU more intelligently.
UI Changes: Lastly, some parts of Kodi 18.0 bring an overhauled interface. The best example can be in the 'Settings' section of Kodi which has been completely reorganized.
Over 36 open-source developers were working on Kodi 18.0.
If you'd like to take a deeper look at what's new in Kodi 18.0, we recommend checking out Kodi's Wiki page. And if you want to check out the technical side of things, make sure to visit Kodi's GitHub page.
Lastly, we'd like to let you know that Kodi's developers don't plan on stopping their hard work. Actually, they've announced that they'll be moving to a 'release early, release often' model. So, check out what to expect from Kodi in 2019.
To update your Kodi to the latest available version, go to the Download section on Kodi's website. Choose your platform, and then proceed to download the latest available version from the 'Recommended' tab.
In case you've already updated to Kodi 18.0, let us know your feedback below. Don't forget to share this article online, and also follow TechNadu on Facebook and Twitter. Thanks!


text:
Q: scraping table with python based on dates since a week ago i have been trying to scrape a table from this site  https://www.bi.go.id/id/moneter/informasi-kurs/transaksi-bi/Default.aspx but i dont have an idea what to write,i am very confused.
iam trying to scrape table of kurs transaction from 2015-2020(20 nov 2015-20 nov 2020,
 but the problem is the link between the default date and the date that I chose is still the same.please help me in any way,Thank you before !
import requests
from bs4 import BeautifulSoup
import pandas as pd
headers={
"User-Agent":"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36",
"X-Requested-With":"XMLHttpRequest"
}
url = "https://www.bi.go.id/id/moneter/informasi-kurs/transaksi-bi/Default.aspx"
import requests
from lxml import html
response = requests.get(url)
content= response.content
print(content)

A: You need to use Selenium. You can install Selenium and then you can install a driver. I use chrome and then once you install it make a note of that path and set your DRIVER_PATH to the location
In the code below what i do is basically request the link you posted and then I enter the dates which you can change. Finally i click on the submit button. That generates the table within the date range. Now you can write follow up code to scrape the information from the table.
Code
import requests
from selenium import webdriver

DRIVER_PATH = 'Yourpath/chromedriver'
driver = webdriver.Chrome(executable_path=DRIVER_PATH)
driver.get('https://www.bi.go.id/id/moneter/informasi-kurs/transaksi-bi/Default.aspx')
start_date = driver.find_element_by_id("ctl00_PlaceHolderMain_biWebKursTransaksiBI_txtFrom")
start_date.send_keys("15-Nov-20")
end_date = driver.find_element_by_id("ctl00_PlaceHolderMain_biWebKursTransaksiBI_txtTo")
end_date.send_keys("20-Nov-20")
submit_button = driver.find_element_by_id("ctl00_PlaceHolderMain_biWebKursTransaksiBI_btnSearch1").click()

redpajama_set_name: RedPajamaStackExchange


The Kaduna State Government has further relaxed night – time curfew in Kaduna metropolis and environs following the gradual return of normalcy.
In a statement issued yesterday in Kaduna, the state government announced that the night time -curfew had been reviewed to commence from 10:p.m to 5.a.m.
According to the statement signed by Samuel Aruwan, media aide to Governor Nasir el-Rufai, the decision was taken at a meeting of "core security team" which was held yesterday at the Government House, Kaduna.
The state government had earlier imposed a 24-hour curfew on the metropolis following the outbreak of violence which led to the killing of over 70 people.
The statement however said the 5 p.m. to 6 a.m curfew in Kachia Local Government Area of the state still remains.
Kachia is the domain of the late traditional ruler, the Agom Adara, Mr. Maiwada Raphael Galadima, who was murdered by his abductors. His death led to tension in the area.
Burial arrangements for the late paramount ruler are expected to be announced by the Adara elders before the end of the week.
The statement said Kaduna "residents are henceforth free to move and pursue legitimate activities everyday, until the hours between 10 p.m. and 5 a.m.
The statement added that "a meeting of the core security team today reviewed the security situation, and advised the government that a relaxation of the curfew hours is prudent.
"The government has therefore, accepted the recommendation to shift the start of curfew time to 10 p.m.
"However, the security review advised that curfew hours in Kachia LGA will remain from 5 p.m. to 6 a.m., until further notice.
"The security agencies will continue to strictly enforce the declared curfew hours.


Freedom of Information Model Publication Scheme for Community Pharmacy Contractors Scotland.
Welcome to the 'ASDA Pharmacy part of ASDA Stores Ltd' publication scheme. This is the publication scheme for the registered pharmacists who practise together in all 'ASDA Pharmacies' operated and run by ASDA Stores Ltd. In Scotland; it is about the NHS services which the Pharmacists provide, as required under section 23 of the Freedom of Information (Scotland) Act 2002.
the publication of reasons for the decisions we make.
In preparing this scheme we have taken account of the questions we are routinely asked by members of the public.
The publications are free unless otherwise indicated. Where information is provided at a cost, the charges will be calculated as set out in Class 7.
Who has responsibility of the Scheme?
The Freedom of Information (Scotland) Act 2002 recognises that members of the public have the right to know how public services are organised and run, how much they cost and how the decisions are made.
Since January 1st 2005, community pharmacists are obliged to respond to requests about information that they hold about NHS Pharmaceutical Services, and is recorded in any format and it will create a right of access to that information. These rights are subject to certain exemptions listed in the Act.
New environmental information regulations will be introduced in January 2005. These will enable similar access to environmental information as under the Freedom of Information (Scotland) Act 2002.
John Evans, Superintendent Pharmacist, ASDA House, Great Wilson St., Leeds, LS11 5AD.
ASDA Pharmacy is part of ASDA Stores Ltd, which is in itself part of Wal-Mart Stores Inc.
The relevant Health Board has made arrangements with the ASDApharmacy for the provision of pharmaceutical services under section 27 of the National Health Service (Scotland) Act 1978. The Pharmacy is contracted to provide a range of NHS services (listed under Section 2 below).
The Superintendent Pharmacist is John Evans. The pharmacy may also employ locum pharmacists.
Some information may be withheld, including personal, confidential information about individuals that is protected by the Data Protection Act.
Every pharmacist must comply with the legal requirements on the sale and supply of medicinal products and comply with the professional standards set down in Medicines, Ethics and Practice published by the Royal Pharmaceutical Society of Great Britain. For some services pharmacists and staff are required to attend training courses and sign service agreements with the NHS board.
It is a requirement of the professional allowance that we receive from the NHS Board that we have a practice leaflet available detailing all our services. This is available from the ASDA Pharmacy.
Our inclusion on the List of the relevant NHS Board is subject to Terms of Service. The Terms of Service for Pharmacists can be obtained from the relevant Board.
The pharmacy keeps computerised patient medication records and is registered under the Data Protection Act.
The addresses of the pharmacy premises from which the Asda1 pharmacy has undertaken to provide NHS services are available from John Evans.
Opening times can vary between locations, so please contact your local pharmacy directly to confirm.
The prescription charge is a tax paid directly to the NHS. It is not received by the pharmacist and does not form part of any remuneration to the pharmacy for NHS pharmaceutical services. The average ingredient cost of a dispensed item is £10.80 and pharmacies receive a dispensing fee for medicines of 95.20 pence per item plus a monthly professional allowance payment which ranges from £575 to £1575 depending on the number of prescriptions dispensed. (Figures correct March 2004). Further information on the cost of drugs and appliances can be found in the Drug Tariff, available from The Common Services Agency. The Information & Statistics Department of the Common Services Agency (Gyle Square, 1 South Gyle Crescent, Edinburgh, EH12 9EB) produces the Drug Tariff quarterly and monthly updates of Part 7 (drug prices) are published by the Scottish Pharmaceutical General Council (42 Queen Street, Edinburgh, EH2 3NH).
Some information in this class may not be released because it is confidential or commercial information or its release may be substantially prejudicial to the conduct of the pharmacy's affairs.
Protocols in relation to prescribing protocols and standard operating procedures relating to the dispensing of prescriptions, data protection.
We have protocols and standard operating procedures relating to dispensing of prescriptions.
We are registered under the Data Protection Act and abide by the Data Protection Act principles.
In order to qualify for the professional allowance we receive from relevant NHS Board, we are required to display a range of health education leaflets. We occasionally receive other information from the NHS Board which we make available to the public.
In addition there is a range of leaflets and booklets distributed by ASDA Pharmacy These are published by a variety of sources.
Ask to speak to the pharmacist.
If you are not happy with our response, you can write to your local Primary Care Trust. Their address and telephone number will be provided on request. Our complaints policy is in line with the Pharmaceutical Services Regulations and the NHS complaints policy.
If you are still not satisfied, ask to see the Store Manager.
The complaints policy is in line with the Pharmaceutical Services Regulations and the NHS Complaints Policy. If you cannot resolve the problem or if you prefer not to raise the complaint with the pharmacy directly you may contact the relevant NHS Board.
In this class we will publish any changes we make to this Publication Scheme, the criteria on which our information management policies are made and a referral point for all enquires regarding information management generally in practice. We will also publish any proposed changes or additions to publications already available.
Requests for paper copies, multiple printouts, or for archived copies of documents, which are no longer accessible or available on the web, may attract a charge for the retrieval, photocopy, postage etc. We will let you know the cost and charges that will have to be paid in advance. We will not provide printouts of other organisation's websites.
Current leaflets and brochures on, for example, services we offer to the public are available from our pharmacies free of charge.
Where there is a charge for patient medication records or other personal information, it is regulated under the Data Protection Act.


text:
Home » Public Policy » Our Policy Priorities
ONN Policy Priorities 2020-2021
ONN works within three broad policy areas: our sector's people (the paid and volunteer work force), our finances, and our regulatory environment. Our goal is to create a more enabling environment for a strong and resilient sector so that nonprofits can focus on supporting Ontario's vibrant communities.
We have four cross-cutting priorities for 2020-2021 that we will work to integrate across our advocacy and network engagement activities:
Promoting the value and influence of the sector and the nonprofit business model.
Continuing to explore the role of the nonprofit sector in responding to the Truth & Reconciliation Commission's calls to action
Expanding our use of an intersectional gender lens (GBA+) from the Decent Work file to our policy files
Exploring and sharing the nonprofit sector's responses to the climate emergency, at the organizational level (e.g., our own investments and purchasing), the subsector or regional level (e.g., local disaster response and recovery, settling climate refugees) and as a sector (e.g., policy advocacy, developing a sustainable and climate-focused lens)
Our goal is to strengthen and support the nonprofit sector labour force and its diverse and active volunteer base. This will result in the mobilization of a decent work movement in the sector.
Policy priorities:
Decent work and pensions
Police record checks
The future of work in the nonprofit sector
OUR FINANCING
Our goal is to catalyze improvements in the Ontario nonprofit sector's funding environment by advocating for the reform of the sector's investment relationship with the government and for the removal of barriers for nonprofits to earn income.
Social value procurement
Burden reduction in funding agreements
OUR REGULATORY ENVIRONMENT
Our goal is to ensure that the Ontario nonprofit sector's legal frameworks – policy, legislation, and regulation – support and empower the sector's work.
Public benefit lens
Web portal for nonprofits
Ontario Not-For-Profit Corporations Act
Read ONN's Policy Priorities 2020-2021
ONN's Policy Priorities 2019-2020
Policy Agenda 2018-2019


text:
package com.cardpay.pccredit.report.model;

import com.wicresoft.jrad.base.database.model.BusinessModel;

/**
 * manaProceMonitor类的描述
 *
 * @author 王海东
 * @created on 2014-12-19
 *
 * @version $Id:$
 */
public class manaProceMonitor extends BusinessModel {

	private static final long serialVersionUID = 1L;

	private String bank;
	private String displayName;
	private String rowindex;
	private String jinjian;
	private String chushen;
	private String luru;
	private String fushen;
	private String chushenapprove;
	private String luruapprove;
	private String fushenapprove;

	private String userId;

	public manaProceMonitor(){}
	public manaProceMonitor(String bank,String rowindex,String displayName,String jinjian,String chushen,String luru,
			String fushen,String chushenapprove,String luruapprove,String fushenapprove,String userId){
		this.setBank(bank);
		this.setRowindex(rowindex);
		this.setDisplayName(displayName);
		this.setJinjian(jinjian);
		this.setChushen(chushen);
		this.setChushenapprove(chushenapprove);
		this.setLuru(luru);
		this.setLuruapprove(luruapprove);
		this.setFushen(fushen);
		this.setFushenapprove(fushenapprove);
		this.setUserId(userId);
	}

	public String getRowindex() {
		return rowindex;
	}

	public void setRowindex(String rowindex) {
		this.rowindex = rowindex;
	}

	public String getBank() {
		return bank;
	}

	public void setBank(String bank) {
		this.bank = bank;
	}

	public String getDisplayName() {
		return displayName;
	}

	public void setDisplayName(String displayName) {
		this.displayName = displayName;
	}

	public String getJinjian() {
		return jinjian;
	}

	public void setJinjian(String jinjian) {
		this.jinjian = jinjian;
	}

	public String getChushen() {
		return chushen;
	}

	public void setChushen(String chushen) {
		this.chushen = chushen;
	}

	public String getLuru() {
		return luru;
	}

	public void setLuru(String luru) {
		this.luru = luru;
	}

	public String getFushen() {
		return fushen;
	}

	public void setFushen(String fushen) {
		this.fushen = fushen;
	}

	public String getChushenapprove() {
		return chushenapprove;
	}

	public void setChushenapprove(String chushenapprove) {
		this.chushenapprove = chushenapprove;
	}

	public String getLuruapprove() {
		return luruapprove;
	}

	public void setLuruapprove(String luruapprove) {
		this.luruapprove = luruapprove;
	}

	public String getFushenapprove() {
		return fushenapprove;
	}

	public void setFushenapprove(String fushenapprove) {
		this.fushenapprove = fushenapprove;
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}
}

redpajama_set_name: RedPajamaGithub


text:
Di seguito l'elenco dei vincitori della Quintana di Foligno dal 1946.

Note

Fonti

spqf.it (WikiFoligno)

Voci correlate
Giostra della Quintana

Foligno

redpajama_set_name: RedPajamaWikipedia


Black Friday Sale! Get Extra 10% Off On Most Goods .
Looking for a discount at Online Tires? Follow this page to check for current offers, and trust SaveurNola.com for online shopping savings. Get your favorite items wherever you are with the best discount code for Online Tires and receive 34% off. Choose from current 6 valide promo codes and deals for Online Tires to grab shocking savings this April. Onlinetires Com Coupon Code Free Shipping you can't miss. Too good to scroll past, don't wait to grab your savings.
What is today's top offer for Online Tires?
Today's top offer is 'Cragar 61C S/S Starting From $195.91 Each'. Find the offer, click on it and follow the link to the offer page at onlinetires.com.


Combining the complexity in climbing with harmony within a rope-party, such is my aim.
Motivated by the search for new itineraries, as well as human relationships, I seek to give my best in top-level mountaineering.
The great north faces of the Alps and the mythical summits of the Mont Blanc massif, which nourished my imagination as a child, are my playing field today: repetition of the Lafaille route on the west face of Les Drus (8 days), winter opening on the north face of the Grandes Jorasses (6 days), opening of a new route on the south face of Mont Blanc and, more recently, on the north face of the Nant Blanc (Aiguille Verte).


text:
Making a Thorough Self-Evaluation
by Charles R. SwindollScriptures: 2 Corinthians 8:7–8
I'll never forget an actual situation I heard about on the radio some years ago. A woman in West Palm Beach, Florida, died alone at the age of 71. The coroner's report was tragic. "Cause of death: malnutrition."
The dear old lady wasted away to 50 pounds. Investigators who found her said the place where she lived was a veritable pigpen, the biggest mess you can imagine. One seasoned inspector declared he'd never seen a residence in greater disarray.
The woman had begged food at her neighbors' back doors and gotten what clothes she had from the Salvation Army. From all outward appearances, she was a penniless recluse, a pitiful and forgotten widow. But such was not the case.
Amid the jumble of her unclean, disheveled belongings, two keys were found which led the officials to safe deposit boxes at two different local banks. What they found was absolutely unbelievable.
The first contained over 100 stock certificates, plus hundreds of other valuable certificates, bonds, and solid financial securities . . . not to mention a stack of cash amounting to nearly $200,000. The second box had no certificates, only more currency—lots of it—$600,000 to be exact. Adding the net worth of both boxes, they found that the woman had in her possession well over a million dollars! She was a millionaire who died a victim of starvation in a humble home.
I conducted a funeral years ago for a man who died without family or friends. All he had was a fox terrier . . . to whom he left his entire estate: around $76,000.
We need to make an investigation of our own possessiveness, our tendency to hoard, to hold onto, rather than invest in the lives of others. Remember Paul's words to the Corinthian church:
But just as you abound in everything, in faith and utterance and knowledge and in all earnestness and in the love we inspired in you, see that you abound in this gracious work also. I am not speaking this as a command, but as proving through the earnestness of others the sincerity of your love also. (2 Corinthians 8:7–8)
A thorough self-evaluation is one of the requisites for following closely. The Corinthians abounded in vision, spiritual gifts, knowledge, zeal, and even love. Paul then said to abound in generosity too. Be givers! Be people who excel in unselfishness!
This is timely advice for our own generation . . . and worth our thorough investigation.
Let's each investigate our own tendency to hoard or hold onto, rather than invest in the lives of others.
Taken from Improving Your Serve by Charles R. Swindoll. Copyright © 1981 by Charles R. Swindoll, Inc. Used by permission of Thomas Nelson. www.thomasnelson.com
I have been listening to your program for about 23 years. It has been such a blessing to me in my spiritual walk and helped me so much in raising our kids and now with our growing family. Thank you so much for your faithfulness and for your wonderful insight into God's Word. May God continue to bless your ministry.
–S. N. from MS


The first Lifting Lives series will feature John Vo and Tommy Vo. The Vo brothers are both artists. John is a painter and president of Nine Dot Gallery. Tommy Vo is a photographer and exhibitions manager of Nine Dot Gallery. Spiro will be lifting the lives of these two artists. They will be Spiro's loaders. They will be loading her barbell with a collection of things that are important to their respective lives. Additionally, they will be loading the barbell to the cadence of a poem that her father wrote. The poem is a reflection on Spiro's year long performances of lifting her parents books from Albania, Italy, France, Russia, and America.
The Lifting Lives series are organized by Kledia Spiro, John Vo and Tommy Vo.
Copyright © Kledia Spiro, All rights reserved.


Clavijo was a bus boy when he was spotted playing in a park. Thus began one of the richest soccer careers in U.S. history.
He's given hints about whom he might pick for the March friendlies, though, based on how the USA played in its first two games.
While Stephen Negoesco was coaching some of the greatest college teams in history, he didn't prowl the sidelines.
His national team career came full circle on Saturday when he returned Avaya Stadium, not far from where he grew up in Northern California.
For a program listing from doubt, to have things go right -- perfect wasn't necessary -- is a huge boost.
A knee injury so severe he was out 10 months didn't deter the 20-year-old Chicago Fire midfielder who scored in his U.S. debut.
MLS is in the business of making heroes, but it's a tough business if it must make new heroes every two or three years.