Change keyword separator " " to "," + new tab
Browse files- Dockerfile +1 -1
- app.py +10 -9
- static/script.js +59 -84
- static/style.css +2 -9
Dockerfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
FROM python:3.
|
2 |
|
3 |
RUN apt-get update && \
|
4 |
apt-get install -y libreoffice libreoffice-writer libreoffice-calc libreoffice-impress && \
|
|
|
1 |
+
FROM python:3.11.3
|
2 |
|
3 |
RUN apt-get update && \
|
4 |
apt-get install -y libreoffice libreoffice-writer libreoffice-calc libreoffice-impress && \
|
app.py
CHANGED
@@ -198,8 +198,8 @@ def get_spec_content(specification: str, version: str):
|
|
198 |
document[toc[curr_index].replace("\t"," ")] = re.sub(r"\s+", " ", " ".join(text[index_toc[curr_index]+1:]))
|
199 |
return document
|
200 |
|
201 |
-
def
|
202 |
-
return string
|
203 |
|
204 |
class DocRequest(BaseModel):
|
205 |
doc_id: str
|
@@ -454,11 +454,12 @@ def search_spec(request: KeywordRequest):
|
|
454 |
release = request.release
|
455 |
working_group = request.working_group
|
456 |
spec_type = request.spec_type
|
457 |
-
kws = [
|
|
|
458 |
unique_specs = set()
|
459 |
results = []
|
460 |
|
461 |
-
if kws == "" and search_mode == "deep":
|
462 |
raise HTTPException(status_code=400, detail="You must enter keywords in deep search mode !")
|
463 |
|
464 |
for string, spec in finder_spec.indexer_specs.items():
|
@@ -480,23 +481,23 @@ def search_spec(request: KeywordRequest):
|
|
480 |
docValid = not isinstance(doc, str)
|
481 |
|
482 |
if request.mode == "and":
|
483 |
-
if all(kw in
|
484 |
put = True
|
485 |
if search_mode == "deep":
|
486 |
if docValid:
|
487 |
for chapter in list(doc.keys())[1:]:
|
488 |
if "references" not in chapter.lower() and "void" not in chapter.lower() and "annexe" not in doc[chapter].lower():
|
489 |
-
if all(kw in
|
490 |
put = True
|
491 |
contents.append(chapter)
|
492 |
elif request.mode == "or":
|
493 |
-
if any(kw in
|
494 |
put = True
|
495 |
if search_mode == "deep":
|
496 |
if docValid:
|
497 |
for chapter in list(doc.keys())[1:]:
|
498 |
-
if "references" not in chapter.lower()
|
499 |
-
if any(kw in
|
500 |
put = True
|
501 |
contents.append(chapter)
|
502 |
else:
|
|
|
198 |
document[toc[curr_index].replace("\t"," ")] = re.sub(r"\s+", " ", " ".join(text[index_toc[curr_index]+1:]))
|
199 |
return document
|
200 |
|
201 |
+
def caseSensitive(string: str, sensitive: bool):
|
202 |
+
return string if sensitive else string.lower()
|
203 |
|
204 |
class DocRequest(BaseModel):
|
205 |
doc_id: str
|
|
|
454 |
release = request.release
|
455 |
working_group = request.working_group
|
456 |
spec_type = request.spec_type
|
457 |
+
kws = [caseSensitive(_, booleanLowered) for _ in request.keywords.split(",")]
|
458 |
+
print(kws)
|
459 |
unique_specs = set()
|
460 |
results = []
|
461 |
|
462 |
+
if kws == [""] and search_mode == "deep":
|
463 |
raise HTTPException(status_code=400, detail="You must enter keywords in deep search mode !")
|
464 |
|
465 |
for string, spec in finder_spec.indexer_specs.items():
|
|
|
481 |
docValid = not isinstance(doc, str)
|
482 |
|
483 |
if request.mode == "and":
|
484 |
+
if all(kw in caseSensitive(string, booleanLowered) for kw in kws):
|
485 |
put = True
|
486 |
if search_mode == "deep":
|
487 |
if docValid:
|
488 |
for chapter in list(doc.keys())[1:]:
|
489 |
if "references" not in chapter.lower() and "void" not in chapter.lower() and "annexe" not in doc[chapter].lower():
|
490 |
+
if all(kw in caseSensitive(doc[chapter], booleanLowered) for kw in kws):
|
491 |
put = True
|
492 |
contents.append(chapter)
|
493 |
elif request.mode == "or":
|
494 |
+
if any(kw in caseSensitive(string, booleanLowered) for kw in kws):
|
495 |
put = True
|
496 |
if search_mode == "deep":
|
497 |
if docValid:
|
498 |
for chapter in list(doc.keys())[1:]:
|
499 |
+
if "references" not in chapter.lower() and "void" not in chapter.lower() and "annexe" not in doc[chapter].lower():
|
500 |
+
if any(kw in caseSensitive(doc[chapter], booleanLowered) for kw in kws):
|
501 |
put = True
|
502 |
contents.append(chapter)
|
503 |
else:
|
static/script.js
CHANGED
@@ -123,7 +123,7 @@ keywordSearchBtn.addEventListener("click", async ()=>{
|
|
123 |
} else if (response.status == 404) {
|
124 |
showError('No specification has been found');
|
125 |
} else {
|
126 |
-
showError(
|
127 |
}
|
128 |
} catch (error) {
|
129 |
showError('Error connecting to the server. Please check if the API is running.');
|
@@ -311,93 +311,68 @@ function displayKeywordResults(data, mode) {
|
|
311 |
}
|
312 |
|
313 |
function openSectionPopup(specId, sections) {
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
container.appendChild(textarea);
|
332 |
-
container.appendChild(copyBtn);
|
333 |
-
popupTextareas.appendChild(container);
|
334 |
-
});
|
335 |
-
|
336 |
-
sectionPopup.style.display = 'block';
|
337 |
-
document.body.style.overflow = 'hidden';
|
338 |
-
}
|
339 |
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
btn.style.backgroundColor = '#34a853';
|
350 |
-
btn.style.color = 'white';
|
351 |
-
|
352 |
-
setTimeout(() => {
|
353 |
-
btn.textContent = originalText;
|
354 |
-
btn.style.backgroundColor = '';
|
355 |
-
btn.style.color = '';
|
356 |
-
}, 1500);
|
357 |
-
}
|
358 |
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
});
|
370 |
-
|
371 |
-
// Créer un textarea temporaire pour copier le contenu
|
372 |
-
const tempTextarea = document.createElement('textarea');
|
373 |
-
tempTextarea.value = allContent;
|
374 |
-
document.body.appendChild(tempTextarea);
|
375 |
-
tempTextarea.select();
|
376 |
-
document.execCommand('copy');
|
377 |
-
document.body.removeChild(tempTextarea);
|
378 |
|
379 |
-
|
380 |
-
|
381 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
382 |
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
});
|
387 |
-
|
388 |
-
// Fermer la popup
|
389 |
-
closePopupBtn.addEventListener('click', () => {
|
390 |
-
sectionPopup.style.display = 'none';
|
391 |
-
document.body.style.overflow = ''; // Rétablir le défilement du body
|
392 |
-
});
|
393 |
-
|
394 |
-
// Fermer la popup en cliquant à l'extérieur
|
395 |
-
window.addEventListener('click', (event) => {
|
396 |
-
if (event.target === sectionPopup) {
|
397 |
-
sectionPopup.style.display = 'none';
|
398 |
-
document.body.style.overflow = '';
|
399 |
-
}
|
400 |
-
});
|
401 |
|
402 |
// Display batch results
|
403 |
function displayBatchResults(data) {
|
|
|
123 |
} else if (response.status == 404) {
|
124 |
showError('No specification has been found');
|
125 |
} else {
|
126 |
+
showError(`Error processing keyword request: ${data.detail}`)
|
127 |
}
|
128 |
} catch (error) {
|
129 |
showError('Error connecting to the server. Please check if the API is running.');
|
|
|
311 |
}
|
312 |
|
313 |
function openSectionPopup(specId, sections) {
|
314 |
+
const newTab = window.open('', '_blank');
|
315 |
+
let htmlContent =
|
316 |
+
`
|
317 |
+
<!DOCTYPE html>
|
318 |
+
<html lang="fr">
|
319 |
+
<head>
|
320 |
+
<meta charset="UTF-8">
|
321 |
+
<title>Sections of specification number ${specId}</title>
|
322 |
+
<link rel="stylesheet" href="/static/style.css">
|
323 |
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap">
|
324 |
+
</head>
|
325 |
+
<body>
|
326 |
+
<div class="popup-header">
|
327 |
+
<h2 id="popupTitle">Sections of specification number ${specId}</h2>
|
328 |
+
</div>
|
329 |
+
<div id="popupTextareas" class="popup-textareas">
|
330 |
+
`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
331 |
|
332 |
+
Object.entries(sections).forEach(([sectionTitle, content], index) => {
|
333 |
+
htmlContent +=
|
334 |
+
`
|
335 |
+
<div class="textarea-container">
|
336 |
+
<h2>${sectionTitle}</h2>
|
337 |
+
<p>${content.replace(/\n/g, '<br>')}</p>
|
338 |
+
</div>
|
339 |
+
`;
|
340 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
341 |
|
342 |
+
htmlContent += `
|
343 |
+
</div>
|
344 |
+
</body>
|
345 |
+
</html>
|
346 |
+
`;
|
347 |
+
|
348 |
+
newTab.document.open();
|
349 |
+
newTab.document.write(htmlContent);
|
350 |
+
newTab.document.close()
|
351 |
+
// popupTitle.textContent = `Sections of specification ${specId}`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
352 |
|
353 |
+
// popupTextareas.innerHTML = '';
|
354 |
+
// Object.entries(sections).forEach(([section, content], index) => {
|
355 |
+
// const container = document.createElement("div");
|
356 |
+
// container.className = "textarea-container";
|
357 |
+
|
358 |
+
// const textarea = document.createElement("textarea");
|
359 |
+
// textarea.id = `section-${index}`;
|
360 |
+
// textarea.value = `${section}\n\n${content}`
|
361 |
+
// textarea.readOnly = true;
|
362 |
+
|
363 |
+
// const copyBtn = document.createElement('button');
|
364 |
+
// copyBtn.className = 'copy-btn';
|
365 |
+
// copyBtn.textContent = 'Copy';
|
366 |
+
// copyBtn.onclick = () => copyTextarea(`section-${index}`);
|
367 |
+
|
368 |
+
// container.appendChild(textarea);
|
369 |
+
// container.appendChild(copyBtn);
|
370 |
+
// popupTextareas.appendChild(container);
|
371 |
+
// });
|
372 |
|
373 |
+
// sectionPopup.style.display = 'block';
|
374 |
+
// document.body.style.overflow = 'hidden';
|
375 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
|
377 |
// Display batch results
|
378 |
function displayBatchResults(data) {
|
static/style.css
CHANGED
@@ -70,7 +70,6 @@
|
|
70 |
display: flex;
|
71 |
flex-direction: column;
|
72 |
gap: 20px;
|
73 |
-
max-height: 60vh;
|
74 |
overflow-y: auto;
|
75 |
padding-right: 10px;
|
76 |
}
|
@@ -81,11 +80,10 @@
|
|
81 |
gap: 8px;
|
82 |
}
|
83 |
|
84 |
-
.textarea-container
|
85 |
width: 100%;
|
86 |
-
height: 100px;
|
87 |
padding: 12px 16px;
|
88 |
-
border: 1px solid
|
89 |
border-radius: 4px;
|
90 |
font-size: 16px;
|
91 |
font-family: 'Roboto', sans-serif;
|
@@ -93,11 +91,6 @@
|
|
93 |
outline: none;
|
94 |
}
|
95 |
|
96 |
-
.textarea-container textarea:focus {
|
97 |
-
border-color: var(--primary-color);
|
98 |
-
box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2);
|
99 |
-
}
|
100 |
-
|
101 |
.copy-btn {
|
102 |
align-self: flex-end;
|
103 |
background-color: var(--secondary-color);
|
|
|
70 |
display: flex;
|
71 |
flex-direction: column;
|
72 |
gap: 20px;
|
|
|
73 |
overflow-y: auto;
|
74 |
padding-right: 10px;
|
75 |
}
|
|
|
80 |
gap: 8px;
|
81 |
}
|
82 |
|
83 |
+
.textarea-container p {
|
84 |
width: 100%;
|
|
|
85 |
padding: 12px 16px;
|
86 |
+
border: 1px solid #ccc;
|
87 |
border-radius: 4px;
|
88 |
font-size: 16px;
|
89 |
font-family: 'Roboto', sans-serif;
|
|
|
91 |
outline: none;
|
92 |
}
|
93 |
|
|
|
|
|
|
|
|
|
|
|
94 |
.copy-btn {
|
95 |
align-self: flex-end;
|
96 |
background-color: var(--secondary-color);
|