From 3675d2a4492aee6e325dc7f6a720ebba7f972c9b Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sun, 30 Jun 2013 16:54:04 +0100 Subject: [PATCH] controller: Move avatar logic to its own class --- SparkleLib/SparkleUser.cs | 2 + SparkleLib/SparkleWrappers.cs | 8 +- SparkleShare/Linux/Makefile.am | 1 + SparkleShare/Mac/SparkleAvatars.cs | 111 +++++++++++++ SparkleShare/Mac/SparkleBubbles.cs | 2 +- SparkleShare/Mac/SparkleShare.csproj | 1 + SparkleShare/SparkleAboutController.cs | 2 +- SparkleShare/SparkleBubblesController.cs | 3 +- SparkleShare/SparkleControllerBase.cs | 185 +++++++--------------- SparkleShare/SparkleEventLogController.cs | 24 +-- SparkleShare/Windows/SparkleShare.csproj | 3 +- 11 files changed, 192 insertions(+), 150 deletions(-) create mode 100644 SparkleShare/Mac/SparkleAvatars.cs diff --git a/SparkleLib/SparkleUser.cs b/SparkleLib/SparkleUser.cs index f15234a4..bdfedb51 100644 --- a/SparkleLib/SparkleUser.cs +++ b/SparkleLib/SparkleUser.cs @@ -24,6 +24,8 @@ namespace SparkleLib { public readonly string Name; public readonly string Email; + public string AvatarFilePath; + public string PrivateKey; public string PrivateKeyFilePath; diff --git a/SparkleLib/SparkleWrappers.cs b/SparkleLib/SparkleWrappers.cs index f97ec46c..95ad180a 100644 --- a/SparkleLib/SparkleWrappers.cs +++ b/SparkleLib/SparkleWrappers.cs @@ -43,12 +43,12 @@ namespace SparkleLib { public string ToMessage () { - string message = "added '{0}'"; + string message = "added: {0}"; switch (Changes [0].Type) { - case SparkleChangeType.Edited: message = "edited '{0}'"; break; - case SparkleChangeType.Deleted: message = "deleted '{0}'"; break; - case SparkleChangeType.Moved: message = "moved '{0}'"; break; + case SparkleChangeType.Edited: message = "edited: {0}"; break; + case SparkleChangeType.Deleted: message = "deleted: {0}"; break; + case SparkleChangeType.Moved: message = "moved: {0}"; break; } if (Changes.Count > 0) diff --git a/SparkleShare/Linux/Makefile.am b/SparkleShare/Linux/Makefile.am index 9e8f5e55..8938e39d 100644 --- a/SparkleShare/Linux/Makefile.am +++ b/SparkleShare/Linux/Makefile.am @@ -22,6 +22,7 @@ SOURCES = \ ../SparkleSetupController.cs \ ../SparkleStatusIconController.cs \ SparkleAbout.cs \ + SparkleAvatars.cs \ SparkleBubbles.cs \ SparkleController.cs \ SparkleEventLog.cs \ diff --git a/SparkleShare/Mac/SparkleAvatars.cs b/SparkleShare/Mac/SparkleAvatars.cs new file mode 100644 index 00000000..3d3f9d2a --- /dev/null +++ b/SparkleShare/Mac/SparkleAvatars.cs @@ -0,0 +1,111 @@ +// SparkleShare, a collaboration and sharing tool. +// Copyright (C) 2010 Hylke Bons +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +using System; +using System.IO; +using System.Collections.Generic; +using System.Net; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; + +using SparkleLib; + +namespace SparkleShare +{ + public static class SparkleAvatars + { + private static List skipped_avatars = new List (); + + + public static string GetAvatar (string email, int size, string target_path) + { + ServicePointManager.ServerCertificateValidationCallback = GetAvatarValidationCallBack; + email = email.ToLower (); + + if (skipped_avatars.Contains (email)) + return null; + + string avatars_path = new string [] { Path.GetDirectoryName (target_path), + "avatars", size + "x" + size }.Combine (); + + string avatar_file_path; + + try { + avatar_file_path = Path.Combine (avatars_path, email.MD5 () + ".png"); + + } catch (InvalidOperationException e) { + SparkleLogger.LogInfo ("Avatars", "Error fetching avatar for " + email, e); + return null; + } + + if (File.Exists (avatar_file_path)) { + if (new FileInfo (avatar_file_path).CreationTime < DateTime.Now.AddDays (-1)) + File.Delete (avatar_file_path); + else + return avatar_file_path; + } + + WebClient client = new WebClient (); + string url = "https://gravatar.com/avatar/" + email.MD5 () + ".png?s=" + size + "&d=404"; + + try { + byte [] buffer = client.DownloadData (url); + + if (buffer.Length > 255) { + if (!Directory.Exists (avatars_path)) { + Directory.CreateDirectory (avatars_path); + SparkleLogger.LogInfo ("Avatars", "Created '" + avatars_path + "'"); + } + + File.WriteAllBytes (avatar_file_path, buffer); + SparkleLogger.LogInfo ("Avatars", "Fetched " + size + "x" + size + " avatar for " + email); + + return avatar_file_path; + + } else { + return null; + } + + } catch (Exception e) { + SparkleLogger.LogInfo ("Avatars", "Error fetching avatar for " + email, e); + skipped_avatars.Add (email); + + return null; + } + } + + + private static bool GetAvatarValidationCallBack (Object sender, + X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) + { + X509Certificate2 certificate2 = new X509Certificate2 (certificate.GetRawCertData ()); + + // On some systems (mostly Linux) we can't assume the needed certificates are + // available, so we have to check the certificate's SHA-1 fingerprint manually. + // + // Obtained from https://www.gravatar.com/ on Aug 18 2012 and expires on Oct 24 2015. + string gravatar_cert_fingerprint = "217ACB08C0A1ACC23A21B6ECDE82CD45E14DEC19"; + + if (!certificate2.Thumbprint.Equals (gravatar_cert_fingerprint)) { + SparkleLogger.LogInfo ("Avatars", "Invalid certificate for https://www.gravatar.com/"); + return false; + } + + return true; + } + } +} diff --git a/SparkleShare/Mac/SparkleBubbles.cs b/SparkleShare/Mac/SparkleBubbles.cs index 601fdaa1..958f261b 100755 --- a/SparkleShare/Mac/SparkleBubbles.cs +++ b/SparkleShare/Mac/SparkleBubbles.cs @@ -39,7 +39,7 @@ namespace SparkleShare { InformativeText = subtext, DeliveryDate = DateTime.Now }; - + NSUserNotificationCenter center = NSUserNotificationCenter.DefaultUserNotificationCenter; center.ShouldPresentNotification = delegate { return true; }; center.DidActivateNotification += delegate { Controller.BubbleClicked (); }; diff --git a/SparkleShare/Mac/SparkleShare.csproj b/SparkleShare/Mac/SparkleShare.csproj index ed607078..07b8eb9f 100644 --- a/SparkleShare/Mac/SparkleShare.csproj +++ b/SparkleShare/Mac/SparkleShare.csproj @@ -99,6 +99,7 @@ SparkleKeys.cs + diff --git a/SparkleShare/SparkleAboutController.cs b/SparkleShare/SparkleAboutController.cs index 05881b86..48d2e74f 100755 --- a/SparkleShare/SparkleAboutController.cs +++ b/SparkleShare/SparkleAboutController.cs @@ -32,7 +32,7 @@ namespace SparkleShare { public readonly string WebsiteLinkAddress = "http://www.sparkleshare.org/"; public readonly string CreditsLinkAddress = "http://www.github.com/hbons/SparkleShare/tree/master/legal/AUTHORS"; public readonly string ReportProblemLinkAddress = "http://www.github.com/hbons/SparkleShare/issues"; - public readonly string DebugLogLinkAddress = "file://" + Program.Controller.ConfigPath; + public readonly string DebugLogLinkAddress = "file://" + Program.Controller.Config.LogFilePath; public string RunningVersion; diff --git a/SparkleShare/SparkleBubblesController.cs b/SparkleShare/SparkleBubblesController.cs index fce7f76b..b3eca179 100755 --- a/SparkleShare/SparkleBubblesController.cs +++ b/SparkleShare/SparkleBubblesController.cs @@ -35,8 +35,7 @@ namespace SparkleShare { }; Program.Controller.NotificationRaised += delegate (SparkleChangeSet change_set) { - ShowBubble (change_set.User.Name, change_set.ToMessage (), - Program.Controller.GetAvatar (change_set.User.Email, 48)); + ShowBubble (change_set.User.Name, change_set.ToMessage (), change_set.User.AvatarFilePath); }; } diff --git a/SparkleShare/SparkleControllerBase.cs b/SparkleShare/SparkleControllerBase.cs index 1242f55d..8bc626c8 100644 --- a/SparkleShare/SparkleControllerBase.cs +++ b/SparkleShare/SparkleControllerBase.cs @@ -19,9 +19,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Net; -using System.Net.Security; -using System.Security.Cryptography.X509Certificates; using System.Threading; using SparkleLib; @@ -37,7 +34,9 @@ namespace SparkleShare { } } - public bool RepositoriesLoaded { get; private set;} + + public SparkleConfig Config { get; private set; } + public bool RepositoriesLoaded { get; private set; } public string FoldersPath { get; private set; } public double ProgressPercentage = 0.0; @@ -78,31 +77,27 @@ namespace SparkleShare { public bool FirstRun { - get { return this.config.User.Email.Equals ("Unknown"); } + get { return Config.User.Email.Equals ("Unknown"); } } public List Folders { get { - List folders = this.config.Folders; + List folders = Config.Folders; return folders; } } - public string ConfigPath { - get { return this.config.LogFilePath; } - } - public SparkleUser CurrentUser { - get { return this.config.User; } - set { this.config.User = value; } + get { return Config.User; } + set { Config.User = value; } } public bool NotificationsEnabled { get { - string notifications_enabled = this.config.GetConfigOption ("notifications"); + string notifications_enabled = Config.GetConfigOption ("notifications"); if (string.IsNullOrEmpty (notifications_enabled)) { - this.config.SetConfigOption ("notifications", bool.TrueString); + Config.SetConfigOption ("notifications", bool.TrueString); return true; } else { @@ -111,6 +106,17 @@ namespace SparkleShare { } } + public bool AvatarsEnabled { + get { + string fetch_avatars_option = Config.GetConfigOption ("fetch_avatars"); + + if (fetch_avatars_option != null && fetch_avatars_option.Equals (bool.FalseString)) + return false; + + return true; + } + } + // Path where the plugins are kept public abstract string PluginsPath { get; } @@ -145,12 +151,10 @@ namespace SparkleShare { public abstract string EventEntryHTML { get; } - private SparkleConfig config; private SparkleFetcherBase fetcher; private FileSystemWatcher watcher; private Object repo_lock = new Object (); private Object check_repos_lock = new Object (); - private List skipped_avatars = new List (); private List repositories = new List (); private bool lost_folders_path = false; @@ -160,9 +164,9 @@ namespace SparkleShare { 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; + Config = new SparkleConfig (config_path, "config.xml"); + SparkleConfig.DefaultConfig = Config; + FoldersPath = Config.FoldersPath; } @@ -181,10 +185,10 @@ namespace SparkleShare { } if (FirstRun) { - this.config.SetConfigOption ("notifications", bool.TrueString); + Config.SetConfigOption ("notifications", bool.TrueString); } else { - string keys_path = Path.GetDirectoryName (this.config.FullPath); + string keys_path = Path.GetDirectoryName (Config.FullPath); string key_file_path = ""; foreach (string file_path in Directory.GetFiles (keys_path)) { @@ -281,7 +285,7 @@ namespace SparkleShare { public void OpenSparkleShareFolder () { - OpenFolder (this.config.FoldersPath); + OpenFolder (Config.FoldersPath); } @@ -293,15 +297,15 @@ namespace SparkleShare { public void ToggleNotifications () { - bool notifications_enabled = this.config.GetConfigOption ("notifications").Equals (bool.TrueString); - this.config.SetConfigOption ("notifications", (!notifications_enabled).ToString ()); + bool notifications_enabled = Config.GetConfigOption ("notifications").Equals (bool.TrueString); + Config.SetConfigOption ("notifications", (!notifications_enabled).ToString ()); } private void CheckRepositories () { lock (this.check_repos_lock) { - string path = this.config.FoldersPath; + string path = Config.FoldersPath; // Detect any renames foreach (string folder_path in Directory.GetDirectories (path)) { @@ -310,7 +314,7 @@ namespace SparkleShare { if (folder_name.Equals (".tmp")) continue; - if (this.config.GetIdentifierForFolder (folder_name) == null) { + if (Config.GetIdentifierForFolder (folder_name) == null) { string identifier_file_path = Path.Combine (folder_path, ".sparkleshare"); if (!File.Exists (identifier_file_path)) @@ -318,9 +322,9 @@ namespace SparkleShare { string identifier = File.ReadAllText (identifier_file_path).Trim (); - if (this.config.IdentifierExists (identifier)) { + if (Config.IdentifierExists (identifier)) { RemoveRepository (folder_path); - this.config.RenameFolder (identifier, folder_name); + Config.RenameFolder (identifier, folder_name); string new_folder_path = Path.Combine (path, folder_name); AddRepository (new_folder_path); @@ -332,11 +336,11 @@ namespace SparkleShare { } // Remove any deleted folders - foreach (string folder_name in this.config.Folders) { + foreach (string folder_name in Config.Folders) { string folder_path = new SparkleFolder (folder_name).FullPath; if (!Directory.Exists (folder_path)) { - this.config.RemoveFolder (folder_name); + Config.RemoveFolder (folder_name); RemoveRepository (folder_path); SparkleLogger.LogInfo ("Controller", "Removed folder '" + folder_name + "' from config"); @@ -348,9 +352,9 @@ namespace SparkleShare { // Remove any duplicate folders string previous_name = ""; - foreach (string folder_name in this.config.Folders) { + foreach (string folder_name in Config.Folders) { if (!string.IsNullOrEmpty (previous_name) && folder_name.Equals (previous_name)) - this.config.RemoveFolder (folder_name); + Config.RemoveFolder (folder_name); else previous_name = folder_name; } @@ -364,12 +368,12 @@ namespace SparkleShare { { SparkleRepoBase repo = null; string folder_name = Path.GetFileName (folder_path); - string backend = this.config.GetBackendForFolder (folder_name); + string backend = Config.GetBackendForFolder (folder_name); try { repo = (SparkleRepoBase) Activator.CreateInstance ( Type.GetType ("SparkleLib." + backend + ".SparkleRepo, SparkleLib." + backend), - new object [] { folder_path, this.config }); + new object [] { folder_path, Config }); } catch (Exception e) { SparkleLogger.LogInfo ("Controller", "Failed to load backend '" + backend + "' for '" + folder_name + "': ", e); @@ -418,6 +422,9 @@ namespace SparkleShare { }; repo.NewChangeSet += delegate (SparkleChangeSet change_set) { + if (AvatarsEnabled) + change_set.User.AvatarFilePath = SparkleAvatars.GetAvatar (change_set.User.Email, 48, Config.FullPath); + NotificationRaised (change_set); }; @@ -441,12 +448,6 @@ namespace SparkleShare { } } - private void StartupInviteScan () - { - foreach (string invite in Directory.GetFiles (FoldersPath, "*.xml")) { - HandleInvite (invite); - } - } private void OnFolderActivity (object o, FileSystemEventArgs args) { @@ -467,11 +468,20 @@ namespace SparkleShare { } + private void StartupInviteScan () + { + foreach (string invite in Directory.GetFiles (FoldersPath, "*.xml")) { + HandleInvite (invite); + } + } + + private void HandleInvite (FileSystemEventArgs args) { HandleInvite (args.FullPath); } + private void HandleInvite (string path) { if (this.fetcher != null && @@ -531,7 +541,7 @@ namespace SparkleShare { public void StartFetcher (SparkleFetcherInfo info) { - string tmp_path = this.config.TmpPath; + string tmp_path = Config.TmpPath; if (!Directory.Exists (tmp_path)) { Directory.CreateDirectory (tmp_path); @@ -623,7 +633,7 @@ namespace SparkleShare { canonical_name = canonical_name.Replace ("%20", " "); bool target_folder_exists = Directory.Exists ( - Path.Combine (this.config.FoldersPath, canonical_name)); + Path.Combine (Config.FoldersPath, canonical_name)); // Add a numbered suffix to the name if a folder with the same name // already exists. Example: "Folder (2)" @@ -631,7 +641,7 @@ namespace SparkleShare { while (target_folder_exists) { suffix++; target_folder_exists = Directory.Exists ( - Path.Combine (this.config.FoldersPath, canonical_name + " (" + suffix + ")")); + Path.Combine (Config.FoldersPath, canonical_name + " (" + suffix + ")")); } string target_folder_name = canonical_name; @@ -639,7 +649,7 @@ namespace SparkleShare { if (suffix > 1) target_folder_name += " (" + suffix + ")"; - string target_folder_path = Path.Combine (this.config.FoldersPath, target_folder_name); + string target_folder_path = Path.Combine (Config.FoldersPath, target_folder_name); try { Directory.Move (this.fetcher.TargetFolder, target_folder_path); @@ -663,11 +673,11 @@ namespace SparkleShare { string backend = SparkleFetcherBase.GetBackend (this.fetcher.RemoteUrl.ToString ()); - this.config.AddFolder (target_folder_name, this.fetcher.Identifier, + Config.AddFolder (target_folder_name, this.fetcher.Identifier, this.fetcher.RemoteUrl.ToString (), backend); if (this.fetcher.OriginalFetcherInfo.AnnouncementsUrl != null) { - this.config.SetFolderOptionalAttribute (target_folder_name, "announcements_url", + Config.SetFolderOptionalAttribute (target_folder_name, "announcements_url", this.fetcher.OriginalFetcherInfo.AnnouncementsUrl); } @@ -684,69 +694,6 @@ namespace SparkleShare { } - public string GetAvatar (string email, int size) - { - ServicePointManager.ServerCertificateValidationCallback = GetAvatarValidationCallBack; - string fetch_avatars_option = this.config.GetConfigOption ("fetch_avatars"); - - if (fetch_avatars_option != null && fetch_avatars_option.Equals (bool.FalseString)) - return null; - - email = email.ToLower (); - - if (this.skipped_avatars.Contains (email)) - return null; - - string avatars_path = new string [] { Path.GetDirectoryName (this.config.FullPath), - "avatars", size + "x" + size }.Combine (); - - string avatar_file_path; - - try { - avatar_file_path = Path.Combine (avatars_path, email.MD5 () + ".png"); - - } catch (InvalidOperationException e) { - SparkleLogger.LogInfo ("Controller", "Error fetching avatar for " + email, e); - return null; - } - - if (File.Exists (avatar_file_path)) { - if (new FileInfo (avatar_file_path).CreationTime < DateTime.Now.AddDays (-1)) - File.Delete (avatar_file_path); - else - return avatar_file_path; - } - - WebClient client = new WebClient (); - string url = "https://gravatar.com/avatar/" + email.MD5 () + ".png?s=" + size + "&d=404"; - - try { - byte [] buffer = client.DownloadData (url); - - if (buffer.Length > 255) { - if (!Directory.Exists (avatars_path)) { - Directory.CreateDirectory (avatars_path); - SparkleLogger.LogInfo ("Controller", "Created '" + avatars_path + "'"); - } - - File.WriteAllBytes (avatar_file_path, buffer); - SparkleLogger.LogInfo ("Controller", "Fetched " + size + "x" + size + " avatar for " + email); - - return avatar_file_path; - - } else { - return null; - } - - } catch (Exception e) { - SparkleLogger.LogInfo ("Controller", "Error fetching avatar for " + email, e); - skipped_avatars.Add (email); - - return null; - } - } - - public virtual void Quit () { foreach (SparkleRepoBase repo in Repositories) @@ -756,26 +703,6 @@ namespace SparkleShare { } - private bool GetAvatarValidationCallBack (Object sender, - X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) - { - X509Certificate2 certificate2 = new X509Certificate2 (certificate.GetRawCertData ()); - - // On some systems (mostly Linux) we can't assume the needed certificates are - // available, so we have to check the certificate's SHA-1 fingerprint manually. - // - // Obtained from https://www.gravatar.com/ on Aug 18 2012 and expires on Oct 24 2015. - string gravatar_cert_fingerprint = "217ACB08C0A1ACC23A21B6ECDE82CD45E14DEC19"; - - if (!certificate2.Thumbprint.Equals (gravatar_cert_fingerprint)) { - SparkleLogger.LogInfo ("Controller", "Invalid certificate for https://www.gravatar.com/"); - return false; - } - - return true; - } - - private void ClearDirectoryAttributes (string path) { if (!Directory.Exists (path)) diff --git a/SparkleShare/SparkleEventLogController.cs b/SparkleShare/SparkleEventLogController.cs index c669d5c6..3c9adb60 100755 --- a/SparkleShare/SparkleEventLogController.cs +++ b/SparkleShare/SparkleEventLogController.cs @@ -368,13 +368,13 @@ namespace SparkleShare { if (count == 1) continue; - - string change_set_avatar = Program.Controller.GetAvatar (change_set.User.Email, 24); - - if (change_set_avatar != null) + + string change_set_avatar = "file:///user-icon-default.png"; + + if (Program.Controller.AvatarsEnabled) { + change_set_avatar = SparkleAvatars.GetAvatar (change_set.User.Email, 24, Program.Controller.Config.FullPath); change_set_avatar = "file://" + change_set_avatar.Replace ("\\", "/"); - else - change_set_avatar = "file:///user-icon-default.png"; + } html += "" + "" + @@ -472,12 +472,12 @@ namespace SparkleShare { } } - 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:///user-icon-default.png"; + string change_set_avatar = "file:///user-icon-default.png"; + + if (Program.Controller.AvatarsEnabled) { + change_set_avatar = SparkleAvatars.GetAvatar (change_set.User.Email, 48, Program.Controller.Config.FullPath); + change_set_avatar = "file://" + change_set_avatar.Replace ("\\", "/"); + } event_entry += ""; diff --git a/SparkleShare/Windows/SparkleShare.csproj b/SparkleShare/Windows/SparkleShare.csproj index dca8b00c..15b97abf 100644 --- a/SparkleShare/Windows/SparkleShare.csproj +++ b/SparkleShare/Windows/SparkleShare.csproj @@ -79,6 +79,7 @@ + @@ -258,4 +259,4 @@ - \ No newline at end of file +