Sitemap, Admin tweaks, MembershipProvider tweaks

This commit is contained in:
Thomas Hounsell 2014-10-31 19:28:16 +00:00
parent 40f04a1013
commit 48acb8d39c
16 changed files with 304 additions and 17 deletions

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace BuildFeed.Areas.admin.Controllers
{
[Authorize(Users = "hounsell")]
public class baseController : Controller
{
// GET: admin/base
public ActionResult index()
{
return View();
}
}
}

View File

@ -12,19 +12,19 @@ namespace BuildFeed.Areas.admin.Controllers
public class usersController : Controller
{
// GET: admin/users
public ActionResult Index()
public ActionResult index()
{
return View(Membership.GetAllUsers().Cast<MembershipUser>().OrderBy(m => m.IsApproved).ThenBy(m => m.UserName));
return View(Membership.GetAllUsers().Cast<MembershipUser>().OrderByDescending(m => m.IsApproved).ThenBy(m => m.UserName));
}
public ActionResult Approve(Guid id)
public ActionResult approve(Guid id)
{
var provider = (Membership.Provider as RedisMembershipProvider);
provider.ChangeApproval(id, true);
return RedirectToAction("Index");
}
public ActionResult Unapprove(Guid id)
public ActionResult unapprove(Guid id)
{
var provider = (Membership.Provider as RedisMembershipProvider);
provider.ChangeApproval(id, false);

View File

@ -0,0 +1,11 @@

@{
ViewBag.Title = "Administration | BuildFeed";
}
<h2>Administration</h2>
<ul>
<li>@Html.ActionLink("Manage users", "index", "users")</li>
</ul>

View File

@ -6,7 +6,7 @@
<h2>User Administration</h2>
<table class="table table-striped table-bordered">
<table class="table table-striped table-bordered table-admin">
<tr>
<th>
Username
@ -14,6 +14,9 @@
<th>
Email Address
</th>
<td>
Last Login Time
</td>
<th style="width:108px;"></th>
</tr>
@ -26,6 +29,9 @@
<td>
@Html.DisplayFor(modelItem => mu.Email)
</td>
<td>
@Html.DisplayFor(modelItem => mu.LastLoginDate)
</td>
<td class="text-right">
@if (mu.IsApproved)
{

View File

@ -15,9 +15,9 @@ public override string AreaName
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"admin_default",
"Admin (Default)",
"admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
new { action = "index", controller = "base", id = UrlParameter.Optional }
);
}
}

View File

@ -355,6 +355,12 @@ public override bool ValidateUser(string username, string password)
isFail |= (hash[i] != rm.PassHash[i]);
}
if(!isFail)
{
rm.LastLoginDate = DateTime.Now;
client.Store(rm);
}
return !isFail;
}
}

View File

@ -145,6 +145,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Areas\admin\Controllers\baseController.cs" />
<Compile Include="Code\BuildDateTimeModelBinder.cs" />
<Compile Include="Code\DisplayHelpers.cs" />
<Compile Include="App_Start\BundleConfig.cs" />
@ -165,6 +166,7 @@
<Compile Include="Models\ViewModel\LoginUser.cs" />
<Compile Include="Models\ViewModel\ChangePassword.cs" />
<Compile Include="Models\ViewModel\RegistrationUser.cs" />
<Compile Include="Models\ViewModel\SitemapData.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
@ -177,6 +179,7 @@
<Content Include="Areas\admin\Views\_ViewStart.cshtml" />
<Content Include="content\tile\wide.png" />
<Content Include="content\Web.config" />
<Content Include="Areas\admin\Views\base\index.cshtml" />
<None Include="Properties\PublishProfiles\Milestone 1 FTP.pubxml" />
<None Include="Scripts\jquery-2.1.1.intellisense.js" />
<Content Include="googleacffc6da14c53e15.html" />
@ -215,6 +218,7 @@
<Content Include="Views\support\password.cshtml" />
<Content Include="Views\support\thanks_register.cshtml" />
<Content Include="Views\support\rss.cshtml" />
<Content Include="Views\support\sitemap.cshtml" />
</ItemGroup>
<ItemGroup>
<Folder Include="App_Data\" />

View File

@ -10,7 +10,7 @@ namespace BuildFeed.Controllers
{
public class buildController : Controller
{
public int pageSize { get { return 15; } }
public static int pageSize { get { return 15; } }
//
// GET: /build/
@ -103,6 +103,7 @@ public ActionResult create(Build build)
try
{
build.Added = DateTime.Now;
build.Modified = DateTime.Now;
Build.Insert(build);
}
catch

View File

@ -85,12 +85,7 @@ public async Task<ActionResult> added()
public async Task<ActionResult> version()
{
var builds = Build.Select()
.OrderByDescending(b => b.MajorVersion)
.ThenByDescending(b => b.MinorVersion)
.ThenByDescending(b => b.Number)
.ThenByDescending(b => b.Revision)
.ThenByDescending(b => b.BuildTime)
var builds = Build.SelectInVersionOrder()
.Take(20);

View File

@ -3,7 +3,9 @@
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using BuildFeed.Models;
using BuildFeed.Models.ViewModel;
namespace BuildFeed.Controllers
@ -116,5 +118,103 @@ public ActionResult rss()
{
return View();
}
public ActionResult sitemap()
{
IEnumerable<Build> builds = Build.SelectInVersionOrder();
Dictionary<string, SitemapPagedAction[]> actions = new Dictionary<string, SitemapPagedAction[]>();
actions.Add("Pages", new SitemapPagedAction[] { new SitemapPagedAction()
{
UrlParams = new RouteValueDictionary(new {
controller = "build",
action = "index",
page = 1
}),
Pages = (builds.Count() + (buildController.pageSize - 1)) / buildController.pageSize
} });
actions.Add("Versions", (from b in builds
group b by new BuildVersion() { Major = b.MajorVersion, Minor = b.MinorVersion } into bv
orderby bv.Key.Major descending,
bv.Key.Minor descending
select new SitemapPagedAction()
{
Name = string.Format("Windows NT {0}.{1}", bv.Key.Major, bv.Key.Minor),
UrlParams = new RouteValueDictionary(new
{
controller = "build",
action = "version",
major = bv.Key.Major,
minor = bv.Key.Minor,
page = 1
}),
Pages = (bv.Count() + (buildController.pageSize - 1)) / buildController.pageSize
}).ToArray());
actions.Add("Labs", (from b in builds
where !string.IsNullOrEmpty(b.Lab)
group b by b.Lab into bv
orderby bv.Key
select new SitemapPagedAction()
{
Name = bv.Key,
UrlParams = new RouteValueDictionary(new
{
controller = "build",
action = "version",
lab = bv.Key,
page = 1
}),
Pages = (bv.Count() + (buildController.pageSize - 1)) / buildController.pageSize
}).ToArray());
actions.Add("Years", (from b in builds
where b.BuildTime.HasValue
group b by b.BuildTime.Value.Year into bv
orderby bv.Key
select new SitemapPagedAction()
{
Name = bv.Key.ToString(),
UrlParams = new RouteValueDictionary(new
{
controller = "build",
action = "year",
year = bv.Key,
page = 1
}),
Pages = (bv.Count() + (buildController.pageSize - 1)) / buildController.pageSize
}).ToArray());
actions.Add("Sources", (from b in builds
group b by b.SourceType into bv
orderby bv.Key
select new SitemapPagedAction()
{
Name = DisplayHelpers.GetDisplayTextForEnum(bv.Key),
UrlParams = new RouteValueDictionary(new
{
controller = "build",
action = "version",
source = bv.Key,
page = 1
}),
Pages = (bv.Count() + (buildController.pageSize - 1)) / buildController.pageSize
}).ToArray());
SitemapData model = new SitemapData()
{
Builds = (from b in builds
select new SitemapDataBuild()
{
Id = b.Id,
Name = b.FullBuildString
}).ToArray(),
Actions = actions
};
return View(model);
}
}
}

View File

@ -45,9 +45,13 @@ public class Build : IHasId<long>
[@Required]
[DisplayName("Time Added")]
[DisplayName("Time Created")]
public DateTime Added { get; set; }
[@Required]
[DisplayName("Time Modified")]
public DateTime Modified { get; set; }
[@Required]
[DisplayName("Source Type")]
[EnumDataType(typeof(TypeOfSource))]
@ -85,7 +89,7 @@ public bool IsLeaked
{
get
{
switch(SourceType)
switch (SourceType)
{
case TypeOfSource.PublicRelease:
case TypeOfSource.InternalLeak:
@ -158,6 +162,21 @@ public static IEnumerable<Build> SelectInBuildOrder()
}
}
[DataObjectMethod(DataObjectMethodType.Select, false)]
public static IEnumerable<Build> SelectInVersionOrder()
{
using (RedisClient rClient = new RedisClient(DatabaseConfig.Host, DatabaseConfig.Port, db: DatabaseConfig.Database))
{
var client = rClient.As<Build>();
return client.GetAll()
.OrderByDescending(b => b.MajorVersion)
.ThenByDescending(b => b.MinorVersion)
.ThenByDescending(b => b.Number)
.ThenByDescending(b => b.Revision)
.ThenByDescending(b => b.BuildTime);
}
}
[DataObjectMethod(DataObjectMethodType.Select, false)]
public static IEnumerable<BuildVersion> SelectBuildVersions()
{
@ -235,6 +254,7 @@ public static void Update(Build item)
{
Build old = Build.SelectById(item.Id);
item.Added = old.Added;
item.Modified = DateTime.Now;
using (RedisClient rClient = new RedisClient(DatabaseConfig.Host, DatabaseConfig.Port, db: DatabaseConfig.Database))
{

View File

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;
namespace BuildFeed.Models.ViewModel
{
public class SitemapData
{
public SitemapDataBuild[] Builds { get; set; }
public Dictionary<string, SitemapPagedAction[]> Actions { get; set; }
}
public class SitemapDataBuild
{
public long Id { get; set; }
public string Name { get; set; }
}
public class SitemapPagedAction
{
public string Name { get; set; }
public RouteValueDictionary UrlParams { get; set; }
public int Pages { get; set; }
public string Action
{
get { return UrlParams["action"].ToString(); }
}
public string UniqueId
{
get { return UrlParams.GetHashCode().ToString("X8").ToLower(); }
}
}
}

View File

@ -214,6 +214,11 @@
<ul class="nav nav-pills nav-stacked">
@if (User.Identity.IsAuthenticated)
{
if (User.Identity.Name == "hounsell")
{
<li>@Html.ActionLink("Administration", "index", new { controller = "base", area = "admin" })</li>
<li>&nbsp;</li>
}
<li>@Html.ActionLink("Add a build", "create", "build")</li>
<li>&nbsp;</li>
<li>@Html.ActionLink("Change your password", "password", "support")</li>

View File

@ -52,7 +52,12 @@
</article>
<footer id="page-footer">
<div class="row">
<div class="col-sm-4 col-sm-offset-8 text-right">
<div class="col-sm-8">
<p>
<a href="@Url.Action("sitemap", new { controller = "support" })">Sitemap</a>
</p>
</div>
<div class="col-sm-4 text-right">
<p>
&copy; 2013 - 2014, BuildFeed<br />
Developed by <a href="https://twitter.com/tomhounsell" target="_blank">Thomas Hounsell</a>

View File

@ -0,0 +1,73 @@
@model BuildFeed.Models.ViewModel.SitemapData
@{
ViewBag.Title = "Sitemap | BuildFeed";
}
<h2>Sitemap</h2>
<ul>
<li>
@Html.ActionLink("BuildFeed", "index", "build")
<ul>
<li>
<a href="#sitemap-builds" data-toggle="collapse">Builds</a>
<ul id="sitemap-builds" class="collapse">
@foreach (var build in Model.Builds)
{
<li>@Html.ActionLink(build.Name, "info", new { controller = "build", id = build.Id })</li>
}
</ul>
</li>
@foreach (var item in Model.Actions)
{
<li>
<a href="#sitemap-@item.Key.ToLower()" data-toggle="collapse">@item.Key</a>
<ul id="sitemap-@item.Key.ToLower()" class="collapse">
@foreach (var action in item.Value)
{
if (string.IsNullOrEmpty(action.Name))
{
for (int i = 1; i <= action.Pages; i++)
{
var urlParams = action.UrlParams;
urlParams["page"] = i;
<li>@Html.ActionLink("Page " + i.ToString(), action.Action, urlParams)</li>
}
}
else
{
<li>
<a href="#sitemap-@action.UniqueId" data-toggle="collapse">@action.Name</a>
<ul id="sitemap-@action.UniqueId" class="collapse">
@for (int i = 1; i <= action.Pages; i++)
{
var urlParams = action.UrlParams;
urlParams["page"] = i;
<li>@Html.ActionLink("Page " + i.ToString(), action.Action, urlParams)</li>
}
</ul>
</li>
}
}
</ul>
</li>
}
<li>
<a href="#sitemap-rss" data-toggle="collapse">RSS Feeds</a>
<ul id="sitemap-rss" class="collapse">
<li><a href="@Url.Action("index", new { controller = "rss" })" title="Recently compiled"><i class="fa fa-sm fa-rss"></i> Recently compiled</a></li>
<li><a href="@Url.Action("added", new { controller = "rss" })" title="Recently added to BuildFeed"><i class="fa fa-sm fa-rss"></i> Recently added to BuildFeed</a></li>
<li><a href="@Url.Action("version", new { controller = "rss" })" title="Highest version"><i class="fa fa-sm fa-rss"></i> Highest version</a></li>
<li>
Flight levels
<ul>
<li><a href="@Url.Action("flight", new { controller = "rss", id = "low" })" title="Low flight level"><i class="fa fa-sm fa-rss"></i> Low flight level</a></li>
<li><a href="@Url.Action("flight", new { controller = "rss", id = "medium" })" title="Medium flight level"><i class="fa fa-sm fa-rss"></i> Medium flight level</a></li>
<li><a href="@Url.Action("flight", new { controller = "rss", id = "high" })" title="High flight level"><i class="fa fa-sm fa-rss"></i> High flight level</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>

View File

@ -97,3 +97,9 @@ label, .control-label, .help-block, .checkbox, .radio {
.table .btn {
padding: 4px 9px;
}
.table-admin > tbody > tr > th,
.table-admin > tbody > tr > td
{
vertical-align: middle;
}