Booksmarks now use proper serialization

This commit is contained in:
Clint Rutkas
2024-09-04 13:23:09 -07:00
parent cee0d3adb6
commit 6de494d826
3 changed files with 87 additions and 112 deletions

View File

@@ -2,16 +2,16 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using Microsoft.Bot.AdaptiveExpressions.Core;
using Microsoft.Windows.CommandPalette.Extensions;
using Microsoft.Windows.CommandPalette.Extensions.Helpers;
using Windows.Foundation;
using Windows.System;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Run.Bookmarks;
@@ -21,8 +21,8 @@ internal sealed class OpenInTerminalAction : InvokableCommand
public OpenInTerminalAction(string folder)
{
this.Name = "Open in Terminal";
this._folder = folder;
Name = "Open in Terminal";
_folder = folder;
}
public override ICommandResult Invoke()
@@ -34,7 +34,7 @@ internal sealed class OpenInTerminalAction : InvokableCommand
{
FileName = "wt.exe",
Arguments = $"-d \"{_folder}\"",
UseShellExecute = true
UseShellExecute = true,
};
System.Diagnostics.Process.Start(startInfo);
}
@@ -47,11 +47,16 @@ internal sealed class OpenInTerminalAction : InvokableCommand
}
}
internal sealed class BookmarkData
public class BookmarkData
{
internal string name = string.Empty;
internal string bookmark = string.Empty;
internal string type = string.Empty;
public string Name = string.Empty;
public string Bookmark = string.Empty;
public string Type = string.Empty;
}
public sealed class Bookmarks
{
public List<BookmarkData> Data { get; set; } = [];
}
[JsonSourceGenerationOptions(WriteIndented = true)]
@@ -149,61 +154,48 @@ internal sealed class AddBookmarkForm : Form
bookmarkType = "web";
}
var formData = new BookmarkData()
{
Name = formName.ToString(),
Bookmark = formBookmark.ToString(),
Type = bookmarkType,
};
// Construct a new json blob with the name and url
var json = string.Empty;
var jsonPath = BookmarksActionProvider.StateJsonPath();
Bookmarks data;
// if the file exists, load it and append the new item
if (File.Exists(BookmarksActionProvider.StateJsonPath()))
if (File.Exists(jsonPath))
{
var state = File.ReadAllText(BookmarksActionProvider.StateJsonPath());
var jsonState = JsonNode.Parse(state);
var items = jsonState?["items"]?.AsArray();
var jsonStringReading = File.ReadAllText(jsonPath);
if (items != null)
{
// var items = jsonState["items"];
var newItem = new JsonObject();
newItem["name"] = formName;
newItem["bookmark"] = formBookmark;
var formData = new BookmarkData()
{
name = formName.ToString(),
bookmark = formBookmark.ToString(),
type = bookmarkType,
};
items.Add(JsonSerializer.SerializeToNode(formData, typeof(BookmarkData), SourceGenerationContext.Default));
json = jsonState?.ToString();
}
data = JsonSerializer.Deserialize<Bookmarks>(jsonStringReading);
}
else
{
json = $$"""
{
"items": [
{
"name": "{{formName}}",
"type": "{{bookmarkType}}",
"bookmark": "{{formBookmark}}",
"hasPlaceholder":"{{hasPlaceholder}}"
}
]
}
""";
data = new Bookmarks();
}
File.WriteAllText(BookmarksActionProvider.StateJsonPath(), json);
data.Data.Add(formData);
var options = new JsonSerializerOptions()
{
IncludeFields = true,
};
var jsonString = JsonSerializer.Serialize<Bookmarks>(data, options);
File.WriteAllText(BookmarksActionProvider.StateJsonPath(), jsonString);
AddedAction?.Invoke(this, null);
return ActionResult.GoHome();
}
}
internal sealed class AddBookmarkPage : Microsoft.Windows.CommandPalette.Extensions.Helpers.FormPage
internal sealed class AddBookmarkPage : FormPage
{
private readonly AddBookmarkForm _addBookmark = new();
internal event TypedEventHandler<object, object?>? AddedAction {
internal event TypedEventHandler<object, object?>? AddedAction
{
add => _addBookmark.AddedAction += value;
remove => _addBookmark.AddedAction -= value;
}
@@ -217,23 +209,25 @@ internal sealed class AddBookmarkPage : Microsoft.Windows.CommandPalette.Extensi
}
}
internal sealed class BookmarkPlaceholderForm: Microsoft.Windows.CommandPalette.Extensions.Helpers.Form
internal sealed class BookmarkPlaceholderForm : Microsoft.Windows.CommandPalette.Extensions.Helpers.Form
{
private List<string> placeholderNames { get; init; }
private readonly List<string> _placeholderNames;
private readonly string _Bookmark = string.Empty;
private readonly string _bookmark = string.Empty;
// TODO pass in an array of placeholders
public BookmarkPlaceholderForm(string name, string url, string type) {
_Bookmark = url;
public BookmarkPlaceholderForm(string name, string url, string type)
{
_bookmark = url;
Regex r = new Regex(Regex.Escape("{") + "(.*?)" + Regex.Escape("}"));
MatchCollection matches = r.Matches(url);
placeholderNames = matches.Select(m => m.Groups[1].Value).ToList();
_placeholderNames = matches.Select(m => m.Groups[1].Value).ToList();
}
public override string TemplateJson()
{
var inputs = placeholderNames.Select(p => {
var inputs = _placeholderNames.Select(p =>
{
return $$"""
{
"type": "Input.Text",
@@ -276,7 +270,7 @@ internal sealed class BookmarkPlaceholderForm: Microsoft.Windows.CommandPalette.
public override ActionResult SubmitForm(string payload)
{
var target = _Bookmark;
var target = _bookmark;
// parse the submitted JSON and then open the link
var formInput = JsonNode.Parse(payload);
@@ -314,7 +308,7 @@ internal sealed class BookmarkPlaceholderForm: Microsoft.Windows.CommandPalette.
}
}
internal sealed class BookmarkPlaceholderPage : Microsoft.Windows.CommandPalette.Extensions.Helpers.FormPage
internal sealed class BookmarkPlaceholderPage : FormPage
{
private readonly IForm _bookmarkPlaceholder;
@@ -330,7 +324,7 @@ internal sealed class BookmarkPlaceholderPage : Microsoft.Windows.CommandPalette
public class UrlAction : InvokableCommand
{
private bool _containsPlaceholder => _url.Contains('{') && _url.Contains('}');
private bool IsContainsPlaceholder => _url.Contains('{') && _url.Contains('}');
public string Type { get; }
@@ -428,12 +422,12 @@ public class BookmarksActionProvider : ICommandProvider
public BookmarksActionProvider()
{
_addNewCommand.AddedAction += _addNewCommand_AddedAction;
_addNewCommand.AddedAction += AddNewCommand_AddedAction;
}
private void _addNewCommand_AddedAction(object sender, object? args)
private void AddNewCommand_AddedAction(object sender, object? args)
{
_addNewCommand.AddedAction += _addNewCommand_AddedAction;
_addNewCommand.AddedAction += AddNewCommand_AddedAction;
_commands.Clear();
}
@@ -447,42 +441,37 @@ public class BookmarksActionProvider : ICommandProvider
collected.Add(_addNewCommand);
try
{
// Open state.json from the disk and read it
var state = File.ReadAllText(BookmarksActionProvider.StateJsonPath());
// Parse the JSON
var json = JsonNode.Parse(state);
var jsonObject = json?.AsObject();
if (jsonObject == null)
var jsonFile = StateJsonPath();
if (File.Exists(jsonFile))
{
return;
}
if (!jsonObject.ContainsKey("items"))
{
return;
}
var itemsJson = jsonObject["items"]?.AsArray();
if (itemsJson == null)
{
return;
}
foreach (var item in itemsJson)
{
var nameToken = item?["name"];
var urlToken = item?["bookmark"];
var typeToken = item?["type"];
if (nameToken == null || urlToken == null || typeToken == null)
// Open state.json from the disk and read it
var jsonString = File.ReadAllText(jsonFile);
var options = new JsonSerializerOptions()
{
continue;
}
IncludeFields = true,
};
var data = JsonSerializer.Deserialize<Bookmarks>(jsonString, options);
var name = nameToken.ToString();
var url = urlToken.ToString();
var type = typeToken.ToString();
collected.Add((url.Contains('{') && url.Contains('}')) ? new BookmarkPlaceholderPage(name, url, type) : new UrlAction(name, url, type));
if (data != null)
{
var items = data?.Data;
foreach (var item in items)
{
var nameToken = item.Name;
var urlToken = item.Bookmark;
var typeToken = item.Type;
if (nameToken == null || urlToken == null || typeToken == null)
{
continue;
}
var name = nameToken.ToString();
var url = urlToken.ToString();
var type = typeToken.ToString();
collected.Add((url.Contains('{') && url.Contains('}')) ? new BookmarkPlaceholderPage(name, url, type) : new UrlAction(name, url, type));
}
}
}
}
catch (Exception ex)
@@ -515,11 +504,11 @@ public class BookmarksActionProvider : ICommandProvider
}
// listItem.Subtitle = "Bookmark";
if (action is AddBookmarkPage) { }
else
if (action is not AddBookmarkPage)
{
listItem.Tags = [
new Tag() {
new Tag()
{
Text = "Bookmark",
// Icon = new("🔗"),

View File

@@ -25,23 +25,9 @@ public class PackageManagerWrapper : IPackageManager
{
var pkgs = _packageManager.FindPackagesForUser(user.Value);
return pkgs.Select(TryGetWrapperFromPackage).Where(package => package != null);
return pkgs.Select(PackageWrapper.GetWrapperFromPackage).Where(package => package != null);
}
return Enumerable.Empty<IPackage>();
}
private static PackageWrapper TryGetWrapperFromPackage(Package package)
{
try
{
return PackageWrapper.GetWrapperFromPackage(package);
}
catch (Exception )
{
// Log.Error(e.Message, typeof(PackageManagerWrapper));
}
return null;
}
}

View File

@@ -632,7 +632,7 @@ public class Win32Program // : IProgram
public static List<Win32Program> DeduplicatePrograms(IEnumerable<Win32Program> programs)
=> new HashSet<Win32Program>(programs, Win32ProgramEqualityComparer.Default).ToList();
private static Win32Program? GetProgramFromPath(string path)
private static Win32Program GetProgramFromPath(string path)
{
var extension = Extension(path);
if (ExecutableApplicationExtensions.Contains(extension))
@@ -649,7 +649,7 @@ public class Win32Program // : IProgram
case InternetShortcutExtension:
return InternetShortcutProgram(path);
default:
return null;
return new Win32Program();
}
}