mirror of
https://github.com/jellyfin/jellyfin-plugin-sessioncleaner.git
synced 2024-11-23 05:59:42 +00:00
clean up
This commit is contained in:
parent
c5fa9c03af
commit
1e9387408d
@ -1,15 +1,14 @@
|
||||
using MediaBrowser.Model.Plugins;
|
||||
|
||||
namespace Jellyfin.Plugin.SessionCleaner.Configuration
|
||||
namespace Jellyfin.Plugin.SessionCleaner.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Plugin configuration.
|
||||
/// </summary>
|
||||
public class PluginConfiguration : BasePluginConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Plugin configuration.
|
||||
/// Gets or sets the amount of days a device should be kept.
|
||||
/// </summary>
|
||||
public class PluginConfiguration : BasePluginConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the amount of days a device should be kept.
|
||||
/// </summary>
|
||||
public int Days { get; set; } = 30;
|
||||
}
|
||||
}
|
||||
public int Days { get; set; } = 30;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.376" PrivateAssets="All" />
|
||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -6,48 +6,47 @@ using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Model.Plugins;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.SessionCleaner
|
||||
namespace Jellyfin.Plugin.SessionCleaner;
|
||||
|
||||
/// <summary>
|
||||
/// Plugin entrypoint.
|
||||
/// </summary>
|
||||
public class SessionCleanerPlugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
||||
{
|
||||
private readonly Guid _id = new("EC9E2A74-1311-4A14-B302-158E3D95FD1D");
|
||||
|
||||
/// <summary>
|
||||
/// Plugin entrypoint.
|
||||
/// Initializes a new instance of the <see cref="SessionCleanerPlugin"/> class.
|
||||
/// </summary>
|
||||
public class SessionCleanerPlugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
||||
/// <param name="applicationPaths">Instance of the <see cref="IApplicationPaths"/> interface.</param>
|
||||
/// <param name="xmlSerializer">Instance of the <see cref="IXmlSerializer"/> interface.</param>
|
||||
public SessionCleanerPlugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
|
||||
: base(applicationPaths, xmlSerializer)
|
||||
{
|
||||
private readonly Guid _id = new ("EC9E2A74-1311-4A14-B302-158E3D95FD1D");
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SessionCleanerPlugin"/> class.
|
||||
/// </summary>
|
||||
/// <param name="applicationPaths">Instance of the <see cref="IApplicationPaths"/> interface.</param>
|
||||
/// <param name="xmlSerializer">Instance of the <see cref="IXmlSerializer"/> interface.</param>
|
||||
public SessionCleanerPlugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
|
||||
: base(applicationPaths, xmlSerializer)
|
||||
/// <summary>
|
||||
/// Gets the current plugin instance.
|
||||
/// </summary>
|
||||
public static SessionCleanerPlugin? Instance { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Guid Id => _id;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Session Cleaner";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Cleans old sessions.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<PluginPageInfo> GetPages()
|
||||
{
|
||||
yield return new PluginPageInfo
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current plugin instance.
|
||||
/// </summary>
|
||||
public static SessionCleanerPlugin? Instance { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Guid Id => _id;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Session Cleaner";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Description => "Cleans old sessions.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<PluginPageInfo> GetPages()
|
||||
{
|
||||
yield return new PluginPageInfo
|
||||
{
|
||||
Name = Name,
|
||||
EmbeddedResourcePath = GetType().Namespace + ".Configuration.config.html"
|
||||
};
|
||||
}
|
||||
Name = Name,
|
||||
EmbeddedResourcePath = GetType().Namespace + ".Configuration.config.html"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -9,82 +9,81 @@ using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Model.Globalization;
|
||||
using MediaBrowser.Model.Tasks;
|
||||
|
||||
namespace Jellyfin.Plugin.SessionCleaner
|
||||
namespace Jellyfin.Plugin.SessionCleaner;
|
||||
|
||||
/// <summary>
|
||||
/// Device cleaner task.
|
||||
/// </summary>
|
||||
public class SessionCleanerTask : IScheduledTask, IConfigurableScheduledTask
|
||||
{
|
||||
private readonly IDeviceManager _deviceManager;
|
||||
private readonly ISessionManager _sessionManager;
|
||||
private readonly ILocalizationManager _localizationManager;
|
||||
|
||||
/// <summary>
|
||||
/// Device cleaner task.
|
||||
/// Initializes a new instance of the <see cref="SessionCleanerTask"/> class.
|
||||
/// </summary>
|
||||
public class SessionCleanerTask : IScheduledTask, IConfigurableScheduledTask
|
||||
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
|
||||
/// <param name="localizationManager">Instance of the <see cref="ILocalizationManager"/> interface.</param>
|
||||
/// <param name="deviceManager">Instance of the <see cref="IDeviceManager"/> interface.</param>
|
||||
public SessionCleanerTask(
|
||||
ISessionManager sessionManager,
|
||||
ILocalizationManager localizationManager,
|
||||
IDeviceManager deviceManager)
|
||||
{
|
||||
private readonly IDeviceManager _deviceManager;
|
||||
private readonly ISessionManager _sessionManager;
|
||||
private readonly ILocalizationManager _localizationManager;
|
||||
_sessionManager = sessionManager;
|
||||
_localizationManager = localizationManager;
|
||||
_deviceManager = deviceManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SessionCleanerTask"/> class.
|
||||
/// </summary>
|
||||
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
|
||||
/// <param name="localizationManager">Instance of the <see cref="ILocalizationManager"/> interface.</param>
|
||||
/// <param name="deviceManager">Instance of the <see cref="IDeviceManager"/> interface.</param>
|
||||
public SessionCleanerTask(
|
||||
ISessionManager sessionManager,
|
||||
ILocalizationManager localizationManager,
|
||||
IDeviceManager deviceManager)
|
||||
/// <inheritdoc />
|
||||
public bool IsHidden => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsEnabled => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsLogged => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "Clean Old Sessions";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Key => "CleanOldSessions";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "Removes sessions older then the configured age.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Category => _localizationManager.GetLocalizedString("TasksMaintenanceCategory");
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(SessionCleanerPlugin.Instance?.Configuration);
|
||||
var expireDays = SessionCleanerPlugin.Instance.Configuration.Days;
|
||||
var expireDate = DateTime.UtcNow.AddDays(expireDays * -1);
|
||||
var deviceResult = await _deviceManager.GetDevices(new DeviceQuery())
|
||||
.ConfigureAwait(false);
|
||||
var devices = deviceResult?.Items;
|
||||
|
||||
if (devices is null)
|
||||
{
|
||||
_sessionManager = sessionManager;
|
||||
_localizationManager = localizationManager;
|
||||
_deviceManager = deviceManager;
|
||||
return;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsHidden => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsEnabled => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsLogged => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "Clean Old Sessions";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Key => "CleanOldSessions";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "Removes sessions older then the configured age.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Category => _localizationManager.GetLocalizedString("TasksMaintenanceCategory");
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
|
||||
foreach (var device in devices)
|
||||
{
|
||||
var expireDays = SessionCleanerPlugin.Instance?.Configuration.Days
|
||||
?? throw new Exception("Plugin instance is null");
|
||||
var expireDate = DateTime.UtcNow.AddDays(expireDays * -1);
|
||||
var deviceResult = await _deviceManager.GetDevices(new DeviceQuery())
|
||||
.ConfigureAwait(false);
|
||||
var devices = deviceResult?.Items;
|
||||
|
||||
if (devices is null)
|
||||
if (device.DateLastActivity < expireDate)
|
||||
{
|
||||
return;
|
||||
await _sessionManager.Logout(device).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
foreach (var device in devices)
|
||||
{
|
||||
if (device.DateLastActivity < expireDate)
|
||||
{
|
||||
await _sessionManager.Logout(device).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||
{
|
||||
return Enumerable.Empty<TaskTriggerInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
|
||||
{
|
||||
return Enumerable.Empty<TaskTriggerInfo>();
|
||||
}
|
||||
}
|
||||
|
35
README.md
35
README.md
@ -1,5 +1,34 @@
|
||||
# Jellyfin Session Cleaner Plugin
|
||||
<h1 align="center">Jellyfin Session Cleaner Plugin</h1>
|
||||
<h3 align="center">Part of the <a href="https://jellyfin.media">Jellyfin Project</a></h3>
|
||||
|
||||
## Part of the [Jellyfin Project](https://jellyfin.org)
|
||||
<p align="center">
|
||||
<img alt="Plugin Banner" src="https://raw.githubusercontent.com/jellyfin/jellyfin-ux/master/plugins/SVG/jellyfin-plugin-sessioncleaner.svg?sanitize=true"/>
|
||||
<br/>
|
||||
<br/>
|
||||
<a href="https://github.com/jellyfin/jellyfin-plugin-sessioncleaner/actions?query=workflow%3A%22Test+Build+Plugin%22">
|
||||
<img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/jellyfin/jellyfin-plugin-sessioncleaner/Test%20Build%20Plugin.svg">
|
||||
</a>
|
||||
<a href="https://github.com/jellyfin/jellyfin-plugin-sessioncleaner">
|
||||
<img alt="GPLv3 License" src="https://img.shields.io/github/license/jellyfin/jellyfin-plugin-sessioncleaner.svg"/>
|
||||
</a>
|
||||
<a href="https://github.com/jellyfin/jellyfin-plugin-sessioncleaner/releases">
|
||||
<img alt="Current Release" src="https://img.shields.io/github/release/jellyfin/jellyfin-plugin-sessioncleaner.svg"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
Cleans sessions (devices) older then the configured age.
|
||||
## About
|
||||
|
||||
This plugin allows automatic cleaning of leftover sessions.
|
||||
|
||||
## Installation
|
||||
|
||||
[See the official documentation for install instructions](https://jellyfin.org/docs/general/server/plugins/index.html#installing).
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome all contributions and pull requests! If you have a larger feature in mind please open an issue so we can discuss the implementation before you start.
|
||||
In general refer to our [contributing guidelines](https://github.com/jellyfin/.github/blob/master/CONTRIBUTING.md) for further information.
|
||||
|
||||
## Licence
|
||||
|
||||
This plugins code and packages are distributed under the GPLv3 License. See [LICENSE](./LICENSE) for more information.
|
||||
|
@ -1,25 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RuleSet Name="Rules for Jellyfin.Server" Description="Code analysis rules for Jellyfin.Server.csproj" ToolsVersion="14.0">
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
|
||||
<!-- disable warning SA1202: 'public' members must come before 'private' members -->
|
||||
<Rule Id="SA1202" Action="Info" />
|
||||
<!-- disable warning SA1204: Static members must appear before non-static members -->
|
||||
<Rule Id="SA1204" Action="Info" />
|
||||
<!-- disable warning SA1404: Code analysis suppression should have justification -->
|
||||
<Rule Id="SA1404" Action="Info" />
|
||||
|
||||
<!-- disable warning SA1009: Closing parenthesis should be followed by a space. -->
|
||||
<Rule Id="SA1009" Action="None" />
|
||||
<!-- disable warning SA1011: Closing square bracket should be followed by a space. -->
|
||||
<Rule Id="SA1011" Action="None" />
|
||||
<!-- disable warning SA1101: Prefix local calls with 'this.' -->
|
||||
<Rule Id="SA1101" Action="None" />
|
||||
<!-- disable warning SA1108: Block statements should not contain embedded comments -->
|
||||
<Rule Id="SA1108" Action="None" />
|
||||
<!-- disable warning SA1118: Parameter must not span multiple lines. -->
|
||||
<Rule Id="SA1118" Action="None" />
|
||||
<!-- disable warning SA1128:: Put constructor initializers on their own line -->
|
||||
<Rule Id="SA1128" Action="None" />
|
||||
<!-- disable warning SA1130: Use lambda syntax -->
|
||||
<Rule Id="SA1130" Action="None" />
|
||||
<!-- disable warning SA1200: 'using' directive must appear within a namespace declaration -->
|
||||
<Rule Id="SA1200" Action="None" />
|
||||
<!-- disable warning SA1202: 'public' members must come before 'private' members -->
|
||||
<Rule Id="SA1202" Action="None" />
|
||||
<!-- disable warning SA1204: Static members must appear before non-static members -->
|
||||
<Rule Id="SA1204" Action="None" />
|
||||
<!-- disable warning SA1309: Fields must not begin with an underscore -->
|
||||
<Rule Id="SA1309" Action="None" />
|
||||
<!-- disable warning SA1413: Use trailing comma in multi-line initializers -->
|
||||
@ -30,21 +31,60 @@
|
||||
<Rule Id="SA1515" Action="None" />
|
||||
<!-- disable warning SA1600: Elements should be documented -->
|
||||
<Rule Id="SA1600" Action="None" />
|
||||
<!-- disable warning SA1602: Enumeration items should be documented -->
|
||||
<Rule Id="SA1602" Action="None" />
|
||||
<!-- disable warning SA1633: The file header is missing or not located at the top of the file -->
|
||||
<Rule Id="SA1633" Action="None" />
|
||||
</Rules>
|
||||
|
||||
<Rules AnalyzerId="Microsoft.CodeAnalysis.FxCopAnalyzers" RuleNamespace="Microsoft.Design">
|
||||
<Rules AnalyzerId="Microsoft.CodeAnalysis.NetAnalyzers" RuleNamespace="Microsoft.Design">
|
||||
<!-- error on CA1063: Implement IDisposable correctly -->
|
||||
<Rule Id="CA1063" Action="Error" />
|
||||
<!-- error on CA1305: Specify IFormatProvider -->
|
||||
<Rule Id="CA1305" Action="Error" />
|
||||
<!-- error on CA1307: Specify StringComparison for clarity -->
|
||||
<Rule Id="CA1307" Action="Error" />
|
||||
<!-- error on CA1309: Use ordinal StringComparison -->
|
||||
<Rule Id="CA1309" Action="Error" />
|
||||
<!-- error on CA1725: Parameter names should match base declaration -->
|
||||
<Rule Id="CA1725" Action="Error" />
|
||||
<!-- error on CA1725: Call async methods when in an async method -->
|
||||
<Rule Id="CA1727" Action="Error" />
|
||||
<!-- error on CA1813: Avoid unsealed attributes -->
|
||||
<Rule Id="CA1813" Action="Error" />
|
||||
<!-- error on CA1843: Do not use 'WaitAll' with a single task -->
|
||||
<Rule Id="CA1843" Action="Error" />
|
||||
<!-- error on CA1845: Use span-based 'string.Concat' -->
|
||||
<Rule Id="CA1845" Action="Error" />
|
||||
<!-- error on CA2016: Forward the CancellationToken parameter to methods that take one
|
||||
or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token -->
|
||||
<Rule Id="CA2016" Action="Error" />
|
||||
<!-- error on CA2254: Template should be a static expression -->
|
||||
<Rule Id="CA2254" Action="Error" />
|
||||
|
||||
<!-- disable warning CA1014: Mark assemblies with CLSCompliantAttribute -->
|
||||
<Rule Id="CA1014" Action="Info" />
|
||||
<!-- disable warning CA1024: Use properties where appropriate -->
|
||||
<Rule Id="CA1024" Action="Info" />
|
||||
<!-- disable warning CA1031: Do not catch general exception types -->
|
||||
<Rule Id="CA1031" Action="Info" />
|
||||
<!-- disable warning CA1032: Implement standard exception constructors -->
|
||||
<Rule Id="CA1032" Action="Info" />
|
||||
<!-- disable warning CA1040: Avoid empty interfaces -->
|
||||
<Rule Id="CA1040" Action="Info" />
|
||||
<!-- disable warning CA1062: Validate arguments of public methods -->
|
||||
<Rule Id="CA1062" Action="Info" />
|
||||
<!-- TODO: enable when false positives are fixed -->
|
||||
<!-- disable warning CA1508: Avoid dead conditional code -->
|
||||
<Rule Id="CA1508" Action="Info" />
|
||||
<!-- disable warning CA1716: Identifiers should not match keywords -->
|
||||
<Rule Id="CA1716" Action="Info" />
|
||||
<!-- disable warning CA1720: Identifiers should not contain type names -->
|
||||
<Rule Id="CA1720" Action="Info" />
|
||||
<!-- disable warning CA1724: Type names should not match namespaces -->
|
||||
<Rule Id="CA1724" Action="Info" />
|
||||
<!-- disable warning CA1805: Do not initialize unnecessarily -->
|
||||
<Rule Id="CA1805" Action="Info" />
|
||||
<!-- disable warning CA1812: internal class that is apparently never instantiated.
|
||||
If so, remove the code from the assembly.
|
||||
If this class is intended to contain only static members, make it static -->
|
||||
@ -53,6 +93,10 @@
|
||||
<Rule Id="CA1822" Action="Info" />
|
||||
<!-- disable warning CA2000: Dispose objects before losing scope -->
|
||||
<Rule Id="CA2000" Action="Info" />
|
||||
<!-- disable warning CA2253: Named placeholders should not be numeric values -->
|
||||
<Rule Id="CA2253" Action="Info" />
|
||||
<!-- disable warning CA5394: Do not use insecure randomness -->
|
||||
<Rule Id="CA5394" Action="Info" />
|
||||
|
||||
<!-- disable warning CA1054: Change the type of parameter url from string to System.Uri -->
|
||||
<Rule Id="CA1054" Action="None" />
|
||||
@ -64,5 +108,11 @@
|
||||
<Rule Id="CA1303" Action="None" />
|
||||
<!-- disable warning CA1308: Normalize strings to uppercase -->
|
||||
<Rule Id="CA1308" Action="None" />
|
||||
<!-- disable warning CA1848: Use the LoggerMessage delegates -->
|
||||
<Rule Id="CA1848" Action="None" />
|
||||
<!-- disable warning CA2101: Specify marshaling for P/Invoke string arguments -->
|
||||
<Rule Id="CA2101" Action="None" />
|
||||
<!-- disable warning CA2234: Pass System.Uri objects instead of strings -->
|
||||
<Rule Id="CA2234" Action="None" />
|
||||
</Rules>
|
||||
</RuleSet>
|
||||
|
Loading…
Reference in New Issue
Block a user