forked from sim0n00ps/OF-DL
Compare commits
No commits in common. "master" and "master" have entirely different histories.
@ -1,5 +0,0 @@
|
|||||||
<Project>
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="CsvHelper" Version="33.0.1"/>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
@ -2873,80 +2873,4 @@ public class APIHelper : IAPIHelper
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Dictionary<string, Subscriptions.List>?> GetActiveSubscribed(string endpoint, bool includeRestricted, IDownloadConfig config)
|
|
||||||
{
|
|
||||||
Dictionary<string, string> getParams = new()
|
|
||||||
{
|
|
||||||
{ "offset", "0" },
|
|
||||||
{ "limit", "50" },
|
|
||||||
{ "type", "active" },
|
|
||||||
{ "format", "infinite"}
|
|
||||||
};
|
|
||||||
|
|
||||||
return await GetSubscriptions(getParams, endpoint, includeRestricted, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Dictionary<string, Subscriptions.List>?> GetSubscriptions(Dictionary<string, string> getParams, string endpoint, bool includeRestricted, IDownloadConfig config)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Dictionary<string, Entities.Subscriptions.List> users = new();
|
|
||||||
Subscriptions subscriptions = new();
|
|
||||||
|
|
||||||
Log.Debug("Calling GetAllSubscrptions");
|
|
||||||
|
|
||||||
string? body = await BuildHeaderAndExecuteRequests(getParams, endpoint, new HttpClient());
|
|
||||||
|
|
||||||
subscriptions = JsonConvert.DeserializeObject<Subscriptions>(body);
|
|
||||||
if (subscriptions is { hasMore: true })
|
|
||||||
{
|
|
||||||
getParams["offset"] = subscriptions.list.Count.ToString();
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
Subscriptions newSubscriptions = new();
|
|
||||||
string? loopbody = await BuildHeaderAndExecuteRequests(getParams, endpoint, new HttpClient());
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(loopbody) && (!loopbody.Contains("[]") || loopbody.Trim() != "[]"))
|
|
||||||
{
|
|
||||||
newSubscriptions = JsonConvert.DeserializeObject<Subscriptions>(loopbody, m_JsonSerializerSettings);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
subscriptions.list.AddRange(newSubscriptions.list);
|
|
||||||
if (!newSubscriptions.hasMore)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
getParams["offset"] = subscriptions.list.Count.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (Subscriptions.List subscription in subscriptions.list)
|
|
||||||
{
|
|
||||||
if ((!(subscription.isRestricted ?? false) || ((subscription.isRestricted ?? false) && includeRestricted)))
|
|
||||||
{
|
|
||||||
users.TryAdd(subscription.username, subscription);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Exception caught: {0}\n\nStackTrace: {1}", ex.Message, ex.StackTrace);
|
|
||||||
Log.Error("Exception caught: {0}\n\nStackTrace: {1}", ex.Message, ex.StackTrace);
|
|
||||||
if (ex.InnerException != null)
|
|
||||||
{
|
|
||||||
Console.WriteLine("\nInner Exception:");
|
|
||||||
Console.WriteLine("Exception caught: {0}\n\nStackTrace: {1}", ex.InnerException.Message, ex.InnerException.StackTrace);
|
|
||||||
Log.Error("Inner Exception: {0}\n\nStackTrace: {1}", ex.InnerException.Message, ex.InnerException.StackTrace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,50 +1,49 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<RootNamespace>OF_DL</RootNamespace>
|
<RootNamespace>OF_DL</RootNamespace>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ApplicationIcon>Icon\download.ico</ApplicationIcon>
|
<ApplicationIcon>Icon\download.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Icon\download.ico" />
|
<Content Include="Icon\download.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Akka" Version="1.5.39" />
|
<PackageReference Include="Akka" Version="1.5.39" />
|
||||||
<PackageReference Include="BouncyCastle.NetCore" Version="2.2.1" />
|
<PackageReference Include="BouncyCastle.NetCore" Version="2.2.1" />
|
||||||
<PackageReference Include="HtmlAgilityPack" Version="1.12.0" />
|
<PackageReference Include="HtmlAgilityPack" Version="1.12.0" />
|
||||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.3" />
|
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.3" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="protobuf-net" Version="3.2.46" />
|
<PackageReference Include="protobuf-net" Version="3.2.46" />
|
||||||
<PackageReference Include="PuppeteerSharp" Version="20.1.3" />
|
<PackageReference Include="PuppeteerSharp" Version="20.1.3" />
|
||||||
<PackageReference Include="Serilog" Version="4.2.0" />
|
<PackageReference Include="Serilog" Version="4.2.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||||
<PackageReference Include="System.Reactive" Version="6.0.1" />
|
<PackageReference Include="System.Reactive" Version="6.0.1" />
|
||||||
<PackageReference Include="xFFmpeg.NET" Version="7.2.0" />
|
<PackageReference Include="xFFmpeg.NET" Version="7.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Spectre.Console">
|
<Reference Include="Spectre.Console">
|
||||||
<HintPath>References\Spectre.Console.dll</HintPath>
|
<HintPath>References\Spectre.Console.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="auth.json">
|
<None Update="auth.json">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="config.conf">
|
<None Update="config.conf">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="rules.json">
|
<None Update="rules.json">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Import Project="Extension.props" />
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -844,17 +844,9 @@ public class Program
|
|||||||
{
|
{
|
||||||
DateTime startTime = DateTime.Now;
|
DateTime startTime = DateTime.Now;
|
||||||
Dictionary<string, int> users = new();
|
Dictionary<string, int> users = new();
|
||||||
var activeSubbed = await m_ApiHelper.GetActiveSubscribed("/subscriptions/subscribes", Config.IncludeRestrictedSubscriptions, Config);
|
Dictionary<string, int> activeSubs = await m_ApiHelper.GetActiveSubscriptions("/subscriptions/subscribes", Config.IncludeRestrictedSubscriptions, Config);
|
||||||
var activeSubs = activeSubbed?.ToDictionary(e => e.Key, e => e.Value.id);
|
|
||||||
{
|
Log.Debug("Subscriptions: ");
|
||||||
if (Directory.Exists(Config.DownloadPath) && activeSubbed != null)
|
|
||||||
{
|
|
||||||
var reportPath = Path.Combine(Config.DownloadPath, "Report.csv");
|
|
||||||
var report = new Reporting(activeSubbed?.Values);
|
|
||||||
report.GenerateReport(reportPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log.Debug("Subscriptions: ");
|
|
||||||
|
|
||||||
foreach (KeyValuePair<string, int> activeSub in activeSubs)
|
foreach (KeyValuePair<string, int> activeSub in activeSubs)
|
||||||
{
|
{
|
||||||
|
@ -1,106 +0,0 @@
|
|||||||
using CsvHelper;
|
|
||||||
using CsvHelper.Configuration;
|
|
||||||
using System.Formats.Asn1;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace OF_DL;
|
|
||||||
|
|
||||||
internal class Reporting(IEnumerable<Entities.Subscriptions.List> subscribedUsers)
|
|
||||||
{
|
|
||||||
public void GenerateReport(string reportPath)
|
|
||||||
{
|
|
||||||
using var fileStream = File.Open(reportPath, FileMode.Create);
|
|
||||||
using var streamWriter = new StreamWriter(fileStream);
|
|
||||||
using var csvWriter = new CsvWriter(streamWriter, CultureInfo.InvariantCulture);
|
|
||||||
|
|
||||||
csvWriter.Context.RegisterClassMap<UserReportViewModelClassMap>();
|
|
||||||
csvWriter.WriteRecords(subscribedUsers.Select(user => new UserReportViewModel(user)).OrderByDescending(e => e.category).ThenBy(e => e.currentTotal));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class UserReportViewModel
|
|
||||||
{
|
|
||||||
private readonly Entities.Subscriptions.List source;
|
|
||||||
|
|
||||||
public const long YoursId = 817758071L;
|
|
||||||
public const long MineId = 817758033L;
|
|
||||||
public const decimal tax = 0.2m;
|
|
||||||
|
|
||||||
private Lazy<string> _category;
|
|
||||||
private Lazy<decimal?> _currentPrice;
|
|
||||||
private Lazy<decimal?> _nextPrice;
|
|
||||||
|
|
||||||
public UserReportViewModel(Entities.Subscriptions.List source)
|
|
||||||
{
|
|
||||||
this.source = source;
|
|
||||||
_category = new Lazy<string>(GetCategory);
|
|
||||||
_currentPrice = new Lazy<decimal?>(() => decimal.TryParse(source.subscribedByData.price, out var price) ? price : null);
|
|
||||||
_nextPrice = new Lazy<decimal?>(() => decimal.TryParse(source.subscribedByData.regularPrice, out var price) ? price : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string name => source.name;
|
|
||||||
|
|
||||||
public string username => source.username;
|
|
||||||
|
|
||||||
public string category => GetCategory();
|
|
||||||
|
|
||||||
public string status => GetStatus();
|
|
||||||
|
|
||||||
public DateTime? until => source.subscribedByData.expiredAt;
|
|
||||||
|
|
||||||
public decimal? currentPrice => _currentPrice.Value;
|
|
||||||
|
|
||||||
public decimal? currentTax => currentPrice * tax;
|
|
||||||
|
|
||||||
public decimal? currentTotal => currentPrice + currentTax;
|
|
||||||
|
|
||||||
public decimal? renewPrice => _nextPrice.Value;
|
|
||||||
|
|
||||||
public decimal? renewTax => renewPrice * tax;
|
|
||||||
|
|
||||||
public decimal? renewTotal => renewPrice + renewTax;
|
|
||||||
|
|
||||||
public string GetCategory()
|
|
||||||
{
|
|
||||||
if (source.listsStates.SingleOrDefault(l => l.id is long intId && intId == YoursId && l.hasUser == true) is { } yours)
|
|
||||||
{
|
|
||||||
return yours.name;
|
|
||||||
}
|
|
||||||
if (source.listsStates.SingleOrDefault(l => l.id is long intId && intId == MineId && l.hasUser == true) is { } mine)
|
|
||||||
{
|
|
||||||
return mine.name;
|
|
||||||
}
|
|
||||||
return "None";
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetStatus()
|
|
||||||
{
|
|
||||||
if (source.subscribedByData is { } subData)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(subData.status)) return subData.status;
|
|
||||||
return "Subscribed";
|
|
||||||
}
|
|
||||||
return "API Error";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class UserReportViewModelClassMap : ClassMap<UserReportViewModel>
|
|
||||||
{
|
|
||||||
public UserReportViewModelClassMap()
|
|
||||||
{
|
|
||||||
var index = 0;
|
|
||||||
Map(m => m.name).Index(index++).Name("Name");
|
|
||||||
Map(m => m.username).Index(index++).Name("Username");
|
|
||||||
Map(m => m.category).Index(index++).Name("Category");
|
|
||||||
Map(m => m.status).Index(index++).Name("Status");
|
|
||||||
Map(m => m.until).Index(index++).Name("Until");
|
|
||||||
Map(m => m.currentPrice).Index(index++).Name("Price");
|
|
||||||
Map(m => m.currentTax).Index(index++).Name("Tax");
|
|
||||||
Map(m => m.currentTotal).Index(index++).Name("Total");
|
|
||||||
Map(m => m.renewPrice).Index(index++).Name("Price");
|
|
||||||
Map(m => m.renewTax).Index(index++).Name("Tax");
|
|
||||||
Map(m => m.renewTotal).Index(index++).Name("Total");
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user