Allow multiple sources.
[redakcja.git] / src / catalogue / wikimedia.py
1 from urllib.parse import unquote
2 from django.core.files.base import ContentFile
3 from cover.utils import get_wikimedia_data, URLOpener
4
5
6 class WikiMedia:
7     def get_description_url(imgdata):
8         if imgdata is None:
9             return None
10         return imgdata.attributes['imageinfo'][0]['descriptionurl']
11
12     @classmethod
13     def descriptionurl(cls, arg):
14         def transform(get_value):
15             value = get_value(arg)
16             if value is None:
17                 return None
18             return cls.get_description_url(value)
19         return transform
20
21     @classmethod
22     def attribution(cls, arg):
23         def transform(get_value):
24             value = get_value(arg)
25             if value is None:
26                 return None
27             media_data = get_wikimedia_data(
28                 cls.get_description_url(value)
29             )
30             parts = [
31                 media_data['title'],
32                 media_data['author'],
33                 media_data['license_name'],
34             ]
35             parts = [p for p in parts if p]
36             attribution = ', '.join(parts)
37             return attribution
38         return transform
39
40     @classmethod
41     def download(cls, arg):
42         def transform(get_value):
43             value = get_value(arg)
44             if value is None:
45                 return None
46             media_data = get_wikimedia_data(
47                 cls.get_description_url(value)
48             )
49             download_url = media_data['download_url']
50             return Downloadable(download_url)
51         return transform
52
53     @classmethod
54     def append(cls, arg):
55         def transform(get_value):
56             value = get_value(arg)
57             return Appendable(value)
58         return transform
59
60
61 class Appendable(str):
62     def as_hint_json(self):
63         return {
64             'value': self,
65             'action': 'append',
66         }
67     
68 class Downloadable:
69     def __init__(self, url):
70         self.url = url
71
72     def apply_to_field(self, obj, attname):
73         t = URLOpener().open(self.url).read()
74         getattr(obj, attname).save(
75             unquote(self.url.rsplit('/', 1)[-1]),
76             ContentFile(t),
77             save=False
78         )
79
80     def as_hint_json(self):
81         return {
82             'download': self.url,
83             'img': self.url,
84         }