Skip to content

Commit cc5ce34

Browse files
Следующая порция улучшений + исправления security инцидентов
1 parent 38e904b commit cc5ce34

81 files changed

Lines changed: 21217 additions & 15012 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Repository instructions
2+
3+
## Versioning and release builds
4+
5+
- Do not bump the application version or build an installer, portable package, or other release artifact unless the user explicitly asks for it.
6+
- For local testing, rebuild only the required application code and update the changed files in the installed application when appropriate.

Api/Application/ClientApp/package-lock.json

Lines changed: 13695 additions & 14182 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Api/Application/ClientApp/package.json

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
},
1313
"private": true,
1414
"dependencies": {
15-
"@angular/animations": "22.0.0",
16-
"@angular/common": "22.0.0",
17-
"@angular/compiler": "22.0.0",
18-
"@angular/core": "22.0.0",
19-
"@angular/forms": "22.0.0",
20-
"@angular/platform-browser": "22.0.0",
21-
"@angular/platform-browser-dynamic": "22.0.0",
22-
"@angular/router": "22.0.0",
15+
"@angular/animations": "22.1.0",
16+
"@angular/common": "22.1.0",
17+
"@angular/compiler": "22.1.0",
18+
"@angular/core": "22.1.0",
19+
"@angular/forms": "22.1.0",
20+
"@angular/platform-browser": "22.1.0",
21+
"@angular/platform-browser-dynamic": "22.1.0",
22+
"@angular/router": "22.1.0",
2323
"@fortawesome/fontawesome-free": "^7.2.0",
2424
"bootstrap": "^5.3.8",
2525
"flatted": "^3.3.1",
@@ -29,19 +29,27 @@
2929
"zone.js": "^0.16.2"
3030
},
3131
"devDependencies": {
32-
"@angular-devkit/build-angular": "22.0.0",
33-
"@angular/cli": "22.0.0",
34-
"@angular/compiler-cli": "22.0.0",
32+
"@angular-devkit/build-angular": "22.1.2",
33+
"@angular/cli": "22.1.2",
34+
"@angular/compiler-cli": "22.1.0",
3535
"@types/jasmine": "^5.1.13",
3636
"@types/node": "^25.9.1",
3737
"ajv": "^8.20.0",
3838
"jasmine-core": "^6.2.0",
3939
"jasmine-spec-reporter": "^7.0.0",
40-
"karma": "~6.3.16",
40+
"karma": "^6.4.4",
4141
"karma-chrome-launcher": "^3.2.0",
4242
"karma-coverage": "^2.2.1",
4343
"karma-jasmine": "^5.1.0",
4444
"karma-jasmine-html-reporter": "^2.1.0",
4545
"typescript": "6.0.3"
46+
},
47+
"overrides": {
48+
"@hono/node-server": "2.1.0",
49+
"@angular/cli": {
50+
"@modelcontextprotocol/sdk": "1.30.0"
51+
},
52+
"uuid": "11.1.1",
53+
"ws": "8.21.0"
4654
}
4755
}

Api/Application/Controllers/OneNoteIntegrationController.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ public async Task<ActionResult<OneNoteComContentResponse>> PageContent(string pa
4848
};
4949
}
5050

51+
[HttpGet]
52+
public async Task<ActionResult<OneNotePageLinkResponse>> PageLink(string pageId)
53+
{
54+
if (string.IsNullOrWhiteSpace(pageId))
55+
return BadRequest("pageId is required.");
56+
57+
return new OneNotePageLinkResponse
58+
{
59+
ClientUrl = await oneNoteApp.GetHyperlinkToObjectAsync(pageId)
60+
};
61+
}
62+
5163
[HttpPost]
5264
public async Task<ActionResult<QuickAnalyzeCurrentPageResponse>> QuickAnalyzeCurrentPage()
5365
{
@@ -71,6 +83,11 @@ public class OneNoteComContentResponse
7183
public string Xml { get; set; }
7284
}
7385

86+
public class OneNotePageLinkResponse
87+
{
88+
public string ClientUrl { get; set; }
89+
}
90+
7491
public class QuickAnalyzeCurrentPageResponse : OneNoteCurrentPageInfo
7592
{
7693
public bool PageUpdated { get; set; }

Api/Application/Controllers/VerseParsingController.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,10 @@ public ActionResult<ParsePageResponse> ParsePage([FromBody] ParsePageRequest req
322322

323323
using (var parser = documentParserFactory.Create(provider, documentId))
324324
{
325+
var defaultBook = TryGetTitleBook(request.Title);
326+
if (defaultBook != null)
327+
parser.SetDefaultBook(defaultBook.BibleBook, defaultBook.ModuleName);
328+
325329
if (!string.IsNullOrWhiteSpace(request.Html))
326330
{
327331
updatedHtml = ParseHtml(parser, request.Html, paragraphs, updateHtml);
@@ -381,6 +385,30 @@ public ActionResult<ParsePageResponse> ParsePage([FromBody] ParsePageRequest req
381385
}
382386
}
383387

388+
private Abbreviation TryGetTitleBook(string title)
389+
{
390+
if (string.IsNullOrWhiteSpace(title))
391+
return null;
392+
393+
var matches = applicationManager.CurrentModuleInfo.BibleStructure.AllAbbreviations.Values
394+
.Where(abbreviation => abbreviation.IsFullBookName
395+
&& TitleContainsBookName(title, abbreviation.Value))
396+
.GroupBy(abbreviation => abbreviation.BibleBook.Index)
397+
.Select(group => group.OrderByDescending(abbreviation => abbreviation.Value.Length).First())
398+
.ToList();
399+
400+
return matches.Count == 1 ? matches[0] : null;
401+
}
402+
403+
private static bool TitleContainsBookName(string title, string bookName)
404+
{
405+
var words = Regex.Split(bookName.Trim(), @"\s+")
406+
.Where(word => word.Length > 0)
407+
.Select(Regex.Escape);
408+
var pattern = @"(?<![\p{L}\p{N}])" + string.Join(@"\s+", words) + @"(?![\p{L}\p{N}])";
409+
return Regex.IsMatch(title, pattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
410+
}
411+
384412
[HttpGet]
385413
public ActionResult<VerseTextResponse> VerseText([FromQuery] VerseTextRequest request)
386414
{

Api/Providers/OneNote/Contracts/IOneNoteAppWrapper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public interface IOneNoteAppWrapper : IDisposable
1212
Task<string> GetHierarchyContentAsync(string hierarchyId, HierarchyScope scope);
1313
Task<string> GetCurrentPageIdAsync();
1414
Task<OneNoteCurrentPageInfo> GetCurrentPageInfoAsync();
15+
Task<string> GetHyperlinkToObjectAsync(string hierarchyId, string objectId = "");
1516
Task<string> GetCurrentSectionIdAsync();
1617
Task UpdatePageContentAsync(XDocument pageDoc);
1718
Task<OneNoteHierarchyInfo> GetHierarchyInfoAsync(string hierarchyId);

Api/Providers/OneNote/Services/OneNoteAppWrapper.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ await UseOneNoteAppInSingleThreadAsync(app =>
8181
return result;
8282
}
8383

84+
public async Task<string> GetHyperlinkToObjectAsync(string hierarchyId, string objectId = "")
85+
{
86+
string result = null;
87+
88+
await UseOneNoteAppInSingleThreadAsync(app =>
89+
{
90+
app.GetHyperlinkToObject(hierarchyId, objectId ?? string.Empty, out result);
91+
});
92+
93+
return result;
94+
}
95+
8496
public async Task<string> GetCurrentSectionIdAsync()
8597
{
8698
string currentSectionId = null;

Api/Services/VerseParsing/Contracts/IDocumentParser.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using BibleNote.Services.VerseParsing.Contracts.ParseContext;
44
using BibleNote.Services.VerseParsing.Models;
55
using BibleNote.Services.VerseParsing.Models.ParseResult;
6+
using BibleNote.Services.ModulesManager.Scheme.Module;
67

78
namespace BibleNote.Services.VerseParsing.Contracts
89
{
@@ -14,6 +15,8 @@ public interface IDocumentParser: IDisposable
1415

1516
ParagraphParseResult ParseParagraph(IXmlNode node);
1617

18+
void SetDefaultBook(BibleBookInfo book, string moduleName);
19+
1720
DisposeHandler ParseHierarchyElement(ElementType paragraphType);
1821
}
1922
}

Api/Services/VerseParsing/Contracts/ParseContext/IDocumentParseContext.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using BibleNote.Services.Contracts;
22
using BibleNote.Services.VerseParsing.Models;
33
using BibleNote.Services.VerseParsing.Models.ParseResult;
4+
using BibleNote.Services.ModulesManager.Scheme.Module;
45

56
namespace BibleNote.Services.VerseParsing.Contracts.ParseContext
67
{
@@ -10,6 +11,10 @@ public interface IDocumentParseContext
1011

1112
ChapterEntry TitleChapter { get; }
1213

14+
BibleBookInfo DefaultBook { get; }
15+
16+
string DefaultBookModuleName { get; }
17+
1318
IParagraphParseContext CurrentParagraph { get; }
1419

1520
IHierarchyParseContext CurrentHierarchy { get; }
@@ -25,6 +30,8 @@ public interface IDocumentParseContextEditor : IDocumentParseContext
2530

2631
void SetTitleVerse(ChapterEntry titleChapter);
2732

33+
void SetDefaultBook(BibleBookInfo book, string moduleName);
34+
2835
DisposeHandler ParseParagraph();
2936

3037
void EnterHierarchyElement(ElementType paragraphType);

Api/Services/VerseParsing/Contracts/ParseContext/IHierarchyParseContext.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public interface IHierarchyParseContext : IElementParseContext
2020

2121
void AddHierarchyResult(HierarchyParseResult hierarchyResult);
2222

23+
void AddStructuralHierarchyResult(HierarchyParseResult hierarchyResult);
24+
2325
void ChangeElementType(ElementType elementType);
2426

2527
ChapterEntry GetPreviousSiblingChapterEntry();

0 commit comments

Comments
 (0)