[PTRun][ValueGenerator]Add URI/URL features (#30648)

* move existing generator classes

* add new generators

* implement new generators

* fixes

* improvements

* shorten query tags

* make spellcheck happy

* add tests

* dev docs

* fix typos

* fix tests
This commit is contained in:
Heiko
2024-01-03 17:30:11 +01:00
committed by GitHub
parent 2a544583c0
commit 7c0f24df65
16 changed files with 475 additions and 13 deletions

View File

@@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Text;
using Wox.Plugin.Logger;
namespace Community.PowerToys.Run.Plugin.ValueGenerator.Uri
{
public class DataEscapeRequest : IComputeRequest
{
public byte[] Result { get; set; }
public string Description => "Data string escaped";
public bool IsSuccessful { get; set; }
public string ErrorMessage { get; set; }
private string DataToEscape { get; set; }
public DataEscapeRequest(string dataToEscape)
{
DataToEscape = dataToEscape ?? throw new ArgumentNullException(nameof(dataToEscape));
}
public bool Compute()
{
IsSuccessful = true;
try
{
Result = Encoding.UTF8.GetBytes(System.Uri.EscapeDataString(DataToEscape));
}
catch (Exception e)
{
Log.Exception(e.Message, e, GetType());
ErrorMessage = e.Message;
IsSuccessful = false;
}
return IsSuccessful;
}
public string ResultToString()
{
return Encoding.UTF8.GetString(Result);
}
}
}

View File

@@ -0,0 +1,58 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Text;
using Wox.Plugin.Logger;
namespace Community.PowerToys.Run.Plugin.ValueGenerator.Uri
{
public class DataUnescapeRequest : IComputeRequest
{
public byte[] Result { get; set; }
public string Description => "Data string unescaped";
public bool IsSuccessful { get; set; }
public string ErrorMessage { get; set; }
private string DataToUnescape { get; set; }
public DataUnescapeRequest(string dataToUnescape)
{
DataToUnescape = dataToUnescape ?? throw new ArgumentNullException(nameof(dataToUnescape));
}
public bool Compute()
{
IsSuccessful = true;
try
{
Result = Encoding.UTF8.GetBytes(System.Uri.UnescapeDataString(DataToUnescape));
}
catch (Exception e)
{
Log.Exception(e.Message, e, GetType());
ErrorMessage = e.Message;
IsSuccessful = false;
}
return IsSuccessful;
}
public string ResultToString()
{
if (Result != null)
{
return Encoding.UTF8.GetString(Result);
}
else
{
return string.Empty;
}
}
}
}

View File

@@ -0,0 +1,58 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Linq;
using System.Text;
using Wox.Plugin.Logger;
namespace Community.PowerToys.Run.Plugin.ValueGenerator.Uri
{
public class HexEscapeRequest : IComputeRequest
{
public byte[] Result { get; set; }
public string Description => "Hex escaped char";
public bool IsSuccessful { get; set; }
public string ErrorMessage { get; set; }
private string DataToEscape { get; set; }
public HexEscapeRequest(string dataToEscape)
{
DataToEscape = dataToEscape ?? throw new ArgumentNullException(nameof(dataToEscape));
// Validate that we have only one character
if (dataToEscape.Length != 1)
{
throw new ArgumentOutOfRangeException(nameof(dataToEscape));
}
}
public bool Compute()
{
IsSuccessful = true;
try
{
char charToEscape = DataToEscape[0];
Result = Encoding.UTF8.GetBytes(System.Uri.HexEscape(charToEscape));
}
catch (Exception e)
{
Log.Exception(e.Message, e, GetType());
ErrorMessage = e.Message;
IsSuccessful = false;
}
return IsSuccessful;
}
public string ResultToString()
{
return Encoding.UTF8.GetString(Result);
}
}
}

View File

@@ -0,0 +1,62 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Text;
using Wox.Plugin.Logger;
namespace Community.PowerToys.Run.Plugin.ValueGenerator.Uri
{
public class HexUnescapeRequest : IComputeRequest
{
public byte[] Result { get; set; }
public string Description => "Hex char unescaped";
public bool IsSuccessful { get; set; }
public string ErrorMessage { get; set; }
private string DataToUnescape { get; set; }
public HexUnescapeRequest(string dataToUnescape)
{
DataToUnescape = dataToUnescape ?? throw new ArgumentNullException(nameof(dataToUnescape));
}
public bool Compute()
{
IsSuccessful = true;
try
{
int index = 0;
if (System.Uri.IsHexEncoding(DataToUnescape, index))
{
Result = Encoding.UTF8.GetBytes(System.Uri.HexUnescape(DataToUnescape, ref index).ToString());
}
}
catch (Exception e)
{
Log.Exception(e.Message, e, GetType());
ErrorMessage = e.Message;
IsSuccessful = false;
}
return IsSuccessful;
}
public string ResultToString()
{
if (Result != null)
{
return Encoding.UTF8.GetString(Result);
}
else
{
return string.Empty;
}
}
}
}

View File

@@ -0,0 +1,60 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Security.Policy;
using System.Text;
using System.Web;
using Wox.Plugin.Logger;
namespace Community.PowerToys.Run.Plugin.ValueGenerator.Uri
{
public class UrlDecodeRequest : IComputeRequest
{
public byte[] Result { get; set; }
public string Description => "Decoded URL";
public bool IsSuccessful { get; set; }
public string ErrorMessage { get; set; }
private string DataToDecode { get; set; }
public UrlDecodeRequest(string dataToDecode)
{
DataToDecode = dataToDecode ?? throw new ArgumentNullException(nameof(dataToDecode));
}
public bool Compute()
{
IsSuccessful = true;
try
{
Result = Encoding.UTF8.GetBytes(HttpUtility.UrlDecode(DataToDecode));
}
catch (Exception e)
{
Log.Exception(e.Message, e, GetType());
ErrorMessage = e.Message;
IsSuccessful = false;
}
return IsSuccessful;
}
public string ResultToString()
{
if (Result != null)
{
return Encoding.UTF8.GetString(Result);
}
else
{
return string.Empty;
}
}
}
}

View File

@@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Security.Policy;
using System.Text;
using System.Web;
using Wox.Plugin.Logger;
namespace Community.PowerToys.Run.Plugin.ValueGenerator.Uri
{
public class UrlEncodeRequest : IComputeRequest
{
public byte[] Result { get; set; }
public string Description => "Encoded URL";
public bool IsSuccessful { get; set; }
public string ErrorMessage { get; set; }
private string DataToEncode { get; set; }
public UrlEncodeRequest(string dataToEncode)
{
DataToEncode = dataToEncode ?? throw new ArgumentNullException(nameof(dataToEncode));
}
public bool Compute()
{
IsSuccessful = true;
try
{
Result = Encoding.UTF8.GetBytes(HttpUtility.UrlEncode(DataToEncode));
}
catch (Exception e)
{
Log.Exception(e.Message, e, GetType());
ErrorMessage = e.Message;
IsSuccessful = false;
}
return IsSuccessful;
}
public string ResultToString()
{
return Encoding.UTF8.GetString(Result);
}
}
}

View File

@@ -8,6 +8,7 @@ using System.Text;
using Community.PowerToys.Run.Plugin.ValueGenerator.Base64;
using Community.PowerToys.Run.Plugin.ValueGenerator.GUID;
using Community.PowerToys.Run.Plugin.ValueGenerator.Hashing;
using Community.PowerToys.Run.Plugin.ValueGenerator.Uri;
using Wox.Plugin;
using Wox.Plugin.Logger;
@@ -127,6 +128,69 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator
string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();
request = new Base64DecodeRequest(content);
}
else if (command.StartsWith("esc:", StringComparison.OrdinalIgnoreCase))
{
// Escape things
if (command.Equals("esc:data", StringComparison.OrdinalIgnoreCase))
{
int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);
string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();
request = new DataEscapeRequest(content);
}
else if (command.Equals("esc:hex", StringComparison.OrdinalIgnoreCase))
{
int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);
string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();
// This is only for single chars
if (content.Length > 1)
{
throw new ArgumentException($"Invalid Query: {query.RawUserQuery} (To many characters.)");
}
else if (content.Length == 0)
{
throw new FormatException($"Invalid Query: {query.RawUserQuery}");
}
request = new HexEscapeRequest(content);
}
else
{
throw new FormatException($"Invalid Query: {query.RawUserQuery}");
}
}
else if (command.StartsWith("uesc:", StringComparison.OrdinalIgnoreCase))
{
// Unescape things
if (command.Equals("uesc:data", StringComparison.OrdinalIgnoreCase))
{
int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);
string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();
request = new DataUnescapeRequest(content);
}
else if (command.Equals("uesc:hex", StringComparison.OrdinalIgnoreCase))
{
int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);
string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();
request = new HexUnescapeRequest(content);
}
else
{
throw new FormatException($"Invalid Query: {query.RawUserQuery}");
}
}
else if (command.Equals("url", StringComparison.OrdinalIgnoreCase))
{
int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);
string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();
request = new UrlEncodeRequest(content);
}
else if (command.Equals("urld", StringComparison.OrdinalIgnoreCase))
{
int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);
string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();
request = new UrlDecodeRequest(content);
}
else
{
throw new FormatException($"Invalid Query: {query.RawUserQuery}");

View File

@@ -93,7 +93,16 @@ namespace Community.PowerToys.Run.Plugin.ValueGenerator
try
{
IComputeRequest computeRequest = _inputParser.ParseInput(query);
results.Add(GetResult(computeRequest));
var result = GetResult(computeRequest);
if (!string.IsNullOrEmpty(result.Title))
{
results.Add(result);
}
else
{
return results;
}
}
catch (ArgumentException e)
{