示例#1
0
    class TestFieldModel(models.Model):
        title = models.CharField(max_length=200)
        mlist = ListField()
        mlist_default = ListField(default=["a", "b"])
        slist = ListField(ordering=lambda x: x)
        slist_default = ListField(default=["b", "a"], ordering=lambda x: x)
        mdict = DictField()
        mdict_default = DictField(default={"a": "a", 'b': 1})
        mset = SetField()
        mset_default = SetField(default=set(["a", 'b']))

        class MongoMeta:
            index_together = [{'fields': [('title', -1), 'mlist']}]
示例#2
0
    class TestFieldModel(models.Model):
        title = models.CharField(max_length=200)
        mlist = ListField()
        mlist_default = ListField(default=["a", "b"])
        slist = ListField(ordering=lambda x:x)
        slist_default = ListField(default=["b", "a"], ordering=lambda x:x)
        mdict = DictField()
        mdict_default = DictField(default={"a": "a", 'b':1})
        mset = SetField()
        mset_default = SetField(default=set(["a", 'b']))

        class MongoMeta:
            index_together = [{
                                'fields' : [ ('title', False), 'mlist']
                                }]
        def __unicode__(self):
            return "Test special field model: %s" % (self.title)
示例#3
0
class BaseObjectPermission(models.Model):
    permission_set = SetField(models.CharField(max_length=64))

    content_type = models.CharField(max_length=256)
    object_id = models.PositiveIntegerField()

    def get_permissions(self):
        return self.permission_set

    def set_permissions(self, permission_list):
        self.permission_set = permission_list

    permissions = property(get_permissions, set_permissions)

    class Meta:
        abstract = True
示例#4
0
class PmUser(AbstractBaseUser):
    name = models.CharField(max_length=30, blank=False)
    email = models.CharField(unique=True, db_index=True, max_length=255)
    phoneNumber = models.CharField(max_length=20, blank=True)
    isActive = models.BooleanField(default=True)
    type = models.CharField(max_length=10, blank=True)
    is_staff = models.BooleanField(default=False)
    sources = SetField()
    additionalInfo = DictField()
    is_email_subscribed = models.BooleanField(default=False)
    isDeleted = models.BooleanField(default=False)
    createdAt = models.DateTimeField(default=datetime.datetime.now())
    autoLogOutTime = models.IntegerField(default=0)
    USERNAME_FIELD = 'email'

    objects = CustomUserManager()

    def get_full_name(self):
        return self.name

    def get_email(self):
        return self.email

    def get_phone_number(self):
        return self.phoneNumber

    def get_short_name(self):
        return self.email

    @property
    def is_superuser(self):
        return self.is_staff

    def has_perm(self, perm, obj=None):
        return self.is_staff

    def has_module_perms(self, app_label):
        return self.is_staff

    class MongoMeta:
        db_table = 'Users'
        index_together = ["name"]
示例#5
0
文件: models.py 项目: wandesky/oclapi
class ConceptVersion(ConceptValidationMixin, ResourceVersionModel):
    external_id = models.TextField(null=True, blank=True)
    concept_class = models.TextField()
    datatype = models.TextField(null=True, blank=True)
    names = ListField(EmbeddedModelField('LocalizedText'))
    descriptions = ListField(EmbeddedModelField('LocalizedText'), null=True)
    retired = models.BooleanField(default=False)
    root_version = models.ForeignKey('self', null=True, blank=True)
    is_latest_version = models.BooleanField(default=True)
    version_created_by = models.TextField()
    update_comment = models.TextField(null=True, blank=True)
    source_version_ids = SetField()

    class MongoMeta:
        indexes = [[('uri', 1)],
                   [('versioned_object_id', 1), ('is_latest_version', 1),
                    ('created_at', -1)],
                   [('source_version_ids', 1), ('updated_at', -1)]]

    objects = MongoDBManager()

    def clone(self):
        concept_version = ConceptVersion(
            mnemonic='--TEMP--',
            public_access=self.public_access,
            external_id=self.external_id,
            concept_class=self.concept_class,
            datatype=self.datatype,
            names=map(lambda n: n.clone(), self.names),
            retired=self.retired,
            versioned_object_id=self.versioned_object_id,
            versioned_object_type=self.versioned_object_type,
            released=self.released,
            previous_version=self,
            parent_version=self.parent_version,
            root_version=self.root_version,
            is_latest_version=self.is_latest_version,
            extras=self.extras)

        if self.descriptions:
            concept_version.descriptions = map(lambda d: d.clone(),
                                               self.descriptions)
        else:
            concept_version.descriptions = []

        return concept_version

    @property
    def name(self):
        return self.versioned_object.mnemonic

    @property
    def owner(self):
        return self.versioned_object.owner

    @property
    def owner_name(self):
        return self.versioned_object.owner_name

    @property
    def owner_type(self):
        return self.versioned_object.owner_type

    @property
    def owner_url(self):
        return self.versioned_object.owner_url

    @property
    def display_name(self):
        return Concept.get_display_name_for(self)

    @property
    def display_locale(self):
        return Concept.get_display_locale_for(self)

    @property
    def source(self):
        return self.versioned_object.parent

    @property
    def parent_source(self):
        return self.source

    def get_collection_versions(self):
        from collection.models import CollectionVersion
        return CollectionVersion.get_collection_versions_with_concept(self.id)

    @property
    def mappings_url(self):
        concept = self.versioned_object
        source = concept.parent
        owner = source.owner
        owner_kwarg = 'user' if isinstance(owner, User) else 'org'
        return reverse('concept-mapping-list',
                       kwargs={
                           'concept': concept.mnemonic,
                           'source': source.mnemonic,
                           owner_kwarg: owner.mnemonic
                       })

    @property
    def names_for_default_locale(self):
        names = []
        for name in self.names:
            if settings.DEFAULT_LOCALE == name.locale:
                names.append(name.name)
        return names

    @property
    def all_names(self):
        names = []
        for name in self.names:
            names.append(name.name)
        return names

    @property
    def descriptions_for_default_locale(self):
        descriptions = []
        if self.descriptions:
            for desc in self.descriptions:
                if settings.DEFAULT_LOCALE == desc.locale:
                    descriptions.append(desc.name)
        return descriptions

    @property
    def is_root_version(self):
        return self == self.root_version

    @property
    def public_can_view(self):
        return self.source.public_access in [
            ACCESS_TYPE_EDIT, ACCESS_TYPE_VIEW
        ]

    def get_empty_mappings(self):
        return self.versioned_object.get_empty_mappings()

    def get_unidirectional_mappings(self):
        return self.versioned_object.get_unidirectional_mappings()

    def get_bidirectional_mappings(self):
        return self.versioned_object.get_bidirectional_mappings()

    @classmethod
    def get_latest_version_of(cls, concept):
        versions = ConceptVersion.objects.filter(
            versioned_object_id=concept.id,
            is_latest_version=True).order_by('-created_at')
        return versions[0] if versions else None

    @classmethod
    def get_latest_version_by_id(cls, id):
        versions = ConceptVersion.objects.filter(
            versioned_object_id=id,
            is_latest_version=True).order_by('-created_at')
        return versions[0] if versions else None

    @classmethod
    def for_concept(cls,
                    concept,
                    label,
                    previous_version=None,
                    parent_version=None):
        return ConceptVersion(
            mnemonic=label,
            public_access=concept.public_access,
            external_id=concept.external_id,
            concept_class=concept.concept_class,
            datatype=concept.datatype,
            extras=concept.extras,
            names=concept.names,
            descriptions=concept.descriptions,
            retired=concept.retired,
            versioned_object_id=concept.id,
            versioned_object_type=ContentType.objects.get_for_model(Concept),
            released=False,
            previous_version=previous_version,
            parent_version=parent_version,
            version_created_by=concept.created_by,
            created_by=concept.created_by,
            updated_by=concept.updated_by,
        )

    @classmethod
    def diff(cls, v1, v2):
        diffs = {}
        if v1.public_access != v2.public_access:
            diffs['public_access'] = {
                'was': v1.public_access,
                'is': v2.public_access
            }
        if v1.external_id != v2.external_id:
            diffs['external_id'] = {
                'was': v1.external_id,
                'is': v2.external_id
            }
        if v1.concept_class != v2.concept_class:
            diffs['concept_class'] = {
                'was': v1.concept_class,
                'is': v2.concept_class
            }
        if v1.datatype != v2.datatype:
            diffs['datatype'] = {'was': v1.datatype, 'is': v2.datatype}

        # Diff names
        names_diff = cls.diff_in_localized_text_list(v1.names, v2.names)
        if names_diff:
            diffs['names'] = names_diff

        # Diff descriptions
        desc_diff = cls.diff_in_localized_text_list(v1.descriptions,
                                                    v2.descriptions)
        if desc_diff:
            diffs['descriptions'] = desc_diff

            # Diff extras
        extras1 = v1.extras if v1.extras else {}
        extras2 = v2.extras if v2.extras else {}
        diff = len(extras1) != len(extras2)
        if not diff:
            for key in extras1:
                if key not in extras2:
                    diff = True
                    break
                if extras2[key] != extras1[key]:
                    diff = True
                    break
        if diff:
            diffs['extras'] = {'was': extras1, 'is': extras2}

        return diffs

    @classmethod
    def diff_in_localized_text_list(cls, names1, names2):
        if names1 is None or names2 is None:
            return None
        if len(names1) != len(names2):
            return True

        n1 = sorted(names1, key=lambda n: n.name)
        n2 = sorted(names2, key=lambda n: n.name)
        for i, n in enumerate(n1):
            if n.external_id != n2[i].external_id:
                return True
            if n.name != n2[i].name:
                return True
            if n.type != n2[i].type:
                return True
            if n.locale != n2[i].locale:
                return True
            if n.locale_preferred != n2[i].locale_preferred:
                return True

        return False

    @classmethod
    def persist_clone(cls, obj, user=None, **kwargs):
        errors = dict()
        if not user:
            errors[
                'version_created_by'] = 'Must specify which user is attempting to create a new concept version.'
            return errors
        obj.version_created_by = user.username
        previous_version = obj.previous_version
        previous_was_latest = previous_version.is_latest_version and obj.is_latest_version
        source_version = SourceVersion.get_head_of(obj.versioned_object.parent)
        persisted = False
        errored_action = 'saving new concept version'
        try:
            obj.clean()
            obj.save(**kwargs)
            obj.mnemonic = obj.id
            obj.save()

            errored_action = "updating 'is_latest_version' attribute on previous version"
            if previous_was_latest:
                previous_version.is_latest_version = False
                previous_version.save()

            errored_action = 'replacing previous version in latest version of source'
            source_version.update_concept_version(obj)

            # Mark versioned object as updated
            concept = obj.versioned_object
            concept.extras = obj.extras
            concept.names = obj.names
            concept.descriptions = obj.descriptions
            concept.concept_class = obj.concept_class
            concept.datatype = obj.datatype
            concept.save()

            persisted = True
        except ValidationError as err:
            errors.update(err.message_dict)
        finally:
            if not persisted:
                source_version.update_concept_version(obj.previous_version)
                if previous_was_latest:
                    previous_version.is_latest_version = True
                    previous_version.save()
                if obj.id:
                    obj.delete()
                errors['non_field_errors'] = [
                    'An error occurred while %s.' % errored_action
                ]
        return errors

    @classmethod
    def resource_type(cls):
        return VERSION_TYPE

    @classmethod
    def versioned_resource_type(cls):
        return CONCEPT_TYPE

    @staticmethod
    def get_url_kwarg():
        return 'concept_version'
示例#6
0
class MappingVersion(MappingValidationMixin, ResourceVersionModel):
    parent = models.ForeignKey(Source, related_name='mappings_version_from')
    map_type = models.TextField()
    from_concept = models.ForeignKey(Concept,
                                     related_name='mappings_version_from')
    to_concept = models.ForeignKey(Concept,
                                   null=True,
                                   blank=True,
                                   related_name='mappings_version_to')
    to_source = models.ForeignKey(Source,
                                  null=True,
                                  blank=True,
                                  related_name='mappings_version_to')
    to_concept_code = models.TextField(null=True, blank=True)
    to_concept_name = models.TextField(null=True, blank=True)
    retired = models.BooleanField(default=False)
    external_id = models.TextField(null=True, blank=True)
    is_latest_version = models.BooleanField(default=True)
    update_comment = models.TextField(null=True, blank=True)
    source_version_ids = SetField()

    objects = MongoDBManager()

    class MongoMeta:
        indexes = [[('parent', 1), ('map_type', 1), ('from_concept', 1),
                    ('to_concept', 1), ('to_source', 1),
                    ('to_concept_code', 1)],
                   [('parent', 1), ('map_type', 1), ('from_concept', 1),
                    ('to_source', 1), ('to_concept_code', 1),
                    ('to_concept_name', 1)],
                   [('parent', 1), ('from_concept', 1), ('to_concept', 1),
                    ('is_active', 1), ('retired', 1)],
                   [('versioned_object_id', 1), ('is_latest_version', 1),
                    ('created_at', -1)],
                   [('source_version_ids', 1), ('updated_at', -1)]]

    def clone(self):
        return MappingVersion(mnemonic='--TEMP--',
                              parent=self.parent,
                              map_type=self.map_type,
                              from_concept=self.from_concept,
                              to_concept=self.to_concept,
                              to_source=self.to_source,
                              to_concept_code=self.to_concept_code,
                              to_concept_name=self.to_concept_name,
                              retired=self.retired,
                              versioned_object_id=self.versioned_object_id,
                              versioned_object_type=self.versioned_object_type,
                              released=self.released,
                              previous_version=self,
                              parent_version=self.parent_version,
                              is_latest_version=self.is_latest_version,
                              extras=self.extras)

    class Meta:
        pass

    @property
    def source(self):
        return self.parent.mnemonic

    @property
    def parent_source(self):
        return self.parent

    @property
    def owner(self):
        return self.parent.owner_name

    @property
    def owner_type(self):
        return self.parent.owner_type

    @property
    def from_source(self):
        return self.from_concept.parent

    @property
    def from_source_owner(self):
        return self.from_source.owner_name

    @property
    def from_source_owner_mnemonic(self):
        return self.from_source.owner.mnemonic

    @property
    def from_source_owner_type(self):
        return self.from_source.owner_type

    @property
    def from_source_name(self):
        return self.from_source.mnemonic

    @property
    def from_source_url(self):
        return self.from_source.url

    @property
    def from_source_shorthand(self):
        return "%s:%s" % (self.from_source_owner_mnemonic,
                          self.from_source_name)

    @property
    def from_concept_code(self):
        return self.from_concept.mnemonic

    @property
    def from_concept_name(self):
        return self.from_concept.display_name

    @property
    def from_concept_url(self):
        return self.from_concept.url

    @property
    def from_concept_shorthand(self):
        return "%s:%s" % (self.from_source_shorthand, self.from_concept_code)

    def get_to_source(self):
        return self.to_source or self.to_concept and self.to_concept.parent

    @property
    def to_source_name(self):
        return self.get_to_source() and self.get_to_source().mnemonic

    @property
    def to_source_url(self):
        to_source = self.get_to_source()
        return to_source.url if to_source else None

    @property
    def to_mapping_url(self):
        return self.versioned_object.uri

    @property
    def to_source_owner(self):
        return self.get_to_source() and unicode(self.get_to_source().parent)

    @property
    def to_source_owner_mnemonic(self):
        return self.get_to_source() and self.get_to_source().owner.mnemonic

    @property
    def to_source_owner_type(self):
        return self.get_to_source() and self.get_to_source().owner_type

    @property
    def to_source_shorthand(self):
        return self.get_to_source() and "%s:%s" % (
            self.to_source_owner_mnemonic, self.to_source_name)

    def get_to_concept_name(self):
        return self.to_concept_name or (self.to_concept
                                        and self.to_concept.display_name)

    def get_to_concept_code(self):
        return self.to_concept_code or (self.to_concept
                                        and self.to_concept.mnemonic)

    @property
    def to_concept_url(self):
        return self.to_concept.url if self.to_concept else None

    @property
    def to_concept_shorthand(self):
        return "%s:%s" % (self.to_source_shorthand, self.get_to_concept_code())

    @property
    def public_can_view(self):
        return self.public_access in [ACCESS_TYPE_EDIT, ACCESS_TYPE_VIEW]

    @staticmethod
    def resource_type():
        return MAPPING_VERSION_RESOURCE_TYPE

    @property
    def collection_versions(self):
        return get_model('collection',
                         'CollectionVersion').objects.filter(mappings=self.id)

    @staticmethod
    def get_url_kwarg():
        return 'mapping_version'

    @classmethod
    def for_mapping(cls, mapping, previous_version=None, parent_version=None):
        return MappingVersion(
            public_access=mapping.public_access,
            is_active=True,
            parent=mapping.parent,
            map_type=mapping.map_type,
            from_concept=mapping.from_concept,
            to_concept=mapping.to_concept,
            to_source=mapping.to_source,
            to_concept_code=mapping.to_concept_code,
            to_concept_name=mapping.to_concept_name,
            retired=mapping.retired,
            external_id=mapping.external_id,
            versioned_object_id=mapping.id,
            versioned_object_type=ContentType.objects.get_for_model(Mapping),
            released=False,
            previous_version=previous_version,
            parent_version=parent_version,
            created_by=mapping.created_by,
            updated_by=mapping.updated_by)

    @classmethod
    def get_latest_version_by_id(cls, id):
        versions = MappingVersion.objects.filter(
            versioned_object_id=id,
            is_latest_version=True).order_by('-created_at')
        return versions[0] if versions else None

    @classmethod
    def persist_clone(cls, obj, user=None, prev_latest_version=None, **kwargs):
        errors = dict()
        if not user:
            errors[
                'version_created_by'] = 'Must specify which user is attempting to create a new concept version.'
            return errors
        obj.version_created_by = user.username
        previous_version = obj.previous_version
        previous_was_latest = previous_version.is_latest_version and obj.is_latest_version
        source_version = SourceVersion.get_head_of(obj.versioned_object.parent)

        persisted = False
        errored_action = 'saving new mapping version'
        try:
            obj.save(**kwargs)
            obj.mnemonic = int(prev_latest_version.mnemonic) + 1
            obj.save()

            errored_action = "updating 'is_latest_version' attribute on previous version"
            if previous_was_latest:
                previous_version.is_latest_version = False
                previous_version.save()

            errored_action = 'replacing previous version in latest version of source'
            source_version.update_mapping_version(obj)

            # Mark versioned object as updated
            mapping = obj.versioned_object
            mapping.save()

            persisted = True
        finally:
            if not persisted:
                source_version.update_mapping_version(obj.previous_version)
                if previous_was_latest:
                    previous_version.is_latest_version = True
                    previous_version.save()
                if obj.id:
                    obj.delete()
                errors['non_field_errors'] = [
                    'An error occurred while %s.' % errored_action
                ]
        return errors
示例#7
0
class Service(models.Model):
    SLUG_RE = re.compile(r'^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])$')
    slug = models.SlugField(unique=True, db_index=True)
    label = models.CharField(max_length=255)
    backend = models.ForeignKey(Backend, null=True)
    params = models.TextField()
    owners = SetField(models.ForeignKey(User))
    if use_ancestor:
        key = DbKeyField(primary_key=True)

    @classmethod
    def validate_slug(cls, slug):
        return cls.SLUG_RE.search(slug)

    @classmethod
    def split_request_host(cls, request):
        host = request.META['HTTP_HOST']
        pieces = host.split('.', 1)
        if not cls.validate_slug(pieces[0]):
            raise Http404
        if len(pieces) < 2:
            pieces.append('')
        else:
            pieces[1] = '.' + pieces[1]
        return tuple(pieces)

    @classmethod
    def get_from_request(cls, request):
        return cls.objects.get(slug=cls.split_request_host(request)[0])

    @classmethod
    def new_from_request(cls, request):
        return cls(slug=cls.split_request_host(request)[0])

    @classmethod
    def is_creation_allowed(cls, request):
        slug = cls.split_request_host(request)[0]
        if not cls.validate_slug(slug):
            return False
        pattern = getattr(settings, 'MULTITREEHOLE_SERVICE_SLUG_DISALLOWED', None)
        if pattern is None:
            return True
        return not re.search(pattern, slug)

    @classmethod
    def build_host(cls, slug, request):
        return slug + cls.split_request_host(request)[1]

    def get_host(self, request):
        return self.build_host(self.slug, request)

    def get_params(self):
        if not hasattr(self, 'params_data'):
            self.params_data = json.loads(self.params)
        return self.params_data

    def check_access(self, request, text=None):
        '''
        This method returns three values.

        The first is access level:
        * If text is set, returns 'accept', 'moderate', 'throttle' or 'reject'.
        * If text is not set, returns 'accept', 'throttle' or 'reject'.

        The second is user identifier as a string.
        Usually this is user IP with last bits cleared.

        The third is a "confirm" function. Call it after a message is placed
        to confirm access (for throttling).
        '''
        for access in self.get_params().get('access', []):
            access_level, user_identifier, confirm = self.match_access(access, request)
            if access_level != 'reject':
                if text is None or access_level == 'throttle':
                    return access_level, user_identifier, confirm
                else:
                    if 'reject' in access:
                        reject_re = re.compile(access['reject'])
                        if reject_re.search(text):
                            return 'reject', user_identifier, confirm
                    if 'moderate' in access:
                        moderate_re = re.compile(access['moderate'])
                        if moderate_re.search(text):
                            return 'moderate', user_identifier, confirm
                    # access_level should be 'accept' here.
                    return access_level, user_identifier, confirm
        return 'reject', None, lambda obj: True

    def match_access(self, access, request):
        '''
        Returns 'accept', 'throttle' or 'reject',
        plus the user identifier mentioned above.
        '''
        from datetime import datetime, timedelta
        user_identifier = self.extract_user_identifier(access, request)
        confirm = lambda obj: True
        if user_identifier:
            throttle = access.get('throttle')
            if throttle:
                delta = timedelta(seconds=throttle)
                threshold = datetime.now() - delta
                def confirm(obj=None):
                    try:
                        existing = Message.filter_service(self).get(
                            user_identifier=user_identifier,
                            timestamp__gt=threshold,
                        )
                    except ObjectDoesNotExist:
                        if obj:
                            # Shouldn't happen
                            raise Exception('Expected message object is missing when confirming throttling')
                        else:
                            return True
                    except MultipleObjectsReturned:
                        return False
                    # existing is returned
                    if obj:
                        if existing != obj:
                            raise Exception('Expected message object is not returned when confirming throttling')
                        else:
                            return True
                    else:
                        return False
                if not confirm():
                    return 'throttle', user_identifier, confirm
            return 'accept', user_identifier, confirm
        return 'reject', user_identifier, confirm

    def extract_user_identifier(self, access, request):
        import ipaddr
        try:
            network = ipaddr.IPNetwork(access.get('network'))
        except ValueError:
            network = None
        address = ipaddr.IPAddress(request.META['REMOTE_ADDR'])
        if network and address in network:
            subnet = ipaddr.IPNetwork(address).supernet(access.get('suffixlen', 0))
            return str(subnet.network)
        return None

    def is_owner(self, user):
        # Must be request.user.pk
        return user.pk in self.owners or user.is_superuser

    def __unicode__(self):
        return self.label
示例#8
0
class ConceptContainerVersionModel(ResourceVersionModel):
    name = models.TextField()
    full_name = models.TextField(null=True, blank=True)
    default_locale = models.TextField(default=Common.DEFAULT_LOCALE,
                                      blank=True)
    supported_locales = ListField(null=True, blank=True)
    website = models.TextField(null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    version_external_id = models.TextField(null=True, blank=True)
    external_id = models.TextField(null=True, blank=True)
    _background_process_ids = SetField()

    # Used to skip saving _background_process_ids,
    # which is updated using atomic raw queries, see https://stackoverflow.com/a/33225984
    default_save_fields = None

    def __init__(self, *args, **kwargs):
        super(ConceptContainerVersionModel, self).__init__(*args, **kwargs)
        if self.default_save_fields is None:
            # This block should only get called for the first object loaded
            default_save_fields = {
                f.name
                for f in self._meta.fields if not f.auto_created
            }
            default_save_fields.difference_update({
                '_background_process_ids',
            })
            self.__class__.default_save_fields = tuple(default_save_fields)

    def save(self, **kwargs):
        if self.id is not None and 'update_fields' not in kwargs:
            # If self.id is None (meaning the object has yet to be saved)
            # then do a normal update with all fields.
            # Otherwise, make sure `update_fields` is in kwargs.
            kwargs['update_fields'] = self.default_save_fields
        super(ConceptContainerVersionModel, self).save(**kwargs)

    class Meta(ResourceVersionModel.Meta):
        abstract = True

    @property
    def owner(self):
        return self.versioned_object.owner

    @property
    def owner_name(self):
        return self.versioned_object.owner_name

    @property
    def owner_type(self):
        return self.versioned_object.owner_type

    @property
    def owner_url(self):
        return self.versioned_object.owner_url

    @property
    def parent_resource(self):
        return self.versioned_object.parent_resource

    @property
    def parent_resource_type(self):
        return self.versioned_object.parent_resource_type

    @property
    def parent_url(self):
        return self.versioned_object.parent_url

    @staticmethod
    def get_url_kwarg():
        return 'version'

    @classmethod
    def get_latest_released_version_of(cls, versioned_object):
        versions = versioned_object.get_version_model().objects.filter(
            versioned_object_id=versioned_object.id,
            is_active=True,
            released=True,
            retired=False).order_by('-created_at')
        return versions[0] if versions else None

    @classmethod
    def persist_new(cls, obj, user=None, **kwargs):
        obj.is_active = True
        if user:
            obj.created_by = user
            obj.updated_by = user
        kwargs['seed_concepts'] = True
        kwargs['seed_mappings'] = True
        return cls.persist_changes(obj, **kwargs)

    def update_version_data(self, obj=None):
        pass

    @classmethod
    def persist_changes(cls, obj, **kwargs):
        errors = dict()

        # Ensure versioned object specified
        versioned_object = kwargs.pop('versioned_object', obj.versioned_object)
        if versioned_object is None:
            errors['non_field_errors'] = ['Must specify a versioned object.']
            return errors
        obj.versioned_object = versioned_object

        # Ensure mnemonic does not conflict with existing
        old_mnemonic = obj.mnemonic
        mnemonic = kwargs.pop('mnemonic', obj.mnemonic)
        if mnemonic != old_mnemonic:
            if cls.objects.filter(versioned_object_id=versioned_object.id,
                                  mnemonic=obj.mnemonic).exists():
                errors['mnemonic'] = [
                    "Version with mnemonic %s already exists for %s %s." %
                    (obj.mnemonic, cls.name, versioned_object.mnemonic)
                ]
                return errors
        obj.mnemonic = mnemonic

        # Ensure previous version is valid
        if hasattr(obj, '_previous_version_mnemonic'
                   ) and obj._previous_version_mnemonic:
            previous_version_queryset = cls.objects.filter(
                versioned_object_id=versioned_object.id,
                mnemonic=obj._previous_version_mnemonic)
            if not previous_version_queryset.exists():
                errors['previousVersion'] = [
                    "Previous version %s does not exist." %
                    obj._previous_version_mnemonic
                ]
            elif obj.mnemonic == obj._previous_version_mnemonic:
                errors['previousVersion'] = [
                    "Previous version cannot be the same as current version."
                ]
            else:
                obj.previous_version = previous_version_queryset[0]
                del obj._previous_version_mnemonic

        # Ensure parent version is valid
        if hasattr(
                obj,
                '_parent_version_mnemonic') and obj._parent_version_mnemonic:
            parent_version_queryset = cls.objects.filter(
                versioned_object_id=versioned_object.id,
                mnemonic=obj._parent_version_mnemonic)
            if not parent_version_queryset.exists():
                errors['parentVersion'] = [
                    "Parent version %s does not exist." %
                    obj._parent_version_mnemonic
                ]
            elif obj.mnemonic == obj._parent_version_mnemonic:
                errors['parentVersion'] = [
                    "Parent version cannot be the same as current version."
                ]
            else:
                obj.parent_version = parent_version_queryset[0]
                del obj._parent_version_mnemonic

        # If there are errors at this point, fall out before doing any more work
        if errors:
            return errors

        # Seed mappings from another version, if requested
        seed_references = kwargs.pop('seed_references', False)
        if seed_references:
            obj.seed_references()

        obj.update_version_data()

        try:
            persisted = False
            seed_concepts = kwargs.pop('seed_concepts', False)
            seed_mappings = kwargs.pop('seed_mappings', False)

            obj.save(**kwargs)

            # Seed concepts from another version, if requested
            if seed_concepts:
                obj.seed_concepts()

            # Seed mappings from another version, if requested
            if seed_mappings:
                obj.seed_mappings()

            persisted = True
        finally:
            if not persisted:
                errors['non_field_errors'] = [
                    "Encountered an error while updating version."
                ]
        return errors

    def add_processing(self, process_id):
        if self.id:
            # Using raw query to atomically add item to the list
            self.__class__.objects.raw_update(
                {'_id': ObjectId(self.id)},
                {'$push': {
                    '_background_process_ids': process_id
                }})
        # Update the current object
        self._background_process_ids.add(process_id)

    def remove_processing(self, process_id):
        if self.id:
            # Using raw query to atomically remove item from the list
            self.__class__.objects.raw_update(
                {'_id': ObjectId(self.id)},
                {'$pull': {
                    '_background_process_ids': process_id
                }})
        # Update the current object
        self._background_process_ids.remove(process_id)

    @property
    def is_processing(self):
        if self._background_process_ids:
            for process_id in tuple(self._background_process_ids):
                res = AsyncResult(process_id)
                if (res.successful() or res.failed()):
                    self.remove_processing(process_id)
                else:
                    return True
        if self._background_process_ids:
            return True
        else:
            return False

    def clear_processing(self):
        self._background_process_ids = set()
        self.save(update_fields=['_background_process_ids'])

    @staticmethod
    def clear_all_processing(type):
        type.objects.all().update(_background_process_ids=set())
示例#9
0
文件: models.py 项目: pgcd/a3-mongo
class Topic(models.Model):
    homepage = models.BooleanField(db_index=True)
    hidden = models.BooleanField()
    deleted = models.BooleanField()
    tags = SetField(db_index=True)
    obj = EmbeddedModelField()
    objects = TopicManager()
    views_count = models.PositiveIntegerField(default=0)
    replies_count = models.PositiveIntegerField(default=0)
    rating = models.IntegerField(default=0)
    timeshift = models.IntegerField(default=0) #Mostly used for bookkeeping, but might be useful later
    timestamp = models.PositiveIntegerField(default=0, db_index=True)


    def __init__(self, *args, **kwargs):
        super(Topic, self).__init__(*args, **kwargs)


    @property
    def title(self):
        return self.obj.title or self.pk

    @property
    def body(self):
        return self.obj.body

    def save(self, *args, **kwargs):
        if not self.timestamp:
            self.timestamp = int(time.mktime(datetime.datetime.now().timetuple()))
#        self.addToUserTopics() #The data transfer is massive so the benefit of this is slim to negative.
        super(Topic, self).save(*args, **kwargs)


    def updateRepliesCount(self):
        replies_count = self.replies.count()
        Topic.objects.raw_update({"_id": ObjectId(self.pk)}, {"$set": {"replies_count": replies_count}})
        return replies_count

    def addToUserTopics(self):
        try:
            Profile.objects.raw_update(
                {"user_id": ObjectId(self.obj.user.pk)},
                {"$addToSet": {"topics": self.pk}, })
        except AttributeError:
            #If the obj has no user attribute (it's not a Post, for instance)
            pass
        return self

    def adjustRating(self, rating=0):
        Topic.objects.raw_update({"_id": ObjectId(self.pk)}, {"$inc": {"rating": rating}})
        return self

    def tag(self, tagname):
        self.tags.add(tagname)
        return Tag.objects.create_or_update_count(tagname, self)

    def __unicode__(self):
        return self.title

    @permalink
    def get_absolute_url(self):
        return 'board_topic_view', (self.pk,), {}

    class Meta:
        ordering = ['-timestamp']