Skip to content

Commit

Permalink
v10.3.X-1 (#23)
Browse files Browse the repository at this point in the history
* Update the videos/playlists pull pipelines to automatically refresh the search index to prevent a race condition (#14)

Co-authored-by: Cody Rodgers <[email protected]>

* v10.1.X-3.6 (#18)

* V10.2.0.3 (#16)

* Fixed broken DXF configuration content for labels/folders

* Add more error handling to the folder and labels property value readers

* Fix bug preventing new labels from being synced

* Remove automatic re-indexing from the videos/playlists pipeline

---------

Co-authored-by: Cody Rodgers <[email protected]>

* Add missing embed media buttons

* Reorganize DEF files

* Update the DEF GET pipelines to have better error handling and removed broken SetFolderSettings code

* Update the DEF resolve pipelines to have better error handling

* Updated the UPDATE DEF pipelines to have better logging and error handling

* Update playlist/video pipelines to accuratly reflect video name changes made outside of Sitecore

* Fix bug preventing deleted Brightcove items from being deleted in Sitecore

* Fix broken standard values for experience items

* Update the Brightcove services to trim account ids/secrets

* Update logging levels on video/player pipelines

* Update all pipelines to handle name changes

* Update sitecore package creation script to include patching instructions

* Update the pull pipelines to support creating items in languages other an "en"

* Update all template fields to be shared

* Update the push pipelines to support creating items in languages other than "en"

* Update the folder/labels value readers to have better error handling

* Add support for embedding medai links again. It was removed as part of the upgrade but returned on client request

* Update the resolve asset item pipeline step to rename resolved items if the name has been changed since creation

* Fix the brightcove settings config so it loads both html editor scripts correctly

* Update sitecore package creation script

---------

Co-authored-by: Cody Rodgers <[email protected]>

* Fix bug which prevents the user from embedding media in the Siteocre RTE in certain scenarios

* Add support for syncing video scheduling/status information

* Reserialize content

* Add some help text to the new scheduling fields

---------

Co-authored-by: Cody Rodgers <[email protected]>
  • Loading branch information
codrod and rdacrodgers authored Dec 19, 2023
1 parent bf78d2a commit 0a8a017
Show file tree
Hide file tree
Showing 43 changed files with 784 additions and 59 deletions.
1 change: 1 addition & 0 deletions Brightcove.Core/Brightcove.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
<Compile Include="Models\IngestTextTrack.cs" />
<Compile Include="Models\IngestVideo.cs" />
<Compile Include="Models\Experience.cs" />
<Compile Include="Models\VideoSchedule.cs" />
<Compile Include="Models\Label.cs" />
<Compile Include="Models\Player.cs" />
<Compile Include="Models\TemporaryIngestUrls.cs" />
Expand Down
13 changes: 7 additions & 6 deletions Brightcove.Core/EmbedGenerator/BrightcoveEmbedGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public class BrightcoveEmbedGenerator
{
protected string iframeBaseUrl = "https://players.brightcove.net/{0}/{1}_default/index.html?{3}={2}";
protected string iframeTemplate = "<div class='brightcove-media-container brightcove-media-container-iframe'><iframe src='{0}' allowfullscreen='' allow='encrypted-media' width='{1}' height='{2}'></iframe></div>";
protected string iframeResponsiveTemplate = "<div class='brightcove-media-container brightcove-media-container-iframe' style='position: relative; display: block; max-width: {1}px;'><div style='padding-top: {2}%;'><iframe src='{0}' allowfullscreen='' allow='encrypted-media' style='position: absolute; top: 0px; right: 0px; bottom: 0px; left: 0px; width: 100%; height: 100%;'></iframe></div></div>";
protected string iframeResponsiveTemplate = "<div class='brightcove-media-container brightcove-media-container-iframe' style='position: relative; display: block; max-width: {1}px;'><div style='padding-top: {2}%;'><p><iframe src='{0}' allowfullscreen='' allow='encrypted-media' style='position: absolute; top: 0px; right: 0px; bottom: 0px; left: 0px; width: 100%; height: 100%;'></iframe></p></div></div>";

protected string jsTemplate = "<div class='brightcove-media-container brightcove-media-container-js' style='width: {4}px;'><video-js data-account='{0}' data-player='{1}' data-embed='default' controls='' data-video-id='{2}' data-playlist-id='{3}' data-application-id='' width='{4}' height='{5}' class='vjs-fluid' {7} {8} {9}></video-js>{6}</div>";
protected string jsResponsiveTemplate = "<div class='brightcove-media-container brightcove-media-container-js' style='max-width: {4}px;'><style>video-js.video-js.vjs-fluid:not(.vjs-audio-only-mode) {{padding-top: {5}%;}}</style><video-js data-account='{0}' data-player='{1}' data-embed='default' controls='' data-video-id='{2}' data-playlist-id='{3}' data-application-id='' class='vjs-fluid' {7} {8} {9}></video-js>{6}</div>";
Expand Down Expand Up @@ -91,7 +91,7 @@ protected virtual EmbedMarkup GenerateJavaScript(EmbedModel model)
EmbedMarkup result = new EmbedMarkup();
string videoId = "";
string playlistId = "";
string playlistMarkup = "";
string innerHtml = "";
string autoplay = "";
string muted = "";
string language = "";
Expand All @@ -103,7 +103,7 @@ protected virtual EmbedMarkup GenerateJavaScript(EmbedModel model)
break;
case MediaType.Playlist:
playlistId = model.MediaId;
playlistMarkup = "<div class='vjs-playlist'></div>";
innerHtml = "<div class='vjs-playlist'></div>";
break;
default:
throw new Exception("Invalid media type for javascript embed");
Expand All @@ -126,20 +126,21 @@ protected virtual EmbedMarkup GenerateJavaScript(EmbedModel model)
language = $"lang='{model.Language}'";
}

innerHtml += string.Format(jsScriptTemplate, model.AccountId, model.PlayerId);

switch (model.MediaSizing)
{
case MediaSizing.Responsive:
string aspectRatio = ((double)model.Height / model.Width * 100.0).ToString("F2");
result.Markup = string.Format(jsResponsiveTemplate, model.AccountId, model.PlayerId, videoId, playlistId, model.Width, aspectRatio, playlistMarkup, autoplay, muted, language);
result.Markup = string.Format(jsResponsiveTemplate, model.AccountId, model.PlayerId, videoId, playlistId, model.Width, aspectRatio, innerHtml, autoplay, muted, language);
break;
case MediaSizing.Fixed:
result.Markup = string.Format(jsTemplate, model.AccountId, model.PlayerId, videoId, playlistId, model.Width, model.Height, playlistMarkup, autoplay, muted, language);
result.Markup = string.Format(jsTemplate, model.AccountId, model.PlayerId, videoId, playlistId, model.Width, model.Height, innerHtml, autoplay, muted, language);
break;
default:
throw new Exception("Invalid media sizing for javascript embed");
}

result.ScriptTag = string.Format(jsScriptTemplate, model.AccountId, model.PlayerId);
result.Model = model;

return result;
Expand Down
2 changes: 0 additions & 2 deletions Brightcove.Core/EmbedGenerator/Models/EmbedMarkup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,5 @@ public class EmbedMarkup
public EmbedModel Model { get; set; } = new EmbedModel();

public string Markup { get; set; } = "";

public string ScriptTag { get; set; } = "";
}
}
3 changes: 3 additions & 0 deletions Brightcove.Core/Models/Video.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ public class Video : Asset
[JsonIgnore]
public bool IngestSuccessful { get; set; }

[JsonProperty("schedule", NullValueHandling = NullValueHandling.Ignore)]
public VideoSchedule Schedule { get; set; }

public Video ShallowCopy()
{
return (Video)this.MemberwiseClone();
Expand Down
14 changes: 14 additions & 0 deletions Brightcove.Core/Models/VideoSchedule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Newtonsoft.Json;
using System;

namespace Brightcove.Core.Models
{
public class VideoSchedule
{
[JsonProperty("starts_at", NullValueHandling = NullValueHandling.Ignore)]
public DateTime? StartsAt { get; set; }

[JsonProperty("ends_at", NullValueHandling = NullValueHandling.Ignore)]
public DateTime? EndsAt { get; set; }
}
}
4 changes: 3 additions & 1 deletion Brightcove.Core/Services/BrightcoveService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,9 @@ public Video UpdateVideo(Video video)
newVideo.Id = null;
newVideo.Images = null;

request.Content = new StringContent(JsonConvert.SerializeObject(newVideo), Encoding.UTF8, "application/json");
string content = JsonConvert.SerializeObject(newVideo);

request.Content = new StringContent(content, Encoding.UTF8, "application/json");

HttpResponseMessage response = SendRequest(request);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@
<Compile Include="Converters\PipelineStep\UpdatePipelineStepConverter.cs" />
<Compile Include="Converters\ValueAccessor\LabelsPropertyValueAccessorConverter.cs" />
<Compile Include="Converters\ValueAccessor\FolderPropertyValueAccessorConverter.cs" />
<Compile Include="Converters\ValueAccessor\DateTimePropertyValueAccessorConverter.cs" />
<Compile Include="Converters\WebApiEndpointConverter.cs" />
<Compile Include="Converters\PipelineStep\ResolveAssetItemPipelineStepConverter.cs" />
<Compile Include="Converters\ValueAccessor\CsvStringPropertyValueAccessorConverter.cs" />
Expand Down Expand Up @@ -505,6 +506,8 @@
<Compile Include="Settings\ResolveAssetModelSettings.cs" />
<Compile Include="Settings\WebApiSettings.cs" />
<Compile Include="ValueReaders\CsvStringPropertyValueReader.cs" />
<Compile Include="ValueReaders\DateTimePropertyValueReader.cs" />
<Compile Include="ValueWriters\DateTimePropertyValueWriter.cs" />
<Compile Include="ValueReaders\NullableEnumValueReader.cs" />
<Compile Include="ValueReaders\LabelsPropertyValueReader.cs" />
<Compile Include="ValueReaders\FolderPropertyValueReader.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Brightcove.DataExchangeFramework.ValueReaders;
using Brightcove.DataExchangeFramework.ValueWriters;
using Sitecore.DataExchange;
using Sitecore.DataExchange.Attributes;
using Sitecore.DataExchange.Converters.DataAccess.ValueAccessors;
using Sitecore.DataExchange.DataAccess;
using Sitecore.DataExchange.DataAccess.Readers;
using Sitecore.DataExchange.DataAccess.Writers;
using Sitecore.DataExchange.Repositories;
using Sitecore.Services.Core.Model;

namespace Brightcove.DataExchangeFramework
{
[SupportedIds(new string[] { "{CC5AC65C-ACAF-4D89-8811-43B2D8E8134A}" })]
public class DateTimePropertyValueAccessorConverter : ValueAccessorConverter
{
public const string FieldNamePropertyName = "PropertyName";

public DateTimePropertyValueAccessorConverter(IItemModelRepository repository)
: base(repository)
{
}

protected override ConvertResult<IValueAccessor> ConvertSupportedItem(
ItemModel source)
{
ConvertResult<IValueAccessor> convertResult = base.ConvertSupportedItem(source);
if (!convertResult.WasConverted)
return convertResult;
string stringValue = this.GetStringValue(source, "PropertyName");
if (string.IsNullOrWhiteSpace(stringValue))
return this.NegativeResult(source, "The property name field must have a value specified.", "field: PropertyName");
IValueAccessor convertedValue = convertResult.ConvertedValue;
if (convertedValue == null)
return this.NegativeResult(source, "A null value accessor was returned by the converter.");
if (convertedValue.ValueReader == null)
{
DateTimePropertyValueReader propertyValueReader = new DateTimePropertyValueReader(stringValue);
convertedValue.ValueReader = (IValueReader)propertyValueReader;
}
if (convertedValue.ValueWriter == null)
{
DateTimePropertyValueWriter propertyValueWriter = new DateTimePropertyValueWriter(stringValue);
convertedValue.ValueWriter = (IValueWriter)propertyValueWriter;
}
return this.PositiveResult(convertedValue);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Sitecore.DataExchange.DataAccess;
using Sitecore.DataExchange.DataAccess.Readers;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Web;

namespace Brightcove.DataExchangeFramework.ValueReaders
{
public class DateTimePropertyValueReader : ChainedPropertyValueReader
{
public DateTimePropertyValueReader(string propertyName) : base(propertyName)
{
}

public override ReadResult Read(object source, DataAccessContext context)
{
if (context == null)
throw new ArgumentNullException(nameof(context));

var result = base.Read(source, context);

bool wasValueRead = result.WasValueRead;
object obj = result.ReadValue;

if(obj == null || !(obj is DateTime))
{
obj = "";
wasValueRead = true;
}
else
{
obj = ((DateTime)obj).ToString("yyyyMMddTHHmmss\\Z");
}

return new ReadResult(DateTime.UtcNow)
{
WasValueRead = wasValueRead,
ReadValue = obj
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Sitecore.DataExchange.DataAccess;
using System;
using System.Globalization;

namespace Brightcove.DataExchangeFramework.ValueWriters
{
public class DateTimePropertyValueWriter : ChainedPropertyValueWriter
{
public DateTimePropertyValueWriter(string propertyName) : base(propertyName)
{

}

public override bool Write(object target, object value, DataAccessContext context)
{
DateTime? returnValue = null;

try
{
if ((value is string) && !string.IsNullOrWhiteSpace((string)value))
{
string sourceValue = (string)value;
DateTime tmp;

if (DateTime.TryParseExact(sourceValue, new string[2] { "yyyyMMddTHHmmss", "yyyyMMddTHHmmss\\Z" }, (IFormatProvider)CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out tmp))
{
returnValue = tmp;
}
}
}
catch
{
returnValue = null;
}

return base.Write(target, returnValue, context);
}
}
}
4 changes: 4 additions & 0 deletions Brightcove.Web/EmbedGenerator/SitecoreEmbedGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ public class SitecoreEmbedGenerator : BrightcoveEmbedGenerator
{
public SitecoreEmbedGenerator() : base()
{
//1) We wrap the iframe in a paragraph tag so that the RTE handles it better
//2) We don't support using a resposive iframe in the RTE
iframeTemplate = "<p><iframe class='brightcove-media-container brightcove-media-container-iframe' src='{0}' allowfullscreen='' allow='encrypted-media' width='{1}' height='{2}'></iframe></p>";

//1) The RTE does not like the <video-js> tag and will try to incorrectly HTML encode it so we use standard <video> instead.
//2) Using <video> instead also breaks some styling so we have to change the class to "video-js" (instead of vjs-fluid) and tweak the responsive styling.
//3) Note that the controls attribute must be set to 'true' or the RTE will strip it away and break the embed
Expand Down
2 changes: 1 addition & 1 deletion Brightcove.Web/UI/Wizards/EmbedMediaWizard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ protected virtual void InsertMedia(EmbedRenderingParameters parameters)
break;

default:
SheerResponse.Eval("scClose(" + StringUtil.EscapeJavascriptString(result.Markup + result.ScriptTag + "<p>&nbsp;</p>") + ")");
SheerResponse.Eval("scClose(" + StringUtil.EscapeJavascriptString(result.Markup) + ")");
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@

<div class="brightcove-media-rendering-container">
@Html.Raw(Model.Markup)
@Html.Raw(Model.ScriptTag)
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,29 @@ var EditorOptions = function () {
var embedRadiogroup = document.getElementsByName("EmbedRadiogroup");
var sizingRadiogroup = document.getElementsByName("SizingRadiogroup");

for (var i = 0; i < embedRadiogroup.length; i++) {
/*for (var i = 0; i < embedRadiogroup.length; i++) {
embedRadiogroup[i].addEventListener("change", function () { SetRadioSelection(embedInput, embedRadiogroup); }, false);
}
*/
for (var i = 0; i < sizingRadiogroup.length; i++) {
sizingRadiogroup[i].addEventListener("change", function () { SetRadioSelection(sizingInput, sizingRadiogroup); }, false);
}
if (aspectRatioSelect !== null && widthInput !== null && heightInput !== null) {
aspectRatioSelect.addEventListener("change", function () { CalculateDimensions(aspectRatioSelect, widthInput, heightInput); }, false);
widthInput.addEventListener("change", function () { CalculateDimensions(aspectRatioSelect, widthInput, heightInput); }, false);
}

document.getElementById("IframeRadiobutton").addEventListener("change", function (event) {
document.getElementById("ResponsiveRadiobutton").disabled = true;
document.getElementById("FixedRadiobutton").checked = true;
SetRadioSelection(embedInput, embedRadiogroup);
SetRadioSelection(sizingInput, sizingRadiogroup);
});

document.getElementById("JavascriptRadiobutton").addEventListener("change", function () {
document.getElementById("ResponsiveRadiobutton").disabled = false;
document.getElementById("ResponsiveRadiobutton").checked = true;
SetRadioSelection(embedInput, embedRadiogroup);
SetRadioSelection(sizingInput, sizingRadiogroup);
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
ID: "e6d6979d-50c4-4904-a82f-970b9abfbbda"
Parent: "9f623c7f-51f5-4091-8645-daad69627e67"
Template: "cc5ac65c-acaf-4d89-8811-43b2d8e8134a"
Path: /sitecore/templates/Branches/Data Exchange/Framework/Branches/Brightcove Tenant/$name/Data Access/Value Accessor Sets/Providers/Brightcove/Video Model Properties/Schedule_StartsAt Property
DB: master
SharedFields:
- ID: "bbcf1be5-5f6b-4e21-9c8e-00e12aa2f042"
Hint: PropertyName
Value: Schedule.StartsAt
Languages:
- Language: en
Versions:
- Version: 1
Fields:
- ID: "25bed78c-4957-4165-998a-ca1b52f67497"
Hint: __Created
Value: 20231115T163646Z
- ID: "5dd74568-4d4b-44c1-b513-0af5f4cda34f"
Hint: __Created by
Value: |
sitecore\Admin
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
ID: "a9578900-8b33-4ac4-9edd-8f3d0942b967"
Parent: "9f623c7f-51f5-4091-8645-daad69627e67"
Template: "729aeffb-b5bd-4cd4-958f-e25b50948ac8"
Path: /sitecore/templates/Branches/Data Exchange/Framework/Branches/Brightcove Tenant/$name/Data Access/Value Accessor Sets/Providers/Brightcove/Video Model Properties/ItemState Property
DB: master
SharedFields:
- ID: "06fd1c3e-a7f7-4cd2-a54e-a995d7a9e4de"
Hint: PropertyName
Value: ItemState
Languages:
- Language: en
Versions:
- Version: 1
Fields:
- ID: "25bed78c-4957-4165-998a-ca1b52f67497"
Hint: __Created
Value: 20231115T142712Z
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
ID: "95f41ff7-7660-478f-9a25-dc576db83c81"
Parent: "9f623c7f-51f5-4091-8645-daad69627e67"
Template: "cc5ac65c-acaf-4d89-8811-43b2d8e8134a"
Path: /sitecore/templates/Branches/Data Exchange/Framework/Branches/Brightcove Tenant/$name/Data Access/Value Accessor Sets/Providers/Brightcove/Video Model Properties/Schedule_EndsAt Property
DB: master
SharedFields:
- ID: "bbcf1be5-5f6b-4e21-9c8e-00e12aa2f042"
Hint: PropertyName
Value: Schedule.EndsAt
Languages:
- Language: en
Versions:
- Version: 1
Fields:
- ID: "25bed78c-4957-4165-998a-ca1b52f67497"
Hint: __Created
Value: 20231115T163711Z
- ID: "5dd74568-4d4b-44c1-b513-0af5f4cda34f"
Hint: __Created by
Value: |
sitecore\Admin
Loading

0 comments on commit 0a8a017

Please sign in to comment.