Allow saving report JSON to internal dir

Closes #2
This commit is contained in:
2026-03-03 10:49:06 +09:00
parent abc97eea2b
commit 94cf073012
5 changed files with 107 additions and 22 deletions
+2
View File
@@ -8,6 +8,8 @@ class Constants
public static string[] AllowedFileExtensionPatterns = [ "*.png", "*.jpg", "*.jpeg", "*.gif", "*.bmp", "*.webp", "*.pdf", "*.heic", ]; public static string[] AllowedFileExtensionPatterns = [ "*.png", "*.jpg", "*.jpeg", "*.gif", "*.bmp", "*.webp", "*.pdf", "*.heic", ];
public static string[] AllowedFileExtensionsNoStar = [ "png", "jpg", "jpeg", "gif", "bmp", "webp", "pdf", "heic", ]; public static string[] AllowedFileExtensionsNoStar = [ "png", "jpg", "jpeg", "gif", "bmp", "webp", "pdf", "heic", ];
public static string ReportSavedDataFileName = "report_data.json";
public static string[] GetQuotes() public static string[] GetQuotes()
{ {
// sources: // sources:
+44 -3
View File
@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
@@ -16,6 +17,9 @@ class Settings : ChangeNotifier
private bool _saveOutputPdfInWorkingDir; private bool _saveOutputPdfInWorkingDir;
private string _outputPdfDir; private string _outputPdfDir;
private decimal _imageResizeThreshold; private decimal _imageResizeThreshold;
private bool _saveReportJsonDataInInternalDir;
private Dictionary<string, string> _workingFolderToInternalFolderName;
public int _settingsVersion;
public Settings() public Settings()
{ {
@@ -24,6 +28,9 @@ class Settings : ChangeNotifier
_saveOutputPdfInWorkingDir = true; _saveOutputPdfInWorkingDir = true;
_outputPdfDir = ""; _outputPdfDir = "";
_imageResizeThreshold = 1.5m; _imageResizeThreshold = 1.5m;
_saveReportJsonDataInInternalDir = false;
_workingFolderToInternalFolderName = [];
_settingsVersion = 1;
} }
public Settings(Settings other) public Settings(Settings other)
@@ -33,6 +40,9 @@ class Settings : ChangeNotifier
_saveOutputPdfInWorkingDir = other.SaveOutputPdfInWorkingDir; _saveOutputPdfInWorkingDir = other.SaveOutputPdfInWorkingDir;
_outputPdfDir = other.OutputPdfDir; _outputPdfDir = other.OutputPdfDir;
_imageResizeThreshold = other.ImageResizeThreshold; _imageResizeThreshold = other.ImageResizeThreshold;
_saveReportJsonDataInInternalDir = other.SaveReportJsonDataInInternalDir;
_workingFolderToInternalFolderName = other.WorkingFolderToInternalFolderName;
_settingsVersion = other.SettingsVersion;
} }
[JsonInclude] [JsonInclude]
@@ -71,15 +81,46 @@ class Settings : ChangeNotifier
set { _imageResizeThreshold = value; NotifyPropertyChanged(); } set { _imageResizeThreshold = value; NotifyPropertyChanged(); }
} }
public static string GetSettingsFileName() [JsonInclude]
public bool SaveReportJsonDataInInternalDir
{ {
return "settings.json"; get => _saveReportJsonDataInInternalDir;
set { _saveReportJsonDataInInternalDir = value; NotifyPropertyChanged(); }
} }
[JsonInclude]
public Dictionary<string, string> WorkingFolderToInternalFolderName
{
get => _workingFolderToInternalFolderName;
set { _workingFolderToInternalFolderName = value; NotifyPropertyChanged(); }
}
[JsonInclude]
public int SettingsVersion
{
get => _settingsVersion;
set { _settingsVersion = value; NotifyPropertyChanged(); }
}
public static string SettingsFileName = "settings.json";
public static string GetSettingsPath() public static string GetSettingsPath()
{ {
var path = Utilities.GetInternalDataPath(); var path = Utilities.GetInternalDataPath();
return Path.Combine(path, GetSettingsFileName()); return Path.Combine(path, SettingsFileName);
}
public string SaveSettingsNotAsync()
{
var jsonContext = new SourceGenerationContext(Utilities.GetSerializerOptions());
using MemoryStream memoryStream = new MemoryStream();
JsonSerializer.Serialize(memoryStream, this, jsonContext.Settings);
memoryStream.Position = 0;
using var reader = new StreamReader(memoryStream);
var json = reader.ReadToEnd();
File.WriteAllText(GetSettingsPath(), json);
return json;
} }
public async Task<string> SaveSettingsAsync() public async Task<string> SaveSettingsAsync()
+48 -17
View File
@@ -51,7 +51,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
{ {
_isPerformingInitialLoad = true; _isPerformingInitialLoad = true;
_processDir = Path.GetDirectoryName(Environment.ProcessPath) ?? ""; _processDir = Path.GetDirectoryName(Environment.ProcessPath) ?? "";
Console.WriteLine("Process is running from: {0}", _processDir); Console.WriteLine("Internal storage directory is: {0}", Utilities.GetInternalDataPath());
_isCreatingPDF = false; _isCreatingPDF = false;
var quotes = Constants.GetQuotes(); var quotes = Constants.GetQuotes();
Random random = new Random(); Random random = new Random();
@@ -93,7 +93,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
public bool IsTitleBoxVisible public bool IsTitleBoxVisible
{ {
get => !string.IsNullOrWhiteSpace(_workingFolder); get => !string.IsNullOrWhiteSpace(WorkingFolder);
} }
public bool CanAddItem public bool CanAddItem
@@ -121,12 +121,12 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
public bool HasWorkingFolder public bool HasWorkingFolder
{ {
get => !string.IsNullOrWhiteSpace(_workingFolder) && Directory.Exists(_workingFolder); get => !string.IsNullOrWhiteSpace(WorkingFolder) && Directory.Exists(WorkingFolder);
} }
public bool HasWorkingFolderAndNotMakingPDF public bool HasWorkingFolderAndNotMakingPDF
{ {
get => !string.IsNullOrWhiteSpace(_workingFolder) && Directory.Exists(_workingFolder) && !_isCreatingPDF; get => !string.IsNullOrWhiteSpace(WorkingFolder) && Directory.Exists(WorkingFolder) && !_isCreatingPDF;
} }
public string WorkingFolder public string WorkingFolder
@@ -203,14 +203,49 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
} }
} }
private string GetReportSavedDataPath(string folderPath)
{
if (_settings.SaveReportJsonDataInInternalDir)
{
var internalPath = Utilities.GetInternalDataPath();
if (!_settings.WorkingFolderToInternalFolderName.ContainsKey(folderPath))
{
var uuid = "";
var potentialPath = "";
var isDone = false;
// make sure uuid not already used...just in case...because paranoia...
do
{
uuid = Guid.NewGuid().ToString();
potentialPath = Path.Combine(internalPath, uuid);
isDone = !Directory.Exists(potentialPath);
} while (!isDone);
// make internal dir -- using dir so we have option to copy data into dir later if needed
// (if we ever implement a more robust report system where we keep all files)
Directory.CreateDirectory(potentialPath);
_settings.WorkingFolderToInternalFolderName[folderPath] = uuid;
_settings.SaveSettingsNotAsync(); // save new key/value pair
}
return Path.Combine(
internalPath,
_settings.WorkingFolderToInternalFolderName[folderPath],
Constants.ReportSavedDataFileName
);
}
else
{
return Path.Combine(folderPath, Constants.ReportSavedDataFileName);
}
}
private void ScanFolder(string path) private void ScanFolder(string path)
{ {
if (Directory.Exists(path)) if (Directory.Exists(path))
{ {
WorkingFolder = path; WorkingFolder = path;
NotifyPropertyChanged(nameof(IsTitleBoxVisible)); NotifyPropertyChanged(nameof(IsTitleBoxVisible));
NotifyPropertyChanged(nameof(CanAddItem)); NotifyPropertyChanged(nameof(CanAddItem));
var reportFilePath = Path.Combine(path, GetReportSavedDataFileName()); var reportFilePath = GetReportSavedDataPath(path);
var successfullyLoadedPriorReport = false; var successfullyLoadedPriorReport = false;
if (File.Exists(reportFilePath)) if (File.Exists(reportFilePath))
{ {
@@ -220,6 +255,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
var report = JsonSerializer.Deserialize<PDFReport>(json, jsonContext.PDFReport); var report = JsonSerializer.Deserialize<PDFReport>(json, jsonContext.PDFReport);
if (report != null && report.Files.Count > 0) if (report != null && report.Files.Count > 0)
{ {
Console.WriteLine("Loading prior report data at {0}", reportFilePath);
ReportFiles = new ObservableCollection<ReportFile>(report.Files); ReportFiles = new ObservableCollection<ReportFile>(report.Files);
ReportTitle = report.Title; ReportTitle = report.Title;
WorkingFolder = report.BaseFolder; WorkingFolder = report.BaseFolder;
@@ -233,7 +269,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
// Scan folder for files and display in DataGrid // Scan folder for files and display in DataGrid
ReportFiles.Clear(); ReportFiles.Clear();
ReportTitle = ""; ReportTitle = "";
var filePaths = Directory.GetFiles(_workingFolder); var filePaths = Directory.GetFiles(WorkingFolder);
foreach (var filePath in filePaths) foreach (var filePath in filePaths)
{ {
AddFileBasedOnPath(filePath); AddFileBasedOnPath(filePath);
@@ -350,7 +386,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
} }
if (!didMatch) if (!didMatch)
{ {
if (!filePath.EndsWith(GetReportSavedDataFileName())) if (!filePath.EndsWith(Constants.ReportSavedDataFileName))
{ {
LogInfo("File {0} did not match allowed file extension types, so it was not added.", filePath); LogInfo("File {0} did not match allowed file extension types, so it was not added.", filePath);
} }
@@ -464,7 +500,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
{ {
try try
{ {
await Task.Run(() => CreatePDF(_workingFolder)); await Task.Run(() => CreatePDF(WorkingFolder));
} catch (Exception e) } catch (Exception e)
{ {
LogInfo("PDF process failed! Reason: " + e.Message); LogInfo("PDF process failed! Reason: " + e.Message);
@@ -492,7 +528,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
{ {
Title = ReportTitle, Title = ReportTitle,
Files = ReportFiles.ToList(), Files = ReportFiles.ToList(),
BaseFolder = _workingFolder, BaseFolder = WorkingFolder,
LastSaved = DateTime.Now, LastSaved = DateTime.Now,
LastGenerated = _lastGeneratedTime, LastGenerated = _lastGeneratedTime,
}; };
@@ -507,7 +543,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
memoryStream.Position = 0; memoryStream.Position = 0;
using var reader = new StreamReader(memoryStream); using var reader = new StreamReader(memoryStream);
var json = await reader.ReadToEndAsync(); var json = await reader.ReadToEndAsync();
var savePath = Path.Combine(_workingFolder, GetReportSavedDataFileName()); var savePath = GetReportSavedDataPath(WorkingFolder);
await File.WriteAllTextAsync(savePath, json); await File.WriteAllTextAsync(savePath, json);
LogInfo("Saved report information to {0}", savePath); LogInfo("Saved report information to {0}", savePath);
HasUnsavedWork = false; HasUnsavedWork = false;
@@ -519,7 +555,7 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
{ {
Title = ReportTitle, Title = ReportTitle,
Files = ReportFiles.ToList(), Files = ReportFiles.ToList(),
BaseFolder = _workingFolder, BaseFolder = WorkingFolder,
LastSaved = DateTime.Now, LastSaved = DateTime.Now,
LastGenerated = DateTime.Now, LastGenerated = DateTime.Now,
}; };
@@ -527,11 +563,6 @@ class MainViewModel : BaseViewModel, IFontResolver, ICanCheckShutdown
await SavePDFReportDataToDisk(report); await SavePDFReportDataToDisk(report);
} }
private string GetReportSavedDataFileName()
{
return "report_data.json";
}
public byte[]? GetFont(string faceName) public byte[]? GetFont(string faceName)
{ {
LogInfo(string.Format("Loading font {0}", faceName)); LogInfo(string.Format("Loading font {0}", faceName));
+11 -1
View File
@@ -94,7 +94,17 @@ class SettingsViewModel: ChangeNotifier
set set
{ {
_settings.ImageResizeThreshold = value; _settings.ImageResizeThreshold = value;
NotifyPropertyChanged(nameof(ImageResizeThreshold)); NotifyPropertyChanged();
}
}
public bool SaveReportJsonDataInInternalDir
{
get => _settings.SaveReportJsonDataInInternalDir;
set
{
_settings.SaveReportJsonDataInInternalDir = value;
NotifyPropertyChanged();
} }
} }
+2 -1
View File
@@ -35,7 +35,7 @@
<CheckBox IsChecked="{Binding SaveOutputPdfInWorkingDir}">Always save report PDF in working directory</CheckBox> <CheckBox IsChecked="{Binding SaveOutputPdfInWorkingDir}">Always save report PDF in working directory</CheckBox>
<Grid ColumnDefinitions="Auto, *" <Grid ColumnDefinitions="Auto, *"
IsVisible="{Binding !SaveOutputPdfInWorkingDir}"> IsVisible="{Binding !SaveOutputPdfInWorkingDir}">
<Button Content="Choose output folder..." <Button Content="Choose report output folder..."
Grid.Column="0" Grid.Column="0"
Command="{Binding ChooseOutputFolder}" Command="{Binding ChooseOutputFolder}"
VerticalAlignment="Top"/> VerticalAlignment="Top"/>
@@ -46,6 +46,7 @@
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top"/> VerticalAlignment="Top"/>
</Grid> </Grid>
<CheckBox IsChecked="{Binding SaveReportJsonDataInInternalDir}">Save report data (names, notes, etc.) in MayShow settings directory (saves in working directory by default)</CheckBox>
<TextBlock TextWrapping="Wrap" <TextBlock TextWrapping="Wrap"
Foreground="Red" Foreground="Red"
Text="{Binding ErrorMessage}" Text="{Binding ErrorMessage}"