Beispiel #1
0
class Article(Page):
    translators = ParentalManyToManyField(
        "author.Author", related_name="translations_by_author", blank=True)
    strap = models.TextField(blank=True)
    content = RichTextField(
        blank=True,
        verbose_name="Content - Deprecated. Use 'MODULAR CONTENT' instead.")
    modular_content = StreamField([
        ('paragraph', ParagraphBlock()),
        ('n_column_paragraph', NColumnParagraphBlock()),
        ('paragraph_with_map', ParagraphWithMapBlock()),
        ('paragraph_with_page', ParagraphWithPageBlock()),
        ('paragraph_with_quote', ParagraphWithBlockQuoteBlock()),
        ('full_width_quote', FullWidthBlockQuote()),
        ('video_with_quote', VideoWithQuoteBlock()),
        ('image_with_quote_and_paragraph', ImageWithQuoteAndParagraphBlock()),
        ('full_width_image', FullWidthImageBlock()),
        ('columnar_image_with_text', NColumnImageWithTextBlock()),
        ('full_width_embed', FullWidthEmbedBlock()),
        ('paragraph_with_embed', ParagraphWithEmbedBlock()),
        ('paragraph_with_raw_embed', ParagraphWithRawEmbedBlock()),
    ],
                                  null=True,
                                  blank=True)
    show_modular_content = models.BooleanField(default=False)
    language = models.CharField(max_length=7, choices=settings.LANGUAGES)
    original_published_date = models.DateField(null=True, blank=True)
    show_day = models.BooleanField(default=True)
    show_month = models.BooleanField(default=True)
    show_year = models.BooleanField(default=True)
    featured_image = models.ForeignKey('core.AffixImage',
                                       null=True,
                                       blank=True,
                                       on_delete=models.SET_NULL)
    show_featured_image = models.BooleanField(default=True)

    categories = ParentalManyToManyField("category.Category",
                                         related_name="articles_by_category")
    locations = ParentalManyToManyField("location.Location",
                                        related_name="articles_by_location",
                                        blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('strap'),
        InlinePanel('authors', label='Authors', min_num=1),
        M2MFieldPanel('translators'),
        FieldPanel('language'),
        MultiFieldPanel([
            FieldPanel('original_published_date'),
            FieldRowPanel([
                FieldPanel('show_day', classname="col4"),
                FieldPanel('show_month', classname="col4"),
                FieldPanel('show_year', classname="col4")
            ])
        ], 'Date'),
        FieldPanel('content'),
        MultiFieldPanel([
            ImageChooserPanel('featured_image'),
            FieldPanel('show_featured_image'),
        ], 'Cover Image'),
        FieldPanel('categories'),
        M2MFieldPanel('locations'),
    ]

    tags = ClusterTaggableManager(through=ArticleTag, blank=True)
    promote_panels = Page.promote_panels + [
        FieldPanel('tags'),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('title', partial_match=True,
                          boost=SearchBoost.TITLE),
        index.SearchField(
            'get_authors', partial_match=True, boost=SearchBoost.AUTHOR),
        index.SearchField(
            'get_translators', partial_match=True, boost=SearchBoost.AUTHOR),
        index.SearchField(
            'strap', partial_match=True, boost=SearchBoost.DESCRIPTION),
        index.SearchField(
            'content', partial_match=True, boost=SearchBoost.CONTENT),
        index.SearchField(
            'modular_content', partial_match=True, boost=SearchBoost.CONTENT),
        index.SearchField('get_district_from_location',
                          partial_match=True,
                          boost=SearchBoost.LOCATION),
        index.SearchField('language', partial_match=True),
        index.FilterField('language'),
        index.FilterField('get_search_type'),
        index.FilterField('get_categories'),
        index.FilterField('get_minimal_locations'),
        index.FilterField('get_authors_or_photographers'),
        index.FilterField('title'),
        index.FilterField('get_state_from_locations')
    ]

    def __str__(self):
        return self.title

    def get_authors(self):
        return [
            article_author.author.name
            for article_author in self.authors.all()
        ]

    def get_author_role_map(self, **kwargs):
        authors_with_role = kwargs['authors_with_role']
        temp = defaultdict(list)
        for awr in authors_with_role:
            role = awr.role
            if role:
                temp[role.name].append(awr.author)
            else:
                temp['None'].append(awr.author)
        return dict((key, tuple(val)) for key, val in temp.items())

    def beginning_authors_with_role(self):
        return self.get_author_role_map(authors_with_role=self.authors.filter(
            show_in_beginning=True).all())

    def end_authors_with_role(self):
        return self.get_author_role_map(authors_with_role=self.authors.filter(
            show_in_end=True).all())

    def get_translators(self):
        return [translator.name for translator in self.translators.all()]

    def get_authors_or_photographers(self):
        return self.get_authors()

    def get_district_from_location(self):
        return [location.address for location in self.locations.all()]

    def get_minimal_locations(self):
        return [location.minimal_address for location in self.locations.all()]

    def get_state_from_locations(self):
        return [location.state for location in self.locations.all()]

    def get_context(self, request, *args, **kwargs):
        try:
            site = Site.objects.get(hostname=request.get_host())
        except Site.DoesNotExist:
            site = Site.objects.filter(is_default_site=True)[0]
        return {
            'article': self,
            'beginning_authors_with_role': self.beginning_authors_with_role(),
            'end_authors_with_role': self.end_authors_with_role(),
            'request': request,
            'site': site
        }

    def get_absolute_url(self):
        name = "article-detail"
        return reverse(name, kwargs={"slug": self.slug})

    def get_translation(self):
        return get_translations_for_page(self)

    # Elastic search related methods
    def get_search_type(self):
        categories = [category.name for category in self.categories.all()]

        if 'VideoZone' in categories:
            return 'video'
        elif 'AudioZone' in categories:
            return 'audio'
        else:
            return 'article'

    def get_categories(self):
        return [category.name for category in self.categories.all()]

    def related_articles(self):
        if not self.pk:
            # In preview mode
            return []

        max_results = getattr(settings, "MAX_RELATED_RESULTS", 4)
        es_backend = get_search_backend()
        mapping = Elasticsearch6Mapping(self.__class__)

        minimal_locations = ""
        if (self.get_minimal_locations()):
            minimal_locations = self.get_minimal_locations()

        state_locations = ""
        if (self.get_state_from_locations()):
            state_locations = self.get_state_from_locations()

        authors_of_article = ""

        if self.authors:
            for article_author in self.authors.all():
                authors_of_article += article_author.author.name

        query = {
            "track_scores":
            "true",
            "query": {
                "bool": {
                    "must": [{
                        "multi_match": {
                            "fields": ["*language_filter"],
                            "query": self.language
                        }
                    }, {
                        "term": {
                            "live_filter": "true"
                        }
                    }],
                    "must_not": [{
                        "term": {
                            "title_filter": self.title
                        }
                    }],
                    "should": [{
                        "multi_match": {
                            "fields": ["*get_authors_or_photographers_filter"],
                            "query": authors_of_article,
                            "type": "cross_fields",
                            "operator": "and"
                        }
                    }, {
                        "multi_match": {
                            "fields": ["*get_authors"],
                            "query": authors_of_article,
                            "type": "cross_fields",
                            "operator": "and"
                        }
                    }, {
                        "multi_match": {
                            "fields": ["*get_minimal_locations_filter"],
                            "query": ' '.join(minimal_locations),
                            "type": "cross_fields",
                            "operator": "and"
                        }
                    }, {
                        "multi_match": {
                            "fields": ["*get_state_from_locations_filter"],
                            "query": ' '.join(state_locations),
                            "type": "cross_fields",
                            "operator": "and"
                        }
                    }, {
                        "match": {
                            "title": self.title
                        }
                    }],
                    "minimum_should_match":
                    1
                }
            },
            "sort": [{
                "_score": {
                    "order": "desc"
                }
            }, {
                "article_article__get_authors_or_photographers_filter": {
                    "order": "desc"
                }
            }, {
                "album_album__get_authors_or_photographers_filter": {
                    "order": "desc"
                }
            }, {
                "face_face__get_authors_or_photographers_filter": {
                    "order": "desc"
                }
            }, {
                "first_published_at_filter": "desc"
            }]
        }

        try:
            mlt = es_backend.es.search(doc_type=mapping.get_document_type(),
                                       body=query)
        except ConnectionError:
            return []
        # Get pks from results
        pks = [hit['_source']['pk']
               for hit in mlt['hits']['hits']][:max_results]

        # Initialise results dictionary
        results = dict((str(pk), None) for pk in pks)

        # Find objects in database and add them to dict
        queryset = self._meta.default_manager.filter(pk__in=pks)
        for obj in queryset:
            results[str(obj.pk)] = obj

        # Return results in order given by ElasticSearch
        return [results[str(pk)] for pk in pks if results[str(pk)]]
Beispiel #2
0
class Face(Page):
    image = models.ForeignKey("core.AffixImage",
                              related_name="face_for_image",
                              null=True,
                              on_delete=models.SET_NULL)
    location = models.ForeignKey("location.Location",
                                 null=True,
                                 on_delete=models.SET_NULL,
                                 verbose_name="Place of Origin")
    additional_info = RichTextField(blank=True)
    language = models.CharField(max_length=7, choices=settings.LANGUAGES)

    occupation = models.CharField(
        max_length=100,
        null=True,
        blank=True,
        help_text="Enter the occupation of the person")
    occupation_of_parent = models.CharField(max_length=100,
                                            null=True,
                                            blank=True)
    adivasi = models.CharField(max_length=100, null=True, blank=True)
    quote = RichTextField(blank=True)
    child = models.BooleanField(default=False)
    age = models.IntegerField(null=True, blank=True)

    GENDER_CHOICES = (
        ('F', 'Female'),
        ('M', 'Male'),
        ('T', 'Transgender'),
    )
    gender = models.CharField(max_length=1,
                              choices=GENDER_CHOICES,
                              null=True,
                              blank=True)

    def __str__(self):
        return "{0} {1}".format(self.title, self.location.district)

    @property
    def featured_image(self):
        return self.image

    @property
    def title_to_share(self):
        title = "Meet " + self.title
        title += ", " + self.occupation if self.occupation else ""
        title += " from " + self.location.district
        title += ", " + self.location.state
        return title

    @property
    def locations(self):
        return [self.location]

    @property
    def photographers(self):
        return self.image.photographers.all()

    def get_authors_or_photographers(self):
        return [photographer.name for photographer in self.photographers]

    search_fields = Page.search_fields + [
        index.SearchField('title', partial_match=True,
                          boost=SearchBoost.TITLE),
        index.FilterField('image'),
        index.SearchField(
            'additional_info', partial_match=True, boost=SearchBoost.CONTENT),
        index.FilterField('location'),
        index.RelatedFields('location', [
            index.SearchField('name'),
            index.SearchField('block'),
            index.SearchField('district'),
            index.SearchField('state'),
            index.SearchField('panchayat'),
        ]),
        index.SearchField('occupation'),
        index.SearchField('occupation_of_parent'),
        index.SearchField('quote'),
        index.SearchField('get_locations_index',
                          partial_match=True,
                          boost=SearchBoost.LOCATION),
        index.SearchField('get_photographers_index',
                          partial_match=True,
                          boost=SearchBoost.AUTHOR),
        index.SearchField('adivasi'),
        index.SearchField('language'),
        index.FilterField('get_search_type'),
        index.FilterField('language'),
        index.FilterField('get_minimal_locations'),
        index.FilterField('get_authors_or_photographers')
    ]

    def get_locations_index(self):
        return self.image.get_locations_index()

    def get_minimal_locations(self):
        return [self.location.minimal_address]

    def get_photographers_index(self):
        return self.image.get_all_photographers()

    def get_search_type(self):
        return self.__class__.__name__.lower()

    content_panels = Page.content_panels + [
        ImageChooserPanel('image'),
        M2MFieldPanel('location'),
        FieldPanel('adivasi'),
        MultiFieldPanel([
            FieldPanel('child'),
            FieldPanel('occupation'),
            FieldPanel('occupation_of_parent'),
            FieldPanel('age'),
            FieldPanel('gender'),
        ],
                        heading="Personal details",
                        classname="collapsible "),
        MultiFieldPanel([
            FieldPanel('additional_info'),
            FieldPanel('language'),
            FieldPanel('quote'),
        ],
                        heading="Additional details",
                        classname="collapsible"),
    ]

    def get_absolute_url(self):
        name = "face-detail-single"
        return reverse(name,
                       kwargs={
                           "alphabet": self.location.district[0].lower(),
                           "slug": self.slug
                       })

    def get_context(self, request, *args, **kwargs):
        return {
            'faces': [self],
            'alphabet': self.location.district[0].lower(),
            'request': request
        }
Beispiel #3
0
class Article(Page):
    authors = M2MField("author.Author", related_name="articles_by_author")
    translators = M2MField("author.Author",
                           related_name="translations_by_author",
                           blank=True)
    strap = models.TextField(blank=True)
    content = RichTextField()
    language = models.CharField(max_length=7, choices=settings.LANGUAGES)
    original_published_date = models.DateField(null=True, blank=True)
    featured_image = models.ForeignKey('core.AffixImage',
                                       null=True,
                                       blank=True,
                                       on_delete=models.SET_NULL)
    categories = M2MField("category.Category",
                          related_name="articles_by_category")
    locations = M2MField("location.Location",
                         related_name="articles_by_location")

    content_panels = Page.content_panels + [
        FieldPanel('strap'),
        M2MFieldPanel('authors'),
        M2MFieldPanel('translators'),
        FieldPanel('language'),
        FieldPanel('original_published_date'),
        FieldPanel('content'),
        ImageChooserPanel('featured_image'),
        FieldPanel('categories'),
        M2MFieldPanel('locations'),
    ]

    search_fields = Page.search_fields + (
        index.SearchField('title', partial_match=True),
        index.SearchField('authors', partial_match=True, boost=2),
        index.SearchField('translators', partial_match=True, boost=2),
        index.SearchField('strap', partial_match=True),
        index.SearchField('content', partial_match=True),
        index.FilterField('categories'),
        index.SearchField('locations', partial_match=True, boost=2),
        index.FilterField('language'),
    )

    def __str__(self):
        return self.title

    def get_context(self, request, *args, **kwargs):
        try:
            site = Site.objects.get(hostname=request.get_host())
        except Site.DoesNotExist:
            site = Site.objects.filter(is_default_site=True)[0]
        return {'article': self, 'request': request, 'site': site}

    def get_absolute_url(self):
        name = "article-detail"
        return reverse(name, kwargs={"slug": self.slug})

    def related_articles(self):
        if not self.pk:
            # In preview mode
            return []
        max_results = getattr(settings, "MAX_RELATED_RESULTS", 4)
        es_backend = get_search_backend()
        mapping = ElasticSearchMapping(self.__class__)
        search_fields = []
        for ii in self.search_fields:
            if getattr(ii, "boost", None):
                search_fields.append("{0}^{1}".format(ii.field_name, ii.boost))
            else:
                search_fields.append(ii.field_name)
        query = {
            "query": {
                "filtered": {
                    "filter": {
                        "term": {
                            "live_filter": True
                        }
                    },
                    "query": {
                        "more_like_this": {
                            "docs": [{
                                "_id": mapping.get_document_id(self),
                                "_type": mapping.get_document_type()
                            }],
                            "min_doc_freq":
                            1,
                            "min_term_freq":
                            2,
                            "max_query_terms":
                            500,
                            "min_word_length":
                            4,
                            "fields":
                            search_fields
                        }
                    }
                }
            }
        }

        try:
            mlt = es_backend.es.search(index=es_backend.index_name,
                                       doc_type=mapping.get_document_type(),
                                       body=query)
        except ConnectionError:
            return []
        # Get pks from results
        pks = [hit['_source']['pk']
               for hit in mlt['hits']['hits']][:max_results]

        # Initialise results dictionary
        results = dict((str(pk), None) for pk in pks)

        # Find objects in database and add them to dict
        queryset = self._default_manager.filter(pk__in=pks)
        for obj in queryset:
            results[str(obj.pk)] = obj

        # Return results in order given by ElasticSearch
        return [results[str(pk)] for pk in pks if results[str(pk)]]