summaryrefslogtreecommitdiff
path: root/Project-Unite
diff options
context:
space:
mode:
authorMichael <[email protected]>2017-04-07 21:13:44 -0400
committerMichael <[email protected]>2017-04-07 21:13:44 -0400
commitb1e6d3dee9fa6519c65dd7564eac02b9e68bc3ce (patch)
treedbff9719e4e9985951127c65db2be28fc6a46605 /Project-Unite
parent1de8bc4bd0af72646ed58ecd7619a8731c48b09d (diff)
downloadproject-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.cs169
-rw-r--r--Project-Unite/Models/BlogModels.cs65
-rw-r--r--Project-Unite/Models/IdentityModels.cs1
-rw-r--r--Project-Unite/Project-Unite.csproj5
-rw-r--r--Project-Unite/Views/Blog/Index.cshtml27
-rw-r--r--Project-Unite/Views/Blog/PostBlog.cshtml32
-rw-r--r--Project-Unite/Views/Blog/ViewBlog.cshtml71
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