diff --git a/WordByWord/WordByWord.Test/LibraryTests.cs b/WordByWord/WordByWord.Test/LibraryTests.cs index 173dccd..b9d3569 100644 --- a/WordByWord/WordByWord.Test/LibraryTests.cs +++ b/WordByWord/WordByWord.Test/LibraryTests.cs @@ -1,8 +1,12 @@ -using CommonServiceLocator; +using System.Collections.Generic; +using System.IO; +using CommonServiceLocator; using GalaSoft.MvvmLight.Ioc; using MahApps.Metro.Controls.Dialogs; using Microsoft.VisualStudio.TestTools.UnitTesting; -using WordByWord.Helpers; +using Newtonsoft.Json; +using WordByWord.Models; +using WordByWord.Services; namespace WordByWord.Test { @@ -24,10 +28,50 @@ public static void TestSetup(TestContext testContext) } [TestMethod] - public void ImageCharacterRecognitionTest() + public void ImageCharacterRecognitionTest()//Must be run in debug! { string ocrResult = _viewModel.GetTextFromImage(@"TestFiles\LockeEssay.PNG"); Assert.IsTrue(ocrResult.Length > 0); } + + [TestMethod] + public void LibrarySaveAndLoadTest() + { + OcrDocument doc1 = new OcrDocument("g") + { + FileName = "Hello!", + IsBusy = false, + IsEditingFileName = false, + OcrText = "g" + }; + + OcrDocument doc2 = new OcrDocument("C:\\Users\\dan\\Pictures\\GDB.PNG") + { + FileName = "GDB.PNG", + OcrText = "00081 Oxbfffea68 --> 0x342\r\n\r\n00121 0xbfffea6c --> 0xbfffed24 --> 0xbfffef2b (\"/h0me/seed/Desktop/exploit\")\r\n00161 0xbfffea70 --> Oxb7fe3d39 (: add ebx,0xlb2c7)\r\n00201 Oxbfffea74 --> Oxb7bf73d0 --> 0X94b90ca0\r\n\r\n00241 0xbfffea78 --> 0x53d\r\n\r\n00281 0xbfffea7c --> 0xb7ffd5b0 --> Oxb7bf3000 --> 0x464c457f\r\n\r\n[ ------------------------------------------------------------------------------ ]\r\n\r\nLegend: code, data, rodata, value\r\n\r\nBreakpoint 1, main (argc=0x1, argv=0xbfffed24) at exploit.c:25\r\n25 memset(&buffer, 0x90, 500);\r\n\r\ngdb-peda$ p &buffer\r\n\r\n$1 = (char (*)[500]) Oxbfffea78\r\n\r\ngdb-peda$ p $ebp\r\n\r\n$2 = (void *) 0xbfffec78\r\n\r\ngdb-peda$ p 0xbfffec78 .. 0xbfffea78\r\n\r\n$3 = OXZOO", + IsBusy = false, + IsEditingFileName = false + }; + + OcrDocument doc3 = new OcrDocument("C:\\Users\\dan\\Pictures\\GDB2.PNG") + { + FileName = "GDB2.PNG", + OcrText = "(gdb) info frame\r\nStack level. 0, frame at 0xbfffeae0:\r\n\r\neip = 0x80484c1 in bof (stack.c:11); saved eip = 0x804852e\r\ncalled by frame at OxbfffedIO\r\n\r\nsource language c.\r\nArglist at Oxbfffead8, args:\r\n\r\nstr=0xbfffeaf8 \"1N300Ph//shh/bin\\211N343PS\\211.'Nj\"\r\n\r\nLocals at Oxbfffead8, Previous frame's sp is Oxbfffeae0\r\nSaved registers:\r\n\r\nebp at Oxbfffead8, eip at Oxbfffeadc", + IsBusy = false, + IsEditingFileName = false + }; + + List testLibrary = new List { doc1, doc2, doc3 }; + + string serializedTestLibrary = JsonConvert.SerializeObject(testLibrary, Formatting.Indented); + + Assert.AreEqual(File.ReadAllText(@"TestFiles\library.json"), serializedTestLibrary); + + List deserializedLibrary = + JsonConvert.DeserializeObject>(File.ReadAllText(@"TestFiles\library.json")); + + Assert.IsNotNull(deserializedLibrary); + Assert.AreEqual(testLibrary.Count, deserializedLibrary.Count); + } } } diff --git a/WordByWord/WordByWord.Test/ReaderTests.cs b/WordByWord/WordByWord.Test/ReaderTests.cs index 348b7d7..b2816fc 100644 --- a/WordByWord/WordByWord.Test/ReaderTests.cs +++ b/WordByWord/WordByWord.Test/ReaderTests.cs @@ -4,7 +4,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Collections.Generic; using System.Threading.Tasks; -using WordByWord.Helpers; +using WordByWord.Services; namespace WordByWord.Test { diff --git a/WordByWord/WordByWord.Test/TestFiles/library.json b/WordByWord/WordByWord.Test/TestFiles/library.json new file mode 100644 index 0000000..25ba799 --- /dev/null +++ b/WordByWord/WordByWord.Test/TestFiles/library.json @@ -0,0 +1,23 @@ +[ + { + "FilePath": "g", + "FileName": "Hello!", + "OcrText": "g", + "IsBusy": false, + "IsEditingFileName": false + }, + { + "FilePath": "C:\\Users\\dan\\Pictures\\GDB.PNG", + "FileName": "GDB.PNG", + "OcrText": "00081 Oxbfffea68 --> 0x342\r\n\r\n00121 0xbfffea6c --> 0xbfffed24 --> 0xbfffef2b (\"/h0me/seed/Desktop/exploit\")\r\n00161 0xbfffea70 --> Oxb7fe3d39 (: add ebx,0xlb2c7)\r\n00201 Oxbfffea74 --> Oxb7bf73d0 --> 0X94b90ca0\r\n\r\n00241 0xbfffea78 --> 0x53d\r\n\r\n00281 0xbfffea7c --> 0xb7ffd5b0 --> Oxb7bf3000 --> 0x464c457f\r\n\r\n[ ------------------------------------------------------------------------------ ]\r\n\r\nLegend: code, data, rodata, value\r\n\r\nBreakpoint 1, main (argc=0x1, argv=0xbfffed24) at exploit.c:25\r\n25 memset(&buffer, 0x90, 500);\r\n\r\ngdb-peda$ p &buffer\r\n\r\n$1 = (char (*)[500]) Oxbfffea78\r\n\r\ngdb-peda$ p $ebp\r\n\r\n$2 = (void *) 0xbfffec78\r\n\r\ngdb-peda$ p 0xbfffec78 .. 0xbfffea78\r\n\r\n$3 = OXZOO", + "IsBusy": false, + "IsEditingFileName": false + }, + { + "FilePath": "C:\\Users\\dan\\Pictures\\GDB2.PNG", + "FileName": "GDB2.PNG", + "OcrText": "(gdb) info frame\r\nStack level. 0, frame at 0xbfffeae0:\r\n\r\neip = 0x80484c1 in bof (stack.c:11); saved eip = 0x804852e\r\ncalled by frame at OxbfffedIO\r\n\r\nsource language c.\r\nArglist at Oxbfffead8, args:\r\n\r\nstr=0xbfffeaf8 \"1N300Ph//shh/bin\\211N343PS\\211.'Nj\"\r\n\r\nLocals at Oxbfffead8, Previous frame's sp is Oxbfffeae0\r\nSaved registers:\r\n\r\nebp at Oxbfffead8, eip at Oxbfffeadc", + "IsBusy": false, + "IsEditingFileName": false + } +] \ No newline at end of file diff --git a/WordByWord/WordByWord.Test/WordByWord.Test.csproj b/WordByWord/WordByWord.Test/WordByWord.Test.csproj index 7775b63..afc64af 100644 --- a/WordByWord/WordByWord.Test/WordByWord.Test.csproj +++ b/WordByWord/WordByWord.Test/WordByWord.Test.csproj @@ -63,6 +63,9 @@ ..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + @@ -76,6 +79,9 @@ + + PreserveNewest + diff --git a/WordByWord/WordByWord.Test/packages.config b/WordByWord/WordByWord.Test/packages.config index 055fa14..508cd6d 100644 --- a/WordByWord/WordByWord.Test/packages.config +++ b/WordByWord/WordByWord.Test/packages.config @@ -6,4 +6,5 @@ + \ No newline at end of file diff --git a/WordByWord/WordByWord/App.xaml.cs b/WordByWord/WordByWord/App.xaml.cs index dbb8613..d6ef4eb 100644 --- a/WordByWord/WordByWord/App.xaml.cs +++ b/WordByWord/WordByWord/App.xaml.cs @@ -2,7 +2,7 @@ using CommonServiceLocator; using GalaSoft.MvvmLight.Ioc; using MahApps.Metro.Controls.Dialogs; -using WordByWord.Helpers; +using WordByWord.Services; namespace WordByWord { diff --git a/WordByWord/WordByWord/InputText.xaml.cs b/WordByWord/WordByWord/InputText.xaml.cs index dbccdb7..7522913 100644 --- a/WordByWord/WordByWord/InputText.xaml.cs +++ b/WordByWord/WordByWord/InputText.xaml.cs @@ -1,17 +1,4 @@ using MahApps.Metro.Controls; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; namespace WordByWord { @@ -20,13 +7,10 @@ namespace WordByWord /// public partial class InputText : MetroWindow { - ViewModel.ViewModel _viewModel; - public InputText(ViewModel.ViewModel viewModel) { InitializeComponent(); - _viewModel = viewModel; - this.DataContext = _viewModel; + this.DataContext = viewModel; } } } diff --git a/WordByWord/WordByWord/Library.xaml b/WordByWord/WordByWord/Library.xaml index b678f5b..9348795 100644 --- a/WordByWord/WordByWord/Library.xaml +++ b/WordByWord/WordByWord/Library.xaml @@ -54,7 +54,7 @@ - + diff --git a/WordByWord/WordByWord/Library.xaml.cs b/WordByWord/WordByWord/Library.xaml.cs index cd537ce..a418ea5 100644 --- a/WordByWord/WordByWord/Library.xaml.cs +++ b/WordByWord/WordByWord/Library.xaml.cs @@ -1,6 +1,7 @@ using System.Windows.Input; using CommonServiceLocator; using MahApps.Metro.Controls; +using WordByWord.Models; namespace WordByWord { @@ -29,14 +30,25 @@ private void ListViewItem_MouseDoubleClick(object sender, MouseButtonEventArgs e private void Rename_Click(object sender, System.Windows.RoutedEventArgs e) { - _viewModel.SelectedDocument.IsEditingFileName = true; + if (_viewModel.SelectedDocument != null) + { + OcrDocument listViewDoc = (OcrDocument) LibraryListView.Items[LibraryListView.SelectedIndex]; + if (!_viewModel.SelectedDocument.IsBusy && listViewDoc.FilePath == _viewModel.SelectedDocument.FilePath) + { + _viewModel.SelectedDocument.IsEditingFileName = true; + } + } } private void ListViewItem_KeyDown(object sender, KeyEventArgs e) { - if (e.Key == Key.Enter && _viewModel.SelectedDocument.IsEditingFileName) + if (_viewModel.SelectedDocument != null) { - _viewModel.SelectedDocument.IsEditingFileName = false; + if (e.Key == Key.Enter && _viewModel.SelectedDocument.IsEditingFileName) + { + _viewModel.SelectedDocument.IsEditingFileName = false; + _viewModel.SaveLibrary(); + } } } } diff --git a/WordByWord/WordByWord/Helpers/WindowService.cs b/WordByWord/WordByWord/Services/WindowService.cs similarity index 98% rename from WordByWord/WordByWord/Helpers/WindowService.cs rename to WordByWord/WordByWord/Services/WindowService.cs index a76e7f8..2793e26 100644 --- a/WordByWord/WordByWord/Helpers/WindowService.cs +++ b/WordByWord/WordByWord/Services/WindowService.cs @@ -1,5 +1,5 @@  -namespace WordByWord.Helpers +namespace WordByWord.Services { public interface IWindowService { diff --git a/WordByWord/WordByWord/ViewModel/ViewModel.cs b/WordByWord/WordByWord/ViewModel/ViewModel.cs index 8a99b77..a10f1ed 100644 --- a/WordByWord/WordByWord/ViewModel/ViewModel.cs +++ b/WordByWord/WordByWord/ViewModel/ViewModel.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using GalaSoft.MvvmLight; using System.Collections.ObjectModel; +using System.IO; using System.Linq; using System.Threading.Tasks; using System.Windows; @@ -12,9 +13,10 @@ using Microsoft.Win32; using WordByWord.Models; using MahApps.Metro.Controls.Dialogs; -using WordByWord.Helpers; -using System.Text; +using WordByWord.Services; using System.Text.RegularExpressions; +using Newtonsoft.Json; +using System.Text; namespace WordByWord.ViewModel { @@ -36,6 +38,9 @@ public class ViewModel : ObservableObject private int _numberOfSentences = 1; private int _previousGrouping = 1; + private static readonly string SerializedDataFolderPath = $@"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\word-by-word\"; + private readonly string _serializedLibraryPath = $"{SerializedDataFolderPath}library.json"; + private readonly IDialogCoordinator _dialogService; private readonly IWindowService _windowService; @@ -54,6 +59,8 @@ public ViewModel(IDialogCoordinator dialogService, IWindowService windowService) ConfirmEditCommand = new RelayCommand(ConfirmEdit); ReadSelectedDocumentCommand = new RelayCommand(ReadSelectedDocument, () => !IsBusy); CreateDocFromUserInputCommand = new RelayCommand(CreateDocFromUserInput); + + LoadLibrary(); } #region Properties @@ -83,13 +90,16 @@ public int NumberOfSentences set { Set(() => NumberOfSentences, ref _numberOfSentences, value); - switch(value) + switch (value) { - case 1: ReaderFontSize = 30; + case 1: + ReaderFontSize = 30; break; - case 2: ReaderFontSize = 20; + case 2: + ReaderFontSize = 20; break; - case 3: ReaderFontSize = 20; + case 3: + ReaderFontSize = 20; break; } } @@ -111,7 +121,7 @@ public int NumberOfGroups { Set(() => NumberOfGroups, ref _numberOfGroups, value); CurrentWord = string.Empty; - switch(value) + switch (value) { case 1: ReaderFontSize = 50; @@ -254,6 +264,7 @@ private async void UploadImage_Click(object sender, RoutedEventArgs e) if (filePaths.Count > 0) { await RunOcrOnFiles(filePaths); + SaveLibrary(); } } } @@ -262,17 +273,35 @@ private async void UploadImage_Click(object sender, RoutedEventArgs e) #region Methods + public void SaveLibrary() + { + if (!Directory.Exists(SerializedDataFolderPath)) + { + Directory.CreateDirectory(SerializedDataFolderPath); + } + string libraryAsJson = JsonConvert.SerializeObject(_library.Where(doc => !doc.IsBusy), Formatting.Indented); + File.WriteAllText(_serializedLibraryPath, libraryAsJson, Encoding.UTF8); + } + + public void LoadLibrary() + { + string serializedLibraryFile = Directory.GetFiles(SerializedDataFolderPath).FirstOrDefault(); + if (!string.IsNullOrEmpty(serializedLibraryFile)) + { + Library = JsonConvert.DeserializeObject>(File.ReadAllText(serializedLibraryFile)); + } + } + private void CreateDocFromUserInput() { if (!string.IsNullOrEmpty(UserInputTitle)) { if (Library.All(doc => doc.FileName != UserInputTitle)) { - OcrDocument newDoc = - new OcrDocument(UserInputTitle) //All OcrDocuments must be created with a filePath! - { - OcrText = UserInputBody - }; + OcrDocument newDoc = new OcrDocument(UserInputTitle) //All OcrDocuments must be created with a filePath! + { + OcrText = UserInputBody + }; Library.Add(newDoc); @@ -280,6 +309,8 @@ private void CreateDocFromUserInput() UserInputBody = string.Empty; _windowService.CloseWindow("InputText", this); + + SaveLibrary(); } else { @@ -318,7 +349,7 @@ private async Task ReadSelectedDocumentWordsAsync() if (!string.IsNullOrWhiteSpace(word)) { CurrentWord = word; - await Task.Delay((int) ReaderDelay); + await Task.Delay(ReaderDelay); } } IsBusy = false; @@ -337,7 +368,7 @@ private async Task ReadSelectedDocumentSentencesAsync() if (!string.IsNullOrWhiteSpace(sentence)) { CurrentWord = sentence; - await Task.Delay((int) CalcDelay(sentence)); + await Task.Delay((int)CalcDelay(sentence)); } } IsBusy = false; @@ -382,7 +413,7 @@ await Task.Run(() => groups.Add(group); } }); - + return groups; } @@ -403,6 +434,8 @@ private void ConfirmEdit() Library.Single(doc => doc.FilePath == SelectedDocument.FilePath).OcrText = EditorText; _windowService.CloseWindow("Editor", this); + + SaveLibrary(); } internal void OpenReaderWindow() diff --git a/WordByWord/WordByWord/WordByWord.csproj b/WordByWord/WordByWord/WordByWord.csproj index 6ed857e..11ea6c3 100644 --- a/WordByWord/WordByWord/WordByWord.csproj +++ b/WordByWord/WordByWord/WordByWord.csproj @@ -56,6 +56,9 @@ ..\packages\MahApps.Metro.1.6.5\lib\net46\MahApps.Metro.dll + + ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + @@ -88,7 +91,7 @@ Editor.xaml - + InputText.xaml diff --git a/WordByWord/WordByWord/packages.config b/WordByWord/WordByWord/packages.config index 45371b6..821d918 100644 --- a/WordByWord/WordByWord/packages.config +++ b/WordByWord/WordByWord/packages.config @@ -7,5 +7,6 @@ + \ No newline at end of file