Skip to content

Commit

Permalink
dumili: WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
bperel committed Dec 29, 2024
1 parent 279b7c2 commit 55907a4
Show file tree
Hide file tree
Showing 13 changed files with 111 additions and 50 deletions.
3 changes: 3 additions & 0 deletions apps/dumili/api/paddleocr/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from paddleocr import PaddleOCR
from http.server import BaseHTTPRequestHandler, HTTPServer
import json
import os

# select countrycode, GROUP_CONCAT(languagecode ORDER BY entries_with_language DESC) AS languages
# from (select countrycode, coalesce(inducks_entry.languagecode, ip.languagecode) as languagecode, count(*) as entries_with_language
Expand Down Expand Up @@ -333,6 +334,8 @@ def do_POST(self):
post_data = json.loads(self.rfile.read(content_length))
url = post_data['url']
language = post_data['language']

os.remove("tmp.jpg") if os.path.exists("tmp.jpg") else None
result = ocr_languages[language].ocr(url, cls=True)
result = result[0]

Expand Down
9 changes: 5 additions & 4 deletions apps/dumili/api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ model image {
id Int @id @default(autoincrement())
url String @unique(map: "image_url_uindex") @db.VarChar(255)
aiOcrResultId Int? @map("ai_ocr_result_id")
aiOcrResult aiOcrResult? @relation(fields: [aiOcrResultId], references: [id], onDelete: Restrict, onUpdate: Restrict, map: "image_ai_ocr_result_id_fk")
aiKumikoResultId Int? @map("ai_kumiko_result_id")
aiKumikoResult aiKumikoResult? @relation(fields: [aiKumikoResultId], references: [id], onDelete: Restrict, onUpdate: Restrict, map: "image_ai_kumiko_result_id_fk")
aiOcrResult aiOcrResult? @relation(fields: [aiOcrResultId], references: [id], onDelete: Restrict, onUpdate: Restrict, map: "image_ai_ocr_result_id_fk")
page page[]
@@index([aiKumikoResultId], map: "image_ai_kumiko_result_id_fk")
Expand Down Expand Up @@ -94,6 +94,7 @@ model storySuggestion {
entry entry @relation(fields: [entryId], references: [id], onDelete: Cascade, onUpdate: Restrict, map: "story_suggestion_entry_id_fk")
ai storySuggestionAi?
@@unique([entryId, storycode], map: "story_suggestion_entry_id_storycode_uindex")
@@index([entryId], map: "story_suggestion_entry_id_fk")
@@index([ocrDetailsId], map: "story_suggestion_ai_ocr_possible_story_id_fk")
@@map("story_suggestion")
Expand Down Expand Up @@ -147,23 +148,23 @@ model aiKumikoResultPanel {
model issueSuggestionAi {
id Int @id @default(autoincrement())
suggestionId Int @unique(map: "issue_suggestion_ai_issue_suggestion_id_unique_fk") @map("suggestion_id")
issueSuggestion issueSuggestion @relation(fields: [suggestionId], references: [id], onUpdate: Restrict, map: "issue_suggestion_ai_issue_suggestion_id_unique_fk")
issueSuggestion issueSuggestion @relation(fields: [suggestionId], references: [id], onDelete: Cascade, onUpdate: Restrict, map: "issue_suggestion_ai_issue_suggestion_id_unique_fk")
@@map("issue_suggestion_ai")
}

model storyKindSuggestionAi {
id Int @id @default(autoincrement())
suggestionId Int @unique(map: "story_kind_suggestion_ai_story_kind_suggestion_id_unique_fk") @map("suggestion_id")
storyKindSuggestion storyKindSuggestion @relation(fields: [suggestionId], references: [id], onUpdate: Restrict, map: "story_kind_suggestion_ai_story_kind_suggestion_id_unique_fk")
storyKindSuggestion storyKindSuggestion @relation(fields: [suggestionId], references: [id], onDelete: Cascade, onUpdate: Restrict, map: "story_kind_suggestion_ai_story_kind_suggestion_id_unique_fk")
@@map("story_kind_suggestion_ai")
}

model storySuggestionAi {
id Int @id @default(autoincrement())
suggestionId Int @unique(map: "story_suggestion_ai_story_suggestion_id_unique_fk") @map("suggestion_id")
storySuggestion storySuggestion @relation(fields: [suggestionId], references: [id], onUpdate: Restrict, map: "story_suggestion_ai_story_suggestion_id_fk")
storySuggestion storySuggestion @relation(fields: [suggestionId], references: [id], onDelete: Cascade, onUpdate: Restrict, map: "story_suggestion_ai_story_suggestion_id_fk")
@@map("story_suggestion_ai")
}
Expand Down
21 changes: 18 additions & 3 deletions apps/dumili/api/services/indexation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,14 @@ const getFullIndexation = (socket: IndexationSocket, indexationId: string) =>
})
.then((indexation) => {
if (indexation && !isAiRunning) {
isAiRunning = true
runKumikoOnPages(socket, indexation)
.then(() =>
runOcrOnImages(
socket,
indexation.pages
.filter(({ image }) => !!image)
.map(({ pageNumber, image }) => ({pageNumber, image: image!})),
.map(({ pageNumber, image }) => ({ pageNumber, image: image! })),
),
)
.then(() => setInferredEntriesStoryKinds(socket, indexation.entries))
Expand Down Expand Up @@ -97,6 +98,18 @@ const createAiStorySuggestions = async (

const currentlyAcceptedStorycode = entry.acceptedStory?.storycode;

await prisma.storySuggestionAi.deleteMany({
where: {
storySuggestion: {
entryId: entry.id
}
},
});
await prisma.storySuggestion.deleteMany({
where: {
entryId: entry.id
},
});
const newEntry = await prisma.entry.update({
include: {
storySuggestions: true,
Expand All @@ -121,7 +134,7 @@ const createAiStorySuggestions = async (
},
},
}),
),
)
},
},
});
Expand Down Expand Up @@ -312,7 +325,7 @@ export default (io: Server) => {
const entryIdx = indexation.entries.findIndex(
({ id }) => id === entryId,
);
const entryToExtend = indexation.entries[entryToExtendIdx][entryIdToExtend === "previous" ? entryIdx - 1 : entryIdx + 1];
const entryToExtend = indexation.entries[entryIdToExtend === "previous" ? entryIdx - 1 : entryIdx + 1];
if (!entryToExtend) {
if (entryIdToExtend === "previous") {
callback({ error: "This entry does not have any previous entry" });
Expand Down Expand Up @@ -341,6 +354,8 @@ export default (io: Server) => {
id: entryToExtend.id,
},
});

callback({status: 'OK'})
});

indexationSocket.on(
Expand Down
6 changes: 3 additions & 3 deletions apps/dumili/api/services/indexation/ocr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ export const runOcrOnImages = async (
for (const {image, pageNumber} of pages) {
const firstPanel = image!.aiKumikoResult?.detectedPanels[0];
if (!firstPanel) {
console.log("This page does not have any panels");
console.log(`Page ${pageNumber}: This page does not have any panels`);
continue;
}
if (image!.aiOcrResultId) {
console.log("This page already has OCR results");
console.log(`Page ${pageNumber}: This page already has OCR results`);
continue;
}
socket.emit("runOcrOnImage", image!.id);
Expand All @@ -39,7 +39,7 @@ export const runOcrOnImages = async (
`/c_crop,h_${firstPanel.height},w_${firstPanel.width},x_${firstPanel.x},y_${firstPanel.y},pg_`,
);

console.log(`Running OCR on page ${pageNumber}`);
console.log(`Page ${pageNumber}: Running OCR on ${firstPanelUrl}`);

const ocrResults = await runOcr(firstPanelUrl);
const matches = ocrResults.map(
Expand Down
2 changes: 1 addition & 1 deletion apps/dumili/src/components/Entry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
:model-value="entry.title"
:placeholder="$t('Titre de l\'histoire')"
type="text"
class="w-100 text-center"
class="w-100 text-center bg-transparent text-black"
@update:model-value="entry.title = ($event as string).replace(/[\r\n]+/g, '')"
/><template v-else>
{{ title || $t("Sans titre") }}
Expand Down
2 changes: 1 addition & 1 deletion apps/dumili/src/components/StoryKindBadge.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<b-badge
size="xl"
:class="{ [`kind-${storyKind}`]: true }"
class="text-black fw-normal"
class="text-black fw-normal fs-6"
>{{ (storyKind && storyKinds[storyKind]) || $t("Type inconnu") }}</b-badge
>
</template>
Expand Down
39 changes: 21 additions & 18 deletions apps/dumili/src/components/suggestions/PageStoryKindTooltip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,28 @@
showAiDetectionsOn = $event ? { type: 'page', id: page.id } : undefined
"
>
<b>{{ $t("Cases détectées") }}</b>
<table-results
:data="
page.image?.aiKumikoResult?.detectedPanels.map(
({ x, y, width, height }) => ({
x,
y,
width,
height,
}),
) || []
"
/>
<div>
<b>{{ $t("Type d'entrée déduit pour la page") }}</b>
<div v-if="!page.image">
{{ $t("Aucune image") }}
</div>
<story-kind-badge
:story-kind="page.image?.aiKumikoResult?.inferredStoryKind"
/>
<template v-else>
<b>{{ $t("Cases détectées") }}</b>
<table-results
:data="
page.image?.aiKumikoResult?.detectedPanels.map(
({ x, y, width, height }) => ({
x,
y,
width,
height,
}),
) || []
" />
<div>
<b>{{ $t("Type d'entrée déduit pour la page") }}</b>
</div>
<story-kind-badge
:story-kind="page.image?.aiKumikoResult?.inferredStoryKind"
/></template>
</ai-tooltip>
</template>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const acceptStory = async (storycode: storySuggestion["storycode"] | null) => {
.originalstoryversioncode!
].kind,
)!.id;
indexationSocket.value!.services.acceptStoryKindSuggestion(
await indexationSocket.value!.services.acceptStoryKindSuggestion(
entry.value.id,
correspondingStoryKindId,
);
Expand Down
49 changes: 39 additions & 10 deletions apps/dumili/src/components/suggestions/StorySuggestionsTooltip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,46 @@
<template v-if="entry.acceptedStoryKind?.kind === STORY">
<template v-if="firstPageOcrResult">
<template v-if="entry.storySuggestions.length">
{{ $t("Résultats OCR pour la première case:") }}
<table-results :data="firstPageOcrResult.matches" />
{{ $t("Histoires potentielles:") }}
<table-results
:data="
<h4>{{ $t("Résultats OCR pour la première case") }}</h4>
<b-table
:fields="[
{ key: 'text', label: $t('Texte') },
{ key: 'x1' },
{ key: 'x2' },
{ key: 'y1' },
{ key: 'y2' },
{ key: 'confidence', label: $t('Confiance') },
]"
:items="firstPageOcrResult.matches"
><template #empty>{{ $t("Aucun texte détecté") }}</template>
</b-table>
<h4>{{ $t("Histoires potentielles") }}</h4>
<b-table
:fields="[
{ key: 'storycode', label: $t('Code histoire') },
{ key: 'title', label: $t('Titre') },
]"
:items="
entry.storySuggestions.filter(({ai}) => ai).map(({ storycode }) => ({
storycode,
title: storyDetails[storycode!].title,
}))
" /></template
></template>
"
>
<template #cell(storycode)="row">
<a
class="text-nowrap"
:href="`https://inducks.org/story.php?c=${encodeURIComponent(row.item.storycode)}`"
target="_blank"
>{{ row.item.storycode }}</a
></template
></b-table
></template
></template
>
<template v-else-if="!firstPage.image">{{
$t("Non calculé car la première page de l'entrée n'a pas d'image")
}}</template>
<template v-else>{{ $t("Non calculé") }}</template></template
><template v-else>{{
$t("Aucune suggestion car cette entrée n'est pas une histoire.")
Expand All @@ -48,7 +77,7 @@ const { storyDetails } = storeToRefs(coa());
const { showAiDetectionsOn } = storeToRefs(ui());
const firstPageOcrResult = computed(
() => getEntryPages(indexation.value!, entry.id)[0].image?.aiOcrResult,
);
const firstPage = computed(() => getEntryPages(indexation.value!, entry.id)[0]);
const firstPageOcrResult = computed(() => firstPage.value.image?.aiOcrResult);
</script>
4 changes: 4 additions & 0 deletions apps/dumili/src/style.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
@use "sass:color";

textarea::placeholder {
color: black !important;
}

.opacity-100-hover:hover {
opacity: 1 !important;
}
Expand Down
4 changes: 2 additions & 2 deletions apps/dumili/translations/messages.en.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"Entrez le numéro": "Type the number",
"Envoi d'images de pages": "Upload page files",
"Galerie des pages": "Gallery",
"Histoires potentielles:": "Potential stories:",
"Histoires potentielles": "Potential stories:",
"Ignorer les pages existantes": "Ignore existing pages",
"Images": "Images",
"Indexations en cours": "Ongoing indexations",
Expand All @@ -41,7 +41,7 @@
"Prix": "Price",
"Rechercher...": "Search...",
"Remplacer les pages existantes": "Overwrite existing pages",
"Résultats OCR pour la première case:": "OCR results for the first page:",
"Résultats OCR pour la première case": "OCR results for the first page",
"Sans titre": "Untitled.",
"Sélectionner...": "Select...",
"Sélectionnez un pays": "Select a country",
Expand Down
6 changes: 3 additions & 3 deletions apps/dumili/translations/messages.ta.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"Entrez le numéro": "எண்ணை உள்ளிடவும்",
"Envoi d'images de pages": "பக்கங்களை அனுப்புகிறது",
"Galerie des pages": "பக்கங்கள்",
"Histoires potentielles:": "சாத்தியமான கதைகள்:",
"Histoires potentielles": "சாத்தியமான கதைகள்",
"Ignorer les pages existantes": "தற்போதுள்ள பக்கங்களை புறக்கணிக்கவும்",
"Images": "படங்கள்",
"Indexations en cours": "தற்போதைய குறியீடுகள்",
Expand All @@ -39,7 +39,7 @@
"Prix": "ப்ரிக்ச்",
"Rechercher...": "ஆராய்வதற்கு ...",
"Remplacer les pages existantes": "இருக்கும் பக்கங்களை மாற்றவும்",
"Résultats OCR pour la première case:": "முதல் பெட்டியின் OCR முடிவுகள்:",
"Résultats OCR pour la première case": "முதல் பெட்டியின் OCR முடிவுகள்",
"Sans titre": "",
"Sélectionner...": "தேர்ந்தெடுக்கவும் ...",
"Sélectionnez un pays": "ஒரு நாட்டைத் தேர்ந்தெடுக்கவும்",
Expand All @@ -59,4 +59,4 @@
"{numberOfPanels} cases trouvées": "{numberOfPanels} பெட்டிகள் காணப்படுகின்றன",
"{numberOfStories} histoires trouvées avec ces mots-clés": "{numberOfStories} இந்த முக்கிய வார்த்தைகளுடன் காணப்படும் கதைகள்",
"{textNumber} textes trouvés": "{textNumber} காணப்பட்ட நூல்கள்"
}
}
14 changes: 10 additions & 4 deletions packages/prisma-schemas/schemas/coa/extended/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ export default (prismaClient: PrismaClient) =>
})
.$extends({
client: {
getInducksIssueData: (issuecodes: string[], withTitle: boolean) =>
getInducksIssueData: <WithTitle extends boolean>(
issuecodes: string[],
withTitle: WithTitle,
) =>
prismaClient.inducks_issue
.findMany({
select: {
Expand All @@ -38,12 +41,15 @@ export default (prismaClient: PrismaClient) =>
})
.then((inducksIssues) =>
(
inducksIssues as {
inducksIssues as ({
publicationcode: string;
issuenumber: string;
issuecode: string;
title?: string;
}[]
} & (WithTitle extends boolean
? {
title?: string;
}
: object))[]
).groupBy("issuecode"),
),
},
Expand Down

0 comments on commit 55907a4

Please sign in to comment.