-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
104 changed files
with
1,294 additions
and
1,040 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
144 changes: 144 additions & 0 deletions
144
Hohoema.Models/Models.Domain/Application/ThumbnailCacheManager.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
using LiteDB; | ||
using Microsoft.Toolkit.Mvvm.DependencyInjection; | ||
using System; | ||
using System.Buffers; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Windows.Storage.Streams; | ||
using Windows.UI.Xaml.Data; | ||
using Windows.UI.Xaml.Media.Imaging; | ||
using Windows.Web.Http; | ||
|
||
namespace Hohoema.Models.Domain.Application | ||
{ | ||
public class UrlToCachedImageConverter : IValueConverter | ||
{ | ||
private readonly ThumbnailCacheManager _thumbnailCacheManager; | ||
|
||
public UrlToCachedImageConverter() | ||
{ | ||
_thumbnailCacheManager = Ioc.Default.GetService<ThumbnailCacheManager>(); | ||
} | ||
|
||
public object Convert(object value, Type targetType, object parameter, string language) | ||
{ | ||
if (value is string url) | ||
{ | ||
var bitmap = new Windows.UI.Xaml.Media.Imaging.BitmapImage(); | ||
_thumbnailCacheManager.ResolveImage(bitmap, url); | ||
return bitmap; | ||
} | ||
else if (value is Uri uri) | ||
{ | ||
var bitmap = new Windows.UI.Xaml.Media.Imaging.BitmapImage(); | ||
_thumbnailCacheManager.ResolveImage(bitmap, uri.OriginalString); | ||
return bitmap; | ||
} | ||
else | ||
{ | ||
throw new NotSupportedException(); | ||
} | ||
} | ||
|
||
public object ConvertBack(object value, Type targetType, object parameter, string language) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} | ||
|
||
public sealed class ThumbnailCacheManager | ||
{ | ||
private readonly LiteStorage _fileStorage; | ||
private readonly HttpClient _httpClient; | ||
|
||
public ThumbnailCacheManager( | ||
LiteDatabase liteDatabase | ||
) | ||
{ | ||
_fileStorage = liteDatabase.FileStorage; | ||
#if DEBUG && true | ||
foreach (var file in _fileStorage.FindAll().ToArray()) | ||
{ | ||
_fileStorage.Delete(file.Id); | ||
} | ||
#endif | ||
_httpClient = new HttpClient(); | ||
} | ||
|
||
public void Maitenance(TimeSpan expiredTime, int maxCount) | ||
{ | ||
DateTime expiredDateTime = DateTime.Now - expiredTime; | ||
foreach (var fileInfo in _fileStorage.FindAll().Where(x => x.Metadata.TryGetValue("updateAt", out var val) && (DateTime)val < expiredDateTime).ToArray()) | ||
{ | ||
_fileStorage.Delete(fileInfo.Id); | ||
} | ||
|
||
foreach (var fileInfo in _fileStorage.FindAll().OrderByDescending(x => x.UploadDate).Skip(maxCount).ToArray()) | ||
{ | ||
_fileStorage.Delete(fileInfo.Id); | ||
} | ||
} | ||
|
||
public async void ResolveImage(BitmapImage image, string imageUrl) | ||
{ | ||
var id = imageUrl.Replace("https://nicovideo.cdn.nimg.jp/thumbnails/", ""); | ||
if (TryGetCacheImageStream(id, imageUrl, out var stream)) | ||
{ | ||
using var _ = stream; | ||
image.SetSource(stream.AsRandomAccessStream()); | ||
} | ||
else | ||
{ | ||
using var res = await _httpClient.GetAsync(new Uri(imageUrl)); | ||
if (!res.Content.TryComputeLength(out var length)) { throw new InvalidOperationException(); } | ||
using var memoryStream = new MemoryStream((int)length); | ||
await res.Content.WriteToStreamAsync(memoryStream.AsOutputStream()); | ||
memoryStream.Seek(0, SeekOrigin.Begin); | ||
image.SetSource(memoryStream.AsRandomAccessStream()); | ||
memoryStream.Seek(0, SeekOrigin.Begin); | ||
SetCacheImage(id, imageUrl, memoryStream.AsInputStream()); | ||
} | ||
} | ||
|
||
private bool TryGetCacheImageStream(string id, string imageUrl, out Stream outImageStream) | ||
{ | ||
id = $"$/{id}"; | ||
if (_fileStorage.Exists(id)) | ||
{ | ||
var file = _fileStorage.FindById(id); | ||
var stream = new MemoryStream((int)file.Length); | ||
try | ||
{ | ||
file.CopyTo(stream); | ||
stream.Seek(0, SeekOrigin.Begin); | ||
_fileStorage.SetMetadata(id, new BsonDocument(new Dictionary<string, BsonValue>() { { "updateAt", DateTime.Now } })); | ||
outImageStream = stream; | ||
return true; | ||
} | ||
catch | ||
{ | ||
stream.Dispose(); | ||
throw; | ||
} | ||
} | ||
else | ||
{ | ||
outImageStream = null; | ||
return false; | ||
} | ||
|
||
} | ||
|
||
|
||
private bool SetCacheImage(string id, string imageUrl, IInputStream stream) | ||
{ | ||
id = $"$/{id}"; | ||
var file = _fileStorage.Upload(id, imageUrl, stream.AsStreamForRead()); | ||
_fileStorage.SetMetadata(id, new BsonDocument(new Dictionary<string, BsonValue>() { { "updateAt", DateTime.Now } })); | ||
return true; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.