Skip to content

Commit

Permalink
Added Limbo.Umbraco.Video dependency
Browse files Browse the repository at this point in the history
Besides the dependency. this commit also contains a number of related changes, as well as a breaking change in the way the video data is saved in Umbraco, requiring existing videos to be inserted.

Due to the way Umbraco/JSON.net handles date like string values (eg. string values containing an ISO 8601 date), we need to keep a serialized version the video data received from the YouTube API in order to prevent corrupt timestamps. See this issue for further information: umbraco/Umbraco-CMS#3075
  • Loading branch information
abjerner committed Mar 23, 2022
1 parent f9886ee commit 433c4a7
Show file tree
Hide file tree
Showing 16 changed files with 287 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,37 @@

const vm = this;

if (!$scope.model.value) {
$scope.model.value = { source: "" };
}
let rawVideoData = null;

// Gets information about the video of the entered URL
vm.getVideo = function() {
vm.getVideo = function () {

const source = $scope.model.value.source.trim();
const source = $scope.model.value && $scope.model.value.source ? $scope.model.value.source.trim() : null;

if (source) {

vm.loading = true;
vm.updateUI();

youTubeService.getVideo(source).then(function (res) {

// Update the credentials and embed details
$scope.model.value.credentials = res.data.credentials;
$scope.model.value.video = res.data.video;
$scope.model.value.embed = res.data.embed;

// As Umbraco/JSON.net will corrupt any timestamps in the JSON, we need to store it as serialized
$scope.model.value.video = { _data: angular.toJson(res.data.video) };
rawVideoData = res.data.video;

vm.loading = false;
vm.updateUI();

});

} else {

vm.embed = false;
rawVideoData = null;

delete $scope.model.value.credentials;
delete $scope.model.value.video;
Expand All @@ -49,7 +56,7 @@
// Updates the video information for the UI
vm.updateUI = function () {

const embed = $scope.model.value.source && $scope.model.value.source.indexOf("<") >= 0;
const embed = $scope.model.value && $scope.model.value.source && $scope.model.value.source.indexOf("<") >= 0;

if (embed !== vm.embed) {
vm.embed = embed;
Expand All @@ -61,19 +68,39 @@
}, 20);
}
}

const video = $scope.model.value.video;

if (!video) {

if (!rawVideoData) {
vm.videoId = null;
vm.title = null,
vm.duration = null;
vm.thumbnail = null;
return;
}

vm.duration = youTubeService.getDuration(video);
vm.thumbnail = youTubeService.getThumbnail(video);
vm.videoId = rawVideoData.id;
vm.title = rawVideoData.snippet?.title,
vm.duration = youTubeService.getDuration(rawVideoData);
vm.thumbnail = youTubeService.getThumbnail(rawVideoData);

};

vm.updateUI();
function init() {

if (!$scope.model.value) {
$scope.model.value = null;
return;
}

if (!$scope.model.value.video) return;
if (!$scope.model.value.video._data) return;

// Get the Vimeo video data from the "_data" property (necessary due to Umbraco/JSON.net issue)
rawVideoData = angular.fromJson($scope.model.value.video._data);

vm.updateUI();

}

init();

});
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
<th>
<localize key="dreambroker_id">ID</localize>
</th>
<td><code>{{model.value.video.id}}</code></td>
<td><code>{{vm.videoId}}</code></td>
</tr>
<tr>
<th>
<localize key="dreambroker_title">Title</localize>
</th>
<td>{{model.value.video.snippet.title}}</td>
<td>{{vm.title}}</td>
</tr>
<tr>
<th>
Expand Down
8 changes: 4 additions & 4 deletions src/Limbo.Umbraco.YouTube/Composers/YouTubeComposer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using Limbo.Umbraco.YouTube.Models;
using Limbo.Umbraco.YouTube.Models.Settings;
using Limbo.Umbraco.YouTube.Services;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
Expand All @@ -11,13 +11,13 @@
#pragma warning disable 1591

namespace Limbo.Umbraco.YouTube.Composers {

public class YouTubeComposer : IComposer {

public void Compose(IUmbracoBuilder builder) {

builder.Services.AddTransient<YouTubeService>();

builder.AddUmbracoOptions<YouTubeSettings>();

}
Expand Down
17 changes: 8 additions & 9 deletions src/Limbo.Umbraco.YouTube/Controllers/YouTubeController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Linq;
using Limbo.Umbraco.YouTube.Models;
using Limbo.Umbraco.YouTube.Models.Credentials;
using Limbo.Umbraco.YouTube.Services;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
Expand All @@ -11,10 +11,10 @@
#pragma warning disable 1591

namespace Limbo.Umbraco.YouTube.Controllers {

[PluginController("Limbo")]
public class YouTubeController : UmbracoAuthorizedApiController {

private readonly YouTubeService _youTubeService;

#region Constructors
Expand All @@ -26,11 +26,11 @@ public class YouTubeController : UmbracoAuthorizedApiController {
#endregion

#region Public API methods

[HttpGet]
[HttpPost]
public object GetVideo() {

// Get the "source" parameter from either GET or POST
string source = HttpContext.Request.Query.GetString("source");
if (string.IsNullOrWhiteSpace(source) && HttpContext.Request.HasFormContentType) {
Expand All @@ -40,10 +40,10 @@ public class YouTubeController : UmbracoAuthorizedApiController {
if (string.IsNullOrWhiteSpace(source)) return BadRequest("No source specified.");

if (!_youTubeService.TryGetVideoId(source, out YouTubeVideoOptions options)) return BadRequest("Source doesn't match a valid URL or embed code.");

YouTubeCredentials credentials = _youTubeService.GetCredentials().FirstOrDefault();
if (credentials == null || !_youTubeService.TryGetHttpService(credentials, out var http)) return BadRequest("No credentials configured for YouTube.");

var o = new YouTubeGetVideoListOptions(options.VideoId) {
Part = YouTubeVideoParts.Snippet + YouTubeVideoParts.ContentDetails,
};
Expand All @@ -56,13 +56,12 @@ public class YouTubeController : UmbracoAuthorizedApiController {

JObject embed = JObject.FromObject(options);
embed.Remove("videoId");
embed.Add("html", options.GetEmbedCode().ToString());

return new {
credentials = new {
key = credentials.Key
},
video = video?.JObject,
video = video.JObject,
embed
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,26 @@
using Skybrud.Essentials.Json;

namespace Limbo.Umbraco.YouTube.Json.Converters {

/// <summary>
/// JSON converter for serializing instances of <see cref="JsonObjectBase"/>.
/// </summary>
public class JsonObjectBaseConverter : JsonConverter {

/// <inheritdoc />
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
switch (value) {
case null:
writer.WriteNull();
return;
case JsonObjectBase obj: {
if (obj.JObject == null) {
writer.WriteNull();
} else {
obj.JObject.WriteTo(writer);
if (obj.JObject == null) {
writer.WriteNull();
} else {
obj.JObject.WriteTo(writer);
}
return;
}
return;
}
default:
throw new Exception("Unsupported type: " + value.GetType());
}
Expand All @@ -32,7 +32,7 @@ public class JsonObjectBaseConverter : JsonConverter {
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
throw new NotImplementedException();
}

/// <inheritdoc />
public override bool CanConvert(Type objectType) {
return objectType == typeof(JsonObjectBase);
Expand Down
3 changes: 3 additions & 0 deletions src/Limbo.Umbraco.YouTube/Limbo.Umbraco.YouTube.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@

<!-- Include NuGet dependencies -->
<ItemGroup>
<PackageReference Include="Limbo.Umbraco.Video" Version="1.0.0-beta001">
<ExcludeAssets>content;build</ExcludeAssets>
</PackageReference>
<PackageReference Include="Skybrud.Essentials.AspNetCore" Version="1.0.0-alpha003" />
<PackageReference Include="Skybrud.Social.Google.YouTube" Version="1.0.0-beta002" />
<PackageReference Include="Umbraco.Cms.Core" Version="9.0.0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System;
using Limbo.Umbraco.Video.Models.Credentials;

namespace Limbo.Umbraco.YouTube.Models {
namespace Limbo.Umbraco.YouTube.Models.Credentials {

/// <summary>
/// Class with information about the credentials used for accessing the YouTube API.
/// </summary>
public class YouTubeCredentials {
public class YouTubeCredentials : ICredentials {

/// <summary>
/// Gets the key of the credentials.
/// </summary>
Expand All @@ -17,11 +18,16 @@ public class YouTubeCredentials {
/// </summary>
public string Name { get; internal set; }

/// <summary>
/// Gets the description of the credentials.
/// </summary>
public string Description { get; internal set; }

/// <summary>
/// If configured, gets the Google server key. Server keys allow accessing the YouTube API without a user context.
/// </summary>
public string ApiKey { get; internal set; }

/// <summary>
/// Initializes a new instance with default options.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using Umbraco.Cms.Core.Configuration.Models;
using Limbo.Umbraco.YouTube.Models.Credentials;
using Umbraco.Cms.Core.Configuration.Models;

namespace Limbo.Umbraco.YouTube.Models.Settings {

namespace Limbo.Umbraco.YouTube.Models {

/// <summary>
/// Class representing the settings for this package.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using Limbo.Umbraco.YouTube.Services;
using Limbo.Umbraco.Video.Models.Videos;
using Limbo.Umbraco.YouTube.Services;
using Microsoft.AspNetCore.Html;
using Newtonsoft.Json;
using Skybrud.Essentials.Json.Converters;

namespace Limbo.Umbraco.YouTube.Models {
namespace Limbo.Umbraco.YouTube.Models.Videos {

/// <summary>
/// Class representing the embed options of the video.
/// </summary>
public class YouTubeEmbed {
public class YouTubeEmbed : IVideoEmbed {

#region Properties

Expand Down
23 changes: 23 additions & 0 deletions src/Limbo.Umbraco.YouTube/Models/Videos/YouTubeThumbnail.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Limbo.Umbraco.Video.Models.Videos;
using Skybrud.Social.Google.YouTube.Models.Videos;

namespace Limbo.Umbraco.YouTube.Models.Videos {

/// <summary>
/// Class representing a YouTube thumbnail.
/// </summary>
public class YouTubeThumbnail : VideoThumbnail {

/// <summary>
/// Initializes a new instance based on the specified <paramref name="thumbnail"/>.
/// </summary>
/// <param name="thumbnail">The video thumbnail from the YouTube API.</param>
public YouTubeThumbnail(YouTubeVideoThumbnail thumbnail) {
Width = thumbnail.Width;
Height = thumbnail.Height;
Url = thumbnail.Url;
}

}

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using Limbo.Umbraco.YouTube.PropertyEditors;
using Limbo.Umbraco.Video.Models.Videos;
using Limbo.Umbraco.YouTube.PropertyEditors;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Skybrud.Essentials.Json.Extensions;

namespace Limbo.Umbraco.YouTube.Models {
namespace Limbo.Umbraco.YouTube.Models.Videos {

/// <summary>
/// Class representing the value of the <see cref="YouTubeEditor"/> property editor.
/// </summary>
public class YouTubeValue {
public class YouTubeValue : IVideoValue {

#region Properties

Expand All @@ -30,6 +31,10 @@ public class YouTubeValue {
[JsonProperty("embed")]
public YouTubeEmbed Embed { get; }

IVideoDetails IVideoValue.Video => Video;

IVideoEmbed IVideoValue.Embed => Embed;

#endregion

#region Constructors
Expand Down

0 comments on commit 433c4a7

Please sign in to comment.