Esempio n. 1
0
    def base_manager(self):
        base_manager_name = self.base_manager_name
        if not base_manager_name:
            # Get the first parent's base_manager_name if there's one.
            for parent in self.model.mro()[1:]:
                if hasattr(parent, '_meta'):
                    if parent._base_manager.name != '_base_manager':
                        base_manager_name = parent._base_manager.name
                    break

        if base_manager_name:
            try:
                return self.managers_map[base_manager_name]
            except KeyError:
                raise ValueError(
                    "%s has no manager named %r" % (
                        self.object_name,
                        base_manager_name,
                    )
                )

        manager = Manager()
        manager.name = '_base_manager'
        manager.model = self.model
        manager.auto_created = True
        return manager
Esempio n. 2
0
def manager_class(model, queryset_class=None, class_name=None,
                  use_for_related_fields=False):
    """
    Return the manager class for model.

    If an optional queryset is given, returns a new class using the
    Manager.from_queryset() API.
    """

    for cls in model.mro():
        if not issubclass(model, Model):
            continue
        try:
            mgm = cls.objects
            break
        except AttributeError:
            pass
    else:
        mgm = Manager()

    if not isinstance(mgm, BaseManager):
        raise TypeError('unexpected manager class: %s' %
                        mgm.__class__.__name__)

    if queryset_class is not None:
        mgm = mgm.from_queryset(queryset_class, class_name=class_name)

    if use_for_related_fields:
        mgm.use_for_related_fields = True

    return mgm
Esempio n. 3
0
 def test_consider_real_django_fields_only(self):
     id_ = ModelWithImpostorField._meta.get_field('id')
     with patch.object(mommy.Mommy, 'get_fields') as mock:
         f = Manager()
         f.name = 'foo'
         mock.return_value = [id_, f]
         try:
             mommy.make(ModelWithImpostorField)
         except TypeError:
             self.fail('TypeError raised')
Esempio n. 4
0
 def test_consider_real_django_fields_only(self):
     id_ = models.ModelWithImpostorField._meta.get_field("id")
     with patch.object(mommy.Mommy, "get_fields") as mock:
         f = Manager()
         f.name = "foo"
         mock.return_value = [id_, f]
         try:
             mommy.make(models.ModelWithImpostorField)
         except TypeError:
             self.fail("TypeError raised")
Esempio n. 5
0
    def base_manager(self):
        base_manager_name = self.base_manager_name
        if not base_manager_name:
            # Get the first parent's base_manager_name if there's one.
            for parent in self.model.mro()[1:]:
                if hasattr(parent, '_meta'):
                    if parent._base_manager.name != '_base_manager':
                        base_manager_name = parent._base_manager.name
                    break

        if base_manager_name:
            try:
                return self.managers_map[base_manager_name]
            except KeyError:
                raise ValueError(
                    "%s has no manager named %r" % (
                        self.object_name,
                        base_manager_name,
                    )
                )

        # Deprecation shim for `use_for_related_fields`.
        for i, base_manager_class in enumerate(self.default_manager.__class__.mro()):
            if getattr(base_manager_class, 'use_for_related_fields', False):
                if not getattr(base_manager_class, 'silence_use_for_related_fields_deprecation', False):
                    warnings.warn(
                        "use_for_related_fields is deprecated, instead "
                        "set Meta.base_manager_name on '{}'.".format(self.model._meta.label),
                        RemovedInDjango20Warning, 2
                    )

                if i == 0:
                    manager = self.default_manager
                else:
                    manager = base_manager_class()
                    manager.name = '_base_manager'
                    manager.model = self.model

                return manager

        manager = Manager()
        manager.name = '_base_manager'
        manager.model = self.model
        manager.auto_created = True
        return manager
Esempio n. 6
0
        :type permission: str

        This method only works with permissions that are defined in
        :data:`~bridgekeeper.perms`;
        regular Django row-level permission checkers can't be invoked on
        the QuerySet level.

        It is a convenience wrapper around
        :meth:`~bridgekeeper.rules.Rule.filter`.
        """

        try:
            rule = self.__permission_map[permission]
        except KeyError:
            raise ValueError("Permission {} does not exist, or is not "
                             "registered in Bridgekeeper".format(permission))
        return rule.filter(user, self)


#: Django model manager using :class:`PermissionQuerySet`.
#:
#: For easy access to :class:`PermissionQuerySet` on your models,
#: assign this manager to the ``objects`` property::
#:
#:     class MyModel(models.Model):
#:         ...  # your fields here
#:
#:         objects = PermissionManager()
PermissionManager = Manager.from_queryset(PermissionQuerySet,
                                          class_name="PermissionManager")
Esempio n. 7
0
class RobotManager(Manager.from_queryset(RobotQuerySet)):
    pass
Esempio n. 8
0
 class WrongActiveModel(models.ActiveModel):
     objects = Manager()
Esempio n. 9
0
# Closest equivalent to SUM in Django
from django.db.models import Manager
result = Manager.raw(
    u"""select SUM(royalty_price*conversion_to_usd)from sales_raw where date='2012-06-01'"""
)
Esempio n. 10
0
class Profile(Model):
    user = FK(to=User, related_name='profiles', on_delete=CASCADE, default=1)
    status = CharField(max_length=50, choices=STATUS, default='npc')
    is_alive = BooleanField(default=True)
    is_active = BooleanField(default=True)
    image = ImageField(
        default='profile_pics/profile_default.jpg',
        upload_to='profile_pics',
        blank=True,
        null=True,
        storage=ReplaceFileStorage(),
    )
    # Character name copied from Character (by signal) to avoid queries
    character_name_copy = CharField(max_length=100, blank=True, null=True)

    objects = Manager()
    non_gm = NonGMProfileManager()
    gm_controlled = GMControlledProfileManager()
    players = PlayerProfileManager()
    active_players = ActivePlayerProfileManager()
    npcs = NPCProfileManager()
    living = LivingProfileManager()
    contactables = ContactableProfileManager()

    class Meta:
        ordering = ['-status', '-is_active', 'character_name_copy']

    def __str__(self):
        return self.character_name_copy or self.user.username

    def save(self, *args, **kwargs):
        first_save = True if not self.pk else False
        super().save(*args, **kwargs)
        if first_save and self.image:
            img = Image.open(self.image.path)
            if img.height > 300 or img.width > 300:
                output_size = (300, 300)
                img.thumbnail(output_size)
                img.save(self.image.path)

    def characters_all_known_annotated_if_indirectly(self):
        from prosoponomikon.models import Character
        if self.can_view_all:
            qs = Character.objects.all()
        else:
            known_dir = self.characters_known_directly.all()
            known_indir = self.characters_known_indirectly.all()
            known_only_indir = known_indir.exclude(id__in=known_dir)
            all_known = (known_dir | known_indir).distinct()
            qs = all_known.annotate(only_indirectly=Case(
                When(id__in=known_only_indir, then=Value(1)),
                default=Value(0),
                output_field=IntegerField(),
            ))
        qs = qs.prefetch_related('known_directly', 'known_indirectly')
        qs = qs.select_related('profile')
        qs = qs.exclude(id=self.character.id)
        return qs

    def locations_all_known_annotated_if_indirectly(self):
        if self.can_view_all:
            from toponomikon.models import Location
            qs = Location.objects.all()
        else:
            known_dir = self.locs_known_directly.all()
            known_indir = self.locs_known_indirectly.all()
            known_only_indir = known_indir.exclude(id__in=known_dir)
            all_known = (known_dir | known_indir).distinct()
            qs = all_known.annotate(only_indirectly=Case(
                When(id__in=known_only_indir, then=Value(1)),
                default=Value(0),
                output_field=IntegerField(),
            ))
        qs = qs.prefetch_related('known_directly', 'known_indirectly')
        qs = qs.select_related('main_image__image')
        return qs

    def characters_groups_authored_with_characters(self):
        characters = self.characters_all_known_annotated_if_indirectly()
        character_groups = self.character_groups_authored.all()
        character_groups = character_groups.prefetch_related(
            Prefetch('characters', queryset=characters),
            'characters__profile__user', 'characters__known_directly',
            'characters__known_indirectly', 'characters__first_name')
        return character_groups

    def skills_acquired_with_skill_levels(self):
        from rules.models import Skill, SkillLevel
        skills = Skill.objects.filter(skill_levels__acquired_by=self)
        skill_levels = SkillLevel.objects.filter(acquired_by=self)
        skills = skills.prefetch_related(
            Prefetch('skill_levels', queryset=skill_levels))
        return skills.distinct()

    @property
    def undone_demands(self):
        demands = self.received_demands.exclude(author=self)
        return demands.exclude(is_done=True)

    @property
    def unseen_announcements(self):
        from communications.models import Announcement, Statement
        unseen_statements = Statement.objects.exclude(seen_by=self)
        return Announcement.objects.filter(known_directly=self,
                                           statements__in=unseen_statements)

    @property
    def unseen_debates(self):
        from communications.models import Statement, Debate
        unseen_remarks = Statement.objects.exclude(seen_by=self)
        return Debate.objects.filter(known_directly=self,
                                     statements__in=unseen_remarks).distinct()

    @property
    def can_view_all(self):
        return self.status in ['gm', 'spectator']

    @property
    def can_action(self):
        return self.status in ['gm', 'player']
Esempio n. 11
0
# Closest equivalent to SUM in Django
from django.db.models import Manager

result = Manager.raw(u"""select SUM(royalty_price*conversion_to_usd)from sales_raw where date='2012-06-01'""")
Esempio n. 12
0
class RawMasterMixin(Model):
    """Base class for MasterMixin. **Users shouldn't use this
    class directly.**"""

    CQRS_ID = None
    """Unique CQRS identifier for all microservices."""

    CQRS_PRODUCE = True
    """If false, no cqrs data is sent through the transport."""

    CQRS_FIELDS = ALL_BASIC_FIELDS
    """
    List of fields to include in the CQRS payload.
    You can also set the fields attribute to the special value '__all__'
    to indicate that all fields in the model should be used.
    """

    CQRS_SERIALIZER = None
    """
    Optional serializer used to create the instance representation.
    Must be expressed as a module dotted path string like
    `mymodule.serializers.MasterModelSerializer`.
    """

    CQRS_TRACKED_FIELDS = None
    """
    List of fields of the main model for which you want to track the changes
    and send the previous values via transport. You can also set the field
    attribute to the special value "__all__" to indicate that all fields in
    the model must be used.
    """

    objects = Manager()

    cqrs = MasterManager()
    """Manager that adds needed CQRS queryset methods."""

    cqrs_revision = IntegerField(
        default=0,
        help_text="This field must be incremented on any model update. "
        "It's used to for CQRS sync.",
    )
    cqrs_updated = DateTimeField(
        auto_now=True,
        help_text="This field must be incremented on every model update. "
        "It's used to for CQRS sync.",
    )

    class Meta:
        abstract = True

    @property
    def cqrs_saves_count(self):
        """Shows how many times this instance has been saved within the transaction."""
        return getattr(self, '_cqrs_saves_count', 0)

    @property
    def is_initial_cqrs_save(self):
        """This flag is used to check if instance has already been registered for CQRS update."""
        return self.cqrs_saves_count < 2

    def reset_cqrs_saves_count(self):
        """This method is used to automatically reset instance CQRS counters on transaction commit.
        But this can also be used to control custom behaviour within transaction
        or in case of rollback,
        when several sequential transactions are used to change the same instance.
        """
        if hasattr(self, '_cqrs_saves_count'):
            self._cqrs_saves_count = 0

    def save(self, *args, **kwargs):
        using = kwargs.get('using') or router.db_for_write(self.__class__,
                                                           instance=self)
        connection = transaction.get_connection(using)
        if connection.in_atomic_block:
            _cqrs_saves_count = self.cqrs_saves_count
            self._cqrs_saves_count = _cqrs_saves_count + 1
        else:
            self.reset_cqrs_saves_count()

        if self.is_initial_cqrs_save and (not self._state.adding):
            self.cqrs_revision = F('cqrs_revision') + 1

        self._save_tracked_fields()

        return super(RawMasterMixin, self).save(*args, **kwargs)

    def _save_tracked_fields(self):
        if hasattr(self, FIELDS_TRACKER_FIELD_NAME):
            tracker = getattr(self, FIELDS_TRACKER_FIELD_NAME)
            setattr(self, TRACKED_FIELDS_ATTR_NAME, tracker.changed())

    def to_cqrs_dict(self, using=None, sync=False):
        """CQRS serialization for transport payload.

        :param using: The using argument can be used to force the database
                      to use, defaults to None
        :type using: str, optional
        :type sync: bool, optional
        :return: The serialized instance data.
        :rtype: dict
        """
        if self.CQRS_SERIALIZER:
            data = self._class_serialization(using, sync=sync)
        else:
            self._refresh_f_expr_values(using)
            data = self._common_serialization(using)
        return data

    def get_tracked_fields_data(self):
        """CQRS serialization for tracked fields to include
        in the transport payload.

        :return: Previous values for tracked fields.
        :rtype: dict
        """
        return getattr(self, TRACKED_FIELDS_ATTR_NAME, None)

    def cqrs_sync(self, using=None, queue=None):
        """Manual instance synchronization.

        :param using: The using argument can be used to force the database
                      to use, defaults to None
        :type using: str, optional
        :param queue: Syncing can be executed just for a single queue, defaults to None
                      (all queues)
        :type queue: str, optional
        :return: True if instance can be synced, False otherwise.
        :rtype: bool
        """
        if self._state.adding:
            return False

        if not self.CQRS_SERIALIZER:
            try:
                self.refresh_from_db()
            except self._meta.model.DoesNotExist:
                return False

        MasterSignals.post_save(
            self._meta.model,
            instance=self,
            using=using,
            queue=queue,
            sync=True,
        )
        return True

    def is_sync_instance(self):
        """
        This method can be overridden to apply syncing only to instances by some rules.
        For example, only objects with special status or after some creation date, etc.

        :return: True if this instance needs to be synced, False otherwise
        :rtype: bool
        """
        return True

    @classmethod
    def relate_cqrs_serialization(cls, queryset):
        """
        This method shoud be overriden to optimize database access
        for example using `select_related` and `prefetch_related`
        when related models must be included into the master model
        representation.

        :param queryset: The initial queryset.
        :type queryset: django.db.models.QuerySet
        :return: The optimized queryset.
        :rtype: django.db.models.QuerySet
        """
        return queryset

    @classmethod
    def call_post_bulk_create(cls, instances, using=None):
        """ Post bulk create signal caller (django doesn't support it by default).

        .. code-block:: python

            # On PostgreSQL
            instances = model.objects.bulk_create(instances)
            model.call_post_bulk_create(instances)
        """
        post_bulk_create.send(cls, instances=instances, using=using)

    @classmethod
    def call_post_update(cls, instances, using=None):
        """ Post bulk update signal caller (django doesn't support it by default).

        .. code-block:: python

            # Used automatically by cqrs.bulk_update()
            qs = model.objects.filter(k1=v1)
            model.cqrs.bulk_update(qs, k2=v2)
        """
        post_update.send(cls, instances=instances, using=using)

    def _common_serialization(self, using):
        opts = self._meta

        if isinstance(self.CQRS_FIELDS,
                      str) and self.CQRS_FIELDS == ALL_BASIC_FIELDS:
            included_fields = None
        else:
            included_fields = self.CQRS_FIELDS

        data = {}
        for f in opts.fields:
            if included_fields and (f.name not in included_fields):
                continue

            value = f.value_from_object(self)
            if value is not None and isinstance(f, (DateField, DateTimeField)):
                value = str(value)

            data[f.name] = value

        # We need to include additional fields for synchronisation, f.e. to prevent de-duplication
        data['cqrs_revision'] = self.cqrs_revision
        data['cqrs_updated'] = str(self.cqrs_updated)

        return data

    def _class_serialization(self, using, sync=False):
        if sync:
            instance = self
        else:
            db = using if using is not None else self._state.db
            qs = self.__class__._default_manager.using(db).filter(pk=self.pk)

            instance = self.relate_cqrs_serialization(qs).first()
            if not instance:
                raise RuntimeError(
                    "Couldn't serialize CQRS class ({}).".format(self.CQRS_ID))

        data = self._cqrs_serializer_cls(instance).data
        data['cqrs_revision'] = instance.cqrs_revision
        data['cqrs_updated'] = str(instance.cqrs_updated)

        return data

    def _refresh_f_expr_values(self, using):
        opts = self._meta
        fields_to_refresh = []
        if isinstance(self.cqrs_revision, CombinedExpression):
            fields_to_refresh.append('cqrs_revision')

        if isinstance(self.CQRS_FIELDS,
                      str) and self.CQRS_FIELDS == ALL_BASIC_FIELDS:
            included_fields = None
        else:
            included_fields = self.CQRS_FIELDS

        for f in opts.fields:
            if included_fields and (f.name not in included_fields):
                continue

            value = f.value_from_object(self)

            if value is not None and isinstance(value, CombinedExpression):
                fields_to_refresh.append(f.name)

        if fields_to_refresh:
            self.refresh_from_db(fields=fields_to_refresh)

    @property
    def _cqrs_serializer_cls(self):
        """ Serialization class loader. """
        if hasattr(self.__class__, '_cqrs_serializer_class'):
            return self.__class__._cqrs_serializer_class

        try:
            serializer = import_string(self.CQRS_SERIALIZER)
            self.__class__._cqrs_serializer_class = serializer
            return serializer
        except ImportError:
            raise ImportError(
                "Model {}: CQRS_SERIALIZER can't be imported.".format(
                    self.__class__))

    def get_custom_cqrs_delete_data(self):
        """ This method should be overridden when additional data is needed in DELETE payload. """
        pass
Esempio n. 13
0
class Unit(models.Model):
    id = models.IntegerField(primary_key=True)

    public = models.BooleanField(null=False, default=True)

    location = models.PointField(null=True, srid=PROJECTION_SRID)  # lat, lng?
    geometry = models.GeometryField(srid=PROJECTION_SRID, null=True)
    department = models.ForeignKey(Department,
                                   null=True,
                                   on_delete=models.CASCADE)
    root_department = models.ForeignKey(Department,
                                        null=True,
                                        related_name='descendant_units',
                                        on_delete=models.CASCADE)

    organizer_type = models.PositiveSmallIntegerField(choices=ORGANIZER_TYPES,
                                                      null=True)
    organizer_name = models.CharField(max_length=150, null=True)
    organizer_business_id = models.CharField(max_length=10, null=True)

    provider_type = models.PositiveSmallIntegerField(choices=PROVIDER_TYPES,
                                                     null=True)
    contract_type = models.PositiveSmallIntegerField(choices=CONTRACT_TYPES,
                                                     null=True)

    picture_url = models.URLField(max_length=250, null=True)
    picture_entrance_url = models.URLField(max_length=500, null=True)
    streetview_entrance_url = models.URLField(max_length=500, null=True)

    description = models.TextField(null=True)
    short_description = models.TextField(null=True)
    name = models.CharField(max_length=200, db_index=True)
    street_address = models.CharField(max_length=100, null=True)

    www = models.URLField(max_length=400, null=True)
    address_postal_full = models.CharField(max_length=100, null=True)
    call_charge_info = models.CharField(max_length=100, null=True)

    picture_caption = models.TextField(null=True)

    phone = models.CharField(max_length=120, null=True)
    fax = models.CharField(max_length=50, null=True)
    email = models.EmailField(max_length=100, null=True)
    accessibility_phone = models.CharField(max_length=50, null=True)
    accessibility_email = models.EmailField(max_length=100, null=True)
    accessibility_www = models.URLField(max_length=400, null=True)

    created_time = models.DateTimeField(
        null=True)  # ASK API: are these UTC? no Z in output

    municipality = models.ForeignKey(Municipality,
                                     null=True,
                                     db_index=True,
                                     on_delete=models.CASCADE)
    address_zip = models.CharField(max_length=10, null=True)

    data_source = models.CharField(max_length=50, null=True)
    extensions = HStoreField(null=True)

    last_modified_time = models.DateTimeField(
        db_index=True, help_text='Time of last modification')

    service_nodes = models.ManyToManyField("ServiceNode", related_name='units')
    services = models.ManyToManyField("Service",
                                      related_name='units',
                                      through='UnitServiceDetails')
    keywords = models.ManyToManyField(Keyword)

    connection_hash = models.CharField(
        max_length=40,
        null=True,
        help_text='Automatically generated hash of connection info')
    accessibility_property_hash = models.CharField(
        max_length=40,
        null=True,
        help_text='Automatically generated hash of accessibility property info'
    )
    identifier_hash = models.CharField(
        max_length=40,
        null=True,
        help_text='Automatically generated hash of other identifiers')
    service_details_hash = models.CharField(max_length=40, null=True)

    accessibility_viewpoints = JSONField(default=dict, null=True)

    # Cached fields for better performance
    root_service_nodes = models.CharField(max_length=50, null=True)

    objects = Manager()
    search_objects = UnitSearchManager()

    class Meta:
        ordering = ['-pk']

    def __str__(self):
        return "%s (%s)" % (get_translated(self, 'name'), self.id)

    def get_root_service_nodes(self):
        from .service_node import ServiceNode

        tree_ids = self.service_nodes.all().values_list('tree_id',
                                                        flat=True).distinct()
        qs = ServiceNode.objects.filter(level=0).filter(
            tree_id__in=list(tree_ids))
        service_node_list = qs.values_list('id', flat=True).distinct()
        return sorted(service_node_list)

    def service_names(self):
        return "\n".join((service.name for service in self.services.all()))

    def highlight_names(self):
        UnitConnection = apps.get_model(app_label='services',
                                        model_name='UnitConnection')
        return "\n".join((connection.name
                          for connection in self.connections.filter(
                              section_type=UnitConnection.HIGHLIGHT_TYPE)))
Esempio n. 14
0
class ExtManager(Manager.from_queryset(ExtQuerySet)):
	"""
	A subclassable Manager
	"""
	pass
Esempio n. 15
0
class Post(Model):
    """
    A Post can either be a Thread or Reply.
    It's a Reply iff it has a parent_thread.

    This is basically a poor man's Single Table Inheritance implementation:
        - CheckConstraints at least provide some guarantees.
        - thread_objects/reply_objects help avoid mistakes when querying one of the two.

    In return we can cleanly implement universal "link to post" regardless of if the
    post is a thread or reply.

    (if someone finds a cleaner way to model this in Django, I'm all ears tbh)
    """

    subject = CharField(max_length=100, blank=True)
    comment = TextField(max_length=2500, blank=True)
    parent_thread = ForeignKey(
        "self", on_delete=CASCADE, null=True, blank=True, related_name="replies"
    )
    board = ForeignKey(
        Board, on_delete=CASCADE, related_name="threads", null=True, blank=True
    )
    created_at = DateTimeField(auto_now_add=True)

    # Of course there's pic and thumbnail
    pic = ImageField(
        upload_to=_upload_to,
        height_field="pic_height",
        width_field="pic_width",
        null=True,
        blank=True,
    )
    pic_height = PositiveIntegerField(null=True)
    pic_width = PositiveIntegerField(null=True)
    thumbnail = ImageField(
        upload_to="thumbnails/",
        height_field="thumbnail_height",
        width_field="thumbnail_width",
        null=True,
        blank=True,
    )
    thumbnail_height = PositiveIntegerField(null=True)
    thumbnail_width = PositiveIntegerField(null=True)

    objects = Manager()
    thread_objects = ThreadManager()
    reply_objects = ReplyManager()

    class Meta:
        db_table = "post"
        constraints = [
            CheckConstraint(
                name="has_subject_iff_is_thread",
                check=(
                    (Q(parent_thread__isnull=True) & ~Q(subject=""))
                    | Q(parent_thread__isnull=False, subject="")
                ),
            ),
            CheckConstraint(
                name="has_board_iff_is_thread",
                check=(
                    Q(parent_thread__isnull=True, board__isnull=False)
                    | Q(parent_thread__isnull=False, board__isnull=True)
                ),
            ),
            CheckConstraint(
                name="has_pic_if_is_thread",
                check=(
                    Q(parent_thread__isnull=True, pic__isnull=False)
                    | Q(parent_thread__isnull=False)
                ),
            ),
        ]

    @property
    def is_thread(self):
        return self.parent_thread is None

    @property
    def pic_public_url(self):
        # BIIIIG assumption that I name each env's bucket after their domain name.
        # TODO make this support plain old FileSystemStorage backend.
        return (
            f"https://{settings.AWS_STORAGE_BUCKET_NAME}/{self.pic.name}"
            if self.pic
            else ""
        )

    def __str__(self):
        if self.is_thread:
            return f"Thread ({self.id}) {self.subject[:50]}"
        else:
            return f"Reply ({self.id}) {self.comment[:50]}"

    def get_absolute_url(self):
        if self.is_thread:
            thread_url = reverse(
                "thread", kwargs={"board_id": self.board_id, "thread_id": self.id}
            )
            return f"{thread_url}#p{self.id}"
        else:
            thread = self.parent_thread
            thread_url = reverse(
                "thread", kwargs={"board_id": thread.board_id, "thread_id": thread.id}
            )
            return f"{thread_url}#p{self.id}"
Esempio n. 16
0
def register(model, model_document):
    default_manager = type(getattr(model, "objects", Manager()))

    if isinstance(default_manager, SearchManagerBase):
        # Already patched!
        # FIXME: Use the registry instead?
        return

    document_class = document_from_model_document(model, model_document)

    def _do_search(query, **options):
        """
            Return a list of model instance_ids from the results
            of the specified query
        """

        index = model_document.index()
        documents = index.search(query,
                                 document_class=document_class,
                                 **options)
        return [x.instance_id for x in documents]

    class SearchQueryset(models.QuerySet):
        def search(self, query, ordered_ids=None, **options):
            keys = _do_search(query, **options)
            if ordered_ids is not None:
                ordered_ids.extend(keys)
            return self.filter(pk__in=keys)

        def search_and_rank(self, query, **options):
            keys = _do_search(query, **options)

            return sorted(self.filter(pk__in=keys),
                          key=lambda x: keys.index(x.pk))

    class SearchManager(default_manager, SearchManagerBase):
        def get_queryset(self):
            qs = SearchQueryset(model, using=self._db)

            # Apply any filtering from any parent manager
            parent_qs = super().get_queryset()
            qs.query = parent_qs.query

            return qs

        def search(self, query, ordered_ids=None, **options):
            return self.get_queryset().search(query=query,
                                              ordered_ids=ordered_ids,
                                              **options)

        def search_and_rank(self, query, **options):
            return self.get_queryset().search_and_rank(query=query, **options)

    # FIXME: Is this safe? I feel like it should be but 'objects' is
    # a ManagerDescriptor so this might not be doing what I think it
    # is.
    model.objects.__class__ = SearchManager

    def delete_decorator(func):
        from djangae.contrib.search.models import DocumentRecord

        @wraps(func)
        def wrapped(self, *args, **kwargs):
            instance_id = self.pk

            func(self, *args, **kwargs)

            results = DocumentRecord.objects.filter(
                data__instance_id=instance_id).values_list("pk", flat=True)

            for result in results:
                model_document.index().remove(result)

        return wrapped

    model.delete = delete_decorator(model.delete)

    def save_decorator(func):
        @wraps(func)
        def wrapped(self, *args, **kwargs):
            func(self, *args, **kwargs)

            # Force un-indexing before re-index
            delete_decorator(lambda self: None)(self)

            attrs = {
                f: model._meta.get_field(f).value_from_object(self)
                for f in model_document._meta().all_fields
            }

            attrs["instance_id"] = self.pk

            doc = document_class(**attrs)
            model_document.index().add(doc)

        return wrapped

    model.save = save_decorator(model.save)
Esempio n. 17
0
class MaterialManager(Manager.from_queryset(MaterialQuerySet)):
    pass
Esempio n. 18
0
class Project(models.Model):
    STAGES = (
        ('T', 'Tender'),
        ('J', 'Job In Hand'),
    )
    STATUS = (('TR', 'Tender'), ('JC', 'JIH-Main Contractor'),
              ('J1', 'JIH-Stage 1'), ('J2', 'JIH-Stage 2'), ('J3',
                                                             'JIH-Stage 3'),
              ('J4', 'JIH-Stage 4'), ('CL', 'Closed'), ('CA', 'Cancelled'))

    reference_no = models.CharField(max_length=60, blank=True)
    name = models.CharField(max_length=60)
    stage = models.CharField(max_length=1, choices=STAGES, default='T')
    status = models.CharField(max_length=2, choices=STATUS, default='TR')
    segment = models.ForeignKey(ProjectSegment, on_delete=models.PROTECT)
    value = models.DecimalField(max_digits=20, decimal_places=3)
    location = models.TextField(blank=True)
    latitude = models.CharField(max_length=100, blank=True, null=True)
    longitude = models.CharField(max_length=100, blank=True, null=True)
    country = models.ForeignKey(Country, on_delete=models.PROTECT)
    companies_linked = models.ManyToManyField(Company, blank=True)
    intro_by = models.ForeignKey(settings.AUTH_USER_MODEL,
                                 on_delete=models.PROTECT)
    intro_date = models.DateField()
    completion = models.DecimalField(max_digits=20,
                                     decimal_places=3,
                                     blank=True)
    exp_start_date = models.DateField(blank=True, null=True)
    exp_end_date = models.DateField(blank=True, null=True)
    main_contractor = models.ForeignKey(Customer,
                                        on_delete=models.PROTECT,
                                        related_name='main_contractors',
                                        blank=True,
                                        null=True)
    main_sub_contractor = models.ForeignKey(Customer,
                                            on_delete=models.PROTECT,
                                            related_name='sub_contractors',
                                            blank=True,
                                            null=True)
    client = models.ForeignKey(Customer,
                               on_delete=models.PROTECT,
                               related_name='clients',
                               blank=True,
                               null=True)
    design_consultant = models.ForeignKey(Customer,
                                          on_delete=models.PROTECT,
                                          related_name='design_consultants',
                                          blank=True,
                                          null=True)
    supervision_consultant = models.ForeignKey(
        Customer,
        on_delete=models.PROTECT,
        related_name='supervision_consultants',
        blank=True,
        null=True)

    objects = Manager()
    query_objects = CustomProjectQueryset.as_manager()

    class Meta:
        ordering = ['-id']
Esempio n. 19
0
from django.db.models import Manager

from .querysets import OrderableQueryset


OrderableManager = Manager.from_queryset(OrderableQueryset)
Esempio n. 20
0
class ReplicaMixin(Model, metaclass=ReplicaMeta):
    """
    Mixin for the replica CQRS model, that will receive data updates from master. Models, using
    this mixin should be readonly, but this is not enforced (f.e. for admin).
    """
    CQRS_ID = None
    """Unique CQRS identifier for all microservices."""

    CQRS_MAPPING = None
    """Mapping of master data field name to replica model field name."""

    CQRS_CUSTOM_SERIALIZATION = False
    """Set it to True to skip default data check."""

    CQRS_SELECT_FOR_UPDATE = False
    """Set it to True to acquire lock on instance creation/update."""

    CQRS_NO_DB_OPERATIONS = False
    """Set it to True to disable any default DB operations for this model."""

    objects = Manager()

    cqrs = ReplicaManager()
    """Manager that adds needed CQRS queryset methods."""

    cqrs_revision = IntegerField()
    cqrs_updated = DateTimeField()

    class Meta:
        abstract = True

    @classmethod
    def cqrs_save(cls, master_data, previous_data=None, sync=False):
        """ This method saves (creates or updates) model instance from CQRS master instance data.
        This method must not be overridden. Otherwise, sync checks need to be implemented manually.

        :param dict master_data: CQRS master instance data.
        :param dict previous_data: Previous values for tracked fields.
        :param bool sync: Sync package flag.
        :return: Model instance.
        :rtype: django.db.models.Model
        """
        if cls.CQRS_NO_DB_OPERATIONS:
            raise NotImplementedError

        return cls.cqrs.save_instance(master_data, previous_data, sync)

    @classmethod
    def cqrs_create(cls, sync, mapped_data, previous_data=None):
        """ This method creates model instance from CQRS mapped instance data. It must be overridden
        by replicas of master models with custom serialization.

        :param bool sync: Sync package flag.
        :param dict mapped_data: CQRS mapped instance data.
        :param dict previous_data: Previous mapped values for tracked fields.
        :return: Model instance.
        :rtype: django.db.models.Model
        """
        return cls._default_manager.create(**mapped_data)

    def cqrs_update(self, sync, mapped_data, previous_data=None):
        """ This method updates model instance from CQRS mapped instance data. It must be overridden
        by replicas of master models with custom serialization.

        :param bool sync: Sync package flag.
        :param dict mapped_data: CQRS mapped instance data.
        :param dict previous_data: Previous mapped values for tracked fields.
        :return: Model instance.
        :rtype: django.db.models.Model
        """

        for key, value in mapped_data.items():
            setattr(self, key, value)
        self.save()
        return self

    @classmethod
    def cqrs_delete(cls, master_data):
        """ This method deletes model instance from mapped CQRS master instance data.

        :param dict master_data: CQRS master instance data.
        :return: Flag, if delete operation is successful (even if nothing was deleted).
        :rtype: bool
        """
        if cls.CQRS_NO_DB_OPERATIONS:
            raise NotImplementedError

        return cls.cqrs.delete_instance(master_data)
Esempio n. 21
0
            self._result_cache = list(self.iterator())
        has_prefetch_relateds = len(self._prefetch_related_lookups) > 0
        has_prefetch_models = len(self._our_prefetches) > 0
        needs_prefetches = has_prefetch_relateds or has_prefetch_models
        if needs_prefetches and not self._prefetch_done:
            self._prefetch_related_objects()


    def iterator(self):
        iterator = super(InheritingQuerySet, self).iterator()
        relations_for_attrgetter = tuple(x.replace(LOOKUP_SEP, '.') for x in lookups_to_text(self._our_joins))
        print(relations_for_attrgetter)
        attrgetters = tuple(attrgetter(x) for x in relations_for_attrgetter)
        for obj in iterator:
            yield dig_for_obj(obj=obj, attrgetters=attrgetters)
    #
    def _prefetch_related_objects(self):
        things = defaultdict(list)
        for index, thing in enumerate(self._result_cache, start=0):
            things[thing.__class__].append(thing)

        for klass, instances in things.items():
            prefetches = self._prefetch_related_lookups[:]
            if klass in self._our_prefetches:
                prefetches.extend(self._our_prefetches[klass])
            prefetch_related_objects(instances, prefetches)
        return None


InheritingManager = Manager.from_queryset(InheritingQuerySet)
Esempio n. 22
0
from mozillians.phonebook.validators import (validate_email, validate_twitter,
                                             validate_website, validate_username_not_url,
                                             validate_phone_number, validate_linkedin,
                                             validate_discord)
from mozillians.users import get_languages_for_locale
from mozillians.users.managers import (EMPLOYEES,
                                       MOZILLIANS, PRIVACY_CHOICES, PRIVACY_CHOICES_WITH_PRIVATE,
                                       PRIVATE, PUBLIC, PUBLIC_INDEXABLE_FIELDS,
                                       UserProfileQuerySet)
from mozillians.users.tasks import send_userprofile_to_cis


COUNTRIES = product_details.get_regions('en-US')
AVATAR_SIZE = (300, 300)
logger = logging.getLogger(__name__)
ProfileManager = Manager.from_queryset(UserProfileQuerySet)


def _calculate_photo_filename(instance, filename):
    """Generate a unique filename for uploaded photo."""
    return os.path.join(settings.USER_AVATAR_DIR, str(uuid.uuid4()) + '.jpg')


class PrivacyField(models.PositiveSmallIntegerField):

    def __init__(self, *args, **kwargs):
        myargs = {'default': MOZILLIANS,
                  'choices': PRIVACY_CHOICES}
        myargs.update(kwargs)
        super(PrivacyField, self).__init__(*args, **myargs)
Esempio n. 23
0
class Content(models.Model):
    """
    Common fields for all content files.

    Field info:
    status -
    privacy - PRIVATE, RESTRICTED, PUBLIC
    uid - unique random identifier string
    user - Django User, if relevant
    group -
    originalfilename - original filename
    filesize - file size of original file in bytes
    filetime - creation time of original file (e.g. EXIF timestamp)
    mimetype - Official MIME Media Type (e.g. image/jpeg, video/mp4)
    file - original file object
    preview - thumbnail object if relevant
    md5 - md5 of original file in hex-format
    sha1 - sha1 of original file in hex-format
    created - creation timestamp
    updated - last update timestamp
    opens - optional timestamp after which this Content is available
    expires - optional timestamp after which this object isn't available
    peers = Content's peers, if relevant
    parent - Content's parent Content, if relevant
    linktype - information of the type of child-parent relation
    point = models.PointField(geography=True, blank=True, null=True)

    It would be useful to save
    Uploadinfo, if the content is saved via HTTP like this:
    Uploadinfo.create(c, request).save()

    title - title text of this Content, a few words max
    caption - descriptive text of this Content
    author - Content author's name or nickname
    keywords - comma separated list of keywords/tags
    place - country, state/province, city, address or other textual description
    """

    status = models.CharField(max_length=40,
                              default="UNPROCESSED",
                              editable=False)
    privacy = models.CharField(max_length=40,
                               default="PRIVATE",
                               verbose_name=_("Privacy"),
                               choices=CONTENT_PRIVACY_CHOICES)
    uid = models.CharField(max_length=40,
                           unique=True,
                           db_index=True,
                           default=get_uid,
                           editable=False)
    user = models.ForeignKey(User,
                             blank=True,
                             null=True,
                             on_delete=models.SET_NULL)
    group = models.ForeignKey(Group,
                              blank=True,
                              null=True,
                              on_delete=models.SET_NULL)
    originalfilename = models.CharField(max_length=256,
                                        null=True,
                                        verbose_name=_("Original file name"),
                                        editable=False)
    filesize = models.IntegerField(null=True, editable=False)
    filetime = models.DateTimeField(blank=True, null=True, editable=False)
    mimetype = models.CharField(max_length=200, null=True, editable=False)
    file = models.FileField(
        storage=content_storage,
        upload_to=upload_split_by_1000)  # , editable=False)
    preview = models.ImageField(storage=preview_storage,
                                blank=True,
                                upload_to=upload_split_by_1000,
                                editable=False)
    md5 = models.CharField(max_length=32, null=True, editable=False)
    sha1 = models.CharField(max_length=40, null=True, editable=False)

    # license
    # origin, e.g. City museum, John Smith's photo album
    # Links and relations to other content files
    peers = models.ManyToManyField("self", blank=True, editable=False)
    parent = models.ForeignKey("self",
                               blank=True,
                               null=True,
                               editable=False,
                               on_delete=models.SET_NULL)
    linktype = models.CharField(max_length=500, blank=True)
    # point (geography) is used for e.g. distance calculations
    point = models.PointField(geography=True, blank=True, null=True)
    # point_geom (geometry) is used to enable e.g. within queries
    point_geom = models.PointField(blank=True, null=True)
    # TODO: to be removed (text fields are implemented elsewhere
    title = models.CharField(max_length=200,
                             blank=True,
                             verbose_name=_("Title"))
    # TODO: to be removed (text fields are implemented elsewhere
    caption = models.TextField(blank=True, verbose_name=_("Caption"))
    # TODO: to be removed (text fields are implemented elsewhere
    author = models.CharField(max_length=200,
                              blank=True,
                              verbose_name=_("Author"))
    # TODO: to be removed (text fields are implemented elsewhere
    keywords = models.CharField(max_length=500,
                                blank=True,
                                verbose_name=_("Keywords"))
    # TODO: to be removed (text fields are implemented elsewhere
    place = models.CharField(max_length=500,
                             blank=True,
                             verbose_name=_("Place"))
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    opens = models.DateTimeField(blank=True, null=True)
    expires = models.DateTimeField(blank=True, null=True)

    # In referencing model add e.g. `files = GenericRelation(Content)`
    content_type = models.ForeignKey(ContentType,
                                     blank=True,
                                     null=True,
                                     default=None,
                                     on_delete=models.SET_NULL)
    object_id = models.PositiveIntegerField(blank=True, null=True)
    content_object = GenericForeignKey("content_type", "object_id")

    objects = Manager()

    # TODO: replace this with property stuff
    def latlon(self):
        # FIXME: should this be lonlat?
        return self.point.coords if self.point else None

    def set_latlon(self, lat, lon):
        p = Point(lon, lat)
        self.point = p
        self.point_geom = p

    def save_file(self, originalfilename: str,
                  filecontent: UploadedFile | io.IOBase | str):
        """
        Save filecontent to the filesystem and fill filename, filesize fields.
        filecontent may be
        - open file handle (opened in "rb"-mode)
        - existing file name (full path)
        - raw file data
        """
        # TODO: check functionality with very large files
        self.originalfilename = os.path.basename(originalfilename)
        self.save()  # Must save here to get self.id
        root, ext = os.path.splitext(originalfilename)
        filename = "{:09d}-{}{}".format(self.id, self.uid, ext.lower())
        if isinstance(filecontent, UploadedFile):  # Is an open file
            self.file.save(filename, File(filecontent))
        elif isinstance(filecontent, io.IOBase):  # Is open file
            self.file.save(filename, File(filecontent))
        elif len(filecontent) < 1000 and os.path.isfile(filecontent):
            # Is existing file in file system
            with open(filecontent, "rb") as f:
                self.file.save(filename, File(f))
        else:  # Is just something in the memory
            self.file.save(filename, ContentFile(filecontent))
        self.filesize = self.file.size
        self.save()

    def set_file(
        self,
        originalfilename: str,
        filecontent: UploadedFile | io.IOBase | str,
        mimetype: str = None,
        md5: str = None,
        sha1: str = None,
    ):
        """
        Save Content.file and all it's related fields
        (filename, filesize, mimetype, md5, sha1).
        'filecontent' may be
        - open file handle (opened in "rb"-mode)
        - existing file name (full path)
        - raw file data
        """
        self.save_file(originalfilename, filecontent)
        if md5 is None or sha1 is None:
            self.md5, self.sha1 = filetools.hashfile(self.file.path)
        if mimetype:
            self.mimetype = mimetype
        else:
            info = filetools.fileinfo(self.file.path)
            mime = info["mimetype"]
            if mime:
                self.mimetype = mime
            else:
                self.mimetype = mimetypes.guess_type(originalfilename)[0]
        self.status = "PROCESSED"
        self.save()

    def set_fileinfo(self, mime: str = None):
        """
        Create (or update if it already exists) Content.video/audio/image.
        Save width, height, duration, bitrate where appropriate.
        """
        if mime is None:
            mime = self.mimetype
        obj = info = None
        if mime.startswith("image"):
            info = filetools.get_imageinfo(self.file.path)
            try:
                obj = self.image
            except Image.DoesNotExist:
                obj = Image(content=self)
        elif mime.startswith("video"):
            ffp = filetools.FFProbe(self.file.path)
            info = ffp.get_videoinfo()
            try:
                obj = self.video
            except Video.DoesNotExist:
                obj = Video(content=self)
        elif mime.startswith("audio"):
            ffp = filetools.FFProbe(self.file.path)
            info = ffp.get_audioinfo()
            try:
                obj = self.audio
            except Audio.DoesNotExist:
                obj = Audio(content=self)
        if obj and info:
            obj.set_metadata(info)
            obj.save()  # Save new instance to the database
            # Save common data into self
            if "gps" in info:
                if self.point is None and "lat" in info["gps"]:
                    self.set_latlon(info["gps"]["lat"], info["gps"]["lon"])
            if self.filetime is None:
                if "gps" in info and "gpstime" in info["gps"]:
                    self.filetime = info["gps"]["gpstime"]
                elif "creation_time" in info:
                    self.filetime = info.get("creation_time")
            self.save()
            return obj

    def get_fileinfo(self):
        info = filetools.get_imageinfo(self.file.path)
        return info

    def generate_thumbnail(self):
        """
        Generates the file to preview field for Videos, Images and PDFs.
        TODO: use only content.preview for thumbnails, not video/image.thumbnail
        """
        # TODO: create generic thumbnail functions for video, image and pdf
        if self.mimetype.startswith("image"):
            try:
                im = PIL.Image.open(self.file.path)
                self.image.generate_thumb(im, self.image.thumbnail,
                                          THUMBNAIL_PARAMETERS)
                if self.image.thumbnail:
                    self.preview = self.image.thumbnail
                    self.save()
            except Image.DoesNotExist:
                pass
        elif self.mimetype.startswith("video"):
            try:
                if self.video.thumbnail:
                    self.video.thumbnail.delete()
                self.video.generate_thumb()
                if self.video.thumbnail:
                    self.preview = self.video.thumbnail
                    self.save()
            except Video.DoesNotExist:
                pass
        elif self.mimetype.startswith("application/pdf"):
            fd, tmp_name = tempfile.mkstemp()  # Remember to close fd!
            tmp_name += ".png"
            if do_pdf_thumbnail(self.file.path, tmp_name):
                postfix = "{}-{}-{}x{}".format(THUMBNAIL_PARAMETERS)
                filename = "{:09d}-{}-{}.png".format(self.id, self.uid,
                                                     postfix)
                if os.path.isfile(tmp_name):
                    with open(tmp_name, "rb") as f:
                        self.preview.save(filename, File(f))
                    self.save()
                    os.unlink(tmp_name)
            os.close(fd)
        else:
            return None

    def preview_ext(self):
        """Return the file extension of preview if it exists."""
        # TODO: use pathlib
        if self.preview:
            root, ext = os.path.splitext(self.preview.path)
        else:
            root, ext = os.path.splitext(self.file.path)
        return ext.lstrip(".")

    def thumbnail(self):
        """
        Return thumbnail if it exists.
        Thumbnail is always an image (can be shown with <img> tag).
        """
        if self.preview:
            return self.preview
        if self.mimetype is None:
            return None
        elif self.mimetype.startswith("image"):
            try:
                return self.image.thumbnail
            except Image.DoesNotExist:
                return None
        elif self.mimetype.startswith("video"):  # and self.video.thumbnail:
            try:
                return self.video.thumbnail
            except Video.DoesNotExist:
                return None
        else:
            return None

    def delete(self, *args, **kwargs):
        """
        Set Content.status = "DELETE". Real deletion (referencing Videos and
        Audios, Video and AudioInstances) can be done later e.g. with
        some management command (not implemented yet).
        """
        if kwargs.get("purge", False) is True and self.status == "DELETED":
            # TODO:
            # for f in [self.file, self.preview]:
            #    if os.path.isfile(f):
            #        os.unlink(f)
            # Delete all instance files too
            print("REALLY DELETING HERE ALL INSTANCES "
                  "AND FILES FROM FILESYSTEM")
            # Super.delete
        else:
            self.status = "DELETED"
            self.save()

    def __str__(self):
        text = self.caption[:50] if self.caption else self.title
        return f'"{text}" {self.mimetype}  ({self.filesize}B)'
Esempio n. 24
0
class ContentRating(Model):
    """
    This Model contains data related to one rated content,
    its overall rating, category ratings, word counts,
    and created and updated dates.
    """
    from capstoneproject.models.models.category_rating import CategoryRating
    from capstoneproject.models.models.content import Content
    from capstoneproject.models.models.word_count import WordCount
    from capstoneproject.models.fields.rating_field import RatingField
    content = ForeignKey('Content',
                         related_name='content_ratings',
                         on_delete=CASCADE)
    rating = RatingField(default=0)
    category_ratings = ManyToManyField(CategoryRating,
                                       related_name='content_ratings')
    word_counts = ManyToManyField(WordCount, related_name='content_ratings')
    created = DateTimeField(auto_now_add=True)
    updated = DateTimeField(auto_now=True)
    content_ratings = Manager()

    def __str__(self):
        string = 'Rating\n'
        string += '  Content: {}\n'.format(self.content)
        string += '  Overall Rating: {}\n'.format(self.rating)
        string += '  Category Ratings: {}\n'.format(self.category_ratings)
        string += '  Word Counts: {}\n'.format(self.word_counts)
        string += '  Created: {}    Updated: {}\n'.format(
            self.created, self.updated)
        return string

    def isRelated(self):
        """
        Determines if any relatives rely on this model instance.
        :return: True if relatives rely on this model instance.
        """
        return len(self.user_storage.all()) > 0

    def isOrphaned(self):
        """
        Determines if no relatives rely on this model instance.
        :return: True if no relatives rely on this model instance.
        """
        return len(self.user_storage.all()) == 0

    def delete_relatives(self):
        """
        Deletes relatives to this model.
        :return:
        """
        category_ratings = list(self.category_ratings.all())
        self.category_ratings.clear()
        for category_rating in category_ratings:
            if category_rating.isOrphaned():
                category_rating.delete()

        word_counts = list(self.word_counts.all())
        self.word_counts.clear()
        for word_count in word_counts:
            if word_count.isOrphaned():
                word_count.delete()

    def delete(self, *args, **kwargs):
        """
        Deletes this model after deleting its relatives.
        :return:
        """
        self.delete_relatives()
        old_content = self.content
        super().delete(*args, **kwargs)
        if old_content.isOrphaned():
            old_content.delete()

    def get_category_ratings(self):
        """
        Retrieves the CategoryRatings for this Category.
        :return: a dict of CategoryRatings.
        """
        category_ratings = dict()
        for cat_rating in self.category_ratings.all():
            category_ratings[cat_rating.category.name] = cat_rating.rating
        return category_ratings

    def _create_word_count_dict(self):
        """
        Compile a dictionary of the WordCounts for this ContentRating.
        :return: a dictionary of Words and their Counts.
        """
        word_counts = dict()
        for wc in self.word_counts.all():
            word_counts[wc.word.name] = wc.count
        return word_counts

    def get_word_count_category(self):
        """
        Compile a dictionary of the WordCounts for this ContentRating's \
        Categories.
        :return: a dictionary of Categories, Words, and their Counts.
        """
        word_count_category_dict = dict()
        from capstoneproject.models.models.category import Category
        for cat in Category.categories.all():
            word_count_category_dict[cat.name] = dict()

        word_count_dict = self._create_word_count_dict()
        for word, count in word_count_dict.items():
            from capstoneproject.models.models.word import Word
            word_model = Word.words.get_word(word=word)
            for word_cat in word_model.get_categories():
                word_count_category_dict[word_cat][word] = count

        return word_count_category_dict

    class Meta:
        """Settings for the ContentRating model."""
        default_manager_name = 'content_ratings'
Esempio n. 25
0
class Project(models.Model):
    name = models.CharField(max_length=20,
                            null=True,
                            blank=True,
                            help_text=name_help_text)
    app_name = models.CharField(max_length=200, null=True)
    full_name = models.CharField(max_length=300, unique=True, db_index=True)

    namespace_abbreviation = models.TextField(max_length=255,
                                              null=True,
                                              blank=True)
    namespace_uri = models.URLField(null=True, blank=True)
    namespace_description = models.TextField(null=True, blank=True)

    abstract = models.TextField(max_length=4000,
                                null=True,
                                blank=True,
                                help_text=abstract_help_text)
    is_standard = models.BooleanField(default=False)
    attribution = models.TextField(max_length=1000,
                                   null=True,
                                   blank=True,
                                   help_text=attribution_help_text)
    website = models.URLField(null=True, blank=True)
    geographic = models.CharField(max_length=255, null=True, blank=True)
    temporal = models.CharField(max_length=255, null=True, blank=True)
    graphic = models.FileField(max_length=255,
                               null=True,
                               blank=True,
                               upload_to="uploads/images/projects")
    occurrence_table_name = models.CharField(
        max_length=255,
        null=True,
        blank=True,
        help_text=occurrence_table_name_help_text)
    is_public = models.BooleanField(
        default=False,
        help_text="Is the raw data to be made publicly viewable?")
    display_summary_info = models.BooleanField(
        default=True, help_text=display_summary_info_help_text)
    display_fields = models.TextField(max_length=2000,
                                      default="['id',]",
                                      null=True,
                                      blank=True,
                                      help_text=display_fields_help_text)
    display_filter_fields = models.TextField(
        max_length=2000,
        default="[]",
        null=True,
        blank=True,
        help_text=display_filter_fields_help_text)
    # users = models.ManyToManyField(User, blank=True)
    terms = models.ManyToManyField('Term', through='ProjectTerm', blank=True)
    default_app_model = models.TextField(null=True, blank=True)
    #default_app_model = models.ForeignKey(ContentType, blank=True, null=True, on_delete=models.SET_NULL)
    #geom = models.PointField(srid=4326, blank=True, null=True)
    geom = models.CharField(max_length=255, null=True, blank=True)
    objects = Manager()

    class Meta:
        ordering = ["name"]
        verbose_name_plural = "Projects"
        verbose_name = "Project"

    def __str__(self):
        return self.full_name

    def record_count(self):
        if self.is_standard:
            return 0
        else:
            model = apps.get_model(self.app_name, self.occurrence_table_name)
            return model.objects.count()

    def get_terms(self):
        """
        Return a queryset of term objects associated with the project.
        To get a list of the term names as used by the project use,
        [term.get_mapping(self.app_name) for term in project_terms]
        :return: returns a queryset of term objects
        """
        return Term.objects.filter(
            projects=self)  # get a queryset of all terms for a project
        # [term.get_mapping(self.app_name) for term in project_terms]

    def get_properties(self):
        """
        Get a list of all the property terms associated with the project.
        :return: returns a queryset of term objects
        """
        # get a queryset of all terms for a project that are not classes, i.e. get all properties
        return Term.objects.filter(projects=self).exclude(is_class=True)
        # [term.get_mapping(self.app_name) for term in project_terms]

    def get_verbatim_categories(self):
        """
        Get a list of all verbatim class terms associated project.
        :return:
        """
        # get a queryset of all terms for a project that are classes
        return Term.objects.filter(projects=self).filter(
            is_class=True).order_by('term_ordering')

    def get_term_names(self):
        """
        Get a list of the term names as used by the project
        :return: returns a list of term names
        """
        term_qs = self.get_terms()
        return [term.get_mapping(self.app_name) for term in term_qs]

    def map_terms(self, proj):
        """
        Map terms between two projects
        :param proj: accept either the project object or the project name as string
        :return: returns a dictionary with keys for each term in self and corresponding mapped values in proj
        """
        result_dict = {}  # initialize dictionary for result
        term_qs = self.get_terms(
        )  # get a list of terms related to the project
        if type(
                proj
        ) == str:  # test proj argument and if it's a string fetch the object
            project = Project.objects.get(name=proj)
        else:
            project = proj
        for term in term_qs:
            try:
                ProjectTerm.objects.get(term=term, project=project)
                result_dict[term.get_mapping(self.name)] = term.get_mapping(
                    project.name)
            except ProjectTerm.DoesNotExist:
                result_dict[term.get_mapping(self.name)] = None
        return result_dict
Esempio n. 26
0
from django.db import connections
from django.db.models import QuerySet, Manager
from django.db.models.sql.datastructures import EmptyResultSet


class FuzzyCountQuerySet(QuerySet):

    def fuzzy_count(self):
        cursor = connections[self.db].cursor()

        try:
            cursor.execute('SELECT count_estimate(%s);', (cursor.mogrify(*self.query.sql_with_params()).decode(), ))
        except EmptyResultSet:
            return 0

        return int(cursor.fetchone()[0])

FuzzyCountManager = Manager.from_queryset(FuzzyCountQuerySet)
Esempio n. 27
0
class Post(models.Model):
    # ****************************************************************************************
    seller = models.ForeignKey(User,
                               on_delete=models.CASCADE,
                               null=True,
                               blank=False,
                               related_name="posts")
    # ****************************************************************************************
    title = models.CharField(max_length=100)

    # ****************************************************************************************

    def validate_ISBN(value):
        print(not (f'{value}'.isnumeric()))
        if (len(value) != 10 and len(value) != 13):
            raise ValidationError(
                f'number of digits in {value} is neither 10 nor 13',
                params={'value': value},
            )
        elif (not (f'{value}'.isnumeric())):
            raise ValidationError(
                f'{value} has non-numeric elements',
                params={'value': value},
            )

    ISBN = models.CharField(max_length=13, validators=[validate_ISBN])
    # ****************************************************************************************
    author = models.CharField(max_length=50)
    # ****************************************************************************************
    description = models.TextField(max_length=350)
    # ****************************************************************************************
    image = models.ImageField(default='default_book.png',
                              upload_to='book_pics')
    # ****************************************************************************************
    date_posted = models.DateTimeField(default=timezone.now)  # UTC time
    # ****************************************************************************************
    edition = models.PositiveSmallIntegerField(blank=True, null=True)

    # ****************************************************************************************
    price = models.PositiveSmallIntegerField(default=0)

    # ****************************************************************************************
    swappable = models.BooleanField(default=False)
    # ****************************************************************************************

    IN_PROGRESS = "In progress"
    COMPLETE = "Complete"
    states = (
        (IN_PROGRESS, "In progress"),
        (COMPLETE, "Complete"),
    )
    transaction_state = models.CharField(max_length=50,
                                         choices=states,
                                         default=IN_PROGRESS)

    # ****************************************************************************************

    OTHER = "Other"
    TEXTBOOK = "Textbook"
    post_types = (
        (OTHER, "Other"),
        (TEXTBOOK, "Textbook"),
    )
    post_type = models.CharField(max_length=50,
                                 choices=post_types,
                                 default=OTHER)

    # ****************************************************************************************
    bookmarks = models.ManyToManyField(User,
                                       related_name="bookmarked_post",
                                       through='Bookmark')
    # ****************************************************************************************
    objects = Manager()

    def __str__(self):
        return (f"Seller: {self.seller} | Title: {self.title} | ID: {self.pk}")

    class Meta:
        verbose_name = 'Post'
        # Name the model will appear under in the Django Admin page.
        verbose_name_plural = 'Posts'
Esempio n. 28
0
class FormatManager(Manager.from_queryset(FormatQuerySet)):  # type: ignore
    use_for_related_fields = True
Esempio n. 29
0
                                             validate_website,
                                             validate_username_not_url,
                                             validate_phone_number,
                                             validate_linkedin,
                                             validate_discord)
from mozillians.users import get_languages_for_locale
from mozillians.users.managers import (EMPLOYEES, MOZILLIANS, PRIVACY_CHOICES,
                                       PRIVACY_CHOICES_WITH_PRIVATE, PRIVATE,
                                       PUBLIC, PUBLIC_INDEXABLE_FIELDS,
                                       UserProfileQuerySet)
from mozillians.users.tasks import send_userprofile_to_cis

COUNTRIES = product_details.get_regions('en-US')
AVATAR_SIZE = (300, 300)
logger = logging.getLogger(__name__)
ProfileManager = Manager.from_queryset(UserProfileQuerySet)


def _calculate_photo_filename(instance, filename):
    """Generate a unique filename for uploaded photo."""
    return os.path.join(settings.USER_AVATAR_DIR, str(uuid.uuid4()) + '.jpg')


class PrivacyField(models.PositiveSmallIntegerField):
    def __init__(self, *args, **kwargs):
        myargs = {'default': MOZILLIANS, 'choices': PRIVACY_CHOICES}
        myargs.update(kwargs)
        super(PrivacyField, self).__init__(*args, **myargs)


class UserProfilePrivacyModel(models.Model):
Esempio n. 30
0
class Event(Model):
    title = CharField(_("title"), max_length=254)
    description = TextField(_("description"), blank=True, null=True)
    location = CharField(_("location"), max_length=254)
    type = ForeignKey(EventType,
                      on_delete=models.CASCADE,
                      verbose_name=_("event type"))
    active = BooleanField(default=False)
    mail_updates = BooleanField(_("send updates via mail"), default=True)

    objects = ActiveManager()
    all_objects = Manager()

    class Meta:
        verbose_name = _("event")
        verbose_name_plural = _("events")
        permissions = [("view_past_event", _("Can view past events"))]
        db_table = "event"

    def get_start_time(self):
        # use shifts.all() in case the shifts have been prefetched
        return min(s.start_time
                   for s in self.shifts.all()) if self.shifts.all() else None

    def get_end_time(self):
        return max(s.end_time
                   for s in self.shifts.all()) if self.shifts.all() else None

    def get_signup_stats(self) -> "SignupStats":
        """Return a SignupStats object aggregated over all shifts of this event, or a default"""
        from ephios.core.signup import SignupStats

        default_for_no_shifts = SignupStats(0, 0, None, None)

        return functools.reduce(
            operator.add,
            [
                shift.signup_method.get_signup_stats()
                for shift in self.shifts.all()
            ] or [default_for_no_shifts],
        )

    def __str__(self):
        return str(self.title)

    def get_canonical_slug(self):
        return slugify(self.title)

    def get_absolute_url(self):
        from django.urls import reverse

        return reverse("core:event_detail",
                       kwargs=dict(pk=self.id, slug=self.get_canonical_slug()))

    def activate(self):
        from ephios.core import mail

        if not self.active:
            with transaction.atomic():
                self.active = True
                self.full_clean()
                self.save()
                if self.mail_updates:
                    mail.new_event(self)
Esempio n. 31
0
class SharedSlugSpace(Model):
    objects = Manager()
    name = CharField(max_length=200)
    # ensure that any subclasses use the base model's manager for testing
    # slug uniqueness
    slug = AutoSlugField(populate_from='name', unique=True, manager=objects)
Esempio n. 32
0
class CommentQuerySet(QuerySet):
    DEFAULT_COLUMNS = {
        'content': 'text',
        'author__name': 'author',
        'conversation__title': 'conversation',
    }

    def approved(self):
        return self.filter(status=self.model.STATUS.approved)

    def pending(self):
        return self.filter(status=self.model.STATUS.pending)

    def rejected(self):
        return self.filter(status=self.model.STATUS.rejected)

    def statistics(self):
        return [x.statistics() for x in self]

    def display_dataframe(self, columns=DEFAULT_COLUMNS):
        qs = self.values_list('id', *columns.keys())
        df = pd.DataFrame(list(qs), columns=['id', *columns.values()])
        df.index = df.pop('id')
        return df


ConversationManager = Manager.from_queryset(ConversationQuerySet,
                                            'ConversationManager')
CommentManager = Manager.from_queryset(CommentQuerySet, 'CommentManager')
BoogieManager = Manager.from_queryset(QuerySet)
Esempio n. 33
0
class Manager(DjangoManager.from_queryset(QuerySet)):
    pass
Esempio n. 34
0
from django.db import connections
from django.db.models import QuerySet, Manager
from django.db.models.sql.datastructures import EmptyResultSet


class FuzzyCountQuerySet(QuerySet):
    def fuzzy_count(self):
        cursor = connections[self.db].cursor()

        try:
            cursor.execute(
                'SELECT count_estimate(%s);',
                (cursor.mogrify(*self.query.sql_with_params()).decode(), ))
        except EmptyResultSet:
            return 0

        return int(cursor.fetchone()[0])


FuzzyCountManager = Manager.from_queryset(FuzzyCountQuerySet)
class Feriado(Model):
    feriado = CharField(max_length=100)
    data = DateField()

    objetos = Manager()
Esempio n. 36
0
class Anno(Model):
    created = DateTimeField(db_index=True, auto_now_add=True, null=False)
    modified = DateTimeField(auto_now=True, null=False)

    schema_version = CharField(
        max_length=128, null=False, default=CATCH_CURRENT_SCHEMA_VERSION)
    creator_id = CharField(max_length=128, null=False)
    creator_name = CharField(max_length=128, null=False)

    anno_id = CharField(max_length=128, primary_key=True)
    # soft delete
    anno_deleted = BooleanField(db_index=True, default=False)
    # comment to a parent annotation
    anno_reply_to = ForeignKey('Anno', null=True, blank=True, on_delete=CASCADE)
    anno_tags = ManyToManyField('Tag', blank=True)
    # permissions are lists of user_ids, blank means public
    can_read = ArrayField(CharField(max_length=128), null=True, default=list)
    can_update = ArrayField(CharField(max_length=128), null=True, default=list)
    can_delete = ArrayField(CharField(max_length=128), null=True, default=list)
    can_admin = ArrayField(CharField(max_length=128), null=True, default=list)

    # support for only one _text_ body
    # max length for body_text is restricted in django request
    # in settings.DATA_UPLOAD_MAX_MEMORY_SIZE (default is 2.5Mb)
    body_text = TextField(null=True)
    # body_format is a mime type, like 'text/html', 'text/richtext',
    # 'application/rtf', 'application/x-rtf', etc
    # note that rich text can have binaries embedded (like images)
    body_format = CharField(max_length=128, null=False, default='text/html')

    target_type = CharField(
            max_length=16,
            choices=RESOURCE_TYPE_CHOICES,
            default=RESOURCE_TYPE_UNDEFINED)

    raw = JSONField()

    # default model manager
    objects = Manager()

    # TODO: manager for custom searches
    # http://stackoverflow.com/a/30941292
    # _c_manager = getattr(settings, 'CATCHA_CUSTOM_MANANGER', None)
    # if _c_manager:
    #     module_name, class_name = _c_manager.rsplit('.', 1)
    #     CustomClass = getattr(importlib.import_modUle(module_name), class_name)
    #     custom_manager = CustomClass()
    # else:
    #     custom_manager = SearchManager()
    custom_manager = SearchManager()

    class Meta:
        indexes = [
            GinIndex(
                fields=['raw'],
                name='anno_raw_gin',
            ),
        ]

    def __repr__(self):
        return '({}_{})'.format(self.schema_version, self.anno_id)

    def __str__(self):
        return self.__repr__()

    @property
    def total_replies(self):
        #return self.anno_set.count()
        return self.anno_set.all().filter(anno_deleted=False).count()

    @property
    def replies(self):
        # exclude deleted replies!
        #
        # ATT: this makes marked_for_deletion replies _unaccessible via API_
        #
        return self.anno_set.all().filter(anno_deleted=False).order_by('created')

    @property
    def total_targets(self):
        return self.target_set.count()

    @property
    def targets(self):
        return self.target_set.all()

    @property
    def serialized(self):
        s = self.raw.copy()
        s['totalReplies'] = self.total_replies
        s['created'] = self.created.replace(microsecond=0).isoformat()
        s['modified'] = self.modified.replace(microsecond=0).isoformat()
        s['id'] = self.anno_id
        return s

    def permissions_for_user(self, user):
        '''list of ops user is allowed to perform in this anno instance.

        note: implementation of this method makes it impossible to have update,
        delete, admin open to public.
        '''
        permissions = []
        if not self.can_read or user in self.can_read:
            permissions.append('can_read')
        if user in self.can_update:
            permissions.append('can_update')
        if user in self.can_delete:
            permissions.append('can_delete')
        if user in self.can_admin:
            permissions.append('can_admin')
        return permissions

    def mark_as_deleted(self, *args, **kwargs):
        '''
        overwrite delete to perform a soft delete.
        '''
        self.anno_deleted = True

    def has_permission_for(self, op, user_id):
        '''check if user has permission for operation.'''
        if op == 'read':
            if not self.can_read or user_id in self.can_read:
                return True
        permission = getattr(self, 'can_{}'.format(op))
        if permission is not None:
            return (user_id in permission)
        else:
            return False
Esempio n. 37
0
class BMC(CleanSave, TimestampedModel):
    """A `BMC` represents an existing 'baseboard management controller'.  For
    practical purposes in MAAS, this is any addressable device that can control
    the power state of Nodes. The BMC associated with a Node is the one
    expected to control its power.

    Power parameters that apply to all nodes controlled by a BMC are stored
    here in the BMC. Those that are specific to different Nodes on the same BMC
    are stored in the Node model instances.

    :ivar ip_address: This `BMC`'s IP Address.
    :ivar power_type: The power type defines which type of BMC this is.
        Its value must match a power driver class name.
    :ivar power_parameters: Some JSON containing arbitrary parameters this
        BMC's power driver requires to function.
    :ivar objects: The :class:`BMCManager`.
    """
    class Meta(DefaultMeta):
        unique_together = ("power_type", "power_parameters", "ip_address")

    objects = Manager()

    bmcs = BMCManager()

    bmc_type = IntegerField(choices=BMC_TYPE_CHOICES,
                            editable=False,
                            default=BMC_TYPE.DEFAULT)

    ip_address = ForeignKey(StaticIPAddress,
                            default=None,
                            blank=True,
                            null=True,
                            editable=False,
                            on_delete=SET_NULL)

    # The possible choices for this field depend on the power types advertised
    # by the rack controllers.  This needs to be populated on the fly, in
    # forms.py, each time the form to edit a node is instantiated.
    power_type = CharField(max_length=10, null=False, blank=True, default='')

    # JSON-encoded set of parameters for power control, limited to 32kiB when
    # encoded as JSON. These apply to all Nodes controlled by this BMC.
    power_parameters = JSONObjectField(max_length=(2**15),
                                       blank=True,
                                       default='')

    # Rack controllers that have access to the BMC by routing instead of
    # having direct layer 2 access.
    routable_rack_controllers = ManyToManyField(
        "RackController",
        blank=True,
        editable=True,
        through="BMCRoutableRackControllerRelationship",
        related_name="routable_bmcs")

    # Values for Pod's.
    #  1. Name of the Pod.
    #  2. List of architectures that a Pod supports.
    #  3. Capabilities that the Pod supports.
    #  4. Total cores in the Pod.
    #  5. Fastest CPU speed in the Pod.
    #  6. Total amount of memory in the Pod.
    #  7. Total about in bytes of local storage available in the Pod.
    #  8. Total number of available local disks in the Pod.
    #  9. The resource pool machines in the pod should belong to by default.
    name = CharField(max_length=255, default='', blank=True, unique=True)
    architectures = ArrayField(TextField(),
                               blank=True,
                               null=True,
                               default=list)
    capabilities = ArrayField(TextField(), blank=True, null=True, default=list)
    cores = IntegerField(blank=False, null=False, default=0)
    cpu_speed = IntegerField(blank=False, null=False, default=0)  # MHz
    memory = IntegerField(blank=False, null=False, default=0)
    local_storage = BigIntegerField(  # Bytes
        blank=False, null=False, default=0)
    local_disks = IntegerField(blank=False, null=False, default=-1)
    iscsi_storage = BigIntegerField(  # Bytes
        blank=False, null=False, default=-1)
    default_pool = ForeignKey(ResourcePool,
                              default=None,
                              null=True,
                              blank=True,
                              editable=True,
                              on_delete=PROTECT)

    def __str__(self):
        return "%s (%s)" % (self.id,
                            self.ip_address if self.ip_address else "No IP")

    def _as(self, model):
        """Create a `model` that shares underlying storage with `self`.

        In other words, the newly returned object will be an instance of
        `model` and its `__dict__` will be `self.__dict__`. Not a copy, but a
        reference to, so that changes to one will be reflected in the other.
        """
        new = object.__new__(model)
        new.__dict__ = self.__dict__
        return new

    def as_bmc(self):
        """Return a reference to self that behaves as a `BMC`."""
        return self._as(BMC)

    def as_pod(self):
        """Return a reference to self that behaves as a `Pod`."""
        return self._as(Pod)

    _as_self = {
        BMC_TYPE.BMC: as_bmc,
        BMC_TYPE.POD: as_pod,
    }

    def as_self(self):
        """Return a reference to self that behaves as its own type."""
        return self._as_self[self.bmc_type](self)

    def delete(self):
        """Delete this BMC."""
        maaslog.info("%s: Deleting BMC", self)
        super(BMC, self).delete()

    def save(self, *args, **kwargs):
        """Save this BMC."""
        super(BMC, self).save(*args, **kwargs)
        # We let name be blank for the initial save, but fix it before the
        # save completes.  This is because set_random_name() operates by
        # trying to re-save the BMC with a random hostname, and retrying until
        # there is no conflict.
        if self.name == '':
            self.set_random_name()

    def set_random_name(self):
        """Set a random `name`."""
        while True:
            self.name = petname.Generate(2, "-")
            try:
                self.save()
            except ValidationError:
                pass
            else:
                break

    def clean(self):
        """ Update our ip_address if the address extracted from our power
        parameters has changed. """
        new_ip = BMC.extract_ip_address(self.power_type, self.power_parameters)
        current_ip = None if self.ip_address is None else self.ip_address.ip
        # Set the ip_address field.  If we have a bracketed address, assume
        # it's IPv6, and strip the brackets.
        if new_ip and new_ip.startswith('[') and new_ip.endswith(']'):
            new_ip = new_ip[1:-1]
        if new_ip != current_ip:
            if new_ip is None:
                self.ip_address = None
            else:
                # Update or create a StaticIPAddress for the new IP.
                try:
                    # This atomic block ensures that an exception within will
                    # roll back only this block's DB changes. This allows us to
                    # swallow exceptions in here and keep all changes made
                    # before or after this block is executed.
                    with transaction.atomic():
                        subnet = Subnet.objects.get_best_subnet_for_ip(new_ip)
                        (self.ip_address,
                         _) = StaticIPAddress.objects.get_or_create(
                             ip=new_ip,
                             defaults={
                                 'alloc_type': IPADDRESS_TYPE.STICKY,
                                 'subnet': subnet,
                             })
                except Exception as error:
                    maaslog.info(
                        "BMC could not save extracted IP "
                        "address '%s': '%s'", new_ip, error)

    @staticmethod
    def scope_power_parameters(power_type, power_params):
        """Separate the global, bmc related power_parameters from the local,
        node-specific ones."""
        if not power_type:
            # If there is no power type, treat all params as node params.
            return ({}, power_params)
        power_driver = PowerDriverRegistry.get_item(power_type)
        if power_driver is None:
            # If there is no power driver, treat all params as node params.
            return ({}, power_params)
        power_fields = power_driver.settings
        if not power_fields:
            # If there is no parameter info, treat all params as node params.
            return ({}, power_params)
        bmc_params = {}
        node_params = {}
        for param_name in power_params:
            power_field = power_driver.get_setting(param_name)
            if (power_field and power_field.get('scope') == SETTING_SCOPE.BMC):
                bmc_params[param_name] = power_params[param_name]
            else:
                node_params[param_name] = power_params[param_name]
        return (bmc_params, node_params)

    @staticmethod
    def extract_ip_address(power_type, power_parameters):
        """ Extract the ip_address from the power_parameters. If there is no
        power_type, no power_parameters, or no valid value provided in the
        power_address field, returns None. """
        if not power_type or not power_parameters:
            # Nothing to extract.
            return None
        power_driver = PowerDriverRegistry.get_item(power_type)
        if power_driver is None:
            maaslog.warning("No power driver for power type %s" % power_type)
            return None
        power_type_parameters = power_driver.settings
        if not power_type_parameters:
            maaslog.warning("No power driver settings for power type %s" %
                            power_type)
            return None
        ip_extractor = power_driver.ip_extractor
        if not ip_extractor:
            maaslog.info("No IP extractor configured for power type %s. "
                         "IP will not be extracted." % power_type)
            return None
        field_value = power_parameters.get(ip_extractor.get('field_name'))
        if not field_value:
            maaslog.warning("IP extractor field_value missing for %s" %
                            power_type)
            return None
        extraction_pattern = ip_extractor.get('pattern')
        if not extraction_pattern:
            maaslog.warning("IP extractor extraction_pattern missing for %s" %
                            power_type)
            return None
        match = re.match(extraction_pattern, field_value)
        if match:
            return match.group('address')
        # no match found - return None
        return None

    def get_layer2_usable_rack_controllers(self, with_connection=True):
        """Return a list of `RackController`'s that have the ability to access
        this `BMC` directly through a layer 2 connection."""
        ip_address = self.ip_address
        if ip_address is None or ip_address.ip is None or ip_address.ip == '':
            return set()

        # The BMC has a valid StaticIPAddress set. Make sure that the subnet
        # is correct for that BMC.
        subnet = Subnet.objects.get_best_subnet_for_ip(ip_address.ip)
        if subnet is not None and self.ip_address.subnet_id != subnet.id:
            self.ip_address.subnet = subnet
            self.ip_address.save()

        # Circular imports.
        from maasserver.models.node import RackController
        return RackController.objects.filter_by_url_accessible(
            ip_address.ip, with_connection=with_connection)

    def get_routable_usable_rack_controllers(self, with_connection=True):
        """Return a list of `RackController`'s that have the ability to access
        this `BMC` through a route on the rack controller."""
        routable_racks = [
            relationship.rack_controller
            for relationship in (self.routable_rack_relationships.all(
            ).select_related("rack_controller")) if relationship.routable
        ]
        if with_connection:
            conn_rack_ids = [client.ident for client in getAllClients()]
            return [
                rack for rack in routable_racks
                if rack.system_id in conn_rack_ids
            ]
        else:
            return routable_racks

    def get_usable_rack_controllers(self, with_connection=True):
        """Return a list of `RackController`'s that have the ability to access
        this `BMC` either using layer2 or routable if no layer2 are available.
        """
        racks = self.get_layer2_usable_rack_controllers(
            with_connection=with_connection)
        if len(racks) == 0:
            # No layer2 routable rack controllers. Use routable rack
            # controllers.
            racks = self.get_routable_usable_rack_controllers(
                with_connection=with_connection)
        return racks

    def get_client_identifiers(self):
        """Return a list of identifiers that can be used to get the
        `rpc.common.Client` for this `BMC`.

        :raise NoBMCAccessError: Raised when no rack controllers have access
            to this `BMC`.
        """
        rack_controllers = self.get_usable_rack_controllers()
        identifers = [controller.system_id for controller in rack_controllers]
        return identifers

    def is_accessible(self):
        """If the BMC is accessible by at least one rack controller."""
        racks = self.get_usable_rack_controllers(with_connection=False)
        return len(racks) > 0

    def update_routable_racks(self, routable_racks_ids,
                              non_routable_racks_ids):
        """Set the `routable_rack_controllers` relationship to the new
        information."""
        BMCRoutableRackControllerRelationship.objects.filter(
            bmc=self.as_bmc()).delete()
        self._create_racks_relationship(routable_racks_ids, True)
        self._create_racks_relationship(non_routable_racks_ids, False)

    def _create_racks_relationship(self, rack_ids, routable):
        """Create `BMCRoutableRackControllerRelationship` for list of
        `rack_ids` and wether they are `routable`."""
        # Circular imports.
        from maasserver.models.node import RackController
        for rack_id in rack_ids:
            try:
                rack = RackController.objects.get(system_id=rack_id)
            except RackController.DoesNotExist:
                # Possible it was delete before this call, but very very rare.
                pass
            BMCRoutableRackControllerRelationship(bmc=self,
                                                  rack_controller=rack,
                                                  routable=routable).save()
Esempio n. 38
0
 class MessageManager(Manager.from_queryset(MessageQuerySet)):
     """Message manager"""
     pass
# -*- coding: utf-8 -*-
from __future__ import absolute_import

from django.db.models import Manager

# Need to substitute model_utils in Django<1.7
try:
    Manager.from_queryset
except AttributeError:
    from model_utils.managers import PassThroughManager as Manager
    Manager.from_queryset = Manager.for_queryset_class

from .queryset import CursorQueryset


CursorManager = Manager.from_queryset(CursorQueryset)
Esempio n. 40
0
class MutationManager(Manager.from_queryset(MutationQuerySet)):
    def get_by_natural_key(self, genome, locus, name):
        return self.get(gene_locus__genome__code=genome,
                        gene_locus__name=locus,
                        name=name)
Esempio n. 41
0
# -*- coding: utf-8 -*-

"""Manager and queryset for the redirects app."""

from django.db.models import Manager
from django.db.models.query import QuerySet


class RedirectQuerySet(QuerySet):

    def get_redirect_path(self, path, language=None, version_slug=None):
        for redirect in self.select_related('project'):
            new_path = redirect.get_redirect_path(
                path=path,
                language=language,
                version_slug=version_slug,
            )
            if new_path:
                return new_path
        return None


RedirectManager = Manager.from_queryset(RedirectQuerySet)
Esempio n. 42
0
class Order_basic(models.Model):
    """订单基本信息"""

    # 订单号
    orderId = models.CharField(max_length=100, verbose_name=_("支付流水号"))

    # 用户,一个用户多个收货地址
    consumer = models.ForeignKey(
        User,
        verbose_name=_('用户名'),
        max_length=50,
        related_name='order_basic',
        on_delete=models.CASCADE,
    )

    # 收货地址,后期改成下拉列表的形式
    region = models.ForeignKey(Address,
                               verbose_name=_('收货人'),
                               on_delete=models.CASCADE,
                               related_name='order_basic')
    # 支付方式
    payment_choice = (('1', '货到付款'), ('2', '微信支付'), ('3', '支付宝'), ('4',
                                                                   '银联支付'))
    payment = models.CharField(
        verbose_name=_('支付方式'),
        choices=payment_choice,
        max_length=1,
    )

    # 商品总数
    commodity_total_counts = models.PositiveIntegerField(
        verbose_name=_('商品总数'),
        default=1,
        validators=[
            MaxValueValidator(10000, message=_('订单中商品总数不超过10000件')),
        ])
    # 商品总价钱
    total_price = models.DecimalField(
        max_digits=9,
        decimal_places=2,
        verbose_name=_('商品总价格'),
        validators=[
            MaxValueValidator(99999999.99,
                              message=_('商品的总价格不能超过999999.99人民币')),
        ],
        null=True)

    # 产生订单日期
    generate_time = models.DateTimeField(verbose_name=_('生成订单时间'),
                                         auto_now_add=True)

    # 审核订单完毕日期
    check_time = models.DateTimeField(verbose_name=_('审核完毕订单时间'),
                                      auto_now=True)

    # 交易编号,支付包会返回的一个编号
    trade_number = models.CharField(verbose_name=_('交易编号'),
                                    max_length=128,
                                    null=True)

    # 订单状态
    status_choice = (
        ("1", '代付款'),  # 用户提交订单,尚未付款,此时会锁定库存
        ("2", '代发货'),  # 用户付款后,等待商家接单前
        ("3", '代收货'),  # 用户付款后,等待收获
        ("4", '交易成功'),  # 用户确认收货之后,订单完成交易
        ("5", '已取消'),  # 付款前取消订单
        ("6", '售后中'),  # 商家发货或付款后,用户取消订单
        ("7", '交易关闭'),  # 取消订单或售后结束或退货成功都转移到交易关闭
        ("8", '正在退货'),  # 用户选择退货,移至此
        ("9", '退款成功'),  # 用户选择退货,移至此
    )

    status = models.CharField(
        verbose_name=_('订单状态'),
        max_length=1,
        choices=status_choice,
        default=1,
    )

    # 是否审核(同意接单)
    checked = models.BooleanField(verbose_name=_('是否审核'), default=False)

    # 是否可以评论
    remarked = models.BooleanField(verbose_name=_('是否可以评论'), default=False)

    # 用户删除订单状态,假删除
    delete_consumer = models.BooleanField(verbose_name=_('消费者是否删除订单'),
                                          default=False)

    # 商家删除订单状态,假删除
    delete_shopper = models.BooleanField(verbose_name=_('商家是否删除订单'),
                                         default=False)

    # 订单提交有效时间
    efficient_time = models.DateTimeField(verbose_name=_('订单过期时间'),
                                          null=True,
                                          auto_now=True)

    order_basic_ = Manager()

    class Meta:
        db_table = 'Order_basic'
        verbose_name = _('订单信息表')
        verbose_name_plural = _('订单信息表')

    def __str__(self):
        return '订单号:{}'.format(self.orderId)