Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-m-o committed Nov 22, 2023
2 parents 98b43d8 + f17bba7 commit 7587a63
Show file tree
Hide file tree
Showing 110 changed files with 7,771 additions and 341 deletions.
5 changes: 4 additions & 1 deletion yomininja-e/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ data/
third-party-licenses.txt

# Browser extensions
extensions/
extensions/

# zip
/*.zip
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

export type AutoGeneratedFurigana = {
text: string;
startIdx: number;
endIdx: number;
}

export type GenerateFurigana_Input = {
term: string;
reading: string;
};

export type GenerateFurigana_Output = {
formatedFurigana: string;
furigana: AutoGeneratedFurigana[];
};

export interface JapaneseHelperAdapter {

generateFurigana( input: GenerateFurigana_Input ): GenerateFurigana_Output;
isKanji( char: string ): boolean;
hasKanji( text: string ): boolean;
hasKatakana( text: string ): boolean;
toHiragana( sentence: string ): string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,22 @@ export type OcrRecognitionInput = {
languageCode: string; // Two letters
};

export interface OcrEngineSettingsOptions {
inference_runtime: {
value: string,
displayName: string;
}[]
}

export interface OcrAdapter {
name: string;
status: OcrAdapterStatus;
initialize: ( serviceAddress?: string ) => void;
recognize: ( input: OcrRecognitionInput ) => Promise< OcrResult | null >;
getSupportedLanguages: () => Promise< string[] >; // Get this by calling the grpc stub or reading it's config files
updateSettings: ( input: OcrEngineSettings ) => Promise< boolean >;
getDefaultSettings: () => OcrEngineSettings;
getSettingsOptions: () => OcrEngineSettingsOptions;
restart: ( callback: () => void ) => void;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Language } from "../../domain/language/language";

export type GetTermsInput = {
text: string;
language?: Language;
};

export type ExtractedTerms = {
standard: string[];
kanaNormalized?: string[];
readingNormalized?: string[];
};

export interface TermExtractorAdapter {
getTerms: ( input: GetTermsInput ) => ExtractedTerms;
getTermsAsync: ( input: GetTermsInput ) => Promise< ExtractedTerms >;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { SettingsPreset } from "../../../domain/settings_preset/settings_preset";
import { SettingsPresetTypeOrmSchema } from "../../../infra/db/typeorm/settings_preset/settings_preset.schema";
import SettingsPresetTypeOrmRepository from "../../../infra/db/typeorm/settings_preset/settings_preset.typeorm.repository";
import { DataSource } from 'typeorm';

import { FakeOcrTestAdapter } from "../../../infra/test/fake_ocr.adapter/fake_ocr.adapter";
import { CreateSettingsPresetUseCase, CreateSettingsPreset_Input } from "./create_settings_preset.use_case";

describe("CreateSettingsPresetUseCase tests", () => {

let useCase: CreateSettingsPresetUseCase;

let settingsPresetRepo: SettingsPresetTypeOrmRepository;


beforeEach( async () => {

const dataSource = new DataSource({
type: 'sqlite',
database: ':memory:',
synchronize: true,
logging: false,
entities: [
SettingsPresetTypeOrmSchema,
],
});

await dataSource.initialize();

settingsPresetRepo = new SettingsPresetTypeOrmRepository(
dataSource.getRepository( SettingsPreset )
);
useCase = new CreateSettingsPresetUseCase({
settingsPresetRepo,
ocrAdapter: new FakeOcrTestAdapter()
});

});

it("should create the default settings preset", async () => {

await useCase.execute();

const foundPreset = await settingsPresetRepo.findOne({
name: SettingsPreset.default_name
});

expect( foundPreset?.name ).toStrictEqual( SettingsPreset.default_name );
expect( foundPreset?.ocr_engine.inference_runtime )
.toStrictEqual( 'ONNX_CPU' );
});

it("should create a custom settings preset", async () => {

const input: CreateSettingsPreset_Input = {
name: 'Custom',
ocr_engine: {
cpu_threads: 32,
image_scaling_factor: 1,
max_image_width: 1920,
inference_runtime: 'Open_VINO',
invert_colors: false,
ocr_adapter_name: FakeOcrTestAdapter._name
}
};

await useCase.execute( input );

const foundPreset = await settingsPresetRepo.findOne({ name: input.name });

expect( foundPreset?.ocr_engine )
.toStrictEqual( input.ocr_engine );
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { SettingsPreset, SettingsPresetJson } from "../../../domain/settings_preset/settings_preset";
import { SettingsPresetRepository } from "../../../domain/settings_preset/settings_preset.repository";
import { OcrAdapter } from "../../adapters/ocr.adapter";

export interface CreateSettingsPreset_Input extends Partial< Omit< SettingsPresetJson, 'id' > >{
}

export class CreateSettingsPresetUseCase {

public settingsPresetRepo: SettingsPresetRepository;
public ocrAdapter: OcrAdapter;

constructor( input: {
settingsPresetRepo: SettingsPresetRepository,
ocrAdapter: OcrAdapter
}) {
this.settingsPresetRepo = input.settingsPresetRepo;
this.ocrAdapter = input.ocrAdapter;
}

async execute( input?: CreateSettingsPreset_Input ): Promise< void > {

if ( input ) {
const foundSettingsPreset = await this.settingsPresetRepo.findOne({ name: input?.name });
if ( foundSettingsPreset )
return;
}

let settingsPreset: SettingsPreset;

if ( input?.name )
settingsPreset = SettingsPreset.create({ name: input.name });
else
settingsPreset = SettingsPreset.create();


if ( input?.ocr_engine )
settingsPreset.updateOcrEngineSettings( input?.ocr_engine );
else
settingsPreset.updateOcrEngineSettings( this.ocrAdapter.getDefaultSettings() );

if ( input?.overlay )
settingsPreset.updateOverlaySettings( input?.overlay );

if ( input?.dictionary )
settingsPreset.updateDictionarySettings( input?.dictionary );

await this.settingsPresetRepo.insert( settingsPreset );

if ( settingsPreset.name === SettingsPreset.default_name ) {
const restart = await this.ocrAdapter.updateSettings( settingsPreset.ocr_engine );

if ( restart )
this.ocrAdapter.restart( () => {} );
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { DataSource } from "typeorm";
import { DictionaryTypeOrmSchema } from "../../../../infra/db/typeorm/dictionary/dictionary.schema";
import { DictionaryTagTypeOrmSchema } from "../../../../infra/db/typeorm/dictionary/dictionary_tag/dictionary_tag.schema";
import DictionaryTypeOrmRepository from "../../../../infra/db/typeorm/dictionary/dictionary.typeorm.repository";
import { DictionaryDefinition } from "../../../../domain/dictionary/dictionary_definition/dictionary_definition";
import { DictionaryDefinitionTypeOrmSchema } from "../../../../infra/db/typeorm/dictionary/dictionary_definition/dictionary_definition.schema";
import { DictionaryHeadwordTypeOrmSchema } from "../../../../infra/db/typeorm/dictionary/dictionary_headword/dictionary_headword.schema";
import { DictionaryRepository } from "../../../../domain/dictionary/dictionary.repository";
import { DictionaryTagRepository } from "../../../../domain/dictionary/dictionary_tag/dictionary_tag.repository";
import { DictionaryDefinitionRepository } from "../../../../domain/dictionary/dictionary_definition/dictionary_definition.repository";
import { DictionaryHeadwordRepository } from "../../../../domain/dictionary/dictionary_headword/dictionary_headword.repository";
import { Dictionary } from "../../../../domain/dictionary/dictionary";
import DictionaryTagTypeOrmRepository from "../../../../infra/db/typeorm/dictionary/dictionary_tag/dictionary_tag.typeorm.repository";
import { DictionaryTag } from "../../../../domain/dictionary/dictionary_tag/dictionary_tag";
import DictionaryDefinitionTypeOrmRepository from "../../../../infra/db/typeorm/dictionary/dictionary_definition/dictionary_definition.typeorm.repository";
import DictionaryHeadwordTypeOrmRepository from "../../../../infra/db/typeorm/dictionary/dictionary_headword/dictionary_headword.typeorm.repository";
import { DictionaryHeadword } from "../../../../domain/dictionary/dictionary_headword/dictionary_headword";
import { Language } from "../../../../domain/language/language";
import { getRawDictionaryTags } from "../../../../domain/dictionary/common/test/dictionary_tag_test_data";
import { getRawDictionaryDefinitions } from "../../../../domain/dictionary/common/test/dictionary_definition_test_data";
import { DeleteAllDictionariesUseCase } from "./delete_all_dictionaries.use_case";




describe('DeleteAllDictionariesUseCase tests', () => {

let useCase: DeleteAllDictionariesUseCase;

let dataSource: DataSource;
let dictionariesRepo: DictionaryRepository;
let definitionsRepo: DictionaryDefinitionRepository;
let headwordsRepo: DictionaryHeadwordRepository;
let tagsRepo: DictionaryTagRepository;

let dictionary: Dictionary;

beforeEach( async () => {

dataSource = new DataSource({
type: 'sqlite',
database: ':memory:',
synchronize: true,
logging: false,
entities: [
DictionaryTypeOrmSchema,
DictionaryTagTypeOrmSchema,
DictionaryDefinitionTypeOrmSchema,
DictionaryHeadwordTypeOrmSchema,
]
});

await dataSource.initialize();

dictionariesRepo = new DictionaryTypeOrmRepository(
dataSource.getRepository( Dictionary )
);

tagsRepo = new DictionaryTagTypeOrmRepository(
dataSource.getRepository( DictionaryTag )
);

definitionsRepo = new DictionaryDefinitionTypeOrmRepository(
dataSource.getRepository( DictionaryDefinition )
);

headwordsRepo = new DictionaryHeadwordTypeOrmRepository(
dataSource.getRepository( DictionaryHeadword )
);

useCase = new DeleteAllDictionariesUseCase({
dictionariesRepo,
tagsRepo,
definitionsRepo,
headwordsRepo
});

dictionary = Dictionary.create({
name: "JMdict (English)",
version: "jmdict4",
enabled: true,
order: 0,
source_language: 'ja',
target_language: 'en',
})
await dictionariesRepo.insert( dictionary );

const rawDefinitions = getRawDictionaryDefinitions();

for ( const rawDefinition of rawDefinitions ) {

expect( rawDefinition ).toBeDefined();
if ( !rawDefinition ) return;

const dictionary_headword_id = DictionaryHeadword.generateId({
term: rawDefinition.term,
reading: rawDefinition.reading
});

await dataSource.getRepository( DictionaryDefinition )
.save(
DictionaryDefinition.create({
...rawDefinition,
dictionary_headword_id,
dictionary_id: dictionary.id,
tags: [],
popularity_score: rawDefinition.popularity
})
);

const headwordExists = await headwordsRepo.exist({ id: dictionary_headword_id });
if ( headwordExists )
continue;

const headword = DictionaryHeadword.create({
...rawDefinition,
tags: [],
definitions: [],
});

console.log( headword )

await dataSource.getRepository( DictionaryHeadword )
.save( headword );
}


const rawPnTag = getRawDictionaryTags().find( item => item.name === 'pn' );
expect( rawPnTag ).toBeDefined();
if(!rawPnTag) return;

await dataSource.getRepository( DictionaryTag )
.save(
DictionaryTag.create({
...rawPnTag,
dictionary_id: dictionary.id,
})
);

const dictionaries = await dataSource.getRepository( Dictionary ).find();
const definitions = await dataSource.getRepository( DictionaryDefinition ).find();
const headwords = await dataSource.getRepository( DictionaryHeadword ).find();
const tags = await dataSource.getRepository( DictionaryTag ).find();

expect( dictionaries.length > 0 ).toBeTruthy();
expect( definitions.length > 0 ).toBeTruthy();
expect( headwords.length > 0 ).toBeTruthy();
expect( tags.length > 0 ).toBeTruthy();
});

it('should delete all installed dictionaries, including headwords, definitions and tags', async () => {

await useCase.execute();

const dictionariesAfter = await dictionariesRepo.getAll();
expect( dictionariesAfter ).toHaveLength( 0 );


const dictionaries = await dataSource.getRepository( Dictionary ).find();
const definitions = await dataSource.getRepository( DictionaryDefinition ).find();
const headwords = await dataSource.getRepository( DictionaryHeadword ).find();
const tags = await dataSource.getRepository( DictionaryTag ).find();

expect( dictionaries.length == 0 ).toBeTruthy();
expect( definitions.length == 0 ).toBeTruthy();
expect( headwords.length == 0 ).toBeTruthy();
expect( tags.length == 0 ).toBeTruthy();
});

});
Loading

0 comments on commit 7587a63

Please sign in to comment.