-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Publish a post #22 * Set publish date * Move images/files to new folder, when slug changes (folder name is slug) * Preview button, show unpublished the post for a logged in user * move seed to sample app and add waffle gen * Update prism version and new prism theme
- Loading branch information
1 parent
c113119
commit c740db8
Showing
32 changed files
with
1,592 additions
and
1,160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
using Opw.PineBlog.Entities; | ||
using Opw.PineBlog.EntityFrameworkCore; | ||
using System; | ||
using System.Linq; | ||
using WaffleGenerator; | ||
|
||
namespace Opw.PineBlog.Sample | ||
{ | ||
internal class DatabaseSeed | ||
{ | ||
private readonly BlogEntityDbContext _dbContext; | ||
|
||
public DatabaseSeed(BlogEntityDbContext context) | ||
{ | ||
_dbContext = context; | ||
} | ||
|
||
public void Run() | ||
{ | ||
if (DateTime.UtcNow.Day % 2 == 0) | ||
CreateAuthor("John Smith", "images/avatar-male.png"); | ||
else | ||
CreateAuthor("Mary Smith", "images/avatar-female.png"); | ||
|
||
CreateBlogPosts(); | ||
} | ||
|
||
void CreateAuthor(string name, string imagePath) | ||
{ | ||
if (_dbContext.Authors.Count() > 0) return; | ||
|
||
var email = "pineblog@example.com"; | ||
if (_dbContext.Authors.Count(a => a.UserName.Equals(email)) > 0) return; | ||
|
||
_dbContext.Authors.Add(new Author | ||
{ | ||
UserName = email, | ||
Email = email, | ||
DisplayName = name, | ||
Avatar = imagePath, | ||
Bio = WaffleEngine.Text(1, false), | ||
}); | ||
|
||
_dbContext.SaveChanges(); | ||
} | ||
|
||
void CreateBlogPosts() | ||
{ | ||
if (_dbContext.Posts.Count() > 0) return; | ||
|
||
var author = _dbContext.Authors.Single(); | ||
|
||
for(int i = 0; i < 5; i++) | ||
{ | ||
var title = WaffleEngine.Title(); | ||
var post = new Post | ||
{ | ||
AuthorId = author.Id, | ||
Title = title, | ||
Slug = title.ToSlug(), | ||
Description = WaffleEngine.Text(1, false), | ||
Published = DateTime.UtcNow.AddDays(-i * 10) | ||
}; | ||
|
||
if (i % 2 == 0) | ||
{ | ||
post.CoverUrl = "/images/woods.gif"; | ||
post.CoverCaption = "Battle background for the Misty Woods in the game Shadows of Adam by Tim Wendorf"; | ||
post.CoverLink = "http://pixeljoint.com/pixelart/94359.htm"; | ||
post.Content = $"## {WaffleEngine.Text(1, true)} {WaffleEngine.Text(1, false)} \n``` csharp\npublic class {{\n var myVar = \"Some value\";\n}}\n```\n ## {WaffleEngine.Text(1, true)} {WaffleEngine.Text(2, false)}"; | ||
post.Categories = "csharp,waffle,random"; | ||
} | ||
else | ||
{ | ||
post.Content = $"## {WaffleEngine.Text(1, true)} {WaffleEngine.Text(1, false)} ### {WaffleEngine.Text(1, true)} \n``` yaml\nYAML: YAML Ain't Markup Language\n```\n ## {WaffleEngine.Text(1, true)} {WaffleEngine.Text(2, false)}"; | ||
post.Categories = "yaml,waffle,random"; | ||
} | ||
|
||
_dbContext.Posts.Add(post); | ||
} | ||
|
||
_dbContext.SaveChanges(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using MediatR; | ||
using Microsoft.EntityFrameworkCore; | ||
using Opw.HttpExceptions; | ||
using Opw.PineBlog.Entities; | ||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace Opw.PineBlog.Posts | ||
{ | ||
/// <summary> | ||
/// Command that publishes a post. | ||
/// </summary> | ||
public class PublishPostCommand : IRequest<Result<Post>> | ||
{ | ||
/// <summary> | ||
/// The post id. | ||
/// </summary> | ||
public Guid Id { get; set; } | ||
|
||
/// <summary> | ||
/// Handler for the PublishPostCommand. | ||
/// </summary> | ||
public class Handler : IRequestHandler<PublishPostCommand, Result<Post>> | ||
{ | ||
private readonly IBlogEntityDbContext _context; | ||
|
||
/// <summary> | ||
/// Implementation of PublishPostCommand.Handler. | ||
/// </summary> | ||
/// <param name="context">The blog entity context.</param> | ||
public Handler(IBlogEntityDbContext context) | ||
{ | ||
_context = context; | ||
} | ||
|
||
/// <summary> | ||
/// Handle the PublishPostCommand request. | ||
/// </summary> | ||
/// <param name="request">The PublishPostCommand request.</param> | ||
/// <param name="cancellationToken">A cancellation token.</param> | ||
public async Task<Result<Post>> Handle(PublishPostCommand request, CancellationToken cancellationToken) | ||
{ | ||
var entity = await _context.Posts.SingleOrDefaultAsync(e => e.Id.Equals(request.Id)); | ||
if (entity == null) | ||
return Result<Post>.Fail(new NotFoundException<Post>($"Could not find post, id: \"{request.Id}\"")); | ||
|
||
entity.Published = DateTime.UtcNow; | ||
|
||
_context.Posts.Update(entity); | ||
var result = await _context.SaveChangesAsync(true, cancellationToken); | ||
if (!result.IsSuccess) | ||
return Result<Post>.Fail(result.Exception); | ||
|
||
return Result<Post>.Success(entity); | ||
} | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/Opw.PineBlog.Core/Posts/PublishPostCommandValidator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using FluentValidation; | ||
using Opw.FluentValidation; | ||
|
||
namespace Opw.PineBlog.Posts | ||
{ | ||
/// <summary> | ||
/// Validator for the PublishPostCommand request. | ||
/// </summary> | ||
public class PublishPostCommandValidator : AbstractValidator<PublishPostCommand> | ||
{ | ||
/// <summary> | ||
/// Implementation of PublishPostCommandValidator. | ||
/// </summary> | ||
public PublishPostCommandValidator() | ||
{ | ||
RuleFor(c => c.Id).IsRequiredGuid(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using MediatR; | ||
using Microsoft.EntityFrameworkCore; | ||
using Opw.HttpExceptions; | ||
using Opw.PineBlog.Entities; | ||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace Opw.PineBlog.Posts | ||
{ | ||
/// <summary> | ||
/// Command that unpublishes a post. | ||
/// </summary> | ||
public class UnpublishPostCommand : IRequest<Result<Post>> | ||
{ | ||
/// <summary> | ||
/// The post id. | ||
/// </summary> | ||
public Guid Id { get; set; } | ||
|
||
/// <summary> | ||
/// Handler for the UnpublishPostCommand. | ||
/// </summary> | ||
public class Handler : IRequestHandler<UnpublishPostCommand, Result<Post>> | ||
{ | ||
private readonly IBlogEntityDbContext _context; | ||
|
||
/// <summary> | ||
/// Implementation of UnpublishPostCommand.Handler. | ||
/// </summary> | ||
/// <param name="context">The blog entity context.</param> | ||
public Handler(IBlogEntityDbContext context) | ||
{ | ||
_context = context; | ||
} | ||
|
||
/// <summary> | ||
/// Handle the UnpublishPostCommand request. | ||
/// </summary> | ||
/// <param name="request">The UnpublishPostCommand request.</param> | ||
/// <param name="cancellationToken">A cancellation token.</param> | ||
public async Task<Result<Post>> Handle(UnpublishPostCommand request, CancellationToken cancellationToken) | ||
{ | ||
var entity = await _context.Posts.SingleOrDefaultAsync(e => e.Id.Equals(request.Id)); | ||
if (entity == null) | ||
return Result<Post>.Fail(new NotFoundException<Post>($"Could not find post, id: \"{request.Id}\"")); | ||
|
||
entity.Published = null; | ||
|
||
_context.Posts.Update(entity); | ||
var result = await _context.SaveChangesAsync(true, cancellationToken); | ||
if (!result.IsSuccess) | ||
return Result<Post>.Fail(result.Exception); | ||
|
||
return Result<Post>.Success(entity); | ||
} | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/Opw.PineBlog.Core/Posts/UnpublishPostCommandValidator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using FluentValidation; | ||
using Opw.FluentValidation; | ||
|
||
namespace Opw.PineBlog.Posts | ||
{ | ||
/// <summary> | ||
/// Validator for the UnpublishPostCommand request. | ||
/// </summary> | ||
public class UnpublishPostCommandValidator : AbstractValidator<UnpublishPostCommand> | ||
{ | ||
/// <summary> | ||
/// Implementation of UnpublishPostCommandValidator. | ||
/// </summary> | ||
public UnpublishPostCommandValidator() | ||
{ | ||
RuleFor(c => c.Id).IsRequiredGuid(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.