Skip to content

Commit

Permalink
Merge pull request #351 from opentween/thumbnailinfo
Browse files Browse the repository at this point in the history
ThumbnailInfoから画像ダウンロード処理を分離
  • Loading branch information
upsilon authored Jun 5, 2024
2 parents a5456ea + cfa9a02 commit 5f66767
Show file tree
Hide file tree
Showing 24 changed files with 211 additions and 160 deletions.
2 changes: 1 addition & 1 deletion OpenTween.Tests/Thumbnail/Services/ImgAzyobuziNetTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public async Task MatchTest()
Assert.NotNull(thumbinfo);
Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.azyobuzi.net/api/redirect?size=large&uri=http%3A%2F%2Fexample.com%2Fabcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
Assert.Equal("", thumbinfo.TooltipText);
}

[Fact]
Expand Down
14 changes: 7 additions & 7 deletions OpenTween.Tests/Thumbnail/Services/MetaThumbnailServiceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public async Task OGPMetaTest()
Assert.NotNull(thumbinfo);
Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
Assert.Equal("", thumbinfo.TooltipText);
}

[Fact]
Expand All @@ -94,7 +94,7 @@ public async Task TwitterMetaTest()
Assert.NotNull(thumbinfo);
Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
Assert.Equal("", thumbinfo.TooltipText);
}

[Fact]
Expand All @@ -116,7 +116,7 @@ public async Task InvalidMetaTest()
Assert.NotNull(thumbinfo);
Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
Assert.Equal("", thumbinfo.TooltipText);
}

[Fact]
Expand All @@ -138,7 +138,7 @@ public async Task ReverseMetaTest()
Assert.NotNull(thumbinfo);
Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
Assert.Equal("", thumbinfo.TooltipText);
}

[Fact]
Expand All @@ -161,7 +161,7 @@ public async Task BadMetaTest()
Assert.NotNull(thumbinfo);
Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
Assert.Equal("", thumbinfo.TooltipText);
}

[Fact]
Expand All @@ -183,7 +183,7 @@ public async Task BadMetaOneLineTest()
Assert.NotNull(thumbinfo);
Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
Assert.Equal("", thumbinfo.TooltipText);
}

[Fact]
Expand All @@ -205,7 +205,7 @@ public async Task ReverseMetaOneLineTest()
Assert.NotNull(thumbinfo);
Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
Assert.Equal("", thumbinfo.TooltipText);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public async Task RegexMatchTest()
Assert.NotNull(thumbinfo);
Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
Assert.Equal("", thumbinfo.TooltipText);
}

[Fact]
Expand Down
12 changes: 5 additions & 7 deletions OpenTween.Tests/Thumbnail/Services/TonTwitterComTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,12 @@ public async Task LoadThumbnailImageAsync_Test()
.ReturnsAsync(response);

var apiConnection = mock.Object;
var thumb = new TonTwitterCom.Thumbnail(apiConnection)
{
MediaPageUrl = "https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg:large",
FullSizeImageUrl = "https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg:large",
ThumbnailImageUrl = "https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg",
};
var thumbLoader = new TonTwitterCom.ThumbnailLoader(
apiConnection,
new("https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg")
);

var result = await thumb.LoadThumbnailImageAsync(CancellationToken.None);
var result = await thumbLoader.Load(null!, CancellationToken.None);
Assert.Equal(image, result);

mock.VerifyAll();
Expand Down
7 changes: 1 addition & 6 deletions OpenTween.Tests/Thumbnail/Services/TumblrTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,7 @@ public void ParsePostJson_Test()

var expected = new[]
{
new ThumbnailInfo
{
MediaPageUrl = "http://example.com/post/1234567",
ThumbnailImageUrl = "http://example.com/photo/1280/1234567/1/tumblr_hogehoge",
TooltipText = null,
},
new ThumbnailInfo("http://example.com/post/1234567", "http://example.com/photo/1280/1234567/1/tumblr_hogehoge"),
};
Assert.Equal(expected, thumbs);
}
Expand Down
41 changes: 24 additions & 17 deletions OpenTween.Tests/TweetThumbnailTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,17 @@ private IThumbnailService CreateThumbnailService()
.Setup(
x => x.GetThumbnailInfoAsync("http://example.com/abcd", It.IsAny<PostClass>(), It.IsAny<CancellationToken>())
)
.ReturnsAsync(new MockThumbnailInfo
.ReturnsAsync(new ThumbnailInfo("http://example.com/abcd", "http://img.example.com/abcd.png")
{
MediaPageUrl = "http://example.com/abcd",
ThumbnailImageUrl = "http://img.example.com/abcd.png",
Loader = new FakeThumbnailLoader(),
});
thumbnailServiceMock
.Setup(
x => x.GetThumbnailInfoAsync("http://example.com/efgh", It.IsAny<PostClass>(), It.IsAny<CancellationToken>())
)
.ReturnsAsync(new MockThumbnailInfo
.ReturnsAsync(new ThumbnailInfo("http://example.com/efgh", "http://img.example.com/efgh.png")
{
MediaPageUrl = "http://example.com/efgh",
ThumbnailImageUrl = "http://img.example.com/efgh.png",
Loader = new FakeThumbnailLoader(),
});
return thumbnailServiceMock.Object;
}
Expand Down Expand Up @@ -124,7 +122,10 @@ public async Task PrepareThumbnails_CancelTest()
.Returns(async () =>
{
await Task.Delay(200);
return new MockThumbnailInfo();
return new ThumbnailInfo("http://slow.example.com/abcd", "http://slow.example.com/abcd")
{
Loader = new FakeThumbnailLoader(),
};
});

var thumbnailGenerator = this.CreateThumbnailGenerator();
Expand All @@ -151,10 +152,10 @@ public async Task PrepareThumbnails_CancelTest()
public async Task LoadSelectedThumbnail_Test()
{
using var image = TestUtils.CreateDummyImage();
var thumbnailInfoMock = new Mock<ThumbnailInfo>() { CallBase = true };
thumbnailInfoMock
var thumbnailLoaderMock = new Mock<IThumbnailLoader>();
thumbnailLoaderMock
.Setup(
x => x.LoadThumbnailImageAsync(It.IsAny<HttpClient>(), It.IsAny<CancellationToken>())
x => x.Load(It.IsAny<HttpClient>(), It.IsAny<CancellationToken>())
)
.ReturnsAsync(image);

Expand All @@ -163,7 +164,10 @@ public async Task LoadSelectedThumbnail_Test()
.Setup(
x => x.GetThumbnailInfoAsync("http://example.com/abcd", It.IsAny<PostClass>(), It.IsAny<CancellationToken>())
)
.ReturnsAsync(thumbnailInfoMock.Object);
.ReturnsAsync(new ThumbnailInfo("http://example.com/abcd", "http://example.com/abcd")
{
Loader = thumbnailLoaderMock.Object,
});

var thumbnailGenerator = this.CreateThumbnailGenerator();
thumbnailGenerator.Services.Add(thumbnailServiceMock.Object);
Expand All @@ -187,10 +191,10 @@ public async Task LoadSelectedThumbnail_Test()
public async Task LoadSelectedThumbnail_RequestCollapsingTest()
{
var tsc = new TaskCompletionSource<MemoryImage>();
var thumbnailInfoMock = new Mock<ThumbnailInfo>() { CallBase = true };
thumbnailInfoMock
var thumbnailLoaderMock = new Mock<IThumbnailLoader>();
thumbnailLoaderMock
.Setup(
x => x.LoadThumbnailImageAsync(It.IsAny<HttpClient>(), It.IsAny<CancellationToken>())
x => x.Load(It.IsAny<HttpClient>(), It.IsAny<CancellationToken>())
)
.Returns(tsc.Task);

Expand All @@ -199,7 +203,10 @@ public async Task LoadSelectedThumbnail_RequestCollapsingTest()
.Setup(
x => x.GetThumbnailInfoAsync("http://example.com/abcd", It.IsAny<PostClass>(), It.IsAny<CancellationToken>())
)
.ReturnsAsync(thumbnailInfoMock.Object);
.ReturnsAsync(new ThumbnailInfo("http://example.com/abcd", "http://example.com/abcd")
{
Loader = thumbnailLoaderMock.Object,
});

var thumbnailGenerator = this.CreateThumbnailGenerator();
thumbnailGenerator.Services.Add(thumbnailServiceMock.Object);
Expand Down Expand Up @@ -354,9 +361,9 @@ public async Task Scroll_Test()
Assert.Equal(0, tweetThumbnail.SelectedIndex);
}

private class MockThumbnailInfo : ThumbnailInfo
private class FakeThumbnailLoader : IThumbnailLoader
{
public override Task<MemoryImage> LoadThumbnailImageAsync(HttpClient http, CancellationToken cancellationToken)
public Task<MemoryImage> Load(HttpClient http, CancellationToken cancellationToken)
=> Task.FromResult(TestUtils.CreateDummyImage());
}
}
Expand Down
34 changes: 34 additions & 0 deletions OpenTween/Thumbnail/IThumbnailLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// OpenTween - Client of Twitter
// Copyright (c) 2024 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
// All rights reserved.
//
// This file is part of OpenTween.
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.

#nullable enable

using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace OpenTween.Thumbnail
{
public interface IThumbnailLoader
{
public Task<MemoryImage> Load(HttpClient http, CancellationToken cancellationToken);
}
}
10 changes: 4 additions & 6 deletions OpenTween/Thumbnail/MapThumbGoogle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@ public class MapThumbGoogle : MapThumb
{
public override Task<ThumbnailInfo> GetThumbnailInfoAsync(PostClass.StatusGeo geo)
{
var thumb = new ThumbnailInfo
{
MediaPageUrl = this.CreateMapLinkUrl(geo.Latitude, geo.Longitude),
ThumbnailImageUrl = this.CreateStaticMapUrl(geo.Latitude, geo.Longitude),
TooltipText = null,
};
var mapUrl = this.CreateMapLinkUrl(geo.Latitude, geo.Longitude);
var staticImageUrl = this.CreateStaticMapUrl(geo.Latitude, geo.Longitude);

var thumb = new ThumbnailInfo(mapUrl, staticImageUrl);

return Task.FromResult(thumb);
}
Expand Down
13 changes: 7 additions & 6 deletions OpenTween/Thumbnail/MapThumbOSM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ public override Task<ThumbnailInfo> GetThumbnailInfoAsync(PostClass.StatusGeo ge
var size = new Size(SettingManager.Instance.Common.MapThumbnailWidth, SettingManager.Instance.Common.MapThumbnailHeight);
var zoom = SettingManager.Instance.Common.MapThumbnailZoom;

var thumb = new OSMThumbnailInfo(geo.Latitude, geo.Longitude, zoom, size)
var mapUrl = this.CreateMapLinkUrl(geo.Latitude, geo.Longitude);
var thumb = new ThumbnailInfo(mapUrl, null)
{
MediaPageUrl = this.CreateMapLinkUrl(geo.Latitude, geo.Longitude),
Loader = new OSMThumbnailLoader(geo.Latitude, geo.Longitude, zoom, size),
};

return Task.FromResult((ThumbnailInfo)thumb);
return Task.FromResult(thumb);
}

public string CreateMapLinkUrl(double latitude, double longitude)
Expand All @@ -57,7 +58,7 @@ public string CreateMapLinkUrl(double latitude, double longitude)
}
}

public class OSMThumbnailInfo : ThumbnailInfo
public class OSMThumbnailLoader : IThumbnailLoader
{
/// <summary>openstreetmap.org タイルサーバー</summary>
public static readonly string TileServerBase = "https://a.tile.openstreetmap.org";
Expand All @@ -77,15 +78,15 @@ public class OSMThumbnailInfo : ThumbnailInfo
/// <summary>生成するサムネイル画像のサイズ (ピクセル単位)</summary>
public Size ThumbnailSize { get; }

public OSMThumbnailInfo(double latitude, double longitude, int zoom, Size thumbSize)
public OSMThumbnailLoader(double latitude, double longitude, int zoom, Size thumbSize)
{
this.Latitude = latitude;
this.Longitude = longitude;
this.Zoom = zoom;
this.ThumbnailSize = thumbSize;
}

public override async Task<MemoryImage> LoadThumbnailImageAsync(HttpClient http, CancellationToken cancellationToken)
public async Task<MemoryImage> Load(HttpClient http, CancellationToken cancellationToken)
{
// 画像中央に描画されるタイル (ピクセル単位ではなくタイル番号を表す)
// タイル番号に小数部が含まれているが、これはタイル内の相対的な位置を表すためこのまま保持する
Expand Down
5 changes: 1 addition & 4 deletions OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,9 @@ protected virtual async Task<byte[]> FetchRegexAsync(string apiBase)
{
if (regex.IsMatch(url))
{
return new ThumbnailInfo
return new ThumbnailInfo(url, this.apiBase + "redirect?size=large&uri=" + Uri.EscapeDataString(url))
{
MediaPageUrl = url,
ThumbnailImageUrl = this.apiBase + "redirect?size=large&uri=" + Uri.EscapeDataString(url),
FullSizeImageUrl = this.apiBase + "redirect?size=full&uri=" + Uri.EscapeDataString(url),
TooltipText = null,
};
}
}
Expand Down
7 changes: 1 addition & 6 deletions OpenTween/Thumbnail/Services/MetaThumbnailService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,7 @@ public MetaThumbnailService(HttpClient? http, string urlPattern, string[]? propN
var thumbnailUrl = this.GetThumbnailUrl(content);
if (MyCommon.IsNullOrEmpty(thumbnailUrl)) return null;

return new ThumbnailInfo
{
MediaPageUrl = url,
ThumbnailImageUrl = thumbnailUrl,
TooltipText = null,
};
return new ThumbnailInfo(url, thumbnailUrl);
}
catch (HttpRequestException)
{
Expand Down
4 changes: 1 addition & 3 deletions OpenTween/Thumbnail/Services/Nicovideo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,8 @@ public class Nicovideo : IThumbnailService
if (thumbUrlElement == null)
return null;

return new ThumbnailInfo
return new ThumbnailInfo(url, thumbUrlElement.Value)
{
MediaPageUrl = url,
ThumbnailImageUrl = thumbUrlElement.Value,
TooltipText = BuildTooltip(thumbElement),
IsPlayable = true,
};
Expand Down
6 changes: 2 additions & 4 deletions OpenTween/Thumbnail/Services/PbsTwimgCom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,9 @@ public class PbsTwimgCom : IThumbnailService
var media = post.Media.FirstOrDefault(x => x.Url == url);
var altText = media?.AltText;

var thumb = new ThumbnailInfo
var thumb = new ThumbnailInfo(mediaOrig, mediaLarge)
{
MediaPageUrl = mediaOrig,
ThumbnailImageUrl = mediaLarge,
TooltipText = altText,
TooltipText = altText ?? "",
FullSizeImageUrl = mediaOrig,
};

Expand Down
Loading

0 comments on commit 5f66767

Please sign in to comment.