Allow renaming of folders. Closes #466
This commit is contained in:
parent
c769f6c7a8
commit
ec2f5f36a2
|
@ -771,49 +771,6 @@ namespace SparkleLib.Git {
|
||||||
return change_sets;
|
return change_sets;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string EnsureSpecialCharacters (string file_path)
|
|
||||||
{
|
|
||||||
if (file_path.StartsWith("\""))
|
|
||||||
{
|
|
||||||
System.Diagnostics.Debug.Assert(file_path.Length > 2 && file_path.EndsWith("\""), "unexpected path");
|
|
||||||
file_path = ResolveSpecialChars(file_path.Substring(1, file_path.Length - 2));
|
|
||||||
}
|
|
||||||
return file_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Resolves special characters like \303\244 (ä) to their real character
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="file_path"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private string ResolveSpecialChars (string file_path)
|
|
||||||
{
|
|
||||||
var builder = new System.Text.StringBuilder(file_path.Length);
|
|
||||||
var codes = new List<byte>();
|
|
||||||
for (int i = 0; i < file_path.Length; i++)
|
|
||||||
{
|
|
||||||
while (file_path[i] == '\\'
|
|
||||||
&& file_path.Length - i > 3
|
|
||||||
&& char.IsNumber(file_path[i + 1])
|
|
||||||
&& char.IsNumber(file_path[i + 2])
|
|
||||||
&& char.IsNumber(file_path[i + 3]))
|
|
||||||
{
|
|
||||||
codes.Add (Convert.ToByte(file_path.Substring(i + 1, 3), 8));
|
|
||||||
i += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (codes.Count > 0)
|
|
||||||
{
|
|
||||||
builder.Append(System.Text.Encoding.UTF8.GetString (codes.ToArray ()));
|
|
||||||
codes.Clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.Append(file_path[i]);
|
|
||||||
}
|
|
||||||
return builder.ToString();
|
|
||||||
//System.Text.Encoding.UTF8.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private string EnsureSpecialCharacters (string path)
|
private string EnsureSpecialCharacters (string path)
|
||||||
{
|
{
|
||||||
|
@ -825,11 +782,6 @@ namespace SparkleLib.Git {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Resolves special characters like \303\244 (ä) to their real character
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="file_path"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private string ResolveSpecialChars (string s)
|
private string ResolveSpecialChars (string s)
|
||||||
{
|
{
|
||||||
StringBuilder builder = new StringBuilder (s.Length);
|
StringBuilder builder = new StringBuilder (s.Length);
|
||||||
|
|
|
@ -248,6 +248,15 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void RenameFolder (string identifier, string name)
|
||||||
|
{
|
||||||
|
XmlNode node_folder = SelectSingleNode (string.Format ("/sparkleshare/folder[identifier=\"{0}\"]", identifier));
|
||||||
|
node_folder ["name"].InnerText = name;
|
||||||
|
|
||||||
|
Save ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public string GetBackendForFolder (string name)
|
public string GetBackendForFolder (string name)
|
||||||
{
|
{
|
||||||
return GetFolderValue (name, "backend");
|
return GetFolderValue (name, "backend");
|
||||||
|
@ -266,6 +275,17 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool IdentifierExists (string identifier)
|
||||||
|
{
|
||||||
|
foreach (XmlNode node_folder in SelectNodes ("/sparkleshare/folder")) {
|
||||||
|
if (node_folder ["identifier"].InnerText.Equals (identifier))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool SetFolderOptionalAttribute (string folder_name, string key, string value)
|
public bool SetFolderOptionalAttribute (string folder_name, string key, string value)
|
||||||
{
|
{
|
||||||
XmlNode folder = GetFolder (folder_name);
|
XmlNode folder = GetFolder (folder_name);
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace SparkleLib {
|
||||||
public readonly bool FetchPriorHistory = false;
|
public readonly bool FetchPriorHistory = false;
|
||||||
public string TargetFolder { get; protected set; }
|
public string TargetFolder { get; protected set; }
|
||||||
public bool IsActive { get; private set; }
|
public bool IsActive { get; private set; }
|
||||||
public string Identifier = CreateIdentifier ();
|
public string Identifier;
|
||||||
|
|
||||||
public string [] Warnings {
|
public string [] Warnings {
|
||||||
get {
|
get {
|
||||||
|
@ -66,13 +66,34 @@ namespace SparkleLib {
|
||||||
|
|
||||||
|
|
||||||
protected List<string> warnings = new List<string> ();
|
protected List<string> warnings = new List<string> ();
|
||||||
protected List<string> errors = new List<string> ();
|
protected List<string> errors = new List<string> ();
|
||||||
|
|
||||||
|
protected string [] ExcludeRules = new string [] {
|
||||||
|
"*.autosave", // Various autosaving apps
|
||||||
|
"*~", // gedit and emacs
|
||||||
|
".~lock.*", // LibreOffice
|
||||||
|
"*.part", "*.crdownload", // Firefox and Chromium temporary download files
|
||||||
|
".*.sw[a-z]", "*.un~", "*.swp", "*.swo", // vi(m)
|
||||||
|
".directory", // KDE
|
||||||
|
".DS_Store", "Icon\r\r", "._*", ".Spotlight-V100", ".Trashes", // Mac OS X
|
||||||
|
"*(Autosaved).graffle", // Omnigraffle
|
||||||
|
"Thumbs.db", "Desktop.ini", // Windows
|
||||||
|
"~*.tmp", "~*.TMP", "*~*.tmp", "*~*.TMP", // MS Office
|
||||||
|
"~*.ppt", "~*.PPT", "~*.pptx", "~*.PPTX",
|
||||||
|
"~*.xls", "~*.XLS", "~*.xlsx", "~*.XLSX",
|
||||||
|
"~*.doc", "~*.DOC", "~*.docx", "~*.DOCX",
|
||||||
|
"*/CVS/*", ".cvsignore", "*/.cvsignore", // CVS
|
||||||
|
"/.svn/*", "*/.svn/*", // Subversion
|
||||||
|
"/.hg/*", "*/.hg/*", "*/.hgignore", // Mercurial
|
||||||
|
"/.bzr/*", "*/.bzr/*", "*/.bzrignore" // Bazaar
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
|
|
||||||
|
|
||||||
public SparkleFetcherBase (string server, string required_fingerprint, string remote_path,
|
public SparkleFetcherBase (string server, string required_fingerprint,
|
||||||
string target_folder, bool fetch_prior_history)
|
string remote_path, string target_folder, bool fetch_prior_history)
|
||||||
{
|
{
|
||||||
RequiredFingerprint = required_fingerprint;
|
RequiredFingerprint = required_fingerprint;
|
||||||
FetchPriorHistory = fetch_prior_history;
|
FetchPriorHistory = fetch_prior_history;
|
||||||
|
@ -105,7 +126,6 @@ namespace SparkleLib {
|
||||||
if (Directory.Exists (TargetFolder))
|
if (Directory.Exists (TargetFolder))
|
||||||
Directory.Delete (TargetFolder, true);
|
Directory.Delete (TargetFolder, true);
|
||||||
|
|
||||||
|
|
||||||
string host = RemoteUrl.Host;
|
string host = RemoteUrl.Host;
|
||||||
string host_key = GetHostKey ();
|
string host_key = GetHostKey ();
|
||||||
|
|
||||||
|
@ -116,7 +136,6 @@ namespace SparkleLib {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool warn = true;
|
bool warn = true;
|
||||||
if (RequiredFingerprint != null) {
|
if (RequiredFingerprint != null) {
|
||||||
string host_fingerprint = GetFingerprint (host_key);
|
string host_fingerprint = GetFingerprint (host_key);
|
||||||
|
@ -141,30 +160,31 @@ namespace SparkleLib {
|
||||||
|
|
||||||
AcceptHostKey (host_key, warn);
|
AcceptHostKey (host_key, warn);
|
||||||
|
|
||||||
|
this.thread = new Thread (
|
||||||
|
new ThreadStart (delegate {
|
||||||
|
if (Fetch ()) {
|
||||||
|
Thread.Sleep (500);
|
||||||
|
SparkleHelpers.DebugInfo ("Fetcher", "Finished");
|
||||||
|
|
||||||
this.thread = new Thread (new ThreadStart (delegate {
|
IsActive = false;
|
||||||
if (Fetch ()) {
|
|
||||||
Thread.Sleep (500);
|
|
||||||
SparkleHelpers.DebugInfo ("Fetcher", "Finished");
|
|
||||||
|
|
||||||
IsActive = false;
|
// TODO: Find better way to determine if folder should have crypto setup
|
||||||
|
bool repo_is_encrypted = RemoteUrl.ToString ().Contains ("crypto");
|
||||||
|
|
||||||
// TODO: Find better way to determine if folder should have crypto setup
|
if (Finished != null)
|
||||||
bool repo_is_encrypted = RemoteUrl.ToString ().Contains ("crypto");
|
Finished (repo_is_encrypted, IsFetchedRepoEmpty, Warnings);
|
||||||
|
|
||||||
if (Finished != null)
|
} else {
|
||||||
Finished (repo_is_encrypted, IsFetchedRepoEmpty, Warnings);
|
Thread.Sleep (500);
|
||||||
|
SparkleHelpers.DebugInfo ("Fetcher", "Failed");
|
||||||
|
|
||||||
} else {
|
IsActive = false;
|
||||||
Thread.Sleep (500);
|
|
||||||
SparkleHelpers.DebugInfo ("Fetcher", "Failed");
|
|
||||||
|
|
||||||
IsActive = false;
|
if (Failed != null)
|
||||||
|
Failed ();
|
||||||
if (Failed != null)
|
}
|
||||||
Failed ();
|
})
|
||||||
}
|
);
|
||||||
}));
|
|
||||||
|
|
||||||
this.thread.Start ();
|
this.thread.Start ();
|
||||||
}
|
}
|
||||||
|
@ -174,8 +194,13 @@ namespace SparkleLib {
|
||||||
{
|
{
|
||||||
string identifier_path = Path.Combine (TargetFolder, ".sparkleshare");
|
string identifier_path = Path.Combine (TargetFolder, ".sparkleshare");
|
||||||
|
|
||||||
if (!File.Exists (identifier_path))
|
if (File.Exists (identifier_path)) {
|
||||||
|
Identifier = File.ReadAllText (identifier_path).Trim ();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Identifier = CreateIdentifier ();
|
||||||
File.WriteAllText (identifier_path, Identifier);
|
File.WriteAllText (identifier_path, Identifier);
|
||||||
|
}
|
||||||
|
|
||||||
if (IsFetchedRepoEmpty)
|
if (IsFetchedRepoEmpty)
|
||||||
CreateInitialChangeSet ();
|
CreateInitialChangeSet ();
|
||||||
|
@ -204,6 +229,32 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string CreateIdentifier ()
|
||||||
|
{
|
||||||
|
Random random = new Random ();
|
||||||
|
string number = "" + random.Next () + "" + random.Next () + "" + random.Next ();
|
||||||
|
|
||||||
|
return SparkleHelpers.SHA1 (number);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string GetBackend (string path)
|
||||||
|
{
|
||||||
|
string extension = Path.GetExtension (path);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty (extension)) {
|
||||||
|
extension = extension.Substring (1);
|
||||||
|
char [] letters = extension.ToCharArray ();
|
||||||
|
letters [0] = char.ToUpper (letters [0]);
|
||||||
|
|
||||||
|
return new string (letters);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return "Git";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Dispose ()
|
public void Dispose ()
|
||||||
{
|
{
|
||||||
if (this.thread != null) {
|
if (this.thread != null) {
|
||||||
|
@ -213,15 +264,6 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static string CreateIdentifier ()
|
|
||||||
{
|
|
||||||
Random random = new Random ();
|
|
||||||
string number = "" + random.Next () + "" + random.Next () + "" + random.Next ();
|
|
||||||
|
|
||||||
return SparkleHelpers.SHA1 (number);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected void OnProgressChanged (double percentage) {
|
protected void OnProgressChanged (double percentage) {
|
||||||
if (ProgressChanged != null)
|
if (ProgressChanged != null)
|
||||||
ProgressChanged (percentage);
|
ProgressChanged (percentage);
|
||||||
|
@ -242,7 +284,7 @@ namespace SparkleLib {
|
||||||
process.StartInfo.RedirectStandardOutput = true;
|
process.StartInfo.RedirectStandardOutput = true;
|
||||||
process.StartInfo.CreateNoWindow = true;
|
process.StartInfo.CreateNoWindow = true;
|
||||||
|
|
||||||
process.StartInfo.FileName = "ssh-keyscan";
|
process.StartInfo.FileName = "ssh-keyscan";
|
||||||
process.StartInfo.Arguments = "-t rsa " + host;
|
process.StartInfo.Arguments = "-t rsa " + host;
|
||||||
|
|
||||||
process.Start ();
|
process.Start ();
|
||||||
|
@ -283,7 +325,7 @@ namespace SparkleLib {
|
||||||
// WaitForExit, or it will hang forever on output > 4096 bytes
|
// WaitForExit, or it will hang forever on output > 4096 bytes
|
||||||
string fingerprint = process.StandardOutput.ReadToEnd ().Trim ();
|
string fingerprint = process.StandardOutput.ReadToEnd ().Trim ();
|
||||||
process.WaitForExit ();
|
process.WaitForExit ();
|
||||||
|
|
||||||
File.Delete (tmp_file_path);
|
File.Delete (tmp_file_path);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -329,98 +371,5 @@ namespace SparkleLib {
|
||||||
if (warn)
|
if (warn)
|
||||||
this.warnings.Add ("The following host key has been accepted:\n" + GetFingerprint (host_key));
|
this.warnings.Add ("The following host key has been accepted:\n" + GetFingerprint (host_key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static string GetBackend (string path)
|
|
||||||
{
|
|
||||||
string extension = Path.GetExtension (path);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty (extension)) {
|
|
||||||
extension = extension.Substring (1);
|
|
||||||
char [] letters = extension.ToCharArray ();
|
|
||||||
letters [0] = char.ToUpper (letters [0]);
|
|
||||||
|
|
||||||
return new string (letters);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return "Git";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected string [] ExcludeRules = new string [] {
|
|
||||||
// Various autosaving apps
|
|
||||||
"*.autosave",
|
|
||||||
|
|
||||||
// gedit and emacs
|
|
||||||
"*~",
|
|
||||||
|
|
||||||
// LibreOffice
|
|
||||||
".~lock.*",
|
|
||||||
|
|
||||||
// Firefox and Chromium temporary download files
|
|
||||||
"*.part",
|
|
||||||
"*.crdownload",
|
|
||||||
|
|
||||||
// vi(m)
|
|
||||||
".*.sw[a-z]",
|
|
||||||
"*.un~",
|
|
||||||
"*.swp",
|
|
||||||
"*.swo",
|
|
||||||
|
|
||||||
// KDE
|
|
||||||
".directory",
|
|
||||||
|
|
||||||
// Mac OS X
|
|
||||||
".DS_Store",
|
|
||||||
"Icon\r\r",
|
|
||||||
"._*",
|
|
||||||
".Spotlight-V100",
|
|
||||||
".Trashes",
|
|
||||||
|
|
||||||
// Omnigraffle
|
|
||||||
"*(Autosaved).graffle",
|
|
||||||
|
|
||||||
// Windows
|
|
||||||
"Thumbs.db",
|
|
||||||
"Desktop.ini",
|
|
||||||
|
|
||||||
// MS Office
|
|
||||||
"~*.tmp",
|
|
||||||
"~*.TMP",
|
|
||||||
"*~*.tmp",
|
|
||||||
"*~*.TMP",
|
|
||||||
"~*.ppt",
|
|
||||||
"~*.PPT",
|
|
||||||
"~*.pptx",
|
|
||||||
"~*.PPTX",
|
|
||||||
"~*.xls",
|
|
||||||
"~*.XLS",
|
|
||||||
"~*.xlsx",
|
|
||||||
"~*.XLSX",
|
|
||||||
"~*.doc",
|
|
||||||
"~*.DOC",
|
|
||||||
"~*.docx",
|
|
||||||
"~*.DOCX",
|
|
||||||
|
|
||||||
// CVS
|
|
||||||
"*/CVS/*",
|
|
||||||
".cvsignore",
|
|
||||||
"*/.cvsignore",
|
|
||||||
|
|
||||||
// Subversion
|
|
||||||
"/.svn/*",
|
|
||||||
"*/.svn/*",
|
|
||||||
|
|
||||||
// Mercurial
|
|
||||||
"/.hg/*",
|
|
||||||
"*/.hg/*",
|
|
||||||
"*/.hgignore",
|
|
||||||
|
|
||||||
// Bazaar
|
|
||||||
"/.bzr/*",
|
|
||||||
"*/.bzr/*",
|
|
||||||
"*/.bzrignore"
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,12 +34,8 @@ namespace SparkleShare {
|
||||||
|
|
||||||
public SparkleRepoBase [] Repositories {
|
public SparkleRepoBase [] Repositories {
|
||||||
get {
|
get {
|
||||||
lock (this.repo_lock) {
|
lock (this.repo_lock)
|
||||||
SparkleRepoBase [] repositories =
|
return this.repositories.GetRange (0, this.repositories.Count).ToArray ();
|
||||||
this.repositories.GetRange (0, this.repositories.Count).ToArray ();
|
|
||||||
|
|
||||||
return repositories;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,8 +166,8 @@ namespace SparkleShare {
|
||||||
|
|
||||||
|
|
||||||
private SparkleFetcherBase fetcher;
|
private SparkleFetcherBase fetcher;
|
||||||
private Object repo_lock = new Object ();
|
private Object repo_lock = new Object ();
|
||||||
private Object delete_watcher_lock = new Object ();
|
private Object check_repos_lock = new Object ();
|
||||||
|
|
||||||
|
|
||||||
// Short alias for the translations
|
// Short alias for the translations
|
||||||
|
@ -186,6 +182,110 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void HandleInvite (FileSystemEventArgs args)
|
||||||
|
{
|
||||||
|
if (this.fetcher != null &&
|
||||||
|
this.fetcher.IsActive) {
|
||||||
|
|
||||||
|
if (AlertNotificationRaised != null)
|
||||||
|
AlertNotificationRaised ("SparkleShare Setup seems busy",
|
||||||
|
"Please wait for it to finish");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (InviteReceived != null) {
|
||||||
|
SparkleInvite invite = new SparkleInvite (args.FullPath);
|
||||||
|
|
||||||
|
// It may be that the invite we received a path to isn't
|
||||||
|
// fully downloaded yet, so we try to read it several times
|
||||||
|
int tries = 0;
|
||||||
|
while (!invite.IsValid) {
|
||||||
|
Thread.Sleep (1 * 250);
|
||||||
|
invite = new SparkleInvite (args.FullPath);
|
||||||
|
tries++;
|
||||||
|
if (tries > 20)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invite.IsValid) {
|
||||||
|
InviteReceived (invite);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (AlertNotificationRaised != null)
|
||||||
|
AlertNotificationRaised ("Oh noes!",
|
||||||
|
"This invite seems screwed up...");
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Delete (args.FullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void CheckRepositories ()
|
||||||
|
{
|
||||||
|
lock (this.check_repos_lock) {
|
||||||
|
string path = SparkleConfig.DefaultConfig.FoldersPath;
|
||||||
|
|
||||||
|
foreach (string folder_path in Directory.GetDirectories (path)) {
|
||||||
|
string folder_name = Path.GetFileName (folder_path);
|
||||||
|
|
||||||
|
if (folder_name.Equals (".tmp"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (SparkleConfig.DefaultConfig.GetIdentifierForFolder (folder_name) == null) {
|
||||||
|
string identifier_file_path = Path.Combine (folder_path, ".sparkleshare");
|
||||||
|
|
||||||
|
if (!File.Exists (identifier_file_path))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string identifier = File.ReadAllText (identifier_file_path).Trim ();
|
||||||
|
|
||||||
|
if (SparkleConfig.DefaultConfig.IdentifierExists (identifier)) {
|
||||||
|
RemoveRepository (folder_path);
|
||||||
|
SparkleConfig.DefaultConfig.RenameFolder (identifier, folder_name);
|
||||||
|
|
||||||
|
string new_folder_path = Path.Combine (path, folder_name);
|
||||||
|
AddRepository (new_folder_path);
|
||||||
|
|
||||||
|
SparkleHelpers.DebugInfo ("Controller",
|
||||||
|
"Renamed folder with identifier " + identifier + " to '" + folder_name + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string folder_name in SparkleConfig.DefaultConfig.Folders) {
|
||||||
|
string folder_path = new SparkleFolder (folder_name).FullPath;
|
||||||
|
|
||||||
|
if (!Directory.Exists (folder_path)) {
|
||||||
|
SparkleConfig.DefaultConfig.RemoveFolder (folder_name);
|
||||||
|
RemoveRepository (folder_path);
|
||||||
|
|
||||||
|
SparkleHelpers.DebugInfo ("Controller",
|
||||||
|
"Removed folder '" + folder_name + "' from config");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FolderListChanged != null)
|
||||||
|
FolderListChanged ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void OnFolderActivity (object o, FileSystemEventArgs args)
|
||||||
|
{
|
||||||
|
if (args != null &&
|
||||||
|
args.ChangeType == WatcherChangeTypes.Created &&
|
||||||
|
args.FullPath.EndsWith (".xml")) {
|
||||||
|
|
||||||
|
HandleInvite (args);
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
CheckRepositories ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public virtual void Initialize ()
|
public virtual void Initialize ()
|
||||||
{
|
{
|
||||||
SparklePlugin.PluginsPath = PluginsPath;
|
SparklePlugin.PluginsPath = PluginsPath;
|
||||||
|
@ -201,69 +301,17 @@ namespace SparkleShare {
|
||||||
ImportPrivateKey ();
|
ImportPrivateKey ();
|
||||||
|
|
||||||
// Watch the SparkleShare folder
|
// Watch the SparkleShare folder
|
||||||
FileSystemWatcher watcher = new FileSystemWatcher (SparkleConfig.DefaultConfig.FoldersPath) {
|
FileSystemWatcher watcher = new FileSystemWatcher () {
|
||||||
|
Filter = "*",
|
||||||
IncludeSubdirectories = false,
|
IncludeSubdirectories = false,
|
||||||
EnableRaisingEvents = true,
|
Path = SparkleConfig.DefaultConfig.FoldersPath
|
||||||
Filter = "*"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
watcher.Deleted += delegate (object o, FileSystemEventArgs args) {
|
watcher.Deleted += OnFolderActivity;
|
||||||
lock (this.delete_watcher_lock) {
|
watcher.Created += OnFolderActivity;
|
||||||
foreach (string folder_name in SparkleConfig.DefaultConfig.Folders) {
|
watcher.Renamed += OnFolderActivity;
|
||||||
string folder_path = new SparkleFolder (folder_name).FullPath;
|
|
||||||
|
|
||||||
if (!Directory.Exists (folder_path)) {
|
watcher.EnableRaisingEvents = true;
|
||||||
SparkleConfig.DefaultConfig.RemoveFolder (folder_name);
|
|
||||||
RemoveRepository (folder_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FolderListChanged != null)
|
|
||||||
FolderListChanged ();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
watcher.Created += delegate (object o, FileSystemEventArgs args) {
|
|
||||||
if (!args.FullPath.EndsWith (".xml"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (this.fetcher != null &&
|
|
||||||
this.fetcher.IsActive) {
|
|
||||||
|
|
||||||
if (AlertNotificationRaised != null)
|
|
||||||
AlertNotificationRaised ("SparkleShare Setup seems busy",
|
|
||||||
"Please wait for it to finish");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (InviteReceived != null) {
|
|
||||||
SparkleInvite invite = new SparkleInvite (args.FullPath);
|
|
||||||
|
|
||||||
// It may be that the invite we received a path to isn't
|
|
||||||
// fully downloaded yet, so we try to read it several times
|
|
||||||
int tries = 0;
|
|
||||||
while (!invite.IsValid) {
|
|
||||||
Thread.Sleep (1 * 250);
|
|
||||||
invite = new SparkleInvite (args.FullPath);
|
|
||||||
tries++;
|
|
||||||
if (tries > 20)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (invite.IsValid) {
|
|
||||||
InviteReceived (invite);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
invite = null;
|
|
||||||
|
|
||||||
if (AlertNotificationRaised != null)
|
|
||||||
AlertNotificationRaised ("Oh noes!",
|
|
||||||
"This invite seems screwed up...");
|
|
||||||
}
|
|
||||||
|
|
||||||
File.Delete (args.FullPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -327,11 +375,9 @@ namespace SparkleShare {
|
||||||
|
|
||||||
string path = new SparkleFolder (name).FullPath;
|
string path = new SparkleFolder (name).FullPath;
|
||||||
|
|
||||||
lock (this.repo_lock) {
|
foreach (SparkleRepoBase repo in Repositories) {
|
||||||
foreach (SparkleRepoBase repo in Repositories) {
|
if (repo.LocalPath.Equals (path))
|
||||||
if (repo.LocalPath.Equals (path))
|
return repo.ChangeSets;
|
||||||
return repo.ChangeSets;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -511,7 +557,6 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Adds a repository to the list of repositories
|
|
||||||
private void AddRepository (string folder_path)
|
private void AddRepository (string folder_path)
|
||||||
{
|
{
|
||||||
SparkleRepoBase repo = null;
|
SparkleRepoBase repo = null;
|
||||||
|
@ -531,16 +576,8 @@ namespace SparkleShare {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repo.ChangesDetected += delegate {
|
||||||
repo.NewChangeSet += delegate (SparkleChangeSet change_set) {
|
UpdateState ();
|
||||||
if (NotificationRaised != null)
|
|
||||||
NotificationRaised (change_set);
|
|
||||||
};
|
|
||||||
|
|
||||||
repo.ConflictResolved += delegate {
|
|
||||||
if (AlertNotificationRaised != null)
|
|
||||||
AlertNotificationRaised ("Conflict detected",
|
|
||||||
"Don't worry, SparkleShare made a copy of each conflicting file.");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
repo.SyncStatusChanged += delegate (SyncStatus status) {
|
repo.SyncStatusChanged += delegate (SyncStatus status) {
|
||||||
|
@ -565,8 +602,15 @@ namespace SparkleShare {
|
||||||
UpdateState ();
|
UpdateState ();
|
||||||
};
|
};
|
||||||
|
|
||||||
repo.ChangesDetected += delegate {
|
repo.NewChangeSet += delegate (SparkleChangeSet change_set) {
|
||||||
UpdateState ();
|
if (NotificationRaised != null)
|
||||||
|
NotificationRaised (change_set);
|
||||||
|
};
|
||||||
|
|
||||||
|
repo.ConflictResolved += delegate {
|
||||||
|
if (AlertNotificationRaised != null)
|
||||||
|
AlertNotificationRaised ("Conflict detected",
|
||||||
|
"Don't worry, SparkleShare made a copy of each conflicting file.");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.repositories.Add (repo);
|
this.repositories.Add (repo);
|
||||||
|
@ -574,45 +618,25 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Removes a repository from the list of repositories and
|
|
||||||
// updates the statusicon menu
|
|
||||||
private void RemoveRepository (string folder_path)
|
private void RemoveRepository (string folder_path)
|
||||||
{
|
{
|
||||||
string folder_name = Path.GetFileName (folder_path);
|
for (int i = 0; i < this.repositories.Count; i++) {
|
||||||
|
SparkleRepoBase repo = this.repositories [i];
|
||||||
|
|
||||||
for (int i = 0; i < Repositories.Length; i++) {
|
if (repo.LocalPath.Equals (folder_path)) {
|
||||||
SparkleRepoBase repo = Repositories [i];
|
|
||||||
|
|
||||||
if (repo.Name.Equals (folder_name)) {
|
|
||||||
repo.Dispose ();
|
repo.Dispose ();
|
||||||
|
this.repositories.Remove (repo);
|
||||||
lock (this.repo_lock) {
|
|
||||||
this.repositories.Remove (repo);
|
|
||||||
}
|
|
||||||
|
|
||||||
repo = null;
|
repo = null;
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Updates the list of repositories with all the
|
|
||||||
// folders in the SparkleShare folder
|
|
||||||
private void PopulateRepositories ()
|
private void PopulateRepositories ()
|
||||||
{
|
{
|
||||||
lock (this.repo_lock) {
|
CheckRepositories ();
|
||||||
foreach (string folder_name in SparkleConfig.DefaultConfig.Folders) {
|
|
||||||
string folder_path = new SparkleFolder (folder_name).FullPath;
|
|
||||||
|
|
||||||
if (Directory.Exists (folder_path))
|
|
||||||
AddRepository (folder_path);
|
|
||||||
else
|
|
||||||
SparkleConfig.DefaultConfig.RemoveFolder (folder_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RepositoriesLoaded = true;
|
RepositoriesLoaded = true;
|
||||||
|
|
||||||
if (FolderListChanged != null)
|
if (FolderListChanged != null)
|
||||||
|
@ -922,9 +946,7 @@ namespace SparkleShare {
|
||||||
target_folder_name, "announcements_url", announcements_url);
|
target_folder_name, "announcements_url", announcements_url);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
lock (this.repo_lock) {
|
AddRepository (target_folder_path);
|
||||||
AddRepository (target_folder_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FolderListChanged != null)
|
if (FolderListChanged != null)
|
||||||
FolderListChanged ();
|
FolderListChanged ();
|
||||||
|
|
Loading…
Reference in a new issue