]> git.ipfire.org Git - ipfire.org.git/blame - src/backend/util.py
search: Use PostgreSQL's websearch_to_tsquery()
[ipfire.org.git] / src / backend / util.py
CommitLineData
9523790a 1#!/usr/bin/python3
66862195 2
5ef115cd
MT
3import PIL.Image
4import PIL.ImageFilter
2b72638d 5import PIL.ImageOps
5ef115cd
MT
6import io
7import logging
e96e445b 8import random
9523790a 9import re
e96e445b 10import string
75d9b3da 11import unicodedata
e96e445b 12
84604476
MT
13def format_size(s, max_unit=None):
14 units = ("B", "kB", "MB", "GB", "TB")
66862195
MT
15
16 i = 0
17 while s >= 1024 and i < len(units) - 1:
18 s /= 1024
19 i += 1
20
84604476
MT
21 if max_unit and units[i] == max_unit:
22 break
23
66862195
MT
24 return "%.0f%s" % (s, units[i])
25
5ac74b02 26def format_time(s, shorter=True):
66862195
MT
27 #_ = handler.locale.translate
28 _ = lambda x: x
29
30 hrs, s = divmod(s, 3600)
31 min, s = divmod(s, 60)
32
33 if s >= 30:
34 min += 1
35
36 if shorter and not hrs:
37 return _("%(min)d min") % { "min" : min }
38
39 return _("%(hrs)d:%(min)02d hrs") % {"hrs" : hrs, "min" : min}
e96e445b
MT
40
41def random_string(length=8):
42 input_chars = string.ascii_letters + string.digits
43
44 r = (random.choice(input_chars) for i in range(length))
45
46 return "".join(r)
75d9b3da
MT
47
48def normalize(s):
49 # Remove any non-ASCII characters
50 try:
51 s = unicodedata.normalize("NFKD", s)
52 except TypeError:
53 pass
54
55 # Remove excessive whitespace
56 s = re.sub(r"[^\w]+", " ", s)
57
58 return "-".join(s.split())
5ef115cd 59
2de3dacc 60def generate_thumbnail(data, size, square=False, **args):
5ef115cd
MT
61 assert data, "No image data received"
62
63 image = PIL.Image.open(io.BytesIO(data))
64
65 # Save image format
66 format = image.format
67
68 # Remove any alpha-channels
69 if image.format == "JPEG" and not image.mode == "RGB":
70 # Make a white background
71 background = PIL.Image.new("RGBA", image.size, (255,255,255))
72
73 # Convert image to RGBA if not in RGBA, yet
74 if not image.mode == "RGBA":
75 image = image.convert("RGBA")
76
77 # Flatten both images together
78 flattened_image = PIL.Image.alpha_composite(background, image)
79
80 # Remove the alpha channel
81 image = flattened_image.convert("RGB")
82
83 # Resize the image to the desired resolution
2de3dacc 84 if square:
7e222133 85 image = PIL.ImageOps.fit(image, (size, size), PIL.Image.LANCZOS)
2de3dacc
MT
86 else:
87 image.thumbnail((size, size), PIL.Image.LANCZOS)
5ef115cd
MT
88
89 if image.format == "JPEG":
90 # Apply a gaussian blur to make compression easier
91 image = image.filter(PIL.ImageFilter.GaussianBlur(radius=0.05))
92
93 # Arguments to optimise the compression
94 args.update({
95 "subsampling" : "4:2:0",
96 "quality" : 70,
97 })
98
99 with io.BytesIO() as f:
100 # If writing out the image does not work with optimization,
101 # we try to write it out without any optimization.
102 try:
103 image.save(f, format, optimize=True, **args)
104 except:
105 image.save(f, format, **args)
106
107 return f.getvalue()