NadekoBot/NadekoBot/Classes/Extensions.cs

296 lines
10 KiB
C#
Raw Normal View History

2016-04-18 21:38:19 +00:00
using Discord;
using Discord.Commands;
using NadekoBot.Classes;
using System;
2015-12-05 10:27:00 +00:00
using System.Collections.Generic;
2016-04-18 21:38:19 +00:00
using System.Drawing;
using System.IO;
2015-12-05 10:27:00 +00:00
using System.Linq;
using System.Security.Cryptography;
2016-04-18 21:38:19 +00:00
using System.Threading.Tasks;
2015-12-05 10:27:00 +00:00
2016-04-18 21:38:19 +00:00
namespace NadekoBot.Extensions
{
2015-12-05 10:27:00 +00:00
public static class Extensions
{
private static Random rng = new Random();
2016-04-18 21:38:19 +00:00
public static string Scramble(this string word)
{
var letters = word.ToArray();
var count = 0;
2016-04-18 21:38:19 +00:00
for (var i = 0; i < letters.Length; i++)
{
if (letters[i] == ' ')
continue;
count++;
if (count <= letters.Length / 5)
continue;
if (count % 3 == 0)
continue;
if (letters[i] != ' ')
letters[i] = '_';
}
2016-04-18 21:38:19 +00:00
return "`" + string.Join(" ", letters) + "`";
}
2016-04-18 21:38:19 +00:00
public static string TrimTo(this string str, int num, bool hideDots = false)
{
2016-01-30 11:08:30 +00:00
if (num < 0)
throw new ArgumentOutOfRangeException(nameof(num), "TrimTo argument cannot be less than 0");
2016-01-30 11:08:30 +00:00
if (num == 0)
return string.Empty;
2016-01-30 11:08:30 +00:00
if (num <= 3)
return string.Join("", str.Select(c => '.'));
2016-01-30 11:08:30 +00:00
if (str.Length < num)
return str;
return string.Join("", str.Take(num - 3)) + (hideDots ? "" : "...");
2016-01-30 11:08:30 +00:00
}
/// <summary>
/// Removes trailing S or ES (if specified) on the given string if the num is 1
/// </summary>
/// <param name="str"></param>
/// <param name="num"></param>
/// <param name="es"></param>
/// <returns>String with the correct singular/plural form</returns>
2016-04-18 21:38:19 +00:00
public static string SnPl(this string str, int? num, bool es = false)
{
if (str == null)
throw new ArgumentNullException(nameof(str));
if (num == null)
throw new ArgumentNullException(nameof(num));
return num == 1 ? str.Remove(str.Length - 1, es ? 2 : 1) : str;
}
/// <summary>
/// Sends a message to the channel from which this command is called.
/// </summary>
/// <param name="e">EventArg</param>
/// <param name="message">Message to be sent</param>
/// <returns></returns>
2016-04-18 21:38:19 +00:00
public static async Task<Message> Send(this CommandEventArgs e, string message)
=> await e.Channel.SendMessage(message).ConfigureAwait(false);
/// <summary>
/// Sends a message to the channel from which MessageEventArg came.
/// </summary>
/// <param name="e">EventArg</param>
/// <param name="message">Message to be sent</param>
/// <returns></returns>
public static async Task Send(this MessageEventArgs e, string message)
{
2016-02-04 06:24:40 +00:00
if (string.IsNullOrWhiteSpace(message))
return;
2016-04-18 21:38:19 +00:00
await e.Channel.SendMessage(message).ConfigureAwait(false);
}
/// <summary>
/// Sends a message to this channel.
/// </summary>
/// <param name="c"></param>
/// <param name="message"></param>
/// <returns></returns>
public static async Task Send(this Channel c, string message)
{
2016-04-18 21:38:19 +00:00
await c.SendMessage(message).ConfigureAwait(false);
}
/// <summary>
/// Sends a private message to this user.
/// </summary>
/// <param name="c"></param>
/// <param name="message"></param>
/// <returns></returns>
public static async Task Send(this User u, string message)
{
2016-04-18 21:38:19 +00:00
await u.SendMessage(message).ConfigureAwait(false);
}
/// <summary>
/// Replies to a user who invoked this command, message start with that user's mention.
/// </summary>
/// <param name="e"></param>
/// <param name="message"></param>
/// <returns></returns>
public static async Task Reply(this CommandEventArgs e, string message)
{
2016-04-18 21:38:19 +00:00
await e.Channel.SendMessage(e.User.Mention + " " + message).ConfigureAwait(false);
}
/// <summary>
/// Replies to a user who invoked this command, message start with that user's mention.
/// </summary>
/// <param name="e"></param>
/// <param name="message"></param>
/// <returns></returns>
public static async Task Reply(this MessageEventArgs e, string message)
{
2016-04-18 21:38:19 +00:00
await e.Channel.SendMessage(e.User.Mention + " " + message).ConfigureAwait(false);
}
/// <summary>
/// Randomizes element order in a list
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
2015-12-05 10:27:00 +00:00
public static void Shuffle<T>(this IList<T> list)
{
// Thanks to @Joe4Evr for finding a bug in the old version of the shuffle
var provider = new RNGCryptoServiceProvider();
var n = list.Count;
2015-12-05 10:27:00 +00:00
while (n > 1)
{
var box = new byte[(n / Byte.MaxValue) + 1];
int boxSum;
do
{
provider.GetBytes(box);
boxSum = box.Sum(b => b);
}
while (!(boxSum < n * ((Byte.MaxValue * box.Length) / n)));
var k = (boxSum % n);
2015-12-05 10:27:00 +00:00
n--;
var value = list[k];
2015-12-05 10:27:00 +00:00
list[k] = list[n];
list[n] = value;
}
}
2015-12-30 04:44:36 +00:00
/// <summary>
/// Shortens a string URL
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action"></param>
2016-04-18 21:38:19 +00:00
public static async Task<string> ShortenUrl(this string str) => await SearchHelper.ShortenUrl(str).ConfigureAwait(false);
2016-01-21 22:22:55 +00:00
/// <summary>
/// Gets the program runtime
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action"></param>
public static string GetRuntime(this DiscordClient c) => ".Net Framework 4.5.2";
public static string Matrix(this string s)
=>
string.Join("", s.Select(c => c.ToString() + " ̵̢̬̜͉̞̭̖̰͋̉̎ͬ̔̇̌̀".TrimTo(rng.Next(0, 12), true)));
2016-04-18 21:38:19 +00:00
//.Replace("`", "");
2016-04-18 21:38:19 +00:00
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (var element in source)
{
2015-12-30 04:44:36 +00:00
action(element);
}
}
//http://www.dotnetperls.com/levenshtein
2016-04-18 21:38:19 +00:00
public static int LevenshteinDistance(this string s, string t)
{
var n = s.Length;
var m = t.Length;
var d = new int[n + 1, m + 1];
// Step 1
2016-04-18 21:38:19 +00:00
if (n == 0)
{
return m;
}
2016-04-18 21:38:19 +00:00
if (m == 0)
{
return n;
}
// Step 2
2016-04-18 21:38:19 +00:00
for (var i = 0; i <= n; d[i, 0] = i++)
{
}
2016-04-18 21:38:19 +00:00
for (var j = 0; j <= m; d[0, j] = j++)
{
}
// Step 3
2016-04-18 21:38:19 +00:00
for (var i = 1; i <= n; i++)
{
//Step 4
2016-04-18 21:38:19 +00:00
for (var j = 1; j <= m; j++)
{
// Step 5
var cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
// Step 6
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
return d[n, m];
}
public static int KiB(this int value) => value * 1024;
public static int KB(this int value) => value * 1000;
public static int MiB(this int value) => value.KiB() * 1024;
public static int MB(this int value) => value.KB() * 1000;
public static int GiB(this int value) => value.MiB() * 1024;
public static int GB(this int value) => value.MB() * 1000;
2016-04-18 21:38:19 +00:00
public static Stream ToStream(this Image img, System.Drawing.Imaging.ImageFormat format = null)
{
if (format == null)
format = System.Drawing.Imaging.ImageFormat.Jpeg;
var stream = new MemoryStream();
img.Save(stream, format);
stream.Position = 0;
return stream;
}
/// <summary>
/// Merges Images into 1 Image and returns a bitmap.
/// </summary>
/// <param name="images">The Images you want to merge.</param>
/// <returns>Merged bitmap</returns>
2016-04-18 21:38:19 +00:00
public static Bitmap Merge(this IEnumerable<Image> images, int reverseScaleFactor = 1)
{
var imageArray = images as Image[] ?? images.ToArray();
if (!imageArray.Any()) return null;
var width = imageArray.Sum(i => i.Width);
2016-04-18 21:38:19 +00:00
var height = imageArray.First().Height;
var bitmap = new Bitmap(width / reverseScaleFactor, height / reverseScaleFactor);
var r = new Random();
var offsetx = 0;
2016-04-18 21:38:19 +00:00
foreach (var img in imageArray)
{
var bm = new Bitmap(img);
2016-04-18 21:38:19 +00:00
for (var w = 0; w < img.Width; w++)
{
for (var h = 0; h < bitmap.Height; h++)
{
bitmap.SetPixel(w / reverseScaleFactor + offsetx, h, bm.GetPixel(w, h * reverseScaleFactor));
}
}
2016-04-18 21:38:19 +00:00
offsetx += img.Width / reverseScaleFactor;
}
return bitmap;
}
2016-02-05 07:01:31 +00:00
/// <summary>
/// Merges Images into 1 Image and returns a bitmap asynchronously.
/// </summary>
/// <param name="images">The Images you want to merge.</param>
/// <param name="reverseScaleFactor"></param>
2016-02-05 07:01:31 +00:00
/// <returns>Merged bitmap</returns>
public static async Task<Bitmap> MergeAsync(this IEnumerable<Image> images, int reverseScaleFactor = 1) =>
2016-04-18 21:38:19 +00:00
await Task.Run(() => images.Merge(reverseScaleFactor)).ConfigureAwait(false);
2015-12-05 10:27:00 +00:00
}
}