More work around using the PlexDatabase

pull/591/head^2
Jamie.Rees 8 years ago
parent 67b124148c
commit dc92285cfa

@ -44,7 +44,8 @@ namespace PlexRequests.Core
if (!string.IsNullOrEmpty(settings.PlexDatabaseLocationOverride))
{
Plex.DbLocation = settings.PlexDatabaseLocationOverride;
//Overriden setting
Plex.DbLocation = Path.Combine(settings.PlexDatabaseLocationOverride, "Plug-in Support", "Databases", "com.plexapp.plugins.library.db");
}
else if (Type.GetType("Mono.Runtime") != null)
{
@ -61,7 +62,11 @@ namespace PlexRequests.Core
public IEnumerable<MetadataItems> GetItemsAddedAfterDate(DateTime dateTime)
{
return Plex.QueryMetadataItems("select * from metadata_items where added_at > @AddedAt",
// type 1 = Movie, type 4 = TV Episode
return Plex.QueryMetadataItems(@"SELECT * FROM metadata_items
WHERE added_at > @AddedAt
AND metadata_type in (1,4)
AND title <> ''",
new { AddedAt = dateTime });
}
}

@ -42,6 +42,7 @@ using PlexRequests.Core.SettingModels;
using PlexRequests.Helpers;
using PlexRequests.Services.Interfaces;
using PlexRequests.Services.Jobs.Templates;
using PlexRequests.Store.Models.Plex;
using Quartz;
@ -52,7 +53,8 @@ namespace PlexRequests.Services.Jobs
public RecentlyAdded(IPlexApi api, ISettingsService<PlexSettings> plexSettings,
ISettingsService<EmailNotificationSettings> email,
ISettingsService<ScheduledJobsSettings> scheduledService, IJobRecord rec,
ISettingsService<PlexRequestSettings> plexRequest)
ISettingsService<PlexRequestSettings> plexRequest,
IPlexReadOnlyDatabase db)
{
JobRecord = rec;
Api = api;
@ -60,6 +62,7 @@ namespace PlexRequests.Services.Jobs
EmailSettings = email;
ScheduledJobsSettings = scheduledService;
PlexRequestSettings = plexRequest;
PlexDb = db;
}
private IPlexApi Api { get; }
@ -70,6 +73,7 @@ namespace PlexRequests.Services.Jobs
private ISettingsService<PlexRequestSettings> PlexRequestSettings { get; }
private ISettingsService<ScheduledJobsSettings> ScheduledJobsSettings { get; }
private IJobRecord JobRecord { get; }
private IPlexReadOnlyDatabase PlexDb { get; }
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
@ -108,7 +112,7 @@ namespace PlexRequests.Services.Jobs
public void Test()
{
Start(true);
StartDb(true);
}
private void Start(bool testEmail = false)
@ -135,8 +139,26 @@ namespace PlexRequests.Services.Jobs
Send(html, plexSettings, testEmail);
}
private void GenerateMovieHtml(IEnumerable<RecentlyAddedChild> movies, PlexSettings plexSettings,
ref StringBuilder sb)
private void StartDb(bool testEmail = false)
{
var sb = new StringBuilder();
var plexSettings = PlexSettings.GetSettings();
var recentlyAdded = PlexDb.GetItemsAddedAfterDate(DateTime.Now.AddDays(-7));
var movies = recentlyAdded.Where(x => x.MetadataType == 1);
var tv = recentlyAdded.Where(x => x.MetadataType == 4);
GenerateMovieHtmlDb(movies, ref sb);
GenerateTvHtml(tv, ref sb);
var template = new RecentlyAddedTemplate();
var html = template.LoadTemplate(sb.ToString());
Send(html, plexSettings, testEmail);
}
private void GenerateMovieHtml(IEnumerable<RecentlyAddedChild> movies, PlexSettings plexSettings,ref StringBuilder sb)
{
sb.Append("<h1>New Movies:</h1><br/><br/>");
sb.Append(
@ -195,6 +217,65 @@ namespace PlexRequests.Services.Jobs
sb.Append("</table><br/><br/>");
}
private void GenerateMovieHtmlDb(IEnumerable<MetadataItems> movies, ref StringBuilder sb)
{
sb.Append("<h1>New Movies:</h1><br/><br/>");
sb.Append(
"<table border=\"0\" cellpadding=\"0\" align=\"center\" cellspacing=\"0\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;\" width=\"100%\">");
foreach (var movie in movies)
{
var plexGUID = string.Empty;
try
{
plexGUID = movie.Guid;
var imdbId = PlexHelper.GetProviderIdFromPlexGuid(plexGUID);
var info = _movieApi.GetMovieInformation(imdbId).Result;
sb.Append("<tr>");
sb.Append("<td align=\"center\">");
sb.AppendFormat(
"<img src=\"https://image.tmdb.org/t/p/w500{0}\" width=\"400px\" text-align=\"center\" />",
info.BackdropPath);
sb.Append("</td>");
sb.Append("</tr>");
sb.Append("<tr>");
sb.Append(
"<td align=\"center\" style=\"font-family: sans-serif; font-size: 14px; vertical-align: top;\" valign=\"top\">");
sb.AppendFormat(
"<a href=\"https://www.imdb.com/title/{0}/\"><h3 style=\"font-family: sans-serif; font-weight: normal; margin: 0; Margin-bottom: 15px;\">{1} {2}</p></a>",
info.ImdbId, info.Title, info.ReleaseDate?.ToString("yyyy") ?? string.Empty);
if (info.Genres.Any())
{
sb.AppendFormat(
"<p style=\"font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;\">Genre: {0}</p>",
string.Join(", ", info.Genres.Select(x => x.Name.ToString()).ToArray()));
}
sb.AppendFormat(
"<p style=\"font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;\">{0}</p>",
info.Overview);
sb.Append("<td");
sb.Append("<hr>");
sb.Append("<br>");
sb.Append("<br>");
sb.Append("</tr>");
}
catch (Exception e)
{
Log.Error(e);
Log.Error("Exception when trying to process a Movie, either in getting the metadata from Plex OR getting the information from TheMovieDB, Plex GUID = {0}", plexGUID);
}
}
sb.Append("</table><br/><br/>");
}
private void GenerateTvHtml(IEnumerable<RecentlyAddedChild> tv, PlexSettings plexSettings, ref StringBuilder sb)
{
// TV
@ -249,6 +330,65 @@ namespace PlexRequests.Services.Jobs
sb.Append("</table><br/><br/>");
}
private void GenerateTvHtml(IEnumerable<MetadataItems> tv, ref StringBuilder sb)
{
// TV
sb.Append("<h1>New Episodes:</h1><br/><br/>");
sb.Append(
"<table border=\"0\" cellpadding=\"0\" align=\"center\" cellspacing=\"0\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;\" width=\"100%\">");
foreach (var t in tv)
{
var plexGUID = string.Empty;
try
{
plexGUID = t.Guid;
var seasonInfo = PlexHelper.GetSeasonsAndEpisodesFromPlexGuid(plexGUID);
var info = TvApi.ShowLookupByTheTvDbId(int.Parse(PlexHelper.GetProviderIdFromPlexGuid(plexGUID)));
var banner = info.image?.original;
if (!string.IsNullOrEmpty(banner))
{
banner = banner.Replace("http", "https"); // Always use the Https banners
}
sb.Append("<tr>");
sb.Append("<td align=\"center\">");
sb.AppendFormat("<img src=\"{0}\" width=\"400px\" text-align=\"center\" />", banner);
sb.Append("</td>");
sb.Append("</tr>");
sb.Append("<tr>");
sb.Append("<td align=\"center\" style=\"font-family: sans-serif; font-size: 14px; vertical-align: top;\" valign=\"top\">");
sb.AppendFormat("<a href=\"https://www.imdb.com/title/{0}/\"><h3 style=\"font-family: sans-serif; font-weight: normal; margin: 0; Margin-bottom: 15px;\">{1} {2}</p></a>",
info.externals.imdb, info.name, info.premiered.Substring(0, 4)); // Only the year
sb.AppendFormat("<p style=\"font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;\">Season: {0}, Episode: {1}</p>", seasonInfo.SeasonNumber, seasonInfo.EpisodeNumber);
if (info.genres.Any())
{
sb.AppendFormat(
"<p style=\"font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;\">Genre: {0}</p>",
string.Join(", ", info.genres.Select(x => x.ToString()).ToArray()));
}
sb.AppendFormat("<p style=\"font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;\">{0}</p>",
string.IsNullOrEmpty(t.Summary) ? info.summary : t.Summary); // Episode Summary
sb.Append("<td");
sb.Append("<hr>");
sb.Append("<br>");
sb.Append("<br>");
sb.Append("</tr>");
}
catch (Exception e)
{
Log.Error(e);
Log.Error("Exception when trying to process a TV Show, either in getting the metadata from Plex OR getting the information from TVMaze, Plex GUID = {0}", plexGUID);
}
}
sb.Append("</table><br/><br/>");
}
private void Send(string html, PlexSettings plexSettings, bool testEmail = false)
{
var settings = EmailSettings.GetSettings();

@ -84,7 +84,7 @@ namespace PlexRequests.Store
{
using (var con = DbConnection())
{
return con.Query<MetadataItems>(query, param);
return (IEnumerable<MetadataItems>)con.Query(query, param);
}
}
}

@ -122,8 +122,8 @@ namespace PlexRequests.UI.Helpers
var sb = new StringBuilder();
var startUrl = $"{content}/Content";
sb.AppendLine($"<link rel=\"stylesheet\" href=\"/{startUrl}/datepicker.min.css\" type=\"text/css\"/>");
sb.AppendLine($"<script src=\"/{startUrl}/bootstrap-datetimepicker.min.js\"></script>");
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{startUrl}/datepicker.min.css\" type=\"text/css\"/>");
sb.AppendLine($"<script src=\"{startUrl}/bootstrap-datetimepicker.min.js\"></script>");
return helper.Raw(sb.ToString());
}

@ -25,7 +25,8 @@
// ************************************************************************/
#endregion
using System;
using System.IO;
using Mono.Data.Sqlite;
using Nancy;
using Nancy.ModelBinding;
using Nancy.Security;
@ -35,6 +36,8 @@ using NLog;
using PlexRequests.Api.Interfaces;
using PlexRequests.Core;
using PlexRequests.Core.SettingModels;
using PlexRequests.Store;
using PlexRequests.Store.Repository;
using PlexRequests.UI.Helpers;
using PlexRequests.UI.Models;
@ -59,7 +62,7 @@ namespace PlexRequests.UI.Modules
Post["/plex"] = _ => PlexTest();
Post["/sickrage"] = _ => SickRageTest();
Post["/headphones"] = _ => HeadphonesTest();
Post["/plexdb"] = _ => TestPlexDb();
}
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
@ -223,5 +226,65 @@ namespace PlexRequests.UI.Modules
return Response.AsJson(new JsonResponseModel { Result = false, Message = message }); ;
}
}
private Response TestPlexDb()
{
var settings = this.Bind<PlexSettings>();
var valid = this.Validate(settings);
if (!valid.IsValid)
{
return Response.AsJson(valid.SendJsonError());
}
try
{
var location = string.Empty;
if (string.IsNullOrEmpty(settings.PlexDatabaseLocationOverride))
{
if (Type.GetType("Mono.Runtime") != null)
{
// Mono
location = Path.Combine("/var/lib/plexmediaserver/Library/Application Support/",
"Plex Media Server", "Plug-in Support", "Databases", "com.plexapp.plugins.library.db");
}
else
{
// Default Windows
location = Path.Combine(Environment.ExpandEnvironmentVariables("%LOCALAPPDATA%"),
"Plex Media Server", "Plug-in Support", "Databases", "com.plexapp.plugins.library.db");
}
}
else
{
location = Path.Combine(settings.PlexDatabaseLocationOverride, "Plug-in Support", "Databases", "com.plexapp.plugins.library.db");
}
if (File.Exists(location))
{
return Response.AsJson(new JsonResponseModel
{
Result = true,
Message = "Found the database!"
});
}
return Response.AsJson(new JsonResponseModel
{
Result = false,
Message = $"Could not find the database at the following full location : {location}"
});
}
catch (Exception e)
{
Log.Warn("Exception thrown when attempting to find the plex database: ");
Log.Warn(e);
var message = $"Could not find Plex's DB, please check your settings. <strong>Exception Message:</strong> {e.Message}";
if (e.InnerException != null)
{
message = $"Could not find Plex's DB, please check your settings. <strong>Exception Message:</strong> {e.InnerException.Message}";
}
return Response.AsJson(new JsonResponseModel { Result = false, Message = message }); ;
}
}
}
}

@ -46,6 +46,7 @@ namespace PlexRequests.UI.NinjectModules
Bind<ICacheProvider>().To<MemoryCacheProvider>().InSingletonScope();
Bind<ISqliteConfiguration>().To<DbConfiguration>().WithConstructorArgument("provider", new SqliteFactory());
Bind<IPlexDatabase>().To<PlexDatabase>().WithConstructorArgument("provider", new SqliteFactory());
Bind<IPlexReadOnlyDatabase>().To<PlexReadOnlyDatabase>();
Bind<IUserMapper>().To<UserMapper>();

@ -121,6 +121,8 @@
});
$('#save').click(function (e) {
e.preventDefault();
var start = '';
var end = '';
if ($startDate.data("DateTimePicker").date()) {
@ -130,8 +132,6 @@
end = $endDate.data("DateTimePicker").date().toISOString();
}
e.preventDefault();
var $form = $("#mainForm");
var data = $form.serialize();

@ -91,7 +91,15 @@
<div class="form-group">
<label for="PlexDatabaseLocationOverride" class="control-label">Plex Database Override</label>
<div>
<input type="text" class="form-control form-control-custom " id="PlexDatabaseLocationOverride" name="PlexDatabaseLocationOverride" value="@Model.PlexDatabaseLocationOverride">
<input type="text" class="form-control form-control-custom " id="PlexDatabaseLocationOverride" name="PlexDatabaseLocationOverride" placeholder="%LOCALAPPDATA%\Plex Media Server\" value="@Model.PlexDatabaseLocationOverride">
</div>
<small>
This is your Plex data directory location, if we cannot manually find it then you need to specify the location! See <a href="https://support.plex.tv/hc/en-us/articles/202915258-Where-is-the-Plex-Media-Server-data-directory-located-">Here</a>.
</small>
</div>
<div class="form-group">
<div class="">
<button id="dbTest" class="btn btn-primary-outline">Test Database Directory <i class="fa fa-database"></i> <div id="dbSpinner"></div></button>
</div>
</div>
@ -101,6 +109,8 @@
<input type="text" class="form-control-custom form-control" id="authToken" name="PlexAuthToken" placeholder="Plex Auth Token" value="@Model.PlexAuthToken">
</div>
</div>
<div class="form-group">
<label for="username" class="control-label">Username and Password</label>
@ -173,6 +183,38 @@
});
});
$('#dbTest').click(function (e) {
e.preventDefault();
var url = createBaseUrl(base, '/test/plexdb');
var $form = $("#mainForm");
$('#dbSpinner').attr("class", "fa fa-spinner fa-spin");
$.ajax({
type: $form.prop("method"),
url: url,
data: $form.serialize(),
dataType: "json",
success: function (response) {
$('#dbSpinner').attr("class", "");
console.log(response);
if (response.result === true) {
generateNotify(response.message, "success");
$('#dbSpinner').attr("class", "fa fa-check");
} else {
generateNotify(response.message, "warning");
$('#dbSpinner').attr("class", "fa fa-times");
}
},
error: function (e) {
$('#spinner').attr("class", "fa fa-times");
console.log(e);
generateNotify("Something went wrong!", "danger");
}
});
});
$('#requestToken').click(function (e) {
e.preventDefault();
var $form = $("#mainForm");

Loading…
Cancel
Save