diff options
| author | Michael <[email protected]> | 2017-04-07 21:13:44 -0400 |
|---|---|---|
| committer | Michael <[email protected]> | 2017-04-07 21:13:44 -0400 |
| commit | b1e6d3dee9fa6519c65dd7564eac02b9e68bc3ce (patch) | |
| tree | dbff9719e4e9985951127c65db2be28fc6a46605 /Project-Unite | |
| parent | 1de8bc4bd0af72646ed58ecd7619a8731c48b09d (diff) | |
| download | project-unite-b1e6d3dee9fa6519c65dd7564eac02b9e68bc3ce.tar.gz project-unite-b1e6d3dee9fa6519c65dd7564eac02b9e68bc3ce.tar.bz2 project-unite-b1e6d3dee9fa6519c65dd7564eac02b9e68bc3ce.zip | |
Developer blog
Diffstat (limited to 'Project-Unite')
| -rw-r--r-- | Project-Unite/Controllers/BlogController.cs | 169 | ||||
| -rw-r--r-- | Project-Unite/Models/BlogModels.cs | 65 | ||||
| -rw-r--r-- | Project-Unite/Models/IdentityModels.cs | 1 | ||||
| -rw-r--r-- | Project-Unite/Project-Unite.csproj | 5 | ||||
| -rw-r--r-- | Project-Unite/Views/Blog/Index.cshtml | 27 | ||||
| -rw-r--r-- | Project-Unite/Views/Blog/PostBlog.cshtml | 32 | ||||
| -rw-r--r-- | Project-Unite/Views/Blog/ViewBlog.cshtml | 71 |
7 files changed, 370 insertions, 0 deletions
diff --git a/Project-Unite/Controllers/BlogController.cs b/Project-Unite/Controllers/BlogController.cs new file mode 100644 index 0000000..d1aa0f9 --- /dev/null +++ b/Project-Unite/Controllers/BlogController.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using Microsoft.AspNet.Identity; +using Project_Unite.Models; + +namespace Project_Unite.Controllers +{ + public class BlogController : Controller + { + // GET: Blog + public ActionResult Index() + { + return View(new ApplicationDbContext().BlogPosts); + } + + public ActionResult ViewBlog(string id) + { + var db = new ApplicationDbContext(); + var blog = db.BlogPosts.FirstOrDefault(x => x.Id == id); + if (blog == null) + return new HttpStatusCodeResult(404); + return View(blog); + } + + [Authorize] + public ActionResult DislikePost(string id) + { + var db = new ApplicationDbContext(); + var topic = db.BlogPosts.FirstOrDefault(x => x.Id == id); + var uid = User.Identity.GetUserId(); + if (topic == null) + return new HttpStatusCodeResult(404); + if (topic.EditHistory.OrderBy(x => x.EditedAt).First().UserId == User.Identity.GetUserId()) + return RedirectToAction("Index", new { id = id, triedtolikeowntopic = true }); + var like = db.Likes.Where(x => x.Topic == topic.Id).FirstOrDefault(x => x.User == uid); + if (like != null) + { + if (like.IsDislike == false) + { + like.IsDislike = true; + } + else + { + db.Likes.Remove(like); + } + } + else + { + like = new Models.Like(); + like.Id = Guid.NewGuid().ToString(); + like.User = User.Identity.GetUserId(); + like.Topic = topic.Id; + like.LikedAt = DateTime.Now; + like.IsDislike = true; + db.Likes.Add(like); + } + db.SaveChanges(); + return RedirectToAction("Index", new { id = id }); + } + + [Authorize] + public ActionResult LikePost(string id) + { + var db = new ApplicationDbContext(); + var topic = db.BlogPosts.FirstOrDefault(x => x.Id == id); + var uid = User.Identity.GetUserId(); + if (topic == null) + return new HttpStatusCodeResult(404); + if (topic.EditHistory.OrderBy(x => x.EditedAt).First().UserId == User.Identity.GetUserId()) + return RedirectToAction("Index", new { id = id, triedtolikeowntopic = true }); + var like = db.Likes.Where(x => x.Topic == topic.Id).FirstOrDefault(x => x.User == uid); + if (like != null) + { + if (like.IsDislike == true) + { + like.IsDislike = false; + } + else + { + db.Likes.Remove(like); + } + } + else + { + like = new Models.Like(); + like.Id = Guid.NewGuid().ToString(); + like.User = User.Identity.GetUserId(); + like.Topic = topic.Id; + like.LikedAt = DateTime.Now; + like.IsDislike = false; + db.Likes.Add(like); + } + db.SaveChanges(); + return RedirectToAction("Index", new { id = id }); + } + + + [ValidateInput(false)] + [Authorize] + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult ViewBlog(string id, string comment) + { + var db = new ApplicationDbContext(); + var blog = db.BlogPosts.FirstOrDefault(x => x.Id == id); + if (blog == null) + return new HttpStatusCodeResult(404); + if (string.IsNullOrWhiteSpace(comment)) + { + ViewBag.Error = "You must enter a comment with actual text in it."; + return View(blog); + } + if(comment.Length < 20) + { + ViewBag.Error = "Your comment must have at least 20 characters in it."; + return View(blog); + } + var post = new ForumPost(); + post.AuthorId = User.Identity.GetUserId(); + post.Body = comment; + post.Id = Guid.NewGuid().ToString(); + post.Parent = id; + post.PostedAt = DateTime.Now; + db.ForumPosts.Add(post); + db.SaveChanges(); + + return View(blog); + } + + [Authorize] + public ActionResult PostBlog() + { + if (!ACL.Granted(User.Identity.Name, "CanBlog")) + return new HttpStatusCodeResult(403); + + var model = new PostBlogViewModel(); + return View(model); + } + + [Authorize] + [ValidateAntiForgeryToken] + [HttpPost] + public ActionResult PostBlog(PostBlogViewModel model) + { + if (!ModelState.IsValid) + return View(model); + + var db = new ApplicationDbContext(); + var blog = new BlogPost(); + blog.AuthorId = User.Identity.GetUserId(); + blog.Contents = model.Contents; + blog.Name = model.Name; + blog.Id = model.Name.ToLower(); + string allowed = "-_abcdefghijklmnopqrstuvwxyz1234567890"; + foreach(var c in blog.Id.ToCharArray()) + { + if (!allowed.Contains(c)) + blog.Id = blog.Id.Replace(c, '_'); + } + blog.PostedAt = DateTime.Now; + db.BlogPosts.Add(blog); + db.SaveChanges(); + return RedirectToAction("ViewBlog", new { id = blog.Id }); + } + } +}
\ No newline at end of file diff --git a/Project-Unite/Models/BlogModels.cs b/Project-Unite/Models/BlogModels.cs new file mode 100644 index 0000000..00ffbea --- /dev/null +++ b/Project-Unite/Models/BlogModels.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Web; +using System.Web.Mvc; + +namespace Project_Unite.Models +{ + public class PostBlogViewModel + { + [Required(ErrorMessage="Please enter a name for your post!")] + [MinLength(5, ErrorMessage ="Your post's name must have at least 5 characters.")] + [MaxLength(50, ErrorMessage = "Your post's name must have at least 50 characters.")] + public string Name { get; set; } + + [AllowHtml] + [Required(ErrorMessage ="You can't post an empty blog post!")] + [MinLength(20, ErrorMessage = "Your post must have at least 20 characters.")] + public string Contents { get; set; } + } + + public class BlogPost + { + public string Id { get; set; } + public string AuthorId { get; set; } + public ForumPost[] Comments + { + get + { + return new ApplicationDbContext().ForumPosts.Where(x => x.Parent == this.Id).ToArray(); + } + } + public Like[] Likes + { + get + { + return new ApplicationDbContext().Likes.Where(x => x.Topic == this.Id&&x.IsDislike == false).ToArray(); + } + } + + public string Name { get; set; } + + public string Summary + { + get + { + return Contents.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)[0]; + } + } + + public Like[] Dislikes + { + get + { + return new ApplicationDbContext().Likes.Where(x => x.Topic == this.Id && x.IsDislike == true).ToArray(); + + } + } + + public DateTime PostedAt { get; set; } + + public string Contents { get; set; } + } +}
\ No newline at end of file diff --git a/Project-Unite/Models/IdentityModels.cs b/Project-Unite/Models/IdentityModels.cs index cf04def..42f9e30 100644 --- a/Project-Unite/Models/IdentityModels.cs +++ b/Project-Unite/Models/IdentityModels.cs @@ -219,6 +219,7 @@ namespace Project_Unite.Models return new ApplicationDbContext(); } + public DbSet<BlogPost> BlogPosts { get; set; } public DbSet<ReadPost> ReadPosts { get; set; } public DbSet<Download> Downloads { get; set; } public DbSet<DatabaseBackup> Backups { get; set; } diff --git a/Project-Unite/Project-Unite.csproj b/Project-Unite/Project-Unite.csproj index 5f09e0c..cde0944 100644 --- a/Project-Unite/Project-Unite.csproj +++ b/Project-Unite/Project-Unite.csproj @@ -243,6 +243,7 @@ <Compile Include="Controllers\AccountController.cs" /> <Compile Include="Controllers\AdminController.cs" /> <Compile Include="Controllers\APIController.cs" /> + <Compile Include="Controllers\BlogController.cs" /> <Compile Include="Controllers\DeveloperController.cs" /> <Compile Include="Controllers\DownloadController.cs" /> <Compile Include="Controllers\ForumController.cs" /> @@ -424,6 +425,7 @@ <Compile Include="Models\AccountViewModels.cs" /> <Compile Include="Models\AddUserToRoleViewModel.cs" /> <Compile Include="Models\AdminViewModels.cs" /> + <Compile Include="Models\BlogModels.cs" /> <Compile Include="Models\Download.cs" /> <Compile Include="Models\ForumCategory.cs" /> <Compile Include="Models\ForumViewModels.cs" /> @@ -554,6 +556,9 @@ <Content Include="Views\Wiki\AddPage.cshtml" /> <Content Include="Views\Wiki\EditPage.cshtml" /> <Content Include="Views\Home\Search.cshtml" /> + <Content Include="Views\Blog\ViewBlog.cshtml" /> + <Content Include="Views\Blog\Index.cshtml" /> + <Content Include="Views\Blog\PostBlog.cshtml" /> </ItemGroup> <ItemGroup> <Folder Include="App_Data\" /> diff --git a/Project-Unite/Views/Blog/Index.cshtml b/Project-Unite/Views/Blog/Index.cshtml new file mode 100644 index 0000000..56af4ef --- /dev/null +++ b/Project-Unite/Views/Blog/Index.cshtml @@ -0,0 +1,27 @@ +@model IEnumerable<Project_Unite.Models.BlogPost> +@{ + ViewBag.Title = "Blog"; +} + +<h2>Developer Blog</h2> + +<p>We ShiftOS devs have a lot going on. If you want to find out a bit more about what we do behind the scenes, this is the place for you. We'll post lots of things for you to read here.</p> + +@if(ACL.Granted(User.Identity.Name, "CanBlog")) +{ + <ul class="nav nav-pills"> + <li><a href="@Url.Action("PostBlog")"><span class="glyphicon glyphicon-file"></span> Post</a></li> + </ul> +} + +@foreach(var blog in Model) +{ + <div class="panel"> + <div class="panel-body"> + <h4>@blog.Name</h4> + <p>Posted by @Html.UserLink(blog.AuthorId) at @blog.PostedAt - @blog.Likes.Length likes, @blog.Dislikes.Length dislikes</p> + <p>@Html.Markdown(blog.Summary)</p> + @Html.ActionLink("Read more", "ViewBlog", "Blog", new { id = blog.Id }, new { @class = "btn btn-default" }) + </div> + </div> +}
\ No newline at end of file diff --git a/Project-Unite/Views/Blog/PostBlog.cshtml b/Project-Unite/Views/Blog/PostBlog.cshtml new file mode 100644 index 0000000..e3ad6f7 --- /dev/null +++ b/Project-Unite/Views/Blog/PostBlog.cshtml @@ -0,0 +1,32 @@ +@model Project_Unite.Models.PostBlogViewModel +@{ + ViewBag.Title = "Post blog"; +} + +<h2>Post a blog</h2> + +<p>Just fill in the form and we'll get the post up onto the cloud.</p> + +@using (Html.BeginForm()) +{ + <div class="panel-danger panel"> + <div class="panel-body"> + @Html.ValidationSummary() + </div> + </div> + + <table class="table"> + <tr> + <td style="width:25%">Name:</td> + <td>@Html.TextBoxFor(Model=>Model.Name, new{@class="form-control"})</td> + </tr> + <tr> + <td style="width:25%">Body:</td> + <td>@Html.TextAreaFor(Model => Model.Contents, new { @class = "form-control", rows="10" })</td> + </tr> + <tr> + <td></td> + <td><input type="submit" value="Post!" class="btn btn-primary" /></td> + </tr> + </table> +}
\ No newline at end of file diff --git a/Project-Unite/Views/Blog/ViewBlog.cshtml b/Project-Unite/Views/Blog/ViewBlog.cshtml new file mode 100644 index 0000000..0511698 --- /dev/null +++ b/Project-Unite/Views/Blog/ViewBlog.cshtml @@ -0,0 +1,71 @@ +@model Project_Unite.Models.BlogPost +@{ + ViewBag.Title = Model.Name; +} + +<h2>Developer Blog</h2> + +<h3>@Model.Name</h3> + +@if (!string.IsNullOrWhiteSpace(ViewBag.Error)) +{ + <div class="panel panel-danger"> + <div class="panel-body"> + <p><span class="glyphicon glyphicon-exclamation-sign"></span> @ViewBag.Error</p> + </div> + </div> +} + +<p>Posted by @Html.UserLink(Model.AuthorId) at @Model.PostedAt</p> + +<div class="panel"> + <div class="panel-body"> + @Html.Markdown(Model.Contents) + </div> +</div> + +<ul class="nav nav-pills"> + @{ + string like_uri = "#"; + string dislike_uri = "#"; + + if (Request.IsAuthenticated) + { + like_uri = Url.Action("LikePost", new { id = Model.Id }); + dislike_uri = Url.Action("DislikePost", new { id = Model.Id }); + } + + <li><a href="@like_uri"><span class="glyphicon glyphicon-thumbs-up"></span> @Model.Likes.Length</a></li> + <li><a href="@dislike_uri"><span class="glyphicon glyphicon-thumbs-down"></span> @Model.Dislikes.Length</a></li> + } +</ul> + +<hr/> + +<h4>Comments</h4> + +@if (Request.IsAuthenticated) +{ + <div class="panel"> + <div class="panel-body"> + @using (Html.BeginForm()) + { + <input type="hidden" name="id" value="@Model.Id" /> + @Html.AntiForgeryToken() + + <textarea class="form-control" rows="5" name="comment" value=""></textarea> + <input type="submit" class="btn btn-primary" value="Comment" /> + } + </div> + </div> +} + +@foreach(var comment in Model.Comments.OrderBy(x=>x.PostedAt)) +{ + <div class="panel"> + <div class="panel-body"> + <p><strong>@Html.UserLink(comment.AuthorId)</strong> said on @comment.PostedAt:</p> + <p>@Html.Markdown(comment.Body)</p> + </div> + </div> +}
\ No newline at end of file |
