Skip to content

Commit 7e0e5fa

Browse files
committed
monographs: add slug field which regenerates on update
1 parent e489ce7 commit 7e0e5fa

File tree

4 files changed

+49
-9
lines changed

4 files changed

+49
-9
lines changed

Notesnook.API/Controllers/MonographsController.cs

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,24 @@ You should have received a copy of the Affero GNU General Public License
1818
*/
1919

2020
using System;
21-
using System.Collections.Generic;
2221
using System.Linq;
2322
using System.Security.Claims;
2423
using System.Text.Json;
2524
using System.Threading.Tasks;
2625
using AngleSharp;
27-
using AngleSharp.Dom;
2826
using Microsoft.AspNetCore.Authorization;
2927
using Microsoft.AspNetCore.Http;
3028
using Microsoft.AspNetCore.Mvc;
3129
using Microsoft.Extensions.Logging;
3230
using MongoDB.Bson;
3331
using MongoDB.Driver;
34-
using Notesnook.API.Authorization;
32+
using NanoidDotNet;
3533
using Notesnook.API.Models;
3634
using Notesnook.API.Services;
3735
using Streetwriters.Common;
3836
using Streetwriters.Common.Helpers;
3937
using Streetwriters.Common.Interfaces;
4038
using Streetwriters.Common.Messages;
41-
using Streetwriters.Data.Interfaces;
4239
using Streetwriters.Data.Repositories;
4340

4441
namespace Notesnook.API.Controllers
@@ -95,6 +92,22 @@ private async Task<Monograph> FindMonographAsync(string itemId)
9592
return await result.FirstOrDefaultAsync();
9693
}
9794

95+
private async Task<Monograph> FindMonographBySlugAsync(string slug)
96+
{
97+
var result = await monographs.Collection.FindAsync(
98+
Builders<Monograph>.Filter.Eq("Slug", slug),
99+
new FindOptions<Monograph>
100+
{
101+
Limit = 1
102+
});
103+
return await result.FirstOrDefaultAsync();
104+
}
105+
106+
private static string GenerateSlug()
107+
{
108+
return Nanoid.Generate(size: 24);
109+
}
110+
98111
[HttpPost]
99112
public async Task<IActionResult> PublishAsync([FromQuery] string? deviceId, [FromBody] Monograph monograph)
100113
{
@@ -120,6 +133,7 @@ public async Task<IActionResult> PublishAsync([FromQuery] string? deviceId, [Fro
120133
}
121134
monograph.Deleted = false;
122135
monograph.ViewCount = 0;
136+
monograph.Slug = GenerateSlug();
123137
await monographs.Collection.ReplaceOneAsync(
124138
CreateMonographFilter(userId, monograph),
125139
monograph,
@@ -131,7 +145,8 @@ await monographs.Collection.ReplaceOneAsync(
131145
return Ok(new
132146
{
133147
id = monograph.ItemId,
134-
datePublished = monograph.DatePublished
148+
datePublished = monograph.DatePublished,
149+
slug = monograph.Slug
135150
});
136151
}
137152
catch (Exception e)
@@ -164,6 +179,7 @@ public async Task<IActionResult> UpdateAsync([FromQuery] string? deviceId, [From
164179
monograph.Content = null;
165180

166181
monograph.DatePublished = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
182+
monograph.Slug = GenerateSlug();
167183
var result = await monographs.Collection.UpdateOneAsync(
168184
CreateMonographFilter(userId, monograph),
169185
Builders<Monograph>.Update
@@ -172,6 +188,7 @@ public async Task<IActionResult> UpdateAsync([FromQuery] string? deviceId, [From
172188
.Set(m => m.EncryptedContent, monograph.EncryptedContent)
173189
.Set(m => m.SelfDestruct, monograph.SelfDestruct)
174190
.Set(m => m.Title, monograph.Title)
191+
.Set(m => m.Slug, monograph.Slug)
175192
.Set(m => m.Password, monograph.Password)
176193
);
177194
if (!result.IsAcknowledged) return BadRequest();
@@ -181,7 +198,8 @@ public async Task<IActionResult> UpdateAsync([FromQuery] string? deviceId, [From
181198
return Ok(new
182199
{
183200
id = monograph.ItemId,
184-
datePublished = monograph.DatePublished
201+
datePublished = monograph.DatePublished,
202+
slug = monograph.Slug
185203
});
186204
}
187205
catch (Exception e)
@@ -208,11 +226,25 @@ public async Task<IActionResult> GetUserMonographsAsync()
208226
return Ok(userMonographs.Select((m) => m.ItemId ?? m.Id));
209227
}
210228

211-
[HttpGet("{id}")]
229+
[HttpGet("{slugOrId}")]
212230
[AllowAnonymous]
213-
public async Task<IActionResult> GetMonographAsync([FromRoute] string id)
231+
public async Task<IActionResult> GetMonographAsync([FromRoute] string slugOrId)
214232
{
215-
var monograph = await FindMonographAsync(id);
233+
var monograph = await FindMonographBySlugAsync(slugOrId);
234+
235+
if (monograph == null)
236+
{
237+
monograph = await FindMonographAsync(slugOrId);
238+
if (!string.IsNullOrEmpty(monograph?.Slug))
239+
{
240+
return NotFound(new
241+
{
242+
error = "invalid_id",
243+
error_description = $"No such monograph found."
244+
});
245+
}
246+
}
247+
216248
if (monograph == null || monograph.Deleted)
217249
{
218250
return NotFound(new

Notesnook.API/Hubs/SyncV2Hub.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ private async Task<SyncV2Metadata> HandleRequestFetch(string deviceId, bool incl
282282
Password = m.Password,
283283
SelfDestruct = m.SelfDestruct,
284284
Title = m.Title,
285+
Slug = m.Slug,
285286
ItemId = m.ItemId ?? m.Id.ToString(),
286287
ViewCount = m.ViewCount
287288
}).ToListAsync();

Notesnook.API/Models/Monograph.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ public Monograph()
5656
[JsonPropertyName("title")]
5757
public string? Title { get; set; }
5858

59+
[JsonPropertyName("slug")]
60+
[MessagePack.Key("slug")]
61+
public string? Slug { get; set; }
62+
5963
[JsonPropertyName("userId")]
6064
public string? UserId { get; set; }
6165

Notesnook.API/Models/MonographMetadata.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ public required string ItemId
3737
[JsonPropertyName("title")]
3838
public string? Title { get; set; }
3939

40+
[JsonPropertyName("slug")]
41+
public string? Slug { get; set; }
42+
4043
[JsonPropertyName("selfDestruct")]
4144
public bool SelfDestruct { get; set; }
4245

0 commit comments

Comments
 (0)