Skip to content

Commit

Permalink
Move M3U8 sync settings into Options
Browse files Browse the repository at this point in the history
  • Loading branch information
electroly committed Nov 24, 2024
1 parent 3cff5c1 commit ad96f33
Show file tree
Hide file tree
Showing 11 changed files with 279 additions and 227 deletions.
21 changes: 18 additions & 3 deletions src/J.App/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@

namespace J.App;

public sealed class Client(IHttpClientFactory httpClientFactory, AccountSettingsProvider accountSettingsProvider)
: IDisposable
public sealed class Client(
IHttpClientFactory httpClientFactory,
AccountSettingsProvider accountSettingsProvider,

Check warning on line 13 in src/J.App/Client.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'accountSettingsProvider' is unread.

Check warning on line 13 in src/J.App/Client.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'accountSettingsProvider' is unread.
Preferences preferences
) : IDisposable
{
private readonly HttpClient _httpClient = httpClientFactory.CreateClient(typeof(Client).FullName!);

Expand Down Expand Up @@ -39,7 +42,10 @@ public void Start()
};

Port = FindRandomUnusedPort();
var bindHost = accountSettingsProvider.Current.EnableLocalM3u8Folder ? "*" : "localhost";

var m3u8Settings = preferences.GetJson<M3u8SyncSettings>(Preferences.Key.M3u8FolderSync_Settings);

var bindHost = m3u8Settings.EnableLocalM3u8Folder ? "*" : "localhost";
psi.Environment["ASPNETCORE_URLS"] = $"http://{bindHost}:{Port}";
psi.Environment["JACKPOT_SESSION_PASSWORD"] = SessionPassword;

Expand All @@ -66,6 +72,15 @@ public void Stop()
}
}

public void Restart()
{
lock (_lock)
{
Stop();
Start();
}
}

public string GetMovieM3u8Url(Movie movie)
{
var query = HttpUtility.ParseQueryString("");
Expand Down
3 changes: 0 additions & 3 deletions src/J.App/LibraryProviderAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ public async Task DeleteTagAsync(TagId id, Action<double> updateProgress, Cancel

public byte[] GetMovieClip(MovieId movieId) => libraryProvider.GetMovieClip(movieId);

public byte[] GetM3u8(MovieId movieId, int portNumber, string sessionPassword) =>
libraryProvider.GetM3u8(movieId, portNumber, sessionPassword);

public async Task NewTagTypeAsync(TagType tagType, Action<double> updateProgress, CancellationToken cancel)
{
m3U8FolderSync.Invalidate(tagTypes: [tagType.Id]);
Expand Down
306 changes: 123 additions & 183 deletions src/J.App/LoginForm.cs

Large diffs are not rendered by default.

16 changes: 10 additions & 6 deletions src/J.App/M3u8FolderSync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ namespace J.App;
public sealed partial class M3u8FolderSync(
AccountSettingsProvider accountSettingsProvider,

Check warning on line 7 in src/J.App/M3u8FolderSync.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'accountSettingsProvider' is unread.

Check warning on line 7 in src/J.App/M3u8FolderSync.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'accountSettingsProvider' is unread.
LibraryProvider libraryProvider,
Client client
Client client,
Preferences preferences
)
{
private readonly string _filesystemInvalidChars =
Expand All @@ -18,7 +19,8 @@ Client client
private readonly HashSet<MovieId> _invalidatedMovies = [];
private bool _invalidatedAll = true;

public bool Enabled => accountSettingsProvider.Current.EnableLocalM3u8Folder;
public bool Enabled =>
preferences.GetJson<M3u8SyncSettings>(Preferences.Key.M3u8FolderSync_Settings).EnableLocalM3u8Folder;

public void Invalidate(
IEnumerable<TagTypeId>? tagTypes = null,
Expand Down Expand Up @@ -47,8 +49,7 @@ public void Invalidate(

public void InvalidateAll()
{
if (!Enabled)
return;
// Still invalidate even if sync is disabled, so that the next time it's enabled, it will sync everything.

lock (_lock)
{
Expand All @@ -65,7 +66,9 @@ public void Sync(Action<double> updateProgress)
{
var portNumber = client.Port;
var sessionPassword = client.SessionPassword;
var dir = accountSettingsProvider.Current.LocalM3u8FolderPath;
var dir = preferences
.GetJson<M3u8SyncSettings>(Preferences.Key.M3u8FolderSync_Settings)
.LocalM3u8FolderPath;

var movieTags = libraryProvider.GetMovieTags().ToLookup(x => x.TagId, x => x.MovieId);
var movies = libraryProvider.GetMovies().ToDictionary(x => x.Id);
Expand Down Expand Up @@ -240,7 +243,8 @@ bool writeFile

if (writeFile)
{
var bytes = libraryProvider.GetM3u8(movie.Id, portNumber, sessionPassword);
var hostname = preferences.GetJson<M3u8SyncSettings>(Preferences.Key.M3u8FolderSync_Settings).M3u8Hostname;
var bytes = libraryProvider.GetM3u8(movie.Id, portNumber, sessionPassword, hostname);
File.WriteAllBytes(m3u8FilePath, bytes);
}
}
Expand Down
43 changes: 33 additions & 10 deletions src/J.App/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using J.Base;
using J.Core;
using J.Core.Data;
using Microsoft.AspNetCore.Routing.Matching;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
Expand All @@ -23,6 +24,7 @@ public sealed partial class MainForm : Form
private readonly SingleInstanceManager _singleInstanceManager;
private readonly Preferences _preferences;
private readonly MovieExporter _movieExporter;
private readonly M3u8FolderSync _m3U8FolderSync;
private readonly Ui _ui;
private readonly ToolStrip _toolStrip;
private readonly ToolStripDropDownButton _filterButton,
Expand Down Expand Up @@ -75,7 +77,8 @@ public MainForm(
ImportProgressFormFactory importProgressFormFactory,
SingleInstanceManager singleInstanceManager,
Preferences preferences,
MovieExporter movieExporter
MovieExporter movieExporter,
M3u8FolderSync m3U8FolderSync
)
{
_serviceProvider = serviceProvider;
Expand All @@ -85,6 +88,7 @@ MovieExporter movieExporter
_singleInstanceManager = singleInstanceManager;
_preferences = preferences;
_movieExporter = movieExporter;
_m3U8FolderSync = m3U8FolderSync;
Ui ui = new(this);
_ui = ui;

Expand Down Expand Up @@ -654,17 +658,11 @@ private void BrowseBackButton_Click(object? sender, EventArgs e)

private void Browser_NavigationStarting(object? sender, CoreWebView2NavigationStartingEventArgs e)
{
if (!_browser.Visible)
return;

_titleLabel.Text = "Loading...";
}

private void Browser_NavigationCompleted(object? sender, CoreWebView2NavigationCompletedEventArgs e)
{
if (!_browser.Visible)
return;

var title = _browser.CoreWebView2.DocumentTitle;
if (title.Length > 100)
title = title[..100] + "...";
Expand Down Expand Up @@ -1058,13 +1056,38 @@ private void ConvertMoviesButton_Click(object? sender, EventArgs e)

private async void OptionsButton_Click(object? sender, EventArgs e)
{
var oldM3u8Settings = _preferences.GetJson<M3u8SyncSettings>(Preferences.Key.M3u8FolderSync_Settings);

using var f = _serviceProvider.GetRequiredService<OptionsForm>();
if (f.ShowDialog(this) != DialogResult.OK)
return;

ApplyFullscreenPreference();
await _client.RefreshLibraryAsync(CancellationToken.None).ConfigureAwait(true);
_browser.Reload();
try
{
var newM3u8Settings = _preferences.GetJson<M3u8SyncSettings>(Preferences.Key.M3u8FolderSync_Settings);

if (!oldM3u8Settings.Equals(newM3u8Settings))
{
_client.Restart();
_m3U8FolderSync.InvalidateAll();
SimpleProgressForm.Do(
this,
"Synchronizing M3U8 folder...",
(updateProgress, cancel) =>
{
_m3U8FolderSync.Sync(updateProgress);
}
);
}

ApplyFullscreenPreference();
await _client.RefreshLibraryAsync(CancellationToken.None).ConfigureAwait(true);
_browser.Reload();
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

private void ApplyFullscreenPreference()
Expand Down
89 changes: 75 additions & 14 deletions src/J.App/OptionsForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ public sealed class OptionsForm : Form
private readonly Preferences _preferences;
private readonly TableLayoutPanel _table;
private readonly FlowLayoutPanel _buttonFlow,
_generalFlow;
_generalFlow,
_m3u8Flow;
private readonly TabControl _tabControl;
private readonly TabPage _generalTab;
private readonly TabPage _generalTab,
_m3u8Page;
private readonly ComboBox _vlcCombo,
_windowMaximizeBehaviorCombo,
_columnCountCombo;
private readonly Button _okButton,
_cancelButton;
private readonly CheckBox _enableM3u8FolderCheck;
private readonly TextBox _m3u8FolderText,
_m3u8HostnameText;

// VLC installation to use for playback
private readonly List<VlcInstallationToUse> _vlcValues =
Expand Down Expand Up @@ -44,7 +49,7 @@ public OptionsForm(Preferences preferences)
_table.RowStyles[0].SizeType = SizeType.Percent;
_table.RowStyles[0].Height = 100;

_table.Controls.Add(_tabControl = ui.NewTabControl(100), 0, 0);
_table.Controls.Add(_tabControl = ui.NewTabControl(200), 0, 0);
{
_tabControl.TabPages.Add(_generalTab = ui.NewTabPage("General"));
{
Expand Down Expand Up @@ -92,6 +97,44 @@ public OptionsForm(Preferences preferences)
}
}
}

_tabControl.TabPages.Add(_m3u8Page = ui.NewTabPage("Network Sharing"));
{
var m3u8Settings = preferences.GetJson<M3u8SyncSettings>(Preferences.Key.M3u8FolderSync_Settings);

_m3u8Page.Controls.Add(_m3u8Flow = ui.NewFlowColumn());
{
_m3u8Flow.Padding = ui.DefaultPadding;

_m3u8Flow.Controls.Add(
ui.NewLabel(
"Jackpot can maintain a folder of M3U8 files for non-Windows\ndevices to play via Windows file sharing."
)
);

_m3u8Flow.Controls.Add(
_enableM3u8FolderCheck = ui.NewCheckBox("Store M3U8 files in a local folder")
);
{
_enableM3u8FolderCheck.Margin += ui.TopSpacingBig + ui.BottomSpacing;
_enableM3u8FolderCheck.Checked = m3u8Settings.EnableLocalM3u8Folder;
}

Control p;
(p, _m3u8FolderText) = ui.NewLabeledOpenFolderTextBox("Folder:", 400, _ => { });
{
_m3u8Flow.Controls.Add(p);
p.Margin = ui.BottomSpacing;
_m3u8FolderText.Text = m3u8Settings.LocalM3u8FolderPath;
}

(p, _m3u8HostnameText) = ui.NewLabeledTextBox("Host or IP address to use in M3U8 files:", 300);
{
_m3u8Flow.Controls.Add(p);
_m3u8HostnameText.Text = m3u8Settings.M3u8Hostname;
}
}
}
}

_table.Controls.Add(_buttonFlow = ui.NewFlowRow(), 0, 1);
Expand All @@ -111,7 +154,7 @@ public OptionsForm(Preferences preferences)

Text = "Options";
StartPosition = FormStartPosition.CenterScreen;
MinimumSize = Size = ui.GetSize(400, 400);
MinimumSize = Size = ui.GetSize(500, 400);
FormBorderStyle = FormBorderStyle.FixedDialog;
MinimizeBox = false;
MaximizeBox = false;
Expand All @@ -124,16 +167,34 @@ public OptionsForm(Preferences preferences)

private void OkButton_Click(object? sender, EventArgs e)
{
_preferences.WithTransaction(() =>
try
{
if (_enableM3u8FolderCheck.Checked)
{
if (string.IsNullOrWhiteSpace(_m3u8FolderText.Text))
throw new Exception("Please enter a folder for .M3U8 files.");
}

M3u8SyncSettings m3u8SyncSettings =
new(_enableM3u8FolderCheck.Checked, _m3u8FolderText.Text, _m3u8HostnameText.Text);

_preferences.WithTransaction(() =>
{
_preferences.SetEnum(Preferences.Key.Shared_VlcInstallationToUse, _vlcValues[_vlcCombo.SelectedIndex]);
_preferences.SetEnum(
Preferences.Key.MainForm_WindowMaximizeBehavior,
_windowMaximizeBehaviorValues[_windowMaximizeBehaviorCombo.SelectedIndex]
);
_preferences.SetInteger(Preferences.Key.Shared_ColumnCount, _columnCountCombo.SelectedIndex + 1);
_preferences.SetJson(Preferences.Key.M3u8FolderSync_Settings, m3u8SyncSettings);
});

DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_preferences.SetEnum(Preferences.Key.Shared_VlcInstallationToUse, _vlcValues[_vlcCombo.SelectedIndex]);
_preferences.SetEnum(
Preferences.Key.MainForm_WindowMaximizeBehavior,
_windowMaximizeBehaviorValues[_windowMaximizeBehaviorCombo.SelectedIndex]
);
_preferences.SetInteger(Preferences.Key.Shared_ColumnCount, _columnCountCombo.SelectedIndex + 1);
});
DialogResult = DialogResult.OK;
Close();
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
7 changes: 2 additions & 5 deletions src/J.Core/Data/AccountSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ public readonly record struct AccountSettings(
string AccessKeyId,
string SecretAccessKey,
string Bucket,
string PasswordText,
bool EnableLocalM3u8Folder,
string LocalM3u8FolderPath,
string M3u8Hostname
string PasswordText
)
{
public Password Password => new(PasswordText);
Expand All @@ -20,7 +17,7 @@ string M3u8Hostname
&& !string.IsNullOrWhiteSpace(Bucket)
&& !string.IsNullOrWhiteSpace(PasswordText);

public static AccountSettings Empty => new("", "", "", "", "", false, "", "");
public static AccountSettings Empty => new("", "", "", "", "");

public AccountSettings Upgrade()
{
Expand Down
10 changes: 10 additions & 0 deletions src/J.Core/Data/M3u8SyncSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace J.Core.Data;

public readonly record struct M3u8SyncSettings(
bool EnableLocalM3u8Folder,
string LocalM3u8FolderPath,
string M3u8Hostname
)
{
public static M3u8SyncSettings Default => new(false, "", "localhost");
}
3 changes: 1 addition & 2 deletions src/J.Core/LibraryProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -353,9 +353,8 @@ public void DeleteMovie(MovieId id)

public byte[] GetMovieClip(MovieId movieId) => GetMovieFileData(movieId, "clip.mp4");

public byte[] GetM3u8(MovieId movieId, int portNumber, string sessionPassword)
public byte[] GetM3u8(MovieId movieId, int portNumber, string sessionPassword, string hostname)
{
var hostname = _accountSettingsProvider.Current.M3u8Hostname;
if (string.IsNullOrWhiteSpace(hostname))
hostname = "localhost";

Expand Down
2 changes: 2 additions & 0 deletions src/J.Core/Preferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public enum Key
MainForm_CompleteWindowState,
Shared_LibraryViewStyle,
Shared_ColumnCount,
M3u8FolderSync_Settings,
}

public Preferences()
Expand All @@ -48,6 +49,7 @@ public Preferences()
""",
[Key.Shared_LibraryViewStyle] = LibraryViewStyle.Grid.ToString(),
[Key.Shared_ColumnCount] = 5L,
[Key.M3u8FolderSync_Settings] = JsonSerializer.Serialize(M3u8SyncSettings.Default),
}.ToFrozenDictionary();

// Make sure every default is one of the four supported types.
Expand Down
Loading

0 comments on commit ad96f33

Please sign in to comment.