Author photos and nicer Wikidata imports.
[redakcja.git] / src / catalogue / wikimedia.py
diff --git a/src/catalogue/wikimedia.py b/src/catalogue/wikimedia.py
new file mode 100644 (file)
index 0000000..534ca17
--- /dev/null
@@ -0,0 +1,70 @@
+from urllib.parse import unquote
+from django.core.files.base import ContentFile
+from cover.utils import get_wikimedia_data, URLOpener
+
+
+class WikiMedia:
+    def get_description_url(imgdata):
+        if imgdata is None:
+            return None
+        return imgdata.attributes['imageinfo'][0]['descriptionurl']
+
+    @classmethod
+    def descriptionurl(cls, arg):
+        def transform(get_value):
+            value = get_value(arg)
+            if value is None:
+                return None
+            return cls.get_description_url(value)
+        return transform
+
+    @classmethod
+    def attribution(cls, arg):
+        def transform(get_value):
+            value = get_value(arg)
+            if value is None:
+                return None
+            media_data = get_wikimedia_data(
+                cls.get_description_url(value)
+            )
+            parts = [
+                media_data['title'],
+                media_data['author'],
+                media_data['license_name'],
+            ]
+            parts = [p for p in parts if p]
+            attribution = ', '.join(parts)
+            return attribution
+        return transform
+
+    @classmethod
+    def download(cls, arg):
+        def transform(get_value):
+            value = get_value(arg)
+            if value is None:
+                return None
+            media_data = get_wikimedia_data(
+                cls.get_description_url(value)
+            )
+            download_url = media_data['download_url']
+            return Downloadable(download_url)
+        return transform
+
+
+class Downloadable:
+    def __init__(self, url):
+        self.url = url
+
+    def apply_to_field(self, obj, attname):
+        t = URLOpener().open(self.url).read()
+        getattr(obj, attname).save(
+            unquote(self.url.rsplit('/', 1)[-1]),
+            ContentFile(t),
+            save=False
+        )
+
+    def as_hint_json(self):
+        return {
+            'download': self.url,
+            'img': self.url,
+        }