1.0-dev3-feature2 (Twitch Channels support added)

This commit is contained in:
2021-12-23 23:34:01 +01:00
Unverified
parent 54099a1c67
commit 6174d35416
6 changed files with 60 additions and 74 deletions

View File

@@ -50,7 +50,8 @@ namespace VDownload.Services
{ "use_mrfcrf444", "1" }, { "use_mrfcrf444", "1" },
{ "use_hardware_acceleration", "1" }, { "use_hardware_acceleration", "1" },
{ "delete_temp_on_start", "1" }, { "delete_temp_on_start", "1" },
{ "delete_video_temp_after_error", "1" } { "delete_video_temp_after_error", "1" },
{ "max_playlist_videos", "0" },
}; };
// SETTINGS CONTAINER // SETTINGS CONTAINER

View File

@@ -30,13 +30,16 @@ namespace VDownload.Sources
public PlaylistSource SourceType { get; private set; } public PlaylistSource SourceType { get; private set; }
public string ID { get; private set; } public string ID { get; private set; }
public Dictionary<VObject, TextBlock> VObjects { get; private set; } public Dictionary<VObject, TextBlock> VObjects { get; private set; }
private List<VObject> DeletedVObjects { get; set; }
// PLAYLIST PANEL OBJECTS
public StackPanel PlaylistPanel { get; set; } public StackPanel PlaylistPanel { get; set; }
private List<VObject> DeletedVObjects = new List<VObject>();
private Grid DeletedVideosPanel { get; set; } private Grid DeletedVideosPanel { get; set; }
// CONSTRUCTOR // CONSTRUCTOR
public PObject(Uri url) public PObject(Uri url)
{ {
DeletedVObjects = new List<VObject>();
VObjects = new Dictionary<VObject, TextBlock>(); VObjects = new Dictionary<VObject, TextBlock>();
(SourceType, ID) = Source.GetPlaylistSourceData(url); (SourceType, ID) = Source.GetPlaylistSourceData(url);
if (SourceType == PlaylistSource.Null) if (SourceType == PlaylistSource.Null)
@@ -54,39 +57,40 @@ namespace VDownload.Sources
// GET VIDEOS // GET VIDEOS
public async Task GetVideos() public async Task GetVideos()
{ {
VObject[] videos = null;
switch (SourceType) switch (SourceType)
{ {
case PlaylistSource.TwitchChannel: case PlaylistSource.TwitchChannel:
// TODO videos = await Twitch.Channel.GetVideos(ID);
break; break;
case PlaylistSource.Null: case PlaylistSource.Null:
throw new ArgumentException(); throw new ArgumentException();
} }
}
// ADD VIDEOS TO LIST foreach(VObject video in videos)
public async Task InitPlaylistPanel(StackPanel parent)
{
// Attach to panel object to PObject
PlaylistPanel = parent;
// Add videos to panel
foreach (VObject video in VObjects.Keys.ToArray())
{ {
await HandleVideoOnList(video); VObjects.Add(video, null);
} }
} }
#endregion #endregion
#region VIDEO PANEL #region VIDEO PANEL
// INIT PLAYLIST PANEL
public async Task InitPlaylistPanel()
{
// Add videos to panel
foreach (VObject video in VObjects.Keys.ToArray())
{
await VideoPanelHandler(video);
}
}
// VIDEO PANEL HANDLER // VIDEO PANEL HANDLER
private async Task HandleVideoOnList(VObject Video) private async Task VideoPanelHandler(VObject Video)
{ {
// Video panel // Video panel
Expander videoPanel = new Expander Expander videoPanel = new Expander
@@ -99,18 +103,16 @@ namespace VDownload.Sources
// Header // Header
#region HEADER Grid videoPanelHeader = new Grid
Grid header = new Grid
{ {
Margin = new Thickness(0, 15, 0, 15), Margin = new Thickness(0, 15, 0, 15),
}; };
header.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); videoPanelHeader.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
header.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(15) }); videoPanelHeader.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(15) });
header.ColumnDefinitions.Add(new ColumnDefinition()); videoPanelHeader.ColumnDefinitions.Add(new ColumnDefinition());
header.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(15) }); videoPanelHeader.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(15) });
header.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); videoPanelHeader.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
videoPanel.Header = header; videoPanel.Header = videoPanelHeader;
// Thumbnail // Thumbnail
Image thumbnailImage = new Image Image thumbnailImage = new Image
@@ -119,8 +121,7 @@ namespace VDownload.Sources
Width = 120, Width = 120,
}; };
Grid.SetColumn(thumbnailImage, 0); Grid.SetColumn(thumbnailImage, 0);
header.Children.Add(thumbnailImage); videoPanelHeader.Children.Add(thumbnailImage);
// Metadata grid // Metadata grid
@@ -129,7 +130,7 @@ namespace VDownload.Sources
metadataGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(10) }); metadataGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(10) });
metadataGrid.RowDefinitions.Add(new RowDefinition()); metadataGrid.RowDefinitions.Add(new RowDefinition());
Grid.SetColumn(metadataGrid, 2); Grid.SetColumn(metadataGrid, 2);
header.Children.Add(metadataGrid); videoPanelHeader.Children.Add(metadataGrid);
// Title & Source icon grid // Title & Source icon grid
Grid titleSourceGrid = new Grid(); Grid titleSourceGrid = new Grid();
@@ -260,7 +261,6 @@ namespace VDownload.Sources
detailedMetadataGrid.Children.Add(durationDataTextBlock); detailedMetadataGrid.Children.Add(durationDataTextBlock);
// Delete button // Delete button
AppBarButton deleteButton = new AppBarButton AppBarButton deleteButton = new AppBarButton
{ {
@@ -277,19 +277,14 @@ namespace VDownload.Sources
DeletedVideosPanelHandler(); DeletedVideosPanelHandler();
}; };
Grid.SetColumn(deleteButton, 4); Grid.SetColumn(deleteButton, 4);
header.Children.Add(deleteButton); videoPanelHeader.Children.Add(deleteButton);
#endregion
// Content // Content
#region CONTENT
Grid content = new Grid Grid content = new Grid
{ {
HorizontalAlignment = HorizontalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Stretch,
//Margin = new Thickness(0, 15, 0, 15),
}; };
content.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); content.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
content.RowDefinitions.Add(new RowDefinition { Height = new GridLength(50) }); content.RowDefinitions.Add(new RowDefinition { Height = new GridLength(50) });
@@ -297,7 +292,6 @@ namespace VDownload.Sources
videoPanel.Content = content; videoPanel.Content = content;
// Download options // Download options
Grid downloadOptionsGrid = new Grid Grid downloadOptionsGrid = new Grid
{ {
@@ -464,7 +458,6 @@ namespace VDownload.Sources
trimTextBoxGrid.Children.Add(AddPlaylistVideoDownloadOptionsTrimEndTextBox); trimTextBoxGrid.Children.Add(AddPlaylistVideoDownloadOptionsTrimEndTextBox);
// File & location // File & location
Grid fileLocationGrid = new Grid Grid fileLocationGrid = new Grid
{ {
@@ -556,8 +549,6 @@ namespace VDownload.Sources
Grid.SetColumn(AddPlaylistVideoLocationDataChooseLocationButton, 2); Grid.SetColumn(AddPlaylistVideoLocationDataChooseLocationButton, 2);
locationGrid.Children.Add(AddPlaylistVideoLocationDataChooseLocationButton); locationGrid.Children.Add(AddPlaylistVideoLocationDataChooseLocationButton);
#endregion
// Set items in quality combobox // Set items in quality combobox
@@ -725,7 +716,7 @@ namespace VDownload.Sources
PlaylistPanel.Children.Add(videoPanel); PlaylistPanel.Children.Add(videoPanel);
} }
// HANDLE DELETED VIDEOS PANEL // DELETED VIDEOS PANEL HANDLER
private void DeletedVideosPanelHandler() private void DeletedVideosPanelHandler()
{ {
if (DeletedVideosPanel == null) if (DeletedVideosPanel == null)
@@ -762,7 +753,7 @@ namespace VDownload.Sources
{ {
foreach (VObject v in DeletedVObjects) foreach (VObject v in DeletedVObjects)
{ {
await HandleVideoOnList(v); await VideoPanelHandler(v);
} }
DeletedVObjects.Clear(); DeletedVObjects.Clear();
PlaylistPanel.Children.Remove(DeletedVideosPanel); PlaylistPanel.Children.Remove(DeletedVideosPanel);
@@ -776,6 +767,7 @@ namespace VDownload.Sources
} }
else else
{ {
// Update panel
((TextBlock)DeletedVideosPanel.Children[0]).Text = ResourceLoader.GetForCurrentView().GetString("AddPlaylistDeletedVideosPanelTextBlock").Replace("{x}", DeletedVObjects.Count.ToString()); ((TextBlock)DeletedVideosPanel.Children[0]).Text = ResourceLoader.GetForCurrentView().GetString("AddPlaylistDeletedVideosPanelTextBlock").Replace("{x}", DeletedVObjects.Count.ToString());
} }
} }

View File

@@ -6,42 +6,26 @@ using System.Linq;
using System.Net; using System.Net;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using VDownload.Services;
namespace VDownload.Sources.Twitch namespace VDownload.Sources.Twitch
{ {
internal class Channel internal class Channel
{ {
#region INIT
// ID
private string ID { get; set; }
// CONSTRUCTOR
public Channel(string id)
{
ID = id;
}
#endregion
#region MAIN
// GET VIDEOS // GET VIDEOS
public async Task<string[]> GetVideos() public static async Task<VObject[]> GetVideos(string ID)
{ {
// Client settings // Client settings
WebClient Client = new WebClient(); WebClient Client = new WebClient();
Client.Headers.Add("Accept", "application/vnd.twitchtv.v5+json"); Client.Headers.Add("Accept", "application/vnd.twitchtv.v5+json");
Client.Headers.Add("Client-ID", "uo6dggojyb8d6soh92zknwmi5ej1q2"); Client.Headers.Add("Client-ID", "v8kfhyc2980it9e7t5hhc7baukzuj2");
// Get channel id // Get channel id
Uri requestUri; Uri requestUri;
JObject response; JObject response;
if (!ID.All(char.IsDigit)) if (!ID.All(char.IsDigit))
{ {
Debug.WriteLine(ID);
requestUri = new Uri($"https://api.twitch.tv/kraken/users?login={ID}"); requestUri = new Uri($"https://api.twitch.tv/kraken/users?login={ID}");
response = JObject.Parse(await Client.DownloadStringTaskAsync(requestUri)); response = JObject.Parse(await Client.DownloadStringTaskAsync(requestUri));
response = (JObject)response["users"][0]; response = (JObject)response["users"][0];
@@ -54,7 +38,7 @@ namespace VDownload.Sources.Twitch
string id = response["_id"].ToString(); string id = response["_id"].ToString();
// Get list // Get list
List<string> videos = new List<string>(); List<VObject> videos = new List<VObject>();
int offset = 0; int offset = 0;
do do
{ {
@@ -66,11 +50,23 @@ namespace VDownload.Sources.Twitch
response = JObject.Parse(await Client.DownloadStringTaskAsync(requestUri)); response = JObject.Parse(await Client.DownloadStringTaskAsync(requestUri));
foreach (var v in response["videos"]) foreach (var v in response["videos"])
{ {
Debug.WriteLine(v["_id"].ToString().Replace("v", "")); if (int.Parse(Config.GetValue("max_playlist_videos")) == 0 || videos.Count < int.Parse(Config.GetValue("max_playlist_videos")))
videos.Add(v["_id"].ToString().Replace("v", "")); {
try
{
VObject vid = new VObject(new Uri($"https://www.twitch.tv/videos/{v["_id"].ToString().Replace("v", "")}"));
await vid.GetMetadata();
videos.Add(vid);
}
catch { }
}
else
{
break;
}
} }
if (response["videos"].ToArray().Length == 100) if (response["videos"].ToArray().Length == 100 && !(int.Parse(Config.GetValue("max_playlist_videos")) == 0 || videos.Count < int.Parse(Config.GetValue("max_playlist_videos"))))
{ {
offset += 100; offset += 100;
} }
@@ -83,7 +79,5 @@ namespace VDownload.Sources.Twitch
// Return videos // Return videos
return videos.ToArray(); return videos.ToArray();
} }
#endregion
} }
} }

View File

@@ -15,7 +15,7 @@
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="40"/> <RowDefinition Height="20"/>
<RowDefinition/> <RowDefinition/>
</Grid.RowDefinitions> </Grid.RowDefinitions>

View File

@@ -62,9 +62,8 @@ namespace VDownload.Views.AddPlaylist
// Get playlist object from parent // Get playlist object from parent
base.OnNavigatedTo(e); base.OnNavigatedTo(e);
Playlist = (PObject)e.Parameter; Playlist = (PObject)e.Parameter;
await Playlist.InitPlaylistPanel(AddPlaylistVideoPanel); Playlist.PlaylistPanel = AddPlaylistVideoPanel;
await Playlist.InitPlaylistPanel();
} }
// SELECT LOCATION // SELECT LOCATION

View File

@@ -40,7 +40,7 @@
<!-- Left --> <!-- Left -->
<AppBarButton Grid.Column="0" x:Name="AppBarDownloadAllButton" x:Uid="AppBarDownloadAllButton" Click="AppBarDownloadAllButton_Click" Icon="Download" Label="Download All" Width="90"/> <AppBarButton Grid.Column="0" x:Name="AppBarDownloadAllButton" x:Uid="AppBarDownloadAllButton" Click="AppBarDownloadAllButton_Click" Icon="Download" Label="Download All" Width="90"/>
<AppBarSeparator Grid.Column="1" VerticalAlignment="Center" Height="50"/> <AppBarSeparator Grid.Column="1" VerticalAlignment="Center" Height="50"/>
<AppBarButton Grid.Column="2" x:Name="AppBarAddVideoButton" x:Uid="AppBarAddVideoButton" Click="AppBarAddVideoButton_Click" Icon="Add" Label="Add video" Width="75"/> <AppBarButton Grid.Column="2" x:Name="AppBarAddVideoButton" x:Uid="AppBarAddVideoButton" Click="AppBarAddVideoButton_Click" Icon="Video" Label="Add video" Width="75"/>
<AppBarButton Grid.Column="3" x:Name="AppBarAddPlaylistButton" x:Uid="AppBarAddPlaylistButton" Click="AppBarAddPlaylistButton_Click" Icon="List" Label="Add playlist" Width="85"/> <AppBarButton Grid.Column="3" x:Name="AppBarAddPlaylistButton" x:Uid="AppBarAddPlaylistButton" Click="AppBarAddPlaylistButton_Click" Icon="List" Label="Add playlist" Width="85"/>
<!-- Right --> <!-- Right -->
<AppBarButton Grid.Column="5" x:Name="AppBarSettingsButton" x:Uid="AppBarSettingsButton" Click="AppBarSettingsButton_Click" Icon="Setting" Label="Settings" Width="65"/> <AppBarButton Grid.Column="5" x:Name="AppBarSettingsButton" x:Uid="AppBarSettingsButton" Click="AppBarSettingsButton_Click" Icon="Setting" Label="Settings" Width="65"/>