mirror of
https://github.com/spaytac/linkdingsync.git
synced 2026-01-22 09:14:45 +00:00
**update** added task selection
**upate** updated README.md
This commit is contained in:
parent
fdcfba3c90
commit
00e2a3e07a
1
.idea/.idea.Linkding.Sync/.idea/.name
Normal file
1
.idea/.idea.Linkding.Sync/.idea/.name
Normal file
@ -0,0 +1 @@
|
|||||||
|
Linkding.Sync
|
||||||
6
.idea/.idea.Linkding.Sync/.idea/GitLink.xml
Normal file
6
.idea/.idea.Linkding.Sync/.idea/GitLink.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="uk.co.ben_gibson.git.link.SettingsState">
|
||||||
|
<option name="host" value="72037fcc-cb9c-4c22-960a-ffe73fd5e229" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
41
README.md
41
README.md
@ -14,7 +14,7 @@ Environment variables for the wallabag worker.
|
|||||||
|
|
||||||
| Variable | Value | Description | Attention |
|
| 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') | |
|
| Worker__SyncTag | text | The linkding tag to create the bookmarks in Wallabag. (default value 'readlater') | |
|
||||||
| Linkding__Url | text | URL to the linkding instance | |
|
| 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) |
|
| Linkding__Key | text | The linkding application key | [Instructions](https://github.com/sissbruecker/linkding/blob/master/docs/API.md) |
|
||||||
@ -28,12 +28,45 @@ Environment variables for the wallabag worker.
|
|||||||
Environment variables for the linkding worker.
|
Environment variables for the linkding worker.
|
||||||
|
|
||||||
| Variable | Value | Description | Attention |
|
| 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__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__SyncTag | text | The linkding tag to create the bookmarks in Wallabag. | |
|
| 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__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) |
|
| 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://<url>
|
||||||
|
- Linkding__Key=<secret>
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
The following explains the configuration options. The Configuration file must be mapped to **/app/data/config.yml**
|
The following explains the configuration options. The Configuration file must be mapped to **/app/data/config.yml**
|
||||||
### WallabagSync
|
### WallabagSync
|
||||||
|
|||||||
@ -32,8 +32,8 @@ taggingRule:
|
|||||||
pattern: https://[[a-zA-Z0-9]+\.]?(xbox)\.com(?:/.*)?
|
pattern: https://[[a-zA-Z0-9]+\.]?(xbox)\.com(?:/.*)?
|
||||||
replace: $1
|
replace: $1
|
||||||
- name: github
|
- name: github
|
||||||
pattern: https://([a-zA-Z0-9]+)?[\.]?(github)\.com[/]?([a-zA-Z0-9\-\+_]+)(?:/)?([a-zA-Z0-9\-\+_]+)?(?:/.*)?
|
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
|
- 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
|
replace: $1,$2,$3
|
||||||
@ -8,6 +8,9 @@ services:
|
|||||||
# env_file:
|
# env_file:
|
||||||
# - .env
|
# - .env
|
||||||
environment:
|
environment:
|
||||||
- Worker__Intervall=0
|
- Worker__Interval=0
|
||||||
|
- Worker__TagNameLength=64
|
||||||
|
- Worker__Tasks__0=AddPopularSitesAsTag
|
||||||
|
- Worker__Tasks__1=AddYearToBookmark
|
||||||
- Linkding__Url=https://<url>
|
- Linkding__Url=https://<url>
|
||||||
- Linkding__Key=<secret>
|
- Linkding__Key=<secret>
|
||||||
|
|||||||
@ -8,7 +8,7 @@ services:
|
|||||||
# env_file:
|
# env_file:
|
||||||
# - .env
|
# - .env
|
||||||
environment:
|
environment:
|
||||||
- Worker__Intervall=0
|
- Worker__Interval=0
|
||||||
- Worker__SyncTag=<tagName>
|
- Worker__SyncTag=<tagName>
|
||||||
- Linkding__Url=https://<url>
|
- Linkding__Url=https://<url>
|
||||||
- Linkding__Key=<secret>
|
- Linkding__Key=<secret>
|
||||||
|
|||||||
14
src/Domain/Core/Handler/ILinkdingTagTaskHandler.cs
Normal file
14
src/Domain/Core/Handler/ILinkdingTagTaskHandler.cs
Normal file
@ -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<HandlerResult> ProcessAsync(Tag tag, ILogger logger, IConfiguration configuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/Linkding/Extensions/StringExtensions.cs
Normal file
15
src/Linkding/Extensions/StringExtensions.cs
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,8 +10,6 @@ namespace Linkding.Handler;
|
|||||||
|
|
||||||
public class AddPopularSitesAsTagHandler : ILinkdingTaskHandler
|
public class AddPopularSitesAsTagHandler : ILinkdingTaskHandler
|
||||||
{
|
{
|
||||||
private record RegexExpressionGroups(string Expression, string Replace);
|
|
||||||
|
|
||||||
public string Command { get; } = "AddPopularSitesAsTag";
|
public string Command { get; } = "AddPopularSitesAsTag";
|
||||||
public async Task<HandlerResult> ProcessAsync(Bookmark bookmark, ILogger logger, IConfiguration configuration)
|
public async Task<HandlerResult> ProcessAsync(Bookmark bookmark, ILogger logger, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
@ -34,11 +32,12 @@ public class AddPopularSitesAsTagHandler : ILinkdingTaskHandler
|
|||||||
var tags = tagsCommaSeparated.Split(',');
|
var tags = tagsCommaSeparated.Split(',');
|
||||||
foreach (var tag in tags)
|
foreach (var tag in tags)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(tag) && !returnValue.Instance.TagNames.Contains(tag) &&
|
var normalizeTag = tag.NormalizeTag();
|
||||||
returnValue.Instance.TagNames.FirstOrDefault(x => x.ToLower() == tag.ToLower()) == null)
|
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.PerformAction = true;
|
||||||
returnValue.Action = LinkdingItemAction.Update;
|
returnValue.Action = LinkdingItemAction.Update;
|
||||||
}
|
}
|
||||||
|
|||||||
43
src/Linkding/Handler/NormalizeTagHandler.cs
Normal file
43
src/Linkding/Handler/NormalizeTagHandler.cs
Normal file
@ -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<HandlerResult> ProcessAsync(Bookmark bookmark, ILogger logger, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
var returnValue = new HandlerResult() {Instance = bookmark};
|
||||||
|
var update = false;
|
||||||
|
|
||||||
|
var maxTagLength = configuration.GetValue<int>("Worker:TagNameLength");
|
||||||
|
|
||||||
|
var normalizedTagnames = new List<string>();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,5 +4,7 @@ public class WorkerSettings
|
|||||||
{
|
{
|
||||||
public const string Position = "Worker";
|
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<string> Tasks { get; set; } = new List<string>();
|
||||||
}
|
}
|
||||||
@ -4,6 +4,7 @@ IHost host = Host.CreateDefaultBuilder(args)
|
|||||||
.ConfigureServices((ctx, services) =>
|
.ConfigureServices((ctx, services) =>
|
||||||
{
|
{
|
||||||
services.Add_Linkding_HttpClient(ctx.Configuration);
|
services.Add_Linkding_HttpClient(ctx.Configuration);
|
||||||
|
services.Add_Linkding_Worker(ctx.Configuration);
|
||||||
services.AddHostedService<Worker>();
|
services.AddHostedService<Worker>();
|
||||||
})
|
})
|
||||||
.Build();
|
.Build();
|
||||||
|
|||||||
@ -34,24 +34,24 @@ public class Worker : BackgroundService
|
|||||||
{
|
{
|
||||||
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
|
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
|
||||||
|
|
||||||
await RunTaskHandler();
|
await RunBookmarksTaskHandler();
|
||||||
int delay = _settings.Intervall * 60000;
|
int delay = _settings.Interval * 60000;
|
||||||
|
|
||||||
if (delay > 0)
|
if (delay > 0)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"Worker paused for: {_settings.Intervall} minutes");
|
_logger.LogInformation($"Worker paused for: {_settings.Interval} minutes");
|
||||||
|
|
||||||
await Task.Delay(delay, stoppingToken);
|
await Task.Delay(delay, stoppingToken);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"Intervall value is '0' --> stopping worker");
|
_logger.LogInformation($"Interval value is '0' --> stopping worker");
|
||||||
_hostApplicationLifetime.StopApplication();
|
_hostApplicationLifetime.StopApplication();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RunTaskHandler()
|
public async Task RunBookmarksTaskHandler()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_linkdingSettings.Url) && _linkdingSettings.UpdateBookmarks)
|
if (!string.IsNullOrEmpty(_linkdingSettings.Url) && _linkdingSettings.UpdateBookmarks)
|
||||||
{
|
{
|
||||||
@ -70,6 +70,7 @@ public class Worker : BackgroundService
|
|||||||
var linkdingBookmarks = await _linkdingService.GetAllBookmarksAsync();
|
var linkdingBookmarks = await _linkdingService.GetAllBookmarksAsync();
|
||||||
if (linkdingBookmarks.Count() > 0)
|
if (linkdingBookmarks.Count() > 0)
|
||||||
{
|
{
|
||||||
|
var tasksLowerCase = _settings.Tasks.Select(x => x.ToLower());
|
||||||
|
|
||||||
_logger.LogInformation($"{linkdingBookmarks.Count()} bookmarks found in {_linkdingSettings.Url}");
|
_logger.LogInformation($"{linkdingBookmarks.Count()} bookmarks found in {_linkdingSettings.Url}");
|
||||||
|
|
||||||
@ -80,6 +81,14 @@ public class Worker : BackgroundService
|
|||||||
{
|
{
|
||||||
handlerInstance = (ILinkdingTaskHandler) Activator.CreateInstance(handler);
|
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)
|
foreach (var linkdingBookmark in linkdingBookmarks)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@ -33,7 +33,7 @@ taggingRule:
|
|||||||
replace: $1
|
replace: $1
|
||||||
- name: github
|
- name: github
|
||||||
pattern: https://([ a-zA-Z0-9 ]+)?[ \. ]?(github)\.com[ / ]?([ a-zA-Z0-9\-\+_ ]+)(?:/)?([ a-zA-Z0-9\-\+_ ]+)?(?:/.*)?
|
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
|
- 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
|
replace: $2,$3,$4
|
||||||
@ -4,7 +4,7 @@ public class WorkerSettings
|
|||||||
{
|
{
|
||||||
public const string Position = "Worker";
|
public const string Position = "Worker";
|
||||||
|
|
||||||
public int Intervall { get; set; } = 0;
|
public int Interval { get; set; } = 0;
|
||||||
|
|
||||||
public string SyncTag { get; set; } = "readlater";
|
public string SyncTag { get; set; } = "readlater";
|
||||||
}
|
}
|
||||||
@ -42,11 +42,11 @@ public class Worker : BackgroundService
|
|||||||
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
|
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
|
||||||
|
|
||||||
await RunSyncWallabag();
|
await RunSyncWallabag();
|
||||||
int delay = _settings.Intervall * 60000;
|
int delay = _settings.Interval * 60000;
|
||||||
|
|
||||||
if (delay > 0)
|
if (delay > 0)
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"Worker paused for: {_settings.Intervall} minutes");
|
_logger.LogInformation($"Worker paused for: {_settings.Interval} minutes");
|
||||||
|
|
||||||
await Task.Delay(delay, stoppingToken);
|
await Task.Delay(delay, stoppingToken);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user