Skip to content

Commit d00a6bd

Browse files
committed
add elo parsing to bulk-tags
1 parent 781e0cf commit d00a6bd

File tree

5 files changed

+104
-33
lines changed

5 files changed

+104
-33
lines changed

packages/platform-ui/src/components/Edit/BulkImportView.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ Example:
1111
Card 1 Question
1212
{{blank}}
1313
tags: tagA, tagB
14+
elo: 1500
1415
---
1516
---
1617
Card 2 Question
1718
Another {{blank}}
19+
elo: 1200
1820
tags: tagC"
1921
rows="15"
2022
varient="outlined"

packages/platform-ui/src/utils/bulkImport/cardParser.ts

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ import { ParsedCard } from './types';
66
export interface CardParserConfig {
77
/** Custom tag identifier (defaults to 'tags:') */
88
tagIdentifier?: string;
9+
/** Custom ELO identifier (defaults to 'elo:') */
10+
eloIdentifier?: string;
911
}
1012

1113
/**
1214
* Default configuration for the card parser
1315
*/
1416
const DEFAULT_PARSER_CONFIG: CardParserConfig = {
1517
tagIdentifier: 'tags:',
18+
eloIdentifier: 'elo:',
1619
};
1720

1821
/**
@@ -35,20 +38,43 @@ export function parseCard(cardString: string, config: CardParserConfig = DEFAULT
3538

3639
const lines = trimmedCardString.split('\n');
3740
let tags: string[] = [];
41+
let elo: number | undefined = undefined;
3842
const markdownLines = [...lines];
39-
40-
if (lines.length > 0) {
41-
const lastLine = lines[lines.length - 1].trim();
42-
const tagId = config.tagIdentifier || DEFAULT_PARSER_CONFIG.tagIdentifier;
43+
44+
// Process the lines from bottom to top to handle metadata
45+
let metadataLines = 0;
46+
47+
// Get the configured identifiers
48+
const tagId = config.tagIdentifier || DEFAULT_PARSER_CONFIG.tagIdentifier;
49+
const eloId = config.eloIdentifier || DEFAULT_PARSER_CONFIG.eloIdentifier;
50+
51+
// Check the last few lines for metadata (tags and elo)
52+
for (let i = lines.length - 1; i >= 0 && i >= lines.length - 2; i--) {
53+
const line = lines[i].trim();
4354

44-
if (lastLine.toLowerCase().startsWith(tagId!.toLowerCase())) {
45-
tags = lastLine
55+
// Check for tags
56+
if (line.toLowerCase().startsWith(tagId!.toLowerCase())) {
57+
tags = line
4658
.substring(tagId!.length)
4759
.split(',')
4860
.map((tag) => tag.trim())
4961
.filter((tag) => tag);
50-
markdownLines.pop(); // Remove the tags line
62+
metadataLines++;
5163
}
64+
// Check for ELO
65+
else if (line.toLowerCase().startsWith(eloId!.toLowerCase())) {
66+
const eloValue = line.substring(eloId!.length).trim();
67+
const parsedElo = parseInt(eloValue, 10);
68+
if (!isNaN(parsedElo)) {
69+
elo = parsedElo;
70+
}
71+
metadataLines++;
72+
}
73+
}
74+
75+
// Remove metadata lines from the end of the content
76+
if (metadataLines > 0) {
77+
markdownLines.splice(markdownLines.length - metadataLines);
5278
}
5379

5480
const markdown = markdownLines.join('\n').trim();
@@ -57,7 +83,7 @@ export function parseCard(cardString: string, config: CardParserConfig = DEFAULT
5783
return null;
5884
}
5985

60-
return { markdown, tags };
86+
return { markdown, tags, elo };
6187
}
6288

6389
/**

packages/platform-ui/src/utils/bulkImport/cardProcessor.ts

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { parseCard, splitCardsText } from './cardParser';
55

66
/**
77
* Processes multiple cards from bulk text input
8-
*
8+
*
99
* @param bulkText - Raw text containing multiple cards
1010
* @param courseDB - Course database interface
1111
* @param config - Configuration for the card processor
@@ -17,7 +17,7 @@ export async function processBulkCards(
1717
config: BulkCardProcessorConfig
1818
): Promise<ImportResult[]> {
1919
const results: ImportResult[] = [];
20-
20+
2121
if (!bulkText.trim()) {
2222
return results;
2323
}
@@ -55,7 +55,9 @@ export async function processBulkCards(
5555
results.push({
5656
originalText,
5757
status: 'error',
58-
message: `Error processing card: ${error instanceof Error ? error.message : 'Unknown error'}`,
58+
message: `Error processing card: ${
59+
error instanceof Error ? error.message : 'Unknown error'
60+
}`,
5961
});
6062
}
6163
}
@@ -65,7 +67,7 @@ export async function processBulkCards(
6567

6668
/**
6769
* Processes a single parsed card
68-
*
70+
*
6971
* @param parsedCard - Parsed card data
7072
* @param courseDB - Course database interface
7173
* @param config - Configuration for the card processor
@@ -76,24 +78,49 @@ async function processCard(
7678
courseDB: CourseDBInterface,
7779
config: BulkCardProcessorConfig
7880
): Promise<ImportResult> {
79-
const { markdown, tags } = parsedCard;
80-
const originalText = `${markdown}\ntags: ${tags.join(', ')}`;
81+
const { markdown, tags, elo } = parsedCard;
82+
83+
// Build the original text representation including metadata
84+
let originalText = markdown;
85+
if (tags.length > 0) {
86+
originalText += `\ntags: ${tags.join(', ')}`;
87+
}
88+
if (elo !== undefined) {
89+
originalText += `\nelo: ${elo}`;
90+
}
8191

8292
// Create card data object
8393
const cardData: CardData = {
8494
Input: markdown,
8595
Uploads: [], // No uploads for bulk import
8696
};
8797

98+
const tagsElo = {};
99+
for (const tag of tags) {
100+
tagsElo[tag] = {
101+
score: elo || 0,
102+
count: 1,
103+
};
104+
}
105+
88106
try {
89107
const result = await courseDB.addNote(
90108
config.courseCode,
91109
config.dataShape,
92110
cardData,
93111
config.userName,
94112
tags,
95-
undefined, // deck
96-
undefined // elo
113+
undefined, // attachments
114+
elo
115+
? {
116+
global: {
117+
score: elo,
118+
count: 1,
119+
},
120+
tags: tagsElo,
121+
misc: {},
122+
}
123+
: undefined
97124
);
98125

99126
if (result.status === Status.ok) {
@@ -122,33 +149,34 @@ async function processCard(
122149

123150
/**
124151
* Validates the configuration for bulk card processing
125-
*
152+
*
126153
* @param config - Configuration to validate
127154
* @returns Object with validation result and error message if any
128155
*/
129-
export function validateProcessorConfig(config: Partial<BulkCardProcessorConfig>):
130-
{ isValid: boolean; errorMessage?: string } {
131-
156+
export function validateProcessorConfig(config: Partial<BulkCardProcessorConfig>): {
157+
isValid: boolean;
158+
errorMessage?: string;
159+
} {
132160
if (!config.dataShape) {
133-
return {
134-
isValid: false,
135-
errorMessage: 'No data shape provided for card processing'
161+
return {
162+
isValid: false,
163+
errorMessage: 'No data shape provided for card processing',
136164
};
137165
}
138-
166+
139167
if (!config.courseCode) {
140-
return {
141-
isValid: false,
142-
errorMessage: 'No course code provided for card processing'
168+
return {
169+
isValid: false,
170+
errorMessage: 'No course code provided for card processing',
143171
};
144172
}
145-
173+
146174
if (!config.userName) {
147-
return {
148-
isValid: false,
149-
errorMessage: 'No user name provided for card processing'
175+
return {
176+
isValid: false,
177+
errorMessage: 'No user name provided for card processing',
150178
};
151179
}
152-
180+
153181
return { isValid: true };
154-
}
182+
}

packages/platform-ui/src/utils/bulkImport/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ async function exampleUsage(courseDB: CourseDBInterface, dataShape: DataShape) {
1919
const bulkText = `Card 1 Question
2020
{{blank}}
2121
tags: tagA, tagB
22+
elo: 1500
2223
---
2324
---
2425
Card 2 Question
2526
Another {{blank}}
27+
elo: 1200
2628
tags: tagC`;
2729
2830
// Validate config
@@ -45,5 +47,16 @@ tags: tagC`;
4547
console.log(`Processed ${results.length} cards`);
4648
console.log(`Success: ${results.filter(r => r.status === 'success').length}`);
4749
console.log(`Errors: ${results.filter(r => r.status === 'error').length}`);
50+
51+
// Example of parsing a single card with tags and elo
52+
const singleCard = `Example card with a {{blank}}
53+
elo: 1600
54+
tags: tag1, tag2`;
55+
const parsed = parseCard(singleCard);
56+
console.log('Parsed card:', {
57+
markdown: parsed?.markdown,
58+
tags: parsed?.tags,
59+
elo: parsed?.elo // Will show 1600
60+
});
4861
}
4962
*/

packages/platform-ui/src/utils/bulkImport/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export interface ParsedCard {
2222
markdown: string;
2323
/** Tags associated with the card */
2424
tags: string[];
25+
/** ELO rating for the card (optional) */
26+
elo?: number;
2527
}
2628

2729
/**

0 commit comments

Comments
 (0)