Skip to content

Commit

Permalink
* fix all violations of ReSharper inspections
Browse files Browse the repository at this point in the history
* enable `GenerateDocumentationFile` to fix `SA0001: XML comment analysis is disabled due to project configuration` at build time @ Directory.Build.props
* disable Roslyn analyzer rule `CS1591` and ReSharper inspection `SeparateLocalFunctionsWithJumpStatement` @ .editorconfig
@ c#
  • Loading branch information
n0099 committed Mar 24, 2024
1 parent 56e93b4 commit bb8a5ed
Show file tree
Hide file tree
Showing 14 changed files with 117 additions and 107 deletions.
13 changes: 7 additions & 6 deletions c#/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ root = true
###############################
# All files
[*]
# Standard properties
indent_style = space
end_of_line = lf
charset = utf-8
indent_size = 4
insert_final_newline = true

# ReSharper properties
resharper_allow_comment_after_lbrace = true
Expand Down Expand Up @@ -62,12 +67,6 @@ resharper_wrap_chained_binary_expressions = chop_if_long
resharper_wrap_chained_binary_patterns = chop_if_long
resharper_wrap_chained_method_calls = wrap_if_long

# Standard properties
end_of_line = lf
insert_final_newline = true
indent_size = 4
charset = utf-8

# Microsoft .NET properties
csharp_new_line_before_members_in_object_initializers = false
csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async:suggestion
Expand Down Expand Up @@ -113,6 +112,7 @@ dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
dotnet_diagnostic.CS1591.severity = none

# ReSharper inspection severities
# https://youtrack.jetbrains.com/issue/RSRP-463998
Expand Down Expand Up @@ -142,6 +142,7 @@ 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
resharper_separate_local_functions_with_jump_statement_highlighting = none

###############################
# .NET Coding Conventions #
Expand Down
1 change: 1 addition & 0 deletions c#/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<PathMap>$(MSBuildProjectDirectory)=/</PathMap>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="$(MSBuildThisFileDirectory)\stylecop.json" />
Expand Down
2 changes: 2 additions & 0 deletions c#/crawler/src/Tieba/Crawl/Crawler/BaseCrawler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ namespace tbm.Crawler.Tieba.Crawl.Crawler;
public abstract partial class BaseCrawler<TResponse, TPostProtoBuf>
{
public abstract Exception FillExceptionData(Exception e);

// ReSharper disable once UnusedParameter.Global
public abstract IList<TPostProtoBuf> GetValidPosts(TResponse response, CrawlRequestFlag flag);
public abstract TbClient.Page? GetResponsePage(TResponse response);
protected abstract RepeatedField<TPostProtoBuf> GetResponsePostList(TResponse response);
Expand Down
5 changes: 4 additions & 1 deletion c#/crawler/src/Worker/ArchiveCrawlWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,12 @@ private async Task<SaverChangeSet<ThreadPost>?> CrawlThreads
var crawler = facadeFactory.Value(fid, forumName);
var savedThreads = (await crawler.CrawlPageRange(
page, page, stoppingToken)).SaveCrawled(stoppingToken);

// ReSharper disable once InvertIf
if (savedThreads != null)
{
var failureCountsKeyByTid = savedThreads.NewlyAdded.ToDictionary(th => th.Tid, _ => (FailureCount)0);
var failureCountsKeyByTid = savedThreads.NewlyAdded
.ToDictionary(th => th.Tid, _ => (FailureCount)0);
await using var threadLate = threadLateCrawlerAndSaverFactory();
await threadLate.Value(fid).CrawlThenSave(failureCountsKeyByTid, stoppingToken);
}
Expand Down
38 changes: 19 additions & 19 deletions c#/crawler/src/Worker/PushAllPostContentsIntoSonicWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace tbm.Crawler.Worker;

// ReSharper disable once UnusedType.Global
public class PushAllPostContentsIntoSonicWorker(
ILogger<PushAllPostContentsIntoSonicWorker> logger,
IConfiguration config,
Expand Down Expand Up @@ -82,27 +83,26 @@ private int PushPostContentsWithTiming<T>(
var pushedCount = acc.Count + 1;
var totalPushedCount = previousPushedPostCount + pushedCount;
var ca = ArchiveCrawlWorker.GetCumulativeAverage(elapsedMs, acc.DurationCa, pushedCount);
if (pushedCount % 1000 == 0)
{
static double GetPercentage(float current, float total, int digits = 2) =>
Math.Round(current / total * 100, digits);
if (pushedCount % 1000 != 0) return (pushedCount, ca);

static double GetPercentage(float current, float total, int digits = 2) =>
Math.Round(current / total * 100, digits);
#pragma warning disable IDE0042 // Deconstruct variable declaration
var currentForumEta = ArchiveCrawlWorker.GetEta(postApproxCount, pushedCount, ca);
var totalForumEta = ArchiveCrawlWorker.GetEta(forumsPostTotalApproxCount, totalPushedCount, ca);
var currentForumEta = ArchiveCrawlWorker.GetEta(postApproxCount, pushedCount, ca);
var totalForumEta = ArchiveCrawlWorker.GetEta(forumsPostTotalApproxCount, totalPushedCount, ca);
#pragma warning restore IDE0042 // Deconstruct variable declaration
logger.LogInformation("Pushing progress for {} in fid {}: {}/~{} ({}%) cumulativeAvg={:F3}ms"
+ " ETA: {} @ {}, Total forums progress: {}/{} posts: {}/~{} ({}%) ETA {} @ {}",
postTypeInLog, fid,
pushedCount, postApproxCount, GetPercentage(pushedCount, postApproxCount),
ca, currentForumEta.Relative, currentForumEta.At, currentForumIndex, forumCount,
totalPushedCount, forumsPostTotalApproxCount, GetPercentage(totalPushedCount, forumsPostTotalApproxCount),
totalForumEta.Relative, totalForumEta.At);
Console.Title = $"Pushing progress for {postTypeInLog} in fid {fid}"
+ $": {pushedCount}/~{postApproxCount} ({GetPercentage(pushedCount, postApproxCount)}%)"
+ $", Total forums progress: {currentForumIndex}/{forumCount} posts:"
+ $" {totalPushedCount}/~{forumsPostTotalApproxCount} ({GetPercentage(totalPushedCount, forumsPostTotalApproxCount)}%)"
+ $" ETA {totalForumEta.Relative} @ {totalForumEta.At}";
}
logger.LogInformation("Pushing progress for {} in fid {}: {}/~{} ({}%) cumulativeAvg={:F3}ms"
+ " ETA: {} @ {}, Total forums progress: {}/{} posts: {}/~{} ({}%) ETA {} @ {}",
postTypeInLog, fid,
pushedCount, postApproxCount, GetPercentage(pushedCount, postApproxCount),
ca, currentForumEta.Relative, currentForumEta.At, currentForumIndex, forumCount,
totalPushedCount, forumsPostTotalApproxCount, GetPercentage(totalPushedCount, forumsPostTotalApproxCount),
totalForumEta.Relative, totalForumEta.At);
Console.Title = $"Pushing progress for {postTypeInLog} in fid {fid}"
+ $": {pushedCount}/~{postApproxCount} ({GetPercentage(pushedCount, postApproxCount)}%)"
+ $", Total forums progress: {currentForumIndex}/{forumCount} posts:"
+ $" {totalPushedCount}/~{forumsPostTotalApproxCount} ({GetPercentage(totalPushedCount, forumsPostTotalApproxCount)}%)"
+ $" ETA {totalForumEta.Relative} @ {totalForumEta.At}";
return (pushedCount, ca);
});
logger.LogInformation("Pushing {} historical {}' content into sonic for fid {} finished after {} (total={}ms, cumulativeAvg={:F3}ms)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ protected override Task DoWork(CancellationToken stoppingToken)
logger.LogWarning("Malformed fid {} when resume suspend post contents push into sonic, line={}", fidStr, line);
return null;
}

// ReSharper disable once InvertIf
if (!PostId.TryParse(postIdStr, out var postId))
{
logger.LogWarning("Malformed post id {} when resume suspend post contents push into sonic, line={}", postIdStr, line);
Expand Down
26 changes: 13 additions & 13 deletions c#/crawler/src/Worker/RetryCrawlWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,20 @@ protected override async Task DoWork(CancellationToken stoppingToken)
var pages = failureCountsKeyByPage.Keys.ToList();
FailureCount FailureCountSelector(Page p) => failureCountsKeyByPage[p];

if (lockType == "thread")
switch (lockType)
{
await RetryThread(fid, pages,
failureCountsKeyByPage.Count, FailureCountSelector, stoppingToken);
}
else if (lockType == "reply" && tid != null)
{
await RetryReply(fid, tid.Value, pages,
failureCountsKeyByPage.Count, FailureCountSelector, stoppingToken);
}
else if (lockType == "subReply" && tid != null && pid != null)
{
await RetrySubReply(fid, tid.Value, pid.Value, pages,
failureCountsKeyByPage.Count, FailureCountSelector, stoppingToken);
case "thread":
await RetryThread(fid, pages,
failureCountsKeyByPage.Count, FailureCountSelector, stoppingToken);
break;
case "reply" when tid != null:
await RetryReply(fid, tid.Value, pages,
failureCountsKeyByPage.Count, FailureCountSelector, stoppingToken);
break;
case "subReply" when tid != null && pid != null:
await RetrySubReply(fid, tid.Value, pid.Value, pages,
failureCountsKeyByPage.Count, FailureCountSelector, stoppingToken);
break;
}
};

Expand Down
14 changes: 7 additions & 7 deletions c#/imagePipeline/src/Consumer/HashConsumer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ private static Func<ImageKeyWithMatrix, KeyValuePair<ImageKeyWithMatrix, byte[]>
{
stoppingToken.ThrowIfCancellationRequested();
var mat = imageKeyWithMatrix.Matrix;
if (mat.Width > 100 || mat.Height > 100)
{ // not preserve the original aspect ratio
// https://stackoverflow.com/questions/44650888/resize-an-image-without-distortion-opencv
using var thumbnail = mat.Resize(new(100, 100), interpolation: InterpolationFlags.Area);
return new(imageKeyWithMatrix, GetThumbHashForMatrix(thumbnail));
}
return new(imageKeyWithMatrix, GetThumbHashForMatrix(mat));
if (mat is {Width: <= 100, Height: <= 100})
return new(imageKeyWithMatrix, GetThumbHashForMatrix(mat));

// not preserve the original aspect ratio
// https://stackoverflow.com/questions/44650888/resize-an-image-without-distortion-opencv
using var thumbnail = mat.Resize(new(100, 100), interpolation: InterpolationFlags.Area);
return new(imageKeyWithMatrix, GetThumbHashForMatrix(thumbnail));

static byte[] GetThumbHashForMatrix(Mat mat)
{
Expand Down
108 changes: 54 additions & 54 deletions c#/imagePipeline/src/Consumer/MetadataConsumer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,58 +119,58 @@ private Func<ImageWithBytes, ImageMetadata> GetImageMetaData

var ret = CreateEmbeddedFromProfile<ExifProfile, ImageMetadata.Exif>
(_commonEmbeddedMetadataXxHash3ToIgnore.Exif, exif, i => i.ToByteArray());
if (ret != null && exif != null)
{ // https://exiftool.org/TagNames/EXIF.html, https://exiv2.org/tags.html
ret.Orientation = exif.TryGetValue(ExifTag.Orientation, out var orientation)
? Enum.GetName((ImageMetadata.Exif.ExifOrientation)orientation.Value)
: null;
ret.ImageDescription = GetExifTagValueOrNull(ExifTag.ImageDescription).NullIfEmpty();
ret.UserComment = GetExifTagValueOrNull2(ExifTag.UserComment).ToString().NullIfEmpty();
ret.Artist = GetExifTagValueOrNull(ExifTag.Artist).NullIfEmpty();
ret.XpAuthor = GetExifTagValueOrNull(ExifTag.XPAuthor).NullIfEmpty();
ret.Copyright = GetExifTagValueOrNull(ExifTag.Copyright).NullIfEmpty();
ret.ImageUniqueId = GetExifTagValueOrNull(ExifTag.ImageUniqueID).NullIfEmpty();
ret.BodySerialNumber = GetExifTagValueOrNull(ExifTag.SerialNumber).NullIfEmpty();
ret.Make = GetExifTagValueOrNull(ExifTag.Make).NullIfEmpty();
ret.Model = GetExifTagValueOrNull(ExifTag.Model).NullIfEmpty();
ret.Software = GetExifTagValueOrNull(ExifTag.Software).NullIfEmpty();
ret.CustomRendered = GetExifTagValueOrNull2(ExifTag.CustomRendered);

var parsedDateTime = ExifDateTimeTagValuesParser.ParseExifDateTimeOrNull(
GetExifTagValueOrNull(ExifTag.DateTime), GetExifTagValueOrNull(ExifTag.SubsecTime));
ret.DateTime = parsedDateTime?.DateTime;
ret.DateTimeOffset = parsedDateTime?.Offset;

var parsedDateTimeDigitized = ExifDateTimeTagValuesParser.ParseExifDateTimeOrNull(
GetExifTagValueOrNull(ExifTag.DateTimeDigitized), GetExifTagValueOrNull(ExifTag.SubsecTimeDigitized));
ret.DateTimeDigitized = parsedDateTimeDigitized?.DateTime;
ret.DateTimeDigitizedOffset = parsedDateTimeDigitized?.Offset;

var parsedDateTimeOriginal = ExifDateTimeTagValuesParser.ParseExifDateTimeOrNull(
GetExifTagValueOrNull(ExifTag.DateTimeOriginal), GetExifTagValueOrNull(ExifTag.SubsecTimeOriginal));
ret.DateTimeOriginal = parsedDateTimeOriginal?.DateTime;
ret.DateTimeOriginalOffset = parsedDateTimeOriginal?.Offset;

ret.OffsetTime = GetExifTagValueOrNull(ExifTag.OffsetTime).NullIfEmpty();
ret.OffsetTimeDigitized = GetExifTagValueOrNull(ExifTag.OffsetTimeDigitized).NullIfEmpty();
ret.OffsetTimeOriginal = GetExifTagValueOrNull(ExifTag.OffsetTimeOriginal).NullIfEmpty();

ret.GpsDateTime = ExifGpsTagValuesParser.ParseGpsDateTimeOrNull(
GetExifTagValueOrNull(ExifTag.GPSTimestamp),
GetExifTagValueOrNull(ExifTag.GPSDateStamp));
ret.GpsCoordinate = ExifGpsTagValuesParser.ParseGpsCoordinateOrNull(exif.Values,
GetExifTagValueOrNull(ExifTag.GPSLatitude),
GetExifTagValueOrNull(ExifTag.GPSLatitudeRef),
GetExifTagValueOrNull(ExifTag.GPSLongitude),
GetExifTagValueOrNull(ExifTag.GPSLongitudeRef));
ret.GpsImgDirection = GetExifTagValueOrNull2(ExifTag.GPSImgDirection)?.ToSingle().NanToNull();
ret.GpsImgDirectionRef = GetExifTagValueOrNull(ExifTag.GPSImgDirectionRef).NullIfEmpty();

ret.TagNames = exif.Values.Select(i => new ImageMetadata.Exif.TagName {Name = i.Tag.ToString()})

// tags might be duplicated in EXIF with same or different values
.DistinctBy(tagName => tagName.Name).ToList();
}
if (ret == null || exif == null) return ret;

// https://exiftool.org/TagNames/EXIF.html, https://exiv2.org/tags.html
ret.Orientation = exif.TryGetValue(ExifTag.Orientation, out var orientation)
? Enum.GetName((ImageMetadata.Exif.ExifOrientation)orientation.Value)
: null;
ret.ImageDescription = GetExifTagValueOrNull(ExifTag.ImageDescription).NullIfEmpty();
ret.UserComment = GetExifTagValueOrNull2(ExifTag.UserComment).ToString().NullIfEmpty();
ret.Artist = GetExifTagValueOrNull(ExifTag.Artist).NullIfEmpty();
ret.XpAuthor = GetExifTagValueOrNull(ExifTag.XPAuthor).NullIfEmpty();
ret.Copyright = GetExifTagValueOrNull(ExifTag.Copyright).NullIfEmpty();
ret.ImageUniqueId = GetExifTagValueOrNull(ExifTag.ImageUniqueID).NullIfEmpty();
ret.BodySerialNumber = GetExifTagValueOrNull(ExifTag.SerialNumber).NullIfEmpty();
ret.Make = GetExifTagValueOrNull(ExifTag.Make).NullIfEmpty();
ret.Model = GetExifTagValueOrNull(ExifTag.Model).NullIfEmpty();
ret.Software = GetExifTagValueOrNull(ExifTag.Software).NullIfEmpty();
ret.CustomRendered = GetExifTagValueOrNull2(ExifTag.CustomRendered);

var parsedDateTime = ExifDateTimeTagValuesParser.ParseExifDateTimeOrNull(
GetExifTagValueOrNull(ExifTag.DateTime), GetExifTagValueOrNull(ExifTag.SubsecTime));
ret.DateTime = parsedDateTime?.DateTime;
ret.DateTimeOffset = parsedDateTime?.Offset;

var parsedDateTimeDigitized = ExifDateTimeTagValuesParser.ParseExifDateTimeOrNull(
GetExifTagValueOrNull(ExifTag.DateTimeDigitized), GetExifTagValueOrNull(ExifTag.SubsecTimeDigitized));
ret.DateTimeDigitized = parsedDateTimeDigitized?.DateTime;
ret.DateTimeDigitizedOffset = parsedDateTimeDigitized?.Offset;

var parsedDateTimeOriginal = ExifDateTimeTagValuesParser.ParseExifDateTimeOrNull(
GetExifTagValueOrNull(ExifTag.DateTimeOriginal), GetExifTagValueOrNull(ExifTag.SubsecTimeOriginal));
ret.DateTimeOriginal = parsedDateTimeOriginal?.DateTime;
ret.DateTimeOriginalOffset = parsedDateTimeOriginal?.Offset;

ret.OffsetTime = GetExifTagValueOrNull(ExifTag.OffsetTime).NullIfEmpty();
ret.OffsetTimeDigitized = GetExifTagValueOrNull(ExifTag.OffsetTimeDigitized).NullIfEmpty();
ret.OffsetTimeOriginal = GetExifTagValueOrNull(ExifTag.OffsetTimeOriginal).NullIfEmpty();

ret.GpsDateTime = ExifGpsTagValuesParser.ParseGpsDateTimeOrNull(
GetExifTagValueOrNull(ExifTag.GPSTimestamp),
GetExifTagValueOrNull(ExifTag.GPSDateStamp));
ret.GpsCoordinate = ExifGpsTagValuesParser.ParseGpsCoordinateOrNull(exif.Values,
GetExifTagValueOrNull(ExifTag.GPSLatitude),
GetExifTagValueOrNull(ExifTag.GPSLatitudeRef),
GetExifTagValueOrNull(ExifTag.GPSLongitude),
GetExifTagValueOrNull(ExifTag.GPSLongitudeRef));
ret.GpsImgDirection = GetExifTagValueOrNull2(ExifTag.GPSImgDirection)?.ToSingle().NanToNull();
ret.GpsImgDirectionRef = GetExifTagValueOrNull(ExifTag.GPSImgDirectionRef).NullIfEmpty();

ret.TagNames = exif.Values.Select(i => new ImageMetadata.Exif.TagName {Name = i.Tag.ToString()})

// tags might be duplicated in EXIF with same or different values
.DistinctBy(tagName => tagName.Name).ToList();
return ret;
}

Expand Down Expand Up @@ -199,7 +199,7 @@ private static class ExifGpsTagValuesParser
}

public static Point? ParseGpsCoordinateOrNull(
IReadOnlyList<IExifValue> allTagValues,
IEnumerable<IExifValue> allTagValues,
IEnumerable<Rational>? latitude,
string? latitudeRef,
IEnumerable<Rational>? longitude,
Expand Down Expand Up @@ -251,7 +251,7 @@ private static double ConvertDmsToDd(IReadOnlyList<double> dms)
}
}

private sealed partial class ExifDateTimeTagValuesParser
private static partial class ExifDateTimeTagValuesParser
{
public static DateTimeAndOffset? ParseExifDateTimeOrNull(string? exifDateTime, string? exifFractionalSeconds)
{ // https://gist.github.com/thanatos/eee17100476a336a711e
Expand Down
5 changes: 3 additions & 2 deletions c#/imagePipeline/src/Db/ImageMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable PropertyCanBeMadeInitOnly.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable UnusedMemberInSuper.Global
using System.ComponentModel;
using SixLabors.ImageSharp.PixelFormats;
using Point = NetTopologySuite.Geometries.Point;
Expand Down Expand Up @@ -56,7 +57,7 @@ public enum ExifOrientation
MirrorHorizontalRotate270Cw = 5,
Rotate90Cw = 6,
MirrorHorizontalRotate90Cw = 7,
Rotate270Cw = 8,
Rotate270Cw = 8
}

[Key] public uint ImageId { get; set; }
Expand Down Expand Up @@ -90,7 +91,7 @@ public enum ExifOrientation

// workaround to work with MetadataConsumer.CreateEmbeddedFromProfile()
// https://stackoverflow.com/questions/75266722/type-cannot-satisfy-the-new-constraint-on-parameter-tparam-because-type
public ICollection<TagName> TagNames { get; set; } = new List<TagName>();
public ICollection<TagName> TagNames { get; set; } = [];

public class TagName : IImageMetadata
{
Expand Down
Loading

0 comments on commit bb8a5ed

Please sign in to comment.