diff --git a/SparkleLib/SparkleFetcher.cs b/SparkleLib/SparkleFetcher.cs
index 378fac49..951e5ae1 100644
--- a/SparkleLib/SparkleFetcher.cs
+++ b/SparkleLib/SparkleFetcher.cs
@@ -20,6 +20,8 @@ using System.Diagnostics;
namespace SparkleLib {
+ // A helper class that fetches and and configures
+ // a remote repository
public class SparkleFetcher {
public delegate void CloningStartedEventHandler (object o, SparkleEventArgs args);
@@ -98,7 +100,6 @@ namespace SparkleLib {
private void InstallUserInfo ()
{
- // TODO: Use TargetFolder and move SparklePaths out of SparkleLib
string global_config_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleConfigPath, "config");
if (File.Exists (global_config_file_path)) {
@@ -124,11 +125,18 @@ namespace SparkleLib {
private void InstallExcludeRules ()
{
- TextWriter writer = new StreamWriter (SparkleHelpers.CombineMore (TargetFolder, ".git/info/exclude"));
+ string exlude_rules_file_path = SparkleHelpers.CombineMore (TargetFolder, ".git", "info", "exclude");
- writer.WriteLine ("*~"); // Ignore gedit swap files
- writer.WriteLine (".*.sw?"); // Ignore vi swap files
- writer.WriteLine (".DS_store"); // Ignore OSX's invisible directories
+ TextWriter writer = new StreamWriter (exlude_rules_file_path);
+
+ // Ignore gedit swap files
+ writer.WriteLine ("*~");
+
+ // Ignore vi swap files
+ writer.WriteLine (".*.sw?");
+
+ // Ignore OSX's invisible directories
+ writer.WriteLine (".DS_store");
writer.Close ();
diff --git a/SparkleLib/SparkleRepo.cs b/SparkleLib/SparkleRepo.cs
index a8734677..181789d0 100644
--- a/SparkleLib/SparkleRepo.cs
+++ b/SparkleLib/SparkleRepo.cs
@@ -558,7 +558,7 @@ namespace SparkleLib {
UnixUserInfo unix_user_info = new UnixUserInfo (UnixEnvironment.UserName);
if (unix_user_info.RealName.Equals (""))
- user_name = "???";
+ user_name = "Mysterious Stranger";
else
user_name = unix_user_info.RealName;
@@ -582,8 +582,12 @@ namespace SparkleLib {
process.StartInfo.WorkingDirectory = LocalPath;
process.StartInfo.Arguments = "config --get user.email";
process.Start ();
+
user_email = process.StandardOutput.ReadToEnd ().Trim ();
+ if (user_email.Equals (""))
+ user_email = "Unknown Email";
+
return user_email;
}
diff --git a/SparkleShare/SparkleIntro.cs b/SparkleShare/SparkleIntro.cs
index ce253633..a7f0f0e2 100644
--- a/SparkleShare/SparkleIntro.cs
+++ b/SparkleShare/SparkleIntro.cs
@@ -724,14 +724,22 @@ namespace SparkleShare {
string config_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleConfigPath, "config");
+ string name = NameEntry.Text;
+ string email = EmailEntry.Text;
+
+ // Write the user's information to a text file
TextWriter writer = new StreamWriter (config_file_path);
writer.WriteLine ("[user]\n" +
- "\tname = " + NameEntry.Text + "\n" +
- "\temail = " + EmailEntry.Text);
+ "\tname = " + name + "\n" +
+ "\temail = " + email);
writer.Close ();
SparkleHelpers.DebugInfo ("Config", "Created '" + config_file_path + "'");
+ // Set the user's name and email globally
+ SparkleShare.UserName = name;
+ SparkleShare.UserEmail = email;
+
GenerateKeyPair ();
}
diff --git a/SparkleShare/SparkleInvitation.cs b/SparkleShare/SparkleInvitation.cs
index e9d0bfef..e127df48 100644
--- a/SparkleShare/SparkleInvitation.cs
+++ b/SparkleShare/SparkleInvitation.cs
@@ -14,17 +14,29 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+using Gtk;
+using Mono.Unix;
+using SparkleLib;
using System;
using System.IO;
+using System.Net;
using System.Xml;
namespace SparkleShare {
- class SparkleInvitation {
+ class SparkleInvitation : SparkleWindow {
public string Server;
- public string Repository;
- public string Key;
+ public string Folder;
+ public string InviteKey;
+ public string FilePath;
+
+
+ // Short alias for the translations
+ public static string _ (string s)
+ {
+ return Catalog.GetString (s);
+ }
public SparkleInvitation (string file_path)
@@ -33,25 +45,132 @@ namespace SparkleShare {
if (!File.Exists (file_path))
return;
+ FilePath = file_path;
+
XmlDocument xml_doc = new XmlDocument ();
xml_doc.Load (file_path);
XmlNodeList server_xml = xml_doc.GetElementsByTagName ("server");
- XmlNodeList repository_xml = xml_doc.GetElementsByTagName ("repository");
- XmlNodeList key_xml = xml_doc.GetElementsByTagName ("key");
+ XmlNodeList folder_xml = xml_doc.GetElementsByTagName ("folder");
+ XmlNodeList invite_key_xml = xml_doc.GetElementsByTagName ("invitekey");
- Server = server_xml [0].InnerText;
- Repository = repository_xml [0].InnerText;
- Key = key_xml [0].InnerText;
+ Server = server_xml [0].InnerText;
+ Folder = folder_xml [0].InnerText;
+ InviteKey = invite_key_xml [0].InnerText;
}
- public void Activate ()
+ // Uploads the user's public key to the
+ // server and starts the syncing process
+ public void Configure ()
{
- string url = "http://" + Server + "/repo=" + Repository + "&key=" + Key;
- Console.WriteLine (url);
+ // The location of the user's public key for SparkleShare
+ string public_key_file_path = SparkleHelpers.CombineMore (SparklePaths.HomePath, ".ssh",
+ "sparkleshare." + SparkleShare.UserEmail + ".key.pub");
+
+ if (!File.Exists (public_key_file_path))
+ return;
+
+ StreamReader reader = new StreamReader (public_key_file_path);
+ string public_key = reader.ReadToEnd ();
+ reader.Close ();
+
+ string url = "http://" + Server + "/folder=" + Folder +
+ "&invite=" + InviteKey +
+ "&key=" + public_key;
+
+ SparkleHelpers.DebugInfo ("WebRequest", url);
+
+ HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url);
+ HttpWebResponse response = (HttpWebResponse) request.GetResponse();
+
+ if (response.StatusCode == HttpStatusCode.OK)
+ File.Delete (FilePath);
+
+ response.Close ();
+
+ }
+
+
+ public void PresentInvitation ()
+ {
+
+ VBox layout_vertical = new VBox (false, 0);
+
+ Label header = new Label ("" +
+ _("Invitation received!") +
+ "") {
+ UseMarkup = true,
+ Xalign = 0
+ };
+
+ Label information = new Label (_("You've received an invitation to join a shared folder.\n" +
+ "We're ready to hook you up immediately if you wish.")) {
+ Xalign = 0,
+ Wrap = true
+ };
+
+ Label question = new Label (_("Do you accept this invitation?")) {
+ Xalign = 0,
+ Wrap = true
+ };
+
+ Table table = new Table (2, 2, true) {
+ RowSpacing = 6
+ };
+
+ Label server_label = new Label (_("Server Address:")) {
+ Xalign = 0
+ };
+
+ Label server = new Label ("" + Server + "") {
+ UseMarkup = true,
+ Xalign = 0
+ };
+
+ Label folder_label = new Label (_("Folder Name:")) {
+ Xalign = 0
+ };
+
+ Label folder = new Label ("" + Folder + "") {
+ UseMarkup = true,
+ Xalign = 0
+ };
+
+ table.Attach (folder_label, 0, 1, 0, 1);
+ table.Attach (folder, 1, 2, 0, 1);
+ table.Attach (server_label, 0, 1, 1, 2);
+ table.Attach (server, 1, 2, 1, 2);
+
+ Button reject_button = new Button (_("Reject"));
+ Button accept_button = new Button (_("Accept"));
+
+ reject_button.Clicked += delegate {
+
+ // Delete the invitation
+ File.Delete (FilePath);
+
+ Destroy ();
+
+ };
+
+ AddButton (reject_button);
+ AddButton (accept_button);
+
+ layout_vertical.PackStart (header, false, false, 0);
+ layout_vertical.PackStart (information, false, false, 21);
+ layout_vertical.PackStart (new Label (""), false, false, 0);
+ layout_vertical.PackStart (table, false, false, 0);
+ layout_vertical.PackStart (new Label (""), false, false, 0);
+ layout_vertical.PackStart (question, false, false, 21);
+
+ Add (layout_vertical);
+
+ ShowAll ();
+
+ Present ();
}
diff --git a/SparkleShare/SparkleShare.cs b/SparkleShare/SparkleShare.cs
index 1bb77ad1..90750cd5 100644
--- a/SparkleShare/SparkleShare.cs
+++ b/SparkleShare/SparkleShare.cs
@@ -18,6 +18,7 @@ using Gtk;
using Mono.Unix;
using System;
using System.Diagnostics;
+using System.IO;
using SparkleLib;
namespace SparkleShare {
@@ -26,6 +27,8 @@ namespace SparkleShare {
public class SparkleShare {
public static SparkleUI SparkleUI;
+ public static string UserName;
+ public static string UserEmail;
// Short alias for the translations
@@ -42,26 +45,39 @@ namespace SparkleShare {
Catalog.Init (Defines.GETTEXT_PACKAGE, Defines.LOCALE_DIR);
// Check whether git is installed
- Process Process = new Process ();
- Process.StartInfo.FileName = "git";
- Process.StartInfo.RedirectStandardOutput = true;
- Process.StartInfo.UseShellExecute = false;
- Process.Start ();
+ Process process = new Process ();
+ process.StartInfo.FileName = "git";
+ process.StartInfo.RedirectStandardOutput = true;
+ process.StartInfo.UseShellExecute = false;
+ process.Start ();
+
+ if (process.StandardOutput.ReadToEnd ().IndexOf ("version") == -1) {
- if (Process.StandardOutput.ReadToEnd ().IndexOf ("version") == -1) {
Console.WriteLine (_("Git wasn't found."));
Console.WriteLine (_("You can get Git from http://git-scm.com/."));
+
Environment.Exit (0);
+
}
+
+ UnixUserInfo user_info = new UnixUserInfo (UnixEnvironment.UserName);
+
// Don't allow running as root
- UnixUserInfo UnixUserInfo = new UnixUserInfo (UnixEnvironment.UserName);
- if (UnixUserInfo.UserId == 0) {
+ if (user_info.UserId == 0) {
+
Console.WriteLine (_("Sorry, you can't run SparkleShare with these permissions."));
Console.WriteLine (_("Things would go utterly wrong."));
+
Environment.Exit (0);
+
}
+
+ UserName = GetUserName ();
+ UserEmail = GetUserEmail ();
+
+
bool HideUI = false;
// Parse the command line arguments
@@ -132,6 +148,49 @@ namespace SparkleShare {
}
+
+ // Looks up the user's name from the global configuration
+ public static string GetUserName ()
+ {
+
+ string global_config_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleConfigPath, "config");
+
+ StreamReader reader = new StreamReader (global_config_file_path);
+
+ // Discard the first line
+ reader.ReadLine ();
+
+ string line = reader.ReadLine ();
+ reader.Close ();
+
+ string name = line.Substring (line.IndexOf ("=") + 2);
+
+ return name;
+
+ }
+
+
+ // Looks up the user's email from the global configuration
+ public static string GetUserEmail ()
+ {
+
+ string global_config_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleConfigPath, "config");
+
+ StreamReader reader = new StreamReader (global_config_file_path);
+
+ // Discard the first two lines
+ reader.ReadLine ();
+ reader.ReadLine ();
+
+ string line = reader.ReadLine ();
+ reader.Close ();
+
+ string email = line.Substring (line.IndexOf ("=") + 2);
+
+ return email;
+
+ }
+
}
}
diff --git a/SparkleShare/SparkleUI.cs b/SparkleShare/SparkleUI.cs
index 7e404828..c2cf8597 100644
--- a/SparkleShare/SparkleUI.cs
+++ b/SparkleShare/SparkleUI.cs
@@ -30,10 +30,8 @@ namespace SparkleShare {
public class SparkleUI {
- public static SparkleStatusIcon NotificationIcon;
public static List Repositories;
-
- private Process Process;
+ public static SparkleStatusIcon NotificationIcon;
// Short alias for the translations
@@ -51,17 +49,13 @@ namespace SparkleShare {
SetProcessName ("sparkleshare");
+ // The list of repositories
Repositories = new List ();
- Process = new Process () {
- EnableRaisingEvents = true
- };
- Process.StartInfo.RedirectStandardOutput = true;
- Process.StartInfo.UseShellExecute = false;
-
EnableSystemAutostart ();
InstallLauncher ();
+
// Create the SparkleShare folder and add it to the bookmarks
if (!Directory.Exists (SparklePaths.SparklePath)) {
@@ -79,20 +73,25 @@ namespace SparkleShare {
Filter = "*"
};
+
+ // Remove the repository when a delete event occurs
watcher.Deleted += delegate (object o, FileSystemEventArgs args) {
RemoveRepository (args.FullPath);
};
+ // Add the repository when a create event occurs
watcher.Created += delegate (object o, FileSystemEventArgs args) {
+ // Handle invitations when the user saves an
+ // invitation into the SparkleShare folder
if (args.Name.EndsWith ("sparkleshare.invitation")) {
SparkleInvitation invitation;
invitation = new SparkleInvitation (args.FullPath);
- invitation.Activate ();
+ Application.Invoke (delegate { invitation.PresentInvitation (); });
} else if (Directory.Exists (args.FullPath)) {
@@ -106,18 +105,22 @@ namespace SparkleShare {
CreateConfigurationFolders ();
PopulateRepositories ();
- // Don't create the window and status
- // icon when --disable-gui was given
+
+ // Don't create the window and status icon when
+ // the --disable-gui command line argument was given
if (!HideUI) {
- // Show the intro screen if there are no folders
- if (Repositories.Count == 0) {
+ string global_config_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleConfigPath, "config");
+
+ // Show the introduction screen if SparkleShare isn't configured
+ if (!File.Exists (global_config_file_path)) {
SparkleIntro intro = new SparkleIntro ();
intro.ShowAll ();
}
+ // Create the statusicon
NotificationIcon = new SparkleStatusIcon ();
}
@@ -125,10 +128,10 @@ namespace SparkleShare {
}
+ // Runs the main loop
public void Run ()
{
- // The main loop
Gtk.Application.Run ();
}
@@ -165,8 +168,8 @@ namespace SparkleShare {
}
- // Creates .desktop entry in autostart folder to
- // start SparkleShare automnatically at login
+ // Creates a .desktop entry in autostart folder to
+ // start SparkleShare automatically at login
public void EnableSystemAutostart ()
{
@@ -235,7 +238,7 @@ namespace SparkleShare {
// Adds the SparkleShare folder to the user's
- // list of bookmarked folders
+ // list of bookmarked places
public void AddToBookmarks ()
{
@@ -267,20 +270,26 @@ namespace SparkleShare {
}
- // Creates the SparkleShare folder in the user's home folder if
- // it's not already there
+ // Creates the SparkleShare folder in the user's home folder
public void CreateSparkleShareFolder ()
{
Directory.CreateDirectory (SparklePaths.SparklePath);
SparkleHelpers.DebugInfo ("Config", "Created '" + SparklePaths.SparklePath + "'");
-
+
+ string icon_file_path = SparkleHelpers.CombineMore (Defines.PREFIX, "share", "icons", "hicolor", "48x48",
+ "apps", "folder-sparkleshare.png");
+
+ Process process = new Process ();
+
+ process.StartInfo.RedirectStandardOutput = true;
+ process.StartInfo.UseShellExecute = false;
+
// Add a special icon to the SparkleShare folder
- Process.StartInfo.FileName = "gvfs-set-attribute";
- Process.StartInfo.Arguments = SparklePaths.SparklePath + " metadata::custom-icon " +
- "file://" + SparkleHelpers.CombineMore (Defines.PREFIX, "share", "icons",
- "hicolor", "48x48", "apps", "folder-sparkleshare.png");
- Process.Start ();
+ process.StartInfo.FileName = "gvfs-set-attribute";
+ process.StartInfo.Arguments = SparklePaths.SparklePath + " metadata::custom-icon " +
+ "file://" + icon_file_path;
+ process.Start ();
}
@@ -305,7 +314,8 @@ namespace SparkleShare {
// Shows a notification bubble when there
// was a conflict
- public void ShowConflictBubble (object o, EventArgs args) {
+ public void ShowConflictBubble (object o, EventArgs args)
+ {
string title = _("Ouch! Mid-air collision!");
string subtext = _("Don't worry, SparkleShare made a copy of each conflicting file.");
@@ -336,7 +346,10 @@ namespace SparkleShare {
}
- public void AddRepository (string folder_path) {
+ // Adds a repository to the list of repositories and
+ // updates the statusicon menu
+ public void AddRepository (string folder_path)
+ {
// Check if the folder is a git repo
if (!Directory.Exists (SparkleHelpers.CombineMore (folder_path, ".git")))
@@ -380,7 +393,10 @@ namespace SparkleShare {
}
- public void RemoveRepository (string folder_path) {
+ // Removes a repository from the list of repositories and
+ // updates the statusicon menu
+ public void RemoveRepository (string folder_path)
+ {
string repo_name = Path.GetFileName (folder_path);
@@ -435,10 +451,7 @@ namespace SparkleShare {
}
- [DllImport ("libc")]
- private static extern int prctl (int option, byte [] arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5);
-
-
+ // Method to set the unix process name to 'sparkleshare' instead of 'mono'
private void SetProcessName (string name)
{
@@ -451,10 +464,19 @@ namespace SparkleShare {
}
- } catch (EntryPointNotFoundException) {}
+ } catch (EntryPointNotFoundException) {
+
+ Console.WriteLine ("SetProcessName: Entry point not found");
+
+ }
}
+
+ // Strange magic needed by SetProcessName
+ [DllImport ("libc")]
+ private static extern int prctl (int option, byte [] arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5);
+
}
}