From 4e6446b7445882be30e5b5476e13f12004723178 Mon Sep 17 00:00:00 2001 From: Rikki Tooley Date: Fri, 3 Apr 2015 17:34:28 +0100 Subject: [PATCH] Syro now saves/loads session state to solution directory --- src/IF.Lastfm.Syro/IF.Lastfm.Syro.csproj | 1 + src/IF.Lastfm.Syro/Pages/MainPage.xaml | 28 ++- src/IF.Lastfm.Syro/ViewModels/MainState.cs | 123 ++++++++++ .../ViewModels/MainViewModel.cs | 226 ++++++++---------- 4 files changed, 241 insertions(+), 137 deletions(-) create mode 100644 src/IF.Lastfm.Syro/ViewModels/MainState.cs diff --git a/src/IF.Lastfm.Syro/IF.Lastfm.Syro.csproj b/src/IF.Lastfm.Syro/IF.Lastfm.Syro.csproj index e08a6d6..d748bc6 100644 --- a/src/IF.Lastfm.Syro/IF.Lastfm.Syro.csproj +++ b/src/IF.Lastfm.Syro/IF.Lastfm.Syro.csproj @@ -108,6 +108,7 @@ + diff --git a/src/IF.Lastfm.Syro/Pages/MainPage.xaml b/src/IF.Lastfm.Syro/Pages/MainPage.xaml index 9740011..3fac78d 100644 --- a/src/IF.Lastfm.Syro/Pages/MainPage.xaml +++ b/src/IF.Lastfm.Syro/Pages/MainPage.xaml @@ -5,8 +5,6 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" xmlns:viewModels="clr-namespace:IF.Lastfm.Syro.ViewModels" - xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" - xmlns:objectModel="clr-namespace:System.Collections.ObjectModel;assembly=System" mc:Ignorable="d" d:DataContext="{d:DesignInstance viewModels:MainViewModel}" d:DesignWidth="400" d:DesignHeight="308"> @@ -30,17 +28,17 @@ + Text="{Binding State.CommandMethodName, Mode=TwoWay}"/> @@ -74,7 +72,7 @@ Style="{StaticResource SyroNormalFontStyle}" Margin="10,0"/> + Text="{Binding State.CommandPageNumber, Mode=TwoWay}"/> @@ -87,7 +85,7 @@ Style="{StaticResource SyroNormalFontStyle}" Margin="10,0"/> + Text="{Binding State.CommandItemCount, Mode=TwoWay}"/> @@ -179,20 +177,26 @@ - + - - + + + Config is automatically saved to (SolutionDir)/syro.json on exit. diff --git a/src/IF.Lastfm.Syro/ViewModels/MainState.cs b/src/IF.Lastfm.Syro/ViewModels/MainState.cs new file mode 100644 index 0000000..4dce619 --- /dev/null +++ b/src/IF.Lastfm.Syro/ViewModels/MainState.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using IF.Lastfm.Syro.Helpers; + +namespace IF.Lastfm.Syro.ViewModels +{ + internal class MainState : ViewModelBase + { + private Type _selectedLastObjectType; + private Type _selectedResponseType; + private Type _selectedCommandType; + + private string _lastPassword; + private string _lastUsername; + + private string _commandMethodName; + private string _commandPageNumber; + private string _commandItemCount; + + private Dictionary _commandParameters; + + public string CommandMethodName + { + get { return _commandMethodName; } + set + { + if (value == _commandMethodName) return; + _commandMethodName = value; + OnPropertyChanged(); + } + } + + public string CommandPageNumber + { + get { return _commandPageNumber; } + set + { + if (value == _commandPageNumber) return; + _commandPageNumber = value; + OnPropertyChanged(); + } + } + + public string CommandItemCount + { + get { return _commandItemCount; } + set + { + if (value == _commandItemCount) return; + _commandItemCount = value; + OnPropertyChanged(); + } + } + + public Type SelectedResponseType + { + get { return _selectedResponseType; } + set + { + if (value == _selectedResponseType) return; + _selectedResponseType = value; + OnPropertyChanged(); + } + } + + public Type SelectedLastObjectType + { + get { return _selectedLastObjectType; } + set + { + if (value == _selectedLastObjectType) return; + _selectedLastObjectType = value; + OnPropertyChanged(); + } + } + + public Type SelectedBaseCommandType + { + get { return _selectedCommandType; } + set + { + if (value == _selectedCommandType) return; + + _selectedCommandType = value; + OnPropertyChanged(); + } + } + + public string LastUsername + { + get { return _lastUsername; } + set + { + if (value == _lastUsername) return; + _lastUsername = value; + OnPropertyChanged(); + } + } + + public string LastPassword + { + get { return _lastPassword; } + set + { + if (value == _lastPassword) return; + _lastPassword = value; + OnPropertyChanged(); + } + } + + public Dictionary CommandParameters + { + get { return _commandParameters; } + set + { + if (Equals(value, _commandParameters)) return; + _commandParameters = value; + OnPropertyChanged(); + } + } + } +} \ No newline at end of file diff --git a/src/IF.Lastfm.Syro/ViewModels/MainViewModel.cs b/src/IF.Lastfm.Syro/ViewModels/MainViewModel.cs index aaad15a..ab86e3a 100644 --- a/src/IF.Lastfm.Syro/ViewModels/MainViewModel.cs +++ b/src/IF.Lastfm.Syro/ViewModels/MainViewModel.cs @@ -13,7 +13,9 @@ using System.Linq; using System.Reflection; using System.Threading.Tasks; +using System.Windows; using System.Windows.Input; +using Newtonsoft.Json.Linq; namespace IF.Lastfm.Syro.ViewModels { @@ -24,25 +26,21 @@ internal class MainViewModel : ViewModelBase private List _remainingCommands; private int _apiProgress; private string _reportPath; - private Type _selectedCommandType; - private ObservableCollection> _commandParameters; - private Type _selectedLastObjectType; - private bool _executingCommand; - private Type _selectedResponseType; private ILastAuth _lastAuth; + private bool _executingCommand; private string _commandResult; - private string _commandMethodName; - private string _commandPageNumber; - private string _commandItemCount; - private string _lastPassword; - private string _lastUsername; + private const string SYRO_CONFIG_FILENAME = "syro.json"; private const string ReportFilename = "PROGRESS.md"; + private MainState _state; + private string _configPath; + private ObservableCollection> _commandParameters; #region Binding properties public ICommand GenerateProgressReportCommand { get; private set; } public ICommand OpenReportCommand { get; private set; } public ICommand ExecuteSelectedCommandCommand { get; private set; } + public ICommand DeleteConfigCommand { get; private set; } public string CommandResult { @@ -99,42 +97,30 @@ public List RemainingCommands } } - public IEnumerable BaseCommandTypes { get; private set; } - - public Type SelectedBaseCommandType + public MainState State { - get { return _selectedCommandType; } + get { return _state; } set { - if (value == _selectedCommandType) return; - - _selectedCommandType = value; + if (Equals(value, _state)) return; + _state = value; OnPropertyChanged(); } } + public IEnumerable BaseCommandTypes { get; private set; } + public IEnumerable LastObjectTypes { get; private set; } - public Type SelectedLastObjectType - { - get { return _selectedLastObjectType; } - set - { - if (value == _selectedLastObjectType) return; - _selectedLastObjectType = value; - OnPropertyChanged(); - } - } - public IEnumerable LastResponseTypes { get; private set; } - - public Type SelectedResponseType + + public bool ExecutingCommand { - get { return _selectedResponseType; } + get { return _executingCommand; } set { - if (value == _selectedResponseType) return; - _selectedResponseType = value; + if (value.Equals(_executingCommand)) return; + _executingCommand = value; OnPropertyChanged(); } } @@ -150,72 +136,6 @@ public ObservableCollection> CommandParameters } } - public bool ExecutingCommand - { - get { return _executingCommand; } - set - { - if (value.Equals(_executingCommand)) return; - _executingCommand = value; - OnPropertyChanged(); - } - } - - public string CommandMethodName - { - get { return _commandMethodName; } - set - { - if (value == _commandMethodName) return; - _commandMethodName = value; - OnPropertyChanged(); - } - } - - public string CommandPageNumber - { - get { return _commandPageNumber; } - set - { - if (value == _commandPageNumber) return; - _commandPageNumber = value; - OnPropertyChanged(); - } - } - - public string CommandItemCount - { - get { return _commandItemCount; } - set - { - if (value == _commandItemCount) return; - _commandItemCount = value; - OnPropertyChanged(); - } - } - - public string LastUsername - { - get { return _lastUsername; } - set - { - if (value == _lastUsername) return; - _lastUsername = value; - OnPropertyChanged(); - } - } - - public string LastPassword - { - get { return _lastPassword; } - set - { - if (value == _lastPassword) return; - _lastPassword = value; - OnPropertyChanged(); - } - } - #endregion public MainViewModel(ILastAuth lastAuth) @@ -225,34 +145,90 @@ public MainViewModel(ILastAuth lastAuth) GenerateProgressReportCommand = new AsyncDelegateCommand(GenerateProgressReport); OpenReportCommand = new DelegateCommand(OpenProgressReport); ExecuteSelectedCommandCommand = new AsyncDelegateCommand(ExecuteSelectedCommand); + DeleteConfigCommand = new DelegateCommand(() => + { + if (_configPath != null && File.Exists(_configPath)) + { + File.Delete(_configPath); + } + + InitialiseState(); + }); var currentDir = AppDomain.CurrentDomain.BaseDirectory; SolutionDir = Path.GetFullPath(currentDir + "../../../../"); // assuming this is running in debug dir + _configPath = Path.GetFullPath(SolutionDir + SYRO_CONFIG_FILENAME); BaseCommandTypes = new List { typeof(DummyGetAsyncCommand<>), typeof(DummyPostAsyncCommand<>) }; - LastObjectTypes = Reflektor.FindClassesCastableTo(typeof (ILastfmObject)); - LastResponseTypes = Reflektor.FindClassesCastableTo(typeof (LastResponse)); + LastObjectTypes = Reflektor.FindClassesCastableTo(typeof(ILastfmObject)); + LastResponseTypes = Reflektor.FindClassesCastableTo(typeof(LastResponse)); - SelectedBaseCommandType = BaseCommandTypes.FirstOrDefault(); - SelectedLastObjectType = LastObjectTypes.FirstOrDefault(); - SelectedResponseType = LastResponseTypes.FirstOrDefault(); + InitialiseState(); - CommandParameters = new ObservableCollection>(new List> + Application.Current.Exit += OnAppExit; + } + + private void InitialiseState() + { + var state = LoadState(); + var pairs = state.CommandParameters != null + ? state.CommandParameters.Select(kv => new Pair(kv.Key, kv.Value)) + : Enumerable.Repeat(new Pair(), 5); + + State = state; + CommandParameters = new ObservableCollection>(pairs); + } + + private void OnAppExit(object sender, ExitEventArgs e) + { + var json = JsonConvert.SerializeObject(_state); + var lines = new[] { - new Pair(), - new Pair(), - new Pair(), - new Pair(), - new Pair() - }); + json + }; - CommandMethodName = "album.getInfo"; - CommandPageNumber = "0"; - CommandItemCount = "20"; + File.WriteAllLines(_configPath, lines); + } + + public MainState LoadState() + { + MainState state = null; + if (File.Exists(_configPath)) + { + try + { + var json = File.ReadAllText(_configPath); + state = JsonConvert.DeserializeObject(json); + } + catch + { + state = null; + } + } + + if (state == null) + { + state = new MainState + { + SelectedBaseCommandType = BaseCommandTypes.FirstOrDefault(), + SelectedLastObjectType = LastObjectTypes.FirstOrDefault(), + SelectedResponseType = LastResponseTypes.FirstOrDefault(), + + CommandParameters = new Dictionary{ + {"album", "The Fall of Math"}, + {"artist", "65daysofstatic"} + }, + CommandMethodName = "album.getInfo", + CommandPageNumber = "0", + CommandItemCount = "20", + }; + } + + return state; } private async Task ExecuteSelectedCommand() @@ -267,13 +243,13 @@ private async Task ExecuteSelectedCommand() try { // build up the command> - var responseType = SelectedResponseType.MakeGenericType(SelectedLastObjectType); - var genericType = SelectedBaseCommandType.MakeGenericType(responseType); + var responseType = _state.SelectedResponseType.MakeGenericType(_state.SelectedLastObjectType); + var genericType = _state.SelectedBaseCommandType.MakeGenericType(responseType); - if ((_lastAuth.UserSession == null || _lastAuth.UserSession.Username != LastUsername) - && SelectedBaseCommandType == typeof (DummyPostAsyncCommand<>)) + if ((_lastAuth.UserSession == null || _lastAuth.UserSession.Username != _state.LastUsername) + && _state.SelectedBaseCommandType == typeof(DummyPostAsyncCommand<>)) { - await _lastAuth.GetSessionTokenAsync(LastUsername, LastPassword); + await _lastAuth.GetSessionTokenAsync(_state.LastUsername, _state.LastPassword); } var instance = Activator.CreateInstance(genericType, _lastAuth); @@ -283,15 +259,16 @@ private async Task ExecuteSelectedCommand() .ToDictionary(pair => pair.Key, pair => pair.Value); var methodProperty = genericType.GetProperty("Method", BindingFlags.Public | BindingFlags.Instance); - methodProperty.SetValue(instance, CommandMethodName); + methodProperty.SetValue(instance, _state.CommandMethodName); - if (SelectedResponseType == typeof(PageResponse<>)) + if (_state.SelectedResponseType == typeof(PageResponse<>) + || _state.CommandMethodName.EndsWith("s")) // yolo { var pageProperty = genericType.GetProperty("Page", BindingFlags.Public | BindingFlags.Instance); - pageProperty.SetValue(instance, int.Parse(CommandPageNumber)); + pageProperty.SetValue(instance, int.Parse(_state.CommandPageNumber)); var countProperty = genericType.GetProperty("Count", BindingFlags.Public | BindingFlags.Instance); - countProperty.SetValue(instance, int.Parse(CommandItemCount)); + countProperty.SetValue(instance, int.Parse(_state.CommandItemCount)); } var parametersProperty = genericType.GetProperty("Parameters", @@ -309,8 +286,7 @@ private async Task ExecuteSelectedCommand() var formattedJson = jo.ToString(Formatting.Indented); // writeout to file - var filename = string.Format("syro-{0}-{1}.json", jo.Properties().First().Name, - DateTime.Now.ToString("yyMMdd-HHmmss")); + var filename = string.Format("syro-{0}-{1}.json", _state.CommandMethodName.Replace(".", "-"), DateTime.Now.ToString("yyMMdd-HHmmss")); var tempDirPath = Path.GetFullPath(SolutionDir + "tmp/"); if (!Directory.Exists(tempDirPath))