Jamie.Rees 8 years ago
parent a4b0e9e1d3
commit 33398084be

@ -7,5 +7,6 @@ namespace PlexRequests.Core
public interface IStatusChecker
{
Task<StatusModel> GetStatus();
Task<Issue> ReportBug(string title, string body);
}
}

@ -179,5 +179,16 @@ namespace PlexRequests.Core.StatusChecker
return model;
}
public async Task<Issue> ReportBug(string title, string body)
{
var issue = new NewIssue(title)
{
Body = body
};
var result = await Git.Issue.Create(Owner, RepoName, issue);
return result;
}
}
}

@ -0,0 +1,76 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: OperatingSystemHelper.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
namespace PlexRequests.Helpers
{
public static class OperatingSystemHelper
{
public static string GetOs()
{
var os = System.Environment.OSVersion;
var osVersion = os.Version;
if (osVersion.Major.Equals(10))
{
return "Windows 10/Windows Server 2016";
}
if (osVersion.Major.Equals(6))
{
if (osVersion.Minor.Equals(3))
{
return "Windows 8.1/Windows Server 2012 R2";
}
if (osVersion.Minor.Equals(2))
{
return "Windows 8/Windows Server 2012";
}
if (osVersion.Minor.Equals(1))
{
return "Windows 7/Windows Server 2008 R2";
}
if (osVersion.Minor.Equals(0))
{
return "Windows Vista/Windows Server 2008";
}
}
if (osVersion.Major.Equals(5))
{
if (osVersion.Minor.Equals(2))
{
return "Windows XP 64-Bit Edition/Windows Server 2003";
}
if (osVersion.Minor.Equals(1))
{
return "Windows XP";
}
if (osVersion.Minor.Equals(0))
{
return "Windows 2000";
}
}
return os.VersionString;
}
}
}

@ -83,6 +83,7 @@
<Compile Include="LoggingHelper.cs" />
<Compile Include="MemoryCacheProvider.cs" />
<Compile Include="ObjectCopier.cs" />
<Compile Include="OperatingSystemHelper.cs" />
<Compile Include="PasswordHasher.cs" />
<Compile Include="EnumExtensions.cs" />
<Compile Include="Permissions\Features.cs" />

File diff suppressed because one or more lines are too long

@ -26,6 +26,7 @@
#endregion
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using Nancy;
using Nancy.ViewEngines.Razor;
@ -233,6 +234,16 @@ namespace PlexRequests.UI.Helpers
return helper.Raw(sb.ToString());
}
public static IHtmlString LoadAsset(this HtmlHelpers helper, string contentPath, bool javascript)
{
var assetLocation = GetBaseUrl();
var content = GetContentUrl(assetLocation);
if (javascript)
{
return helper.Raw($"<script src=\"{content}{contentPath}?v={Assembly}\" type=\"text/javascript\"></script>");
}
return helper.Raw($"<link rel=\"stylesheet\" type=\"text/css\" href=\"{content}{contentPath}?v={Assembly}\" />");
}
public static IHtmlString LoadTableAssets(this HtmlHelpers helper)
{

@ -0,0 +1,37 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: AboutAdminViewModel.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
namespace PlexRequests.UI.Models
{
public class AboutAdminViewModel
{
public string Os { get; set; } // Windows/Mono
public string SystemVersion { get; set; } // Windows 10/ mono 4.2.5
public string ApplicationVersion { get; set; } // File Version
public string Branch { get; set; }
public string LogLevel { get; set; }
}
}

@ -0,0 +1,115 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: AboutModule.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using System;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Nancy;
using Nancy.Responses.Negotiation;
using NLog;
using PlexRequests.Core;
using PlexRequests.Core.SettingModels;
using PlexRequests.Helpers;
using PlexRequests.Helpers.Permissions;
using PlexRequests.UI.Models;
using TMDbLib.Utilities;
using ISecurityExtensions = PlexRequests.Core.ISecurityExtensions;
namespace PlexRequests.UI.Modules.Admin
{
public class AboutModule : BaseModule
{
public AboutModule(ISettingsService<PlexRequestSettings> settingsService,
ISettingsService<SystemSettings> systemService, ISecurityExtensions security,
IStatusChecker statusChecker) : base("admin", settingsService, security)
{
Before += (ctx) => Security.AdminLoginRedirect(Permissions.Administrator, ctx);
SettingsService = systemService;
StatusChecker = statusChecker;
Get["/about", true] = async (x,ct) => await Index();
Post["/about", true] = async (x,ct) => await ReportIssue();
}
private ISettingsService<SystemSettings> SettingsService { get; }
private IStatusChecker StatusChecker { get; }
private async Task<Negotiator> Index()
{
var vm = new AboutAdminViewModel();
var systemSettings = await SettingsService.GetSettingsAsync();
var type = Type.GetType("Mono.Runtime");
if (type != null) // mono
{
vm.Os = "Mono";
var displayName = type.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
if (displayName != null)
{
vm.SystemVersion = displayName.Invoke(null, null).ToString();
}
}
else
{
// Windows
vm.Os = OperatingSystemHelper.GetOs();
vm.SystemVersion = Environment.Version.ToString();
}
vm.ApplicationVersion = AssemblyHelper.GetFileVersion();
vm.Branch = EnumHelper<Branches>.GetDisplayValue(systemSettings.Branch);
vm.LogLevel = LogManager.Configuration.LoggingRules.FirstOrDefault(x => x.NameMatches("database"))?.Levels?.FirstOrDefault()?.Name ?? "Unknown";
return View["About", vm];
}
private async Task<Response> ReportIssue()
{
var title = Request.Form["title"];
var body = Request.Form["body"];
if (string.IsNullOrEmpty(title) || string.IsNullOrEmpty(body))
{
return
Response.AsJson(
new
{
result = false,
message = "The title or issue body is empty! Please give me a bit more detail :)"
});
}
var result = await StatusChecker.ReportBug(title,body);
return Response.AsJson(new {result = true, url = result.HtmlUrl.ToString()});
}
}
}

@ -105,6 +105,10 @@
<HintPath>..\packages\NLog.4.3.6\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Octokit, Version=0.19.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Octokit.0.19.0\lib\net45\Octokit.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
<Private>True</Private>
@ -228,6 +232,7 @@
<Compile Include="ModelDataProviders\AuthSettingsDataProvider.cs" />
<Compile Include="ModelDataProviders\UserUpdateViewModelDataProvider.cs" />
<Compile Include="ModelDataProviders\RequestedModelDataProvider.cs" />
<Compile Include="Models\AboutAdminViewModel.cs" />
<Compile Include="Models\DatatablesModel.cs" />
<Compile Include="Models\EpisodeListViewModel.cs" />
<Compile Include="Models\EpisodeRequestModel.cs" />
@ -244,6 +249,7 @@
<Compile Include="Models\SearchMovieViewModel.cs" />
<Compile Include="Models\UserManagement\DeleteUserViewModel.cs" />
<Compile Include="Models\UserManagement\UserUpdateViewModel.cs" />
<Compile Include="Modules\Admin\AboutModule.cs" />
<Compile Include="Modules\Admin\CustomizationModule.cs" />
<Compile Include="Modules\Admin\UserManagementSettingsModule.cs" />
<Compile Include="Modules\Admin\FaultQueueModule.cs" />
@ -368,6 +374,9 @@
<DependentUpon>datepicker.css</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Content\helpers\bootbox.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\issue-details.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -749,6 +758,9 @@
<Content Include="Views\Admin\NotificationSettings.cshtml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Views\About\About.cshtml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="Views\Admin\NewsletterSettings.cshtml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

@ -0,0 +1,111 @@
@using PlexRequests.UI.Helpers
@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<PlexRequests.UI.Models.AboutAdminViewModel>
@Html.Partial("Shared/Partial/_Sidebar")
@Html.LoadAsset("/Content/helpers/bootbox.min.js", true)
<div id="lightbox" style="display:none"></div>
<div class="col-sm-8 col-sm-push-1">
<fieldset>
<legend>About</legend>
<div class="form-group">
<label>Application Version: </label>
<label>@Model.ApplicationVersion</label>
</div>
<div class="form-group">
<label class="control-label">OS: </label>
<label class="control-label">@Model.Os</label>
</div>
<div class="form-group">
<label class="control-label">System Version: </label>
<label class="control-label">@Model.SystemVersion</label>
</div>
<div class="form-group">
<label class="control-label">Branch: </label>
<label class="control-label">@Model.Branch</label>
</div>
<div class="form-group">
<label class="control-label">Log Level: </label>
<label class="control-label">@Model.LogLevel</label>
</div>
<div class="form-group">
<div>
<button id="save" type="submit" class="btn btn-danger-outline">Report a bug</button>
</div>
</div>
</fieldset>
</div>
<script>
var issueTitle = "";
var baseUrl = '@Html.GetBaseUrl()';
$('#save').click(function () {
startBug();
});
function startBug() {
bootbox.prompt({
size: "small",
title: "What is the title of the issue?",
inputType: 'textarea',
callback: mainContent
});
}
function mainContent(userTitle) {
if (!userTitle) {
generateNotify("Please provide a valid title", "danger");
return startBug();
}
issueTitle = userTitle;
bootbox.prompt({
title: "Please provide details of the issue including any logs and reproduction steps",
inputType: 'textarea',
callback: reportBug
});
}
function reportBug(additionalInfo) {
if (!additionalInfo) {
generateNotify("Please provide some information", "danger");
return mainContent();
}
var url = "/admin/about";
url = createBaseUrl(baseUrl, url);
$.ajax({
type: "post",
url: url,
data: {title : issueTitle, body : additionalInfo},
dataType: "json",
success: function (response) {
if (response && response.result) {
generateNotify("Issue Reported, see here: " + response.url);
} else {
if (response.message) {
generateNotify(response.message, "danger");
}
}
},
error: function (e) {
console.log(e);
generateNotify("Something went wrong!", "danger");
}
});
}
</script>

@ -35,6 +35,7 @@
<package id="Ninject" version="3.2.0.0" targetFramework="net45" />
<package id="Ninject.Extensions.ChildKernel" version="3.2.0.0" targetFramework="net45" />
<package id="NLog" version="4.3.6" targetFramework="net45" />
<package id="Octokit" version="0.19.0" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="Quartz" version="2.3.3" targetFramework="net45" />
<package id="RestSharp" version="105.2.3" targetFramework="net45" />

Loading…
Cancel
Save