MyFSIO v0.2.6 Release #18
@@ -36,10 +36,11 @@ class GzipMiddleware:
|
|||||||
content_type = None
|
content_type = None
|
||||||
content_length = None
|
content_length = None
|
||||||
should_compress = False
|
should_compress = False
|
||||||
|
is_streaming = False
|
||||||
exc_info_holder = [None]
|
exc_info_holder = [None]
|
||||||
|
|
||||||
def custom_start_response(status: str, headers: List[Tuple[str, str]], exc_info=None):
|
def custom_start_response(status: str, headers: List[Tuple[str, str]], exc_info=None):
|
||||||
nonlocal response_started, status_code, response_headers, content_type, content_length, should_compress
|
nonlocal response_started, status_code, response_headers, content_type, content_length, should_compress, is_streaming
|
||||||
response_started = True
|
response_started = True
|
||||||
status_code = int(status.split(' ', 1)[0])
|
status_code = int(status.split(' ', 1)[0])
|
||||||
response_headers = list(headers)
|
response_headers = list(headers)
|
||||||
@@ -54,6 +55,9 @@ class GzipMiddleware:
|
|||||||
elif name_lower == 'content-encoding':
|
elif name_lower == 'content-encoding':
|
||||||
should_compress = False
|
should_compress = False
|
||||||
return start_response(status, headers, exc_info)
|
return start_response(status, headers, exc_info)
|
||||||
|
elif name_lower == 'x-stream-response':
|
||||||
|
is_streaming = True
|
||||||
|
return start_response(status, headers, exc_info)
|
||||||
|
|
||||||
if content_type and content_type in COMPRESSIBLE_MIMES:
|
if content_type and content_type in COMPRESSIBLE_MIMES:
|
||||||
if content_length is None or content_length >= self.min_size:
|
if content_length is None or content_length >= self.min_size:
|
||||||
@@ -61,7 +65,12 @@ class GzipMiddleware:
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
response_body = b''.join(self.app(environ, custom_start_response))
|
app_iter = self.app(environ, custom_start_response)
|
||||||
|
|
||||||
|
if is_streaming:
|
||||||
|
return app_iter
|
||||||
|
|
||||||
|
response_body = b''.join(app_iter)
|
||||||
|
|
||||||
if not response_started:
|
if not response_started:
|
||||||
return [response_body]
|
return [response_body]
|
||||||
|
|||||||
@@ -711,6 +711,7 @@ def stream_bucket_objects(bucket_name: str):
|
|||||||
headers={
|
headers={
|
||||||
'Cache-Control': 'no-cache',
|
'Cache-Control': 'no-cache',
|
||||||
'X-Accel-Buffering': 'no',
|
'X-Accel-Buffering': 'no',
|
||||||
|
'X-Stream-Response': 'true',
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -182,6 +182,9 @@
|
|||||||
let visibleItems = [];
|
let visibleItems = [];
|
||||||
let renderedRange = { start: 0, end: 0 };
|
let renderedRange = { start: 0, end: 0 };
|
||||||
|
|
||||||
|
let memoizedVisibleItems = null;
|
||||||
|
let memoizedInputs = { objectCount: -1, prefix: null, filterTerm: null };
|
||||||
|
|
||||||
const createObjectRow = (obj, displayKey = null) => {
|
const createObjectRow = (obj, displayKey = null) => {
|
||||||
const tr = document.createElement('tr');
|
const tr = document.createElement('tr');
|
||||||
tr.dataset.objectRow = '';
|
tr.dataset.objectRow = '';
|
||||||
@@ -340,7 +343,21 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const computeVisibleItems = () => {
|
const computeVisibleItems = (forceRecompute = false) => {
|
||||||
|
const currentInputs = {
|
||||||
|
objectCount: allObjects.length,
|
||||||
|
prefix: currentPrefix,
|
||||||
|
filterTerm: currentFilterTerm
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!forceRecompute &&
|
||||||
|
memoizedVisibleItems !== null &&
|
||||||
|
memoizedInputs.objectCount === currentInputs.objectCount &&
|
||||||
|
memoizedInputs.prefix === currentInputs.prefix &&
|
||||||
|
memoizedInputs.filterTerm === currentInputs.filterTerm) {
|
||||||
|
return memoizedVisibleItems;
|
||||||
|
}
|
||||||
|
|
||||||
const items = [];
|
const items = [];
|
||||||
const folders = new Set();
|
const folders = new Set();
|
||||||
|
|
||||||
@@ -381,6 +398,8 @@
|
|||||||
return aKey.localeCompare(bKey);
|
return aKey.localeCompare(bKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
memoizedVisibleItems = items;
|
||||||
|
memoizedInputs = currentInputs;
|
||||||
return items;
|
return items;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -533,6 +552,8 @@
|
|||||||
loadedObjectCount = 0;
|
loadedObjectCount = 0;
|
||||||
totalObjectCount = 0;
|
totalObjectCount = 0;
|
||||||
allObjects = [];
|
allObjects = [];
|
||||||
|
memoizedVisibleItems = null;
|
||||||
|
memoizedInputs = { objectCount: -1, prefix: null, filterTerm: null };
|
||||||
pendingStreamObjects = [];
|
pendingStreamObjects = [];
|
||||||
|
|
||||||
streamAbortController = new AbortController();
|
streamAbortController = new AbortController();
|
||||||
@@ -643,6 +664,8 @@
|
|||||||
loadedObjectCount = 0;
|
loadedObjectCount = 0;
|
||||||
totalObjectCount = 0;
|
totalObjectCount = 0;
|
||||||
allObjects = [];
|
allObjects = [];
|
||||||
|
memoizedVisibleItems = null;
|
||||||
|
memoizedInputs = { objectCount: -1, prefix: null, filterTerm: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (append && loadMoreSpinner) {
|
if (append && loadMoreSpinner) {
|
||||||
@@ -985,13 +1008,15 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const navigateToFolder = (prefix) => {
|
const navigateToFolder = (prefix) => {
|
||||||
|
if (streamAbortController) {
|
||||||
|
streamAbortController.abort();
|
||||||
|
streamAbortController = null;
|
||||||
|
}
|
||||||
|
|
||||||
currentPrefix = prefix;
|
currentPrefix = prefix;
|
||||||
|
|
||||||
if (scrollContainer) scrollContainer.scrollTop = 0;
|
if (scrollContainer) scrollContainer.scrollTop = 0;
|
||||||
|
|
||||||
refreshVirtualList();
|
|
||||||
renderBreadcrumb(prefix);
|
|
||||||
|
|
||||||
selectedRows.clear();
|
selectedRows.clear();
|
||||||
|
|
||||||
if (typeof updateBulkDeleteState === 'function') {
|
if (typeof updateBulkDeleteState === 'function') {
|
||||||
@@ -1001,6 +1026,9 @@
|
|||||||
if (previewPanel) previewPanel.classList.add('d-none');
|
if (previewPanel) previewPanel.classList.add('d-none');
|
||||||
if (previewEmpty) previewEmpty.classList.remove('d-none');
|
if (previewEmpty) previewEmpty.classList.remove('d-none');
|
||||||
activeRow = null;
|
activeRow = null;
|
||||||
|
|
||||||
|
isLoadingObjects = false;
|
||||||
|
loadObjects(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderObjectsView = () => {
|
const renderObjectsView = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user