Skip to content

Commit

Permalink
Merge tag 'v0.3.2' into develop
Browse files Browse the repository at this point in the history
tor4kichi committed Mar 22, 2023
2 parents d2c98ec + 7aafcb4 commit 0ca1ebc
Showing 8 changed files with 528 additions and 443 deletions.
8 changes: 4 additions & 4 deletions NiconicoToolkit.Shared/NiconicoToolkit.Shared.projitems
Original file line number Diff line number Diff line change
@@ -235,15 +235,15 @@
<Compile Include="$(MSBuildThisFileDirectory)Video\Watch\Dmc\KeepMethod.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Video\Watch\Dmc\Protocol.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Video\Watch\Dmc\SessionOperationAuth.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Video\Watch\NV_Comment\CommentSubClient.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Video\Watch\NV_Comment\NvCommentSubClient.Core.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Video\Watch\NV_Comment\NvCommentSubClient.Delete.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Video\Watch\NV_Comment\NvCommentSubClient.Get.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Video\Watch\NV_Comment\NvCommentSubClient.Post.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Video\Watch\VideoWatchSubClient.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Video\Watch\WatchDataForGuest.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Video\Watch\WatchPageResponse.cs" />
</ItemGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)Live\WatchPageProp\DataPropsSource.Json" />
</ItemGroup>
<ItemGroup>
<Folder Include="$(MSBuildThisFileDirectory)Video\Watch\NV_Comment\" />
</ItemGroup>
</Project>
434 changes: 0 additions & 434 deletions NiconicoToolkit.Shared/Video/Watch/NV_Comment/CommentSubClient.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Text.Json;
using System.Linq;
#if WINDOWS_UWP
using Windows.Web.Http;
using Windows.Web.Http.Headers;
#else
using System.Net.Http;
using System.Net.Http.Headers;
#endif

namespace NiconicoToolkit.Video.Watch.NV_Comment;

public sealed partial class NvCommentSubClient
{
private readonly NiconicoContext _context;
private readonly JsonSerializerOptions _option;

public NvCommentSubClient(NiconicoContext context, JsonSerializerOptions option)
{
_context = context;
_option = option;
}

public const string NVCommentThreadsUrl = "https://nvcomment.nicovideo.jp/v1/threads";
public const string NvApiCommentKeysUrl = "https://nvapi.nicovideo.jp/v1/comment/keys/";
}

public static class ThreadTargetForkConstants
{
public const string Easy = "easy";
public const string Main = "main";
public const string Owner = "owner";
}




Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Threading;
#if WINDOWS_UWP
using Windows.Web.Http;
using Windows.Web.Http.Headers;
#else
using System.Net.Http;
using System.Net.Http.Headers;
#endif

namespace NiconicoToolkit.Video.Watch.NV_Comment;

public partial class NvCommentSubClient
{
/// <summary>
/// 自らが投稿したコメントを削除する際のキーを取得します。
/// </summary>
/// <param name="threadId"></param>
/// <param name="fork">fork または forkLabel を指定。参考:ThreadTargetForkConstants</param>
/// <param name="ct"></param>
/// <returns></returns>
[RequireLogin]
public async Task<ThreadDeleteKeyResponse> GetDeleteKeyAsync(string threadId, string fork, CancellationToken ct = default)
{
return await _context.GetJsonAsAsync<ThreadDeleteKeyResponse>(
$"{NvApiCommentKeysUrl}delete?threadId={threadId}&fork={fork}", ct: ct
);
}


/// <summary>
/// 自らが投稿したコメントを削除します。IsMyPost が true のコメント番号を指定して削除します。
/// </summary>
/// <param name="videoId"></param>
/// <param name="threadId"></param>
/// <param name="fork"></param>
/// <param name="commentNumber">コメントの番号("no")</param>
/// <param name="language"></param>
/// <param name="deleteKey">GetDeleteKeyAsync() によって得られる削除キーを指定します。</param>
/// <param name="ct"></param>
/// <returns></returns>
[RequireLogin]
public async Task<ThreadDeleteResponse> DeleteCommentAsync(
VideoId videoId,
string threadId,
string fork,
int commentNumber,
string language,
string deleteKey,
CancellationToken ct = default
)
{
string requestParamsJson = JsonSerializer.Serialize(new ThreadDeleteRequest()
{
VideoId = videoId.ToString(),
Fork = fork,
DeleteKey = deleteKey,
Language = language,
Targets = new() { new() { Number = commentNumber } }
});

return await _context.SendJsonAsAsync<ThreadDeleteResponse>(HttpMethod.Put,
$"{NVCommentThreadsUrl}/{threadId}/comment-comment-owner-deletions", requestParamsJson, ct: ct);
}
}



public sealed class ThreadDeleteRequest
{
[JsonPropertyName("videoId")]
public string VideoId { get; set; }

[JsonPropertyName("deleteKey")]
public string DeleteKey { get; set; }

[JsonPropertyName("language")]
public string Language { get; set; }

[JsonPropertyName("targets")]
public List<ThreadDeleteTarget> Targets { get; set; }

[JsonPropertyName("fork")]
public string Fork { get; set; }

public sealed class ThreadDeleteTarget
{
[JsonPropertyName("no")]
public int Number { get; set; }

[JsonPropertyName("operation")]
public string Operation { get; set; } = "DELETE";
}
}

public sealed class ThreadDeleteResponse : ResponseWithMeta
{

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Threading;
using System.Text.Json.Serialization;
#if WINDOWS_UWP
using Windows.Web.Http;
using Windows.Web.Http.Headers;
#else
using System.Net.Http;
using System.Net.Http.Headers;
#endif

namespace NiconicoToolkit.Video.Watch.NV_Comment;

public partial class NvCommentSubClient
{

/// <summary>
/// 動画に投稿されたコメントを取得します。
/// </summary>
/// <param name="videoComment">VideoClient.VideoWatch.GetInitialWatchDataAsync() のレスポンスデータに含まれる NvComment を指定します。</param>
/// <param name="ct"></param>
/// <returns></returns>
public async Task<ThreadResponse> GetCommentsAsync(NvComment videoComment, CancellationToken ct = default)
{
string requestParamsJson = JsonSerializer.Serialize(new ThreadRequest()
{
ThreadKey = videoComment.ThreadKey,
Params = new ThreadRequest.ThreadRequestParams()
{
Targets = videoComment.Params.Targets,
Language = videoComment.Params.Language,
}
});
return await _context.SendJsonAsAsync<ThreadResponse>(
HttpMethod.Post,
NVCommentThreadsUrl,
requestParamsJson,
ct: ct
);
}

/// <summary>
/// 動画に投稿されたコメントを取得します。
/// </summary>
/// <param name="videoComment">VideoClient.VideoWatch.GetInitialWatchDataAsync() のレスポンスデータに含まれる NvComment を指定します。</param>
/// <param name="targetForks">取得対象とするコメントForkを指定します。参考:ThreadTargetIdConstants</param>
/// <param name="ct"></param>
/// <returns></returns>
/// <remarks>VideoClient.VideoWatch.GetInitialWatchDataAsync() のレスポンスデータに含まれる NvComment のデータを引数に渡してください。</remarks>
public async Task<ThreadResponse> GetCommentsAsync(NvComment videoComment, IEnumerable<string> targetForks, CancellationToken ct = default)
{
var forks = targetForks.ToHashSet();
string requestParamsJson = JsonSerializer.Serialize(new ThreadRequest()
{
ThreadKey = videoComment.ThreadKey,
Params = new ThreadRequest.ThreadRequestParams()
{
Targets = videoComment.Params.Targets.Where(x => forks.Contains(x.Fork)).ToList(),
Language = videoComment.Params.Language,
}
});
return await _context.SendJsonAsAsync<ThreadResponse>(
HttpMethod.Post,
NVCommentThreadsUrl,
requestParamsJson,
ct: ct
);
}
}


class ThreadRequest
{
[JsonPropertyName("params")]
public ThreadRequestParams Params { get; set; }

[JsonPropertyName("threadKey")]
public string ThreadKey { get; set; }

[JsonPropertyName("additionals")]
public ThreadRequestAdditionals Additionals { get; set; } = new ThreadRequestAdditionals();


public class ThreadRequestAdditionals
{
}

public class ThreadRequestParams
{
[JsonPropertyName("targets")]
public List<NvCommentParamsTarget> Targets { get; set; }

[JsonPropertyName("language")]
public string Language { get; set; }
}
}


public class ThreadResponse : ResponseWithMeta
{
[JsonPropertyName("data")]
public ThreadResponseData Data { get; set; }


public class ThreadResponseData
{
[JsonPropertyName("globalComments")]
public List<GlobalComment> GlobalComments { get; set; }

[JsonPropertyName("threads")]
public List<Thread> Threads { get; set; }
}

public class GlobalComment
{
[JsonPropertyName("id")]
public string Id { get; set; }

[JsonPropertyName("count")]
public int Count { get; set; }
}

public class Thread
{
[JsonPropertyName("id")]
public string Id { get; set; }

[JsonPropertyName("fork")]
public string Fork { get; set; }

[JsonPropertyName("commentCount")]
public int CommentCount { get; set; }

[JsonPropertyName("comments")]
public List<Comment> Comments { get; set; }
}

public class Comment
{
[JsonPropertyName("id")]
public string Id { get; set; }

[JsonPropertyName("no")]
public int No { get; set; }

[JsonPropertyName("vposMs")]
public int VposMs { get; set; }

[JsonPropertyName("body")]
public string Body { get; set; }

[JsonPropertyName("commands")]
public List<string> Commands { get; set; }

[JsonPropertyName("userId")]
public string UserId { get; set; }

[JsonPropertyName("isPremium")]
public bool IsPremium { get; set; }

[JsonPropertyName("score")]
public int Score { get; set; }

[JsonPropertyName("postedAt")]
public DateTime PostedAt { get; set; }

[JsonPropertyName("nicoruCount")]
public int NicoruCount { get; set; }

[JsonPropertyName("nicoruId")]
public object NicoruId { get; set; }

[JsonPropertyName("source")]
public string Source { get; set; }

[JsonPropertyName("isMyPost")]
public bool IsMyPost { get; set; }
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Threading;
using System.Text.Json.Serialization;
#if WINDOWS_UWP
using Windows.Web.Http;
using Windows.Web.Http.Headers;
#else
using System.Net.Http;
using System.Net.Http.Headers;
#endif

namespace NiconicoToolkit.Video.Watch.NV_Comment;

public partial class NvCommentSubClient
{

/// <summary>
/// スレッドにコメントを送信するためのポストキーを取得します。
/// </summary>
/// <param name="threadId">スレッドID。WatchApiResponse.WatchApiData.Comment.Threads から取得できます。</param>
/// <returns></returns>
[RequireLogin]
public async Task<ThreadPostKeyResponse> GetPostKeyAsync(string threadId, CancellationToken ct = default)
{
return await _context.GetJsonAsAsync<ThreadPostKeyResponse>(
$"{NvApiCommentKeysUrl}post?threadId={threadId}", ct: ct
);
}

/// <summary>
/// 動画の指定スレッドに対してコメント投稿を送信します。
/// </summary>
/// <param name="threadId">スレッドID。WatchApiResponse.WatchApiData.Comment.Threads から取得できます。</param>
/// <param name="videoId">動画ID。stringのままでもVideoIdへの暗黙の型変換により指定可能です。</param>
/// <param name="commands">184などのコマンドを指定します</param>
/// <paramref name="commands">https://dic.nicovideo.jp/a/%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89</paramref>
/// <param name="comment">コメント本文。Uriエンコードは不要です。</param>
/// <param name="vPosMs">コメントする動画時間をマイクロ秒単位で指定します。動画秒数に対して1000を掛け算することでマイクロ秒へ変換できます。</param>
/// <param name="postKey">GetPostKeyAsync()を使用して予め取得してください。</param>
/// <param name="ct"></param>
/// <returns></returns>
/// <remarks> パラメータエラーによる失敗は全て INVALID_PARAMETER としてまとめられるため、何が間違いかは判別できません。 </remarks>
[RequireLogin]
public async Task<ThreadPostResponse> PostCommentAsync(
string threadId,
VideoId videoId,
IEnumerable<string> commands,
string comment,
int vPosMs,
string postKey,
CancellationToken ct = default
)
{
string requestParamsJson = JsonSerializer.Serialize(new ThreadPostRequest()
{
VideoId = videoId.ToString(),
Commands = commands.ToList(),
Body = comment,
VposMs = vPosMs,
PostKey = postKey,
});

return await _context.SendJsonAsAsync<ThreadPostResponse>(HttpMethod.Post,
$"{NVCommentThreadsUrl}/{threadId}/comments", requestParamsJson, ct: ct);
}


[RequireLogin]
public async Task<ThreadEasyPostKeyResponse> GetEasyPostKeyAsync(string threadId, CancellationToken ct = default)
{
return await _context.GetJsonAsAsync<ThreadEasyPostKeyResponse>(
$"{NvApiCommentKeysUrl}post-easy?threadId={threadId}", ct: ct
);
}

[RequireLogin]
public async Task<ThreadPostResponse> EasyPostCommentAsync(
string threadId,
VideoId videoId,
string comment,
int vPosMs,
string easyPostKey,
CancellationToken ct = default
)
{
string requestParamsJson = JsonSerializer.Serialize(new ThreadEasyPostRequest()
{
VideoId = videoId.ToString(),
Body = comment,
VposMs = vPosMs,
EasyPostKey = easyPostKey,
});

return await _context.SendJsonAsAsync<ThreadPostResponse>(HttpMethod.Post,
$"{NVCommentThreadsUrl}/{threadId}/easy-comments", requestParamsJson, ct: ct);
}
}

public sealed class ThreadPostKeyResponse : ResponseWithMeta
{
[JsonPropertyName("data")]
public ThreadPostKeyData? Data { get; set; }

public sealed class ThreadPostKeyData
{
[JsonPropertyName("postKey")]
public string PostKey { get; set; }
}
}

sealed class ThreadPostRequest
{
[JsonPropertyName("videoId")]
public string VideoId { get; set; }

[JsonPropertyName("commands")]
public List<string> Commands { get; set; }

[JsonPropertyName("body")]
public string Body { get; set; }

[JsonPropertyName("vposMs")]
public int VposMs { get; set; }

[JsonPropertyName("postKey")]
public string PostKey { get; set; }
}

sealed class ThreadEasyPostRequest
{
[JsonPropertyName("videoId")]
public string VideoId { get; set; }

[JsonPropertyName("body")]
public string Body { get; set; }

[JsonPropertyName("vposMs")]
public int VposMs { get; set; }

[JsonPropertyName("postEasyKey")]
public string EasyPostKey { get; set; }
}

public sealed class ThreadPostResponse : ResponseWithMeta
{
[JsonPropertyName("data")]
public ThreadPostResponseData? Data { get; set; }

public sealed class ThreadPostResponseData
{
[JsonPropertyName("id")]
public string Id { get; set; }

[JsonPropertyName("no")]
public int Number { get; set; }
}
}

public sealed class ThreadDeleteKeyResponse : ResponseWithMeta
{
[JsonPropertyName("data")]
public ThreadDeleteKeyData? Data { get; set; }

public sealed class ThreadDeleteKeyData
{
[JsonPropertyName("deleteKey")]
public string DeleteKey { get; set; }
}
}

public sealed class ThreadEasyPostKeyResponse : ResponseWithMeta
{
[JsonPropertyName("data")]
public ThreadEasyPostKeyData? Data { get; set; }

public sealed class ThreadEasyPostKeyData
{
[JsonPropertyName("postEasyKey")]
public string EasyPostKey { get; set; }
}
}

2 changes: 1 addition & 1 deletion NuSpec/build_nuget.cmd
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nuget pack Package.nuspec -outputDirectory "C:\Users\tor4k\local_nuget" -p version=0.3.1
nuget pack Package.nuspec -outputDirectory "C:\Users\tor4k\local_nuget" -p version=0.3.2
7 changes: 3 additions & 4 deletions Test/NiconicoToolkit.Shared.Test/VideoWatchTest.cs
Original file line number Diff line number Diff line change
@@ -177,9 +177,8 @@ public async Task NvGetCommentWithoutEasyPostAsync(string videoId)

var nvComment = res.WatchApiResponse.WatchApiData.Comment.NvComment;
var commentRes = await _context.Video.NvComment.GetCommentsAsync(
nvComment.ThreadKey,
nvComment.Params.Targets.Where(x => x.Fork != ThreadTargetForkConstants.Easy),
nvComment.Params.Language
nvComment,
new[] { ThreadTargetForkConstants.Owner, ThreadTargetForkConstants.Main }
);

Assert.IsNotNull(commentRes.Data);
@@ -283,7 +282,7 @@ public async Task NvDeleteCommentAsync(string videoId)

var comment = res.WatchApiResponse.WatchApiData.Comment;
var nvComment = comment.NvComment;
var commentRes = await _context.Video.NvComment.GetCommentsAsync(nvComment.ThreadKey, nvComment.Params.Targets.Where(x => x.Fork == ThreadTargetForkConstants.Easy), nvComment.Params.Language);
var commentRes = await _context.Video.NvComment.GetCommentsAsync(nvComment, new[] { ThreadTargetForkConstants.Easy });
var postedThread = commentRes.Data.Threads.FirstOrDefault(x => x.Fork == ThreadTargetForkConstants.Easy);
var myPostComments = postedThread.Comments.Where(x => x.IsMyPost);
int deleteTargetCommentNumber = -1;

0 comments on commit 0ca1ebc

Please sign in to comment.