Skip to content

Commit a1e62e3

Browse files
committed
(#271) Semantic/Vector Search
1 parent 98ec430 commit a1e62e3

File tree

6 files changed

+94
-9
lines changed

6 files changed

+94
-9
lines changed

src/Monolith/ClassifiedAds.Blazor.Modules/Core/Pages/Index.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
</div>
3333

3434
@code{
35-
string version = "7.0";
35+
string version = "10.0";
3636
}

src/Monolith/ClassifiedAds.Blazor.Modules/Files/Pages/Edit.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public partial class Edit
2828

2929
protected AuditLogsDialog AuditLogsDialog { get; set; }
3030

31+
public bool ShowTokenDetails { get; set; }
32+
3133
protected override async Task OnInitializedAsync()
3234
{
3335
File = await FileService.GetFileByIdAsync(Id);
@@ -45,10 +47,22 @@ protected async Task HandleValidSubmit()
4547
NavManager.NavigateTo("/files");
4648
}
4749

50+
protected async Task DownloadText()
51+
{
52+
var ext = Path.GetExtension(File.FileEntryText.TextLocation).ToLowerInvariant();
53+
var token = await FileService.GetAccessToken();
54+
await JSRuntime.InvokeVoidAsync("interop.downloadFile", FileService.GetDownloadTextUrl(File.Id), token, File.FileName + ext);
55+
}
56+
57+
protected async Task DownloadChunk(FileEntryEmbeddingModel chunk)
58+
{
59+
var token = await FileService.GetAccessToken();
60+
await JSRuntime.InvokeVoidAsync("interop.downloadFile", FileService.GetDownloadChunkUrl(File.Id, chunk.ChunkName), token, chunk.ChunkName);
61+
}
62+
4863
protected async Task DownloadEmbedding(FileEntryEmbeddingModel embedding)
4964
{
5065
using var streamRef = new DotNetStreamReference(stream: new MemoryStream(Encoding.UTF8.GetBytes(embedding.Embedding)));
51-
5266
await JSRuntime.InvokeVoidAsync("interop.downloadFileFromStream", "Embedding.txt", streamRef);
5367
}
5468
}

src/Monolith/ClassifiedAds.Blazor.Modules/Files/Pages/Edit.razor

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
<div class="form-group row">
4848
<label for="textLocation" class="col-sm-2 col-form-label">Text Location</label>
4949
<div class="col-sm-10">
50-
@File.FileEntryText?.TextLocation
50+
<a href="javascript:none()" @onclick="(() => DownloadText())">@File.FileEntryText?.TextLocation</a>
5151
</div>
5252
</div>
5353
}
@@ -80,25 +80,36 @@
8080
</div>
8181

8282
<div class="card-body">
83+
<div style="float: right;">
84+
<InputCheckbox id="showTokenDetails" @bind-Value="ShowTokenDetails" /> Show Token Details
85+
</div>
8386
<table class="table">
8487
<thead>
8588
<tr>
8689
<th>Chunk Name</th>
8790
<th>Chunk Location</th>
88-
<th>Embedding</th>
89-
<th>Token Details</th>
9091
<th>Created Date Time</th>
92+
<th>Embedding</th>
93+
@if (ShowTokenDetails)
94+
{
95+
<th>Token Details</th>
96+
}
9197
</tr>
9298
</thead>
9399
<tbody>
94100
@foreach (var fileEntryEmbedding in File.FileEntryEmbeddings)
95101
{
96102
<tr>
97103
<td>@fileEntryEmbedding.ChunkName</td>
98-
<td>@fileEntryEmbedding.ChunkLocation</td>
99-
<td><a href="javascript:none()" @onclick="(() => DownloadEmbedding(fileEntryEmbedding))">Download</a></td>
100-
<td>@fileEntryEmbedding.TokenDetails</td>
104+
<td>
105+
<a href="javascript:none()" @onclick="(() => DownloadChunk(fileEntryEmbedding))">@fileEntryEmbedding.ChunkLocation</a>
106+
</td>
101107
<td>@fileEntryEmbedding.CreatedDateTime</td>
108+
<td><a href="javascript:none()" @onclick="(() => DownloadEmbedding(fileEntryEmbedding))">Download</a></td>
109+
@if (ShowTokenDetails)
110+
{
111+
<td>@fileEntryEmbedding.TokenDetails</td>
112+
}
102113
</tr>
103114
}
104115
</tbody>

src/Monolith/ClassifiedAds.Blazor.Modules/Files/Services/FileService.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ public string GetDownloadUrl(Guid id)
2121
return $"{_httpClient.BaseAddress.AbsoluteUri.Trim('/')}/api/files/{id}/download";
2222
}
2323

24+
public string GetDownloadTextUrl(Guid id)
25+
{
26+
return $"{_httpClient.BaseAddress.AbsoluteUri.Trim('/')}/api/files/{id}/downloadtext";
27+
}
28+
29+
public string GetDownloadChunkUrl(Guid id, string chunkName)
30+
{
31+
return $"{_httpClient.BaseAddress.AbsoluteUri.Trim('/')}/api/files/{id}/downloadchunk/{chunkName}";
32+
}
33+
2434
public string GetUploadUrl()
2535
{
2636
return $"{_httpClient.BaseAddress.AbsoluteUri.Trim('/')}/api/files";

src/Monolith/ClassifiedAds.WebAPI/Controllers/FilesController.cs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ public async Task<ActionResult<IEnumerable<FileEntryModel>>> Get(Guid id)
162162

163163
model.FileEntryEmbeddings = _fileEntryEmbeddingRepository.GetQueryableSet()
164164
.Where(x => x.FileEntryId == fileEntry.Id)
165+
.OrderBy(x => x.CreatedDateTime)
165166
.Select(x => new FileEntryEmbeddingModel
166167
{
167168
ChunkName = x.ChunkName,
@@ -170,7 +171,8 @@ public async Task<ActionResult<IEnumerable<FileEntryModel>>> Get(Guid id)
170171
TokenDetails = x.TokenDetails,
171172
CreatedDateTime = x.CreatedDateTime,
172173
UpdatedDateTime = x.UpdatedDateTime,
173-
}).ToList();
174+
})
175+
.ToList();
174176

175177
return Ok(model);
176178
}
@@ -213,6 +215,53 @@ public async Task<IActionResult> Download(Guid id)
213215
return File(content, MediaTypeNames.Application.Octet, WebUtility.HtmlEncode(fileEntry.FileName));
214216
}
215217

218+
[Authorize(Permissions.DownloadFile)]
219+
[HttpGet("{id}/downloadtext")]
220+
public async Task<IActionResult> DownloadText(Guid id)
221+
{
222+
var fileEntry = await _dispatcher.DispatchAsync(new GetEntityByIdQuery<FileEntry> { Id = id });
223+
224+
var authorizationResult = await _authorizationService.AuthorizeAsync(User, fileEntry, Operations.Read);
225+
if (!authorizationResult.Succeeded)
226+
{
227+
return Forbid();
228+
}
229+
230+
var fileEntryText = _fileEntryTextRepository.GetQueryableSet()
231+
.Where(x => x.FileEntryId == fileEntry.Id)
232+
.Select(x => new FileEntryTextModel
233+
{
234+
TextLocation = x.TextLocation
235+
}).FirstOrDefault();
236+
237+
var stream = System.IO.File.OpenRead(Path.Combine(_options.Storage.TempFolderPath, fileEntryText.TextLocation));
238+
var ext = Path.GetExtension(fileEntryText.TextLocation).ToLowerInvariant();
239+
return File(stream, MediaTypeNames.Application.Octet, WebUtility.HtmlEncode(fileEntry.FileName + ext));
240+
}
241+
242+
[Authorize(Permissions.DownloadFile)]
243+
[HttpGet("{id}/downloadchunk/{chunkName}")]
244+
public async Task<IActionResult> DownloadChunk(Guid id, string chunkName)
245+
{
246+
var fileEntry = await _dispatcher.DispatchAsync(new GetEntityByIdQuery<FileEntry> { Id = id });
247+
248+
var authorizationResult = await _authorizationService.AuthorizeAsync(User, fileEntry, Operations.Read);
249+
if (!authorizationResult.Succeeded)
250+
{
251+
return Forbid();
252+
}
253+
254+
var fileEntryEmbedding = _fileEntryEmbeddingRepository.GetQueryableSet()
255+
.Where(x => x.FileEntryId == fileEntry.Id && x.ChunkName == chunkName)
256+
.Select(x => new FileEntryEmbeddingModel
257+
{
258+
ChunkLocation = x.ChunkLocation,
259+
}).FirstOrDefault();
260+
261+
var stream = System.IO.File.OpenRead(Path.Combine(_options.Storage.TempFolderPath, fileEntryEmbedding.ChunkLocation));
262+
return File(stream, MediaTypeNames.Application.Octet, WebUtility.HtmlEncode(fileEntryEmbedding.ChunkName));
263+
}
264+
216265
[Authorize(Permissions.UpdateFile)]
217266
[HttpPut("{id}")]
218267
[Consumes("application/json")]

src/Monolith/ClassifiedAds.WebAPI/appsettings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
"Storage": {
100100
"Provider": "Local",
101101
"MasterEncryptionKey": "+2ZC9wrwlvPswPxCND0BjrKJ3CfOpImGtn4hloVwo2I=",
102+
"TempFolderPath": "C:\\Data\\Practical.CleanArchitecture\\Temp",
102103
"Local": {
103104
"Path": "C:\\Data\\files"
104105
},

0 commit comments

Comments
 (0)