Basic search working for #32

pull/130/head
tidusjar 9 years ago
parent f49e67da83
commit 1596dce629

@ -0,0 +1,152 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: MusicBrainzSearchResults.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.Collections.Generic;
using Newtonsoft.Json;
namespace PlexRequests.Api.Models.Music
{
public class TextRepresentation
{
public string language { get; set; }
public string script { get; set; }
}
public class Alias
{
[JsonProperty(PropertyName = "sort-name")]
public string SortName { get; set; }
public string name { get; set; }
public object locale { get; set; }
public string type { get; set; }
public object primary { get; set; }
[JsonProperty(PropertyName = "begin-date")]
public object BeginDate { get; set; }
[JsonProperty(PropertyName = "end-date")]
public object EndDate { get; set; }
}
public class Artist
{
public string id { get; set; }
public string name { get; set; }
[JsonProperty(PropertyName = "sort-date")]
public string SortName { get; set; }
public string disambiguation { get; set; }
public List<Alias> aliases { get; set; }
}
public class ArtistCredit
{
public Artist artist { get; set; }
}
public class ReleaseGroup
{
public string id { get; set; }
[JsonProperty(PropertyName = "primary-type")]
public string PrimaryType { get; set; }
[JsonProperty(PropertyName = "secondary-types")]
public List<string> SecondaryTypes { get; set; }
}
public class Area
{
public string id { get; set; }
public string name { get; set; }
[JsonProperty(PropertyName = "sort-name")]
public string SortName { get; set; }
[JsonProperty(PropertyName = "iso-3166-1-codes")]
public List<string> ISO31661Codes { get; set; }
}
public class ReleaseEvent
{
public string date { get; set; }
public Area area { get; set; }
}
public class Label
{
public string id { get; set; }
public string name { get; set; }
}
public class LabelInfo
{
[JsonProperty(PropertyName = "catalog-number")]
public string CatalogNumber { get; set; }
public Label label { get; set; }
}
public class Medium
{
public string format { get; set; }
[JsonProperty(PropertyName = "disc-count")]
public int DiscCount { get; set; }
[JsonProperty(PropertyName = "catalog-number")]
public int CatalogNumber { get; set; }
}
public class Release
{
public string id { get; set; }
public string score { get; set; }
public int count { get; set; }
public string title { get; set; }
public string status { get; set; }
public string disambiguation { get; set; }
public string packaging { get; set; }
[JsonProperty(PropertyName = "text-representation")]
public TextRepresentation TextRepresentation { get; set; }
[JsonProperty(PropertyName = "artist-credit")]
public List<ArtistCredit> ArtistCredit { get; set; }
[JsonProperty(PropertyName = "release-group")]
public ReleaseGroup ReleaseGroup { get; set; }
public string date { get; set; }
public string country { get; set; }
[JsonProperty(PropertyName = "release-events")]
public List<ReleaseEvent> ReleaseEvents { get; set; }
public string barcode { get; set; }
public string asin { get; set; }
[JsonProperty(PropertyName = "label-info")]
public List<LabelInfo> LabelInfo { get; set; }
[JsonProperty(PropertyName = "track-count")]
public int TrackCount { get; set; }
public List<Medium> media { get; set; }
}
public class MusicBrainzSearchResults
{
public string created { get; set; }
public int count { get; set; }
public int offset { get; set; }
public List<Release> releases { get; set; }
}
}

@ -50,6 +50,7 @@
<Compile Include="Movie\CouchPotatoStatus.cs" />
<Compile Include="Music\HeadphonesAlbumSearchResult.cs" />
<Compile Include="Music\HeadphonesArtistSearchResult.cs" />
<Compile Include="Music\MusicBrainzSearchResults.cs" />
<Compile Include="Notifications\PushbulletPush.cs" />
<Compile Include="Notifications\PushbulletResponse.cs" />
<Compile Include="Notifications\PushoverResponse.cs" />

@ -0,0 +1,70 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: MusicBrainzApi.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 Newtonsoft.Json;
using NLog;
using PlexRequests.Api.Models.Music;
using RestSharp;
namespace PlexRequests.Api
{
public class MusicBrainsApi
{
public MusicBrainsApi()
{
Api = new ApiRequest();
}
private ApiRequest Api { get; }
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
private readonly Uri BaseUri = new Uri("http://musicbrainz.org/ws/2/");
public MusicBrainzSearchResults SearchAlbum(string searchTerm)
{
Log.Trace("Searching for album: {0}", searchTerm);
var request = new RestRequest
{
Resource = "release/?query={searchTerm}&fmt=json",
Method = Method.GET
};
request.AddUrlSegment("searchTerm", searchTerm);
try
{
return Api.ExecuteJson<MusicBrainzSearchResults>(request, BaseUri);
}
catch (JsonSerializationException jse)
{
Log.Warn(jse);
return new MusicBrainzSearchResults(); // If there is no matching result we do not get returned a JSON string, it just returns "false".
}
}
}
}

@ -66,6 +66,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="ApiRequest.cs" />
<Compile Include="MusicBrainzApi.cs" />
<Compile Include="MockApiData.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>

@ -6,19 +6,22 @@
});
var searchSource = $("#search-template").html();
var musicSource = $("#music-template").html();
var searchTemplate = Handlebars.compile(searchSource);
var musicTemplate = Handlebars.compile(musicSource);
var noResultsHtml = "<div class='no-search-results'>" +
"<i class='fa fa-film no-search-results-icon'></i><div class='no-search-results-text'>Sorry, we didn't find any results!</div></div>";
var movieTimer = 0;
var tvimer = 0;
var noResultsMusic = "<div class='no-search-results'>" +
"<i class='fa fa-headphones no-search-results-icon'></i><div class='no-search-results-text'>Sorry, we didn't find any results!</div></div>";
var searchTimer = 0;
// Type in movie search
$("#movieSearchContent").on("input", function () {
if (movieTimer) {
clearTimeout(movieTimer);
if (searchTimer) {
clearTimeout(searchTimer);
}
$('#movieSearchButton').attr("class","fa fa-spinner fa-spin");
movieTimer = setTimeout(movieSearch, 400);
searchTimer = setTimeout(movieSearch, 400);
});
@ -34,11 +37,11 @@ $('#moviesInTheaters').on('click', function (e) {
// Type in TV search
$("#tvSearchContent").on("input", function () {
if (tvimer) {
clearTimeout(tvimer);
if (searchTimer) {
clearTimeout(searchTimer);
}
$('#tvSearchButton').attr("class", "fa fa-spinner fa-spin");
tvimer = setTimeout(tvSearch, 400);
searchTimer = setTimeout(tvSearch, 400);
});
// Click TV dropdown option
@ -72,6 +75,16 @@ $(document).on("click", ".dropdownTv", function (e) {
sendRequestAjax(data, type, url, buttonId);
});
// Search Music
$("#musicSearchContent").on("input", function () {
if (searchTimer) {
clearTimeout(searchTimer);
}
$('#musicSearchButton').attr("class", "fa fa-spinner fa-spin");
searchTimer = setTimeout(musicSearch, 400);
});
// Click Request for movie
$(document).on("click", ".requestMovie", function (e) {
e.preventDefault();
@ -133,7 +146,7 @@ function moviesComingSoon() {
}
function moviesInTheaters() {
getMovies("/search/movie/playing")
getMovies("/search/movie/playing");
}
function getMovies(url) {
@ -179,6 +192,29 @@ function getTvShows(url) {
});
};
function musicSearch() {
var query = $("#musicSearchContent").val();
getMusic("/search/music/" + query);
}
function getMusic(url) {
$("#musicList").html("");
$.ajax(url).success(function (results) {
if (results.count > 0) {
results.releases.forEach(function (result) {
var context = buildMusicContext(result);
var html = musicTemplate(context);
$("#musicList").append(html);
});
}
else {
$("#musicList").html(noResultsMusic);
}
$('#musicSearchButton').attr("class", "fa fa-search");
});
};
function buildMovieContext(result) {
var date = new Date(result.releaseDate);
@ -212,3 +248,16 @@ function buildTvShowContext(result) {
};
return context;
}
function buildMusicContext(result) {
var context = {
id: result.id,
title: result.title,
overview: result.disambiguation,
year: result.date,
type: "music"
};
return context;
}

@ -74,6 +74,7 @@ namespace PlexRequests.UI.Modules
Get["movie/{searchTerm}"] = parameters => SearchMovie((string)parameters.searchTerm);
Get["tv/{searchTerm}"] = parameters => SearchTvShow((string)parameters.searchTerm);
Get["music/{searchTerm}"] = parameters => SearchMusic((string)parameters.searchTerm);
Get["movie/upcoming"] = parameters => UpcomingMovies();
Get["movie/playing"] = parameters => CurrentlyPlayingMovies();
@ -152,6 +153,13 @@ namespace PlexRequests.UI.Modules
return Response.AsJson(model);
}
private Response SearchMusic(string searchTerm)
{
var api = new MusicBrainsApi();
var albums = api.SearchAlbum(searchTerm);
return Response.AsJson(albums);
}
private Response UpcomingMovies() // TODO : Not used
{
var movies = MovieApi.GetUpcomingMovies();
@ -174,7 +182,7 @@ namespace PlexRequests.UI.Modules
{
var movieApi = new TheMovieDbApi();
var movieInfo = movieApi.GetMovieInformation(movieId).Result;
string fullMovieName = string.Format("{0}{1}", movieInfo.Title, movieInfo.ReleaseDate.HasValue ? $" ({movieInfo.ReleaseDate.Value.Year})" : string.Empty);
var fullMovieName = $"{movieInfo.Title}{(movieInfo.ReleaseDate.HasValue ? $" ({movieInfo.ReleaseDate.Value.Year})" : string.Empty)}";
Log.Trace("Getting movie info from TheMovieDb");
Log.Trace(movieInfo.DumpJson);
//#if !DEBUG
@ -192,6 +200,7 @@ namespace PlexRequests.UI.Modules
existingRequest.RequestedUsers.Add(Username);
RequestService.UpdateRequest(existingRequest);
}
return Response.AsJson(new JsonResponseModel { Result = true, Message = settings.UsersCanViewOnlyOwnRequests ? $"{fullMovieName} was successfully added!" : $"{fullMovieName} has already been requested!" });
}

@ -161,17 +161,16 @@
<div class="row">
<div class="col-sm-2">
<img class="img-responsive" src="http://image.tmdb.org/t/p/w150/{{posterPath}}" alt="poster">
@*<img class="img-responsive" src="http://image.tmdb.org/t/p/w150/{{posterPath}}" alt="poster">*@
<img class="img-responsive" width="150" src="{{posterPath}}" alt="poster">
</div>
<div class="col-sm-5 ">
<div>
<a href="http://www.imdb.com/title/{{imdb}}/" target="_blank">
@*<a href="http://www.imdb.com/title/{{imdb}}/" target="_blank">*@
<h4>{{title}} ({{year}})</h4>
</a>
@*</a>*@
</div>
<p>{{overview}}</p>
</div>
@ -179,7 +178,7 @@
<form method="POST" action="/search/request/{{type}}" id="form{{id}}">
<input name="{{type}}Id" type="text" value="{{id}}" hidden="hidden" />
<button id="{{id}}" style="text-align: right" class="btn btn-primary-outline requestMovie" type="submit"><i class="fa fa-plus"></i> Request</button>
<button id="{{id}}" style="text-align: right" class="btn btn-primary-outline requestMusic" type="submit"><i class="fa fa-plus"></i> Request</button>
<br />
<br />

Loading…
Cancel
Save