Skip to content

Commit

Permalink
Merge pull request #933 from peppy/storage-improvements
Browse files Browse the repository at this point in the history
Storage improvements
  • Loading branch information
peppy committed Aug 2, 2017
2 parents 46abae5 + dca2603 commit 96daf20
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 89 deletions.
15 changes: 15 additions & 0 deletions osu.Framework.Desktop/Platform/DesktopGameHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using osu.Framework.Desktop.Input.Handlers.Mouse;
using osu.Framework.Input;
using osu.Framework.Input.Handlers;
using osu.Framework.Logging;

namespace osu.Framework.Desktop.Platform
{
Expand All @@ -22,6 +23,20 @@ public abstract class DesktopGameHost : GameHost
private readonly TcpIpcProvider ipcProvider;
private readonly Task ipcTask;

public override Storage Storage
{
get
{
return base.Storage;
}

protected set
{
base.Storage = value;
Logger.Storage = value.GetStorageForDirectory("logs");
}
}

protected DesktopGameHost(string gameName = @"", bool bindIPCPort = false)
: base(gameName)
{
Expand Down
33 changes: 23 additions & 10 deletions osu.Framework.Desktop/Platform/DesktopStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using SQLite.Net.Interop;
using SQLite.Net.Platform.Win32;
using System.Diagnostics;
using osu.Framework.Logging;

namespace osu.Framework.Desktop.Platform
{
Expand All @@ -18,19 +17,33 @@ public class DesktopStorage : Storage
public DesktopStorage(string baseName)
: base(baseName)
{
//todo: this is obviously not the right way to do this.
Logger.LogDirectory = Path.Combine(BasePath, @"logs");
}

protected virtual string BasePath => @"./"; //use current directory by default
protected override string LocateBasePath() => @"./"; //use current directory by default

public override bool Exists(string path) => File.Exists(Path.Combine(BasePath, path));
public override bool Exists(string path) => File.Exists(GetUsablePathFor(path));

public override bool ExistsDirectory(string path) => Directory.Exists(Path.Combine(BasePath, path));
public override bool ExistsDirectory(string path) => Directory.Exists(GetUsablePathFor(path));

public override void DeleteDirectory(string path) => Directory.Delete(Path.Combine(BasePath, path), true);
public override void DeleteDirectory(string path)
{
path = GetUsablePathFor(path);

// handles the case where the directory doesn't exist, which will throw a DirectoryNotFoundException.
if (Directory.Exists(path))
Directory.Delete(path, true);
}

public override void Delete(string path)
{
path = GetUsablePathFor(path);

// handles the case where the containing directory doesn't exist, which will throw a DirectoryNotFoundException.
if (File.Exists(path))
File.Delete(path);
}

public override void Delete(string path) => File.Delete(Path.Combine(BasePath, path));
public override string[] GetDirectories(string path) => Directory.GetDirectories(GetUsablePathFor(path));

public override void OpenInNativeExplorer()
{
Expand All @@ -39,7 +52,7 @@ public override void OpenInNativeExplorer()

public override Stream GetStream(string path, FileAccess access = FileAccess.Read, FileMode mode = FileMode.OpenOrCreate)
{
path = Path.Combine(BasePath, path);
path = GetUsablePathFor(path);

if (string.IsNullOrEmpty(path))
throw new ArgumentNullException(nameof(path));
Expand All @@ -64,7 +77,7 @@ public override SQLiteConnection GetDatabase(string name)
platform = new SQLitePlatformWin32(Architecture.NativeIncludePath);
else
platform = new SQLitePlatformGeneric();
return new SQLiteConnection(platform, Path.Combine(BasePath, $@"{name}.db"));
return new SQLiteConnection(platform, GetUsablePathFor($@"{name}.db"));
}

public override void DeleteDatabase(string name) => Delete($@"{name}.db");
Expand Down
29 changes: 14 additions & 15 deletions osu.Framework.Desktop/Platform/Linux/LinuxStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,23 @@ public LinuxStorage(string baseName)
{
}

protected override string BasePath
protected override string LocateBasePath()
{
get
string home = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string xdg = Environment.GetEnvironmentVariable("XDG_DATA_HOME");
string[] paths =
{
string home = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string xdg = Environment.GetEnvironmentVariable("XDG_DATA_HOME");
string[] paths =
{
Path.Combine(xdg ?? Path.Combine(home, ".local", "share"), BaseName),
Path.Combine(home, "." + BaseName)
};
foreach (string path in paths)
{
if (Directory.Exists(path))
return path;
}
return paths[0];
xdg ?? Path.Combine(home, ".local", "share"),
Path.Combine(home)
};

foreach (string path in paths)
{
if (Directory.Exists(path))
return path;
}

return paths[0];
}
}
}
10 changes: 1 addition & 9 deletions osu.Framework.Desktop/Platform/Windows/WindowsStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE

using System;
using System.IO;

namespace osu.Framework.Desktop.Platform.Windows
{
Expand All @@ -13,13 +12,6 @@ public WindowsStorage(string baseName)
{
}

protected override string BasePath
{
get
{
string appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
return Path.Combine(appdata, BaseName);
}
}
protected override string LocateBasePath() => Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
}
}
69 changes: 14 additions & 55 deletions osu.Framework/Logging/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,13 @@
using System.Diagnostics;
using System.Globalization;
using System.IO;
using osu.Framework.IO.File;
using osu.Framework.Platform;
using osu.Framework.Threading;

namespace osu.Framework.Logging
{
public class Logger
{
/// <summary>
/// Directory to place all log files.
/// </summary>
public static string LogDirectory
{
get { return logDirectory; }
set
{
logDirectory = value;
hasLogDirectory = null; //we should check again whether the directory exists.
}
}

/// <summary>
/// Global control over logging.
/// </summary>
Expand All @@ -46,6 +33,11 @@ public static string LogDirectory
/// </summary>
public static string VersionIdentifier = @"unknown";

/// <summary>
/// The storage to place logs inside.
/// </summary>
public static Storage Storage;

/// <summary>
/// Add a plain-text phrase which should always be filtered from logs.
/// Useful for avoiding logging of credentials.
Expand Down Expand Up @@ -130,7 +122,7 @@ public static Logger GetLogger(LoggingTarget target = LoggingTarget.Runtime, boo

public LoggingTarget Target { get; }

public string Filename => logDirectory == null ? null : Path.Combine(logDirectory, $@"{Target.ToString().ToLower()}.log");
public string Filename => $@"{Target.ToString().ToLower()}.log";

private Logger(LoggingTarget target = LoggingTarget.Runtime)
{
Expand Down Expand Up @@ -189,13 +181,15 @@ public void Add(string message = @"", LogLevel level = LogLevel.Verbose)

background_scheduler.Add(delegate
{
ensureLogDirectoryExists();
if (hasLogDirectory.HasValue && !hasLogDirectory.Value)
if (Storage == null)
return;

try
{
File.AppendAllLines(Filename, lines);
using (var stream = Storage.GetStream(Filename, FileAccess.Write, FileMode.Append))
using (var writer = new StreamWriter(stream))
foreach (var line in lines)
writer.WriteLine(line);
}
catch
{
Expand All @@ -208,20 +202,9 @@ public void Add(string message = @"", LogLevel level = LogLevel.Verbose)
/// <summary>
/// Deletes log file from disk.
/// </summary>
/// <param name="lastLogSuffix">If specified, creates a copy of the last log file with specified suffix.</param>
public void Clear(string lastLogSuffix = null)
public void Clear()
{
background_scheduler.Add(delegate
{
ensureLogDirectoryExists();
if (Filename == null) return;

if (!string.IsNullOrEmpty(lastLogSuffix))
FileSafety.FileMove(Filename, Filename.Replace(@".log", $@"_{lastLogSuffix}.log"));
else
FileSafety.FileDelete(Filename);
});

background_scheduler.Add(() => Storage?.Delete(Filename));
addHeader();
}

Expand All @@ -237,30 +220,6 @@ private void addHeader()
private static readonly List<string> filters = new List<string>();
private static readonly Dictionary<LoggingTarget, Logger> static_loggers = new Dictionary<LoggingTarget, Logger>();
private static readonly ThreadedScheduler background_scheduler = new ThreadedScheduler(@"Logger");
private static bool? hasLogDirectory;
private static string logDirectory;

private void ensureLogDirectoryExists()
{
if (hasLogDirectory.HasValue)
return;

if (logDirectory != null)
{
try
{
Directory.CreateDirectory(logDirectory);
hasLogDirectory = true;
}
catch
{
}

return;
}

hasLogDirectory = false;
}
}

public class LogEntry
Expand Down
44 changes: 44 additions & 0 deletions osu.Framework/Platform/Storage.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE

using System;
using System.IO;
using osu.Framework.IO.File;
using SQLite.Net;
Expand All @@ -11,11 +12,35 @@ public abstract class Storage
{
protected string BaseName { get; set; }

protected readonly string BasePath;

/// <summary>
/// An optional path to be added after <see cref="BaseName"/>.
/// </summary>
protected string SubDirectory { get; set; } = string.Empty;

protected Storage(string baseName)
{
BaseName = FileSafety.FilenameStrip(baseName);
BasePath = LocateBasePath();
if (BasePath == null)
throw new NullReferenceException(nameof(BasePath));
}

/// <summary>
/// Find the location which will be used as a root for this storage.
/// This should usually be a platform-specific implementation.
/// </summary>
/// <returns></returns>
protected abstract string LocateBasePath();

/// <summary>
/// Get a Storage-usable path for the provided path.
/// </summary>
/// <param name="path">An incomplete path, usually provided as user input.</param>
/// <returns></returns>
protected string GetUsablePathFor(string path) => Path.Combine(BasePath, BaseName, SubDirectory, path);

/// <summary>
/// Check whether a file exists at the specified path.
/// </summary>
Expand All @@ -42,6 +67,25 @@ protected Storage(string baseName)
/// <param name="path">The path of the file to delete.</param>
public abstract void Delete(string path);

/// <summary>
/// Retrieve a list of directories at the specified path.
/// </summary>
/// <param name="path">The path to list.</param>
/// <returns>A list of directories in the path, relative to the path.</returns>
public abstract string[] GetDirectories(string path);

/// <summary>
/// Retrieve a <see cref="Storage"/> for a contained directory.
/// </summary>
/// <param name="path">The subdirectory to use as a root.</param>
/// <returns>A more specific storage.</returns>
public Storage GetStorageForDirectory(string path)
{
var clone = (Storage)MemberwiseClone();
clone.SubDirectory = path;
return clone;
}

/// <summary>
/// Retrieve a stream from an underlying file inside this storage.
/// </summary>
Expand Down

0 comments on commit 96daf20

Please sign in to comment.