Start of adding indexer to specifications
This will get renamed and squashed later dw
This commit is contained in:
parent
6de536a7ad
commit
45619a1df3
|
@ -21,6 +21,7 @@ namespace NzbDrone.Core.Blocklisting
|
|||
public long? Size { get; set; }
|
||||
public DownloadProtocol Protocol { get; set; }
|
||||
public string Indexer { get; set; }
|
||||
public int IndexerId { get; set; }
|
||||
public IndexerFlags IndexerFlags { get; set; }
|
||||
public ReleaseType ReleaseType { get; set; }
|
||||
public string Message { get; set; }
|
||||
|
|
|
@ -83,6 +83,7 @@ namespace NzbDrone.Core.Blocklisting
|
|||
PublishedDate = remoteEpisode.Release.PublishDate,
|
||||
Size = remoteEpisode.Release.Size,
|
||||
Indexer = remoteEpisode.Release.Indexer,
|
||||
IndexerId = remoteEpisode.Release.IndexerId,
|
||||
Protocol = remoteEpisode.Release.DownloadProtocol,
|
||||
Message = message,
|
||||
Languages = remoteEpisode.ParsedEpisodeInfo.Languages
|
||||
|
@ -183,6 +184,7 @@ namespace NzbDrone.Core.Blocklisting
|
|||
PublishedDate = DateTime.Parse(message.Data.GetValueOrDefault("publishedDate")),
|
||||
Size = long.Parse(message.Data.GetValueOrDefault("size", "0")),
|
||||
Indexer = message.Data.GetValueOrDefault("indexer"),
|
||||
IndexerId = int.Parse(message.Data.GetValueOrDefault("indexerId")),
|
||||
Protocol = (DownloadProtocol)Convert.ToInt32(message.Data.GetValueOrDefault("protocol")),
|
||||
Message = message.Message,
|
||||
TorrentInfoHash = message.Data.GetValueOrDefault("torrentInfoHash"),
|
||||
|
|
|
@ -42,7 +42,8 @@ namespace NzbDrone.Core.CustomFormats
|
|||
Size = size,
|
||||
Languages = remoteEpisode.Languages,
|
||||
IndexerFlags = remoteEpisode.Release?.IndexerFlags ?? 0,
|
||||
ReleaseType = remoteEpisode.ParsedEpisodeInfo.ReleaseType
|
||||
ReleaseType = remoteEpisode.ParsedEpisodeInfo.ReleaseType,
|
||||
IndexerId = remoteEpisode.Release?.IndexerId ?? 0,
|
||||
};
|
||||
|
||||
return ParseCustomFormat(input);
|
||||
|
@ -78,7 +79,8 @@ namespace NzbDrone.Core.CustomFormats
|
|||
Size = blocklist.Size ?? 0,
|
||||
Languages = blocklist.Languages,
|
||||
IndexerFlags = blocklist.IndexerFlags,
|
||||
ReleaseType = blocklist.ReleaseType
|
||||
ReleaseType = blocklist.ReleaseType,
|
||||
IndexerId = blocklist.IndexerId,
|
||||
};
|
||||
|
||||
return ParseCustomFormat(input);
|
||||
|
@ -89,6 +91,7 @@ namespace NzbDrone.Core.CustomFormats
|
|||
var parsed = Parser.Parser.ParseTitle(history.SourceTitle);
|
||||
|
||||
long.TryParse(history.Data.GetValueOrDefault("size"), out var size);
|
||||
int.TryParse(history.Data.GetValueOrDefault("indexerId"), out var indexerId);
|
||||
Enum.TryParse(history.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags indexerFlags);
|
||||
Enum.TryParse(history.Data.GetValueOrDefault("releaseType"), out ReleaseType releaseType);
|
||||
|
||||
|
@ -108,6 +111,7 @@ namespace NzbDrone.Core.CustomFormats
|
|||
Size = size,
|
||||
Languages = history.Languages,
|
||||
IndexerFlags = indexerFlags,
|
||||
IndexerId = indexerId,
|
||||
ReleaseType = releaseType
|
||||
};
|
||||
|
||||
|
@ -132,6 +136,7 @@ namespace NzbDrone.Core.CustomFormats
|
|||
Size = localEpisode.Size,
|
||||
Languages = localEpisode.Languages,
|
||||
IndexerFlags = localEpisode.IndexerFlags,
|
||||
IndexerId = localEpisode.Release.IndexerId,
|
||||
ReleaseType = localEpisode.ReleaseType,
|
||||
Filename = Path.GetFileName(localEpisode.Path)
|
||||
};
|
||||
|
@ -203,6 +208,7 @@ namespace NzbDrone.Core.CustomFormats
|
|||
Size = episodeFile.Size,
|
||||
Languages = episodeFile.Languages,
|
||||
IndexerFlags = episodeFile.IndexerFlags,
|
||||
IndexerId = episodeFile.IndexerId,
|
||||
ReleaseType = episodeFile.ReleaseType,
|
||||
Filename = Path.GetFileName(episodeFile.RelativePath),
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace NzbDrone.Core.CustomFormats
|
|||
public Series Series { get; set; }
|
||||
public long Size { get; set; }
|
||||
public IndexerFlags IndexerFlags { get; set; }
|
||||
public int IndexerId { get; set; }
|
||||
public List<Language> Languages { get; set; }
|
||||
public string Filename { get; set; }
|
||||
public ReleaseType ReleaseType { get; set; }
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public class IndexerSpecificationValidator : AbstractValidator<IndexerSpecification>
|
||||
{
|
||||
public IndexerSpecificationValidator(/*IIndexerFactory indexerFactory*/)
|
||||
{
|
||||
RuleFor(c => c.Value).NotEmpty();
|
||||
/*
|
||||
RuleFor(c => c.Value).Custom((indexerId, context) =>
|
||||
{
|
||||
if (indexerId != 0 && !indexerFactory.Exists(indexerId))
|
||||
{
|
||||
context.AddFailure($"Invalid indexer value: {indexerId}");
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
public class IndexerSpecification : CustomFormatSpecificationBase
|
||||
{
|
||||
private static readonly IndexerSpecificationValidator Validator = new ();
|
||||
|
||||
public override int Order => 11;
|
||||
public override string ImplementationName => "Indexer";
|
||||
|
||||
[FieldDefinition(1, Label = "CustomFormatsSpecificationIndexer", Type = FieldType.Select, SelectOptionsProviderAction = "getIndexersList")]
|
||||
public int Value { get; set; }
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
|
||||
{
|
||||
return input.IndexerId == Value;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -170,6 +170,7 @@ namespace NzbDrone.Core.History
|
|||
history.Data.Add("SeriesMatchType", message.Episode.SeriesMatchType.ToString());
|
||||
history.Data.Add("ReleaseSource", message.Episode.ReleaseSource.ToString());
|
||||
history.Data.Add("IndexerFlags", message.Episode.Release.IndexerFlags.ToString());
|
||||
history.Data.Add("IndexerId", message.Episode.Release.IndexerId.ToString());
|
||||
history.Data.Add("ReleaseType", message.Episode.ParsedEpisodeInfo.ReleaseType.ToString());
|
||||
|
||||
if (!message.Episode.ParsedEpisodeInfo.ReleaseHash.IsNullOrWhiteSpace())
|
||||
|
@ -223,6 +224,7 @@ namespace NzbDrone.Core.History
|
|||
history.Data.Add("CustomFormatScore", message.EpisodeInfo.CustomFormatScore.ToString());
|
||||
history.Data.Add("Size", message.EpisodeInfo.Size.ToString());
|
||||
history.Data.Add("IndexerFlags", message.ImportedEpisode.IndexerFlags.ToString());
|
||||
history.Data.Add("IndexerId", message.ImportedEpisode.IndexerId.ToString());
|
||||
history.Data.Add("ReleaseType", message.ImportedEpisode.ReleaseType.ToString());
|
||||
|
||||
_historyRepository.Insert(history);
|
||||
|
@ -284,6 +286,7 @@ namespace NzbDrone.Core.History
|
|||
history.Data.Add("Reason", message.Reason.ToString());
|
||||
history.Data.Add("ReleaseGroup", message.EpisodeFile.ReleaseGroup);
|
||||
history.Data.Add("Size", message.EpisodeFile.Size.ToString());
|
||||
history.Data.Add("IndexerId", message.EpisodeFile.IndexerId.ToString());
|
||||
history.Data.Add("IndexerFlags", message.EpisodeFile.IndexerFlags.ToString());
|
||||
history.Data.Add("ReleaseType", message.EpisodeFile.ReleaseType.ToString());
|
||||
|
||||
|
@ -318,6 +321,7 @@ namespace NzbDrone.Core.History
|
|||
history.Data.Add("ReleaseGroup", message.EpisodeFile.ReleaseGroup);
|
||||
history.Data.Add("Size", message.EpisodeFile.Size.ToString());
|
||||
history.Data.Add("IndexerFlags", message.EpisodeFile.IndexerFlags.ToString());
|
||||
history.Data.Add("IndexerId", message.EpisodeFile.IndexerId.ToString());
|
||||
history.Data.Add("ReleaseType", message.EpisodeFile.ReleaseType.ToString());
|
||||
|
||||
_historyRepository.Insert(history);
|
||||
|
|
|
@ -37,6 +37,18 @@ namespace NzbDrone.Core.Indexers
|
|||
return base.Active().Where(c => c.Enable).ToList();
|
||||
}
|
||||
|
||||
public virtual object RequestAction(string action, IDictionary<string, string> query)
|
||||
{
|
||||
_logger.Info("HELLO WORLD");
|
||||
|
||||
if (action == "getIndexerList")
|
||||
{
|
||||
return GetAvailableProviders();
|
||||
}
|
||||
|
||||
return new { };
|
||||
}
|
||||
|
||||
public override void SetProviderCharacteristics(IIndexer provider, IndexerDefinition definition)
|
||||
{
|
||||
base.SetProviderCharacteristics(provider, definition);
|
||||
|
|
|
@ -284,6 +284,7 @@
|
|||
"CustomFormatsSettingsSummary": "Custom Formats and Settings",
|
||||
"CustomFormatsSettingsTriggerInfo": "A Custom Format will be applied to a release or file when it matches at least one of each of the different condition types chosen.",
|
||||
"CustomFormatsSpecificationFlag": "Flag",
|
||||
"CustomFormatsSpecificationIndexer": "Indexer",
|
||||
"CustomFormatsSpecificationLanguage": "Language",
|
||||
"CustomFormatsSpecificationMaximumSize": "Maximum Size",
|
||||
"CustomFormatsSpecificationMaximumSizeHelpText": "Release must be less than or equal to this size",
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||
public string ReleaseGroup { get; set; }
|
||||
public string ReleaseHash { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public int IndexerId { get; set; }
|
||||
public IndexerFlags IndexerFlags { get; set; }
|
||||
public MediaInfoModel MediaInfo { get; set; }
|
||||
public LazyLoaded<List<Episode>> Episodes { get; set; }
|
||||
|
|
|
@ -97,6 +97,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
|||
episodeFile.ReleaseGroup = localEpisode.ReleaseGroup;
|
||||
episodeFile.ReleaseHash = localEpisode.ReleaseHash;
|
||||
episodeFile.Languages = localEpisode.Languages;
|
||||
episodeFile.IndexerId = localEpisode.IndexerId;
|
||||
|
||||
// Prefer the release type from the download client, folder and finally the file so we have the most accurate information.
|
||||
episodeFile.ReleaseType = localEpisode.DownloadClientEpisodeInfo?.ReleaseType ??
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
|||
public List<Language> Languages { get; set; }
|
||||
public string ReleaseGroup { get; set; }
|
||||
public int IndexerFlags { get; set; }
|
||||
public int IndexerId { get; set; }
|
||||
public ReleaseType ReleaseType { get; set; }
|
||||
public string DownloadId { get; set; }
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
|||
public List<CustomFormat> CustomFormats { get; set; }
|
||||
public int CustomFormatScore { get; set; }
|
||||
public int IndexerFlags { get; set; }
|
||||
public int IndexerId { get; set; }
|
||||
public ReleaseType ReleaseType { get; set; }
|
||||
public IEnumerable<Rejection> Rejections { get; set; }
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
|||
{
|
||||
List<ManualImportItem> GetMediaFiles(int seriesId, int? seasonNumber);
|
||||
List<ManualImportItem> GetMediaFiles(string path, string downloadId, int? seriesId, bool filterExistingFiles);
|
||||
ManualImportItem ReprocessItem(string path, string downloadId, int seriesId, int? seasonNumber, List<int> episodeIds, string releaseGroup, QualityModel quality, List<Language> languages, int indexerFlags, ReleaseType releaseType);
|
||||
ManualImportItem ReprocessItem(string path, string downloadId, int seriesId, int? seasonNumber, List<int> episodeIds, string releaseGroup, QualityModel quality, List<Language> languages, int indexerFlags, int indexerId, ReleaseType releaseType);
|
||||
}
|
||||
|
||||
public class ManualImportService : IExecute<ManualImportCommand>, IManualImportService
|
||||
|
@ -139,7 +139,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
|||
return ProcessFolder(path, path, downloadId, seriesId, filterExistingFiles);
|
||||
}
|
||||
|
||||
public ManualImportItem ReprocessItem(string path, string downloadId, int seriesId, int? seasonNumber, List<int> episodeIds, string releaseGroup, QualityModel quality, List<Language> languages, int indexerFlags, ReleaseType releaseType)
|
||||
public ManualImportItem ReprocessItem(string path, string downloadId, int seriesId, int? seasonNumber, List<int> episodeIds, string releaseGroup, QualityModel quality, List<Language> languages, int indexerFlags, int indexerId, ReleaseType releaseType)
|
||||
{
|
||||
var rootFolder = Path.GetDirectoryName(path);
|
||||
var series = _seriesService.GetSeries(seriesId);
|
||||
|
@ -170,6 +170,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
|||
localEpisode.Languages = languages?.Count <= 1 && (languages?.SingleOrDefault() ?? Language.Unknown) == Language.Unknown ? languageParse : languages;
|
||||
localEpisode.Quality = quality.Quality == Quality.Unknown ? QualityParser.ParseQuality(path) : quality;
|
||||
localEpisode.IndexerFlags = (IndexerFlags)indexerFlags;
|
||||
localEpisode.IndexerId = indexerId;
|
||||
localEpisode.ReleaseType = releaseType;
|
||||
|
||||
localEpisode.CustomFormats = _formatCalculator.ParseCustomFormat(localEpisode);
|
||||
|
@ -202,6 +203,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
|||
Languages = languages?.Count <= 1 && (languages?.SingleOrDefault() ?? Language.Unknown) == Language.Unknown ? LanguageParser.ParseLanguages(path) : languages,
|
||||
Quality = quality.Quality == Quality.Unknown ? QualityParser.ParseQuality(path) : quality,
|
||||
IndexerFlags = (IndexerFlags)indexerFlags,
|
||||
IndexerId = indexerId,
|
||||
ReleaseType = releaseType
|
||||
};
|
||||
|
||||
|
@ -428,6 +430,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
|||
item.Size = _diskProvider.GetFileSize(decision.LocalEpisode.Path);
|
||||
item.Rejections = decision.Rejections;
|
||||
item.IndexerFlags = (int)decision.LocalEpisode.IndexerFlags;
|
||||
item.IndexerId = decision.LocalEpisode.IndexerId;
|
||||
item.ReleaseType = decision.LocalEpisode.ReleaseType;
|
||||
|
||||
return item;
|
||||
|
@ -448,6 +451,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
|||
item.Quality = episodeFile.Quality;
|
||||
item.Languages = episodeFile.Languages;
|
||||
item.IndexerFlags = (int)episodeFile.IndexerFlags;
|
||||
item.IndexerId = episodeFile.IndexerId;
|
||||
item.ReleaseType = episodeFile.ReleaseType;
|
||||
item.Size = _diskProvider.GetFileSize(item.Path);
|
||||
item.Rejections = Enumerable.Empty<Rejection>();
|
||||
|
@ -486,6 +490,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
|||
Quality = file.Quality,
|
||||
Languages = file.Languages,
|
||||
IndexerFlags = (IndexerFlags)file.IndexerFlags,
|
||||
IndexerId = file.IndexerId,
|
||||
ReleaseType = file.ReleaseType,
|
||||
Series = series,
|
||||
Size = 0
|
||||
|
@ -516,6 +521,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
|||
localEpisode.Quality = file.Quality;
|
||||
localEpisode.Languages = file.Languages;
|
||||
localEpisode.IndexerFlags = (IndexerFlags)file.IndexerFlags;
|
||||
localEpisode.IndexerId = file.IndexerId;
|
||||
localEpisode.ReleaseType = file.ReleaseType;
|
||||
|
||||
// TODO: Cleanup non-tracked downloads
|
||||
|
|
|
@ -91,6 +91,7 @@ namespace NzbDrone.Core.Notifications.CustomScript
|
|||
environmentVariables.Add("Sonarr_Release_QualityVersion", remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version.ToString());
|
||||
environmentVariables.Add("Sonarr_Release_ReleaseGroup", releaseGroup ?? string.Empty);
|
||||
environmentVariables.Add("Sonarr_Release_IndexerFlags", remoteEpisode.Release.IndexerFlags.ToString());
|
||||
environmentVariables.Add("Sonarr_Release_IndexerId", remoteEpisode.Release.IndexerId.ToString());
|
||||
environmentVariables.Add("Sonarr_Download_Client", message.DownloadClientName ?? string.Empty);
|
||||
environmentVariables.Add("Sonarr_Download_Client_Type", message.DownloadClientType ?? string.Empty);
|
||||
environmentVariables.Add("Sonarr_Download_Id", message.DownloadId ?? string.Empty);
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace NzbDrone.Core.Parser.Model
|
|||
{
|
||||
public string Title { get; set; }
|
||||
public string Indexer { get; set; }
|
||||
public int IndexerId { get; set; }
|
||||
public long Size { get; set; }
|
||||
|
||||
public List<int> EpisodeIds { get; set; }
|
||||
|
@ -18,11 +19,14 @@ namespace NzbDrone.Core.Parser.Model
|
|||
var episodeIds = grabbedHistories.Select(h => h.EpisodeId).Distinct().ToList();
|
||||
|
||||
grabbedHistory.Data.TryGetValue("indexer", out var indexer);
|
||||
grabbedHistory.Data.TryGetValue("indexerId", out var indexerIdString);
|
||||
grabbedHistory.Data.TryGetValue("size", out var sizeString);
|
||||
long.TryParse(sizeString, out var size);
|
||||
int.TryParse(indexerIdString, out var indexerId);
|
||||
|
||||
Title = grabbedHistory.SourceTitle;
|
||||
Indexer = indexer;
|
||||
IndexerId = indexerId;
|
||||
Size = size;
|
||||
EpisodeIds = episodeIds;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace NzbDrone.Core.Parser.Model
|
|||
public QualityModel Quality { get; set; }
|
||||
public List<Language> Languages { get; set; }
|
||||
public IndexerFlags IndexerFlags { get; set; }
|
||||
public int IndexerId { get; set; }
|
||||
public ReleaseType ReleaseType { get; set; }
|
||||
public MediaInfoModel MediaInfo { get; set; }
|
||||
public bool ExistingFile { get; set; }
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace Sonarr.Api.V3.EpisodeFiles
|
|||
public List<CustomFormatResource> CustomFormats { get; set; }
|
||||
public int CustomFormatScore { get; set; }
|
||||
public int? IndexerFlags { get; set; }
|
||||
public int IndexerId { get; set; }
|
||||
public ReleaseType? ReleaseType { get; set; }
|
||||
public MediaInfoResource MediaInfo { get; set; }
|
||||
|
||||
|
@ -65,6 +66,7 @@ namespace Sonarr.Api.V3.EpisodeFiles
|
|||
CustomFormats = customFormats.ToResource(false),
|
||||
CustomFormatScore = customFormatScore,
|
||||
IndexerFlags = (int)model.IndexerFlags,
|
||||
IndexerId = model.IndexerId,
|
||||
ReleaseType = model.ReleaseType,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace Sonarr.Api.V3.ManualImport
|
|||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
var processedItem = _manualImportService.ReprocessItem(item.Path, item.DownloadId, item.SeriesId, item.SeasonNumber, item.EpisodeIds ?? new List<int>(), item.ReleaseGroup, item.Quality, item.Languages, item.IndexerFlags, item.ReleaseType);
|
||||
var processedItem = _manualImportService.ReprocessItem(item.Path, item.DownloadId, item.SeriesId, item.SeasonNumber, item.EpisodeIds ?? new List<int>(), item.ReleaseGroup, item.Quality, item.Languages, item.IndexerFlags, item.IndexerId, item.ReleaseType);
|
||||
|
||||
item.SeasonNumber = processedItem.SeasonNumber;
|
||||
item.Episodes = processedItem.Episodes.ToResource();
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace Sonarr.Api.V3.ManualImport
|
|||
public List<CustomFormatResource> CustomFormats { get; set; }
|
||||
public int CustomFormatScore { get; set; }
|
||||
public int IndexerFlags { get; set; }
|
||||
public int IndexerId { get; set; }
|
||||
public ReleaseType ReleaseType { get; set; }
|
||||
public IEnumerable<Rejection> Rejections { get; set; }
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace Sonarr.Api.V3.ManualImport
|
|||
public List<CustomFormatResource> CustomFormats { get; set; }
|
||||
public int CustomFormatScore { get; set; }
|
||||
public int IndexerFlags { get; set; }
|
||||
public int IndexerId { get; set; }
|
||||
public ReleaseType ReleaseType { get; set; }
|
||||
public IEnumerable<Rejection> Rejections { get; set; }
|
||||
}
|
||||
|
@ -62,6 +63,7 @@ namespace Sonarr.Api.V3.ManualImport
|
|||
EpisodeFileId = model.EpisodeFileId,
|
||||
ReleaseGroup = model.ReleaseGroup,
|
||||
Quality = model.Quality,
|
||||
IndexerId = model.IndexerId,
|
||||
Languages = model.Languages,
|
||||
CustomFormats = customFormats.ToResource(false),
|
||||
CustomFormatScore = customFormatScore,
|
||||
|
|
Loading…
Reference in New Issue