Skip to content

Instantly share code, notes, and snippets.

@atifaziz
Last active August 26, 2020 21:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atifaziz/a61d34ccab9558b3271913c491976c6e to your computer and use it in GitHub Desktop.
Save atifaziz/a61d34ccab9558b3271913c491976c6e to your computer and use it in GitHub Desktop.
dotnet-coway as a LINQPad C# Query Program (http://share.linqpad.net/9bfa4d.linq)
<Query Kind="Program">
<NuGetReference Version="1.0.0">Kurukuru</NuGetReference>
<NuGetReference Version="2.2.4">McMaster.Extensions.CommandLineUtils</NuGetReference>
<NuGetReference Version="11.0.2">Newtonsoft.Json</NuGetReference>
<Namespace>Kurukuru</Namespace>
<Namespace>Newtonsoft.Json</Namespace>
<Namespace>McMaster.Extensions.CommandLineUtils</Namespace>
<Namespace>System.Threading.Tasks</Namespace>
<Namespace>System.Net.Http</Namespace>
</Query>
static void Main(string[] args) =>
App.Run(args);
// https://github.com/isaacrlevin/dotnet-cowsay/tree/d94facb0721efad77c50864d1ad6112f694345b5
//
// MIT License
//
// Copyright (c) 2018 Isaac Levin
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
[Command(Description = "Cowsay a Blog Post.")]
class App
{
public static int Run(string[] args) => CommandLineApplication.Execute<App>(args);
private async Task<int> OnExecute()
{
await GetLink();
return 0;
}
private async Task GetLink()
{
await SpinnerEx.StartAsync("Looking for an awesome article..", async spinner =>
{
try
{
Blog blog = new Blog();
HttpClient client = new HttpClient();
string url = "https://discoverdot.net/data/blogs.json";
string content = await client.GetStringAsync(url);
var blogList = JsonConvert.DeserializeObject<List<Blog>>(content);
Random rnd = new Random();
blog = blogList[rnd.Next(0, blogList.Count - 1)];
var cow = Cow.GetCow();
var bubbleText = blog.title + Environment.NewLine + blog.newestFeedItem.title + Environment.NewLine + blog.newestFeedItem.link;
string SpeechBubbleReturned = SpeechBubble.ReturnSpeechBubble(bubbleText, new SayBubbleChars(), blog.newestFeedItem.link.Length);
Console.WriteLine(
#if LINQPAD
Util.FixedFont
#endif
(Environment.NewLine + SpeechBubbleReturned + Environment.NewLine + cow));
}
catch
{
spinner.Fail("Something went wrong, please try again");
}
});
}
}
public static class Cow
{
public static string GetCow()
{
var cow = @"
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
";
return cow.TrimStart('\r', '\n');
}
}
public interface IBubbleChars
{
char TopLine { get; }
char BottomLine { get; }
string UpLeft { get; }
string UpRight { get; }
string DownLeft { get; }
string DownRight { get; }
string Left { get; }
string Right { get; }
string SmallLeft { get; }
string SmallRight { get; }
string Bubble { get; }
}
public class BubbleChars : IBubbleChars
{
public char TopLine { get; set; }
public char BottomLine { get; set; }
public string UpLeft { get; set; }
public string UpRight { get; set; }
public string DownLeft { get; set; }
public string DownRight { get; set; }
public string Left { get; set; }
public string Right { get; set; }
public string SmallLeft { get; set; }
public string SmallRight { get; set; }
public string Bubble { get; set; }
public BubbleChars()
{
TopLine = '_';
BottomLine = '-';
}
}
public class SayBubbleChars : BubbleChars
{
public SayBubbleChars()
{
UpLeft = DownRight = "/";
UpRight = DownLeft = Bubble = "\\";
Left = Right = "|";
SmallLeft = "<";
SmallRight = ">";
}
}
static public class SpeechBubble
{
static public string ReturnSpeechBubble(string message, IBubbleChars bubbles, int maxLineLength)
{
char[] splitChar = { ' ', (char)10, (char)13 };
List<string> messageAsList = new List<string>();
messageAsList = message.Split(
new[] { "\r\n", "\r", "\n" },
StringSplitOptions.None
).ToList();
if (message.Length > maxLineLength || messageAsList.Count > 1)
{
message = CreateLargeWordBubble(messageAsList, bubbles);
}
else
{
message = CreateSmallWordBubble(message, bubbles);
}
return message;
}
static string RepeatCharacter(char character, int numberOfUnderscores)
{
return new string(character, numberOfUnderscores);
}
static string CreateSmallWordBubble(string message, IBubbleChars bubbles)
{
int lengthOfMessage = message.Length;
int lengthOfTopAndBottomLinesInBubble = lengthOfMessage + 2;
string topBubbleLine = RepeatCharacter(bubbles.TopLine, lengthOfTopAndBottomLinesInBubble);
string bottomBubbleLine = RepeatCharacter(bubbles.BottomLine, lengthOfTopAndBottomLinesInBubble);
return $" {topBubbleLine} \r\n{bubbles.SmallLeft} {message.Trim()} {bubbles.SmallRight}\r\n {bottomBubbleLine}";
}
static string CreateLargeWordBubble(List<string> list, IBubbleChars bubbles)
{
StringBuilder bubbleBuilder = new StringBuilder();
int longestLineInList = list.Max(s => s.Length);
int lengthOfTopAndBottomLinesInBubble = longestLineInList + 2;
string topBubbleLine = $" {RepeatCharacter(bubbles.TopLine, lengthOfTopAndBottomLinesInBubble)}";
string bottomBubbleLine = $" {RepeatCharacter(bubbles.BottomLine, lengthOfTopAndBottomLinesInBubble)}";
string firstLineInMessageSpaces = RepeatCharacter(' ', longestLineInList - list[0].Length + 1);
string lastLineInMessageSpaces = RepeatCharacter(' ', longestLineInList - list[list.Count - 1].Length + 1);
bubbleBuilder.AppendLine(topBubbleLine);
bubbleBuilder.AppendLine($"{bubbles.UpLeft} {list[0]}{firstLineInMessageSpaces}{bubbles.UpRight}");
for (int i = 1; i < list.Count() - 1; i++)
{
int numberofspaces = longestLineInList - list[i].Length;
string spacesInLine = RepeatCharacter(' ', numberofspaces + 1);
bubbleBuilder.AppendLine($"{bubbles.Left} {list[i]}{spacesInLine}{bubbles.Right}");
}
bubbleBuilder.AppendLine($"{bubbles.DownLeft} {list[list.Count - 1]}{lastLineInMessageSpaces}{bubbles.DownRight}");
bubbleBuilder.AppendLine(bottomBubbleLine);
return bubbleBuilder.ToString();
}
}
public class Blog
{
public string key { get; set; }
public string title { get; set; }
public string link { get; set; }
public string description { get; set; }
public string website { get; set; }
public string feed { get; set; }
public string language { get; set; }
public DateTime lastPublished { get; set; }
public Newestfeeditem newestFeedItem { get; set; }
}
public class Newestfeeditem
{
public string title { get; set; }
public string link { get; set; }
public string description { get; set; }
public DateTime published { get; set; }
public bool recent { get; set; }
public Links links { get; set; }
public object author { get; set; }
}
public class Links {}
static class SpinnerEx
{
public static void Start(string text, Action action, Pattern pattern = null, Pattern fallbackPattern = null)
{
Start(text, _ => action(), pattern, fallbackPattern);
}
public static void Start(string text, Action<Spinner> action, Pattern pattern = null, Pattern fallbackPattern = null)
{
using (var spinner = new Spinner(text, pattern, fallbackPattern: fallbackPattern))
{
spinner.Start();
try
{
action(spinner);
if (!spinner.Stopped)
{
spinner.Stop("", "");
}
}
catch
{
if (!spinner.Stopped)
{
spinner.Stop("", "");
}
throw;
}
}
}
public static Task StartAsync(string text, Func<Task> action, Pattern pattern = null, Pattern fallbackPattern = null)
{
return StartAsync(text, _ => action(), pattern, fallbackPattern);
}
public static async Task StartAsync(string text, Func<Spinner, Task> action, Pattern pattern = null, Pattern fallbackPattern = null)
{
using (var spinner = new Spinner(text, pattern, fallbackPattern: fallbackPattern))
{
spinner.Start();
try
{
await action(spinner);
if (!spinner.Stopped)
{
spinner.Stop("", "");
}
}
catch
{
if (!spinner.Stopped)
{
spinner.Stop("", "");
}
throw;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment