diff --git a/.github/workflows/c#.yml b/.github/workflows/c#.yml index 86a618aa..8332141f 100644 --- a/.github/workflows/c#.yml +++ b/.github/workflows/c#.yml @@ -37,6 +37,7 @@ jobs: - uses: muno92/resharper_inspectcode@v1 with: + minimumReportSeverity: info solutionPath: c#/tbm.sln cachesHome: ${{ github.workspace }}/.resharper diff --git a/c#/.editorconfig b/c#/.editorconfig index fd644e34..0b9fdd7f 100644 --- a/c#/.editorconfig +++ b/c#/.editorconfig @@ -118,7 +118,6 @@ dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggest # https://youtrack.jetbrains.com/issue/RSRP-463998 resharper_arrange_constructor_or_destructor_body_highlighting = none resharper_arrange_method_or_operator_body_highlighting = none -resharper_arrange_object_creation_when_type_not_evident_highlighting = suggestion resharper_arrange_redundant_parentheses_highlighting = hint resharper_arrange_this_qualifier_highlighting = hint resharper_arrange_type_member_modifiers_highlighting = hint @@ -137,12 +136,12 @@ resharper_enforce_lock_statement_braces_highlighting = warning resharper_enforce_using_statement_braces_highlighting = warning resharper_enforce_while_statement_braces_highlighting = warning resharper_loop_can_be_partly_converted_to_query_highlighting = warning -resharper_redundant_base_qualifier_highlighting = warning resharper_remove_redundant_braces_highlighting = warning resharper_suggest_var_or_type_built_in_types_highlighting = hint resharper_suggest_var_or_type_elsewhere_highlighting = hint resharper_suggest_var_or_type_simple_types_highlighting = hint resharper_entity_framework_model_validation_unlimited_string_length_highlighting = none +resharper_move_local_function_after_jump_statement_highlighting = none ############################### # .NET Coding Conventions # diff --git a/c#/crawler/src/Db/CrawlerDbContext.cs b/c#/crawler/src/Db/CrawlerDbContext.cs index b0784bed..05d23311 100644 --- a/c#/crawler/src/Db/CrawlerDbContext.cs +++ b/c#/crawler/src/Db/CrawlerDbContext.cs @@ -21,7 +21,6 @@ public CrawlerDbContext() : this(fid: 0) { } public DbSet Replies => Set(); public DbSet ReplySignatures => Set(); public DbSet ReplyContents => Set(); - public DbSet SubReplies => Set(); public DbSet SubReplyContents => Set(); public DbSet Forums => Set(); @@ -36,6 +35,7 @@ public void TimestampingEntities() => var updatedAtProp = e.Property(ie => ie.UpdatedAt); var lastSeenAtProp = e.Entity is IPost ? e.Property(ie => ((IPost)ie).LastSeenAt) : null; + // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault switch (originalEntityState) { // mutates Entry.CurrentValue will always update Entry.IsModified // and the value of corresponding field in entity class instance diff --git a/c#/crawler/src/Db/Post/IPostWithAuthorExpGrade.cs b/c#/crawler/src/Db/Post/IPostWithAuthorExpGrade.cs index fde07650..15af2a55 100644 --- a/c#/crawler/src/Db/Post/IPostWithAuthorExpGrade.cs +++ b/c#/crawler/src/Db/Post/IPostWithAuthorExpGrade.cs @@ -1,3 +1,4 @@ +// ReSharper disable UnusedMemberInSuper.Global namespace tbm.Crawler.Db.Post; public interface IPostWithAuthorExpGrade diff --git a/c#/crawler/src/ExtensionMethods.cs b/c#/crawler/src/ExtensionMethods.cs index 4670f7c6..8febe666 100644 --- a/c#/crawler/src/ExtensionMethods.cs +++ b/c#/crawler/src/ExtensionMethods.cs @@ -55,7 +55,7 @@ public static IEnumerable GetInnerExceptions(this Exception ex) } while (inner != null); } - public static void SetIfNotNull(this IDictionary dict, T1 key, T2? value) + public static void SetIfNotNull(this IDictionary dict, T1 key, T2? value) where T2 : class { if (value != null) dict[key] = value; } diff --git a/c#/crawler/src/SonicPusher.cs b/c#/crawler/src/SonicPusher.cs index 0b692e60..a8010339 100644 --- a/c#/crawler/src/SonicPusher.cs +++ b/c#/crawler/src/SonicPusher.cs @@ -36,7 +36,7 @@ public float PushPost(Fid fid, string type, PostId id, RepeatedField? c .Trim() // https://github.com/spikensbror-dotnet/nsonic/pull/10 - .Replace("\\", "\\\\").Replace("\n", "\\n").Replace("\"", "\\\""); + .Replace("\\", @"\\").Replace("\n", "\\n").Replace("\"", "\\\""); if (contentTexts == "") return GetElapsedMs(); try @@ -72,16 +72,13 @@ public void PushPostWithCancellationToken( _ = PushPost(fid, postType, postIdSelector(p), postContentSelector(p)); } } - catch (OperationCanceledException e) + catch (OperationCanceledException e) when (e.CancellationToken == stoppingToken) { - if (e.CancellationToken == stoppingToken) - { - string GetBase64EncodedPostContent(T p) => - Convert.ToBase64String(Helper.WrapPostContent(postContentSelector(p)) - ?.ToByteArray() ?? ReadOnlySpan.Empty); - File.AppendAllLines(ResumeSuspendPostContentsPushingWorker.GetFilePath(postType), - posts.Select(p => $"{fid},{postIdSelector(p)},{GetBase64EncodedPostContent(p)}")); - } + string GetBase64EncodedPostContent(T p) => + Convert.ToBase64String(Helper.WrapPostContent(postContentSelector(p)) + ?.ToByteArray() ?? ReadOnlySpan.Empty); + File.AppendAllLines(ResumeSuspendPostContentsPushingWorker.GetFilePath(postType), + posts.Select(p => $"{fid},{postIdSelector(p)},{GetBase64EncodedPostContent(p)}")); throw; } finally diff --git a/c#/crawler/src/Tieba/ClientRequester.cs b/c#/crawler/src/Tieba/ClientRequester.cs index cd4483a7..57be4e57 100644 --- a/c#/crawler/src/Tieba/ClientRequester.cs +++ b/c#/crawler/src/Tieba/ClientRequester.cs @@ -155,6 +155,7 @@ private async Task Post( var ret = responseTaskFactory(http); _ = ret.ContinueWith(task => { + // ReSharper disable once MergeIntoPattern if (task.IsCompletedSuccessfully && task.Result.IsSuccessStatusCode) requesterTcs.Increase(); else requesterTcs.Decrease(); }, stoppingToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); diff --git a/c#/crawler/src/Tieba/Crawl/Crawler/ReplyCrawler.cs b/c#/crawler/src/Tieba/Crawl/Crawler/ReplyCrawler.cs index c3b0b93c..92fd7f6c 100644 --- a/c#/crawler/src/Tieba/Crawl/Crawler/ReplyCrawler.cs +++ b/c#/crawler/src/Tieba/Crawl/Crawler/ReplyCrawler.cs @@ -19,13 +19,12 @@ public override IList GetValidPosts(ReplyResponse response, CrawlRequestF var ret = EnsureNonEmptyPostList(response, "Reply list is empty, posts might already deleted from tieba."); var fidInResponse = response.Data.Forum.Id; - if (fidInResponse != fid) - { // fid will be the protoBuf default value 0 when reply list is empty, so we EnsureNonEmptyPostList() by first - var message = $"Parent forum id within thread response: {fidInResponse} is not match with the param value of" - + $" crawler ctor: {fid}, this thread might be multi forum or \"livepost\" thread."; - throw new TiebaException(shouldRetry: false, message); - } - return ret; + if (fidInResponse == fid) return ret; + + // fid will be the protoBuf default value 0 when reply list is empty, so we EnsureNonEmptyPostList() by first + var message = $"Parent forum id within thread response: {fidInResponse} is not match with the param value of" + + $" crawler ctor: {fid}, this thread might be multi forum or \"livepost\" thread."; + throw new TiebaException(shouldRetry: false, message); } public override TbClient.Page GetResponsePage(ReplyResponse response) => response.Data.Page; @@ -33,7 +32,7 @@ public override IList GetValidPosts(ReplyResponse response, CrawlRequestF protected override int GetResponseErrorCode(ReplyResponse response) => response.Error.Errorno; protected override IEnumerable GetRequestsForPage(Page page, CancellationToken stoppingToken = default) => [ - new Request(Requester.RequestProtoBuf("c/f/pb/page?cmd=302001", "12.26.1.0", + new(Requester.RequestProtoBuf("c/f/pb/page?cmd=302001", "12.26.1.0", new ReplyRequest {Data = new() { // reverse order will be {"last", "1"}, {"r", "1"} Kz = (long)tid, diff --git a/c#/crawler/src/Tieba/Crawl/Crawler/SubReplyCrawler.cs b/c#/crawler/src/Tieba/Crawl/Crawler/SubReplyCrawler.cs index 3711e7cf..69f33b4b 100644 --- a/c#/crawler/src/Tieba/Crawl/Crawler/SubReplyCrawler.cs +++ b/c#/crawler/src/Tieba/Crawl/Crawler/SubReplyCrawler.cs @@ -33,7 +33,7 @@ public override IList GetValidPosts(SubReplyResponse response, CrawlRe protected override int GetResponseErrorCode(SubReplyResponse response) => response.Error.Errorno; protected override IEnumerable GetRequestsForPage(Page page, CancellationToken stoppingToken = default) => [ - new Request(Requester.RequestProtoBuf("c/f/pb/floor?cmd=302002", "12.26.1.0", + new(Requester.RequestProtoBuf("c/f/pb/floor?cmd=302002", "12.26.1.0", new SubReplyRequest {Data = new() { Kz = (long)tid, diff --git a/c#/crawler/src/Tieba/Crawl/Crawler/ThreadArchiveCrawler.cs b/c#/crawler/src/Tieba/Crawl/Crawler/ThreadArchiveCrawler.cs index 730d4d18..8f5aae2a 100644 --- a/c#/crawler/src/Tieba/Crawl/Crawler/ThreadArchiveCrawler.cs +++ b/c#/crawler/src/Tieba/Crawl/Crawler/ThreadArchiveCrawler.cs @@ -12,8 +12,8 @@ protected override IEnumerable GetRequestsForPage(Page page, Cancellati () => new ThreadResponse(), stoppingToken); return [ // passing CrawlRequestFlag.ThreadClientVersion602 in the second one in order to invokes ThreadParser.ShouldSkipParse() - new Request(response), - new Request(response, CrawlRequestFlag.ThreadClientVersion602) + new(response), + new(response, CrawlRequestFlag.ThreadClientVersion602) ]; } } diff --git a/c#/crawler/src/Tieba/Crawl/Crawler/ThreadCrawler.cs b/c#/crawler/src/Tieba/Crawl/Crawler/ThreadCrawler.cs index 461a1b69..85a3a6e4 100644 --- a/c#/crawler/src/Tieba/Crawl/Crawler/ThreadCrawler.cs +++ b/c#/crawler/src/Tieba/Crawl/Crawler/ThreadCrawler.cs @@ -37,11 +37,11 @@ protected override IEnumerable GetRequestsForPage(Page page, Cancellati }; return [ - new Request(Requester.RequestProtoBuf(EndPointUrl, "12.26.1.0", + new(Requester.RequestProtoBuf(EndPointUrl, "12.26.1.0", new ThreadRequest {Data = data}, (req, common) => req.Data.Common = common, () => new ThreadResponse(), stoppingToken)), - new Request(Requester.RequestProtoBuf(LegacyEndPointUrl, "6.0.2", + new(Requester.RequestProtoBuf(LegacyEndPointUrl, "6.0.2", new ThreadRequest {Data = data602}, (req, common) => req.Data.Common = common, () => new ThreadResponse(), stoppingToken), CrawlRequestFlag.ThreadClientVersion602) diff --git a/c#/imagePipeline/src/Consumer/MetadataConsumer.cs b/c#/imagePipeline/src/Consumer/MetadataConsumer.cs index 67a038d7..7fcd18cd 100644 --- a/c#/imagePipeline/src/Consumer/MetadataConsumer.cs +++ b/c#/imagePipeline/src/Consumer/MetadataConsumer.cs @@ -93,6 +93,7 @@ private Func GetImageMetaData IEnumerable commonXxHash3ToIgnore, TImageSharpProfile? profile, Func rawBytesSelector) + where TImageSharpProfile : class where TEmbeddedMetadata : class, ImageMetadata.IEmbedded, new() { if (profile == null) return null;