Created monitoring object and refactored code accordingly.

This commit is contained in:
Patrick Fic
2020-01-17 14:19:49 -08:00
parent 3357a8a564
commit b7218b6771
16 changed files with 217 additions and 76 deletions

View File

@@ -253,6 +253,7 @@
</ApplicationDefinition>
<Compile Include="Models\DTO_Base.cs" />
<Compile Include="Models\DTO_QueueItem.cs" />
<Compile Include="Models\Monitor.cs" />
<Compile Include="Properties\Resources.es-MX.Designer.cs">
<DependentUpon>Resources.es-MX.resx</DependentUpon>
<AutoGen>True</AutoGen>

View File

@@ -4,6 +4,16 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BodyshopUploader
{
public enum SourceSystem
{
Mitchell = 0,
Audatex = 1,
CCC = 2
}
}
namespace BodyshopUploader.Models
{
public class DTO_QueueItem : DTO_Base
@@ -13,6 +23,13 @@ namespace BodyshopUploader.Models
}
private SourceSystem _source;
public SourceSystem Source
{
get { return _source; }
set { SetProperty(ref _source, value); }
}
private dynamic _job;
public dynamic Job
{

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BodyshopUploader.Models
{
public class Monitor : DTO_Base
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
public Monitor()
{
}
private SourceSystem _source;
public SourceSystem Source
{
get { return _source; }
set { SetProperty(ref _source, value); }
}
private string _filePath;
public string FilePath
{
get { return _filePath; }
set { SetProperty(ref _filePath, value); }
}
private string _status;
public string Status
{
get { return _status; }
set { SetProperty(ref _status, value); }
}
private Utils.CIECAMonitor _folderMonitor;
public Utils.CIECAMonitor FolderMonitor
{
get { return _folderMonitor; }
set { SetProperty(ref _folderMonitor, value); }
}
public void StartMonitor()
{
logger.Debug("Starting folder monitor for path {0}", FilePath);
System.IO.Directory.CreateDirectory(FilePath);
FolderMonitor = new Utils.CIECAMonitor(FilePath);
}
public void StopMonitor()
{
logger.Debug("Stopping folder monitor for path {0}", FilePath);
FolderMonitor?.Dispose();
}
}
}

View File

@@ -114,6 +114,24 @@ namespace BodyshopUploader.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to File Path.
/// </summary>
public static string Label_FilePath {
get {
return ResourceManager.GetString("Label_FilePath", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Source System.
/// </summary>
public static string Label_SourceSystem {
get {
return ResourceManager.GetString("Label_SourceSystem", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Start All Monitors.
/// </summary>
@@ -141,6 +159,15 @@ namespace BodyshopUploader.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to New Job Uploaded.
/// </summary>
public static string Msg_NewJobUploaded {
get {
return ResourceManager.GetString("Msg_NewJobUploaded", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Password.
/// </summary>

View File

@@ -135,6 +135,12 @@
<data name="Label_AddMonitoringPath" xml:space="preserve">
<value>Add Path</value>
</data>
<data name="Label_FilePath" xml:space="preserve">
<value>File Path</value>
</data>
<data name="Label_SourceSystem" xml:space="preserve">
<value>Source System</value>
</data>
<data name="Label_StartAllMonitors" xml:space="preserve">
<value>Start All Monitors</value>
</data>
@@ -144,6 +150,9 @@
<data name="Login" xml:space="preserve">
<value>Login</value>
</data>
<data name="Msg_NewJobUploaded" xml:space="preserve">
<value>New Job Uploaded</value>
</data>
<data name="Password" xml:space="preserve">
<value>Password</value>
</data>

View File

@@ -49,9 +49,9 @@ namespace BodyshopUploader.Properties {
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("C:\\ImEX\r\nC:\\000")]
public global::System.Collections.ObjectModel.ObservableCollection<System.String> MonitoringPaths {
public global::System.Collections.Generic.List<System.String> MonitoringPaths {
get {
return ((global::System.Collections.ObjectModel.ObservableCollection<System.String>)(this["MonitoringPaths"]));
return ((global::System.Collections.Generic.List<System.String>)(this["MonitoringPaths"]));
}
set {
this["MonitoringPaths"] = value;

View File

@@ -8,7 +8,7 @@
<Setting Name="Password" Type="System.Security.SecureString" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="MonitoringPaths" Type="System.Collections.ObjectModel.ObservableCollection&lt;System.String&gt;" Scope="User">
<Setting Name="MonitoringPaths" Type="System.Collections.Generic.List&lt;System.String&gt;" Scope="User">
<Value Profile="(Default)">C:\ImEX
C:\000</Value>
</Setting>

View File

@@ -43,7 +43,7 @@ namespace BodyshopUploader.Utils
//Deleted += Watcher_Deleted;
//Renamed += Watcher_Renamed;
Error += Wathcer_Error;
logger.Debug("CIECA Folder watcher started for path: {0}", Path);
logger.Debug("CIECA Folder watcher initialized for path: {0}", Path);
}
private void Wathcer_Error(object sender, ErrorEventArgs e)

View File

@@ -23,11 +23,9 @@ namespace BodyshopUploader.Utils.Decoder
/// <returns></returns>
public static dynamic DecodeEstimate(string FilePath)
{
//Sleep the thread so that all files can finish writing.
Thread.Sleep(1000);
dynamic ret = new JObject();
ret.CiecaId = Path.GetFileNameWithoutExtension(FilePath);
ret.ciecaid = Path.GetFileNameWithoutExtension(FilePath);
string _dir = Path.GetDirectoryName(FilePath) + @"\";
@@ -42,18 +40,18 @@ namespace BodyshopUploader.Utils.Decoder
public static void ParseAd1File(ref dynamic j, string RootFilePath)
{
if (string.IsNullOrWhiteSpace(j.CiecaId.Value))
if (string.IsNullOrWhiteSpace(j.ciecaid.Value))
{
return;
}
logger.Trace(@"Parsing AD1 at: {0}{1}", RootFilePath, j.CiecaId.Value);
logger.Trace(@"Parsing AD1 at: {0}{1}", RootFilePath, j.ciecaid.Value);
int retryNumber = 0;
while (retryNumber < 11)
{
try
{
using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + "A.ad1", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + "A.ad1", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var reader = new DBFReader(fis);
reader.SetSelectFields(new string[] { "INS_CO_NM", "CLM_NO", "OWNR_LN", "OWNR_FN", "OWNR_EA", "OWNR_PH1" });
@@ -80,16 +78,16 @@ namespace BodyshopUploader.Utils.Decoder
public static void ParseVehFile(ref dynamic j, string RootFilePath)
{
if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) { return; }
if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; }
logger.Trace(@"Parsing Veh at: {0}{1}", RootFilePath, j.CiecaId.Value);
logger.Trace(@"Parsing Veh at: {0}{1}", RootFilePath, j.ciecaid.Value);
int retryNumber = 0;
while (retryNumber < 11)
{
try
{
using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + "v.veh", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + "v.veh", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var reader = new DBFReader(fis);
reader.SetSelectFields(new string[] { "V_MODEL_YR", "V_MAKEDESC", "V_MODEL", "V_COLOR", "PLATE_NO", "V_VIN" });
@@ -115,9 +113,9 @@ namespace BodyshopUploader.Utils.Decoder
public static void ParseTtlFile(ref dynamic j, string RootFilePath)
{
if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) { return; }
if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; }
logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.CiecaId.Value);
logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.ciecaid.Value);
@@ -126,7 +124,7 @@ namespace BodyshopUploader.Utils.Decoder
{
try
{
using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + ".ttl", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + ".ttl", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var reader = new DBFReader(fis);
reader.SetSelectFields(new string[] { "G_TTL_AMT" });
@@ -146,9 +144,9 @@ namespace BodyshopUploader.Utils.Decoder
public static void ParseStlFile(ref dynamic j, string RootFilePath)
{
if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) { return; }
if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; }
logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.CiecaId.Value);
logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.ciecaid.Value);
@@ -157,7 +155,7 @@ namespace BodyshopUploader.Utils.Decoder
{
try
{
using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + ".stl", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + ".stl", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var reader = new DBFReader(fis);
reader.SetSelectFields(new string[] { "TTL_TYPECD", "T_HRS" });
@@ -192,9 +190,9 @@ namespace BodyshopUploader.Utils.Decoder
public static void ParseLinFile(ref dynamic j, string RootFilePath)
{
if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) { return; }
if (string.IsNullOrWhiteSpace(j.ciecaid.Value)) { return; }
logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.CiecaId.Value);
logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.ciecaid.Value);
//j.JobSublets = new List<JobSublet>();
string _maxSupp = "";
@@ -204,7 +202,7 @@ namespace BodyshopUploader.Utils.Decoder
{
try
{
using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + ".lin", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (Stream fis = File.Open(RootFilePath + j.ciecaid.Value + ".lin", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var reader = new DBFReader(fis);
reader.SetSelectFields(new string[] { "PART_TYPE", "LINE_DESC", "UNQ_SEQ", "LINE_IND" });

View File

@@ -6,13 +6,11 @@
xmlns:local="clr-namespace:BodyshopUploader.Utils.Growls"
mc:Ignorable="d"
SizeToContent="WidthAndHeight"
AllowsTransparency="True"
WindowStyle="None"
ShowInTaskbar="False"
Topmost="True"
UseLayoutRounding="True"
Title="BodyshopUploader Notification"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
@@ -37,9 +35,9 @@
Background="Transparent"
SizeChanged="NotificationWindowSizeChanged">
<Border Name="border"
Background="#2a3345"
Background="#808080"
BorderThickness="0"
CornerRadius="10"
CornerRadius="4"
Margin="10">
<Border.Effect>
<DropShadowEffect ShadowDepth="0"
@@ -128,8 +126,8 @@
From="1"
To="0"
Storyboard.TargetProperty="Opacity"
Duration="0:0:2"
BeginTime="0:0:3" />
Duration="0:0:1"
BeginTime="0:0:2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>

View File

@@ -36,19 +36,6 @@ namespace BodyshopUploader.Utils.Growls
}
}
private int threadid;
public int ThreadId
{
get { return threadid; }
set
{
if (threadid == value) return;
threadid = value;
OnPropertyChanged("ThreadId");
}
}
private string imageUrl;
public string ImageUrl
{

View File

@@ -7,6 +7,7 @@ using System.Threading;
using System.Threading.Tasks;
using BodyshopUploader.Utils;
using BodyshopUploader.Models;
using BodyshopUploader.Utils.Growls;
namespace BodyshopUploader.Utils
{
@@ -15,6 +16,12 @@ namespace BodyshopUploader.Utils
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private static Queue<DTO_QueueItem> _jobs = new Queue<DTO_QueueItem>();
private static bool _delegateQueuedOrRunning = false;
private static GrowlNotification Growler;
public static void SetGrowler(GrowlNotification g)
{
Growler = g;
}
public static void Enqueue(DTO_QueueItem item)
{
@@ -60,9 +67,10 @@ namespace BodyshopUploader.Utils
DecodeQueueItemJob(item);
UpsertQueueItem(item);
}
catch
catch (Exception ex)
{
ThreadPool.UnsafeQueueUserWorkItem(ProcessQueuedItems, null);
logger.Error(ex, "Error processing job queue item. ");
throw;
}
}
@@ -79,7 +87,17 @@ namespace BodyshopUploader.Utils
{
//Save the job to the DB.
logger.Info("Should upsert the job graphqlly here. {0}", item.Job);
App.Current.Dispatcher.Invoke(() =>
{
Growler.AddNotification(new Notification()
{
Title = Properties.Resources.Msg_NewJobUploaded,
Subtitle = item.Job?.owner?.first_name?.Value + " " + item.Job?.owner?.last_name?.Value,
Message = item.Job?.vehicle?.v_model_yr?.Value + " " + item.Job?.vehicle?.v_make_desc?.Value + " " + item.Job?.vehicle?.v_model_desc?.Value
});
});
_jobs.Dequeue();
}

View File

@@ -63,8 +63,8 @@ namespace BodyshopUploader.ViewModels
if (_removeMonitoringPathCommand == null)
{
_removeMonitoringPathCommand = new RelayCommand(
p => FolderMonitors.Count == 0,
p => RemoveFolderMonitoringPath(p as string)
p => true,
p => RemoveFolderMonitoringPath(p as Models.Monitor)
);
}
return _removeMonitoringPathCommand;
@@ -95,7 +95,7 @@ namespace BodyshopUploader.ViewModels
if (_stopFolderMonitorsCommand == null)
{
_stopFolderMonitorsCommand = new RelayCommand(
p => FolderMonitors.Count > 0,
p => MonitoringPaths.Count > 0,
p => StopAllFolderMonitors()
);
}

View File

@@ -1,4 +1,5 @@
using BodyshopUploader.Utils.Growls;
using BodyshopUploader.Models;
using BodyshopUploader.Utils.Growls;
using GraphQL.Client;
using GraphQL.Common.Request;
using System;
@@ -17,12 +18,18 @@ namespace BodyshopUploader.ViewModels
public MainViewModel()
{
logger.Trace("Main VM Created.");
Growler = new GrowlNotification(this);
Utils.JobProcessingQueue.SetGrowler(Growler);
//Create Variables
if (MonitoringPaths == null) MonitoringPaths = new ObservableCollection<string>();
//Restore list of paths, convert to monitor object.
List<string> listOfPaths = Properties.Settings.Default.MonitoringPaths;
if (listOfPaths == null) listOfPaths = new List<string>();
foreach (var p in listOfPaths)
{
MonitoringPaths.Add(new Models.Monitor() { FilePath = p });
}
MonitoringPaths.CollectionChanged += MonitoringPathsChanged;
logger.Trace("Main VM Created.");
}
private void MonitoringPathsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
@@ -36,42 +43,43 @@ namespace BodyshopUploader.ViewModels
if (dialog.ShowDialog().GetValueOrDefault())
{
logger.Debug("Adding folder {0} to monitoring paths.", dialog.SelectedPath);
MonitoringPaths.Add(dialog.SelectedPath);
Properties.Settings.Default.MonitoringPaths = MonitoringPaths;
MonitoringPaths.Add(new Models.Monitor() { FilePath = dialog.SelectedPath });
Properties.Settings.Default.MonitoringPaths = MonitoringPaths.Select(x => x.FilePath).ToList(); ;
Properties.Settings.Default.Save();
}
}
public void RemoveFolderMonitoringPath(string Path)
public void RemoveFolderMonitoringPath(Monitor m)
{
logger.Debug("Removing folder {0} to monitoring paths.", Path);
MonitoringPaths.Remove(Path);
Properties.Settings.Default.MonitoringPaths = MonitoringPaths;
logger.Debug("Removing folder {0} to monitoring paths.", m.FilePath);
m.StopMonitor();
MonitoringPaths.Remove(m);
Properties.Settings.Default.MonitoringPaths = MonitoringPaths.Select(x => x.FilePath).ToList();
Properties.Settings.Default.Save();
}
public void StartAllFolderMonitors()
{
if (FolderMonitors.Count > 0)
foreach (var m in FolderMonitors)
if (MonitoringPaths.Count > 0)
foreach (var m in MonitoringPaths)
{
m.Dispose();
m.StopMonitor();
}
foreach (var p in MonitoringPaths)
{
//Ensure the directory exists, then start monitoring for CIECA files.
System.IO.Directory.CreateDirectory(p);
FolderMonitors.Add(new Utils.CIECAMonitor(p));
p.StartMonitor();
}
}
public void StopAllFolderMonitors()
{
if (FolderMonitors.Count > 0)
foreach (var m in FolderMonitors)
if (MonitoringPaths.Count > 0)
foreach (var m in MonitoringPaths)
{
m.Dispose();
m.StopMonitor();
}
}
@@ -80,7 +88,6 @@ namespace BodyshopUploader.ViewModels
Notification _n = new Notification()
{
Id = 123,
ThreadId = 123,
Title = "This is a title",
Subtitle = "Subtitle",
Message = "Somethin"

View File

@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BodyshopUploader.Utils.Growls;
using BodyshopUploader.Models;
namespace BodyshopUploader.ViewModels
{
@@ -12,15 +13,8 @@ namespace BodyshopUploader.ViewModels
{
public GrowlNotification Growler;
private ObservableCollection<Utils.CIECAMonitor> _folderMonitors = new ObservableCollection<Utils.CIECAMonitor>() ;
public ObservableCollection<Utils.CIECAMonitor> FolderMonitors
{
get { return _folderMonitors; }
set { SetProperty(ref _folderMonitors, value); }
}
private ObservableCollection<string> _monitoringPaths = Properties.Settings.Default.MonitoringPaths ;
public ObservableCollection<string> MonitoringPaths
private ObservableCollection<Monitor> _monitoringPaths = new ObservableCollection<Monitor>();
public ObservableCollection<Monitor> MonitoringPaths
{
get { return _monitoringPaths; }
set { SetProperty(ref _monitoringPaths, value); }

View File

@@ -68,12 +68,38 @@
</Button>
<StackPanel DockPanel.Dock="Right">
<Button Command="{Binding StartFolderMonitorsCommand}"
Content="{x:Static p:Resources.Label_StartAllMonitors}"/>
Content="{x:Static p:Resources.Label_StartAllMonitors}" />
<Button Command="{Binding StopFolderMonitorsCommand}"
Content="{x:Static p:Resources.Label_StopAllMonitors}" />
</StackPanel>
<ItemsControl ItemsSource="{Binding MonitoringPaths}">
<DataGrid ItemsSource="{Binding MonitoringPaths}"
AutoGenerateColumns="False"
CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding FilePath}"
Header="{x:Static p:Resources.Label_FilePath}" />
<DataGridTextColumn Binding="{Binding Source}"
Header="{x:Static p:Resources.Label_SourceSystem}" />
<DataGridTemplateColumn Header="1">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}"
Command="{Binding DataContext.RemoveMonitoringPathCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
CommandParameter="{Binding .}">
<materialDesign:PackIcon Kind="RemoveCircle"
Height="24"
Width="24" />
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<!--<ItemsControl ItemsSource="{Binding MonitoringPaths}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
@@ -100,6 +126,6 @@
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ItemsControl>-->
</DockPanel>
</Window>