ShareX/ShareX/WorkerTask.cs

1260 lines
45 KiB
C#
Raw Normal View History

2013-11-03 23:53:49 +13:00
#region License Information (GPL v3)
/*
ShareX - A program that allows you to take screenshots and share any file type
2024-01-03 12:57:14 +13:00
Copyright (c) 2007-2024 ShareX Team
2013-11-03 23:53:49 +13:00
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
*/
#endregion License Information (GPL v3)
2014-12-11 09:25:20 +13:00
using ShareX.HelpersLib;
using ShareX.Properties;
2014-12-11 09:25:20 +13:00
using ShareX.UploadersLib;
2016-02-15 19:53:30 +13:00
using System;
2016-09-17 19:07:02 +12:00
using System.Collections.Generic;
using System.Diagnostics;
2016-02-15 19:53:30 +13:00
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
2016-02-15 19:53:30 +13:00
using System.Threading;
using System.Windows.Forms;
2013-11-03 23:53:49 +13:00
namespace ShareX
{
2015-08-31 18:03:03 +12:00
public class WorkerTask : IDisposable
2013-11-03 23:53:49 +13:00
{
2015-08-31 18:03:03 +12:00
public delegate void TaskEventHandler(WorkerTask task);
2020-03-24 08:33:26 +13:00
public delegate void TaskImageEventHandler(WorkerTask task, Bitmap image);
public delegate void UploaderServiceEventHandler(IUploaderService uploaderService);
2013-11-03 23:53:49 +13:00
public event TaskEventHandler StatusChanged, UploadStarted, UploadProgressChanged, UploadCompleted, TaskCompleted;
public event TaskImageEventHandler ImageReady;
public event UploaderServiceEventHandler UploadersConfigWindowRequested;
2013-11-03 23:53:49 +13:00
public TaskInfo Info { get; private set; }
public TaskStatus Status { get; private set; }
2016-12-13 01:19:02 +13:00
public bool IsBusy => Status == TaskStatus.InQueue || IsWorking;
public bool IsWorking => Status == TaskStatus.Preparing || Status == TaskStatus.Working || Status == TaskStatus.Stopping;
2014-06-09 04:36:47 +12:00
public bool StopRequested { get; private set; }
2013-11-03 23:53:49 +13:00
public bool RequestSettingUpdate { get; private set; }
public bool EarlyURLCopied { get; private set; }
public Stream Data { get; private set; }
2020-03-24 08:33:26 +13:00
public Bitmap Image { get; private set; }
public bool KeepImage { get; set; }
2019-03-27 19:12:17 +13:00
public string Text { get; private set; }
2013-11-03 23:53:49 +13:00
private ThreadWorker threadWorker;
2016-04-15 12:25:08 +12:00
private GenericUploader uploader;
private TaskReferenceHelper taskReferenceHelper;
2013-11-03 23:53:49 +13:00
#region Constructors
2015-08-31 18:03:03 +12:00
private WorkerTask(TaskSettings taskSettings)
2013-11-03 23:53:49 +13:00
{
Status = TaskStatus.InQueue;
Info = new TaskInfo(taskSettings);
}
public static WorkerTask CreateHistoryTask(RecentTask recentTask)
{
WorkerTask task = new WorkerTask(null);
task.Status = TaskStatus.History;
task.Info.FilePath = recentTask.FilePath;
task.Info.FileName = recentTask.FileName;
task.Info.Result.URL = recentTask.URL;
task.Info.Result.ThumbnailURL = recentTask.ThumbnailURL;
task.Info.Result.DeletionURL = recentTask.DeletionURL;
task.Info.Result.ShortenedURL = recentTask.ShortenedURL;
2017-06-12 08:01:11 +12:00
task.Info.TaskEndTime = recentTask.Time;
return task;
}
2015-08-31 18:03:03 +12:00
public static WorkerTask CreateDataUploaderTask(EDataType dataType, Stream stream, string fileName, TaskSettings taskSettings)
2013-11-03 23:53:49 +13:00
{
2015-08-31 18:03:03 +12:00
WorkerTask task = new WorkerTask(taskSettings);
2013-11-03 23:53:49 +13:00
task.Info.Job = TaskJob.DataUpload;
task.Info.DataType = dataType;
task.Info.FileName = fileName;
task.Data = stream;
return task;
}
2015-08-31 18:03:03 +12:00
public static WorkerTask CreateFileUploaderTask(string filePath, TaskSettings taskSettings)
2013-11-03 23:53:49 +13:00
{
2015-08-31 18:03:03 +12:00
WorkerTask task = new WorkerTask(taskSettings);
2013-11-03 23:53:49 +13:00
task.Info.FilePath = filePath;
task.Info.DataType = TaskHelpers.FindDataType(task.Info.FilePath, taskSettings);
2013-11-03 23:53:49 +13:00
if (task.Info.TaskSettings.UploadSettings.FileUploadUseNamePattern)
2013-11-03 23:53:49 +13:00
{
string ext = FileHelpers.GetFileNameExtension(task.Info.FilePath);
2021-12-12 10:21:19 +13:00
task.Info.FileName = TaskHelpers.GetFileName(task.Info.TaskSettings, ext);
2013-11-03 23:53:49 +13:00
}
if (task.Info.TaskSettings.AdvancedSettings.ProcessImagesDuringFileUpload && task.Info.DataType == EDataType.Image)
2013-11-03 23:53:49 +13:00
{
task.Info.Job = TaskJob.Job;
task.Image = ImageHelpers.LoadImage(task.Info.FilePath);
2013-11-03 23:53:49 +13:00
}
else
{
task.Info.Job = TaskJob.FileUpload;
if (!task.LoadFileStream())
{
return null;
}
2013-11-03 23:53:49 +13:00
}
return task;
}
2021-12-12 00:56:42 +13:00
public static WorkerTask CreateImageUploaderTask(TaskMetadata metadata, TaskSettings taskSettings, string customFileName = null)
2013-11-03 23:53:49 +13:00
{
2015-08-31 18:03:03 +12:00
WorkerTask task = new WorkerTask(taskSettings);
task.Info.Job = TaskJob.Job;
2013-11-03 23:53:49 +13:00
task.Info.DataType = EDataType.Image;
2015-10-23 11:43:04 +13:00
if (!string.IsNullOrEmpty(customFileName))
{
task.Info.FileName = FileHelpers.AppendExtension(customFileName, "bmp");
2015-10-23 11:43:04 +13:00
}
else
{
2021-12-12 10:21:19 +13:00
task.Info.FileName = TaskHelpers.GetFileName(taskSettings, "bmp", metadata);
2015-10-23 11:43:04 +13:00
}
2021-12-12 00:56:42 +13:00
task.Info.Metadata = metadata;
task.Image = metadata.Image;
2013-11-03 23:53:49 +13:00
return task;
}
2015-08-31 18:03:03 +12:00
public static WorkerTask CreateTextUploaderTask(string text, TaskSettings taskSettings)
2013-11-03 23:53:49 +13:00
{
2015-08-31 18:03:03 +12:00
WorkerTask task = new WorkerTask(taskSettings);
2013-11-03 23:53:49 +13:00
task.Info.Job = TaskJob.TextUpload;
task.Info.DataType = EDataType.Text;
2021-12-12 10:21:19 +13:00
task.Info.FileName = TaskHelpers.GetFileName(taskSettings, taskSettings.AdvancedSettings.TextFileExtension);
2019-03-27 19:12:17 +13:00
task.Text = text;
2013-11-03 23:53:49 +13:00
return task;
}
2015-08-31 18:03:03 +12:00
public static WorkerTask CreateURLShortenerTask(string url, TaskSettings taskSettings)
2013-11-03 23:53:49 +13:00
{
2015-08-31 18:03:03 +12:00
WorkerTask task = new WorkerTask(taskSettings);
2013-11-03 23:53:49 +13:00
task.Info.Job = TaskJob.ShortenURL;
task.Info.DataType = EDataType.URL;
2014-10-25 13:04:41 +13:00
task.Info.FileName = string.Format(Resources.UploadTask_CreateURLShortenerTask_Shorten_URL___0__, taskSettings.URLShortenerDestination.GetLocalizedDescription());
2013-11-03 23:53:49 +13:00
task.Info.Result.URL = url;
return task;
}
2015-08-31 18:03:03 +12:00
public static WorkerTask CreateShareURLTask(string url, TaskSettings taskSettings)
{
2015-08-31 18:03:03 +12:00
WorkerTask task = new WorkerTask(taskSettings);
task.Info.Job = TaskJob.ShareURL;
task.Info.DataType = EDataType.URL;
2014-10-25 13:04:41 +13:00
task.Info.FileName = string.Format(Resources.UploadTask_CreateShareURLTask_Share_URL___0__, taskSettings.URLSharingServiceDestination.GetLocalizedDescription());
task.Info.Result.URL = url;
return task;
}
public static WorkerTask CreateFileJobTask(string filePath, TaskMetadata metadata, TaskSettings taskSettings, string customFileName = null)
{
2015-08-31 18:03:03 +12:00
WorkerTask task = new WorkerTask(taskSettings);
task.Info.FilePath = filePath;
task.Info.DataType = TaskHelpers.FindDataType(task.Info.FilePath, taskSettings);
2015-10-23 11:43:04 +13:00
if (!string.IsNullOrEmpty(customFileName))
{
string ext = FileHelpers.GetFileNameExtension(task.Info.FilePath);
task.Info.FileName = FileHelpers.AppendExtension(customFileName, ext);
2015-10-23 11:43:04 +13:00
}
else if (task.Info.TaskSettings.UploadSettings.FileUploadUseNamePattern)
{
string ext = FileHelpers.GetFileNameExtension(task.Info.FilePath);
2021-12-12 10:21:19 +13:00
task.Info.FileName = TaskHelpers.GetFileName(task.Info.TaskSettings, ext);
}
task.Info.Metadata = metadata;
task.Info.Job = TaskJob.Job;
if (task.Info.IsUploadJob && !task.LoadFileStream())
{
return null;
}
return task;
}
public static WorkerTask CreateDownloadTask(string url, bool upload, TaskSettings taskSettings)
{
2015-08-31 18:03:03 +12:00
WorkerTask task = new WorkerTask(taskSettings);
task.Info.Job = upload ? TaskJob.DownloadUpload : TaskJob.Download;
2015-08-29 18:11:37 +12:00
2021-12-12 10:21:19 +13:00
string fileName = URLHelpers.URLDecode(url, 10);
fileName = URLHelpers.GetFileName(fileName);
2022-05-23 19:30:06 +12:00
fileName = FileHelpers.SanitizeFileName(fileName);
if (task.Info.TaskSettings.UploadSettings.FileUploadUseNamePattern)
{
string ext = FileHelpers.GetFileNameExtension(fileName);
2021-12-12 10:21:19 +13:00
fileName = TaskHelpers.GetFileName(task.Info.TaskSettings, ext);
}
2021-12-12 10:21:19 +13:00
if (string.IsNullOrEmpty(fileName))
2015-08-29 18:11:37 +12:00
{
return null;
}
2021-12-12 10:21:19 +13:00
task.Info.FileName = fileName;
task.Info.DataType = TaskHelpers.FindDataType(task.Info.FileName, taskSettings);
task.Info.Result.URL = url;
return task;
}
2013-11-03 23:53:49 +13:00
#endregion Constructors
public void Start()
{
2014-06-09 04:36:47 +12:00
if (Status == TaskStatus.InQueue && !StopRequested)
2013-11-03 23:53:49 +13:00
{
2017-06-12 08:01:11 +12:00
Info.TaskStartTime = DateTime.Now;
2013-11-03 23:53:49 +13:00
threadWorker = new ThreadWorker();
Prepare();
2013-11-03 23:53:49 +13:00
threadWorker.DoWork += ThreadDoWork;
threadWorker.Completed += ThreadCompleted;
threadWorker.Start(ApartmentState.STA);
}
}
private void Prepare()
{
Status = TaskStatus.Preparing;
switch (Info.Job)
{
case TaskJob.Job:
2013-11-03 23:53:49 +13:00
case TaskJob.TextUpload:
Info.Status = Resources.UploadTask_Prepare_Preparing;
2013-11-03 23:53:49 +13:00
break;
default:
Info.Status = Resources.UploadTask_Prepare_Starting;
2013-11-03 23:53:49 +13:00
break;
}
OnStatusChanged();
}
public void Stop()
{
2014-06-09 04:36:47 +12:00
StopRequested = true;
2013-11-03 23:53:49 +13:00
2014-06-09 04:36:47 +12:00
switch (Status)
{
case TaskStatus.InQueue:
OnTaskCompleted();
2014-06-09 04:36:47 +12:00
break;
case TaskStatus.Preparing:
case TaskStatus.Working:
if (uploader != null) uploader.StopUpload();
Status = TaskStatus.Stopping;
Info.Status = Resources.UploadTask_Stop_Stopping;
2013-11-03 23:53:49 +13:00
OnStatusChanged();
2014-06-09 04:36:47 +12:00
break;
2013-11-03 23:53:49 +13:00
}
}
2020-07-07 18:05:16 +12:00
public void ShowErrorWindow()
{
if (Info != null && Info.Result != null && Info.Result.IsError)
{
string errors = Info.Result.ErrorsToString();
if (!string.IsNullOrEmpty(errors))
{
2022-05-15 09:32:09 +12:00
using (ErrorForm form = new ErrorForm(Resources.UploadInfoManager_ShowErrors_Upload_errors, errors, Program.LogsFilePath, Links.GitHubIssues, false))
2020-07-07 18:05:16 +12:00
{
form.ShowDialog();
}
}
}
}
2013-11-03 23:53:49 +13:00
private void ThreadDoWork()
{
CreateTaskReferenceHelper();
try
{
StopRequested = !DoThreadJob();
OnImageReady();
if (!StopRequested)
{
if (Info.IsUploadJob && TaskHelpers.IsUploadAllowed())
{
DoUploadJob();
}
else
{
Info.Result.IsURLExpected = false;
}
}
}
finally
{
KeepImage = Image != null && Info.TaskSettings.GeneralSettings.ShowToastNotificationAfterTaskCompleted;
Dispose();
if (EarlyURLCopied && (StopRequested || Info.Result == null || string.IsNullOrEmpty(Info.Result.URL)) && ClipboardHelpers.ContainsText())
{
2019-12-13 02:12:46 +13:00
ClipboardHelpers.Clear();
}
if ((Info.Job == TaskJob.Job || (Info.Job == TaskJob.FileUpload && Info.TaskSettings.AdvancedSettings.UseAfterCaptureTasksDuringFileUpload))
&& Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.DeleteFile) && !string.IsNullOrEmpty(Info.FilePath) && File.Exists(Info.FilePath))
{
File.Delete(Info.FilePath);
}
}
if (!StopRequested && Info.Result != null && Info.Result.IsURLExpected && !Info.Result.IsError)
{
if (string.IsNullOrEmpty(Info.Result.URL))
{
AddErrorMessage(Resources.UploadTask_ThreadDoWork_URL_is_empty_);
}
else
{
DoAfterUploadJobs();
}
}
}
2013-11-03 23:53:49 +13:00
private void CreateTaskReferenceHelper()
{
taskReferenceHelper = new TaskReferenceHelper()
{
DataType = Info.DataType,
OverrideFTP = Info.TaskSettings.OverrideFTP,
FTPIndex = Info.TaskSettings.FTPIndex,
OverrideCustomUploader = Info.TaskSettings.OverrideCustomUploader,
CustomUploaderIndex = Info.TaskSettings.CustomUploaderIndex,
TextFormat = Info.TaskSettings.AdvancedSettings.TextFormat
};
}
private void DoUploadJob()
{
if (Program.Settings.ShowUploadWarning)
2013-11-03 23:53:49 +13:00
{
bool disableUpload = !FirstTimeUploadForm.ShowForm();
Program.Settings.ShowUploadWarning = false;
if (disableUpload)
{
Program.DefaultTaskSettings.AfterCaptureJob = Program.DefaultTaskSettings.AfterCaptureJob.Remove(AfterCaptureTasks.UploadImageToHost);
foreach (HotkeySettings hotkeySettings in Program.HotkeysConfig.Hotkeys)
{
if (hotkeySettings.TaskSettings != null)
{
hotkeySettings.TaskSettings.AfterCaptureJob = hotkeySettings.TaskSettings.AfterCaptureJob.Remove(AfterCaptureTasks.UploadImageToHost);
}
}
Info.TaskSettings.AfterCaptureJob = Info.TaskSettings.AfterCaptureJob.Remove(AfterCaptureTasks.UploadImageToHost);
Info.Result.IsURLExpected = false;
RequestSettingUpdate = true;
return;
}
}
if (Program.Settings.ShowLargeFileSizeWarning > 0)
{
long dataSize = Program.Settings.BinaryUnits ? Program.Settings.ShowLargeFileSizeWarning * 1024 * 1024 : Program.Settings.ShowLargeFileSizeWarning * 1000 * 1000;
if (Data != null && Data.Length > dataSize)
{
using (MyMessageBox msgbox = new MyMessageBox(Resources.UploadTask_DoUploadJob_You_are_attempting_to_upload_a_large_file, "ShareX",
MessageBoxButtons.YesNo, Resources.UploadManager_IsUploadConfirmed_Don_t_show_this_message_again_))
{
msgbox.ShowDialog();
if (msgbox.IsChecked) Program.Settings.ShowLargeFileSizeWarning = 0;
if (msgbox.DialogResult == DialogResult.No) Stop();
}
}
}
if (!StopRequested)
{
SettingManager.WaitUploadersConfig();
2013-11-03 23:53:49 +13:00
Status = TaskStatus.Working;
Info.Status = Resources.UploadTask_DoUploadJob_Uploading;
2013-11-03 23:53:49 +13:00
TaskbarManager.SetProgressState(Program.MainForm, TaskbarProgressBarStatus.Normal);
2013-11-03 23:53:49 +13:00
bool cancelUpload = false;
2013-11-03 23:53:49 +13:00
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.ShowBeforeUploadWindow))
{
2017-08-06 08:04:21 +12:00
using (BeforeUploadForm form = new BeforeUploadForm(Info))
{
cancelUpload = form.ShowDialog() != DialogResult.OK;
}
}
if (!cancelUpload)
{
OnUploadStarted();
2014-04-13 18:59:18 +12:00
2021-07-15 03:30:26 +12:00
bool isError = DoUpload(Data, Info.FileName);
if (isError && Program.Settings.MaxUploadFailRetry > 0)
{
2018-06-11 05:39:48 +12:00
for (int retry = 1; !StopRequested && isError && retry <= Program.Settings.MaxUploadFailRetry; retry++)
{
2018-06-11 05:39:48 +12:00
DebugHelper.WriteLine("Upload failed. Retrying upload.");
2021-07-15 03:30:26 +12:00
isError = DoUpload(Data, Info.FileName, retry);
}
2013-11-03 23:53:49 +13:00
}
if (!isError)
{
OnUploadCompleted();
}
2013-11-03 23:53:49 +13:00
}
else
{
Info.Result.IsURLExpected = false;
}
2013-11-03 23:53:49 +13:00
}
}
2021-12-12 10:21:19 +13:00
private bool DoUpload(Stream data, string fileName, int retry = 0)
2013-11-03 23:53:49 +13:00
{
bool isError = false;
2014-04-13 18:59:18 +12:00
if (retry > 0)
{
2014-04-13 18:59:18 +12:00
if (Program.Settings.UseSecondaryUploaders)
{
Info.TaskSettings.ImageDestination = Program.Settings.SecondaryImageUploaders[retry - 1];
Info.TaskSettings.ImageFileDestination = Program.Settings.SecondaryFileUploaders[retry - 1];
Info.TaskSettings.TextDestination = Program.Settings.SecondaryTextUploaders[retry - 1];
Info.TaskSettings.TextFileDestination = Program.Settings.SecondaryFileUploaders[retry - 1];
Info.TaskSettings.FileDestination = Program.Settings.SecondaryFileUploaders[retry - 1];
2014-04-13 18:59:18 +12:00
}
else
{
Thread.Sleep(1000);
}
}
SSLBypassHelper sslBypassHelper = null;
2013-11-03 23:53:49 +13:00
try
{
if (HelpersOptions.AcceptInvalidSSLCertificates)
{
sslBypassHelper = new SSLBypassHelper();
}
2021-12-12 10:21:19 +13:00
if (!CheckUploadFilters(data, fileName))
2013-11-03 23:53:49 +13:00
{
switch (Info.UploadDestination)
{
case EDataType.Image:
2021-12-12 10:21:19 +13:00
Info.Result = UploadImage(data, fileName);
break;
case EDataType.Text:
2021-12-12 10:21:19 +13:00
Info.Result = UploadText(data, fileName);
break;
case EDataType.File:
2021-12-12 10:21:19 +13:00
Info.Result = UploadFile(data, fileName);
break;
}
2013-11-03 23:53:49 +13:00
}
StopRequested |= taskReferenceHelper.StopRequested;
2013-11-03 23:53:49 +13:00
}
catch (Exception e)
{
2014-06-09 04:36:47 +12:00
if (!StopRequested)
2013-11-03 23:53:49 +13:00
{
DebugHelper.WriteException(e);
isError = true;
AddErrorMessage(e.ToString());
2013-11-03 23:53:49 +13:00
}
}
finally
{
if (sslBypassHelper != null)
{
sslBypassHelper.Dispose();
}
if (Info.Result == null)
{
Info.Result = new UploadResult();
}
if (uploader != null)
{
2022-10-05 20:22:02 +13:00
AddErrorMessage(uploader.Errors);
}
2013-11-03 23:53:49 +13:00
isError |= Info.Result.IsError;
}
return isError;
}
2022-10-05 20:22:02 +13:00
private void AddErrorMessage(UploaderErrorManager errors)
{
if (Info.Result == null)
{
Info.Result = new UploadResult();
}
2022-10-05 20:22:02 +13:00
Info.Result.Errors.Add(errors);
}
private void AddErrorMessage(string error)
{
if (Info.Result == null)
{
Info.Result = new UploadResult();
}
Info.Result.Errors.Add(error);
}
private bool DoThreadJob()
2013-11-03 23:53:49 +13:00
{
2014-07-23 08:32:28 +12:00
if (Info.IsUploadJob && Info.TaskSettings.AdvancedSettings.AutoClearClipboard)
{
ClipboardHelpers.Clear();
}
if (Info.Job == TaskJob.Download || Info.Job == TaskJob.DownloadUpload)
{
2016-07-20 22:35:45 +12:00
bool downloadResult = DownloadFromURL(Info.Job == TaskJob.DownloadUpload);
if (!downloadResult)
{
return false;
}
else if (Info.Job == TaskJob.Download)
{
return true;
}
}
if (Info.Job == TaskJob.Job)
2013-11-03 23:53:49 +13:00
{
if (!DoAfterCaptureJobs())
{
return false;
}
DoFileJobs();
2013-11-03 23:53:49 +13:00
}
2019-03-27 19:12:17 +13:00
else if (Info.Job == TaskJob.TextUpload && !string.IsNullOrEmpty(Text))
2013-11-03 23:53:49 +13:00
{
DoTextJobs();
2013-11-03 23:53:49 +13:00
}
else if (Info.Job == TaskJob.FileUpload && Info.TaskSettings.AdvancedSettings.UseAfterCaptureTasksDuringFileUpload)
{
DoFileJobs();
}
2013-11-03 23:53:49 +13:00
2016-05-13 11:43:33 +12:00
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.DoOCR))
{
DoOCR();
}
2013-11-03 23:53:49 +13:00
if (Info.IsUploadJob && Data != null && Data.CanSeek)
{
Data.Position = 0;
}
return true;
2013-11-03 23:53:49 +13:00
}
private bool DoAfterCaptureJobs()
2013-11-03 23:53:49 +13:00
{
if (Image == null)
{
return true;
}
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.BeautifyImage))
{
Image = TaskHelpers.BeautifyImage(Image, Info.TaskSettings);
if (Image == null)
{
return false;
}
}
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.AddImageEffects))
2013-11-03 23:53:49 +13:00
{
Image = TaskHelpers.ApplyImageEffects(Image, Info.TaskSettings.ImageSettingsReference);
if (Image == null)
{
DebugHelper.WriteLine("Error: Applying image effects resulted empty image.");
return false;
}
2013-11-03 23:53:49 +13:00
}
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.AnnotateImage))
2013-11-03 23:53:49 +13:00
{
2020-03-24 08:33:26 +13:00
Image = TaskHelpers.AnnotateImage(Image, null, Info.TaskSettings, true);
if (Image == null)
{
return false;
}
2013-11-03 23:53:49 +13:00
}
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.CopyImageToClipboard))
2013-11-03 23:53:49 +13:00
{
ClipboardHelpers.CopyImage(Image, Info.FileName);
DebugHelper.WriteLine("Image copied to clipboard.");
2013-11-03 23:53:49 +13:00
}
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.PinToScreen))
{
Image imageCopy = Image.CloneSafe();
2023-10-07 18:32:40 +13:00
TaskHelpers.PinToScreen(imageCopy, Info.TaskSettings.ToolsSettingsReference.PinToScreenOptions);
}
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.SendImageToPrinter))
2013-11-03 23:53:49 +13:00
{
TaskHelpers.PrintImage(Image);
2013-11-03 23:53:49 +13:00
}
2021-12-14 13:45:17 +13:00
Info.Metadata.Image = Image;
2016-05-13 11:43:33 +12:00
if (Info.TaskSettings.AfterCaptureJob.HasFlagAny(AfterCaptureTasks.SaveImageToFile, AfterCaptureTasks.SaveImageToFileWithDialog, AfterCaptureTasks.DoOCR,
AfterCaptureTasks.UploadImageToHost))
2013-11-03 23:53:49 +13:00
{
ImageData imageData = TaskHelpers.PrepareImage(Image, Info.TaskSettings);
Data = imageData.ImageStream;
Info.FileName = Path.ChangeExtension(Info.FileName, imageData.ImageFormat.GetDescription());
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.SaveImageToFile))
2013-11-03 23:53:49 +13:00
{
string screenshotsFolder = TaskHelpers.GetScreenshotsFolder(Info.TaskSettings, Info.Metadata);
string filePath = TaskHelpers.HandleExistsFile(screenshotsFolder, Info.FileName, Info.TaskSettings);
2013-11-03 23:53:49 +13:00
if (!string.IsNullOrEmpty(filePath))
2013-11-03 23:53:49 +13:00
{
Info.FilePath = filePath;
imageData.Write(Info.FilePath);
DebugHelper.WriteLine("Image saved to file: " + Info.FilePath);
2013-11-03 23:53:49 +13:00
}
}
2013-11-03 23:53:49 +13:00
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.SaveImageToFileWithDialog))
{
using (SaveFileDialog sfd = new SaveFileDialog())
2013-11-03 23:53:49 +13:00
{
string initialDirectory = null;
if (!string.IsNullOrEmpty(HelpersOptions.LastSaveDirectory) && Directory.Exists(HelpersOptions.LastSaveDirectory))
{
initialDirectory = HelpersOptions.LastSaveDirectory;
}
else
{
initialDirectory = TaskHelpers.GetScreenshotsFolder(Info.TaskSettings, Info.Metadata);
}
bool imageSaved;
do
{
sfd.InitialDirectory = initialDirectory;
sfd.FileName = Info.FileName;
sfd.DefaultExt = Path.GetExtension(Info.FileName).Substring(1);
sfd.Filter = string.Format("*{0}|*{0}|All files (*.*)|*.*", Path.GetExtension(Info.FileName));
sfd.Title = Resources.UploadTask_DoAfterCaptureJobs_Choose_a_folder_to_save + " " + Path.GetFileName(Info.FileName);
if (sfd.ShowDialog() == DialogResult.OK && !string.IsNullOrEmpty(sfd.FileName))
{
Info.FilePath = sfd.FileName;
HelpersOptions.LastSaveDirectory = Path.GetDirectoryName(Info.FilePath);
imageSaved = imageData.Write(Info.FilePath);
if (imageSaved)
{
DebugHelper.WriteLine("Image saved to file with dialog: " + Info.FilePath);
}
}
else
{
break;
}
} while (!imageSaved);
2013-11-03 23:53:49 +13:00
}
}
2013-11-03 23:53:49 +13:00
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.SaveThumbnailImageToFile))
{
2021-12-12 10:21:19 +13:00
string thumbnailFileName, thumbnailFolder;
if (!string.IsNullOrEmpty(Info.FilePath))
{
2021-12-12 10:21:19 +13:00
thumbnailFileName = Path.GetFileName(Info.FilePath);
thumbnailFolder = Path.GetDirectoryName(Info.FilePath);
}
else
{
2021-12-12 10:21:19 +13:00
thumbnailFileName = Info.FileName;
thumbnailFolder = TaskHelpers.GetScreenshotsFolder(Info.TaskSettings, Info.Metadata);
}
2021-12-12 10:21:19 +13:00
Info.ThumbnailFilePath = TaskHelpers.CreateThumbnail(Image, thumbnailFolder, thumbnailFileName, Info.TaskSettings);
if (!string.IsNullOrEmpty(Info.ThumbnailFilePath))
{
DebugHelper.WriteLine("Thumbnail saved to file: " + Info.ThumbnailFilePath);
}
}
}
return true;
}
private void DoFileJobs()
{
if (!string.IsNullOrEmpty(Info.FilePath) && File.Exists(Info.FilePath))
{
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.PerformActions) && Info.TaskSettings.ExternalPrograms != null)
{
2016-09-17 19:07:02 +12:00
IEnumerable<ExternalProgram> actions = Info.TaskSettings.ExternalPrograms.Where(x => x.IsActive);
2013-11-03 23:53:49 +13:00
if (actions.Count() > 0)
{
bool isFileModified = false;
string fileName = Info.FileName;
foreach (ExternalProgram fileAction in actions)
{
string modifiedPath = fileAction.Run(Info.FilePath);
if (!string.IsNullOrEmpty(modifiedPath))
{
isFileModified = true;
Info.FilePath = modifiedPath;
2021-03-27 13:40:59 +13:00
if (Data != null)
{
Data.Dispose();
}
fileAction.DeletePendingInputFile();
}
2013-11-03 23:53:49 +13:00
}
if (isFileModified)
{
string extension = FileHelpers.GetFileNameExtension(Info.FilePath);
Info.FileName = FileHelpers.ChangeFileNameExtension(fileName, extension);
LoadFileStream();
}
2013-11-03 23:53:49 +13:00
}
}
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.CopyFileToClipboard))
{
ClipboardHelpers.CopyFile(Info.FilePath);
}
else if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.CopyFilePathToClipboard))
{
ClipboardHelpers.CopyText(Info.FilePath);
}
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.ShowInExplorer))
{
FileHelpers.OpenFolderWithFile(Info.FilePath);
}
if (Info.TaskSettings.AfterCaptureJob.HasFlag(AfterCaptureTasks.ScanQRCode) && Info.DataType == EDataType.Image)
{
2023-06-14 18:35:37 +12:00
QRCodeForm.OpenFormScanFromImageFile(Info.FilePath).ShowDialog();
}
2013-11-03 23:53:49 +13:00
}
}
private void DoTextJobs()
{
if (Info.TaskSettings.AdvancedSettings.TextTaskSaveAsFile)
{
string screenshotsFolder = TaskHelpers.GetScreenshotsFolder(Info.TaskSettings);
string filePath = TaskHelpers.HandleExistsFile(screenshotsFolder, Info.FileName, Info.TaskSettings);
if (!string.IsNullOrEmpty(filePath))
{
Info.FilePath = filePath;
FileHelpers.CreateDirectoryFromFilePath(Info.FilePath);
2019-03-27 19:12:17 +13:00
File.WriteAllText(Info.FilePath, Text, Encoding.UTF8);
DebugHelper.WriteLine("Text saved to file: " + Info.FilePath);
}
}
2019-03-27 19:12:17 +13:00
byte[] byteArray = Encoding.UTF8.GetBytes(Text);
Data = new MemoryStream(byteArray);
}
2013-11-03 23:53:49 +13:00
private void DoAfterUploadJobs()
{
try
{
if (Info.TaskSettings.UploadSettings.URLRegexReplace)
{
Info.Result.URL = Regex.Replace(Info.Result.URL, Info.TaskSettings.UploadSettings.URLRegexReplacePattern,
Info.TaskSettings.UploadSettings.URLRegexReplaceReplacement);
}
if (Info.TaskSettings.AdvancedSettings.ResultForceHTTPS)
{
Info.Result.ForceHTTPS();
}
if (Info.Job != TaskJob.ShareURL && (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.UseURLShortener) || Info.Job == TaskJob.ShortenURL ||
(Info.TaskSettings.AdvancedSettings.AutoShortenURLLength > 0 && Info.Result.URL.Length > Info.TaskSettings.AdvancedSettings.AutoShortenURLLength)))
2013-11-03 23:53:49 +13:00
{
UploadResult result = ShortenURL(Info.Result.URL);
if (result != null)
{
Info.Result.ShortenedURL = result.ShortenedURL;
2022-10-05 20:22:02 +13:00
Info.Result.Errors.Add(result.Errors);
2013-11-03 23:53:49 +13:00
}
}
if (Info.Job != TaskJob.ShortenURL && (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.ShareURL) || Info.Job == TaskJob.ShareURL))
2013-11-03 23:53:49 +13:00
{
UploadResult result = ShareURL(Info.Result.ToString());
if (result != null)
{
2022-10-05 20:22:02 +13:00
Info.Result.Errors.Add(result.Errors);
}
if (Info.Job == TaskJob.ShareURL)
{
Info.Result.IsURLExpected = false;
}
2013-11-03 23:53:49 +13:00
}
if (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.CopyURLToClipboard))
2013-11-03 23:53:49 +13:00
{
string txt;
if (!string.IsNullOrEmpty(Info.TaskSettings.AdvancedSettings.ClipboardContentFormat))
2013-11-03 23:53:49 +13:00
{
txt = new UploadInfoParser().Parse(Info, Info.TaskSettings.AdvancedSettings.ClipboardContentFormat);
2013-11-03 23:53:49 +13:00
}
else
{
txt = Info.Result.ToString();
}
if (!string.IsNullOrEmpty(txt))
{
ClipboardHelpers.CopyText(txt);
}
}
2014-06-11 12:47:20 +12:00
if (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.OpenURL))
{
string result;
if (!string.IsNullOrEmpty(Info.TaskSettings.AdvancedSettings.OpenURLFormat))
{
result = new UploadInfoParser().Parse(Info, Info.TaskSettings.AdvancedSettings.OpenURLFormat);
}
else
{
result = Info.Result.ToString();
}
URLHelpers.OpenURL(result);
2014-06-11 12:47:20 +12:00
}
if (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.ShowQRCode))
{
threadWorker.InvokeAsync(() => new QRCodeForm(Info.Result.ToString()).Show());
}
2013-11-03 23:53:49 +13:00
}
catch (Exception e)
{
DebugHelper.WriteException(e);
AddErrorMessage(e.ToString());
2013-11-03 23:53:49 +13:00
}
}
public UploadResult UploadData(IGenericUploaderService service, Stream stream, string fileName)
2013-11-03 23:53:49 +13:00
{
if (!service.CheckConfig(Program.UploadersConfig))
{
return GetInvalidConfigResult(service);
}
2016-04-15 12:25:08 +12:00
uploader = service.CreateUploader(Program.UploadersConfig, taskReferenceHelper);
if (uploader != null)
2013-11-03 23:53:49 +13:00
{
uploader.Errors.DefaultTitle = service.ServiceName + " " + "error";
uploader.BufferSize = (int)Math.Pow(2, Program.Settings.BufferSizePower) * 1024;
uploader.ProgressChanged += uploader_ProgressChanged;
if (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.CopyURLToClipboard) && Info.TaskSettings.AdvancedSettings.EarlyCopyURL)
{
uploader.EarlyURLCopyRequested += url =>
{
ClipboardHelpers.CopyText(url);
EarlyURLCopied = true;
};
}
fileName = URLHelpers.RemoveBidiControlCharacters(fileName);
if (Info.TaskSettings.UploadSettings.FileUploadReplaceProblematicCharacters)
{
2018-07-14 18:10:06 +12:00
fileName = URLHelpers.ReplaceReservedCharacters(fileName, "_");
}
Info.UploadDuration = Stopwatch.StartNew();
UploadResult result = uploader.Upload(stream, fileName);
Info.UploadDuration.Stop();
return result;
2013-11-03 23:53:49 +13:00
}
return null;
}
2021-12-12 10:21:19 +13:00
private bool CheckUploadFilters(Stream stream, string fileName)
{
2021-12-12 10:21:19 +13:00
if (Info.TaskSettings.UploadSettings.UploaderFilters != null && !string.IsNullOrEmpty(fileName) && stream != null)
{
2021-12-12 10:21:19 +13:00
UploaderFilter filter = Info.TaskSettings.UploadSettings.UploaderFilters.FirstOrDefault(x => x.IsValidFilter(fileName));
if (filter != null)
{
IGenericUploaderService service = filter.GetUploaderService();
if (service != null)
{
2021-12-12 10:21:19 +13:00
Info.Result = UploadData(service, stream, fileName);
return true;
}
}
}
return false;
}
public UploadResult UploadImage(Stream stream, string fileName)
2013-11-03 23:53:49 +13:00
{
2016-04-15 12:25:08 +12:00
ImageUploaderService service = UploaderFactory.ImageUploaderServices[Info.TaskSettings.ImageDestination];
return UploadData(service, stream, fileName);
}
2013-11-03 23:53:49 +13:00
public UploadResult UploadText(Stream stream, string fileName)
{
2016-04-15 12:25:08 +12:00
TextUploaderService service = UploaderFactory.TextUploaderServices[Info.TaskSettings.TextDestination];
return UploadData(service, stream, fileName);
2013-11-03 23:53:49 +13:00
}
public UploadResult UploadFile(Stream stream, string fileName)
{
2016-04-15 12:25:08 +12:00
FileUploaderService service = UploaderFactory.FileUploaderServices[Info.TaskSettings.GetFileDestinationByDataType(Info.DataType)];
return UploadData(service, stream, fileName);
2013-11-03 23:53:49 +13:00
}
public UploadResult ShortenURL(string url)
{
2016-04-15 12:25:08 +12:00
URLShortenerService service = UploaderFactory.URLShortenerServices[Info.TaskSettings.URLShortenerDestination];
if (!service.CheckConfig(Program.UploadersConfig))
{
return GetInvalidConfigResult(service);
}
URLShortener urlShortener = service.CreateShortener(Program.UploadersConfig, taskReferenceHelper);
2013-12-21 04:59:26 +13:00
if (urlShortener != null)
{
return urlShortener.ShortenURL(url);
2013-11-03 23:53:49 +13:00
}
return null;
}
public UploadResult ShareURL(string url)
2014-06-15 22:29:09 +12:00
{
if (!string.IsNullOrEmpty(url))
{
2016-04-15 12:25:08 +12:00
URLSharingService service = UploaderFactory.URLSharingServices[Info.TaskSettings.URLSharingServiceDestination];
if (!service.CheckConfig(Program.UploadersConfig))
{
return GetInvalidConfigResult(service);
}
2017-09-10 22:55:21 +12:00
URLSharer urlSharer = service.CreateSharer(Program.UploadersConfig, taskReferenceHelper);
2017-09-10 22:55:21 +12:00
if (urlSharer != null)
{
return urlSharer.ShareURL(url);
}
}
return null;
2014-06-15 22:29:09 +12:00
}
private UploadResult GetInvalidConfigResult(IUploaderService uploaderService)
{
UploadResult ur = new UploadResult();
2016-07-13 13:14:54 +12:00
string message = string.Format(Resources.WorkerTask_GetInvalidConfigResult__0__configuration_is_invalid_or_missing__Please_check__Destination_settings__window_to_configure_it_,
uploaderService.ServiceName);
2016-04-05 23:03:05 +12:00
DebugHelper.WriteLine(message);
ur.Errors.Add(message);
OnUploadersConfigWindowRequested(uploaderService);
return ur;
}
private bool DownloadFromURL(bool upload)
{
string url = Info.Result.URL.Trim();
2016-05-25 06:15:45 +12:00
Info.Result.URL = "";
if (!Info.TaskSettings.UploadSettings.FileUploadUseNamePattern)
{
try
{
2023-10-29 19:58:20 +13:00
string fileName = WebHelpers.GetFileNameFromWebServerAsync(url).GetAwaiter().GetResult();
if (!string.IsNullOrEmpty(fileName))
{
Info.FileName = FileHelpers.SanitizeFileName(fileName);
}
}
catch (Exception e)
{
DebugHelper.WriteException(e);
}
}
string screenshotsFolder = TaskHelpers.GetScreenshotsFolder(Info.TaskSettings);
Info.FilePath = TaskHelpers.HandleExistsFile(screenshotsFolder, Info.FileName, Info.TaskSettings);
2015-08-29 18:11:37 +12:00
if (!string.IsNullOrEmpty(Info.FilePath))
{
2015-08-29 18:11:37 +12:00
Info.Status = Resources.UploadTask_DownloadAndUpload_Downloading;
OnStatusChanged();
2015-08-29 18:11:37 +12:00
try
{
2023-10-29 19:58:20 +13:00
WebHelpers.DownloadFileAsync(url, Info.FilePath).GetAwaiter().GetResult();
if (upload)
{
LoadFileStream();
}
2015-08-29 18:11:37 +12:00
return true;
}
catch (Exception e)
{
DebugHelper.WriteException(e);
MessageBox.Show(string.Format(Resources.UploadManager_DownloadAndUploadFile_Download_failed, e), "ShareX", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
return false;
}
2016-05-13 11:43:33 +12:00
private void DoOCR()
{
2018-11-30 20:43:56 +13:00
if (Image != null && Info.DataType == EDataType.Image)
2016-05-13 11:43:33 +12:00
{
2022-04-20 16:15:08 +12:00
TaskHelpers.OCRImage(Image, Info.TaskSettings).GetAwaiter().GetResult();
2016-05-13 11:43:33 +12:00
}
}
private bool LoadFileStream()
{
try
{
Data = new FileStream(Info.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
}
catch (Exception e)
{
2017-04-22 08:42:52 +12:00
e.ShowError();
return false;
}
return true;
}
2013-11-03 23:53:49 +13:00
private void ThreadCompleted()
{
OnTaskCompleted();
2013-11-03 23:53:49 +13:00
}
private void uploader_ProgressChanged(ProgressManager progress)
{
if (progress != null)
{
Info.Progress = progress;
OnUploadProgressChanged();
2013-11-03 23:53:49 +13:00
}
}
private void OnStatusChanged()
{
if (StatusChanged != null)
{
threadWorker.InvokeAsync(() => StatusChanged(this));
2013-11-03 23:53:49 +13:00
}
}
private void OnImageReady()
{
if (ImageReady != null)
{
2020-03-24 08:33:26 +13:00
Bitmap image = null;
if (Program.Settings.TaskViewMode == TaskViewMode.ThumbnailView && Image != null)
{
2020-03-24 08:33:26 +13:00
image = (Bitmap)Image.Clone();
}
threadWorker.InvokeAsync(() =>
{
using (image)
{
ImageReady(this, image);
}
});
}
}
2013-11-03 23:53:49 +13:00
private void OnUploadStarted()
{
if (UploadStarted != null)
{
threadWorker.InvokeAsync(() => UploadStarted(this));
2013-11-03 23:53:49 +13:00
}
}
private void OnUploadCompleted()
{
if (UploadCompleted != null)
{
threadWorker.InvokeAsync(() => UploadCompleted(this));
}
}
2013-11-03 23:53:49 +13:00
private void OnUploadProgressChanged()
{
if (UploadProgressChanged != null)
{
threadWorker.InvokeAsync(() => UploadProgressChanged(this));
2013-11-03 23:53:49 +13:00
}
}
private void OnTaskCompleted()
2013-11-03 23:53:49 +13:00
{
2017-06-12 08:01:11 +12:00
Info.TaskEndTime = DateTime.Now;
2014-06-09 04:36:47 +12:00
if (StopRequested)
2013-11-03 23:53:49 +13:00
{
2018-06-11 05:39:48 +12:00
Status = TaskStatus.Stopped;
Info.Status = Resources.UploadTask_OnUploadCompleted_Stopped;
2013-11-03 23:53:49 +13:00
}
2018-06-11 05:39:48 +12:00
else if (Info.Result.IsError)
{
Status = TaskStatus.Failed;
Info.Status = Resources.TaskManager_task_UploadCompleted_Error;
}
2013-11-03 23:53:49 +13:00
else
{
2018-06-11 05:39:48 +12:00
Status = TaskStatus.Completed;
Info.Status = Resources.UploadTask_OnUploadCompleted_Done;
2013-11-03 23:53:49 +13:00
}
2021-06-10 10:14:01 +12:00
TaskCompleted?.Invoke(this);
2013-11-03 23:53:49 +13:00
Dispose();
}
private void OnUploadersConfigWindowRequested(IUploaderService uploaderService)
{
if (UploadersConfigWindowRequested != null)
{
threadWorker.InvokeAsync(() => UploadersConfigWindowRequested(uploaderService));
}
}
public void Dispose()
2013-11-03 23:53:49 +13:00
{
if (Data != null)
{
Data.Dispose();
Data = null;
}
if (!KeepImage && Image != null)
{
Image.Dispose();
Image = null;
}
2013-11-03 23:53:49 +13:00
}
}
}