Better management of manually-set members.
[wolnelektury.git] / src / references / models.py
1 import json
2 from django.db import models
3 from wikidata.client import Client
4
5
6 class Entity(models.Model):
7     WIKIDATA_PREFIX = 'https://www.wikidata.org/wiki/'
8     WIKIDATA_IMAGE = 'P18'
9     WIKIDATA_COORDINATE_LOCATION = 'P625'
10     WIKIDATA_EARTH = 'Q2'
11
12     uri = models.CharField(max_length=255, unique=True, db_index=True)
13     label = models.CharField(max_length=1024, blank=True)
14     description = models.CharField(max_length=2048, blank=True)
15     wikipedia_link = models.CharField(max_length=1024, blank=True)
16     lat = models.FloatField(null=True, blank=True)
17     lon = models.FloatField(null=True, blank=True)
18     images = models.TextField(blank=True)
19
20     @property
21     def is_interesting(self):
22         return self.wikipedia_link or (self.lat and self.lon) or len(self.images)>2
23     
24     def populate(self):
25         if self.uri.startswith(self.WIKIDATA_PREFIX):
26             self.populate_from_wikidata(
27                 self.uri[len(self.WIKIDATA_PREFIX):]
28             )
29
30     def populate_from_wikidata(self, wikidata_id):
31         client = Client()
32         entity = client.get(wikidata_id)
33
34         self.label = entity.label.get('pl', entity.label) or ''
35         self.description = entity.description.get('pl', entity.description) or ''
36         sitelinks = entity.attributes.get('sitelinks', {})
37         self.wikipedia_link = sitelinks.get('plwiki', sitelinks.get('enwiki', {})).get('url') or ''
38
39         location_prop = client.get(self.WIKIDATA_COORDINATE_LOCATION)
40         location = entity.get(location_prop)
41         if location and location.globe.id == self.WIKIDATA_EARTH:
42             self.lat = location.latitude
43             self.lon = location.longitude
44
45         images = entity.getlist(client.get(self.WIKIDATA_IMAGE))
46         self.images = json.dumps([
47             {
48                 "url": image.image_url,
49                 "page": image.page_url,
50                 "resolution": image.image_resolution,
51             } for image in images
52         ])
53
54
55 class Reference(models.Model):
56     book = models.ForeignKey('catalogue.Book', models.CASCADE)
57     entity = models.ForeignKey(Entity, models.CASCADE)
58     first_section = models.CharField(max_length=255)
59
60     class Meta:
61         unique_together = (('book', 'entity'),)
62