TSK-842: Fix resume recognition functionality (#2736)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2023-03-15 23:36:50 +07:00 committed by GitHub
parent fff4debc49
commit 3979c1acb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 95 additions and 51 deletions

View File

@ -89,7 +89,8 @@ services:
- ACCOUNTS_URL=http://localhost:3000
- REKONI_URL=http://localhost:4004
- COLLABORATOR_URL=ws://localhost:3078
- FRONT_URL=http://front:8080
- GMAIL_URL=http://localhost:8088
- TELEGRAM_URL=http://localhost:8086
- UPLOAD_URL=/files
- TRANSACTOR_URL=ws://localhost:3333
- ELASTIC_URL=http://elastic:9200

View File

@ -3,7 +3,7 @@ LOGIN_ENDPOINT=ws://localhost:3333
TELEGRAM_URL=http://localhost:8086
GMAIL_URL=http://localhost:8088
FRONT_URL=http://front:8080
FRONT_URL=http://localhost:8080
REKONI_URL=http://localhost:4004

View File

@ -1,4 +0,0 @@
TELEGRAM_URL = https://telegram.hc.engineering
GMAIL_URL = https://gmail.hc.engineering
REKONI_URL = https://rekoni.hc.engineering

View File

@ -2,5 +2,8 @@
"ACCOUNTS_URL":"/account",
"COLLABORATOR_URL": "ws://localhost:3078",
"UPLOAD_URL":"/files",
"MODEL_VERSION": null
"MODEL_VERSION": null,
"TELEGRAM_URL": "http://localhost:8086",
"GMAIL_URL": "http://localhost:8088",
"REKONI_URL": "http://localhost:4004"
}

View File

@ -80,8 +80,18 @@ import { textEditorId } from '@hcengineering/text-editor'
import { setMetadata } from '@hcengineering/platform'
interface Config {
ACCOUNTS_URL: string
UPLOAD_URL: string
MODEL_VERSION: string
COLLABORATOR_URL: string
REKONI_URL: string
TELEGRAM_URL: string
GMAIL_URL: string
}
export async function configurePlatform() {
const config = await (await fetch('/config.json')).json()
const config: Config = await (await fetch('/config.json')).json()
console.log('loading configuration', config)
setMetadata(login.metadata.AccountsUrl, config.ACCOUNTS_URL)
setMetadata(login.metadata.UploadUrl, config.UPLOAD_URL)
@ -92,12 +102,11 @@ export async function configurePlatform() {
console.log('Minimal Model version requirement', config.MODEL_VERSION)
setMetadata(presentation.metadata.RequiredVersion, config.MODEL_VERSION)
}
setMetadata(login.metadata.TelegramUrl, process.env.TELEGRAM_URL ?? 'http://localhost:8086')
setMetadata(login.metadata.GmailUrl, process.env.GMAIL_URL ?? 'http://localhost:8087')
setMetadata(login.metadata.TelegramUrl, config.TELEGRAM_URL ?? 'http://localhost:8086')
setMetadata(login.metadata.GmailUrl, config.GMAIL_URL ?? 'http://localhost:8087')
setMetadata(login.metadata.OverrideEndpoint, process.env.LOGIN_ENDPOINT)
setMetadata(login.metadata.FrontUrl, process.env.FRONT_URL)
setMetadata(rekoni.metadata.RekoniUrl, process.env.REKONI_URL)
setMetadata(rekoni.metadata.RekoniUrl, config.REKONI_URL)
setMetadata(uiPlugin.metadata.DefaultApplication, login.component.LoginApp)

View File

@ -24,23 +24,24 @@ export * from './types'
/**
* @public
*/
export async function recognizeDocument (token: string, url: string, contentType: string): Promise<ReconiDocument> {
export async function recognizeDocument (token: string, file: File): Promise<ReconiDocument> {
const rekoniUrl = getMetadata(plugin.metadata.RekoniUrl)
if (rekoniUrl === undefined) {
// We could try use recognition service to find some document properties.
throw new PlatformError(unknownError('recognition framework is not configured'))
}
const data = new FormData()
data.append('file', file)
data.append('type', file.type)
data.append('name', file.name)
return (await (
await fetch(concatLink(rekoniUrl, '/recognize'), {
method: 'POST',
headers: {
Authorization: 'Bearer ' + token,
'Content-Type': 'application/json'
Authorization: 'Bearer ' + token
},
body: JSON.stringify({
contentType,
fileUrl: url
})
body: data
})
).json()) as ReconiDocument
}

View File

@ -37,7 +37,6 @@
createQuery,
EditableAvatar,
getClient,
getFileUrl,
getUserDraft,
KeyedAttribute,
MessageBox,
@ -348,13 +347,11 @@
}
}
async function recognize (contentType: string): Promise<void> {
async function recognize (file: File): Promise<void> {
const token = getMetadata(login.metadata.LoginToken) ?? ''
const frontUrl = getMetadata(login.metadata.FrontUrl) ?? ''
const fileUrl = frontUrl + getFileUrl(resume.uuid)
try {
const doc = await recognizeDocument(token, fileUrl, contentType)
const doc = await recognizeDocument(token, file)
if (isUndef(object.title) && doc.title !== undefined) {
object.title = doc.title
@ -462,7 +459,7 @@
resume.type = file.type
resume.lastModified = file.lastModified
await recognize(file.type)
await recognize(file)
} catch (err: any) {
setPlatformStatus(unknownError(err))
} finally {

View File

@ -35,6 +35,7 @@
icon={recruit.icon.CreateCandidate}
label={draftExists ? recruit.string.ResumeDraft : recruit.string.CreateTalent}
justify={'left'}
kind={'primary'}
width={'100%'}
on:click={newCandidate}
>

View File

@ -69,7 +69,6 @@
</div>
</Button>
</div>
<Button icon={tracker.icon.Magnifier} on:click={async () => {}} />
</div>
<style lang="scss">

View File

@ -68,7 +68,6 @@ export async function configurePlatform() {
setMetadata(login.metadata.TelegramUrl, process.env.TELEGRAM_URL ?? 'http://localhost:8086')
setMetadata(login.metadata.GmailUrl, process.env.GMAIL_URL ?? 'http://localhost:8087')
setMetadata(login.metadata.OverrideEndpoint, process.env.LOGIN_ENDPOINT)
setMetadata(login.metadata.FrontUrl, process.env.FRONT_URL)
setMetadata(uiPlugin.metadata.DefaultApplication, workbench.component.WorkbenchApp)
setMetadata(workbench.metadata.ExcludedApplications, [contact.app.Contacts])

View File

@ -28,8 +28,6 @@ spec:
value: /files
- name: TRANSACTOR_URL
value: wss://transactor.hc.engineering/
- name: FRONT_URL
value: https://front.hc.engineering/
- name: GMAIL_URL
value: gmail.hc.engineering
- name: ELASTIC_URL

View File

@ -77,6 +77,24 @@ if (collaboratorUrl === undefined) {
process.exit(1)
}
const gmailUrl = process.env.GMAIL_URL
if (gmailUrl === undefined) {
console.error('please provide gmail url')
process.exit(1)
}
const telegramUrl = process.env.TELEGRAM_URL
if (telegramUrl === undefined) {
console.error('please provide telegram url')
process.exit(1)
}
const rekoniUrl = process.env.REKONI_URL
if (rekoniUrl === undefined) {
console.error('please provide rekoni url')
process.exit(1)
}
const modelVersion = process.env.MODEL_VERSION
if (modelVersion === undefined) {
console.error('please provide model version requirement')
@ -91,7 +109,18 @@ if (serverSecret === undefined) {
setMetadata(serverToken.metadata.Secret, serverSecret)
const config = { transactorEndpoint, elasticUrl, minio, accountsUrl, uploadUrl, modelVersion, collaboratorUrl }
const config = {
transactorEndpoint,
elasticUrl,
minio,
accountsUrl,
uploadUrl,
modelVersion,
collaboratorUrl,
gmailUrl,
telegramUrl,
rekoniUrl
}
console.log('Starting Front service with', config)
const shutdown = start(config, SERVER_PORT)

View File

@ -137,6 +137,9 @@ export function start (
uploadUrl: string
modelVersion: string
collaboratorUrl: string
rekoniUrl: string
telegramUrl: string
gmailUrl: string
},
port: number
): () => void {
@ -168,7 +171,10 @@ export function start (
ACCOUNTS_URL: config.accountsUrl,
UPLOAD_URL: config.uploadUrl,
MODEL_VERSION: config.modelVersion,
COLLABORATOR_URL: config.collaboratorUrl
COLLABORATOR_URL: config.collaboratorUrl,
REKONI_URL: config.rekoniUrl,
TELEGRAM_URL: config.telegramUrl,
GMAIL_URL: config.gmailUrl
})
})

View File

@ -36,6 +36,12 @@ export function disableLogging (): void {
LOGGING_ENABLED = false
}
function timeoutPromise (time: number): Promise<void> {
return new Promise((resolve) => {
setTimeout(resolve, time)
})
}
interface Workspace {
id: string
pipeline: Promise<Pipeline>
@ -203,20 +209,22 @@ class SessionManager {
const workspaceId = workspace.id
if (LOGGING_ENABLED) console.log('no sessions for workspace', wsid, workspaceId)
async function waitAndClose (workspace: Workspace): Promise<void> {
const pipeline = await workspace.pipeline
await pipeline.close()
}
workspace.closing = waitAndClose(workspace).then(() => {
if (this.workspaces.get(wsid)?.id === workspaceId) {
const waitAndClose = async (workspace: Workspace): Promise<void> => {
try {
const pl = await workspace.pipeline
await Promise.race([pl, timeoutPromise(60000)])
await Promise.race([pl.close(), timeoutPromise(60000)])
if (this.workspaces.get(wsid)?.id === workspaceId) {
this.workspaces.delete(wsid)
}
console.log('Closed workspace', workspaceId)
} catch (err: any) {
this.workspaces.delete(wsid)
console.error(err)
}
console.log('Closed workspace', workspaceId)
})
workspace.closing.catch((err) => {
this.workspaces.delete(wsid)
console.error(err)
})
}
workspace.closing = waitAndClose(workspace)
await workspace.closing
}
}
@ -259,12 +267,7 @@ class SessionManager {
console.error(err)
}
}
await Promise.race([
closePipeline(),
new Promise((resolve) => {
setTimeout(resolve, 15000)
})
])
await Promise.race([closePipeline(), timeoutPromise(15000)])
console.log(workspace.id, 'Workspace closed...')
}

View File

@ -84,6 +84,9 @@ services:
- UPLOAD_URL=/files
- TRANSACTOR_URL=ws://localhost:3334
- ELASTIC_URL=http://elastic:9200
- GMAIL_URL=http://localhost:8088
- TELEGRAM_URL=http://localhost:8086
- REKONI_URL=http://rekoni:4005
- MINIO_ENDPOINT=minio
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin
@ -112,7 +115,7 @@ services:
image: hardcoreeng/rekoni-service
restart: on-failure
ports:
- 4004:4005
- 4005:4004
deploy:
resources:
limits:

View File

@ -3,7 +3,6 @@
docker-compose -p sanity kill
docker-compose -p sanity down --volumes
docker-compose -p sanity up -d --force-recreate --renew-anon-volumes
./setup-elastic.sh 9201
# Creae workspace record in accounts
./tool.sh create-workspace sanity-ws -o SanityTest