diff --git a/src/Jackett/Indexers/CardigannIndexer.cs b/src/Jackett/Indexers/CardigannIndexer.cs
index f9c7d8614..b01201a2f 100644
--- a/src/Jackett/Indexers/CardigannIndexer.cs
+++ b/src/Jackett/Indexers/CardigannIndexer.cs
@@ -1029,6 +1029,9 @@ namespace Jackett.Indexers
case "urldecode":
Data = HttpUtility.UrlDecode(Data, Encoding);
break;
+ case "urlencode":
+ Data = HttpUtility.UrlEncode(Data, Encoding);
+ break;
case "timeago":
case "reltime":
Data = DateTimeUtil.FromTimeAgo(Data).ToString(DateTimeUtil.RFC1123ZPattern);
@@ -1036,6 +1039,9 @@ namespace Jackett.Indexers
case "fuzzytime":
Data = DateTimeUtil.FromUnknown(Data).ToString(DateTimeUtil.RFC1123ZPattern);
break;
+ case "validfilename":
+ Data = StringUtil.MakeValidFileName(Data, '_', false);
+ break;
case "hexdump":
// this is mainly for debugging invisible special char related issues
var HexData = string.Join("", Data.Select(c => c + "(" + ((int)c).ToString("X2") + ")"));
diff --git a/src/Jackett/Utils/StringUtil.cs b/src/Jackett/Utils/StringUtil.cs
index ff9d6e959..0c91ffc55 100644
--- a/src/Jackett/Utils/StringUtil.cs
+++ b/src/Jackett/Utils/StringUtil.cs
@@ -89,6 +89,43 @@ namespace Jackett.Utils
return String.Join("\n", fields);
}
+ static char[] MakeValidFileName_invalids;
+
+ /// Replaces characters in text that are not allowed in
+ /// file names with the specified replacement character.
+ /// Text to make into a valid filename. The same string is returned if it is valid already.
+ /// Replacement character, or null to simply remove bad characters.
+ /// Whether to replace quotes and slashes with the non-ASCII characters ” and ⁄.
+ /// A string that can be used as a filename. If the output string would otherwise be empty, returns "_".
+ public static string MakeValidFileName(string text, char? replacement = '_', bool fancy = true)
+ {
+ StringBuilder sb = new StringBuilder(text.Length);
+ var invalids = MakeValidFileName_invalids ?? (MakeValidFileName_invalids = Path.GetInvalidFileNameChars());
+ bool changed = false;
+ for (int i = 0; i < text.Length; i++)
+ {
+ char c = text[i];
+ if (invalids.Contains(c))
+ {
+ changed = true;
+ var repl = replacement ?? '\0';
+ if (fancy)
+ {
+ if (c == '"') repl = '”'; // U+201D right double quotation mark
+ else if (c == '\'') repl = '’'; // U+2019 right single quotation mark
+ else if (c == '/') repl = '⁄'; // U+2044 fraction slash
+ }
+ if (repl != '\0')
+ sb.Append(repl);
+ }
+ else
+ sb.Append(c);
+ }
+ if (sb.Length == 0)
+ return "_";
+ return changed ? sb.ToString() : text;
+ }
+
public static string GetQueryString(this NameValueCollection collection, Encoding encoding = null)
{
if (encoding == null)