#106 MediaCubeAPI bővítése szinkron folyamat futtatással
authorVásáry Dániel <daniel.vasary@userrendszerhaz.hu>
Thu, 6 Dec 2018 16:03:48 +0000 (16:03 +0000)
committerVásáry Dániel <daniel.vasary@userrendszerhaz.hu>
Thu, 6 Dec 2018 16:03:48 +0000 (16:03 +0000)
#107 Folyamat futtatás és monitorozás kiajánlása WS-en

git-tfs-id: [http://tfs.userrendszerhaz.hu:8080/tfs/DefaultCollection]$/MediaCube;C31360

43 files changed:
client/DxPlay/PlayerForm.Designer.cs
client/DxPlay/PlayerForm.resx
client/Maestro/Configuration/configuration - Copy.json
client/Maestro/Configuration/configuration.json
client/Maestro/Maestro.csproj
client/Maestro/MaestroForm.Designer.cs
client/Maestro/MaestroForm.Metadata.cs
client/Maestro/MaestroForm.cs
client/Maestro/MaestroForm.resx
client/Maestro/Metadata/MetaDataInfo.cs
client/Maestro/Program.cs
client/Maestro/Properties/Resources.Designer.cs
client/Maestro/Properties/Resources.resx
client/Maestro/Resources/ic_playlist_add_black_24dp.png [new file with mode: 0644]
client/Maestro/RestoreMedia.Designer.cs [new file with mode: 0644]
client/Maestro/RestoreMedia.cs [new file with mode: 0644]
client/Maestro/RestoreMedia.resx [new file with mode: 0644]
client/Maestro/Sources/NexioRESTSource.cs
client/MaestroShared/Commons/PatternNameMaker.cs
client/MaestroShared/Commons/ShortGuid.cs [new file with mode: 0644]
client/MaestroShared/Configuration/ConfigurationInfo.cs
client/MaestroShared/MaestroShared.csproj
client/MaestroShared/Model/Model.cs
client/MaestroShared/Resources/baseline_playlist_play_black_18dp.png [new file with mode: 0644]
client/MaestroShared/Resources/ic_play_for_work_black_18dp.png [new file with mode: 0644]
client/MaestroShared/Resources/ic_play_for_work_black_24dp.png [new file with mode: 0644]
client/MaestroShared/Resources/ic_playlist_add_black_18dp.png [new file with mode: 0644]
client/MaestroShared/Targets/FTPTargetProcessor.cs
client/MediaCubeClient/MediaCubeApi.cs
client/MediaCubeClient/MediaCubeClient.csproj
client/MediaCubeClient/MediaCubeJsonConvert.cs [new file with mode: 0644]
client/MediaCubeClient/MediaCubeWSApi.cs
server/-configuration/run-mediacube-server-bsh.launch
server/user.jobengine.executors/config/config.xml
server/user.jobengine.executors/jobtemplates/retrieve-material.xml
server/user.jobengine.executors/src/user/jobengine/server/steps/CleanupMountedLocationStep.java
server/user.jobengine.executors/src/user/jobengine/server/steps/CopyForArchiveNEXIORecordingsStep.java
server/user.jobengine.executors/src/user/jobengine/server/steps/TSMSystemRestoreStep.java [new file with mode: 0644]
server/user.jobengine.osgi.commons/src/user/commons/nexio/api/ClipImpl.java
server/user.jobengine.osgi.db/src/user/jobengine/db/DynamicAttributes.java
server/user.jobengine.osgi.db/src/user/jobengine/db/Media.java
server/user.jobengine.osgi.services/src/user/jobengine/osgi/mediacube/MediaCubeService.java
server/user.jobengine.osgi.services/src/user/jobengine/osgi/ws/mediacube/MediaCubeAPIWSSocket.java

index f96aea3d9bc62c178722474d6bfd93defdd7ad51..fe8e5f2568af1c275b5146707ecf4f5d4ee2549b 100644 (file)
@@ -185,7 +185,7 @@ namespace DxPlay {
             this.tpSegments.Location = new System.Drawing.Point(4, 4);\r
             this.tpSegments.Name = "tpSegments";\r
             this.tpSegments.Padding = new System.Windows.Forms.Padding(3);\r
-            this.tpSegments.Size = new System.Drawing.Size(263, 304);\r
+            this.tpSegments.Size = new System.Drawing.Size(192, 30);\r
             this.tpSegments.TabIndex = 1;\r
             this.tpSegments.Text = "Segments";\r
             this.tpSegments.UseVisualStyleBackColor = true;\r
@@ -215,7 +215,7 @@ namespace DxPlay {
             this.dgSegments.Name = "dgSegments";\r
             this.dgSegments.RowHeadersVisible = false;\r
             this.dgSegments.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;\r
-            this.dgSegments.Size = new System.Drawing.Size(257, 273);\r
+            this.dgSegments.Size = new System.Drawing.Size(186, 0);\r
             this.dgSegments.TabIndex = 1;\r
             this.dgSegments.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgSegments_CellContentClick);\r
             this.dgSegments.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgSegments_CellMouseDoubleClick);\r
@@ -237,7 +237,7 @@ namespace DxPlay {
             this.segmentActions.Location = new System.Drawing.Point(3, 3);\r
             this.segmentActions.Name = "segmentActions";\r
             this.segmentActions.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;\r
-            this.segmentActions.Size = new System.Drawing.Size(257, 25);\r
+            this.segmentActions.Size = new System.Drawing.Size(186, 25);\r
             this.segmentActions.TabIndex = 0;\r
             this.segmentActions.Text = "toolStrip1";\r
             // \r
index 3a82e29c83099d020e72155499b6ba2527cccaba..21ddb0c48d9e200b9b33e00deefbb23c260f7057 100644 (file)
         AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w\r
         LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0\r
         ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABo\r
-        CAAAAk1TRnQBSQFMAgEBAgEAAZgBAQGYAQEBGAEAARgBAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo\r
+        CAAAAk1TRnQBSQFMAgEBAgEAAaABAQGgAQEBGAEAARgBAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo\r
         AwABYAMAARgDAAEBAQABCAYAAQkYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA\r
         AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5\r
         AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA\r
index 8a54c54bf99b9dc41ce1c1e8523606c8c02e4890..188c8a81e40bb236e3935e904f30cc0cc2f297ec 100644 (file)
@@ -1,6 +1,6 @@
 {\r
   "title": "Development",\r
-  "active": true,\r
+  "active": false,\r
   "startInTray": false,\r
   "enableCustomMetadataId": true,\r
   "filter": "avi",\r
@@ -10,7 +10,7 @@
     "$type": "NEXIOSource",\r
     "hideEmpty":  true,\r
     "local": {\r
-      "address": "ws://localhost:8888/services/nexio"\r
+      "address": "ws://10.10.1.27:88/services/nexio"\r
     },\r
     "remote": {\r
       "address": "ftp://10.10.1.55:2098",\r
@@ -23,7 +23,7 @@
       "$type": "OctopusMetadata",\r
       "server": {\r
         "address": "http://10.10.1.27/services/rest/octopus",\r
-        "timeout": 1000\r
+        "timeout": 3000\r
       }\r
     },\r
     {\r
index 325033a449034b4681ca1c41712dfdd4883af9d2..5c0e1a050f1526208eb40b059626b4bf4cc1c41f 100644 (file)
@@ -1,16 +1,25 @@
 {\r
   "title": "Development",\r
-  "active": false,\r
+  "active": true,\r
   "startInTray": false,\r
   "enableCustomMetadataId": true,\r
   "filter": "avi",\r
   "player": {\r
+    "enabled": true,\r
+    "autoStart": false,\r
+    "segmentEditor": true\r
   },\r
   "source": {\r
     "$type": "UNCSource",\r
     "filter": "avi,wav,mxf",\r
     "local": {\r
-      "address": "file://c:\\_video",\r
+      "address": "file://10.10.1.105/BRAAVOS/TESZT/TC",\r
+      "userName": "mediacube",\r
+      "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy",\r
+      "timeout": 1000\r
+    },\r
+    "remote": {\r
+      "address": "ftp://10.10.1.105/TESZT/TC",\r
       "userName": "mediacube",\r
       "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy",\r
       "timeout": 1000\r
@@ -20,8 +29,8 @@
     {\r
       "$type": "OctopusMetadata",\r
       "server": {\r
-        "address": "http://localhost:8888/services/rest/octopus",\r
-        "timeout": 1000\r
+        "address": "http://10.10.1.27/services/rest/octopus",\r
+        "timeout": 3000\r
       }\r
     },\r
     {\r
         "userName": "MAM",\r
         "password": "7RKZYBzumKjL40SJwuwiFCvX57xuCN8zay6OttUm2wbrgImyYZBHyZTUUYrXX31Ge2Uwew07HYsqh2uzdJeDBDwcVntxaHg3nIpv9Dyq/odVoiC4tUF/K+lgvKWANcrZ",\r
         "timeout": 1000\r
-      }\r
+      },\r
+      "version": 2\r
     },\r
     {\r
       "$type": "MediaCubeMetadata",\r
       "server": {\r
-        "address": "http://10.10.1.27/services/rest/jobengine",\r
+        "address": "http://localhost:8888/services/rest/jobengine",\r
         "userName": "mediacube",\r
         "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy",\r
         "timeout": 1000\r
-      }\r
+      },\r
+      "wsserver": {\r
+        "address": "ws://localhost:8888/services/wsapi",\r
+        "timeout": 1000\r
+      },\r
+      "jobTemplate": "retrieve-material.xml",\r
+      "archiveFolder": "file://10.10.1.100/BRAAVOS/ARCHIVE",\r
+      "restoreFolder": "file://10.10.1.100/BRAAVOS/ARCHIVE_RESTORE",\r
+      "restoreNamePattern": "%s_%GUID%",\r
+      "serverRestoreFolder": "/mnt/ISILON/RESTORE",\r
+      "killDateDays": 1\r
     }\r
   ],\r
   "targets": [\r
+    {\r
+      "label": "Adáskész",\r
+      "processor": "FXPTargetProcessor",\r
+      "outputFormat": "%ID%",\r
+      "killDateDays": 5,\r
+      "saveSegments": false,\r
+      "tag": "Adáskész",\r
+      "disableFileVersioning": true,\r
+      "enableOverride": false,\r
+      "saveMorpheusMetadata": true,\r
+      "pathMorpheusMetadata": "/TESZT/TC/CHECK/Input",\r
+      "deviceIdMorpheus": "ISILON",\r
+      "remote": {\r
+        "address": "ftp://10.10.1.105/TESZT/TC/CHECK",\r
+        "userName": "mediacube",\r
+        "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy",\r
+        "timeout": 1000\r
+      }\r
+    },\r
     {\r
       "label": "Teszt",\r
       "processor": "FTPTargetProcessor",\r
       "killDateDays": 7,\r
       "saveArchiveMetadata": false,\r
       "remote": {\r
-        "address": "ftp://isilon.intra.echotv.hu/TESZT/CHECK",\r
+        "address": "ftp://10.10.1.105/TESZT/CHECK",\r
+        "userName": "mediacube",\r
+        "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy",\r
+        "timeout": 1000\r
+      }\r
+    },\r
+    {\r
+      "label": "Napi megtekintőbe",\r
+      "processor": "FTPTargetProcessor",\r
+      "outputFormat": "%ID%-%TEXT%",\r
+      "tag": "Online",\r
+      "disableFileVersioning": true,\r
+      "killDateDays": 2,\r
+      "saveArchiveMetadata": false,\r
+      "remote": {\r
+        "address": "ftp://10.10.1.105/TESZT/CHECK",\r
         "userName": "mediacube",\r
         "password": "Dn8t4gfHcK98o8hyPgLDhr5SgSji4JCxsfpMJsODikUp3nXgrM0UNCi45lLAK8ZOnmEneO44P9qpJ4QDqhctN6MxZodjJgdZTyoZKmSa+ECzEzLr/wPYNgxVaXrVotEy",\r
         "timeout": 1000\r
       }\r
     }\r
+\r
   ]\r
 }\r
index c2f30eae110b311fc6edb2a92c28689c801ff8ed..6b80905e74f37823de18dfe04bbec49c7fb6459b 100644 (file)
     <PlatformTarget>x64</PlatformTarget>\r
     <ErrorReport>prompt</ErrorReport>\r
     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>\r
+    <Deterministic>true</Deterministic>\r
   </PropertyGroup>\r
   <ItemGroup>\r
     <Reference Include="LinkDotNet.MessageHandling, Version=0.2.0.0, Culture=neutral, processorArchitecture=MSIL">\r
       <SubType>Component</SubType>\r
     </Compile>\r
     <Compile Include="Metadata\MetaDataInfo.cs" />\r
+    <Compile Include="RestoreMedia.cs">\r
+      <SubType>Form</SubType>\r
+    </Compile>\r
+    <Compile Include="RestoreMedia.Designer.cs">\r
+      <DependentUpon>RestoreMedia.cs</DependentUpon>\r
+    </Compile>\r
     <Compile Include="Splash.cs">\r
       <SubType>Form</SubType>\r
     </Compile>\r
       <DependentUpon>Resources.resx</DependentUpon>\r
       <DesignTime>True</DesignTime>\r
     </Compile>\r
+    <EmbeddedResource Include="RestoreMedia.resx">\r
+      <DependentUpon>RestoreMedia.cs</DependentUpon>\r
+    </EmbeddedResource>\r
     <EmbeddedResource Include="Splash.resx">\r
       <DependentUpon>Splash.cs</DependentUpon>\r
       <SubType>Designer</SubType>\r
     <None Include="Resources\ic_refresh_black_24dp_1x.jpg" />\r
     <None Include="Resources\ic_refresh_black_24dp_1x.png" />\r
     <None Include="Resources\ic_cached_black_18dp.png" />\r
+    <None Include="Resources\ic_playlist_add_black_18dp.png" />\r
+    <None Include="Resources\ic_playlist_add_black_24dp.png" />\r
     <Content Include="Resources\play.ico" />\r
     <Content Include="TODO.txt" />\r
   </ItemGroup>\r
index 458e2251d579fc2e2caea4b746af266fb2b25b3d..dc76d91f0e5d2815a09b255c3576eb1c5a2bba99 100644 (file)
@@ -63,6 +63,7 @@ namespace Maestro {
             this.trafficIDSelector = new TrafficClient.TrafficIDSelector();\r
             this.pMetadataDisplay = new System.Windows.Forms.TableLayoutPanel();\r
             this.tsMetadata = new System.Windows.Forms.ToolStrip();\r
+            this.btnRedefineSegments = new System.Windows.Forms.ToolStripButton();\r
             this.btnEditMetadata = new System.Windows.Forms.ToolStripButton();\r
             this.btnDefineSegments = new System.Windows.Forms.ToolStripButton();\r
             this.btnLookupMetadata = new System.Windows.Forms.Button();\r
@@ -545,6 +546,7 @@ namespace Maestro {
             this.pMetadataDisplay.SetColumnSpan(this.tsMetadata, 2);\r
             this.tsMetadata.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;\r
             this.tsMetadata.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\r
+            this.btnRedefineSegments,\r
             this.btnEditMetadata,\r
             this.btnDefineSegments});\r
             this.tsMetadata.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.Flow;\r
@@ -555,6 +557,19 @@ namespace Maestro {
             this.tsMetadata.Size = new System.Drawing.Size(330, 31);\r
             this.tsMetadata.TabIndex = 17;\r
             // \r
+            // btnRedefineSegments\r
+            // \r
+            this.btnRedefineSegments.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;\r
+            this.btnRedefineSegments.Image = global::Maestro.Properties.Resources.ic_playlist_add_black_24dp;\r
+            this.btnRedefineSegments.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;\r
+            this.btnRedefineSegments.ImageTransparentColor = System.Drawing.Color.Magenta;\r
+            this.btnRedefineSegments.Name = "btnRedefineSegments";\r
+            this.btnRedefineSegments.Size = new System.Drawing.Size(28, 28);\r
+            this.btnRedefineSegments.Text = "toolStripButton3";\r
+            this.btnRedefineSegments.ToolTipText = "Újraszegmentálás ";\r
+            this.btnRedefineSegments.Visible = false;\r
+            this.btnRedefineSegments.Click += new System.EventHandler(this.OnRedefineSegments);\r
+            // \r
             // btnEditMetadata\r
             // \r
             this.btnEditMetadata.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;\r
@@ -975,7 +990,7 @@ namespace Maestro {
             this.btnSweepJobList.ImageTransparentColor = System.Drawing.Color.Magenta;\r
             this.btnSweepJobList.Name = "btnSweepJobList";\r
             this.btnSweepJobList.Size = new System.Drawing.Size(23, 22);\r
-            this.btnSweepJobList.Text = "toolStripButton2";\r
+            this.btnSweepJobList.Text = "Takarítás";\r
             this.btnSweepJobList.Click += new System.EventHandler(this.OnSweepJobList);\r
             // \r
             // toolStripSeparator3\r
@@ -1246,6 +1261,7 @@ namespace Maestro {
         private DataGridViewTextBoxColumn columnKillDate;\r
         private DataGridViewTextBoxColumn columnMessage;\r
         private ToolStripLabel lSelectionCounts;\r
+        private ToolStripButton btnRedefineSegments;\r
     }\r
 }\r
 \r
index c5b8876d62ece01e126e0d546db3ee71f5cb34c2..11cc4e60f98c8be22ee275a7559d56df2fa7939e 100644 (file)
@@ -9,6 +9,7 @@ using OctopusClient;
 using System;\r
 using System.Collections.Generic;\r
 using System.ComponentModel;\r
+using System.IO;\r
 using System.Linq;\r
 using System.Windows.Forms;\r
 using TrafficClient;\r
@@ -16,6 +17,7 @@ using TrafficClient;
 namespace Maestro {\r
     public partial class MaestroForm {\r
         private const string ARCHIVEID_PREFIX = "MC-";\r
+        private const string MXFEXT = ".MXF";\r
 \r
         private MetadataInfo selectedMetadata;\r
         private BindingList<MovieSegment> movieSegments;\r
@@ -378,6 +380,7 @@ namespace Maestro {
         }\r
 \r
         private void OnTrafficIDSelected(string id, int variantID, string text) {\r
+            btnRedefineSegments.Visible = false;\r
             if (id == null) {\r
                 ArchiveMetadata = null;\r
                 SelectedMetadata = null;\r
@@ -391,6 +394,48 @@ namespace Maestro {
                 MetadataText = text,\r
                 VariantID = variantID\r
             };\r
+\r
+            CheckIfRedefineSegments();\r
+        }\r
+\r
+        private void CheckIfRedefineSegments() {\r
+            bool enableRedefine = false;\r
+            string mediaHouseId = SelectedMetadata.ID + MXFEXT;\r
+            MediaCubeMetadata metadata = MetadataProvider.Get<MediaCubeMetadata>(Configuration.Metadatas);\r
+            if (metadata != null && metadata.ArchiveFolder != null) {\r
+                string location = Path.Combine(metadata.ArchiveFolder.LocalPath, mediaHouseId);\r
+                enableRedefine = File.Exists(location);\r
+                if (enableRedefine)\r
+                    SelectedMetadata.RedefineSegmentsFile = location;\r
+            }\r
+\r
+            if (!enableRedefine && mediaCubeApi != null) {\r
+                Media media = mediaCubeApi.GetMediaByHouseId(mediaHouseId);\r
+                if (media != null) {\r
+                    enableRedefine = true;\r
+                    SelectedMetadata.RedefineSegmentsFile = Path.Combine(metadata.RestoreFolder.LocalPath, mediaHouseId);\r
+                    SelectedMetadata.RedefineWithRestore = true;\r
+                    SelectedMetadata.RedefineMedia = media;\r
+                }\r
+            }\r
+\r
+            if (enableRedefine) {\r
+                btnRedefineSegments.Visible = true;\r
+            }\r
+        }\r
+\r
+        private void OnRedefineSegments(object sender, EventArgs e) {\r
+            if (SelectedMetadata == null)\r
+                return;\r
+            MediaCubeMetadata mediaCubeMetadata = MetadataProvider.Get<MediaCubeMetadata>(Configuration.Metadatas);\r
+            if (SelectedMetadata.RedefineWithRestore) {\r
+                RestoreMedia restoreForm = new RestoreMedia(SelectedMetadata, mediaCubeMetadata, errorMessageBus);\r
+                if (restoreForm.ShowDialog(this) == DialogResult.Cancel)\r
+                    return;\r
+            }\r
+\r
+\r
+\r
         }\r
 \r
         private static string GetMetadataTypeTooltip(MetadataType? metadataType) {\r
index d9eb9be9d0014e4b067ac25e6c4d604e48b394dc..160eabacd3260471ca2becdea4c0d2020ec4f8a9 100644 (file)
@@ -82,6 +82,7 @@ namespace Maestro {
             errorMessageBus.Subscribe<OctopusAPIMessage>(OnMessage);\r
             errorMessageBus.Subscribe<TrafficAPIMessage>(OnMessage);\r
             errorMessageBus.Subscribe<MediaCubeMessage>(OnMessage);\r
+            errorMessageBus.Subscribe<MediaCubeWSMessage>(OnMessage);\r
 \r
             if (Configuration.MetadataOnly) {\r
                 scOperations.Panel1Collapsed = true;\r
@@ -331,5 +332,7 @@ namespace Maestro {
             bindingSourceJobs.DataSource = jobs;\r
             UpdateJobCounts();\r
         }\r
+\r
+\r
     }\r
 }\r
index 106019a8f976fab4ee5938bee776f3979ac69ab0..901e11c9f82d0319baa02d7618814278055ea8a3 100644 (file)
         AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w\r
         LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0\r
         ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAS\r
-        CAAAAk1TRnQBSQFMAgEBAgEAATABAgEwAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo\r
+        CAAAAk1TRnQBSQFMAgEBAgEAAXABAgFwAQIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo\r
         AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA\r
         AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5\r
         AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA\r
index 4afb706143428ea9f9881ef153c38a0996f332dd..efb2bc892c42ac1842f821a368cb8b3caf52f5ef 100644 (file)
@@ -1,4 +1,5 @@
 using MaestroShared.Metadata;\r
+using MaestroShared.Model;\r
 \r
 namespace Maestro.Metadata {\r
     public class MetadataInfo {\r
@@ -6,6 +7,8 @@ namespace Maestro.Metadata {
         public string MetadataText { get; set; }\r
         public MetadataType Kind { get; set; }\r
         public int VariantID { get; set; }\r
-\r
+        public string RedefineSegmentsFile { get; set; }\r
+        public bool RedefineWithRestore { get; set; }\r
+        public Media RedefineMedia { get; set; }\r
     }\r
 }\r
index 907f2637da83c55de157ddb1ae677220cc7c15b3..cc2f29b35224fbcceac9a77b2050938d56a1ef90 100644 (file)
@@ -29,25 +29,6 @@ namespace Maestro {
         [STAThread]\r
         [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]\r
         static void Main() {\r
-            /*\r
-            IMessageBus mb = new MessageBus();\r
-            mb.Subscribe<MediaCubeWSMessage>(m => {\r
-                if (m.Finished) {\r
-                    if (!string.IsNullOrEmpty(m.Content))\r
-                        Debug.WriteLine("Error " + m.Content);\r
-                    Debug.WriteLine("Finished");\r
-                } else\r
-                    Debug.WriteLine("Progress " + m.Data.As<int>("progress"));\r
-            });\r
-            MediaCubeWSApi c = new MediaCubeWSApi("ws://localhost:8888/services/wsapi", mb);\r
-            JObject data = new JObject();\r
-            data.Add("itemID", JToken.FromObject(0));\r
-            data.Add("resultID", JToken.FromObject(0));\r
-            c.SubmitJob("fake.xml", data);\r
-            Thread.Sleep(1000000);\r
-            return;\r
-            */\r
-\r
             string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();\r
             string userName = WindowsIdentity.GetCurrent().Name;\r
             string mutexId = string.Format("Global\\{0}-{1}", appGuid, userName.Replace('\\', '-'));\r
index 180d0c302dff17bf180e9a7a586ffeba1c28f528..765cc214465af5ddf341d6f661464def0655059b 100644 (file)
@@ -120,6 +120,16 @@ namespace Maestro.Properties {
             }\r
         }\r
         \r
+        /// <summary>\r
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.\r
+        /// </summary>\r
+        internal static System.Drawing.Bitmap ic_playlist_add_black_24dp {\r
+            get {\r
+                object obj = ResourceManager.GetObject("ic_playlist_add_black_24dp", resourceCulture);\r
+                return ((System.Drawing.Bitmap)(obj));\r
+            }\r
+        }\r
+        \r
         /// <summary>\r
         ///   Looks up a localized resource of type System.Drawing.Bitmap.\r
         /// </summary>\r
index 2775772dfc75ae30a3c89c09b074e8972dd17b17..f2783a5ad69bc299e0cd520fa6dc4bebe0f04fcc 100644 (file)
   <data name="ic_cached_black_18dp" type="System.Resources.ResXFileRef, System.Windows.Forms">\r
     <value>..\Resources\ic_cached_black_18dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r
   </data>\r
+  <data name="ic_playlist_add_black_24dp" type="System.Resources.ResXFileRef, System.Windows.Forms">\r
+    <value>..\Resources\ic_playlist_add_black_24dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\r
+  </data>\r
 </root>
\ 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 (file)
index 0000000..d7a7514
Binary files /dev/null and b/client/Maestro/Resources/ic_playlist_add_black_24dp.png differ
diff --git a/client/Maestro/RestoreMedia.Designer.cs b/client/Maestro/RestoreMedia.Designer.cs
new file mode 100644 (file)
index 0000000..537d75e
--- /dev/null
@@ -0,0 +1,101 @@
+namespace Maestro {\r
+    partial class RestoreMedia {\r
+        /// <summary>\r
+        /// Required designer variable.\r
+        /// </summary>\r
+        private System.ComponentModel.IContainer components = null;\r
+\r
+        /// <summary>\r
+        /// Clean up any resources being used.\r
+        /// </summary>\r
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>\r
+        protected override void Dispose(bool disposing) {\r
+            if (disposing && (components != null)) {\r
+                components.Dispose();\r
+            }\r
+            base.Dispose(disposing);\r
+        }\r
+\r
+        #region Windows Form Designer generated code\r
+\r
+        /// <summary>\r
+        /// Required method for Designer support - do not modify\r
+        /// the contents of this method with the code editor.\r
+        /// </summary>\r
+        private void InitializeComponent() {\r
+            this.progressBar = new System.Windows.Forms.ProgressBar();\r
+            this.btnCancel = new System.Windows.Forms.Button();\r
+            this.label1 = new System.Windows.Forms.Label();\r
+            this.lFileName = new System.Windows.Forms.Label();\r
+            this.SuspendLayout();\r
+            // \r
+            // progressBar\r
+            // \r
+            this.progressBar.Location = new System.Drawing.Point(12, 12);\r
+            this.progressBar.Name = "progressBar";\r
+            this.progressBar.Size = new System.Drawing.Size(449, 23);\r
+            this.progressBar.TabIndex = 0;\r
+            // \r
+            // btnCancel\r
+            // \r
+            this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));\r
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;\r
+            this.btnCancel.Location = new System.Drawing.Point(386, 47);\r
+            this.btnCancel.Name = "btnCancel";\r
+            this.btnCancel.Size = new System.Drawing.Size(75, 23);\r
+            this.btnCancel.TabIndex = 1;\r
+            this.btnCancel.Text = "Mégsem";\r
+            this.btnCancel.UseVisualStyleBackColor = true;\r
+            // \r
+            // label1\r
+            // \r
+            this.label1.AutoSize = true;\r
+            this.label1.Location = new System.Drawing.Point(12, 52);\r
+            this.label1.Name = "label1";\r
+            this.label1.Size = new System.Drawing.Size(26, 13);\r
+            this.label1.TabIndex = 2;\r
+            this.label1.Text = "Fájl:";\r
+            // \r
+            // lFileName\r
+            // \r
+            this.lFileName.AutoSize = true;\r
+            this.lFileName.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));\r
+            this.lFileName.Location = new System.Drawing.Point(44, 52);\r
+            this.lFileName.Name = "lFileName";\r
+            this.lFileName.Size = new System.Drawing.Size(0, 13);\r
+            this.lFileName.TabIndex = 3;\r
+            // \r
+            // RestoreMedia\r
+            // \r
+            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\r
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\r
+            this.CancelButton = this.btnCancel;\r
+            this.ClientSize = new System.Drawing.Size(473, 82);\r
+            this.ControlBox = false;\r
+            this.Controls.Add(this.lFileName);\r
+            this.Controls.Add(this.label1);\r
+            this.Controls.Add(this.btnCancel);\r
+            this.Controls.Add(this.progressBar);\r
+            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;\r
+            this.MaximizeBox = false;\r
+            this.MinimizeBox = false;\r
+            this.Name = "RestoreMedia";\r
+            this.ShowInTaskbar = false;\r
+            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;\r
+            this.Text = "Anyag visszatöltése";\r
+            this.TopMost = true;\r
+            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.RestoreMedia_FormClosing);\r
+            this.Shown += new System.EventHandler(this.RestoreMedia_Shown);\r
+            this.ResumeLayout(false);\r
+            this.PerformLayout();\r
+\r
+        }\r
+\r
+        #endregion\r
+\r
+        private System.Windows.Forms.ProgressBar progressBar;\r
+        private System.Windows.Forms.Button btnCancel;\r
+        private System.Windows.Forms.Label label1;\r
+        private System.Windows.Forms.Label lFileName;\r
+    }\r
+}
\ No newline at end of file
diff --git a/client/Maestro/RestoreMedia.cs b/client/Maestro/RestoreMedia.cs
new file mode 100644 (file)
index 0000000..08ac622
--- /dev/null
@@ -0,0 +1,65 @@
+using LinkDotNet.MessageHandling;\r
+using LinkDotNet.MessageHandling.Contracts;\r
+using Maestro.Metadata;\r
+using MaestroShared.Commons;\r
+using MaestroShared.Configuration;\r
+using MediaCubeClient;\r
+using Newtonsoft.Json.Linq;\r
+using NLog;\r
+using System;\r
+using System.Windows.Forms;\r
+\r
+namespace Maestro {\r
+    public partial class RestoreMedia : Form {\r
+        private static readonly Logger logger = LogManager.GetCurrentClassLogger();\r
+        private readonly MetadataInfo selectedMetadata;\r
+        private readonly MediaCubeMetadata mediaCubeMetadata;\r
+        private readonly IMessageBus systemBus;\r
+        private readonly IMessageBus messageBus;\r
+        private MediaCubeWSApi api;\r
+\r
+        public RestoreMedia(MetadataInfo selectedMetadata, MediaCubeMetadata mediaCubeMetadata, IMessageBus systemBus) {\r
+            InitializeComponent();\r
+            lFileName.Text = selectedMetadata.ID;\r
+            this.selectedMetadata = selectedMetadata;\r
+            this.mediaCubeMetadata = mediaCubeMetadata;\r
+            this.systemBus = systemBus;\r
+            messageBus = new MessageBus();\r
+        }\r
+\r
+        private void RestoreMedia_Shown(object sender, EventArgs e) {\r
+            if (mediaCubeMetadata?.WSServer?.Address == null) {\r
+                MsgBox.Error("Hiányos a konfigurációs állomány. Nem található a MediaCubeMetadata.WSServer.Address beállítása.");\r
+                DialogResult = DialogResult.Cancel;\r
+                Close();\r
+                return;\r
+            }\r
+            messageBus.Subscribe<MediaCubeWSMessage>(m => {\r
+                BeginInvoke((Action)(() => {\r
+                    if (m.Finished) {\r
+                        if (m.Content?.Length > 0)\r
+                            systemBus.Send(m);\r
+                        Close();\r
+                    } else\r
+                        progressBar.Value = m.Data.As<int>("progress");\r
+                }));\r
+            });\r
+            api = new MediaCubeWSApi(mediaCubeMetadata.WSServer, messageBus);\r
+            string pattern = PatternNameMaker.Get(mediaCubeMetadata.RestoreNamePattern, null, null, null, null, null, null);\r
+            JObject data = new JObject {\r
+                { "targetPath", mediaCubeMetadata.ServerRestoreFolder },\r
+                { "targetNamePattern", pattern },\r
+                { "successRecipient", null },\r
+                { "killDateDays", mediaCubeMetadata.KillDateDays },\r
+                { "mediaCubeMedia", selectedMetadata.RedefineMedia.Serialize() }\r
+            };\r
+            logger.Info("Submitting {0}", data.ToString());\r
+            api.SubmitJob(mediaCubeMetadata.JobTemplate, data);\r
+        }\r
+\r
+        private void RestoreMedia_FormClosing(object sender, FormClosingEventArgs e) {\r
+            if (api != null)\r
+                api.Close();\r
+        }\r
+    }\r
+}\r
diff --git a/client/Maestro/RestoreMedia.resx b/client/Maestro/RestoreMedia.resx
new file mode 100644 (file)
index 0000000..29dcb1b
--- /dev/null
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<root>\r
+  <!-- \r
+    Microsoft ResX Schema \r
+    \r
+    Version 2.0\r
+    \r
+    The primary goals of this format is to allow a simple XML format \r
+    that is mostly human readable. The generation and parsing of the \r
+    various data types are done through the TypeConverter classes \r
+    associated with the data types.\r
+    \r
+    Example:\r
+    \r
+    ... ado.net/XML headers & schema ...\r
+    <resheader name="resmimetype">text/microsoft-resx</resheader>\r
+    <resheader name="version">2.0</resheader>\r
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>\r
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>\r
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">\r
+        <value>[base64 mime encoded serialized .NET Framework object]</value>\r
+    </data>\r
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">\r
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r
+        <comment>This is a comment</comment>\r
+    </data>\r
+                \r
+    There are any number of "resheader" rows that contain simple \r
+    name/value pairs.\r
+    \r
+    Each data row contains a name, and value. The row also contains a \r
+    type or mimetype. Type corresponds to a .NET class that support \r
+    text/value conversion through the TypeConverter architecture. \r
+    Classes that don't support this are serialized and stored with the \r
+    mimetype set.\r
+    \r
+    The mimetype is used for serialized objects, and tells the \r
+    ResXResourceReader how to depersist the object. This is currently not \r
+    extensible. For a given mimetype the value must be set accordingly:\r
+    \r
+    Note - application/x-microsoft.net.object.binary.base64 is the format \r
+    that the ResXResourceWriter will generate, however the reader can \r
+    read any of the formats listed below.\r
+    \r
+    mimetype: application/x-microsoft.net.object.binary.base64\r
+    value   : The object must be serialized with \r
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\r
+            : and then encoded with base64 encoding.\r
+    \r
+    mimetype: application/x-microsoft.net.object.soap.base64\r
+    value   : The object must be serialized with \r
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r
+            : and then encoded with base64 encoding.\r
+\r
+    mimetype: application/x-microsoft.net.object.bytearray.base64\r
+    value   : The object must be serialized into a byte array \r
+            : using a System.ComponentModel.TypeConverter\r
+            : and then encoded with base64 encoding.\r
+    -->\r
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">\r
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />\r
+    <xsd:element name="root" msdata:IsDataSet="true">\r
+      <xsd:complexType>\r
+        <xsd:choice maxOccurs="unbounded">\r
+          <xsd:element name="metadata">\r
+            <xsd:complexType>\r
+              <xsd:sequence>\r
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />\r
+              </xsd:sequence>\r
+              <xsd:attribute name="name" use="required" type="xsd:string" />\r
+              <xsd:attribute name="type" type="xsd:string" />\r
+              <xsd:attribute name="mimetype" type="xsd:string" />\r
+              <xsd:attribute ref="xml:space" />\r
+            </xsd:complexType>\r
+          </xsd:element>\r
+          <xsd:element name="assembly">\r
+            <xsd:complexType>\r
+              <xsd:attribute name="alias" type="xsd:string" />\r
+              <xsd:attribute name="name" type="xsd:string" />\r
+            </xsd:complexType>\r
+          </xsd:element>\r
+          <xsd:element name="data">\r
+            <xsd:complexType>\r
+              <xsd:sequence>\r
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />\r
+              </xsd:sequence>\r
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />\r
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />\r
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />\r
+              <xsd:attribute ref="xml:space" />\r
+            </xsd:complexType>\r
+          </xsd:element>\r
+          <xsd:element name="resheader">\r
+            <xsd:complexType>\r
+              <xsd:sequence>\r
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
+              </xsd:sequence>\r
+              <xsd:attribute name="name" type="xsd:string" use="required" />\r
+            </xsd:complexType>\r
+          </xsd:element>\r
+        </xsd:choice>\r
+      </xsd:complexType>\r
+    </xsd:element>\r
+  </xsd:schema>\r
+  <resheader name="resmimetype">\r
+    <value>text/microsoft-resx</value>\r
+  </resheader>\r
+  <resheader name="version">\r
+    <value>2.0</value>\r
+  </resheader>\r
+  <resheader name="reader">\r
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+  </resheader>\r
+  <resheader name="writer">\r
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
+  </resheader>\r
+</root>
\ No newline at end of file
index d72bad836fb7899c346ec8311de9119b1755337a..6dbb927fdceea4daaa972bc7551af9dfc4383483 100644 (file)
@@ -9,6 +9,7 @@ using NLog;
 using System;\r
 using System.Collections.Generic;\r
 using System.ComponentModel;\r
+using System.Diagnostics;\r
 using System.Drawing;\r
 using System.Linq;\r
 using System.Windows.Forms;\r
@@ -236,6 +237,8 @@ namespace Maestro.Sources {
                 item.Agency = token[EXTAGENCY]?.ToString();\r
                 DateTime? created = token.Value<DateTime?>(RECORDDATE);\r
                 item.Created = created ?? DateTime.MinValue;\r
+                if (item.Created == DateTime.MinValue)\r
+                    Debug.WriteLine("");\r
                 DateTime? modified = token.Value<DateTime?>(MODIFIED);\r
                 item.Modified = modified ?? DateTime.MinValue;\r
                 item.Frames = token.Value<int>(DURATION);\r
index 859e1b45bf7020de02c9108fac051c1bb13200c6..6cdeaa358444faf8cf6ca70857262f2d7bc74242 100644 (file)
@@ -13,6 +13,7 @@ namespace MaestroShared.Commons {
         private const string PATTERN_COMPUTERNAME = "%COMPUTERNAME%";\r
         private const string PATTERN_ID = "%ID%";\r
         private const string PATTERN_IDROOT = "%IDROOT%";\r
+        private const string PATTERN_GUID = "%GUID%";\r
         private const string PATTERN_SOURCENAME = "%SOURCENAME%";\r
         private const string PATTERN_SOURCESTARTID = "%SOURCESTARTID%";\r
         private const string PATTERN_TIMESTAMP = "%TIMESTAMP%";\r
@@ -41,11 +42,12 @@ namespace MaestroShared.Commons {
         }\r
 \r
         static public string Get(string pattern, string id, string inputName, string outputName, string userName, string text, DateTime? storedDateTime = null) {\r
-            string idRoot = id.Contains(UNDERSCORE) ? id.Split(UNDERSCORE[0])[0] : id;\r
+            string idRoot = id != null && id.Contains(UNDERSCORE) ? id.Split(UNDERSCORE[0])[0] : id;\r
             DateTime dt = storedDateTime == null ? DateTime.Now : (DateTime)storedDateTime;\r
             string result = pattern\r
                 .Replace(PATTERN_ID, id)\r
                 .Replace(PATTERN_IDROOT, idRoot)\r
+                .Replace(PATTERN_GUID, ((ShortGuid)Guid.NewGuid()).ToString())\r
                 .Replace(PATTERN_TIMESTAMP, dt.ToString(DATETIME_FORMAT, CultureInfo.InvariantCulture))\r
                 .Replace(PATTERN_DATESTAMP, dt.ToString(DATE_FORMAT_NODOTS, CultureInfo.InvariantCulture));\r
 \r
@@ -71,7 +73,7 @@ namespace MaestroShared.Commons {
 \r
             if (!String.IsNullOrEmpty(text))\r
                 result = result.Replace(PATTERN_TEXT, Normalize(text));\r
-            return result; \r
+            return result;\r
         }\r
 \r
 \r
diff --git a/client/MaestroShared/Commons/ShortGuid.cs b/client/MaestroShared/Commons/ShortGuid.cs
new file mode 100644 (file)
index 0000000..dc2da09
--- /dev/null
@@ -0,0 +1,244 @@
+using System;\r
+\r
+namespace MaestroShared.Commons {\r
+    /// <summary>\r
+    /// Represents a globally unique identifier (GUID) with a \r
+    /// shorter string value. Sguid\r
+    /// </summary>\r
+    public struct ShortGuid {\r
+        #region Static\r
+\r
+        /// <summary>\r
+        /// A read-only instance of the ShortGuid class whose value \r
+        /// is guaranteed to be all zeroes. \r
+        /// </summary>\r
+        public static readonly ShortGuid Empty = new ShortGuid(Guid.Empty);\r
+\r
+        #endregion\r
+\r
+        #region Fields\r
+\r
+        Guid _guid;\r
+        string _value;\r
+\r
+        #endregion\r
+\r
+        #region Contructors\r
+\r
+        /// <summary>\r
+        /// Creates a ShortGuid from a base64 encoded string\r
+        /// </summary>\r
+        /// <param name="value">The encoded guid as a \r
+        /// base64 string</param>\r
+        public ShortGuid(string value) {\r
+            _value = value;\r
+            _guid = Decode(value);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Creates a ShortGuid from a Guid\r
+        /// </summary>\r
+        /// <param name="guid">The Guid to encode</param>\r
+        public ShortGuid(Guid guid) {\r
+            _value = Encode(guid);\r
+            _guid = guid;\r
+        }\r
+\r
+        #endregion\r
+\r
+        #region Properties\r
+\r
+        /// <summary>\r
+        /// Gets/sets the underlying Guid\r
+        /// </summary>\r
+        public Guid Guid {\r
+            get { return _guid; }\r
+            set {\r
+                if (value != _guid) {\r
+                    _guid = value;\r
+                    _value = Encode(value);\r
+                }\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// Gets/sets the underlying base64 encoded string\r
+        /// </summary>\r
+        public string Value {\r
+            get { return _value; }\r
+            set {\r
+                if (value != _value) {\r
+                    _value = value;\r
+                    _guid = Decode(value);\r
+                }\r
+            }\r
+        }\r
+\r
+        #endregion\r
+\r
+        #region ToString\r
+\r
+        /// <summary>\r
+        /// Returns the base64 encoded guid as a string\r
+        /// </summary>\r
+        /// <returns></returns>\r
+        public override string ToString() {\r
+            return _value;\r
+        }\r
+\r
+        #endregion\r
+\r
+        #region Equals\r
+\r
+        /// <summary>\r
+        /// Returns a value indicating whether this instance and a \r
+        /// specified Object represent the same type and value.\r
+        /// </summary>\r
+        /// <param name="obj">The object to compare</param>\r
+        /// <returns></returns>\r
+        public override bool Equals(object obj) {\r
+            if (obj is ShortGuid)\r
+                return _guid.Equals(((ShortGuid)obj)._guid);\r
+            if (obj is Guid)\r
+                return _guid.Equals((Guid)obj);\r
+            if (obj is string)\r
+                return _guid.Equals(((ShortGuid)obj)._guid);\r
+            return false;\r
+        }\r
+\r
+        #endregion\r
+\r
+        #region GetHashCode\r
+\r
+        /// <summary>\r
+        /// Returns the HashCode for underlying Guid.\r
+        /// </summary>\r
+        /// <returns></returns>\r
+        public override int GetHashCode() {\r
+            return _guid.GetHashCode();\r
+        }\r
+\r
+        #endregion\r
+\r
+        #region NewGuid\r
+\r
+        /// <summary>\r
+        /// Initialises a new instance of the ShortGuid class\r
+        /// </summary>\r
+        /// <returns></returns>\r
+        public static ShortGuid NewGuid() {\r
+            return new ShortGuid(Guid.NewGuid());\r
+        }\r
+\r
+        #endregion\r
+\r
+        #region Encode\r
+\r
+        /// <summary>\r
+        /// Creates a new instance of a Guid using the string value, \r
+        /// then returns the base64 encoded version of the Guid.\r
+        /// </summary>\r
+        /// <param name="value">An actual Guid string (i.e. not a ShortGuid)</param>\r
+        /// <returns></returns>\r
+        public static string Encode(string value) {\r
+            Guid guid = new Guid(value);\r
+            return Encode(guid);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Encodes the given Guid as a base64 string that is 22 \r
+        /// characters long.\r
+        /// </summary>\r
+        /// <param name="guid">The Guid to encode</param>\r
+        /// <returns></returns>\r
+        public static string Encode(Guid guid) {\r
+            string encoded = Convert.ToBase64String(guid.ToByteArray());\r
+            encoded = encoded\r
+                .Replace("/", "_")\r
+                .Replace("+", "-");\r
+            return encoded.Substring(0, 22);\r
+        }\r
+\r
+        #endregion\r
+\r
+        #region Decode\r
+\r
+        /// <summary>\r
+        /// Decodes the given base64 string\r
+        /// </summary>\r
+        /// <param name="value">The base64 encoded string of a Guid</param>\r
+        /// <returns>A new Guid</returns>\r
+        public static Guid Decode(string value) {\r
+            value = value\r
+                .Replace("_", "/")\r
+                .Replace("-", "+");\r
+            byte[] buffer = Convert.FromBase64String(value + "==");\r
+            return new Guid(buffer);\r
+        }\r
+\r
+        #endregion\r
+\r
+        #region Operators\r
+\r
+        /// <summary>\r
+        /// Determines if both ShortGuids have the same underlying \r
+        /// Guid value.\r
+        /// </summary>\r
+        /// <param name="x"></param>\r
+        /// <param name="y"></param>\r
+        /// <returns></returns>\r
+        public static bool operator ==(ShortGuid x, ShortGuid y) {\r
+            if ((object)x == null) return (object)y == null;\r
+            return x._guid == y._guid;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Determines if both ShortGuids do not have the \r
+        /// same underlying Guid value.\r
+        /// </summary>\r
+        /// <param name="x"></param>\r
+        /// <param name="y"></param>\r
+        /// <returns></returns>\r
+        public static bool operator !=(ShortGuid x, ShortGuid y) {\r
+            return !(x == y);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Implicitly converts the ShortGuid to it's string equivilent\r
+        /// </summary>\r
+        /// <param name="shortGuid"></param>\r
+        /// <returns></returns>\r
+        public static implicit operator string(ShortGuid shortGuid) {\r
+            return shortGuid._value;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Implicitly converts the ShortGuid to it's Guid equivilent\r
+        /// </summary>\r
+        /// <param name="shortGuid"></param>\r
+        /// <returns></returns>\r
+        public static implicit operator Guid(ShortGuid shortGuid) {\r
+            return shortGuid._guid;\r
+        }\r
+\r
+        /// <summary>\r
+        /// Implicitly converts the string to a ShortGuid\r
+        /// </summary>\r
+        /// <param name="shortGuid"></param>\r
+        /// <returns></returns>\r
+        public static implicit operator ShortGuid(string shortGuid) {\r
+            return new ShortGuid(shortGuid);\r
+        }\r
+\r
+        /// <summary>\r
+        /// Implicitly converts the Guid to a ShortGuid \r
+        /// </summary>\r
+        /// <param name="guid"></param>\r
+        /// <returns></returns>\r
+        public static implicit operator ShortGuid(Guid guid) {\r
+            return new ShortGuid(guid);\r
+        }\r
+\r
+        #endregion\r
+    }\r
+}\r
index 8427af26d5ddef74fcd461ad28ee41e8c207cbf2..1a31301ad474b4524962e7190ad3cbb899364ec4 100644 (file)
@@ -190,12 +190,19 @@ namespace MaestroShared.Configuration {
     public class TrafficMetadata : MetadataProvider {\r
         public ProjectSettings ProjectSettings { get; set; }\r
         public string FunctionName { get; set; }\r
-\r
+        public int Version { get; set; }\r
     }\r
 \r
     public class MediaCubeMetadata : MetadataProvider {\r
         public string MetadataTitleFormat { get; set; }\r
         public string MetadataIDFormat { get; set; }\r
+        public Connection WSServer { get; set; }\r
+        public string JobTemplate { get; set; }\r
+        public int KillDateDays { get; set; }\r
+        public Uri ArchiveFolder { get; set; }\r
+        public Uri RestoreFolder { get; set; }\r
+        public string RestoreNamePattern { get; set; }\r
+        public string ServerRestoreFolder { get; set; }\r
     }\r
 \r
     public class UISettings {\r
index a2b69961d3dfda9ef2d3b496dd435ec7b35d42af..2ce64179fa86a206c4ebbc64819969ff7c0e3b70 100644 (file)
@@ -50,6 +50,7 @@
     <PlatformTarget>x64</PlatformTarget>\r
     <ErrorReport>prompt</ErrorReport>\r
     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>\r
+    <Deterministic>true</Deterministic>\r
   </PropertyGroup>\r
   <ItemGroup>\r
     <Reference Include="FluentFTP, Version=19.1.2.0, Culture=neutral, PublicKeyToken=f4af092b1d8df44f, processorArchitecture=MSIL">\r
     <Compile Include="Targets\FTPTargetProcessor.cs" />\r
     <Compile Include="Targets\FXPTargetProcessor.cs" />\r
     <Compile Include="Targets\ITargetProcessor.cs" />\r
+    <Compile Include="Commons\ShortGuid.cs" />\r
     <Compile Include="Targets\Strings.cs" />\r
     <Compile Include="Targets\TargetProcessor.cs" />\r
     <Compile Include="Targets\TargetProcessorParameter.cs" />\r
   <ItemGroup>\r
     <None Include="Resources\ic_fiber_manual_record_black_24dp_2x.png" />\r
   </ItemGroup>\r
-  <ItemGroup>\r
-    <None Include="Resources\ic_playlist_add_check_black_24dp_1x.png" />\r
-  </ItemGroup>\r
   <ItemGroup>\r
     <None Include="Resources\ic_playlist_add_check_black_24dp_1x_green1.png" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="Resources\outline_backup_black_24dp.png" />\r
   </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="Resources\baseline_playlist_play_black_18dp.png" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="Resources\ic_play_for_work_black_18dp.png" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="Resources\ic_play_for_work_black_24dp.png" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="Resources\ic_playlist_add_check_black_24dp_1x.png" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="Resources\ic_playlist_add_black_18dp.png" />\r
+  </ItemGroup>\r
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
 </Project>
\ No newline at end of file
index 9d0dee8a3fbfacccd0b0b9841130e33da7ee83ce..695869ed76023706921c49482c9eadbd2c7aa72e 100644 (file)
@@ -20,4 +20,16 @@ namespace MaestroShared.Model {
         public long id;\r
         public DateTime? created;\r
     }\r
+\r
+    public class Media {\r
+        public long id;\r
+        public DateTime archived;\r
+        public DateTime created;\r
+        public string description;\r
+        public string houseId;\r
+        public long itemId;\r
+        public long length;\r
+        public string title;\r
+    }\r
+\r
 }\r
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 (file)
index 0000000..6c3d0a3
Binary files /dev/null and b/client/MaestroShared/Resources/baseline_playlist_play_black_18dp.png differ
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 (file)
index 0000000..daeb0b9
Binary files /dev/null and b/client/MaestroShared/Resources/ic_play_for_work_black_18dp.png differ
diff --git a/client/MaestroShared/Resources/ic_play_for_work_black_24dp.png b/client/MaestroShared/Resources/ic_play_for_work_black_24dp.png
new file mode 100644 (file)
index 0000000..da5fdd7
Binary files /dev/null and b/client/MaestroShared/Resources/ic_play_for_work_black_24dp.png differ
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 (file)
index 0000000..241f42a
Binary files /dev/null and b/client/MaestroShared/Resources/ic_playlist_add_black_18dp.png differ
index 868c472e7b428a7db75dc6fb0895f999804fea91..835e2cac4397db59bb9a711e822d97c4a66a5406 100644 (file)
@@ -150,13 +150,14 @@ namespace MaestroShared.Targets {
         }\r
 \r
         protected FtpClient CreateClient(Connection connection) {\r
+\r
             Uri address = connection.Address;\r
             string addr = address.Host;\r
 \r
             IPHostEntry hostEntry = Dns.GetHostEntry(addr);\r
             if (hostEntry != null && hostEntry.AddressList.Length > 0)\r
                 addr = hostEntry.AddressList[0].ToString();\r
-\r
+            logger.Info("Remote address is {0}", addr);\r
             FtpClient result = new FtpClient() {\r
                 Host = addr,\r
                 Port = address.Port,\r
index de5433027b5b14c963055f334be4118288702040..952532ed30c3fc5ac5c47d06359f2f4d9c718ad8 100644 (file)
@@ -1,15 +1,14 @@
 using LinkDotNet.MessageHandling.Contracts;\r
 using MaestroShared.Interfaces;\r
 using MaestroShared.MessageBus;\r
+using MaestroShared.Model;\r
 using Newtonsoft.Json;\r
-using Newtonsoft.Json.Serialization;\r
+using Newtonsoft.Json.Linq;\r
 using NLog;\r
 using RestSharp;\r
 using RestSharp.Authenticators;\r
-using System;\r
 using System.Diagnostics;\r
 using System.Net;\r
-using System.Runtime.Serialization;\r
 \r
 namespace MediaCubeClient {\r
     public class MediaCubeMessage : MaestroMessage {\r
@@ -18,14 +17,11 @@ namespace MediaCubeClient {
     }\r
 \r
     public class MediaCubeApi : IMediaCubeApi {\r
-        private const string DATEFORMAT = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK";\r
         private static Logger logger = LogManager.GetCurrentClassLogger();\r
         private RestClient client;\r
-        private JsonSerializerSettings serializerSettings;\r
         private string user;\r
         private string pwd;\r
         private IMessageBus messageBus;\r
-        private object template;\r
 \r
         public MediaCubeApi(string address, string user, string pwd, int timeout, IMessageBus messageBus) {\r
             this.user = user;\r
@@ -35,16 +31,11 @@ namespace MediaCubeClient {
                 Authenticator = new HttpBasicAuthenticator(user, pwd),\r
                 Timeout = timeout\r
             };\r
-            serializerSettings = new JsonSerializerSettings {\r
-                TypeNameHandling = TypeNameHandling.Objects,\r
-                SerializationBinder = new TypeNameSerializationBinder(),\r
-                DateFormatString = DATEFORMAT\r
-            };\r
         }\r
 \r
         public T Create<T>(object data) {\r
             var request = new RestRequest("create", Method.POST);\r
-            string body = JsonConvert.SerializeObject(data, serializerSettings);\r
+            string body = data.Serialize();\r
             //Debug.WriteLine(body);\r
             request.AddParameter("application/json", body, ParameterType.RequestBody);\r
             var response = client.Execute(request);\r
@@ -67,6 +58,20 @@ namespace MediaCubeClient {
                 return;\r
         }\r
 \r
+        public Media GetMediaByHouseId(string mediaHouseId) {\r
+            var request = new RestRequest("media", Method.GET);\r
+            request.AddQueryParameter("mediaHouseId", mediaHouseId);\r
+            var response = client.Execute(request);\r
+            if (response.StatusCode != HttpStatusCode.OK || response.Content.Length < 1) {\r
+                messageBus.Send(new MediaCubeMessage("Hiba a lekérdezésben. A rendszer üzenete: " + response.ErrorMessage));\r
+                return null;\r
+            }\r
+            JObject media = JObject.Parse(response.Content);\r
+            if (media != null)\r
+                return media.Deserialize<Media>();\r
+\r
+            return null;\r
+        }\r
 \r
         public void Item() {\r
             var request = new RestRequest("item", Method.GET);\r
@@ -77,15 +82,3 @@ namespace MediaCubeClient {
 \r
 }\r
 \r
-public class TypeNameSerializationBinder : SerializationBinder, ISerializationBinder {\r
-\r
-    public override void BindToName(Type serializedType, out string assemblyName, out string typeName) {\r
-        assemblyName = null;\r
-        typeName = serializedType.Name;\r
-    }\r
-\r
-    public override Type BindToType(string assemblyName, string typeName) {\r
-        string resolvedTypeName = typeName;\r
-        return Type.GetType(resolvedTypeName, true);\r
-    }\r
-}\r
index b59eb955e8400d49eba1f81fc9352866dc9de71e..03a2b9e3a29bb46fd4d47f8376c74f8d78bb85a1 100644 (file)
@@ -75,6 +75,7 @@
     <PlatformTarget>x64</PlatformTarget>\r
     <ErrorReport>prompt</ErrorReport>\r
     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>\r
+    <Deterministic>true</Deterministic>\r
   </PropertyGroup>\r
   <ItemGroup>\r
     <Reference Include="LinkDotNet.MessageHandling.Contracts, Version=0.2.0.0, Culture=neutral, processorArchitecture=MSIL">\r
     </Reference>\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <Compile Include="MediaCubeJsonConvert.cs" />\r
     <Compile Include="MediaCubeWSApi.cs" />\r
     <Compile Include="MediaCubeApi.cs" />\r
     <Compile Include="MediaCubeStrings.cs" />\r
diff --git a/client/MediaCubeClient/MediaCubeJsonConvert.cs b/client/MediaCubeClient/MediaCubeJsonConvert.cs
new file mode 100644 (file)
index 0000000..c0e8f9c
--- /dev/null
@@ -0,0 +1,43 @@
+using Newtonsoft.Json;\r
+using Newtonsoft.Json.Serialization;\r
+using System;\r
+using System.Runtime.Serialization;\r
+\r
+namespace MediaCubeClient {\r
+\r
+    public static class MediaCubeJsonConvert {\r
+        private const string DATEFORMAT = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK";\r
+        private static readonly JsonSerializerSettings serializerSettings;\r
+\r
+        static MediaCubeJsonConvert() {\r
+            serializerSettings = new JsonSerializerSettings {\r
+                TypeNameHandling = TypeNameHandling.Objects,\r
+                SerializationBinder = new TypeNameSerializationBinder(),\r
+                DateFormatString = DATEFORMAT\r
+            };\r
+\r
+        }\r
+\r
+        public static string Serialize(this object data) {\r
+            return JsonConvert.SerializeObject(data, serializerSettings);\r
+        }\r
+\r
+        public static T Deserialize<T>(this object data) {\r
+            return JsonConvert.DeserializeObject<T>(data.ToString(), serializerSettings);\r
+        }\r
+    }\r
+\r
+    public class TypeNameSerializationBinder : SerializationBinder, ISerializationBinder {\r
+\r
+        public override void BindToName(Type serializedType, out string assemblyName, out string typeName) {\r
+            assemblyName = null;\r
+            typeName = serializedType.Name;\r
+        }\r
+\r
+        public override Type BindToType(string assemblyName, string typeName) {\r
+            string resolvedTypeName = "MaestroShared.Model." + typeName + ", MaestroShared";\r
+            return Type.GetType(resolvedTypeName, true);\r
+        }\r
+    }\r
+\r
+}\r
index bdf7be3b3c79a5dce74fcea9ea1bc9660ed1c206..08f50b0797c94de600f5677cfb32dbfb1aaae3e0 100644 (file)
@@ -1,4 +1,5 @@
 using LinkDotNet.MessageHandling.Contracts;\r
+using MaestroShared.Configuration;\r
 using MaestroShared.MessageBus;\r
 using Newtonsoft.Json;\r
 using Newtonsoft.Json.Linq;\r
@@ -29,11 +30,13 @@ namespace MediaCubeClient {
         private const string DATEFORMAT = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK";\r
         private static NLog.Logger logger = LogManager.GetCurrentClassLogger();\r
         private JsonSerializerSettings serializerSettings;\r
-        private readonly string address;\r
         private IMessageBus messageBus;\r
+        private WebSocket ws;\r
 \r
-        public MediaCubeWSApi(string address, IMessageBus messageBus) {\r
-            this.address = address;\r
+        public MediaCubeWSApi(Connection connection, IMessageBus messageBus) {\r
+            ws = new WebSocket(connection.Address.ToString()) {\r
+                WaitTime = TimeSpan.FromMilliseconds(connection.Timeout)\r
+            };\r
             this.messageBus = messageBus;\r
             serializerSettings = new JsonSerializerSettings {\r
                 TypeNameHandling = TypeNameHandling.Objects,\r
@@ -58,15 +61,14 @@ namespace MediaCubeClient {
                 }\r
         */\r
         public void SubmitJob(string template, JObject parameters) {\r
-            WebSocket ws = new WebSocket(address);\r
             ws.SslConfiguration.ServerCertificateValidationCallback = (s, c, ch, e) => {\r
                 return true;\r
             };\r
             ws.OnMessage += (s, e) => {\r
                 JObject jo = JObject.Parse(e.Data);\r
-                if (true.Equals(jo.As<bool>(MediaCubeStrings.ERROR))) {\r
+                if ("SUSPENDED".Equals(jo.As<string>(MediaCubeStrings.STATUS))) {\r
                     ws.Close();\r
-                    messageBus.Send(new MediaCubeWSMessage("Hiba a MediaCube szolgáltatás használata során. A rendszer üzenete: " + jo.As<string>(MediaCubeStrings.ERROR)));\r
+                    messageBus.Send(new MediaCubeWSMessage("Hiba a MediaCube szolgáltatás használata során. Rendszerüzenet: " + jo.As<string>(MediaCubeStrings.ERROR)));\r
                     return;\r
                 }\r
                 if ("FINISHED".Equals(jo.As<string>(MediaCubeStrings.STATUS))) {\r
@@ -78,7 +80,7 @@ namespace MediaCubeClient {
             };\r
             ws.OnError += (s, e) => {\r
                 ws.Close();\r
-                messageBus.Send(new MediaCubeWSMessage("Hiba a MediaCube szolgáltatás használata során. A rendszer üzenete: " + e.Message));\r
+                messageBus.Send(new MediaCubeWSMessage("Hiba a MediaCube szolgáltatás használata során. Rendszerüzenet: " + e.Message));\r
             };\r
 \r
             try {\r
@@ -92,13 +94,17 @@ namespace MediaCubeClient {
                 data.Add(MediaCubeStrings.ACTION, JToken.FromObject(MediaCubeStrings.STARTJOB));\r
                 data.Add(MediaCubeStrings.TEMPLATE, JToken.FromObject(template));\r
                 data.Add(MediaCubeStrings.PARAMETERS, JToken.FromObject(parameters));\r
-                ws.Send(data.ToString());\r
+                ws.Send(data.Serialize());\r
             } catch (Exception e) {\r
                 ws.Close();\r
                 messageBus.Send(new MediaCubeWSMessage("Sikertelen MediaCube folyamatindítás."));\r
             }\r
         }\r
 \r
+        public void Close() {\r
+            if (ws != null)\r
+                ws.Close();\r
+        }\r
 \r
     }\r
 \r
index 73dd62c3c035c671229206097a83d39e025fec3e..b004926bea9f9a6fed2b35a1ab0ed707b6d7f5cc 100644 (file)
@@ -19,7 +19,7 @@
 <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
 <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console"/>\r
 <stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>\r
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Djavax.ws.rs.ext.RuntimeDelegate=org.jboss.resteasy.spi.ResteasyProviderFactory&#13;&#10;-Dorg.eclipse.epp.logging.aeri.skipReports=true &#13;&#10;-Declipse.ignoreApp=true &#13;&#10;-Dosgi.noShutdown=true&#13;&#10;-Djobengine.jobsteps.root=&quot;${workspace_loc}/user.jobengine.executors/config&quot;&#13;&#10;-Djobengine.jobtemplates.root=&quot;${workspace_loc}/user.jobengine.executors/jobtemplates&quot;&#13;&#10;-Djobengine.db.url=jdbc:db2://10.10.1.27:50000/mc:retrieveMessagesFromServerOnGetMessage=true;&#13;&#10;-Djobengine.db.user=db2admin&#13;&#10;-Djobengine.db.password=password&#13;&#10;-Djobengine.loglevel=INFO&#13;&#10;-Dlog4j.configurationFile=&quot;${workspace_loc}/-configuration/log4j2.xml&quot;&#13;&#10;-Djobengine.jobsteps.alternate.root=&quot;${workspace_loc}/user.jobengine.executors/bin/&quot;&#13;&#10;-Djetty.home=&quot;${workspace_loc:}/-configuration/jetty&quot;&#13;&#10;-Djetty.etc.config.urls=etc/user-jetty.xml,etc/user-jetty-ssl.xml,etc/user-jetty-ssl-context.xml,,etc/user-jetty-http.xml,etc/user-jetty-https.xml&#13;&#10;-Dorg.eclipse.jetty.webapp.basetempdir=c:\temp\jetty&#13;&#10;-Djava.io.tmpdir=c:\temp\jetty&#13;&#10;-Djobengine.octopus.api.address=http://10.10.1.11/api/v1&#13;&#10;-Djobengine.octopus.api.user=mam&#13;&#10;-Djobengine.octopus.api.password=napocska&#13;&#10;-Djobengine.nosql.db.url=jdbc:db2://10.10.1.27:50000/mc:retrieveMessagesFromServerOnGetMessage=true;&#13;&#10;-Djobengine.nosql.db.user=db2admin&#13;&#10;-Djobengine.nosql.db.password=password&#13;&#10;-Djobengine.nosql.db.schema=test&#13;&#10;-Djobengine.selenio.address=http://10.10.1.71:44000/TranscodeMgrWS?wsdl&#13;&#10;-Djobengine.selenio.projectfilepath=\\10.10.1.71\Data\Blueprints\MP4_H264_AAC.zenium&#13;&#10;-Djobengine.jobscheduling.config=&quot;${workspace_loc}/-configuration/scheduledjobs.json&quot;&#13;&#10;-Dnexio.host=192.168.10.105&#13;&#10;-Djobengine.nexio.name=testnexioclips&#13;&#10;-Dnexio.disable=true&#13;&#10;-Djobengine.octopus.rundowns.name=rundowns&#13;&#10;-Djobengine.octopus.storyfolders.name=storyfolders&#13;&#10;-Djobengine.octopus.stories.name=stories&#13;&#10;-Dmediacube.auth.location=&quot;${workspace_loc}/-configuration/mediacube-auth.properties&quot;"/>\r
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Djavax.ws.rs.ext.RuntimeDelegate=org.jboss.resteasy.spi.ResteasyProviderFactory&#13;&#10;-Dorg.eclipse.epp.logging.aeri.skipReports=true &#13;&#10;-Declipse.ignoreApp=true &#13;&#10;-Dosgi.noShutdown=true&#13;&#10;-Djobengine.jobsteps.root=&quot;${workspace_loc}/user.jobengine.executors/config&quot;&#13;&#10;-Djobengine.jobtemplates.root=&quot;${workspace_loc}/user.jobengine.executors/jobtemplates&quot;&#13;&#10;-Djobengine.db.url=jdbc:db2://10.10.1.27:50000/mc:retrieveMessagesFromServerOnGetMessage=true;&#13;&#10;-Djobengine.db.user=db2admin&#13;&#10;-Djobengine.db.password=password&#13;&#10;-Djobengine.loglevel=INFO&#13;&#10;-Dlog4j.configurationFile=&quot;${workspace_loc}/-configuration/log4j2.xml&quot;&#13;&#10;-Djobengine.jobsteps.alternate.root=&quot;${workspace_loc}/user.jobengine.executors/bin/&quot;&#13;&#10;-Djetty.home=&quot;${workspace_loc:}/-configuration/jetty&quot;&#13;&#10;-Djetty.etc.config.urls=etc/user-jetty.xml,etc/user-jetty-ssl.xml,etc/user-jetty-ssl-context.xml,,etc/user-jetty-http.xml,etc/user-jetty-https.xml&#13;&#10;-Dorg.eclipse.jetty.webapp.basetempdir=c:\temp\jetty&#13;&#10;-Djava.io.tmpdir=c:\temp\jetty&#13;&#10;-Djobengine.octopus.api.address=http://10.10.1.11/api/v1&#13;&#10;-Djobengine.octopus.api.user=mam&#13;&#10;-Djobengine.octopus.api.password=napocska&#13;&#10;-Djobengine.nosql.db.url=jdbc:db2://10.10.1.27:50000/mc:retrieveMessagesFromServerOnGetMessage=true;&#13;&#10;-Djobengine.nosql.db.user=db2admin&#13;&#10;-Djobengine.nosql.db.password=password&#13;&#10;-Djobengine.nosql.db.schema=test&#13;&#10;-Djobengine.selenio.address=http://10.10.1.71:44000/TranscodeMgrWS?wsdl&#13;&#10;-Djobengine.selenio.projectfilepath=\\10.10.1.71\Data\Blueprints\MP4_H264_AAC.zenium&#13;&#10;-Djobengine.jobscheduling.config=&quot;${workspace_loc}/-configuration/scheduledjobs.json&quot;&#13;&#10;-Djobengine.nexio.db.url=jdbc:sqlserver://10.10.1.59:1433;databaseName=NXDB;&#13;&#10;-Djobengine.nexio.db.user=sa&#13;&#10;-Djobengine.nexio.db.password=resolve&#13;&#10;-Dnexio.host=10.10.1.55&#13;&#10;-Djobengine.nexio.name=testnexioclips&#13;&#10;-Dnexio.useMOSGateway=true&#13;&#10;-Dnexio.disable=true&#13;&#10;-Djobengine.octopus.rundowns.name=rundowns&#13;&#10;-Djobengine.octopus.storyfolders.name=storyfolders&#13;&#10;-Djobengine.octopus.stories.name=stories&#13;&#10;-Dmediacube.auth.location=&quot;${workspace_loc}/-configuration/mediacube-auth.properties&quot;"/>\r
 <stringAttribute key="pde.version" value="3.3"/>\r
 <booleanAttribute key="show_selected_only" value="false"/>\r
 <stringAttribute key="target_bundles" value="cglib@default:default,com.auth0.java-jwt@default:default,com.fasterxml.jackson.core.jackson-annotations@default:default,com.fasterxml.jackson.core.jackson-core@default:default,com.fasterxml.jackson.core.jackson-databind@default:default,com.fasterxml.jackson.datatype.jackson-datatype-joda@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-base@default:default,com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider@default:default,com.fasterxml.jackson.module.jackson-module-jaxb-annotations@default:default,com.google.guava@default:default,com.ibm.db2jcc4@default:default,com.ibm.nosql@default:default,com.microsoft.sqlserver.sqljdbc@default:default,com.sun.el.javax.el@default:default,commons-logging@default:default,humble.video.noarch@default:default,humble.video.windows@default:default,javax.annotation-api@default:default,javax.inject@default:default,javax.mail@default:default,javax.servlet-api@default:default,javax.servlet.jsp-api@default:default,javax.validation.api@default:default,javax.ws.rs-api@default:default,jcifs@default:default,joda-time@default:default,org.apache.aries.spifly.dynamic.bundle@default:default,org.apache.aries.util@default:default,org.apache.commons.beanutils@default:default,org.apache.commons.codec@default:default,org.apache.commons.collections@default:default,org.apache.commons.digester@default:default,org.apache.commons.io@default:default,org.apache.commons.lang3@default:default,org.apache.commons.lang@default:default,org.apache.commons.logging@default:default,org.apache.commons.net@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.apache.jasper.glassfish@default:default,org.apache.logging.log4j.api@1:true,org.apache.logging.log4j.core@default:default,org.apache.logging.log4j.slf4j-impl@default:default,org.apache.servicemix.bundles.quartz@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.util@default:default,org.eclipse.jetty.client@default:default,org.eclipse.jetty.deploy@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.jsp@default:default,org.eclipse.jetty.osgi.boot.jsp@default:false,org.eclipse.jetty.osgi.boot@default:true,org.eclipse.jetty.schemas@default:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.jetty.webapp@default:default,org.eclipse.jetty.websocket.api@default:default,org.eclipse.jetty.websocket.client@default:default,org.eclipse.jetty.websocket.common@default:default,org.eclipse.jetty.websocket.server@default:default,org.eclipse.jetty.websocket.servlet@default:default,org.eclipse.jetty.xml@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.hamcrest.core@default:default,org.jboss.resteasy.client@default:default,org.jboss.resteasy.jaxrs@default:default,org.jmock.junit4@default:default,org.jmock@default:default,org.junit@default:default,org.objectweb.asm.commons@default:default,org.objectweb.asm.tree@default:default,org.objectweb.asm@default:default,slf4j.api@default:default,slf4j.simple@default:false"/>\r
index 1d7487a9580fb33ef7dc452d720c8a0b32e0f758..e1d591d4950627a181454ef1bcf17ba946f1cecc 100644 (file)
@@ -29,6 +29,7 @@
        <executor className="user.jobengine.server.steps.TSMBackupStep" maxConcurrent="1"/>\r
        <executor className="user.jobengine.server.steps.TSMExtendedRetrieveStep" maxConcurrent="1" />\r
        <executor className="user.jobengine.server.steps.TSMRestoreStep" maxConcurrent="1"/>\r
+       <executor className="user.jobengine.server.steps.TSMSystemRestoreStep" maxConcurrent="1"/>\r
        <executor className="user.jobengine.server.steps.TSMRetrieveMissingMaterialStep" maxConcurrent="1"/>\r
        <executor className="user.jobengine.server.steps.UploadRecordingToNexioStep" maxConcurrent="1"/>\r
        <executor className="user.jobengine.server.steps.MediaToolStep" maxConcurrent="1"/>\r
index d8088ad62a13a39e9215d7e6c1557905877281ba..1890feed769ca148be4c29daab028019e6095610 100644 (file)
@@ -10,7 +10,7 @@
                </parameters>\r
        </declarations>\r
        <commands>\r
-               <calljobstep id="id1" type="user.jobengine.server.steps.TSMRestoreStep" weight="1">\r
+               <calljobstep id="id1" type="user.jobengine.server.steps.TSMSystemRestoreStep" weight="1">\r
                        <inputs>\r
                                <input>\r
                                        <parameter name="mediaCubeMedia" />\r
index 99c266500bfb1f9ee23d8da72e0ed2ba8b2b2881..4dbef3810a87bc74c77aff845a1a3abd31ff6edd 100644 (file)
@@ -141,7 +141,13 @@ public class CleanupMountedLocationStep extends JobStep implements FileVisitor<P
        private List<Path> getKillDateFiles(Path filePath) {\r
                String killDateFilePattern = String.format("%s.*%s", filePath.getFileName().toString(), KILLDATEEXT);\r
                List<Path> result = new ArrayList<>();\r
-               Path statusPath = Paths.get(filePath.getParent().toString(), STATUSFOLDER);\r
+               Path statusPath = null;\r
+               try {\r
+                       statusPath = Paths.get(filePath.getParent().toString(), STATUSFOLDER);\r
+               } catch (Exception e) {\r
+                       logger.catching(e);\r
+                       return null;\r
+               }\r
                File statusPathFile = statusPath.toFile();\r
                if (statusPathFile.exists() && statusPathFile.isDirectory()) {\r
                        try (DirectoryStream<Path> stream = Files.newDirectoryStream(statusPath, killDateFilePattern)) {\r
@@ -183,7 +189,7 @@ public class CleanupMountedLocationStep extends JobStep implements FileVisitor<P
 \r
                logger.info("Checking {}", filePath);\r
                List<Path> killDateFiles = getKillDateFiles(filePath);\r
-               if (killDateFiles.size() == 0) {\r
+               if (killDateFiles == null || killDateFiles.size() == 0) {\r
                        logger.warn(marker, "A {} fájlhoz nem található 'killdate' állomány.", filePath);\r
                        return;\r
                }\r
index 1aaa8e1057efe9ce8d68e49a938ea1d849595fbe..0b98ad33ba5c14c613634e225ae3e363b9bbe30c 100644 (file)
@@ -29,6 +29,7 @@ import com.ibm.nosql.json.api.QueryBuilder;
 import user.commons.CalendarUtils;\r
 import user.commons.ListUtils;\r
 import user.commons.StoreUri;\r
+import user.commons.nexio.NexioDispatcher;\r
 import user.commons.nosql.NoSQLUtils;\r
 import user.commons.octopus.IOctopusAPI;\r
 import user.commons.octopus.OctopusAPI;\r
@@ -49,7 +50,7 @@ public class CopyForArchiveNEXIORecordingsStep extends JobStep {
        private static final String XML_EXT = ".xml";\r
        private static final String DURATION = "duration";\r
        private static final String MXFEXT = ".MXF";\r
-       private static final String NEXIOCLIPS = "nexioclips";\r
+       private static final String NEXIOCLIPS = NexioDispatcher.CLIP_COLLECTION_NAME;\r
        private static final String LONGNAMEID = "longnameid";\r
        private static final String EXTAGENCY = "extagency";\r
        private static final String RECORDDATE = "recorddate";\r
@@ -229,9 +230,9 @@ public class CopyForArchiveNEXIORecordingsStep extends JobStep {
                                                        return null;\r
                                                }\r
                                        }\r
-               \r
+\r
                                        RundownArchive item2 = null;\r
-               \r
+\r
                                        try {\r
                                                item2 = processRundow(rundown, clipName, duration);\r
                                        } catch (Exception e) {\r
@@ -240,7 +241,7 @@ public class CopyForArchiveNEXIORecordingsStep extends JobStep {
                                                                e.getMessage());\r
                                                return null;\r
                                        }\r
-               \r
+\r
                                        result.setItemTitle(result.getItemTitle() + " + NAPIAKT");\r
                                        StoryArchive storyArchive = result.getStoryArchives().get(0);\r
                                        StoryArchive storyArchive2 = item2.getStoryArchives().get(0);\r
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 (file)
index 0000000..314cd8e
--- /dev/null
@@ -0,0 +1,143 @@
+package user.jobengine.server.steps;\r
+\r
+import java.io.IOException;\r
+import java.util.List;\r
+\r
+import org.apache.commons.lang.StringUtils;\r
+import org.apache.logging.log4j.LogManager;\r
+import org.apache.logging.log4j.Logger;\r
+import org.apache.logging.log4j.Marker;\r
+import org.apache.logging.log4j.message.Message;\r
+\r
+import user.commons.LogUtils;\r
+import user.commons.MediaCubeMarker;\r
+import user.commons.RemoteFile;\r
+import user.commons.StoreUri;\r
+import user.commons.remotestore.IProgressEventListener;\r
+import user.commons.remotestore.IStatusEventListener;\r
+import user.commons.remotestore.ProgressEvent;\r
+import user.commons.remotestore.RemoteStoreProtocol;\r
+import user.commons.remotestore.StatusEvent;\r
+import user.jobengine.db.IItemManager;\r
+import user.jobengine.db.Media;\r
+import user.jobengine.db.MediaFile;\r
+import user.jobengine.db.Store;\r
+import user.jobengine.server.IJobEngine;\r
+import user.jobengine.server.IJobRuntime;\r
+\r
+public class TSMSystemRestoreStep extends JobStep {\r
+       private static final Logger logger = LogManager.getLogger();\r
+       private IItemManager manager;\r
+       private StoreUri targetUri;\r
+       private StoreUri sourceUri;\r
+       private String sourceFileName;\r
+       private Marker marker;\r
+\r
+       protected void afterRestore(StoreUri targetUri, String targetPath, int killDateDays, String targetFileName) throws IOException, Exception {\r
+               if (killDateDays > 0)\r
+                       EscortFiles.createUNCKillDate(targetPath, targetFileName, killDateDays, marker);\r
+       }\r
+\r
+       protected void beforeRestore(StoreUri targetURI, String targetFileName) throws Exception {\r
+       }\r
+\r
+       protected void checkTargetPath(String targetPath) {\r
+               if (StringUtils.isBlank(targetPath)) {\r
+                       logger.error(marker, "A folyamat 'targetPath' bemeneti paramétere üres.");\r
+                       throw new NullPointerException("System is not configured properly, 'targetPath' input parameter missing.");\r
+               }\r
+       }\r
+\r
+       protected StoreUri createTargetUri(IItemManager manager, String targetPath) {\r
+               return manager.createStoreUri(RemoteStoreProtocol.LOCAL, targetPath);\r
+       }\r
+\r
+       @StepEntry\r
+       public Object[] execute(Media mediaCubeMedia, String targetPath, String targetNamePattern, String successRecipient, int killDateDays, IJobEngine jobEngine,\r
+                       IJobRuntime jobRuntime) throws Exception {\r
+               marker = jobRuntime.getMarker();\r
+               setAndCheck(mediaCubeMedia, targetPath, targetNamePattern, jobEngine);\r
+               String targetFileName = String.format(targetNamePattern, sourceFileName);\r
+               try {\r
+                       beforeRestore(targetUri, targetNamePattern);\r
+                       final IJobRuntime runtime = jobRuntime;\r
+                       sourceUri.addProgressListener(new IProgressEventListener() {\r
+                               @Override\r
+                               public void progressChanged(ProgressEvent evt) {\r
+                                       runtime.incrementProgress(evt.getProgress());\r
+                               }\r
+                       });\r
+                       sourceUri.addStatusListener(new IStatusEventListener() {\r
+                               @Override\r
+                               public void statusChanged(StatusEvent evt) {\r
+                                       evt.setCancel(!canContinue());\r
+                               }\r
+                       });\r
+                       RemoteFile result = sourceUri.transferFrom(targetUri, sourceFileName, targetFileName);\r
+\r
+                       Message msg = LogUtils.format("Az '{}' állomány visszatöltése sikeres volt '{}' néven. ", sourceFileName, targetFileName);\r
+                       if (StringUtils.isNotBlank(successRecipient))\r
+                               logger.info(new MediaCubeMarker(successRecipient), msg);\r
+                       logger.info(marker, msg);\r
+                       afterRestore(targetUri, targetPath, killDateDays, targetFileName);\r
+\r
+               } catch (Exception e) {\r
+                       Message msg = LogUtils.format("Az '{}' állomány visszatöltése sikertelen. A rendszer hibaüzenete: {}", sourceFileName, e.getMessage());\r
+                       logger.error(marker, msg);\r
+                       // logger.error(jobRuntime.marker, msg);\r
+                       logger.catching(e);\r
+                       throw e;\r
+               }\r
+\r
+               return null;\r
+       }\r
+\r
+       private String getSourceFileName(Media mediaCubeMedia, Store store) {\r
+               List<MediaFile> mediaFiles = mediaCubeMedia.getMediaFiles();\r
+               if (mediaFiles == null)\r
+                       return null;\r
+               for (MediaFile mediaFile : mediaFiles) {\r
+                       if (mediaFile.getStore().getId() == store.getId())\r
+                               return mediaFile.getRelativePath();\r
+               }\r
+               return null;\r
+       }\r
+\r
+       private void setAndCheck(Media mediaCubeMedia, String targetPath, String targetNamePattern, IJobEngine jobEngine) {\r
+               if (jobEngine == null) {\r
+                       logger.error(marker, "Az folyamatkezelő réteg nem elérhető.");\r
+                       throw new NullPointerException("Internal error, missing JobEngine reference.");\r
+               }\r
+               manager = jobEngine.getItemManager();\r
+               if (manager == null) {\r
+                       logger.error(marker, "Az adatbáziskezelő réteg nem elérhető.");\r
+                       throw new NullPointerException("Internal error, missing ItemManager reference.");\r
+               }\r
+               if (mediaCubeMedia == null) {\r
+                       logger.error(marker, "A folyamat 'mediaCubeMedia' bemeneti paramétere üres.");\r
+                       throw new NullPointerException("System is not configured properly, 'mediaCubeMedia' input parameter missing.");\r
+               }\r
+               checkTargetPath(targetPath);\r
+               if (StringUtils.isBlank(targetNamePattern)) {\r
+                       logger.error(marker, "A folyamat 'targetNamePattern' bemeneti paramétere üres.");\r
+                       throw new NullPointerException("System is not configured properly, 'targetNamePattern' input parameter missing.");\r
+               }\r
+               Store tsmStore = manager.getSystemStore(false);\r
+               if (tsmStore == null) {\r
+                       logger.error(marker, "A TSM rendszer beállítás nem elérhető.");\r
+                       throw new NullPointerException("System is not configured properly, missing TSM Store.");\r
+               }\r
+               sourceUri = tsmStore.getSourceStoreUri(RemoteStoreProtocol.TSM);\r
+               if (sourceUri == null) {\r
+                       logger.error(marker, "A TSM rendszer beállítás paraméterei nem elérhetőek.");\r
+                       throw new NullPointerException("System is not configured properly, missing TSM StoreUri.");\r
+               }\r
+               targetUri = createTargetUri(manager, targetPath);\r
+               sourceFileName = getSourceFileName(mediaCubeMedia, tsmStore);\r
+               if (sourceFileName == null) {\r
+                       logger.error(marker, "Adatbázis bejegyzés hiba, a visszatöltendő fájl neve nem található.");\r
+                       throw new NullPointerException("Database error, missing MediaFile 'relativePath'.");\r
+               }\r
+\r
+       }\r
+}\r
index c8d92db18697be26cdabcd1fa3faffc122790322..3eeb9c5411b97fccbec4949240aac9bb76c69cb8 100644 (file)
@@ -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;
index 57fd2ce5cc0f56acc94a3d5d5d37d3c20d489f05..f8d1b2be67a8ba517a8660d03515b3e1dc13a2af 100644 (file)
@@ -19,10 +19,6 @@ public class DynamicAttributes extends JSONBase implements Serializable {
        private long itemTypeId = 0;\r
        private boolean loaded = false;\r
 \r
-       public Metadata getMetadata(String name) {\r
-               return getItemType().getMetadata(name);\r
-       }\r
-\r
        public Object getAttribute(String name) {\r
                ItemManager.getInstance().traceIn();\r
                Object result = null;\r
@@ -37,6 +33,7 @@ public class DynamicAttributes extends JSONBase implements Serializable {
                return this.attributes;\r
        }\r
 \r
+       @JsonIgnore\r
        public ItemType getItemType() {\r
                if (itemType == null && itemTypeId > 0) {\r
                        itemType = (ItemType) ItemManager.getInstance().get(ItemType.class, itemTypeId);\r
@@ -50,6 +47,10 @@ public class DynamicAttributes extends JSONBase implements Serializable {
                return this.itemTypeId;\r
        }\r
 \r
+       public Metadata getMetadata(String name) {\r
+               return getItemType().getMetadata(name);\r
+       }\r
+\r
        private void initalize() {\r
                ItemManager.getInstance().traceIn();\r
                if (attributes == null) {\r
@@ -63,8 +64,7 @@ public class DynamicAttributes extends JSONBase implements Serializable {
                                        }\r
                                }\r
                                if (getId() > 0 && !loaded) {\r
-                                       DynamicAttributesDAO daDAO = (DynamicAttributesDAO) ItemManager.getInstance()\r
-                                                       .getBaseDAO(DynamicAttributes.class);\r
+                                       DynamicAttributesDAO daDAO = (DynamicAttributesDAO) ItemManager.getInstance().getBaseDAO(DynamicAttributes.class);\r
                                        daDAO.get(this);\r
                                }\r
                        }\r
index a556b8323097e36070285d39a7a05d3aa854edd9..c15074fdb3b84cab764b737b32d6a33761f37b5d 100644 (file)
@@ -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<MediaFile> getMediaFiles() {
                if (mediaFiles == null)
                        mediaFiles = (List<MediaFile>) (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<MediaFile> files = getMediaFiles();
index a5b0ce8ade43de4c96090127c41925e0b04bde86..4d2d4db3f697cf13057b562fc674a33d63f9008d 100644 (file)
@@ -1,9 +1,5 @@
 package user.jobengine.osgi.mediacube;\r
 \r
-import java.sql.ResultSetMetaData;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
 import javax.ws.rs.Consumes;\r
 import javax.ws.rs.GET;\r
 import javax.ws.rs.POST;\r
@@ -17,14 +13,13 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;\r
 import org.eclipse.core.runtime.adaptor.EclipseStarter;\r
 \r
-import com.ibm.nosql.json.api.BasicDBObject;\r
-\r
 import user.commons.MediaCubeMarker;\r
 import user.jobengine.db.IItemManager;\r
 import user.jobengine.db.IResultSetConsumer;\r
 import user.jobengine.db.IStatementDecorator;\r
 import user.jobengine.db.Item;\r
 import user.jobengine.db.JSONBase;\r
+import user.jobengine.db.Media;\r
 import user.jobengine.osgi.rest.ComponentBinder;\r
 import user.jobengine.server.IJobEngine;\r
 \r
@@ -97,22 +92,36 @@ public class MediaCubeService {
                        if (itemManager == null)\r
                                throw new Exception("No ItemManager found");\r
 \r
-                       List<BasicDBObject> items = new ArrayList<>();\r
-                       String sql = "select * from VW_ITEMS where mediafilehouseid = ? order by mediafilehouseid";\r
+                       Media medias[] = { null };\r
+                       String sql = "select m.* from MEDIA m left outer join MEDIAFILE mf on (m.id = mf.mediaid) where mf.houseid = ?";\r
                        IStatementDecorator decorator = ps -> {\r
                                ps.setString(1, mediaHouseId);\r
                        };\r
                        IResultSetConsumer consumer = rs -> {\r
+                               Media media = new Media();\r
+                               media.setId(rs.getLong("id"));\r
+                               media.setTitle(rs.getString("title"));\r
+                               media.setDescription(rs.getString("description"));\r
+                               media.setItemId(rs.getLong("itemid"));\r
+                               media.setItemTypeId(rs.getLong("itemtypeid"));\r
+                               media.setHouseId(rs.getString("houseid"));\r
+                               media.setLength(rs.getLong("length"));\r
+                               media.setCreated(rs.getTimestamp("created"));\r
+                               media.setArchived(rs.getTimestamp("archived"));\r
+                               medias[0] = media;\r
+                               //entity.setPoster(iterator.poster());\r
+                               /*\r
                                ResultSetMetaData metaData = rs.getMetaData();\r
                                BasicDBObject o = new BasicDBObject();\r
                                for (int i = 1; i <= metaData.getColumnCount(); i++) {\r
                                        o.put(metaData.getColumnName(i), rs.getObject(i));\r
                                }\r
                                items.add(o);\r
-                               return true;\r
+                               */\r
+                               return false;\r
                        };\r
                        itemManager.executeQuery(sql, consumer, decorator);\r
-                       result = Response.ok(items).build();\r
+                       result = Response.ok(medias[0]).build();\r
                } catch (Exception e) {\r
                        result = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();\r
                }\r
index 61ce989be1c86f459acf2721a9b1c27c791e510f..058879b6db0b59469d944504da948a944227d9d7 100644 (file)
@@ -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);
        }