var appenders = loggerRepository.GetAppenders();
+
var lossyAppender = appenders.OfType<BufferingForwardingAppender>()
.FirstOrDefault(appender => appender.Name == "LossyFileAppender");
if (lossyAppender!=null)
}
private void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)
- {
- var messages=new List<UserMessage>();
+ {
+ Log.Error("Unobserved Task Exception", e.Exception);
+
+ var messages = new List<UserMessage>();
e.Exception.Handle(exc=>{
messages.Add(new UserMessage
{
return true;
});
- Log.Error("Unobserved Task Exception",e.Exception);
-
- var message = String.Format(@"{0}\r\n{1}\r\n\r\n{2}",
+
+ var message = String.Format(@"{0}<LineBreak/>{1}<LineBreak/><LineBreak/>{2}",
WPF.Properties.Resources.Unexpected_Error,
WPF.Properties.Resources.We_Apologize,
WPF.Properties.Resources.Please_Submit_Error);
get { return _settings.PithosSite; }
}*/
- public string PithosLoginUrl
- {
- get { return _settings.PithosLoginUrl; }
- }
public string IconsPath
{
try
{
- var credentials = PithosAccount.RetrieveCredentials(Settings.Default.PithosLoginUrl);
+ var loginUri=new Uri(new Uri(CurrentServer) , "login");
+ var credentials = PithosAccount.RetrieveCredentials(loginUri.ToString());
if (credentials == null)
return;
AccountName = credentials.UserName;
public void RefreshApiKey()
{
//_events.Publish(new Notification { Title = "Authorization failed", Message = "Your API Key has probably expired. You will be directed to a page where you can renew it", Level = TraceLevel.Error });
-
+ if (CurrentAccount == null)
+ return;
try
{
- var name = CurrentAccount != null ? CurrentAccount.AccountName : null;
- var credentials = PithosAccount.RetrieveCredentials(Settings.PithosLoginUrl,name);
+ var name = CurrentAccount.AccountName;
+
+ var loginUri = new Uri(new Uri(CurrentAccount.ServerUrl), "login");
+ var credentials = PithosAccount.RetrieveCredentials(loginUri.ToString(),name);
if (credentials==null)
return;
//The server will return credentials for a different account, not just the current account
}
+/*
public void AddPithosAccount()
{
- var credentials=PithosAccount.RetrieveCredentials(Settings.PithosLoginUrl);
+ var credentials=PithosAccount.RetrieveCredentials(null);
if (credentials == null)
return;
var account = Settings.Accounts.FirstOrDefault(act => act.AccountName == credentials.UserName);
NotifyOfPropertyChange(() => Accounts);
NotifyOfPropertyChange(()=>Settings);
}
+*/
readonly List<AccountSettings> _accountsToRemove = new List<AccountSettings>();
SearchOption.AllDirectories))
File.Copy(newFilePath, newFilePath.Replace(oldPath, newPath));
+ Log.InfoFormat("Deleting account folder {0}",oldPath);
Directory.Delete(oldPath, true);
//We also need to change the path of the existing file states
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.7.20310.0")]
-[assembly: AssemblyFileVersionAttribute("0.7.20310.0")]
+[assembly: AssemblyVersion("0.7.20311.0")]
+[assembly: AssemblyFileVersionAttribute("0.7.20311.0")]
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("https://pithos.dev.grnet.gr/login")]
- public string PithosLoginUrl {
- get {
- return ((string)(this["PithosLoginUrl"]));
- }
- }
-
- [global::System.Configuration.ApplicationScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("https://pithos.dev.grnet.gr/im/feedback")]
public string FeedbackUri {
get {
<Setting Name="CloudfilesAuthenticationUrl" Type="System.String" Scope="Application">
<Value Profile="(Default)">https://auth.api.rackspacecloud.com</Value>
</Setting>
- <Setting Name="PithosLoginUrl" Type="System.String" Scope="Application">
- <Value Profile="(Default)">https://pithos.dev.grnet.gr/login</Value>
- </Setting>
<Setting Name="FeedbackUri" Type="System.String" Scope="Application">
<Value Profile="(Default)">https://pithos.dev.grnet.gr/im/feedback</Value>
</Setting>
</MenuItem.ItemTemplate>
</MenuItem>
<Separator />
- <MenuItem x:Name="StatusMessage" Header="{Binding Path=StatusMessage, Converter={StaticResource SingleConverter}}" MaxWidth="200" />
+ <MenuItem x:Name="StatusMessage" Header="{Binding Path=StatusMessage, Converter={StaticResource SingleConverter}}" MaxWidth="200" cal:Message.Attach="OnStatusAction" ToolTip="{Binding TooltipMessage}"/>
<Separator Visibility="{Binding Path=HasAccounts, Converter={StaticResource BooleanToVisible}}"/>
<MenuItem Header="{Binding PauseSyncCaption}" x:Name="ToggleSynching" cal:Message.Attach="ToggleSynching" Visibility="{Binding Path=HasAccounts, Converter={StaticResource BooleanToVisible}}"/>
<Separator />
Proxy.SetFromSettings(settings);
StatusMessage = Settings.Accounts.Count==0
- ? "No Accounts added. Please add an account"
+ ? "No Accounts added\r\nPlease add an account"
: "Starting";
_accounts.CollectionChanged += (sender, e) =>
NotifyOfPropertyChange(() => HasAccounts);
};
- Assembly assembly = Assembly.GetExecutingAssembly();
- var fileVersion = FileVersionInfo.GetVersionInfo(assembly.Location);
- VersionMessage = String.Format("Pithos+ {0}", fileVersion.FileVersion);
-
+ SetVersionMessage();
}
catch (Exception exc)
{
}
+ private void SetVersionMessage()
+ {
+ Assembly assembly = Assembly.GetExecutingAssembly();
+ var fileVersion = FileVersionInfo.GetVersionInfo(assembly.Location);
+ VersionMessage = String.Format("Pithos+ {0}", fileVersion.FileVersion);
+ }
- protected override void OnActivate()
+ public void OnStatusAction()
+ {
+ if (Accounts.Count==0)
+ {
+ ShowPreferences("AccountTab");
+ }
+ }
+ protected override void OnActivate()
{
base.OnActivate();
- _sparkle = new Sparkle(Settings.UpdateUrl);
- _sparkle.updateDetected += OnUpgradeDetected;
- _sparkle.ShowDiagnosticWindow = Settings.UpdateDiagnostics;
+ InitializeSparkle();
- //Must delay opening the upgrade window
+ //Must delay opening the upgrade window
//to avoid Windows Messages sent by the TaskbarIcon
TaskEx.Delay(5000).ContinueWith(_=>
Execute.OnUIThread(()=> _sparkle.StartLoop(true,Settings.UpdateForceCheck,Settings.UpdateCheckInterval)));
StartMonitoring();
}
- private void OnUpgradeDetected(object sender, UpdateDetectedEventArgs e)
+
+ private void OnCheckFinished(object sender, bool updaterequired)
{
+
+ Log.InfoFormat("Upgrade check finished. Need Upgrade: {0}", updaterequired);
+ if (_manualUpgradeCheck)
+ {
+ _manualUpgradeCheck = false;
+ if (!updaterequired)
+ //Sparkle raises events on a background thread
+ Execute.OnUIThread(()=>
+ ShowBalloonFor(new Notification{Title="Pithos+ is up to date",Message="You have the latest Pitsos+ version. No update is required"}));
+ }
+ }
+
+ private void OnUpgradeDetected(object sender, UpdateDetectedEventArgs e)
+ {
Log.InfoFormat("Update detected {0}",e.LatestVersion);
}
public void CheckForUpgrade()
{
+ ShowBalloonFor(new Notification{Title="Checking for upgrades",Message="Contacting the server to retrieve the latest Pithos+ version."});
Log.Error("Test Error message");
_sparkle.StopLoop();
+ _sparkle.updateDetected -= OnUpgradeDetected;
+ _sparkle.checkLoopFinished -= OnCheckFinished;
_sparkle.Dispose();
- _sparkle=new Sparkle(Settings.UpdateUrl);
+
+ _manualUpgradeCheck = true;
+ InitializeSparkle();
_sparkle.StartLoop(true,true,Settings.UpdateCheckInterval);
}
+ private void InitializeSparkle()
+ {
+ _sparkle = new Sparkle(Settings.UpdateUrl);
+ _sparkle.updateDetected += OnUpgradeDetected;
+ _sparkle.checkLoopFinished += OnCheckFinished;
+ _sparkle.ShowDiagnosticWindow = Settings.UpdateDiagnostics;
+ }
+
private async void StartMonitoring()
{
try
private bool _pollStarted;
private Sparkle _sparkle;
+ private bool _manualUpgradeCheck;
//SMELL: Doing so much work for notifications in the shell is wrong
//The notifications should be moved to their own view/viewmodel pair
if (String.IsNullOrWhiteSpace(notification.Message) && String.IsNullOrWhiteSpace(notification.Title))
return;
- ShowBalloonFor(notification);
+ if (notification.Level <= TraceLevel.Warning)
+ ShowBalloonFor(notification);
}
private void ShowBalloonFor(Notification notification)
BalloonIcon icon;
switch (notification.Level)
{
- case TraceLevel.Info:
- case TraceLevel.Verbose:
+ case TraceLevel.Verbose:
return;
+ case TraceLevel.Info:
+ icon = BalloonIcon.Info;
+ break;
case TraceLevel.Error:
icon = BalloonIcon.Error;
break;
<setting name="CloudfilesAuthenticationUrl" serializeAs="String">
<value>https://auth.api.rackspacecloud.com</value>
</setting>
- <setting name="PithosLoginUrl" serializeAs="String">
- <value>https://pithos.dev.grnet.gr/login</value>
- </setting>
<setting name="FeedbackUri" serializeAs="String">
<value>https://pithos.dev.grnet.gr/im/feedback</value>
</setting>
</appender>
<appender name="DumpFileAppender" type="log4net.Appender.RollingFileAppender">
- <file value="log.txt" />
+ <file value="errorlog.xml" />
<appendToFile value="false" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<appender-ref ref="DumpFileAppender" />
</appender>
+<!--
<appender name="MemoryAppender" type="log4net.Appender.MemoryAppender" >
<threshold value="All" />
</appender>
+-->
<!--
<appender name="LossySmtpAppender" type="log4net.Appender.SmtpAppender">
<to value="pkanavos@gmail.com" />
</appender>
-->
- <logger name="NHibernate" additivity="false">
+ <logger name="NHibernate" additivity="true">
<level value="WARN"/>
<appender-ref ref="TraceAppender"/>
</logger>
<appender-ref ref="TraceAppender"/>
</logger>
- <logger name="Pithos" additivity="false">
+ <logger name="Pithos" additivity="true">
<level value="ALL"/>
<appender-ref ref="TraceAppender"/>
</logger>
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
+using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
{
class BlockUpdater
{
+ private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
public string FilePath { get; private set; }
public string RelativePath { get; private set; }
private void ClearBlocks()
{
+ if (Log.IsDebugEnabled)
+ Log.DebugFormat("Clearing blocks for {0}",this.FilePath);
//Get all the the block paths, orphan or not
var paths= _blocks.Select(pair => pair.Value)
.Union(_orphanBlocks.Select(pair => pair.Value));
public void Delete(string relativePath)
{
var absolutePath = Path.Combine(RootPath, relativePath).ToLower();
+ if (Log.IsDebugEnabled)
+ Log.DebugFormat("Deleting {0}", absolutePath);
if (File.Exists(absolutePath))
{
try
var account = cloudFile.Account;
var container = cloudFile.Container;
- if (cloudFile.Content_Type == @"application/directory")
+ if (cloudFile.IsDirectory)
{
if (!Directory.Exists(localPath))
try
throw new ArgumentNullException("filePath");
if (!Path.IsPathRooted(filePath))
throw new ArgumentException("The localPath must be rooted", "filePath");
+ if (cloudFile.IsDirectory)
+ throw new ArgumentException("cloudFile is a directory, not a file","cloudFile");
Contract.EndContractBlock();
var localPath = Pithos.Interfaces.FileInfoExtensions.GetProperFilePathCapitalization(filePath);
var fileInfo = new FileInfo(localFolder);
if (fileInfo.Exists && fileInfo.Length == 0)
{
+ Log.WarnFormat("Malformed directory object detected for [{0}]", localFolder);
fileInfo.Delete();
Directory.CreateDirectory(localFolder);
}
throw new ArgumentException("The filePath must be rooted", "filePath");
if (serverHash == null)
throw new ArgumentNullException("serverHash");
+ if (cloudFile.IsDirectory)
+ throw new ArgumentException("cloudFile is a directory, not a file", "cloudFile");
Contract.EndContractBlock();
var fileAgent = GetFileAgent(accountInfo);
var deletedFiles = new List<FileSystemInfo>();\r
foreach (var objectInfo in cloudFiles)\r
{\r
- Log.DebugFormat("Handle deleted [{0}]",objectInfo.Uri);\r
+ if (Log.IsDebugEnabled)\r
+ Log.DebugFormat("Handle deleted [{0}]",objectInfo.Uri);\r
var relativePath = objectInfo.RelativeUrlToFilePath(accountInfo.UserName);\r
var item = FileAgent.GetFileAgent(accountInfo).GetFileSystemInfo(relativePath);\r
- Log.DebugFormat("Will delete [{0}] for [{1}]", item.FullName,objectInfo.Uri);\r
+ if (Log.IsDebugEnabled)\r
+ Log.DebugFormat("Will delete [{0}] for [{1}]", item.FullName,objectInfo.Uri);\r
if (item.Exists)\r
{\r
if ((item.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)\r
item.Attributes = item.Attributes & ~FileAttributes.ReadOnly;\r
\r
}\r
+ \r
+ \r
+ Log.DebugFormat("Deleting {0}", item.FullName);\r
+\r
var directory = item as DirectoryInfo;\r
if (directory!=null)\r
directory.Delete(true);\r
Contract.Requires(!String.IsNullOrWhiteSpace(dbPath));
Contract.Requires(!String.IsNullOrWhiteSpace(appDataPath));
+
var oldDbPath = Path.Combine(appDataPath, "Pithos", "pithos.db");
var oldDbInfo = new FileInfo(oldDbPath);
if (oldDbInfo.Exists && !File.Exists(dbPath))
{
+ Log.InfoFormat("Moving database from {0} to {1}",oldDbInfo.FullName,dbPath);
var oldDirectory = oldDbInfo.Directory;
- oldDbInfo.MoveTo(dbPath);
+ oldDbInfo.MoveTo(dbPath);
+
+ if (Log.IsDebugEnabled)
+ Log.DebugFormat("Deleting {0}",oldDirectory.FullName);
+
oldDirectory.Delete(true);
}
}
--- /dev/null
+<html>
+<body>
+<h2>Pithos MS Client v. 0.7.20311</h2>
+Release Date: March 16, 2012, 15:00
+<br/>
+Includes:
+<br/>
+<ul>
+<li> Fixed the production login URL</li>
+<li> When the user clics on "Check for upgrades", a notification is shown if no upgrades are available</li>
+<li> Fix in black-box logging</li>
+</ul>
+</body>
+</html>
\ No newline at end of file
<description></description> \r
<language>en</language> \r
<item> \r
+ <title>Version 0.7.20311</title>\r
+ <sparkle:releaseNotesLink>https://code.grnet.gr/projects/pithos-ms-client/repository/revisions/master/raw/trunk/Pithos.Installer/rnotes.0.7.20311.html</sparkle:releaseNotesLink>\r
+ <pubDate>Tue, 16 Mar 2012 15:00:00 +0200</pubDate>\r
+ <enclosure \r
+ url="https://code.grnet.gr/attachments/download/1017/PithosPlus_Setupv0.7.20311.0.exe"\r
+ length="4336044" \r
+ type="application/octet-stream"\r
+ sparkle:version="0.7.20311" \r
+ />\r
+ </item>\r
+ <item> \r
+ <title>Version 0.7.20310</title>\r
+ <sparkle:releaseNotesLink>https://code.grnet.gr/projects/pithos-ms-client/repository/revisions/master/raw/trunk/Pithos.Installer/rnotes.0.7.20310.html</sparkle:releaseNotesLink>\r
+ <pubDate>Tue, 15 Mar 2012 21:00:00 +0200</pubDate>\r
+ <enclosure \r
+ url="https://code.grnet.gr/attachments/download/1015/PithosPlus_Setupv0.7.20310.0.exe"\r
+ length="4344290" \r
+ type="application/octet-stream"\r
+ sparkle:version="0.7.20310" \r
+ />\r
+ </item>\r
+ <item> \r
<title>Version 0.7.20310</title>\r
<sparkle:releaseNotesLink>https://code.grnet.gr/projects/pithos-ms-client/repository/revisions/master/raw/trunk/Pithos.Installer/rnotes.0.7.20310.html</sparkle:releaseNotesLink>\r
<pubDate>Tue, 15 Mar 2012 21:00:00 +0200</pubDate>\r
public ObjectInfo Previous { get; private set; }
+ public bool IsDirectory
+ {
+ get
+ {
+ return String.Equals(Content_Type, @"application/directory",StringComparison.InvariantCultureIgnoreCase);
+ }
+ }
+
public ObjectInfo SetPrevious(ObjectInfo previous)
{
Previous = previous;