增加同步指定博主的作品

This commit is contained in:
lijianyou
2025-10-19 01:11:55 +08:00
parent 14a709e691
commit 59ce4f59ed
25 changed files with 1865 additions and 277 deletions
+11
View File
@@ -63,5 +63,16 @@ namespace dy.net.service
sqlSugarClient.Updateable(collectViedos).ExecuteCommand();
}
}
/// <summary>
/// 重置所有Cookie的同步状态为0
/// </summary>
/// <returns></returns>
public bool UpdateAllCookieSyncedToZero()
{
var sql = "update dy_cookie set CollHasSyncd=0,FavHasSyncd=0,UperSyncd=0";
return sqlSugarClient.Ado.ExecuteCommand(sql) > 0;
}
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
using dy.net.model;
using dy.net.repository;
using SqlSugar;
using System.Linq.Expressions;
namespace dy.net.service
@@ -34,7 +35,7 @@ namespace dy.net.service
}
return _cookieRepository.Insert(dyUserCookies);
}
// 查询单个
public async Task<DyUserCookies> GetByIdAsync(string id)
{
+451 -153
View File
@@ -9,9 +9,7 @@ namespace dy.net.service
{
public class DyHttpClientService
{
private static readonly string CollectApi = "https://www.douyin.com/aweme/v1/web/aweme/listcollection/";
private static readonly string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36";
public static readonly string DouYinApi = "https://www.douyin.com/aweme/v1/web/aweme";
// 随机数生成器(避免重复实例化,保证随机性)
private readonly IHttpClientFactory _clientFactory;
public DyHttpClientService(IHttpClientFactory clientFactory)
@@ -45,26 +43,27 @@ namespace dy.net.service
try
{
using var httpClient = _clientFactory.CreateClient("douyin");
using var httpClient = _clientFactory.CreateClient("dy_collect");
if (httpClient.DefaultRequestHeaders.Contains("Cookie"))
{
httpClient.DefaultRequestHeaders.Remove("Cookie");
}
httpClient.DefaultRequestHeaders.Add("Cookie", cookie);
var dics = CreateUserCollectHeader();
dics.Add("cursor", cursor);
dics.Add("count", count);
var dics = DySyncBaseParamDics.CollectParams;
dics["cursor"]=cursor;
dics["count"] = count;
try
{
var token = await TokenManager.GenRealMsTokenAsync();
dics.Add("msToken", token);
dics["msToken"] = token;
}
catch (Exception ex)
{
Serilog.Log.Error($"获取mstoken失败{ex.Message}");
}
var endPoint = BogusManager.XbModel2Endpoint(CollectApi, dics, UserAgent);
string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36";
var endPoint = BogusManager.XbModel2Endpoint($"{DouYinApi}/listcollection", dics, UserAgent);
var respose = await httpClient.PostAsync(endPoint, null);
if (respose.IsSuccessStatusCode)
{
@@ -87,12 +86,13 @@ namespace dy.net.service
/// <summary>
/// 查询用户喜欢的视频
/// </summary>
/// <param name="count"></param>
/// <param name="cursor"></param>
/// <param name="secUserId"></param>
/// <param name="cookie"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public async Task<CollectVideoInfo> SyncFavoriteVideos(string cursor, string secUserId, string cookie)
public async Task<CollectVideoInfo> SyncFavoriteVideos(string count,string cursor, string secUserId, string cookie)
{
if (string.IsNullOrWhiteSpace(cursor))
{
@@ -111,20 +111,24 @@ namespace dy.net.service
try
{
using var httpClient = _clientFactory.CreateClient("douyinfav");
using var httpClient = _clientFactory.CreateClient("dy_favorite");
if (httpClient.DefaultRequestHeaders.Contains("Cookie"))
{
httpClient.DefaultRequestHeaders.Remove("Cookie");
}
httpClient.DefaultRequestHeaders.Add("Cookie", cookie);
var dics = CreateUserFavoriteParams();
dics.Add("max_cursor", cursor);
dics.Add("sec_user_id", secUserId);
var dics = DySyncBaseParamDics.FavoriteParams;
{
// 添加动态参数
dics["max_cursor"] = cursor;
dics["sec_user_id"] = secUserId;
dics["count"] = count;
}
// 构建请求URL
string baseUrl = "https://www.douyin.com/aweme/v1/web/aweme/favorite/";
var queryString = new FormUrlEncodedContent(dics);
string fullUrl = $"{baseUrl}?{await queryString.ReadAsStringAsync()}";
string fullUrl = $"{DouYinApi}/favorite?{await queryString.ReadAsStringAsync()}";
var respose = await httpClient.GetAsync(fullUrl);
if (respose.IsSuccessStatusCode)
{
@@ -145,170 +149,464 @@ namespace dy.net.service
}
/// <summary>
/// 下载文件并保存到本地
/// 查询Up主作品
/// </summary>
/// <param name="videoUrl">文件地址</param>
/// <param name="savePath">保存路径</param>
public async Task<bool> DownloadAsync(string videoUrl, string savePath, string cookie)
/// <param name="count"></param>
/// <param name="cursor"></param>
/// <param name="secUserId"></param>
/// <param name="cookie"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public async Task<CollectVideoInfo> SyncUpderPostVideos(string count, string cursor, string secUserId, string cookie)
{
if (string.IsNullOrWhiteSpace(cursor))
{
throw new ArgumentException($"“{nameof(cursor)}”不能为 null 或空。", nameof(cursor));
}
if (string.IsNullOrWhiteSpace(secUserId))
{
throw new ArgumentException($"“{nameof(secUserId)}”不能为 null 或空。", nameof(secUserId));
}
if (string.IsNullOrWhiteSpace(cookie))
{
throw new ArgumentException($"“{nameof(cookie)}”不能为 null 或空。", nameof(cookie));
}
try
{
// 防止文件被占用,先删除已存在的文件
if (File.Exists(savePath))
using var httpClient = _clientFactory.CreateClient("dy_uper");
if (httpClient.DefaultRequestHeaders.Contains("Cookie"))
{
File.Delete(savePath);
httpClient.DefaultRequestHeaders.Remove("Cookie");
}
// 创建HTTP客户端(设置超时时间和请求头)
using (var httpClient = _clientFactory.CreateClient("douyin"))
httpClient.DefaultRequestHeaders.Add("Cookie", cookie);
var parameters = DySyncBaseParamDics.UpderPostParams;
{
if (httpClient.DefaultRequestHeaders.Contains("Cookie"))
{
httpClient.DefaultRequestHeaders.Remove("Cookie");
}
httpClient.DefaultRequestHeaders.Add("Cookie", cookie);
httpClient.Timeout = TimeSpan.FromMinutes(5); // 设置5分钟超时
// 获取视频流
using (var response = await httpClient.GetAsync(videoUrl, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode(); // 确保请求成功
// 获取文件总大小(用于进度显示)
long? totalBytes = response.Content.Headers.ContentLength;
// 读取流并写入文件
using (var stream = await response.Content.ReadAsStreamAsync())
using (var fileStream = new FileStream(savePath, FileMode.CreateNew))
{
byte[] buffer = new byte[8192];
int bytesRead;
long totalRead = 0;
// 循环读取并写入
while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await fileStream.WriteAsync(buffer, 0, bytesRead);
totalRead += bytesRead;
// 显示下载进度
if (totalBytes.HasValue)
{
double progress = (double)totalRead / totalBytes.Value * 100;
//Console.Write($"\r下载进度:{progress:F2}% ({totalRead}/{totalBytes.Value} bytes)");
}
}
//Console.WriteLine(); // 进度显示结束后换行
}
}
// 添加动态参数
parameters["max_cursor"] = cursor;
parameters["sec_user_id"] = secUserId;
parameters["count"] = count;
}
// 构建请求URL
var queryString = new FormUrlEncodedContent(parameters);
string fullUrl = $"{DouYinApi}/post?{await queryString.ReadAsStringAsync()}";
var ablog = new ABogus();//计算X-Bogus
var a_bogus = ablog.GetValue(parameters);
fullUrl += $"&X-Bogus={a_bogus}";
var respose = await httpClient.GetAsync(fullUrl);
if (respose.IsSuccessStatusCode)
{
var data = await respose.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<CollectVideoInfo>(data);
}
else
{
Serilog.Log.Error($"SyncUpderPostVideos fail: {respose.StatusCode}");
return null;
}
return true;
}
catch (Exception ex)
{
Serilog.Log.Error($"DownloadVideoAsync fail: {ex.Message}");
Serilog.Log.Error($"DownloadVideoAsync fail: {ex.StackTrace}");
return false;
Serilog.Log.Error($"SyncUpderPostVideos error: {ex.Message}");
return null;
}
}
//AI优化2
/// <summary>
/// 下载文件并保存到本地(支持重试机制,优化批量下载稳定性)
/// </summary>
/// <param name="videoUrl">文件地址</param>
/// <param name="savePath">保存路径</param>
/// <param name="cookie">请求Cookie</param>
/// <param name="httpclientName">HttpClient名称(默认"dy_down1"</param>
/// <param name="cancellationToken">取消令牌(用于终止任务)</param>
/// <param name="streamTimeout">流读取超时时间(默认60秒)</param>
/// <param name="maxRetryCount">最大重试次数(默认3次)</param>
/// <param name="initialRetryDelay">初始重试延迟(默认1秒,指数退避)</param>
/// <returns>是否下载成功</returns>
public async Task<bool> DownloadAsync(
string videoUrl,
string savePath,
string cookie,
CancellationToken cancellationToken = default,
TimeSpan? streamTimeout = null,
int maxRetryCount = 3,
TimeSpan? initialRetryDelay = null)
{
// 重试参数初始化
int retryCount = 0;
var retryDelay = initialRetryDelay ?? TimeSpan.FromSeconds(1); // 初始延迟1秒
streamTimeout ??= TimeSpan.FromSeconds(60); // 流读取超时默认60秒
while (true)
{
try
{
// 执行单次下载逻辑(提取为内部方法,避免代码重复)
return await TryDownloadOnceAsync(
videoUrl, savePath, cookie, cancellationToken, streamTimeout.Value);
}
catch (Exception ex) when (IsRetryableException(ex) && retryCount < maxRetryCount)
{
// 可重试异常且未达最大次数,等待后重试
retryCount++;
var delay = TimeSpan.FromMilliseconds(retryDelay.TotalMilliseconds * Math.Pow(2, retryCount - 1)); // 指数退避(1s→2s→4s...
Serilog.Log.Warning(ex, $"下载失败(第{retryCount}/{maxRetryCount}次重试):{videoUrl},将在{delay.TotalSeconds:F1}秒后重试");
try
{
// 等待重试延迟(响应取消令牌)
await Task.Delay(delay, cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
// 等待期间被取消,直接返回失败
Serilog.Log.Information($"重试等待被取消:{videoUrl}");
return false;
}
}
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
// 主动取消,不重试
Serilog.Log.Information($"下载被取消:{videoUrl}");
return false;
}
catch (Exception ex)
{
// 不可重试的异常(如参数错误、权限不足等),直接失败
Serilog.Log.Error(ex, $"下载失败(不可重试):{videoUrl}");
CleanupIncompleteFile(savePath); // 清理不完整文件
return false;
}
}
}
/// <summary>
/// 清理文件名中的非法字符
/// 单次下载尝试(核心下载逻辑)
/// </summary>
static string SanitizeFileName(string fileName)
private async Task<bool> TryDownloadOnceAsync(
string videoUrl,
string savePath,
string cookie,
CancellationToken cancellationToken,
TimeSpan streamTimeout)
{
foreach (char c in Path.GetInvalidFileNameChars())
DateTime lastStreamActivity = DateTime.UtcNow; // 流活动时间戳
// 确保目录存在
var directory = Path.GetDirectoryName(savePath);
if (!Directory.Exists(directory))
{
fileName = fileName.Replace(c, '_');
Directory.CreateDirectory(directory);
}
// 限制文件名长度
return fileName.Length > 100 ? fileName.Substring(0, 100) : fileName;
// 清理已存在的文件(避免占用)
CleanupIncompleteFile(savePath);
using (var httpClient = _clientFactory.CreateClient("dy_download"))
{
// 配置请求头
httpClient.DefaultRequestHeaders.Remove("Cookie");
httpClient.DefaultRequestHeaders.Add("Cookie", cookie);
httpClient.Timeout = TimeSpan.FromMinutes(5); // 总请求超时
// 发送请求
using (var response = await httpClient.GetAsync(
videoUrl,
HttpCompletionOption.ResponseHeadersRead,
cancellationToken).ConfigureAwait(false))
{
response.EnsureSuccessStatusCode(); // 验证HTTP状态
long? totalBytes = response.Content.Headers.ContentLength;
// 读取流并写入文件
using (var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false))
using (var fileStream = new FileStream(
savePath,
FileMode.CreateNew,
FileAccess.Write,
FileShare.None,
bufferSize: 8192,
options: FileOptions.Asynchronous | FileOptions.SequentialScan))
{
byte[] buffer = new byte[8192];
int bytesRead;
long totalRead = 0;
while ((bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) > 0)
{
// 检查流读取超时
if (DateTime.UtcNow - lastStreamActivity > streamTimeout)
{
throw new TimeoutException($"流读取超时({streamTimeout.TotalSeconds}秒无数据)");
}
await fileStream.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
totalRead += bytesRead;
lastStreamActivity = DateTime.UtcNow;
// 进度计算(可选)
if (totalBytes.HasValue)
{
double progress = (double)totalRead / totalBytes.Value * 100;
// 进度上报逻辑:OnProgressChanged(progress);
}
}
await fileStream.FlushAsync(cancellationToken).ConfigureAwait(false); // 确保数据写入磁盘
}
}
}
return true;
}
// 创建包含默认值的字典
Dictionary<string, string> CreateUserCollectHeader()
/// <summary>
/// 判断异常是否可重试
/// </summary>
private bool IsRetryableException(Exception ex)
{
return new Dictionary<string, string>
{
{"device_platform", "webapp"},
{"aid", "6383"},
{"channel", "channel_pc_web"},
{"pc_client_type", "1"},
{"version_code", "290100"},
{"version_name", "29.1.0"},
{"cookie_enabled", "true"},
{"screen_width", "1920"},
{"screen_height", "1080"},
{"browser_language", "zh-CN"},
{"browser_platform", "Win32"},
{"browser_name", "Chrome"},
{"browser_version", "130.0.0.0"},
{"browser_online", "true"},
{"engine_name", "Blink"},
{"engine_version", "130.0.0.0"},
{"os_name", "Windows"},
{"os_version", "10"},
{"cpu_core_num", "12"},
{"device_memory", "8"},
{"platform", "PC"},
{"downlink", "10"},
{"effective_type", "4g"},
{"from_user_page", "1"},
{"locate_query", "false"},
{"need_time_list", "1"},
{"pc_libra_divert", "Windows"},
{"publish_video_strategy_type", "2"},
{"round_trip_time", "0"},
{"show_live_replay_strategy", "1"},
{"time_list_query", "0"},
{"whale_cut_token", ""},
{"update_version_code", "170400"}
};
// 可重试的异常类型:网络错误、超时、服务器临时错误等
return ex is HttpRequestException // HTTP请求失败(如5xx错误、连接中断)
|| ex is TimeoutException // 超时(包括流超时和请求超时)
|| ex is IOException // IO错误(如临时磁盘问题)
|| (ex is AggregateException aggEx && aggEx.InnerExceptions.Any(IsRetryableException)); // 聚合异常中包含可重试项
}
Dictionary<string, string> CreateUserFavoriteParams()
{
var parameters = new Dictionary<string, string>
/// <summary>
/// 清理不完整的文件
/// </summary>
private void CleanupIncompleteFile(string savePath)
{
{"device_platform", "webapp"},
{"aid", "6383"},
{"channel", "channel_pc_web"},
{"min_cursor", "0"},
{"whale_cut_token", ""},
{"cut_version", "1"},
{"count", "18"},
{"publish_video_strategy_type", "2"},
{"update_version_code", "170400"},
{"pc_client_type", "1"},
{"pc_libra_divert", "Windows"},
{"support_h265", "1"},
{"support_dash", "1"},
{"cpu_core_num", "20"},
{"version_code", "170400"},
{"version_name", "17.4.0"},
{"cookie_enabled", "true"},
{"screen_width", "1536"},
{"screen_height", "960"},
{"browser_language", "zh-CN"},
{"browser_platform", "Win32"},
{"browser_name", "Chrome"},
{"browser_version", "140.0.0.0"},
{"browser_online", "true"},
{"engine_name", "Blink"},
{"engine_version", "140.0.0.0"},
{"os_name", "Windows"},
{"os_version", "10"},
{"device_memory", "8"},
{"platform", "PC"},
{"downlink", "10"},
{"effective_type", "4g"},
{"round_trip_time", "0"},
//{"webid", "7516440221375268388"}
};
return parameters;
if (File.Exists(savePath))
{
try
{
File.Delete(savePath);
}
catch (IOException ex)
{
Serilog.Log.Warning(ex, $"清理不完整文件失败:{savePath}(可能被占用)");
}
}
}
//--AI优化后的-1
///// <summary>
///// 下载文件并保存到本地(优化批量下载假死问题)
///// </summary>
///// <param name="videoUrl">文件地址</param>
///// <param name="savePath">保存路径</param>
///// <param name="cookie">请求Cookie</param>
///// <param name="cancellationToken">取消令牌(用于终止卡住的任务)</param>
///// <param name="streamTimeout">流读取超时时间(默认30秒)</param>
///// <returns>是否下载成功</returns>
//public async Task<bool> DownloadAsync(
// string videoUrl,
// string savePath,
// string cookie, string httpclientName=null,
// CancellationToken cancellationToken = default,
// TimeSpan? streamTimeout = null)
//{
// // 流读取超时默认60秒(避免长时间无数据导致假死)
// var streamTimeoutValue = streamTimeout ?? TimeSpan.FromSeconds(60);
// // 记录上次流活动时间(用于超时判断)
// DateTime lastStreamActivity = DateTime.UtcNow;
// try
// {
// // 确保目录存在
// var directory = Path.GetDirectoryName(savePath);
// if (!Directory.Exists(directory))
// {
// Directory.CreateDirectory(directory);
// }
// // 先删除已存在文件(处理文件占用问题)
// if (File.Exists(savePath))
// {
// // 重试删除(防止文件刚被释放)
// for (int i = 0; i < 3; i++)
// {
// try
// {
// File.Delete(savePath);
// break;
// }
// catch (IOException) when (i < 2)
// {
// await Task.Delay(100, cancellationToken).ConfigureAwait(false);
// }
// }
// }
// httpclientName??="dy_down1";
// // 使用客户端工厂创建HttpClient(复用连接池)
// using (var httpClient = _clientFactory.CreateClient(httpclientName))
// {
// // 清理并添加Cookie
// httpClient.DefaultRequestHeaders.Remove("Cookie");
// httpClient.DefaultRequestHeaders.Add("Cookie", cookie);
// // 总请求超时(包括连接和初始响应)
// httpClient.Timeout = TimeSpan.FromMinutes(5);
// // 发起请求(响应头就绪后返回,不等待完整内容)
// using (var response = await httpClient.GetAsync(
// videoUrl,
// HttpCompletionOption.ResponseHeadersRead,
// cancellationToken).ConfigureAwait(false))
// {
// response.EnsureSuccessStatusCode(); // 验证HTTP状态码
// // 获取文件总大小(用于进度计算)
// long? totalBytes = response.Content.Headers.ContentLength;
// // 读取响应流并写入文件
// using (var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken)
// .ConfigureAwait(false))
// // 优化FileStream:异步模式+顺序扫描(提升大文件写入效率)
// using (var fileStream = new FileStream(
// savePath,
// FileMode.CreateNew,
// FileAccess.Write,
// FileShare.None,
// bufferSize: 8192,
// options: FileOptions.Asynchronous | FileOptions.SequentialScan))
// {
// byte[] buffer = new byte[8192];
// int bytesRead;
// long totalRead = 0;
// // 循环读取流(带超时和取消检查)
// while ((bytesRead = await responseStream.ReadAsync(
// buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) > 0)
// {
// // 检查流读取超时(长时间无数据)
// if (DateTime.UtcNow - lastStreamActivity > streamTimeoutValue)
// {
// throw new TimeoutException($"流读取超时({streamTimeoutValue.TotalSeconds}秒无数据)");
// }
// // 写入文件
// await fileStream.WriteAsync(
// buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
// // 更新进度和活动时间
// totalRead += bytesRead;
// lastStreamActivity = DateTime.UtcNow;
// // (可选)进度上报逻辑
// if (totalBytes.HasValue)
// {
// double progress = (double)totalRead / totalBytes.Value * 100;
// // 可通过事件或委托上报进度:OnProgressChanged(progress);
// }
// }
// // 确保数据刷入磁盘
// await fileStream.FlushAsync(cancellationToken).ConfigureAwait(false);
// }
// }
// }
// return true;
// }
// catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
// {
// // 正常取消操作(非错误)
// Serilog.Log.Information($"下载被取消:{videoUrl}");
// return false;
// }
// catch (Exception ex)
// {
// // 记录错误并清理可能的不完整文件
// Serilog.Log.Error(ex, $"下载失败:{videoUrl}");
// if (File.Exists(savePath))
// {
// try { File.Delete(savePath); } catch { /* 忽略删除失败 */ }
// }
// return false;
// }
//}
///// <summary>
///// 下载文件并保存到本地
///// </summary>
///// <param name="videoUrl">文件地址</param>
///// <param name="savePath">保存路径</param>
///// <param name="cookie"></param>
//public async Task<bool> DownloadAsync(string videoUrl, string savePath, string cookie)
//{
// try
// {
// // 防止文件被占用,先删除已存在的文件
// if (File.Exists(savePath))
// {
// File.Delete(savePath);
// }
// // 创建HTTP客户端(设置超时时间和请求头)
// using (var httpClient = _clientFactory.CreateClient("dy_down"))
// {
// if (httpClient.DefaultRequestHeaders.Contains("Cookie"))
// {
// httpClient.DefaultRequestHeaders.Remove("Cookie");
// }
// httpClient.DefaultRequestHeaders.Add("Cookie", cookie);
// httpClient.Timeout = TimeSpan.FromMinutes(5); // 设置5分钟超时
// // 获取视频流
// using (var response = await httpClient.GetAsync(videoUrl, HttpCompletionOption.ResponseHeadersRead))
// {
// response.EnsureSuccessStatusCode(); // 确保请求成功
// // 获取文件总大小(用于进度显示)
// long? totalBytes = response.Content.Headers.ContentLength;
// // 读取流并写入文件
// using (var stream = await response.Content.ReadAsStreamAsync())
// using (var fileStream = new FileStream(savePath, FileMode.CreateNew))
// {
// byte[] buffer = new byte[8192];
// int bytesRead;
// long totalRead = 0;
// // 循环读取并写入
// while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
// {
// await fileStream.WriteAsync(buffer, 0, bytesRead);
// totalRead += bytesRead;
// // 显示下载进度
// if (totalBytes.HasValue)
// {
// double progress = (double)totalRead / totalBytes.Value * 100;
// //Console.Write($"\r下载进度:{progress:F2}% ({totalRead}/{totalBytes.Value} bytes)");
// }
// }
// //Console.WriteLine(); // 进度显示结束后换行
// }
// }
// }
// return true;
// }
// catch (Exception ex)
// {
// Serilog.Log.Error($"DownloadVideoAsync fail: {ex.Message}");
// Serilog.Log.Error($"DownloadVideoAsync fail: {ex.StackTrace}");
// return false;
// }
//}
}
}
+67 -4
View File
@@ -16,18 +16,28 @@ namespace dy.net.service
///
/// </summary>
/// <param name="expression"></param>
/// <param name="delay"></param>
/// <returns></returns>
public async Task StartJob(string expression)
public async Task StartJob(string expression,int delay=5000)
{
await StartCollectJob(expression);
await Task.Delay(10000);
await Task.Delay(delay);
//如果是数字则加1分钟,减少并发
if (int.TryParse(expression, out int cron)) {
if (int.TryParse(expression, out int cron))
{
cron++;
expression= cron.ToString();
expression = cron.ToString();
}
await StartFavoriteJob(expression);
await Task.Delay(delay);
if (int.TryParse(expression, out int cron2))
{
cron2++;
expression = cron2.ToString();
}
await StartUperPostJob(expression);
}
private async Task<bool> StartCollectJob(string expression)
@@ -134,5 +144,58 @@ namespace dy.net.service
}
return true;
}
private async Task<bool> StartUperPostJob(string expression)
{
try
{
var __scheduler1 = await _schedulerFactory.GetScheduler();
var jobKey = new JobKey("dy.job.key.uper", "group1");
var triggerKey = new TriggerKey("dy.trigger.key.uper", "group1");
var jobDetail = await __scheduler1.GetJobDetail(jobKey);
if (jobDetail != null)
{
//await __scheduler1.Shutdown();
await __scheduler1.DeleteJob(jobKey);//删掉原来的
}
IJobDetail job = JobBuilder.Create<DouYinUperPostSyncJob>()
.WithIdentity(jobKey)
.Build();
ITrigger trigger;
//var expression = Appsettings.Get("Interval");
if (CronExpression.IsValidExpression(expression))
{
trigger = TriggerBuilder.Create()
.WithIdentity(triggerKey)
.WithCronSchedule(expression)
.StartAt(DateTime.Now.AddSeconds(30))
.StartNow()
.Build();
}
else
{
int Interval = int.TryParse(expression, out int _Interval) ? _Interval : 30;
trigger = TriggerBuilder.Create()
.WithIdentity(triggerKey)
//.StartNow()
.StartAt(DateTime.Now.AddSeconds(3))
.WithSimpleSchedule(x => x
.WithIntervalInMinutes(Interval)
.RepeatForever())
.Build();
}
// Tell Quartz to schedule the job using our trigger
await __scheduler1.ScheduleJob(job, trigger);
}
catch (Exception ex)
{
Serilog.Log.Error("start dy.uper job error", ex);
return false;
}
return true;
}
}
}