Skip to content

Commit

Permalink
Upgrade to v8.1
Browse files Browse the repository at this point in the history
  • Loading branch information
mythz committed Feb 6, 2024
1 parent ad47876 commit 2a72fa7
Show file tree
Hide file tree
Showing 19 changed files with 299 additions and 114 deletions.
31 changes: 11 additions & 20 deletions MyApp.ServiceInterface/EmailServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,32 +48,24 @@ public class SmtpConfig
/// <summary>
/// Uses a configured SMTP client to send emails
/// </summary>
public class EmailServices : Service
public class EmailServices(SmtpConfig config, ILogger<EmailServices> log)
// TODO: Uncomment to enable sending emails with SMTP
// : Service
{
public EmailServices(SmtpConfig config, ILogger<EmailServices> log)
{
Config = config;
Log = log;
}

public SmtpConfig Config { get; }
public ILogger<EmailServices> Log { get; }

/* Uncomment to enable sending emails with SMTP
public object Any(SendEmail request)
{
Log.LogInformation("Sending email to {Email} with subject {Subject}", request.To, request.Subject);
log.LogInformation("Sending email to {Email} with subject {Subject}", request.To, request.Subject);

using var client = new SmtpClient(Config.Host, Config.Port);
client.Credentials = new System.Net.NetworkCredential(Config.Username, Config.Password);
using var client = new SmtpClient(config.Host, config.Port);
client.Credentials = new System.Net.NetworkCredential(config.Username, config.Password);
client.EnableSsl = true;

// If DevToEmail is set, send all emails to that address instead
var emailTo = Config.DevToEmail != null
? new MailAddress(Config.DevToEmail)
var emailTo = config.DevToEmail != null
? new MailAddress(config.DevToEmail)
: new MailAddress(request.To, request.ToName);

var emailFrom = new MailAddress(Config.FromEmail, Config.FromName);
var emailFrom = new MailAddress(config.FromEmail, config.FromName);

var msg = new MailMessage(emailFrom, emailTo)
{
Expand All @@ -82,14 +74,13 @@ public object Any(SendEmail request)
IsBodyHtml = request.BodyHtml != null,
};

if (Config.Bcc != null)
if (config.Bcc != null)
{
msg.Bcc.Add(new MailAddress(Config.Bcc));
msg.Bcc.Add(new MailAddress(config.Bcc));
}

client.Send(msg);

return new EmptyResponse();
}
*/
}
5 changes: 2 additions & 3 deletions MyApp.ServiceModel/Hello.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

namespace MyApp.ServiceModel;

[Route("/hello")]
[Route("/hello/{Name}")]
public class Hello : IReturn<HelloResponse>
public class Hello : IGet, IReturn<HelloResponse>
{
public string? Name { get; set; }
}

public class HelloResponse
{
public string Result { get; set; } = default!;
public required string Result { get; set; }
}
2 changes: 1 addition & 1 deletion MyApp/Components/Pages/Posts/Author.razor
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<BlogPosts Posts=@Blog.GetPosts(author: author.Name) />

<div class="mt-8 text-center">
<a class="text-sm font-semibold hover:underline" href="@Blog.GetAllPostsLink()">view all posts</a>
<a class="text-sm font-semibold hover:underline" href="@Blog.GetPostsLink()">view all posts</a>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@page "/posts/all"
@page "/posts/"
@inject MarkdownBlog Blog
@inject AppConfig AppConfig

Expand Down
2 changes: 1 addition & 1 deletion MyApp/Components/Pages/Posts/Tagged.razor
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<BlogPosts Posts=@Blog.GetPosts(tag: selectedTag ?? "unknown") />

<div class="mt-8 text-center">
<a class="text-sm font-semibold hover:underline" href="@Blog.GetAllPostsLink()">view all posts</a>
<a class="text-sm font-semibold hover:underline" href="@Blog.GetPostsLink()">view all posts</a>
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion MyApp/Components/Pages/Posts/Year.razor
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<BlogPosts Posts=@Blog.GetPosts(year: ForYear) />

<div class="mt-8 text-center">
<a class="text-sm font-semibold hover:underline" href="@Blog.GetAllPostsLink()">view all posts</a>
<a class="text-sm font-semibold hover:underline" href="@Blog.GetPostsLink()">view all posts</a>
</div>
</div>

Expand Down
2 changes: 1 addition & 1 deletion MyApp/Configure.Auth.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ public void Configure(IWebHostBuilder builder) => builder
.ConfigureAppHost(appHost =>
{
appHost.Plugins.Add(new AuthFeature(IdentityAuth.For<ApplicationUser>(options => {
options.EnableCredentialsAuth = true;
options.SessionFactory = () => new CustomUserSession();
options.CredentialsAuth();
})));
});
}
5 changes: 2 additions & 3 deletions MyApp/Configure.AutoQuery.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using ServiceStack;
using ServiceStack.Data;
using ServiceStack.Data;

[assembly: HostingStartup(typeof(MyApp.ConfigureAutoQuery))]

Expand All @@ -11,7 +10,7 @@ public void Configure(IWebHostBuilder builder) => builder
.ConfigureServices(services => {
// Enable Audit History
services.AddSingleton<ICrudEvents>(c =>
new OrmLiteCrudEvents(c.Resolve<IDbConnectionFactory>()));
new OrmLiteCrudEvents(c.GetRequiredService<IDbConnectionFactory>()));
})
.ConfigureAppHost(appHost => {

Expand Down
3 changes: 0 additions & 3 deletions MyApp/Configure.Markdown.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ public void Configure(IWebHostBuilder builder) => builder
var blogPosts = appHost.Resolve<MarkdownBlog>();

blogPosts.Authors = AppConfig.Instance.Authors;
new IMarkdownPages[] { pages, videos, blogPosts }
.Each(x => x.VirtualFiles = appHost.VirtualFiles);

pages.LoadFrom("_pages");
videos.LoadFrom("_videos");
blogPosts.LoadFrom("_posts");
Expand Down
45 changes: 18 additions & 27 deletions MyApp/Markdown.Blog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Globalization;
using Markdig;
using ServiceStack.IO;
using ServiceStack.Logging;

namespace MyApp;

Expand All @@ -18,18 +17,18 @@ public class AuthorInfo
public string? MastodonUrl { get; set; }
}

public class MarkdownBlog : MarkdownPagesBase<MarkdownFileInfo>
public class MarkdownBlog(ILogger<MarkdownBlog> log, IWebHostEnvironment env, IVirtualFiles fs)
: MarkdownPagesBase<MarkdownFileInfo>(log, env, fs)
{
public override string Id => "posts";
public MarkdownBlog(ILogger<MarkdownBlog> log, IWebHostEnvironment env) : base(log,env) {}
List<MarkdownFileInfo> Posts { get; set; } = new();
List<MarkdownFileInfo> Posts { get; set; } = [];

public List<MarkdownFileInfo> VisiblePosts => Posts.Where(IsVisible).ToList();

public string FallbackProfileUrl { get; set; } = Svg.ToDataUri(Svg.Create(Svg.Body.User, stroke:"none").Replace("fill='currentColor'","fill='#0891b2'"));
public string FallbackSplashUrl { get; set; } = "https://source.unsplash.com/random/2000x1000/?stationary";

public List<AuthorInfo> Authors { get; set; } = new();
public List<AuthorInfo> Authors { get; set; } = [];

public Dictionary<string, AuthorInfo> AuthorSlugMap { get; } = new();
public Dictionary<string, string> TagSlugMap { get; } = new();
Expand Down Expand Up @@ -71,7 +70,7 @@ public List<MarkdownFileInfo> GetPosts(string? author = null, string? tag = null

public string GetPostLink(MarkdownFileInfo post) => $"posts/{post.Slug}";

public string GetAllPostsLink() => "posts/all";
public string GetPostsLink() => "posts/";
public string? GetAuthorLink(string? author) => author != null && Authors.Any(x => x.Name.Equals(author, StringComparison.OrdinalIgnoreCase))
? $"posts/author/{author.GenerateSlug()}"
: null;
Expand All @@ -81,19 +80,13 @@ public List<MarkdownFileInfo> GetPosts(string? author = null, string? tag = null
public string GetDateLabel(DateTime? date) => X.Map(date ?? DateTime.UtcNow, d => d.ToString("MMMM d, yyyy"))!;
public string GetDateTimestamp(DateTime? date) => X.Map(date ?? DateTime.UtcNow, d => d.ToString("O"))!;

public AuthorInfo? GetAuthorBySlug(string? slug)
{
return AuthorSlugMap.TryGetValue(slug, out var author)
? author
: null;
}
public AuthorInfo? GetAuthorBySlug(string? slug) => slug != null && AuthorSlugMap.TryGetValue(slug, out var author)
? author
: null;

public string? GetTagBySlug(string? slug)
{
return TagSlugMap.TryGetValue(slug, out var tag)
? tag
: null;
}
public string? GetTagBySlug(string? slug) => slug != null && TagSlugMap.TryGetValue(slug, out var tag)
? tag
: null;

public string GetSplashImage(MarkdownFileInfo post)
{
Expand All @@ -108,14 +101,14 @@ public string GetSplashImage(MarkdownFileInfo post)
public override MarkdownFileInfo? Load(string path, MarkdownPipeline? pipeline = null)
{
var file = VirtualFiles.GetFile(path)
?? throw new FileNotFoundException(path.LastRightPart('/'));
?? throw new FileNotFoundException(path.LastRightPart('/'));
var content = file.ReadAllText();

var writer = new StringWriter();
var doc = CreateMarkdownFile(content, writer, pipeline);
if (doc?.Title == null)
if (doc.Title == null)
{
Log.LogWarning("No frontmatter found for {0}, ignoring...", file.VirtualPath);
log.LogWarning("No frontmatter found for {VirtualPath}, ignoring...", file.VirtualPath);
return null;
}

Expand All @@ -127,7 +120,7 @@ public string GetSplashImage(MarkdownFileInfo post)
if (!DateTime.TryParseExact(datePart, "yyyy-MM-dd", CultureInfo.InvariantCulture,
DateTimeStyles.AdjustToUniversal, out var date))
{
Log.LogWarning("Could not parse date '{0}', ignoring...", datePart);
log.LogWarning("Could not parse date '{DatePart}', ignoring...", datePart);
return null;
}

Expand All @@ -143,10 +136,8 @@ public string GetSplashImage(MarkdownFileInfo post)
public void LoadFrom(string fromDirectory)
{
Posts.Clear();
var fs = AssertVirtualFiles();
var files = fs.GetDirectory(fromDirectory).GetAllFiles().ToList();
var log = LogManager.GetLogger(GetType());
log.InfoFormat("Found {0} posts", files.Count);
var files = VirtualFiles.GetDirectory(fromDirectory).GetAllFiles().ToList();
log.LogInformation("Found {Count} posts", files.Count);

var pipeline = CreatePipeline();

Expand All @@ -162,7 +153,7 @@ public void LoadFrom(string fromDirectory)
}
catch (Exception e)
{
log.Error(e, "Couldn't load {0}: {1}", file.VirtualPath, e.Message);
log.LogError(e, "Couldn't load {VirtualPath}: {Message}", file.VirtualPath, e.Message);
}
}

Expand Down
60 changes: 60 additions & 0 deletions MyApp/Markdown.Meta.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using ServiceStack.IO;
using ServiceStack.Text;

namespace MyApp;

public class MarkdownMeta
{
public List<IMarkdownPages> Features { get; set; } = [];

public async Task RenderToAsync(string metaDir, string baseUrl)
{
FileSystemVirtualFiles.RecreateDirectory(metaDir);
using var scope = JsConfig.With(new Config { ExcludeTypeInfo = true });
var featureDocs = new Dictionary<string, List<MarkdownFileBase>>();
var allYears = new HashSet<int>();
var index = new Dictionary<string, object>();
foreach (var feature in Features.Safe())
{
var allDocs = feature.GetAll()
.OrderByDescending(x => x.Date!.Value)
.ThenBy(x => x.Order)
.ThenBy(x => x.FileName)
.ToList();
allDocs.ForEach(x => {
if (x.Url?.StartsWith("/") == true)
x.Url = baseUrl.CombineWith(x.Url);
if (x.Image?.StartsWith("/") == true)
x.Image = baseUrl.CombineWith(x.Image);
});
featureDocs[feature.Id] = allDocs;
var featureYears = allDocs.Select(x => x.Date!.Value.Year).Distinct().OrderBy(x => x).ToList();
featureYears.ForEach(x => allYears.Add(x));

index[feature.Id] = featureYears.Map(x => baseUrl.CombineWith($"/meta/{x}/{feature.Id}.json"));
foreach (var year in featureYears)
{
var yearDocs = allDocs
.Where(x => x.Date!.Value.Year == year)
.ToList();
var yearDir = metaDir.CombineWith(year).AssertDir();
var metaPath = yearDir.CombineWith($"{feature.Id}.json");
await File.WriteAllTextAsync(metaPath, yearDocs.ToJson());
}
}
await File.WriteAllTextAsync(metaDir.CombineWith("index.json"), JSON.stringify(index));

await File.WriteAllTextAsync(metaDir.CombineWith("all.json"), JSON.stringify(featureDocs));
foreach (var year in allYears.OrderBy(x => x))
{
var yearDocs = new Dictionary<string, List<MarkdownFileBase>>();
foreach (var entry in featureDocs)
{
yearDocs[entry.Key] = entry.Value
.Where(x => x.Date!.Value.Year == year)
.ToList();
}
await File.WriteAllTextAsync(metaDir.CombineWith($"{year}/all.json"), JSON.stringify(yearDocs));
}
}
}
Loading

0 comments on commit 2a72fa7

Please sign in to comment.