Skip to content

Commit 7849357

Browse files
committed
first commit
0 parents  commit 7849357

19 files changed

+4711
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.vs/

Atex Host Manager.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.35130.168
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Atex Host Manager", "Atex Host Manager\Atex Host Manager.csproj", "{EC3BB941-81C8-4A4F-A8B5-2839A0395516}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{EC3BB941-81C8-4A4F-A8B5-2839A0395516}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{EC3BB941-81C8-4A4F-A8B5-2839A0395516}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{EC3BB941-81C8-4A4F-A8B5-2839A0395516}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{EC3BB941-81C8-4A4F-A8B5-2839A0395516}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {126BEF7D-F3B4-44A3-B2B2-A96EACB75723}
24+
EndGlobalSection
25+
EndGlobal

Atex Host Manager/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bin/
2+
obj/
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>WinExe</OutputType>
5+
<TargetFramework>net5.0-windows</TargetFramework>
6+
<RootNamespace>Atex_Host_Manager</RootNamespace>
7+
<UseWindowsForms>true</UseWindowsForms>
8+
<ApplicationManifest>app.manifest</ApplicationManifest>
9+
<ApplicationIcon>icon (1).ico</ApplicationIcon>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<Compile Update="Properties\Settings.Designer.cs">
18+
<DesignTimeSharedInput>True</DesignTimeSharedInput>
19+
<AutoGen>True</AutoGen>
20+
<DependentUpon>Settings.settings</DependentUpon>
21+
</Compile>
22+
</ItemGroup>
23+
24+
<ItemGroup>
25+
<None Update="Properties\Settings.settings">
26+
<Generator>SettingsSingleFileGenerator</Generator>
27+
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
28+
</None>
29+
</ItemGroup>
30+
31+
</Project>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<ItemGroup>
4+
<Compile Update="Form1.cs">
5+
<SubType>Form</SubType>
6+
</Compile>
7+
</ItemGroup>
8+
</Project>

Atex Host Manager/AtexHostDB.cs

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Newtonsoft.Json;
5+
using System.Text.RegularExpressions;
6+
using System.Text;
7+
using System.Windows.Forms;
8+
9+
namespace Atex_Host_Manager
10+
{
11+
public class AtexHostDB
12+
{
13+
private string dataType = "hosts";
14+
private List<HostEntry> hostEntries = new List<HostEntry>();
15+
private List<VHostEntry> vHostEntries = new List<VHostEntry>();
16+
17+
public AtexHostDB (string dataType = "hosts")
18+
{
19+
this.dataType = dataType;
20+
}
21+
public void setData(string jsonData, string type)
22+
{
23+
dataType = type.ToLower();
24+
if (dataType == "hosts")
25+
{
26+
hostEntries = JsonConvert.DeserializeObject<List<HostEntry>>(jsonData);
27+
}
28+
else if (dataType.Trim() == "vhosts")
29+
{
30+
var newEntries = JsonConvert.DeserializeObject<List<VHostEntry>>(jsonData);
31+
vHostEntries.AddRange(newEntries);
32+
}
33+
else
34+
{
35+
throw new ArgumentException("Invalid data type. Must be 'hosts' or 'vhosts'.");
36+
}
37+
}
38+
39+
public string getDataType()
40+
{
41+
return this.dataType;
42+
}
43+
44+
// Getters for JSON data
45+
public string GetHostEntriesAsJson()
46+
{
47+
if (dataType == "hosts")
48+
{
49+
return JsonConvert.SerializeObject(hostEntries);
50+
}
51+
throw new InvalidOperationException("Current data type is not 'hosts'.");
52+
}
53+
54+
public string GetVHostEntriesAsJson()
55+
{
56+
if (dataType == "vhosts")
57+
{
58+
return JsonConvert.SerializeObject(vHostEntries);
59+
}
60+
throw new InvalidOperationException("Current data type is not 'vhosts'.");
61+
}
62+
63+
// Methods for Host Entries (CRUD Operations)
64+
// Search host entries by IP
65+
public List<HostEntry> SearchHostByIp(string ip)
66+
{
67+
if (dataType != "hosts")
68+
throw new InvalidOperationException("Current data type is not 'hosts'.");
69+
70+
return hostEntries.Where(h => h.Ip.Equals(ip, StringComparison.OrdinalIgnoreCase)).ToList();
71+
}
72+
73+
// Search host entries by Hostname
74+
public List<HostEntry> SearchHostByHostname(string hostname)
75+
{
76+
if (dataType != "hosts")
77+
throw new InvalidOperationException("Current data type is not 'hosts'.");
78+
79+
return hostEntries.Where(h => h.Hostname.Equals(hostname, StringComparison.OrdinalIgnoreCase)).ToList();
80+
}
81+
82+
// Add a new Host Entry
83+
public void AddHostEntry(string ip, string hostname)
84+
{
85+
if (dataType != "hosts")
86+
throw new InvalidOperationException("Current data type is not 'hosts'.");
87+
88+
var existingEntry = hostEntries.FirstOrDefault(e => e.Ip == ip && e.Hostname.Equals(hostname, StringComparison.OrdinalIgnoreCase));
89+
if (existingEntry == null)
90+
{
91+
hostEntries.Add(new HostEntry { Id = hostEntries.Count + 1, Ip = ip, Hostname = hostname });
92+
}
93+
else
94+
{
95+
throw new InvalidOperationException("Host entry with the same IP and hostname already exists.");
96+
}
97+
}
98+
99+
// Update a Host Entry by ID
100+
public void UpdateHostEntry(int id, string newHostname)
101+
{
102+
if (dataType != "hosts")
103+
throw new InvalidOperationException("Current data type is not 'hosts'.");
104+
105+
var entry = hostEntries.FirstOrDefault(e => e.Id == id);
106+
if (entry != null)
107+
{
108+
entry.Hostname = newHostname;
109+
}
110+
else
111+
{
112+
//throw new KeyNotFoundException("Host entry with the specified ID not found.");
113+
}
114+
}
115+
116+
// Remove Host Entry by Hostname
117+
public void RemoveHostEntryByHostname(string hostname)
118+
{
119+
if (dataType != "hosts")
120+
throw new InvalidOperationException("Current data type is not 'hosts'.");
121+
122+
hostEntries.RemoveAll(e => e.Hostname.Equals(hostname, StringComparison.OrdinalIgnoreCase));
123+
}
124+
125+
public string ConvertToHosts()
126+
{
127+
if (dataType != "hosts")
128+
throw new InvalidOperationException("Current data type is not 'hosts'.");
129+
130+
// Use a dictionary to group hostnames by their IP addresses
131+
var groupedHosts = hostEntries
132+
.GroupBy(entry => entry.Ip)
133+
.ToDictionary(group => group.Key, group => group.Select(entry => entry.Hostname).ToList());
134+
135+
// Convert the dictionary into hosts file format
136+
var hostsFileContent = new List<string>();
137+
foreach (var kvp in groupedHosts)
138+
{
139+
string line = $"{kvp.Key} {string.Join(" ", kvp.Value)}"; // Format: IP Hostname1 Hostname2 ...
140+
hostsFileContent.Add(line);
141+
}
142+
143+
// Join all lines into a single string with line breaks
144+
return string.Join(Environment.NewLine, hostsFileContent);
145+
}
146+
147+
148+
// Methods for VHost Entries (CRUD Operations)
149+
// Search VHost Entries by keyword (preg match)
150+
public List<VHostEntry> SearchVHostEntries(string pattern)
151+
{
152+
//if (dataType != "vhosts")
153+
// MessageBox.Show(dataType.ToString());
154+
//throw new InvalidOperationException("Current data type is not 'vhosts'.");
155+
156+
// Compile the regex pattern once to use for both hostname and directory searches
157+
var regex = new Regex(pattern, RegexOptions.IgnoreCase);
158+
159+
// Filter vHostEntries by matching the pattern in Hostname or Directory
160+
return vHostEntries.Where(v =>
161+
(v.Hostname != null && regex.IsMatch(v.Hostname)) ||
162+
(v.Directory != null && regex.IsMatch(v.Directory))
163+
).ToList();
164+
}
165+
166+
public string ConvertVHostEntriesToConfig()
167+
{
168+
// if (dataType != "vhosts")
169+
// throw new InvalidOperationException("Current data type is not 'vhosts'.");
170+
171+
StringBuilder configBuilder = new StringBuilder();
172+
173+
foreach (var entry in vHostEntries)
174+
{
175+
// Replace backslashes with forward slashes in Directory
176+
string formattedDirectory = entry.Directory.Replace("\\", "/");
177+
178+
// Construct the VirtualHost configuration block
179+
string virtualHostConfig = $@"
180+
#
181+
# Host Definition: {entry.Hostname}
182+
# Author: Muhammad Athar
183+
# Email: cma@atexcode.com, athar.techs@gmail.com
184+
# Web: https://atexcode.com/
185+
# GitHub: https://github.com/atexcode
186+
#
187+
<VirtualHost *:80>
188+
ServerAdmin webmaster@{entry.Hostname}
189+
DocumentRoot ""{formattedDirectory}""
190+
ServerName {entry.Hostname}
191+
ErrorLog ""logs/{entry.Hostname}-error.log""
192+
CustomLog ""logs/{entry.Hostname}-access.log"" common
193+
194+
# Allow Directory Permissions
195+
<Directory ""{formattedDirectory}"">
196+
Options Indexes FollowSymLinks MultiViews
197+
AllowOverride All
198+
Require all granted
199+
</Directory>
200+
</VirtualHost>
201+
";
202+
203+
// Append the formatted VirtualHost block to the builder
204+
configBuilder.AppendLine(virtualHostConfig);
205+
}
206+
207+
// Return the complete configuration as a string
208+
return configBuilder.ToString();
209+
}
210+
211+
// Add a new VHost Entry
212+
public void AddVHostEntry(string hostname, string directory)
213+
{
214+
//if (dataType != "vhosts")
215+
// throw new InvalidOperationException("Current data type is not 'vhosts'.");
216+
217+
var existingEntry = vHostEntries.FirstOrDefault(e => e.Hostname.Equals(hostname, StringComparison.OrdinalIgnoreCase) && e.Directory.Equals(directory, StringComparison.OrdinalIgnoreCase));
218+
if (existingEntry == null)
219+
{
220+
vHostEntries.Add(new VHostEntry { Id = hostEntries.Count + 1, Hostname = hostname, Directory = directory });
221+
}
222+
else
223+
{
224+
throw new InvalidOperationException("Host entry with the same hostname already exists.");
225+
}
226+
227+
//MessageBox.Show(JsonConvert.SerializeObject(vHostEntries));
228+
}
229+
230+
// Update a VHost Entry by ID
231+
public void UpdateVHostEntry(int id, string hostname, string directory)
232+
{
233+
if (dataType != "vhosts")
234+
throw new InvalidOperationException("Current data type is not 'vhosts'.");
235+
236+
var entry = vHostEntries.FirstOrDefault(v => v.Id == id);
237+
if (entry != null)
238+
{
239+
entry.Hostname = hostname;
240+
entry.Directory = directory;
241+
}
242+
else
243+
{
244+
throw new KeyNotFoundException("VHost entry with the specified ID not found.");
245+
}
246+
}
247+
248+
public void RemoveVHostEntryById(int id)
249+
{
250+
if (dataType != "vhosts")
251+
throw new InvalidOperationException("Current data type is not 'vhosts'.");
252+
253+
vHostEntries.RemoveAll(v => v.Id == id);
254+
}
255+
256+
// Remove VHost Entry by pattern match
257+
public void RemoveVHostEntryByPattern(string pattern)
258+
{
259+
if (dataType != "vhosts")
260+
throw new InvalidOperationException("Current data type is not 'vhosts'.");
261+
262+
vHostEntries.RemoveAll(v => v.ConfigLines.Any(line => Regex.IsMatch(line, pattern, RegexOptions.IgnoreCase)));
263+
}
264+
}
265+
266+
267+
}

0 commit comments

Comments
 (0)