예제 #1
0
파일: models.py 프로젝트: francepremium/hp
class Record(models.Model):
    form = models.ForeignKey('form_designer.Form')
    environment = models.ForeignKey('appstore.Environment')

    data = jsonfield.JSONField(db_type='json')
    text_data = models.TextField()

    string_representation = models.CharField(max_length=100, blank=True)

    search_index = VectorField()
    objects = SearchManager(fields=('text_data', ),
                            auto_update_search_field=True)

    def get_absolute_url(self):
        return reverse('formapp_record_detail', args=(self.pk, ))

    def __unicode__(self):
        return self.string_representation

    @property
    def feature(self):
        return self.form.appform.app.provides

    class Meta:
        ordering = ('text_data', )
예제 #2
0
class Human(MPTTModel):
    full_name = models.CharField(max_length=150,
                                 default="",
                                 verbose_name='ФИО')
    """position = models.ForeignKey(Position, null=True, on_delete=models.SET_NULL, verbose_name='Должность')"""
    position = models.CharField(max_length=150, verbose_name='Должность')
    employment_date = models.DateField(auto_now=False,
                                       verbose_name='Дата прийома на работу')
    salary = models.IntegerField(verbose_name='Зарплата')
    parent = TreeForeignKey('self',
                            on_delete=models.SET_NULL,
                            null=True,
                            blank=True,
                            related_name="children",
                            verbose_name='Начальник')

    search_index = VectorField()

    search_manager = SearchManager(fields=('full_name', 'position'),
                                   config='pg_catalog.russian',
                                   search_field='search_index',
                                   auto_update_search_field=True)

    class MPTTMeta:
        unique_together = (('full_name', 'parent'), )

    def __str__(self):
        return self.full_name
예제 #3
0
파일: models.py 프로젝트: vmnet04/pnews
class Document(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField(auto_now_add=True)
    modified_date = models.DateTimeField(auto_now=True)
    body = models.TextField()
    url = models.CharField(max_length=500)
    entities = models.ManyToManyField(Entity)
    feed = models.ForeignKey(Feed)
    cluster = models.ForeignKey(Cluster, null=True, blank=True)

    search_index = VectorField()
    objects = SearchManager(fields=('title', 'body'),
                            config='pg_catalog.english',
                            search_field='search_index',
                            auto_update_search_field=True)

    def content(self):
        text = self.title
        if self.body:
            text = text + ' \n\n' + self.body
        return text

    def highlighted(self):
        return Highlighter.highlight_text(self.content(), None,
                                          self.entities.all())

    def num_entities(self):
        return self.entities.count()

    def __str__(self):
        return self.title
예제 #4
0
class Fingerprint(models.Model):
    ip = models.GenericIPAddressField()
    port = models.PositiveIntegerField()
    service = models.CharField(max_length=64, blank=True)

    os = models.CharField(max_length=32, blank=True)
    info = models.CharField(max_length=256, blank=True)
    product = models.CharField(max_length=256, blank=True)
    hostname = models.CharField(max_length=128, blank=True)
    device = models.CharField(max_length=128, blank=True)
    version = models.CharField(max_length=128, blank=True)
    cpes = ArrayField(models.CharField(max_length=128), default=[])

    certificate = JSONField(default={})
    banner = models.TextField()
    raw = models.TextField()

    timestamp = models.DateTimeField(auto_now=True)

    search_index = VectorField(db_index=False)
    objects = SearchManager(
        fields=('os', 'info', 'service', 'product', 'hostname', 'device', 'version', 'banner'),
        config='chinese',
        search_field='search_index',
        auto_update_search_field=True
    )

    def __str__(self):
        return '%s:%d' % (self.ip, self.port)
예제 #5
0
class Book(models.Model):
    author = models.ForeignKey(Person)
    name = models.CharField(max_length=32)
    search_index = VectorField()

    objects = SearchManager(fields=('name', ),
                            search_field='search_index',
                            auto_update_search_field=True,
                            config='names')

    def __str__(self):
        return self.name
예제 #6
0
class Person3(models.Model):
    name = models.CharField(max_length=32)
    description = models.TextField()
    search_index = VectorField()

    objects = SearchManager(fields=('name', 'description'),
                            search_field='search_index',
                            auto_update_search_field=True,
                            config='names')

    def __str__(self):
        return self.name
예제 #7
0
class Person2(models.Model):
    name = models.CharField(max_length=32)
    description = models.TextField()
    search_index = VectorField()

    objects = SearchManager(
        fields=(('name', 'A'), ('description', 'B')),
        search_field='search_index',
        config='names',
    )

    def __str__(self):
        return self.name
예제 #8
0
class Performer(Agent):
    performer_id = models.AutoField(primary_key=True)
    about = models.CharField(max_length=255, blank=True)
    bio = models.TextField(blank=True)
    artists_we_like = models.CharField(max_length=255, blank=True)
    band_members = models.CharField(max_length=255, blank=True)
    booking_agent = models.CharField(max_length=255, blank=True)
    category = models.CharField(max_length=255, blank=True)
    cover_id = models.IntegerField(blank=True, null=True)
    cover_source = models.CharField(max_length=1000, blank=True)
    current_location = models.CharField(max_length=255, blank=True)
    description = models.TextField(blank=True)
    genre = models.CharField(max_length=255, blank=True)
    hometown = models.CharField(max_length=255, blank=True)
    likes = models.IntegerField(blank=True, null=True)
    link = models.CharField(max_length=255, blank=True)
    band_type = models.CharField(max_length=55)
    record_label = models.CharField(max_length=255, blank=True)
    talking_about_count = models.PositiveIntegerField(null=True)
    website = models.CharField(max_length=255, blank=True)
    twitter_handle = models.CharField(max_length=255, blank=True)
    sound_path = models.URLField(max_length=500, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    edited = models.DateTimeField(blank=True, null=True, auto_now=True)
    email_address = models.EmailField(max_length=255, blank=True)
    deleted = models.BooleanField(default=0)
    # Foreign
    location = models.ForeignKey(Location,
                                 models.DO_NOTHING,
                                 blank=True,
                                 null=True)
    events = models.ManyToManyField(Event)
    genres = models.ManyToManyField(Genre, through="PerformerGenre")
    accounts = models.ManyToManyField(Account)

    #Fulltextindex
    genre_index = VectorField()
    objects = SearchManager(
        fields=(('about', 'A'), ('bio', 'B'), ('genre', 'A'), ('description',
                                                               'B')),
        config='pg_catalog.english',  # this is default
        search_field='genre_index',  # this is default
        auto_update_search_field=True)

    # fts_index = TSVectorField(
    #     (('about', 'A'), ('bio', 'B'), ('genre', 'A'), ('description', 'B')),
    #     dictionary='english'
    # )

    def __str__(self):
        return self.name
예제 #9
0
class Document(models.Model):
    title = models.CharField(max_length=200)
    text = models.TextField()

    search_index = VectorField()

    objects = SearchManager(
        fields=(('title', 'A'), ('text', 'D')),
        config='pg_catalog.english',  # this is default
        search_field='search_index',  # this is default
        auto_update_search_field=True)

    def __str__(self):
        return self.title
예제 #10
0
class Post(models.Model):
    class Meta:
        verbose_name = 'Статья'
        verbose_name_plural = 'Статьи'
        ordering = ['-created']
        db_table = 'article'

    title = models.CharField(max_length=200, verbose_name='Заголовок')
    body = RichTextUploadingField(
        verbose_name='Статья',
        config_name='default')  #models.TextField(verbose_name='Статья')
    slug = models.SlugField(max_length=200, unique=True, verbose_name='Ссылка')
    created = models.DateTimeField(auto_now_add=True,
                                   verbose_name='Дата создания')
    image = models.ImageField(upload_to='post',
                              blank=True,
                              default='post/default.jpg')
    pageviews = models.PositiveIntegerField(
        verbose_name='Количество просмотров', default=0, blank=True)
    tags = TaggableManager(through=RuTaggedItem)  #through=RuTaggedItem
    category = models.ForeignKey(Category,
                                 default='',
                                 verbose_name='Категория')
    description = models.TextField(blank=True,
                                   null=True,
                                   verbose_name='Описание')

    search_index = VectorField()
    objects = SearchManager(fields=('title', 'description'),
                            config='pg_catalog.russian',
                            search_field='search_index',
                            auto_update_search_field=True)

    def __str__(self):
        return self.title

    def get_object(self):
        return get_object_or_404(Post, slug__iexact=self.kwargs['slug'])

    def get_absolute_url(self):
        return reverse("article_detail", kwargs={"slug": self.slug})

    def image_tag(self):
        if self.image:
            return u'<img src="%s" style="width:100px" />' % self.image.url
        else:
            return '(нет изображения)'

    image_tag.short_description = 'Изображение'
    image_tag.allow_tags = True
예제 #11
0
class Page(models.Model):
    url = models.CharField(max_length=255, primary_key=True)
    title = models.CharField(max_length=255, blank=True)
    text = models.TextField(blank=True)
    lang = models.CharField(max_length=2, blank=True)
    search_index = VectorField()

    objects = models.Manager()
    search_manager = SearchManager(fields=('title', 'text'),
                                   config='pg_catalog.russian',
                                   search_field='search_index',
                                   auto_update_search_field=True)

    def __str__(self):
        return self.url
예제 #12
0
class Subject(models.Model):
    description = models.CharField(max_length=300, null=False, blank=False, unique=True)

    search_index = VectorField()

    objects = SearchManager(
        fields=('description', ),
        config='pg_catalog.english',
        search_field='search_index',
        auto_update_search_field=True
    )
    search_subject = SubjectManager()

    def __unicode__(self):
        return self.description
예제 #13
0
파일: models.py 프로젝트: snickaren/CIPAC
class Card(BaseCard):
    box = models.ForeignKey(Box, related_name="cards", verbose_name="kort")
    search_index = VectorField()
    objects = SearchManager(fields=('name', 'ocr_text'),
                            config='pg_catalog.swedish',
                            search_field='search_index',
                            auto_update_search_field=True)

    # readonly field to show preview pic in django admin interface
    def image_tag(self):
        return """<img style="width:450px" alt="Kort %s" src="/static/%s/%s" />""" % (
            self.catalog_sequence_number, settings.HSNOMINAL_CARDS_SUBFOLDER,
            self.box.folder_name + "/" + self.filename)

    image_tag.short_description = 'Bild'
    image_tag.allow_tags = True
예제 #14
0
class Network(models.Model):
    network = CidrAddressField(primary_key=True)
    name = models.CharField(max_length=255, blank=True, null=True)
    gateway = InetAddressField(blank=True, null=True)
    description = models.TextField(blank=True, null=True)
    vlans = models.ManyToManyField(
        "Vlan", through="NetworkToVlan", related_name="vlan_networks"
    )
    dhcp_group = models.ForeignKey(
        "DhcpGroup", db_column="dhcp_group", blank=True, null=True
    )
    shared_network = models.ForeignKey(
        "SharedNetwork", db_column="shared_network", blank=True, null=True
    )
    changed = models.DateTimeField(auto_now=True)
    changed_by = models.ForeignKey(settings.AUTH_USER_MODEL, db_column="changed_by")

    search_index = VectorField()

    # objects = NetworkQuerySet.as_manager()
    objects = NetworkManager.from_queryset(NetworkQuerySet)()

    searcher = SearchManager(
        fields=("name", "description"),
        config="pg_catalog.english",  # this is default
        search_field="search_index",  # this is default
        auto_update_search_field=True,
    )

    tags = TaggableManager(through=TaggedNetworks, blank=True)

    # Forcing pk as string
    @property
    def pk(self):
        return str(self.network)

    def __str__(self):
        return "%s" % self.network

    class Meta:
        db_table = "networks"
        permissions = (
            ("is_owner_network", "Is owner"),
            ("add_records_to_network", "Can add records to"),
        )
        default_permissions = ("add", "change", "delete", "view")
        ordering = ("network",)
예제 #15
0
class PermitData(models.Model):
    # Attach this PermitData object to a specific PermitArea object
    owner = models.ForeignKey(PermitArea, related_name='data')

    # These are basic fields supported by all the municipalities that we
    # currently pull data from. They are all character fields.
    name = models.CharField(max_length=1024, null=True)
    proj_id = models.CharField(max_length=1024, null=True)
    #link = models.CharField(max_length=1024, null=True)
    info_link = models.ForeignKey(InfoLink, null=True)
    status = models.CharField(max_length=1024, null=True)
    comment = models.TextField(null=True)
    # We also store this here in case it changes over time.
    # Having it here also gives us full text search on category
    category = models.CharField(max_length=1024, null=True)

    # Date on which the values in this row were captured
    saved_on = models.DateField()

    # We must use a GeoManager because of our foreign key relation to the
    # PermitArea object. Otherwise we'll get errors.
    objects = GeoManager()

    VALUE_FIELDS = ('name', 'comment', 'proj_id', 'status', 'category')

    # In order to support full text search, we have a SECOND model
    # that allows for that access pattern. Attempts to use the GIS
    # mixin that is available in the pgfulltext module failed
    # miserably, so we go with this route for now. The main drawback
    # is that we must manually update the search fields on save
    # because this is not the default manager. That's not too terrible,
    # however, because we only ever save from one place inside kmlutils.py.
    search_index = VectorField()
    text = SearchManager(
        # List all the fields that you want indexed
        fields=VALUE_FIELDS,
        # This may be redundant now. Not sure.
        auto_update_search_field=False)

    @classmethod
    def create_query_dict(cls, area, data_dict):
        for field in PermitData.VALUE_FIELDS:
            if field not in data_dict:
                data_dict[field] = None
        data_dict['owner'] = area
        return data_dict
예제 #16
0
class Note(TimeStampedModel):
    title = models.CharField(max_length=100)
    body = models.TextField()
    raw_body = models.TextField()
    name = models.CharField(max_length=50)
    tags = models.ManyToManyField("Tag",
                                  related_name="notes",
                                  through="NoteTagRelation")

    search_index = VectorField()

    objects = SearchManager(fields=(("title", "A"), ("tags__title", "B"),
                                    ("raw_body", "D")),
                            auto_update_search_field=True)

    def __unicode__(self):
        return self.title
예제 #17
0
class Person(models.Model):
    name = models.CharField(max_length=32)
    description = models.TextField()
    search_index = VectorField()

    objects = SearchManager(
        fields=('name', 'description'),
        search_field='search_index',
        config='names',
    )

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        super(Person, self).save(*args, **kwargs)
        self.update_search_field()
예제 #18
0
class SearchIndex(models.Model):
    backoffice_instance = models.CharField(max_length=32)
    model_slug = models.CharField(max_length=32)
    model_id = models.PositiveIntegerField()
    to_index = models.TextField(blank=True)

    search_index = VectorField()

    objects = SearchManager(fields=('to_index', ),
                            search_field='search_index',
                            auto_update_search_field=True)

    class Meta:
        verbose_name = u'search index entry'
        verbose_name_plural = u'search index entries'

    def __unicode__(self):
        return u'%s/%s/%d' % (self.backoffice_instance, self.model_slug,
                              self.model_id)
예제 #19
0
class Story(models.Model):
    title = models.TextField()
    url = models.URLField()
    date = models.DateField()
    primary_image = models.URLField(null=True)
    primary_image_caption = models.TextField(null=True)
    primary_image_rights_information = models.TextField(null=True)
    subjects = models.TextField(null=True)
    station = models.TextField(null=True)
    state = models.TextField(null=True)
    place = models.TextField(null=True)
    keywords = models.TextField(null=True)
    location = PointField()

    search_index = VectorField()

    objects = SearchManager(fields=('title', 'primary_image_caption'),
                            config='pg_catalog.english',
                            search_field='search_index',
                            auto_update_search_field=True)
예제 #20
0
class Person4(models.Model):
    INDEXED_KEY = 'indexed_key'

    name = models.CharField(max_length=32)
    description = models.TextField()
    data = models.TextField(default='{}')

    search_index = VectorField()
    data_search_index = VectorField()

    objects = SearchManager(fields=('name', 'description'),
                            search_field='search_index',
                            auto_update_search_field=True,
                            config='names')

    def __str__(self):
        return self.name

    def update_search_field(self, **kwargs):
        self._fts_manager.update_search_field(**kwargs)
        self._fts_manager.update_search_field(search_field='data_search_index',
                                              fields=('data', ),
                                              config='names',
                                              extra={
                                                  'key': self.INDEXED_KEY,
                                              })

    @staticmethod
    def _convert_field_to_db(field, weight, config, using, extra=None):
        if field.name != 'data':
            # Use the default converter
            return

        connection = connections[using]
        qn = connection.ops.quote_name

        return "setweight(to_tsvector('%s', coalesce(to_json(%s.%s::json) ->> '%s', '')), '%s')" % (
            config, qn(field.model._meta.db_table), qn(
                field.column), extra['key'], weight)
예제 #21
0
class Topic(models.Model):
    PROGRAM_CHOICES = (
        ("SBIR", "SBIR"),
        ("STTR", "STTR"),
    )

    topic_number = models.TextField(unique=True)
    solicitation = models.ForeignKey(Solicitation, related_name='solicitation')
    url = models.TextField(unique=True)
    title = models.TextField()
    agency = models.TextField(blank=True, null=True)
    program = models.CharField(max_length=10, choices=PROGRAM_CHOICES)
    description = models.TextField()
    objective = models.TextField()
    fts = VectorField()
    saved_by = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                      blank=True,
                                      null=True,
                                      related_name='saved_topics')

    objects = SearchManager(fields=None,
                            search_field='fts',
                            auto_update_search_field=False)
예제 #22
0
class Website(models.Model):
    domain = models.CharField(max_length=64)
    ip = models.GenericIPAddressField()
    port = models.IntegerField(default=80)
    title = models.TextField(blank=True)

    url = models.CharField(max_length=512)
    headers = JSONField(default={})
    raw_headers = models.TextField(blank=True)
    html = models.TextField()  # full html source
    app_joint = models.CharField(max_length=256, default='')  # ' '.join(apps), for full search

    timestamp = models.DateTimeField(auto_now=True)

    search_index = VectorField(db_index=False)
    objects = SearchManager(
        fields=('domain', 'url', 'raw_headers', 'app_joint', 'html', 'title'),
        config='chinese',
        search_field='search_index',
        auto_update_search_field=True
    )

    def __str__(self):
        return self.title
예제 #23
0
class Exercise(TimeStampedModel):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             verbose_name=_('Created by'))
    title = models.CharField(max_length=155, verbose_name=_('Title'))
    slug = models.SlugField(_("Slug"), unique_for_date='created', default='')

    description = models.TextField(verbose_name=_('Description'))

    solution_text = models.TextField(verbose_name=_('Text solution'))
    solution_file = models.FileField(verbose_name=_('File solution'),
                                     blank=True,
                                     null=True)

    search_index = VectorField()

    objects = SearchManager(fields=('title', 'description'),
                            config='pg_catalog.english',
                            search_field='search_index',
                            auto_update_search_field=True)

    tags = TaggableManager()

    def __unicode__(self):
        return self.title
예제 #24
0
class Host(DirtyFieldsMixin, models.Model):
    mac = MACAddressField("Mac Address", primary_key=True)
    hostname = models.CharField(
        max_length=255, unique=True, validators=[validate_hostname], db_index=True
    )
    description = models.TextField(blank=True, null=True)
    address_type_id = models.ForeignKey(
        "network.AddressType",
        blank=True,
        null=True,
        db_column="address_type_id",
        on_delete=models.SET_NULL,
    )
    pools = models.ManyToManyField(
        "network.Pool", through="network.HostToPool", related_name="pool_hosts"
    )
    # freeform_attributes = models.ManyToManyField('Attribute', through='FreeformAttributeToHost',
    #                                             related_name='freeform_hosts',  blank=True, null=True)
    # structured_attributes = models.ManyToManyField('Attribute', through='StructuredAttributeToHost',
    #                                               related_name='structured_hosts',  blank=True, null=True)
    dhcp_group = models.ForeignKey(
        "network.DhcpGroup",
        db_column="dhcp_group",
        verbose_name="DHCP Group",
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
    )
    expires = models.DateTimeField()
    changed = models.DateTimeField(auto_now=True)
    changed_by = models.ForeignKey(settings.AUTH_USER_MODEL, db_column="changed_by")
    last_notified = models.DateTimeField(blank=True, null=True)

    objects = HostManager.from_queryset(HostQuerySet)()

    search_index = VectorField()
    searcher = SearchManager(
        fields=("hostname", "description"),
        config="pg_catalog.english",  # this is default
        search_field="search_index",  # this is default
        auto_update_search_field=True,
    )

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

        # Initialize setters
        self._expire_days = None
        self._user_owners = None
        self._group_owners = None
        self._user = None
        self._master_dns_deleted = False

        self.ip_address = None
        self.pool = None
        self.network = None

        super(Host, self).__init__(*args, **kwargs)

    def __str__(self):
        return self.hostname

    # Overload getattr for get original values
    def __getattr__(self, name):
        if name.startswith("original_") and name.split("_", 1)[1] in list(
            self._original_state.keys()
        ):

            def _original(fieldname):
                fieldvalue = self._original_state.get(fieldname, None)
                if fieldvalue is not None:
                    return fieldvalue

            return _original(name.split("_", 1)[1])
        else:
            return self.__getattribute__(name)

    def reset_state(self):
        self._expire_days = None
        self._user_owners = None
        self._group_owners = None
        self._user = None
        self._master_dns_deleted = False

        self.ip_address = None
        self.pool = None
        self.network = None

        try:
            del self.ip_addresses
            del self.master_ip_address
            del self.owners
            del self._pools_cache
            del self._addresses_cache
        except AttributeError:
            pass

    @cached_property
    def _addresses_cache(self):
        return list(self.addresses.all())

    @cached_property
    def _pools_cache(self):
        return list(self.pools.all())

    @property
    def expire_days(self):
        if self._expire_days:
            return self._expire_days
        else:
            return self.get_expire_days()

    @expire_days.setter
    def expire_days(self, days):
        self._expire_days = days

    @cached_property
    def owners(self):
        return self.get_owners()

    def get_owners(
        self,
        ids_only=False,
        name_only=False,
        owner_detail=False,
        users_only=False,
        user_perms_prefetch=None,
        group_perms_prefetch=None,
    ):
        # users_dict = get_users_with_perms(self, attach_perms=True, with_group_users=False)
        # groups_dict = get_groups_with_perms(self, attach_perms=True)
        content_type = ContentType.objects.get_for_model(self)

        users = []
        if user_perms_prefetch:
            user_perms = list(
                filter(
                    lambda x: x.object_pk == str(self.mac)
                    and x.permission.codename == "is_owner_host",
                    user_perms_prefetch,
                )
            )
        else:
            user_perms = UserObjectPermission.objects.filter(
                content_type=content_type,
                object_pk=str(self.mac),
                permission__codename="is_owner_host",
            )
        for perm in user_perms:
            users.append(perm.user)

        groups = []
        if group_perms_prefetch:
            group_perms = list(
                filter(
                    lambda x: x.object_pk == str(self.mac)
                    and x.permission.codename == "is_owner_host",
                    group_perms_prefetch,
                )
            )
        else:
            group_perms = GroupObjectPermission.objects.filter(
                content_type=content_type,
                object_pk=str(self.mac),
                permission__codename="is_owner_host",
            )
        for perm in group_perms:
            groups.append(perm.group)

        # for user, permissions in users_dict.iteritems():
        #    if 'is_owner_host' in permissions:
        #        users.append(user)

        # groups = []
        # for group, permissions in groups_dict.iteritems():
        #    if 'is_owner_host' in permissions:
        #        groups.append(group)

        if users_only:
            User = get_user_model()
            users_from_groups = [
                user for user in User.objects.filter(groups__in=groups)
            ]
            users = list(set(users + users_from_groups))
            return users

        if owner_detail:
            users = [
                (user.pk, user.username, user.get_full_name(), user.email)
                for user in users
            ]
            groups = [(group.pk, group.name) for group in groups]

        elif ids_only:
            users = [user.pk for user in users]
            groups = [group.pk for group in groups]

        elif name_only:
            users = [user.username for user in users]
            groups = [group.name for group in groups]

        return users, groups

    @property
    def user_owners(self):
        if self._user_owners:
            return self._user_owners
        else:
            return [owner.username for owner in self.owners[0]]

    @user_owners.setter
    def user_owners(self, owners):
        self._user_owners = owners

    @property
    def user(self):
        if self._user:
            return self._user
        else:
            return self.changed_by

    @user.setter
    def user(self, value):
        self._user = value

    @property
    def master_dns_deleted(self):
        return self._master_dns_deleted

    @master_dns_deleted.setter
    def master_dns_deleted(self, value):
        self._master_dns_deleted = value

    @property
    def group_owners(self):
        if self._group_owners:
            return self._group_owners
        else:
            return [owner.name for owner in self.owners[1]]

    @group_owners.setter
    def group_owners(self, owners):
        self._group_owners = owners

    @property
    def is_dynamic(self):
        if self.is_dirty() is False:
            return True if self._pools_cache else False
        else:
            return True if self.pools.all() else False

    @property
    def is_static(self):
        return True if self.is_dynamic is False else False

    # This is set on the queryset manager now.
    # @property
    # def is_disabled(self):
    #     try:
    #         return True if self.disabled_host else False
    #     except ObjectDoesNotExist:
    #         return False

    @property
    def disabled_host(self):
        if self.is_disabled:
            return Disabled.objects.filter(pk=self.mac).first()
        else:
            return None

    @property
    def is_expired(self):
        return True if self.expires < timezone.now() else False

    @property
    def address_type(self):
        # TODO: Address type is old and eventually will be deprecated.
        # Try to set address type if doesn't exist if host already exists in DB.
        if self.pk and not self.address_type_id:
            from openipam.network.models import AddressType, NetworkRange

            addresses = self._addresses_cache
            pools = self._pools_cache

            try:
                # if (len(addresses) + len(pools)) > 1:
                #     self.address_type = None
                # elif addresses:
                if addresses:
                    try:
                        ranges = NetworkRange.objects.filter(
                            range__net_contains_or_equals=addresses[0].address
                        )
                        if ranges:
                            self.address_type_id = AddressType.objects.get(
                                ranges__in=ranges
                            )
                        else:
                            raise AddressType.DoesNotExist
                    except AddressType.DoesNotExist:
                        self.address_type_id = AddressType.objects.get(is_default=True)
                elif pools:
                    self.address_type_id = AddressType.objects.get(pool=pools[0])
            except AddressType.DoesNotExist:
                self.address_type_id = None

        return self.address_type_id

    @address_type.setter
    def address_type(self, value):
        self.address_type_id = value

    @property
    def mac_stripped(self):
        mac = str(self.mac)
        mac = [c for c in mac if c.isdigit() or c.isalpha()]
        return "".join(mac)

    @property
    def mac_last_seen(self):
        gul_mac = GulRecentArpBymac.objects.filter(mac=self.mac).order_by("-stopstamp")

        if gul_mac:
            return gul_mac[0].stopstamp
        else:
            return None

    @property
    def oui(self):
        return OUI.objects.extra(
            where=["'%s' >= ouis.start and '%s' <= ouis.stop" % (self.mac, self.mac)]
        ).first()

    @cached_property
    def master_ip_address(self):
        if self.is_static:
            if not self.ip_addresses:
                return None
            elif len(self.ip_addresses) == 1:
                return self.ip_addresses[0]
            else:
                address = self.addresses.filter(arecords__name=self.hostname).first()
                return str(address) if address else self.ip_addresses[0]
        return None

    @cached_property
    def ip_addresses(self):
        return [str(address) for address in self.addresses.all()]

    def delete_ip_address(self, user, address):

        if isinstance(address, string_types):
            address = self.addresses.filter(address=address)

        # Delete DNS PTR and A Records
        self.delete_dns_records(user=user, addresses=address)

        # Release address
        address.release(user=user)

    def add_ip_address(self, user=None, ip_address=None, network=None, hostname=None):
        from openipam.network.models import Network, Address
        from openipam.dns.models import DnsRecord, DnsType

        user = user or self._user
        if not user:
            raise Exception("A User must be given to add ip addresses.")

        if not hostname:
            raise ValidationError("A hostname is required.")

        address = None

        # Check to see if hostname already taken for any hosts other then the current one if being updated.
        used_hostname = (
            DnsRecord.objects.filter(
                dns_type__in=[DnsType.objects.A, DnsType.objects.AAAA], name=hostname
            )
            .exclude(ip_content__address=self.master_ip_address)
            .first()
        )
        if used_hostname:
            raise ValidationError(
                "Hostname %s is already assigned to DNS A Record: %s."
                % (hostname, used_hostname.ip_content)
            )

        user_pools = get_objects_for_user(
            user, ["network.add_records_to_pool", "network.change_pool"], any_perm=True
        )

        user_nets = get_objects_for_user(
            user,
            [
                "network.add_records_to_network",
                "network.is_owner_network",
                "network.change_network",
            ],
            any_perm=True,
        )

        if network:
            if isinstance(network, string_types):
                network = Network.objects.get(network=network)

            if not user_nets.filter(network=network.network):
                raise ValidationError(
                    "You do not have access to assign host '%s' to the "
                    "network specified: %s." % (hostname, network)
                )

            try:
                network_address = (
                    Address.objects.filter(
                        Q(pool__in=user_pools) | Q(pool__isnull=True),
                        Q(leases__isnull=True)
                        | Q(leases__abandoned=True)
                        | Q(leases__ends__lte=timezone.now())
                        | Q(leases__host=self),
                        network=network,
                        host__isnull=True,
                        reserved=False,
                    )
                    .order_by("address")
                    .first()
                )

                if not network_address:
                    raise Address.DoesNotExist
                else:
                    address = network_address

            except ValidationError:
                raise ValidationError("The network '%s' is invalid." % network)
            except Address.DoesNotExist:
                raise ValidationError(
                    "There are no avaiable addresses for the network entered: %s"
                    % network
                )

        elif ip_address:
            # Validate IP Address
            try:
                validate_ipv46_address(ip_address)
            except ValidationError:
                raise ValidationError(
                    "IP Address %s is invalid.  Enter a valid IPv4 or IPv6 address."
                    % ip_address
                )

            if ip_address in self.ip_addresses:
                raise ValidationError(
                    "IP address %s is already assigned to this host." % ip_address
                )

            try:
                address = Address.objects.get(
                    Q(pool__in=user_pools)
                    | Q(pool__isnull=True)
                    | Q(network__in=user_nets),
                    Q(leases__isnull=True)
                    | Q(leases__abandoned=True)
                    | Q(leases__ends__lte=timezone.now())
                    | Q(leases__host=self),
                    Q(host__isnull=True) | Q(host=self),
                    address=ip_address,
                    reserved=False,
                )
            except ValidationError:
                raise ValidationError(
                    "There IP Address %s is not available." % ip_address
                )
            except Address.DoesNotExist:
                raise ValidationError(
                    "There are no avaiable addresses for the IP entered: %s"
                    % ip_address
                )
        else:
            raise ValidationError(
                "A Network or IP Address must be given to assign this host an address."
            )

        # Make sure pool is clear on addresses we are assigning.
        address.pool_id = None
        address.host = self
        address.changed_by = user
        address.save()

        # Update A and PTR dns records
        self.add_dns_records(user=user, hostname=hostname, address=address)

        return address

    def delete_dns_records(
        self, user=None, delete_only_master_dns=False, delete_dchpdns=True, addresses=[]
    ):
        from openipam.dns.models import DnsType

        user = user or self._user
        if not user:
            raise Exception("A User must be given to delete dns records for host.")

        if self.master_dns_deleted is False:

            # If addresses list is empty, we use the master address
            # So By default we are deleting DNS for just the primary address
            if not addresses:
                addresses = self.addresses.filter(address=self.master_ip_address)

            if delete_only_master_dns:
                # Here we only delete the master DNS (A and PTR) record
                # If modifying a host, this will get recreated later in the call.
                self.dns_records.filter(
                    Q(name=self.original_hostname)
                    | Q(text_content=self.original_hostname),
                    dns_type__in=[
                        DnsType.objects.PTR,
                        DnsType.objects.A,
                        DnsType.objects.AAAA,
                    ],
                ).update(changed=timezone.now(), changed_by=user)
                # Delete Assocatiated PTR and A or AAAA records.
                self.dns_records.filter(
                    Q(name=self.original_hostname)
                    | Q(text_content=self.original_hostname),
                    dns_type__in=[
                        DnsType.objects.PTR,
                        DnsType.objects.A,
                        DnsType.objects.AAAA,
                    ],
                ).delete()
            else:
                # TODO: There is a foreign key for host on this table but we cant use it
                # cause are aren't sure this will get everything due to not all records
                # using the FK.
                # Update Changed by Assocatiated PTR and A or AAAA records.
                self.dns_records.filter(
                    Q(
                        name__in=[
                            address.address.reverse_pointer for address in addresses
                        ]
                    )
                    | Q(ip_content__in=[address for address in addresses]),
                    dns_type__in=[
                        DnsType.objects.PTR,
                        DnsType.objects.A,
                        DnsType.objects.AAAA,
                    ],
                ).update(changed=timezone.now(), changed_by=user)
                # Delete Assocatiated PTR and A or AAAA records.
                self.dns_records.filter(
                    Q(
                        name__in=[
                            address.address.reverse_pointer for address in addresses
                        ]
                    )
                    | Q(ip_content__in=[address for address in addresses]),
                    dns_type__in=[
                        DnsType.objects.PTR,
                        DnsType.objects.A,
                        DnsType.objects.AAAA,
                    ],
                ).delete()

            if delete_dchpdns:
                # Delete DHCP DNS records for dynamics if they exist.
                DhcpDnsRecord.objects.filter(
                    host__hostname=self.original_hostname
                ).delete()

            if not addresses or self.master_ip_address in [
                str(address.address) for address in addresses
            ]:
                self.master_dns_deleted = True

    def add_dns_records(self, user=None, hostname=None, address=None):
        from openipam.dns.models import DnsRecord, DnsType
        from openipam.network.models import Address

        user = user or self._user
        if not user:
            raise Exception("A User must be given to add dns records for host.")

        # Only do this on static hosts.
        if self.is_static:

            if not hostname:
                hostname = self.hostname

            if isinstance(address, string_types):
                address = Address.objects.filter(address=address).first()
            elif not address:
                address = Address.objects.filter(address=self.master_ip_address).first()

            # Add Associated PTR
            DnsRecord.objects.add_or_update_record(
                user=user,
                name=address.address.reverse_pointer,
                content=hostname,
                dns_type=DnsType.objects.PTR,
                host=self,
            )

            # Add Associated A or AAAA record
            arecord = DnsRecord.objects.filter(
                dns_type__in=[DnsType.objects.A, DnsType.objects.AAAA],
                host=self,
                name=hostname,
            ).first()
            DnsRecord.objects.add_or_update_record(
                user=user,
                name=hostname,
                content=address.address,
                dns_type=DnsType.objects.A
                if address.address.version == 4
                else DnsType.objects.AAAA,
                host=self,
                record=arecord if arecord else None,
            )

        # Reset dns deleted flag if this is the master hostname
        if hostname == self.hostname:
            self.master_dns_deleted = False

    def get_dns_records(self):
        from openipam.dns.models import DnsRecord

        addresses = self.addresses.all()
        a_record_names = (
            DnsRecord.objects.select_related("ip_content", "host", "dns_type")
            .filter(ip_content__in=addresses)
            .values_list("name")
        )
        dns_records = (
            DnsRecord.objects.select_related("ip_content", "host", "dns_type")
            .filter(
                Q(text_content__in=a_record_names)
                | Q(name__in=a_record_names)
                | Q(ip_content__in=addresses)
                | Q(host=self)
                | Q(text_content=self.hostname)  # For dynamic hosts
            )
            .order_by("dns_type__name")
        )

        return dns_records

    def get_expire_days(self):
        if self.expires:
            delta = self.expires - timezone.now()
            return delta.days if delta.days > 0 else None
        else:
            return None

    def set_expiration(self, expire_days):
        if isinstance(expire_days, int) or isinstance(expire_days, string_types):
            expire_days = timedelta(int(expire_days))
        now = timezone.now()
        self.expires = (
            datetime(now.year, now.month, now.day) + timedelta(1) + expire_days
        )
        self.expires = self.expires.replace(tzinfo=utc)

    def set_mac_address(self, new_mac_address):
        if self.mac and str(self.mac).lower() != str(new_mac_address).lower():
            cursor = connection.cursor()
            cursor.execute(
                """
                UPDATE hosts SET mac = %s WHERE mac = %s
            """,
                [str(new_mac_address), str(self.mac)],
            )
            self.mac = str(new_mac_address).lower()
        elif not self.pk:
            self.mac = str(new_mac_address).lower()

    def set_hostname(self, hostname, user=None):
        user = user or self._user
        if not user:
            raise Exception("A User must be given to save hosts.")

        self.hostname = hostname
        if (
            self.original_hostname
            and self.hostname
            and self.hostname != self.original_hostname
        ):
            self.delete_dns_records(user=user, delete_only_master_dns=True)

    # TODO: Clean this up, I dont like where this is at.
    def set_network_ip_or_pool(self, user=None, delete=False):
        user = user or self._user
        if not user:
            raise Exception("A User must be given to save hosts.")

        # Set the pool if attached to model otherwise find it by address type
        pool = self.pool
        current_pool = self._pools_cache[0] if self._pools_cache else None

        # TODO: Currently un-used function
        if delete:
            # Remove all pools
            self.pools.clear()
            # Delete DNS
            self.delete_dns_records(user=user, addresses=self.addresses.all())
            # Remove all addresses
            self.addresses.release(user=user)

        # If we have a pool, this dynamic and we assign
        if pool and pool != current_pool:
            from openipam.network.models import Pool

            # Delete DNS
            self.delete_dns_records(user=user, addresses=self.addresses.all())
            # Remove all addresses
            self.addresses.release(user=user)

            # TODO: Kill this later.
            host_pool_check = self.host_pools.all()
            if len(host_pool_check) > 1:
                self.pools.clear()

            host_pool = self.host_pools.filter(pool__name=pool).first()
            if host_pool:
                host_pool.changed_by = user
                host_pool.save()
            else:
                # Delete what is there and create a new one.
                self.pools.clear()
                # Assign new pool if it doesn't already exist
                self.host_pools.create(
                    host=self, pool=Pool.objects.get(name=pool), changed_by=user
                )

        # If we have a Network or IP address, then assign that address to host
        elif self.network or (
            self.ip_address and self.ip_address not in self.ip_addresses
        ):

            # Remove all pools
            self.pools.clear()
            # TODO: Look at delete_dns for a way to only delete dhcp dns records.
            try:
                self.dhcpdnsrecord.delete()
            except ObjectDoesNotExist:
                pass

            # Current IP
            current_ip_address = self.master_ip_address

            if current_ip_address:
                # Delete DNS
                self.delete_dns_records(user=user)
                # Release the current IP to add another
                self.addresses.filter(address=current_ip_address).release(user=user)

            # Add new IP
            self.add_ip_address(
                user=user,
                ip_address=self.ip_address,
                network=self.network,
                hostname=self.hostname,
            )

    def remove_owners(self):
        users, groups = self.get_owners()
        self.remove_user_owners(users)
        self.remove_group_owners(groups)

    def remove_user_owners(self, users=None):
        if not users:
            users = self.get_owners(users_only=True)
        for user in users:
            remove_perm("is_owner_host", user, self)

    def remove_group_owners(self, groups=None):
        if not groups:
            users, groups = self.get_owners()
        for group in groups:
            remove_perm("is_owner_host", group, self)

    def remove_owner(self, user_or_group):
        return remove_perm("is_owner_host", user_or_group, self)

    def assign_owner(self, user_or_group):
        return assign_perm("is_owner_host", user_or_group, self)

    def save(self, user=None, add_dns=True, *args, **kwargs):
        user = user or self._user
        if not user:
            raise Exception("A User must be given to save hosts.")

        # Make sure hostname is lowercase
        self.hostname = self.hostname.lower()
        # Make sure mac is lowercase
        self.mac = str(self.mac).lower()

        # Updating changed and changed_by
        self.changed_by = user
        self.changed = timezone.now()

        # If master DNS delete, re-create it
        if add_dns and self.master_dns_deleted is True:
            self.add_dns_records(user=user)

        super(Host, self).save(*args, **kwargs)

    def delete(self, user=None, *args, **kwargs):
        user = user or self._user
        if not user:
            raise Exception("A User must be given to save hosts.")

        # Delete primary DNS (PTR, A, and AAAA, updating changed and changed by)
        self.delete_dns_records(user=user, addresses=self.addresses.all())

        # Release all addresses associated with host.
        self.addresses.release(user=user)

        # Re-save so that it captures user for postgres log table
        try:
            self.save(user=user, add_dns=False, force_update=True)
        except DatabaseError:
            pass
        with transaction.atomic():
            super(Host, self).delete(*args, **kwargs)

    def clean(self):
        from openipam.dns.models import DnsRecord, DnsType
        from openipam.network.models import Address

        # Perform check to on hostname to not let users create a host
        if self.hostname and self.hostname != self.original_hostname:
            existing_hostname = Host.objects.filter(hostname=self.hostname).first()
            if existing_hostname:
                raise ValidationError(
                    "The hostname '%s' already exists." % (self.hostname)
                )

            existing_dns_hostname = (
                DnsRecord.objects.filter(
                    dns_type__in=[DnsType.objects.A, DnsType.objects.AAAA],
                    name=self.hostname,
                )
                .exclude(host=self)
                .first()
            )
            if existing_dns_hostname:
                raise ValidationError(
                    "DNS Records already exist for this hostname: %s. "
                    " Please contact an IPAM Administrator." % (self.hostname)
                )

        # Perform permission checks if user is attached to this instance
        # Domain permission checks if hostname has changed
        if self.hostname and self.hostname != self.original_hostname:
            domain_from_host = self.hostname.split(".")[1:]
            domain_from_host = ".".join(domain_from_host)

            valid_domain = get_objects_for_user(
                self.user,
                [
                    "dns.add_records_to_domain",
                    "dns.is_owner_domain",
                    "dns.change_domain",
                ],
                any_perm=True,
            ).filter(name=domain_from_host)
            if not valid_domain:
                raise ValidationError(
                    "Insufficient permissions to add hosts "
                    "for domain: %s. Please contact an IPAM Administrator."
                    % domain_from_host
                )

        # Pool and Network permission checks
        # Check for pool assignment and perms
        if self.address_type and self.address_type.pool:
            valid_pools = get_objects_for_user(
                self.user,
                ["network.add_records_to_pool", "network.change_pool"],
                any_perm=True,
            )
            if self.address_type.pool not in valid_pools:
                raise ValidationError(
                    "Insufficient permissions to add hosts to "
                    "the assigned pool: %s. Please contact an IPAM Administrator."
                    % self.address_type.pool
                )

        # If network defined check for address assignment and perms
        if self.network:
            valid_network = get_objects_for_user(
                self.user,
                [
                    "network.add_records_to_network",
                    "network.is_owner_network",
                    "network.change_network",
                ],
                any_perm=True,
            )
            if self.network.network not in [
                network.network for network in valid_network
            ]:
                raise ValidationError(
                    "Insufficient permissions to add hosts to "
                    "the assigned network: %s. Please contact an IPAM Administrator."
                    % self.network.network
                )

        # If IP Address defined, check validity and perms
        if self.ip_address:
            ip_address = self.ip_address

            user_pools = get_objects_for_user(
                self.user,
                ["network.add_records_to_pool", "network.change_pool"],
                any_perm=True,
            )
            user_nets = get_objects_for_user(
                self.user,
                [
                    "network.add_records_to_network",
                    "network.is_owner_network",
                    "network.change_network",
                ],
                any_perm=True,
            )

            # Make sure this is valid.
            validate_ipv46_address(ip_address)
            address = Address.objects.filter(
                Q(pool__in=user_pools)
                | Q(pool__isnull=True)
                | Q(network__in=user_nets),
                Q(leases__isnull=True)
                | Q(leases__abandoned=True)
                | Q(leases__ends__lte=timezone.now())
                | Q(leases__host=self),
                Q(host__isnull=True) | Q(host=self),
                address=ip_address,
                reserved=False,
            )
            if not address:
                raise ValidationError(
                    "The IP Address is reserved, in use, or not allowed. "
                    "Please contact an IPAM Administrator."
                )

    class Meta:
        db_table = "hosts"
        permissions = (("is_owner_host", "Is owner"),)
        default_permissions = ("add", "change", "delete", "view")
        ordering = ("hostname",)
예제 #25
0
class Submission(models.Model):
    def user_display_name(self):
        return self.voter.user_display_name()

    category = models.ForeignKey(Category)
    idea = models.TextField(verbose_name=_('Question'))

    headline = models.TextField(null=False, blank=False)
    followup = models.TextField(null=True, blank=True)

    citation = models.CharField(
        max_length=2000,
        null=True,
        blank=True,
        db_index=True,
        verbose_name=_("Optional link to full proposal or reference"))
    citation_verified = models.BooleanField(default=False, db_index=True)

    voter = models.ForeignKey("Voter")
    created_at = models.DateTimeField(db_index=True)

    ip_address = models.CharField(max_length=255, db_index=True)

    editors_pick = models.BooleanField(default=False)
    approved = models.BooleanField(default=False, db_index=True)

    # if True, will not show up again in moderation list.
    moderated_removal = models.BooleanField(default=False, db_index=True)

    has_duplicates = models.BooleanField(default=False, db_index=True)

    duplicate_of = models.ForeignKey('opendebates.Submission',
                                     null=True,
                                     blank=True,
                                     related_name="duplicates")

    votes = models.IntegerField(default=0, db_index=True)
    local_votes = models.IntegerField(default=0, db_index=True)
    score = models.FloatField(default=0, db_index=True)
    rank = models.FloatField(default=0, db_index=True)

    random_id = models.FloatField(default=0, db_index=True)

    search_index = VectorField()

    keywords = models.TextField(null=True, blank=True)

    objects = SearchManager(fields=["idea", "keywords"],
                            auto_update_search_field=True)

    source = models.CharField(max_length=255, null=True, blank=True)

    happened = models.DateField(null=True, blank=True)
    is_positive = models.BooleanField(default=False)

    class Meta:
        ordering = ['-happened']

    def get_recent_votes(self):
        timespan = datetime.datetime.now() - datetime.timedelta(1)
        return Vote.objects.filter(submission=self,
                                   created_at__gte=timespan).count()

    def get_duplicates(self):
        if not self.has_duplicates:
            return None
        return Submission.objects.select_related(
            "voter", "category", "voter__user").filter(approved=True,
                                                       duplicate_of=self)

    def __unicode__(self):
        return self.idea

    @models.permalink
    def get_absolute_url(self):
        return "vote", [self.id]

    def my_tweet_text(self):
        params = {
            "hashtag": settings.SITE_THEME['HASHTAG'],
        }
        return _(
            u"Vote for my progressive idea for @ThinkBigUS #%s(hashtag)s. "
            "30 leaders in Congress will see top ideas!" % params)

    def tweet_text(self):
        text = settings.SITE_THEME['TWITTER_QUESTION_TEXT']
        if self.voter.twitter_handle:
            text += u" h/t @%s" % self.voter.twitter_handle
        return text

    def facebook_text(self):
        if len(self.idea) > 240:
            return self.idea[:240] + u'…'
        return self.idea

    def facebook_url(self):
        return u"https://www.facebook.com/sharer/sharer.php?&u=%(idea_url)s" % {
            "idea_url": quote_plus(self.really_absolute_url('fb')),
        }

    def reddit_url(self):
        return u"//www.reddit.com/submit?url=%s" % (quote_plus(
            self.really_absolute_url('reddit')), )

    def email_url(self):
        subject = settings.SITE_THEME['EMAIL_SUBJECT']
        body = settings.SITE_THEME['EMAIL_BODY'] % {
            "url": self.really_absolute_url('email'),
        }
        return u"mailto:?subject=%s&body=%s" % (urlquote(subject),
                                                urlquote(body))

    def sms_url(self):
        params = {
            "url": self.really_absolute_url('sms'),
            "hashtag": settings.SITE_THEME['HASHTAG'],
        }
        body = _(
            u"Vote for my progressive idea for @OpenDebaters #%(hashtag)s. %(url)s"
            % params)
        return u"sms:;?body=%s" % (quote_plus(body), )

    def really_absolute_url(self, source=None):
        url = settings.SITE_DOMAIN_WITH_PROTOCOL + self.get_absolute_url()
        if source is not None:
            url += '?source=share-%s-%s' % (source, self.id)
        return url

    def twitter_url(self):
        url_tmpl = u"https://twitter.com/intent/tweet?url=" + \
                   "%(idea_url)s&text=%(tweet_text)s"
        return url_tmpl % {
            "idea_url": quote_plus(self.really_absolute_url('tw')),
            "tweet_text": quote_plus(self.tweet_text()),
        }

    def twitter_title(self):
        # Vote on this question for the FL-Sen #OpenDebate!
        return settings.SITE_THEME['TWITTER_QUESTION_TITLE'].format(
            idea=self.idea)

    def twitter_description(self):
        # "{idea}" At 8pm EDT on 4/25, Jolly & Grayson answer top vote-getting questions at
        # bottom-up #OpenDebate hosted by [TBD], Open Debate Coalition, Progressive Change Institute
        return settings.SITE_THEME['TWITTER_QUESTION_DESCRIPTION'].format(
            idea=self.idea)

    def facebook_title(self):
        return settings.SITE_THEME['FACEBOOK_QUESTION_TITLE'].format(
            idea=self.idea)

    def facebook_description(self):
        return settings.SITE_THEME['FACEBOOK_QUESTION_DESCRIPTION'].format(
            idea=self.idea)
예제 #26
0
class Species(models.Model):
    species_name = CharField(max_length = 256) 
    species_first_name = CharField(max_length = 128)
    species_last_name = CharField(max_length = 128)
    category = ForeignKey('ebay_parse.eBayCategory', on_delete=models.CASCADE)
    
    species_photo = ImageField(blank=True, upload_to='species')
    
    def getSpeciesDetailInfo(self):
        cursor = connection.cursor()
        cursor.execute("""
        WITH info as(
            select ss.id, count(*), avg(ebay_item_price), min(ebay_item_price), max(ebay_item_price), avg(ebay_watch_count) AS ebay_watch_count,
                string_agg(DISTINCT country_name, ', ') AS counties 
                from species_species ss
                join species_scpecies2item si ON ss.id=si.species_id
                join ebay_parse_ebayitem pe ON pe.ebay_item_id = si.item_id
                join ebay_parse_country USING(country_id)
                group by ss.id)
            select * from species_species ss 
            LEFT JOIN info USING(id)
            JOIN ebay_parse_ebaycategory ec ON ec.ebay_category_id = ss.category_id
            WHERE id = %s
            """, [self.id])
        return dictfetchall(cursor)[0]
    
    def getGenusStatistics(genus):
        cursor = connection.cursor()
        cursor.execute("""
        select species_first_name, species_last_name, round(avg(ebay_item_price),2) as avg, count(*) lots_count
                from species_species ss
                join species_scpecies2item si ON ss.id=si.species_id
                join ebay_parse_ebayitem pe ON pe.ebay_item_id = si.item_id
                WHERE species_first_name = %s
                GROUP BY species_first_name, species_last_name
                order by lots_count desc
            """, [genus])
        return dictfetchall(cursor)

    def getBestSpecies():
        cursor = connection.cursor()
        cursor.execute("""
        select ss.id, species_name, species_photo, count(*), to_char(avg(ebay_watch_count), '9999999.99') avg , avg(ebay_watch_count) sort
                from species_species ss
                join species_scpecies2item si ON ss.id=si.species_id
                join ebay_parse_ebayitem pe ON pe.ebay_item_id = si.item_id
                GROUP BY ss.id, species_name,species_photo
                Order by 6 desc
                limit 100
            """)
        return dictfetchall(cursor)
    
    def best_image(self):
        cursor = connection.cursor()
        cursor.execute("""
           select ebay_gallery_icon
                from species_species ss
                join species_scpecies2item si ON ss.id=si.species_id
                join ebay_parse_ebayitem pe ON pe.ebay_item_id = si.item_id
                where ss.id = %s
                limit 1;

            """, [self.id])
        try:
            return cursor.fetchone()[0]
        except TypeError:
            return ''
    
    def save(self):
        if self.species_photo is None:
            self.species_photo = self.best_image()
        super(Species, self).save()
            
    def saveUnknownSpecies(self, item):
        self.species_name = item.ebay_item_title
        self.category = item.ebay_category
        self.species_photo = item.ebay_gallery_icon
        
        translator = Translator()
        try:
            russian = translator.translate(item.ebay_item_title, dest='ru', src='en')
        except json.decoder.JSONDecodeError as e:
            return
        russian = re.sub(r'[^a-zA-Z ]', '', str(russian))
        russian = re.sub(r'^Translatedsrcen destru text', '', russian)
        russian = re.sub(r'pronunciationNone$', '', russian)            
        russian = re.sub(r'\s+', ' ', russian)
        russian = re.sub('^\s', '', russian)
        russian = russian.lower()
        #delete stop words
        for word in stopWords.objects.all():
            russian = re.sub(word.word.lower(), '', russian)
            if russian != '':
                if not Species.objects.filter(species_name = russian).exists():
                    self.species_name = russian

        print("2> "+self.species_name)                    
        if Species.objects.filter(species_name = self.species_name).exists():
            self.id = Species.objects.filter(species_name = self.species_name).first().id           
            print("2> dublicate " + self.species_name)  
        
        super(Species, self).save()

    
    def species_photo_img(self):
        if self.species_photo:
            return u'<a href="{0}" target="_blank"><img src="{0}" width="100"/></a>'.format(self.species_photo.url)
        else:
            return '(Нет изображения)'
        
    def show_category(self):
        return self.category.ebay_category_name
        
    species_photo_img.short_description = 'Картинка'
    species_photo_img.allow_tags = True    

    def findGenusByDescription(desc):
        cursor = connection.cursor()
        cursor.execute("""
            select DISTINCT lower(species_first_name) 
                from species_species 
                where to_tsvector(%s) @@ to_tsquery(species_first_name);
        """, [desc])
        return cursor.fetchall()

    def findSpeciesRelation(it):
        genuses = Species.findGenusByDescription(it.ebay_item_title)
        for genus in genuses:
            cursor = connection.cursor()
            cursor.execute("""
                select DISTINCT lower(species_last_name) 
                    from species_species 
                    where lower(species_first_name) = %s AND
                        to_tsvector(%s) @@ to_tsquery(species_last_name);
            """, [genus[0].lower(), it.ebay_item_title])
            rows = cursor.fetchall()
            if len(rows) > 0:
                return Species.objects.filter(species_first_name__iexact = genus[0], species_last_name__iexact = rows[0][0]).first()

    
    #удаляет дубликаты в списке видов
    def deleteDublicates():
        #Шаг1 поиск дубликатов (род/вид)
        cursor = connection.cursor()
        cursor.execute("""
           WITH species AS(
                SELECT lower(species_first_name) species_first_name, lower(species_last_name) species_last_name, count(*) AS count
                  FROM species_species
                  GROUP BY lower(species_first_name), lower(species_last_name)
            )
            select * from species
                WHERE count >1 ;
            """)
        #перебираем дублированные записи и чистим лишние
        i = 0
        for row in cursor.fetchall():
            species = Species.objects.filter(species_first_name = row[0], species_last_name = row[1]).all()
            for s in species[1:]:
                Scpecies2Item.objects.filter(species = s).update(species= species[0])
                s.delete()
            i = i + 1 
        return i
    
    findGenusByDescription = staticmethod(findGenusByDescription)
    findSpeciesRelation = staticmethod(findSpeciesRelation)
    getGenusStatistics = staticmethod(getGenusStatistics)
    deleteDublicates = staticmethod(deleteDublicates)
    getBestSpecies = staticmethod(getBestSpecies)
    
    #full text search
    search_index = VectorField()
    
    objects = SearchManager(
        fields=('species_name', 'species_first_name', 'species_last_name'),
        config='pg_catalog.english',
        search_field='search_index',
        auto_update_search_field=True
    )
    
    def getPriceStatistic(self):
        c = connection.cursor()
        c.callproc("get_price_distribution", [self.id])
        return dictfetchall(c)        

    def getChronologyStatistic(self):
        cursor = connection.cursor()
        cursor.execute("""
            SELECT to_char(date_trunc('mon' ,current_date) - s.a * interval '1 mon', 'Month')  b, 
        (select to_char(coalesce(avg(ebay_item_price), 0), '9999999.99') avg
                from species_species ss
                join species_scpecies2item si ON ss.id=si.species_id
                join ebay_parse_ebayitem pe ON pe.ebay_item_id = si.item_id
                WHERE ss.id = %s AND ebay_item_endtime BETWEEN date_trunc('mon' ,current_date) - s.a * interval '1 mon' AND 
                date_trunc('mon' ,current_date) - (s.a -1 ) * interval '1 mon'),
        (select count(*)
                from species_species ss
                join species_scpecies2item si ON ss.id=si.species_id
                join ebay_parse_ebayitem pe ON pe.ebay_item_id = si.item_id
                WHERE ss.id = %s AND ebay_item_endtime BETWEEN date_trunc('mon' ,current_date) - s.a * interval '1 mon' AND 
                date_trunc('mon' ,current_date) - (s.a -1 ) * interval '1 mon')
  FROM generate_series(0,12) as s(a) order by a desc;
        """, [self.id, self.id])
        return dictfetchall(cursor)
예제 #27
0
class Log(models.Model):
    bot = models.ForeignKey('bots.ChatBot', null=True)
    channel = models.ForeignKey('bots.Channel', null=True)
    timestamp = models.DateTimeField(db_index=True)
    nick = models.CharField(max_length=255)
    text = models.TextField()
    action = models.BooleanField(default=False)

    command = models.CharField(max_length=50, null=True, blank=True)
    host = models.TextField(null=True, blank=True)
    raw = models.TextField(null=True, blank=True)

    # freenode chan name length limit is 50 chars, Campfire room ids are ints,
    #  so 100 should be enough
    room = models.CharField(max_length=100, null=True, blank=True)

    search_index = VectorField()

    objects = SearchManager(
        fields=('text', ),
        config='pg_catalog.english',  # this is default
        search_field='search_index',  # this is default
        auto_update_search_field=True)

    class Meta:
        ordering = ('-timestamp', )
        index_together = [
            ['channel', 'timestamp'],
        ]

    def get_absolute_url(self):
        kwargs = channel_url_kwargs(self.channel)
        kwargs['msg_pk'] = self.pk

        return reverse('log_message_permalink', kwargs=kwargs)

    def as_html(self):
        return render_to_string("logs/log_display.html",
                                {'message_list': [self]})

    def get_cleaned_host(self):
        if self.host:
            if '@' in self.host:
                return self.host.split('@')[1]
            else:
                return self.host

    def notify(self):
        """Send update to Nginx to be sent out via SSE"""
        utils.send_event_with_id("log",
                                 self.as_html(),
                                 self.timestamp.isoformat(),
                                 self.get_cleaned_host(),
                                 channel=self.channel_id)

    def get_nick_color(self):
        return hash(self.nick) % 32

    def __unicode__(self):
        if self.command == u"PRIVMSG":
            text = u''
            if self.nick:
                text += u'{0}: '.format(self.nick)
            text += self.text[:20]
        else:
            try:
                text = MSG_TMPL[self.command].format(nick=self.nick,
                                                     text=self.text)
            except KeyError:
                text = u"{}: {}".format(self.command, self.text)

        return text

    def save(self, *args, **kwargs):
        is_new = False
        if not self.pk:
            is_new = True
        if self.nick in settings.EXCLUDE_NICKS:
            self.text = REDACTED_TEXT

        obj = super(Log, self).save(*args, **kwargs)
        if is_new:
            self.notify()
        return obj
예제 #28
0
class Secret(HashIDModel):
    HASHID_NAMESPACE = "Secret"

    ACCESS_POLICY_REQUEST = 1
    ACCESS_POLICY_ANY = 2
    ACCESS_POLICY_HIDDEN = 3
    ACCESS_POLICY_CHOICES = (
        (ACCESS_POLICY_REQUEST, _("request")),
        (ACCESS_POLICY_ANY, _("everyone")),
        (ACCESS_POLICY_HIDDEN, _("hidden")),
    )
    CONTENT_PASSWORD = 1
    CONTENT_CC = 2
    CONTENT_FILE = 3
    CONTENT_CHOICES = (
        (CONTENT_PASSWORD, _("Password")),
        (CONTENT_CC, _("Credit Card")),
        (CONTENT_FILE, _("File")),
    )
    STATUS_OK = 1
    STATUS_NEEDS_CHANGING = 2
    STATUS_DELETED = 3
    STATUS_CHOICES = (
        (STATUS_OK, _("OK")),
        (STATUS_NEEDS_CHANGING, _("needs changing")),
        (STATUS_DELETED, _("deleted")),
    )

    access_policy = models.PositiveSmallIntegerField(
        choices=ACCESS_POLICY_CHOICES,
        default=ACCESS_POLICY_REQUEST,
    )
    allowed_groups = models.ManyToManyField(
        Group,
        blank=True,
        related_name='allowed_passwords',
    )
    allowed_users = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        blank=True,
        related_name='allowed_passwords',
    )
    content_type = models.PositiveSmallIntegerField(
        choices=CONTENT_CHOICES,
        default=CONTENT_PASSWORD,
    )
    created = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        related_name='passwords_created',
    )
    current_revision = models.ForeignKey(
        'SecretRevision',
        blank=True,
        null=True,
        related_name='_password_current_revision',
    )
    description = models.TextField(
        blank=True,
        null=True,
    )
    filename = models.CharField(
        blank=True,
        max_length=255,
        null=True,
    )
    last_read = models.DateTimeField(default=now, )
    name = models.CharField(max_length=92)
    needs_changing_on_leave = models.BooleanField(default=True, )
    status = models.PositiveSmallIntegerField(
        choices=STATUS_CHOICES,
        default=STATUS_OK,
    )
    url = models.CharField(
        blank=True,
        max_length=255,
        null=True,
        # Django's builtin URL validation is pretty strict to the point
        # of rejecting perfectly good URLs, thus we roll our own very
        # liberal validation
        validators=[validate_url],
    )
    username = models.CharField(
        blank=True,
        max_length=255,
        null=True,
    )

    search_index = VectorField()
    objects = SearchManager(
        fields=(
            ('name', 'A'),
            ('description', 'B'),
            ('filename', 'C'),
        ),
        search_field='search_index',
        auto_update_search_field=True,
    )

    class Meta:
        ordering = ('name', 'username')

    def __str__(self):
        return self.name

    def __repr__(self):
        return "<Secret '{name}' ({id})>".format(id=self.hashid,
                                                 name=self.name)

    def check_access(self, user):
        if not self.is_visible_to_user(user):
            raise Http404
        elif not self.is_readable_by_user(user):
            raise PermissionDenied()

    def get_absolute_url(self):
        return reverse('secrets.secret-detail', args=[str(self.hashid)])

    def get_data(self, user):
        if not self.current_revision:
            raise Http404
        if not self.is_readable_by_user(user):
            log(
                _("{user} tried to access '{name}' without permission").format(
                    name=self.name,
                    user=user.username,
                ),
                actor=user,
                level='warn',
                secret=self,
            )
            raise PermissionError(
                _("{user} not allowed access to '{name}' ({id})").format(
                    id=self.id,
                    name=self.name,
                    user=user.username,
                ))
        f = Fernet(settings.TEAMVAULT_SECRET_KEY)
        log(
            _("{user} read '{name}'").format(
                name=self.name,
                user=user.username,
            ),
            actor=user,
            level='info',
            secret=self,
            secret_revision=self.current_revision,
        )
        self.current_revision.accessed_by.add(user)
        self.current_revision.save()
        self.last_read = now()
        self.save()

        plaintext_data = f.decrypt(
            self.current_revision.encrypted_data.tobytes())
        if self.content_type != Secret.CONTENT_FILE:
            plaintext_data = plaintext_data.decode('utf-8')
        return plaintext_data

    @classmethod
    def get_all_readable_by_user(cls, user):
        if user.is_superuser:
            return cls.objects.all()
        return (cls.objects.filter(access_policy=cls.ACCESS_POLICY_ANY)
                | cls.objects.filter(allowed_users=user) | cls.objects.filter(
                    allowed_groups__in=user.groups.all())).exclude(
                        status=cls.STATUS_DELETED).distinct()

    @classmethod
    def get_all_visible_to_user(cls, user, queryset=None):
        if queryset is None:
            queryset = cls.objects.all()
        if user.is_superuser:
            return queryset
        return (queryset.filter(access_policy__in=(cls.ACCESS_POLICY_ANY,
                                                   cls.ACCESS_POLICY_REQUEST))
                | queryset.filter(allowed_users=user) |
                queryset.filter(allowed_groups__in=user.groups.all())).exclude(
                    status=cls.STATUS_DELETED).distinct()

    @classmethod
    def get_search_results(cls, user, term, limit=None):
        base_queryset = cls.get_all_visible_to_user(user)
        name_hits = base_queryset.filter(name__icontains=term)
        fulltext_hits = cls.get_all_visible_to_user(
            user, queryset=cls.objects.search(term))
        substr_hits = base_queryset.filter(
            models.Q(filename__icontains=term) | models.Q(url__icontains=term)
            | models.Q(username__icontains=term))
        if limit:
            name_hits = name_hits[:limit]
            fulltext_hits = fulltext_hits[:limit]
            substr_hits = substr_hits[:limit]
        # concatenate and remove duplicates
        result = list(
            OrderedDict.fromkeys(
                list(name_hits) + list(fulltext_hits) + list(substr_hits)))
        if limit:
            return result[:limit]
        else:
            return result

    def is_readable_by_user(self, user):
        return (user.is_superuser
                or ((self.access_policy == self.ACCESS_POLICY_ANY
                     or user in self.allowed_users.all()
                     or set(self.allowed_groups.all()).intersection(
                         set(user.groups.all())))
                    and self.status != self.STATUS_DELETED))

    def is_visible_to_user(self, user):
        return (user.is_superuser
                or ((self.access_policy in
                     (self.ACCESS_POLICY_ANY, self.ACCESS_POLICY_REQUEST)
                     or self.is_readable_by_user(user))
                    and self.status != self.STATUS_DELETED))

    def set_data(self, user, plaintext_data):
        if not self.is_readable_by_user(user):
            raise PermissionError(
                _("{user} not allowed access to '{name}' ({id})").format(
                    id=self.id,
                    name=self.name,
                    user=user.username,
                ))
        # save the length before encoding so multi-byte characters don't
        # mess up the result
        plaintext_length = len(plaintext_data)
        if isinstance(plaintext_data, str):
            plaintext_data = plaintext_data.encode('utf-8')
        f = Fernet(settings.TEAMVAULT_SECRET_KEY)
        encrypted_data = f.encrypt(plaintext_data)
        try:
            # see the comment on unique_together for SecretRevision
            p = SecretRevision.objects.get(
                encrypted_data=encrypted_data,
                secret=self,
            )
        except SecretRevision.DoesNotExist:
            p = SecretRevision()
        p.encrypted_data = encrypted_data
        # the hash is needed for unique_together (see below)
        # unique_together uses an index on its fields which is
        # problematic with the largeish blobs we might store here (see
        # issue #30)
        p.encrypted_data_sha256 = sha256(encrypted_data).hexdigest()
        p.length = plaintext_length
        p.secret = self
        p.set_by = user
        p.save()
        p.accessed_by.add(user)
        if self.current_revision:
            previous_revision_id = self.current_revision.id
        else:
            previous_revision_id = _("none")
        self.current_revision = p
        self.last_read = now()
        self.save()
        log(
            _("{user} set a new secret for '{name}' ({oldrev}->{newrev})").
            format(
                name=self.name,
                newrev=self.current_revision.id,
                oldrev=previous_revision_id,
                user=user.username,
            ),
            actor=user,
            level='info',
            secret=self,
            secret_revision=self.current_revision,
        )
예제 #29
0
class Match(models.Model):
    """A match between two teams."""
    date = models.DateTimeField()
    league = models.ForeignKey(League, on_delete=models.CASCADE, null=True)
    matchday = models.IntegerField(default=0)
    team_home = models.ForeignKey(Team,
                                  related_name='+',
                                  on_delete=models.DO_NOTHING)
    team_visitor = models.ForeignKey(Team,
                                     related_name='+',
                                     on_delete=models.DO_NOTHING)
    round = models.CharField(default='1', max_length=64)
    location = models.CharField(max_length=128, null=True)
    score_home = models.IntegerField(default=0)
    score_visitor = models.IntegerField(default=0)
    wallet = models.ForeignKey("django_bitcoin.Wallet",
                               on_delete=models.DO_NOTHING)
    xmlsoccer_matchid = models.IntegerField()
    finished = models.BooleanField(default=False)
    updated = models.DateTimeField(default=timezone.now)
    timeinfo = models.TextField(null=True)
    content = models.TextField(null=True)

    #full text search
    search_index = VectorField()

    objects = SearchManager(fields=('content', ),
                            config='pg_catalog.english',
                            search_field='search_index',
                            auto_update_search_field=True)

    def has_started(self):
        return self.date <= timezone.now()

    def times(self):
        try:
            minutes = re.match('(\d+)', self.timeinfo)
            if minutes:
                minutes = minutes.group(0)
                return int(minutes) // 45 + 1
        except Exception:
            return None

    def __str__(self):
        return '%s %s - %s (%s %s)' % (
            self.date, self.team_home.name, self.team_visitor.name,
            self.league.country, self.league.league_name)

    def short(self):
        return '%s - %s' % (self.team_home.name, self.team_visitor.name)

    # this is not needed if small_image is created at set_image
    def save(self, *args, **kwargs):
        str_wallet = '%s-%s' % (self.team_home.handle,
                                self.team_visitor.handle)
        str_wallet = str_wallet[:45]
        self.wallet, created = Wallet.objects.get_or_create(label=str_wallet)
        self.content = self.__str__()
        super(Match, self).save(*args, **kwargs)
        # I write bets coefficients in table
        if MatchBet.objects.filter(match=self).count() == 0:
            for bet in BetType.objects.all():
                row = MatchBet(match=self,
                               bet=bet,
                               max_value=bet.max_value,
                               min_value=bet.min_value)
                row.save()

    def closeMatch(self):
        if self.finished == True:
            logger = logging.getLogger("Match__closeMatch")
            result = True
            logger.info("Закрывается матч: " + str(self))
            bank_profile = Profile.objects.filter(
                user__is_superuser=True).first()
            for tip in Tipp.objects.filter(match=self, state="In Game"):
                closed = tip.close(bank_profile.wallet)
                result &= closed
            try:
                if self.wallet.total_balance() > 0:
                    self.wallet.send_to_wallet(bank_profile.wallet,
                                               self.wallet.total_balance())
            except Wallet.DoesNotExist:
                logger.error("К матчу " + str(self) +
                             " не привязан кошелек! Проверьте работу bitcoind")
            return result
        return False

    #Coefficient bid for
    def getMainBets(self):
        bets = BetType.objects.filter(bet_group__is_main=True).all()
        return MatchBet.objects.filter(match=self).filter(
            bet__in=bets).order_by('bet__order').all()

    def getAllBets(self):
        return MatchBet.objects.filter(match=self).filter(
            models.Q(bet__bet_group__is_main=True)
            | models.Q(is_enabled=True)).order_by("bet__id").all()

    def total_balance(self):
        return self.wallet.total_balance()

    def needUpdateOdds(self):
        if MatchBet.objects.filter(match=self).filter(
                match__updated__lte=timezone.now() - timedelta(days=1)).filter(
                    match__date__lte=timezone.now() +
                    timedelta(days=14)).count() > 0 and self.league.is_enabled:
            return True
        return False

    def updateOdds(self):
        for bet in MatchBet.objects.filter(match=self).all():
            bet.calculate()
        self.updated = timezone.now()
        self.save()

    def isIntrestingOdds(self):
        if MatchBet.objects.filter(match=self).filter(score__gte=1.1).filter(
                bet__bet_group__is_main=True).count() == 3:
            return True
        return False
예제 #30
0
class ArtistProfile(models.Model):
    proprietary_user = models.ForeignKey(GenericUser)
    """Proprietary of this artist profile, as it can be an artist or a agency"""

    artistic_name = models.CharField(max_length=100)
    artistic_name_normalized = models.CharField(max_length=100)
    slug = models.SlugField(max_length=255,
                            blank=False,
                            default='',
                            unique=True)
    category = models.ForeignKey(ArtistCategory, related_name="category")
    secondary_categories = models.ManyToManyField(
        ArtistCategory, blank=True, related_name="secondary_categories")
    event_type = models.ManyToManyField(ArtistEventTypeCategory,
                                        related_name="event_type")
    provinces = models.ManyToManyField(ArtistProvince,
                                       related_name="provinces")
    min_price = models.IntegerField(max_length=10)
    max_price = models.IntegerField(max_length=10)
    show_description = models.TextField(blank=False, null=False)
    show_description_normalized = models.TextField(blank=False,
                                                   null=False,
                                                   default="")
    date_created = models.DateTimeField(default=timezone.now)
    date_modified = models.DateTimeField(default=timezone.now)
    is_published = models.BooleanField(
        default=True,
        help_text=('Designates whether the artistic profile is published'))
    is_vip = models.BooleanField(
        default=False,
        help_text=('Designates whether the artistic profile is VIP'))
    contact_sum = models.IntegerField(
        default=0, help_text=('Sum of the contact button clicks'))

    search_index = VectorField()

    objects = SearchManager(
        fields=('artistic_name_normalized', 'show_description_normalized'),
        config='pg_catalog.english',  # this is default
        search_field='search_index',  # this is default
        auto_update_search_field=True)

    class Meta:
        ordering = [
            'proprietary_user__artist_plan', '-date_modified', '-date_created'
        ]

    def __unicode__(self):
        return self.artistic_name

    def get_published_status(self):
        return self.is_published

    def get_owner_plan(self):
        return self.proprietary_user.artist_plan

    def get_owner_plan_name(self):
        artist_plans = {"4": "Gratuito", "3": "Iniciado", "2": "Ilimitado"}
        return artist_plans[self.proprietary_user.artist_plan]

    def get_secondary_categories(self):
        objects = self.secondary_categories.all()
        list = []
        for i in objects:
            url = ', <a href="/catalog/' + i.slug + '">' + i.name + '</a>'
            list.append(url)
        return ''.join(list)

    def get_secondary_categories_flat(self):
        objects = self.secondary_categories.all()
        list = []
        for i in objects:
            name = ', ' + i.name + ''
            list.append(name)
        return ''.join(list)

    def get_provinces(self):
        objects = self.provinces.all()
        if objects.count() == 52:
            return 'Todas las provincias'
        list = []
        for i in objects:
            list.append(i.name)
        return ', '.join(list)

    def get_event_type(self):
        objects = self.event_type.all()
        list = []
        for i in objects:
            list.append(i.name)
        return ', '.join(list)

    def get_picture_quantity(self):
        return len(ArtistPicture.objects.filter(artistprofile_id=self.id))

    def get_video_quantity(self):
        return len(ArtistVideo.objects.filter(artistprofile_id=self.id))

    def get_image_catalog_03(self):
        image = ArtistPicture.objects.filter(artistprofile_id=self.id).get(
            is_main=True)
        if image:
            return image.get_image_name_template_03()
        else:
            return False

    def get_image_catalog_04(self):
        image = ArtistPicture.objects.filter(artistprofile_id=self.id).get(
            is_main=True)
        if image:
            return image.get_image_name_template_04()
        else:
            return False

    def get_image_catalog_05(self):
        image = ArtistPicture.objects.filter(artistprofile_id=self.id).get(
            is_main=True)
        if image:
            return image.get_image_name_template_05()
        else:
            return False

    def get_absolute_url(self):
        return "/catalog/" + str(self.category.slug) + "/" + str(self.slug)

    def get_price(self):
        if self.min_price == self.max_price:
            price = "{:,}".format(self.max_price) + ' €'
            return price.replace(',', '.')
        else:
            price = 'entre ' + "{:,}".format(
                self.min_price) + ' € y ' + "{:,}".format(
                    self.max_price) + ' €'
            return price.replace(',', '.')