diff --git a/mdfinder/App.config b/mdfinder/App.config
index 731f6de..adba596 100644
--- a/mdfinder/App.config
+++ b/mdfinder/App.config
@@ -1,6 +1,32 @@
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 25
+
+
+
\ No newline at end of file
diff --git a/mdfinder/App.xaml b/mdfinder/App.xaml
index d99b7ea..ee73f38 100644
--- a/mdfinder/App.xaml
+++ b/mdfinder/App.xaml
@@ -4,6 +4,10 @@
xmlns:local="clr-namespace:mdfinder"
StartupUri="MainWindow.xaml">
-
+
+
+
+
+
diff --git a/mdfinder/BoolVisibilityConverter.cs b/mdfinder/BoolVisibilityConverter.cs
new file mode 100644
index 0000000..818643b
--- /dev/null
+++ b/mdfinder/BoolVisibilityConverter.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+
+namespace mdfinder
+{
+ /// A visibility converter.
+ /// This code is derived from code in the butterflow-ui project. https://github.com/wagesj45/butterflow-ui
+ [ValueConversion(typeof(bool), typeof(Visibility))]
+ public class BoolVisibilityConverter : IValueConverter
+ {
+ /// Converts a value.
+ /// Thrown when an object cannot be cast to a required
+ /// type.
+ /// The value produced by the binding source.
+ /// The type of the binding target property.
+ /// The converter parameter to use.
+ /// The culture to use in the converter.
+ ///
+ /// A converted value. If the method returns , the valid null value is
+ /// used.
+ ///
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (targetType == typeof(Visibility))
+ {
+ return (bool)value ? Visibility.Visible : Visibility.Hidden;
+ }
+
+ throw new InvalidCastException(string.Format(Localization.Localization.BooleanInvalidCastExceptionFormat, targetType.Name));
+ }
+
+ /// Converts a value.
+ /// Thrown when an object cannot be cast to a required
+ /// type.
+ /// The value that is produced by the binding target.
+ /// The type to convert to.
+ /// The converter parameter to use.
+ /// The culture to use in the converter.
+ ///
+ /// A converted value. If the method returns , the valid null value is
+ /// used.
+ ///
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (targetType == typeof(Visibility))
+ {
+ return ((Visibility)value == Visibility.Visible) ? true : false;
+ }
+
+ throw new InvalidCastException(string.Format(Localization.Localization.BooleanInvalidCastExceptionFormat, targetType.Name));
+ }
+ }
+}
diff --git a/mdfinder/DBHelper.cs b/mdfinder/DBHelper.cs
new file mode 100644
index 0000000..44c2d08
--- /dev/null
+++ b/mdfinder/DBHelper.cs
@@ -0,0 +1,70 @@
+using LiteDB;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace mdfinder
+{
+ /// A database helper class.
+ public class DBHelper
+ {
+ #region Members
+
+ /// The default database file name.
+ private const string DEFAULT_DB_FILE_NAME = "mdfinder.db";
+
+ #endregion
+
+ #region Properties
+
+ /// Gets or sets the database.
+ /// The database.
+ private LiteDatabase Database { get; set; }
+
+ /// Gets the file records.
+ /// The file records.
+ public LiteCollection FileRecords
+ {
+ get
+ {
+ return this.Database.GetCollection("FileRecords");
+ }
+ }
+
+ #endregion
+
+ #region Constructors
+
+ /// Default constructor.
+ public DBHelper()
+ {
+ this.Database = new LiteDatabase(DEFAULT_DB_FILE_NAME);
+ }
+
+ /// Constructor.
+ /// The database.
+ public DBHelper(string database)
+ {
+ this.Database = new LiteDatabase(database);
+ }
+
+ #endregion
+
+ #region Methods
+
+ /// Inserts a file record.
+ /// Full pathname of the file.
+ /// The size.
+ /// The hash.
+ /// The hash provider.
+ public void InsertFileRecord(string path, long size, string hash, string hashProvider)
+ {
+ this.FileRecords.Insert(new FileRecord() { Path = path, Size = size, Hash = hash, HashProvider = hashProvider });
+ }
+
+ #endregion
+ }
+}
diff --git a/mdfinder/Extensions.cs b/mdfinder/Extensions.cs
new file mode 100644
index 0000000..89c0ce0
--- /dev/null
+++ b/mdfinder/Extensions.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace mdfinder
+{
+ public static class Extensions
+ {
+ /// Enumerates into bins of size .
+ /// Generic type parameter.
+ /// The items to act on.
+ /// Size of the bin.
+ ///
+ /// An enumerator that allows foreach to be used to process bin in this collection.
+ ///
+ /// Thanks to @juharr at Stack Overflow. https://stackoverflow.com/a/32970228/1210377
+ public static IEnumerable> Bin(this IEnumerable items, int binSize)
+ {
+ if(binSize <= 0)
+ {
+ throw new ArgumentOutOfRangeException("binSize", Localization.Localization.BinSizeOutOfRangeExceptionMessage);
+ }
+
+ return items.Select((x, i) => new { x, i })
+ .GroupBy(a => a.i / binSize)
+ .Select(grp => grp.Select(a => a.x));
+ }
+ }
+}
diff --git a/mdfinder/FileRecord.cs b/mdfinder/FileRecord.cs
new file mode 100644
index 0000000..d832fbd
--- /dev/null
+++ b/mdfinder/FileRecord.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace mdfinder
+{
+ public class FileRecord
+ {
+ #region Properties
+
+ /// Gets or sets the identifier.
+ /// The identifier.
+ public uint Id { get; set; }
+
+ /// Gets or sets the full pathname of the file.
+ /// The full pathname of the file.
+ public string Path { get; set; }
+
+ /// Gets or sets the size.
+ /// The size.
+ public long Size { get; set; }
+
+ /// Gets or sets the hash.
+ /// The hash.
+ public string Hash { get; set; }
+
+ /// Gets or sets the hash provider.
+ /// The hash provider.
+ public string HashProvider { get; set; }
+
+ #endregion
+ }
+}
diff --git a/mdfinder/Icons.xaml b/mdfinder/Icons.xaml
new file mode 100644
index 0000000..d55ffda
--- /dev/null
+++ b/mdfinder/Icons.xaml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mdfinder/InverseBoolConverter.cs b/mdfinder/InverseBoolConverter.cs
new file mode 100644
index 0000000..4ead163
--- /dev/null
+++ b/mdfinder/InverseBoolConverter.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace mdfinder
+{
+ /// An inverse boolean converter.
+ /// This code is derived from code in the butterflow-ui project. https://github.com/wagesj45/butterflow-ui
+ [ValueConversion(typeof(bool), typeof(bool))]
+ public class InverseBoolConverter : IValueConverter
+ {
+ /// Converts a boolean to its inverse.
+ /// Thrown when an object cannot be cast to a required
+ /// type.
+ /// The value produced by the binding source.
+ /// The type of the binding target property.
+ /// The converter parameter to use.
+ /// The culture to use in the converter.
+ ///
+ /// A converted value. If the method returns , the valid null value is
+ /// used.
+ ///
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (targetType == typeof(bool))
+ {
+ return !(bool)value;
+ }
+
+ throw new InvalidCastException(string.Format(Localization.Localization.BooleanInvalidCastExceptionFormat, targetType.Name));
+ }
+
+ /// Converts an inverse boolean back to its original state.
+ /// Thrown when an object cannot be cast to a required
+ /// type.
+ /// The value that is produced by the binding target.
+ /// The type to convert to.
+ /// The converter parameter to use.
+ /// The culture to use in the converter.
+ ///
+ /// A converted value. If the method returns , the valid null value is
+ /// used.
+ ///
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (targetType == typeof(bool))
+ {
+ return !(bool)value;
+ }
+
+ throw new InvalidCastException(string.Format(Localization.Localization.BooleanInvalidCastExceptionFormat, targetType.Name));
+ }
+ }
+}
diff --git a/mdfinder/InverseBoolVisibilityConverter.cs b/mdfinder/InverseBoolVisibilityConverter.cs
new file mode 100644
index 0000000..f4348f2
--- /dev/null
+++ b/mdfinder/InverseBoolVisibilityConverter.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+
+namespace mdfinder
+{
+ /// An inverse bool visibility converter.
+ /// This code is derived from code in the butterflow-ui project. https://github.com/wagesj45/butterflow-ui
+ [ValueConversion(typeof(bool), typeof(Visibility))]
+ public class InverseBoolVisibilityConverter : IValueConverter
+ {
+ /// Converts a value.
+ /// Thrown when an object cannot be cast to a required
+ /// type.
+ /// The value produced by the binding source.
+ /// The type of the binding target property.
+ /// The converter parameter to use.
+ /// The culture to use in the converter.
+ ///
+ /// A converted value. If the method returns , the valid null value is
+ /// used.
+ ///
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (targetType == typeof(Visibility))
+ {
+ return (bool)value ? Visibility.Hidden : Visibility.Visible;
+ }
+
+ throw new InvalidCastException(string.Format(Localization.Localization.BooleanInvalidCastExceptionFormat, targetType.Name));
+ }
+
+ /// Converts a value.
+ /// Thrown when an object cannot be cast to a required
+ /// type.
+ /// The value that is produced by the binding target.
+ /// The type to convert to.
+ /// The converter parameter to use.
+ /// The culture to use in the converter.
+ ///
+ /// A converted value. If the method returns , the valid null value is
+ /// used.
+ ///
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (targetType == typeof(Visibility))
+ {
+ return ((Visibility)value == Visibility.Visible) ? false : true;
+ }
+
+ throw new InvalidCastException(string.Format(Localization.Localization.BooleanInvalidCastExceptionFormat, targetType.Name));
+ }
+ }
+}
diff --git a/mdfinder/Localization/Localization.Designer.cs b/mdfinder/Localization/Localization.Designer.cs
new file mode 100644
index 0000000..614a0ea
--- /dev/null
+++ b/mdfinder/Localization/Localization.Designer.cs
@@ -0,0 +1,216 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace mdfinder.Localization {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ public class Localization {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Localization() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("mdfinder.Localization.Localization", typeof(Localization).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Actions.
+ ///
+ public static string ActionBarLabel {
+ get {
+ return ResourceManager.GetString("ActionBarLabel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Would you like to visit mdfinder to update to the latest version?.
+ ///
+ public static string BehindVersionQuestion {
+ get {
+ return ResourceManager.GetString("BehindVersionQuestion", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The current version is behind the github repository and should be updated..
+ ///
+ public static string BehindVersionStatusDescription {
+ get {
+ return ResourceManager.GetString("BehindVersionStatusDescription", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The bin size must be greater than or equal to 1 and less than [int max | todo: find out the actual value]..
+ ///
+ public static string BinSizeOutOfRangeExceptionMessage {
+ get {
+ return ResourceManager.GetString("BinSizeOutOfRangeExceptionMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot convert type to {0} from or to a boolean..
+ ///
+ public static string BooleanInvalidCastExceptionFormat {
+ get {
+ return ResourceManager.GetString("BooleanInvalidCastExceptionFormat", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The current version is up to date with the github repository..
+ ///
+ public static string CurrentVersionStatusDescription {
+ get {
+ return ResourceManager.GetString("CurrentVersionStatusDescription", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The current version is ahead of the github repository, or is a custom version of butterflow-ui that cannot be compared to the github repository..
+ ///
+ public static string CustomVersionStatusDescription {
+ get {
+ return ResourceManager.GetString("CustomVersionStatusDescription", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Edit.
+ ///
+ public static string EditMenu {
+ get {
+ return ResourceManager.GetString("EditMenu", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to File.
+ ///
+ public static string FileMenu {
+ get {
+ return ResourceManager.GetString("FileMenu", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Help.
+ ///
+ public static string HelpMenu {
+ get {
+ return ResourceManager.GetString("HelpMenu", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Open File Database....
+ ///
+ public static string OpenMenuItem {
+ get {
+ return ResourceManager.GetString("OpenMenuItem", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Save File Database....
+ ///
+ public static string SaveMenuItem {
+ get {
+ return ResourceManager.GetString("SaveMenuItem", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Scan.
+ ///
+ public static string ScanLabel {
+ get {
+ return ResourceManager.GetString("ScanLabel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Location to Scan.
+ ///
+ public static string ScanLocationLabel {
+ get {
+ return ResourceManager.GetString("ScanLocationLabel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Scan the selected path.
+ ///
+ public static string ScanTooltip {
+ get {
+ return ResourceManager.GetString("ScanTooltip", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to mdfinder.
+ ///
+ public static string Title {
+ get {
+ return ResourceManager.GetString("Title", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Github failed to respond with the current version. This could be because of rate limits or a network failure..
+ ///
+ public static string UnknownVersionStatusDescription {
+ get {
+ return ResourceManager.GetString("UnknownVersionStatusDescription", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/mdfinder/Localization/Localization.resx b/mdfinder/Localization/Localization.resx
new file mode 100644
index 0000000..573dcde
--- /dev/null
+++ b/mdfinder/Localization/Localization.resx
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Actions
+
+
+ Would you like to visit mdfinder to update to the latest version?
+
+
+ The current version is behind the github repository and should be updated.
+
+
+ The bin size must be greater than or equal to 1 and less than [int max | todo: find out the actual value].
+
+
+ Cannot convert type to {0} from or to a boolean.
+
+
+ The current version is up to date with the github repository.
+
+
+ The current version is ahead of the github repository, or is a custom version of butterflow-ui that cannot be compared to the github repository.
+
+
+ Edit
+
+
+ File
+
+
+ Help
+
+
+ Open File Database...
+
+
+ Save File Database...
+
+
+ Scan
+
+
+ Location to Scan
+
+
+ Scan the selected path
+
+
+ mdfinder
+
+
+ Github failed to respond with the current version. This could be because of rate limits or a network failure.
+
+
\ No newline at end of file
diff --git a/mdfinder/MainWindow.xaml b/mdfinder/MainWindow.xaml
index f68ce3d..a686699 100644
--- a/mdfinder/MainWindow.xaml
+++ b/mdfinder/MainWindow.xaml
@@ -3,10 +3,76 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:local="clr-namespace:mdfinder"
+ xmlns:mdfinder="clr-namespace:mdfinder"
+ xmlns:loc="clr-namespace:mdfinder.Localization"
mc:Ignorable="d"
- Title="MainWindow" Height="450" Width="800">
-
-
-
+ Title="{x:Static loc:Localization.Title}" Height="450" Width="800">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mdfinder/MainWindow.xaml.cs b/mdfinder/MainWindow.xaml.cs
index f8aa603..8088ba4 100644
--- a/mdfinder/MainWindow.xaml.cs
+++ b/mdfinder/MainWindow.xaml.cs
@@ -20,9 +20,21 @@ namespace mdfinder
///
public partial class MainWindow : Window
{
+ #region Properties
+
+ public DBHelper Database { get; set; }
+
+ #endregion
+
+ #region Constructors
+
+ /// Default constructor for the main window of the application.
public MainWindow()
{
+ this.Database = new DBHelper();
InitializeComponent();
- }
+ }
+
+ #endregion
}
}
diff --git a/mdfinder/OctokitWrapper.cs b/mdfinder/OctokitWrapper.cs
new file mode 100644
index 0000000..d086dba
--- /dev/null
+++ b/mdfinder/OctokitWrapper.cs
@@ -0,0 +1,145 @@
+using csmic;
+using Octokit;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace mdfinder
+{
+ /// An octokit wrapper.
+ public static class OctokitWrapper
+ {
+ #region Members
+
+ /// The RegEx string for matching .
+ private const string REGEX_VERSION = @"(?\d+ ?)\.(?\d+ ?)\.(?\d+ ?)";
+
+ /// The version status of the current installation.
+ private static VersionStatus versionStatus = VersionStatus.Unknown;
+
+ #endregion
+
+ #region Properties
+
+ /// Gets the current version status of this installation.
+ /// The current version status of this installation.
+ public static VersionStatus CurrentVersionStatus
+ {
+ get
+ {
+ return versionStatus;
+ }
+ }
+
+ /// Gets information describing the current version status.
+ /// Information describing the current version status.
+ public static string CurrentVersionStatusDescription
+ {
+ get
+ {
+ switch (CurrentVersionStatus)
+ {
+ case VersionStatus.Current:
+ return Localization.Localization.CurrentVersionStatusDescription;
+ case VersionStatus.Behind:
+ return Localization.Localization.BehindVersionStatusDescription;
+ case VersionStatus.Custom:
+ return Localization.Localization.CustomVersionStatusDescription;
+ case VersionStatus.Unknown:
+ default:
+ return Localization.Localization.UnknownVersionStatusDescription;
+ }
+ }
+ }
+
+ #endregion
+
+ #region Constructor
+
+ /// Static constructor.
+ static OctokitWrapper()
+ {
+ versionStatus = GetVersionStatus();
+ }
+
+ #endregion
+
+ #region Methods
+
+ /// Gets version status from github.
+ /// The current version status.
+ private static VersionStatus GetVersionStatus()
+ {
+ try
+ {
+ var interpreter = new InputInterpreter();
+ var client = new GitHubClient(new ProductHeaderValue("mdfinder"));
+ var releases = client.Repository.Release.GetAll("wagesj45", "mdfinder").Result;
+
+ if (releases.Any())
+ {
+ var latest = releases.First();
+ decimal latestMajor = 0, latestMinor = 0, latestPatch = 0, currentMajor = 0, currentMinor = 0, currentPatch = 0;
+
+ var regex = new Regex(REGEX_VERSION);
+ foreach (Match match in regex.Matches(latest.TagName))
+ {
+ latestMajor = interpreter.ComputeExpression(match.Groups["Major"].Value);
+ latestMinor = interpreter.ComputeExpression(match.Groups["Minor"].Value);
+ latestPatch = interpreter.ComputeExpression(match.Groups["Patch"].Value);
+ }
+
+ foreach (Match match in regex.Matches(Assembly.GetExecutingAssembly().GetName().Version.ToString()))
+ {
+ currentMajor = interpreter.ComputeExpression(match.Groups["Major"].Value);
+ currentMinor = interpreter.ComputeExpression(match.Groups["Minor"].Value);
+ currentPatch = interpreter.ComputeExpression(match.Groups["Patch"].Value);
+ }
+
+ if (latestMajor == currentMajor && latestMinor == currentMinor && latestPatch == currentPatch)
+ {
+ return VersionStatus.Current;
+ }
+
+ if (latestMajor >= currentMajor && latestMinor >= currentMinor && latestPatch >= currentPatch)
+ {
+ return VersionStatus.Behind;
+ }
+
+ return VersionStatus.Custom;
+ }
+ }
+ catch (Exception e)
+ {
+ //There was an issue connecting to Github. This could be caused by a missing network connection.
+ //We can safely ignore an error in this process and proceed, falling through to the default connection
+ //value of Unknown.
+ }
+
+ return VersionStatus.Unknown;
+ }
+
+ #endregion
+
+ #region Subclasses
+
+ /// Values that represent version status of the current installation of butterflow-ui.
+ public enum VersionStatus
+ {
+ /// The current version is up to date with the github repository.
+ Current,
+ /// The current version is behind the github repository and should be updated.
+ Behind,
+ /// The current version is ahead of the github repository, or is a custom version of butterflow-ui that cannot be compared to the github repository.
+ Custom,
+ /// Github failed to respond with the current version. This could be because of rate limits or a network failure.
+ Unknown
+ }
+
+ #endregion
+ }
+}
diff --git a/mdfinder/Properties/Settings.Designer.cs b/mdfinder/Properties/Settings.Designer.cs
index 3de99ba..39eaf3a 100644
--- a/mdfinder/Properties/Settings.Designer.cs
+++ b/mdfinder/Properties/Settings.Designer.cs
@@ -8,23 +8,31 @@
//
//------------------------------------------------------------------------------
-namespace mdfinder.Properties
-{
-
-
+namespace mdfinder.Properties {
+
+
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
- internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
- {
-
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-
- public static Settings Default
- {
- get
- {
+
+ public static Settings Default {
+ get {
return defaultInstance;
}
}
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("25")]
+ public int FilesFoundAlert {
+ get {
+ return ((int)(this["FilesFoundAlert"]));
+ }
+ set {
+ this["FilesFoundAlert"] = value;
+ }
+ }
}
}
diff --git a/mdfinder/Properties/Settings.settings b/mdfinder/Properties/Settings.settings
index 033d7a5..e5a4c8e 100644
--- a/mdfinder/Properties/Settings.settings
+++ b/mdfinder/Properties/Settings.settings
@@ -1,7 +1,9 @@
-
-
-
-
-
+
+
+
+
+ 25
+
+
\ No newline at end of file
diff --git a/mdfinder/Scanner.cs b/mdfinder/Scanner.cs
new file mode 100644
index 0000000..0780d5d
--- /dev/null
+++ b/mdfinder/Scanner.cs
@@ -0,0 +1,186 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace mdfinder
+{
+ /// Scans directories, logging files and their attributes.
+ public static class Scanner
+ {
+ #region Members
+
+ /// Event queue for all listeners interested in FilesFound events.
+ public static event EventHandler FilesFound;
+
+ /// Event queue for all listeners interested in DirectoryFound events.
+ public static event EventHandler DirectoryFound;
+
+ /// Event queue for all listeners interested in ReportProgress events.
+ public static event EventHandler ReportProgress;
+
+ #endregion
+
+ #region Properties
+
+ public static uint Processed { get; private set; }
+
+ public static uint Total { get; private set; }
+
+ public static bool IsScanning { get; private set; }
+
+ #endregion
+
+ #region Methods
+
+ public static void Scan(string path)
+ {
+ Processed = 0;
+ Total = 0;
+
+ var scanPath = new DirectoryInfo(path);
+ if (scanPath.Exists)
+ {
+ Scan(scanPath);
+ }
+ }
+
+ private static void Scan(DirectoryInfo directory)
+ {
+ var files = directory.GetFiles();
+ var fileBatches = files.Bin(Properties.Settings.Default.FilesFoundAlert);
+ var subdirectories = directory.GetDirectories();
+
+ Total += (uint)files.Count();
+
+ foreach (var subdirectory in subdirectories)
+ {
+ OnDirectoryFound(subdirectory);
+
+ Scan(subdirectory);
+ }
+
+ foreach (var batch in fileBatches)
+ {
+ OnFilesFound(batch);
+
+ Processed += (uint)batch.Count();
+
+ OnReportProgress(Processed, Total);
+ }
+ }
+
+ /// Executes the files found action.
+ /// The files.
+ private static void OnFilesFound(IEnumerable files)
+ {
+ FilesFound?.Invoke(null, new FilesFoundEventArgs(files));
+ }
+
+ /// Executes the directory found action.
+ /// Pathname of the directory.
+ private static void OnDirectoryFound(DirectoryInfo directory)
+ {
+ DirectoryFound?.Invoke(null, new DirectoryFoundEventArgs(directory));
+ }
+
+ /// Executes the report progress action.
+ /// The processed.
+ /// Number of.
+ private static void OnReportProgress(uint processed, uint total)
+ {
+ ReportProgress?.Invoke(null, new ProgressReportEventArgs(processed, total));
+ }
+
+ #endregion
+
+ #region Subclasses
+
+ /// Event arguments describing the state of the when it has found files.
+ public class FilesFoundEventArgs : EventArgs
+ {
+ #region Properties
+
+ /// Gets or sets the files.
+ /// The files.
+ public IEnumerable Files { get; private set; }
+
+ #endregion
+
+ #region Constructors
+
+ /// Constructor.
+ /// The files.
+ public FilesFoundEventArgs(IEnumerable files)
+ {
+ this.Files = files;
+ }
+
+ #endregion
+ }
+
+ /// Event arguments describing the state of the when it has found a directory.
+ public class DirectoryFoundEventArgs : EventArgs
+ {
+ #region Properties
+
+ /// Gets or sets the pathname of the directory.
+ /// The pathname of the directory.
+ public DirectoryInfo Directory { get; private set; }
+
+ #endregion
+
+ #region Constructors
+
+ /// Constructor.
+ /// The pathname of the directory.
+ public DirectoryFoundEventArgs(DirectoryInfo directory)
+ {
+ this.Directory = directory;
+ }
+
+ #endregion
+ }
+
+ public class ProgressReportEventArgs : EventArgs
+ {
+ #region Properties
+
+ /// Gets or sets the progress as a percentage.
+ /// The percentage.
+ public double Percentage
+ {
+ get
+ {
+ return ((double)this.Processed / (double)this.Total);
+ }
+ }
+
+ /// Gets or sets the number of processed items.
+ /// The processed.
+ public uint Processed { get; private set; }
+
+ /// Gets or sets the number of items discovered to process.
+ /// The total.
+ public uint Total { get; private set; }
+
+ #endregion
+
+ #region Constructors
+
+ /// Constructor.
+ /// The processed item count.
+ /// The total discovereditem count.
+ public ProgressReportEventArgs(uint processed, uint total)
+ {
+
+ }
+
+ #endregion
+ }
+
+ #endregion
+ }
+}
diff --git a/mdfinder/mdfinder.csproj b/mdfinder/mdfinder.csproj
index 0e9f495..0e1d3f3 100644
--- a/mdfinder/mdfinder.csproj
+++ b/mdfinder/mdfinder.csproj
@@ -14,6 +14,8 @@
4truetrue
+
+ AnyCPU
@@ -35,8 +37,23 @@
4
+
+ ..\packages\csmic.1.1.4\lib\net40\csmic.dll
+
+
+ ..\packages\LiteDB.4.1.4\lib\net40\LiteDB.dll
+
+
+ ..\packages\Octokit.0.32.0\lib\net45\Octokit.dll
+
+
+ ..\packages\Standard.Licensing.1.1.5\lib\net45\Standard.Licensing.dll
+
+
+
+
@@ -55,6 +72,10 @@
MSBuild:CompileDesigner
+
+ Designer
+ MSBuild:Compile
+ MSBuild:CompileDesigner
@@ -63,12 +84,25 @@
App.xamlCode
+
+
+
+
+
+
+
+
+ True
+ True
+ Localization.resx
+ MainWindow.xamlCode
+ Code
@@ -82,10 +116,15 @@
Settings.settingsTrue
+
+ PublicResXFileCodeGenerator
+ Localization.Designer.cs
+ ResXFileCodeGeneratorResources.Designer.cs
+ SettingsSingleFileGeneratorSettings.Designer.cs
@@ -94,5 +133,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mdfinder/packages.config b/mdfinder/packages.config
new file mode 100644
index 0000000..4421dc4
--- /dev/null
+++ b/mdfinder/packages.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file