Add - Added option to set sings subtitles as default

Chg - Log message for when "No active Subscription" is displayed in login tab
Fix - Chapter crashed the downloader in some cases
Fix - Custom calendar crashed the downloader in some cases
This commit is contained in:
Elwador 2024-07-26 02:18:39 +02:00
parent 607fee38b6
commit e9109210af
15 changed files with 98 additions and 47 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -205,7 +205,7 @@ public class CalendarManager{
calEpisode.EpisodeName = crBrowseEpisode.Title;
calEpisode.SeriesUrl = $"https://www.crunchyroll.com/{CrunchyrollManager.Instance.CrunOptions.HistoryLang}/series/" + crBrowseEpisode.EpisodeMetadata.SeriesId;
calEpisode.EpisodeUrl = $"https://www.crunchyroll.com/{CrunchyrollManager.Instance.CrunOptions.HistoryLang}/watch/{crBrowseEpisode.Id}/";
calEpisode.ThumbnailUrl = crBrowseEpisode.Images.Thumbnail.First().First().Source;
calEpisode.ThumbnailUrl = crBrowseEpisode.Images.Thumbnail?.FirstOrDefault()?.FirstOrDefault().Source ?? ""; //https://www.crunchyroll.com/i/coming_soon_beta_thumb.jpg
calEpisode.IsPremiumOnly = crBrowseEpisode.EpisodeMetadata.IsPremiumOnly;
calEpisode.IsPremiere = crBrowseEpisode.EpisodeMetadata.Episode == "1";
calEpisode.SeasonName = crBrowseEpisode.EpisodeMetadata.SeasonTitle;

View File

@ -127,7 +127,6 @@ public class CrAuth{
} else{
crunInstance.Profile.HasPremium = subsc.IsActive;
}
} else{
crunInstance.Profile.HasPremium = false;
Console.Error.WriteLine("Failed to check premium subscription status");

View File

@ -19,7 +19,6 @@ using CRD.Utils.Muxing;
using CRD.Utils.Sonarr;
using CRD.Utils.Structs;
using CRD.Utils.Structs.History;
using CRD.ViewModels;
using CRD.Views;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@ -34,7 +33,7 @@ public class CrunchyrollManager{
public CrProfile Profile = new();
private readonly Lazy<CrDownloadOptions> _optionsLazy;
public CrDownloadOptions CrunOptions => _optionsLazy.Value;
#region History Variables
public ObservableCollection<HistorySeries> HistoryList = new();
@ -42,7 +41,7 @@ public class CrunchyrollManager{
public HistorySeries SelectedSeries = new HistorySeries{
Seasons =[]
};
#endregion
@ -58,7 +57,7 @@ public class CrunchyrollManager{
public CrEpisode CrEpisode;
public CrSeries CrSeries;
public History History;
#region Singelton
private static CrunchyrollManager? _instance;
@ -86,9 +85,8 @@ public class CrunchyrollManager{
private CrDownloadOptions InitDownloadOptions(){
var options = new CrDownloadOptions();
options.AutoDownload = false;
options.RemoveFinishedDownload = false;
options.Chapters = true;
@ -123,7 +121,7 @@ public class CrunchyrollManager{
return options;
}
public void InitOptions(){
_widevine = Widevine.Instance;
@ -144,8 +142,6 @@ public class CrunchyrollManager{
}
public async Task Init(){
if (CrunOptions.LogMode){
CfgManager.EnableLogMode();
} else{
@ -181,7 +177,6 @@ public class CrunchyrollManager{
}
public async Task<bool> DownloadEpisode(CrunchyEpMeta data, CrDownloadOptions options){
QueueManager.Instance.ActiveDownloads++;
@ -369,7 +364,7 @@ public class CrunchyrollManager{
}
}
}
syncVideosList.ForEach(syncVideo => Helpers.DeleteFile(syncVideo.Path));
}
@ -648,14 +643,13 @@ public class CrunchyrollManager{
}
dlFailed = true;
return new DownloadResponse{
Data = new List<DownloadedMedia>(),
Error = dlFailed,
FileName = "./unknown",
ErrorText = "Hardsubs not available"
};
}
} else{
streams = streams.Where((s) => {
@ -1601,27 +1595,42 @@ public class CrunchyrollManager{
var showRequestResponse = await HttpClientReq.Instance.SendHttpRequest(showRequest);
if (showRequestResponse.IsOk){
JObject jObject = JObject.Parse(showRequestResponse.ResponseContent);
CrunchyChapters chapterData = new CrunchyChapters();
chapterData.lastUpdate = jObject["lastUpdate"]?.ToObject<DateTime?>();
chapterData.mediaId = jObject["mediaId"]?.ToObject<string>();
chapterData.Chapters = new List<CrunchyChapter>();
foreach (var property in jObject.Properties()){
// Check if the property value is an object and the property is not one of the known non-dictionary properties
if (property.Value.Type == JTokenType.Object && property.Name != "lastUpdate" && property.Name != "mediaId"){
// Deserialize the property value into a CrunchyChapter and add it to the dictionary
CrunchyChapter chapter = property.Value.ToObject<CrunchyChapter>();
chapterData.Chapters.Add(chapter);
try{
JObject jObject = JObject.Parse(showRequestResponse.ResponseContent);
if (jObject.TryGetValue("lastUpdate", out JToken lastUpdateToken)){
chapterData.lastUpdate = lastUpdateToken.ToObject<DateTime?>();
}
if (jObject.TryGetValue("mediaId", out JToken mediaIdToken)){
chapterData.mediaId = mediaIdToken.ToObject<string>();
}
chapterData.Chapters = new List<CrunchyChapter>();
foreach (var property in jObject.Properties()){
if (property.Value.Type == JTokenType.Object && property.Name != "lastUpdate" && property.Name != "mediaId"){
try{
CrunchyChapter chapter = property.Value.ToObject<CrunchyChapter>();
chapterData.Chapters.Add(chapter);
} catch (Exception ex){
Console.Error.WriteLine($"Error parsing chapter: {ex.Message}");
}
}
}
} catch (Exception ex){
Console.Error.WriteLine($"Error parsing JSON response: {ex.Message}");
}
if (chapterData.Chapters.Count > 0){
chapterData.Chapters.Sort((a, b) => {
if (a.start != null && b.start != null)
return a.start.Value - b.start.Value;
return 0;
if (a.start.HasValue && b.start.HasValue){
return a.start.Value.CompareTo(b.start.Value);
}
return 0; // Both values are null, they are considered equal
});
if (!((chapterData.Chapters.Any(c => c.type == "intro")) || chapterData.Chapters.Any(c => c.type == "recap"))){

View File

@ -7,6 +7,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using CRD.Downloader.Crunchyroll;
using CRD.Utils.Structs;
using DynamicData;
@ -191,7 +192,7 @@ public class Merger{
args.Add($"--track-name {trackName}");
args.Add($"--language 0:\"{subObj.Language.Code}\"");
if (options.Defaults.Sub.Code == subObj.Language.Code && subObj.ClosedCaption == false){
if (options.Defaults.Sub.Code == subObj.Language.Code && CrunchyrollManager.Instance.CrunOptions.DefaultSubSigns == subObj.Signs && subObj.ClosedCaption == false){
args.Add("--default-track 0");
} else{
args.Add("--default-track 0:0");

View File

@ -2,9 +2,12 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Http;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using CommunityToolkit.Mvvm.Input;
using CRD.Downloader;
using CRD.Downloader.Crunchyroll;
@ -33,7 +36,7 @@ public partial class CalendarEpisode : INotifyPropertyChanged{
public Bitmap? ImageBitmap{ get; set; }
public string? EpisodeNumber{ get; set; }
public bool IsPremiumOnly{ get; set; }
public bool IsPremiere{ get; set; }
@ -48,18 +51,22 @@ public partial class CalendarEpisode : INotifyPropertyChanged{
if (match.Success){
var locale = match.Groups[1].Value; // Capture the locale part
var id = match.Groups[2].Value; // Capture the ID part
QueueManager.Instance.CRAddEpisodeToQue(id, Languages.Locale2language(locale).CrLocale, CrunchyrollManager.Instance.CrunOptions.DubLang,true);
QueueManager.Instance.CRAddEpisodeToQue(id, Languages.Locale2language(locale).CrLocale, CrunchyrollManager.Instance.CrunOptions.DubLang, true);
}
}
public async Task LoadImage(){
try{
using (var client = new HttpClient()){
var response = await client.GetAsync(ThumbnailUrl);
response.EnsureSuccessStatusCode();
using (var stream = await response.Content.ReadAsStreamAsync()){
ImageBitmap = new Bitmap(stream);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ImageBitmap)));
if (string.IsNullOrEmpty(ThumbnailUrl)){
} else{
using (var client = new HttpClient()){
var response = await client.GetAsync(ThumbnailUrl);
response.EnsureSuccessStatusCode();
using (var stream = await response.Content.ReadAsStreamAsync()){
ImageBitmap = new Bitmap(stream);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ImageBitmap)));
}
}
}
} catch (Exception ex){

View File

@ -13,12 +13,12 @@ public struct CrunchyChapters{
public struct CrunchyChapter{
public string approverId { get; set; }
public string distributionNumber { get; set; }
public int? end { get; set; }
public int? start { get; set; }
public double? end { get; set; }
public double? start { get; set; }
public string title { get; set; }
public string seriesId { get; set; }
[JsonProperty("new")]
public bool New { get; set; }
public string? New { get; set; }
public string type { get; set; }
}

View File

@ -95,6 +95,9 @@ public class CrDownloadOptions{
[YamlMember(Alias = "mux_default_sub", ApplyNamingConventions = false)]
public string DefaultSub{ get; set; }
[YamlMember(Alias = "mux_default_sub_signs", ApplyNamingConventions = false)]
public bool DefaultSubSigns{ get; set; }
[YamlMember(Alias = "mux_default_dub", ApplyNamingConventions = false)]
public string DefaultAudio{ get; set; }

View File

@ -185,7 +185,7 @@ public struct Images{
[JsonProperty("promo_image")]
public List<List<Image>>? PromoImage{ get; set; }
public List<List<Image>> Thumbnail{ get; set; }
public List<List<Image>>? Thumbnail{ get; set; }
}
public struct Image{

View File

@ -38,6 +38,7 @@ public class Languages{
new(){ CrLocale = "te-IN", Locale = "te-IN", Code = "tel", Name = "Telugu (India)", Language = "తెలుగు" },
new(){ CrLocale = "id-ID", Locale = "id", Code = "in", Name = "Indonesian " }
};
public static LanguageItem FixAndFindCrLc(string cr_locale){
if (string.IsNullOrEmpty(cr_locale)){

View File

@ -11,6 +11,7 @@ using CRD.Downloader.Crunchyroll;
using CRD.Utils.Structs;
using CRD.Views.Utils;
using FluentAvalonia.UI.Controls;
using Newtonsoft.Json;
namespace CRD.ViewModels;
@ -40,6 +41,9 @@ public partial class AccountPageViewModel : ViewModelBase{
if (remaining <= TimeSpan.Zero){
RemainingTime = "No active Subscription";
_timer.Stop();
if (CrunchyrollManager.Instance.Profile.Subscription != null){
Console.Error.WriteLine(JsonConvert.SerializeObject(CrunchyrollManager.Instance.Profile.Subscription, Formatting.Indented));
}
} else{
RemainingTime = $"{(IsCancelled ? "Subscription ending in: " : "Subscription refreshing in: ")}{remaining:dd\\:hh\\:mm\\:ss}";
}
@ -82,6 +86,11 @@ public partial class AccountPageViewModel : ViewModelBase{
_timer.Tick -= Timer_Tick;
}
RaisePropertyChanged(nameof(RemainingTime));
if (CrunchyrollManager.Instance.Profile.Subscription != null){
Console.Error.WriteLine(JsonConvert.SerializeObject(CrunchyrollManager.Instance.Profile.Subscription, Formatting.Indented));
}
}
}

View File

@ -1,8 +1,14 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CRD.Downloader;
@ -56,8 +62,9 @@ public partial class CalendarPageViewModel : ViewModelBase{
private CalendarWeek? currentWeek;
private bool loading = true;
public CalendarPageViewModel(){
CalendarDays = new ObservableCollection<CalendarDay>();
foreach (var languageItem in Languages.languages){
@ -75,7 +82,7 @@ public partial class CalendarPageViewModel : ViewModelBase{
loading = false;
LoadCalendar(GetThisWeeksMondayDate(), false);
}
private string GetThisWeeksMondayDate(){
// Get today's date
DateTime today = DateTime.Today;
@ -226,7 +233,7 @@ public partial class CalendarPageViewModel : ViewModelBase{
CrunchyrollManager.Instance.CrunOptions.CustomCalendar = value;
LoadCalendar(GetThisWeeksMondayDate(), true);
CfgManager.WriteSettingsToFile();
}

View File

@ -57,6 +57,8 @@ public partial class SettingsPageViewModel : ViewModelBase{
[ObservableProperty]
private bool _syncTimings;
[ObservableProperty]
private bool _defaultSubSigns;
[ObservableProperty]
private bool _includeEpisodeDescription;
@ -380,6 +382,7 @@ public partial class SettingsPageViewModel : ViewModelBase{
AddScaledBorderAndShadow = options.SubsAddScaledBorder is ScaledBorderAndShadowSelection.ScaledBorderAndShadowNo or ScaledBorderAndShadowSelection.ScaledBorderAndShadowYes;
SelectedScaledBorderAndShadow = GetScaledBorderAndShadowFromOptions(options);
DefaultSubSigns = options.DefaultSubSigns;
HistoryAddSpecials = options.HistoryAddSpecials;
DownloadSpeed = options.DownloadSpeedLimit;
IncludeEpisodeDescription = options.IncludeVideoDescription;
@ -445,7 +448,8 @@ public partial class SettingsPageViewModel : ViewModelBase{
if (!settingsLoaded){
return;
}
CrunchyrollManager.Instance.CrunOptions.DefaultSubSigns = DefaultSubSigns;
CrunchyrollManager.Instance.CrunOptions.IncludeVideoDescription = IncludeEpisodeDescription;
CrunchyrollManager.Instance.CrunOptions.HistoryAddSpecials = HistoryAddSpecials;
CrunchyrollManager.Instance.CrunOptions.VideoTitle = FileTitle;

View File

@ -177,7 +177,12 @@
Text="{Binding DateTime, StringFormat='hh:mm tt'}"
Margin="0,0,0,0" />
<Grid HorizontalAlignment="Center">
<Image HorizontalAlignment="Center" Source="{Binding ImageBitmap}" />
<Grid>
<Image HorizontalAlignment="Center" Source="../Assets/coming_soon_ep.jpg" />
<Image HorizontalAlignment="Center" Source="{Binding ImageBitmap}" />
</Grid>
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
<TextBlock VerticalAlignment="Center" TextAlignment="Center"
Margin="0 0 5 0" Width="30" Height="30"

View File

@ -315,6 +315,12 @@
</ComboBox>
</controls:SettingsExpanderItem.Footer>
</controls:SettingsExpanderItem>
<controls:SettingsExpanderItem Content="Default Subtitle Signs" Description="Will set the signs subtitle as default instead">
<controls:SettingsExpanderItem.Footer>
<CheckBox IsChecked="{Binding DefaultSubSigns}"> </CheckBox>
</controls:SettingsExpanderItem.Footer>
</controls:SettingsExpanderItem>
<controls:SettingsExpanderItem Content="File title"
Description="${showTitle} ${seriesTitle} ${title} ${season} ${episode} ${height} ${width}">