2010-05-06 00:17:00 +00:00
|
|
|
// SparkleShare, an instant update workflow to Git.
|
|
|
|
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
|
|
|
//
|
|
|
|
// 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
2010-05-10 13:42:46 +00:00
|
|
|
using Gtk;
|
2010-06-20 21:05:11 +00:00
|
|
|
using Mono.Unix;
|
2010-05-06 00:17:00 +00:00
|
|
|
using System;
|
|
|
|
using System.IO;
|
|
|
|
using System.Net;
|
|
|
|
using System.Security.Cryptography;
|
|
|
|
using System.Text;
|
2010-07-15 11:22:32 +00:00
|
|
|
|
2010-05-06 00:17:00 +00:00
|
|
|
|
2010-08-02 15:42:42 +00:00
|
|
|
namespace SparkleLib {
|
2010-05-06 00:17:00 +00:00
|
|
|
|
2010-06-15 23:24:48 +00:00
|
|
|
public static class SparkleHelpers
|
|
|
|
{
|
2010-06-04 19:45:42 +00:00
|
|
|
|
2010-07-13 18:23:59 +00:00
|
|
|
// Gets the avatar for a specific email address and size
|
2010-06-15 23:24:48 +00:00
|
|
|
public static Gdk.Pixbuf GetAvatar (string Email, int Size)
|
|
|
|
{
|
2010-05-06 00:17:00 +00:00
|
|
|
|
2010-07-13 18:23:59 +00:00
|
|
|
string AvatarPath = CombineMore (SparklePaths.SparkleLocalIconPath, Size + "x" + Size, "status");
|
2010-05-06 00:17:00 +00:00
|
|
|
|
|
|
|
if (!Directory.Exists (AvatarPath)) {
|
|
|
|
Directory.CreateDirectory (AvatarPath);
|
2010-06-15 23:24:48 +00:00
|
|
|
SparkleHelpers.DebugInfo ("Config", "Created '" + AvatarPath + "'");
|
2010-05-06 00:17:00 +00:00
|
|
|
}
|
2010-07-21 22:31:51 +00:00
|
|
|
|
2010-07-13 18:23:59 +00:00
|
|
|
string AvatarFilePath = CombineMore (AvatarPath, "avatar-" + Email);
|
2010-05-06 00:17:00 +00:00
|
|
|
|
2010-05-08 14:31:44 +00:00
|
|
|
if (File.Exists (AvatarFilePath))
|
2010-05-10 22:20:17 +00:00
|
|
|
return new Gdk.Pixbuf (AvatarFilePath);
|
2010-05-06 00:17:00 +00:00
|
|
|
else {
|
|
|
|
|
|
|
|
// Let's try to get the person's gravatar for next time
|
|
|
|
WebClient WebClient = new WebClient ();
|
2010-06-15 23:24:48 +00:00
|
|
|
Uri GravatarUri = new Uri ("http://www.gravatar.com/avatar/" + GetMD5 (Email) +
|
|
|
|
".jpg?s=" + Size + "&d=404");
|
2010-06-12 09:42:37 +00:00
|
|
|
|
2010-06-15 23:24:48 +00:00
|
|
|
string TmpFile = CombineMore (SparklePaths.SparkleTmpPath, Email + Size);
|
2010-05-06 00:17:00 +00:00
|
|
|
|
|
|
|
if (!File.Exists (TmpFile)) {
|
|
|
|
|
|
|
|
WebClient.DownloadFileAsync (GravatarUri, TmpFile);
|
|
|
|
WebClient.DownloadFileCompleted += delegate {
|
2010-06-12 09:42:37 +00:00
|
|
|
File.Delete (AvatarFilePath);
|
2010-05-06 00:17:00 +00:00
|
|
|
FileInfo TmpFileInfo = new FileInfo (TmpFile);
|
|
|
|
if (TmpFileInfo.Length > 255)
|
2010-06-12 09:42:37 +00:00
|
|
|
File.Move (TmpFile, AvatarFilePath);
|
2010-05-06 00:17:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-06-12 09:42:37 +00:00
|
|
|
// Fall back to a generic icon if there is no gravatar
|
|
|
|
if (File.Exists (AvatarFilePath))
|
|
|
|
return new Gdk.Pixbuf (AvatarFilePath);
|
2010-05-06 00:17:00 +00:00
|
|
|
else
|
2010-05-10 22:20:17 +00:00
|
|
|
return GetIcon ("avatar-default", Size);
|
2010-05-08 14:38:21 +00:00
|
|
|
|
2010-05-06 00:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-06-15 23:24:48 +00:00
|
|
|
|
|
|
|
// Creates an MD5 hash of input
|
|
|
|
public static string GetMD5 (string s)
|
|
|
|
{
|
2010-06-12 09:45:44 +00:00
|
|
|
MD5 md5 = new MD5CryptoServiceProvider ();
|
2010-07-13 18:23:59 +00:00
|
|
|
Byte[] bytes = ASCIIEncoding.Default.GetBytes (s);
|
|
|
|
Byte[] encodedBytes = md5.ComputeHash (bytes);
|
|
|
|
return BitConverter.ToString (encodedBytes).ToLower ().Replace ("-", "");
|
2010-05-06 00:17:00 +00:00
|
|
|
}
|
2010-05-08 14:31:44 +00:00
|
|
|
|
2010-05-08 14:38:21 +00:00
|
|
|
// Makes it possible to combine more than
|
2010-07-15 11:22:32 +00:00
|
|
|
// two paths at once
|
2010-06-15 23:24:48 +00:00
|
|
|
public static string CombineMore (params string [] Parts)
|
|
|
|
{
|
2010-05-18 19:44:15 +00:00
|
|
|
string NewPath = " ";
|
2010-05-08 14:31:44 +00:00
|
|
|
foreach (string Part in Parts)
|
2010-05-10 13:42:46 +00:00
|
|
|
NewPath = Path.Combine (NewPath, Part);
|
2010-05-08 14:31:44 +00:00
|
|
|
return NewPath;
|
|
|
|
}
|
2010-05-06 00:17:00 +00:00
|
|
|
|
2010-06-15 23:24:48 +00:00
|
|
|
|
2010-05-10 13:42:46 +00:00
|
|
|
// Looks up an icon from the system's theme
|
2010-07-29 13:03:10 +00:00
|
|
|
public static Gdk.Pixbuf GetIcon (string name, int size)
|
2010-06-15 23:24:48 +00:00
|
|
|
{
|
2010-07-27 11:00:01 +00:00
|
|
|
|
2010-06-19 16:07:45 +00:00
|
|
|
IconTheme IconTheme = new IconTheme ();
|
2010-07-13 18:23:59 +00:00
|
|
|
IconTheme.AppendSearchPath (SparklePaths.SparkleIconPath);
|
|
|
|
IconTheme.AppendSearchPath (SparklePaths.SparkleLocalIconPath);
|
2010-07-29 13:03:10 +00:00
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
return IconTheme.LoadIcon (name, size, IconLookupFlags.GenericFallback);
|
|
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
return IconTheme.LoadIcon ("gtk-missing-image", size, IconLookupFlags.GenericFallback);
|
|
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2010-07-27 11:00:01 +00:00
|
|
|
|
2010-05-10 13:42:46 +00:00
|
|
|
}
|
|
|
|
|
2010-06-15 23:24:48 +00:00
|
|
|
|
|
|
|
public static bool ShowDebugInfo = true;
|
|
|
|
|
2010-07-04 22:41:47 +00:00
|
|
|
|
2010-06-15 23:24:48 +00:00
|
|
|
// Show debug info if needed
|
|
|
|
public static void DebugInfo (string Type, string Message)
|
|
|
|
{
|
2010-07-04 22:41:47 +00:00
|
|
|
|
2010-06-04 19:45:42 +00:00
|
|
|
if (ShowDebugInfo) {
|
|
|
|
DateTime DateTime = new DateTime ();
|
2010-06-15 23:24:48 +00:00
|
|
|
string TimeStamp = DateTime.Now.ToString ("HH:mm:ss");
|
2010-07-21 22:31:51 +00:00
|
|
|
if (Message.StartsWith ("["))
|
|
|
|
Console.WriteLine ("[" + TimeStamp + "]" + "[" + Type + "]" + Message);
|
|
|
|
else
|
|
|
|
Console.WriteLine ("[" + TimeStamp + "]" + "[" + Type + "] " + Message);
|
2010-06-04 19:45:42 +00:00
|
|
|
}
|
2010-06-15 23:24:48 +00:00
|
|
|
|
2010-06-04 19:45:42 +00:00
|
|
|
}
|
|
|
|
|
2010-06-20 19:42:41 +00:00
|
|
|
|
|
|
|
// Formats a timestamp to a relative date compared to the current time
|
|
|
|
// Example: "about 5 hours ago"
|
|
|
|
public static string ToRelativeDate (DateTime date_time)
|
|
|
|
{
|
2010-07-04 22:41:47 +00:00
|
|
|
|
2010-06-20 19:42:41 +00:00
|
|
|
TimeSpan time_span = new TimeSpan (0);
|
|
|
|
time_span = DateTime.Now - date_time;
|
|
|
|
|
|
|
|
if (time_span <= TimeSpan.FromSeconds (60)) {
|
2010-06-21 13:47:29 +00:00
|
|
|
return string.Format (Catalog.GetPluralString ("a second ago", "{0} seconds ago",
|
|
|
|
time_span.Seconds),
|
|
|
|
time_span.Seconds);
|
2010-06-20 19:42:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (time_span <= TimeSpan.FromSeconds (60)) {
|
2010-06-21 13:47:29 +00:00
|
|
|
return string.Format (Catalog.GetPluralString ("a minute ago", "about {0} minutes ago",
|
|
|
|
time_span.Minutes),
|
|
|
|
time_span.Minutes);
|
2010-06-20 19:42:41 +00:00
|
|
|
}
|
|
|
|
|
2010-07-04 22:41:47 +00:00
|
|
|
if (time_span <= TimeSpan.FromHours (24)) {
|
2010-06-21 14:42:17 +00:00
|
|
|
return string.Format (Catalog.GetPluralString ("about an hour ago", "about {0} hours ago",
|
2010-06-21 13:47:29 +00:00
|
|
|
time_span.Hours),
|
|
|
|
time_span.Hours);
|
2010-06-20 19:42:41 +00:00
|
|
|
}
|
|
|
|
|
2010-07-04 22:41:47 +00:00
|
|
|
if (time_span <= TimeSpan.FromDays (30)) {
|
2010-06-21 13:47:29 +00:00
|
|
|
return string.Format (Catalog.GetPluralString ("yesterday", "{0} days ago",
|
|
|
|
time_span.Days),
|
|
|
|
time_span.Days);
|
2010-06-20 19:42:41 +00:00
|
|
|
}
|
|
|
|
|
2010-07-04 22:41:47 +00:00
|
|
|
if (time_span <= TimeSpan.FromDays (365)) {
|
2010-06-21 13:47:29 +00:00
|
|
|
return string.Format (Catalog.GetPluralString ("a month ago", "{0} months ago",
|
2010-06-21 14:42:17 +00:00
|
|
|
(int) time_span.Days / 30),
|
2010-06-21 13:47:29 +00:00
|
|
|
(int) time_span.Days / 30);
|
2010-06-20 19:42:41 +00:00
|
|
|
}
|
|
|
|
|
2010-06-21 13:47:29 +00:00
|
|
|
return string.Format (Catalog.GetPluralString ("a year ago", "{0} years ago",
|
|
|
|
(int) time_span.Days / 365),
|
|
|
|
(int) time_span.Days / 365);
|
2010-07-04 22:41:47 +00:00
|
|
|
|
2010-06-20 21:05:11 +00:00
|
|
|
}
|
|
|
|
|
2010-07-04 22:41:47 +00:00
|
|
|
|
2010-05-06 00:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|