|
|
|
@ -8,7 +8,7 @@ from datetime import datetime
|
|
|
|
from tempfile import NamedTemporaryFile
|
|
|
|
from tempfile import NamedTemporaryFile
|
|
|
|
import pytz
|
|
|
|
import pytz
|
|
|
|
|
|
|
|
|
|
|
|
from diskcache import Cache
|
|
|
|
from django.core.cache import cache
|
|
|
|
from django.conf import settings
|
|
|
|
from django.conf import settings
|
|
|
|
from rest_framework.exceptions import ValidationError, NotFound
|
|
|
|
from rest_framework.exceptions import ValidationError, NotFound
|
|
|
|
|
|
|
|
|
|
|
|
@ -25,42 +25,42 @@ from cvat.apps.engine.mime_types import mimetypes
|
|
|
|
from utils.dataset_manifest import ImageManifestManager
|
|
|
|
from utils.dataset_manifest import ImageManifestManager
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CacheInteraction:
|
|
|
|
class MediaCache:
|
|
|
|
def __init__(self, dimension=DimensionType.DIM_2D):
|
|
|
|
def __init__(self, dimension=DimensionType.DIM_2D):
|
|
|
|
self._cache = Cache(settings.CACHE_ROOT)
|
|
|
|
|
|
|
|
self._dimension = dimension
|
|
|
|
self._dimension = dimension
|
|
|
|
|
|
|
|
|
|
|
|
def __del__(self):
|
|
|
|
@staticmethod
|
|
|
|
self._cache.close()
|
|
|
|
def _get_or_set_cache_item(key, create_function):
|
|
|
|
|
|
|
|
item = cache.get(key)
|
|
|
|
|
|
|
|
if not item:
|
|
|
|
|
|
|
|
item = create_function()
|
|
|
|
|
|
|
|
cache.set(key, item)
|
|
|
|
|
|
|
|
|
|
|
|
def get_buf_chunk_with_mime(self, chunk_number, quality, db_data):
|
|
|
|
return item
|
|
|
|
cache_key = f'{db_data.id}_{chunk_number}_{quality}'
|
|
|
|
|
|
|
|
chunk, tag = self._cache.get(cache_key, tag=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not chunk:
|
|
|
|
def get_buf_chunk_with_mime(self, chunk_number, quality, db_data):
|
|
|
|
chunk, tag = self._prepare_chunk_buff(db_data, quality, chunk_number)
|
|
|
|
item = self._get_or_set_cache_item(
|
|
|
|
self._cache.set(cache_key, chunk, tag=tag)
|
|
|
|
key=f'{db_data.id}_{chunk_number}_{quality}',
|
|
|
|
|
|
|
|
create_function=lambda: self._prepare_chunk_buff(db_data, quality, chunk_number),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return chunk, tag
|
|
|
|
return item
|
|
|
|
|
|
|
|
|
|
|
|
def get_local_preview_with_mime(self, frame_number, db_data):
|
|
|
|
def get_local_preview_with_mime(self, frame_number, db_data):
|
|
|
|
key = f'data_{db_data.id}_{frame_number}_preview'
|
|
|
|
item = self._get_or_set_cache_item(
|
|
|
|
buf, mime = self._cache.get(key, tag=True)
|
|
|
|
key=f'data_{db_data.id}_{frame_number}_preview',
|
|
|
|
if not buf:
|
|
|
|
create_function=lambda: self._prepare_local_preview(frame_number, db_data),
|
|
|
|
buf, mime = self._prepare_local_preview(frame_number, db_data)
|
|
|
|
)
|
|
|
|
self._cache.set(key, buf, tag=mime)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return buf, mime
|
|
|
|
return item
|
|
|
|
|
|
|
|
|
|
|
|
def get_cloud_preview_with_mime(self, db_storage):
|
|
|
|
def get_cloud_preview_with_mime(self, db_storage):
|
|
|
|
key = f'cloudstorage_{db_storage.id}_preview'
|
|
|
|
item = self._get_or_set_cache_item(
|
|
|
|
preview, mime = self._cache.get(key, tag=True)
|
|
|
|
key=f'cloudstorage_{db_storage.id}_preview',
|
|
|
|
|
|
|
|
create_function=lambda: self._prepare_cloud_preview(db_storage)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if not preview:
|
|
|
|
return item
|
|
|
|
preview, mime = self._prepare_cloud_preview(db_storage)
|
|
|
|
|
|
|
|
self._cache.set(key, preview, tag=mime)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return preview, mime
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
@staticmethod
|
|
|
|
def _get_frame_provider():
|
|
|
|
def _get_frame_provider():
|
|
|
|
@ -147,9 +147,9 @@ class CacheInteraction:
|
|
|
|
def _prepare_local_preview(self, frame_number, db_data):
|
|
|
|
def _prepare_local_preview(self, frame_number, db_data):
|
|
|
|
FrameProvider = self._get_frame_provider()
|
|
|
|
FrameProvider = self._get_frame_provider()
|
|
|
|
frame_provider = FrameProvider(db_data, self._dimension)
|
|
|
|
frame_provider = FrameProvider(db_data, self._dimension)
|
|
|
|
buf, mime = frame_provider.get_preview(frame_number)
|
|
|
|
buff, mime_type = frame_provider.get_preview(frame_number)
|
|
|
|
|
|
|
|
|
|
|
|
return buf, mime
|
|
|
|
return buff, mime_type
|
|
|
|
|
|
|
|
|
|
|
|
def _prepare_cloud_preview(self, db_storage):
|
|
|
|
def _prepare_cloud_preview(self, db_storage):
|
|
|
|
storage = db_storage_to_storage_instance(db_storage)
|
|
|
|
storage = db_storage_to_storage_instance(db_storage)
|
|
|
|
@ -179,7 +179,7 @@ class CacheInteraction:
|
|
|
|
slogger.cloud_storage[db_storage.pk].info(msg)
|
|
|
|
slogger.cloud_storage[db_storage.pk].info(msg)
|
|
|
|
raise NotFound(msg)
|
|
|
|
raise NotFound(msg)
|
|
|
|
|
|
|
|
|
|
|
|
preview = storage.download_fileobj(preview_path)
|
|
|
|
buff = storage.download_fileobj(preview_path)
|
|
|
|
mime = mimetypes.guess_type(preview_path)[0]
|
|
|
|
mime_type = mimetypes.guess_type(preview_path)[0]
|
|
|
|
|
|
|
|
|
|
|
|
return preview, mime
|
|
|
|
return buff, mime_type
|
|
|
|
|