Thumbnails: first version

This commit is contained in:
SuhorukovAnton 2020-06-16 14:55:46 +03:00
parent 09e7a81e9b
commit 5fbe80d32a
12 changed files with 931 additions and 3 deletions

View File

@ -52,10 +52,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppLimit.CloudComputing.Sha
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Files.Service", "products\ASC.Files\Service\ASC.Files.Service.csproj", "{5D41FFFF-816C-40B2-95CD-E2DDDCB83784}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASC.ApiSystem", "common\services\ASC.ApiSystem\ASC.ApiSystem.csproj", "{C2BB03A0-C35B-433F-96D4-3A06CBC06AD7}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.ApiSystem", "common\services\ASC.ApiSystem\ASC.ApiSystem.csproj", "{C2BB03A0-C35B-433F-96D4-3A06CBC06AD7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.UrlShortener.Svc", "common\services\ASC.UrlShortener.Svc\ASC.UrlShortener.Svc.csproj", "{04A56018-C41E-4634-A185-A13E9250C75A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Thumbnails.Svc", "common\services\ASC.Thumbnails.Svc\ASC.Thumbnails.Svc.csproj", "{1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -162,6 +164,10 @@ Global
{04A56018-C41E-4634-A185-A13E9250C75A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{04A56018-C41E-4634-A185-A13E9250C75A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{04A56018-C41E-4634-A185-A13E9250C75A}.Release|Any CPU.Build.0 = Release|Any CPU
{1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ApplicationIcon />
<OutputType>Exe</OutputType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ASC.Thumbnails.Svc
{
public static class BookmarkingRequestConstants
{
//Page address to be used in a get request
public const string BookmarkingPageName = "Default.aspx";
public const string Question_Sybmol = "?";
public const string BookmarkInfoPageName = "BookmarkInfo.aspx";
public const string FavouriteBookmarksPageName = "FavouriteBookmarks.aspx";
public const string CreateBookmarkPageName = "CreateBookmark.aspx";
public const string UrlGetRequest = "url";
public const string SelectedTab = "selectedtab";
public const string SelectedTabBookmarkCommnets = "bookmarkcommnetstab";
public const string SelectedTabBookmarkAddedBy = "bookmarkaddedbytab";
public const string BookmarksCreatedByUserPageName = "UserBookmarks.aspx";
public const string UidParam = "uid";
//Sorting constants
public const string SortByParam = "sortby";
public const string SortByDateParam = "date";
public const string SortByRaitingParam = "raiting";
public const string MostRecentParam = "mostrecent";
public const string TopOfTheDayParam = "topoftheday";
public const string WeekParam = "week";
public const string MonthParam = "month";
public const string YearParam = "year";
public const string PopularityParam = "popularity";
public const string NameParam = "name";
public const string EqualsSymbol = "=";
public const string AMPERSAND_SYMBOL = "&";
//Search
public const string Search = "search";
//Tags
public const string Tag = "tag";
//URL
public const string URL_Prefix = "http://";
public const string URL_HTTPS_Prefix = "https://";
public const string Default_URL = "http://";
//Tags image
public const string TagsImageName = "tags.png";
//Pagination
public const string Pagination = "p";
//No thumbnail available image
public const string NoImageAvailable = "noimageavailable.jpg";
public const string BookmarkingBasePath = "~/Products/Community/Modules/Bookmarking";
public const string BookmarkingStorageManagerID = "bookmarking";
}
}

View File

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ASC.Thumbnails.Svc
{
public class BookmarkingSettings
{
public static Guid ModuleId = new Guid("28B10049-DD20-4f54-B986-873BC14CCFC7");
public const string BookmarkingSctiptKey = "__boomarking_script_key";
public const string BookmarkingTagsAutocompleteSctiptKey = "__boomarking_Tags_Autocomplete_script_key";
public static int BookmarksCountOnPage = 10;
public static int VisiblePageCount = 3;
public static ImageFormat CaptureImageFormat = ImageFormat.Jpeg;
public static string ThumbnailAbsoluteFilePath { get; set; }
public static string ThumbnailAbsolutePath { get; set; }
public static string ThumbnailRelativePath = "Products/Community/Modules/Bookmarking/Data/images/";
public const string ThumbnailVirtualPath = "~/Products/Community/Modules/Bookmarking/Data/images/";
public static int Timeout = 180;
public static readonly BookmarkingThumbnailSize ThumbSmallSize = new BookmarkingThumbnailSize(96, 72);
public static readonly BookmarkingThumbnailSize ThumbMediumSize = new BookmarkingThumbnailSize(192, 152);
public static readonly Size BrowserSize = new Size(1280, 1020);
public static Encoding PageTitleEncoding = Encoding.GetEncoding("windows-1251");
public static int PingTimeout = 3000;
public const int NameMaxLength = 255;
public const int DescriptionMaxLength = 65535;
}
}

View File

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace ASC.Thumbnails.Svc
{
public class BookmarkingThumbnailSize
{
public int Width { get; set; }
public int Height { get; set; }
public BookmarkingThumbnailSize()
{
Width = BookmarkingSettings.ThumbSmallSize.Width;
Height = BookmarkingSettings.ThumbSmallSize.Height;
}
public BookmarkingThumbnailSize(int width, int height)
{
Width = width;
Height = height;
}
private const string SizePrefix = "_size";
public override string ToString()
{
return String.Format("{0}{1}-{2}", SizePrefix, Width, Height);
}
public static BookmarkingThumbnailSize ParseThumbnailSize(string fileName)
{
if (!fileName.Contains(SizePrefix))
{
return new BookmarkingThumbnailSize();
}
var m = Regex.Match(fileName, String.Format(".*{0}(?<size>).*", SizePrefix));
var sizeAsString = m.Groups["size"].Value;
var dimensions = sizeAsString.Split('-');
if (dimensions.Length == 2)
{
try
{
var width = Int32.Parse(dimensions[0]);
var height = Int32.Parse(dimensions[1]);
return new BookmarkingThumbnailSize(width, height);
}
catch
{
return new BookmarkingThumbnailSize();
}
}
return new BookmarkingThumbnailSize();
}
}
}

View File

@ -0,0 +1,432 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using ASC.Common;
using ASC.Common.Web;
using ASC.Core;
using ASC.Data.Storage;
using Microsoft.AspNetCore.Http;
namespace ASC.Thumbnails.Svc
{
public interface IThumbnailHelper
{
void MakeThumbnail(string url, bool async, bool notOverride, int tenantID);
string GetThumbnailUrl(string Url, BookmarkingThumbnailSize size);
string GetThumbnailUrlForUpdate(string Url, BookmarkingThumbnailSize size);
void DeleteThumbnail(string Url);
}
public class ThumbnailHelper
{
private IThumbnailHelper Helper { get; set; }
public ThumbnailHelper(WebSiteThumbnailHelper webSiteThumbnailHelper, ServiceThumbnailHelper serviceThumbnailHelper, NullThumbnailHelper nullThumbnailHelper)
{
if (HasService)
{
Helper = serviceThumbnailHelper;
}
if (Environment.OSVersion.Platform == PlatformID.MacOSX ||
Environment.OSVersion.Platform == PlatformID.Unix ||
Environment.OSVersion.Platform == PlatformID.Xbox)
{
Helper = nullThumbnailHelper;
}
Helper = webSiteThumbnailHelper;
}
public static bool HasService
{
get { return ConfigurationManager.AppSettings["bookmarking:thumbnail-url"] != null; }
}
public static string ServiceUrl
{
get { return ConfigurationManager.AppSettings["bookmarking:thumbnail-url"]; }
}
/*
public static IThumbnailHelper Instance
{
get
{
if (HasService)
{
return ServiceHelper;
}
if (Environment.OSVersion.Platform == PlatformID.MacOSX ||
Environment.OSVersion.Platform == PlatformID.Unix ||
Environment.OSVersion.Platform == PlatformID.Xbox)
{
return NullHelper;
}
return ProcessHelper;
}
}*/
}
public class ServiceThumbnailHelper : IThumbnailHelper
{
private readonly string CoreMachineKey;
public ServiceThumbnailHelper()
{
CoreMachineKey = ConfigurationManager.AppSettings["core:machinekey"];
}
public void MakeThumbnail(string url, bool async, bool notOverride, int tenantID)
{
}
public string GetThumbnailUrl(string Url, BookmarkingThumbnailSize size)
{
return string.Format("/thumb.ashx?url={0}", Url);
}
public string GetThumbnailUrlForUpdate(string Url, BookmarkingThumbnailSize size)
{
return GetThumbnailUrl(Url, size);
}
public void DeleteThumbnail(string Url)
{
}
}
public class NullThumbnailHelper : IThumbnailHelper
{
public void MakeThumbnail(string url, bool async, bool notOverride, int tenantID)
{
}
public void DeleteThumbnail(string Url)
{
}
public string GetThumbnailUrl(string Url, BookmarkingThumbnailSize size)
{
return null;
}
public string GetThumbnailUrlForUpdate(string Url, BookmarkingThumbnailSize size)
{
return GetThumbnailUrl(Url, size);
}
}
public class WebSiteThumbnailHelper : IThumbnailHelper
{
private List<Uri> ProcessedUrls { get; set; }
private TenantManager TenantManager { get; set;}
private StorageFactory StorageFactory { get; set;}
private IHttpContextAccessor HttpContextAccessor { get; set;}
public WebSiteThumbnailHelper(TenantManager tenantManager, StorageFactory storageFactory, IHttpContextAccessor httpContextAccessor)
{
ProcessedUrls = new List<Uri>();
TenantManager = tenantManager;
StorageFactory = storageFactory;
HttpContextAccessor = httpContextAccessor;
}
private IDataStore getStore()
{
return StorageFactory.GetStorage(TenantManager.CurrentTenant.TenantId.ToString(), BookmarkingRequestConstants.BookmarkingStorageManagerID);
}
private IDataStore getStore(int tenant)
{
return StorageFactory.GetStorage(tenant.ToString(), BookmarkingRequestConstants.BookmarkingStorageManagerID);
}
public void MakeThumbnail(string url)
{
MakeThumbnail(url, true, true, TenantManager.CurrentTenant.TenantId);
}
public void MakeThumbnail(string url, bool async, bool notOverride, int tenantID)
{
try
{
if (string.IsNullOrEmpty(url)) return;
if (notOverride)
{
var fileName = GetFileNameByUrl(HttpUtility.UrlEncode(url), BookmarkingSettings.ThumbSmallSize);
if (getStore(tenantID).IsFile(string.Empty, fileName))
{
return;
}
}
List<object> p = new List<object>();
p.Add(url);
p.Add(HttpContextAccessor.HttpContext);
p.Add(tenantID);
ThreadPool.QueueUserWorkItem(MakeThumbnailCallback, p);
//if (!async) thread.Join();
}
catch { }
}
private void MakeThumbnailCallback(object p)
{
#region Sanity Check
var url = string.Empty;
var context = HttpContextAccessor.HttpContext;
int tenant = 0;
try
{
if (p is List<Object>)
{
var s = p as List<object>;
if (s.Count == 3)
{
if (s[0] is string)
{
url = s[0] as string;
}
if (s[1] is HttpContext)
{
context = s[1] as HttpContext;
}
if (s[2] is int)
{
tenant = (int)s[2];
}
}
}
}
catch { }
#endregion
var outFileName = string.Empty;
Process ps = null;
int psid = -1;
Uri uri = null;
try
{
//Check true url
if (!string.IsNullOrEmpty(url) && context != null && Uri.TryCreate(url, UriKind.Absolute, out uri))
{
lock (ProcessedUrls)
{
if (ProcessedUrls.Contains(uri)) return;//Screen ih bin processing go away!
ProcessedUrls.Add(uri);
}
//We got normal url
//Map server path
var appDataDir = VirtualPathUtility.ToAbsolute("~/Products/Community/Modules/Bookmarking/App_Data");
var screenShoterName = Path.Combine(appDataDir, "IECapt.exe");
if (File.Exists(screenShoterName))
{
outFileName = Path.Combine(appDataDir, Path.Combine("screens", Guid.NewGuid() + ".png"));
if (!Directory.Exists(Path.GetDirectoryName(outFileName)))
{
Directory.CreateDirectory(Path.GetDirectoryName(outFileName));
}
var arguments = BuildArguments(uri, outFileName);
//Launch process
using (ps = new Process())
{
ps.StartInfo = new ProcessStartInfo(screenShoterName, arguments);
ps.StartInfo.CreateNoWindow = true;
ps.Start();
psid = ps.Id;
if (ps.WaitForExit(15000))//Wait 15 sec and close
{
//Ta da. File created
if (File.Exists(outFileName))
{
//Upload!
//Warning! Huge memory overhead!
using (Image image = Image.FromFile(outFileName))
{
using (
Image clipImage = new Bitmap(BookmarkingSettings.ThumbSmallSize.Width,
BookmarkingSettings.ThumbSmallSize.Height))
{
using (var graphics = Graphics.FromImage(clipImage))
{
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
//Bicubic is better for minimizing image.
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.DrawImage(image,
Rectangle.FromLTRB(0, 0,
BookmarkingSettings.ThumbSmallSize
.
Width,
BookmarkingSettings.ThumbSmallSize
.
Height),
Rectangle.FromLTRB(0, 0,
BookmarkingSettings.BrowserSize.
Width,
BookmarkingSettings.BrowserSize.
Height),
GraphicsUnit.Pixel
);
using (var ms = new MemoryStream())
{
clipImage.Save(ms, BookmarkingSettings.CaptureImageFormat);
ms.Position = 0;
IDataStore store = getStore( tenant);
var fileName = GetFileNameByUrl(HttpUtility.UrlEncode(url), BookmarkingSettings.ThumbSmallSize);
store.Save(string.Empty, fileName, ms);
}
}
}
}
}
}
else
{
//Process hasn't exited
//finally will kill it
}
}
}
}
}
catch (Exception)
{
}
finally
{
if (ps != null)
{
try
{
ps.Kill();
}
catch
{
//Don't throw
}
}
//try kill
if (psid != -1)
{
try
{
var proc = Process.GetProcessById(psid);
if (proc != null)
{
proc.Kill();
}
}
catch
{
//Don't throw
}
}
if (!string.IsNullOrEmpty(outFileName) && File.Exists(outFileName))
{
File.Delete(outFileName);
}
lock (ProcessedUrls)
{
if (uri != null && ProcessedUrls.Contains(uri))
{
ProcessedUrls.Remove(uri);
}
}
}
}
private static string BuildArguments(Uri uri, string outFileName)
{
return string.Format("--url=\"{0}\" --out=\"{1}\" --delay={2} --max-wait={4} --min-width={3} --silent ",
uri, outFileName, 1000, BookmarkingSettings.BrowserSize.Width, 10000);
}
public string GetThumbnailUrl(string Url, BookmarkingThumbnailSize size)
{
var fileName = GetFileNameByUrl(Url, size);
return getStore().IsFile(string.Empty, fileName) ? getStore().GetUri(string.Empty, fileName).ToString() : string.Empty;
}
public string GetThumbnailUrlForUpdate(string Url, BookmarkingThumbnailSize size)
{
return GetThumbnailUrl(Url, size);
}
#region DeleteThumbnail
public void DeleteThumbnail(string Url)
{
try
{
var fileName = GetFileNameByUrl(Url, BookmarkingSettings.ThumbSmallSize);
getStore(TenantManager.CurrentTenant.TenantId).Delete(fileName);
}
catch (FileNotFoundException) { }
}
#endregion
private static string GetSHA256(string text)
{
var ue = new UnicodeEncoding();
var message = ue.GetBytes(text);
var hashString = new SHA256Managed();
var hashValue = hashString.ComputeHash(message);
var hex = new StringBuilder();
foreach (byte x in hashValue) hex.AppendFormat("{0:x2}", x);
return hex.ToString();
}
private static string GetFileNameByUrl(string url, BookmarkingThumbnailSize size)
{
string sizeString = size == null ? string.Empty : size.ToString();
return string.Format("{0}{1}.{2}", GetSHA256(url), sizeString, BookmarkingSettings.CaptureImageFormat.ToString());
}
}
public static class ThumbnailHelperExtension
{
public static DIHelper AddThumbnailHelperService(this DIHelper services)
{
services.TryAddScoped<ThumbnailHelper>();
services.TryAddScoped<WebSiteThumbnailHelper>();
services.TryAddScoped<ServiceThumbnailHelper>();
services.TryAddScoped<NullThumbnailHelper>();
return services
.AddTenantManagerService()
.AddStorageFactoryService();
}
}
}

View File

@ -0,0 +1,95 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2020
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using ASC.Common;
using ASC.Common.DependencyInjection;
using ASC.Common.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace ASC.Thumbnails.Svc
{
public class Program
{
public static async Task Main(string[] args)
{
var host = Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostContext, config) =>
{
var buided = config.Build();
var path = buided["pathToConf"];
if (!Path.IsPathRooted(path))
{
path = Path.GetFullPath(Path.Combine(hostContext.HostingEnvironment.ContentRootPath, path));
}
config.SetBasePath(path);
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
config
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
)
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env}.json", true)
.AddJsonFile($"urlshortener.{env}.json", true)
.AddJsonFile("storage.json")
.AddJsonFile("kafka.json")
.AddJsonFile("thumbnails.json")
.AddJsonFile($"kafka.{env}.json", true)
.AddEnvironmentVariables()
.AddCommandLine(args);
})
.ConfigureServices((hostContext, services) =>
{
var diHelper = new DIHelper(services);
diHelper.AddNLogManager("ASC.Thumbnails.Svc");
services.AddHostedService<ThumbnailsServiceLauncher>();
diHelper.AddThumbnailsServiceLauncher();
services.AddAutofac(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath, false, false);
})
.UseConsoleLifetime()
.Build();
using (host)
{
// Start the host
await host.StartAsync();
// Wait for the host to shutdown
await host.WaitForShutdownAsync();
}
}
}
}

View File

@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:55420/",
"sslPort": 44311
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"ASC.Thumbnails.Svc": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}

View File

@ -0,0 +1,125 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using ASC.Common.Utils;
using ASC.Common.Logging;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using ASC.Common;
namespace ASC.Thumbnails.Svc
{
public class ThumbnailsServiceLauncher : IHostedService
{
private ProcessStartInfo StartInfo { get; set; }
private Process Proc { get; set; }
private ILog Logger { get; set; }
private IConfiguration Configuration { get; set; }
public ThumbnailsServiceLauncher(IOptionsMonitor<ILog> options, IConfiguration configuration)
{
Logger = options.CurrentValue;
Configuration = configuration;
}
public Task StartAsync(CancellationToken cancellationToken)
{
try
{
var settings = Configuration.GetSetting<ThumbnailsSettings>("backup");
StartInfo = new ProcessStartInfo
{
CreateNoWindow = false,
UseShellExecute = false,
FileName = "node",
WindowStyle = ProcessWindowStyle.Hidden,
Arguments = string.Format("\"{0}\"", Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, settings.Path, "index.js"))),
WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory
};
var savePath = settings.SavePath;
if (!savePath.EndsWith("/"))
{
savePath += "/";
}
StartInfo.EnvironmentVariables.Add("port", settings.Port);
StartInfo.EnvironmentVariables.Add("logPath", Path.Combine(Logger.LogDirectory, "web.thumbnails.log"));
StartInfo.EnvironmentVariables.Add("savePath", Path.GetFullPath(savePath));
StartNode(cancellationToken);
}
catch(Exception e)
{
Logger.Error("Start", e);
}
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
try
{
if (Proc != null && !Proc.HasExited)
{
Proc.Kill();
Proc.WaitForExit(10000);
Proc.Close();
Proc.Dispose();
Proc = null;
}
}
catch(Exception e)
{
Logger.Error("Stop", e);
}
return Task.CompletedTask;
}
private void StartNode(CancellationToken cancellationToken)
{
StopAsync(cancellationToken);
Proc = Process.Start(StartInfo);
}
}
public static class ThumbnailsServiceLauncherExtension
{
public static DIHelper AddThumbnailsServiceLauncher(this DIHelper services)
{
services.TryAddScoped<ThumbnailsServiceLauncher>();
return services;
}
}
}

View File

@ -0,0 +1,9 @@
namespace ASC.Thumbnails.Svc
{
public class ThumbnailsSettings
{
public string Path { get; set; }
public string Port { get; set; }
public string SavePath { get; set; }
}
}

View File

@ -33,6 +33,7 @@
<ProjectReference Include="..\..\common\ASC.Common\ASC.Common.csproj" />
<ProjectReference Include="..\..\common\ASC.Core.Common\ASC.Core.Common.csproj" />
<ProjectReference Include="..\..\common\ASC.Data.Reassigns\ASC.Data.Reassigns.csproj" />
<ProjectReference Include="..\..\common\services\ASC.Thumbnails.Svc\ASC.Thumbnails.Svc.csproj" />
<ProjectReference Include="..\ASC.Web.Core\ASC.Web.Core.csproj" />
</ItemGroup>

View File

@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Net;
using System.Security;
using ASC.Api.Core;
@ -11,6 +12,7 @@ using ASC.Core.Tenants;
using ASC.Core.Users;
using ASC.MessagingSystem;
using ASC.Security.Cryptography;
using ASC.Thumbnails.Svc;
using ASC.Web.Api.Routing;
using ASC.Web.Core;
using ASC.Web.Core.Utility;
@ -20,6 +22,8 @@ using ASC.Web.Studio.Utility;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using SecurityContext = ASC.Core.SecurityContext;
namespace ASC.Web.Api.Controllers
{
[DefaultRoute]
@ -36,6 +40,7 @@ namespace ASC.Web.Api.Controllers
public UrlShortener UrlShortener { get; }
public AuthContext AuthContext { get; }
public WebItemSecurity WebItemSecurity { get; }
public SecurityContext SecurityContext { get; }
public ILog Log { get; }
@ -48,7 +53,8 @@ namespace ASC.Web.Api.Controllers
CommonLinkUtility commonLinkUtility,
UrlShortener urlShortener,
AuthContext authContext,
WebItemSecurity webItemSecurity
WebItemSecurity webItemSecurity,
SecurityContext securityContext
)
{
Log = options.CurrentValue;
@ -60,6 +66,7 @@ namespace ASC.Web.Api.Controllers
UrlShortener = urlShortener;
AuthContext = authContext;
WebItemSecurity = webItemSecurity;
SecurityContext = securityContext;
}
[Read("")]
@ -148,6 +155,40 @@ namespace ASC.Web.Api.Controllers
{
return CommonLinkUtility.GetFullAbsolutePath(virtualPath);
}
[Read("thumb")]
public FileResult GetThumb(string url)
{
if (!SecurityContext.IsAuthenticated || !ThumbnailHelper.HasService )
{
ProccessFail();
return null;
}
url = url.Replace("&amp;", "&");
url = System.Net.WebUtility.UrlEncode(url);
try
{
using (var wc = new WebClient())
{
var bytes = wc.DownloadData(string.Format(ThumbnailHelper.ServiceUrl, url));
var type = wc.ResponseHeaders["Content-Type"] ?? "image/png";
return File(bytes, type);
/* context.Response.BinaryWrite(bytes);
context.Response.Flush();*/
}
}
catch
{
ProccessFail();
return null;
}
}
private void ProccessFail()
{
// context.Response.Redirect("~/Products/Community/Modules/Bookmarking/App_Themes/default/images/noimageavailable.jpg");
}
}
public static class PortalControllerExtension
@ -167,7 +208,8 @@ namespace ASC.Web.Api.Controllers
.AddPaymentManagerService()
.AddCommonLinkUtilityService()
.AddAuthContextService()
.AddWebItemSecurity();
.AddWebItemSecurity()
.AddSecurityContextService();
}
}
}