This commit is contained in:
TannedCung 2024-06-06 14:31:05 +07:00
commit e4fa15f196
5 changed files with 86 additions and 46 deletions

View File

@ -4,6 +4,7 @@ import urllib
import random import random
import numpy as np import numpy as np
from pathlib import Path from pathlib import Path
import urllib.parse
import uuid import uuid
from copy import deepcopy from copy import deepcopy
import sys, os import sys, os
@ -33,10 +34,18 @@ def sbt_predict(image_url, engine, metadata={}) -> None:
img = cv2.imdecode(arr, -1) img = cv2.imdecode(arr, -1)
save_dir = "./tmp_results" save_dir = "./tmp_results"
try:
parsed_url = urllib.parse.urlparse(image_url)
query_params = urllib.parse.parse_qs(parsed_url.query)
file_name = query_params['file_name'][0]
except Exception as e:
print(f"[ERROR]: Error extracting file name from url: {image_url}")
file_name = f"{uuid.uuid4()}.jpg"
os.makedirs(save_dir, exist_ok=True) os.makedirs(save_dir, exist_ok=True)
# image_path = os.path.join(save_dir, f"{image_url}.jpg") # image_path = os.path.join(save_dir, f"{image_url}.jpg")
os.makedirs(save_dir, exist_ok = True) os.makedirs(save_dir, exist_ok = True)
tmp_image_path = os.path.join(save_dir, f"{uuid.uuid4()}.jpg") tmp_image_path = os.path.join(save_dir, file_name)
cv2.imwrite(tmp_image_path, img) cv2.imwrite(tmp_image_path, img)
extra_params = {'sub': metadata.get("subsidiary", None)} # example of 'AU' extra_params = {'sub': metadata.get("subsidiary", None)} # example of 'AU'
outputs = process_img(img=tmp_image_path, outputs = process_img(img=tmp_image_path,

View File

@ -847,7 +847,6 @@ def calculate_a_request(report, request):
rv_avg_acc = avg_dict(att["acc"]["reviewed"]) rv_avg_acc = avg_dict(att["acc"]["reviewed"])
image.is_required = fb_avg_acc < settings.BAD_THRESHOLD image.is_required = fb_avg_acc < settings.BAD_THRESHOLD
image.is_reviewed = rv_avg_acc > 0
if image.processing_time < 0: if image.processing_time < 0:
continue continue

View File

@ -8,10 +8,9 @@ import { Button, Tag } from 'antd';
const FileCard = ({ file, isSelected, onClick }) => { const FileCard = ({ file, isSelected, onClick }) => {
const fileName = file['File Name']; const fileName = file['File Name'];
const extensionType = fileName.split('.').pop(); const extensionType = fileName.split('.').pop();
let status = true; const isRequired = file['Is Required'];
if (file['Is Required'] && !file['Is Reviewed']) { const isReviewd = file['Is Reviewed'];
status = false;
}
return ( return (
<div <div
style={{ style={{
@ -52,20 +51,29 @@ const FileCard = ({ file, isSelected, onClick }) => {
> >
{fileName {fileName
? fileName.substring(0, 25).replace('temp_', '') ? fileName.substring(0, 25).replace('temp_', '')
: fileName} : fileName}{' '}
{' '}({extensionType}) ({extensionType})
</span> </span>
</div> </div>
<Tag <div style={{display: 'flex', justifyContent: 'space-between', alignItems:'center'}}>
color={status ? 'success' : 'warning'} <Tag
icon={ color={isRequired ? 'warning' : ''}
status ? <CheckCircleOutlined /> : <ExclamationCircleOutlined /> style={{ display: 'inline-block', fontWeight: 'bold' , textTransform: 'capitalize' }}
} // bordered={false}
style={{ display: 'inline-block', fontWeight: 'bold' }} >
// bordered={false} Required: {isRequired.toString()}
> </Tag>
{status ? 'Good' : 'Warning'}{' '}
</Tag>
<Tag
color={isReviewd ? 'success' : 'warning'}
style={{ display: 'inline-block', fontWeight: 'bold', textTransform: 'capitalize' }}
// bordered={false}
>
Reviewed: {isReviewd.toString()}
</Tag>
</div>
</div> </div>
<Button <Button
style={{ style={{

View File

@ -56,7 +56,7 @@ export const updateRevisedData = async (requestID: any) => {
console.log(error); console.log(error);
throw error; throw error;
}); });
if (result.status != 200) { if (!result.ok) {
throw new Error('Could not update revised data'); throw new Error('Could not update revised data');
} }
}; };

View File

@ -53,6 +53,8 @@ import {
} from './const'; } from './const';
import FileCard from './FileCard'; import FileCard from './FileCard';
import RecentRequest from './RecentRequest'; import RecentRequest from './RecentRequest';
import './style.css';
const ReviewPage = () => { const ReviewPage = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [fullscreen, setFullscreen] = useState(false); const [fullscreen, setFullscreen] = useState(false);
@ -124,11 +126,11 @@ const ReviewPage = () => {
} }
}, []); }, []);
useEffect(() => { // useEffect(() => {
if (reason) { // if (reason) {
setSolution(counter_measure_map[reason]); // setSolution(counter_measure_map[reason]);
} // }
}, [reason]); // }, [reason]);
const updateSelectedFileDataSource = (fileContent) => { const updateSelectedFileDataSource = (fileContent) => {
let tempData = {}; let tempData = {};
@ -137,13 +139,20 @@ const ReviewPage = () => {
SOURCE_OBJECT_NAMES.forEach((name) => { SOURCE_OBJECT_NAMES.forEach((name) => {
tempData[k][name] = fileContent[name][k]; tempData[k][name] = fileContent[name][k];
}); });
if ( if (!isEmpty(tempData[k][PREDICTED_RESULT])) {
(isEmpty(tempData[k][REVIEWED_RESULT]) || let isEmptyResult = false;
(tempData[k][REVIEWED_RESULT].length == 1 && if (isEmpty(tempData[k][REVIEWED_RESULT])) {
isEmpty(tempData[k][REVIEWED_RESULT][0]))) && isEmptyResult = true;
!isEmpty(tempData[k][PREDICTED_RESULT]) }
) { if (Array.isArray(tempData[k][REVIEWED_RESULT]) && tempData[k][REVIEWED_RESULT].length > 0) {
tempData[k][REVIEWED_RESULT] = tempData[k][PREDICTED_RESULT]; isEmptyResult = tempData[k][REVIEWED_RESULT].every((r: any) =>
isEmpty(r),
);
}
if (isEmptyResult) {
tempData[k][REVIEWED_RESULT] = tempData[k][PREDICTED_RESULT];
}
} }
}); });
@ -166,16 +175,20 @@ const ReviewPage = () => {
if (!reason) { if (!reason) {
setReason(null); setReason(null);
setOtherReason(null);
} else if (REASON_BAD_QUALITY.some((r) => r.value === reason)) { } else if (REASON_BAD_QUALITY.some((r) => r.value === reason)) {
setReason(reason); setReason(reason);
setOtherReason(null);
} else { } else {
setReason('other'); setReason('other');
setOtherReason(reason); setOtherReason(reason);
} }
if (!solution) { if (!solution) {
setSolution(null); setSolution(null);
setOtherSolution(null);
} else if (SOLUTION_BAD_QUALITY.some((r) => r.value === solution)) { } else if (SOLUTION_BAD_QUALITY.some((r) => r.value === solution)) {
setSolution(solution); setSolution(solution);
setOtherSolution(null);
} else { } else {
setSolution('other'); setSolution('other');
setOtherSolution(solution); setOtherSolution(solution);
@ -190,7 +203,6 @@ const ReviewPage = () => {
setImageLoading(false); setImageLoading(false);
} }
}; };
const loadCurrentRequest = (requestIndex) => { const loadCurrentRequest = (requestIndex) => {
setLoading(true); setLoading(true);
setImageLoading(true); setImageLoading(true);
@ -277,8 +289,8 @@ const ReviewPage = () => {
); );
if (isConfirmed) { if (isConfirmed) {
try { try {
addRecentRequest(currentRequest?.RequestID);
await updateRevisedData(currentRequest?.RequestID); await updateRevisedData(currentRequest?.RequestID);
addRecentRequest(currentRequest?.RequestID);
setCurrentRequest({ setCurrentRequest({
...currentRequest, ...currentRequest,
['Is Reviewed']: true, ['Is Reviewed']: true,
@ -298,11 +310,18 @@ const ReviewPage = () => {
let request_file_result = {}; let request_file_result = {};
SOURCE_KEYS.forEach((k) => { SOURCE_KEYS.forEach((k) => {
request_file_result[k] = selectedFileDataSource[k][REVIEWED_RESULT]; request_file_result[k] = selectedFileDataSource[k][REVIEWED_RESULT];
if(Array.isArray(selectedFileDataSource[k][REVIEWED_RESULT])){
request_file_result[k] = selectedFileDataSource[k][REVIEWED_RESULT].toString();
}else{
request_file_result[k] = selectedFileDataSource[k][REVIEWED_RESULT];
}
}); });
let data = { let data = {
request_file_result, request_file_result,
reason: reason ? reason : otherReason, reason: reason !== 'other' ? reason : otherReason,
solution: solution ? solution : otherSolution, solution: solution !== 'other' ? solution : otherSolution,
}; };
try { try {
await updateRevisedDataByFile(currentRequest?.RequestID, fileId, data); await updateRevisedDataByFile(currentRequest?.RequestID, fileId, data);
@ -327,6 +346,8 @@ const ReviewPage = () => {
// use left/right keys to navigate // use left/right keys to navigate
useHotkeys('left', gotoPreviousRequest); useHotkeys('left', gotoPreviousRequest);
useHotkeys('right', gotoNextRequest); useHotkeys('right', gotoNextRequest);
useHotkeys('u', submitRevisedData);
useHotkeys('c', handleConfirmReview);
const fileExtension = selectedFileName const fileExtension = selectedFileName
? selectedFileName.split('.').pop() ? selectedFileName.split('.').pop()
@ -334,10 +355,10 @@ const ReviewPage = () => {
const [lightBox, setLightBox] = useState(false); const [lightBox, setLightBox] = useState(false);
const updateRevised = (fieldName) => { const updateRevisedByFeedback = (fieldName) => {
setSelectedFileDataSource((prevData) => { setSelectedFileDataSource((prevData) => {
prevData[fieldName][REVIEWED_RESULT] = prevData[fieldName][REVIEWED_RESULT] =
prevData[fieldName][FEEDBACK_RESULT]; prevData[fieldName][FEEDBACK_RESULT];
return { return {
...prevData, ...prevData,
}; };
@ -527,13 +548,12 @@ const ReviewPage = () => {
overflowX: 'visible', overflowX: 'visible',
}} }}
> >
<Spin spinning={imageLoading}> <Spin spinning={imageLoading} wrapperClassName='image-spin'>
<img <img
style={{ style={{
maxHeight: '100%', height: '100%',
maxWidth: '100%', width: '100%',
height: 'auto', objectFit: 'contain',
width: 'auto',
cursor: 'zoom-in', cursor: 'zoom-in',
}} }}
src={selectedFileData} src={selectedFileData}
@ -666,7 +686,7 @@ const ReviewPage = () => {
style={{ minWidth: '120px' }} style={{ minWidth: '120px' }}
onClick={handleConfirmReview} onClick={handleConfirmReview}
> >
Confirm request Confirm request
</Button> </Button>
</div> </div>
</div> </div>
@ -721,7 +741,7 @@ const ReviewPage = () => {
} }
} catch (error) {} } catch (error) {}
return ( return (
<div style={{ margin: '0 0 8px' }}> <div style={{ margin: '0 0 8px' }} className='file-input-group'>
<div <div
style={{ style={{
display: 'flex', display: 'flex',
@ -737,7 +757,7 @@ const ReviewPage = () => {
ghost ghost
icon={<CopyOutlined />} icon={<CopyOutlined />}
size='small' size='small'
onClick={() => updateRevised(data)} onClick={() => updateRevisedByFeedback(data)}
/> />
</div> </div>
<Input <Input
@ -776,7 +796,11 @@ const ReviewPage = () => {
placeholder='Select a reason' placeholder='Select a reason'
style={{ width: 170, flexBasis: '50%', height: '32px' }} style={{ width: 170, flexBasis: '50%', height: '32px' }}
options={REASON_BAD_QUALITY} options={REASON_BAD_QUALITY}
onChange={setReason} onChange={(value) => {
let newReason = value;
setReason(newReason);
setSolution(counter_measure_map[newReason]);
}}
value={reason} value={reason}
/> />
{reason === 'other' && ( {reason === 'other' && (