From 1a0d2376d19df275408d02b47a1c397cb51f83bc Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Fri, 8 Nov 2024 12:11:46 -0500
Subject: [PATCH 01/16] Add support for channel_id, clipper, and clipper_id
filename params
---
TwitchDownloaderCore/Tools/FilenameService.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/TwitchDownloaderCore/Tools/FilenameService.cs b/TwitchDownloaderCore/Tools/FilenameService.cs
index e59cb99e..4ba70011 100644
--- a/TwitchDownloaderCore/Tools/FilenameService.cs
+++ b/TwitchDownloaderCore/Tools/FilenameService.cs
@@ -10,7 +10,8 @@ namespace TwitchDownloaderCore.Tools
{
public static class FilenameService
{
- public static string GetFilename(string template, [AllowNull] string title, [AllowNull] string id, DateTime date, [AllowNull] string channel, TimeSpan trimStart, TimeSpan trimEnd, long viewCount, [AllowNull] string game)
+ public static string GetFilename(string template, [AllowNull] string title, [AllowNull] string id, DateTime date, [AllowNull] string channel, [AllowNull] string channelId, TimeSpan trimStart, TimeSpan trimEnd, long viewCount,
+ [AllowNull] string game, [AllowNull] string clipper = null, [AllowNull] string clipperId = null)
{
var videoLength = trimEnd - trimStart;
@@ -18,6 +19,9 @@ public static string GetFilename(string template, [AllowNull] string title, [All
.Replace("{title}", ReplaceInvalidFilenameChars(title))
.Replace("{id}", ReplaceInvalidFilenameChars(id))
.Replace("{channel}", ReplaceInvalidFilenameChars(channel))
+ .Replace("{channel_id}", ReplaceInvalidFilenameChars(channelId))
+ .Replace("{clipper}", ReplaceInvalidFilenameChars(clipper))
+ .Replace("{clipper_id}", ReplaceInvalidFilenameChars(clipperId))
.Replace("{date}", date.ToString("M-d-yy"))
.Replace("{random_string}", Path.GetRandomFileName().Remove(8)) // Remove the period
.Replace("{trim_start}", TimeSpanHFormat.ReusableInstance.Format(@"HH\-mm\-ss", trimStart))
From ad4000209e082022c446d03b38bff5a88e8cfeb4 Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Fri, 8 Nov 2024 12:12:28 -0500
Subject: [PATCH 02/16] Update tests
---
.../ToolTests/FilenameServiceTests.cs | 67 ++++++++++---------
1 file changed, 37 insertions(+), 30 deletions(-)
diff --git a/TwitchDownloaderCore.Tests/ToolTests/FilenameServiceTests.cs b/TwitchDownloaderCore.Tests/ToolTests/FilenameServiceTests.cs
index 2a6a02cc..8765975b 100644
--- a/TwitchDownloaderCore.Tests/ToolTests/FilenameServiceTests.cs
+++ b/TwitchDownloaderCore.Tests/ToolTests/FilenameServiceTests.cs
@@ -4,28 +4,31 @@ namespace TwitchDownloaderCore.Tests.ToolTests
{
public class FilenameServiceTests
{
- private static (string title, string id, DateTime date, string channel, TimeSpan trimStart, TimeSpan trimEnd, int viewCount, string game) GetExampleInfo() =>
- ("A Title", "abc123", new DateTime(1984, 11, 1, 9, 43, 21), "streamer8", new TimeSpan(0, 1, 2, 3, 4), new TimeSpan(0, 5, 6, 7, 8), 123456789, "A Game");
+ private static (string title, string id, DateTime date, string channel, string channelId, TimeSpan trimStart, TimeSpan trimEnd, int viewCount, string game, string clipper, string clipperId) GetExampleInfo() =>
+ ("A Title", "abc123", new DateTime(1984, 11, 1, 9, 43, 21), "streamer8", "123456789", new TimeSpan(0, 1, 2, 3, 4), new TimeSpan(0, 5, 6, 7, 8), 123456789, "A Game", "viewer8", "987654321");
[Theory]
[InlineData("{title}", "A Title")]
[InlineData("{id}", "abc123")]
[InlineData("{channel}", "streamer8")]
+ [InlineData("{channel_id}", "123456789")]
[InlineData("{date}", "11-1-84")]
[InlineData("{trim_start}", "01-02-03")]
[InlineData("{trim_end}", "05-06-07")]
[InlineData("{length}", "04-04-04")]
[InlineData("{views}", "123456789")]
[InlineData("{game}", "A Game")]
+ [InlineData("{clipper}", "viewer8")]
+ [InlineData("{clipper_id}", "987654321")]
[InlineData("{date_custom=\"s\"}", "1984-11-01T09_43_21")]
[InlineData("{trim_start_custom=\"hh\\-mm\\-ss\"}", "01-02-03")]
[InlineData("{trim_end_custom=\"hh\\-mm\\-ss\"}", "05-06-07")]
[InlineData("{length_custom=\"hh\\-mm\\-ss\"}", "04-04-04")]
public void CorrectlyGeneratesIndividualTemplates(string template, string expected)
{
- var (title, id, date, channel, trimStart, trimEnd, viewCount, game) = GetExampleInfo();
+ var (title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId) = GetExampleInfo();
- var result = FilenameService.GetFilename(template, title, id, date, channel, trimStart, trimEnd, viewCount, game);
+ var result = FilenameService.GetFilename(template, title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId);
Assert.Equal(expected, result);
}
@@ -36,9 +39,9 @@ public void CorrectlyGeneratesIndividualTemplates(string template, string expect
[InlineData("{title} by {channel} playing {game} on {date_custom=\"M dd, yyyy\"} for {length_custom=\"h'h 'm'm 's's'\"} with {views} views", "A Title by streamer8 playing A Game on 11 01, 1984 for 4h 4m 4s with 123456789 views")]
public void CorrectlyGeneratesLargeTemplates(string template, string expected)
{
- var (title, id, date, channel, trimStart, trimEnd, viewCount, game) = GetExampleInfo();
+ var (title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId) = GetExampleInfo();
- var result = FilenameService.GetFilename(template, title, id, date, channel, trimStart, trimEnd, viewCount, game);
+ var result = FilenameService.GetFilename(template, title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId);
Assert.Equal(expected, result);
}
@@ -48,9 +51,9 @@ public void CorrectlyInterpretsMultipleCustomParameters()
{
const string TEMPLATE = "{date_custom=\"yyyy\"} {date_custom=\"MM\"} {date_custom=\"dd\"} {trim_start_custom=\"hh\\-mm\\-ss\"} {trim_end_custom=\"hh\\-mm\\-ss\"} {length_custom=\"hh\\-mm\\-ss\"}";
const string EXPECTED = "1984 11 01 01-02-03 05-06-07 04-04-04";
- var (title, id, date, channel, trimStart, trimEnd, viewCount, game) = GetExampleInfo();
+ var (title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId) = GetExampleInfo();
- var result = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, trimStart, trimEnd, viewCount, game);
+ var result = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId);
Assert.Equal(EXPECTED, result);
}
@@ -60,9 +63,9 @@ public void CorrectlyGeneratesSubFolders_WithForwardSlash()
{
const string TEMPLATE = "{channel}/{date_custom=\"yyyy\"}/{date_custom=\"MM\"}/{date_custom=\"dd\"}/{title}.mp4";
var expected = Path.Combine("streamer8", "1984", "11", "01", "A Title.mp4");
- var (title, id, date, channel, trimStart, trimEnd, viewCount, game) = GetExampleInfo();
+ var (title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId) = GetExampleInfo();
- var result = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, trimStart, trimEnd, viewCount, game);
+ var result = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId);
Assert.Equal(expected, result);
}
@@ -72,25 +75,29 @@ public void CorrectlyGeneratesSubFolders_WithBackSlash()
{
const string TEMPLATE = "{channel}\\{date_custom=\"yyyy\"}\\{date_custom=\"MM\"}\\{date_custom=\"dd\"}\\{title}";
var expected = Path.Combine("streamer8", "1984", "11", "01", "A Title");
- var (title, id, date, channel, trimStart, trimEnd, viewCount, game) = GetExampleInfo();
+ var (title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId) = GetExampleInfo();
- var result = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, trimStart, trimEnd, viewCount, game);
+ var result = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId);
Assert.Equal(expected, result);
}
[Theory]
- [InlineData("{title}", ""*:<>?|/\")]
- [InlineData("{id}", ""*:<>?|/\")]
- [InlineData("{channel}", ""*:<>?|/\")]
- [InlineData("{game}", ""*:<>?|/\")]
- public void CorrectlyReplacesInvalidCharactersForNonCustomTemplates(string template, string expected)
+ [InlineData("{title}")]
+ [InlineData("{id}")]
+ [InlineData("{channel}")]
+ [InlineData("{channel_id}")]
+ [InlineData("{clipper}")]
+ [InlineData("{clipper_id}")]
+ [InlineData("{game}")]
+ public void CorrectlyReplacesInvalidCharactersForNonCustomTemplates(string template)
{
const string INVALID_CHARS = "\"*:<>?|/\\";
+ const string EXPECTED = ""*:<>?|/\";
- var result = FilenameService.GetFilename(template, INVALID_CHARS, INVALID_CHARS, default, INVALID_CHARS, default, default, default, INVALID_CHARS);
+ var result = FilenameService.GetFilename(template, INVALID_CHARS, INVALID_CHARS, default, INVALID_CHARS, INVALID_CHARS, default, default, default, INVALID_CHARS, INVALID_CHARS, INVALID_CHARS);
- Assert.Equal(expected, result);
+ Assert.Equal(EXPECTED, result);
}
[Theory]
@@ -104,7 +111,7 @@ public void CorrectlyReplacesInvalidCharactersForCustomTemplates(string template
const string INVALID_CHARS = "\"*:<>?|/\\\\";
var template = templateStart + INVALID_CHARS + "'\"}";
- var result = FilenameService.GetFilename(template, INVALID_CHARS, INVALID_CHARS, default, INVALID_CHARS, default, default, default, INVALID_CHARS);
+ var result = FilenameService.GetFilename(template, INVALID_CHARS, INVALID_CHARS, default, INVALID_CHARS, INVALID_CHARS, default, default, default, INVALID_CHARS, INVALID_CHARS, INVALID_CHARS);
Assert.Equal(EXPECTED, result);
}
@@ -116,9 +123,9 @@ public void CorrectlyReplacesInvalidCharactersForSubFolders()
const string FULL_WIDTH_CHARS = ""*:<>?|";
const string TEMPLATE = INVALID_CHARS + "\\{title}";
var expected = Path.Combine(FULL_WIDTH_CHARS, "A Title");
- var (title, id, date, channel, trimStart, trimEnd, viewCount, game) = GetExampleInfo();
+ var (title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId) = GetExampleInfo();
- var result = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, trimStart, trimEnd, viewCount, game);
+ var result = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId);
Assert.Equal(expected, result);
}
@@ -127,10 +134,10 @@ public void CorrectlyReplacesInvalidCharactersForSubFolders()
public void RandomStringIsRandom()
{
const string TEMPLATE = "{random_string}";
- var (title, id, date, channel, trimStart, trimEnd, viewCount, game) = GetExampleInfo();
+ var (title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId) = GetExampleInfo();
- var result = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, trimStart, trimEnd, viewCount, game);
- var result2 = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, trimStart, trimEnd, viewCount, game);
+ var result = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId);
+ var result2 = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId);
Assert.NotEqual(result, result2);
}
@@ -140,9 +147,9 @@ public void DoesNotInterpretBogusTemplateParameter()
{
const string TEMPLATE = "{foobar}";
const string EXPECTED = "{foobar}";
- var (title, id, date, channel, trimStart, trimEnd, viewCount, game) = GetExampleInfo();
+ var (title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId) = GetExampleInfo();
- var result = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, trimStart, trimEnd, viewCount, game);
+ var result = FilenameService.GetFilename(TEMPLATE, title, id, date, channel, channelId, trimStart, trimEnd, viewCount, game, clipper, clipperId);
Assert.Equal(EXPECTED, result);
}
@@ -150,10 +157,10 @@ public void DoesNotInterpretBogusTemplateParameter()
[Fact]
public void GetFilenameDoesNotThrow_WhenNullOrDefaultInput()
{
- const string TEMPLATE = "{title}_{id}_{date}_{channel}_{trim_start}_{trim_end}_{length}_{views}_{game}_{date_custom=\"s\"}_{trim_start_custom=\"hh\\-mm\\-ss\"}_{trim_end_custom=\"hh\\-mm\\-ss\"}_{length_custom=\"hh\\-mm\\-ss\"}";
- const string EXPECTED = "__1-1-01__00-00-00_00-00-00_00-00-00_0__0001-01-01T00_00_00_00-00-00_00-00-00_00-00-00";
+ const string TEMPLATE = "{title}_{id}_{date}_{channel}_{channel_id}_{trim_start}_{trim_end}_{length}_{views}_{game}_{clipper}_{clipper_id}_{date_custom=\"s\"}_{trim_start_custom=\"hh\\-mm\\-ss\"}_{trim_end_custom=\"hh\\-mm\\-ss\"}_{length_custom=\"hh\\-mm\\-ss\"}";
+ const string EXPECTED = "__1-1-01___00-00-00_00-00-00_00-00-00_0____0001-01-01T00_00_00_00-00-00_00-00-00_00-00-00";
- var result = FilenameService.GetFilename(TEMPLATE, default, default, default, default, default, default, default, default);
+ var result = FilenameService.GetFilename(TEMPLATE, default, default, default, default, default, default, default, default, default, default, default);
Assert.Equal(EXPECTED, result);
}
From 8cb8cbe2e7f3749dc4f1b93788b646def808d12c Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Fri, 8 Nov 2024 12:14:15 -0500
Subject: [PATCH 03/16] Implement new filename params support in GUI
---
TwitchDownloaderWPF/PageChatDownload.xaml.cs | 16 ++++++++++-----
TwitchDownloaderWPF/PageChatUpdate.xaml.cs | 4 +++-
TwitchDownloaderWPF/PageClipDownload.xaml.cs | 9 ++++++++-
TwitchDownloaderWPF/PageVodDownload.xaml.cs | 6 ++++--
TwitchDownloaderWPF/TwitchTasks/TaskData.cs | 3 +++
.../WindowQueueOptions.xaml.cs | 20 ++++++++++---------
TwitchDownloaderWPF/WindowUrlList.xaml.cs | 4 ++++
7 files changed, 44 insertions(+), 18 deletions(-)
diff --git a/TwitchDownloaderWPF/PageChatDownload.xaml.cs b/TwitchDownloaderWPF/PageChatDownload.xaml.cs
index d0e244fb..adcdaab7 100644
--- a/TwitchDownloaderWPF/PageChatDownload.xaml.cs
+++ b/TwitchDownloaderWPF/PageChatDownload.xaml.cs
@@ -29,7 +29,9 @@ public partial class PageChatDownload : Page
{
public DownloadType downloadType;
public string downloadId;
- public int streamerId;
+ public string streamerId;
+ public string clipper;
+ public string clipperId;
public DateTime currentVideoTime;
public TimeSpan vodLength;
public int viewCount;
@@ -144,7 +146,9 @@ private async Task GetVideoInfo()
var videoTime = videoInfo.data.video.createdAt;
textCreatedAt.Text = Settings.Default.UTCVideoTime ? videoTime.ToString(CultureInfo.CurrentCulture) : videoTime.ToLocalTime().ToString(CultureInfo.CurrentCulture);
currentVideoTime = Settings.Default.UTCVideoTime ? videoTime : videoTime.ToLocalTime();
- streamerId = int.Parse(videoInfo.data.video.owner.id);
+ streamerId = videoInfo.data.video.owner.id;
+ clipper = null;
+ clipperId = null;
viewCount = videoInfo.data.video.viewCount;
game = videoInfo.data.video.game?.displayName ?? Translations.Strings.UnknownGame;
@@ -193,7 +197,9 @@ private async Task GetVideoInfo()
textCreatedAt.Text = Settings.Default.UTCVideoTime ? clipCreatedAt.ToString(CultureInfo.CurrentCulture) : clipCreatedAt.ToLocalTime().ToString(CultureInfo.CurrentCulture);
currentVideoTime = Settings.Default.UTCVideoTime ? clipCreatedAt : clipCreatedAt.ToLocalTime();
textTitle.Text = clipInfo.data.clip.title;
- streamerId = int.Parse(clipInfo.data.clip.broadcaster?.id ?? "-1");
+ streamerId = clipInfo.data.clip.broadcaster?.id;
+ clipper = clipInfo.data.clip.curator.displayName;
+ clipperId = clipInfo.data.clip.curator.id;
labelLength.Text = vodLength.ToString("c");
SetEnabled(true);
@@ -498,10 +504,10 @@ private async void SplitBtnDownload_Click(object sender, RoutedEventArgs e)
var saveFileDialog = new SaveFileDialog
{
- FileName = FilenameService.GetFilename(Settings.Default.TemplateChat, textTitle.Text, downloadId, currentVideoTime, textStreamer.Text,
+ FileName = FilenameService.GetFilename(Settings.Default.TemplateChat, textTitle.Text, downloadId, currentVideoTime, textStreamer.Text, streamerId,
CheckTrimStart.IsChecked == true ? new TimeSpan((int)numStartHour.Value, (int)numStartMinute.Value, (int)numStartSecond.Value) : TimeSpan.Zero,
CheckTrimEnd.IsChecked == true ? new TimeSpan((int)numEndHour.Value, (int)numEndMinute.Value, (int)numEndSecond.Value) : vodLength,
- viewCount, game)
+ viewCount, game, clipper, clipperId)
};
if (radioJson.IsChecked == true)
diff --git a/TwitchDownloaderWPF/PageChatUpdate.xaml.cs b/TwitchDownloaderWPF/PageChatUpdate.xaml.cs
index 19fcecc3..28623a2e 100644
--- a/TwitchDownloaderWPF/PageChatUpdate.xaml.cs
+++ b/TwitchDownloaderWPF/PageChatUpdate.xaml.cs
@@ -31,6 +31,7 @@ public partial class PageChatUpdate : Page
public string InputFile;
public ChatRoot ChatJsonInfo;
public string VideoId;
+ public string StreamerId;
public DateTime VideoCreatedAt;
public TimeSpan VideoLength;
public int ViewCount;
@@ -109,6 +110,7 @@ private async void btnBrowse_Click(object sender, RoutedEventArgs e)
: Translations.Strings.UnknownVideoLength;
VideoId = ChatJsonInfo.video.id ?? ChatJsonInfo.comments.FirstOrDefault()?.content_id ?? "-1";
+ StreamerId = ChatJsonInfo.streamer.id.ToString(CultureInfo.InvariantCulture);
ViewCount = ChatJsonInfo.video.viewCount;
Game = ChatJsonInfo.video.game ?? ChatJsonInfo.video.chapters.FirstOrDefault()?.gameDisplayName ?? Translations.Strings.UnknownGame;
@@ -497,7 +499,7 @@ private async void SplitBtnUpdate_Click(object sender, RoutedEventArgs e)
var saveFileDialog = new SaveFileDialog
{
FileName = FilenameService.GetFilename(Settings.Default.TemplateChat, textTitle.Text,
- ChatJsonInfo.video.id ?? ChatJsonInfo.comments.FirstOrDefault()?.content_id ?? "-1", VideoCreatedAt, textStreamer.Text,
+ ChatJsonInfo.video.id ?? ChatJsonInfo.comments.FirstOrDefault()?.content_id ?? "-1", VideoCreatedAt, textStreamer.Text, StreamerId,
checkStart.IsChecked == true ? new TimeSpan((int)numStartHour.Value, (int)numStartMinute.Value, (int)numStartSecond.Value) : TimeSpan.FromSeconds(double.IsNegative(ChatJsonInfo.video.start) ? 0.0 : ChatJsonInfo.video.start),
checkEnd.IsChecked == true ? new TimeSpan((int)numEndHour.Value, (int)numEndMinute.Value, (int)numEndSecond.Value) : VideoLength,
ViewCount, Game)
diff --git a/TwitchDownloaderWPF/PageClipDownload.xaml.cs b/TwitchDownloaderWPF/PageClipDownload.xaml.cs
index 05a8410d..b48eabd3 100644
--- a/TwitchDownloaderWPF/PageClipDownload.xaml.cs
+++ b/TwitchDownloaderWPF/PageClipDownload.xaml.cs
@@ -26,6 +26,9 @@ namespace TwitchDownloaderWPF
public partial class PageClipDownload : Page
{
public string clipId = "";
+ public string streamerId;
+ public string clipper;
+ public string clipperId;
public DateTime currentVideoTime;
public TimeSpan clipLength;
public int viewCount;
@@ -71,6 +74,9 @@ private async Task GetClipInfo()
clipLength = TimeSpan.FromSeconds(taskClipInfo.Result.data.clip.durationSeconds);
textStreamer.Text = clipData.data.clip.broadcaster?.displayName ?? Translations.Strings.UnknownUser;
+ streamerId = clipData.data.clip.broadcaster?.id;
+ clipper = clipData.data.clip.curator.displayName;
+ clipperId = clipData.data.clip.curator.id;
var clipCreatedAt = clipData.data.clip.createdAt;
textCreatedAt.Text = Settings.Default.UTCVideoTime ? clipCreatedAt.ToString(CultureInfo.CurrentCulture) : clipCreatedAt.ToLocalTime().ToString(CultureInfo.CurrentCulture);
currentVideoTime = Settings.Default.UTCVideoTime ? clipCreatedAt : clipCreatedAt.ToLocalTime();
@@ -201,7 +207,8 @@ private async void SplitBtnDownload_Click(object sender, RoutedEventArgs e)
SaveFileDialog saveFileDialog = new SaveFileDialog
{
Filter = "MP4 Files | *.mp4",
- FileName = FilenameService.GetFilename(Settings.Default.TemplateClip, textTitle.Text, clipId, currentVideoTime, textStreamer.Text, TimeSpan.Zero, clipLength, viewCount, game) + ".mp4"
+ FileName = FilenameService.GetFilename(Settings.Default.TemplateClip, textTitle.Text, clipId, currentVideoTime, textStreamer.Text, streamerId, TimeSpan.Zero, clipLength, viewCount, game, clipper,
+ clipperId) + ".mp4"
};
if (saveFileDialog.ShowDialog() != true)
{
diff --git a/TwitchDownloaderWPF/PageVodDownload.xaml.cs b/TwitchDownloaderWPF/PageVodDownload.xaml.cs
index a2ba8a68..713d7cc6 100644
--- a/TwitchDownloaderWPF/PageVodDownload.xaml.cs
+++ b/TwitchDownloaderWPF/PageVodDownload.xaml.cs
@@ -37,6 +37,7 @@ public partial class PageVodDownload : Page
public TimeSpan vodLength;
public int viewCount;
public string game;
+ public string streamerId;
private CancellationTokenSource _cancellationTokenSource;
public PageVodDownload()
@@ -138,6 +139,7 @@ private async Task GetVideoInfo()
vodLength = TimeSpan.FromSeconds(taskVideoInfo.Result.data.video.lengthSeconds);
textStreamer.Text = taskVideoInfo.Result.data.video.owner.displayName;
+ streamerId = taskVideoInfo.Result.data.video.owner.id;
textTitle.Text = taskVideoInfo.Result.data.video.title;
var videoCreatedAt = taskVideoInfo.Result.data.video.createdAt;
textCreatedAt.Text = Settings.Default.UTCVideoTime ? videoCreatedAt.ToString(CultureInfo.CurrentCulture) : videoCreatedAt.ToLocalTime().ToString(CultureInfo.CurrentCulture);
@@ -203,7 +205,7 @@ public VideoDownloadOptions GetOptions(string filename, string folder)
ThrottleKib = Settings.Default.DownloadThrottleEnabled
? Settings.Default.MaximumBandwidthKib
: -1,
- Filename = filename ?? Path.Combine(folder, FilenameService.GetFilename(Settings.Default.TemplateVod, textTitle.Text, currentVideoId.ToString(), currentVideoTime, textStreamer.Text,
+ Filename = filename ?? Path.Combine(folder, FilenameService.GetFilename(Settings.Default.TemplateVod, textTitle.Text, currentVideoId.ToString(), currentVideoTime, textStreamer.Text, streamerId,
checkStart.IsChecked == true ? new TimeSpan((int)numStartHour.Value, (int)numStartMinute.Value, (int)numStartSecond.Value) : TimeSpan.Zero,
checkEnd.IsChecked == true ? new TimeSpan((int)numEndHour.Value, (int)numEndMinute.Value, (int)numEndSecond.Value) : vodLength,
viewCount, game) + FilenameService.GuessVodFileExtension(comboQuality.Text)),
@@ -422,7 +424,7 @@ private async void SplitBtnDownloader_Click(object sender, RoutedEventArgs e)
SaveFileDialog saveFileDialog = new SaveFileDialog
{
Filter = comboQuality.Text.Contains("Audio", StringComparison.OrdinalIgnoreCase) ? "M4A Files | *.m4a" : "MP4 Files | *.mp4",
- FileName = FilenameService.GetFilename(Settings.Default.TemplateVod, textTitle.Text, currentVideoId.ToString(), currentVideoTime, textStreamer.Text,
+ FileName = FilenameService.GetFilename(Settings.Default.TemplateVod, textTitle.Text, currentVideoId.ToString(), currentVideoTime, textStreamer.Text, streamerId,
checkStart.IsChecked == true ? new TimeSpan((int)numStartHour.Value, (int)numStartMinute.Value, (int)numStartSecond.Value) : TimeSpan.Zero,
checkEnd.IsChecked == true ? new TimeSpan((int)numEndHour.Value, (int)numEndMinute.Value, (int)numEndSecond.Value) : vodLength,
viewCount, game) + FilenameService.GuessVodFileExtension(comboQuality.Text)
diff --git a/TwitchDownloaderWPF/TwitchTasks/TaskData.cs b/TwitchDownloaderWPF/TwitchTasks/TaskData.cs
index 5d2c8872..6e694ee6 100644
--- a/TwitchDownloaderWPF/TwitchTasks/TaskData.cs
+++ b/TwitchDownloaderWPF/TwitchTasks/TaskData.cs
@@ -7,6 +7,9 @@ public class TaskData
{
public string Id { get; set; }
public string Streamer { get; set; }
+ public string StreamerId { get; set; }
+ public string Clipper { get; set; }
+ public string ClipperId { get; set; }
public string Title { get; set; }
public ImageSource Thumbnail { get; set; }
public DateTime Time { get; set; }
diff --git a/TwitchDownloaderWPF/WindowQueueOptions.xaml.cs b/TwitchDownloaderWPF/WindowQueueOptions.xaml.cs
index 54a80b08..09bf749f 100644
--- a/TwitchDownloaderWPF/WindowQueueOptions.xaml.cs
+++ b/TwitchDownloaderWPF/WindowQueueOptions.xaml.cs
@@ -260,8 +260,8 @@ private void btnQueue_Click(object sender, RoutedEventArgs e)
ClipDownloadOptions downloadOptions = new ClipDownloadOptions
{
Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateClip, clipDownloadPage.textTitle.Text, clipDownloadPage.clipId,
- clipDownloadPage.currentVideoTime, clipDownloadPage.textStreamer.Text, TimeSpan.Zero, clipDownloadPage.clipLength,
- clipDownloadPage.viewCount, clipDownloadPage.game) + ".mp4"),
+ clipDownloadPage.currentVideoTime, clipDownloadPage.textStreamer.Text, clipDownloadPage.streamerId, TimeSpan.Zero, clipDownloadPage.clipLength,
+ clipDownloadPage.viewCount, clipDownloadPage.game, clipDownloadPage.clipper, clipDownloadPage.clipId) + ".mp4"),
Id = clipDownloadPage.clipId,
Quality = clipDownloadPage.comboQuality.Text,
ThrottleKib = Settings.Default.DownloadThrottleEnabled
@@ -301,8 +301,8 @@ private void btnQueue_Click(object sender, RoutedEventArgs e)
chatOptions.TimeFormat = TimestampFormat.Relative;
chatOptions.EmbedData = checkEmbed.IsChecked.GetValueOrDefault();
chatOptions.Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateChat, downloadTask.Info.Title, chatOptions.Id,
- clipDownloadPage.currentVideoTime, clipDownloadPage.textStreamer.Text, TimeSpan.Zero, clipDownloadPage.clipLength,
- clipDownloadPage.viewCount, clipDownloadPage.game) + "." + chatOptions.FileExtension);
+ clipDownloadPage.currentVideoTime, clipDownloadPage.textStreamer.Text, clipDownloadPage.streamerId, TimeSpan.Zero, clipDownloadPage.clipLength,
+ clipDownloadPage.viewCount, clipDownloadPage.game, clipDownloadPage.clipper, clipDownloadPage.clipId) + "." + chatOptions.FileExtension);
chatOptions.FileCollisionCallback = HandleFileCollisionCallback;
ChatDownloadTask chatTask = new ChatDownloadTask
@@ -377,6 +377,7 @@ private void btnQueue_Click(object sender, RoutedEventArgs e)
ChatDownloadOptions chatOptions = MainWindow.pageChatDownload.GetOptions(null);
chatOptions.Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateChat, chatDownloadPage.textTitle.Text, chatOptions.Id,chatDownloadPage.currentVideoTime, chatDownloadPage.textStreamer.Text,
+ chatDownloadPage.streamerId,
chatOptions.TrimBeginning ? TimeSpan.FromSeconds(chatOptions.TrimBeginningTime) : TimeSpan.Zero,
chatOptions.TrimEnding ? TimeSpan.FromSeconds(chatOptions.TrimEndingTime) : chatDownloadPage.vodLength,
chatDownloadPage.viewCount, chatDownloadPage.game) + "." + chatOptions.FileExtension);
@@ -449,6 +450,7 @@ private void btnQueue_Click(object sender, RoutedEventArgs e)
ChatUpdateOptions chatOptions = MainWindow.pageChatUpdate.GetOptions(null);
chatOptions.InputFile = chatUpdatePage.InputFile;
chatOptions.OutputFile = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateChat, chatUpdatePage.textTitle.Text, chatUpdatePage.VideoId, chatUpdatePage.VideoCreatedAt, chatUpdatePage.textStreamer.Text,
+ chatUpdatePage.StreamerId,
chatOptions.TrimBeginning ? TimeSpan.FromSeconds(chatOptions.TrimBeginningTime) : TimeSpan.Zero,
chatOptions.TrimEnding ? TimeSpan.FromSeconds(chatOptions.TrimEndingTime) : chatUpdatePage.VideoLength,
chatUpdatePage.ViewCount, chatUpdatePage.Game) + "." + chatOptions.FileExtension);
@@ -574,7 +576,7 @@ private void EnqueueDataList()
: -1,
FileCollisionCallback = HandleFileCollisionCallback,
};
- downloadOptions.Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateVod, taskData.Title, taskData.Id, taskData.Time, taskData.Streamer,
+ downloadOptions.Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateVod, taskData.Title, taskData.Id, taskData.Time, taskData.Streamer, taskData.StreamerId,
downloadOptions.TrimBeginning ? downloadOptions.TrimBeginningTime : TimeSpan.Zero,
downloadOptions.TrimEnding ? downloadOptions.TrimEndingTime : TimeSpan.FromSeconds(taskData.Length),
taskData.Views, taskData.Game) + FilenameService.GuessVodFileExtension(downloadOptions.Quality));
@@ -600,8 +602,8 @@ private void EnqueueDataList()
{
Id = taskData.Id,
Quality = (ComboPreferredQuality.SelectedItem as ComboBoxItem)?.Content as string,
- Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateClip, taskData.Title, taskData.Id, taskData.Time, taskData.Streamer,
- TimeSpan.Zero, TimeSpan.FromSeconds(taskData.Length), taskData.Views, taskData.Game) + ".mp4"),
+ Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateClip, taskData.Title, taskData.Id, taskData.Time, taskData.Streamer, taskData.StreamerId,
+ TimeSpan.Zero, TimeSpan.FromSeconds(taskData.Length), taskData.Views, taskData.Game, taskData.Clipper, taskData.ClipperId) + ".mp4"),
ThrottleKib = Settings.Default.DownloadThrottleEnabled
? Settings.Default.MaximumBandwidthKib
: -1,
@@ -646,10 +648,10 @@ private void EnqueueDataList()
downloadOptions.DownloadFormat = ChatFormat.Html;
else
downloadOptions.DownloadFormat = ChatFormat.Text;
- downloadOptions.Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateChat, taskData.Title, taskData.Id, taskData.Time, taskData.Streamer,
+ downloadOptions.Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateChat, taskData.Title, taskData.Id, taskData.Time, taskData.Streamer, taskData.StreamerId,
downloadOptions.TrimBeginning ? TimeSpan.FromSeconds(downloadOptions.TrimBeginningTime) : TimeSpan.Zero,
downloadOptions.TrimEnding ? TimeSpan.FromSeconds(downloadOptions.TrimEndingTime) : TimeSpan.FromSeconds(taskData.Length),
- taskData.Views, taskData.Game) + "." + downloadOptions.FileExtension);
+ taskData.Views, taskData.Game, taskData.Clipper, taskData.ClipperId) + "." + downloadOptions.FileExtension);
ChatDownloadTask downloadTask = new ChatDownloadTask
{
diff --git a/TwitchDownloaderWPF/WindowUrlList.xaml.cs b/TwitchDownloaderWPF/WindowUrlList.xaml.cs
index 08c5c168..222b2b2a 100644
--- a/TwitchDownloaderWPF/WindowUrlList.xaml.cs
+++ b/TwitchDownloaderWPF/WindowUrlList.xaml.cs
@@ -99,6 +99,7 @@ private async void btnQueue_Click(object sender, RoutedEventArgs e)
Thumbnail = thumbnail,
Title = videoInfo.title,
Streamer = videoInfo.owner.displayName,
+ StreamerId = videoInfo.owner.id,
Time = Settings.Default.UTCVideoTime ? videoInfo.createdAt : videoInfo.createdAt.ToLocalTime(),
Views = videoInfo.viewCount,
Game = videoInfo.game?.displayName ?? Translations.Strings.UnknownGame,
@@ -137,6 +138,9 @@ private async void btnQueue_Click(object sender, RoutedEventArgs e)
Thumbnail = thumbnail,
Title = clipInfo.title,
Streamer = clipInfo.broadcaster?.displayName ?? Translations.Strings.UnknownUser,
+ StreamerId = clipInfo.broadcaster?.id,
+ Clipper = clipInfo.curator.displayName,
+ ClipperId = clipInfo.curator.id,
Time = Settings.Default.UTCVideoTime ? clipInfo.createdAt : clipInfo.createdAt.ToLocalTime(),
Views = clipInfo.viewCount,
Game = clipInfo.game?.displayName ?? Translations.Strings.UnknownGame,
From b2969e36d5eafd0c3e29ca44f5d3ed14f82fa0bf Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Fri, 8 Nov 2024 12:23:59 -0500
Subject: [PATCH 04/16] Add new filename params to settings window & update
translations
---
.../Translations/Strings.Designer.cs | 27 +++++++++++++++++++
.../Translations/Strings.es.resx | 9 +++++++
.../Translations/Strings.fr.resx | 9 +++++++
.../Translations/Strings.it.resx | 9 +++++++
.../Translations/Strings.ja.resx | 9 +++++++
.../Translations/Strings.pl.resx | 9 +++++++
.../Translations/Strings.pt-br.resx | 9 +++++++
TwitchDownloaderWPF/Translations/Strings.resx | 9 +++++++
.../Translations/Strings.ru.resx | 9 +++++++
.../Translations/Strings.tr.resx | 9 +++++++
.../Translations/Strings.uk.resx | 9 +++++++
.../Translations/Strings.zh-cn.resx | 9 +++++++
.../Translations/Strings.zh-tw.resx | 9 +++++++
TwitchDownloaderWPF/WindowSettings.xaml | 9 +++++++
14 files changed, 144 insertions(+)
diff --git a/TwitchDownloaderWPF/Translations/Strings.Designer.cs b/TwitchDownloaderWPF/Translations/Strings.Designer.cs
index 43bb4510..d95785b6 100644
--- a/TwitchDownloaderWPF/Translations/Strings.Designer.cs
+++ b/TwitchDownloaderWPF/Translations/Strings.Designer.cs
@@ -1022,6 +1022,15 @@ public static string FileCollisionBehaviorTooltip {
}
}
+ ///
+ /// Looks up a localized string similar to The ID of the channel which owns the video/clip/chat..
+ ///
+ public static string FilenameParameterChannelIdTooltip {
+ get {
+ return ResourceManager.GetString("FilenameParameterChannelIdTooltip", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to The display name of the channel which owns the video/clip/chat..
///
@@ -1031,6 +1040,24 @@ public static string FilenameParameterChannelTooltip {
}
}
+ ///
+ /// Looks up a localized string similar to The ID of the channel which created the clip, or empty for videos..
+ ///
+ public static string FilenameParameterClipperIdTooltip {
+ get {
+ return ResourceManager.GetString("FilenameParameterClipperIdTooltip", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The display name of the channel which created the clip, or empty for videos..
+ ///
+ public static string FilenameParameterClipperTooltip {
+ get {
+ return ResourceManager.GetString("FilenameParameterClipperTooltip", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to The date that the video/clip was created in a customizable format..
///
diff --git a/TwitchDownloaderWPF/Translations/Strings.es.resx b/TwitchDownloaderWPF/Translations/Strings.es.resx
index d2ee2578..e2270d98 100644
--- a/TwitchDownloaderWPF/Translations/Strings.es.resx
+++ b/TwitchDownloaderWPF/Translations/Strings.es.resx
@@ -1006,4 +1006,13 @@
Cancel
+
+ The ID of the channel which owns the video/clip/chat.
+
+
+ The display name of the channel which created the clip, or empty for videos.
+
+
+ The ID of the channel which created the clip, or empty for videos.
+
diff --git a/TwitchDownloaderWPF/Translations/Strings.fr.resx b/TwitchDownloaderWPF/Translations/Strings.fr.resx
index c12a158f..b0615498 100644
--- a/TwitchDownloaderWPF/Translations/Strings.fr.resx
+++ b/TwitchDownloaderWPF/Translations/Strings.fr.resx
@@ -1005,4 +1005,13 @@
Cancel
+
+ The ID of the channel which owns the video/clip/chat.
+
+
+ The display name of the channel which created the clip, or empty for videos.
+
+
+ The ID of the channel which created the clip, or empty for videos.
+
\ No newline at end of file
diff --git a/TwitchDownloaderWPF/Translations/Strings.it.resx b/TwitchDownloaderWPF/Translations/Strings.it.resx
index fa1db3ff..3cc28b5e 100644
--- a/TwitchDownloaderWPF/Translations/Strings.it.resx
+++ b/TwitchDownloaderWPF/Translations/Strings.it.resx
@@ -1006,4 +1006,13 @@
Cancel
+
+ The ID of the channel which owns the video/clip/chat.
+
+
+ The display name of the channel which created the clip, or empty for videos.
+
+
+ The ID of the channel which created the clip, or empty for videos.
+
diff --git a/TwitchDownloaderWPF/Translations/Strings.ja.resx b/TwitchDownloaderWPF/Translations/Strings.ja.resx
index 34b3998f..d9d4a79c 100644
--- a/TwitchDownloaderWPF/Translations/Strings.ja.resx
+++ b/TwitchDownloaderWPF/Translations/Strings.ja.resx
@@ -1004,4 +1004,13 @@
Cancel
+
+ The ID of the channel which owns the video/clip/chat.
+
+
+ The display name of the channel which created the clip, or empty for videos.
+
+
+ The ID of the channel which created the clip, or empty for videos.
+
\ No newline at end of file
diff --git a/TwitchDownloaderWPF/Translations/Strings.pl.resx b/TwitchDownloaderWPF/Translations/Strings.pl.resx
index 4e806e55..3a505ed0 100644
--- a/TwitchDownloaderWPF/Translations/Strings.pl.resx
+++ b/TwitchDownloaderWPF/Translations/Strings.pl.resx
@@ -1005,4 +1005,13 @@
Cancel
+
+ The ID of the channel which owns the video/clip/chat.
+
+
+ The display name of the channel which created the clip, or empty for videos.
+
+
+ The ID of the channel which created the clip, or empty for videos.
+
\ No newline at end of file
diff --git a/TwitchDownloaderWPF/Translations/Strings.pt-br.resx b/TwitchDownloaderWPF/Translations/Strings.pt-br.resx
index 1b1e1f4c..91b76f4e 100644
--- a/TwitchDownloaderWPF/Translations/Strings.pt-br.resx
+++ b/TwitchDownloaderWPF/Translations/Strings.pt-br.resx
@@ -1008,4 +1008,13 @@
Cancel
+
+ The ID of the channel which owns the video/clip/chat.
+
+
+ The display name of the channel which created the clip, or empty for videos.
+
+
+ The ID of the channel which created the clip, or empty for videos.
+
\ No newline at end of file
diff --git a/TwitchDownloaderWPF/Translations/Strings.resx b/TwitchDownloaderWPF/Translations/Strings.resx
index 9a620884..b4a139ea 100644
--- a/TwitchDownloaderWPF/Translations/Strings.resx
+++ b/TwitchDownloaderWPF/Translations/Strings.resx
@@ -1004,4 +1004,13 @@
Cancel
+
+ The ID of the channel which owns the video/clip/chat.
+
+
+ The display name of the channel which created the clip, or empty for videos.
+
+
+ The ID of the channel which created the clip, or empty for videos.
+
\ No newline at end of file
diff --git a/TwitchDownloaderWPF/Translations/Strings.ru.resx b/TwitchDownloaderWPF/Translations/Strings.ru.resx
index 591d0baf..03c731b9 100644
--- a/TwitchDownloaderWPF/Translations/Strings.ru.resx
+++ b/TwitchDownloaderWPF/Translations/Strings.ru.resx
@@ -1005,4 +1005,13 @@
Cancel
+
+ The ID of the channel which owns the video/clip/chat.
+
+
+ The display name of the channel which created the clip, or empty for videos.
+
+
+ The ID of the channel which created the clip, or empty for videos.
+
\ No newline at end of file
diff --git a/TwitchDownloaderWPF/Translations/Strings.tr.resx b/TwitchDownloaderWPF/Translations/Strings.tr.resx
index 23ea271b..ce385816 100644
--- a/TwitchDownloaderWPF/Translations/Strings.tr.resx
+++ b/TwitchDownloaderWPF/Translations/Strings.tr.resx
@@ -1006,4 +1006,13 @@
Cancel
+
+ The ID of the channel which owns the video/clip/chat.
+
+
+ The display name of the channel which created the clip, or empty for videos.
+
+
+ The ID of the channel which created the clip, or empty for videos.
+
\ No newline at end of file
diff --git a/TwitchDownloaderWPF/Translations/Strings.uk.resx b/TwitchDownloaderWPF/Translations/Strings.uk.resx
index 95df1ada..0070cf7d 100644
--- a/TwitchDownloaderWPF/Translations/Strings.uk.resx
+++ b/TwitchDownloaderWPF/Translations/Strings.uk.resx
@@ -1005,4 +1005,13 @@
Cancel
+
+ The ID of the channel which owns the video/clip/chat.
+
+
+ The display name of the channel which created the clip, or empty for videos.
+
+
+ The ID of the channel which created the clip, or empty for videos.
+
diff --git a/TwitchDownloaderWPF/Translations/Strings.zh-cn.resx b/TwitchDownloaderWPF/Translations/Strings.zh-cn.resx
index 06d5de43..da6882f9 100644
--- a/TwitchDownloaderWPF/Translations/Strings.zh-cn.resx
+++ b/TwitchDownloaderWPF/Translations/Strings.zh-cn.resx
@@ -1007,4 +1007,13 @@
取消
+
+ The ID of the channel which owns the video/clip/chat.
+
+
+ The display name of the channel which created the clip, or empty for videos.
+
+
+ The ID of the channel which created the clip, or empty for videos.
+
diff --git a/TwitchDownloaderWPF/Translations/Strings.zh-tw.resx b/TwitchDownloaderWPF/Translations/Strings.zh-tw.resx
index 766ddbaa..7ea0ae79 100644
--- a/TwitchDownloaderWPF/Translations/Strings.zh-tw.resx
+++ b/TwitchDownloaderWPF/Translations/Strings.zh-tw.resx
@@ -1007,4 +1007,13 @@
取消
+
+ The ID of the channel which owns the video/clip/chat.
+
+
+ The display name of the channel which created the clip, or empty for videos.
+
+
+ The ID of the channel which created the clip, or empty for videos.
+
diff --git a/TwitchDownloaderWPF/WindowSettings.xaml b/TwitchDownloaderWPF/WindowSettings.xaml
index f1341d41..e7a2707d 100644
--- a/TwitchDownloaderWPF/WindowSettings.xaml
+++ b/TwitchDownloaderWPF/WindowSettings.xaml
@@ -136,6 +136,15 @@
{channel}
+
+ {channel_id}
+
+
+ {clipper}
+
+
+ {clipper_id}
+
{random_string}
From 8199b9ae72a72f13fb3e8f54fa1b65ed8d04d316 Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Sun, 10 Nov 2024 09:21:16 -0500
Subject: [PATCH 05/16] Add clipper to ChatRoot
---
TwitchDownloaderCore/ChatDownloader.cs | 5 +++++
TwitchDownloaderCore/ChatUpdater.cs | 6 ++++++
TwitchDownloaderCore/TwitchObjects/ChatRoot.cs | 7 +++++++
3 files changed, 18 insertions(+)
diff --git a/TwitchDownloaderCore/ChatDownloader.cs b/TwitchDownloaderCore/ChatDownloader.cs
index f33ae961..f14527fb 100644
--- a/TwitchDownloaderCore/ChatDownloader.cs
+++ b/TwitchDownloaderCore/ChatDownloader.cs
@@ -372,6 +372,11 @@ private async Task DownloadAsyncImpl(FileInfo outputFileInfo, FileStream outputF
videoId = clipInfoResponse.data.clip.video.id;
chatRoot.streamer.name = clipInfoResponse.data.clip.broadcaster.displayName;
chatRoot.streamer.id = int.Parse(clipInfoResponse.data.clip.broadcaster.id);
+ chatRoot.clipper = new Clipper
+ {
+ name = clipInfoResponse.data.clip.curator.displayName,
+ id = int.Parse(clipInfoResponse.data.clip.curator.id),
+ };
chatRoot.video.title = clipInfoResponse.data.clip.title;
chatRoot.video.created_at = clipInfoResponse.data.clip.createdAt;
chatRoot.video.start = (double)clipInfoResponse.data.clip.videoOffsetSeconds + (downloadOptions.TrimBeginning ? downloadOptions.TrimBeginningTime : 0);
diff --git a/TwitchDownloaderCore/ChatUpdater.cs b/TwitchDownloaderCore/ChatUpdater.cs
index 1edcaa41..64303197 100644
--- a/TwitchDownloaderCore/ChatUpdater.cs
+++ b/TwitchDownloaderCore/ChatUpdater.cs
@@ -174,6 +174,12 @@ private async Task UpdateVideoInfo(int totalSteps, int currentStep, Cancellation
return;
}
+ chatRoot.clipper ??= new Clipper
+ {
+ name = clipInfo.curator.displayName,
+ id = int.Parse(clipInfo.curator.id),
+ };
+
chatRoot.video.title = clipInfo.title;
chatRoot.video.created_at = clipInfo.createdAt;
chatRoot.video.length = clipInfo.durationSeconds;
diff --git a/TwitchDownloaderCore/TwitchObjects/ChatRoot.cs b/TwitchDownloaderCore/TwitchObjects/ChatRoot.cs
index c0604a1e..3494b3f5 100644
--- a/TwitchDownloaderCore/TwitchObjects/ChatRoot.cs
+++ b/TwitchDownloaderCore/TwitchObjects/ChatRoot.cs
@@ -11,6 +11,12 @@ public class Streamer
public int id { get; set; }
}
+ public class Clipper
+ {
+ public string name { get; set; }
+ public int id { get; set; }
+ }
+
[DebuggerDisplay("{display_name}")]
public class Commenter
{
@@ -271,6 +277,7 @@ public class ChatRoot
{
public ChatRootInfo FileInfo { get; set; } = new();
public Streamer streamer { get; set; }
+ public Clipper clipper { get; set; }
public Video video { get; set; }
public List comments { get; set; }
public EmbeddedData embeddedData { get; set; }
From 15f97a3b90f06084c509b1d24720ac979b4dd3e0 Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Sun, 10 Nov 2024 09:26:55 -0500
Subject: [PATCH 06/16] Support clip name params in chat updater page
---
TwitchDownloaderWPF/PageChatUpdate.xaml.cs | 6 +++++-
TwitchDownloaderWPF/PageClipDownload.xaml.cs | 6 +++---
TwitchDownloaderWPF/TwitchTasks/TaskData.cs | 2 +-
TwitchDownloaderWPF/WindowQueueOptions.xaml.cs | 10 +++++-----
TwitchDownloaderWPF/WindowUrlList.xaml.cs | 2 +-
5 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/TwitchDownloaderWPF/PageChatUpdate.xaml.cs b/TwitchDownloaderWPF/PageChatUpdate.xaml.cs
index 28623a2e..f8b682cd 100644
--- a/TwitchDownloaderWPF/PageChatUpdate.xaml.cs
+++ b/TwitchDownloaderWPF/PageChatUpdate.xaml.cs
@@ -32,6 +32,8 @@ public partial class PageChatUpdate : Page
public ChatRoot ChatJsonInfo;
public string VideoId;
public string StreamerId;
+ public string ClipperName;
+ public string ClipperId;
public DateTime VideoCreatedAt;
public TimeSpan VideoLength;
public int ViewCount;
@@ -111,6 +113,8 @@ private async void btnBrowse_Click(object sender, RoutedEventArgs e)
VideoId = ChatJsonInfo.video.id ?? ChatJsonInfo.comments.FirstOrDefault()?.content_id ?? "-1";
StreamerId = ChatJsonInfo.streamer.id.ToString(CultureInfo.InvariantCulture);
+ ClipperName = ChatJsonInfo.clipper?.name;
+ ClipperId = ChatJsonInfo.clipper?.id.ToString(CultureInfo.InvariantCulture);
ViewCount = ChatJsonInfo.video.viewCount;
Game = ChatJsonInfo.video.game ?? ChatJsonInfo.video.chapters.FirstOrDefault()?.gameDisplayName ?? Translations.Strings.UnknownGame;
@@ -502,7 +506,7 @@ private async void SplitBtnUpdate_Click(object sender, RoutedEventArgs e)
ChatJsonInfo.video.id ?? ChatJsonInfo.comments.FirstOrDefault()?.content_id ?? "-1", VideoCreatedAt, textStreamer.Text, StreamerId,
checkStart.IsChecked == true ? new TimeSpan((int)numStartHour.Value, (int)numStartMinute.Value, (int)numStartSecond.Value) : TimeSpan.FromSeconds(double.IsNegative(ChatJsonInfo.video.start) ? 0.0 : ChatJsonInfo.video.start),
checkEnd.IsChecked == true ? new TimeSpan((int)numEndHour.Value, (int)numEndMinute.Value, (int)numEndSecond.Value) : VideoLength,
- ViewCount, Game)
+ ViewCount, Game, ClipperName, ClipperId)
};
if (radioJson.IsChecked == true)
diff --git a/TwitchDownloaderWPF/PageClipDownload.xaml.cs b/TwitchDownloaderWPF/PageClipDownload.xaml.cs
index b48eabd3..0761acc7 100644
--- a/TwitchDownloaderWPF/PageClipDownload.xaml.cs
+++ b/TwitchDownloaderWPF/PageClipDownload.xaml.cs
@@ -27,7 +27,7 @@ public partial class PageClipDownload : Page
{
public string clipId = "";
public string streamerId;
- public string clipper;
+ public string clipperName;
public string clipperId;
public DateTime currentVideoTime;
public TimeSpan clipLength;
@@ -75,7 +75,7 @@ private async Task GetClipInfo()
clipLength = TimeSpan.FromSeconds(taskClipInfo.Result.data.clip.durationSeconds);
textStreamer.Text = clipData.data.clip.broadcaster?.displayName ?? Translations.Strings.UnknownUser;
streamerId = clipData.data.clip.broadcaster?.id;
- clipper = clipData.data.clip.curator.displayName;
+ clipperName = clipData.data.clip.curator.displayName;
clipperId = clipData.data.clip.curator.id;
var clipCreatedAt = clipData.data.clip.createdAt;
textCreatedAt.Text = Settings.Default.UTCVideoTime ? clipCreatedAt.ToString(CultureInfo.CurrentCulture) : clipCreatedAt.ToLocalTime().ToString(CultureInfo.CurrentCulture);
@@ -207,7 +207,7 @@ private async void SplitBtnDownload_Click(object sender, RoutedEventArgs e)
SaveFileDialog saveFileDialog = new SaveFileDialog
{
Filter = "MP4 Files | *.mp4",
- FileName = FilenameService.GetFilename(Settings.Default.TemplateClip, textTitle.Text, clipId, currentVideoTime, textStreamer.Text, streamerId, TimeSpan.Zero, clipLength, viewCount, game, clipper,
+ FileName = FilenameService.GetFilename(Settings.Default.TemplateClip, textTitle.Text, clipId, currentVideoTime, textStreamer.Text, streamerId, TimeSpan.Zero, clipLength, viewCount, game, clipperName,
clipperId) + ".mp4"
};
if (saveFileDialog.ShowDialog() != true)
diff --git a/TwitchDownloaderWPF/TwitchTasks/TaskData.cs b/TwitchDownloaderWPF/TwitchTasks/TaskData.cs
index 6e694ee6..88408ffb 100644
--- a/TwitchDownloaderWPF/TwitchTasks/TaskData.cs
+++ b/TwitchDownloaderWPF/TwitchTasks/TaskData.cs
@@ -8,7 +8,7 @@ public class TaskData
public string Id { get; set; }
public string Streamer { get; set; }
public string StreamerId { get; set; }
- public string Clipper { get; set; }
+ public string ClipperName { get; set; }
public string ClipperId { get; set; }
public string Title { get; set; }
public ImageSource Thumbnail { get; set; }
diff --git a/TwitchDownloaderWPF/WindowQueueOptions.xaml.cs b/TwitchDownloaderWPF/WindowQueueOptions.xaml.cs
index 09bf749f..3fd0ec43 100644
--- a/TwitchDownloaderWPF/WindowQueueOptions.xaml.cs
+++ b/TwitchDownloaderWPF/WindowQueueOptions.xaml.cs
@@ -261,7 +261,7 @@ private void btnQueue_Click(object sender, RoutedEventArgs e)
{
Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateClip, clipDownloadPage.textTitle.Text, clipDownloadPage.clipId,
clipDownloadPage.currentVideoTime, clipDownloadPage.textStreamer.Text, clipDownloadPage.streamerId, TimeSpan.Zero, clipDownloadPage.clipLength,
- clipDownloadPage.viewCount, clipDownloadPage.game, clipDownloadPage.clipper, clipDownloadPage.clipId) + ".mp4"),
+ clipDownloadPage.viewCount, clipDownloadPage.game, clipDownloadPage.clipperName, clipDownloadPage.clipperId) + ".mp4"),
Id = clipDownloadPage.clipId,
Quality = clipDownloadPage.comboQuality.Text,
ThrottleKib = Settings.Default.DownloadThrottleEnabled
@@ -302,7 +302,7 @@ private void btnQueue_Click(object sender, RoutedEventArgs e)
chatOptions.EmbedData = checkEmbed.IsChecked.GetValueOrDefault();
chatOptions.Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateChat, downloadTask.Info.Title, chatOptions.Id,
clipDownloadPage.currentVideoTime, clipDownloadPage.textStreamer.Text, clipDownloadPage.streamerId, TimeSpan.Zero, clipDownloadPage.clipLength,
- clipDownloadPage.viewCount, clipDownloadPage.game, clipDownloadPage.clipper, clipDownloadPage.clipId) + "." + chatOptions.FileExtension);
+ clipDownloadPage.viewCount, clipDownloadPage.game, clipDownloadPage.clipperName, clipDownloadPage.clipId) + "." + chatOptions.FileExtension);
chatOptions.FileCollisionCallback = HandleFileCollisionCallback;
ChatDownloadTask chatTask = new ChatDownloadTask
@@ -453,7 +453,7 @@ private void btnQueue_Click(object sender, RoutedEventArgs e)
chatUpdatePage.StreamerId,
chatOptions.TrimBeginning ? TimeSpan.FromSeconds(chatOptions.TrimBeginningTime) : TimeSpan.Zero,
chatOptions.TrimEnding ? TimeSpan.FromSeconds(chatOptions.TrimEndingTime) : chatUpdatePage.VideoLength,
- chatUpdatePage.ViewCount, chatUpdatePage.Game) + "." + chatOptions.FileExtension);
+ chatUpdatePage.ViewCount, chatUpdatePage.Game, chatUpdatePage.ClipperName, chatUpdatePage.ClipperId) + "." + chatOptions.FileExtension);
chatOptions.FileCollisionCallback = HandleFileCollisionCallback;
ChatUpdateTask chatTask = new ChatUpdateTask
@@ -603,7 +603,7 @@ private void EnqueueDataList()
Id = taskData.Id,
Quality = (ComboPreferredQuality.SelectedItem as ComboBoxItem)?.Content as string,
Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateClip, taskData.Title, taskData.Id, taskData.Time, taskData.Streamer, taskData.StreamerId,
- TimeSpan.Zero, TimeSpan.FromSeconds(taskData.Length), taskData.Views, taskData.Game, taskData.Clipper, taskData.ClipperId) + ".mp4"),
+ TimeSpan.Zero, TimeSpan.FromSeconds(taskData.Length), taskData.Views, taskData.Game, taskData.ClipperName, taskData.ClipperId) + ".mp4"),
ThrottleKib = Settings.Default.DownloadThrottleEnabled
? Settings.Default.MaximumBandwidthKib
: -1,
@@ -651,7 +651,7 @@ private void EnqueueDataList()
downloadOptions.Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateChat, taskData.Title, taskData.Id, taskData.Time, taskData.Streamer, taskData.StreamerId,
downloadOptions.TrimBeginning ? TimeSpan.FromSeconds(downloadOptions.TrimBeginningTime) : TimeSpan.Zero,
downloadOptions.TrimEnding ? TimeSpan.FromSeconds(downloadOptions.TrimEndingTime) : TimeSpan.FromSeconds(taskData.Length),
- taskData.Views, taskData.Game, taskData.Clipper, taskData.ClipperId) + "." + downloadOptions.FileExtension);
+ taskData.Views, taskData.Game, taskData.ClipperName, taskData.ClipperId) + "." + downloadOptions.FileExtension);
ChatDownloadTask downloadTask = new ChatDownloadTask
{
diff --git a/TwitchDownloaderWPF/WindowUrlList.xaml.cs b/TwitchDownloaderWPF/WindowUrlList.xaml.cs
index 222b2b2a..5dfe6977 100644
--- a/TwitchDownloaderWPF/WindowUrlList.xaml.cs
+++ b/TwitchDownloaderWPF/WindowUrlList.xaml.cs
@@ -139,7 +139,7 @@ private async void btnQueue_Click(object sender, RoutedEventArgs e)
Title = clipInfo.title,
Streamer = clipInfo.broadcaster?.displayName ?? Translations.Strings.UnknownUser,
StreamerId = clipInfo.broadcaster?.id,
- Clipper = clipInfo.curator.displayName,
+ ClipperName = clipInfo.curator.displayName,
ClipperId = clipInfo.curator.id,
Time = Settings.Default.UTCVideoTime ? clipInfo.createdAt : clipInfo.createdAt.ToLocalTime(),
Views = clipInfo.viewCount,
From 921506faec30882e2567f2d02cf24a6ffcbda9b6 Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Sun, 10 Nov 2024 09:29:41 -0500
Subject: [PATCH 07/16] Fallback to web request if null
---
TwitchDownloaderWPF/PageChatUpdate.xaml.cs | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/TwitchDownloaderWPF/PageChatUpdate.xaml.cs b/TwitchDownloaderWPF/PageChatUpdate.xaml.cs
index f8b682cd..9bc92d01 100644
--- a/TwitchDownloaderWPF/PageChatUpdate.xaml.cs
+++ b/TwitchDownloaderWPF/PageChatUpdate.xaml.cs
@@ -159,8 +159,8 @@ private async void btnBrowse_Click(object sender, RoutedEventArgs e)
numEndHour.Maximum = 0;
}
- GqlClipResponse videoInfo = await TwitchHelper.GetClipInfo(VideoId);
- if (videoInfo.data.clip.video == null)
+ GqlClipResponse clipInfo = await TwitchHelper.GetClipInfo(VideoId);
+ if (clipInfo.data.clip.video == null)
{
AppendLog(Translations.Strings.ErrorLog + Translations.Strings.UnableToFindThumbnail + ": " + Translations.Strings.VodExpiredOrIdCorrupt);
_ = ThumbnailService.TryGetThumb(ThumbnailService.THUMBNAIL_MISSING_URL, out var image);
@@ -168,12 +168,14 @@ private async void btnBrowse_Click(object sender, RoutedEventArgs e)
}
else
{
- VideoLength = TimeSpan.FromSeconds(videoInfo.data.clip.durationSeconds);
+ VideoLength = TimeSpan.FromSeconds(clipInfo.data.clip.durationSeconds);
labelLength.Text = VideoLength.ToString("c");
- ViewCount = videoInfo.data.clip.viewCount;
- Game = videoInfo.data.clip.game?.displayName;
+ ViewCount = clipInfo.data.clip.viewCount;
+ Game = clipInfo.data.clip.game?.displayName;
+ ClipperName ??= clipInfo.data.clip.curator.displayName;
+ ClipperId ??= clipInfo.data.clip.curator.id;
- var thumbUrl = videoInfo.data.clip.thumbnailURL;
+ var thumbUrl = clipInfo.data.clip.thumbnailURL;
if (!ThumbnailService.TryGetThumb(thumbUrl, out var image))
{
AppendLog(Translations.Strings.ErrorLog + Translations.Strings.UnableToFindThumbnail);
From 079081f662da1e02664b3b421fb6ee2c6f6f003d Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Sun, 10 Nov 2024 10:17:14 -0500
Subject: [PATCH 08/16] Support new filename params in non-url mass downloaders
---
TwitchDownloaderCore/TwitchHelper.cs | 18 +++++++-
.../Gql/GqlClipSearchResponse.cs | 7 +++
.../TwitchObjects/Gql/GqlUserIdResponse.cs | 20 +++++++++
.../TwitchObjects/Gql/GqlUserInfoResponse.cs | 1 +
.../WindowMassDownload.xaml.cs | 43 +++++++++++++++----
5 files changed, 78 insertions(+), 11 deletions(-)
create mode 100644 TwitchDownloaderCore/TwitchObjects/Gql/GqlUserIdResponse.cs
diff --git a/TwitchDownloaderCore/TwitchHelper.cs b/TwitchDownloaderCore/TwitchHelper.cs
index a3816eef..68cdcde9 100644
--- a/TwitchDownloaderCore/TwitchHelper.cs
+++ b/TwitchDownloaderCore/TwitchHelper.cs
@@ -173,7 +173,7 @@ public static async Task GetGqlClips(string channelName,
{
RequestUri = new Uri("https://gql.twitch.tv/gql"),
Method = HttpMethod.Post,
- Content = new StringContent("{\"query\":\"query{user(login:\\\"" + channelName + "\\\"){clips(first: " + limit + (cursor == "" ? "" : ", after: \\\"" + cursor + "\\\"") +", criteria: { period: " + period + " }) { edges { cursor, node { id, slug, title, createdAt, durationSeconds, thumbnailURL, viewCount, game { id, displayName } } }, pageInfo { hasNextPage, hasPreviousPage } }}}\",\"variables\":{}}", Encoding.UTF8, "application/json")
+ Content = new StringContent("{\"query\":\"query{user(login:\\\"" + channelName + "\\\"){clips(first: " + limit + (cursor == "" ? "" : ", after: \\\"" + cursor + "\\\"") +", criteria: { period: " + period + " }) { edges { cursor, node { id, slug, title, createdAt, curator, { id, displayName }, durationSeconds, thumbnailURL, viewCount, game { id, displayName } } }, pageInfo { hasNextPage, hasPreviousPage } }}}\",\"variables\":{}}", Encoding.UTF8, "application/json")
};
request.Headers.Add("Client-ID", "kd1unb4b3q4t58fwlpcbzcbnm76a8fp");
using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
@@ -1033,6 +1033,20 @@ where DateTime.UtcNow.Ticks - directoryInfo.LastWriteTimeUtc.Ticks > TimeSpan.Ti
: $"{wasDeleted} old video caches were deleted, {toDelete.Length - wasDeleted} could not be deleted.");
}
+ public static async Task GetUserIds(IEnumerable nameList)
+ {
+ var request = new HttpRequestMessage()
+ {
+ RequestUri = new Uri("https://gql.twitch.tv/gql"),
+ Method = HttpMethod.Post,
+ Content = new StringContent("{\"query\":\"query{users(logins:[" + string.Join(",", nameList.Select(x => "\\\"" + x + "\\\"").ToArray()) + "]){id}}\",\"variables\":{}}", Encoding.UTF8, "application/json")
+ };
+ request.Headers.Add("Client-ID", "kimne78kx3ncx6brgo4mv6wki5h1ko");
+ using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
+ response.EnsureSuccessStatusCode();
+ return await response.Content.ReadFromJsonAsync();
+ }
+
public static async Task GetStreamerName(int id)
{
try
@@ -1049,7 +1063,7 @@ public static async Task GetUserInfo(IEnumerable id
{
RequestUri = new Uri("https://gql.twitch.tv/gql"),
Method = HttpMethod.Post,
- Content = new StringContent("{\"query\":\"query{users(ids:[" + string.Join(",", idList.Select(x => "\\\"" + x + "\\\"").ToArray()) + "]){id,login,createdAt,updatedAt,description,profileImageURL(width:300)}}\",\"variables\":{}}", Encoding.UTF8, "application/json")
+ Content = new StringContent("{\"query\":\"query{users(ids:[" + string.Join(",", idList.Select(x => "\\\"" + x + "\\\"").ToArray()) + "]){id,displayName,login,createdAt,updatedAt,description,profileImageURL(width:300)}}\",\"variables\":{}}", Encoding.UTF8, "application/json")
};
request.Headers.Add("Client-ID", "kimne78kx3ncx6brgo4mv6wki5h1ko");
using var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
diff --git a/TwitchDownloaderCore/TwitchObjects/Gql/GqlClipSearchResponse.cs b/TwitchDownloaderCore/TwitchObjects/Gql/GqlClipSearchResponse.cs
index d11f5482..0fcac8cb 100644
--- a/TwitchDownloaderCore/TwitchObjects/Gql/GqlClipSearchResponse.cs
+++ b/TwitchDownloaderCore/TwitchObjects/Gql/GqlClipSearchResponse.cs
@@ -9,12 +9,19 @@ public class ClipNodeGame
public string displayName { get; set; }
}
+ public class ClipNodeCurator
+ {
+ public string id { get; set; }
+ public string displayName { get; set; }
+ }
+
public class ClipNode
{
public string id { get; set; }
public string slug { get; set; }
public string title { get; set; }
public DateTime createdAt { get; set; }
+ public ClipNodeCurator curator { get; set; }
public int durationSeconds { get; set; }
public string thumbnailURL { get; set; }
public int viewCount { get; set; }
diff --git a/TwitchDownloaderCore/TwitchObjects/Gql/GqlUserIdResponse.cs b/TwitchDownloaderCore/TwitchObjects/Gql/GqlUserIdResponse.cs
new file mode 100644
index 00000000..ac8e85b6
--- /dev/null
+++ b/TwitchDownloaderCore/TwitchObjects/Gql/GqlUserIdResponse.cs
@@ -0,0 +1,20 @@
+using System.Collections.Generic;
+
+namespace TwitchDownloaderCore.TwitchObjects.Gql
+{
+ public class UserId
+ {
+ public string id { get; set; }
+ }
+
+ public class UserIdData
+ {
+ public List users { get; set; }
+ }
+
+ public class GqlUserIdResponse
+ {
+ public UserIdData data { get; set; }
+ public Extensions extensions { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/TwitchDownloaderCore/TwitchObjects/Gql/GqlUserInfoResponse.cs b/TwitchDownloaderCore/TwitchObjects/Gql/GqlUserInfoResponse.cs
index 2f228c90..c6770d72 100644
--- a/TwitchDownloaderCore/TwitchObjects/Gql/GqlUserInfoResponse.cs
+++ b/TwitchDownloaderCore/TwitchObjects/Gql/GqlUserInfoResponse.cs
@@ -17,6 +17,7 @@ public class GqlUserInfoResponse
public class User
{
public string id { get; set; }
+ public string displayName { get; set; }
public string login { get; set; }
public DateTime createdAt { get; set; }
public DateTime updatedAt { get; set; }
diff --git a/TwitchDownloaderWPF/WindowMassDownload.xaml.cs b/TwitchDownloaderWPF/WindowMassDownload.xaml.cs
index 3e65bce0..75475d59 100644
--- a/TwitchDownloaderWPF/WindowMassDownload.xaml.cs
+++ b/TwitchDownloaderWPF/WindowMassDownload.xaml.cs
@@ -26,7 +26,7 @@ public partial class WindowMassDownload : Window
public readonly List selectedItems = new List();
public readonly List cursorList = new List();
public int cursorIndex = 0;
- public string currentChannel = "";
+ public User currentChannel;
public string period = "";
public int videoCount = 50;
@@ -57,11 +57,32 @@ private void ResetLists()
cursorIndex = 0;
}
- private Task ChangeCurrentChannel()
+ private async Task ChangeCurrentChannel()
{
- currentChannel = textChannel.Text;
+ var textTrimmed = textChannel.Text.Trim();
+ if (currentChannel?.login != textTrimmed)
+ {
+ currentChannel = null;
+ if (!string.IsNullOrEmpty(textTrimmed))
+ {
+ try
+ {
+ var idRes = await TwitchHelper.GetUserIds(new[] { textTrimmed });
+ var infoRes = await TwitchHelper.GetUserInfo(idRes.data.users.Select(x => x.id));
+ currentChannel = infoRes.data.users[0];
+ }
+ catch (Exception ex)
+ {
+ if (Settings.Default.VerboseErrors)
+ {
+ MessageBox.Show(this, ex.ToString(), Translations.Strings.VerboseErrorOutput, MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+ }
+ }
+
ResetLists();
- return UpdateList();
+ await UpdateList();
}
private async Task UpdateList()
@@ -71,7 +92,7 @@ private async Task UpdateList()
StatusImage.Visibility = Visibility.Visible;
- if (string.IsNullOrWhiteSpace(currentChannel))
+ if (string.IsNullOrWhiteSpace(currentChannel?.login))
{
// Pretend we are doing something so the status icon has time to show
await Task.Delay(50);
@@ -91,7 +112,7 @@ private async Task UpdateList()
GqlVideoSearchResponse res;
try
{
- res = await TwitchHelper.GetGqlVideos(currentChannel, currentCursor, videoCount);
+ res = await TwitchHelper.GetGqlVideos(currentChannel.login, currentCursor, videoCount);
}
catch (Exception ex)
{
@@ -123,7 +144,8 @@ private async Task UpdateList()
Id = video.node.id,
Time = Settings.Default.UTCVideoTime ? video.node.createdAt : video.node.createdAt.ToLocalTime(),
Views = video.node.viewCount,
- Streamer = currentChannel,
+ Streamer = currentChannel.displayName,
+ StreamerId = currentChannel.id,
Game = video.node.game?.displayName ?? Translations.Strings.UnknownGame,
Thumbnail = thumbnail
});
@@ -155,7 +177,7 @@ private async Task UpdateList()
GqlClipSearchResponse res;
try
{
- res = await TwitchHelper.GetGqlClips(currentChannel, period, currentCursor, videoCount);
+ res = await TwitchHelper.GetGqlClips(currentChannel.login, period, currentCursor, videoCount);
}
catch (Exception ex)
{
@@ -187,7 +209,10 @@ private async Task UpdateList()
Id = clip.node.slug,
Time = Settings.Default.UTCVideoTime ? clip.node.createdAt : clip.node.createdAt.ToLocalTime(),
Views = clip.node.viewCount,
- Streamer = currentChannel,
+ Streamer = currentChannel.displayName,
+ StreamerId = currentChannel.id,
+ ClipperName = clip.node.curator.displayName,
+ ClipperId = clip.node.curator.id,
Game = clip.node.game?.displayName ?? Translations.Strings.UnknownGame,
Thumbnail = thumbnail
});
From 513cd52248175fa6efd64ed01c6e84a04b5dbca2 Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Sun, 10 Nov 2024 10:19:44 -0500
Subject: [PATCH 09/16] Bump ChatRootVersion
---
TwitchDownloaderCore/TwitchObjects/ChatRootInfo.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TwitchDownloaderCore/TwitchObjects/ChatRootInfo.cs b/TwitchDownloaderCore/TwitchObjects/ChatRootInfo.cs
index 689de2a9..6eb27389 100644
--- a/TwitchDownloaderCore/TwitchObjects/ChatRootInfo.cs
+++ b/TwitchDownloaderCore/TwitchObjects/ChatRootInfo.cs
@@ -15,7 +15,7 @@ public record ChatRootVersion
public uint Minor { get; init; }
public uint Patch { get; init; }
- public static ChatRootVersion CurrentVersion { get; } = new(1, 3, 1);
+ public static ChatRootVersion CurrentVersion { get; } = new(1, 4, 0);
///
/// Initializes a new object with the default version of 1.0.0
From 7dcd5548365ef821459e2241db032543a0e70654 Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Fri, 15 Nov 2024 11:49:17 -0500
Subject: [PATCH 10/16] TaskData.Streamer -> TaskData.StreamerName
---
TwitchDownloaderWPF/TwitchTasks/TaskData.cs | 2 +-
TwitchDownloaderWPF/WindowMassDownload.xaml.cs | 4 ++--
TwitchDownloaderWPF/WindowQueueOptions.xaml.cs | 6 +++---
TwitchDownloaderWPF/WindowUrlList.xaml.cs | 4 ++--
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/TwitchDownloaderWPF/TwitchTasks/TaskData.cs b/TwitchDownloaderWPF/TwitchTasks/TaskData.cs
index 88408ffb..b3b64fd3 100644
--- a/TwitchDownloaderWPF/TwitchTasks/TaskData.cs
+++ b/TwitchDownloaderWPF/TwitchTasks/TaskData.cs
@@ -6,7 +6,7 @@ namespace TwitchDownloaderWPF.TwitchTasks
public class TaskData
{
public string Id { get; set; }
- public string Streamer { get; set; }
+ public string StreamerName { get; set; }
public string StreamerId { get; set; }
public string ClipperName { get; set; }
public string ClipperId { get; set; }
diff --git a/TwitchDownloaderWPF/WindowMassDownload.xaml.cs b/TwitchDownloaderWPF/WindowMassDownload.xaml.cs
index 75475d59..af643cad 100644
--- a/TwitchDownloaderWPF/WindowMassDownload.xaml.cs
+++ b/TwitchDownloaderWPF/WindowMassDownload.xaml.cs
@@ -144,7 +144,7 @@ private async Task UpdateList()
Id = video.node.id,
Time = Settings.Default.UTCVideoTime ? video.node.createdAt : video.node.createdAt.ToLocalTime(),
Views = video.node.viewCount,
- Streamer = currentChannel.displayName,
+ StreamerName = currentChannel.displayName,
StreamerId = currentChannel.id,
Game = video.node.game?.displayName ?? Translations.Strings.UnknownGame,
Thumbnail = thumbnail
@@ -209,7 +209,7 @@ private async Task UpdateList()
Id = clip.node.slug,
Time = Settings.Default.UTCVideoTime ? clip.node.createdAt : clip.node.createdAt.ToLocalTime(),
Views = clip.node.viewCount,
- Streamer = currentChannel.displayName,
+ StreamerName = currentChannel.displayName,
StreamerId = currentChannel.id,
ClipperName = clip.node.curator.displayName,
ClipperId = clip.node.curator.id,
diff --git a/TwitchDownloaderWPF/WindowQueueOptions.xaml.cs b/TwitchDownloaderWPF/WindowQueueOptions.xaml.cs
index 3fd0ec43..69781ec0 100644
--- a/TwitchDownloaderWPF/WindowQueueOptions.xaml.cs
+++ b/TwitchDownloaderWPF/WindowQueueOptions.xaml.cs
@@ -576,7 +576,7 @@ private void EnqueueDataList()
: -1,
FileCollisionCallback = HandleFileCollisionCallback,
};
- downloadOptions.Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateVod, taskData.Title, taskData.Id, taskData.Time, taskData.Streamer, taskData.StreamerId,
+ downloadOptions.Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateVod, taskData.Title, taskData.Id, taskData.Time, taskData.StreamerName, taskData.StreamerId,
downloadOptions.TrimBeginning ? downloadOptions.TrimBeginningTime : TimeSpan.Zero,
downloadOptions.TrimEnding ? downloadOptions.TrimEndingTime : TimeSpan.FromSeconds(taskData.Length),
taskData.Views, taskData.Game) + FilenameService.GuessVodFileExtension(downloadOptions.Quality));
@@ -602,7 +602,7 @@ private void EnqueueDataList()
{
Id = taskData.Id,
Quality = (ComboPreferredQuality.SelectedItem as ComboBoxItem)?.Content as string,
- Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateClip, taskData.Title, taskData.Id, taskData.Time, taskData.Streamer, taskData.StreamerId,
+ Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateClip, taskData.Title, taskData.Id, taskData.Time, taskData.StreamerName, taskData.StreamerId,
TimeSpan.Zero, TimeSpan.FromSeconds(taskData.Length), taskData.Views, taskData.Game, taskData.ClipperName, taskData.ClipperId) + ".mp4"),
ThrottleKib = Settings.Default.DownloadThrottleEnabled
? Settings.Default.MaximumBandwidthKib
@@ -648,7 +648,7 @@ private void EnqueueDataList()
downloadOptions.DownloadFormat = ChatFormat.Html;
else
downloadOptions.DownloadFormat = ChatFormat.Text;
- downloadOptions.Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateChat, taskData.Title, taskData.Id, taskData.Time, taskData.Streamer, taskData.StreamerId,
+ downloadOptions.Filename = Path.Combine(folderPath, FilenameService.GetFilename(Settings.Default.TemplateChat, taskData.Title, taskData.Id, taskData.Time, taskData.StreamerName, taskData.StreamerId,
downloadOptions.TrimBeginning ? TimeSpan.FromSeconds(downloadOptions.TrimBeginningTime) : TimeSpan.Zero,
downloadOptions.TrimEnding ? TimeSpan.FromSeconds(downloadOptions.TrimEndingTime) : TimeSpan.FromSeconds(taskData.Length),
taskData.Views, taskData.Game, taskData.ClipperName, taskData.ClipperId) + "." + downloadOptions.FileExtension);
diff --git a/TwitchDownloaderWPF/WindowUrlList.xaml.cs b/TwitchDownloaderWPF/WindowUrlList.xaml.cs
index 5dfe6977..f80b81df 100644
--- a/TwitchDownloaderWPF/WindowUrlList.xaml.cs
+++ b/TwitchDownloaderWPF/WindowUrlList.xaml.cs
@@ -98,7 +98,7 @@ private async void btnQueue_Click(object sender, RoutedEventArgs e)
Id = id,
Thumbnail = thumbnail,
Title = videoInfo.title,
- Streamer = videoInfo.owner.displayName,
+ StreamerName = videoInfo.owner.displayName,
StreamerId = videoInfo.owner.id,
Time = Settings.Default.UTCVideoTime ? videoInfo.createdAt : videoInfo.createdAt.ToLocalTime(),
Views = videoInfo.viewCount,
@@ -137,7 +137,7 @@ private async void btnQueue_Click(object sender, RoutedEventArgs e)
Id = id,
Thumbnail = thumbnail,
Title = clipInfo.title,
- Streamer = clipInfo.broadcaster?.displayName ?? Translations.Strings.UnknownUser,
+ StreamerName = clipInfo.broadcaster?.displayName ?? Translations.Strings.UnknownUser,
StreamerId = clipInfo.broadcaster?.id,
ClipperName = clipInfo.curator.displayName,
ClipperId = clipInfo.curator.id,
From 9484b94f8f9d6a69943f84cb9e745ab52454fa92 Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Fri, 15 Nov 2024 11:59:59 -0500
Subject: [PATCH 11/16] Return streamer displayName instead of login
---
TwitchDownloaderCore/TwitchHelper.cs | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/TwitchDownloaderCore/TwitchHelper.cs b/TwitchDownloaderCore/TwitchHelper.cs
index 68cdcde9..63bb7169 100644
--- a/TwitchDownloaderCore/TwitchHelper.cs
+++ b/TwitchDownloaderCore/TwitchHelper.cs
@@ -1047,14 +1047,17 @@ public static async Task GetUserIds(IEnumerable nameL
return await response.Content.ReadFromJsonAsync();
}
- public static async Task GetStreamerName(int id)
+ public static async Task GetStreamerDisplayName(int id)
{
try
{
- GqlUserInfoResponse info = await GetUserInfo(new List { id.ToString() });
- return info.data.users[0].login;
+ GqlUserInfoResponse info = await GetUserInfo(new[] { id.ToString() });
+ return info.data.users[0].displayName;
+ }
+ catch
+ {
+ return "";
}
- catch { return ""; }
}
public static async Task GetUserInfo(IEnumerable idList)
From bdd278aa2b59ad9ea8abeafd46822e5634e27655 Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Fri, 15 Nov 2024 12:00:22 -0500
Subject: [PATCH 12/16] Forgot to stage
---
TwitchDownloaderCore/Chat/ChatJson.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TwitchDownloaderCore/Chat/ChatJson.cs b/TwitchDownloaderCore/Chat/ChatJson.cs
index 137f67b4..1596152a 100644
--- a/TwitchDownloaderCore/Chat/ChatJson.cs
+++ b/TwitchDownloaderCore/Chat/ChatJson.cs
@@ -208,7 +208,7 @@ private static async Task UpgradeChatJson(ChatRoot chatRoot)
}
}
- var assumedName = chatRoot.video.user_name ?? broadcaster.Value?.commenter.display_name ?? await TwitchHelper.GetStreamerName(assumedId);
+ var assumedName = chatRoot.video.user_name ?? broadcaster.Value?.commenter.display_name ?? await TwitchHelper.GetStreamerDisplayName(assumedId);
chatRoot.streamer = new Streamer { id = assumedId, name = assumedName };
}
From b65b329843e2a0fdfad3be3beb5a621ef23ab76c Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Fri, 15 Nov 2024 21:21:39 -0500
Subject: [PATCH 13/16] Store streamer/clipper logins in chatroot
---
TwitchDownloaderCore/Chat/ChatJson.cs | 40 +++++++++++++++----
TwitchDownloaderCore/ChatDownloader.cs | 3 ++
TwitchDownloaderCore/ChatUpdater.cs | 1 +
TwitchDownloaderCore/TwitchHelper.cs | 13 ------
.../TwitchObjects/ChatRoot.cs | 2 +
5 files changed, 39 insertions(+), 20 deletions(-)
diff --git a/TwitchDownloaderCore/Chat/ChatJson.cs b/TwitchDownloaderCore/Chat/ChatJson.cs
index 1596152a..c43aa8f5 100644
--- a/TwitchDownloaderCore/Chat/ChatJson.cs
+++ b/TwitchDownloaderCore/Chat/ChatJson.cs
@@ -192,25 +192,51 @@ private static async Task UpgradeChatJson(ChatRoot chatRoot)
if (chatRoot.streamer is null)
{
- var broadcaster = new Lazy(() =>
- chatRoot.comments
- .Where(x => x.message.user_badges != null)
- .FirstOrDefault(x => x.message.user_badges.Any(b => b._id.Equals("broadcaster"))));
+ var broadcaster = chatRoot.comments
+ .Where(x => x.message.user_badges != null)
+ .FirstOrDefault(x => x.message.user_badges.Any(b => b._id.Equals("broadcaster")));
if (!int.TryParse(chatRoot.video.user_id, out var assumedId))
{
if (chatRoot.comments.FirstOrDefault(x => int.TryParse(x.channel_id, out assumedId)) is null)
{
- if (!int.TryParse(broadcaster.Value?.commenter._id, out assumedId))
+ if (!int.TryParse(broadcaster?.commenter._id, out assumedId))
{
assumedId = 0;
}
}
}
- var assumedName = chatRoot.video.user_name ?? broadcaster.Value?.commenter.display_name ?? await TwitchHelper.GetStreamerDisplayName(assumedId);
+ var assumedName = chatRoot.video.user_name ?? broadcaster?.commenter.display_name;
+ var assumedLogin = broadcaster?.commenter.name;
- chatRoot.streamer = new Streamer { id = assumedId, name = assumedName };
+ if ((assumedName is null || assumedLogin is null) && assumedId != 0)
+ {
+ try
+ {
+ var userInfo = await TwitchHelper.GetUserInfo(new[] { assumedId.ToString() });
+ assumedName ??= userInfo.data.users.FirstOrDefault()?.displayName;
+ assumedLogin ??= userInfo.data.users.FirstOrDefault()?.login;
+ }
+ catch { /* ignored */ }
+ }
+
+ chatRoot.streamer = new Streamer
+ {
+ name = assumedName,
+ login = assumedLogin,
+ id = assumedId
+ };
+ }
+
+ if (chatRoot.streamer.login is null && chatRoot.streamer.id != 0)
+ {
+ try
+ {
+ var userInfo = await TwitchHelper.GetUserInfo(new[] { chatRoot.streamer.id.ToString() });
+ chatRoot.streamer.login = userInfo.data.users.FirstOrDefault()?.login;
+ }
+ catch { /* ignored */ }
}
if (chatRoot.video.user_name is not null)
diff --git a/TwitchDownloaderCore/ChatDownloader.cs b/TwitchDownloaderCore/ChatDownloader.cs
index f14527fb..0e20aaf0 100644
--- a/TwitchDownloaderCore/ChatDownloader.cs
+++ b/TwitchDownloaderCore/ChatDownloader.cs
@@ -331,6 +331,7 @@ private async Task DownloadAsyncImpl(FileInfo outputFileInfo, FileStream outputF
}
chatRoot.streamer.name = videoInfoResponse.data.video.owner.displayName;
+ chatRoot.streamer.login = videoInfoResponse.data.video.owner.login;
chatRoot.streamer.id = int.Parse(videoInfoResponse.data.video.owner.id);
chatRoot.video.description = videoInfoResponse.data.video.description?.Replace(" \n", "\n").Replace("\n\n", "\n").TrimEnd();
chatRoot.video.title = videoInfoResponse.data.video.title;
@@ -371,10 +372,12 @@ private async Task DownloadAsyncImpl(FileInfo outputFileInfo, FileStream outputF
videoId = clipInfoResponse.data.clip.video.id;
chatRoot.streamer.name = clipInfoResponse.data.clip.broadcaster.displayName;
+ chatRoot.streamer.login = clipInfoResponse.data.clip.broadcaster.login;
chatRoot.streamer.id = int.Parse(clipInfoResponse.data.clip.broadcaster.id);
chatRoot.clipper = new Clipper
{
name = clipInfoResponse.data.clip.curator.displayName,
+ login = clipInfoResponse.data.clip.curator.login,
id = int.Parse(clipInfoResponse.data.clip.curator.id),
};
chatRoot.video.title = clipInfoResponse.data.clip.title;
diff --git a/TwitchDownloaderCore/ChatUpdater.cs b/TwitchDownloaderCore/ChatUpdater.cs
index 64303197..aee1f5f1 100644
--- a/TwitchDownloaderCore/ChatUpdater.cs
+++ b/TwitchDownloaderCore/ChatUpdater.cs
@@ -177,6 +177,7 @@ private async Task UpdateVideoInfo(int totalSteps, int currentStep, Cancellation
chatRoot.clipper ??= new Clipper
{
name = clipInfo.curator.displayName,
+ login = clipInfo.curator.login,
id = int.Parse(clipInfo.curator.id),
};
diff --git a/TwitchDownloaderCore/TwitchHelper.cs b/TwitchDownloaderCore/TwitchHelper.cs
index 63bb7169..fd101dfa 100644
--- a/TwitchDownloaderCore/TwitchHelper.cs
+++ b/TwitchDownloaderCore/TwitchHelper.cs
@@ -1047,19 +1047,6 @@ public static async Task GetUserIds(IEnumerable nameL
return await response.Content.ReadFromJsonAsync();
}
- public static async Task GetStreamerDisplayName(int id)
- {
- try
- {
- GqlUserInfoResponse info = await GetUserInfo(new[] { id.ToString() });
- return info.data.users[0].displayName;
- }
- catch
- {
- return "";
- }
- }
-
public static async Task GetUserInfo(IEnumerable idList)
{
var request = new HttpRequestMessage()
diff --git a/TwitchDownloaderCore/TwitchObjects/ChatRoot.cs b/TwitchDownloaderCore/TwitchObjects/ChatRoot.cs
index 3494b3f5..5d83c795 100644
--- a/TwitchDownloaderCore/TwitchObjects/ChatRoot.cs
+++ b/TwitchDownloaderCore/TwitchObjects/ChatRoot.cs
@@ -8,12 +8,14 @@ namespace TwitchDownloaderCore.TwitchObjects
public class Streamer
{
public string name { get; set; }
+ public string login { get; set; }
public int id { get; set; }
}
public class Clipper
{
public string name { get; set; }
+ public string login { get; set; }
public int id { get; set; }
}
From b23c66c4b6171761340f73645733f5b1497c0e5d Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Fri, 15 Nov 2024 21:28:12 -0500
Subject: [PATCH 14/16] Use array instead of list
---
TwitchDownloaderCore/TwitchObjects/Gql/GqlUserIdResponse.cs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/TwitchDownloaderCore/TwitchObjects/Gql/GqlUserIdResponse.cs b/TwitchDownloaderCore/TwitchObjects/Gql/GqlUserIdResponse.cs
index ac8e85b6..39fa5860 100644
--- a/TwitchDownloaderCore/TwitchObjects/Gql/GqlUserIdResponse.cs
+++ b/TwitchDownloaderCore/TwitchObjects/Gql/GqlUserIdResponse.cs
@@ -1,5 +1,3 @@
-using System.Collections.Generic;
-
namespace TwitchDownloaderCore.TwitchObjects.Gql
{
public class UserId
@@ -9,7 +7,7 @@ public class UserId
public class UserIdData
{
- public List users { get; set; }
+ public UserId[] users { get; set; }
}
public class GqlUserIdResponse
From 21aeb70834a433824e2c937fd45fcbf188463098 Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Fri, 15 Nov 2024 22:15:39 -0500
Subject: [PATCH 15/16] Rename broadcaster comment variable
---
TwitchDownloaderCore/Chat/ChatJson.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/TwitchDownloaderCore/Chat/ChatJson.cs b/TwitchDownloaderCore/Chat/ChatJson.cs
index c43aa8f5..65f88eba 100644
--- a/TwitchDownloaderCore/Chat/ChatJson.cs
+++ b/TwitchDownloaderCore/Chat/ChatJson.cs
@@ -192,7 +192,7 @@ private static async Task UpgradeChatJson(ChatRoot chatRoot)
if (chatRoot.streamer is null)
{
- var broadcaster = chatRoot.comments
+ var broadcasterComment = chatRoot.comments
.Where(x => x.message.user_badges != null)
.FirstOrDefault(x => x.message.user_badges.Any(b => b._id.Equals("broadcaster")));
@@ -200,15 +200,15 @@ private static async Task UpgradeChatJson(ChatRoot chatRoot)
{
if (chatRoot.comments.FirstOrDefault(x => int.TryParse(x.channel_id, out assumedId)) is null)
{
- if (!int.TryParse(broadcaster?.commenter._id, out assumedId))
+ if (!int.TryParse(broadcasterComment?.commenter._id, out assumedId))
{
assumedId = 0;
}
}
}
- var assumedName = chatRoot.video.user_name ?? broadcaster?.commenter.display_name;
- var assumedLogin = broadcaster?.commenter.name;
+ var assumedName = chatRoot.video.user_name ?? broadcasterComment?.commenter.display_name;
+ var assumedLogin = broadcasterComment?.commenter.name;
if ((assumedName is null || assumedLogin is null) && assumedId != 0)
{
From a5ff23c111580e42248fa378b493df8bfa61a995 Mon Sep 17 00:00:00 2001
From: ScrubN <72096833+ScrubN@users.noreply.github.com>
Date: Sat, 16 Nov 2024 00:10:53 -0500
Subject: [PATCH 16/16] Ignore case when comparing channel text
---
TwitchDownloaderWPF/WindowMassDownload.xaml.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/TwitchDownloaderWPF/WindowMassDownload.xaml.cs b/TwitchDownloaderWPF/WindowMassDownload.xaml.cs
index af643cad..b02245ad 100644
--- a/TwitchDownloaderWPF/WindowMassDownload.xaml.cs
+++ b/TwitchDownloaderWPF/WindowMassDownload.xaml.cs
@@ -60,7 +60,7 @@ private void ResetLists()
private async Task ChangeCurrentChannel()
{
var textTrimmed = textChannel.Text.Trim();
- if (currentChannel?.login != textTrimmed)
+ if (!textTrimmed.Equals(currentChannel?.login, StringComparison.InvariantCultureIgnoreCase))
{
currentChannel = null;
if (!string.IsNullOrEmpty(textTrimmed))