Skip to content

Commit 564f2e6

Browse files
authored
Merge pull request #11 from ahwm/1.0-fixes
fixes #7, fixes #8, fixes #9
2 parents 6790101 + 44ad68d commit 564f2e6

File tree

12 files changed

+129
-129
lines changed

12 files changed

+129
-129
lines changed

src/SvnManager.WebUI/MainModule.cs

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
using Nancy;
22
using System;
33
using System.Collections.Generic;
4-
using System.Collections.ObjectModel;
4+
using System.Configuration;
5+
using System.Diagnostics;
56
using System.IO;
67
using System.Linq;
7-
using System.Management.Automation;
8-
using System.Net;
98
using System.Reflection;
10-
using System.Text;
119
using System.Text.RegularExpressions;
12-
using System.Threading.Tasks;
1310

1411
namespace SvnManager.WebUI
1512
{
1613
public class MainModule : NancyModule
1714
{
15+
private static string RepoPath => ConfigurationManager.AppSettings["Manager.RepoPath"];
16+
private static string SvnLocation => ConfigurationManager.AppSettings["SvnLocation"];
1817
public MainModule()
1918
{
2019
Get["/"] = x =>
@@ -52,36 +51,27 @@ public MainModule()
5251
}
5352
private List<string> GetRepos()
5453
{
55-
List<string> repos = new List<string>();
56-
try
57-
{
58-
using (PowerShell ps = PowerShell.Create())
59-
{
60-
ps.AddCommand("Get-SvnRepository");
61-
Collection<PSObject> output = ps.Invoke();
62-
foreach (var o in output)
63-
{
64-
repos.Add((string)o.Members["Name"].Value);
65-
}
66-
}
67-
}
68-
catch { }
54+
List<string> repos = new DirectoryInfo(RepoPath).GetDirectories().Select(r => r.Name).ToList();
6955

7056
return repos;
7157
}
7258
private void CreateRepo(string name)
7359
{
74-
using (PowerShell ps = PowerShell.Create())
60+
using (Process p = new Process())
7561
{
76-
ps.AddCommand("New-SvnRepository");
77-
ps.AddArgument(name);
78-
ps.Invoke();
62+
p.StartInfo = new ProcessStartInfo($@"{SvnLocation}\svnadmin", $@"create {name}")
63+
{
64+
WorkingDirectory = RepoPath,
65+
RedirectStandardError = true
66+
};
67+
p.Start();
68+
p.WaitForExit();
7969
}
8070

8171
// This gives all users read/write access
82-
string svnAuthz = File.ReadAllText($@"C:\Repositories\{name}\conf\VisualSVN-SvnAuthz.ini");
72+
string svnAuthz = File.ReadAllText($@"C:\Repositories\{name}\conf\SvnAuthz.ini");
8373
svnAuthz += "\r\n\r\n[/]\r\n*=rw";
84-
File.WriteAllText($@"C:\Repositories\{name}\conf\VisualSVN-SvnAuthz.ini", svnAuthz);
74+
File.WriteAllText($@"C:\Repositories\{name}\conf\SvnAuthz.ini", svnAuthz);
8575

8676
// pre-commit hook to require commit messages
8777
using (var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream("SvnManager.Api.SvnHooks.pre-commit.cmd"))

src/SvnManager.WebUI/NancyHostControl.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
using Nancy.Hosting.Self;
22
using System;
3-
using System.Collections.Generic;
4-
using System.Linq;
5-
using System.Text;
6-
using System.Threading.Tasks;
73

84
namespace SvnManager.WebUI
95
{
106
public class NancyHostControl : IDisposable
117
{
128
NancyHost _host { get; set; }
13-
public NancyHostControl(string host, bool https = false)
9+
public NancyHostControl(string host, int port = 9664, bool https = false)
1410
{
1511
string scheme = https ? "https" : "http";
16-
_host = new NancyHost(new Uri($"{scheme}://{host}:9664"));
12+
_host = new NancyHost(new Uri($"{scheme}://{host}:{port}"));
1713
}
1814

1915
public void Start()

src/SvnManager.WebUI/Notification.cs

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Net;
2+
using System.Configuration;
53
using System.Net.Mail;
6-
using System.Text;
7-
using System.Threading.Tasks;
84

95
namespace SvnManager.WebUI
106
{
@@ -17,22 +13,21 @@ static public void SendError(Exception ex)
1713
static public void SendError(Exception ex, string note)
1814
{
1915
// that send process does not include default bcc copying
20-
MailMessage m = new MailMessage("", "");
21-
m.Subject = "SVN Manager Error" + (note.Length > 0 ? " (" + note + ")" : "");
22-
m.Body = GetFullError(ex);
23-
24-
try
16+
using (MailMessage m = new MailMessage(ConfigurationManager.AppSettings["Manger.SendEmailFrom"], ConfigurationManager.AppSettings["Manger.SendErrorsTo"]))
2517
{
26-
SmtpClient c = new SmtpClient();
27-
c.Host = "";
28-
c.Port = 587;
29-
c.EnableSsl = true;
30-
c.Credentials = new NetworkCredential("", "");
31-
c.Send(m);
18+
m.Subject = "SVN Manager Error" + (note.Length > 0 ? " (" + note + ")" : "");
19+
m.Body = GetFullError(ex);
20+
21+
using (SmtpClient c = new SmtpClient())
22+
{
23+
try
24+
{
25+
c.Send(m);
26+
}
27+
catch (Exception)
28+
{ }
29+
}
3230
}
33-
catch (Exception)
34-
{ }
35-
m.Dispose();
3631
}
3732
static private string GetFullError(Exception ex)
3833
{
@@ -48,7 +43,7 @@ static private string GetFullError(Exception ex)
4843

4944
return
5045
header +
51-
"Error Type: SVN Application Error\n" +
46+
"Error Type: SVN Manager Application Error\n" +
5247
"Exception: \n" + ExcDetails.Get(ex);
5348
}
5449
}

src/SvnManager.WebUI/RepositoriesModule.cs

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,43 @@
11
using Nancy;
2-
using System;
32
using System.Collections.Generic;
4-
using System.Collections.ObjectModel;
3+
using System.Configuration;
4+
using System.Diagnostics;
55
using System.IO;
66
using System.Linq;
7-
using System.Management.Automation;
8-
using System.Management.Automation.Runspaces;
97
using System.Reflection;
10-
using System.Text;
11-
using System.Threading.Tasks;
128

139
namespace SvnManager.WebUI
1410
{
1511
public class RepositoriesModule : NancyModule
1612
{
13+
private static string RepoPath => ConfigurationManager.AppSettings["Manager.RepoPath"];
14+
private static string SvnLocation => ConfigurationManager.AppSettings["SvnLocation"];
15+
1716
public RepositoriesModule() : base("/api/repositories")
1817
{
1918
Get["/"] = x =>
2019
{
21-
List<string> repos = new List<string>();
22-
using (PowerShell ps = PowerShell.Create())
23-
{
24-
ps.AddCommand("Get-SvnRepository");
25-
Collection<PSObject> output = ps.Invoke();
26-
foreach (var o in output)
27-
{
28-
repos.Add((string)o.Members["Name"].Value);
29-
}
30-
}
20+
List<string> repos = new DirectoryInfo(RepoPath).GetDirectories().Select(r => r.Name).ToList();
3121

3222
return Response.AsJson(repos).WithStatusCode(HttpStatusCode.OK);
3323
};
3424
Post["/{name}"] = x =>
3525
{
36-
using (PowerShell ps = PowerShell.Create())
26+
using (Process p = new Process())
3727
{
38-
ps.AddCommand("New-SvnRepository");
39-
ps.AddArgument(x.name);
40-
ps.Invoke();
28+
p.StartInfo = new ProcessStartInfo($@"{SvnLocation}\svnadmin", $@"create {x.name}")
29+
{
30+
WorkingDirectory = RepoPath,
31+
RedirectStandardError = true
32+
};
33+
p.Start();
34+
p.WaitForExit();
4135
}
4236

4337
// This gives all users read/write access
44-
string svnAuthz = File.ReadAllText($@"C:\Repositories\{x.name}\conf\VisualSVN-SvnAuthz.ini");
38+
string svnAuthz = File.ReadAllText($@"C:\Repositories\{x.name}\conf\SvnAuthz.ini");
4539
svnAuthz += "\r\n\r\n[/]\r\n*=rw";
46-
File.WriteAllText($@"C:\Repositories\{x.name}\conf\VisualSVN-SvnAuthz.ini", svnAuthz);
40+
File.WriteAllText($@"C:\Repositories\{x.name}\conf\SvnAuthz.ini", svnAuthz);
4741

4842
// pre-commit hook to require commit messages
4943
using (var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream("SvnManager.Api.SvnHooks.pre-commit.cmd"))

src/SvnManager.WebUI/SvnBackups.cs

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@
33
using Amazon.S3.Model;
44
using System;
55
using System.Collections.Generic;
6+
using System.Configuration;
7+
using System.Diagnostics;
68
using System.IO;
79
using System.Linq;
8-
using System.Management.Automation;
9-
using System.Net;
10-
using System.Text;
11-
using System.Threading.Tasks;
1210

1311
namespace SvnManager.WebUI
1412
{
1513
public class SvnBackups
1614
{
17-
private const string AccessKey = "";
18-
private const string SecretKey = "";
19-
private const string BucketName = "";
20-
private const string BackupLocation = "";
15+
private static string AccessKey => ConfigurationManager.AppSettings["Backups.S3AccessKey"];
16+
private static string SecretKey => ConfigurationManager.AppSettings["Backups.S3SecretKey"];
17+
private static string BucketName => ConfigurationManager.AppSettings["Backups.S3BucketName"];
18+
private static string BackupLocation => ConfigurationManager.AppSettings["Backups.BackupLocation"];
19+
private static string RepoPath => ConfigurationManager.AppSettings["Manager.RepoPath"];
20+
private static string SvnLocation => ConfigurationManager.AppSettings["SvnLocation"];
21+
private static int DaysBetweenBackups => Convert.ToInt32(ConfigurationManager.AppSettings["Backups.DaysBetweenBackups"]) * -1;
2122

2223
public static void Upload()
2324
{
@@ -27,13 +28,13 @@ public static void Upload()
2728
{
2829
BasicAWSCredentials cred = new BasicAWSCredentials(AccessKey, SecretKey);
2930
AmazonS3Client c = new AmazonS3Client(cred, Amazon.RegionEndpoint.USWest2);
30-
var files = new DirectoryInfo(BackupLocation).EnumerateFiles().Where(f => f.CreationTimeUtc > DateTime.UtcNow.AddDays(-7));
31+
var files = new DirectoryInfo(BackupLocation).EnumerateFiles().Where(f => f.CreationTimeUtc > DateTime.UtcNow.AddDays(DaysBetweenBackups));
3132
foreach (var file in files)
3233
{
3334
InitiateMultipartUploadResponse initResponse = c.InitiateMultipartUpload(new InitiateMultipartUploadRequest { StorageClass = S3StorageClass.StandardInfrequentAccess, BucketName = BucketName, Key = file.Name });
34-
long partSize = 100 * (long)Math.Pow(2, 20);
35+
long partSize = Convert.ToInt64(ConfigurationManager.AppSettings["Backups.S3PartSize"]) * (long)Math.Pow(2, 20);
3536
List<UploadPartResponse> resps = new List<UploadPartResponse>();
36-
//var resp = c.PutObject(new Amazon.S3.Model.PutObjectRequest() { FilePath = file.FullName, BucketName = BucketName, Key = file.Name, StorageClass = S3StorageClass.StandardInfrequentAccess });
37+
3738
try
3839
{
3940
long filePosition = 0;
@@ -88,7 +89,7 @@ public static void DeleteLocal()
8889
{
8990
try
9091
{
91-
var files = new DirectoryInfo(BackupLocation).EnumerateFiles().Where(f => f.CreationTimeUtc < DateTime.UtcNow.AddDays(-7));
92+
var files = new DirectoryInfo(BackupLocation).EnumerateFiles().Where(f => f.CreationTimeUtc < DateTime.UtcNow.AddDays(DaysBetweenBackups));
9293
foreach (var file in files)
9394
{
9495
file.Delete();
@@ -102,15 +103,27 @@ public static void DeleteLocal()
102103

103104
public static void RunBackups()
104105
{
106+
string output;
105107
try
106108
{
107-
// TODO: Create backups
108-
//using (PowerShell ps = PowerShell.Create())
109-
//{
110-
// ps.AddCommand("Backup-SvnRepository");
111-
// ps.AddArgument("*");
112-
// ps.Invoke();
113-
//}
109+
var repos = new DirectoryInfo(RepoPath).GetDirectories();
110+
foreach (var r in repos)
111+
{
112+
using (Process p = new Process())
113+
{
114+
p.StartInfo = new ProcessStartInfo($@"{SvnLocation}\svnadmin", $@"dump {r.FullName} > {BackupLocation}\{r.Name}_{DateTime.UtcNow:yyyyMMddHHmm}.dump")
115+
{
116+
RedirectStandardError = true
117+
};
118+
p.Start();
119+
p.WaitForExit();
120+
output = p.StandardError.ReadToEnd();
121+
if (p.ExitCode != 0)
122+
{
123+
// TODO: Send email with output ?
124+
}
125+
}
126+
}
114127
}
115128
catch (Exception ex)
116129
{
@@ -120,7 +133,7 @@ public static void RunBackups()
120133

121134
public static bool IsBackupTime()
122135
{
123-
var files = new DirectoryInfo(BackupLocation).EnumerateFiles().Where(f => f.CreationTimeUtc > DateTime.UtcNow.AddDays(-7));
136+
var files = new DirectoryInfo(BackupLocation).EnumerateFiles().Where(f => f.CreationTimeUtc > DateTime.UtcNow.AddDays(-DaysBetweenBackups));
124137
if (files.Count() <= 0 && DateTime.UtcNow.Hour > 3 && DateTime.UtcNow.Hour < 8)
125138
return true;
126139

src/SvnManager.WebUI/SvnManager.WebUI.csproj

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,8 @@
4747
<HintPath>..\packages\Nancy.Hosting.Self.1.4.1\lib\net40\Nancy.Hosting.Self.dll</HintPath>
4848
</Reference>
4949
<Reference Include="System" />
50+
<Reference Include="System.Configuration" />
5051
<Reference Include="System.Core" />
51-
<Reference Include="System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
52-
<SpecificVersion>False</SpecificVersion>
53-
<HintPath>..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll</HintPath>
54-
</Reference>
5552
<Reference Include="System.Xml.Linq" />
5653
<Reference Include="System.Data.DataSetExtensions" />
5754
<Reference Include="Microsoft.CSharp" />

src/SvnManager.WebUI/UserModule.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
using Nancy;
33
using System;
44
using System.Collections.Generic;
5+
using System.Configuration;
56
using System.IO;
6-
using System.Linq;
7-
using System.Text;
8-
using System.Threading.Tasks;
97

108
namespace SvnManager.WebUI
119
{
@@ -31,9 +29,9 @@ public UserModule() : base("/user")
3129
string strPassword = password;
3230
string userPasswordHash = Crypter.MD5.Crypt(strPassword, new CrypterOptions { { CrypterOption.Variant, MD5CrypterVariant.Apache } });
3331

34-
var pwds = File.ReadAllText(@"C:\Repositories\htpasswd");
32+
var pwds = File.ReadAllText($@"{ConfigurationManager.AppSettings["Manger.RepoPath"].TrimEnd('\\')}\htpasswd");
3533
pwds += $"{name}:{userPasswordHash}{Environment.NewLine}";
36-
File.WriteAllText(@"C:\Repositories\htpasswd", pwds);
34+
File.WriteAllText($@"{ConfigurationManager.AppSettings["Manger.RepoPath"].TrimEnd('\\')}\htpasswd", pwds);
3735
}
3836
catch (Exception ex)
3937
{
@@ -51,7 +49,7 @@ private List<dynamic> GetUsers()
5149
var users = new List<dynamic>();
5250

5351
string line;
54-
using (StreamReader fs = new StreamReader(@"C:\Repositories\htpasswd"))
52+
using (StreamReader fs = new StreamReader($@"{ConfigurationManager.AppSettings["Manger.RepoPath"].TrimEnd('\\')}\htpasswd"))
5553
{
5654
while ((line = fs.ReadLine()) != null)
5755
{

src/SvnManager.WebUI/WebEvents.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
62

73
namespace SvnManager.WebUI
84
{

0 commit comments

Comments
 (0)