diff --git a/MatterControlLib/Library/RemoteLibraryItem.cs b/MatterControlLib/Library/RemoteLibraryItem.cs new file mode 100644 index 000000000..6877c7e0a --- /dev/null +++ b/MatterControlLib/Library/RemoteLibraryItem.cs @@ -0,0 +1,107 @@ +/* +Copyright (c) 2018, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System; +using System.Net.Http; +using System.Threading.Tasks; +using MatterHackers.Agg; +using MatterHackers.Localizations; + +namespace MatterHackers.MatterControl.Library +{ + public class RemoteLibraryItem : ILibraryAssetStream + { + private string url; + private HttpClient httpClient; + + public RemoteLibraryItem(string url, string name) + { + httpClient = new HttpClient(); + + // TODO: We need a way to ask library items to initialize before use, so that content type could be requested from the remote source before the stream is acquired. Currently properties are + // tested before GetStream is invoked that determine which provider should be used, which is impossible to know before we have the actual content type + + //// Send HEAD request to help bypass the 401 auth challenge for the latter POST assuming + //// that the authentication will be cached and re-used later when PreAuthenticate is true. + //var request = new HttpRequestMessage(HttpMethod.Head, url); + + //httpClient.SendAsync(request).ContinueWith(t => + //{ + // var headers = t.Result.Content.Headers; + + // this.ContentType = headers.ContentType.MediaType.Replace("image/", ""); + // this.FileSize = headers.ContentLength ?? 0; + //}); + + this.url = url; + this.Name = name ?? "Unknown".Localize(); + this.ID = agg_basics.GetLongHashCode(url).ToString(); + } + + public string ID { get; set; } + + public string Name { get; set; } + + public string FileName => $"{this.Name}.{this.ContentType}"; + + public bool IsProtected => false; + + public bool IsVisible => true; + + public DateTime DateCreated { get; } = DateTime.Now; + + public DateTime DateModified { get; } = DateTime.Now; + + public string ContentType { get; private set; } = "jpg"; // TODO: Remove invalid static assignment used to depict what would be possible with more effort + + public string Category => "General"; + + public string AssetPath { get; set; } + + public long FileSize { get; private set; } = 0; + + public bool LocalContentExists => false; + + public async Task GetStream(Action progress) + { + + var response = await httpClient.GetAsync(this.url); + + var headers = response.Content.Headers; + + //this.ContentType = headers.ContentType.MediaType; + + return new StreamAndLength() + { + Stream = await response.Content.ReadAsStreamAsync(), + Length = headers.ContentLength ?? 0 + }; + } + } +} \ No newline at end of file diff --git a/MatterControlLib/Library/Widgets/LibraryWidget.cs b/MatterControlLib/Library/Widgets/LibraryWidget.cs index b6ba28219..fa0a11fc2 100644 --- a/MatterControlLib/Library/Widgets/LibraryWidget.cs +++ b/MatterControlLib/Library/Widgets/LibraryWidget.cs @@ -1056,7 +1056,8 @@ namespace MatterHackers.MatterControl.PrintLibrary mouseEvent.AcceptDrop = mouseEvent.DragFiles?.Count > 0 && mouseEvent.DragFiles.TrueForAll(filePath => ApplicationController.Instance.IsLoadableFile(filePath) || (Path.GetExtension(filePath) is string extension - && string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase))); + && string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase)) + || filePath.StartsWith("http", StringComparison.OrdinalIgnoreCase)); } } diff --git a/MatterControlLib/Library/Widgets/PrintLibraryWidget.cs b/MatterControlLib/Library/Widgets/PrintLibraryWidget.cs index 337d440a1..1f00f3d1d 100644 --- a/MatterControlLib/Library/Widgets/PrintLibraryWidget.cs +++ b/MatterControlLib/Library/Widgets/PrintLibraryWidget.cs @@ -457,7 +457,8 @@ namespace MatterHackers.MatterControl.PrintLibrary mouseEvent.AcceptDrop = mouseEvent.DragFiles?.Count > 0 && mouseEvent.DragFiles.TrueForAll(filePath => ApplicationController.Instance.IsLoadableFile(filePath) || (Path.GetExtension(filePath) is string extension - && string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase))); + && string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase)) + || filePath.StartsWith("http", StringComparison.OrdinalIgnoreCase)); } } diff --git a/MatterControlLib/PartPreviewWindow/View3D/View3DWidget.cs b/MatterControlLib/PartPreviewWindow/View3D/View3DWidget.cs index ddfa36b82..43f6a6b28 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/View3DWidget.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/View3DWidget.cs @@ -1387,7 +1387,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { return ApplicationController.Instance.IsLoadableFile(filePath) // Disallow GCode drop in part view - && (this.Printer != null || !string.Equals(System.IO.Path.GetExtension(filePath), ".gcode", StringComparison.OrdinalIgnoreCase)); + && (this.Printer != null || !string.Equals(System.IO.Path.GetExtension(filePath), ".gcode", StringComparison.OrdinalIgnoreCase)) + || filePath.StartsWith("http", StringComparison.OrdinalIgnoreCase); }); // View3DWidgets Filesystem DropDrop handler @@ -1402,7 +1403,15 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { // Project DragFiles to IEnumerable this.StartDragDrop( - mouseEvent.DragFiles.Select(path => new FileSystemFileItem(path)), + mouseEvent.DragFiles.Select(path => + { + if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase)) + { + return new RemoteLibraryItem(path, null); + } + + return new FileSystemFileItem(path); + }), screenSpaceMousePosition: this.TransformToScreenSpace(mouseEvent.Position), trackSourceFiles: true); }