Skip to content

Commit

Permalink
Merge pull request #14 from Jisco/progress
Browse files Browse the repository at this point in the history
add possibility to show progress during file parsing
  • Loading branch information
Jisco committed Feb 6, 2022
2 parents 4cebb54 + 5dac524 commit 35fde02
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 11 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ I am aware that there are already several parsers for the gedcom format. However

##### Via commandline

Just run npx ts-node src/index.ts with the wanted flags. Eg if you run "npm run demo:JSON" it will execute "ts-node src/index.ts --path 'examples/simpsons.get'" and will print out the Simpsons GEDCOM examplke file as JSON object in the console. With "npm run demoFile:JSON" it will do the same but prints the JSON object in a 'test.json' file.
Just run npx ts-node src/console.ts with the wanted flags. Eg if you run "npm run demo:JSON" it will execute "ts-node src/console.ts --path 'examples/simpsons.get'" and will print out the Simpsons GEDCOM examplke file as JSON object in the console. With "npm run demoFile:JSON" it will do the same but prints the JSON object in a 'test.json' file.

| Flag | Description |
| ---------------- | ------------------------------------------------------------ |
Expand All @@ -40,6 +40,7 @@ Just run npx ts-node src/index.ts with the wanted flags. Eg if you run "npm run
| --out *xxx.json* | File path to print into |
| --path *xxx.ged* | Set the path to the GEDCOM file |
| --silent | Don't print anything to the console |
| --showProgress | Print the progress during processing the file |

##### Via Node or JS

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"clean": "tsc --build ./tsconfig.json --clean",
"demo:JSON": "ts-node src/console.ts --path 'examples/simpsons.ged'",
"demoFile:JSON": "ts-node src/console.ts --path 'examples/simpsons.ged' --out 'test.json'",
"demoFileWithProgress:JSON": "ts-node src/console.ts --path 'examples/royal92.ged' --out 'test.json' --showProgress",
"test": "nyc mocha",
"test:watch": "mocha --watch --watch-files src, tests/**/*.ts",
"doc": "typedoc --out docs src",
Expand Down
6 changes: 6 additions & 0 deletions src/ToJSON/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ export function Convert(argv:any) {
options.SetConfigFile(argv.opt as string);
}

if (argv.showProgress) {
options.SetProgressFunction((linesCount: number, lineNumber:number) => {
process.stdout.write(`\rProgress: parsing line ${lineNumber} from ${linesCount}`);
});
}

let silent = false;
if (argv.silent) {
silent = true;
Expand Down
6 changes: 3 additions & 3 deletions src/ToJSON/models/Parsing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default class Parsing {
return new ParsingResult({});
}

return ParseText(this.options.GetText(), this.options.GetConfig());
return ParseText(this.options.GetText(), this.options.GetConfig(), this.options.GetProgressFunction());
}

ParseTextAsync(): Promise<ParsingResult> {
Expand All @@ -29,7 +29,7 @@ export default class Parsing {
}

return new Promise<ParsingResult>((resolve, reject) => {
resolve(ParseText(this.options.GetText(), this.options.GetConfig()));
resolve(ParseText(this.options.GetText(), this.options.GetConfig(), this.options.GetProgressFunction()));
});
}

Expand All @@ -39,7 +39,7 @@ export default class Parsing {
return;
}

ParseFile(filePath, this.options.GetConfig(), doneCallback, errorCallback);
ParseFile(filePath, this.options.GetConfig(), doneCallback, errorCallback, this.options.GetProgressFunction());
}

ParseFileAsync(): Promise<ParsingResult> {
Expand Down
9 changes: 9 additions & 0 deletions src/ToJSON/models/ParsingOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export default class ParsingOptions {
private text?: string;
private filePath?: string;
private config?: string;
private progressFunction?: (linesCount: number, actualLine: number) => void;

SetText(text: string) {
this.text = text;
Expand Down Expand Up @@ -30,4 +31,12 @@ export default class ParsingOptions {
GetConfig() {
return this.config ?? require('fs').readFileSync('options/version551.yaml', 'utf8');
}

SetProgressFunction(func: (linesCount: number, actualLine: number) => void) {
this.progressFunction = func;
}

GetProgressFunction() : ((linesCount: number, actualLine: number) => void) | undefined {
return this.progressFunction;
}
}
61 changes: 55 additions & 6 deletions src/ToJSON/parsing/parsing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ let stats = new Statistics();
*
* @param text - The text
* @param parsingOptions - The parsing options
* @param invokeProgressFunction - Set function that is called before each line, to show progress in some way
* @returns An object which includes the parsed object and parsing statistics
*/
export function ParseText(text?: string, parsingOptions?: string): ParsingResult {
export function ParseText(
text?: string,
parsingOptions?: string,
invokeProgressFunction?: (linesCount: number, actualLine: number) => void): ParsingResult {

if (!text || !parsingOptions){
return new ParsingResult({});
}
Expand Down Expand Up @@ -51,8 +56,12 @@ export function ParseText(text?: string, parsingOptions?: string): ParsingResult
lineNumber++;
};

forEach(lines, line => {
ProcessNewLine(lastLevel, lineNumber, line, nextLine);
forEach(lines, (line, index) => {
if (invokeProgressFunction) {
invokeProgressFunction(lines.length, index);
}

ProcessNewLine(lastLevel, lineNumber, line, nextLine);
});

let result = GetResult();
Expand All @@ -67,11 +76,47 @@ export function ParseText(text?: string, parsingOptions?: string): ParsingResult
* @param parsingOptions - The parsing options
* @param doneCallback - Returns the resulting object when file is readed completly
* @param errorCallback - Returns file reading errors
* @param invokeProgressFunction - Set function that is called before each line, to show progress in some way
* @returns An object which includes the parsed object and parsing statistics
*/

/* istanbul ignore next */ // maybe later ;)
export function ParseFile(path: string, parsingOptions: string, doneCallback: (result: ParsingResult) => void, errorCallback: any) {
let lr = new LineByLineReader(path);
export function ParseFile(
path: string,
parsingOptions: string,
doneCallback: (result: ParsingResult) => void,
errorCallback: any,
invokeProgressFunction?: ((linesCount: number, actualLine: number) => void) | undefined) {

// if no progress should be shown, it is not necessary to get the line count of the file at first
if (!invokeProgressFunction) {
ExecuteParseFile(path, parsingOptions, doneCallback, errorCallback, 0);
return;
}

// read first time to get lines count
let linesCountLr = new LineByLineReader(path);
let linesCount = 0;
linesCountLr.on('line', function (line: any) {
linesCountLr.pause();
linesCount++;
linesCountLr.resume();
});

linesCountLr.on('end', function () {
ExecuteParseFile(path, parsingOptions, doneCallback, errorCallback, linesCount, invokeProgressFunction);
});
}

/* istanbul ignore next */ // maybe later ;)
function ExecuteParseFile(
path: string,
parsingOptions: string,
doneCallback: (result: ParsingResult) => void,
errorCallback: any,
linesCount: number,
invokeProgressFunction?: ((linesCount: number, actualLine: number) => void) | undefined) {
let lr = new LineByLineReader(path);
let lastLevel = 0;
let lineNumber = 1;
let yamlOptions: string | object | undefined = {};
Expand All @@ -93,6 +138,10 @@ export function ParseFile(path: string, parsingOptions: string, doneCallback: (r
lastLevel = lastLine.Level;
}

if (invokeProgressFunction) {
invokeProgressFunction(linesCount, lineNumber);
}

lineNumber++;
lr.resume();
};
Expand All @@ -115,7 +164,7 @@ export function ParseFile(path: string, parsingOptions: string, doneCallback: (r
// All lines are read, file is closed now.
doneCallback(new ParsingResult(result, stats));
});
}
}

/**
* Function that processes a text line
Expand Down
2 changes: 1 addition & 1 deletion src/ToJSON/parsing/processLine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import ParsingPath from '../models/ParsingPath';
import { ClearDateTimeMergingInfos } from './parseDate';

const eachDeep = require('deepdash/eachDeep');
let parsingOptions: any;

/**
* Store for file\text processing
Expand All @@ -30,7 +31,6 @@ export function ResetProcessing() {
parsingOptions = {};
}

let parsingOptions: any;
export function SetParsingOptions(options: any) {
parsingOptions = options;
}
Expand Down
33 changes: 33 additions & 0 deletions tests/ToJSON/Parsing.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,37 @@ describe('Parsing text', () => {
expect(stats.NotParsedLinesWithoutGEDCOMTag).lengthOf(1);
});
});

it('With Progress', () => {
let testData = `
0 @N00010@ NOTE
0 TRLR`;

let options = `
Definition:
- Tag: NOTE
CollectAs: Notes
Property: Id
`;

let allLinesCount = 0;
let invokeCounter = 0;
let lineNumberArray: number[] = [];
let progressFunc = (linesCount: number, lineNumber:number) => {
allLinesCount = linesCount;
invokeCounter++;
lineNumberArray.push(lineNumber);
};

expect(ParseText(testData, options, progressFunc).Object).to.deep.equal({
Notes:
{
Id: "@N00010@"
}
});

expect(allLinesCount).to.equal(3);
expect(invokeCounter).to.equal(3);
expect(lineNumberArray).to.deep.equal([ 0, 1, 2 ]);
});
});

0 comments on commit 35fde02

Please sign in to comment.