<commit_before>import __builtin__
from pytest import raises
from mock import MagicMock, Mock, PropertyMock, patch, call
from pygit2 import (GIT_CHECKOUT_SAFE_CREATE, GIT_CHECKOUT_FORCE, GIT_SORT_TIME,
                    GIT_BRANCH_REMOTE, Repository as _Repository)

from .base import RepositoryBaseTest
from gitfs.utils import Repository

class TestRepository(RepositoryBaseTest):

    def setup(self):
        super(TestRepository, self).setup()

        def mock_super(*args, **kwargs):
            if args and issubclass(Repository, args[0]):
                return MagicMock()

            return original_super(*args, **kwargs)

        __builtin__.original_super = super
        __builtin__.super = mock_super

    def teardown(self):
        __builtin__.super = __builtin__.original_super
        del __builtin__.original_super

    def _get_repository(self):
        with patch.multiple('gitfs.utils.repository',
                            _Repository=MagicMock(),
                            clone_repository=MagicMock()):
            repo = Repository.clone(self.remote_url, self.repo_path, self.branch)

        return repo

    def test_push(self):
        mocked_remote = MagicMock()
        mocked_get_remote = MagicMock(return_value=mocked_remote)

        remote = "origin"
        branch = "master"

        repo = self._get_repository()
        repo.get_remote = mocked_get_remote
        repo.push(remote, branch)

        mocked_get_remote.assert_called_once_with(remote)
        assert mocked_remote.method_calls == [call.push("refs/heads/%s" % (branch))]

    def test_pull(self):
        remote = "origin"
        branch = "master"
        branch_target = 'test_target'

        mocked_remote = MagicMock()
        mocked_get_remote = MagicMock(return_value=mocked_remote)
        mocked_returned_commit = MagicMock(name='the-commit')
        mocked_commit = MagicMock(return_value=mocked_returned_commit)
        mocked_branch = MagicMock()
        mocked_branch.target = branch_target
        mocked_lookup_branch = MagicMock(return_value=mocked_branch)
        mocked_merge = MagicMock()
        mocked_create_reference = MagicMock()
        mocked_checkout_head = MagicMock()
        mocked_clean_state_files = MagicMock()

        repo = self._get_repository()
        repo.lookup_branch = mocked_lookup_branch
        repo.merge = mocked_merge
        repo.create_reference = mocked_create_reference
        repo.commit = mocked_commit
        repo.checkout_head = mocked_checkout_head
        repo.get_remote = mocked_get_remote
        repo.clean_state_files = mocked_clean_state_files
        repo.pull(remote, branch)

        mocked_get_remote.assert_called_once_with(remote)
        assert mocked_remote.method_calls == [call.fetch()]
        mocked_lookup_branch.assert_called_once_with("%s/%s" % (remote, branch),
                                    GIT_BRANCH_REMOTE)
        mocked_merge.assert_called_once_with(branch_target)
        mocked_checkout_head.assert_called_once_with(GIT_CHECKOUT_FORCE)
        mocked_clean_state_files.assert_called_once_with()
        assert mocked_create_reference.call_count == 2
        mocked_create_reference_calls = [
            call('refs/heads/%s' % branch, branch_target, force=True),
            call('refs/heads/%s' % branch, mocked_returned_commit, force=True)]
        mocked_create_reference.has_calls(mocked_create_reference_calls)

    def test_get_remote(self):
        remote1 = MagicMock()
        remote1.name = 'remote1'
        remote2 = MagicMock()
        remote2.name = 'remote2'

        with patch('gitfs.utils.repository.Repository.remotes',
                   new_callable=PropertyMock) as mocked_remotes:
            mocked_remotes.return_value = [remote1, remote2]
            repo = self._get_repository()
            remote = repo.get_remote('remote2')
            assert remote.name == 'remote2'

            with raises(ValueError):
                remote = repo.get_remote('unavailable_remote')

    def test_get_commit_dates(self):
        mocked_commit1 = MagicMock()
        mocked_commit1.commit_time = '1408626757'
        mocked_commit2 = MagicMock()
        mocked_commit2.commit_time = '1408626757'

        mocked_walk = MagicMock()
        mocked_walk.return_value = [mocked_commit1, mocked_commit2]

        mocked_lookup_reference = MagicMock()
        mocked_lookup_reference.return_value.resolve.return_value.target = 'target'

        mocked_datetime = MagicMock()

        mocked_commit_date1 = MagicMock()
        mocked_commit_date1.strftime.return_value = mocked_commit1.commit_time

        mocked_commit_date2 = MagicMock()
        mocked_commit_date2.strftime.return_value = mocked_commit2.commit_time

        mocked_datetime.fromtimestamp.return_value.date.side_effect = [
            mocked_commit_date1, mocked_commit_date2]

        with patch.multiple('gitfs.utils.repository',
                            _Repository=MagicMock(),
                            datetime=mocked_datetime):
            repo = self._get_repository()
            repo.walk = mocked_walk
            repo.lookup_reference = mocked_lookup_reference

            commit_dates = repo.get_commit_dates()

            assert mocked_lookup_reference.mock_calls == [call('HEAD'),
                                                          call().resolve()]

            assert mocked_walk.mock_calls == [call('target', GIT_SORT_TIME)]
            datetime_calls = [call.fromtimestamp('1408626757'),
                              call.fromtimestamp().date()]
            mocked_datetime.assert_has_calls(datetime_calls)
            mocked_commit_date.assert_has_calls([call.strftime('%Y-%m-%d')])
<commit_msg>Add TODO list methods that still need to be tested.<commit_after>import __builtin__
from pytest import raises
from mock import MagicMock, Mock, PropertyMock, patch, call
from pygit2 import (GIT_CHECKOUT_SAFE_CREATE, GIT_CHECKOUT_FORCE, GIT_SORT_TIME,
                    GIT_BRANCH_REMOTE, Repository as _Repository)

from .base import RepositoryBaseTest
from gitfs.utils import Repository

"""
TODO (still need to be tested):
    * commit
    * get_blob_data
    * get_blob_size
    * get_git_object
    * get_git_object_type
"""
class TestRepository(RepositoryBaseTest):

    def setup(self):
        super(TestRepository, self).setup()

        def mock_super(*args, **kwargs):
            if args and issubclass(Repository, args[0]):
                return MagicMock()

            return original_super(*args, **kwargs)

        __builtin__.original_super = super
        __builtin__.super = mock_super

    def teardown(self):
        __builtin__.super = __builtin__.original_super
        del __builtin__.original_super

    def _get_repository(self):
        with patch.multiple('gitfs.utils.repository',
                            _Repository=MagicMock(),
                            clone_repository=MagicMock()):
            repo = Repository.clone(self.remote_url, self.repo_path, self.branch)

        return repo

    def test_push(self):
        mocked_remote = MagicMock()
        mocked_get_remote = MagicMock(return_value=mocked_remote)

        remote = "origin"
        branch = "master"

        repo = self._get_repository()
        repo.get_remote = mocked_get_remote
        repo.push(remote, branch)

        mocked_get_remote.assert_called_once_with(remote)
        assert mocked_remote.method_calls == [call.push("refs/heads/%s" % (branch))]

    def test_pull(self):
        remote = "origin"
        branch = "master"
        branch_target = 'test_target'

        mocked_remote = MagicMock()
        mocked_get_remote = MagicMock(return_value=mocked_remote)
        mocked_returned_commit = MagicMock(name='the-commit')
        mocked_commit = MagicMock(return_value=mocked_returned_commit)
        mocked_branch = MagicMock()
        mocked_branch.target = branch_target
        mocked_lookup_branch = MagicMock(return_value=mocked_branch)
        mocked_merge = MagicMock()
        mocked_create_reference = MagicMock()
        mocked_checkout_head = MagicMock()
        mocked_clean_state_files = MagicMock()

        repo = self._get_repository()
        repo.lookup_branch = mocked_lookup_branch
        repo.merge = mocked_merge
        repo.create_reference = mocked_create_reference
        repo.commit = mocked_commit
        repo.checkout_head = mocked_checkout_head
        repo.get_remote = mocked_get_remote
        repo.clean_state_files = mocked_clean_state_files
        repo.pull(remote, branch)

        mocked_get_remote.assert_called_once_with(remote)
        assert mocked_remote.method_calls == [call.fetch()]
        mocked_lookup_branch.assert_called_once_with("%s/%s" % (remote, branch),
                                    GIT_BRANCH_REMOTE)
        mocked_merge.assert_called_once_with(branch_target)
        mocked_checkout_head.assert_called_once_with(GIT_CHECKOUT_FORCE)
        mocked_clean_state_files.assert_called_once_with()
        assert mocked_create_reference.call_count == 2
        mocked_create_reference_calls = [
            call('refs/heads/%s' % branch, branch_target, force=True),
            call('refs/heads/%s' % branch, mocked_returned_commit, force=True)]
        mocked_create_reference.has_calls(mocked_create_reference_calls)

    def test_get_remote(self):
        remote1 = MagicMock()
        remote1.name = 'remote1'
        remote2 = MagicMock()
        remote2.name = 'remote2'

        with patch('gitfs.utils.repository.Repository.remotes',
                   new_callable=PropertyMock) as mocked_remotes:
            mocked_remotes.return_value = [remote1, remote2]
            repo = self._get_repository()
            remote = repo.get_remote('remote2')
            assert remote.name == 'remote2'

            with raises(ValueError):
                remote = repo.get_remote('unavailable_remote')

    def test_get_commit_dates(self):
        mocked_commit1 = MagicMock()
        mocked_commit1.commit_time = '1408626757'
        mocked_commit2 = MagicMock()
        mocked_commit2.commit_time = '1408626757'

        mocked_walk = MagicMock()
        mocked_walk.return_value = [mocked_commit1, mocked_commit2]

        mocked_lookup_reference = MagicMock()
        mocked_lookup_reference.return_value.resolve.return_value.target = 'target'

        mocked_datetime = MagicMock()

        mocked_commit_date1 = MagicMock()
        mocked_commit_date1.strftime.return_value = mocked_commit1.commit_time

        mocked_commit_date2 = MagicMock()
        mocked_commit_date2.strftime.return_value = mocked_commit2.commit_time

        mocked_datetime.fromtimestamp.return_value.date.side_effect = [
            mocked_commit_date1, mocked_commit_date2]

        with patch.multiple('gitfs.utils.repository',
                            _Repository=MagicMock(),
                            datetime=mocked_datetime):
            repo = self._get_repository()
            repo.walk = mocked_walk
            repo.lookup_reference = mocked_lookup_reference

            commit_dates = repo.get_commit_dates()

            assert mocked_lookup_reference.mock_calls == [call('HEAD'),
                                                          call().resolve()]

            assert mocked_walk.mock_calls == [call('target', GIT_SORT_TIME)]
            datetime_calls = [call.fromtimestamp('1408626757'),
                              call.fromtimestamp().date()]
            mocked_datetime.assert_has_calls(datetime_calls)
            mocked_commit_date.assert_has_calls([call.strftime('%Y-%m-%d')])
<|endoftext|>


<commit_before>from django.test import TestCase
from phonenumber_field.modelfields import PhoneNumberField

from working_waterfronts.working_waterfronts_api.models import PointOfInterest
from django.contrib.gis.db import models

class PointOfInterestTestCase(TestCase):

    def setUp(self):
        self.expected_fields = {
            'name': models.TextField,
            'alt_name': models.TextField,
            'location': models.PointField,
            'street': models.TextField,
            'city': models.TextField,
            'state': models.TextField,
            'zip': models.TextField,
            'description': models.TextField,
            'history': models.TextField,
            'facts': models.TextField,
            'location_description': models.TextField,
            'website': models.URLField,
            'email': models.EmailField,
            'phone': PhoneNumberField,
            'categories': models.ManyToManyField,
            'pointofinterests_categories': models.ManyToManyField,
            'created': models.DateTimeField,
            'modified': models.DateTimeField,
            'id': models.AutoField
        }

        self.optional_fields = {
            'alt_name',
            'location_description',
            'website',
            'email',
            'phone'
        }

        self.null_fields = {'story', 'phone'}

    def test_fields_exist(self):
        model = models.get_model('working_waterfronts_api', 'PointOfInterest')
        for field, field_type in self.expected_fields.items():
            self.assertEqual(
                field_type, type(model._meta.get_field_by_name(field)[0]))

    def test_no_additional_fields(self):
        fields = PointOfInterest._meta.get_all_field_names()
        self.assertEqual(sorted(fields), sorted(self.expected_fields.keys()))

    def test_created_modified_fields(self):
        self.assertTrue(PointOfInterest._meta.get_field('modified').auto_now)
        self.assertTrue(PointOfInterest._meta.get_field('created').auto_now_add)

    def test___unicode___method(self):
        assert hasattr(PointOfInterest, '__unicode__'), "No __unicode__ method found"

    def test_optional_fields(self):
        models.get_model('working_waterfronts_api', 'PointOfInterest')
        for field in self.optional_fields:
            self.assertEqual(
                PointOfInterest._meta.get_field_by_name(field)[0].blank, True)
        for field in self.null_fields:
            self.assertEqual(
                PointOfInterest._meta.get_field_by_name(field)[0].null, True)
<commit_msg>update POI tests with contact_name<commit_after>from django.test import TestCase
from phonenumber_field.modelfields import PhoneNumberField

from working_waterfronts.working_waterfronts_api.models import PointOfInterest
from django.contrib.gis.db import models

class PointOfInterestTestCase(TestCase):

    def setUp(self):
        self.expected_fields = {
            'name': models.TextField,
            'alt_name': models.TextField,
            'contact_name': models.TextField,
            'location': models.PointField,
            'street': models.TextField,
            'city': models.TextField,
            'state': models.TextField,
            'zip': models.TextField,
            'description': models.TextField,
            'history': models.TextField,
            'facts': models.TextField,
            'location_description': models.TextField,
            'website': models.URLField,
            'email': models.EmailField,
            'phone': PhoneNumberField,
            'categories': models.ManyToManyField,
            'pointofinterests_categories': models.ManyToManyField,
            'created': models.DateTimeField,
            'modified': models.DateTimeField,
            'id': models.AutoField
        }

        self.optional_fields = {
            'alt_name',
            'location_description',
            'website',
            'email',
            'phone'
        }

        self.null_fields = {'story', 'phone'}

    def test_fields_exist(self):
        model = models.get_model('working_waterfronts_api', 'PointOfInterest')
        for field, field_type in self.expected_fields.items():
            self.assertEqual(
                field_type, type(model._meta.get_field_by_name(field)[0]))

    def test_no_additional_fields(self):
        fields = PointOfInterest._meta.get_all_field_names()
        self.assertEqual(sorted(fields), sorted(self.expected_fields.keys()))

    def test_created_modified_fields(self):
        self.assertTrue(PointOfInterest._meta.get_field('modified').auto_now)
        self.assertTrue(PointOfInterest._meta.get_field('created').auto_now_add)

    def test___unicode___method(self):
        assert hasattr(PointOfInterest, '__unicode__'), "No __unicode__ method found"

    def test_optional_fields(self):
        models.get_model('working_waterfronts_api', 'PointOfInterest')
        for field in self.optional_fields:
            self.assertEqual(
                PointOfInterest._meta.get_field_by_name(field)[0].blank, True)
        for field in self.null_fields:
            self.assertEqual(
                PointOfInterest._meta.get_field_by_name(field)[0].null, True)
<|endoftext|>


<commit_before>import copy

from .content_block import ContentBlock

def substitute_none_for_missing(kwargs, kwarg_list):
    new_kwargs = copy.deepcopy(kwargs)
    for kwarg in kwarg_list:
        if not kwarg in new_kwargs:
            new_kwargs[kwarg] = None
    return new_kwargs

class BulletListContentBlock(ContentBlock):
    _content_block_type = "bullet_list"

    @classmethod
    def expect_column_to_exist(cls, expectation, column_name=""):
        params = substitute_none_for_missing(
            expectation["kwargs"],
            ["column", "column_index"],
        )

        if params["column_index"] == None:
            return [{
                "template": "$column is a required field.",
                "params": params,
            }]

        else:
            #!!! FIXME:
            params["column_indexth"] = str(params["column_index"])+"th"
            return [{
                "template": "$column must be the $column_indexth field.",
                "params": params,
            }]

    @classmethod
    def expect_column_value_lengths_to_be_between(cls, expectation, column_name=""):
        if (expectation["kwargs"]["min_value"] is None) and (expectation["kwargs"]["max_value"] is None):
            return [{
                "template": column_name + " has a bogus $expectation_name expectation.",
                "params": {
                    "expectation_name": "expect_column_value_lengths_to_be_between"
                }
            }]

        if "mostly" in expectation["kwargs"]:
            if expectation["kwargs"]["min_value"] is not None and expectation["kwargs"]["max_value"] is not None:
                return [{
                    "template": column_name + " must be between $min and $max characters long at least $mostly% of the time.",
                    "params": {
                        "min": expectation["kwargs"]["min_value"],
                        "max": expectation["kwargs"]["max_value"],
                        "mostly": expectation["kwargs"]["mostly"]
                    }
                }]

            elif expectation["kwargs"]["min_value"] is None:
                return [{
                    "template": column_name + " must be less than $max characters long at least $mostly% of the time.",
                    "params": {
                        "max": expectation["kwargs"]["max_value"],
                        "mostly": expectation["kwargs"]["mostly"]
                    }
                }]

            elif expectation["kwargs"]["max_value"] is None:
                return [{
                    "template": column_name + " must be more than $min characters long at least $mostly% of the time.",
                    "params": {
                        "min": expectation["kwargs"]["min_value"],
                        "mostly": expectation["kwargs"]["mostly"]
                    }
                }]

        else:
            if expectation["kwargs"]["min_value"] is not None and expectation["kwargs"]["max_value"] is not None:
                return [{
                    "template": column_name + " must always be between $min and $max characters long.",
                    "params": {
                        "min": expectation["kwargs"]["min_value"],
                        "max": expectation["kwargs"]["max_value"]
                    }
                }]

            elif expectation["kwargs"]["min_value"] is None:
                return [{
                    "template": column_name + " must always be less than $max characters long.",
                    "params": {
                        "max": expectation["kwargs"]["max_value"]
                    }
                }]

            elif expectation["kwargs"]["max_value"] is None:
                return [{
                    "template": column_name + " must always be more than $min characters long.",
                    "params": {
                        "min": expectation["kwargs"]["min_value"]
                    }
                }]

    @classmethod
    def expect_column_unique_value_count_to_be_between(cls, expectation, column_name=""):
        if (expectation["kwargs"]["min_value"] is None) and (expectation["kwargs"]["max_value"] is None):
            return [{
                "template": column_name + " has a bogus $expectation_name expectation.",
                "params": {
                    "expectation_name": "expect_column_unique_value_count_to_be_between"
                }
            }]

        elif expectation["kwargs"]["min_value"] is None:
            return [{
                "template": column_name + " must have fewer than $max unique values.",
                "params": {
                    "max": expectation["kwargs"]["max_value"]
                }
            }]

        elif expectation["kwargs"]["max_value"] is None:
            return [{
                "template": column_name + " must have at least $min unique values.",
                "params": {
                    "min": expectation["kwargs"]["min_value"]
                }
            }]
        else:
            return [{
                "template": column_name + " must have between $min and $max unique values.",
                "params": {
                    "min": expectation["kwargs"]["min_value"],
                    "max": expectation["kwargs"]["min_value"]
                }
            }]

    @classmethod
    def expect_column_values_to_be_between(cls, expectation, column_name=""):
        params = substitute_none_for_missing(
            expectation["kwargs"],
            ["column", "min_value", "max_value", "mostly"]
        )

        if (params["min_value"] is None) and (params["max_value"] is None):
            #!!! Not sure why we're using a different pattern for templating column names...
            return [{
                "template": column_name + " has a bogus $expectation_name expectation.",
                "params": {
                    "expectation_name": "expect_column_values_to_be_between"
                }
            }]

        if "mostly" in params:
            if params["min_value"] is not None and params["max_value"] is not None:
                return [{
                    "template": column_name + " must be between $min and $max at least $mostly% of the time.",
                    "params": params
                }]

            elif params["min_value"] is None:
                return [{
                    "template": column_name + " must be less than $max at least $mostly% of the time.",
                    "params": params
                }]

            elif params["max_value"] is None:
                return [{
                    "template": column_name + " must be more than $min at least $mostly% of the time.",
                    "params": params
                }]

        else:
            if params["min_value"] is not None and params["max_value"] is not None:
                return [{
                    "template": column_name + " must always be between $min and $max.",
                    "params": params
                }]

            elif params["min_value"] is None:
                return [{
                    "template": column_name + " must always be less than $max.",
                    "params": params
                }]

            elif params["max_value"] is None:
                return [{
                    "template": column_name + " must always be more than $min.",
                    "params": params
                }]

    @classmethod
    def expect_column_pair_values_A_to_be_greater_than_B(cls, expectation):
        params = substitute_none_for_missing(
            expectation["kwargs"],
            ["column_A", "column_B", "parse_strings_as_datetimes",
                "ignore_row_if", "mostly", "or_equal"]
        )

        if (params["column_A"] is None) or (params["column_B"] is None):
            return [{
                "template": " has a bogus $expectation_name expectation.",
                "params": {
                    "expectation_name": "expect_column_pair_values_A_to_be_greater_than_B"
                }
            }]

        if params["mostly"] == None:
            if params["or_equal"] in [None, False]:
                return [{
                    "template": "Values in $column_A must always be greater than those in $column_B.",
                    "params": params
                }]
            else:
                return [{
                    "template": "Values in $column_A must always be greater than or equal to those in $column_B.",
                    "params": params
                }]

        else:
            if params["or_equal"] in [None, False]:
                return [{
                    "template": "Values in $column_A must be greater than those in $column_B at least $mostly % of the time.",
                    "params": params
                }]
            else:
                return [{
                    "template": "Values in $column_A must be greater than or equal to those in $column_B at least $mostly % of the time.",
                    "params": params
                }]

    @classmethod
    def expect_table_columns_to_match_ordered_list(cls, expectation):
        params = substitute_none_for_missing(
            expectation["kwargs"],
            ["column_list"]
        )

        params["column_list_str"] = ", ".join(params["column_list"])
        return [{
            "template": "This table should have these columns in this order: $column_list_str",
            "params": params
        }]
<commit_msg>expect_column_pair_values_to_be_equal<commit_after>import copy

from .content_block import ContentBlock

def substitute_none_for_missing(kwargs, kwarg_list):
    new_kwargs = copy.deepcopy(kwargs)
    for kwarg in kwarg_list:
        if not kwarg in new_kwargs:
            new_kwargs[kwarg] = None
    return new_kwargs

class BulletListContentBlock(ContentBlock):
    _content_block_type = "bullet_list"

    @classmethod
    def expect_column_to_exist(cls, expectation, column_name=""):
        params = substitute_none_for_missing(
            expectation["kwargs"],
            ["column", "column_index"],
        )

        if params["column_index"] == None:
            return [{
                "template": "$column is a required field.",
                "params": params,
            }]

        else:
            #!!! FIXME:
            params["column_indexth"] = str(params["column_index"])+"th"
            return [{
                "template": "$column must be the $column_indexth field.",
                "params": params,
            }]

    @classmethod
    def expect_column_value_lengths_to_be_between(cls, expectation, column_name=""):
        if (expectation["kwargs"]["min_value"] is None) and (expectation["kwargs"]["max_value"] is None):
            return [{
                "template": column_name + " has a bogus $expectation_name expectation.",
                "params": {
                    "expectation_name": "expect_column_value_lengths_to_be_between"
                }
            }]

        if "mostly" in expectation["kwargs"]:
            if expectation["kwargs"]["min_value"] is not None and expectation["kwargs"]["max_value"] is not None:
                return [{
                    "template": column_name + " must be between $min and $max characters long at least $mostly% of the time.",
                    "params": {
                        "min": expectation["kwargs"]["min_value"],
                        "max": expectation["kwargs"]["max_value"],
                        "mostly": expectation["kwargs"]["mostly"]
                    }
                }]

            elif expectation["kwargs"]["min_value"] is None:
                return [{
                    "template": column_name + " must be less than $max characters long at least $mostly% of the time.",
                    "params": {
                        "max": expectation["kwargs"]["max_value"],
                        "mostly": expectation["kwargs"]["mostly"]
                    }
                }]

            elif expectation["kwargs"]["max_value"] is None:
                return [{
                    "template": column_name + " must be more than $min characters long at least $mostly% of the time.",
                    "params": {
                        "min": expectation["kwargs"]["min_value"],
                        "mostly": expectation["kwargs"]["mostly"]
                    }
                }]

        else:
            if expectation["kwargs"]["min_value"] is not None and expectation["kwargs"]["max_value"] is not None:
                return [{
                    "template": column_name + " must always be between $min and $max characters long.",
                    "params": {
                        "min": expectation["kwargs"]["min_value"],
                        "max": expectation["kwargs"]["max_value"]
                    }
                }]

            elif expectation["kwargs"]["min_value"] is None:
                return [{
                    "template": column_name + " must always be less than $max characters long.",
                    "params": {
                        "max": expectation["kwargs"]["max_value"]
                    }
                }]

            elif expectation["kwargs"]["max_value"] is None:
                return [{
                    "template": column_name + " must always be more than $min characters long.",
                    "params": {
                        "min": expectation["kwargs"]["min_value"]
                    }
                }]

    @classmethod
    def expect_column_unique_value_count_to_be_between(cls, expectation, column_name=""):
        if (expectation["kwargs"]["min_value"] is None) and (expectation["kwargs"]["max_value"] is None):
            return [{
                "template": column_name + " has a bogus $expectation_name expectation.",
                "params": {
                    "expectation_name": "expect_column_unique_value_count_to_be_between"
                }
            }]

        elif expectation["kwargs"]["min_value"] is None:
            return [{
                "template": column_name + " must have fewer than $max unique values.",
                "params": {
                    "max": expectation["kwargs"]["max_value"]
                }
            }]

        elif expectation["kwargs"]["max_value"] is None:
            return [{
                "template": column_name + " must have at least $min unique values.",
                "params": {
                    "min": expectation["kwargs"]["min_value"]
                }
            }]
        else:
            return [{
                "template": column_name + " must have between $min and $max unique values.",
                "params": {
                    "min": expectation["kwargs"]["min_value"],
                    "max": expectation["kwargs"]["min_value"]
                }
            }]

    @classmethod
    def expect_column_values_to_be_between(cls, expectation, column_name=""):
        params = substitute_none_for_missing(
            expectation["kwargs"],
            ["column", "min_value", "max_value", "mostly"]
        )

        if (params["min_value"] is None) and (params["max_value"] is None):
            #!!! Not sure why we're using a different pattern for templating column names...
            return [{
                "template": column_name + " has a bogus $expectation_name expectation.",
                "params": {
                    "expectation_name": "expect_column_values_to_be_between"
                }
            }]

        if "mostly" in params:
            if params["min_value"] is not None and params["max_value"] is not None:
                return [{
                    "template": column_name + " must be between $min and $max at least $mostly% of the time.",
                    "params": params
                }]

            elif params["min_value"] is None:
                return [{
                    "template": column_name + " must be less than $max at least $mostly% of the time.",
                    "params": params
                }]

            elif params["max_value"] is None:
                return [{
                    "template": column_name + " must be more than $min at least $mostly% of the time.",
                    "params": params
                }]

        else:
            if params["min_value"] is not None and params["max_value"] is not None:
                return [{
                    "template": column_name + " must always be between $min and $max.",
                    "params": params
                }]

            elif params["min_value"] is None:
                return [{
                    "template": column_name + " must always be less than $max.",
                    "params": params
                }]

            elif params["max_value"] is None:
                return [{
                    "template": column_name + " must always be more than $min.",
                    "params": params
                }]

    @classmethod
    def expect_column_pair_values_A_to_be_greater_than_B(cls, expectation):
        params = substitute_none_for_missing(
            expectation["kwargs"],
            ["column_A", "column_B", "parse_strings_as_datetimes",
                "ignore_row_if", "mostly", "or_equal"]
        )

        if (params["column_A"] is None) or (params["column_B"] is None):
            # FIXME: this string is wrong
            return [{
                "template": " has a bogus $expectation_name expectation.",
                "params": {
                    "expectation_name": "expect_column_pair_values_A_to_be_greater_than_B"
                }
            }]

        if params["mostly"] == None:
            if params["or_equal"] in [None, False]:
                return [{
                    "template": "Values in $column_A must always be greater than those in $column_B.",
                    "params": params
                }]
            else:
                return [{
                    "template": "Values in $column_A must always be greater than or equal to those in $column_B.",
                    "params": params
                }]

        else:
            if params["or_equal"] in [None, False]:
                return [{
                    "template": "Values in $column_A must be greater than those in $column_B at least $mostly % of the time.",
                    "params": params
                }]
            else:
                return [{
                    "template": "Values in $column_A must be greater than or equal to those in $column_B at least $mostly % of the time.",
                    "params": params
                }]

    @classmethod
    def expect_column_pair_values_to_be_equal(cls, expectation):
        params = substitute_none_for_missing(
            expectation["kwargs"],
            ["column_A", "column_B",
                "ignore_row_if", "mostly", ]
        )

        if (params["column_A"] is None) or (params["column_B"] is None):
            # FIXME: this string is wrong
            return [{
                "template": " has a bogus $expectation_name expectation.",
                "params": {
                    "expectation_name": "expect_column_pair_values_to_be_equal"
                }
            }]

        if params["mostly"] == None:
            return [{
                "template": "Values in $column_A and $column_B must always be equal.",
                "params": params
            }]

        else:
            return [{
                "template": "Values in $column_A and $column_B must be equal at least $mostly % of the time.",
                "params": params
            }]

    @classmethod
    def expect_table_columns_to_match_ordered_list(cls, expectation):
        params = substitute_none_for_missing(
            expectation["kwargs"],
            ["column_list"]
        )

        params["column_list_str"] = ", ".join(params["column_list"])
        return [{
            "template": "This table should have these columns in this order: $column_list_str",
            "params": params
        }]
<|endoftext|>


<commit_before># t’s not uncommon for a few unneeded but humongous files or folders to take up the
# bulk of the space on your hard drive. If you’re trying to free up room on your
# computer, you’ll get the most bang for your buck by deleting the most massive of
# the unwanted files. But first you have to find them.
#
# Write a program that walks through a folder tree and searches for exceptionally
# large files or folders—say, ones that have a file size of more than 100MB.
# (Remember, to get a file’s size, you can use os.path.getsize() from the os module.)
# Print these files with their absolute path to the screen.
#
# Note:
# - testfile.txt was created by typing truncate -s 101M testfile.txt in a terminal

import os

FOLDER = "./"
FILESIZE = 100 * (1024 ** 2)  # 1024 ** 2 == 1 MB

for foldername, subfolders, filenames in os.walk(FOLDER):
    for filename in filenames:
        if os.path.getsize(filename) > FILESIZE:
            #os.unlink(filename)
            print(filename)  # DEBUG
<commit_msg>Update P02_deleteBigFiles fixed typo<commit_after># It’s not uncommon for a few unneeded but humongous files or folders to take up the
# bulk of the space on your hard drive. If you’re trying to free up room on your
# computer, you’ll get the most bang for your buck by deleting the most massive of
# the unwanted files. But first you have to find them.
#
# Write a program that walks through a folder tree and searches for exceptionally
# large files or folders—say, ones that have a file size of more than 100MB.
# (Remember, to get a file’s size, you can use os.path.getsize() from the os module.)
# Print these files with their absolute path to the screen.
#
# Note:
# - testfile.txt was created by typing truncate -s 101M testfile.txt in a terminal

import os

FOLDER = "./"
FILESIZE = 100 * (1024 ** 2)  # 1024 ** 2 == 1 MB

for foldername, subfolders, filenames in os.walk(FOLDER):
    for filename in filenames:
        if os.path.getsize(filename) > FILESIZE:
            #os.unlink(filename)
            print(filename)  # DEBUG
<|endoftext|>


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

from django.db import models, migrations, transaction
from django.core.management import call_command
from django.contrib.auth.management import create_permissions
from django.apps import apps as django_apps

from datetime import datetime
from pytz import timezone

import portal.utils

@transaction.atomic
def load_initial_groups(apps, schema_editor):
    # update_all_contenttypes(verbosity=0)
    portal.utils.update_all_contenttypes(verbosity=0)
    auth_app_config = django_apps.get_app_config("auth")
    create_permissions(auth_app_config, verbosity=0)
    call_command("loaddata", "initial_groups", app_label="metadata")

@transaction.atomic
def load_initial_user(apps, schema_editor):
    call_command("loaddata", "initial_user", app_label="metadata")

@transaction.atomic
def load_initial_data(apps, schema_editor):
    """
    Defines some system built-in Datatypes and CompoundDatatypes.

    The DTs we create are:
     - string
     - boolean
     - integer
     - float
     - natural number
     - molecular sequence
     - nucleotide sequence

    The CDTs we create are
     - verif_in: (string to_test?)
     - verif_out: (NaturalNumber failed_row)
     - prototype_cdt: (string example?, bool valid)
     - fasta_cdt: (string FASTA header?, molecular sequence FASTA sequence?)
    """
    User = apps.get_model("auth", "User")
    Group = apps.get_model("auth", "Group")
    kive_user = User.objects.get(pk=1)
    everyone_group = Group.objects.get(pk=1)

    local_tz = timezone("America/Vancouver")

    Datatype = apps.get_model("metadata", "Datatype")
    CompoundDatatype = apps.get_model("metadata", "CompoundDatatype")

    # Note: even though Datatype typically has auto_now_add=True set, here we
    # need to specify it.  This is good, as we would rather not have the date
    # change every time you do this migration.
    STR_DT = Datatype(
        pk=1,
        name="string",
        description="basic string type",
        user=kive_user,
        date_created=datetime(2013, 11, 13, 19, 47, 19, 853000, local_tz)  # "2013-11-13T19:47:19.853Z"
    )
    STR_DT.save()
    STR_DT.groups_allowed.add(everyone_group)

    BOOL_DT = Datatype(
        pk=2,
        name="boolean",
        description="basic boolean type",
        user=kive_user,
        date_created=datetime(2013, 11, 13, 19, 47, 19, 856000, local_tz)  # "2013-11-13T19:47:19.856Z"
    )
    BOOL_DT.save()
    BOOL_DT.restricts.add(STR_DT)
    BOOL_DT.groups_allowed.add(everyone_group)

    FLOAT_DT = Datatype(
        pk=3,
        name="float",
        description="basic float type",
        user=kive_user,
        date_created=datetime(2013, 11, 13, 19, 47, 19, 874000, local_tz)  # "2013-11-13T19:47:19.874Z"
    )
    FLOAT_DT.save()
    FLOAT_DT.restricts.add(STR_DT)
    FLOAT_DT.groups_allowed.add(everyone_group)

    INT_DT = Datatype(
        pk=4,
        name="integer",
        description="basic integer type",
        user=kive_user,
        date_created=datetime(2013, 11, 13, 19, 47, 19, 882000, local_tz)  # "2013-11-13T19:47:19.882Z"
    )
    INT_DT.save()
    # We don't need to add STR_DT as a restricted type because FLOAT_DT
    # already restricts it.
    INT_DT.restricts.add(FLOAT_DT)
    INT_DT.groups_allowed.add(everyone_group)

    NaturalNumber_DT = Datatype(
        pk=5,
        name="natural number",
        description="positive integer",
        user=kive_user,
        date_created=datetime(2013, 11, 13, 19, 47, 19, 890000, local_tz)  # "2013-11-13T19:47:19.890Z"
    )
    NaturalNumber_DT.save()
    NaturalNumber_DT.restricts.add(INT_DT)
    NaturalNumber_DT.basic_constraints.create(
        pk=1,
        ruletype="minval",
        rule="1"
    )
    NaturalNumber_DT.groups_allowed.add(everyone_group)

    MolSeq_DT = Datatype(
        pk=6,
        name="molecular sequence",
        description="String of IUPAC symbols representing either the primary protein sequence "
                    "(amino acids) or a nucleotide sequence (RNA or DNA).  Only standard "
                    "placeholders permitted (gap character '-', ambiguous amino acid '?', "
                    "stop codon '*').",
        user=kive_user,
        date_created=datetime(2014, 6, 10, 16, 36, 44, 948000, local_tz)  # "2014-06-10T16:36:44.948Z"
    )
    MolSeq_DT.save()
    MolSeq_DT.restricts.add(STR_DT)
    MolSeq_DT.basic_constraints.create(
        pk=3,
        ruletype="regexp",
        rule="[A-Za-z*?-]*"
    )
    MolSeq_DT.groups_allowed.add(everyone_group)

    NucSeq_DT = Datatype(
        pk=7,
        name="nucleotide sequence",
        description="A string of IUPAC symbols representing DNA or RNA, including ambiguous bases.",
        user=kive_user,
        date_created=datetime(2014, 6, 10, 18, 32, 15, 268000, local_tz)  # "2014-06-10T18:32:15.268Z"
    )
    NucSeq_DT.save()
    NucSeq_DT.restricts.add(STR_DT)
    NucSeq_DT.basic_constraints.create(
        pk=5,
        ruletype="regexp",
        rule="[ACGTUNacgtuWRKYSMBDHVNwrkysmbdhvn-]*"
    )
    NucSeq_DT.groups_allowed.add(everyone_group)

    verif_in = CompoundDatatype(pk=1, user=kive_user)
    verif_in.save()
    verif_in.members.create(pk=1, datatype=STR_DT, column_name="to_test", blankable=True, column_idx=1)
    verif_in.groups_allowed.add(everyone_group)

    verif_out = CompoundDatatype(pk=2, user=kive_user)
    verif_out.save()
    verif_out.members.create(pk=2, datatype=NaturalNumber_DT, column_name="failed_row", blankable=False, column_idx=1)
    verif_out.groups_allowed.add(everyone_group)

    prototype_cdt = CompoundDatatype(pk=3, user=kive_user)
    prototype_cdt.save()
    prototype_cdt.members.create(pk=3, datatype=STR_DT, column_name="example", blankable=True, column_idx=1)
    prototype_cdt.members.create(pk=4, datatype=BOOL_DT, column_name="valid", blankable=False, column_idx=2)
    prototype_cdt.groups_allowed.add(everyone_group)

    fasta_cdt = CompoundDatatype(pk=4, user=kive_user)
    fasta_cdt.save()
    fasta_cdt.members.create(pk=5, datatype=STR_DT, column_name="FASTA header", blankable=True, column_idx=1)
    fasta_cdt.members.create(pk=6, datatype=MolSeq_DT, column_name="FASTA sequence", blankable=True, column_idx=2)
    fasta_cdt.groups_allowed.add(everyone_group)

@transaction.atomic
def purge_initial_data(apps, schema_editor):
    """
    Reverse operation of load_initial_data.
    """
    Datatype = apps.get_model("metadata", "Datatype")
    CompoundDatatype = apps.get_model("metadata", "CompoundDatatype")

    for cdt_pk in [1,2,3,4]:
        cdt = CompoundDatatype.objects.get(pk=cdt_pk)
        for member in cdt.members.all():
            member.delete()
        cdt.delete()

    for dt_pk in range(1, 8):
        dt = Datatype.objects.get(pk=dt_pk)
        for bc in dt.basic_constraints.all():
            bc.delete()
        dt.delete()

class Migration(migrations.Migration):

    dependencies = [
        ("metadata", "0007_auto_20150218_1045"),
        ("contenttypes", "0002_remove_content_type_name")
    ]

    operations = [
        migrations.RunPython(load_initial_groups, reverse_code=migrations.RunPython.noop),
        migrations.RunPython(load_initial_user, reverse_code=migrations.RunPython.noop),
        migrations.RunPython(load_initial_data, reverse_code=purge_initial_data)
    ]
<commit_msg>Changed the data migration (metadata 0008) toward #521.<commit_after># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations, transaction, DEFAULT_DB_ALIAS, connections
from django.core.management.color import no_style
from django.core.management import call_command
from django.contrib.auth.management import create_permissions
from django.apps import apps as django_apps

from datetime import datetime
from pytz import timezone

import portal.utils

@transaction.atomic
def load_initial_groups(apps, schema_editor):
    # update_all_contenttypes(verbosity=0)
    portal.utils.update_all_contenttypes(verbosity=0)
    auth_app_config = django_apps.get_app_config("auth")
    create_permissions(auth_app_config, verbosity=0)
    call_command("loaddata", "initial_groups", app_label="metadata")

@transaction.atomic
def load_initial_user(apps, schema_editor):
    call_command("loaddata", "initial_user", app_label="metadata")

@transaction.atomic
def load_initial_data(apps, schema_editor):
    """
    Defines some system built-in Datatypes and CompoundDatatypes.

    The DTs we create are:
     - string
     - boolean
     - integer
     - float
     - natural number
     - molecular sequence
     - nucleotide sequence

    The CDTs we create are
     - verif_in: (string to_test?)
     - verif_out: (NaturalNumber failed_row)
     - prototype_cdt: (string example?, bool valid)
     - fasta_cdt: (string FASTA header?, molecular sequence FASTA sequence?)
    """
    User = apps.get_model("auth", "User")
    Group = apps.get_model("auth", "Group")
    kive_user = User.objects.get(pk=1)
    everyone_group = Group.objects.get(pk=1)

    local_tz = timezone("America/Vancouver")

    Datatype = apps.get_model("metadata", "Datatype")
    CompoundDatatype = apps.get_model("metadata", "CompoundDatatype")
    BasicConstraint = apps.get_model("metadata", "BasicConstraint")
    CompoundDatatypeMember = apps.get_model("metadata", "CompoundDatatypeMember")

    # Note: even though Datatype typically has auto_now_add=True set, here we
    # need to specify it.  This is good, as we would rather not have the date
    # change every time you do this migration.
    STR_DT = Datatype(
        pk=1,
        name="string",
        description="basic string type",
        user=kive_user,
        date_created=datetime(2013, 11, 13, 19, 47, 19, 853000, local_tz)  # "2013-11-13T19:47:19.853Z"
    )
    STR_DT.save()
    STR_DT.groups_allowed.add(everyone_group)

    BOOL_DT = Datatype(
        pk=2,
        name="boolean",
        description="basic boolean type",
        user=kive_user,
        date_created=datetime(2013, 11, 13, 19, 47, 19, 856000, local_tz)  # "2013-11-13T19:47:19.856Z"
    )
    BOOL_DT.save()
    BOOL_DT.restricts.add(STR_DT)
    BOOL_DT.groups_allowed.add(everyone_group)

    FLOAT_DT = Datatype(
        pk=3,
        name="float",
        description="basic float type",
        user=kive_user,
        date_created=datetime(2013, 11, 13, 19, 47, 19, 874000, local_tz)  # "2013-11-13T19:47:19.874Z"
    )
    FLOAT_DT.save()
    FLOAT_DT.restricts.add(STR_DT)
    FLOAT_DT.groups_allowed.add(everyone_group)

    INT_DT = Datatype(
        pk=4,
        name="integer",
        description="basic integer type",
        user=kive_user,
        date_created=datetime(2013, 11, 13, 19, 47, 19, 882000, local_tz)  # "2013-11-13T19:47:19.882Z"
    )
    INT_DT.save()
    # We don't need to add STR_DT as a restricted type because FLOAT_DT
    # already restricts it.
    INT_DT.restricts.add(FLOAT_DT)
    INT_DT.groups_allowed.add(everyone_group)

    NaturalNumber_DT = Datatype(
        pk=5,
        name="natural number",
        description="positive integer",
        user=kive_user,
        date_created=datetime(2013, 11, 13, 19, 47, 19, 890000, local_tz)  # "2013-11-13T19:47:19.890Z"
    )
    NaturalNumber_DT.save()
    NaturalNumber_DT.restricts.add(INT_DT)
    NaturalNumber_DT.basic_constraints.create(
        pk=1,
        ruletype="minval",
        rule="1"
    )
    NaturalNumber_DT.groups_allowed.add(everyone_group)

    MolSeq_DT = Datatype(
        pk=6,
        name="molecular sequence",
        description="String of IUPAC symbols representing either the primary protein sequence "
                    "(amino acids) or a nucleotide sequence (RNA or DNA).  Only standard "
                    "placeholders permitted (gap character '-', ambiguous amino acid '?', "
                    "stop codon '*').",
        user=kive_user,
        date_created=datetime(2014, 6, 10, 16, 36, 44, 948000, local_tz)  # "2014-06-10T16:36:44.948Z"
    )
    MolSeq_DT.save()
    MolSeq_DT.restricts.add(STR_DT)
    MolSeq_DT.basic_constraints.create(
        pk=3,
        ruletype="regexp",
        rule="[A-Za-z*?-]*"
    )
    MolSeq_DT.groups_allowed.add(everyone_group)

    NucSeq_DT = Datatype(
        pk=7,
        name="nucleotide sequence",
        description="A string of IUPAC symbols representing DNA or RNA, including ambiguous bases.",
        user=kive_user,
        date_created=datetime(2014, 6, 10, 18, 32, 15, 268000, local_tz)  # "2014-06-10T18:32:15.268Z"
    )
    NucSeq_DT.save()
    NucSeq_DT.restricts.add(STR_DT)
    NucSeq_DT.basic_constraints.create(
        pk=5,
        ruletype="regexp",
        rule="[ACGTUNacgtuWRKYSMBDHVNwrkysmbdhvn-]*"
    )
    NucSeq_DT.groups_allowed.add(everyone_group)

    verif_in = CompoundDatatype(pk=1, user=kive_user)
    verif_in.save()
    verif_in.members.create(pk=1, datatype=STR_DT, column_name="to_test", blankable=True, column_idx=1)
    verif_in.groups_allowed.add(everyone_group)

    verif_out = CompoundDatatype(pk=2, user=kive_user)
    verif_out.save()
    verif_out.members.create(pk=2, datatype=NaturalNumber_DT, column_name="failed_row", blankable=False, column_idx=1)
    verif_out.groups_allowed.add(everyone_group)

    prototype_cdt = CompoundDatatype(pk=3, user=kive_user)
    prototype_cdt.save()
    prototype_cdt.members.create(pk=3, datatype=STR_DT, column_name="example", blankable=True, column_idx=1)
    prototype_cdt.members.create(pk=4, datatype=BOOL_DT, column_name="valid", blankable=False, column_idx=2)
    prototype_cdt.groups_allowed.add(everyone_group)

    fasta_cdt = CompoundDatatype(pk=4, user=kive_user)
    fasta_cdt.save()
    fasta_cdt.members.create(pk=5, datatype=STR_DT, column_name="FASTA header", blankable=True, column_idx=1)
    fasta_cdt.members.create(pk=6, datatype=MolSeq_DT, column_name="FASTA sequence", blankable=True, column_idx=2)
    fasta_cdt.groups_allowed.add(everyone_group)

    conn = connections[DEFAULT_DB_ALIAS]
    if conn.features.supports_sequence_reset:
        sql_list = conn.ops.sequence_reset_sql(
            no_style(), [Datatype, BasicConstraint, CompoundDatatype, CompoundDatatypeMember])
        if sql_list:
            with transaction.atomic(using=DEFAULT_DB_ALIAS):
                cursor = conn.cursor()
                for sql in sql_list:
                    cursor.execute(sql)

@transaction.atomic
def purge_initial_data(apps, schema_editor):
    """
    Reverse operation of load_initial_data.
    """
    Datatype = apps.get_model("metadata", "Datatype")
    CompoundDatatype = apps.get_model("metadata", "CompoundDatatype")

    for cdt_pk in [1,2,3,4]:
        cdt = CompoundDatatype.objects.get(pk=cdt_pk)
        for member in cdt.members.all():
            member.delete()
        cdt.delete()

    for dt_pk in range(1, 8):
        dt = Datatype.objects.get(pk=dt_pk)
        for bc in dt.basic_constraints.all():
            bc.delete()
        dt.delete()

class Migration(migrations.Migration):

    dependencies = [
        ("metadata", "0007_auto_20150218_1045"),
        ("contenttypes", "0002_remove_content_type_name")
    ]

    operations = [
        migrations.RunPython(load_initial_groups, reverse_code=migrations.RunPython.noop),
        migrations.RunPython(load_initial_user, reverse_code=migrations.RunPython.noop),
        migrations.RunPython(load_initial_data, reverse_code=purge_initial_data)
    ]
<|endoftext|>


<commit_before>import bson
import datetime
import pymongo.errors

from . import consistencychecker
from . import containerutil
from .. import config
from .. import util

from ..web.errors import APIStorageException, APIConflictException, APINotFoundException

log = config.log

# TODO: Find a better place to put this until OOP where we can just call cont.children
CHILD_MAP = {
    'groups':   'projects',
    'projects': 'sessions',
    'sessions': 'acquisitions'
}

PARENT_MAP = {v: k for k,v in CHILD_MAP.iteritems()}

# All "containers" are required to return these fields
# 'All' includes users
BASE_DEFAULTS = {
    '_id':      None,
    'created':  None,
    'modified': None
}

# All containers that inherit from 'container' in the DM
CONTAINER_DEFAULTS = BASE_DEFAULTS.copy()
CONTAINER_DEFAULTS.update({
    'permissions':  [],
    'files':        [],
    'notes':        [],
    'tags':         [],
    'info':         {}
})

class ContainerStorage(object):
    """
    This class provides access to mongodb collection elements (called containers).
    It is used by ContainerHandler istances for get, create, update and delete operations on containers.
    Examples: projects, sessions, acquisitions and collections
    """

    def __init__(self, cont_name, use_object_id=False):
        self.cont_name = cont_name
        self.use_object_id = use_object_id
        self.dbc = config.db[cont_name]

    @classmethod
    def factory(cls, cont_name):
        """
        Factory method to aid in the creation of a ContainerStorage instance
        when cont_name is dynamic.
        """
        cont_storage_name = containerutil.singularize(cont_name).capitalize() + 'Storage'
        for subclass in cls.__subclasses__():
            if subclass.__name__ == cont_storage_name:
                return subclass()
        return cls(containerutil.pluralize(cont_name))

    @classmethod
    def get_top_down_hierarchy(cls, cont_name, cid):
        parent_to_child = {
            'groups': 'projects',
            'projects': 'sessions',
            'sessions': 'acquisitions'
        }

        parent_tree = {
            cont_name: [cid]
        }
        parent_name = cont_name
        while parent_to_child.get(parent_name):
            # Parent storage
            storage = ContainerStorage.factory(parent_name)
            child_name = parent_to_child[parent_name]
            parent_tree[child_name] = []

            # For each parent id, find all of its children and add them to the list of child ids in the parent tree
            for parent_id in parent_tree[parent_name]:
                parent_tree[child_name] = parent_tree[child_name] + [cont["_id"] for cont in storage.get_children(parent_id, projection={'_id':1})]

            parent_name = child_name
        return parent_tree

    def _fill_default_values(self, cont):
        if cont:
            defaults = BASE_DEFAULTS.copy()
            if self.cont_name not in ['groups', 'users']:
                defaults = CONTAINER_DEFAULTS.copy()
            for k,v in defaults.iteritems():
                cont.setdefault(k, v)

    def get_container(self, _id, projection=None, get_children=False):
        cont = self.get_el(_id, projection=projection)
        if cont is None:
            raise APINotFoundException('Could not find {} {}'.format(self.cont_name, _id))
        if get_children:
            children = self.get_children(_id, projection=projection)
            cont[CHILD_MAP[self.cont_name]] = children
        return cont

    def get_children(self, _id, projection=None, uid=None):
        try:
            child_name = CHILD_MAP[self.cont_name]
        except KeyError:
            raise APINotFoundException('Children cannot be listed from the {0} level'.format(self.cont_name))
        if not self.use_object_id:
            query = {containerutil.singularize(self.cont_name): _id}
        else:
            query = {containerutil.singularize(self.cont_name): bson.ObjectId(_id)}

        if uid:
            query['permissions'] = {'$elemMatch': {'_id': uid}}
        if not projection:
            projection = {'info': 0, 'files.info': 0, 'subject': 0, 'tags': 0}
        return ContainerStorage.factory(child_name).get_all_el(query, None, projection)

    def _from_mongo(self, cont):
        pass

    def _to_mongo(self, payload):
        pass

    def exec_op(self, action, _id=None, payload=None, query=None, user=None,
                public=False, projection=None, recursive=False, r_payload=None,  # pylint: disable=unused-argument
                replace_metadata=False, unset_payload=None):
        """
        Generic method to exec a CRUD operation from a REST verb.
        """

        check = consistencychecker.get_container_storage_checker(action, self.cont_name)
        data_op = payload or {'_id': _id}
        check(data_op)
        if action == 'GET' and _id:
            return self.get_el(_id, projection=projection, fill_defaults=True)
        if action == 'GET':
            return self.get_all_el(query, user, projection, fill_defaults=True)
        if action == 'DELETE':
            return self.delete_el(_id)
        if action == 'PUT':
            return self.update_el(_id, payload, unset_payload=unset_payload, recursive=recursive, r_payload=r_payload, replace_metadata=replace_metadata)
        if action == 'POST':
            return self.create_el(payload)
        raise ValueError('action should be one of GET, POST, PUT, DELETE')

    def create_el(self, payload):
        self._to_mongo(payload)
        try:
            result = self.dbc.insert_one(payload)
        except pymongo.errors.DuplicateKeyError:
            raise APIConflictException('Object with id {} already exists.'.format(payload['_id']))
        return result

    def update_el(self, _id, payload, unset_payload=None, recursive=False, r_payload=None, replace_metadata=False):
        replace = None
        if replace_metadata:
            replace = {}
            if payload.get('info') is not None:
                replace['info'] = util.mongo_sanitize_fields(payload.pop('info'))
            if payload.get('subject') is not None and payload['subject'].get('info') is not None:
                replace['subject.info'] = util.mongo_sanitize_fields(payload['subject'].pop('info'))

        update = {}

        if payload is not None:
            self._to_mongo(payload)
            update['$set'] = util.mongo_dict(payload)

        if unset_payload is not None:
            update['$unset'] = util.mongo_dict(unset_payload)

        if replace is not None:
            update['$set'].update(replace)

        if self.use_object_id:
            try:
                _id = bson.ObjectId(_id)
            except bson.errors.InvalidId as e:
                raise APIStorageException(e.message)
        if recursive and r_payload is not None:
            containerutil.propagate_changes(self.cont_name, _id, {}, {'$set': util.mongo_dict(r_payload)})
        return self.dbc.update_one({'_id': _id}, update)

    def delete_el(self, _id):
        if self.use_object_id:
            try:
                _id = bson.ObjectId(_id)
            except bson.errors.InvalidId as e:
                raise APIStorageException(e.message)
        return self.dbc.delete_one({'_id':_id})

    def get_el(self, _id, projection=None, fill_defaults=False):
        if self.use_object_id:
            try:
                _id = bson.ObjectId(_id)
            except bson.errors.InvalidId as e:
                raise APIStorageException(e.message)
        cont = self.dbc.find_one(_id, projection)
        self._from_mongo(cont)
        if fill_defaults:
            self._fill_default_values(cont)
        return cont

    def get_all_el(self, query, user, projection, fill_defaults=False):
        if user:
            if query.get('permissions'):
                query['$and'] = [{'permissions': {'$elemMatch': user}}, {'permissions': query.pop('permissions')}]
            else:
                query['permissions'] = {'$elemMatch': user}

        # if projection includes files.info, add new key `info_exists` and allow reserved info keys through
        if projection and ('info' in projection or 'files.info' in projection):
            replace_info_with_bool = True
            projection.pop('files.info', None)
            projection.pop('info', None)
            if not projection:
                # if we've removed everything, set it as None otherwise only the _id is returned
                project = None
        else:
            replace_info_with_bool = False

        results = list(self.dbc.find(query))
        for cont in results:
            self._from_mongo(cont)
            if fill_defaults:
                self._fill_default_values(cont)

            if replace_info_with_bool:
                info = cont.pop('info', {})
                cont['info_exists'] = bool(info)
                cont['info'] = containerutil.sanitize_info(info)

                for f in cont.get('files', []):
                    f_info = f.pop('info', {})
                    f['info_exists'] = bool(f_info)
                    f['info'] = containerutil.sanitize_info(f_info)

        return results

    def modify_info(self, _id, payload, modify_subject=False):

        # Support modification of subject info
        # Can be removed when subject becomes a standalone container
        info_key = 'subject.info' if modify_subject else 'info'

        update = {}
        set_payload = payload.get('set')
        delete_payload = payload.get('delete')
        replace_payload = payload.get('replace')

        if (set_payload or delete_payload) and replace_payload is not None:
            raise APIStorageException('Cannot set or delete AND replace info fields.')

        if replace_payload is not None:
            update = {
                '$set': {
                    info_key: util.mongo_sanitize_fields(replace_payload)
                }
            }

        else:
            if set_payload:
                update['$set'] = {}
                for k,v in set_payload.items():
                    update['$set'][info_key + '.' + k] = util.mongo_sanitize_fields(v)
            if delete_payload:
                update['$unset'] = {}
                for k in delete_payload:
                    update['$unset'][info_key + '.' + k] = ''

        if self.use_object_id:
            _id = bson.objectid.ObjectId(_id)
        query = {'_id': _id }

        if not update.get('$set'):
            update['$set'] = {'modified': datetime.datetime.utcnow()}
        else:
            update['$set']['modified'] = datetime.datetime.utcnow()

        return self.dbc.update_one(query, update)
<commit_msg>Remove unnecessary projection fiddling<commit_after>import bson
import datetime
import pymongo.errors

from . import consistencychecker
from . import containerutil
from .. import config
from .. import util

from ..web.errors import APIStorageException, APIConflictException, APINotFoundException

log = config.log

# TODO: Find a better place to put this until OOP where we can just call cont.children
CHILD_MAP = {
    'groups':   'projects',
    'projects': 'sessions',
    'sessions': 'acquisitions'
}

PARENT_MAP = {v: k for k,v in CHILD_MAP.iteritems()}

# All "containers" are required to return these fields
# 'All' includes users
BASE_DEFAULTS = {
    '_id':      None,
    'created':  None,
    'modified': None
}

# All containers that inherit from 'container' in the DM
CONTAINER_DEFAULTS = BASE_DEFAULTS.copy()
CONTAINER_DEFAULTS.update({
    'permissions':  [],
    'files':        [],
    'notes':        [],
    'tags':         [],
    'info':         {}
})

class ContainerStorage(object):
    """
    This class provides access to mongodb collection elements (called containers).
    It is used by ContainerHandler istances for get, create, update and delete operations on containers.
    Examples: projects, sessions, acquisitions and collections
    """

    def __init__(self, cont_name, use_object_id=False):
        self.cont_name = cont_name
        self.use_object_id = use_object_id
        self.dbc = config.db[cont_name]

    @classmethod
    def factory(cls, cont_name):
        """
        Factory method to aid in the creation of a ContainerStorage instance
        when cont_name is dynamic.
        """
        cont_storage_name = containerutil.singularize(cont_name).capitalize() + 'Storage'
        for subclass in cls.__subclasses__():
            if subclass.__name__ == cont_storage_name:
                return subclass()
        return cls(containerutil.pluralize(cont_name))

    @classmethod
    def get_top_down_hierarchy(cls, cont_name, cid):
        parent_to_child = {
            'groups': 'projects',
            'projects': 'sessions',
            'sessions': 'acquisitions'
        }

        parent_tree = {
            cont_name: [cid]
        }
        parent_name = cont_name
        while parent_to_child.get(parent_name):
            # Parent storage
            storage = ContainerStorage.factory(parent_name)
            child_name = parent_to_child[parent_name]
            parent_tree[child_name] = []

            # For each parent id, find all of its children and add them to the list of child ids in the parent tree
            for parent_id in parent_tree[parent_name]:
                parent_tree[child_name] = parent_tree[child_name] + [cont["_id"] for cont in storage.get_children(parent_id, projection={'_id':1})]

            parent_name = child_name
        return parent_tree

    def _fill_default_values(self, cont):
        if cont:
            defaults = BASE_DEFAULTS.copy()
            if self.cont_name not in ['groups', 'users']:
                defaults = CONTAINER_DEFAULTS.copy()
            for k,v in defaults.iteritems():
                cont.setdefault(k, v)

    def get_container(self, _id, projection=None, get_children=False):
        cont = self.get_el(_id, projection=projection)
        if cont is None:
            raise APINotFoundException('Could not find {} {}'.format(self.cont_name, _id))
        if get_children:
            children = self.get_children(_id, projection=projection)
            cont[CHILD_MAP[self.cont_name]] = children
        return cont

    def get_children(self, _id, projection=None, uid=None):
        try:
            child_name = CHILD_MAP[self.cont_name]
        except KeyError:
            raise APINotFoundException('Children cannot be listed from the {0} level'.format(self.cont_name))
        if not self.use_object_id:
            query = {containerutil.singularize(self.cont_name): _id}
        else:
            query = {containerutil.singularize(self.cont_name): bson.ObjectId(_id)}

        if uid:
            query['permissions'] = {'$elemMatch': {'_id': uid}}
        if not projection:
            projection = {'info': 0, 'files.info': 0, 'subject': 0, 'tags': 0}
        return ContainerStorage.factory(child_name).get_all_el(query, None, projection)

    def _from_mongo(self, cont):
        pass

    def _to_mongo(self, payload):
        pass

    def exec_op(self, action, _id=None, payload=None, query=None, user=None,
                public=False, projection=None, recursive=False, r_payload=None,  # pylint: disable=unused-argument
                replace_metadata=False, unset_payload=None):
        """
        Generic method to exec a CRUD operation from a REST verb.
        """

        check = consistencychecker.get_container_storage_checker(action, self.cont_name)
        data_op = payload or {'_id': _id}
        check(data_op)
        if action == 'GET' and _id:
            return self.get_el(_id, projection=projection, fill_defaults=True)
        if action == 'GET':
            return self.get_all_el(query, user, projection, fill_defaults=True)
        if action == 'DELETE':
            return self.delete_el(_id)
        if action == 'PUT':
            return self.update_el(_id, payload, unset_payload=unset_payload, recursive=recursive, r_payload=r_payload, replace_metadata=replace_metadata)
        if action == 'POST':
            return self.create_el(payload)
        raise ValueError('action should be one of GET, POST, PUT, DELETE')

    def create_el(self, payload):
        self._to_mongo(payload)
        try:
            result = self.dbc.insert_one(payload)
        except pymongo.errors.DuplicateKeyError:
            raise APIConflictException('Object with id {} already exists.'.format(payload['_id']))
        return result

    def update_el(self, _id, payload, unset_payload=None, recursive=False, r_payload=None, replace_metadata=False):
        replace = None
        if replace_metadata:
            replace = {}
            if payload.get('info') is not None:
                replace['info'] = util.mongo_sanitize_fields(payload.pop('info'))
            if payload.get('subject') is not None and payload['subject'].get('info') is not None:
                replace['subject.info'] = util.mongo_sanitize_fields(payload['subject'].pop('info'))

        update = {}

        if payload is not None:
            self._to_mongo(payload)
            update['$set'] = util.mongo_dict(payload)

        if unset_payload is not None:
            update['$unset'] = util.mongo_dict(unset_payload)

        if replace is not None:
            update['$set'].update(replace)

        if self.use_object_id:
            try:
                _id = bson.ObjectId(_id)
            except bson.errors.InvalidId as e:
                raise APIStorageException(e.message)
        if recursive and r_payload is not None:
            containerutil.propagate_changes(self.cont_name, _id, {}, {'$set': util.mongo_dict(r_payload)})
        return self.dbc.update_one({'_id': _id}, update)

    def delete_el(self, _id):
        if self.use_object_id:
            try:
                _id = bson.ObjectId(_id)
            except bson.errors.InvalidId as e:
                raise APIStorageException(e.message)
        return self.dbc.delete_one({'_id':_id})

    def get_el(self, _id, projection=None, fill_defaults=False):
        if self.use_object_id:
            try:
                _id = bson.ObjectId(_id)
            except bson.errors.InvalidId as e:
                raise APIStorageException(e.message)
        cont = self.dbc.find_one(_id, projection)
        self._from_mongo(cont)
        if fill_defaults:
            self._fill_default_values(cont)
        return cont

    def get_all_el(self, query, user, projection, fill_defaults=False):
        if user:
            if query.get('permissions'):
                query['$and'] = [{'permissions': {'$elemMatch': user}}, {'permissions': query.pop('permissions')}]
            else:
                query['permissions'] = {'$elemMatch': user}

        # if projection includes files.info, add new key `info_exists` and allow reserved info keys through
        if projection and ('info' in projection or 'files.info' in projection):
            replace_info_with_bool = True
            projection.pop('files.info', None)
            projection.pop('info', None)
        else:
            replace_info_with_bool = False

        results = list(self.dbc.find(query))
        for cont in results:
            self._from_mongo(cont)
            if fill_defaults:
                self._fill_default_values(cont)

            if replace_info_with_bool:
                info = cont.pop('info', {})
                cont['info_exists'] = bool(info)
                cont['info'] = containerutil.sanitize_info(info)

                for f in cont.get('files', []):
                    f_info = f.pop('info', {})
                    f['info_exists'] = bool(f_info)
                    f['info'] = containerutil.sanitize_info(f_info)

        return results

    def modify_info(self, _id, payload, modify_subject=False):

        # Support modification of subject info
        # Can be removed when subject becomes a standalone container
        info_key = 'subject.info' if modify_subject else 'info'

        update = {}
        set_payload = payload.get('set')
        delete_payload = payload.get('delete')
        replace_payload = payload.get('replace')

        if (set_payload or delete_payload) and replace_payload is not None:
            raise APIStorageException('Cannot set or delete AND replace info fields.')

        if replace_payload is not None:
            update = {
                '$set': {
                    info_key: util.mongo_sanitize_fields(replace_payload)
                }
            }

        else:
            if set_payload:
                update['$set'] = {}
                for k,v in set_payload.items():
                    update['$set'][info_key + '.' + k] = util.mongo_sanitize_fields(v)
            if delete_payload:
                update['$unset'] = {}
                for k in delete_payload:
                    update['$unset'][info_key + '.' + k] = ''

        if self.use_object_id:
            _id = bson.objectid.ObjectId(_id)
        query = {'_id': _id }

        if not update.get('$set'):
            update['$set'] = {'modified': datetime.datetime.utcnow()}
        else:
            update['$set']['modified'] = datetime.datetime.utcnow()

        return self.dbc.update_one(query, update)
<|endoftext|>


<commit_before># Copyright (c) 2012 Lars Hupfeldt Nielsen, Hupfeldt IT
# All rights reserved. This work is under a BSD license, see LICENSE.TXT.

import sys, os.path
from collections import namedtuple
import inspect

class ConfigBaseException(Exception):
    pass

class ConfigException(ConfigBaseException):
    pass

class NoAttributeException(ConfigBaseException):
    pass

class InvalidUsageException(ConfigBaseException):
    pass

_Traceback = namedtuple('Traceback', 'filename, lineno, function, code_context, index')

def _user_file_line(up_level_start=0):
    while 1:
        tb = _Traceback(*inspect.stack()[up_level_start][1:])
        if os.path.basename(os.path.dirname(tb.filename)) != 'multiconf':
            break
        up_level_start += 1

    return tb.filename, tb.lineno

def _error_msg(num_errors, message, up_level=2, error_type='ConfigError'):
    print >> sys.stderr, 'File "%s", line %d' % _user_file_line(up_level+1)
    print >> sys.stderr, error_type + ':', message
    return num_errors + 1

def _warning_msg(message, up_level=2):
    _error_msg(0, message, up_level=up_level+1, error_type='ConfigWarning')
<commit_msg>Fixed file:line collection performance issues by using sys._getframe instead of inspect module<commit_after># Copyright (c) 2012 Lars Hupfeldt Nielsen, Hupfeldt IT
# All rights reserved. This work is under a BSD license, see LICENSE.TXT.

import sys, os.path
from collections import namedtuple

class ConfigBaseException(Exception):
    pass

class ConfigException(ConfigBaseException):
    pass

class NoAttributeException(ConfigBaseException):
    pass

class InvalidUsageException(ConfigBaseException):
    pass

def _user_file_line(up_level_start=1):
    frame = sys._getframe(up_level_start)
    while 1:
        filename = frame.f_globals['__file__']
        if os.path.basename(os.path.dirname(filename)) != 'multiconf':
            break
        frame = frame.f_back

    return filename if filename[-1] == 'y' else filename[:-1], frame.f_lineno

def _error_msg(num_errors, message, up_level=2, error_type='ConfigError'):
    print >> sys.stderr, 'File "%s", line %d' % _user_file_line(up_level+1)
    print >> sys.stderr, error_type + ':', message
    return num_errors + 1

def _warning_msg(message, up_level=2):
    _error_msg(0, message, up_level=up_level+1, error_type='ConfigWarning')
<|endoftext|>


<commit_before>import json
import os
import os.path

class ConfigManager():
	_cache = {}
	def __init__(self, configPath = "configs/"):
		if os.path.isdir(configPath):
			self.configPath = configPath
		else:
			raise IOError("Config Path does not eixst")
		self._configs = {}
		self._syncCache()
		self.getConfigs()

	def __getitem__(self, key):
		try:
			return self._configs[key]
		except KeyError:
			self.syncCache()
			return self._configs[key]

	#Recursive function to get all files. Sub is the relative path from the root config dir.
	def getConfigs(self, path = None, sub = "", overrideCache = False):
		if path == None:
			path = self.configPath
		files = os.listdir(path)
		for item in files:
			#Ignore hidden files.
			if item[0] == ".":
				continue

			#Remove the .json handle from the name
			name = item.replace(".json", "")
			finalName = os.path.join(sub, name)

			#If it's a directory, run this function again within that directory
			if os.path.isdir(os.path.join(path, item)):
				self.getConfigs(path = os.path.join(path, item), sub = os.path.join(sub, item))
			#If we already have something from the cache, or added in previously, skip it.
			elif overrideCache or finalName not in self._configs:
				#Read in the file
				f = open(os.path.join(path, item), "r")
				#Check if it's JSON. If it is, it will be parsed.
				parsed = self.parseConfig(f.read())
				f.close()
				if parsed != None:
					self.addConfig(finalName, parsed)
	#Returns parsed JSON if config is valid JSON, otherwise, return Noen
	def parseConfig(self, config):
		try:
			return json.loads(config)
		except ValueError:
			return None

	def addConfig(self, name, contents):
		self._configs[name] = contents
		ConfigManager._cache[name] = contents

	def _syncCache(self):
		unmatchedKeys = [key for key in ConfigManager._cache.keys() if key not in self._configs]
		for key in unmatchedKeys:
			self._configs[key] = ConfigManager._cache[key]
<commit_msg>Add caches that differ from config path to config path.<commit_after>import json
import os
import os.path

class ConfigManager():
	_caches = {}
	def __init__(self, configPath = "configs/", overrideCache = False):
		if os.path.isdir(configPath):
			self.configPath = configPath
		else:
			raise IOError("Config Path does not eixst")

		if not overrideCache and configPath in ConfigManager._caches:
			self._cache = ConfigManager._caches['path']
		else:
			self._cache = {}

		self._configs = {}
		self._syncCache()
		self.getConfigs()

	def __getitem__(self, key):
		try:
			return self._configs[key]
		except KeyError:
			self.syncCache()
			return self._configs[key]

	#Recursive function to get all files. Sub is the relative path from the root config dir.
	def getConfigs(self, path = None, sub = "", overrideCache = False):
		if path == None:
			path = self.configPath
		files = os.listdir(path)
		for item in files:
			#Ignore hidden files.
			if item[0] == ".":
				continue

			#Remove the .json handle from the name
			name = item.replace(".json", "")
			finalName = os.path.join(sub, name)

			#If it's a directory, run this function again within that directory
			if os.path.isdir(os.path.join(path, item)):
				self.getConfigs(path = os.path.join(path, item), sub = os.path.join(sub, item))
			#If we already have something from the cache, or added in previously, skip it.
			elif overrideCache or finalName not in self._configs:
				#Read in the file
				f = open(os.path.join(path, item), "r")
				#Check if it's JSON. If it is, it will be parsed.
				parsed = self.parseConfig(f.read())
				f.close()
				if parsed != None:
					self.addConfig(finalName, parsed)
	#Returns parsed JSON if config is valid JSON, otherwise, return Noen
	def parseConfig(self, config):
		try:
			return json.loads(config)
		except ValueError:
			return None

	def addConfig(self, name, contents):
		self._configs[name] = contents
		self._cache[name] = contents

	def _syncCache(self):
		unmatchedKeys = [key for key in self._cache.keys() if key not in self._configs]
		for key in unmatchedKeys:
			self._configs[key] = self._cache[key]
<|endoftext|>


<commit_before>DATA_PATH = "/u/daoudat/usr/lib/python/pyGeno/pyGenoData/"
pyGeno_VERSION = "Skiny Cobra Beta 1"
<commit_msg>set versionwq<commit_after>DATA_PATH = "/u/daoudat/usr/lib/python/pyGeno/pyGenoData/"
pyGeno_VERSION = "Stasis : Skiny Cobra Beta 1"
<|endoftext|>


<commit_before>#!/usr/bin/python2.5
#
# Copyright 2008 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Custom widgets used for form fields.
"""

__authors__ = [
  '"Pawel Solyga" <pawel.solyga@gmail.com>',
  ]

import copy

from django import forms
from django.forms import util
from django.forms import widgets
from django.utils import html
from django.utils import simplejson
from django.utils import safestring

from soc.logic import dicts

class ReadOnlyInput(forms.widgets.Input):
  """Read only input widget.
  """
  input_type = 'text'

  def render(self, name, value, attrs=None):
    """Render ReadOnlyInput widget as HTML.
    """
    attrs['readonly'] = 'readonly'
    attrs['class'] = 'plaintext'
    return super(ReadOnlyInput, self).render(name, value, attrs)

class FullTinyMCE(forms.widgets.Textarea):
  """TinyMCE widget.

  Requires to include tiny_mce_src.js in your template. Widget can be
  customized by overwriting or adding extra options to mce_settings
  dictionary

  You can set TinyMCE widget for particular form field using code below:
    class ExampleForm(helper.forms.BaseForm):
      content = forms.fields.CharField(widget=helper.widgets.TinyMCE())

  You can include tiny_mce_src.js in your template using:
    {% block scripts %}

    {% endblock %}
  """

  features1 = ("bold,italic,underline,strikethrough,|,"
               "forecolor,backcolor,blockquote,|"
              ",justifyleft,justifycenter,justifyright,justifyfull,|,"
              "fontselect, fontsizeselect,formatselect")

  features2 = ("newdocument,|,bullist,numlist,|,outdent,indent,|,undo,redo,|"
      ",link,unlink,anchor,image,cleanup,help,code,hr,removeformat,visualaid,|,"
      "sub,sup,|,charmap,"
      "")

  DEF_MCE_SETTINGS = {'mode': "exact",
                      'theme': "advanced",
                      'theme_advanced_buttons1': features1,
                      'theme_advanced_buttons2': features2,
                      'theme_advanced_buttons3': '',
                      'theme_advanced_toolbar_location': "top",
                      'theme_advanced_toolbar_align': "left"}

  TINY_MCE_HTML_FMT = u'''\
<textarea %(attrs)s>%(value)s</textarea>
'''

  def __init__(self, mce_settings=None, *args, **kwargs):
    """Initialize TinyMCE widget with default or customized settings.

    Args:
      mce_settings: dict with TinyMCE widget settings
      *args, **kwargs:  passed through to parent __init__() constructor
    """

    super(forms.widgets.Textarea, self).__init__(*args, **kwargs)
    self.mce_settings = self.DEF_MCE_SETTINGS

  def render(self, name, value, attrs=None):
    """Render TinyMCE widget as HTML.
    """
    if value is None:
      value = ''
    value = util.smart_unicode(value)
    final_attrs = self.build_attrs(attrs, name=name)

    self.mce_settings['elements'] = "id_%s" % name

    # convert mce_settings from dict to JSON
    mce_json = simplejson.JSONEncoder().encode(self.mce_settings)

    return safestring.mark_safe(self.TINY_MCE_HTML_FMT %
        {'attrs': widgets.flatatt(final_attrs),
         'value': html.escape(value),
         'settings_json':  mce_json})

class TinyMCE(FullTinyMCE):
  """Regular version of TinyMce
  """

  def __init__(self, *args, **kwargs):
    """
    """

    super(TinyMCE, self).__init__(*args, **kwargs)
    keys = ['mode', 'theme', 'theme_advanced_toolbar_location',
            'theme_advanced_toolbar_align']
    self.mce_settings = dicts.filter(self.mce_settings, keys)

class ReferenceField(forms.CharField):
  """Widget for selecting a reference to an Entity.
  """

  def __init__(self, reference_url, filter=None,
               *args, **kwargs):
    """Initializes the widget with the specified url and filter.
    """

    self.rf = {}
    self.rf['reference_url'] = reference_url
    self.rf['filter'] = filter if filter else []
    super(ReferenceField, self).__init__(*args, **kwargs)
<commit_msg>Added an AgreementField widget<commit_after>#!/usr/bin/python2.5
#
# Copyright 2008 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Custom widgets used for form fields.
"""

__authors__ = [
  '"Pawel Solyga" <pawel.solyga@gmail.com>',
  ]

import copy

from django import forms
from django.forms import util
from django.forms import widgets
from django.utils import html
from django.utils import simplejson
from django.utils import safestring

from soc.logic import dicts

class ReadOnlyInput(forms.widgets.Input):
  """Read only input widget.
  """
  input_type = 'text'

  def render(self, name, value, attrs=None):
    """Render ReadOnlyInput widget as HTML.
    """
    attrs['readonly'] = 'readonly'
    attrs['class'] = 'plaintext'
    return super(ReadOnlyInput, self).render(name, value, attrs)

class FullTinyMCE(forms.widgets.Textarea):
  """TinyMCE widget.

  Requires to include tiny_mce_src.js in your template. Widget can be
  customized by overwriting or adding extra options to mce_settings
  dictionary

  You can set TinyMCE widget for particular form field using code below:
    class ExampleForm(helper.forms.BaseForm):
      content = forms.fields.CharField(widget=helper.widgets.TinyMCE())

  You can include tiny_mce_src.js in your template using:
    {% block scripts %}

    {% endblock %}
  """

  features1 = ("bold,italic,underline,strikethrough,|,"
               "forecolor,backcolor,blockquote,|"
              ",justifyleft,justifycenter,justifyright,justifyfull,|,"
              "fontselect, fontsizeselect,formatselect")

  features2 = ("newdocument,|,bullist,numlist,|,outdent,indent,|,undo,redo,|"
      ",link,unlink,anchor,image,cleanup,help,code,hr,removeformat,visualaid,|,"
      "sub,sup,|,charmap,"
      "")

  DEF_MCE_SETTINGS = {'mode': "exact",
                      'theme': "advanced",
                      'theme_advanced_buttons1': features1,
                      'theme_advanced_buttons2': features2,
                      'theme_advanced_buttons3': '',
                      'theme_advanced_toolbar_location': "top",
                      'theme_advanced_toolbar_align': "left"}

  TINY_MCE_HTML_FMT = u'''\
<textarea %(attrs)s>%(value)s</textarea>
'''

  def __init__(self, mce_settings=None, *args, **kwargs):
    """Initialize TinyMCE widget with default or customized settings.

    Args:
      mce_settings: dict with TinyMCE widget settings
      *args, **kwargs:  passed through to parent __init__() constructor
    """

    super(forms.widgets.Textarea, self).__init__(*args, **kwargs)
    self.mce_settings = self.DEF_MCE_SETTINGS

  def render(self, name, value, attrs=None):
    """Render TinyMCE widget as HTML.
    """
    if value is None:
      value = ''
    value = util.smart_unicode(value)
    final_attrs = self.build_attrs(attrs, name=name)

    self.mce_settings['elements'] = "id_%s" % name

    # convert mce_settings from dict to JSON
    mce_json = simplejson.JSONEncoder().encode(self.mce_settings)

    return safestring.mark_safe(self.TINY_MCE_HTML_FMT %
        {'attrs': widgets.flatatt(final_attrs),
         'value': html.escape(value),
         'settings_json':  mce_json})

class TinyMCE(FullTinyMCE):
  """Regular version of TinyMce
  """

  def __init__(self, *args, **kwargs):
    """
    """

    super(TinyMCE, self).__init__(*args, **kwargs)
    keys = ['mode', 'theme', 'theme_advanced_toolbar_location',
            'theme_advanced_toolbar_align']
    self.mce_settings = dicts.filter(self.mce_settings, keys)

class ReferenceField(forms.CharField):
  """Widget for selecting a reference to an Entity.
  """

  def __init__(self, reference_url, filter=None,
               *args, **kwargs):
    """Initializes the widget with the specified url and filter.
    """

    self.rf = {}
    self.rf['reference_url'] = reference_url
    self.rf['filter'] = filter if filter else []
    super(ReferenceField, self).__init__(*args, **kwargs)

class AgreementField(widgets.Widget):
  """Widget for selecting a reference to an Entity.
  """

  HTML_CODE = """

      %s

  """

  def __init__(self, *args, **kwargs):
    self.text = "No Agreement Text Specified"
    super(AgreementField, self).__init__(*args, **kwargs)

  def render(self, name, value, attrs=None):
    """
    """

    value = self.text.replace('\n', '
')
    result = self.HTML_CODE % value
    return result
<|endoftext|>