From 72d9a35c64786d1742711e671b229783c527fac7 Mon Sep 17 00:00:00 2001 From: Christoph Date: Sun, 29 Sep 2024 12:51:57 +0200 Subject: [PATCH 1/6] initial VS Project Setup --- App.axaml | 10 ++++++++++ App.axaml.cs | 24 ++++++++++++++++++++++++ MainWindow.axaml | 9 +++++++++ MainWindow.axaml.cs | 12 ++++++++++++ Program.cs | 22 ++++++++++++++++++++++ app.manifest | 18 ++++++++++++++++++ kaelus.csproj | 19 +++++++++++++++++++ kaelus.sln | 25 +++++++++++++++++++++++++ 8 files changed, 139 insertions(+) create mode 100644 App.axaml create mode 100644 App.axaml.cs create mode 100644 MainWindow.axaml create mode 100644 MainWindow.axaml.cs create mode 100644 Program.cs create mode 100644 app.manifest create mode 100644 kaelus.csproj create mode 100644 kaelus.sln diff --git a/App.axaml b/App.axaml new file mode 100644 index 0000000..0b01f3f --- /dev/null +++ b/App.axaml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/App.axaml.cs b/App.axaml.cs new file mode 100644 index 0000000..e55ca4e --- /dev/null +++ b/App.axaml.cs @@ -0,0 +1,24 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; + +namespace kaelus +{ + public partial class App : Application + { + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + desktop.MainWindow = new MainWindow(); + } + + base.OnFrameworkInitializationCompleted(); + } + } +} \ No newline at end of file diff --git a/MainWindow.axaml b/MainWindow.axaml new file mode 100644 index 0000000..6716611 --- /dev/null +++ b/MainWindow.axaml @@ -0,0 +1,9 @@ + + KAELUS + diff --git a/MainWindow.axaml.cs b/MainWindow.axaml.cs new file mode 100644 index 0000000..09a6483 --- /dev/null +++ b/MainWindow.axaml.cs @@ -0,0 +1,12 @@ +using Avalonia.Controls; + +namespace kaelus +{ + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..ea7bb2e --- /dev/null +++ b/Program.cs @@ -0,0 +1,22 @@ +using Avalonia; +using System; + +namespace kaelus +{ + internal class Program + { + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + [STAThread] + public static void Main(string[] args) => BuildAvaloniaApp() + .StartWithClassicDesktopLifetime(args); + + // Avalonia configuration, don't remove; also used by visual designer. + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .UsePlatformDetect() + .WithInterFont() + .LogToTrace(); + } +} diff --git a/app.manifest b/app.manifest new file mode 100644 index 0000000..519d5ba --- /dev/null +++ b/app.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/kaelus.csproj b/kaelus.csproj new file mode 100644 index 0000000..56a5d66 --- /dev/null +++ b/kaelus.csproj @@ -0,0 +1,19 @@ + + + WinExe + net8.0 + enable + true + app.manifest + true + + + + + + + + + + + diff --git a/kaelus.sln b/kaelus.sln new file mode 100644 index 0000000..7c0678d --- /dev/null +++ b/kaelus.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35312.102 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "kaelus", "kaelus.csproj", "{F8CAB4F6-5FA4-4A1D-B0FD-C567E78C332D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F8CAB4F6-5FA4-4A1D-B0FD-C567E78C332D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F8CAB4F6-5FA4-4A1D-B0FD-C567E78C332D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F8CAB4F6-5FA4-4A1D-B0FD-C567E78C332D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F8CAB4F6-5FA4-4A1D-B0FD-C567E78C332D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {198F7A01-39D3-45F1-BA2D-3B6E73B82932} + EndGlobalSection +EndGlobal From efae9186ec103454f79fe176d4fa7f59afba5e58 Mon Sep 17 00:00:00 2001 From: Christoph Date: Sun, 29 Sep 2024 13:44:56 +0200 Subject: [PATCH 2/6] Created UI and basic functions --- MainWindow.axaml | 26 ++++++++++++++++++++++++-- MainWindow.axaml.cs | 13 +++++++++++++ Program.cs | 5 +++++ kaelus.csproj | 11 ++++++----- 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/MainWindow.axaml b/MainWindow.axaml index 6716611..2402a8b 100644 --- a/MainWindow.axaml +++ b/MainWindow.axaml @@ -2,8 +2,30 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="250" + Width="500" Height="250" x:Class="kaelus.MainWindow" + CanResize="False" + WindowStartupLocation="CenterScreen" Title="kaelus"> - KAELUS + + + + + + + + + + + + + + + + + + + + diff --git a/MainWindow.axaml.cs b/MainWindow.axaml.cs index 09a6483..cede998 100644 --- a/MainWindow.axaml.cs +++ b/MainWindow.axaml.cs @@ -1,4 +1,7 @@ using Avalonia.Controls; +using Avalonia.Interactivity; +using MsBox.Avalonia; +using System; namespace kaelus { @@ -8,5 +11,15 @@ public MainWindow() { InitializeComponent(); } + public void StartScan(object sender, RoutedEventArgs args) + { + ResultBox.Text = "This works"; + } + + public void ShowHelp(object sender, RoutedEventArgs args) + { + var helpBox = MessageBoxManager.GetMessageBoxStandard("KAELUS Help", "Just enter the desired URL and click Start. KAELUS will do the rest", MsBox.Avalonia.Enums.ButtonEnum.Ok); + var result = helpBox.ShowAsPopupAsync(this); + } } } \ No newline at end of file diff --git a/Program.cs b/Program.cs index ea7bb2e..f563015 100644 --- a/Program.cs +++ b/Program.cs @@ -18,5 +18,10 @@ public static AppBuilder BuildAvaloniaApp() .UsePlatformDetect() .WithInterFont() .LogToTrace(); + + public static void Test() + { + Console.WriteLine("Hello"); + } } } diff --git a/kaelus.csproj b/kaelus.csproj index 56a5d66..9ffc04b 100644 --- a/kaelus.csproj +++ b/kaelus.csproj @@ -9,11 +9,12 @@ - - - - + + + + - + + From 8cbbd9395bb37644b94c83706a2c641017221904 Mon Sep 17 00:00:00 2001 From: Christoph Date: Sun, 29 Sep 2024 13:49:40 +0200 Subject: [PATCH 3/6] Implemented basic functionality --- Engine.cs | 111 ++++++++++++++++++++++++++++++++++++++++++++ MainWindow.axaml.cs | 16 ++++++- Program.cs | 5 -- 3 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 Engine.cs diff --git a/Engine.cs b/Engine.cs new file mode 100644 index 0000000..83ae4fb --- /dev/null +++ b/Engine.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace kaelus +{ + internal class Engine + { + internal static String GrabbedMails; + + internal static String CheckUrl(String url) + { + string urlString = url; + bool isUrl = IsUrl(urlString); + + if (isUrl) + { + Console.WriteLine($"{urlString} is a valid URL."); + return url; + } + else + { + Console.WriteLine($"You provided an invalid url. {urlString} is not a valid URL."); + //System.Environment.Exit(0); + return "invalid"; + } + } + + internal static String ExtractEmails(String url) + { + // Extract Sourcecode + GetSourceCode(url); + String sourceCode = GetSourceCode(url); + + // Extract E-Mails + String extractedMails = GetEmails(sourceCode); + + // Remove Duplicates + String cleanResults = RemoveDuplicates(GrabbedMails); + + return cleanResults; + //return sourceCode;//TODO: Debug + } + + internal static String GetSourceCode(String url) + { + using (HttpClient client = new()) + { + using (HttpResponseMessage response = client.GetAsync(url).Result) + { + using (HttpContent content = response.Content) + { + string sourceCode = content.ReadAsStringAsync().Result; + return sourceCode; + } + } + } + } + + internal static String GetEmails(String sourceCode) + { + string emailPattern = @"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"; + + // Use Regex.Matches to find all occurrences of email addresses in the input string + MatchCollection matches = Regex.Matches(sourceCode, emailPattern, RegexOptions.IgnoreCase); + + if (matches.Count > 0) + { + Console.WriteLine("Good news! I found some email-addresses"); + string prevMail = ""; + foreach (Match match in matches) + { + //Check if has been output already + if (match.Value.Equals(prevMail)) + { + //skip to next + } + else + { + //add match to string + GrabbedMails = GrabbedMails + match + System.Environment.NewLine; + Console.WriteLine(match.Value); + } + } + return GrabbedMails; + } + else + { + Console.WriteLine("No email addresses found."); + return "No email addresses found."; + } + } + + static bool IsUrl(string input) + { + return Uri.TryCreate(input, UriKind.Absolute, out Uri result) && + (result.Scheme == Uri.UriSchemeHttp || result.Scheme == Uri.UriSchemeHttps); + } + + internal static String RemoveDuplicates(String emails) + { + string input = emails; + string output = Regex.Replace(input, @"\b(\w+)\s+\1\b", "$1"); + return output; + } + } +} diff --git a/MainWindow.axaml.cs b/MainWindow.axaml.cs index cede998..9882f64 100644 --- a/MainWindow.axaml.cs +++ b/MainWindow.axaml.cs @@ -13,7 +13,21 @@ public MainWindow() } public void StartScan(object sender, RoutedEventArgs args) { - ResultBox.Text = "This works"; + //Check if URL is valid + URLBox.Text = Engine.CheckUrl(URLBox.Text); + //Url = SourceUrl.StringValue; + + //is URL valid? + if (URLBox.Text.Equals("invalid")) + { + ResultBox.Text = "Invalid URL provided. Please try another URL."; + } + else + { + //Extract Emails + //ResultBox.StringValue = Grabber.ExtractEmails(Url); + ResultBox.Text = Engine.ExtractEmails(URLBox.Text); + } } public void ShowHelp(object sender, RoutedEventArgs args) diff --git a/Program.cs b/Program.cs index f563015..ea7bb2e 100644 --- a/Program.cs +++ b/Program.cs @@ -18,10 +18,5 @@ public static AppBuilder BuildAvaloniaApp() .UsePlatformDetect() .WithInterFont() .LogToTrace(); - - public static void Test() - { - Console.WriteLine("Hello"); - } } } From 15319c463ede38f13130d8035a67b555800b11d4 Mon Sep 17 00:00:00 2001 From: Christoph Date: Sun, 29 Sep 2024 17:36:06 +0200 Subject: [PATCH 4/6] Fully implemented functionality of kaelus-engine --- Engine.cs | 169 ++++++++++++++++++++++++++++++++------------ MainWindow.axaml | 6 +- MainWindow.axaml.cs | 61 +++++++++++++--- kaelus.csproj | 1 + 4 files changed, 177 insertions(+), 60 deletions(-) diff --git a/Engine.cs b/Engine.cs index 83ae4fb..753474c 100644 --- a/Engine.cs +++ b/Engine.cs @@ -1,67 +1,140 @@ -using System; +using HtmlAgilityPack; +using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Net.Http; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; +using System.Xml; namespace kaelus { internal class Engine { - internal static String GrabbedMails; + #region statics - internal static String CheckUrl(String url) + internal static HashSet foundEmails = new HashSet(); + + internal static string finishedResults = ""; + + #endregion + + #region static methods + + internal static void ExtractSourceCode(string url) + { + + bool isUrl = IsUrl(url); + + if (isUrl) + { + + } + else + { + url = "https://" + url; + } + + // Scan the main index page and get all links on it + ScanLinks(url); + + // Display the collected emails at the end + DisplayCollectedEmails(); + } + + public static string kaelusScan(string url) { - string urlString = url; - bool isUrl = IsUrl(urlString); + bool isUrl = IsUrl(url); if (isUrl) { - Console.WriteLine($"{urlString} is a valid URL."); - return url; + } else { - Console.WriteLine($"You provided an invalid url. {urlString} is not a valid URL."); - //System.Environment.Exit(0); - return "invalid"; + url = "https://" + url; } + + // Scan the main index page and get all links on it + ScanLinks(url); + + // Display the collected emails at the end + DisplayCollectedEmails(); + return finishedResults; } - internal static String ExtractEmails(String url) + internal static void ScanLinks(String url) { - // Extract Sourcecode - GetSourceCode(url); - String sourceCode = GetSourceCode(url); + List links = new List(); + + // Fetch page source + string pageContent = FetchPageContent(url); + + if (string.IsNullOrEmpty(pageContent)) + { + Console.WriteLine("No content found on the page."); + return; + } + + // Use HtmlAgilityPack to parse the HTML and find all links + HtmlDocument doc = new HtmlDocument(); + doc.LoadHtml(pageContent); + + foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]")) + { + string href = link.GetAttributeValue("href", string.Empty); - // Extract E-Mails - String extractedMails = GetEmails(sourceCode); + // If it's a relative link, convert it to an absolute URL + Uri baseUri = new Uri(url); + Uri fullUri = new Uri(baseUri, href); - // Remove Duplicates - String cleanResults = RemoveDuplicates(GrabbedMails); + if (fullUri.Host == baseUri.Host) // Ensure it's the same domain + { + links.Add(fullUri.ToString()); + } + } - return cleanResults; - //return sourceCode;//TODO: Debug + // Scan each link for email addresses + foreach (string link in links) + { + //Console.WriteLine(kaleidolib.lib.Formatting.dim($"Scanning {link} for email addresses...")); + string content = FetchPageContent(link); + if (!string.IsNullOrEmpty(content)) + { + GetMails(content); + } + } } - internal static String GetSourceCode(String url) + // Method to fetch the page content + internal static string FetchPageContent(string url) { - using (HttpClient client = new()) + try { - using (HttpResponseMessage response = client.GetAsync(url).Result) + using (HttpClient client = new()) { - using (HttpContent content = response.Content) + HttpResponseMessage response = client.GetAsync(url).Result; + if (response.IsSuccessStatusCode) + { + return response.Content.ReadAsStringAsync().Result; + } + else { - string sourceCode = content.ReadAsStringAsync().Result; - return sourceCode; + Console.WriteLine($"Failed to fetch {url}"); } } } + catch (Exception ex) + { + Console.WriteLine($"Error fetching page content: {ex.Message}"); + } + return string.Empty; } - internal static String GetEmails(String sourceCode) + // Method to collect emails found on a page + internal static void GetMails(String sourceCode) { string emailPattern = @"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"; @@ -70,28 +143,30 @@ internal static String GetEmails(String sourceCode) if (matches.Count > 0) { - Console.WriteLine("Good news! I found some email-addresses"); - string prevMail = ""; foreach (Match match in matches) { - //Check if has been output already - if (match.Value.Equals(prevMail)) - { - //skip to next - } - else - { - //add match to string - GrabbedMails = GrabbedMails + match + System.Environment.NewLine; - Console.WriteLine(match.Value); - } + // Add to the HashSet to ensure uniqueness + foundEmails.Add(match.Value); + } + } + } + + // Display collected emails and filter duplicates + internal static void DisplayCollectedEmails() + { + if (foundEmails.Count > 0) + { + //Console.WriteLine(Color.green("Good news! I found the following unique email addresses:")); + foreach (var email in foundEmails) + { + Console.WriteLine(email); + finishedResults = finishedResults + email + "\n"; } - return GrabbedMails; } else { - Console.WriteLine("No email addresses found."); - return "No email addresses found."; + //Console.WriteLine(Color.red("No email addresses found.")); + finishedResults = "No email addresses found"; } } @@ -101,11 +176,11 @@ static bool IsUrl(string input) (result.Scheme == Uri.UriSchemeHttp || result.Scheme == Uri.UriSchemeHttps); } - internal static String RemoveDuplicates(String emails) + public static String GetTimestamp(DateTime value) { - string input = emails; - string output = Regex.Replace(input, @"\b(\w+)\s+\1\b", "$1"); - return output; + return value.ToString("yyyyMMddHHmmss"); } + + #endregion } } diff --git a/MainWindow.axaml b/MainWindow.axaml index 2402a8b..d324bd1 100644 --- a/MainWindow.axaml +++ b/MainWindow.axaml @@ -15,6 +15,7 @@ + @@ -25,7 +26,8 @@ - - + + + diff --git a/MainWindow.axaml.cs b/MainWindow.axaml.cs index 9882f64..5c42205 100644 --- a/MainWindow.axaml.cs +++ b/MainWindow.axaml.cs @@ -2,31 +2,43 @@ using Avalonia.Interactivity; using MsBox.Avalonia; using System; +using System.Threading; +using System.Threading.Tasks; namespace kaelus { public partial class MainWindow : Window { + + public string resultBoxText; + public MainWindow() { InitializeComponent(); } - public void StartScan(object sender, RoutedEventArgs args) + public async void StartScan(object sender, RoutedEventArgs args) { - //Check if URL is valid - URLBox.Text = Engine.CheckUrl(URLBox.Text); - //Url = SourceUrl.StringValue; + string url = URLBox.Text; + + // Create a CancellationTokenSource to manage the cancellation + var cancellationTokenSource = new CancellationTokenSource(); + + // Run both tasks concurrently + var progressTask = makeProgress(cancellationTokenSource.Token); + var resultTask = RunKaelusScanAsync(url); + + // When the resultTask completes, cancel the progressTask + await resultTask; + cancellationTokenSource.Cancel(); - //is URL valid? - if (URLBox.Text.Equals("invalid")) + // Await progressTask to ensure proper cleanup + try { - ResultBox.Text = "Invalid URL provided. Please try another URL."; + await progressTask; } - else + catch (OperationCanceledException) { - //Extract Emails - //ResultBox.StringValue = Grabber.ExtractEmails(Url); - ResultBox.Text = Engine.ExtractEmails(URLBox.Text); + ScanProgress.IsVisible = false; } } @@ -35,5 +47,32 @@ public void ShowHelp(object sender, RoutedEventArgs args) var helpBox = MessageBoxManager.GetMessageBoxStandard("KAELUS Help", "Just enter the desired URL and click Start. KAELUS will do the rest", MsBox.Avalonia.Enums.ButtonEnum.Ok); var result = helpBox.ShowAsPopupAsync(this); } + + public async Task makeProgress(CancellationToken cancellationToken) + { + // Fake Progress bar (to indicate work) + ScanProgress.Value = 0; + ScanProgress.IsVisible = true; + ResultBox.Text = "Scanning for email addresses..."; + + while (ScanProgress.Value < ScanProgress.Maximum) + { + if (cancellationToken.IsCancellationRequested) + { + break; + } + + await Task.Delay(2000, cancellationToken); + ScanProgress.Value = Math.Min(ScanProgress.Value + 1, ScanProgress.Maximum); + } + + } + + private async Task RunKaelusScanAsync(string url) + { + string result = await Task.Run(() => Engine.kaelusScan(url)); + + ResultBox.Text = result; + } } } \ No newline at end of file diff --git a/kaelus.csproj b/kaelus.csproj index 9ffc04b..10c5f61 100644 --- a/kaelus.csproj +++ b/kaelus.csproj @@ -15,6 +15,7 @@ + From 1f21b0d62127d0357619e880e7ba156d7b024f55 Mon Sep 17 00:00:00 2001 From: Christoph Date: Sun, 29 Sep 2024 17:48:01 +0200 Subject: [PATCH 5/6] added icon, added info --- Assets/kaelus-icon.ico | Bin 0 -> 1981 bytes MainWindow.axaml | 2 +- kaelus.csproj | 4 ++++ 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 Assets/kaelus-icon.ico diff --git a/Assets/kaelus-icon.ico b/Assets/kaelus-icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..82615f6b46ef0953b69a2411d30cf15241862c7d GIT binary patch literal 1981 zcmaJ?i#ODZ6aRj{b~n4*X6OUYk37Ca$Yb{wg}fqm>Ka$6Wz{H3wWB?Y-iAzZLFJ z-RDg?C$(f|=6^IQW8`bRco5#zNovf}EyibMhuM0$gsJ=LaX60q(p^4l-_a83+?lv` zouQAb5MoZXp4Dp3zrW>q1Aoq>B(!A8F86iOXQ;6)xp05Q&)J`k+uI~Fg%72@OrBT| zS{>!TMP^)NXA#J0d48g8#bz0@Gn#!{DhfI=Q&o-$@69mH5BYIO#&4NFcT4JS>V_1z z$lNVxmvIC3_FUQH4Sm$TH_UBgvX`BjP$Fx!8Yc1mTos4R^~rkr*;jc&|J*a7sPF2B zyl^STd5D_B^xw}Fh)2+}Pk z@R?^Xq3^E+)3iR-CW2jdkHv3f={QF02Dc3+gReg|2QgrneBn9ay~ht5bF?fru-pqU zT)ZWT40A$_ZhosYjCr%IuM^|r55va0=KeSNKb6jHy}IQuu*~b2ypV)B*JuVZ@K{G?Lg=y zv#tar;hN1PlfwVnoBKm!!Z7lOT_wN^%%<`sZpc%VzMr-kf=gyghoXH^*K4sF(JlG~ z7+4PkJ-$##w82pFSeji5z}vaY+&=Weh+h;s#~IO*@)Wne*ZuHR#Y~t1L5bc1Y(sa& zVh0VDq`cIKZynEjg38;66jMVEU^IWQ2e_O0Z4gvHcJmD|EA2H0cH<@v`4lh!9orsO z0O-D%_SA!6W5s^>+p?D&%{SGKGZ(dei2e&K38@3`)I=?ok@>9ZF8P@*6&kO-p-f~H z#*%*@?mnQhO&AMBxO`Kl3L7V@*8#3@v zC<`vCuuQTS_Hi!7qbJUKyCL}~lfPMHs&HLJHP{M~R617rm5;X=A4KAn#$=8ssKJJy z!xDbPCjh|XI;Crrda6-=w~^GK`!*|htm0e%J{J&^iP7m54IqU?oHP#AR0HbJqCT_N z^B6hLLcWoLEupMD-cjA&!=gxktCf88nFh)Cjl$E=KY}tj0uy~^aY(UcutS$NI6&2mK=RR| zHt8d8pc3ms3j7kdsE%@6%!--gIl-;_{e7S|Bie9)Ad)~!M^cqCVxoZS>xokwgLNvx zE@*l^qq1bOj1)Y%2l=R|n2?e^V|-W6hp~22@H$Ytrf{4MwL&_!UgO~k?we?zo^N5| zgK=Oz*gq7zn1!VBj&D!0hg*+WCZKcn!lIyyO$3-ij9F02r6T&Y4`|PK3eU8I1yk6I z3z5-9sbuI1{va|Ei^)*C9dY|N5f@$M4_RNSVh;3QFszEJ>ZmSB8WsaQE#+KElG-7s zb;C==x`zk*Yc(D>JPiYv3UDreXB!`zO-bweX*=0=bN(yEG>#rMn|);|xz^A9|J@o> z1qaw*VrgYS{Edq7^A$p0uzsz7G(2BXCCFp6<2sYA=<#=LKMfr#tvMYMlpC~3uy5(| z=a@l<1^h*+j)u?IG3m#JJ$(B&q4dm))ECxt+06o1{N%|864TDI7_Ee6(B) zP3P2lTvfXJdjgU2j%C32{fF9&<>j*{PTri@yFaanvWNfTz3P^YGD_1AllCC@tPMOl zBL#=}S5KW=Z$tCsC}o;etk0>QskYwO&pxQG?~2fy1gaxD$_w8m)Z3xMTVCc^)O8C3 zedIjjdxzj+{aJzP`W{FT=?GaY3_ph+?QGUkE)#uvx5bc-*mj-dvQ-MNMEI$Xl8Jf> zWade@IQg>0t(~m{n6onuPU7;b58c%}Yj!obHAD&;EkJSYqmgNNdQsW9m3tpF+wlFn z)gOP|Yk#g&iM!@pQlJ-PYLZQLW?Bbmz3!F<_?@qxPi!hpDQa}y?uJ=xoQ&4=h)-;f iTabkQ_ZM5O4iC~#oZTTgC=fWUrmjw&j`tjbPyY)D?P&V| literal 0 HcmV?d00001 diff --git a/MainWindow.axaml b/MainWindow.axaml index d324bd1..e9fab53 100644 --- a/MainWindow.axaml +++ b/MainWindow.axaml @@ -7,7 +7,7 @@ x:Class="kaelus.MainWindow" CanResize="False" WindowStartupLocation="CenterScreen" - Title="kaelus"> + Title="KAELUS - Ultimate Email Extractor."> diff --git a/kaelus.csproj b/kaelus.csproj index 10c5f61..f19f6f4 100644 --- a/kaelus.csproj +++ b/kaelus.csproj @@ -6,7 +6,11 @@ true app.manifest true + Assets\kaelus-icon.ico + + + From 527584076bf603690fc2bcad1588f405327c658c Mon Sep 17 00:00:00 2001 From: Christoph Date: Sun, 29 Sep 2024 20:15:05 +0200 Subject: [PATCH 6/6] Create readme --- README.md | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b18687c..c59fbe9 100644 --- a/README.md +++ b/README.md @@ -1 +1,103 @@ -# kaelus \ No newline at end of file +![Repo-Image](https://druffko.gg/github-images/kaelus-repo.png) + +
+ +![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/druffko/kaelus?include_prereleases) + +![.NET Version](https://img.shields.io/badge/.NET-8.0-brightgreen) +![.NET Version](https://img.shields.io/badge/OS-Windows+macOS-lightgray) +![GitHub last commit](https://img.shields.io/github/last-commit/druffko/kaelus) + +
+ + ![GitHub All Releases](https://img.shields.io/github/downloads/druffko/kaelus/total) + ![GitHub closed issues](https://img.shields.io/github/issues-closed/druffko/kaelus) + ![GitHub issues](https://img.shields.io/github/issues/druffko/kaelus) + +

KAELUS

+

+ KAELUS is a cross-platform (Windows & macOS) Desktop application written in C#, that extracts E-Mail-Addresses from any URL you enter.
+ Based on druffko/kaelus-engine +

+
+ +## Table of Contents +- [About](#about) +- [Features](#features) +- [Installation](#installation) +- [Usage](#usage) +- [Contributing](#contributing) +- [License](#license) +- [Contact](#contact) + +--- + +## About + +KAELUS is a cross-platform (Windows & macOS) Desktop application written in C#, that extracts E-Mail-Addresses from any URL you enter. + +By automatically scanning the source code of each and every link with the same host domain it is able to find email addresses that are listed on said domain, without having to go through them manually. + +![UI-Screenshot](https://druffko.gg/github-images/kaelus/kaelus-ui.png) + +--- + +## Features + +- ✅ Extract email addresses from websites +- ✅ Scans every link on a website +- ✅ Works on Windows and macOS +- ✅ Show results in GUI + +--- + +## Installation + +### Download the latest version + +To start off, please head to the [releases page](https://github.com/druffko/kaelus/releases) and download a pre-built package. + +*If you don't trust me for some reason, feel free to download the latest released source code and build it your self.* + +### Launch the application + +Launch the application using double clicking. If the Application won't execute because it's from a "unknown developer", right-click and click "open". + +--- + +## Usage + +### Getting email addresses +Simply enter the URL you want to scan. You can either enter the "http://" or "https://" or just simply leave it out. FindMail will "fix" the URL. + +### Click start +Just click start and the applicaton will search the website for email-addresses. Results will be returned in a scrollable textview. + +--- + +## Contributing + +Contributions are welcome! Please follow these steps: + +1. Fork the repository +2. Create a new branch (`git checkout -b feature-name`) +3. Commit your changes (`git commit -m 'Add some feature'`) +4. Push to the branch (`git push origin feature-name`) +5. Open a pull request + +--- + +## License + +This project is licensed under the [MIT License](LICENSE). + +--- + +## Contact + +- **druffko** - [@druffko](https://twitter.com/druffko) - hi@druffko.gg +- **Project Link** - https://github.com/druffko/kaelus + +Feel free to reach out if you have any questions or suggestions! + +---