From a97669710e59e868b8f8ca9b0a6d8b1bb220169e Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Thu, 2 Mar 2023 13:20:54 -0600
Subject: [PATCH 01/33] Init C# program
---
.gitignore | 402 +++++++++++++++++-
.../.idea/.gitignore | 13 +
.../.idea/indexLayout.xml | 8 +
.../.idea/vcs.xml | 6 +
.idea/inspectionProfiles/Project_Default.xml | 5 +
BookmarkSync.CLI/BookmarkSync.CLI.csproj | 10 +
BookmarkSync.CLI/Program.cs | 11 +
mastodon-bookmark-sync.sln | 22 +
8 files changed, 471 insertions(+), 6 deletions(-)
create mode 100644 .idea/.idea.mastodon-bookmark-sync/.idea/.gitignore
create mode 100644 .idea/.idea.mastodon-bookmark-sync/.idea/indexLayout.xml
create mode 100644 .idea/.idea.mastodon-bookmark-sync/.idea/vcs.xml
create mode 100644 .idea/inspectionProfiles/Project_Default.xml
create mode 100644 BookmarkSync.CLI/BookmarkSync.CLI.csproj
create mode 100644 BookmarkSync.CLI/Program.cs
create mode 100644 mastodon-bookmark-sync.sln
diff --git a/.gitignore b/.gitignore
index 48dc7d8..8dd4607 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,398 @@
-# macOS crap
-.DS_Store
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
-# Compiled binary
-mastodon-bookmark-sync
+# User-specific files
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
-# Config files / secrets
-config.yaml
\ No newline at end of file
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.tlog
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio 6 auto-generated project file (contains which files were open etc.)
+*.vbp
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+*.ncb
+*.aps
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# JetBrains Rider
+*.sln.iml
\ No newline at end of file
diff --git a/.idea/.idea.mastodon-bookmark-sync/.idea/.gitignore b/.idea/.idea.mastodon-bookmark-sync/.idea/.gitignore
new file mode 100644
index 0000000..de76ff1
--- /dev/null
+++ b/.idea/.idea.mastodon-bookmark-sync/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/modules.xml
+/contentModel.xml
+/projectSettingsUpdater.xml
+/.idea.mastodon-bookmark-sync.iml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/.idea.mastodon-bookmark-sync/.idea/indexLayout.xml b/.idea/.idea.mastodon-bookmark-sync/.idea/indexLayout.xml
new file mode 100644
index 0000000..7b08163
--- /dev/null
+++ b/.idea/.idea.mastodon-bookmark-sync/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.mastodon-bookmark-sync/.idea/vcs.xml b/.idea/.idea.mastodon-bookmark-sync/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/.idea.mastodon-bookmark-sync/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..e13319d
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/BookmarkSync.CLI/BookmarkSync.CLI.csproj b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
new file mode 100644
index 0000000..82b88b8
--- /dev/null
+++ b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net7.0
+ disable
+ enable
+
+
+
diff --git a/BookmarkSync.CLI/Program.cs b/BookmarkSync.CLI/Program.cs
new file mode 100644
index 0000000..0a52f26
--- /dev/null
+++ b/BookmarkSync.CLI/Program.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace BookmarkSync.CLI;
+
+public class Program
+{
+ public static void Main(string[] args)
+ {
+ Console.WriteLine("Hello, World!");
+ }
+}
diff --git a/mastodon-bookmark-sync.sln b/mastodon-bookmark-sync.sln
new file mode 100644
index 0000000..6d66988
--- /dev/null
+++ b/mastodon-bookmark-sync.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B696875F-E32C-4227-920E-4AFD03B7A5FC}"
+ ProjectSection(SolutionItems) = preProject
+ README.md = README.md
+ .gitignore = .gitignore
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.CLI", "BookmarkSync.CLI\BookmarkSync.CLI.csproj", "{696935C2-0383-4409-A2B4-B80A8C905DD2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {696935C2-0383-4409-A2B4-B80A8C905DD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {696935C2-0383-4409-A2B4-B80A8C905DD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {696935C2-0383-4409-A2B4-B80A8C905DD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {696935C2-0383-4409-A2B4-B80A8C905DD2}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
From 4637fcd4adbbf8614952576e9562c25c09c3a0a6 Mon Sep 17 00:00:00 2001
From: prplecake
Date: Thu, 2 Mar 2023 16:00:31 -0600
Subject: [PATCH 02/33] Add ConfigManager and related config objects
---
.gitignore | 3 ++
BookmarkSync.CLI/BookmarkSync.CLI.csproj | 15 ++++++
BookmarkSync.CLI/Program.cs | 39 ++++++++++++--
BookmarkSync.CLI/appsettings.Example.json | 15 ++++++
BookmarkSync.Core/BookmarkSync.Core.csproj | 16 ++++++
.../Configuration/ConfigManager.cs | 52 +++++++++++++++++++
BookmarkSync.Core/Entities/Account.cs | 8 +++
BookmarkSync.Core/Entities/Bookmark.cs | 10 ++++
BookmarkSync.Core/Entities/Config/App.cs | 10 ++++
.../Entities/Config/Bookmarking.cs | 7 +++
.../Entities/Config/ConfigurationBase.cs | 8 +++
BookmarkSync.Core/Entities/Config/Instance.cs | 10 ++++
BookmarkSync.Core/Entities/Config/Pinboard.cs | 6 +++
mastodon-bookmark-sync.sln | 6 +++
14 files changed, 202 insertions(+), 3 deletions(-)
create mode 100644 BookmarkSync.CLI/appsettings.Example.json
create mode 100644 BookmarkSync.Core/BookmarkSync.Core.csproj
create mode 100644 BookmarkSync.Core/Configuration/ConfigManager.cs
create mode 100644 BookmarkSync.Core/Entities/Account.cs
create mode 100644 BookmarkSync.Core/Entities/Bookmark.cs
create mode 100644 BookmarkSync.Core/Entities/Config/App.cs
create mode 100644 BookmarkSync.Core/Entities/Config/Bookmarking.cs
create mode 100644 BookmarkSync.Core/Entities/Config/ConfigurationBase.cs
create mode 100644 BookmarkSync.Core/Entities/Config/Instance.cs
create mode 100644 BookmarkSync.Core/Entities/Config/Pinboard.cs
diff --git a/.gitignore b/.gitignore
index 8dd4607..35bd12e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,9 @@
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
+# Secrets
+appsettings.json
+
# User-specific files
*.rsuser
*.suo
diff --git a/BookmarkSync.CLI/BookmarkSync.CLI.csproj b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
index 82b88b8..5bce381 100644
--- a/BookmarkSync.CLI/BookmarkSync.CLI.csproj
+++ b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
@@ -7,4 +7,19 @@
enable
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
diff --git a/BookmarkSync.CLI/Program.cs b/BookmarkSync.CLI/Program.cs
index 0a52f26..f8b57d3 100644
--- a/BookmarkSync.CLI/Program.cs
+++ b/BookmarkSync.CLI/Program.cs
@@ -1,11 +1,44 @@
using System;
+using System.Threading.Tasks;
+using BookmarkSync.Core.Configuration;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
namespace BookmarkSync.CLI;
public class Program
{
- public static void Main(string[] args)
+ private static IConfiguration Configuration;
+ public async static Task Main(string[] args)
{
- Console.WriteLine("Hello, World!");
+ Configuration = SetupConfiguration(args);
+ IConfigManager configManager = new ConfigManager(Configuration);
+
+ using var host = Host.CreateDefaultBuilder(args)
+ .ConfigureServices(services =>
+ {
+ services.AddSingleton(configManager);
+ })
+ .Build();
+ await host.StartAsync();
+ var lifetime = host.Services.GetRequiredService();
+
+ // Do work here
+ Console.WriteLine("Hello, world!");
+
+ // Shutdown
+ configManager.SaveToFile();
+
+ lifetime.StopApplication();
+ await host.WaitForShutdownAsync();
+ }
+ private static IConfiguration SetupConfiguration(string[] args)
+ {
+ return new ConfigurationBuilder()
+ .AddJsonFile("appsettings.json", false, true)
+ .AddEnvironmentVariables()
+ .AddCommandLine(args)
+ .Build();
}
-}
+}
\ No newline at end of file
diff --git a/BookmarkSync.CLI/appsettings.Example.json b/BookmarkSync.CLI/appsettings.Example.json
new file mode 100644
index 0000000..df410ff
--- /dev/null
+++ b/BookmarkSync.CLI/appsettings.Example.json
@@ -0,0 +1,15 @@
+{
+ "Instances": [
+ {
+ "Uri": "https://compostintraining.club",
+ "AccessToken": "",
+ "DeleteBookmarks": true
+ }
+ ],
+ "App": {
+ "Bookmarking": {
+ "Service": "Pinboard",
+ "ApiToken": ""
+ }
+ }
+}
\ No newline at end of file
diff --git a/BookmarkSync.Core/BookmarkSync.Core.csproj b/BookmarkSync.Core/BookmarkSync.Core.csproj
new file mode 100644
index 0000000..e47591a
--- /dev/null
+++ b/BookmarkSync.Core/BookmarkSync.Core.csproj
@@ -0,0 +1,16 @@
+
+
+
+ net7.0
+ disable
+ enable
+
+
+
+
+
+
+
+
+
+
diff --git a/BookmarkSync.Core/Configuration/ConfigManager.cs b/BookmarkSync.Core/Configuration/ConfigManager.cs
new file mode 100644
index 0000000..b0d8ec0
--- /dev/null
+++ b/BookmarkSync.Core/Configuration/ConfigManager.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using BookmarkSync.Core.Entities.Config;
+using CiT.Common.Exceptions;
+using Microsoft.Extensions.Configuration;
+
+namespace BookmarkSync.Core.Configuration;
+
+public interface IConfigManager
+{
+ IConfiguration Configuration { get; set; }
+ Instance[] Instances { get; set; }
+ App App { get; set; }
+ string GetConfigValue(string key);
+ void SaveToFile();
+}
+public class ConfigManager : IConfigManager
+{
+ public ConfigManager(
+ IConfiguration configuration)
+ {
+ Configuration = configuration;
+ List instance = Configuration.GetSection("Instances").Get>();
+ App app = Configuration.GetSection("App").Get();
+ var instances = Configuration.GetSection("Instances").Get();
+ App = app;
+
+ if (!App.IsValid())
+ {
+ throw new InvalidConfigurationException();
+ }
+ }
+ public IConfiguration Configuration { get; set; }
+ public Instance[] Instances { get; set; }
+ public App App { get; set; }
+ public string GetConfigValue(string key)
+ {
+ string? value = Configuration[key];
+ if (string.IsNullOrWhiteSpace(value))
+ {
+ throw new ConfigurationErrorsException(
+ $"An invalid key was provided: key: {key}");
+ }
+ return value;
+ }
+ public void SaveToFile()
+ {
+ Console.WriteLine(Directory.GetCurrentDirectory());
+ }
+}
diff --git a/BookmarkSync.Core/Entities/Account.cs b/BookmarkSync.Core/Entities/Account.cs
new file mode 100644
index 0000000..09a5515
--- /dev/null
+++ b/BookmarkSync.Core/Entities/Account.cs
@@ -0,0 +1,8 @@
+namespace BookmarkSync.Core.Entities;
+
+public class Account
+{
+ public string Name { get; set; }
+ ///
+ public override string ToString() => Name;
+}
diff --git a/BookmarkSync.Core/Entities/Bookmark.cs b/BookmarkSync.Core/Entities/Bookmark.cs
new file mode 100644
index 0000000..2707cdf
--- /dev/null
+++ b/BookmarkSync.Core/Entities/Bookmark.cs
@@ -0,0 +1,10 @@
+namespace BookmarkSync.Core.Entities;
+
+public class Bookmark
+{
+ public Account Account { get; set; }
+ public string Content { get; set; }
+ public string Id { get; set; }
+ public string Uri { get; set; }
+ public string Visibility { get; set; }
+}
diff --git a/BookmarkSync.Core/Entities/Config/App.cs b/BookmarkSync.Core/Entities/Config/App.cs
new file mode 100644
index 0000000..669ae68
--- /dev/null
+++ b/BookmarkSync.Core/Entities/Config/App.cs
@@ -0,0 +1,10 @@
+using System;
+using CiT.Common.Attributes;
+
+namespace BookmarkSync.Core.Entities.Config;
+
+public class App : ConfigurationBase
+{
+ [ConfigRequired] public Bookmarking Bookmarking { get; set; }
+ public DateTime LastSynced { get; set; }
+}
diff --git a/BookmarkSync.Core/Entities/Config/Bookmarking.cs b/BookmarkSync.Core/Entities/Config/Bookmarking.cs
new file mode 100644
index 0000000..969f398
--- /dev/null
+++ b/BookmarkSync.Core/Entities/Config/Bookmarking.cs
@@ -0,0 +1,7 @@
+namespace BookmarkSync.Core.Entities.Config;
+
+public class Bookmarking : ConfigurationBase
+{
+ public string Service { get; set; }
+ public string ApiToken { get; set; }
+}
diff --git a/BookmarkSync.Core/Entities/Config/ConfigurationBase.cs b/BookmarkSync.Core/Entities/Config/ConfigurationBase.cs
new file mode 100644
index 0000000..b699fdd
--- /dev/null
+++ b/BookmarkSync.Core/Entities/Config/ConfigurationBase.cs
@@ -0,0 +1,8 @@
+using CiT.Common.Validations;
+
+namespace BookmarkSync.Core.Entities.Config;
+
+public class ConfigurationBase
+{
+ public bool IsValid() => !this.IsAnyNullOrEmpty();
+}
diff --git a/BookmarkSync.Core/Entities/Config/Instance.cs b/BookmarkSync.Core/Entities/Config/Instance.cs
new file mode 100644
index 0000000..0b592cb
--- /dev/null
+++ b/BookmarkSync.Core/Entities/Config/Instance.cs
@@ -0,0 +1,10 @@
+namespace BookmarkSync.Core.Entities.Config;
+
+public class Instance : ConfigurationBase
+{
+ public string AccessToken { get; set; }
+ public bool DeleteBookmarks { get; set; }
+ public string Uri { get; set; }
+ ///
+ public override string ToString() => Uri;
+}
diff --git a/BookmarkSync.Core/Entities/Config/Pinboard.cs b/BookmarkSync.Core/Entities/Config/Pinboard.cs
new file mode 100644
index 0000000..1aa1551
--- /dev/null
+++ b/BookmarkSync.Core/Entities/Config/Pinboard.cs
@@ -0,0 +1,6 @@
+namespace BookmarkSync.Core.Entities.Config;
+
+public class Pinboard : ConfigurationBase
+{
+
+}
diff --git a/mastodon-bookmark-sync.sln b/mastodon-bookmark-sync.sln
index 6d66988..29992c0 100644
--- a/mastodon-bookmark-sync.sln
+++ b/mastodon-bookmark-sync.sln
@@ -8,6 +8,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.CLI", "BookmarkSync.CLI\BookmarkSync.CLI.csproj", "{696935C2-0383-4409-A2B4-B80A8C905DD2}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.Core", "BookmarkSync.Core\BookmarkSync.Core.csproj", "{0391DE45-C449-4AEF-93A6-808261868807}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -18,5 +20,9 @@ Global
{696935C2-0383-4409-A2B4-B80A8C905DD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{696935C2-0383-4409-A2B4-B80A8C905DD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{696935C2-0383-4409-A2B4-B80A8C905DD2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0391DE45-C449-4AEF-93A6-808261868807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0391DE45-C449-4AEF-93A6-808261868807}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0391DE45-C449-4AEF-93A6-808261868807}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0391DE45-C449-4AEF-93A6-808261868807}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
From eb8a3ee24b4f758b4fbca07c7c0fec205f798d35 Mon Sep 17 00:00:00 2001
From: prplecake
Date: Thu, 2 Mar 2023 16:05:25 -0600
Subject: [PATCH 03/33] Init bookmarking services
---
BookmarkSync.CLI/BookmarkSync.CLI.csproj | 1 +
BookmarkSync.CLI/Program.cs | 6 +++++-
.../Interfaces/IBookmarkingService.cs | 6 ++++++
.../BookmarkSync.Infrastructure.csproj | 17 +++++++++++++++++
.../Services/PinboardBookmarkingService.cs | 8 ++++++++
mastodon-bookmark-sync.sln | 6 ++++++
6 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 BookmarkSync.Core/Interfaces/IBookmarkingService.cs
create mode 100644 BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj
create mode 100644 BookmarkSync.Infrastructure/Services/PinboardBookmarkingService.cs
diff --git a/BookmarkSync.CLI/BookmarkSync.CLI.csproj b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
index 5bce381..b964d88 100644
--- a/BookmarkSync.CLI/BookmarkSync.CLI.csproj
+++ b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
@@ -14,6 +14,7 @@
+
diff --git a/BookmarkSync.CLI/Program.cs b/BookmarkSync.CLI/Program.cs
index f8b57d3..0cb0073 100644
--- a/BookmarkSync.CLI/Program.cs
+++ b/BookmarkSync.CLI/Program.cs
@@ -1,6 +1,8 @@
using System;
using System.Threading.Tasks;
using BookmarkSync.Core.Configuration;
+using BookmarkSync.Core.Interfaces;
+using BookmarkSync.Infrastructure.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@@ -19,6 +21,8 @@ public async static Task Main(string[] args)
.ConfigureServices(services =>
{
services.AddSingleton(configManager);
+
+ services.AddTransient();
})
.Build();
await host.StartAsync();
@@ -41,4 +45,4 @@ private static IConfiguration SetupConfiguration(string[] args)
.AddCommandLine(args)
.Build();
}
-}
\ No newline at end of file
+}
diff --git a/BookmarkSync.Core/Interfaces/IBookmarkingService.cs b/BookmarkSync.Core/Interfaces/IBookmarkingService.cs
new file mode 100644
index 0000000..8ec9389
--- /dev/null
+++ b/BookmarkSync.Core/Interfaces/IBookmarkingService.cs
@@ -0,0 +1,6 @@
+namespace BookmarkSync.Core.Interfaces;
+
+public interface IBookmarkingService
+{
+
+}
diff --git a/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj b/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj
new file mode 100644
index 0000000..9d63ce0
--- /dev/null
+++ b/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj
@@ -0,0 +1,17 @@
+
+
+
+ net7.0
+ disable
+ enable
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BookmarkSync.Infrastructure/Services/PinboardBookmarkingService.cs b/BookmarkSync.Infrastructure/Services/PinboardBookmarkingService.cs
new file mode 100644
index 0000000..767cedf
--- /dev/null
+++ b/BookmarkSync.Infrastructure/Services/PinboardBookmarkingService.cs
@@ -0,0 +1,8 @@
+using BookmarkSync.Core.Interfaces;
+
+namespace BookmarkSync.Infrastructure.Services;
+
+public class PinboardBookmarkingService : IBookmarkingService
+{
+
+}
diff --git a/mastodon-bookmark-sync.sln b/mastodon-bookmark-sync.sln
index 29992c0..b92a263 100644
--- a/mastodon-bookmark-sync.sln
+++ b/mastodon-bookmark-sync.sln
@@ -10,6 +10,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.CLI", "Bookmar
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.Core", "BookmarkSync.Core\BookmarkSync.Core.csproj", "{0391DE45-C449-4AEF-93A6-808261868807}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.Infrastructure", "BookmarkSync.Infrastructure\BookmarkSync.Infrastructure.csproj", "{D11BD068-7AD0-4C9D-85A0-BD04A67AA7FC}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -24,5 +26,9 @@ Global
{0391DE45-C449-4AEF-93A6-808261868807}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0391DE45-C449-4AEF-93A6-808261868807}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0391DE45-C449-4AEF-93A6-808261868807}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D11BD068-7AD0-4C9D-85A0-BD04A67AA7FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D11BD068-7AD0-4C9D-85A0-BD04A67AA7FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D11BD068-7AD0-4C9D-85A0-BD04A67AA7FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D11BD068-7AD0-4C9D-85A0-BD04A67AA7FC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
From db591ad60bba63a12e214c7a4a8f0801b3f0c0b8 Mon Sep 17 00:00:00 2001
From: prplecake
Date: Thu, 2 Mar 2023 16:28:26 -0600
Subject: [PATCH 04/33] Remove Go
---
.github/workflows/codeql-analysis.yml | 71 ----------
.github/workflows/go.yml | 25 ----
.github/workflows/release.yml | 26 ----
bookmarks.go | 44 ------
config.example.yaml | 8 --
config.go | 75 -----------
go.mod | 14 --
go.sum | 22 ---
mastodon-bookmark-sync.go | 184 --------------------------
9 files changed, 469 deletions(-)
delete mode 100644 .github/workflows/codeql-analysis.yml
delete mode 100644 .github/workflows/go.yml
delete mode 100644 .github/workflows/release.yml
delete mode 100644 bookmarks.go
delete mode 100644 config.example.yaml
delete mode 100644 config.go
delete mode 100644 go.mod
delete mode 100644 go.sum
delete mode 100644 mastodon-bookmark-sync.go
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
deleted file mode 100644
index 24d83e9..0000000
--- a/.github/workflows/codeql-analysis.yml
+++ /dev/null
@@ -1,71 +0,0 @@
-# For most projects, this workflow file will not need changing; you simply need
-# to commit it to your repository.
-#
-# You may wish to alter this file to override the set of languages analyzed,
-# or to provide custom queries or build logic.
-#
-# ******** NOTE ********
-# We have attempted to detect the languages in your repository. Please check
-# the `language` matrix defined below to confirm you have the correct set of
-# supported CodeQL languages.
-#
-name: "CodeQL"
-
-on:
- push:
- branches: [ master ]
- pull_request:
- # The branches below must be a subset of the branches above
- branches: [ master ]
- schedule:
- - cron: '25 23 * * 6'
-
-jobs:
- analyze:
- name: Analyze
- runs-on: ubuntu-latest
- permissions:
- actions: read
- contents: read
- security-events: write
-
- strategy:
- fail-fast: false
- matrix:
- language: [ 'go' ]
- # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
- # Learn more:
- # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v2
-
- # Initializes the CodeQL tools for scanning.
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v1
- with:
- languages: ${{ matrix.language }}
- # If you wish to specify custom queries, you can do so here or in a config file.
- # By default, queries listed here will override any specified in a config file.
- # Prefix the list here with "+" to use these queries and those in the config file.
- # queries: ./path/to/local/query, your-org/your-repo/queries@main
-
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
- # If this step fails, then you should remove it and run the build manually (see below)
- - name: Autobuild
- uses: github/codeql-action/autobuild@v1
-
- # ℹ️ Command-line programs to run using the OS shell.
- # 📚 https://git.io/JvXDl
-
- # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
- # and modify them (or add more) to build your code if your project
- # uses a compiled language
-
- #- run: |
- # make bootstrap
- # make release
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
deleted file mode 100644
index ac4b2d7..0000000
--- a/.github/workflows/go.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-name: Go
-
-on:
- push:
- branches: [ master ]
- pull_request:
- branches: [ master ]
-
-jobs:
-
- build:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
-
- - name: Set up Go
- uses: actions/setup-go@v2
- with:
- go-version: 1.17
-
- - name: Build
- run: go build -v ./...
-
- #- name: Test
- # run: go test -v ./...
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index d77ddab..0000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: Release Go Binary
-
-on:
- release:
- types: [published]
- workflow_dispatch:
-
-jobs:
- releases-matrix:
- name: Release Go Binary
- runs-on: ubuntu-latest
- strategy:
- matrix:
- goos: [linux, windows, darwin]
- goarch: [amd64, arm64]
- exclude:
- - goarch: arm64
- goos: windows
- steps:
- - uses: actions/checkout@v2
- - uses: wangyoucao577/go-release-action@v1.32
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- goos: ${{ matrix.goos }}
- goarch: ${{ matrix.goarch }}
- extra_files: LICENSE README.md config.example.yaml
diff --git a/bookmarks.go b/bookmarks.go
deleted file mode 100644
index 03a96df..0000000
--- a/bookmarks.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package main
-
-import (
- "bytes"
- "encoding/json"
- "log"
-)
-
-type bookmark struct {
- ID string
- URL string
- Content string
- Account account
- Visibility string
-}
-
-type account struct {
- Acct string
-}
-
-func processBookmarks(data []byte) ([]bookmark, error) {
- var rawBookmarks []bookmark
- if err := json.Unmarshal(data, &rawBookmarks); err != nil {
- return nil, err
- }
- if debug {
- var jsonResult bytes.Buffer
- _ = json.Indent(&jsonResult, data, "", " ")
- log.Print(jsonResult.String())
- }
-
- var bookmarks []bookmark
- for _, bookmark := range rawBookmarks {
- if bookmark.Visibility == "private" || bookmark.Visibility == "direct" {
- if debug {
- log.Printf("Removing bookmark %s due to visibility setting", bookmark.URL)
- }
- } else {
- bookmarks = append(bookmarks, bookmark)
- }
- }
-
- return bookmarks, nil
-}
diff --git a/config.example.yaml b/config.example.yaml
deleted file mode 100644
index 1baa088..0000000
--- a/config.example.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-pinboard:
- # https://pinboard.in/settings/password
- apitoken:
-instances:
- # https://tools.splat.soy/pleroma-access-token
-- accesstoken:
- instanceurl: https://compostintraining.club
- deletebookmarks: true
diff --git a/config.go b/config.go
deleted file mode 100644
index e5ce10c..0000000
--- a/config.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package main
-
-import (
- "log"
- "os"
- "time"
-
- "gopkg.in/yaml.v2"
-)
-
-const (
- HttpUserAgent = "mastodon-bookmark-sync/1.0"
-)
-
-var (
- configFile string
-)
-
-type config struct {
- Instances []instanceConfig
- Pinboard pinboardConfig
- LastSynced time.Time
- HttpConfig httpConfig
-}
-
-type instanceConfig struct {
- AccessToken, InstanceURL string
- DeleteBookmarks bool
-}
-
-type pinboardConfig struct {
- APIToken string
-}
-
-type httpConfig struct {
- UserAgent string
-}
-
-func readConfig(fileName string) *config {
- log.Println("reading config...")
- configFile = fileName
- config := new(config)
- cf, err := os.ReadFile(configFile)
- if err != nil {
- log.Fatalln("Failed to read config: ", err)
- }
- err = yaml.Unmarshal(cf, &config)
- if err != nil {
- log.Panic(err)
- }
- if debug {
- log.Printf("Config:\n\n%v", config)
- }
- config.HttpConfig.UserAgent = HttpUserAgent
- return config
-}
-
-func (cf *config) updateLastSynced() {
- log.Println("updating LastSynced key...")
- cf.LastSynced = time.Now()
-}
-
-func (cf *config) Save() error {
- log.Println("saving config to file...")
- cfBytes, err := yaml.Marshal(cf)
- if err != nil {
- log.Fatalln("Failed to marshal config: ", err.Error())
- }
- err = os.WriteFile(configFile, cfBytes, 0644)
- if err != nil {
- log.Fatalf("Failed to save config to file. Error: %s", err.Error())
- }
-
- return nil
-}
diff --git a/go.mod b/go.mod
deleted file mode 100644
index 663f25d..0000000
--- a/go.mod
+++ /dev/null
@@ -1,14 +0,0 @@
-module github.com/prplecake/mastodon-bookmark-sync
-
-go 1.17
-
-require (
- github.com/microcosm-cc/bluemonday v1.0.18
- golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4
- gopkg.in/yaml.v2 v2.4.0
-)
-
-require (
- github.com/aymerick/douceur v0.2.0 // indirect
- github.com/gorilla/css v1.0.0 // indirect
-)
diff --git a/go.sum b/go.sum
deleted file mode 100644
index 522f8b8..0000000
--- a/go.sum
+++ /dev/null
@@ -1,22 +0,0 @@
-github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
-github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
-github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
-github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
-github.com/microcosm-cc/bluemonday v1.0.18 h1:6HcxvXDAi3ARt3slx6nTesbvorIc3QeTzBNRvWktHBo=
-github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM=
-golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
-golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
-gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
diff --git a/mastodon-bookmark-sync.go b/mastodon-bookmark-sync.go
deleted file mode 100644
index 4c13299..0000000
--- a/mastodon-bookmark-sync.go
+++ /dev/null
@@ -1,184 +0,0 @@
-package main
-
-import (
- "flag"
- "fmt"
- "io"
- "log"
- "net/http"
- "net/url"
- "strings"
-
- "github.com/microcosm-cc/bluemonday"
- "golang.org/x/net/html"
-)
-
-var (
- conf *config
- debug bool
- PinboardDescMaxLength = 255
- PinboardApiUrl = "https://api.pinboard.in/v1/posts/add"
-)
-
-func main() {
- var (
- configFile string
- )
- flag.StringVar(&configFile, "c", "config.yaml", "the configuration file to use")
- flag.BoolVar(&debug, "debug", false, "enable debugging")
- flag.Parse()
-
- conf = readConfig(configFile)
-
- if debug {
- log.Println(conf)
- }
-
- log.Println("mastodon-bookmark-sync starting up...")
- log.Println("initializing bluemonday")
- p := bluemonday.StripTagsPolicy()
-
- for _, instance := range conf.Instances {
- log.Printf("Fetching bookmarks from instance: [%s]...", instance.InstanceURL)
- apiURL := instance.InstanceURL + "/api/v1/bookmarks"
-
- var req *http.Request
- req, err := http.NewRequest("GET", apiURL, nil)
- if err != nil {
- log.Fatal(err)
- }
- req.Header.Set("Authorization", "Bearer "+instance.AccessToken)
- req.Header.Set("User-Agent", conf.HttpConfig.UserAgent)
-
- c := &http.Client{}
-
- resp, err := c.Do(req)
- if err != nil {
- log.Fatal(err)
- }
- defer func(Body io.ReadCloser) {
- _ = Body.Close()
- }(resp.Body)
-
- body, err := io.ReadAll(resp.Body)
- if err != nil {
- log.Fatal(err)
- }
- bookmarks, err := processBookmarks(body)
- if err != nil {
- log.Fatal(err)
- }
-
- for i := len(bookmarks) - 1; i >= 0; i-- {
- bookmarks[i].Content = html.UnescapeString(p.Sanitize(
- strings.Replace(bookmarks[i].Content, "
", "\n\n", -1),
- ))
- if debug {
- log.Printf("%d:\n%s\n%s\n%s\n\n",
- i, bookmarks[i].URL,
- bookmarks[i].Content,
- bookmarks[i].Account.Acct,
- )
- }
-
- log.Printf("Saving URL: %s", bookmarks[i].URL)
-
- var (
- descriptionTrimmed = false
- trimmedDescription string
- extended string
- tags = fmt.Sprintf(
- "%s %s",
- "via:@"+bookmarks[i].Account.Acct,
- "via:mastodon-bookmark-sync",
- )
- )
-
- if len(bookmarks[i].Content) > PinboardDescMaxLength {
- trimmedDescription = bookmarks[i].Content[PinboardDescMaxLength:]
- descriptionTrimmed = true
- }
-
- if descriptionTrimmed {
- extended = bookmarks[i].Content
- bookmarks[i].Content = trimmedDescription
- }
-
- data := url.Values{}
- data.Set("auth_token", conf.Pinboard.APIToken)
- data.Set("description", bookmarks[i].Content)
- data.Set("url", bookmarks[i].URL)
- data.Set("shared", "no")
- data.Set("extended", extended)
- data.Set("tags", tags)
- fullURL := PinboardApiUrl + "?" + data.Encode()
-
- if debug {
- log.Print(fullURL)
- }
-
- req, err := http.NewRequest("GET", fullURL, nil)
- if err != nil {
- log.Fatal(err)
- }
- req.Header.Set("User-Agent", conf.HttpConfig.UserAgent)
-
- c := &http.Client{}
-
- resp, err := c.Do(req)
- if err != nil {
- log.Fatal(err)
- }
- defer func(Body io.ReadCloser) {
- _ = Body.Close()
- }(resp.Body)
-
- log.Printf("resp.StatusCode: %d", resp.StatusCode)
-
- if debug {
- buf := new(strings.Builder)
- _, err = io.Copy(buf, resp.Body)
- if err != nil {
- log.Fatal(err)
- }
- log.Printf("resp.Body: %s", buf.String())
- }
-
- if instance.DeleteBookmarks && resp.StatusCode == 200 && bookmarks[i].Visibility != "private" && bookmarks[i].Visibility != "direct" {
- // only delete bookmarks if successfully saved by Pinboard and
- // don't delete bookmarks of private or direct statuses
- instance.deleteBookmark(bookmarks[i])
- }
- }
- }
-}
-
-func (instance *instanceConfig) deleteBookmark(status bookmark) {
- apiURL := instance.InstanceURL + "/api/v1/statuses/" + status.ID + "/unbookmark"
-
- req, err := http.NewRequest("POST", apiURL, nil)
- if err != nil {
- log.Fatal(err)
- }
-
- req.Header.Set("Authorization", "Bearer "+instance.AccessToken)
-
- c := &http.Client{}
-
- resp, err := c.Do(req)
- if err != nil {
- log.Fatal(err)
- }
- defer func(Body io.ReadCloser) {
- _ = Body.Close()
- }(resp.Body)
-
- if debug {
- buf := new(strings.Builder)
- _, err = io.Copy(buf, resp.Body)
- if err != nil {
- log.Fatal(err)
- }
- log.Printf("resp.Body: %s", buf.String())
- }
-}
From ce0d80188492697bdc6868b1f9d99f9b1140c16a Mon Sep 17 00:00:00 2001
From: prplecake
Date: Thu, 2 Mar 2023 16:31:31 -0600
Subject: [PATCH 05/33] Add dotnet CI workflow
---
.github/workflows/dotnet.yml | 66 ++++++++++++++++++++++++++++++++++++
mastodon-bookmark-sync.sln | 1 +
2 files changed, 67 insertions(+)
create mode 100644 .github/workflows/dotnet.yml
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
new file mode 100644
index 0000000..491235d
--- /dev/null
+++ b/.github/workflows/dotnet.yml
@@ -0,0 +1,66 @@
+name: .NET
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 7.0.x
+ - name: Restore dependencies
+ run: |
+ dotnet nuget add source --username prplecake --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/CompostInTraining/index.json"
+ dotnet restore
+ - name: Build
+ run: dotnet build --no-restore
+
+ - name: Test
+ run: dotnet test --no-build --verbosity normal --logger "trx" --results-directory "./TestResults"
+
+ - uses: dorny/test-reporter@v1
+ if: always()
+ with:
+ name: .NET Test Results
+ path: TestResults/*.trx
+ reporter: dotnet-trx
+
+ publish:
+ strategy:
+ matrix:
+ rid: [osx-x64, linux-x64, win-x64]
+
+ runs-on: ubuntu-latest
+ name: publish-${{matrix.rid}}
+ needs: build
+ if: ${{ github.event_name != 'pull_request' }} # don't upload artifacts for PRs
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 7.0.x
+ - name: Add NuGet source
+ run: dotnet nuget add source --username prplecake --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/CompostInTraining/index.json"
+ - name: Publish CLI (${{matrix.rid}}
+ run: dotnet publish BookmarkSync.CLI/BookmarkSync.CLI.csproj -c Release -r ${{matrix.rid}} --self-contained
+ - name: Upload CLI artifact
+ uses: actions/upload-artifact@v3
+ with:
+ name: BookmarkSync.CLI-${{matrix.rid}}
+ path: BookmarkSync.CLI/bin/Release/net7.0/${{matrix.rid}}/publish/
\ No newline at end of file
diff --git a/mastodon-bookmark-sync.sln b/mastodon-bookmark-sync.sln
index b92a263..eba9b9e 100644
--- a/mastodon-bookmark-sync.sln
+++ b/mastodon-bookmark-sync.sln
@@ -4,6 +4,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject
README.md = README.md
.gitignore = .gitignore
+ .github\workflows\dotnet.yml = .github\workflows\dotnet.yml
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.CLI", "BookmarkSync.CLI\BookmarkSync.CLI.csproj", "{696935C2-0383-4409-A2B4-B80A8C905DD2}"
From 0e2af4c27df35251e4bb33f0c86d0aa5a44342b4 Mon Sep 17 00:00:00 2001
From: prplecake
Date: Thu, 2 Mar 2023 18:03:12 -0600
Subject: [PATCH 06/33] Resolve CodeFactor errors and cleanup code
---
.github/workflows/dotnet.yml | 4 ++--
BookmarkSync.CLI/Program.cs | 19 ++++++++-----------
.../Configuration/ConfigManager.cs | 6 +++---
.../Entities/Config/Bookmarking.cs | 2 +-
BookmarkSync.Core/Entities/Config/Pinboard.cs | 5 +----
.../Interfaces/IBookmarkingService.cs | 5 +----
.../Services/PinboardBookmarkingService.cs | 5 +----
7 files changed, 17 insertions(+), 29 deletions(-)
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index 491235d..ba2cbd3 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -41,8 +41,8 @@ jobs:
publish:
strategy:
matrix:
- rid: [osx-x64, linux-x64, win-x64]
-
+ rid: [ osx-x64, linux-x64, win-x64 ]
+
runs-on: ubuntu-latest
name: publish-${{matrix.rid}}
needs: build
diff --git a/BookmarkSync.CLI/Program.cs b/BookmarkSync.CLI/Program.cs
index 0cb0073..8d54aaa 100644
--- a/BookmarkSync.CLI/Program.cs
+++ b/BookmarkSync.CLI/Program.cs
@@ -27,22 +27,19 @@ public async static Task Main(string[] args)
.Build();
await host.StartAsync();
var lifetime = host.Services.GetRequiredService();
-
+
// Do work here
Console.WriteLine("Hello, world!");
-
+
// Shutdown
configManager.SaveToFile();
-
+
lifetime.StopApplication();
await host.WaitForShutdownAsync();
}
- private static IConfiguration SetupConfiguration(string[] args)
- {
- return new ConfigurationBuilder()
- .AddJsonFile("appsettings.json", false, true)
- .AddEnvironmentVariables()
- .AddCommandLine(args)
- .Build();
- }
+ private static IConfiguration SetupConfiguration(string[] args) => new ConfigurationBuilder()
+ .AddJsonFile("appsettings.json", false, true)
+ .AddEnvironmentVariables()
+ .AddCommandLine(args)
+ .Build();
}
diff --git a/BookmarkSync.Core/Configuration/ConfigManager.cs b/BookmarkSync.Core/Configuration/ConfigManager.cs
index b0d8ec0..692459e 100644
--- a/BookmarkSync.Core/Configuration/ConfigManager.cs
+++ b/BookmarkSync.Core/Configuration/ConfigManager.cs
@@ -10,9 +10,9 @@ namespace BookmarkSync.Core.Configuration;
public interface IConfigManager
{
+ App App { get; set; }
IConfiguration Configuration { get; set; }
Instance[] Instances { get; set; }
- App App { get; set; }
string GetConfigValue(string key);
void SaveToFile();
}
@@ -22,8 +22,8 @@ public ConfigManager(
IConfiguration configuration)
{
Configuration = configuration;
- List instance = Configuration.GetSection("Instances").Get>();
- App app = Configuration.GetSection("App").Get();
+ var instance = Configuration.GetSection("Instances").Get>();
+ var app = Configuration.GetSection("App").Get();
var instances = Configuration.GetSection("Instances").Get();
App = app;
diff --git a/BookmarkSync.Core/Entities/Config/Bookmarking.cs b/BookmarkSync.Core/Entities/Config/Bookmarking.cs
index 969f398..b028f53 100644
--- a/BookmarkSync.Core/Entities/Config/Bookmarking.cs
+++ b/BookmarkSync.Core/Entities/Config/Bookmarking.cs
@@ -2,6 +2,6 @@ namespace BookmarkSync.Core.Entities.Config;
public class Bookmarking : ConfigurationBase
{
- public string Service { get; set; }
public string ApiToken { get; set; }
+ public string Service { get; set; }
}
diff --git a/BookmarkSync.Core/Entities/Config/Pinboard.cs b/BookmarkSync.Core/Entities/Config/Pinboard.cs
index 1aa1551..e15f31c 100644
--- a/BookmarkSync.Core/Entities/Config/Pinboard.cs
+++ b/BookmarkSync.Core/Entities/Config/Pinboard.cs
@@ -1,6 +1,3 @@
namespace BookmarkSync.Core.Entities.Config;
-public class Pinboard : ConfigurationBase
-{
-
-}
+public class Pinboard : ConfigurationBase { }
diff --git a/BookmarkSync.Core/Interfaces/IBookmarkingService.cs b/BookmarkSync.Core/Interfaces/IBookmarkingService.cs
index 8ec9389..0b6bba6 100644
--- a/BookmarkSync.Core/Interfaces/IBookmarkingService.cs
+++ b/BookmarkSync.Core/Interfaces/IBookmarkingService.cs
@@ -1,6 +1,3 @@
namespace BookmarkSync.Core.Interfaces;
-public interface IBookmarkingService
-{
-
-}
+public interface IBookmarkingService { }
diff --git a/BookmarkSync.Infrastructure/Services/PinboardBookmarkingService.cs b/BookmarkSync.Infrastructure/Services/PinboardBookmarkingService.cs
index 767cedf..44894a1 100644
--- a/BookmarkSync.Infrastructure/Services/PinboardBookmarkingService.cs
+++ b/BookmarkSync.Infrastructure/Services/PinboardBookmarkingService.cs
@@ -2,7 +2,4 @@
namespace BookmarkSync.Infrastructure.Services;
-public class PinboardBookmarkingService : IBookmarkingService
-{
-
-}
+public class PinboardBookmarkingService : IBookmarkingService { }
From 9a20b8e797e580c99299cd2be5aaa354c11f3007 Mon Sep 17 00:00:00 2001
From: prplecake
Date: Thu, 2 Mar 2023 18:03:39 -0600
Subject: [PATCH 07/33] Add basic tests
---
.../BookmarkSync.Core.Tests.csproj | 23 ++++
.../Configuration/ConfigManagerTests.cs | 52 +++++++++
.../Entities/AccountTests.cs | 30 +++++
.../Entities/BookmarkTests.cs | 22 ++++
.../Entities/Config/AppTests.cs | 21 ++++
.../Entities/Config/BookmarkingTests.cs | 21 ++++
.../Entities/Config/InstanceTests.cs | 34 ++++++
.../Entities/Config/PinboardTests.cs | 19 ++++
.../Helpers/TestHelpers.cs | 106 ++++++++++++++++++
BookmarkSync.Core.Tests/Usings.cs | 2 +
mastodon-bookmark-sync.sln | 6 +
11 files changed, 336 insertions(+)
create mode 100644 BookmarkSync.Core.Tests/BookmarkSync.Core.Tests.csproj
create mode 100644 BookmarkSync.Core.Tests/Configuration/ConfigManagerTests.cs
create mode 100644 BookmarkSync.Core.Tests/Entities/AccountTests.cs
create mode 100644 BookmarkSync.Core.Tests/Entities/BookmarkTests.cs
create mode 100644 BookmarkSync.Core.Tests/Entities/Config/AppTests.cs
create mode 100644 BookmarkSync.Core.Tests/Entities/Config/BookmarkingTests.cs
create mode 100644 BookmarkSync.Core.Tests/Entities/Config/InstanceTests.cs
create mode 100644 BookmarkSync.Core.Tests/Entities/Config/PinboardTests.cs
create mode 100644 BookmarkSync.Core.Tests/Helpers/TestHelpers.cs
create mode 100644 BookmarkSync.Core.Tests/Usings.cs
diff --git a/BookmarkSync.Core.Tests/BookmarkSync.Core.Tests.csproj b/BookmarkSync.Core.Tests/BookmarkSync.Core.Tests.csproj
new file mode 100644
index 0000000..e05c2a9
--- /dev/null
+++ b/BookmarkSync.Core.Tests/BookmarkSync.Core.Tests.csproj
@@ -0,0 +1,23 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BookmarkSync.Core.Tests/Configuration/ConfigManagerTests.cs b/BookmarkSync.Core.Tests/Configuration/ConfigManagerTests.cs
new file mode 100644
index 0000000..5bb81f4
--- /dev/null
+++ b/BookmarkSync.Core.Tests/Configuration/ConfigManagerTests.cs
@@ -0,0 +1,52 @@
+using BookmarkSync.Core.Configuration;
+using Microsoft.Extensions.Configuration;
+
+namespace BookmarkSync.Core.Tests.Configuration;
+
+[TestClass]
+public class ConfigManagerTests
+{
+ [TestInitialize]
+ public void Init()
+ {
+ var inMemoryConfig = new Dictionary
+ {
+ {
+ "App:Bookmarking:Service", "Pinboard"
+ },
+ {
+ "Instances:0:Uri", "https://compostintraining.club"
+ }
+ };
+ _config = new ConfigurationBuilder()
+ .AddInMemoryCollection(inMemoryConfig)
+ .Build();
+
+ _configManager = new ConfigManager(_config);
+ }
+ private IConfigManager _configManager;
+ private IConfiguration _config;
+ [TestMethod]
+ public void ConfigManager_HasProperties()
+ {
+ // Assert
+ Assert.AreEqual(3, _configManager.PropertyCount());
+ Assert.IsTrue(_configManager.HasProperty("Configuration"));
+ Assert.IsTrue(_configManager.HasProperty("Instances"));
+ Assert.IsTrue(_configManager.HasProperty("App"));
+
+ Assert.IsTrue(_configManager.HasMethod("GetConfigValue"));
+ }
+ [TestMethod]
+ public void GetConfigValue_Success()
+ {
+ // Arrange
+ var expected = "Pinboard";
+
+ // Act
+ string actual = _configManager.GetConfigValue("App:Bookmarking:Service");
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+}
diff --git a/BookmarkSync.Core.Tests/Entities/AccountTests.cs b/BookmarkSync.Core.Tests/Entities/AccountTests.cs
new file mode 100644
index 0000000..b817f43
--- /dev/null
+++ b/BookmarkSync.Core.Tests/Entities/AccountTests.cs
@@ -0,0 +1,30 @@
+using BookmarkSync.Core.Entities;
+
+namespace BookmarkSync.Core.Tests.Entities;
+
+[TestClass]
+public class AccountTests
+{
+ [TestMethod]
+ public void Account_HasProperties()
+ {
+ // Arrange
+ Account obj = new();
+
+ // Assert
+ Assert.AreEqual(1, obj.PropertyCount());
+ Assert.IsTrue(obj.HasProperty("Name"));
+ }
+ [TestMethod]
+ public void Account_ToString_Is_Name()
+ {
+ // Arrange
+ Account obj = new()
+ {
+ Name = "@prplecake@compostintraining.club"
+ };
+
+ // Assert
+ Assert.AreEqual(obj.ToString(), obj.Name);
+ }
+}
diff --git a/BookmarkSync.Core.Tests/Entities/BookmarkTests.cs b/BookmarkSync.Core.Tests/Entities/BookmarkTests.cs
new file mode 100644
index 0000000..c38f612
--- /dev/null
+++ b/BookmarkSync.Core.Tests/Entities/BookmarkTests.cs
@@ -0,0 +1,22 @@
+using BookmarkSync.Core.Entities;
+
+namespace BookmarkSync.Core.Tests.Entities;
+
+[TestClass]
+public class BookmarkTests
+{
+ [TestMethod]
+ public void App_HasProperties()
+ {
+ // Arrange
+ Bookmark obj = new();
+
+ // Assert
+ Assert.AreEqual(5, obj.PropertyCount());
+ Assert.IsTrue(obj.HasProperty("Account"));
+ Assert.IsTrue(obj.HasProperty("Content"));
+ Assert.IsTrue(obj.HasProperty("Id"));
+ Assert.IsTrue(obj.HasProperty("Uri"));
+ Assert.IsTrue(obj.HasProperty("Visibility"));
+ }
+}
diff --git a/BookmarkSync.Core.Tests/Entities/Config/AppTests.cs b/BookmarkSync.Core.Tests/Entities/Config/AppTests.cs
new file mode 100644
index 0000000..e979d08
--- /dev/null
+++ b/BookmarkSync.Core.Tests/Entities/Config/AppTests.cs
@@ -0,0 +1,21 @@
+using BookmarkSync.Core.Entities.Config;
+
+namespace BookmarkSync.Core.Tests.Entities.Config;
+
+[TestClass]
+public class AppTests
+{
+ [TestMethod]
+ public void App_HasProperties()
+ {
+ // Arrange
+ App obj = new();
+
+ // Assert
+ Assert.AreEqual(2, obj.PropertyCount());
+ Assert.IsTrue(obj.HasProperty("Bookmarking"));
+ Assert.IsTrue(obj.HasProperty("LastSynced"));
+
+ Assert.IsTrue(obj.HasMethod("IsValid"));
+ }
+}
diff --git a/BookmarkSync.Core.Tests/Entities/Config/BookmarkingTests.cs b/BookmarkSync.Core.Tests/Entities/Config/BookmarkingTests.cs
new file mode 100644
index 0000000..d200847
--- /dev/null
+++ b/BookmarkSync.Core.Tests/Entities/Config/BookmarkingTests.cs
@@ -0,0 +1,21 @@
+using BookmarkSync.Core.Entities.Config;
+
+namespace BookmarkSync.Core.Tests.Entities.Config;
+
+[TestClass]
+public class BookmarkingTests
+{
+ [TestMethod]
+ public void Bookmarking_HasProperties()
+ {
+ // Arrange
+ Bookmarking obj = new();
+
+ // Assert
+ Assert.AreEqual(2, obj.PropertyCount());
+ Assert.IsTrue(obj.HasProperty("ApiToken"));
+ Assert.IsTrue(obj.HasProperty("Service"));
+
+ Assert.IsTrue(obj.HasMethod("IsValid"));
+ }
+}
diff --git a/BookmarkSync.Core.Tests/Entities/Config/InstanceTests.cs b/BookmarkSync.Core.Tests/Entities/Config/InstanceTests.cs
new file mode 100644
index 0000000..cf82c9d
--- /dev/null
+++ b/BookmarkSync.Core.Tests/Entities/Config/InstanceTests.cs
@@ -0,0 +1,34 @@
+using BookmarkSync.Core.Entities.Config;
+
+namespace BookmarkSync.Core.Tests.Entities.Config;
+
+[TestClass]
+public class InstanceTests
+{
+ [TestMethod]
+ public void Instance_HasProperties()
+ {
+ // Arrange
+ Instance obj = new();
+
+ // Assert
+ Assert.AreEqual(3, obj.PropertyCount());
+ Assert.IsTrue(obj.HasProperty("AccessToken"));
+ Assert.IsTrue(obj.HasProperty("DeleteBookmarks"));
+ Assert.IsTrue(obj.HasProperty("Uri"));
+
+ Assert.IsTrue(obj.HasMethod("IsValid"));
+ }
+ [TestMethod]
+ public void Instance_ToString_Is_Uri()
+ {
+ // Arrange
+ Instance obj = new()
+ {
+ Uri = "https://compostintraining.club"
+ };
+
+ // Assert
+ Assert.AreEqual(obj.ToString(), obj.Uri);
+ }
+}
diff --git a/BookmarkSync.Core.Tests/Entities/Config/PinboardTests.cs b/BookmarkSync.Core.Tests/Entities/Config/PinboardTests.cs
new file mode 100644
index 0000000..725d663
--- /dev/null
+++ b/BookmarkSync.Core.Tests/Entities/Config/PinboardTests.cs
@@ -0,0 +1,19 @@
+using BookmarkSync.Core.Entities.Config;
+
+namespace BookmarkSync.Core.Tests.Entities.Config;
+
+[TestClass]
+public class PinboardTests
+{
+ [TestMethod]
+ public void Pinboard_HasProperties()
+ {
+ // Arrange
+ Pinboard obj = new();
+
+ // Assert
+ Assert.AreEqual(0, obj.PropertyCount());
+
+ Assert.IsTrue(obj.HasMethod("IsValid"));
+ }
+}
diff --git a/BookmarkSync.Core.Tests/Helpers/TestHelpers.cs b/BookmarkSync.Core.Tests/Helpers/TestHelpers.cs
new file mode 100644
index 0000000..c947eaf
--- /dev/null
+++ b/BookmarkSync.Core.Tests/Helpers/TestHelpers.cs
@@ -0,0 +1,106 @@
+using System.Reflection;
+#pragma warning disable CS8604
+#pragma warning disable CS8600
+#pragma warning disable CS8602
+namespace BookmarkSync.Core.Tests.Helpers;
+
+public static class EntityTests
+{
+ public static bool HasMethod(this object obj, string methodName)
+ {
+ var type = obj.GetType();
+ try
+ {
+ return type.GetMethod(methodName) != null;
+ }
+ catch (AmbiguousMatchException)
+ {
+ return true;
+ }
+ }
+ public static bool HasProperty(this object obj, string propertyName)
+ {
+ var type = obj.GetType();
+ return type.GetProperty(propertyName) != null;
+ }
+ public static int PropertyCount(this object obj)
+ {
+ var type = obj.GetType();
+ return type.GetProperties().Length;
+ }
+ public static T SetProperties(T domainObject, bool recursive = false)
+ {
+ var props = domainObject.GetType().GetProperties();
+ foreach (var prop in props)
+ {
+ var propType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
+ try
+ {
+ object propObj = null;
+ object data;
+ switch (propType.Name.ToLower())
+ {
+ case "string":
+ data = "test";
+ break;
+ case "int":
+ case "int32":
+ data = 2;
+ break;
+ case "datetime":
+ data = DateTime.Now;
+ break;
+ case "bool":
+ case "boolean":
+ data = true;
+ break;
+ case "decimal":
+ data = decimal.Parse("1.23");
+ break;
+ case "double":
+ data = double.Parse("3.21");
+ break;
+ default:
+ if (propType.IsInterface)
+ {
+ propObj = null;
+ }
+ else if (propType.IsArray)
+ {
+ var elementType = propType.GetElementType();
+ propObj = Array.CreateInstance(elementType, 1);
+ }
+ else
+ {
+ var ctr = propType.GetConstructors()[0];
+ propObj = ctr.GetParameters().Any() ? null : Activator.CreateInstance(propType);
+ }
+ data = propObj;
+ break;
+ }
+ if (data != null && prop.CanWrite)
+ {
+ prop.SetValue(domainObject, data);
+ Assert.AreEqual(data, prop.GetValue(domainObject));
+ }
+ if (recursive && propObj != null)
+ {
+ if (propType.IsGenericType)
+ {
+ var myListElementType = propType.GetGenericArguments().Single();
+ propObj = Activator.CreateInstance(myListElementType);
+ }
+ SetProperties(propObj, recursive);
+ }
+ }
+ catch (Exception ex)
+ {
+ var msg = string.Format(
+ "Error creating instance of {0} because: {1}",
+ propType.Name, ex.Message);
+ Assert.IsNotNull(prop.GetValue(domainObject), msg);
+ }
+ }
+ return domainObject;
+ }
+}
diff --git a/BookmarkSync.Core.Tests/Usings.cs b/BookmarkSync.Core.Tests/Usings.cs
new file mode 100644
index 0000000..87c1c76
--- /dev/null
+++ b/BookmarkSync.Core.Tests/Usings.cs
@@ -0,0 +1,2 @@
+global using BookmarkSync.Core.Tests.Helpers;
+global using Microsoft.VisualStudio.TestTools.UnitTesting;
diff --git a/mastodon-bookmark-sync.sln b/mastodon-bookmark-sync.sln
index eba9b9e..2964f73 100644
--- a/mastodon-bookmark-sync.sln
+++ b/mastodon-bookmark-sync.sln
@@ -13,6 +13,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.Core", "Bookma
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.Infrastructure", "BookmarkSync.Infrastructure\BookmarkSync.Infrastructure.csproj", "{D11BD068-7AD0-4C9D-85A0-BD04A67AA7FC}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.Core.Tests", "BookmarkSync.Core.Tests\BookmarkSync.Core.Tests.csproj", "{9B28E255-C1D4-43A6-861A-DD1752F31A0E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -31,5 +33,9 @@ Global
{D11BD068-7AD0-4C9D-85A0-BD04A67AA7FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D11BD068-7AD0-4C9D-85A0-BD04A67AA7FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D11BD068-7AD0-4C9D-85A0-BD04A67AA7FC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9B28E255-C1D4-43A6-861A-DD1752F31A0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9B28E255-C1D4-43A6-861A-DD1752F31A0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9B28E255-C1D4-43A6-861A-DD1752F31A0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9B28E255-C1D4-43A6-861A-DD1752F31A0E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
From 3aed8ee0dfcd5fad1ed6694ca9cc7ec710e57ee4 Mon Sep 17 00:00:00 2001
From: prplecake
Date: Thu, 2 Mar 2023 18:03:43 -0600
Subject: [PATCH 08/33] Update JetBrains project settings
---
.../.idea/codeStyles/Project.xml | 22 +++++++++++++++++++
.../.idea/codeStyles/codeStyleConfig.xml | 5 +++++
mastodon-bookmark-sync.sln.DotSettings | 2 ++
3 files changed, 29 insertions(+)
create mode 100644 .idea/.idea.mastodon-bookmark-sync/.idea/codeStyles/Project.xml
create mode 100644 .idea/.idea.mastodon-bookmark-sync/.idea/codeStyles/codeStyleConfig.xml
create mode 100644 mastodon-bookmark-sync.sln.DotSettings
diff --git a/.idea/.idea.mastodon-bookmark-sync/.idea/codeStyles/Project.xml b/.idea/.idea.mastodon-bookmark-sync/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..0d4f3b0
--- /dev/null
+++ b/.idea/.idea.mastodon-bookmark-sync/.idea/codeStyles/Project.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.mastodon-bookmark-sync/.idea/codeStyles/codeStyleConfig.xml b/.idea/.idea.mastodon-bookmark-sync/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..79ee123
--- /dev/null
+++ b/.idea/.idea.mastodon-bookmark-sync/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/mastodon-bookmark-sync.sln.DotSettings b/mastodon-bookmark-sync.sln.DotSettings
new file mode 100644
index 0000000..7f259e9
--- /dev/null
+++ b/mastodon-bookmark-sync.sln.DotSettings
@@ -0,0 +1,2 @@
+
+ True
\ No newline at end of file
From 708bd4cc2e7519c2a7ef4e8108cbf797df1d87df Mon Sep 17 00:00:00 2001
From: prplecake
Date: Thu, 2 Mar 2023 18:12:41 -0600
Subject: [PATCH 09/33] Resolve nullability warnings
---
BookmarkSync.CLI/Program.cs | 6 +++---
.../Configuration/ConfigManagerTests.cs | 16 ++++++++--------
BookmarkSync.Core/Configuration/ConfigManager.cs | 16 +++++++---------
BookmarkSync.Core/Entities/Account.cs | 4 ++--
BookmarkSync.Core/Entities/Bookmark.cs | 10 +++++-----
BookmarkSync.Core/Entities/Config/App.cs | 2 +-
BookmarkSync.Core/Entities/Config/Bookmarking.cs | 4 ++--
BookmarkSync.Core/Entities/Config/Instance.cs | 6 +++---
8 files changed, 31 insertions(+), 33 deletions(-)
diff --git a/BookmarkSync.CLI/Program.cs b/BookmarkSync.CLI/Program.cs
index 8d54aaa..82fec66 100644
--- a/BookmarkSync.CLI/Program.cs
+++ b/BookmarkSync.CLI/Program.cs
@@ -11,11 +11,11 @@ namespace BookmarkSync.CLI;
public class Program
{
- private static IConfiguration Configuration;
+ private static IConfiguration? _configuration;
public async static Task Main(string[] args)
{
- Configuration = SetupConfiguration(args);
- IConfigManager configManager = new ConfigManager(Configuration);
+ _configuration = SetupConfiguration(args);
+ IConfigManager configManager = new ConfigManager(_configuration);
using var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
diff --git a/BookmarkSync.Core.Tests/Configuration/ConfigManagerTests.cs b/BookmarkSync.Core.Tests/Configuration/ConfigManagerTests.cs
index 5bb81f4..21aabac 100644
--- a/BookmarkSync.Core.Tests/Configuration/ConfigManagerTests.cs
+++ b/BookmarkSync.Core.Tests/Configuration/ConfigManagerTests.cs
@@ -24,18 +24,18 @@ public void Init()
_configManager = new ConfigManager(_config);
}
- private IConfigManager _configManager;
- private IConfiguration _config;
+ private IConfigManager? _configManager;
+ private IConfiguration? _config;
[TestMethod]
public void ConfigManager_HasProperties()
{
// Assert
- Assert.AreEqual(3, _configManager.PropertyCount());
- Assert.IsTrue(_configManager.HasProperty("Configuration"));
- Assert.IsTrue(_configManager.HasProperty("Instances"));
- Assert.IsTrue(_configManager.HasProperty("App"));
+ Assert.AreEqual(3, _configManager?.PropertyCount());
+ Assert.IsTrue(_configManager?.HasProperty("Configuration"));
+ Assert.IsTrue(_configManager?.HasProperty("Instances"));
+ Assert.IsTrue(_configManager?.HasProperty("App"));
- Assert.IsTrue(_configManager.HasMethod("GetConfigValue"));
+ Assert.IsTrue(_configManager?.HasMethod("GetConfigValue"));
}
[TestMethod]
public void GetConfigValue_Success()
@@ -44,7 +44,7 @@ public void GetConfigValue_Success()
var expected = "Pinboard";
// Act
- string actual = _configManager.GetConfigValue("App:Bookmarking:Service");
+ string? actual = _configManager?.GetConfigValue("App:Bookmarking:Service");
// Assert
Assert.AreEqual(expected, actual);
diff --git a/BookmarkSync.Core/Configuration/ConfigManager.cs b/BookmarkSync.Core/Configuration/ConfigManager.cs
index 692459e..0bcfe34 100644
--- a/BookmarkSync.Core/Configuration/ConfigManager.cs
+++ b/BookmarkSync.Core/Configuration/ConfigManager.cs
@@ -10,9 +10,9 @@ namespace BookmarkSync.Core.Configuration;
public interface IConfigManager
{
- App App { get; set; }
+ App? App { get; set; }
IConfiguration Configuration { get; set; }
- Instance[] Instances { get; set; }
+ List? Instances { get; set; }
string GetConfigValue(string key);
void SaveToFile();
}
@@ -22,19 +22,17 @@ public ConfigManager(
IConfiguration configuration)
{
Configuration = configuration;
- var instance = Configuration.GetSection("Instances").Get>();
- var app = Configuration.GetSection("App").Get();
- var instances = Configuration.GetSection("Instances").Get();
- App = app;
+ App = Configuration.GetSection("App").Get();
+ Instances = Configuration.GetSection("Instances").Get>();
- if (!App.IsValid())
+ if (App is not null && !App.IsValid())
{
throw new InvalidConfigurationException();
}
}
public IConfiguration Configuration { get; set; }
- public Instance[] Instances { get; set; }
- public App App { get; set; }
+ public List? Instances { get; set; }
+ public App? App { get; set; }
public string GetConfigValue(string key)
{
string? value = Configuration[key];
diff --git a/BookmarkSync.Core/Entities/Account.cs b/BookmarkSync.Core/Entities/Account.cs
index 09a5515..452ba8e 100644
--- a/BookmarkSync.Core/Entities/Account.cs
+++ b/BookmarkSync.Core/Entities/Account.cs
@@ -2,7 +2,7 @@ namespace BookmarkSync.Core.Entities;
public class Account
{
- public string Name { get; set; }
+ public string? Name { get; set; }
///
- public override string ToString() => Name;
+ public override string ToString() => Name ?? GetType().Name;
}
diff --git a/BookmarkSync.Core/Entities/Bookmark.cs b/BookmarkSync.Core/Entities/Bookmark.cs
index 2707cdf..8a444d9 100644
--- a/BookmarkSync.Core/Entities/Bookmark.cs
+++ b/BookmarkSync.Core/Entities/Bookmark.cs
@@ -2,9 +2,9 @@ namespace BookmarkSync.Core.Entities;
public class Bookmark
{
- public Account Account { get; set; }
- public string Content { get; set; }
- public string Id { get; set; }
- public string Uri { get; set; }
- public string Visibility { get; set; }
+ public Account? Account { get; set; }
+ public string? Content { get; set; }
+ public string? Id { get; set; }
+ public string? Uri { get; set; }
+ public string? Visibility { get; set; }
}
diff --git a/BookmarkSync.Core/Entities/Config/App.cs b/BookmarkSync.Core/Entities/Config/App.cs
index 669ae68..95ecd3d 100644
--- a/BookmarkSync.Core/Entities/Config/App.cs
+++ b/BookmarkSync.Core/Entities/Config/App.cs
@@ -5,6 +5,6 @@ namespace BookmarkSync.Core.Entities.Config;
public class App : ConfigurationBase
{
- [ConfigRequired] public Bookmarking Bookmarking { get; set; }
+ [ConfigRequired] public Bookmarking? Bookmarking { get; set; }
public DateTime LastSynced { get; set; }
}
diff --git a/BookmarkSync.Core/Entities/Config/Bookmarking.cs b/BookmarkSync.Core/Entities/Config/Bookmarking.cs
index b028f53..179d638 100644
--- a/BookmarkSync.Core/Entities/Config/Bookmarking.cs
+++ b/BookmarkSync.Core/Entities/Config/Bookmarking.cs
@@ -2,6 +2,6 @@ namespace BookmarkSync.Core.Entities.Config;
public class Bookmarking : ConfigurationBase
{
- public string ApiToken { get; set; }
- public string Service { get; set; }
+ public string? ApiToken { get; set; }
+ public string? Service { get; set; }
}
diff --git a/BookmarkSync.Core/Entities/Config/Instance.cs b/BookmarkSync.Core/Entities/Config/Instance.cs
index 0b592cb..9e339d2 100644
--- a/BookmarkSync.Core/Entities/Config/Instance.cs
+++ b/BookmarkSync.Core/Entities/Config/Instance.cs
@@ -2,9 +2,9 @@ namespace BookmarkSync.Core.Entities.Config;
public class Instance : ConfigurationBase
{
- public string AccessToken { get; set; }
+ public string? AccessToken { get; set; }
public bool DeleteBookmarks { get; set; }
- public string Uri { get; set; }
+ public string? Uri { get; set; }
///
- public override string ToString() => Uri;
+ public override string ToString() => Uri ?? GetType().Name;
}
From 5c3767c35ee2427094651f48d79ad4d40b93bfd2 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 01:32:14 -0500
Subject: [PATCH 10/33] Stub out BookmarkingService base and Pinboard class
---
BookmarkSync.Core/Entities/Config/App.cs | 2 +-
.../Interfaces/IBookmarkingService.cs | 12 +++-
.../BookmarkSync.Infrastructure.Tests.csproj | 23 ++++++++
.../Services/BookmarkingServiceTests.cs | 59 +++++++++++++++++++
.../Pinboard/PinboardBookmarkTests.cs | 50 ++++++++++++++++
BookmarkSync.Infrastructure.Tests/Usings.cs | 2 +
.../BookmarkSync.Infrastructure.csproj | 2 +
.../Services/BookmarkSyncService.cs | 39 ++++++++++++
.../Services/BookmarkingService.cs | 44 ++++++++++++++
.../Services/Pinboard/PinboardBookmark.cs | 12 ++++
.../Pinboard/PinboardBookmarkingService.cs | 37 ++++++++++++
.../Services/PinboardBookmarkingService.cs | 5 --
mastodon-bookmark-sync.sln | 6 ++
13 files changed, 286 insertions(+), 7 deletions(-)
create mode 100644 BookmarkSync.Infrastructure.Tests/BookmarkSync.Infrastructure.Tests.csproj
create mode 100644 BookmarkSync.Infrastructure.Tests/Services/BookmarkingServiceTests.cs
create mode 100644 BookmarkSync.Infrastructure.Tests/Services/Pinboard/PinboardBookmarkTests.cs
create mode 100644 BookmarkSync.Infrastructure.Tests/Usings.cs
create mode 100644 BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
create mode 100644 BookmarkSync.Infrastructure/Services/BookmarkingService.cs
create mode 100644 BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmark.cs
create mode 100644 BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmarkingService.cs
delete mode 100644 BookmarkSync.Infrastructure/Services/PinboardBookmarkingService.cs
diff --git a/BookmarkSync.Core/Entities/Config/App.cs b/BookmarkSync.Core/Entities/Config/App.cs
index 95ecd3d..2921eca 100644
--- a/BookmarkSync.Core/Entities/Config/App.cs
+++ b/BookmarkSync.Core/Entities/Config/App.cs
@@ -5,6 +5,6 @@ namespace BookmarkSync.Core.Entities.Config;
public class App : ConfigurationBase
{
- [ConfigRequired] public Bookmarking? Bookmarking { get; set; }
+ [ConfigRequired] public Bookmarking Bookmarking { get; set; } = null!;
public DateTime LastSynced { get; set; }
}
diff --git a/BookmarkSync.Core/Interfaces/IBookmarkingService.cs b/BookmarkSync.Core/Interfaces/IBookmarkingService.cs
index 0b6bba6..7ed1459 100644
--- a/BookmarkSync.Core/Interfaces/IBookmarkingService.cs
+++ b/BookmarkSync.Core/Interfaces/IBookmarkingService.cs
@@ -1,3 +1,13 @@
+using System.Threading.Tasks;
+using BookmarkSync.Core.Entities;
+
namespace BookmarkSync.Core.Interfaces;
-public interface IBookmarkingService { }
+public interface IBookmarkingService
+{
+ ///
+ /// Saves a bookmark to the bookmarking service.
+ ///
+ /// A service's bookmark implementation.
+ public Task Save(Bookmark bookmark);
+}
diff --git a/BookmarkSync.Infrastructure.Tests/BookmarkSync.Infrastructure.Tests.csproj b/BookmarkSync.Infrastructure.Tests/BookmarkSync.Infrastructure.Tests.csproj
new file mode 100644
index 0000000..127dac4
--- /dev/null
+++ b/BookmarkSync.Infrastructure.Tests/BookmarkSync.Infrastructure.Tests.csproj
@@ -0,0 +1,23 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BookmarkSync.Infrastructure.Tests/Services/BookmarkingServiceTests.cs b/BookmarkSync.Infrastructure.Tests/Services/BookmarkingServiceTests.cs
new file mode 100644
index 0000000..c36b1b1
--- /dev/null
+++ b/BookmarkSync.Infrastructure.Tests/Services/BookmarkingServiceTests.cs
@@ -0,0 +1,59 @@
+using BookmarkSync.Core.Configuration;
+using BookmarkSync.Infrastructure.Services;
+using BookmarkSync.Infrastructure.Services.Pinboard;
+using Microsoft.Extensions.Configuration;
+
+namespace BookmarkSync.Infrastructure.Tests.Services;
+
+[TestClass]
+public class BookmarkingServiceTests
+{
+ [TestMethod]
+ public void GetBookmarkingService_Pinboard()
+ {
+ // Arrange
+ var config = new Dictionary
+ {
+ {
+ "App:Bookmarking:Service", "Pinboard"
+ },
+ {
+ "App:Bookmarking:ApiToken", "secret:123456789"
+ }
+ };
+ var configuration = new ConfigurationBuilder()
+ .AddInMemoryCollection(config)
+ .Build();
+
+ IConfigManager configManager = new ConfigManager(configuration);
+
+ // Act
+ var obj = BookmarkingService.GetBookmarkingService(configManager);
+
+ // Assert
+ Assert.AreEqual(obj.GetType(), typeof(PinboardBookmarkingService));
+ Assert.IsInstanceOfType(obj, typeof(PinboardBookmarkingService));
+ }
+ [TestMethod]
+ [ExpectedException(typeof(InvalidOperationException))]
+ public void GetBookmarkingService_Exception()
+ {
+ // Arrange
+ var config = new Dictionary
+ {
+ {
+ "App:Bookmarking:Service", "Nonsense"
+ }
+ };
+ var configuration = new ConfigurationBuilder()
+ .AddInMemoryCollection(config)
+ .Build();
+
+ IConfigManager configManager = new ConfigManager(configuration);
+
+ // Act
+ var unused = BookmarkingService.GetBookmarkingService(configManager);
+
+ // Assert - Exception
+ }
+}
diff --git a/BookmarkSync.Infrastructure.Tests/Services/Pinboard/PinboardBookmarkTests.cs b/BookmarkSync.Infrastructure.Tests/Services/Pinboard/PinboardBookmarkTests.cs
new file mode 100644
index 0000000..d41ba90
--- /dev/null
+++ b/BookmarkSync.Infrastructure.Tests/Services/Pinboard/PinboardBookmarkTests.cs
@@ -0,0 +1,50 @@
+using BookmarkSync.Infrastructure.Services.Pinboard;
+
+namespace BookmarkSync.Infrastructure.Tests.Services.Pinboard;
+
+[TestClass]
+public class PinboardBookmarkTests
+{
+ [TestMethod]
+ public void PinboardBookmark_HasProperties()
+ {
+ // Arrange
+ PinboardBookmark obj = new();
+
+ // Assert
+ Assert.AreEqual(5, obj.PropertyCount());
+ Assert.IsTrue(obj.HasProperty("Description"));
+ Assert.IsTrue(obj.HasProperty("ExtendedDescription"));
+ Assert.IsTrue(obj.HasProperty("Shared"));
+ Assert.IsTrue(obj.HasProperty("Tags"));
+ Assert.IsTrue(obj.HasProperty("Uri"));
+
+ Assert.IsTrue(obj.HasMethod("GetFormattedTags"));
+ }
+
+ [TestMethod]
+ public void GetFormattedTags_NullTags()
+ {
+ // Arrange
+ PinboardBookmark obj = new();
+
+ // Assert
+ Assert.IsNull(obj.GetFormattedTags());
+ }
+ [TestMethod]
+ public void GetFormattedTags_WithTags()
+ {
+ // Arrange
+ PinboardBookmark obj = new()
+ {
+ Tags = new[]
+ {
+ "first-tag", "second-tag"
+ }
+ };
+ const string expected = "first-tag second-tag";
+
+ // Assert
+ Assert.AreEqual(expected, obj.GetFormattedTags());
+ }
+}
diff --git a/BookmarkSync.Infrastructure.Tests/Usings.cs b/BookmarkSync.Infrastructure.Tests/Usings.cs
new file mode 100644
index 0000000..87c1c76
--- /dev/null
+++ b/BookmarkSync.Infrastructure.Tests/Usings.cs
@@ -0,0 +1,2 @@
+global using BookmarkSync.Core.Tests.Helpers;
+global using Microsoft.VisualStudio.TestTools.UnitTesting;
diff --git a/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj b/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj
index 9d63ce0..ca178e5 100644
--- a/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj
+++ b/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj
@@ -8,6 +8,8 @@
+
+
diff --git a/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs b/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
new file mode 100644
index 0000000..96414dc
--- /dev/null
+++ b/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using BookmarkSync.Core.Configuration;
+using BookmarkSync.Core.Entities;
+using BookmarkSync.Core.Interfaces;
+using Microsoft.Extensions.Hosting;
+using Serilog;
+
+namespace BookmarkSync.Infrastructure.Services;
+
+public class BookmarkSyncService : IHostedService
+{
+ private readonly IHostApplicationLifetime _host;
+ private readonly IBookmarkingService _bookmarkingService;
+ private static readonly ILogger _logger = Log.ForContext();
+ public BookmarkSyncService(IHostApplicationLifetime host, IConfigManager configManager)
+ {
+ _bookmarkingService = BookmarkingService.GetBookmarkingService(configManager);
+ _host = host;
+ }
+ ///
+ public Task StartAsync(CancellationToken stoppingToken)
+ {
+ _logger.Information("The current time is: {CurrentTime}", DateTimeOffset.UtcNow);
+
+ // Get bookmarks from mastodon account
+ // TODO
+
+ // Save bookmarks to bookmarking service
+ _bookmarkingService.Save(new Bookmark());
+
+ // Finish task
+ _host.StopApplication();
+ return Task.CompletedTask;
+ }
+ ///
+ public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
+}
diff --git a/BookmarkSync.Infrastructure/Services/BookmarkingService.cs b/BookmarkSync.Infrastructure/Services/BookmarkingService.cs
new file mode 100644
index 0000000..7d6b231
--- /dev/null
+++ b/BookmarkSync.Infrastructure/Services/BookmarkingService.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Diagnostics;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Net.Mime;
+using System.Reflection;
+using System.Threading.Tasks;
+using BookmarkSync.Core.Configuration;
+using BookmarkSync.Core.Entities;
+using BookmarkSync.Core.Interfaces;
+using BookmarkSync.Infrastructure.Services.Pinboard;
+
+namespace BookmarkSync.Infrastructure.Services;
+
+public abstract class BookmarkingService
+{
+ ///
+ /// The HttpClient object.
+ ///
+ private static readonly HttpClient Client = new();
+ protected BookmarkingService()
+ {
+ // Setup HttpClient
+ Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json));
+ Client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("mastodon-bookmark-sync",
+ FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion));
+ }
+ ///
+ /// The API auth token..
+ ///
+ protected string ApiToken { get; init; } = null!;
+ ///
+ /// The Api URL.
+ ///
+ protected string ApiUri { get; init; } = null!;
+ public static IBookmarkingService GetBookmarkingService(IConfigManager configManager)
+ {
+ return configManager.App.Bookmarking.Service switch
+ {
+ "Pinboard" => new PinboardBookmarkingService(configManager),
+ _ => throw new InvalidOperationException("Bookmark service either not provided or unknown")
+ };
+ }
+}
diff --git a/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmark.cs b/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmark.cs
new file mode 100644
index 0000000..fb10171
--- /dev/null
+++ b/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmark.cs
@@ -0,0 +1,12 @@
+namespace BookmarkSync.Infrastructure.Services.Pinboard;
+
+public class PinboardBookmark
+{
+ public string Description { get; set; }
+ public string ExtendedDescription { get; set; } // TODO: check this name
+ public bool Shared { get; set; } = false;
+ public string[]? Tags { get; set; }
+ public string Uri { get; set; }
+ public string? GetFormattedTags()
+ => Tags != null ? string.Join(" ", Tags) : null;
+}
diff --git a/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmarkingService.cs b/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmarkingService.cs
new file mode 100644
index 0000000..263a66e
--- /dev/null
+++ b/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmarkingService.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Threading.Tasks;
+using System.Web;
+using BookmarkSync.Core.Configuration;
+using BookmarkSync.Core.Entities;
+using BookmarkSync.Core.Interfaces;
+using Serilog;
+
+namespace BookmarkSync.Infrastructure.Services.Pinboard;
+
+public class PinboardBookmarkingService : BookmarkingService, IBookmarkingService
+{
+ private static readonly ILogger _logger = Log.ForContext();
+ public PinboardBookmarkingService(IConfigManager configManager)
+ {
+ ApiToken = configManager.App.Bookmarking.ApiToken ?? throw new InvalidOperationException();
+ ApiUri = "https://api.pinboard.in/v1/posts/add";
+ }
+ ///
+ public async Task Save(Bookmark bookmark)
+ {
+ var builder = new UriBuilder(ApiUri);
+ var query = HttpUtility.ParseQueryString(string.Empty);
+ query["auth_token"] = ApiToken;
+ // query["description"] = bookmark.Description;
+ query["url"] = bookmark.Uri;
+ // query["shared"] = bookmark.Shared ? "yes" : "no";
+ // query["extended"] = bookmark.ExtendedDescription;
+ // query["tags"] = bookmark.GetFormattedTags();
+ builder.Query = query.ToString();
+ var requestUri = builder.ToString();
+ _logger.Debug("Request URI: {RequestUri}", requestUri);
+
+ // var result = await Client.GetAsync(requestUri);
+ // result.EnsureSuccessStatusCode();
+ }
+}
diff --git a/BookmarkSync.Infrastructure/Services/PinboardBookmarkingService.cs b/BookmarkSync.Infrastructure/Services/PinboardBookmarkingService.cs
deleted file mode 100644
index 44894a1..0000000
--- a/BookmarkSync.Infrastructure/Services/PinboardBookmarkingService.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-using BookmarkSync.Core.Interfaces;
-
-namespace BookmarkSync.Infrastructure.Services;
-
-public class PinboardBookmarkingService : IBookmarkingService { }
diff --git a/mastodon-bookmark-sync.sln b/mastodon-bookmark-sync.sln
index 2964f73..287c739 100644
--- a/mastodon-bookmark-sync.sln
+++ b/mastodon-bookmark-sync.sln
@@ -15,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.Infrastructure
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.Core.Tests", "BookmarkSync.Core.Tests\BookmarkSync.Core.Tests.csproj", "{9B28E255-C1D4-43A6-861A-DD1752F31A0E}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.Infrastructure.Tests", "BookmarkSync.Infrastructure.Tests\BookmarkSync.Infrastructure.Tests.csproj", "{DA6C5B23-C780-479D-8D14-20307A5A91D8}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -37,5 +39,9 @@ Global
{9B28E255-C1D4-43A6-861A-DD1752F31A0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9B28E255-C1D4-43A6-861A-DD1752F31A0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B28E255-C1D4-43A6-861A-DD1752F31A0E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DA6C5B23-C780-479D-8D14-20307A5A91D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA6C5B23-C780-479D-8D14-20307A5A91D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DA6C5B23-C780-479D-8D14-20307A5A91D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DA6C5B23-C780-479D-8D14-20307A5A91D8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
From dab70108ad2de6e8039e1c346bdfa343ce1dccc6 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 01:33:31 -0500
Subject: [PATCH 11/33] Refactor Program.cs
- Implement Serilog
- Use HostedService
---
BookmarkSync.CLI/BookmarkSync.CLI.csproj | 3 ++
BookmarkSync.CLI/Program.cs | 46 ++++++++++++++---------
BookmarkSync.CLI/appsettings.Example.json | 18 +++++++++
3 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/BookmarkSync.CLI/BookmarkSync.CLI.csproj b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
index b964d88..0bd98c0 100644
--- a/BookmarkSync.CLI/BookmarkSync.CLI.csproj
+++ b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
@@ -10,6 +10,9 @@
+
+
+
diff --git a/BookmarkSync.CLI/Program.cs b/BookmarkSync.CLI/Program.cs
index 82fec66..6085c7f 100644
--- a/BookmarkSync.CLI/Program.cs
+++ b/BookmarkSync.CLI/Program.cs
@@ -1,42 +1,54 @@
using System;
-using System.Threading.Tasks;
using BookmarkSync.Core.Configuration;
-using BookmarkSync.Core.Interfaces;
using BookmarkSync.Infrastructure.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Serilog;
namespace BookmarkSync.CLI;
public class Program
{
private static IConfiguration? _configuration;
- public async static Task Main(string[] args)
+ public static int Main(string[] args)
{
_configuration = SetupConfiguration(args);
IConfigManager configManager = new ConfigManager(_configuration);
+
+ Log.Logger = new LoggerConfiguration()
+ .ReadFrom.Configuration(_configuration)
+ .Enrich.FromLogContext()
+ .CreateLogger();
- using var host = Host.CreateDefaultBuilder(args)
+ try
+ {
+ Log.Information("Starting host");
+ BuildHost(args, configManager).Run();
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ Log.Fatal(ex, "Host terminated unexpectedly");
+ return 1;
+ }
+ finally
+ {
+ // Shutdown
+ configManager.SaveToFile();
+ Log.CloseAndFlush();
+ }
+ }
+ public static IHost BuildHost(string[] args, IConfigManager configManager) =>
+ new HostBuilder()
.ConfigureServices(services =>
{
services.AddSingleton(configManager);
- services.AddTransient();
+ services.AddHostedService();
})
+ .UseSerilog()
.Build();
- await host.StartAsync();
- var lifetime = host.Services.GetRequiredService();
-
- // Do work here
- Console.WriteLine("Hello, world!");
-
- // Shutdown
- configManager.SaveToFile();
-
- lifetime.StopApplication();
- await host.WaitForShutdownAsync();
- }
private static IConfiguration SetupConfiguration(string[] args) => new ConfigurationBuilder()
.AddJsonFile("appsettings.json", false, true)
.AddEnvironmentVariables()
diff --git a/BookmarkSync.CLI/appsettings.Example.json b/BookmarkSync.CLI/appsettings.Example.json
index df410ff..8239684 100644
--- a/BookmarkSync.CLI/appsettings.Example.json
+++ b/BookmarkSync.CLI/appsettings.Example.json
@@ -11,5 +11,23 @@
"Service": "Pinboard",
"ApiToken": ""
}
+ },
+ "Serilog": {
+ "MinimumLevel": {
+ "Default": "Debug",
+ "Override": {
+ "Microsoft": "Information",
+ "System": "Error"
+ }
+ },
+ "WriteTo": [
+ {
+ "Name": "Console",
+ "Args": {
+ "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
+ "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] [{SourceContext}] [{EventId}] {Message}{NewLine}{Exception}"
+ }
+ }
+ ]
}
}
\ No newline at end of file
From 7ad6e34851f214cf4e8071daed110668711c1d00 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 01:33:46 -0500
Subject: [PATCH 12/33] Refactor ConfigManager.App
---
BookmarkSync.Core/Configuration/ConfigManager.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/BookmarkSync.Core/Configuration/ConfigManager.cs b/BookmarkSync.Core/Configuration/ConfigManager.cs
index 0bcfe34..760ef56 100644
--- a/BookmarkSync.Core/Configuration/ConfigManager.cs
+++ b/BookmarkSync.Core/Configuration/ConfigManager.cs
@@ -10,7 +10,7 @@ namespace BookmarkSync.Core.Configuration;
public interface IConfigManager
{
- App? App { get; set; }
+ App App { get; set; }
IConfiguration Configuration { get; set; }
List? Instances { get; set; }
string GetConfigValue(string key);
@@ -22,17 +22,17 @@ public ConfigManager(
IConfiguration configuration)
{
Configuration = configuration;
- App = Configuration.GetSection("App").Get();
+ App = Configuration.GetSection("App").Get() ?? throw new NullReferenceException();
Instances = Configuration.GetSection("Instances").Get>();
- if (App is not null && !App.IsValid())
+ if (!App.IsValid())
{
throw new InvalidConfigurationException();
}
}
public IConfiguration Configuration { get; set; }
public List? Instances { get; set; }
- public App? App { get; set; }
+ public App App { get; set; }
public string GetConfigValue(string key)
{
string? value = Configuration[key];
From 9970e824bdf4cfbf0e79cc50b914e41f4740b4e9 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 01:42:52 -0500
Subject: [PATCH 13/33] Add run configuration
---
.run/BookmarkSync.CLI.run.xml | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 .run/BookmarkSync.CLI.run.xml
diff --git a/.run/BookmarkSync.CLI.run.xml b/.run/BookmarkSync.CLI.run.xml
new file mode 100644
index 0000000..1e35d15
--- /dev/null
+++ b/.run/BookmarkSync.CLI.run.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From 113340a904eed44fe8666b18e7f18c5e4f61edd0 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 02:33:41 -0500
Subject: [PATCH 14/33] Update PinboardBookmarkingService
---
.../Interfaces/IBookmarkingService.cs | 3 ++-
.../Services/BookmarkSyncService.cs | 2 +-
.../Services/BookmarkingService.cs | 4 +--
.../Pinboard/PinboardBookmarkingService.cs | 27 ++++++++++++++-----
4 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/BookmarkSync.Core/Interfaces/IBookmarkingService.cs b/BookmarkSync.Core/Interfaces/IBookmarkingService.cs
index 7ed1459..94a8bf6 100644
--- a/BookmarkSync.Core/Interfaces/IBookmarkingService.cs
+++ b/BookmarkSync.Core/Interfaces/IBookmarkingService.cs
@@ -1,3 +1,4 @@
+using System.Net.Http;
using System.Threading.Tasks;
using BookmarkSync.Core.Entities;
@@ -9,5 +10,5 @@ public interface IBookmarkingService
/// Saves a bookmark to the bookmarking service.
///
/// A service's bookmark implementation.
- public Task Save(Bookmark bookmark);
+ public Task Save(Bookmark bookmark);
}
diff --git a/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs b/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
index 96414dc..67db13e 100644
--- a/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
+++ b/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
@@ -2,7 +2,7 @@
using System.Threading;
using System.Threading.Tasks;
using BookmarkSync.Core.Configuration;
-using BookmarkSync.Core.Entities;
+using BookmarkSync.Core.Entities.Config;
using BookmarkSync.Core.Interfaces;
using Microsoft.Extensions.Hosting;
using Serilog;
diff --git a/BookmarkSync.Infrastructure/Services/BookmarkingService.cs b/BookmarkSync.Infrastructure/Services/BookmarkingService.cs
index 7d6b231..f6788ae 100644
--- a/BookmarkSync.Infrastructure/Services/BookmarkingService.cs
+++ b/BookmarkSync.Infrastructure/Services/BookmarkingService.cs
@@ -4,9 +4,7 @@
using System.Net.Http.Headers;
using System.Net.Mime;
using System.Reflection;
-using System.Threading.Tasks;
using BookmarkSync.Core.Configuration;
-using BookmarkSync.Core.Entities;
using BookmarkSync.Core.Interfaces;
using BookmarkSync.Infrastructure.Services.Pinboard;
@@ -17,7 +15,7 @@ public abstract class BookmarkingService
///
/// The HttpClient object.
///
- private static readonly HttpClient Client = new();
+ protected static readonly HttpClient Client = new();
protected BookmarkingService()
{
// Setup HttpClient
diff --git a/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmarkingService.cs b/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmarkingService.cs
index 263a66e..10092cb 100644
--- a/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmarkingService.cs
+++ b/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmarkingService.cs
@@ -1,4 +1,5 @@
using System;
+using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using BookmarkSync.Core.Configuration;
@@ -10,6 +11,7 @@ namespace BookmarkSync.Infrastructure.Services.Pinboard;
public class PinboardBookmarkingService : BookmarkingService, IBookmarkingService
{
+ private const int PinboardDescriptionMaxLength = 255;
private static readonly ILogger _logger = Log.ForContext();
public PinboardBookmarkingService(IConfigManager configManager)
{
@@ -17,21 +19,32 @@ public PinboardBookmarkingService(IConfigManager configManager)
ApiUri = "https://api.pinboard.in/v1/posts/add";
}
///
- public async Task Save(Bookmark bookmark)
+ public async Task Save(Bookmark bookmark)
{
+ // Prep bookmark
+ string? extended = null;
+ if (bookmark.Content!.Length >= PinboardDescriptionMaxLength)
+ {
+ string? trimmedDescription = bookmark.Content[..PinboardDescriptionMaxLength];
+ extended = bookmark.Content;
+ bookmark.Content = trimmedDescription;
+ }
+
var builder = new UriBuilder(ApiUri);
var query = HttpUtility.ParseQueryString(string.Empty);
query["auth_token"] = ApiToken;
- // query["description"] = bookmark.Description;
+ query["description"] = bookmark.Content;
query["url"] = bookmark.Uri;
- // query["shared"] = bookmark.Shared ? "yes" : "no";
- // query["extended"] = bookmark.ExtendedDescription;
- // query["tags"] = bookmark.GetFormattedTags();
+ query["shared"] = "no";
+ if (!string.IsNullOrEmpty(extended))
+ {
+ query["extended"] = extended;
+ }
+ query["tags"] = string.Join(" ", $"via:@{bookmark.Account}", "via:mastodon-bookmark-sync");
builder.Query = query.ToString();
var requestUri = builder.ToString();
_logger.Debug("Request URI: {RequestUri}", requestUri);
- // var result = await Client.GetAsync(requestUri);
- // result.EnsureSuccessStatusCode();
+ return await Client.GetAsync(requestUri);
}
}
From bd7299eedd26f9d9b1d9de5f7cbba1f1538648bf Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 02:33:54 -0500
Subject: [PATCH 15/33] Update Account, add constructor
---
BookmarkSync.Core/Entities/Account.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/BookmarkSync.Core/Entities/Account.cs b/BookmarkSync.Core/Entities/Account.cs
index 452ba8e..b45db1c 100644
--- a/BookmarkSync.Core/Entities/Account.cs
+++ b/BookmarkSync.Core/Entities/Account.cs
@@ -3,6 +3,11 @@ namespace BookmarkSync.Core.Entities;
public class Account
{
public string? Name { get; set; }
+ public Account(string name)
+ {
+ Name = name;
+ }
+ public Account() { }
///
public override string ToString() => Name ?? GetType().Name;
}
From 67157f167093ef89d3e2f2a269c7fc78a247f2b9 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 02:39:21 -0500
Subject: [PATCH 16/33] Stub out required Mastodon API methods
---
.../Services/BookmarkSyncService.cs | 40 +++++++++++++++----
.../Services/Mastodon/ApiClient.cs | 38 ++++++++++++++++++
2 files changed, 71 insertions(+), 7 deletions(-)
create mode 100644 BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs
diff --git a/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs b/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
index 67db13e..19904fd 100644
--- a/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
+++ b/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using BookmarkSync.Core.Configuration;
@@ -12,27 +13,52 @@ namespace BookmarkSync.Infrastructure.Services;
public class BookmarkSyncService : IHostedService
{
private readonly IHostApplicationLifetime _host;
+ private readonly List? _instances;
private readonly IBookmarkingService _bookmarkingService;
private static readonly ILogger _logger = Log.ForContext();
public BookmarkSyncService(IHostApplicationLifetime host, IConfigManager configManager)
{
_bookmarkingService = BookmarkingService.GetBookmarkingService(configManager);
_host = host;
+ _instances = configManager.Instances;
}
///
- public Task StartAsync(CancellationToken stoppingToken)
+ public async Task StartAsync(CancellationToken stoppingToken)
{
_logger.Information("The current time is: {CurrentTime}", DateTimeOffset.UtcNow);
- // Get bookmarks from mastodon account
- // TODO
-
- // Save bookmarks to bookmarking service
- _bookmarkingService.Save(new Bookmark());
+ if (_instances == null || _instances.Count == 0)
+ {
+ _logger.Information("No instances configured");
+ return;
+ }
+ foreach (var instance in _instances)
+ {
+ _logger.Information("Processing {Instance}", instance);
+ _logger.Debug("Setting up Mastodon API client");
+ var client = new Mastodon.ApiClient(instance);
+ // Get bookmarks from mastodon account
+ var bookmarks = await client.GetBookmarks();
+
+ if (bookmarks == null || bookmarks.Count == 0)
+ {
+ _logger.Information("No bookmarks received");
+ return;
+ }
+ foreach (var bookmark in bookmarks)
+ {
+ // Save bookmarks to bookmarking service
+ var result = await _bookmarkingService.Save(bookmark);
+
+ if (instance.DeleteBookmarks && result.IsSuccessStatusCode)
+ {
+ await client.DeleteBookmark(bookmark);
+ }
+ }
+ }
// Finish task
_host.StopApplication();
- return Task.CompletedTask;
}
///
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
diff --git a/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs b/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs
new file mode 100644
index 0000000..c6a6ee7
--- /dev/null
+++ b/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Net.Mime;
+using System.Reflection;
+using System.Threading.Tasks;
+using BookmarkSync.Core.Entities;
+using BookmarkSync.Core.Entities.Config;
+using Serilog;
+
+namespace BookmarkSync.Infrastructure.Services.Mastodon;
+
+public class ApiClient
+{
+ private readonly HttpClient _client = new();
+ private readonly Instance _instance;
+ private static readonly ILogger _logger = Log.ForContext();
+ public ApiClient(Instance instance)
+ {
+ _instance = instance;
+ _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json));
+ _client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("mastodon-bookmark-sync",
+ FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion));
+ _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _instance.AccessToken);
+ }
+ public async Task?> GetBookmarks()
+ {
+ _logger.Debug("Running {Method}", "GetBookmarks");
+ return null;
+ }
+ public async Task DeleteBookmark(Bookmark bookmark)
+ {
+ _logger.Debug("Running {Method}", "DeleteBookmark");
+ throw new NotImplementedException();
+ }
+}
From 6908fd22024a235e665000e298b655dd6a8381c7 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 02:44:42 -0500
Subject: [PATCH 17/33] Remove PinboardBookmark and related tests
---
.../Pinboard/PinboardBookmarkTests.cs | 50 -------------------
.../Services/Pinboard/PinboardBookmark.cs | 12 -----
2 files changed, 62 deletions(-)
delete mode 100644 BookmarkSync.Infrastructure.Tests/Services/Pinboard/PinboardBookmarkTests.cs
delete mode 100644 BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmark.cs
diff --git a/BookmarkSync.Infrastructure.Tests/Services/Pinboard/PinboardBookmarkTests.cs b/BookmarkSync.Infrastructure.Tests/Services/Pinboard/PinboardBookmarkTests.cs
deleted file mode 100644
index d41ba90..0000000
--- a/BookmarkSync.Infrastructure.Tests/Services/Pinboard/PinboardBookmarkTests.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using BookmarkSync.Infrastructure.Services.Pinboard;
-
-namespace BookmarkSync.Infrastructure.Tests.Services.Pinboard;
-
-[TestClass]
-public class PinboardBookmarkTests
-{
- [TestMethod]
- public void PinboardBookmark_HasProperties()
- {
- // Arrange
- PinboardBookmark obj = new();
-
- // Assert
- Assert.AreEqual(5, obj.PropertyCount());
- Assert.IsTrue(obj.HasProperty("Description"));
- Assert.IsTrue(obj.HasProperty("ExtendedDescription"));
- Assert.IsTrue(obj.HasProperty("Shared"));
- Assert.IsTrue(obj.HasProperty("Tags"));
- Assert.IsTrue(obj.HasProperty("Uri"));
-
- Assert.IsTrue(obj.HasMethod("GetFormattedTags"));
- }
-
- [TestMethod]
- public void GetFormattedTags_NullTags()
- {
- // Arrange
- PinboardBookmark obj = new();
-
- // Assert
- Assert.IsNull(obj.GetFormattedTags());
- }
- [TestMethod]
- public void GetFormattedTags_WithTags()
- {
- // Arrange
- PinboardBookmark obj = new()
- {
- Tags = new[]
- {
- "first-tag", "second-tag"
- }
- };
- const string expected = "first-tag second-tag";
-
- // Assert
- Assert.AreEqual(expected, obj.GetFormattedTags());
- }
-}
diff --git a/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmark.cs b/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmark.cs
deleted file mode 100644
index fb10171..0000000
--- a/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmark.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace BookmarkSync.Infrastructure.Services.Pinboard;
-
-public class PinboardBookmark
-{
- public string Description { get; set; }
- public string ExtendedDescription { get; set; } // TODO: check this name
- public bool Shared { get; set; } = false;
- public string[]? Tags { get; set; }
- public string Uri { get; set; }
- public string? GetFormattedTags()
- => Tags != null ? string.Join(" ", Tags) : null;
-}
From acbb73cbab89ac5f5d96a1a030c24c109e6d723e Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 04:05:45 -0500
Subject: [PATCH 18/33] Add HtmlUtilities to sanitize HTML
---
BookmarkSync.Core/BookmarkSync.Core.csproj | 1 +
BookmarkSync.Core/Entities/Bookmark.cs | 9 ++-
BookmarkSync.Core/Utilities/HtmlUtilities.cs | 80 ++++++++++++++++++++
3 files changed, 89 insertions(+), 1 deletion(-)
create mode 100644 BookmarkSync.Core/Utilities/HtmlUtilities.cs
diff --git a/BookmarkSync.Core/BookmarkSync.Core.csproj b/BookmarkSync.Core/BookmarkSync.Core.csproj
index e47591a..626afc7 100644
--- a/BookmarkSync.Core/BookmarkSync.Core.csproj
+++ b/BookmarkSync.Core/BookmarkSync.Core.csproj
@@ -8,6 +8,7 @@
+
diff --git a/BookmarkSync.Core/Entities/Bookmark.cs b/BookmarkSync.Core/Entities/Bookmark.cs
index 8a444d9..65dc4e6 100644
--- a/BookmarkSync.Core/Entities/Bookmark.cs
+++ b/BookmarkSync.Core/Entities/Bookmark.cs
@@ -1,9 +1,16 @@
+using BookmarkSync.Core.Utilities;
+
namespace BookmarkSync.Core.Entities;
public class Bookmark
{
public Account? Account { get; set; }
- public string? Content { get; set; }
+ private string? _content;
+ public string? Content
+ {
+ get => _content != null ? HtmlUtilities.ConvertToPlainText(_content) : "";
+ set => _content = value;
+ }
public string? Id { get; set; }
public string? Uri { get; set; }
public string? Visibility { get; set; }
diff --git a/BookmarkSync.Core/Utilities/HtmlUtilities.cs b/BookmarkSync.Core/Utilities/HtmlUtilities.cs
new file mode 100644
index 0000000..d931f47
--- /dev/null
+++ b/BookmarkSync.Core/Utilities/HtmlUtilities.cs
@@ -0,0 +1,80 @@
+using System;
+using System.IO;
+using HtmlAgilityPack;
+
+namespace BookmarkSync.Core.Utilities;
+
+public static class HtmlUtilities
+{
+ public static string ConvertToPlainText(string html)
+ {
+ var doc = new HtmlDocument();
+ doc.LoadHtml(html);
+
+ var sw = new StringWriter();
+ ConvertTo(doc.DocumentNode, sw);
+
+ sw.Flush();
+ return sw.ToString();
+ }
+ private static void ConvertTo(HtmlNode node, TextWriter outText)
+ {
+ string html;
+ switch (node.NodeType)
+ {
+ case HtmlNodeType.Comment:
+ // don't output comments
+ break;
+ case HtmlNodeType.Document:
+ ConvertContentTo(node, outText);
+ break;
+
+ case HtmlNodeType.Text:
+ // script and style must not be output
+ string parentName = node.ParentNode.Name;
+ if (parentName is "script" or "style")
+ break;
+
+ // get text
+ html = ((HtmlTextNode)node).Text;
+
+ // is it a special closing node output as text?
+ if (HtmlNode.IsOverlappedClosingElement(html))
+ break;
+
+ // check the text is meaningful and not a bunch of whitespace
+ if (html.Trim().Length > 0)
+ {
+ outText.Write(HtmlEntity.DeEntitize(html));
+ }
+ break;
+
+ case HtmlNodeType.Element:
+ switch (node.Name)
+ {
+ case "p":
+ // treat paragraphs as crlf
+ outText.Write("\r\n");
+ break;
+ case "br":
+ outText.Write("\r\n");
+ break;
+ }
+
+ if (node.HasChildNodes)
+ {
+ ConvertContentTo(node, outText);
+ }
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+ private static void ConvertContentTo(HtmlNode node, TextWriter outText)
+ {
+ foreach (var subnode in node.ChildNodes)
+ {
+ ConvertTo(subnode, outText);
+ }
+ }
+}
From 1feda2f1eef756c4bdb3de322bb2dba39ab49430 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 04:11:55 -0500
Subject: [PATCH 19/33] Finish up PinboardBookmarkingService,
Mastodon.ApiClient, and BookmarkSyncService
---
BookmarkSync.Core/BookmarkSync.Core.csproj | 1 +
BookmarkSync.Core/Entities/Account.cs | 4 ++-
.../BookmarkSync.Infrastructure.csproj | 1 +
.../Services/BookmarkSyncService.cs | 25 ++++++++++++++++---
.../Services/Mastodon/ApiClient.cs | 15 ++++++++---
.../Pinboard/PinboardBookmarkingService.cs | 5 +++-
6 files changed, 43 insertions(+), 8 deletions(-)
diff --git a/BookmarkSync.Core/BookmarkSync.Core.csproj b/BookmarkSync.Core/BookmarkSync.Core.csproj
index 626afc7..c9220eb 100644
--- a/BookmarkSync.Core/BookmarkSync.Core.csproj
+++ b/BookmarkSync.Core/BookmarkSync.Core.csproj
@@ -11,6 +11,7 @@
+
diff --git a/BookmarkSync.Core/Entities/Account.cs b/BookmarkSync.Core/Entities/Account.cs
index b45db1c..2aee3dc 100644
--- a/BookmarkSync.Core/Entities/Account.cs
+++ b/BookmarkSync.Core/Entities/Account.cs
@@ -1,8 +1,10 @@
+using Newtonsoft.Json;
+
namespace BookmarkSync.Core.Entities;
public class Account
{
- public string? Name { get; set; }
+ [JsonProperty("acct")] public string? Name { get; set; }
public Account(string name)
{
Name = name;
diff --git a/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj b/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj
index ca178e5..ddbb223 100644
--- a/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj
+++ b/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj
@@ -9,6 +9,7 @@
+
diff --git a/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs b/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
index 19904fd..5e63bd1 100644
--- a/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
+++ b/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
+using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using BookmarkSync.Core.Configuration;
+using BookmarkSync.Core.Entities;
using BookmarkSync.Core.Entities.Config;
using BookmarkSync.Core.Interfaces;
using Microsoft.Extensions.Hosting;
@@ -38,17 +40,34 @@ public async Task StartAsync(CancellationToken stoppingToken)
_logger.Debug("Setting up Mastodon API client");
var client = new Mastodon.ApiClient(instance);
// Get bookmarks from mastodon account
- var bookmarks = await client.GetBookmarks();
+ List? bookmarks = null;
+ try
+ {
+ bookmarks = await client.GetBookmarks();
+ }
+ catch (HttpRequestException ex)
+ {
+ _logger.Error(ex, "Failed to retrieve bookmarks from {Instance}", instance);
+ }
if (bookmarks == null || bookmarks.Count == 0)
{
_logger.Information("No bookmarks received");
- return;
+ continue;
}
foreach (var bookmark in bookmarks)
{
// Save bookmarks to bookmarking service
- var result = await _bookmarkingService.Save(bookmark);
+ HttpResponseMessage result;
+ try
+ {
+ result = await _bookmarkingService.Save(bookmark);
+ }
+ catch (Exception ex)
+ {
+ _logger.Error(ex, "Failed to save bookmark");
+ continue;
+ }
if (instance.DeleteBookmarks && result.IsSuccessStatusCode)
{
diff --git a/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs b/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs
index c6a6ee7..750458d 100644
--- a/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs
+++ b/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
@@ -8,6 +7,7 @@
using System.Threading.Tasks;
using BookmarkSync.Core.Entities;
using BookmarkSync.Core.Entities.Config;
+using Newtonsoft.Json;
using Serilog;
namespace BookmarkSync.Infrastructure.Services.Mastodon;
@@ -28,11 +28,20 @@ public ApiClient(Instance instance)
public async Task?> GetBookmarks()
{
_logger.Debug("Running {Method}", "GetBookmarks");
- return null;
+ var requestUri = $"{_instance.Uri}/api/v1/bookmarks";
+ var response = await _client.GetAsync(requestUri);
+ response.EnsureSuccessStatusCode();
+ string responseContent = await response.Content.ReadAsStringAsync();
+ var obj = JsonConvert.DeserializeObject>(responseContent);
+
+ return obj;
}
public async Task DeleteBookmark(Bookmark bookmark)
{
_logger.Debug("Running {Method}", "DeleteBookmark");
- throw new NotImplementedException();
+ var requestUri = $"{_instance.Uri}/api/v1/statuses/{bookmark.Id}/unbookmark";
+ var response = await _client.PostAsync(requestUri, null);
+ response.EnsureSuccessStatusCode();
+ _logger.Information("Bookmark {BookmarkId} deleted successfully", bookmark.Id);
}
}
diff --git a/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmarkingService.cs b/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmarkingService.cs
index 10092cb..d2df84d 100644
--- a/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmarkingService.cs
+++ b/BookmarkSync.Infrastructure/Services/Pinboard/PinboardBookmarkingService.cs
@@ -45,6 +45,9 @@ public async Task Save(Bookmark bookmark)
var requestUri = builder.ToString();
_logger.Debug("Request URI: {RequestUri}", requestUri);
- return await Client.GetAsync(requestUri);
+ var response = await Client.GetAsync(requestUri);
+ response.EnsureSuccessStatusCode();
+ _logger.Debug("Response status: {StatusCode}", response.StatusCode);
+ return response;
}
}
From 1c7e5ba78ac133597a98e2f2b9531719f4ccc869 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 04:20:31 -0500
Subject: [PATCH 20/33] Ignore private or direct messages
---
BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs b/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
index 5e63bd1..ca1c3fe 100644
--- a/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
+++ b/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
@@ -43,7 +44,9 @@ public async Task StartAsync(CancellationToken stoppingToken)
List? bookmarks = null;
try
{
- bookmarks = await client.GetBookmarks();
+ bookmarks = (await client.GetBookmarks())
+ .Where(b => b.Visibility is not ("private" or "direct"))
+ .ToList();
}
catch (HttpRequestException ex)
{
From 6ccb2c652a33b55003dba902eabfe0faa0f990d3 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 05:05:47 -0500
Subject: [PATCH 21/33] Change executable name
---
.run/BookmarkSync.CLI.run.xml | 2 +-
BookmarkSync.CLI/BookmarkSync.CLI.csproj | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/.run/BookmarkSync.CLI.run.xml b/.run/BookmarkSync.CLI.run.xml
index 1e35d15..c88836a 100644
--- a/.run/BookmarkSync.CLI.run.xml
+++ b/.run/BookmarkSync.CLI.run.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/BookmarkSync.CLI/BookmarkSync.CLI.csproj b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
index 0bd98c0..49d4e8f 100644
--- a/BookmarkSync.CLI/BookmarkSync.CLI.csproj
+++ b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
@@ -5,6 +5,8 @@
net7.0
disable
enable
+ mastodon-bookmark-sync
+
From 14872644ab2ee0196ce4bb8b85d932181601ca48 Mon Sep 17 00:00:00 2001
From: prplecake
Date: Mon, 27 Mar 2023 09:39:09 -0500
Subject: [PATCH 22/33] Fix project file
---
BookmarkSync.CLI/BookmarkSync.CLI.csproj | 1 -
1 file changed, 1 deletion(-)
diff --git a/BookmarkSync.CLI/BookmarkSync.CLI.csproj b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
index 49d4e8f..5f81d01 100644
--- a/BookmarkSync.CLI/BookmarkSync.CLI.csproj
+++ b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
@@ -7,7 +7,6 @@
enable
mastodon-bookmark-sync
-
From 3003d60b964e13e61b50ea5a6a69290a1bfc58bb Mon Sep 17 00:00:00 2001
From: prplecake
Date: Mon, 27 Mar 2023 09:58:30 -0500
Subject: [PATCH 23/33] Reflection doesn't work with single-file executables
---
BookmarkSync.Core/Meta.cs | 12 ++++++++++++
.../Services/BookmarkingService.cs | 4 ++--
.../Services/Mastodon/ApiClient.cs | 4 ++--
3 files changed, 16 insertions(+), 4 deletions(-)
create mode 100644 BookmarkSync.Core/Meta.cs
diff --git a/BookmarkSync.Core/Meta.cs b/BookmarkSync.Core/Meta.cs
new file mode 100644
index 0000000..39a1103
--- /dev/null
+++ b/BookmarkSync.Core/Meta.cs
@@ -0,0 +1,12 @@
+using System.Diagnostics;
+using System.Net.Http.Headers;
+using System.Reflection;
+
+namespace BookmarkSync.Core;
+
+public class Meta
+{
+ public const string Name = "mastodon-bookmark-sync";
+ public const string Version = "2.0";
+ public static readonly ProductInfoHeaderValue UserAgent = new(Name, Version);
+}
diff --git a/BookmarkSync.Infrastructure/Services/BookmarkingService.cs b/BookmarkSync.Infrastructure/Services/BookmarkingService.cs
index f6788ae..f7de8ca 100644
--- a/BookmarkSync.Infrastructure/Services/BookmarkingService.cs
+++ b/BookmarkSync.Infrastructure/Services/BookmarkingService.cs
@@ -4,6 +4,7 @@
using System.Net.Http.Headers;
using System.Net.Mime;
using System.Reflection;
+using BookmarkSync.Core;
using BookmarkSync.Core.Configuration;
using BookmarkSync.Core.Interfaces;
using BookmarkSync.Infrastructure.Services.Pinboard;
@@ -20,8 +21,7 @@ protected BookmarkingService()
{
// Setup HttpClient
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json));
- Client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("mastodon-bookmark-sync",
- FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion));
+ Client.DefaultRequestHeaders.UserAgent.Add(Meta.UserAgent);
}
///
/// The API auth token..
diff --git a/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs b/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs
index 750458d..3f37bb9 100644
--- a/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs
+++ b/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs
@@ -5,6 +5,7 @@
using System.Net.Mime;
using System.Reflection;
using System.Threading.Tasks;
+using BookmarkSync.Core;
using BookmarkSync.Core.Entities;
using BookmarkSync.Core.Entities.Config;
using Newtonsoft.Json;
@@ -21,8 +22,7 @@ public ApiClient(Instance instance)
{
_instance = instance;
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json));
- _client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("mastodon-bookmark-sync",
- FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion));
+ _client.DefaultRequestHeaders.UserAgent.Add(Meta.UserAgent);
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _instance.AccessToken);
}
public async Task?> GetBookmarks()
From 028d9c718f596ab0a21ac43af66b1b70fb86cd34 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Mon, 27 Mar 2023 10:01:56 -0500
Subject: [PATCH 24/33] Fix logging to console in single file executable
---
BookmarkSync.CLI/appsettings.Example.json | 3 +++
1 file changed, 3 insertions(+)
diff --git a/BookmarkSync.CLI/appsettings.Example.json b/BookmarkSync.CLI/appsettings.Example.json
index 8239684..50778a5 100644
--- a/BookmarkSync.CLI/appsettings.Example.json
+++ b/BookmarkSync.CLI/appsettings.Example.json
@@ -13,6 +13,9 @@
}
},
"Serilog": {
+ "Using": [
+ "Serilog.Sinks.Console"
+ ],
"MinimumLevel": {
"Default": "Debug",
"Override": {
From c6a793373a78764fc1281bac68090bdd4c9e3f24 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Tue, 28 Mar 2023 19:55:58 -0500
Subject: [PATCH 25/33] Reorganize solution
---
mastodon-bookmark-sync.sln | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/mastodon-bookmark-sync.sln b/mastodon-bookmark-sync.sln
index 287c739..a07a4f8 100644
--- a/mastodon-bookmark-sync.sln
+++ b/mastodon-bookmark-sync.sln
@@ -17,6 +17,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.Core.Tests", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.Infrastructure.Tests", "BookmarkSync.Infrastructure.Tests\BookmarkSync.Infrastructure.Tests.csproj", "{DA6C5B23-C780-479D-8D14-20307A5A91D8}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{5EDB0DD2-A23F-410E-9355-B1521E273FF3}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{737ABEA3-2510-4E53-9B5A-A258BE2AF721}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -44,4 +48,11 @@ Global
{DA6C5B23-C780-479D-8D14-20307A5A91D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DA6C5B23-C780-479D-8D14-20307A5A91D8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {9B28E255-C1D4-43A6-861A-DD1752F31A0E} = {737ABEA3-2510-4E53-9B5A-A258BE2AF721}
+ {DA6C5B23-C780-479D-8D14-20307A5A91D8} = {737ABEA3-2510-4E53-9B5A-A258BE2AF721}
+ {696935C2-0383-4409-A2B4-B80A8C905DD2} = {5EDB0DD2-A23F-410E-9355-B1521E273FF3}
+ {0391DE45-C449-4AEF-93A6-808261868807} = {5EDB0DD2-A23F-410E-9355-B1521E273FF3}
+ {D11BD068-7AD0-4C9D-85A0-BD04A67AA7FC} = {5EDB0DD2-A23F-410E-9355-B1521E273FF3}
+ EndGlobalSection
EndGlobal
From 0355d2fd5e5e5f52c4d4d89583b12daa6838656f Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Tue, 28 Mar 2023 19:56:05 -0500
Subject: [PATCH 26/33] Log when stopping host
---
BookmarkSync.CLI/Program.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/BookmarkSync.CLI/Program.cs b/BookmarkSync.CLI/Program.cs
index 6085c7f..3159415 100644
--- a/BookmarkSync.CLI/Program.cs
+++ b/BookmarkSync.CLI/Program.cs
@@ -34,7 +34,7 @@ public static int Main(string[] args)
}
finally
{
- // Shutdown
+ Log.Information("Stopping host");
configManager.SaveToFile();
Log.CloseAndFlush();
}
From 986ea11b111632cc1ed570a0b5730656679b49b6 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Tue, 28 Mar 2023 21:07:33 -0500
Subject: [PATCH 27/33] Resolve ReSharper warnings
---
.../.idea/riderPublish.xml | 10 ++++++++++
BookmarkSync.CLI/Program.cs | 6 +++---
.../Entities/Config/PinboardTests.cs | 19 -------------------
.../Configuration/ConfigManager.cs | 5 ++---
BookmarkSync.Core/Entities/Config/Instance.cs | 2 +-
BookmarkSync.Core/Entities/Config/Pinboard.cs | 3 ---
BookmarkSync.Core/Meta.cs | 9 ++++-----
BookmarkSync.Core/Utilities/HtmlUtilities.cs | 7 +++----
.../Services/BookmarkSyncService.cs | 2 +-
.../Services/BookmarkingService.cs | 2 --
.../Services/Mastodon/ApiClient.cs | 2 --
mastodon-bookmark-sync.sln.DotSettings | 3 ++-
12 files changed, 26 insertions(+), 44 deletions(-)
create mode 100644 .idea/.idea.mastodon-bookmark-sync/.idea/riderPublish.xml
delete mode 100644 BookmarkSync.Core.Tests/Entities/Config/PinboardTests.cs
delete mode 100644 BookmarkSync.Core/Entities/Config/Pinboard.cs
diff --git a/.idea/.idea.mastodon-bookmark-sync/.idea/riderPublish.xml b/.idea/.idea.mastodon-bookmark-sync/.idea/riderPublish.xml
new file mode 100644
index 0000000..d3a6de1
--- /dev/null
+++ b/.idea/.idea.mastodon-bookmark-sync/.idea/riderPublish.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BookmarkSync.CLI/Program.cs b/BookmarkSync.CLI/Program.cs
index 3159415..b0b6b0b 100644
--- a/BookmarkSync.CLI/Program.cs
+++ b/BookmarkSync.CLI/Program.cs
@@ -8,7 +8,7 @@
namespace BookmarkSync.CLI;
-public class Program
+public static class Program
{
private static IConfiguration? _configuration;
public static int Main(string[] args)
@@ -24,7 +24,7 @@ public static int Main(string[] args)
try
{
Log.Information("Starting host");
- BuildHost(args, configManager).Run();
+ BuildHost(configManager).Run();
return 0;
}
catch (Exception ex)
@@ -39,7 +39,7 @@ public static int Main(string[] args)
Log.CloseAndFlush();
}
}
- public static IHost BuildHost(string[] args, IConfigManager configManager) =>
+ private static IHost BuildHost(IConfigManager configManager) =>
new HostBuilder()
.ConfigureServices(services =>
{
diff --git a/BookmarkSync.Core.Tests/Entities/Config/PinboardTests.cs b/BookmarkSync.Core.Tests/Entities/Config/PinboardTests.cs
deleted file mode 100644
index 725d663..0000000
--- a/BookmarkSync.Core.Tests/Entities/Config/PinboardTests.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using BookmarkSync.Core.Entities.Config;
-
-namespace BookmarkSync.Core.Tests.Entities.Config;
-
-[TestClass]
-public class PinboardTests
-{
- [TestMethod]
- public void Pinboard_HasProperties()
- {
- // Arrange
- Pinboard obj = new();
-
- // Assert
- Assert.AreEqual(0, obj.PropertyCount());
-
- Assert.IsTrue(obj.HasMethod("IsValid"));
- }
-}
diff --git a/BookmarkSync.Core/Configuration/ConfigManager.cs b/BookmarkSync.Core/Configuration/ConfigManager.cs
index 760ef56..6831a13 100644
--- a/BookmarkSync.Core/Configuration/ConfigManager.cs
+++ b/BookmarkSync.Core/Configuration/ConfigManager.cs
@@ -10,9 +10,8 @@ namespace BookmarkSync.Core.Configuration;
public interface IConfigManager
{
- App App { get; set; }
- IConfiguration Configuration { get; set; }
- List? Instances { get; set; }
+ App App { get; }
+ List? Instances { get; }
string GetConfigValue(string key);
void SaveToFile();
}
diff --git a/BookmarkSync.Core/Entities/Config/Instance.cs b/BookmarkSync.Core/Entities/Config/Instance.cs
index 9e339d2..865d32a 100644
--- a/BookmarkSync.Core/Entities/Config/Instance.cs
+++ b/BookmarkSync.Core/Entities/Config/Instance.cs
@@ -4,7 +4,7 @@ public class Instance : ConfigurationBase
{
public string? AccessToken { get; set; }
public bool DeleteBookmarks { get; set; }
- public string? Uri { get; set; }
+ public string? Uri { get; init; }
///
public override string ToString() => Uri ?? GetType().Name;
}
diff --git a/BookmarkSync.Core/Entities/Config/Pinboard.cs b/BookmarkSync.Core/Entities/Config/Pinboard.cs
deleted file mode 100644
index e15f31c..0000000
--- a/BookmarkSync.Core/Entities/Config/Pinboard.cs
+++ /dev/null
@@ -1,3 +0,0 @@
-namespace BookmarkSync.Core.Entities.Config;
-
-public class Pinboard : ConfigurationBase { }
diff --git a/BookmarkSync.Core/Meta.cs b/BookmarkSync.Core/Meta.cs
index 39a1103..93bcbb6 100644
--- a/BookmarkSync.Core/Meta.cs
+++ b/BookmarkSync.Core/Meta.cs
@@ -1,12 +1,11 @@
-using System.Diagnostics;
using System.Net.Http.Headers;
-using System.Reflection;
namespace BookmarkSync.Core;
-public class Meta
+public static class Meta
{
- public const string Name = "mastodon-bookmark-sync";
- public const string Version = "2.0";
+ public const string
+ Name = "mastodon-bookmark-sync",
+ Version = "2.0";
public static readonly ProductInfoHeaderValue UserAgent = new(Name, Version);
}
diff --git a/BookmarkSync.Core/Utilities/HtmlUtilities.cs b/BookmarkSync.Core/Utilities/HtmlUtilities.cs
index d931f47..8810e12 100644
--- a/BookmarkSync.Core/Utilities/HtmlUtilities.cs
+++ b/BookmarkSync.Core/Utilities/HtmlUtilities.cs
@@ -19,7 +19,6 @@ public static string ConvertToPlainText(string html)
}
private static void ConvertTo(HtmlNode node, TextWriter outText)
{
- string html;
switch (node.NodeType)
{
case HtmlNodeType.Comment:
@@ -36,7 +35,7 @@ private static void ConvertTo(HtmlNode node, TextWriter outText)
break;
// get text
- html = ((HtmlTextNode)node).Text;
+ string html = ((HtmlTextNode)node).Text;
// is it a special closing node output as text?
if (HtmlNode.IsOverlappedClosingElement(html))
@@ -72,9 +71,9 @@ private static void ConvertTo(HtmlNode node, TextWriter outText)
}
private static void ConvertContentTo(HtmlNode node, TextWriter outText)
{
- foreach (var subnode in node.ChildNodes)
+ foreach (var subNode in node.ChildNodes)
{
- ConvertTo(subnode, outText);
+ ConvertTo(subNode, outText);
}
}
}
diff --git a/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs b/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
index ca1c3fe..dba5f04 100644
--- a/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
+++ b/BookmarkSync.Infrastructure/Services/BookmarkSyncService.cs
@@ -44,7 +44,7 @@ public async Task StartAsync(CancellationToken stoppingToken)
List? bookmarks = null;
try
{
- bookmarks = (await client.GetBookmarks())
+ bookmarks = (await client.GetBookmarks())?
.Where(b => b.Visibility is not ("private" or "direct"))
.ToList();
}
diff --git a/BookmarkSync.Infrastructure/Services/BookmarkingService.cs b/BookmarkSync.Infrastructure/Services/BookmarkingService.cs
index f7de8ca..310a24b 100644
--- a/BookmarkSync.Infrastructure/Services/BookmarkingService.cs
+++ b/BookmarkSync.Infrastructure/Services/BookmarkingService.cs
@@ -1,9 +1,7 @@
using System;
-using System.Diagnostics;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Mime;
-using System.Reflection;
using BookmarkSync.Core;
using BookmarkSync.Core.Configuration;
using BookmarkSync.Core.Interfaces;
diff --git a/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs b/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs
index 3f37bb9..3cdc260 100644
--- a/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs
+++ b/BookmarkSync.Infrastructure/Services/Mastodon/ApiClient.cs
@@ -1,9 +1,7 @@
using System.Collections.Generic;
-using System.Diagnostics;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Mime;
-using System.Reflection;
using System.Threading.Tasks;
using BookmarkSync.Core;
using BookmarkSync.Core.Entities;
diff --git a/mastodon-bookmark-sync.sln.DotSettings b/mastodon-bookmark-sync.sln.DotSettings
index 7f259e9..caab376 100644
--- a/mastodon-bookmark-sync.sln.DotSettings
+++ b/mastodon-bookmark-sync.sln.DotSettings
@@ -1,2 +1,3 @@
- True
\ No newline at end of file
+ True
+ True
\ No newline at end of file
From 7b12b634f390f603cb3ec20d93b430a930dcbe40 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Tue, 28 Mar 2023 21:07:41 -0500
Subject: [PATCH 28/33] Add HtmlUtilitiesTests
---
.../Utilities/HtmlUtilitiesTests.cs | 97 +++++++++++++++++++
1 file changed, 97 insertions(+)
create mode 100644 BookmarkSync.Core.Tests/Utilities/HtmlUtilitiesTests.cs
diff --git a/BookmarkSync.Core.Tests/Utilities/HtmlUtilitiesTests.cs b/BookmarkSync.Core.Tests/Utilities/HtmlUtilitiesTests.cs
new file mode 100644
index 0000000..a02eda4
--- /dev/null
+++ b/BookmarkSync.Core.Tests/Utilities/HtmlUtilitiesTests.cs
@@ -0,0 +1,97 @@
+using System.Configuration;
+using BookmarkSync.Core.Utilities;
+
+namespace BookmarkSync.Core.Tests.Utilities;
+
+[TestClass]
+public class HtmlUtilitiesTests
+{
+ [TestMethod]
+ public void ConvertToPlainText_Success()
+ {
+ // Arrange
+ const string
+ html = "example paragraph
",
+ expected = "\r\nexample paragraph";
+
+ // Act
+ string actual = HtmlUtilities.ConvertToPlainText(html);
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+ [TestMethod]
+ public void ConvertToPlainText_WithBr()
+ {
+ // Arrange
+ const string
+ html = "example paragraph
with breaks
",
+ expected = "\r\nexample paragraph\r\nwith breaks";
+
+ // Act
+ string actual = HtmlUtilities.ConvertToPlainText(html);
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+ [TestMethod]
+ public void ConvertToPlainText_WithComments()
+ {
+ // Arrange
+ const string
+ html = """
+
+html document
+""",
+ expected = "html document";
+
+ // Act
+ string actual = HtmlUtilities.ConvertToPlainText(html).Trim();
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+ [TestMethod]
+ public void ConvertToPlainText_WithScripts()
+ {
+ // Arrange
+ const string
+ html = """
+html document
+
+""",
+ expected = "html document";
+
+ // Act
+ string actual = HtmlUtilities.ConvertToPlainText(html).Trim();
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+ [TestMethod]
+ public void ConvertToPlainText_WithStyle()
+ {
+ // Arrange
+ const string
+ html = """
+
+html document
+""",
+ expected = "html document";
+
+ // Act
+ string actual = HtmlUtilities.ConvertToPlainText(html).Trim();
+
+ // Assert
+ Assert.AreEqual(expected, actual);
+ }
+
+}
\ No newline at end of file
From ee8b0aa64b35d887d462490378a4f84fc41e4d5f Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Tue, 28 Mar 2023 21:07:50 -0500
Subject: [PATCH 29/33] Update dependencies
---
.../BookmarkSync.Core.Tests.csproj | 11 +++++++----
BookmarkSync.Core/BookmarkSync.Core.csproj | 4 ++--
.../BookmarkSync.Infrastructure.Tests.csproj | 11 +++++++----
.../BookmarkSync.Infrastructure.csproj | 2 +-
4 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/BookmarkSync.Core.Tests/BookmarkSync.Core.Tests.csproj b/BookmarkSync.Core.Tests/BookmarkSync.Core.Tests.csproj
index e05c2a9..12e63cd 100644
--- a/BookmarkSync.Core.Tests/BookmarkSync.Core.Tests.csproj
+++ b/BookmarkSync.Core.Tests/BookmarkSync.Core.Tests.csproj
@@ -9,11 +9,14 @@
-
+
-
-
-
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/BookmarkSync.Core/BookmarkSync.Core.csproj b/BookmarkSync.Core/BookmarkSync.Core.csproj
index c9220eb..78346e2 100644
--- a/BookmarkSync.Core/BookmarkSync.Core.csproj
+++ b/BookmarkSync.Core/BookmarkSync.Core.csproj
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/BookmarkSync.Infrastructure.Tests/BookmarkSync.Infrastructure.Tests.csproj b/BookmarkSync.Infrastructure.Tests/BookmarkSync.Infrastructure.Tests.csproj
index 127dac4..e73cea9 100644
--- a/BookmarkSync.Infrastructure.Tests/BookmarkSync.Infrastructure.Tests.csproj
+++ b/BookmarkSync.Infrastructure.Tests/BookmarkSync.Infrastructure.Tests.csproj
@@ -9,10 +9,13 @@
-
-
-
-
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj b/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj
index ddbb223..359094c 100644
--- a/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj
+++ b/BookmarkSync.Infrastructure/BookmarkSync.Infrastructure.csproj
@@ -9,7 +9,7 @@
-
+
From 5d0b95067b97948016bf42552fbb4cc3b674b05c Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Tue, 28 Mar 2023 21:25:12 -0500
Subject: [PATCH 30/33] Update README
---
README.md | 53 ++++++++++-------------------------------------------
1 file changed, 10 insertions(+), 43 deletions(-)
diff --git a/README.md b/README.md
index 937f3bc..a45671a 100644
--- a/README.md
+++ b/README.md
@@ -8,67 +8,34 @@ bookmarks with Pinboard.
mastodon-bookmark-sync supports multiple fediverse accounts.
-## requirements
+## getting started
-* Go 1.17
+You probably just want to grab an executable from the [Releases][releases] page.
-## installation
-
-Download the latest release for your system from the
-[Releases page](https://github.com/prplecake/mastodon-bookmark-sync/releases/latest).
-
-## usage
+[releases]:https://github.com/prplecake/mastodon-bookmark-sync/releases
Before you can start using mastodon-bookmark-sync, you'll need to configure
it. An example configuration can be found [here][config-blob]. You can also
just copy the example:
```shell
-cp config.example.yaml config.yaml
-vim config.yaml # don't forget to edit it!
+cp appsettings.Example.json appsettings.json
+vim appsettings.json # don't forget to edit it!
```
-You'll need an access token as well. You can get on from the [Fediverse
-Instance Access Token Generator][fediverse-access-token].
+You'll need an access token from your Mastodon server.
+i.e. `your.instance/settings/applications`
[fediverse-access-token]:https://tools.splat.soy/fediverse-access-token/
And you'll need your
[Pinboard API token](https://pinboard.in/settings/password).
-## developing
-
-Build the thing:
-
-```shell
-go build
-```
-
-Then you can use it:
-
-```shell
-./mastodon-bookmark-sync
-```
-
-You could also specify the configuration file to use via the command
-line:
-
-```shell
-./mastodon-bookmark-sync -c /path/to/your/config.yaml
-```
-
-This would allow you to place the executable (and configuration)
-anywhere on your system. Once gof is configured, you might want to add it to
-your crontab, or your other favorite task scheduler:
+Once you've got it configured, just run it. You might want to add it to your crontab, or your other favorite task
+scheduler:
```text
0 */6 * * * cd /path/to/mastodon-bookmark-sync; ./mastodon-bookmark-sync
```
-or:
-
-```text
-0 */6 * * * /path/to/mastodon-bookmark-sync -c /path/to/config.yaml
-```
-
-[config-blob]:https://github.com/prplecake/mastodon-bookmark-sync/blob/master/config.example.yaml
+[config-blob]:https://github.com/prplecake/mastodon-bookmark-sync/blob/master/BookmarkSync.CLI/appsettings.Example.json
From 4fa175ac21ff1116052cfc68809b3561328295c5 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Tue, 28 Mar 2023 21:33:15 -0500
Subject: [PATCH 31/33] Update workflows
---
.github/workflows/dotnet-release.yml | 64 ++++++++++++++++++++++++++++
.github/workflows/dotnet.yml | 39 ++++++-----------
mastodon-bookmark-sync.sln | 1 +
3 files changed, 77 insertions(+), 27 deletions(-)
create mode 100644 .github/workflows/dotnet-release.yml
diff --git a/.github/workflows/dotnet-release.yml b/.github/workflows/dotnet-release.yml
new file mode 100644
index 0000000..40a09d9
--- /dev/null
+++ b/.github/workflows/dotnet-release.yml
@@ -0,0 +1,64 @@
+name: .NET Release
+
+on:
+ release:
+ types: [published]
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 7.0.x
+ - name: Restore dependencies
+ run: |
+ dotnet nuget add source --username prplecake --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/CompostInTraining/index.json"
+ dotnet restore
+ - name: Build
+ run: dotnet build --no-restore
+
+ - name: Test
+ run: dotnet test --no-build --verbosity normal --logger "trx" --results-directory "./TestResults"
+
+ - uses: dorny/test-reporter@v1
+ if: always()
+ with:
+ name: .NET Test Results
+ path: TestResults/*.trx
+ reporter: dotnet-trx
+
+ publish:
+ env:
+ ZipFile: mastodon-bookmark-sync-${{ github.ref_name }}.zip
+ strategy:
+ matrix:
+ rid: [ linux-x64, win-x64, osx-x64 ]
+
+ runs-on: ubuntu-latest
+ name: publish-${{matrix.rid}}
+ needs: build
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 7.0.x
+ - name: Add NuGet source
+ run: dotnet nuget add source --username prplecake --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/CompostInTraining/index.json"
+ - name: Publish CLI (${{matrix.rid}})
+ run: |
+ dotnet publish BookmarkSync.CLI/BookmarkSync.CLI.csproj -c Release -r ${{matrix.rid}} --self-contained -p:PublishSingleFile=true -p:PublishReadyToRun=true
+ zip mastodon-bookmark-sync-${{ github.ref_name }}-${{matrix.rid}}.zip BookmarkSync.CLI/bin/Release/net7.0/${{matrix.rid}}/publish/*
+ - name: Release
+ uses: softprops/action-gh-release@v1
+ if: startsWith(github.ref, 'refs/tags/')
+ with:
+ files: mastodon-bookmark-sync-*.zip
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index ba2cbd3..cd2cfe7 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -3,8 +3,20 @@ name: .NET
on:
push:
branches: [ master ]
+ paths-ignore:
+ - 'README.md'
+ - '.gitignore'
+ - 'appsettings.Example.json'
+ - '.github/**'
+ - '.idea/**'
pull_request:
branches: [ master ]
+ paths-ignore:
+ - 'README.md'
+ - '.gitignore'
+ - 'appsettings.Example.json'
+ - '.github/**'
+ - '.idea/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -37,30 +49,3 @@ jobs:
name: .NET Test Results
path: TestResults/*.trx
reporter: dotnet-trx
-
- publish:
- strategy:
- matrix:
- rid: [ osx-x64, linux-x64, win-x64 ]
-
- runs-on: ubuntu-latest
- name: publish-${{matrix.rid}}
- needs: build
- if: ${{ github.event_name != 'pull_request' }} # don't upload artifacts for PRs
- steps:
- - uses: actions/checkout@v3
- with:
- fetch-depth: 0
- - name: Setup .NET
- uses: actions/setup-dotnet@v3
- with:
- dotnet-version: 7.0.x
- - name: Add NuGet source
- run: dotnet nuget add source --username prplecake --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/CompostInTraining/index.json"
- - name: Publish CLI (${{matrix.rid}}
- run: dotnet publish BookmarkSync.CLI/BookmarkSync.CLI.csproj -c Release -r ${{matrix.rid}} --self-contained
- - name: Upload CLI artifact
- uses: actions/upload-artifact@v3
- with:
- name: BookmarkSync.CLI-${{matrix.rid}}
- path: BookmarkSync.CLI/bin/Release/net7.0/${{matrix.rid}}/publish/
\ No newline at end of file
diff --git a/mastodon-bookmark-sync.sln b/mastodon-bookmark-sync.sln
index a07a4f8..cb80368 100644
--- a/mastodon-bookmark-sync.sln
+++ b/mastodon-bookmark-sync.sln
@@ -5,6 +5,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
.gitignore = .gitignore
.github\workflows\dotnet.yml = .github\workflows\dotnet.yml
+ .github\workflows\dotnet-release.yml = .github\workflows\dotnet-release.yml
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookmarkSync.CLI", "BookmarkSync.CLI\BookmarkSync.CLI.csproj", "{696935C2-0383-4409-A2B4-B80A8C905DD2}"
From cc1b13e7c00791f1dc71a7e472ca865ba23c0a67 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Tue, 28 Mar 2023 22:04:15 -0500
Subject: [PATCH 32/33] Don't include debug symbols in Releases
---
BookmarkSync.CLI/BookmarkSync.CLI.csproj | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/BookmarkSync.CLI/BookmarkSync.CLI.csproj b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
index 5f81d01..c6892f3 100644
--- a/BookmarkSync.CLI/BookmarkSync.CLI.csproj
+++ b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
@@ -8,6 +8,10 @@
mastodon-bookmark-sync
+
+ none
+
+
From 3bc617ced471d52fa21abb9f433d348c629339f0 Mon Sep 17 00:00:00 2001
From: Matthew Jorgensen
Date: Tue, 28 Mar 2023 22:05:24 -0500
Subject: [PATCH 33/33] Bump version to 2.0.0
---
BookmarkSync.CLI/BookmarkSync.CLI.csproj | 2 ++
1 file changed, 2 insertions(+)
diff --git a/BookmarkSync.CLI/BookmarkSync.CLI.csproj b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
index c6892f3..23002ed 100644
--- a/BookmarkSync.CLI/BookmarkSync.CLI.csproj
+++ b/BookmarkSync.CLI/BookmarkSync.CLI.csproj
@@ -6,6 +6,8 @@
disable
enable
mastodon-bookmark-sync
+ 2.0.0
+ 2.0.0