]> git.ipfire.org Git - ipfire.org.git/blobdiff - src/backend/wiki.py
wiki: Remove debugging lines
[ipfire.org.git] / src / backend / wiki.py
index 2b65d017bb67fdd35083b0397d629f3050e9c4a4..0689fe499cb8457718fe2062cfe6d65160b0e86a 100644 (file)
@@ -1,8 +1,11 @@
 #!/usr/bin/python3
 
+import PIL
+import io
 import logging
 import os.path
 import re
+import urllib.parse
 
 from . import misc
 from . import util
@@ -120,6 +123,13 @@ class Wiki(misc.Object):
                        mimetype, blob_id, size) VALUES(%s,  %s, %s, %s, %s, %s, %s) RETURNING *", path,
                        filename, author.uid, address, mimetype, blob.id, len(data))
 
+       def find_image(self, path, filename):
+               for p in (path, os.path.dirname(path)):
+                       file = self.get_file_by_path(os.path.join(p, filename))
+
+                       if file and file.is_image():
+                               return file
+
 
 class Page(misc.Object):
        def init(self, id, data=None):
@@ -183,6 +193,40 @@ class Page(misc.Object):
        def _render(self, text):
                logging.debug("Rendering %s" % self)
 
+               # Link images
+               replacements = []
+               for match in re.finditer(r"!\[(.*)\]\((.*)\)", text):
+                       alt_text, url = match.groups()
+
+                       # Skip any absolute and external URLs
+                       if url.startswith("/") or url.startswith("https://") or url.startswith("http://"):
+                               continue
+
+                       # Try to split query string
+                       url, delimiter, qs = url.partition("?")
+
+                       # Parse query arguments
+                       args = urllib.parse.parse_qs(qs)
+
+                       # Find image
+                       file = self.backend.wiki.find_image(self.page, url)
+                       if not file:
+                               continue
+
+                       # Scale down the image if not already done
+                       if not "s" in args:
+                               args["s"] = "768"
+
+                       # Format URL
+                       url = "%s?%s" % (file.url, urllib.parse.urlencode(args))
+
+                       replacements.append((match.span(), file, alt_text, url))
+
+               # Apply all replacements
+               for (start, end), file, alt_text, url in reversed(replacements):
+                       text = text[:start] + "[![%s](%s)](%s?action=detail)" % (alt_text, url, file.url) + text[end:]
+
+               # Add wiki links
                patterns = (
                        (r"\[\[([\w\d\/]+)(?:\|([\w\d\s]+))\]\]", r"/\1", r"\2", None, None),
                        (r"\[\[([\w\d\/\-]+)\]\]", r"/\1", r"\1", self.backend.wiki.get_page_title, r"\1"),
@@ -280,6 +324,18 @@ class File(misc.Object):
        def size(self):
                return self.data.size
 
+       @lazy_property
+       def author(self):
+               if self.data.author_uid:
+                       return self.backend.accounts.get_by_uid(self.data.author_uid)
+
+       @property
+       def created_at(self):
+               return self.data.created_at
+
+       def is_pdf(self):
+               return self.mimetype in ("application/pdf", "application/x-pdf")
+
        def is_image(self):
                return self.mimetype.startswith("image/")
 
@@ -290,3 +346,19 @@ class File(misc.Object):
 
                if res:
                        return bytes(res.data)
+
+       def get_thumbnail(self, size):
+               image = PIL.Image.open(io.BytesIO(self.blob))
+
+               # Resize the image to the desired resolution
+               image.thumbnail((size, size), PIL.Image.ANTIALIAS)
+
+               with io.BytesIO() as f:
+                       # If writing out the image does not work with optimization,
+                       # we try to write it out without any optimization.
+                       try:
+                               image.save(f, image.format, optimize=True, quality=98)
+                       except:
+                               image.save(f, image.format, quality=98)
+
+                       return f.getvalue()