Skip to content

Commit

Permalink
downloading the media items
Browse files Browse the repository at this point in the history
  • Loading branch information
pavel-zhur committed Sep 20, 2024
1 parent bb73a32 commit 063da26
Show file tree
Hide file tree
Showing 9 changed files with 1,703 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<PackageReference Include="CasCap.Apis.GooglePhotos" Version="3.0.1" />
<PackageReference Include="CsvHelper" Version="33.0.1" />
<PackageReference Include="ExifLibNet" Version="2.1.4" />
<PackageReference Include="Nito.AsyncEx.Coordination" Version="5.1.2" />
<PackageReference Include="WTelegramClient" Version="4.1.9" />
</ItemGroup>

Expand Down
69 changes: 67 additions & 2 deletions OneShelf.Videos/OneShelf.Videos.BusinessLogic/Services/Service4.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Nito.AsyncEx;
using OneShelf.Videos.BusinessLogic.Models;
using OneShelf.Videos.Database;
using OneShelf.Videos.Database.Models;
Expand All @@ -17,6 +18,7 @@ namespace OneShelf.Videos.BusinessLogic.Services;
public class Service4(IOptions<VideosOptions> options, ILogger<Service4> logger, VideosDatabase videosDatabase, TelegramLoggerInitializer _) : IDisposable
{
private byte[]? _session;
private readonly AsyncLock _databaseLock = new();

public async Task Try()
{
Expand Down Expand Up @@ -45,9 +47,72 @@ private async Task ProcessChat(Client client, ChatBase chat)

//await client.DownloadFileAsync(topics[0].media[0].document.ToFileLocation(topics[0].media[0].document.LargestThumbSize), outputStream)

logger.LogInformation(string.Join(Environment.NewLine, topics.Select(x => $"{x.Key}={x.Value.name} (d: {x.Value.media.Count(x => x.document != null)}, p: {x.Value.media.Count(x => x.photo != null)})")));

await Save(chat, topics);

await Download(client, chat, topics);
}

private async Task Download(Client client, ChatBase chat, Dictionary<int, (string name, List<(Document? document, Photo? photo, Message message, string mediaFlags)> media)> topics)
{
var liveChat = await videosDatabase.LiveChats.Include(x => x.Topics).ThenInclude(x => x.Mediae).Where(x => x.Id == chat.ID).SingleAsync();
var liveMediae = liveChat.Topics.SelectMany(t => t.Mediae).Join(topics.SelectMany(x => x.Value.media), x => x.Id, x => x.message.ID, (x, y) => (x, y)).ToList();
var downloadedItems = await videosDatabase.DownloadedItems.Where(x => videosDatabase.LiveMediae.Any(y => y.TopicChatId == chat.ID && y.MediaId == x.LiveMediaId)).ToDictionaryAsync(x => x.LiveMediaId);

var success = 0;
var items = liveMediae.DistinctBy(x => x.x.MediaId).Where(x => !downloadedItems.TryGetValue(x.x.MediaId, out var y) || y.ThumbnailFileName == null).ToList();

await Parallel.ForEachAsync(
items,
new ParallelOptions { MaxDegreeOfParallelism = 3, },
async (item, cancellationToken) =>
{
var (liveMedia, (document, photo, message, mediaFlags)) = item;
var downloaded = downloadedItems.GetValueOrDefault(liveMedia.Id);

if (downloaded == null)
{
try
{
using var outputStream = new MemoryStream();
if (document != null)
{
await client.DownloadFileAsync(document, outputStream);
}
else
{
await client.DownloadFileAsync(photo, outputStream);
}

var fileName = liveMedia.FileName != null && !string.IsNullOrWhiteSpace(Path.GetExtension(liveMedia.FileName)) ? $"{liveMedia.MediaId}{Path.GetExtension(liveMedia.FileName)}" : liveMedia.MediaId.ToString();
await File.WriteAllBytesAsync(
Path.Combine(options.Value.BasePath, "_instant", fileName),
outputStream.ToArray(), cancellationToken);

using var _ = await _databaseLock.LockAsync();

videosDatabase.DownloadedItems.Add(downloaded = new()
{
LiveMediaId = liveMedia.MediaId,
FileName = fileName,
});

await videosDatabase.SaveChangesAsync(cancellationToken);
}
catch (Exception e)
{
logger.LogError(e, message: "Error downloading an item.");
downloaded = null;
}
}

if (downloaded != null)
{
// download thumbnail too

}

logger.LogInformation("Success {value} / {total}", Interlocked.Increment(ref success), items.Count);
});
}

private async Task Save(ChatBase chat, Dictionary<int, (string name, List<(Document? document, Photo? photo, Message message, string mediaFlags)> media)> topics)
Expand Down
Loading

0 comments on commit 063da26

Please sign in to comment.