init
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
using MediaBrowser.Model.Plugins;
|
||||
|
||||
namespace Jellyfin.Plugin.RedditComments.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Plugin configuration.
|
||||
/// </summary>
|
||||
public class PluginConfiguration : BasePluginConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PluginConfiguration"/> class.
|
||||
/// </summary>
|
||||
public PluginConfiguration()
|
||||
{
|
||||
RedditClientId = string.Empty;
|
||||
RedditClientSecret = string.Empty;
|
||||
RedditUserAgent = "linux:jellyfin-plugin-reddit-comments:v1.0.0 (by /u/unknown)";
|
||||
Subreddits = "anime";
|
||||
CacheDays = 30;
|
||||
NotFoundCacheHours = 24;
|
||||
MaxRequestsPerMinute = 60;
|
||||
MaxComments = 150;
|
||||
CommentDepth = 8;
|
||||
MinScore = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Reddit app client id (create a "script" app at https://www.reddit.com/prefs/apps).
|
||||
/// </summary>
|
||||
public string RedditClientId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Reddit app client secret.
|
||||
/// </summary>
|
||||
public string RedditClientSecret { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the User-Agent sent to Reddit. Reddit requires a unique, descriptive value.
|
||||
/// </summary>
|
||||
public string RedditUserAgent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the comma-separated list of subreddits to search, in order (without the r/ prefix).
|
||||
/// </summary>
|
||||
public string Subreddits { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets how many days a found thread is cached before it is fetched again.
|
||||
/// </summary>
|
||||
public int CacheDays { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets how many hours a "no thread found" result is cached.
|
||||
/// </summary>
|
||||
public int NotFoundCacheHours { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum number of Reddit API requests per minute (Reddit's own limit is 100).
|
||||
/// </summary>
|
||||
public int MaxRequestsPerMinute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum number of comments requested from Reddit per thread.
|
||||
/// </summary>
|
||||
public int MaxComments { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum reply depth requested from Reddit.
|
||||
/// </summary>
|
||||
public int CommentDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum score a comment must have to be shown.
|
||||
/// </summary>
|
||||
public int MinScore { get; set; }
|
||||
}
|
||||
168
Jellyfin.Plugin.RedditComments/Configuration/configPage.html
Normal file
168
Jellyfin.Plugin.RedditComments/Configuration/configPage.html
Normal file
@@ -0,0 +1,168 @@
|
||||
<div id="RedditCommentsConfigPage" data-role="page" class="page type-interior pluginConfigurationPage" data-require="emby-input,emby-button">
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<style>
|
||||
#RedditCommentsConfigPage .rc-accent { color: #a55aea; }
|
||||
#RedditCommentsConfigPage .rc-info {
|
||||
border-left: 3px solid #a55aea;
|
||||
background: rgba(165, 90, 234, 0.08);
|
||||
border-radius: 0.4em;
|
||||
padding: 1em 1.2em;
|
||||
margin-bottom: 1.5em;
|
||||
line-height: 1.55;
|
||||
}
|
||||
#RedditCommentsConfigPage .rc-info ol { margin: 0.5em 0 0; padding-left: 1.4em; }
|
||||
#RedditCommentsConfigPage .rc-info code {
|
||||
background: rgba(165, 90, 234, 0.15);
|
||||
border-radius: 0.3em;
|
||||
padding: 0.1em 0.4em;
|
||||
}
|
||||
#RedditCommentsConfigPage .rc-section {
|
||||
font-size: 1.1em;
|
||||
font-weight: 600;
|
||||
margin: 1.6em 0 0.6em;
|
||||
padding-bottom: 0.3em;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
#RedditCommentsConfigPage .rc-test-result { margin-left: 1em; font-weight: 600; }
|
||||
</style>
|
||||
|
||||
<h2 style="margin-top:0;">Reddit Comments <span class="rc-accent" id="rcVersion"></span></h2>
|
||||
|
||||
<div class="rc-info">
|
||||
<strong>Reddit API setup (one time):</strong>
|
||||
<ol>
|
||||
<li>Go to <a href="https://www.reddit.com/prefs/apps" target="_blank" rel="noopener" class="rc-accent">reddit.com/prefs/apps</a> and click <em>create app</em>.</li>
|
||||
<li>Choose type <code>script</code>, any name, and <code>http://localhost</code> as the redirect uri.</li>
|
||||
<li>Copy the <strong>client id</strong> (under the app name) and the <strong>secret</strong> into the fields below.</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<form id="RedditCommentsConfigForm">
|
||||
<div class="rc-section rc-accent">Reddit API</div>
|
||||
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="RedditClientId">Client ID</label>
|
||||
<input is="emby-input" type="text" id="RedditClientId" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="RedditClientSecret">Client Secret</label>
|
||||
<input is="emby-input" type="password" id="RedditClientSecret" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="RedditUserAgent">User Agent</label>
|
||||
<input is="emby-input" type="text" id="RedditUserAgent" />
|
||||
<div class="fieldDescription">Reddit requires a unique, descriptive user agent, e.g. <code>linux:jellyfin-reddit-comments:v1.0 (by /u/yourname)</code>.</div>
|
||||
</div>
|
||||
<button is="emby-button" type="button" id="rcTestButton" class="raised button-block">
|
||||
<span>Test connection</span>
|
||||
</button>
|
||||
<span id="rcTestResult" class="rc-test-result"></span>
|
||||
|
||||
<div class="rc-section rc-accent">Search</div>
|
||||
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="Subreddits">Subreddits</label>
|
||||
<input is="emby-input" type="text" id="Subreddits" />
|
||||
<div class="fieldDescription">Comma-separated, without the r/ prefix. Searched in order. Default: <code>anime</code></div>
|
||||
</div>
|
||||
|
||||
<div class="rc-section rc-accent">Caching & rate limits</div>
|
||||
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="CacheDays">Cache found threads for (days)</label>
|
||||
<input is="emby-input" type="number" id="CacheDays" min="1" max="365" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="NotFoundCacheHours">Cache "not found" results for (hours)</label>
|
||||
<input is="emby-input" type="number" id="NotFoundCacheHours" min="1" max="720" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="MaxRequestsPerMinute">Max Reddit requests per minute</label>
|
||||
<input is="emby-input" type="number" id="MaxRequestsPerMinute" min="1" max="100" />
|
||||
<div class="fieldDescription">Hard cap enforced by the plugin. Reddit's own limit is 100/min; 60 is a safe default.</div>
|
||||
</div>
|
||||
|
||||
<div class="rc-section rc-accent">Comments</div>
|
||||
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="MaxComments">Max comments per thread</label>
|
||||
<input is="emby-input" type="number" id="MaxComments" min="1" max="500" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="CommentDepth">Max reply depth</label>
|
||||
<input is="emby-input" type="number" id="CommentDepth" min="1" max="10" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="MinScore">Minimum comment score</label>
|
||||
<input is="emby-input" type="number" id="MinScore" min="-100" max="1000" />
|
||||
<div class="fieldDescription">Comments below this score are hidden. 1 filters out downvoted comments.</div>
|
||||
</div>
|
||||
|
||||
<button is="emby-button" type="submit" class="raised button-submit block">
|
||||
<span>Save</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
var pluginId = '7b2f1c4e-9a3d-4f6b-8c5e-2d1a0f9e7b6c';
|
||||
var page = document.querySelector('#RedditCommentsConfigPage');
|
||||
|
||||
page.addEventListener('pageshow', function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
ApiClient.getPluginConfiguration(pluginId).then(function (config) {
|
||||
page.querySelector('#RedditClientId').value = config.RedditClientId || '';
|
||||
page.querySelector('#RedditClientSecret').value = config.RedditClientSecret || '';
|
||||
page.querySelector('#RedditUserAgent').value = config.RedditUserAgent || '';
|
||||
page.querySelector('#Subreddits').value = config.Subreddits || 'anime';
|
||||
page.querySelector('#CacheDays').value = config.CacheDays;
|
||||
page.querySelector('#NotFoundCacheHours').value = config.NotFoundCacheHours;
|
||||
page.querySelector('#MaxRequestsPerMinute').value = config.MaxRequestsPerMinute;
|
||||
page.querySelector('#MaxComments').value = config.MaxComments;
|
||||
page.querySelector('#CommentDepth').value = config.CommentDepth;
|
||||
page.querySelector('#MinScore').value = config.MinScore;
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
});
|
||||
|
||||
page.querySelector('#rcTestButton').addEventListener('click', function () {
|
||||
var result = page.querySelector('#rcTestResult');
|
||||
result.textContent = 'Testing...';
|
||||
result.style.color = '#aaa';
|
||||
ApiClient.getJSON(ApiClient.getUrl('RedditComments/Test')).then(function (response) {
|
||||
result.textContent = response.message;
|
||||
result.style.color = response.ok ? '#a55aea' : '#e57373';
|
||||
}).catch(function (err) {
|
||||
result.textContent = 'Test failed: ' + (err && err.message ? err.message : 'unknown error');
|
||||
result.style.color = '#e57373';
|
||||
});
|
||||
});
|
||||
|
||||
page.querySelector('#RedditCommentsConfigForm').addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
Dashboard.showLoadingMsg();
|
||||
ApiClient.getPluginConfiguration(pluginId).then(function (config) {
|
||||
config.RedditClientId = page.querySelector('#RedditClientId').value.trim();
|
||||
config.RedditClientSecret = page.querySelector('#RedditClientSecret').value.trim();
|
||||
config.RedditUserAgent = page.querySelector('#RedditUserAgent').value.trim();
|
||||
config.Subreddits = page.querySelector('#Subreddits').value.trim();
|
||||
config.CacheDays = parseInt(page.querySelector('#CacheDays').value, 10) || 30;
|
||||
config.NotFoundCacheHours = parseInt(page.querySelector('#NotFoundCacheHours').value, 10) || 24;
|
||||
config.MaxRequestsPerMinute = parseInt(page.querySelector('#MaxRequestsPerMinute').value, 10) || 60;
|
||||
config.MaxComments = parseInt(page.querySelector('#MaxComments').value, 10) || 150;
|
||||
config.CommentDepth = parseInt(page.querySelector('#CommentDepth').value, 10) || 8;
|
||||
config.MinScore = parseInt(page.querySelector('#MinScore').value, 10);
|
||||
if (isNaN(config.MinScore)) { config.MinScore = 1; }
|
||||
|
||||
ApiClient.updatePluginConfiguration(pluginId, config).then(function (result) {
|
||||
Dashboard.processPluginConfigurationUpdateResult(result);
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
Reference in New Issue
Block a user