Some rearrangements

This commit is contained in:
Hylke Bons 2012-07-14 12:45:54 +02:00
parent 2114a7dd3d
commit eaead8c87d
10 changed files with 518 additions and 514 deletions

View file

@ -32,7 +32,7 @@ namespace SparkleLib.Git {
private bool use_git_bin;
public SparkleRepo (string path) : base (path)
public SparkleRepo (string path, SparkleConfig config) : base (path, config)
{
SparkleGit git = new SparkleGit (LocalPath, "config --get filter.bin.clean");
git.Start ();
@ -199,7 +199,7 @@ namespace SparkleLib.Git {
this.remote_url_is_set = true;
}
Console.WriteLine (this.use_git_bin);
SparkleGitBin git_bin = new SparkleGitBin (LocalPath, "push");
git_bin.Start ();
git_bin.WaitForExit ();
@ -407,13 +407,13 @@ namespace SparkleLib.Git {
if (!this.user_is_set) {
git = new SparkleGit (LocalPath,
"config user.name \"" + SparkleConfig.DefaultConfig.User.Name + "\"");
"config user.name \"" + base.local_config.User.Name + "\"");
git.Start ();
git.WaitForExit ();
git = new SparkleGit (LocalPath,
"config user.email \"" + SparkleConfig.DefaultConfig.User.Email + "\"");
"config user.email \"" + base.local_config.User.Email + "\"");
git.Start ();
git.WaitForExit ();
@ -423,8 +423,8 @@ namespace SparkleLib.Git {
git = new SparkleGit (LocalPath,
"commit --all --message=\"" + message + "\" " +
"--author=\"" + SparkleConfig.DefaultConfig.User.Name +
" <" + SparkleConfig.DefaultConfig.User.Email + ">\"");
"--author=\"" + base.local_config.User.Name +
" <" + base.local_config.User.Email + ">\"");
git.Start ();
git.StandardOutput.ReadToEnd ();
@ -537,7 +537,7 @@ namespace SparkleLib.Git {
// we use "h" between the hours and minutes instead.
string timestamp = DateTime.Now.ToString ("MMM d H\\hmm");
string their_path = Path.GetFileNameWithoutExtension (conflicting_path) +
" (" + SparkleConfig.DefaultConfig.User.Name + ", " + timestamp + ")" +
" (" + base.local_config.User.Name + ", " + timestamp + ")" +
Path.GetExtension (conflicting_path);
string abs_conflicting_path = Path.Combine (LocalPath, conflicting_path);
@ -684,6 +684,8 @@ namespace SparkleLib.Git {
if (file_path.Equals (".sparkleshare"))
continue;
file_path = file_path.Replace ("\\\"", "\"");
if (change_type.Equals ("A")) {
change_set.Changes.Add (
new SparkleChange () {
@ -719,6 +721,9 @@ namespace SparkleLib.Git {
file_path = EnsureSpecialCharacters (file_path);
to_file_path = EnsureSpecialCharacters (to_file_path);
file_path = file_path.Replace ("\\\"", "\"");
to_file_path = to_file_path.Replace ("\\\"", "\"");
if (file_path.EndsWith (".empty"))
file_path = file_path.Substring (0, file_path.Length - 6);
@ -915,7 +920,7 @@ namespace SparkleLib.Git {
}
git_status.WaitForExit ();
return message.Replace ("\"", "\\\"");
return message;
}

View file

@ -25,11 +25,7 @@ namespace SparkleLib {
public class SparkleConfig : XmlDocument {
private static string default_config_path = Path.Combine (
Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData),
"sparkleshare");
public static SparkleConfig DefaultConfig = new SparkleConfig (default_config_path, "config.xml");
public static SparkleConfig DefaultConfig;
public static bool DebugMode = true;
public string FullPath;

View file

@ -105,8 +105,18 @@ namespace SparkleLib {
public static string SHA1 (string s)
{
SHA1 sha1 = new SHA1CryptoServiceProvider ();
Byte [] bytes = ASCIIEncoding.Default.GetBytes (s);
Byte [] enc_bytes = sha1.ComputeHash (bytes);
byte [] bytes = ASCIIEncoding.Default.GetBytes (s);
byte [] enc_bytes = sha1.ComputeHash (bytes);
return BitConverter.ToString (enc_bytes).ToLower ().Replace ("-", "");
}
public static string MD5 (string s)
{
MD5 md5 = new MD5CryptoServiceProvider ();
byte [] bytes = ASCIIEncoding.Default.GetBytes (s);
byte [] enc_bytes = md5.ComputeHash (bytes);
return BitConverter.ToString (enc_bytes).ToLower ().Replace ("-", "");
}

View file

@ -87,7 +87,7 @@ namespace SparkleLib {
return this.identifier;
} else {
string config_identifier = SparkleConfig.DefaultConfig.GetIdentifierForFolder (Name);
string config_identifier = this.local_config.GetIdentifierForFolder (Name);
if (!string.IsNullOrEmpty (config_identifier))
this.identifier = config_identifier;
@ -137,11 +137,16 @@ namespace SparkleLib {
}
public SparkleRepoBase (string path) // TODO: pass a config object
protected SparkleConfig local_config;
public SparkleRepoBase (string path, SparkleConfig config)
{
this.local_config = config;
LocalPath = path;
Name = Path.GetFileName (LocalPath);
RemoteUrl = new Uri (SparkleConfig.DefaultConfig.GetUrlForFolder (Name));
RemoteUrl = new Uri (this.local_config.GetUrlForFolder (Name));
IsBuffering = false;
ServerOnline = true;

View file

@ -166,15 +166,19 @@ namespace SparkleShare {
NSUserDefaults.StandardUserDefaults.SetPersistentDomain (sidebar_plist, "com.apple.sidebarlists");*/
}
// Creates the SparkleShare folder in the user's home folder
public override bool CreateSparkleShareFolder ()
{
this.watcher = new SparkleMacWatcher (SparkleConfig.DefaultConfig.FoldersPath);
this.watcher = new SparkleMacWatcher (Program.Controller.FoldersPath);
if (!Directory.Exists (Program.Controller.FoldersPath)) {
Directory.CreateDirectory (Program.Controller.FoldersPath);
NSWorkspace.SharedWorkspace.SetIconforFile (
NSImage.ImageNamed ("sparkleshare-folder.icns"), FoldersPath,
NSWorkspaceIconCreationOptions.NSExclude10_4Elements);
if (!Directory.Exists (SparkleConfig.DefaultConfig.FoldersPath)) {
Directory.CreateDirectory (SparkleConfig.DefaultConfig.FoldersPath);
return true;
} else {
@ -188,7 +192,14 @@ namespace SparkleShare {
NSWorkspace.SharedWorkspace.OpenFile (path);
}
public override void OpenFile (string path)
{
path = Uri.UnescapeDataString (path);
NSWorkspace.SharedWorkspace.OpenFile (path);
}
public override string EventLogHTML
{
get {
@ -242,12 +253,5 @@ namespace SparkleShare {
}
}
}
public override void OpenFile (string url)
{
url = url.Replace ("%20", " ");
NSWorkspace.SharedWorkspace.OpenFile (url);
}
}
}

View file

@ -78,7 +78,7 @@ namespace SparkleShare {
NSImage folder_icon = new NSImage (folder_icon_path);
NSWorkspace.SharedWorkspace.SetIconforFile (folder_icon,
Program.Controller.SparklePath, 0);
Program.Controller.FoldersPath, 0);
}
}

View file

@ -73,15 +73,11 @@ namespace SparkleShare {
Environment.Exit (-1);
}
// Initialize the controller this way so that
// there aren't any exceptions in the OS specific UI's
Controller = new SparkleController ();
Controller.Initialize ();
if (Controller != null) {
UI = new SparkleUI ();
UI.Run ();
}
UI = new SparkleUI ();
UI.Run ();
#if !__MonoCS__
// Suppress assertion messages in debug mode

View file

@ -17,12 +17,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
@ -41,8 +38,8 @@ namespace SparkleShare {
public bool RepositoriesLoaded { get; private set;}
public List<SparkleRepoBase> repositories = new List<SparkleRepoBase> ();
public readonly string SparklePath = SparkleConfig.DefaultConfig.FoldersPath;
private List<SparkleRepoBase> repositories = new List<SparkleRepoBase> ();
public string FoldersPath { get; private set; }
public double ProgressPercentage = 0.0;
public string ProgressSpeed = "";
@ -70,6 +67,7 @@ namespace SparkleShare {
public event FolderListChangedHandler FolderListChanged;
public delegate void FolderListChangedHandler ();
public event OnIdleHandler OnIdle;
public delegate void OnIdleHandler ();
@ -79,6 +77,7 @@ namespace SparkleShare {
public event OnErrorHandler OnError;
public delegate void OnErrorHandler ();
public event InviteReceivedHandler InviteReceived;
public delegate void InviteReceivedHandler (SparkleInvite invite);
@ -91,13 +90,13 @@ namespace SparkleShare {
public bool FirstRun {
get {
return SparkleConfig.DefaultConfig.User.Email.Equals ("Unknown");
return this.config.User.Email.Equals ("Unknown");
}
}
public List<string> Folders {
get {
List<string> folders = SparkleConfig.DefaultConfig.Folders;
List<string> folders = this.config.Folders;
folders.Sort ();
return folders;
@ -119,20 +118,20 @@ namespace SparkleShare {
public SparkleUser CurrentUser {
get {
return SparkleConfig.DefaultConfig.User;
return this.config.User;
}
set {
SparkleConfig.DefaultConfig.User = value;
this.config.User = value;
}
}
public bool NotificationsEnabled {
get {
string notifications_enabled = SparkleConfig.DefaultConfig.GetConfigOption ("notifications");
string notifications_enabled = this.config.GetConfigOption ("notifications");
if (string.IsNullOrEmpty (notifications_enabled)) {
SparkleConfig.DefaultConfig.SetConfigOption ("notifications", bool.TrueString);
this.config.SetConfigOption ("notifications", bool.TrueString);
return true;
} else {
@ -142,6 +141,10 @@ namespace SparkleShare {
}
public abstract string EventLogHTML { get; }
public abstract string DayEntryHTML { get; }
public abstract string EventEntryHTML { get; }
// Path where the plugins are kept
public abstract string PluginsPath { get; }
@ -165,138 +168,27 @@ namespace SparkleShare {
public abstract void OpenFile (string path);
private SparkleConfig config;
private SparkleFetcherBase fetcher;
private Object repo_lock = new Object ();
private Object check_repos_lock = new Object ();
// Short alias for the translations
public static string _ (string s)
{
return Program._(s);
}
public SparkleControllerBase ()
{
}
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");
} else {
AddRepository (folder_path);
}
}
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 {
if (Directory.Exists (args.FullPath) &&
args.ChangeType == WatcherChangeTypes.Created) {
return;
}
CheckRepositories ();
}
}
public virtual void Initialize ()
{
string app_data_path = Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData);
string config_path = Path.Combine (app_data_path, "sparkleshare");
this.config = new SparkleConfig (config_path, "config.xml");
SparkleConfig.DefaultConfig = this.config;
FoldersPath = this.config.FoldersPath;
SparklePlugin.PluginsPath = PluginsPath;
InstallProtocolHandler ();
@ -305,10 +197,10 @@ namespace SparkleShare {
AddToBookmarks ();
if (FirstRun) {
SparkleConfig.DefaultConfig.SetConfigOption ("notifications", bool.TrueString);
this.config.SetConfigOption ("notifications", bool.TrueString);
} else {
string keys_path = Path.GetDirectoryName (SparkleConfig.DefaultConfig.FullPath);
string keys_path = Path.GetDirectoryName (this.config.FullPath);
string key_file_name = "sparkleshare." + CurrentUser.Email + ".key";
string key_file_path = Path.Combine (keys_path, key_file_name);
@ -325,7 +217,7 @@ namespace SparkleShare {
}
string pubkey_file_path = key_file_path + ".pub";
string link_code_file_path = Path.Combine (SparklePath, CurrentUser.Name + "'s link code.txt");
string link_code_file_path = Path.Combine (FoldersPath, CurrentUser.Name + "'s link code.txt");
// Create an easily accessible copy of the public
// key in the user's SparkleShare folder
@ -340,7 +232,7 @@ namespace SparkleShare {
FileSystemWatcher watcher = new FileSystemWatcher () {
Filter = "*",
IncludeSubdirectories = false,
Path = SparkleConfig.DefaultConfig.FoldersPath
Path = FoldersPath
};
watcher.Deleted += OnFolderActivity;
@ -360,234 +252,13 @@ namespace SparkleShare {
}
public void ShowSetupWindow (PageType page_type)
private void PopulateRepositories ()
{
if (ShowSetupWindowEvent != null)
ShowSetupWindowEvent (page_type);
}
CheckRepositories ();
RepositoriesLoaded = true;
public void ShowAboutWindow ()
{
if (ShowAboutWindowEvent != null)
ShowAboutWindowEvent ();
}
public void ShowEventLogWindow ()
{
if (ShowEventLogWindowEvent != null)
ShowEventLogWindowEvent ();
}
public List<SparkleChangeSet> GetLog ()
{
List<SparkleChangeSet> list = new List<SparkleChangeSet> ();
foreach (SparkleRepoBase repo in Repositories) {
List<SparkleChangeSet> change_sets = repo.ChangeSets;
if (change_sets != null)
list.AddRange (change_sets);
else
SparkleHelpers.DebugInfo ("Log", "Could not create log for " + repo.Name);
}
list.Sort ((x, y) => (x.Timestamp.CompareTo (y.Timestamp)));
list.Reverse ();
if (list.Count > 100)
return list.GetRange (0, 100);
else
return list.GetRange (0, list.Count);
}
public List<SparkleChangeSet> GetLog (string name)
{
if (name == null)
return GetLog ();
foreach (SparkleRepoBase repo in Repositories) {
if (repo.Name.Equals (name))
return repo.ChangeSets;
}
return null;
}
public abstract string EventLogHTML { get; }
public abstract string DayEntryHTML { get; }
public abstract string EventEntryHTML { get; }
public string GetHTMLLog (List<SparkleChangeSet> change_sets)
{
List <ActivityDay> activity_days = new List <ActivityDay> ();
change_sets.Sort ((x, y) => (x.Timestamp.CompareTo (y.Timestamp)));
change_sets.Reverse ();
if (change_sets.Count == 0)
return null;
foreach (SparkleChangeSet change_set in change_sets) {
bool change_set_inserted = false;
foreach (ActivityDay stored_activity_day in activity_days) {
if (stored_activity_day.Date.Year == change_set.Timestamp.Year &&
stored_activity_day.Date.Month == change_set.Timestamp.Month &&
stored_activity_day.Date.Day == change_set.Timestamp.Day) {
stored_activity_day.Add (change_set);
change_set_inserted = true;
break;
}
}
if (!change_set_inserted) {
ActivityDay activity_day = new ActivityDay (change_set.Timestamp);
activity_day.Add (change_set);
activity_days.Add (activity_day);
}
}
string event_log_html = EventLogHTML;
string day_entry_html = DayEntryHTML;
string event_entry_html = EventEntryHTML;
string event_log = "";
foreach (ActivityDay activity_day in activity_days) {
string event_entries = "";
foreach (SparkleChangeSet change_set in activity_day) {
string event_entry = "<dl>";
foreach (SparkleChange change in change_set.Changes) {
if (change.Type != SparkleChangeType.Moved) {
event_entry += "<dd class='document " + change.Type.ToString ().ToLower () + "'>";
event_entry += "<small>" + change.Timestamp.ToString ("HH:mm") +"</small> &nbsp;";
event_entry += FormatBreadCrumbs (change_set.Folder.FullPath, change.Path);
event_entry += "</dd>";
} else {
event_entry += "<dd class='document moved'>";
event_entry += FormatBreadCrumbs (change_set.Folder.FullPath, change.Path);
event_entry += "<br>";
event_entry += "<small>" + change.Timestamp.ToString ("HH:mm") +"</small> &nbsp;";
event_entry += FormatBreadCrumbs (change_set.Folder.FullPath, change.MovedToPath);
event_entry += "</dd>";
}
}
string change_set_avatar = GetAvatar (change_set.User.Email, 48);
if (change_set_avatar != null) {
change_set_avatar = "file://" + change_set_avatar.Replace ("\\", "/");
} else {
change_set_avatar = "file://<!-- $pixmaps-path -->/" +
AssignAvatar (change_set.User.Email);
}
event_entry += "</dl>";
string timestamp = change_set.Timestamp.ToString ("H:mm");
if (!change_set.FirstTimestamp.Equals (new DateTime ()) &&
!change_set.Timestamp.ToString ("H:mm").Equals (change_set.FirstTimestamp.ToString ("H:mm")))
timestamp = change_set.FirstTimestamp.ToString ("H:mm") + " " + timestamp;
event_entries += event_entry_html.Replace ("<!-- $event-entry-content -->", event_entry)
.Replace ("<!-- $event-user-name -->", change_set.User.Name)
.Replace ("<!-- $event-avatar-url -->", change_set_avatar)
.Replace ("<!-- $event-folder -->", change_set.Folder.Name)
.Replace ("<!-- $event-url -->", change_set.RemoteUrl.ToString ())
.Replace ("<!-- $event-revision -->", change_set.Revision);
}
string day_entry = "";
DateTime today = DateTime.Now;
DateTime yesterday = DateTime.Now.AddDays (-1);
if (today.Day == activity_day.Date.Day &&
today.Month == activity_day.Date.Month &&
today.Year == activity_day.Date.Year) {
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
"<span id='today' name='" + activity_day.Date.ToString (_("dddd, MMMM d")) + "'>"
+ _("Today") + "</span>");
} else if (yesterday.Day == activity_day.Date.Day &&
yesterday.Month == activity_day.Date.Month &&
yesterday.Year == activity_day.Date.Year) {
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
"<span id='yesterday' name='" + activity_day.Date.ToString (_("dddd, MMMM d")) + "'>"
+ _("Yesterday") + "</span>");
} else {
if (activity_day.Date.Year != DateTime.Now.Year) {
// TRANSLATORS: This is the date in the event logs
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
activity_day.Date.ToString (_("dddd, MMMM d, yyyy")));
} else {
// TRANSLATORS: This is the date in the event logs, without the year
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
activity_day.Date.ToString (_("dddd, MMMM d")));
}
}
event_log += day_entry.Replace ("<!-- $day-entry-content -->", event_entries);
}
int midnight = (int) (DateTime.Today.AddDays (1) - new DateTime (1970, 1, 1)).TotalSeconds;
string html = event_log_html.Replace ("<!-- $event-log-content -->", event_log)
.Replace ("<!-- $midnight -->", midnight.ToString ());
return html;
}
// Fires events for the current syncing state
public void UpdateState ()
{
bool has_syncing_repos = false;
bool has_unsynced_repos = false;
foreach (SparkleRepoBase repo in Repositories) {
if (repo.Status == SyncStatus.SyncDown ||
repo.Status == SyncStatus.SyncUp ||
repo.IsBuffering) {
has_syncing_repos = true;
} else if (repo.HasUnsyncedChanges) {
has_unsynced_repos = true;
}
}
if (has_syncing_repos) {
if (OnSyncing != null)
OnSyncing ();
} else if (has_unsynced_repos) {
if (OnError != null)
OnError ();
} else {
if (OnIdle != null)
OnIdle ();
}
if (FolderListChanged != null)
FolderListChanged ();
}
@ -595,12 +266,12 @@ namespace SparkleShare {
{
SparkleRepoBase repo = null;
string folder_name = Path.GetFileName (folder_path);
string backend = SparkleConfig.DefaultConfig.GetBackendForFolder (folder_name);
string backend = this.config.GetBackendForFolder (folder_name);
try {
repo = (SparkleRepoBase) Activator.CreateInstance (
Type.GetType ("SparkleLib." + backend + ".SparkleRepo, SparkleLib." + backend),
new object [] {folder_path, SparkleConfig.DefaultConfig}
new object [] {folder_path, this.config}
);
} catch {
@ -668,54 +339,148 @@ namespace SparkleShare {
}
private void PopulateRepositories ()
private void CheckRepositories ()
{
CheckRepositories ();
RepositoriesLoaded = true;
lock (this.check_repos_lock) {
string path = this.config.FoldersPath;
if (FolderListChanged != null)
FolderListChanged ();
foreach (string folder_path in Directory.GetDirectories (path)) {
string folder_name = Path.GetFileName (folder_path);
if (folder_name.Equals (".tmp"))
continue;
if (this.config.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 (this.config.IdentifierExists (identifier)) {
RemoveRepository (folder_path);
this.config.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 this.config.Folders) {
string folder_path = new SparkleFolder (folder_name).FullPath;
if (!Directory.Exists (folder_path)) {
this.config.RemoveFolder (folder_name);
RemoveRepository (folder_path);
SparkleHelpers.DebugInfo ("Controller",
"Removed folder '" + folder_name + "' from config");
} else {
AddRepository (folder_path);
}
}
if (FolderListChanged != null)
FolderListChanged ();
}
}
public void ToggleNotifications () {
bool notifications_enabled =
SparkleConfig.DefaultConfig.GetConfigOption ("notifications")
.Equals (bool.TrueString);
// Fires events for the current syncing state
private void UpdateState ()
{
bool has_syncing_repos = false;
bool has_unsynced_repos = false;
if (notifications_enabled)
SparkleConfig.DefaultConfig.SetConfigOption ("notifications", bool.FalseString);
else
SparkleConfig.DefaultConfig.SetConfigOption ("notifications", bool.TrueString);
foreach (SparkleRepoBase repo in Repositories) {
if (repo.Status == SyncStatus.SyncDown ||
repo.Status == SyncStatus.SyncUp ||
repo.IsBuffering) {
has_syncing_repos = true;
} else if (repo.HasUnsyncedChanges) {
has_unsynced_repos = true;
}
}
if (has_syncing_repos) {
if (OnSyncing != null)
OnSyncing ();
} else if (has_unsynced_repos) {
if (OnError != null)
OnError ();
} else {
if (OnIdle != null)
OnIdle ();
}
}
// Format a file size nicely with small caps.
// Example: 1048576 becomes "1 ᴍʙ"
public string FormatSize (double byte_count)
public void OnFolderActivity (object o, FileSystemEventArgs args)
{
if (byte_count >= 1099511627776)
return String.Format ("{0:##.##} ᴛʙ", Math.Round (byte_count / 1099511627776, 1));
else if (byte_count >= 1073741824)
return String.Format ("{0:##.##} ɢʙ", Math.Round (byte_count / 1073741824, 1));
else if (byte_count >= 1048576)
return String.Format ("{0:##.##} ᴍʙ", Math.Round (byte_count / 1048576, 0));
else if (byte_count >= 1024)
return String.Format ("{0:##.##} ᴋʙ", Math.Round (byte_count / 1024, 0));
else
return byte_count.ToString () + " bytes";
if (args != null &&
args.ChangeType == WatcherChangeTypes.Created &&
args.FullPath.EndsWith (".xml")) {
HandleInvite (args);
return;
} else {
if (Directory.Exists (args.FullPath) &&
args.ChangeType == WatcherChangeTypes.Created) {
return;
}
CheckRepositories ();
}
}
public void OpenSparkleShareFolder ()
public void HandleInvite (FileSystemEventArgs args)
{
OpenFolder (SparkleConfig.DefaultConfig.FoldersPath);
}
if (this.fetcher != null &&
this.fetcher.IsActive) {
if (AlertNotificationRaised != null)
AlertNotificationRaised ("SparkleShare Setup seems busy",
"Please wait for it to finish");
public void OpenSparkleShareFolder (string name)
{
OpenFolder (new SparkleFolder (name).FullPath);
} 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);
}
}
}
@ -725,7 +490,7 @@ namespace SparkleShare {
if (announcements_url != null)
announcements_url = announcements_url.Trim ();
string tmp_path = SparkleConfig.DefaultConfig.TmpPath;
string tmp_path = this.config.TmpPath;
if (!Directory.Exists (tmp_path)) {
Directory.CreateDirectory (tmp_path);
@ -824,7 +589,7 @@ namespace SparkleShare {
string canonical_name = Path.GetFileNameWithoutExtension (this.fetcher.RemoteUrl.AbsolutePath);
bool target_folder_exists = Directory.Exists (
Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, canonical_name));
Path.Combine (this.config.FoldersPath, canonical_name));
// Add a numbered suffix to the name if a folder with the same name
// already exists. Example: "Folder (2)"
@ -833,7 +598,7 @@ namespace SparkleShare {
suffix++;
target_folder_exists = Directory.Exists (
Path.Combine (
SparkleConfig.DefaultConfig.FoldersPath,
this.config.FoldersPath,
canonical_name + " (" + suffix + ")"
)
);
@ -844,14 +609,14 @@ namespace SparkleShare {
if (suffix > 1)
target_folder_name += " (" + suffix + ")";
string target_folder_path = Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, target_folder_name);
string target_folder_path = Path.Combine (this.config.FoldersPath, target_folder_name);
try {
SparkleHelpers.ClearAttributes (this.fetcher.TargetFolder);
Directory.Move (this.fetcher.TargetFolder, target_folder_path);
string backend = SparkleFetcherBase.GetBackend (this.fetcher.RemoteUrl.AbsolutePath);
SparkleConfig.DefaultConfig.AddFolder (target_folder_name, this.fetcher.Identifier,
this.config.AddFolder (target_folder_name, this.fetcher.Identifier,
this.fetcher.RemoteUrl.ToString (), backend);
if (FolderFetched != null)
@ -859,7 +624,7 @@ namespace SparkleShare {
/* TODO
if (!string.IsNullOrEmpty (announcements_url)) {
SparkleConfig.DefaultConfig.SetFolderOptionalAttribute (
this.config.SetFolderOptionalAttribute (
target_folder_name, "announcements_url", announcements_url);
*/
@ -883,9 +648,52 @@ namespace SparkleShare {
}
public void ShowSetupWindow (PageType page_type)
{
if (ShowSetupWindowEvent != null)
ShowSetupWindowEvent (page_type);
}
public void ShowAboutWindow ()
{
if (ShowAboutWindowEvent != null)
ShowAboutWindowEvent ();
}
public void ShowEventLogWindow ()
{
if (ShowEventLogWindowEvent != null)
ShowEventLogWindowEvent ();
}
public void OpenSparkleShareFolder ()
{
OpenFolder (this.config.FoldersPath);
}
public void OpenSparkleShareFolder (string name)
{
OpenFolder (new SparkleFolder (name).FullPath);
}
public void ToggleNotifications () {
bool notifications_enabled = this.config.GetConfigOption ("notifications").Equals (bool.TrueString);
if (notifications_enabled)
this.config.SetConfigOption ("notifications", bool.FalseString);
else
this.config.SetConfigOption ("notifications", bool.TrueString);
}
public string GetAvatar (string email, int size)
{
string fetch_gravatars_option = SparkleConfig.DefaultConfig.GetConfigOption ("fetch_gravatars");
string fetch_gravatars_option = this.config.GetConfigOption ("fetch_gravatars");
if (fetch_gravatars_option != null &&
fetch_gravatars_option.Equals (bool.FalseString)) {
@ -895,7 +703,7 @@ namespace SparkleShare {
email = email.ToLower ();
string avatars_path = new string [] { Path.GetDirectoryName (SparkleConfig.DefaultConfig.FullPath),
string avatars_path = new string [] { Path.GetDirectoryName (this.config.FullPath),
"icons", size + "x" + size, "status" }.Combine ();
string avatar_file_path = Path.Combine (avatars_path, "avatar-" + email);
@ -908,7 +716,7 @@ namespace SparkleShare {
}
WebClient client = new WebClient ();
string url = "http://gravatar.com/avatar/" + GetMD5 (email) + ".jpg?s=" + size + "&d=404";
string url = "http://gravatar.com/avatar/" + SparkleHelpers.MD5 (email) + ".jpg?s=" + size + "&d=404";
try {
byte [] buffer = client.DownloadData (url);
@ -934,18 +742,9 @@ namespace SparkleShare {
}
public virtual void Quit ()
public string AssignAvatar (string s)
{
foreach (SparkleRepoBase repo in Repositories)
repo.Dispose ();
Environment.Exit (0);
}
private string AssignAvatar (string s)
{
string hash = "0" + GetMD5 (s).Substring (0, 8);
string hash = "0" + SparkleHelpers.MD5 (s).Substring (0, 8);
string numbers = Regex.Replace (hash, "[a-z]", "");
int number = int.Parse (numbers);
string letters = "abcdefghijklmnopqrstuvwxyz";
@ -954,67 +753,29 @@ namespace SparkleShare {
}
// Creates an MD5 hash of input
private string GetMD5 (string s)
// Format a file size nicely with small caps.
// Example: 1048576 becomes "1 ᴍʙ"
public string FormatSize (double byte_count)
{
MD5 md5 = new MD5CryptoServiceProvider ();
Byte[] bytes = ASCIIEncoding.Default.GetBytes (s);
Byte[] encoded_bytes = md5.ComputeHash (bytes);
return BitConverter.ToString (encoded_bytes).ToLower ().Replace ("-", "");
if (byte_count >= 1099511627776)
return String.Format ("{0:##.##} ᴛʙ", Math.Round (byte_count / 1099511627776, 1));
else if (byte_count >= 1073741824)
return String.Format ("{0:##.##} ɢʙ", Math.Round (byte_count / 1073741824, 1));
else if (byte_count >= 1048576)
return String.Format ("{0:##.##} ᴍʙ", Math.Round (byte_count / 1048576, 0));
else if (byte_count >= 1024)
return String.Format ("{0:##.##} ᴋʙ", Math.Round (byte_count / 1024, 0));
else
return byte_count.ToString () + " bytes";
}
private string FormatBreadCrumbs (string path_root, string path)
public virtual void Quit ()
{
path_root = path_root.Replace ("/", Path.DirectorySeparatorChar.ToString ());
path = path.Replace ("/", Path.DirectorySeparatorChar.ToString ());
string link = "";
string [] crumbs = path.Split (Path.DirectorySeparatorChar);
foreach (SparkleRepoBase repo in Repositories)
repo.Dispose ();
int i = 0;
string new_path_root = path_root;
bool previous_was_folder = false;
foreach (string crumb in crumbs) {
if (string.IsNullOrEmpty (crumb))
continue;
string crumb_path = Path.Combine (new_path_root, crumb);
if (Directory.Exists (crumb_path)) {
link += "<a href='" + crumb_path + "'>" + crumb + Path.DirectorySeparatorChar + "</a>";
previous_was_folder = true;
} else if (File.Exists (crumb_path)) {
link += "<a href='" + crumb_path + "'>" + crumb + "</a>";
previous_was_folder = false;
} else {
if (i > 0 && !previous_was_folder)
link += Path.DirectorySeparatorChar;
link += crumb;
previous_was_folder = false;
}
new_path_root = Path.Combine (new_path_root, crumb);
i++;
}
return link;
}
// All change sets that happened on a day
private class ActivityDay : List<SparkleChangeSet>
{
public DateTime Date;
public ActivityDay (DateTime date_time)
{
Date = new DateTime (date_time.Year, date_time.Month, date_time.Day);
}
Environment.Exit (0);
}
}
}

View file

@ -90,9 +90,9 @@ namespace SparkleShare {
public string HTML {
get {
List<SparkleChangeSet> change_sets = Program.Controller.GetLog (this.selected_folder);
List<SparkleChangeSet> change_sets = GetLog (this.selected_folder);
string html = Program.Controller.GetHTMLLog (change_sets);
string html = GetHTMLLog (change_sets);
if (UpdateSizeInfoEvent != null)
UpdateSizeInfoEvent (Size, HistorySize);
@ -214,5 +214,232 @@ namespace SparkleShare {
Program.Controller.OpenFile (url);
}
}
private List<SparkleChangeSet> GetLog ()
{
List<SparkleChangeSet> list = new List<SparkleChangeSet> ();
foreach (SparkleRepoBase repo in Program.Controller.Repositories) {
List<SparkleChangeSet> change_sets = repo.ChangeSets;
if (change_sets != null)
list.AddRange (change_sets);
else
SparkleHelpers.DebugInfo ("Log", "Could not create log for " + repo.Name);
}
list.Sort ((x, y) => (x.Timestamp.CompareTo (y.Timestamp)));
list.Reverse ();
if (list.Count > 100)
return list.GetRange (0, 100);
else
return list.GetRange (0, list.Count);
}
private List<SparkleChangeSet> GetLog (string name)
{
if (name == null)
return GetLog ();
foreach (SparkleRepoBase repo in Program.Controller.Repositories) {
if (repo.Name.Equals (name))
return repo.ChangeSets;
}
return null;
}
public string GetHTMLLog (List<SparkleChangeSet> change_sets)
{
List <ActivityDay> activity_days = new List <ActivityDay> ();
change_sets.Sort ((x, y) => (x.Timestamp.CompareTo (y.Timestamp)));
change_sets.Reverse ();
if (change_sets.Count == 0)
return null;
foreach (SparkleChangeSet change_set in change_sets) {
bool change_set_inserted = false;
foreach (ActivityDay stored_activity_day in activity_days) {
if (stored_activity_day.Date.Year == change_set.Timestamp.Year &&
stored_activity_day.Date.Month == change_set.Timestamp.Month &&
stored_activity_day.Date.Day == change_set.Timestamp.Day) {
stored_activity_day.Add (change_set);
change_set_inserted = true;
break;
}
}
if (!change_set_inserted) {
ActivityDay activity_day = new ActivityDay (change_set.Timestamp);
activity_day.Add (change_set);
activity_days.Add (activity_day);
}
}
string event_log_html = Program.Controller.EventLogHTML;
string day_entry_html = Program.Controller.DayEntryHTML;
string event_entry_html = Program.Controller.EventEntryHTML;
string event_log = "";
foreach (ActivityDay activity_day in activity_days) {
string event_entries = "";
foreach (SparkleChangeSet change_set in activity_day) {
string event_entry = "<dl>";
foreach (SparkleChange change in change_set.Changes) {
if (change.Type != SparkleChangeType.Moved) {
event_entry += "<dd class='document " + change.Type.ToString ().ToLower () + "'>";
event_entry += "<small>" + change.Timestamp.ToString ("HH:mm") +"</small> &nbsp;";
event_entry += FormatBreadCrumbs (change_set.Folder.FullPath, change.Path);
event_entry += "</dd>";
} else {
event_entry += "<dd class='document moved'>";
event_entry += FormatBreadCrumbs (change_set.Folder.FullPath, change.Path);
event_entry += "<br>";
event_entry += "<small>" + change.Timestamp.ToString ("HH:mm") +"</small> &nbsp;";
event_entry += FormatBreadCrumbs (change_set.Folder.FullPath, change.MovedToPath);
event_entry += "</dd>";
}
}
string change_set_avatar = Program.Controller.GetAvatar (change_set.User.Email, 48);
if (change_set_avatar != null) {
change_set_avatar = "file://" + change_set_avatar.Replace ("\\", "/");
} else {
change_set_avatar = "file://<!-- $pixmaps-path -->/" +
Program.Controller.AssignAvatar (change_set.User.Email);
}
event_entry += "</dl>";
string timestamp = change_set.Timestamp.ToString ("H:mm");
if (!change_set.FirstTimestamp.Equals (new DateTime ()) &&
!change_set.Timestamp.ToString ("H:mm").Equals (change_set.FirstTimestamp.ToString ("H:mm")))
timestamp = change_set.FirstTimestamp.ToString ("H:mm") + " " + timestamp;
event_entries += event_entry_html.Replace ("<!-- $event-entry-content -->", event_entry)
.Replace ("<!-- $event-user-name -->", change_set.User.Name)
.Replace ("<!-- $event-avatar-url -->", change_set_avatar)
.Replace ("<!-- $event-folder -->", change_set.Folder.Name)
.Replace ("<!-- $event-url -->", change_set.RemoteUrl.ToString ())
.Replace ("<!-- $event-revision -->", change_set.Revision);
}
string day_entry = "";
DateTime today = DateTime.Now;
DateTime yesterday = DateTime.Now.AddDays (-1);
if (today.Day == activity_day.Date.Day &&
today.Month == activity_day.Date.Month &&
today.Year == activity_day.Date.Year) {
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
"<span id='today' name='" + activity_day.Date.ToString ("dddd, MMMM d") + "'>"
+ "Today" + "</span>");
} else if (yesterday.Day == activity_day.Date.Day &&
yesterday.Month == activity_day.Date.Month &&
yesterday.Year == activity_day.Date.Year) {
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
"<span id='yesterday' name='" + activity_day.Date.ToString ("dddd, MMMM d") + "'>"
+ "Yesterday" + "</span>");
} else {
if (activity_day.Date.Year != DateTime.Now.Year) {
// TRANSLATORS: This is the date in the event logs
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
activity_day.Date.ToString ("dddd, MMMM d, yyyy"));
} else {
// TRANSLATORS: This is the date in the event logs, without the year
day_entry = day_entry_html.Replace ("<!-- $day-entry-header -->",
activity_day.Date.ToString ("dddd, MMMM d"));
}
}
event_log += day_entry.Replace ("<!-- $day-entry-content -->", event_entries);
}
int midnight = (int) (DateTime.Today.AddDays (1) - new DateTime (1970, 1, 1)).TotalSeconds;
string html = event_log_html.Replace ("<!-- $event-log-content -->", event_log)
.Replace ("<!-- $midnight -->", midnight.ToString ());
return html;
}
private string FormatBreadCrumbs (string path_root, string path)
{
path_root = path_root.Replace ("/", Path.DirectorySeparatorChar.ToString ());
path = path.Replace ("/", Path.DirectorySeparatorChar.ToString ());
string link = "";
string [] crumbs = path.Split (Path.DirectorySeparatorChar);
int i = 0;
string new_path_root = path_root;
bool previous_was_folder = false;
foreach (string crumb in crumbs) {
if (string.IsNullOrEmpty (crumb))
continue;
string crumb_path = Path.Combine (new_path_root, crumb);
if (Directory.Exists (crumb_path)) {
link += "<a href='" + crumb_path + "'>" + crumb + Path.DirectorySeparatorChar + "</a>";
previous_was_folder = true;
} else if (File.Exists (crumb_path)) {
link += "<a href='" + crumb_path + "'>" + crumb + "</a>";
previous_was_folder = false;
} else {
if (i > 0 && !previous_was_folder)
link += Path.DirectorySeparatorChar;
link += crumb;
previous_was_folder = false;
}
new_path_root = Path.Combine (new_path_root, crumb);
i++;
}
return link;
}
// All change sets that happened on a day
private class ActivityDay : List<SparkleChangeSet>
{
public DateTime Date;
public ActivityDay (DateTime date_time)
{
Date = new DateTime (date_time.Year, date_time.Month, date_time.Day);
}
}
}
}

View file

@ -289,7 +289,7 @@ namespace SparkleShare {
string private_key_file_path = SparkleKeys.GenerateKeyPair (keys_path, key_file_name);
SparkleKeys.ImportPrivateKey (private_key_file_path);
string link_code_file_path = Path.Combine (Program.Controller.SparklePath,
string link_code_file_path = Path.Combine (Program.Controller.FoldersPath,
Program.Controller.CurrentUser.Name + "'s link code.txt");
// Create an easily accessible copy of the public
@ -633,7 +633,7 @@ namespace SparkleShare {
if (HideWindowEvent != null)
HideWindowEvent ();
Program.Controller.UpdateState ();
//Program.Controller.UpdateState (); TODO: still relevant?
}