diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 0000000..b29be29
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,18 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "dotnet-user-secrets": {
+ "version": "2.2.0",
+ "commands": [
+ "dotnet-user-secrets"
+ ]
+ },
+ "dotnet-ef": {
+ "version": "7.0.3",
+ "commands": [
+ "dotnet-ef"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..38bece4
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,25 @@
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/.idea
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
\ No newline at end of file
diff --git a/.idea/.idea.PiwigoDirectorySync/.idea/.gitignore b/.idea/.idea.PiwigoDirectorySync/.idea/.gitignore
new file mode 100644
index 0000000..caa4155
--- /dev/null
+++ b/.idea/.idea.PiwigoDirectorySync/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/projectSettingsUpdater.xml
+/.idea.PiwigoDirectorySync.iml
+/modules.xml
+/contentModel.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/.idea.PiwigoDirectorySync/.idea/encodings.xml b/.idea/.idea.PiwigoDirectorySync/.idea/encodings.xml
new file mode 100644
index 0000000..df87cf9
--- /dev/null
+++ b/.idea/.idea.PiwigoDirectorySync/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.PiwigoDirectorySync/.idea/indexLayout.xml b/.idea/.idea.PiwigoDirectorySync/.idea/indexLayout.xml
new file mode 100644
index 0000000..f5a863a
--- /dev/null
+++ b/.idea/.idea.PiwigoDirectorySync/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.PiwigoDirectorySync/.idea/vcs.xml b/.idea/.idea.PiwigoDirectorySync/.idea/vcs.xml
new file mode 100644
index 0000000..c8397c9
--- /dev/null
+++ b/.idea/.idea.PiwigoDirectorySync/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 0000000..f1f725c
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,68 @@
+pipeline {
+ agent {
+ docker { image 'mcr.microsoft.com/dotnet/sdk:6.0'}
+ }
+
+ environment {
+ APPVERSION = "0.0.1"
+ HOME = "${env.WORKSPACE}"
+ }
+
+ stages {
+ stage('preparing workspace') {
+ steps {
+ cleanWs deleteDirs: true, notFailBuild: true, patterns: [[pattern: '.nuget/NuGet/NuGet.Config', type: 'INCLUDE']]
+ dir('publish') {
+ deleteDir()
+ }
+ withCredentials([usernamePassword(credentialsId: 'giteaNugetPushCreds', passwordVariable: 'NUGETPWD', usernameVariable: 'NUGETUSR')]) {
+ sh 'dotnet nuget add source --name gitea --username $NUGETUSR --password $NUGETPWD --store-password-in-clear-text https://git.haefelfinger.net/api/packages/piwigo/nuget/index.json'
+ }
+ }
+ }
+
+ stage('nuget restore') {
+ steps {
+ sh "dotnet restore ${env.WORKSPACE}/photo.haefelfinger.workflow.sln"
+ }
+ }
+
+ stage('test') {
+ steps {
+ sh "dotnet test ${env.WORKSPACE}/photo.haefelfinger.workflow.sln --no-restore"
+ }
+ }
+
+ stage('build api') {
+ steps {
+ sh "/bin/true"
+ }
+ }
+
+ stage('api docker image') {
+ steps {
+ sh "/bin/true"
+ }
+ }
+
+ stage('build cli') {
+ steps {
+ sh "dotnet publish ${env.WORKSPACE}/photo.haefelfinger.workflow.cli/photo.haefelfinger.workflow.cli.csproj -c Release --self-contained true -r linux-x64 -o ${env.WORKSPACE}/publish/cli-linux -p:Version=${env.APPVERSION}.${env.BUILD_NUMBER}"
+ sh "dotnet publish ${env.WORKSPACE}/photo.haefelfinger.workflow.cli/photo.haefelfinger.workflow.cli.csproj -c Release --self-contained true -r win-x64 -o ${env.WORKSPACE}/publish/cli-win -p:Version=${env.APPVERSION}.${env.BUILD_NUMBER}"
+ }
+ }
+
+ stage('publish docker images') {
+ steps {
+ sh "/bin/true"
+ }
+ }
+
+ }
+
+ post {
+ always {
+ archiveArtifacts artifacts: "publish/**/*", onlyIfSuccessful: true
+ }
+ }
+}
diff --git a/NuGet.Config b/NuGet.Config
new file mode 100644
index 0000000..12573c9
--- /dev/null
+++ b/NuGet.Config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PiwigoDirectorySync.sln b/PiwigoDirectorySync.sln
new file mode 100644
index 0000000..6930b09
--- /dev/null
+++ b/PiwigoDirectorySync.sln
@@ -0,0 +1,16 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PiwigoDirectorySync", "PiwigoDirectorySync\PiwigoDirectorySync.csproj", "{1381617F-F27E-4430-81FD-60EA78A6406F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1381617F-F27E-4430-81FD-60EA78A6406F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1381617F-F27E-4430-81FD-60EA78A6406F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1381617F-F27E-4430-81FD-60EA78A6406F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1381617F-F27E-4430-81FD-60EA78A6406F}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/PiwigoDirectorySync.sln.DotSettings b/PiwigoDirectorySync.sln.DotSettings
new file mode 100644
index 0000000..fe19aae
--- /dev/null
+++ b/PiwigoDirectorySync.sln.DotSettings
@@ -0,0 +1,101 @@
+
+ 3000
+ 2000
+ <?xml version="1.0" encoding="utf-16"?><Profile name="DefaultAll"><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><CppAddTypenameTemplateKeywords>True</CppAddTypenameTemplateKeywords><CppRemoveCastDescriptor>True</CppRemoveCastDescriptor><CppRemoveElseKeyword>True</CppRemoveElseKeyword><CppShortenQualifiedName>True</CppShortenQualifiedName><CppDeleteRedundantSpecifier>True</CppDeleteRedundantSpecifier><CppRemoveStatement>True</CppRemoveStatement><CppDeleteRedundantTypenameTemplateKeywords>True</CppDeleteRedundantTypenameTemplateKeywords><CppCStyleToStaticCastDescriptor>True</CppCStyleToStaticCastDescriptor><CppReplaceExpressionWithBooleanConst>True</CppReplaceExpressionWithBooleanConst><CppMakeIfConstexpr>True</CppMakeIfConstexpr><CppMakePostfixOperatorPrefix>True</CppMakePostfixOperatorPrefix><CppChangeSmartPointerToMakeFunction>True</CppChangeSmartPointerToMakeFunction><CppReplaceThrowWithRethrowFix>True</CppReplaceThrowWithRethrowFix><CppTypeTraitAliasDescriptor>True</CppTypeTraitAliasDescriptor><CppReplaceExpressionWithNullptr>True</CppReplaceExpressionWithNullptr><CppReplaceTieWithStructuredBindingDescriptor>True</CppReplaceTieWithStructuredBindingDescriptor><CppUseAssociativeContainsDescriptor>True</CppUseAssociativeContainsDescriptor><CppUseEraseAlgorithmDescriptor>True</CppUseEraseAlgorithmDescriptor><CppCodeStyleCleanupDescriptor ArrangeBraces="True" ArrangeAuto="True" ArrangeFunctionDeclarations="True" ArrangeNestedNamespaces="True" ArrangeTypeAliases="True" ArrangeCVQualifiers="True" ArrangeSlashesInIncludeDirectives="True" ArrangeOverridingFunctions="True" SortIncludeDirectives="True" SortMemberInitializers="True" /><CppReformatCode>True</CppReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers><CSCodeStyleAttributes ArrangeVarStyle="True" ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" ArrangeArgumentsStyle="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeCodeBodyStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" ArrangeNullCheckingPattern="True" /><FSReformatCode>True</FSReformatCode><RemoveCodeRedundanciesVB>True</RemoveCodeRedundanciesVB><Xaml.RedundantFreezeAttribute>True</Xaml.RedundantFreezeAttribute><Xaml.RemoveRedundantModifiersAttribute>True</Xaml.RemoveRedundantModifiersAttribute><Xaml.RemoveRedundantNameAttribute>True</Xaml.RemoveRedundantNameAttribute><Xaml.RemoveRedundantResource>True</Xaml.RemoveRedundantResource><Xaml.RemoveRedundantCollectionProperty>True</Xaml.RemoveRedundantCollectionProperty><Xaml.RemoveRedundantAttachedPropertySetter>True</Xaml.RemoveRedundantAttachedPropertySetter><Xaml.RemoveRedundantStyledValue>True</Xaml.RemoveRedundantStyledValue><Xaml.RemoveRedundantNamespaceAlias>True</Xaml.RemoveRedundantNamespaceAlias><Xaml.RemoveForbiddenResourceName>True</Xaml.RemoveForbiddenResourceName><Xaml.RemoveRedundantGridDefinitionsAttribute>True</Xaml.RemoveRedundantGridDefinitionsAttribute><Xaml.RemoveRedundantUpdateSourceTriggerAttribute>True</Xaml.RemoveRedundantUpdateSourceTriggerAttribute><Xaml.RemoveRedundantBindingModeAttribute>True</Xaml.RemoveRedundantBindingModeAttribute><Xaml.RemoveRedundantGridSpanAttribut>True</Xaml.RemoveRedundantGridSpanAttribut><XMLReformatCode>True</XMLReformatCode><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><HtmlReformatCode>True</HtmlReformatCode><VBOptimizeImports>True</VBOptimizeImports><VBShortenReferences>True</VBShortenReferences><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><VBReformatCode>True</VBReformatCode><VBFormatDocComments>True</VBFormatDocComments><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><IDEA_SETTINGS><profile version="1.0">
+ <option name="myName" value="DefaultAll" />
+</profile></IDEA_SETTINGS><RIDER_SETTINGS><profile>
+ <Language id="CSS">
+ <Rearrange>true</Rearrange>
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="EditorConfig">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="HTML">
+ <Rearrange>true</Rearrange>
+ <OptimizeImports>true</OptimizeImports>
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="HTTP Request">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="Handlebars">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="Ini">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="JSON">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="Jade">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="JavaScript">
+ <Rearrange>true</Rearrange>
+ <OptimizeImports>true</OptimizeImports>
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="Markdown">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="Properties">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="RELAX-NG">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="SQL">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="VueExpr">
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="XML">
+ <Rearrange>true</Rearrange>
+ <OptimizeImports>true</OptimizeImports>
+ <Reformat>true</Reformat>
+ </Language>
+ <Language id="yaml">
+ <Reformat>true</Reformat>
+ </Language>
+</profile></RIDER_SETTINGS></Profile>
+ Required
+ Required
+ ExpressionBody
+ False
+ False
+ CHOP_IF_LONG
+ 180
+ False
+ True
+ True
+ True
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
\ No newline at end of file
diff --git a/PiwigoDirectorySync/Dockerfile b/PiwigoDirectorySync/Dockerfile
new file mode 100644
index 0000000..5a949d6
--- /dev/null
+++ b/PiwigoDirectorySync/Dockerfile
@@ -0,0 +1,18 @@
+FROM mcr.microsoft.com/dotnet/runtime:7.0 AS base
+WORKDIR /app
+
+FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
+WORKDIR /src
+COPY ["PiwigoDirectorySync/PiwigoDirectorySync.csproj", "PiwigoDirectorySync/"]
+RUN dotnet restore "PiwigoDirectorySync/PiwigoDirectorySync.csproj"
+COPY . .
+WORKDIR "/src/PiwigoDirectorySync"
+RUN dotnet build "PiwigoDirectorySync.csproj" -c Release -o /app/build
+
+FROM build AS publish
+RUN dotnet publish "PiwigoDirectorySync.csproj" -c Release -o /app/publish /p:UseAppHost=false
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "PiwigoDirectorySync.dll"]
diff --git a/PiwigoDirectorySync/PiwigoDirectorySync.csproj b/PiwigoDirectorySync/PiwigoDirectorySync.csproj
new file mode 100644
index 0000000..0619d80
--- /dev/null
+++ b/PiwigoDirectorySync/PiwigoDirectorySync.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ net7.0
+ enable
+ enable
+ Linux
+
+
+
+
+ .dockerignore
+
+
+
+
diff --git a/PiwigoDirectorySync/Program.cs b/PiwigoDirectorySync/Program.cs
new file mode 100644
index 0000000..2d6e81e
--- /dev/null
+++ b/PiwigoDirectorySync/Program.cs
@@ -0,0 +1,3 @@
+// See https://aka.ms/new-console-template for more information
+
+Console.WriteLine("Hello, World!");
\ No newline at end of file