V2 #1
							
								
								
									
										42
									
								
								src/MyWebLog.Data/Category.cs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										42
									
								
								src/MyWebLog.Data/Category.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					namespace MyWebLog.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A category under which a post may be identfied
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Category
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of the category
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Id { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The displayed name
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Name { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The slug (used in category URLs)
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Slug { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// A longer description of the category
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string? Description { get; set; } = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The parent ID of this category (if a subcategory)
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string? ParentId { get; set; } = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The parent of this category (if a subcategory)
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public Category? Parent { get; set; } = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The posts assigned to this category
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public ICollection<Post> Posts { get; set; } = default!;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										62
									
								
								src/MyWebLog.Data/Comment.cs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										62
									
								
								src/MyWebLog.Data/Comment.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					namespace MyWebLog.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A comment on a post
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Comment
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of the comment
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Id { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of the post to which this comment applies
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string PostId { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The post to which this comment applies
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public Post Post { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of the comment to which this comment is a reply
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string? InReplyToId { get; set; } = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The comment to which this comment is a reply
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public Comment? InReplyTo { get; set; } = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The name of the commentor
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Name { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The e-mail address of the commentor
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Email { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The URL of the commentor's personal website
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string? Url { get; set; } = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The status of the comment
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public CommentStatus Status { get; set; } = CommentStatus.Pending;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// When the comment was posted
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DateTime PostedOn { get; set; } = DateTime.UtcNow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The text of the comment
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Text { get; set; } = "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										47
									
								
								src/MyWebLog.Data/Enums.cs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										47
									
								
								src/MyWebLog.Data/Enums.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					namespace MyWebLog.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The source format for a revision
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public enum RevisionSource
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>Markdown text</summary>
 | 
				
			||||||
 | 
					    Markdown,
 | 
				
			||||||
 | 
					    /// <summary>HTML</summary>
 | 
				
			||||||
 | 
					    Html
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A level of authorization for a given web log
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public enum AuthorizationLevel
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>The user may administer all aspects of a web log</summary>
 | 
				
			||||||
 | 
					    Administrator,
 | 
				
			||||||
 | 
					    /// <summary>The user is a known user of a web log</summary>
 | 
				
			||||||
 | 
					    User
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Statuses for posts
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public enum PostStatus
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>The post should not be publicly available</summary>
 | 
				
			||||||
 | 
					    Draft,
 | 
				
			||||||
 | 
					    /// <summary>The post is publicly viewable</summary>
 | 
				
			||||||
 | 
					    Published
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Statuses for post comments
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public enum CommentStatus
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>The comment is approved</summary>
 | 
				
			||||||
 | 
					    Approved,
 | 
				
			||||||
 | 
					    /// <summary>The comment has yet to be approved</summary>
 | 
				
			||||||
 | 
					    Pending,
 | 
				
			||||||
 | 
					    /// <summary>The comment was unsolicited and unwelcome</summary>
 | 
				
			||||||
 | 
					    Spam
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										9
									
								
								src/MyWebLog.Data/MyWebLog.Data.csproj
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										9
									
								
								src/MyWebLog.Data/MyWebLog.Data.csproj
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					<Project Sdk="Microsoft.NET.Sdk">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <PropertyGroup>
 | 
				
			||||||
 | 
					    <TargetFramework>net6.0</TargetFramework>
 | 
				
			||||||
 | 
					    <ImplicitUsings>enable</ImplicitUsings>
 | 
				
			||||||
 | 
					    <Nullable>enable</Nullable>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</Project>
 | 
				
			||||||
							
								
								
									
										62
									
								
								src/MyWebLog.Data/Page.cs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										62
									
								
								src/MyWebLog.Data/Page.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					namespace MyWebLog.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A page (text not associated with a date/time)
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Page
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of this page
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Id { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of the author of this page
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string AuthorId { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The author of this page
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public WebLogUser Author { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The title of the page
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Title { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The link at which this page is displayed
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Permalink { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The instant this page was published
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DateTime PublishedOn { get; set; } = DateTime.MinValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The instant this page was last updated
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DateTime UpdatedOn { get; set; } = DateTime.MinValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Whether this page shows as part of the web log's navigation
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public bool ShowInPageList { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The current text of the page
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Text { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Permalinks at which this page may have been previously served (useful for migrated content)
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public ICollection<PagePermalink> PriorPermalinks { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Revisions of this page
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public ICollection<PageRevision> Revisions { get; set; } = default!;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										49
									
								
								src/MyWebLog.Data/Permalink.cs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										49
									
								
								src/MyWebLog.Data/Permalink.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					namespace MyWebLog.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A permalink which a post or page used to have
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public abstract class Permalink
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of this permalink
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Id { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The link
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Url { get; set; } = "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A prior permalink for a page
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class PagePermalink : Permalink
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of the page to which this permalink belongs
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string PageId { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The page to which this permalink belongs
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public Page Page { get; set; } = default!;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A prior permalink for a post
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class PostPermalink : Permalink
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of the post to which this permalink belongs
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string PostId { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The post to which this permalink belongs
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public Post Post { get; set; } = default!;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										72
									
								
								src/MyWebLog.Data/Post.cs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										72
									
								
								src/MyWebLog.Data/Post.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					namespace MyWebLog.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A web log post
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Post
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of this post
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Id { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of the author of this post
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string AuthorId { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The author of the post
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public WebLogUser Author { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The status
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public PostStatus Status { get; set; } = PostStatus.Draft;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The title
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Title { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The link at which the post resides
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Permalink { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The instant on which the post was originally published
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DateTime? PublishedOn { get; set; } = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The instant on which the post was last updated
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DateTime UpdatedOn { get; set; } = DateTime.MinValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The text of the post in HTML (ready to display) format
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Text { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The Ids of the categories to which this is assigned
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public ICollection<Category> Categories { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The tags for the post
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public ICollection<Tag> Tags { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Permalinks at which this post may have been previously served (useful for migrated content)
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public ICollection<PostPermalink> PriorPermalinks { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The revisions for this post
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public ICollection<PostRevision> Revisions { get; set; } = default!;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										59
									
								
								src/MyWebLog.Data/Revision.cs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										59
									
								
								src/MyWebLog.Data/Revision.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					namespace MyWebLog.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A revision of a page or post
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public abstract class Revision
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of this revision
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Id { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// When this revision was saved
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DateTime AsOf { get; set; } = DateTime.UtcNow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The source language (Markdown or HTML)
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public RevisionSource SourceType { get; set; } = RevisionSource.Html;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The text of the revision
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Text { get; set; } = "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A revision of a page
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class PageRevision : Revision
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of the page to which this revision belongs
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string PageId { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The page to which this revision belongs
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public Page Page { get; set; } = default!;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A revision of a post
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class PostRevision : Revision
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of the post to which this revision applies
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string PostId { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The post to which this revision applies
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public Post Post { get; set; } = default!;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										17
									
								
								src/MyWebLog.Data/Tag.cs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										17
									
								
								src/MyWebLog.Data/Tag.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					namespace MyWebLog.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A tag
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class Tag
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The name of the tag
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Name { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The posts with this tag assigned
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public ICollection<Post> Posts { get; set; } = default!;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										69
									
								
								src/MyWebLog.Data/WebLogDbContext.cs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										69
									
								
								src/MyWebLog.Data/WebLogDbContext.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MyWebLog.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Data context for web log data
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public sealed class WebLogDbContext : DbContext
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The categories for the web log
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DbSet<Category> Categories { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Comments on posts
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DbSet<Comment> Comments { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Pages
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DbSet<Page> Pages { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Web log posts
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DbSet<Post> Posts { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Post tags
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DbSet<Tag> Tags { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The users of the web log
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DbSet<WebLogUser> Users { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The details for the web log
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public DbSet<WebLogDetails> WebLogDetails { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Constructor
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="options">Configuration options</param>
 | 
				
			||||||
 | 
					    public WebLogDbContext(DbContextOptions<WebLogDbContext> options) : base(options) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <inheritdoc />
 | 
				
			||||||
 | 
					    protected override void OnModelCreating(ModelBuilder modelBuilder)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        base.OnModelCreating(modelBuilder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Tag and WebLogDetails use Name as its ID
 | 
				
			||||||
 | 
					        modelBuilder.Entity<Tag>().HasKey(t => t.Name);
 | 
				
			||||||
 | 
					        modelBuilder.Entity<WebLogDetails>().HasKey(wld => wld.Name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Index slugs and links
 | 
				
			||||||
 | 
					        modelBuilder.Entity<Category>().HasIndex(c => c.Slug);
 | 
				
			||||||
 | 
					        modelBuilder.Entity<Page>().HasIndex(p => p.Permalink);
 | 
				
			||||||
 | 
					        modelBuilder.Entity<Post>().HasIndex(p => p.Permalink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Link "author" to "user"
 | 
				
			||||||
 | 
					        modelBuilder.Entity<Page>().HasOne(p => p.Author).WithMany(wbu => wbu.Pages).HasForeignKey(p => p.AuthorId);
 | 
				
			||||||
 | 
					        modelBuilder.Entity<Post>().HasOne(p => p.Author).WithMany(wbu => wbu.Posts).HasForeignKey(p => p.AuthorId);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								src/MyWebLog.Data/WebLogDetails.cs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										37
									
								
								src/MyWebLog.Data/WebLogDetails.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					namespace MyWebLog.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The details about a web log
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class WebLogDetails
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The name of the web log
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Name { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// A subtitle for the web log
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string? Subtitle { get; set; } = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The default page ("posts" or a page Id)
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string DefaultPage { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The path of the theme (within /views/themes)
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string ThemePath { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The URL base
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string UrlBase { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The time zone in which dates/times should be displayed
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string TimeZone { get; set; } = "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										57
									
								
								src/MyWebLog.Data/WebLogUser.cs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										57
									
								
								src/MyWebLog.Data/WebLogUser.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					namespace MyWebLog.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A user of the web log
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public class WebLogUser
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The ID of the user
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Id { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The user name (e-mail address)
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string UserName { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The user's first name
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string FirstName { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The user's last name
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string LastName { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The user's preferred name
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string PreferredName { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The hash of the user's password
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string PasswordHash { get; set; } = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Salt used to calculate the user's password hash
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public Guid Salt { get; set; } = Guid.Empty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The URL of the user's personal site
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string? Url { get; set; } = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Pages written by this author
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public ICollection<Page> Pages { get; set; } = default!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Posts written by this author
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public ICollection<Post> Posts { get; set; } = default!;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										31
									
								
								src/MyWebLog.sln
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
								
							
						
						
									
										31
									
								
								src/MyWebLog.sln
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					Microsoft Visual Studio Solution File, Format Version 12.00
 | 
				
			||||||
 | 
					# Visual Studio Version 17
 | 
				
			||||||
 | 
					VisualStudioVersion = 17.1.32210.238
 | 
				
			||||||
 | 
					MinimumVisualStudioVersion = 10.0.40219.1
 | 
				
			||||||
 | 
					Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "MyWebLog", "MyWebLog\MyWebLog.fsproj", "{2E5E2346-25FE-4CBD-89AA-6148A33DE09C}"
 | 
				
			||||||
 | 
					EndProject
 | 
				
			||||||
 | 
					Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyWebLog.Data", "MyWebLog.Data\MyWebLog.Data.csproj", "{0177C744-F913-4352-A0EC-478B4B0388C3}"
 | 
				
			||||||
 | 
					EndProject
 | 
				
			||||||
 | 
					Global
 | 
				
			||||||
 | 
						GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
				
			||||||
 | 
							Debug|Any CPU = Debug|Any CPU
 | 
				
			||||||
 | 
							Release|Any CPU = Release|Any CPU
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
						GlobalSection(ProjectConfigurationPlatforms) = postSolution
 | 
				
			||||||
 | 
							{2E5E2346-25FE-4CBD-89AA-6148A33DE09C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
				
			||||||
 | 
							{2E5E2346-25FE-4CBD-89AA-6148A33DE09C}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
				
			||||||
 | 
							{2E5E2346-25FE-4CBD-89AA-6148A33DE09C}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
				
			||||||
 | 
							{2E5E2346-25FE-4CBD-89AA-6148A33DE09C}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
				
			||||||
 | 
							{0177C744-F913-4352-A0EC-478B4B0388C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
				
			||||||
 | 
							{0177C744-F913-4352-A0EC-478B4B0388C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
				
			||||||
 | 
							{0177C744-F913-4352-A0EC-478B4B0388C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
				
			||||||
 | 
							{0177C744-F913-4352-A0EC-478B4B0388C3}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
						GlobalSection(SolutionProperties) = preSolution
 | 
				
			||||||
 | 
							HideSolutionNode = FALSE
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
						GlobalSection(ExtensibilityGlobals) = postSolution
 | 
				
			||||||
 | 
							SolutionGuid = {70EEF0F4-8709-44A8-AD9B-24D1EB84CFB4}
 | 
				
			||||||
 | 
						EndGlobalSection
 | 
				
			||||||
 | 
					EndGlobal
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user