Skip to content

Commit fd067bb

Browse files
authored
Async thumbnails generation (#372)
1 parent 419d3e6 commit fd067bb

File tree

9 files changed

+51
-15
lines changed

9 files changed

+51
-15
lines changed

backend/database/images.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def create_from_path(cls, path, dataset_id=None):
7070
image.path = path
7171
image.width = pil_image.size[0]
7272
image.height = pil_image.size[1]
73+
image.regenerate_thumbnail = True
7374

7475
if dataset_id is not None:
7576
image.dataset_id = dataset_id
@@ -94,15 +95,12 @@ def delete(self, *args, **kwargs):
9495

9596
def thumbnail(self):
9697
"""
97-
Generates (if required) and returns thumbnail
98+
Generates (if required) thumbnail
9899
"""
99100

100101
thumbnail_path = self.thumbnail_path()
101102

102-
if self.regenerate_thumbnail or \
103-
not os.path.isfile(thumbnail_path):
104-
105-
# logger.debug(f'Generating thumbnail for {self.id}')
103+
if self.regenerate_thumbnail:
106104

107105
pil_image = self.generate_thumbnail()
108106
pil_image = pil_image.convert("RGB")
@@ -116,9 +114,14 @@ def thumbnail(self):
116114

117115
self.update(is_modified=False)
118116
return pil_image
119-
else:
120-
return Image.open(thumbnail_path)
121-
117+
118+
def open_thumbnail(self):
119+
"""
120+
Return thumbnail
121+
"""
122+
thumbnail_path = self.thumbnail_path()
123+
return Image.open(thumbnail_path)
124+
122125
def thumbnail_path(self):
123126
folders = self.path.split('/')
124127
folders.insert(len(folders)-1, self.THUMBNAIL_DIRECTORY)

backend/webserver/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
from .watcher import run_watcher
2222
from .api import blueprint as api
23-
from .util import query_util
23+
from .util import query_util, thumbnails
2424
from .authentication import login_manager
2525
from .sockets import socketio
2626

@@ -55,6 +55,7 @@ def create_app():
5555
# Remove all poeple who were annotating when
5656
# the server shutdown
5757
ImageModel.objects.update(annotating=[])
58+
thumbnails.generate_thumbnails()
5859

5960
return flask
6061

backend/webserver/api/annotator.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from flask_login import login_required, current_user
55
from flask import request
66

7-
from ..util import query_util, coco_util, profile
7+
from ..util import query_util, coco_util, profile, thumbnails
88

99
from config import Config
1010
from database import (
@@ -141,6 +141,8 @@ def post(self):
141141
set__num_annotations=num_annotations
142142
)
143143

144+
thumbnails.generate_thumbnail(image_model)
145+
144146
return {"success": True}
145147

146148

backend/webserver/api/images.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,8 @@ def get(self, image_id):
132132
if not height:
133133
height = image.height
134134

135-
pil_image = image.thumbnail() if thumbnail else Image.open(image.path)
136-
image.flag_thumbnail(flag=False)
137-
135+
pil_image = image.open_thumbnail() if thumbnail else Image.open(image.path)
136+
138137
pil_image.thumbnail((width, height), Image.ANTIALIAS)
139138
image_io = io.BytesIO()
140139
pil_image = pil_image.convert("RGB")
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from database import ImageModel
2+
3+
4+
def generate_thumbnails():
5+
PREFIX = "[Thumbnails]"
6+
print(f'{PREFIX} Sending request for regenerating images with non actual thumbnails', flush=True)
7+
[generate_thumbnail(image) for image in ImageModel.objects(regenerate_thumbnail=True).all()]
8+
9+
10+
def generate_thumbnail(image):
11+
from workers.tasks import thumbnail_generate_single_image
12+
thumbnail_generate_single_image.delay(image.id)

backend/webserver/watcher.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from config import Config
55
from database import ImageModel
6+
from .util.thumbnails import generate_thumbnail
67

78
import re
89

@@ -32,11 +33,13 @@ def on_any_event(self, event):
3233

3334
if image is None and event.event_type != 'deleted':
3435
self._log(f'Adding new file to database: {path}')
35-
ImageModel.create_from_path(path).save()
36+
image = ImageModel.create_from_path(path).save()
37+
generate_thumbnail(image)
3638

3739
elif event.event_type == 'moved':
3840
self._log(f'Moving image from {event.src_path} to {path}')
3941
image.update(path=path)
42+
generate_thumbnail(image)
4043

4144
elif event.event_type == 'deleted':
4245
self._log(f'Deleting image from database {path}')

backend/workers/tasks/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

22
from .data import *
33
from .test import *
4-
from .scan import *
4+
from .scan import *
5+
from .thumbnails import *

backend/workers/tasks/scan.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from celery import shared_task
88
from ..socket import create_socket
9+
from .thumbnails import thumbnail_generate_single_image
910

1011
import os
1112

@@ -52,6 +53,8 @@ def scan_dataset(task_id, dataset_id):
5253
except:
5354
task.warning(f"Could not read {path}")
5455

56+
[thumbnail_generate_single_image.delay(image.id) for image in ImageModel.objects(regenerate_thumbnail=True).all()]
57+
5558
task.info(f"Created {count} new image(s)")
5659
task.set_progress(100, socket=socket)
5760

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from database import ImageModel
2+
from celery import task
3+
4+
5+
@task
6+
def thumbnail_generate_single_image(image_id):
7+
image = ImageModel.objects(id=image_id).first()
8+
image.thumbnail()
9+
image.flag_thumbnail(flag=False)
10+
11+
12+
__all__ = ["thumbnail_generate_single_image"]

0 commit comments

Comments
 (0)