From b30be812c68057207afaff91e6eedd8a21c99873 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1s=C3=A1ry=20D=C3=A1niel?= Date: Thu, 6 Dec 2018 16:03:48 +0000 Subject: [PATCH] =?utf8?q?#106=20MediaCubeAPI=20b=C5=91v=C3=ADt=C3=A9se=20?= =?utf8?q?szinkron=20folyamat=20futtat=C3=A1ssal=20#107=20Folyamat=20futta?= =?utf8?q?t=C3=A1s=20=C3=A9s=20monitoroz=C3=A1s=20kiaj=C3=A1nl=C3=A1sa=20W?= =?utf8?q?S-en?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit git-tfs-id: [http://tfs.userrendszerhaz.hu:8080/tfs/DefaultCollection]$/MediaCube;C31360 --- client/DxPlay/PlayerForm.Designer.cs | 6 +- client/DxPlay/PlayerForm.resx | 2 +- .../Configuration/configuration - Copy.json | 6 +- .../Maestro/Configuration/configuration.json | 71 ++++- client/Maestro/Maestro.csproj | 12 + client/Maestro/MaestroForm.Designer.cs | 18 +- client/Maestro/MaestroForm.Metadata.cs | 45 ++++ client/Maestro/MaestroForm.cs | 3 + client/Maestro/MaestroForm.resx | 2 +- client/Maestro/Metadata/MetaDataInfo.cs | 5 +- client/Maestro/Program.cs | 19 -- .../Maestro/Properties/Resources.Designer.cs | 10 + client/Maestro/Properties/Resources.resx | 3 + .../Resources/ic_playlist_add_black_24dp.png | Bin 0 -> 100 bytes client/Maestro/RestoreMedia.Designer.cs | 101 ++++++++ client/Maestro/RestoreMedia.cs | 65 +++++ client/Maestro/RestoreMedia.resx | 120 +++++++++ client/Maestro/Sources/NexioRESTSource.cs | 3 + .../MaestroShared/Commons/PatternNameMaker.cs | 6 +- client/MaestroShared/Commons/ShortGuid.cs | 244 ++++++++++++++++++ .../Configuration/ConfigurationInfo.cs | 9 +- client/MaestroShared/MaestroShared.csproj | 20 +- client/MaestroShared/Model/Model.cs | 12 + .../baseline_playlist_play_black_18dp.png | Bin 0 -> 157 bytes .../Resources/ic_play_for_work_black_18dp.png | Bin 0 -> 172 bytes .../Resources/ic_play_for_work_black_24dp.png | Bin 0 -> 183 bytes .../Resources/ic_playlist_add_black_18dp.png | Bin 0 -> 115 bytes .../Targets/FTPTargetProcessor.cs | 3 +- client/MediaCubeClient/MediaCubeApi.cs | 41 ++- client/MediaCubeClient/MediaCubeClient.csproj | 2 + .../MediaCubeClient/MediaCubeJsonConvert.cs | 43 +++ client/MediaCubeClient/MediaCubeWSApi.cs | 22 +- .../run-mediacube-server-bsh.launch | 2 +- .../config/config.xml | 1 + .../jobtemplates/retrieve-material.xml | 2 +- .../steps/CleanupMountedLocationStep.java | 10 +- .../CopyForArchiveNEXIORecordingsStep.java | 9 +- .../server/steps/TSMSystemRestoreStep.java | 143 ++++++++++ .../src/user/commons/nexio/api/ClipImpl.java | 4 +- .../user/jobengine/db/DynamicAttributes.java | 12 +- .../src/user/jobengine/db/Media.java | 5 + .../osgi/mediacube/MediaCubeService.java | 29 ++- .../ws/mediacube/MediaCubeAPIWSSocket.java | 59 +++-- 43 files changed, 1052 insertions(+), 117 deletions(-) create mode 100644 client/Maestro/Resources/ic_playlist_add_black_24dp.png create mode 100644 client/Maestro/RestoreMedia.Designer.cs create mode 100644 client/Maestro/RestoreMedia.cs create mode 100644 client/Maestro/RestoreMedia.resx create mode 100644 client/MaestroShared/Commons/ShortGuid.cs create mode 100644 client/MaestroShared/Resources/baseline_playlist_play_black_18dp.png create mode 100644 client/MaestroShared/Resources/ic_play_for_work_black_18dp.png create mode 100644 client/MaestroShared/Resources/ic_play_for_work_black_24dp.png create mode 100644 client/MaestroShared/Resources/ic_playlist_add_black_18dp.png create mode 100644 client/MediaCubeClient/MediaCubeJsonConvert.cs create mode 100644 server/user.jobengine.executors/src/user/jobengine/server/steps/TSMSystemRestoreStep.java diff --git a/client/DxPlay/PlayerForm.Designer.cs b/client/DxPlay/PlayerForm.Designer.cs index f96aea3d..fe8e5f25 100644 --- a/client/DxPlay/PlayerForm.Designer.cs +++ b/client/DxPlay/PlayerForm.Designer.cs @@ -185,7 +185,7 @@ namespace DxPlay { this.tpSegments.Location = new System.Drawing.Point(4, 4); this.tpSegments.Name = "tpSegments"; this.tpSegments.Padding = new System.Windows.Forms.Padding(3); - this.tpSegments.Size = new System.Drawing.Size(263, 304); + this.tpSegments.Size = new System.Drawing.Size(192, 30); this.tpSegments.TabIndex = 1; this.tpSegments.Text = "Segments"; this.tpSegments.UseVisualStyleBackColor = true; @@ -215,7 +215,7 @@ namespace DxPlay { this.dgSegments.Name = "dgSegments"; this.dgSegments.RowHeadersVisible = false; this.dgSegments.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; - this.dgSegments.Size = new System.Drawing.Size(257, 273); + this.dgSegments.Size = new System.Drawing.Size(186, 0); this.dgSegments.TabIndex = 1; this.dgSegments.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgSegments_CellContentClick); this.dgSegments.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgSegments_CellMouseDoubleClick); @@ -237,7 +237,7 @@ namespace DxPlay { this.segmentActions.Location = new System.Drawing.Point(3, 3); this.segmentActions.Name = "segmentActions"; this.segmentActions.RenderMode = System.Windows.Forms.ToolStripRenderMode.System; - this.segmentActions.Size = new System.Drawing.Size(257, 25); + this.segmentActions.Size = new System.Drawing.Size(186, 25); this.segmentActions.TabIndex = 0; this.segmentActions.Text = "toolStrip1"; // diff --git a/client/DxPlay/PlayerForm.resx b/client/DxPlay/PlayerForm.resx index 3a82e29c..21ddb0c4 100644 --- a/client/DxPlay/PlayerForm.resx +++ b/client/DxPlay/PlayerForm.resx @@ -173,7 +173,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABo - CAAAAk1TRnQBSQFMAgEBAgEAAZgBAQGYAQEBGAEAARgBAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + CAAAAk1TRnQBSQFMAgEBAgEAAaABAQGgAQEBGAEAARgBAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABYAMAARgDAAEBAQABCAYAAQkYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git a/client/Maestro/Configuration/configuration - Copy.json b/client/Maestro/Configuration/configuration - Copy.json index 8a54c54b..188c8a81 100644 --- a/client/Maestro/Configuration/configuration - Copy.json +++ b/client/Maestro/Configuration/configuration - Copy.json @@ -1,6 +1,6 @@ { "title": "Development", - "active": true, + "active": false, "startInTray": false, "enableCustomMetadataId": true, "filter": "avi", @@ -10,7 +10,7 @@ "$type": "NEXIOSource", "hideEmpty": true, "local": { - "address": "ws://localhost:8888/services/nexio" + "address": "ws://10.10.1.27:88/services/nexio" }, "remote": { "address": "ftp://10.10.1.55:2098", @@ -23,7 +23,7 @@ "$type": "OctopusMetadata", "server": { "address": "http://10.10.1.27/services/rest/octopus", - "timeout": 1000 + "timeout": 3000 } }, { diff --git a/client/Maestro/Configuration/configuration.json b/client/Maestro/Configuration/configuration.json index 325033a4..5c0e1a05 100644 --- a/client/Maestro/Configuration/configuration.json +++ b/client/Maestro/Configuration/configuration.json @@ -1,16 +1,25 @@ { "title": "Development", - "active": false, + "active": true, "startInTray": false, "enableCustomMetadataId": true, "filter": "avi", "player": { + "enabled": true, + "autoStart": false, + "segmentEditor": true }, "source": { "$type": "UNCSource", "filter": "avi,wav,mxf", "local": { - "address": "file://c:\\_video", + "address": "file://10.10.1.105/BRAAVOS/TESZT/TC", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 + }, + "remote": { + "address": "ftp://10.10.1.105/TESZT/TC", "userName": "mediacube", "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 @@ -20,8 +29,8 @@ { "$type": "OctopusMetadata", "server": { - "address": "http://localhost:8888/services/rest/octopus", - "timeout": 1000 + "address": "http://10.10.1.27/services/rest/octopus", + "timeout": 3000 } }, { @@ -31,19 +40,49 @@ "userName": "MAM", "password": "7RKZYBzumKjL40SJwuwiFCvX57xuCN8zay6OttUm2wbrgImyYZBHyZTUUYrXX31Ge2Uwew07HYsqh2uzdJeDBDwcVntxaHg3nIpv9Dyq/odVoiC4tUF/K+lgvKWANcrZ", "timeout": 1000 - } + }, + "version": 2 }, { "$type": "MediaCubeMetadata", "server": { - "address": "http://10.10.1.27/services/rest/jobengine", + "address": "http://localhost:8888/services/rest/jobengine", "userName": "mediacube", "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 - } + }, + "wsserver": { + "address": "ws://localhost:8888/services/wsapi", + "timeout": 1000 + }, + "jobTemplate": "retrieve-material.xml", + "archiveFolder": "file://10.10.1.100/BRAAVOS/ARCHIVE", + "restoreFolder": "file://10.10.1.100/BRAAVOS/ARCHIVE_RESTORE", + "restoreNamePattern": "%s_%GUID%", + "serverRestoreFolder": "/mnt/ISILON/RESTORE", + "killDateDays": 1 } ], "targets": [ + { + "label": "Adáskész", + "processor": "FXPTargetProcessor", + "outputFormat": "%ID%", + "killDateDays": 5, + "saveSegments": false, + "tag": "Adáskész", + "disableFileVersioning": true, + "enableOverride": false, + "saveMorpheusMetadata": true, + "pathMorpheusMetadata": "/TESZT/TC/CHECK/Input", + "deviceIdMorpheus": "ISILON", + "remote": { + "address": "ftp://10.10.1.105/TESZT/TC/CHECK", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 + } + }, { "label": "Teszt", "processor": "FTPTargetProcessor", @@ -52,11 +91,27 @@ "killDateDays": 7, "saveArchiveMetadata": false, "remote": { - "address": "ftp://isilon.intra.echotv.hu/TESZT/CHECK", + "address": "ftp://10.10.1.105/TESZT/CHECK", + "userName": "mediacube", + "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", + "timeout": 1000 + } + }, + { + "label": "Napi megtekintőbe", + "processor": "FTPTargetProcessor", + "outputFormat": "%ID%-%TEXT%", + "tag": "Online", + "disableFileVersioning": true, + "killDateDays": 2, + "saveArchiveMetadata": false, + "remote": { + "address": "ftp://10.10.1.105/TESZT/CHECK", "userName": "mediacube", "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy", "timeout": 1000 } } + ] } diff --git a/client/Maestro/Maestro.csproj b/client/Maestro/Maestro.csproj index c2f30eae..6b80905e 100644 --- a/client/Maestro/Maestro.csproj +++ b/client/Maestro/Maestro.csproj @@ -118,6 +118,7 @@ x64 prompt MinimumRecommendedRules.ruleset + true @@ -212,6 +213,12 @@ Component + + Form + + + RestoreMedia.cs + Form @@ -265,6 +272,9 @@ Resources.resx True + + RestoreMedia.cs + Splash.cs Designer @@ -378,6 +388,8 @@ + + diff --git a/client/Maestro/MaestroForm.Designer.cs b/client/Maestro/MaestroForm.Designer.cs index 458e2251..dc76d91f 100644 --- a/client/Maestro/MaestroForm.Designer.cs +++ b/client/Maestro/MaestroForm.Designer.cs @@ -63,6 +63,7 @@ namespace Maestro { this.trafficIDSelector = new TrafficClient.TrafficIDSelector(); this.pMetadataDisplay = new System.Windows.Forms.TableLayoutPanel(); this.tsMetadata = new System.Windows.Forms.ToolStrip(); + this.btnRedefineSegments = new System.Windows.Forms.ToolStripButton(); this.btnEditMetadata = new System.Windows.Forms.ToolStripButton(); this.btnDefineSegments = new System.Windows.Forms.ToolStripButton(); this.btnLookupMetadata = new System.Windows.Forms.Button(); @@ -545,6 +546,7 @@ namespace Maestro { this.pMetadataDisplay.SetColumnSpan(this.tsMetadata, 2); this.tsMetadata.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; this.tsMetadata.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.btnRedefineSegments, this.btnEditMetadata, this.btnDefineSegments}); this.tsMetadata.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.Flow; @@ -555,6 +557,19 @@ namespace Maestro { this.tsMetadata.Size = new System.Drawing.Size(330, 31); this.tsMetadata.TabIndex = 17; // + // btnRedefineSegments + // + this.btnRedefineSegments.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.btnRedefineSegments.Image = global::Maestro.Properties.Resources.ic_playlist_add_black_24dp; + this.btnRedefineSegments.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; + this.btnRedefineSegments.ImageTransparentColor = System.Drawing.Color.Magenta; + this.btnRedefineSegments.Name = "btnRedefineSegments"; + this.btnRedefineSegments.Size = new System.Drawing.Size(28, 28); + this.btnRedefineSegments.Text = "toolStripButton3"; + this.btnRedefineSegments.ToolTipText = "Újraszegmentálás "; + this.btnRedefineSegments.Visible = false; + this.btnRedefineSegments.Click += new System.EventHandler(this.OnRedefineSegments); + // // btnEditMetadata // this.btnEditMetadata.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; @@ -975,7 +990,7 @@ namespace Maestro { this.btnSweepJobList.ImageTransparentColor = System.Drawing.Color.Magenta; this.btnSweepJobList.Name = "btnSweepJobList"; this.btnSweepJobList.Size = new System.Drawing.Size(23, 22); - this.btnSweepJobList.Text = "toolStripButton2"; + this.btnSweepJobList.Text = "Takarítás"; this.btnSweepJobList.Click += new System.EventHandler(this.OnSweepJobList); // // toolStripSeparator3 @@ -1246,6 +1261,7 @@ namespace Maestro { private DataGridViewTextBoxColumn columnKillDate; private DataGridViewTextBoxColumn columnMessage; private ToolStripLabel lSelectionCounts; + private ToolStripButton btnRedefineSegments; } } diff --git a/client/Maestro/MaestroForm.Metadata.cs b/client/Maestro/MaestroForm.Metadata.cs index c5b8876d..11cc4e60 100644 --- a/client/Maestro/MaestroForm.Metadata.cs +++ b/client/Maestro/MaestroForm.Metadata.cs @@ -9,6 +9,7 @@ using OctopusClient; using System; using System.Collections.Generic; using System.ComponentModel; +using System.IO; using System.Linq; using System.Windows.Forms; using TrafficClient; @@ -16,6 +17,7 @@ using TrafficClient; namespace Maestro { public partial class MaestroForm { private const string ARCHIVEID_PREFIX = "MC-"; + private const string MXFEXT = ".MXF"; private MetadataInfo selectedMetadata; private BindingList movieSegments; @@ -378,6 +380,7 @@ namespace Maestro { } private void OnTrafficIDSelected(string id, int variantID, string text) { + btnRedefineSegments.Visible = false; if (id == null) { ArchiveMetadata = null; SelectedMetadata = null; @@ -391,6 +394,48 @@ namespace Maestro { MetadataText = text, VariantID = variantID }; + + CheckIfRedefineSegments(); + } + + private void CheckIfRedefineSegments() { + bool enableRedefine = false; + string mediaHouseId = SelectedMetadata.ID + MXFEXT; + MediaCubeMetadata metadata = MetadataProvider.Get(Configuration.Metadatas); + if (metadata != null && metadata.ArchiveFolder != null) { + string location = Path.Combine(metadata.ArchiveFolder.LocalPath, mediaHouseId); + enableRedefine = File.Exists(location); + if (enableRedefine) + SelectedMetadata.RedefineSegmentsFile = location; + } + + if (!enableRedefine && mediaCubeApi != null) { + Media media = mediaCubeApi.GetMediaByHouseId(mediaHouseId); + if (media != null) { + enableRedefine = true; + SelectedMetadata.RedefineSegmentsFile = Path.Combine(metadata.RestoreFolder.LocalPath, mediaHouseId); + SelectedMetadata.RedefineWithRestore = true; + SelectedMetadata.RedefineMedia = media; + } + } + + if (enableRedefine) { + btnRedefineSegments.Visible = true; + } + } + + private void OnRedefineSegments(object sender, EventArgs e) { + if (SelectedMetadata == null) + return; + MediaCubeMetadata mediaCubeMetadata = MetadataProvider.Get(Configuration.Metadatas); + if (SelectedMetadata.RedefineWithRestore) { + RestoreMedia restoreForm = new RestoreMedia(SelectedMetadata, mediaCubeMetadata, errorMessageBus); + if (restoreForm.ShowDialog(this) == DialogResult.Cancel) + return; + } + + + } private static string GetMetadataTypeTooltip(MetadataType? metadataType) { diff --git a/client/Maestro/MaestroForm.cs b/client/Maestro/MaestroForm.cs index d9eb9be9..160eabac 100644 --- a/client/Maestro/MaestroForm.cs +++ b/client/Maestro/MaestroForm.cs @@ -82,6 +82,7 @@ namespace Maestro { errorMessageBus.Subscribe(OnMessage); errorMessageBus.Subscribe(OnMessage); errorMessageBus.Subscribe(OnMessage); + errorMessageBus.Subscribe(OnMessage); if (Configuration.MetadataOnly) { scOperations.Panel1Collapsed = true; @@ -331,5 +332,7 @@ namespace Maestro { bindingSourceJobs.DataSource = jobs; UpdateJobCounts(); } + + } } diff --git a/client/Maestro/MaestroForm.resx b/client/Maestro/MaestroForm.resx index 106019a8..901e11c9 100644 --- a/client/Maestro/MaestroForm.resx +++ b/client/Maestro/MaestroForm.resx @@ -128,7 +128,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAS - CAAAAk1TRnQBSQFMAgEBAgEAATABAgEwAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + CAAAAk1TRnQBSQFMAgEBAgEAAXABAgFwAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git a/client/Maestro/Metadata/MetaDataInfo.cs b/client/Maestro/Metadata/MetaDataInfo.cs index 4afb7061..efb2bc89 100644 --- a/client/Maestro/Metadata/MetaDataInfo.cs +++ b/client/Maestro/Metadata/MetaDataInfo.cs @@ -1,4 +1,5 @@ using MaestroShared.Metadata; +using MaestroShared.Model; namespace Maestro.Metadata { public class MetadataInfo { @@ -6,6 +7,8 @@ namespace Maestro.Metadata { public string MetadataText { get; set; } public MetadataType Kind { get; set; } public int VariantID { get; set; } - + public string RedefineSegmentsFile { get; set; } + public bool RedefineWithRestore { get; set; } + public Media RedefineMedia { get; set; } } } diff --git a/client/Maestro/Program.cs b/client/Maestro/Program.cs index 907f2637..cc2f29b3 100644 --- a/client/Maestro/Program.cs +++ b/client/Maestro/Program.cs @@ -29,25 +29,6 @@ namespace Maestro { [STAThread] [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)] static void Main() { - /* - IMessageBus mb = new MessageBus(); - mb.Subscribe(m => { - if (m.Finished) { - if (!string.IsNullOrEmpty(m.Content)) - Debug.WriteLine("Error " + m.Content); - Debug.WriteLine("Finished"); - } else - Debug.WriteLine("Progress " + m.Data.As("progress")); - }); - MediaCubeWSApi c = new MediaCubeWSApi("ws://localhost:8888/services/wsapi", mb); - JObject data = new JObject(); - data.Add("itemID", JToken.FromObject(0)); - data.Add("resultID", JToken.FromObject(0)); - c.SubmitJob("fake.xml", data); - Thread.Sleep(1000000); - return; - */ - string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString(); string userName = WindowsIdentity.GetCurrent().Name; string mutexId = string.Format("Global\\{0}-{1}", appGuid, userName.Replace('\\', '-')); diff --git a/client/Maestro/Properties/Resources.Designer.cs b/client/Maestro/Properties/Resources.Designer.cs index 180d0c30..765cc214 100644 --- a/client/Maestro/Properties/Resources.Designer.cs +++ b/client/Maestro/Properties/Resources.Designer.cs @@ -120,6 +120,16 @@ namespace Maestro.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ic_playlist_add_black_24dp { + get { + object obj = ResourceManager.GetObject("ic_playlist_add_black_24dp", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/client/Maestro/Properties/Resources.resx b/client/Maestro/Properties/Resources.resx index 2775772d..f2783a5a 100644 --- a/client/Maestro/Properties/Resources.resx +++ b/client/Maestro/Properties/Resources.resx @@ -175,4 +175,7 @@ ..\Resources\ic_cached_black_18dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\ic_playlist_add_black_24dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/client/Maestro/Resources/ic_playlist_add_black_24dp.png b/client/Maestro/Resources/ic_playlist_add_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..d7a7514a84072ca393b32a30aa1427ab8ed37bb5 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4i*Lm2CurW#S9D#+MX_sAr*|t3Q|2y|8FRs zlww;c?_jc1ii7!8=7D!2J|6qnPW^SL=RM5Bz+iqmd2WuajST|>1B0ilpUXO@geCx@ CnH#DA literal 0 HcmV?d00001 diff --git a/client/Maestro/RestoreMedia.Designer.cs b/client/Maestro/RestoreMedia.Designer.cs new file mode 100644 index 00000000..537d75e5 --- /dev/null +++ b/client/Maestro/RestoreMedia.Designer.cs @@ -0,0 +1,101 @@ +namespace Maestro { + partial class RestoreMedia { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() { + this.progressBar = new System.Windows.Forms.ProgressBar(); + this.btnCancel = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.lFileName = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // progressBar + // + this.progressBar.Location = new System.Drawing.Point(12, 12); + this.progressBar.Name = "progressBar"; + this.progressBar.Size = new System.Drawing.Size(449, 23); + this.progressBar.TabIndex = 0; + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(386, 47); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(75, 23); + this.btnCancel.TabIndex = 1; + this.btnCancel.Text = "Mégsem"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 52); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(26, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Fájl:"; + // + // lFileName + // + this.lFileName.AutoSize = true; + this.lFileName.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238))); + this.lFileName.Location = new System.Drawing.Point(44, 52); + this.lFileName.Name = "lFileName"; + this.lFileName.Size = new System.Drawing.Size(0, 13); + this.lFileName.TabIndex = 3; + // + // RestoreMedia + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(473, 82); + this.ControlBox = false; + this.Controls.Add(this.lFileName); + this.Controls.Add(this.label1); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.progressBar); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "RestoreMedia"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Anyag visszatöltése"; + this.TopMost = true; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.RestoreMedia_FormClosing); + this.Shown += new System.EventHandler(this.RestoreMedia_Shown); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ProgressBar progressBar; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label lFileName; + } +} \ No newline at end of file diff --git a/client/Maestro/RestoreMedia.cs b/client/Maestro/RestoreMedia.cs new file mode 100644 index 00000000..08ac6228 --- /dev/null +++ b/client/Maestro/RestoreMedia.cs @@ -0,0 +1,65 @@ +using LinkDotNet.MessageHandling; +using LinkDotNet.MessageHandling.Contracts; +using Maestro.Metadata; +using MaestroShared.Commons; +using MaestroShared.Configuration; +using MediaCubeClient; +using Newtonsoft.Json.Linq; +using NLog; +using System; +using System.Windows.Forms; + +namespace Maestro { + public partial class RestoreMedia : Form { + private static readonly Logger logger = LogManager.GetCurrentClassLogger(); + private readonly MetadataInfo selectedMetadata; + private readonly MediaCubeMetadata mediaCubeMetadata; + private readonly IMessageBus systemBus; + private readonly IMessageBus messageBus; + private MediaCubeWSApi api; + + public RestoreMedia(MetadataInfo selectedMetadata, MediaCubeMetadata mediaCubeMetadata, IMessageBus systemBus) { + InitializeComponent(); + lFileName.Text = selectedMetadata.ID; + this.selectedMetadata = selectedMetadata; + this.mediaCubeMetadata = mediaCubeMetadata; + this.systemBus = systemBus; + messageBus = new MessageBus(); + } + + private void RestoreMedia_Shown(object sender, EventArgs e) { + if (mediaCubeMetadata?.WSServer?.Address == null) { + MsgBox.Error("Hiányos a konfigurációs állomány. Nem található a MediaCubeMetadata.WSServer.Address beállítása."); + DialogResult = DialogResult.Cancel; + Close(); + return; + } + messageBus.Subscribe(m => { + BeginInvoke((Action)(() => { + if (m.Finished) { + if (m.Content?.Length > 0) + systemBus.Send(m); + Close(); + } else + progressBar.Value = m.Data.As("progress"); + })); + }); + api = new MediaCubeWSApi(mediaCubeMetadata.WSServer, messageBus); + string pattern = PatternNameMaker.Get(mediaCubeMetadata.RestoreNamePattern, null, null, null, null, null, null); + JObject data = new JObject { + { "targetPath", mediaCubeMetadata.ServerRestoreFolder }, + { "targetNamePattern", pattern }, + { "successRecipient", null }, + { "killDateDays", mediaCubeMetadata.KillDateDays }, + { "mediaCubeMedia", selectedMetadata.RedefineMedia.Serialize() } + }; + logger.Info("Submitting {0}", data.ToString()); + api.SubmitJob(mediaCubeMetadata.JobTemplate, data); + } + + private void RestoreMedia_FormClosing(object sender, FormClosingEventArgs e) { + if (api != null) + api.Close(); + } + } +} diff --git a/client/Maestro/RestoreMedia.resx b/client/Maestro/RestoreMedia.resx new file mode 100644 index 00000000..29dcb1b3 --- /dev/null +++ b/client/Maestro/RestoreMedia.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/client/Maestro/Sources/NexioRESTSource.cs b/client/Maestro/Sources/NexioRESTSource.cs index d72bad83..6dbb927f 100644 --- a/client/Maestro/Sources/NexioRESTSource.cs +++ b/client/Maestro/Sources/NexioRESTSource.cs @@ -9,6 +9,7 @@ using NLog; using System; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics; using System.Drawing; using System.Linq; using System.Windows.Forms; @@ -236,6 +237,8 @@ namespace Maestro.Sources { item.Agency = token[EXTAGENCY]?.ToString(); DateTime? created = token.Value(RECORDDATE); item.Created = created ?? DateTime.MinValue; + if (item.Created == DateTime.MinValue) + Debug.WriteLine(""); DateTime? modified = token.Value(MODIFIED); item.Modified = modified ?? DateTime.MinValue; item.Frames = token.Value(DURATION); diff --git a/client/MaestroShared/Commons/PatternNameMaker.cs b/client/MaestroShared/Commons/PatternNameMaker.cs index 859e1b45..6cdeaa35 100644 --- a/client/MaestroShared/Commons/PatternNameMaker.cs +++ b/client/MaestroShared/Commons/PatternNameMaker.cs @@ -13,6 +13,7 @@ namespace MaestroShared.Commons { private const string PATTERN_COMPUTERNAME = "%COMPUTERNAME%"; private const string PATTERN_ID = "%ID%"; private const string PATTERN_IDROOT = "%IDROOT%"; + private const string PATTERN_GUID = "%GUID%"; private const string PATTERN_SOURCENAME = "%SOURCENAME%"; private const string PATTERN_SOURCESTARTID = "%SOURCESTARTID%"; private const string PATTERN_TIMESTAMP = "%TIMESTAMP%"; @@ -41,11 +42,12 @@ namespace MaestroShared.Commons { } static public string Get(string pattern, string id, string inputName, string outputName, string userName, string text, DateTime? storedDateTime = null) { - string idRoot = id.Contains(UNDERSCORE) ? id.Split(UNDERSCORE[0])[0] : id; + string idRoot = id != null && id.Contains(UNDERSCORE) ? id.Split(UNDERSCORE[0])[0] : id; DateTime dt = storedDateTime == null ? DateTime.Now : (DateTime)storedDateTime; string result = pattern .Replace(PATTERN_ID, id) .Replace(PATTERN_IDROOT, idRoot) + .Replace(PATTERN_GUID, ((ShortGuid)Guid.NewGuid()).ToString()) .Replace(PATTERN_TIMESTAMP, dt.ToString(DATETIME_FORMAT, CultureInfo.InvariantCulture)) .Replace(PATTERN_DATESTAMP, dt.ToString(DATE_FORMAT_NODOTS, CultureInfo.InvariantCulture)); @@ -71,7 +73,7 @@ namespace MaestroShared.Commons { if (!String.IsNullOrEmpty(text)) result = result.Replace(PATTERN_TEXT, Normalize(text)); - return result; + return result; } diff --git a/client/MaestroShared/Commons/ShortGuid.cs b/client/MaestroShared/Commons/ShortGuid.cs new file mode 100644 index 00000000..dc2da098 --- /dev/null +++ b/client/MaestroShared/Commons/ShortGuid.cs @@ -0,0 +1,244 @@ +using System; + +namespace MaestroShared.Commons { + /// + /// Represents a globally unique identifier (GUID) with a + /// shorter string value. Sguid + /// + public struct ShortGuid { + #region Static + + /// + /// A read-only instance of the ShortGuid class whose value + /// is guaranteed to be all zeroes. + /// + public static readonly ShortGuid Empty = new ShortGuid(Guid.Empty); + + #endregion + + #region Fields + + Guid _guid; + string _value; + + #endregion + + #region Contructors + + /// + /// Creates a ShortGuid from a base64 encoded string + /// + /// The encoded guid as a + /// base64 string + public ShortGuid(string value) { + _value = value; + _guid = Decode(value); + } + + /// + /// Creates a ShortGuid from a Guid + /// + /// The Guid to encode + public ShortGuid(Guid guid) { + _value = Encode(guid); + _guid = guid; + } + + #endregion + + #region Properties + + /// + /// Gets/sets the underlying Guid + /// + public Guid Guid { + get { return _guid; } + set { + if (value != _guid) { + _guid = value; + _value = Encode(value); + } + } + } + + /// + /// Gets/sets the underlying base64 encoded string + /// + public string Value { + get { return _value; } + set { + if (value != _value) { + _value = value; + _guid = Decode(value); + } + } + } + + #endregion + + #region ToString + + /// + /// Returns the base64 encoded guid as a string + /// + /// + public override string ToString() { + return _value; + } + + #endregion + + #region Equals + + /// + /// Returns a value indicating whether this instance and a + /// specified Object represent the same type and value. + /// + /// The object to compare + /// + public override bool Equals(object obj) { + if (obj is ShortGuid) + return _guid.Equals(((ShortGuid)obj)._guid); + if (obj is Guid) + return _guid.Equals((Guid)obj); + if (obj is string) + return _guid.Equals(((ShortGuid)obj)._guid); + return false; + } + + #endregion + + #region GetHashCode + + /// + /// Returns the HashCode for underlying Guid. + /// + /// + public override int GetHashCode() { + return _guid.GetHashCode(); + } + + #endregion + + #region NewGuid + + /// + /// Initialises a new instance of the ShortGuid class + /// + /// + public static ShortGuid NewGuid() { + return new ShortGuid(Guid.NewGuid()); + } + + #endregion + + #region Encode + + /// + /// Creates a new instance of a Guid using the string value, + /// then returns the base64 encoded version of the Guid. + /// + /// An actual Guid string (i.e. not a ShortGuid) + /// + public static string Encode(string value) { + Guid guid = new Guid(value); + return Encode(guid); + } + + /// + /// Encodes the given Guid as a base64 string that is 22 + /// characters long. + /// + /// The Guid to encode + /// + public static string Encode(Guid guid) { + string encoded = Convert.ToBase64String(guid.ToByteArray()); + encoded = encoded + .Replace("/", "_") + .Replace("+", "-"); + return encoded.Substring(0, 22); + } + + #endregion + + #region Decode + + /// + /// Decodes the given base64 string + /// + /// The base64 encoded string of a Guid + /// A new Guid + public static Guid Decode(string value) { + value = value + .Replace("_", "/") + .Replace("-", "+"); + byte[] buffer = Convert.FromBase64String(value + "=="); + return new Guid(buffer); + } + + #endregion + + #region Operators + + /// + /// Determines if both ShortGuids have the same underlying + /// Guid value. + /// + /// + /// + /// + public static bool operator ==(ShortGuid x, ShortGuid y) { + if ((object)x == null) return (object)y == null; + return x._guid == y._guid; + } + + /// + /// Determines if both ShortGuids do not have the + /// same underlying Guid value. + /// + /// + /// + /// + public static bool operator !=(ShortGuid x, ShortGuid y) { + return !(x == y); + } + + /// + /// Implicitly converts the ShortGuid to it's string equivilent + /// + /// + /// + public static implicit operator string(ShortGuid shortGuid) { + return shortGuid._value; + } + + /// + /// Implicitly converts the ShortGuid to it's Guid equivilent + /// + /// + /// + public static implicit operator Guid(ShortGuid shortGuid) { + return shortGuid._guid; + } + + /// + /// Implicitly converts the string to a ShortGuid + /// + /// + /// + public static implicit operator ShortGuid(string shortGuid) { + return new ShortGuid(shortGuid); + } + + /// + /// Implicitly converts the Guid to a ShortGuid + /// + /// + /// + public static implicit operator ShortGuid(Guid guid) { + return new ShortGuid(guid); + } + + #endregion + } +} diff --git a/client/MaestroShared/Configuration/ConfigurationInfo.cs b/client/MaestroShared/Configuration/ConfigurationInfo.cs index 8427af26..1a31301a 100644 --- a/client/MaestroShared/Configuration/ConfigurationInfo.cs +++ b/client/MaestroShared/Configuration/ConfigurationInfo.cs @@ -190,12 +190,19 @@ namespace MaestroShared.Configuration { public class TrafficMetadata : MetadataProvider { public ProjectSettings ProjectSettings { get; set; } public string FunctionName { get; set; } - + public int Version { get; set; } } public class MediaCubeMetadata : MetadataProvider { public string MetadataTitleFormat { get; set; } public string MetadataIDFormat { get; set; } + public Connection WSServer { get; set; } + public string JobTemplate { get; set; } + public int KillDateDays { get; set; } + public Uri ArchiveFolder { get; set; } + public Uri RestoreFolder { get; set; } + public string RestoreNamePattern { get; set; } + public string ServerRestoreFolder { get; set; } } public class UISettings { diff --git a/client/MaestroShared/MaestroShared.csproj b/client/MaestroShared/MaestroShared.csproj index a2b69961..2ce64179 100644 --- a/client/MaestroShared/MaestroShared.csproj +++ b/client/MaestroShared/MaestroShared.csproj @@ -50,6 +50,7 @@ x64 prompt MinimumRecommendedRules.ruleset + true @@ -128,6 +129,7 @@ + @@ -175,9 +177,6 @@ - - - @@ -226,5 +225,20 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/MaestroShared/Model/Model.cs b/client/MaestroShared/Model/Model.cs index 9d0dee8a..695869ed 100644 --- a/client/MaestroShared/Model/Model.cs +++ b/client/MaestroShared/Model/Model.cs @@ -20,4 +20,16 @@ namespace MaestroShared.Model { public long id; public DateTime? created; } + + public class Media { + public long id; + public DateTime archived; + public DateTime created; + public string description; + public string houseId; + public long itemId; + public long length; + public string title; + } + } diff --git a/client/MaestroShared/Resources/baseline_playlist_play_black_18dp.png b/client/MaestroShared/Resources/baseline_playlist_play_black_18dp.png new file mode 100644 index 0000000000000000000000000000000000000000..6c3d0a336a56f731dddeb64e68bdbf136f185149 GIT binary patch literal 157 zcmV;O0Al}%P)gt`Qw3(4D$dq0`hE0s*#1$bujm%*O!mwEd0vByp5aa?pEX@X8z{udKGD zjx?yGGfk;w40_trKz!~wb+rHQNIhlHO8G)t8q=@pD+9Qn2T0Nd5kIjJ<5Q|~00000 LNkvXXu0mjf28=tC literal 0 HcmV?d00001 diff --git a/client/MaestroShared/Resources/ic_play_for_work_black_18dp.png b/client/MaestroShared/Resources/ic_play_for_work_black_18dp.png new file mode 100644 index 0000000000000000000000000000000000000000..daeb0b9a71367a1c6efbb61a1e5a37b0075b282d GIT binary patch literal 172 zcmV;d08{^oP)5YWOee>!63L0q^?2)bP=v7@Kj@nVsDwH8cImO8>IdpszdiH@&6J zmZ)mghL3CCSLPHnaZTG+g`F32BDQHOR*{Ssy4*R@M|{twE^o*wxv|ijRmKN~1g;va a((wRDIwHa>fAFCI0000}8^6S^$eVa(m4-h;zY}ockxQt2I?>C72+=6= zFARqC*n2`o*}_8K15j&^7Q}!002ovPDHLkV1kO)L;wH) literal 0 HcmV?d00001 diff --git a/client/MaestroShared/Resources/ic_playlist_add_black_18dp.png b/client/MaestroShared/Resources/ic_playlist_add_black_18dp.png new file mode 100644 index 0000000000000000000000000000000000000000..241f42ac95928faefa35f0444c3cc466efd9c3e4 GIT binary patch literal 115 zcmeAS@N?(olHy`uVBq!ia0y~yU=RXf4i*LmhCj#M?l3SgSb4fQhEy;nODs9ixR8<8 zDq#g9*FX1W-YZ-9T!gmuZCE;^OU6Jai(z&h!_DQqE5s%~2yQXCDsoYtfk9f`LSE(l S)^7|93=E#GelF{r5}E+T1|oz2 literal 0 HcmV?d00001 diff --git a/client/MaestroShared/Targets/FTPTargetProcessor.cs b/client/MaestroShared/Targets/FTPTargetProcessor.cs index 868c472e..835e2cac 100644 --- a/client/MaestroShared/Targets/FTPTargetProcessor.cs +++ b/client/MaestroShared/Targets/FTPTargetProcessor.cs @@ -150,13 +150,14 @@ namespace MaestroShared.Targets { } protected FtpClient CreateClient(Connection connection) { + Uri address = connection.Address; string addr = address.Host; IPHostEntry hostEntry = Dns.GetHostEntry(addr); if (hostEntry != null && hostEntry.AddressList.Length > 0) addr = hostEntry.AddressList[0].ToString(); - + logger.Info("Remote address is {0}", addr); FtpClient result = new FtpClient() { Host = addr, Port = address.Port, diff --git a/client/MediaCubeClient/MediaCubeApi.cs b/client/MediaCubeClient/MediaCubeApi.cs index de543302..952532ed 100644 --- a/client/MediaCubeClient/MediaCubeApi.cs +++ b/client/MediaCubeClient/MediaCubeApi.cs @@ -1,15 +1,14 @@ using LinkDotNet.MessageHandling.Contracts; using MaestroShared.Interfaces; using MaestroShared.MessageBus; +using MaestroShared.Model; using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Linq; using NLog; using RestSharp; using RestSharp.Authenticators; -using System; using System.Diagnostics; using System.Net; -using System.Runtime.Serialization; namespace MediaCubeClient { public class MediaCubeMessage : MaestroMessage { @@ -18,14 +17,11 @@ namespace MediaCubeClient { } public class MediaCubeApi : IMediaCubeApi { - private const string DATEFORMAT = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK"; private static Logger logger = LogManager.GetCurrentClassLogger(); private RestClient client; - private JsonSerializerSettings serializerSettings; private string user; private string pwd; private IMessageBus messageBus; - private object template; public MediaCubeApi(string address, string user, string pwd, int timeout, IMessageBus messageBus) { this.user = user; @@ -35,16 +31,11 @@ namespace MediaCubeClient { Authenticator = new HttpBasicAuthenticator(user, pwd), Timeout = timeout }; - serializerSettings = new JsonSerializerSettings { - TypeNameHandling = TypeNameHandling.Objects, - SerializationBinder = new TypeNameSerializationBinder(), - DateFormatString = DATEFORMAT - }; } public T Create(object data) { var request = new RestRequest("create", Method.POST); - string body = JsonConvert.SerializeObject(data, serializerSettings); + string body = data.Serialize(); //Debug.WriteLine(body); request.AddParameter("application/json", body, ParameterType.RequestBody); var response = client.Execute(request); @@ -67,6 +58,20 @@ namespace MediaCubeClient { return; } + public Media GetMediaByHouseId(string mediaHouseId) { + var request = new RestRequest("media", Method.GET); + request.AddQueryParameter("mediaHouseId", mediaHouseId); + var response = client.Execute(request); + if (response.StatusCode != HttpStatusCode.OK || response.Content.Length < 1) { + messageBus.Send(new MediaCubeMessage("Hiba a lekérdezésben. A rendszer üzenete: " + response.ErrorMessage)); + return null; + } + JObject media = JObject.Parse(response.Content); + if (media != null) + return media.Deserialize(); + + return null; + } public void Item() { var request = new RestRequest("item", Method.GET); @@ -77,15 +82,3 @@ namespace MediaCubeClient { } -public class TypeNameSerializationBinder : SerializationBinder, ISerializationBinder { - - public override void BindToName(Type serializedType, out string assemblyName, out string typeName) { - assemblyName = null; - typeName = serializedType.Name; - } - - public override Type BindToType(string assemblyName, string typeName) { - string resolvedTypeName = typeName; - return Type.GetType(resolvedTypeName, true); - } -} diff --git a/client/MediaCubeClient/MediaCubeClient.csproj b/client/MediaCubeClient/MediaCubeClient.csproj index b59eb955..03a2b9e3 100644 --- a/client/MediaCubeClient/MediaCubeClient.csproj +++ b/client/MediaCubeClient/MediaCubeClient.csproj @@ -75,6 +75,7 @@ x64 prompt MinimumRecommendedRules.ruleset + true @@ -102,6 +103,7 @@ + diff --git a/client/MediaCubeClient/MediaCubeJsonConvert.cs b/client/MediaCubeClient/MediaCubeJsonConvert.cs new file mode 100644 index 00000000..c0e8f9c7 --- /dev/null +++ b/client/MediaCubeClient/MediaCubeJsonConvert.cs @@ -0,0 +1,43 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using System; +using System.Runtime.Serialization; + +namespace MediaCubeClient { + + public static class MediaCubeJsonConvert { + private const string DATEFORMAT = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK"; + private static readonly JsonSerializerSettings serializerSettings; + + static MediaCubeJsonConvert() { + serializerSettings = new JsonSerializerSettings { + TypeNameHandling = TypeNameHandling.Objects, + SerializationBinder = new TypeNameSerializationBinder(), + DateFormatString = DATEFORMAT + }; + + } + + public static string Serialize(this object data) { + return JsonConvert.SerializeObject(data, serializerSettings); + } + + public static T Deserialize(this object data) { + return JsonConvert.DeserializeObject(data.ToString(), serializerSettings); + } + } + + public class TypeNameSerializationBinder : SerializationBinder, ISerializationBinder { + + public override void BindToName(Type serializedType, out string assemblyName, out string typeName) { + assemblyName = null; + typeName = serializedType.Name; + } + + public override Type BindToType(string assemblyName, string typeName) { + string resolvedTypeName = "MaestroShared.Model." + typeName + ", MaestroShared"; + return Type.GetType(resolvedTypeName, true); + } + } + +} diff --git a/client/MediaCubeClient/MediaCubeWSApi.cs b/client/MediaCubeClient/MediaCubeWSApi.cs index bdf7be3b..08f50b07 100644 --- a/client/MediaCubeClient/MediaCubeWSApi.cs +++ b/client/MediaCubeClient/MediaCubeWSApi.cs @@ -1,4 +1,5 @@ using LinkDotNet.MessageHandling.Contracts; +using MaestroShared.Configuration; using MaestroShared.MessageBus; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -29,11 +30,13 @@ namespace MediaCubeClient { private const string DATEFORMAT = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK"; private static NLog.Logger logger = LogManager.GetCurrentClassLogger(); private JsonSerializerSettings serializerSettings; - private readonly string address; private IMessageBus messageBus; + private WebSocket ws; - public MediaCubeWSApi(string address, IMessageBus messageBus) { - this.address = address; + public MediaCubeWSApi(Connection connection, IMessageBus messageBus) { + ws = new WebSocket(connection.Address.ToString()) { + WaitTime = TimeSpan.FromMilliseconds(connection.Timeout) + }; this.messageBus = messageBus; serializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects, @@ -58,15 +61,14 @@ namespace MediaCubeClient { } */ public void SubmitJob(string template, JObject parameters) { - WebSocket ws = new WebSocket(address); ws.SslConfiguration.ServerCertificateValidationCallback = (s, c, ch, e) => { return true; }; ws.OnMessage += (s, e) => { JObject jo = JObject.Parse(e.Data); - if (true.Equals(jo.As(MediaCubeStrings.ERROR))) { + if ("SUSPENDED".Equals(jo.As(MediaCubeStrings.STATUS))) { ws.Close(); - messageBus.Send(new MediaCubeWSMessage("Hiba a MediaCube szolgáltatás használata során. A rendszer üzenete: " + jo.As(MediaCubeStrings.ERROR))); + messageBus.Send(new MediaCubeWSMessage("Hiba a MediaCube szolgáltatás használata során. Rendszerüzenet: " + jo.As(MediaCubeStrings.ERROR))); return; } if ("FINISHED".Equals(jo.As(MediaCubeStrings.STATUS))) { @@ -78,7 +80,7 @@ namespace MediaCubeClient { }; ws.OnError += (s, e) => { ws.Close(); - messageBus.Send(new MediaCubeWSMessage("Hiba a MediaCube szolgáltatás használata során. A rendszer üzenete: " + e.Message)); + messageBus.Send(new MediaCubeWSMessage("Hiba a MediaCube szolgáltatás használata során. Rendszerüzenet: " + e.Message)); }; try { @@ -92,13 +94,17 @@ namespace MediaCubeClient { data.Add(MediaCubeStrings.ACTION, JToken.FromObject(MediaCubeStrings.STARTJOB)); data.Add(MediaCubeStrings.TEMPLATE, JToken.FromObject(template)); data.Add(MediaCubeStrings.PARAMETERS, JToken.FromObject(parameters)); - ws.Send(data.ToString()); + ws.Send(data.Serialize()); } catch (Exception e) { ws.Close(); messageBus.Send(new MediaCubeWSMessage("Sikertelen MediaCube folyamatindítás.")); } } + public void Close() { + if (ws != null) + ws.Close(); + } } diff --git a/server/-configuration/run-mediacube-server-bsh.launch b/server/-configuration/run-mediacube-server-bsh.launch index 73dd62c3..b004926b 100644 --- a/server/-configuration/run-mediacube-server-bsh.launch +++ b/server/-configuration/run-mediacube-server-bsh.launch @@ -19,7 +19,7 @@ - + diff --git a/server/user.jobengine.executors/config/config.xml b/server/user.jobengine.executors/config/config.xml index 1d7487a9..e1d591d4 100644 --- a/server/user.jobengine.executors/config/config.xml +++ b/server/user.jobengine.executors/config/config.xml @@ -29,6 +29,7 @@ + diff --git a/server/user.jobengine.executors/jobtemplates/retrieve-material.xml b/server/user.jobengine.executors/jobtemplates/retrieve-material.xml index d8088ad6..1890feed 100644 --- a/server/user.jobengine.executors/jobtemplates/retrieve-material.xml +++ b/server/user.jobengine.executors/jobtemplates/retrieve-material.xml @@ -10,7 +10,7 @@ - + diff --git a/server/user.jobengine.executors/src/user/jobengine/server/steps/CleanupMountedLocationStep.java b/server/user.jobengine.executors/src/user/jobengine/server/steps/CleanupMountedLocationStep.java index 99c26650..4dbef381 100644 --- a/server/user.jobengine.executors/src/user/jobengine/server/steps/CleanupMountedLocationStep.java +++ b/server/user.jobengine.executors/src/user/jobengine/server/steps/CleanupMountedLocationStep.java @@ -141,7 +141,13 @@ public class CleanupMountedLocationStep extends JobStep implements FileVisitor

getKillDateFiles(Path filePath) { String killDateFilePattern = String.format("%s.*%s", filePath.getFileName().toString(), KILLDATEEXT); List result = new ArrayList<>(); - Path statusPath = Paths.get(filePath.getParent().toString(), STATUSFOLDER); + Path statusPath = null; + try { + statusPath = Paths.get(filePath.getParent().toString(), STATUSFOLDER); + } catch (Exception e) { + logger.catching(e); + return null; + } File statusPathFile = statusPath.toFile(); if (statusPathFile.exists() && statusPathFile.isDirectory()) { try (DirectoryStream stream = Files.newDirectoryStream(statusPath, killDateFilePattern)) { @@ -183,7 +189,7 @@ public class CleanupMountedLocationStep extends JobStep implements FileVisitor

killDateFiles = getKillDateFiles(filePath); - if (killDateFiles.size() == 0) { + if (killDateFiles == null || killDateFiles.size() == 0) { logger.warn(marker, "A {} fájlhoz nem található 'killdate' állomány.", filePath); return; } diff --git a/server/user.jobengine.executors/src/user/jobengine/server/steps/CopyForArchiveNEXIORecordingsStep.java b/server/user.jobengine.executors/src/user/jobengine/server/steps/CopyForArchiveNEXIORecordingsStep.java index 1aaa8e10..0b98ad33 100644 --- a/server/user.jobengine.executors/src/user/jobengine/server/steps/CopyForArchiveNEXIORecordingsStep.java +++ b/server/user.jobengine.executors/src/user/jobengine/server/steps/CopyForArchiveNEXIORecordingsStep.java @@ -29,6 +29,7 @@ import com.ibm.nosql.json.api.QueryBuilder; import user.commons.CalendarUtils; import user.commons.ListUtils; import user.commons.StoreUri; +import user.commons.nexio.NexioDispatcher; import user.commons.nosql.NoSQLUtils; import user.commons.octopus.IOctopusAPI; import user.commons.octopus.OctopusAPI; @@ -49,7 +50,7 @@ public class CopyForArchiveNEXIORecordingsStep extends JobStep { private static final String XML_EXT = ".xml"; private static final String DURATION = "duration"; private static final String MXFEXT = ".MXF"; - private static final String NEXIOCLIPS = "nexioclips"; + private static final String NEXIOCLIPS = NexioDispatcher.CLIP_COLLECTION_NAME; private static final String LONGNAMEID = "longnameid"; private static final String EXTAGENCY = "extagency"; private static final String RECORDDATE = "recorddate"; @@ -229,9 +230,9 @@ public class CopyForArchiveNEXIORecordingsStep extends JobStep { return null; } } - + RundownArchive item2 = null; - + try { item2 = processRundow(rundown, clipName, duration); } catch (Exception e) { @@ -240,7 +241,7 @@ public class CopyForArchiveNEXIORecordingsStep extends JobStep { e.getMessage()); return null; } - + result.setItemTitle(result.getItemTitle() + " + NAPIAKT"); StoryArchive storyArchive = result.getStoryArchives().get(0); StoryArchive storyArchive2 = item2.getStoryArchives().get(0); diff --git a/server/user.jobengine.executors/src/user/jobengine/server/steps/TSMSystemRestoreStep.java b/server/user.jobengine.executors/src/user/jobengine/server/steps/TSMSystemRestoreStep.java new file mode 100644 index 00000000..314cd8e8 --- /dev/null +++ b/server/user.jobengine.executors/src/user/jobengine/server/steps/TSMSystemRestoreStep.java @@ -0,0 +1,143 @@ +package user.jobengine.server.steps; + +import java.io.IOException; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.message.Message; + +import user.commons.LogUtils; +import user.commons.MediaCubeMarker; +import user.commons.RemoteFile; +import user.commons.StoreUri; +import user.commons.remotestore.IProgressEventListener; +import user.commons.remotestore.IStatusEventListener; +import user.commons.remotestore.ProgressEvent; +import user.commons.remotestore.RemoteStoreProtocol; +import user.commons.remotestore.StatusEvent; +import user.jobengine.db.IItemManager; +import user.jobengine.db.Media; +import user.jobengine.db.MediaFile; +import user.jobengine.db.Store; +import user.jobengine.server.IJobEngine; +import user.jobengine.server.IJobRuntime; + +public class TSMSystemRestoreStep extends JobStep { + private static final Logger logger = LogManager.getLogger(); + private IItemManager manager; + private StoreUri targetUri; + private StoreUri sourceUri; + private String sourceFileName; + private Marker marker; + + protected void afterRestore(StoreUri targetUri, String targetPath, int killDateDays, String targetFileName) throws IOException, Exception { + if (killDateDays > 0) + EscortFiles.createUNCKillDate(targetPath, targetFileName, killDateDays, marker); + } + + protected void beforeRestore(StoreUri targetURI, String targetFileName) throws Exception { + } + + protected void checkTargetPath(String targetPath) { + if (StringUtils.isBlank(targetPath)) { + logger.error(marker, "A folyamat 'targetPath' bemeneti paramétere üres."); + throw new NullPointerException("System is not configured properly, 'targetPath' input parameter missing."); + } + } + + protected StoreUri createTargetUri(IItemManager manager, String targetPath) { + return manager.createStoreUri(RemoteStoreProtocol.LOCAL, targetPath); + } + + @StepEntry + public Object[] execute(Media mediaCubeMedia, String targetPath, String targetNamePattern, String successRecipient, int killDateDays, IJobEngine jobEngine, + IJobRuntime jobRuntime) throws Exception { + marker = jobRuntime.getMarker(); + setAndCheck(mediaCubeMedia, targetPath, targetNamePattern, jobEngine); + String targetFileName = String.format(targetNamePattern, sourceFileName); + try { + beforeRestore(targetUri, targetNamePattern); + final IJobRuntime runtime = jobRuntime; + sourceUri.addProgressListener(new IProgressEventListener() { + @Override + public void progressChanged(ProgressEvent evt) { + runtime.incrementProgress(evt.getProgress()); + } + }); + sourceUri.addStatusListener(new IStatusEventListener() { + @Override + public void statusChanged(StatusEvent evt) { + evt.setCancel(!canContinue()); + } + }); + RemoteFile result = sourceUri.transferFrom(targetUri, sourceFileName, targetFileName); + + Message msg = LogUtils.format("Az '{}' állomány visszatöltése sikeres volt '{}' néven. ", sourceFileName, targetFileName); + if (StringUtils.isNotBlank(successRecipient)) + logger.info(new MediaCubeMarker(successRecipient), msg); + logger.info(marker, msg); + afterRestore(targetUri, targetPath, killDateDays, targetFileName); + + } catch (Exception e) { + Message msg = LogUtils.format("Az '{}' állomány visszatöltése sikertelen. A rendszer hibaüzenete: {}", sourceFileName, e.getMessage()); + logger.error(marker, msg); + // logger.error(jobRuntime.marker, msg); + logger.catching(e); + throw e; + } + + return null; + } + + private String getSourceFileName(Media mediaCubeMedia, Store store) { + List mediaFiles = mediaCubeMedia.getMediaFiles(); + if (mediaFiles == null) + return null; + for (MediaFile mediaFile : mediaFiles) { + if (mediaFile.getStore().getId() == store.getId()) + return mediaFile.getRelativePath(); + } + return null; + } + + private void setAndCheck(Media mediaCubeMedia, String targetPath, String targetNamePattern, IJobEngine jobEngine) { + if (jobEngine == null) { + logger.error(marker, "Az folyamatkezelő réteg nem elérhető."); + throw new NullPointerException("Internal error, missing JobEngine reference."); + } + manager = jobEngine.getItemManager(); + if (manager == null) { + logger.error(marker, "Az adatbáziskezelő réteg nem elérhető."); + throw new NullPointerException("Internal error, missing ItemManager reference."); + } + if (mediaCubeMedia == null) { + logger.error(marker, "A folyamat 'mediaCubeMedia' bemeneti paramétere üres."); + throw new NullPointerException("System is not configured properly, 'mediaCubeMedia' input parameter missing."); + } + checkTargetPath(targetPath); + if (StringUtils.isBlank(targetNamePattern)) { + logger.error(marker, "A folyamat 'targetNamePattern' bemeneti paramétere üres."); + throw new NullPointerException("System is not configured properly, 'targetNamePattern' input parameter missing."); + } + Store tsmStore = manager.getSystemStore(false); + if (tsmStore == null) { + logger.error(marker, "A TSM rendszer beállítás nem elérhető."); + throw new NullPointerException("System is not configured properly, missing TSM Store."); + } + sourceUri = tsmStore.getSourceStoreUri(RemoteStoreProtocol.TSM); + if (sourceUri == null) { + logger.error(marker, "A TSM rendszer beállítás paraméterei nem elérhetőek."); + throw new NullPointerException("System is not configured properly, missing TSM StoreUri."); + } + targetUri = createTargetUri(manager, targetPath); + sourceFileName = getSourceFileName(mediaCubeMedia, tsmStore); + if (sourceFileName == null) { + logger.error(marker, "Adatbázis bejegyzés hiba, a visszatöltendő fájl neve nem található."); + throw new NullPointerException("Database error, missing MediaFile 'relativePath'."); + } + + } +} diff --git a/server/user.jobengine.osgi.commons/src/user/commons/nexio/api/ClipImpl.java b/server/user.jobengine.osgi.commons/src/user/commons/nexio/api/ClipImpl.java index c8d92db1..3eeb9c54 100644 --- a/server/user.jobengine.osgi.commons/src/user/commons/nexio/api/ClipImpl.java +++ b/server/user.jobengine.osgi.commons/src/user/commons/nexio/api/ClipImpl.java @@ -134,7 +134,9 @@ class ClipImpl implements Clip { @Override public Calendar getRecordDateTimestamp() throws ClipNotFoundException, IOException, ProtocolException { if (timestamp == null) { - timestamp = protocol.executeGetExtendedFieldGetRecordDateTimestamp(id); + //TODO + timestamp = protocol.executeGetExtendedFieldGetModifiedTimestamp(id); + //timestamp = protocol.executeGetExtendedFieldGetRecordDateTimestamp(id); checkClipExists(timestamp); } return timestamp; diff --git a/server/user.jobengine.osgi.db/src/user/jobengine/db/DynamicAttributes.java b/server/user.jobengine.osgi.db/src/user/jobengine/db/DynamicAttributes.java index 57fd2ce5..f8d1b2be 100644 --- a/server/user.jobengine.osgi.db/src/user/jobengine/db/DynamicAttributes.java +++ b/server/user.jobengine.osgi.db/src/user/jobengine/db/DynamicAttributes.java @@ -19,10 +19,6 @@ public class DynamicAttributes extends JSONBase implements Serializable { private long itemTypeId = 0; private boolean loaded = false; - public Metadata getMetadata(String name) { - return getItemType().getMetadata(name); - } - public Object getAttribute(String name) { ItemManager.getInstance().traceIn(); Object result = null; @@ -37,6 +33,7 @@ public class DynamicAttributes extends JSONBase implements Serializable { return this.attributes; } + @JsonIgnore public ItemType getItemType() { if (itemType == null && itemTypeId > 0) { itemType = (ItemType) ItemManager.getInstance().get(ItemType.class, itemTypeId); @@ -50,6 +47,10 @@ public class DynamicAttributes extends JSONBase implements Serializable { return this.itemTypeId; } + public Metadata getMetadata(String name) { + return getItemType().getMetadata(name); + } + private void initalize() { ItemManager.getInstance().traceIn(); if (attributes == null) { @@ -63,8 +64,7 @@ public class DynamicAttributes extends JSONBase implements Serializable { } } if (getId() > 0 && !loaded) { - DynamicAttributesDAO daDAO = (DynamicAttributesDAO) ItemManager.getInstance() - .getBaseDAO(DynamicAttributes.class); + DynamicAttributesDAO daDAO = (DynamicAttributesDAO) ItemManager.getInstance().getBaseDAO(DynamicAttributes.class); daDAO.get(this); } } diff --git a/server/user.jobengine.osgi.db/src/user/jobengine/db/Media.java b/server/user.jobengine.osgi.db/src/user/jobengine/db/Media.java index a556b832..c15074fd 100644 --- a/server/user.jobengine.osgi.db/src/user/jobengine/db/Media.java +++ b/server/user.jobengine.osgi.db/src/user/jobengine/db/Media.java @@ -6,6 +6,8 @@ import java.util.List; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import com.fasterxml.jackson.annotation.JsonIgnore; + import user.commons.TimestampAdapter; /** @@ -67,18 +69,21 @@ public class Media extends DynamicAttributes { } @SuppressWarnings("unchecked") + @JsonIgnore public List getMediaFiles() { if (mediaFiles == null) mediaFiles = (List) (List) ItemManager.getInstance().getAll(MediaFile.class, getId()); return mediaFiles; } + @JsonIgnore public int getMediaFilesCount() { if (mediaFilesCount == -1) mediaFilesCount = getMediaFiles() == null ? 0 : getMediaFiles().size(); return mediaFilesCount; } + @JsonIgnore public String getMediaFilesName() { if (mediaFilesName == null) { List files = getMediaFiles(); diff --git a/server/user.jobengine.osgi.services/src/user/jobengine/osgi/mediacube/MediaCubeService.java b/server/user.jobengine.osgi.services/src/user/jobengine/osgi/mediacube/MediaCubeService.java index a5b0ce8a..4d2d4db3 100644 --- a/server/user.jobengine.osgi.services/src/user/jobengine/osgi/mediacube/MediaCubeService.java +++ b/server/user.jobengine.osgi.services/src/user/jobengine/osgi/mediacube/MediaCubeService.java @@ -1,9 +1,5 @@ package user.jobengine.osgi.mediacube; -import java.sql.ResultSetMetaData; -import java.util.ArrayList; -import java.util.List; - import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -17,14 +13,13 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.eclipse.core.runtime.adaptor.EclipseStarter; -import com.ibm.nosql.json.api.BasicDBObject; - import user.commons.MediaCubeMarker; import user.jobengine.db.IItemManager; import user.jobengine.db.IResultSetConsumer; import user.jobengine.db.IStatementDecorator; import user.jobengine.db.Item; import user.jobengine.db.JSONBase; +import user.jobengine.db.Media; import user.jobengine.osgi.rest.ComponentBinder; import user.jobengine.server.IJobEngine; @@ -97,22 +92,36 @@ public class MediaCubeService { if (itemManager == null) throw new Exception("No ItemManager found"); - List items = new ArrayList<>(); - String sql = "select * from VW_ITEMS where mediafilehouseid = ? order by mediafilehouseid"; + Media medias[] = { null }; + String sql = "select m.* from MEDIA m left outer join MEDIAFILE mf on (m.id = mf.mediaid) where mf.houseid = ?"; IStatementDecorator decorator = ps -> { ps.setString(1, mediaHouseId); }; IResultSetConsumer consumer = rs -> { + Media media = new Media(); + media.setId(rs.getLong("id")); + media.setTitle(rs.getString("title")); + media.setDescription(rs.getString("description")); + media.setItemId(rs.getLong("itemid")); + media.setItemTypeId(rs.getLong("itemtypeid")); + media.setHouseId(rs.getString("houseid")); + media.setLength(rs.getLong("length")); + media.setCreated(rs.getTimestamp("created")); + media.setArchived(rs.getTimestamp("archived")); + medias[0] = media; + //entity.setPoster(iterator.poster()); + /* ResultSetMetaData metaData = rs.getMetaData(); BasicDBObject o = new BasicDBObject(); for (int i = 1; i <= metaData.getColumnCount(); i++) { o.put(metaData.getColumnName(i), rs.getObject(i)); } items.add(o); - return true; + */ + return false; }; itemManager.executeQuery(sql, consumer, decorator); - result = Response.ok(items).build(); + result = Response.ok(medias[0]).build(); } catch (Exception e) { result = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); } diff --git a/server/user.jobengine.osgi.services/src/user/jobengine/osgi/ws/mediacube/MediaCubeAPIWSSocket.java b/server/user.jobengine.osgi.services/src/user/jobengine/osgi/ws/mediacube/MediaCubeAPIWSSocket.java index 61ce989b..058879b6 100644 --- a/server/user.jobengine.osgi.services/src/user/jobengine/osgi/ws/mediacube/MediaCubeAPIWSSocket.java +++ b/server/user.jobengine.osgi.services/src/user/jobengine/osgi/ws/mediacube/MediaCubeAPIWSSocket.java @@ -1,5 +1,6 @@ package user.jobengine.osgi.ws.mediacube; +import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -8,12 +9,15 @@ import org.apache.logging.log4j.Logger; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.WebSocketAdapter; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.ibm.nosql.json.JSONUtil; import com.ibm.nosql.json.api.BasicDBObject; import user.commons.JobStatus; import user.jobengine.db.ItemManagerData.SignalType; +import user.jobengine.db.JSONBase; import user.jobengine.osgi.rest.ComponentBinder; import user.jobengine.osgi.rest.ServiceObjectMapper; import user.jobengine.server.IJobChangedListener; @@ -52,6 +56,40 @@ public class MediaCubeAPIWSSocket extends WebSocketAdapter { } } + private IJobChangedListener createListener(IJobRuntime runtime) { + return event -> { + try { + IJobRuntime job = event.getJob(); + if (job.getId() != runtime.getId()) + return; + BasicDBObject response = new BasicDBObject("jobID", job.getId()).append("status", job.getStatus()).append("signal", event.getSignalType()) + .append("progress", job.getProgress()); + + if (JobStatus.SUSPENDED.equals(job.getStatus())) + response.append("error", job.getDescription()); + asyncSendResponse(response); + if (SignalType.DELETE.equals(event.getSignalType()) || JobStatus.SUSPENDED.equals(job.getStatus())) { + removeJobChangedEventListener(runtime.getId()); + } + } catch (Exception e) { + removeJobChangedEventListener(runtime.getId()); + logger.catching(e); + } + }; + } + + private void deserializeParameters(BasicDBObject parameters) throws IOException, JsonParseException, JsonMappingException { + for (String key : parameters.keySet()) { + String paramData = parameters.getString(key); + Object value = null; + if (paramData != null && paramData.contains("$type")) + value = mapper.readValue(paramData, JSONBase.class); + else + value = parameters.get(key); + parameters.put(key, value); + } + } + @Override public void onWebSocketClose(int statusCode, String reason) { super.onWebSocketClose(statusCode, reason); @@ -112,23 +150,12 @@ public class MediaCubeAPIWSSocket extends WebSocketAdapter { throw new Exception(NO_PARAMETERS_SPECIFIED); BasicDBObject parameters = (BasicDBObject) data.get(PARAMETERS); IJobEngine jobengine = ComponentBinder.getJobengine(); + + if (parameters != null) + deserializeParameters(parameters); + IJobRuntime runtime = jobengine.submit(template, null, parameters); - IJobChangedListener jobChangedListener = event -> { - try { - IJobRuntime job = event.getJob(); - if (job.getId() != runtime.getId()) - return; - BasicDBObject response = new BasicDBObject("jobID", job.getId()).append("status", job.getStatus()).append("signal", event.getSignalType()) - .append("progress", job.getProgress()); - asyncSendResponse(response); - if (SignalType.DELETE.equals(event.getSignalType()) || JobStatus.SUSPENDED.equals(job.getStatus())) { - removeJobChangedEventListener(runtime.getId()); - } - } catch (Exception e) { - removeJobChangedEventListener(runtime.getId()); - logger.catching(e); - } - }; + IJobChangedListener jobChangedListener = createListener(runtime); jobengine.addJobChangedEventListener(jobChangedListener); jobChangedListeners.put(runtime.getId(), jobChangedListener); } -- 2.54.0