diff --git a/.idea/.idea.Linkding.Sync/.idea/.name b/.idea/.idea.Linkding.Sync/.idea/.name
new file mode 100644
index 0000000..bbf3e88
--- /dev/null
+++ b/.idea/.idea.Linkding.Sync/.idea/.name
@@ -0,0 +1 @@
+Linkding.Sync
\ No newline at end of file
diff --git a/.idea/.idea.Linkding.Sync/.idea/GitLink.xml b/.idea/.idea.Linkding.Sync/.idea/GitLink.xml
new file mode 100644
index 0000000..009597c
--- /dev/null
+++ b/.idea/.idea.Linkding.Sync/.idea/GitLink.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 1cb70a3..06db8f1 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Environment variables for the wallabag worker.
| Variable | Value | Description | Attention |
|------------------------|-----------|--------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| Worker__Intervall | int (>=0) | This value sets the execution schedule in minutes. 1 = every minute, 10 = every 10 minutes (default value 0) | 0 = runs only one time. The container will be stopped after the execution. This method is the preferred way to run the container with a scheduler (e.g. cron) |
+| Worker__Interval | int (>=0) | This value sets the execution schedule in minutes. 1 = every minute, 10 = every 10 minutes (default value 0) | 0 = runs only one time. The container will be stopped after the execution. This method is the preferred way to run the container with a scheduler (e.g. cron) |
| Worker__SyncTag | text | The linkding tag to create the bookmarks in Wallabag. (default value 'readlater') | |
| Linkding__Url | text | URL to the linkding instance | |
| Linkding__Key | text | The linkding application key | [Instructions](https://github.com/sissbruecker/linkding/blob/master/docs/API.md) |
@@ -27,12 +27,45 @@ Environment variables for the wallabag worker.
### LinkdingUpdater
Environment variables for the linkding worker.
-| Variable | Value | Description | Attention |
-|------------------------|-----------|--------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| Worker__Intervall | int (>=0) | This value sets the execution schedule in minutes. 1 = every minute, 10 = every 10 minutes | 0 = runs only one time. The container will be stopped after the execution. This method is the preferred way to run the container with a scheduler (e.g. cron) |
-| Worker__SyncTag | text | The linkding tag to create the bookmarks in Wallabag. | |
-| Linkding__Url | text | URL to the linkding instance | |
-| Linkding__Key | text | The linkding application key | [Instructions](https://github.com/sissbruecker/linkding/blob/master/docs/API.md) |
+| Variable | Value | Description | Attention |
+|-------------------------------|-----------|--------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Worker__Interval | int (>=0) | This value sets the execution schedule in minutes. 1 = every minute, 10 = every 10 minutes | 0 = runs only one time. The container will be stopped after the execution. This method is the preferred way to run the container with a scheduler (e.g. cron) |
+| Worker__Worker__TagNameLength | int | The max tag name length. Default is 64 characters | |
+| Worker__Tasks__X | text | The tasks which should be executed. X is the array index for the tasks entry | currently supported tasks: AddPopularSitesAsTag,AddYearToBookmark. |
+| Linkding__Url | text | URL to the linkding instance | |
+| Linkding__Key | text | The linkding application key | [Instructions](https://github.com/sissbruecker/linkding/blob/master/docs/API.md) |
+
+#### Tasks
+Tasks define the logic that directly make changes to the bookmarks.
+Currently available tasks:
+
+| Name | Description |
+|-----------------------|------------------------------------------------------------------------------------------------------------------------------------|
+| AddYearToBookmark | If the bookmark does not have the year of the creation date as a tag, it will be added. |
+| AddPopularSitesAsTag | This is the task for dynamic creation of tags. For this task to work, the rules must be passed to the container as configuration. |
+
+The tasks are defined as environment variables, if no tasks are defined, the container will be executed but no changes will be made.
+The tasks are passed as follows:
+```yaml
+version: '3.9'
+
+services:
+ linkdingupdater:
+ image: ghcr.io/spaytac/linkding-updater:latest
+ volumes:
+ - ./config.yml:/app/data/config.yml
+ # env_file:
+ # - .env
+ environment:
+ - Worker__Interval=0
+ - Worker__TagNameLength=64
+ - Worker__Tasks__0=AddPopularSitesAsTag
+ - Worker__Tasks__1=AddYearToBookmark
+ - Linkding__Url=https://
+ - Linkding__Key=
+
+
+```
## Configuration
The following explains the configuration options. The Configuration file must be mapped to **/app/data/config.yml**
diff --git a/examples/linkding/config.yml b/examples/linkding/config.yml
index 1650e79..4ccaa8c 100644
--- a/examples/linkding/config.yml
+++ b/examples/linkding/config.yml
@@ -32,8 +32,8 @@ taggingRule:
pattern: https://[[a-zA-Z0-9]+\.]?(xbox)\.com(?:/.*)?
replace: $1
- name: github
- pattern: https://([a-zA-Z0-9]+)?[\.]?(github)\.com[/]?([a-zA-Z0-9\-\+_]+)(?:/)?([a-zA-Z0-9\-\+_]+)?(?:/.*)?
- replace: $1,$2,$3,$4
+ pattern: https://([ a-zA-Z0-9 ]+)?[ \. ]?(github)\.com[ / ]?([ a-zA-Z0-9\-\+_ ]+)(?:/)?([ a-zA-Z0-9\-\+_ ]+)?(?:/.*)?
+ replace: $2,$3,$4
- name: github.io
- pattern: https://([a-zA-Z0-9]+)\.(github)\.io[/]?([a-zA-Z0-9\-\+_]+)(?:/)?([a-zA-Z0-9\-\+_]+)?(?:/.*)?
+ pattern: https://([ a-zA-Z0-9 ]+)\.(github)\.io[ / ]?([ a-zA-Z0-9\-\+_ ]+)(?:/)?([ a-zA-Z0-9\-\+_ ]+)?(?:/.*)?
replace: $1,$2,$3
\ No newline at end of file
diff --git a/examples/linkding/docker-compose.yml b/examples/linkding/docker-compose.yml
index 9c07970..3bb079d 100644
--- a/examples/linkding/docker-compose.yml
+++ b/examples/linkding/docker-compose.yml
@@ -8,6 +8,9 @@ services:
# env_file:
# - .env
environment:
- - Worker__Intervall=0
+ - Worker__Interval=0
+ - Worker__TagNameLength=64
+ - Worker__Tasks__0=AddPopularSitesAsTag
+ - Worker__Tasks__1=AddYearToBookmark
- Linkding__Url=https://
- Linkding__Key=
diff --git a/examples/wallabag/docker-compose.yml b/examples/wallabag/docker-compose.yml
index e32f13f..01fcc88 100644
--- a/examples/wallabag/docker-compose.yml
+++ b/examples/wallabag/docker-compose.yml
@@ -8,7 +8,7 @@ services:
# env_file:
# - .env
environment:
- - Worker__Intervall=0
+ - Worker__Interval=0
- Worker__SyncTag=
- Linkding__Url=https://
- Linkding__Key=
diff --git a/src/Domain/Core/Handler/ILinkdingTagTaskHandler.cs b/src/Domain/Core/Handler/ILinkdingTagTaskHandler.cs
new file mode 100644
index 0000000..df04fad
--- /dev/null
+++ b/src/Domain/Core/Handler/ILinkdingTagTaskHandler.cs
@@ -0,0 +1,14 @@
+using System.Threading.Tasks;
+using Core.Entities.Linkding;
+using LinkdingUpdater.Handler;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+
+namespace Core.Handler
+{
+ public interface ILinkdingTagTaskHandler
+ {
+ string Command { get; }
+ Task ProcessAsync(Tag tag, ILogger logger, IConfiguration configuration);
+ }
+}
\ No newline at end of file
diff --git a/src/Linkding/Extensions/StringExtensions.cs b/src/Linkding/Extensions/StringExtensions.cs
new file mode 100644
index 0000000..d4b5de4
--- /dev/null
+++ b/src/Linkding/Extensions/StringExtensions.cs
@@ -0,0 +1,15 @@
+namespace Microsoft.Extensions.DependencyInjection;
+
+public static class StringExtensions
+{
+ public static string NormalizeTag(this string tag, int maxTagLength = 64)
+ {
+ //in the database only 64 characters are allowed for tags
+ if (tag.Length >= maxTagLength)
+ {
+ tag = tag.Substring(0, (maxTagLength));
+ }
+
+ return tag;
+ }
+}
\ No newline at end of file
diff --git a/src/Linkding/Handler/AddPopularSitesAsTagHandler.cs b/src/Linkding/Handler/AddPopularSitesAsTagHandler.cs
index b606486..174beac 100644
--- a/src/Linkding/Handler/AddPopularSitesAsTagHandler.cs
+++ b/src/Linkding/Handler/AddPopularSitesAsTagHandler.cs
@@ -10,8 +10,6 @@ namespace Linkding.Handler;
public class AddPopularSitesAsTagHandler : ILinkdingTaskHandler
{
- private record RegexExpressionGroups(string Expression, string Replace);
-
public string Command { get; } = "AddPopularSitesAsTag";
public async Task ProcessAsync(Bookmark bookmark, ILogger logger, IConfiguration configuration)
{
@@ -34,11 +32,12 @@ public class AddPopularSitesAsTagHandler : ILinkdingTaskHandler
var tags = tagsCommaSeparated.Split(',');
foreach (var tag in tags)
{
- if (!string.IsNullOrEmpty(tag) && !returnValue.Instance.TagNames.Contains(tag) &&
- returnValue.Instance.TagNames.FirstOrDefault(x => x.ToLower() == tag.ToLower()) == null)
+ var normalizeTag = tag.NormalizeTag();
+ if (!string.IsNullOrEmpty(normalizeTag) && !returnValue.Instance.TagNames.Contains(normalizeTag) &&
+ returnValue.Instance.TagNames.FirstOrDefault(x => x.ToLower() == normalizeTag.ToLower()) == null)
{
- returnValue.Instance.TagNames = returnValue.Instance.TagNames.Add(tag);
+ returnValue.Instance.TagNames = returnValue.Instance.TagNames.Add(normalizeTag);
returnValue.PerformAction = true;
returnValue.Action = LinkdingItemAction.Update;
}
diff --git a/src/Linkding/Handler/NormalizeTagHandler.cs b/src/Linkding/Handler/NormalizeTagHandler.cs
new file mode 100644
index 0000000..65d15b2
--- /dev/null
+++ b/src/Linkding/Handler/NormalizeTagHandler.cs
@@ -0,0 +1,43 @@
+using Core.Entities.Linkding;
+using Core.Handler;
+using LinkdingUpdater.Handler;
+
+namespace Linkding.Handler;
+
+public class NormalizeTagHandler : ILinkdingTaskHandler
+{
+ public string Command { get; } = "NormalizeTag";
+
+ public async Task ProcessAsync(Bookmark bookmark, ILogger logger, IConfiguration configuration)
+ {
+ var returnValue = new HandlerResult() {Instance = bookmark};
+ var update = false;
+
+ var maxTagLength = configuration.GetValue("Worker:TagNameLength");
+
+ var normalizedTagnames = new List();
+ foreach (var tagName in returnValue.Instance.TagNames)
+ {
+ if (tagName.Length > maxTagLength)
+ {
+ var normalizeTag = tagName.NormalizeTag();
+ normalizedTagnames.Add(normalizeTag);
+ update = true;
+ }
+ else
+ {
+ normalizedTagnames.Add(tagName);
+ }
+ }
+
+ if (update)
+ {
+ logger.LogInformation($"Start updating bookmark {returnValue.Instance.WebsiteTitle} - {returnValue.Instance.Id}");
+ returnValue.Instance.TagNames = normalizedTagnames;
+ returnValue.PerformAction = true;
+ returnValue.Action = LinkdingItemAction.Update;
+ }
+
+ return returnValue;
+ }
+}
\ No newline at end of file
diff --git a/src/Linkding/Options/WorkerSettings.cs b/src/Linkding/Options/WorkerSettings.cs
index 7b87cfa..60847b7 100644
--- a/src/Linkding/Options/WorkerSettings.cs
+++ b/src/Linkding/Options/WorkerSettings.cs
@@ -4,5 +4,7 @@ public class WorkerSettings
{
public const string Position = "Worker";
- public int Intervall { get; set; } = 0;
+ public int Interval { get; set; } = 0;
+ public int TagNameLength { get; set; } = 64;
+ public List Tasks { get; set; } = new List();
}
\ No newline at end of file
diff --git a/src/Linkding/Program.cs b/src/Linkding/Program.cs
index 71d8ee2..ec1ff17 100644
--- a/src/Linkding/Program.cs
+++ b/src/Linkding/Program.cs
@@ -4,6 +4,7 @@ IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices((ctx, services) =>
{
services.Add_Linkding_HttpClient(ctx.Configuration);
+ services.Add_Linkding_Worker(ctx.Configuration);
services.AddHostedService();
})
.Build();
diff --git a/src/Linkding/Worker.cs b/src/Linkding/Worker.cs
index f41a26a..249791d 100644
--- a/src/Linkding/Worker.cs
+++ b/src/Linkding/Worker.cs
@@ -34,24 +34,24 @@ public class Worker : BackgroundService
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
- await RunTaskHandler();
- int delay = _settings.Intervall * 60000;
+ await RunBookmarksTaskHandler();
+ int delay = _settings.Interval * 60000;
if (delay > 0)
{
- _logger.LogInformation($"Worker paused for: {_settings.Intervall} minutes");
+ _logger.LogInformation($"Worker paused for: {_settings.Interval} minutes");
await Task.Delay(delay, stoppingToken);
}
else
{
- _logger.LogInformation($"Intervall value is '0' --> stopping worker");
+ _logger.LogInformation($"Interval value is '0' --> stopping worker");
_hostApplicationLifetime.StopApplication();
}
}
}
- public async Task RunTaskHandler()
+ public async Task RunBookmarksTaskHandler()
{
if (!string.IsNullOrEmpty(_linkdingSettings.Url) && _linkdingSettings.UpdateBookmarks)
{
@@ -70,6 +70,7 @@ public class Worker : BackgroundService
var linkdingBookmarks = await _linkdingService.GetAllBookmarksAsync();
if (linkdingBookmarks.Count() > 0)
{
+ var tasksLowerCase = _settings.Tasks.Select(x => x.ToLower());
_logger.LogInformation($"{linkdingBookmarks.Count()} bookmarks found in {_linkdingSettings.Url}");
@@ -80,6 +81,14 @@ public class Worker : BackgroundService
{
handlerInstance = (ILinkdingTaskHandler) Activator.CreateInstance(handler);
+ var task = tasksLowerCase.FirstOrDefault(x =>
+ x.Equals(handlerInstance.Command, StringComparison.InvariantCultureIgnoreCase));
+
+ if (string.IsNullOrEmpty(task))
+ {
+ continue;
+ }
+
foreach (var linkdingBookmark in linkdingBookmarks)
{
try
diff --git a/src/Linkding/config.yml b/src/Linkding/config.yml
index fa05237..6f1a483 100644
--- a/src/Linkding/config.yml
+++ b/src/Linkding/config.yml
@@ -33,7 +33,7 @@ taggingRule:
replace: $1
- name: github
pattern: https://([ a-zA-Z0-9 ]+)?[ \. ]?(github)\.com[ / ]?([ a-zA-Z0-9\-\+_ ]+)(?:/)?([ a-zA-Z0-9\-\+_ ]+)?(?:/.*)?
- replace: $1,$2,$3,$4
+ replace: $2,$3,$4
- name: github.io
pattern: https://([ a-zA-Z0-9 ]+)\.(github)\.io[ / ]?([ a-zA-Z0-9\-\+_ ]+)(?:/)?([ a-zA-Z0-9\-\+_ ]+)?(?:/.*)?
- replace: $1,$2,$3
\ No newline at end of file
+ replace: $2,$3,$4
\ No newline at end of file
diff --git a/src/Wallabag/Options/WorkerSettings.cs b/src/Wallabag/Options/WorkerSettings.cs
index d0f868f..3ca3db6 100644
--- a/src/Wallabag/Options/WorkerSettings.cs
+++ b/src/Wallabag/Options/WorkerSettings.cs
@@ -4,7 +4,7 @@ public class WorkerSettings
{
public const string Position = "Worker";
- public int Intervall { get; set; } = 0;
+ public int Interval { get; set; } = 0;
public string SyncTag { get; set; } = "readlater";
}
\ No newline at end of file
diff --git a/src/Wallabag/Worker.cs b/src/Wallabag/Worker.cs
index 8d14838..fac68f2 100644
--- a/src/Wallabag/Worker.cs
+++ b/src/Wallabag/Worker.cs
@@ -42,11 +42,11 @@ public class Worker : BackgroundService
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await RunSyncWallabag();
- int delay = _settings.Intervall * 60000;
+ int delay = _settings.Interval * 60000;
if (delay > 0)
{
- _logger.LogInformation($"Worker paused for: {_settings.Intervall} minutes");
+ _logger.LogInformation($"Worker paused for: {_settings.Interval} minutes");
await Task.Delay(delay, stoppingToken);
}