From d32acbda828ea8d7096215945972abf02e1fda23 Mon Sep 17 00:00:00 2001 From: Pavel Zhur Date: Sat, 7 Sep 2024 16:02:38 +0300 Subject: [PATCH] downloading the items locally to the drive --- ...9_TelegramMediaItemsDownloaded.Designer.cs | 707 ++++++++++++++++++ ...0907124519_TelegramMediaItemsDownloaded.cs | 38 + .../Migrations/VideosDatabaseModelSnapshot.cs | 6 + .../Models/TelegramItem.cs | 3 + .../Commands/DownloadAll.cs | 86 +++ .../Commands/ShowHandlers.cs | 1 - .../PipelineHandlers/VideosCollector.cs | 33 +- .../ServiceCollectionExtensions.cs | 1 + .../Services/SingletonAbstractions.cs | 1 + 9 files changed, 845 insertions(+), 31 deletions(-) create mode 100644 OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240907124519_TelegramMediaItemsDownloaded.Designer.cs create mode 100644 OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240907124519_TelegramMediaItemsDownloaded.cs create mode 100644 OneShelf.Videos/OneShelf.Videos.Telegram.Processor/Commands/DownloadAll.cs diff --git a/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240907124519_TelegramMediaItemsDownloaded.Designer.cs b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240907124519_TelegramMediaItemsDownloaded.Designer.cs new file mode 100644 index 00000000..9d3aef8d --- /dev/null +++ b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240907124519_TelegramMediaItemsDownloaded.Designer.cs @@ -0,0 +1,707 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using OneShelf.Videos.Database; + +#nullable disable + +namespace OneShelf.Videos.Database.Migrations.VideosDatabaseMigrations +{ + [DbContext(typeof(VideosDatabase))] + [Migration("20240907124519_TelegramMediaItemsDownloaded")] + partial class TelegramMediaItemsDownloaded + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.Album", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Albums"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.AlbumConstraint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("After") + .HasColumnType("datetime2"); + + b.Property("AlbumId") + .HasColumnType("int"); + + b.Property("Before") + .HasColumnType("datetime2"); + + b.Property("Include") + .HasColumnType("bit"); + + b.Property("IsSquare") + .HasColumnType("bit"); + + b.Property("MessageSelectedType") + .HasColumnType("nvarchar(max)"); + + b.Property("TopicId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("AlbumId"); + + b.HasIndex("TopicId"); + + b.ToTable("AlbumConstraints"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.ChatFolder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("Root") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ChatFolders"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.InventoryItem", b => + { + b.Property("DatabaseInventoryItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("DatabaseInventoryItemId")); + + b.Property("BaseUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ContributorInfoDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ContributorInfoProfilePictureBaseUrl") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("FileName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Id") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsPhoto") + .HasColumnType("bit"); + + b.Property("IsVideo") + .HasColumnType("bit"); + + b.Property("MediaMetadataCreationTime") + .HasColumnType("datetime2"); + + b.Property("MediaMetadataHeight") + .HasColumnType("nvarchar(max)"); + + b.Property("MediaMetadataPhotoApertureFNumber") + .HasColumnType("real"); + + b.Property("MediaMetadataPhotoCameraMake") + .HasColumnType("nvarchar(max)"); + + b.Property("MediaMetadataPhotoCameraModel") + .HasColumnType("nvarchar(max)"); + + b.Property("MediaMetadataPhotoExposureTime") + .HasColumnType("nvarchar(max)"); + + b.Property("MediaMetadataPhotoFocalLength") + .HasColumnType("real"); + + b.Property("MediaMetadataPhotoIsoEquivalent") + .HasColumnType("int"); + + b.Property("MediaMetadataVideoCameraMake") + .HasColumnType("nvarchar(max)"); + + b.Property("MediaMetadataVideoCameraModel") + .HasColumnType("nvarchar(max)"); + + b.Property("MediaMetadataVideoFps") + .HasColumnType("float"); + + b.Property("MediaMetadataVideoStatus") + .HasColumnType("nvarchar(max)"); + + b.Property("MediaMetadataWidth") + .HasColumnType("nvarchar(max)"); + + b.Property("MimeType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ProductUrl") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SyncDate") + .HasColumnType("datetime2"); + + b.HasKey("DatabaseInventoryItemId"); + + b.ToTable("InventoryItems"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.Json.Chat", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("ChatFolderId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ChatFolderId") + .IsUnique(); + + b.ToTable("Chats"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.Json.Message", b => + { + b.Property("DatabaseMessageId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("DatabaseMessageId")); + + b.Property("Action") + .HasColumnType("nvarchar(max)"); + + b.Property("Actor") + .HasColumnType("nvarchar(max)"); + + b.Property("ActorId") + .HasColumnType("nvarchar(max)"); + + b.Property("Boosts") + .HasColumnType("int"); + + b.Property("ChatId") + .HasColumnType("bigint"); + + b.Property("ContactInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("DateUnixtime") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Duration") + .HasColumnType("int"); + + b.Property("DurationSeconds") + .HasColumnType("int"); + + b.Property("Edited") + .HasColumnType("datetime2"); + + b.Property("EditedUnixtime") + .HasColumnType("nvarchar(max)"); + + b.Property("File") + .HasColumnType("nvarchar(max)"); + + b.Property("FileName") + .HasColumnType("nvarchar(max)"); + + b.Property("ForwardedFrom") + .HasColumnType("nvarchar(max)"); + + b.Property("From") + .HasColumnType("nvarchar(max)"); + + b.Property("FromId") + .HasColumnType("nvarchar(max)"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Id") + .HasColumnType("int"); + + b.Property("InlineBotButtons") + .HasColumnType("nvarchar(max)"); + + b.Property("Inviter") + .HasColumnType("nvarchar(max)"); + + b.Property("LiveLocationPeriodSeconds") + .HasColumnType("int"); + + b.Property("LocationInformation") + .HasColumnType("nvarchar(max)"); + + b.Property("MediaType") + .HasColumnType("nvarchar(max)"); + + b.Property("Members") + .HasColumnType("nvarchar(max)"); + + b.Property("MessageId") + .HasColumnType("int"); + + b.Property("MimeType") + .HasColumnType("nvarchar(max)"); + + b.Property("NewIconEmojiId") + .HasColumnType("bigint"); + + b.Property("NewTitle") + .HasColumnType("nvarchar(max)"); + + b.Property("Performer") + .HasColumnType("nvarchar(max)"); + + b.Property("Photo") + .HasColumnType("nvarchar(max)"); + + b.Property("Poll") + .HasColumnType("nvarchar(max)"); + + b.Property("ReplyToMessageId") + .HasColumnType("int"); + + b.Property("ReplyToPeerId") + .HasColumnType("nvarchar(max)"); + + b.Property("SavedFrom") + .HasColumnType("nvarchar(max)"); + + b.Property("ScheduleDate") + .HasColumnType("int"); + + b.Property("SelectedType") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("nvarchar(max)") + .HasComputedColumnSql("case when photo is not null then 'photo' when mimetype like 'video/%' and isnull(mediatype, 'null') in ('video_file', 'null') then 'video' else null end"); + + b.Property("StickerEmoji") + .HasColumnType("nvarchar(max)"); + + b.Property("Text") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TextEntities") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Thumbnail") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .HasColumnType("nvarchar(max)"); + + b.Property("TopicId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ViaBot") + .HasColumnType("nvarchar(max)"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("DatabaseMessageId"); + + b.HasIndex("TopicId"); + + b.HasIndex("ChatId", "Id") + .IsUnique(); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.TelegramMedia", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChatId") + .HasColumnType("bigint"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("DownloadedFileName") + .HasColumnType("nvarchar(max)"); + + b.Property("DownloadedThumbnailFileName") + .HasColumnType("nvarchar(max)"); + + b.Property("Duration") + .HasColumnType("int"); + + b.Property("FileId") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FileName") + .HasColumnType("nvarchar(max)"); + + b.Property("FileSize") + .HasColumnType("bigint"); + + b.Property("FileUniqueId") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ForwardOriginTitle") + .HasColumnType("nvarchar(max)"); + + b.Property("HandlerMessageId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("MediaGroupId") + .HasColumnType("nvarchar(450)"); + + b.Property("MessageId") + .HasColumnType("int"); + + b.Property("MimeType") + .HasColumnType("nvarchar(max)"); + + b.Property("TelegramPublishedOn") + .HasColumnType("datetime2"); + + b.Property("TelegramUpdateId") + .HasColumnType("int"); + + b.Property("ThumbnailFileId") + .HasColumnType("nvarchar(max)"); + + b.Property("ThumbnailHeight") + .HasColumnType("int"); + + b.Property("ThumbnailWidth") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("MediaGroupId"); + + b.HasIndex("TelegramUpdateId") + .IsUnique(); + + b.ToTable("TelegramMedia"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.TelegramUpdate", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("Json") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("TelegramUpdates"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.Topic", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChatId") + .HasColumnType("bigint"); + + b.Property("OriginalTitle") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("RootMessageIdOr0") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ChatId", "RootMessageIdOr0") + .IsUnique(); + + b.ToTable("Topics"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.UploadedAlbum", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AlbumId") + .HasColumnType("int"); + + b.Property("GoogleAlbumId") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("AlbumId") + .IsUnique(); + + b.ToTable("UploadedAlbums"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.UploadedItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChatId") + .HasColumnType("bigint"); + + b.Property("CreatedOn") + .HasColumnType("datetime2"); + + b.Property("FileNameTimestamp") + .HasColumnType("datetime2"); + + b.Property("Json") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("MediaItemId") + .HasColumnType("nvarchar(max)"); + + b.Property("MediaItemIsPhoto") + .HasColumnType("bit"); + + b.Property("MediaItemIsVideo") + .HasColumnType("bit"); + + b.Property("MediaItemMetadataCreationTime") + .HasColumnType("datetime2"); + + b.Property("MediaItemMimeType") + .HasColumnType("nvarchar(max)"); + + b.Property("MediaItemSyncDate") + .HasColumnType("datetime2"); + + b.Property("MessageId") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("nvarchar(max)"); + + b.Property("StatusCode") + .HasColumnType("int"); + + b.Property("StatusMessage") + .HasColumnType("nvarchar(max)"); + + b.Property("TelegramPublishedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("UploadedItems"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.AlbumConstraint", b => + { + b.HasOne("OneShelf.Videos.Database.Models.Album", "Album") + .WithMany("Constraints") + .HasForeignKey("AlbumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OneShelf.Videos.Database.Models.Topic", "Topic") + .WithMany("AlbumConstraints") + .HasForeignKey("TopicId"); + + b.Navigation("Album"); + + b.Navigation("Topic"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.Json.Chat", b => + { + b.HasOne("OneShelf.Videos.Database.Models.ChatFolder", "ChatFolder") + .WithOne("Chat") + .HasForeignKey("OneShelf.Videos.Database.Models.Json.Chat", "ChatFolderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatFolder"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.Json.Message", b => + { + b.HasOne("OneShelf.Videos.Database.Models.Json.Chat", "Chat") + .WithMany("Messages") + .HasForeignKey("ChatId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OneShelf.Videos.Database.Models.Topic", "Topic") + .WithMany("Messages") + .HasForeignKey("TopicId"); + + b.Navigation("Chat"); + + b.Navigation("Topic"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.TelegramMedia", b => + { + b.HasOne("OneShelf.Videos.Database.Models.TelegramUpdate", "TelegramUpdate") + .WithOne("TelegramMedia") + .HasForeignKey("OneShelf.Videos.Database.Models.TelegramMedia", "TelegramUpdateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TelegramUpdate"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.Topic", b => + { + b.HasOne("OneShelf.Videos.Database.Models.Json.Chat", "Chat") + .WithMany() + .HasForeignKey("ChatId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chat"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.UploadedAlbum", b => + { + b.HasOne("OneShelf.Videos.Database.Models.Album", "Album") + .WithOne("UploadedAlbum") + .HasForeignKey("OneShelf.Videos.Database.Models.UploadedAlbum", "AlbumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Album"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.Album", b => + { + b.Navigation("Constraints"); + + b.Navigation("UploadedAlbum"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.ChatFolder", b => + { + b.Navigation("Chat"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.Json.Chat", b => + { + b.Navigation("Messages"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.TelegramUpdate", b => + { + b.Navigation("TelegramMedia"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.Topic", b => + { + b.Navigation("AlbumConstraints"); + + b.Navigation("Messages"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240907124519_TelegramMediaItemsDownloaded.cs b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240907124519_TelegramMediaItemsDownloaded.cs new file mode 100644 index 00000000..613dd64d --- /dev/null +++ b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240907124519_TelegramMediaItemsDownloaded.cs @@ -0,0 +1,38 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace OneShelf.Videos.Database.Migrations.VideosDatabaseMigrations +{ + /// + public partial class TelegramMediaItemsDownloaded : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "DownloadedFileName", + table: "TelegramMedia", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.AddColumn( + name: "DownloadedThumbnailFileName", + table: "TelegramMedia", + type: "nvarchar(max)", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "DownloadedFileName", + table: "TelegramMedia"); + + migrationBuilder.DropColumn( + name: "DownloadedThumbnailFileName", + table: "TelegramMedia"); + } + } +} diff --git a/OneShelf.Videos/OneShelf.Videos.Database/Migrations/VideosDatabaseModelSnapshot.cs b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/VideosDatabaseModelSnapshot.cs index 242254b4..6311e048 100644 --- a/OneShelf.Videos/OneShelf.Videos.Database/Migrations/VideosDatabaseModelSnapshot.cs +++ b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/VideosDatabaseModelSnapshot.cs @@ -391,6 +391,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("CreatedOn") .HasColumnType("datetime2"); + b.Property("DownloadedFileName") + .HasColumnType("nvarchar(max)"); + + b.Property("DownloadedThumbnailFileName") + .HasColumnType("nvarchar(max)"); + b.Property("Duration") .HasColumnType("int"); diff --git a/OneShelf.Videos/OneShelf.Videos.Database/Models/TelegramItem.cs b/OneShelf.Videos/OneShelf.Videos.Database/Models/TelegramItem.cs index 9addbe3a..0bbe12a6 100644 --- a/OneShelf.Videos/OneShelf.Videos.Database/Models/TelegramItem.cs +++ b/OneShelf.Videos/OneShelf.Videos.Database/Models/TelegramItem.cs @@ -15,6 +15,9 @@ public class TelegramMedia public int? HandlerMessageId { get; set; } + public string? DownloadedFileName { get; set; } + public string? DownloadedThumbnailFileName { get; set; } + public required DateTime CreatedOn { get; set; } public required DateTime TelegramPublishedOn { get; set; } diff --git a/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/Commands/DownloadAll.cs b/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/Commands/DownloadAll.cs new file mode 100644 index 00000000..e1ea6366 --- /dev/null +++ b/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/Commands/DownloadAll.cs @@ -0,0 +1,86 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; +using OneShelf.Common; +using OneShelf.Telegram.Model.CommandAttributes; +using OneShelf.Telegram.Model.Ios; +using OneShelf.Telegram.Services.Base; +using OneShelf.Videos.BusinessLogic.Models; +using OneShelf.Videos.Database; +using OneShelf.Videos.Database.Models; +using OneShelf.Videos.Telegram.Processor.Model; +using Telegram.BotAPI; +using Telegram.BotAPI.AvailableMethods; +using Telegram.BotAPI.UpdatingMessages; +using File = System.IO.File; + +namespace OneShelf.Videos.Telegram.Processor.Commands; + +[AdminCommand("download_all", "Скачать", "Скачать с хендлерами")] +public class DownloadAll : Command +{ + private readonly VideosDatabase _videosDatabase; + private readonly IOptions _telegramOptions; + private readonly IOptions _videoOptions; + private readonly TelegramBotClient _botClient; + private readonly HttpClient _httpClient; + + public DownloadAll(Io io, VideosDatabase videosDatabase, IOptions telegramOptions, HttpClient httpClient, IOptions videoOptions) + : base(io) + { + _videosDatabase = videosDatabase; + _telegramOptions = telegramOptions; + _httpClient = httpClient; + _videoOptions = videoOptions; + _botClient = new(_telegramOptions.Value.Token); + } + + protected override async Task ExecuteQuickly() + { + var items = await _videosDatabase.TelegramMedia + .Where(x => x.HandlerMessageId.HasValue && x.DownloadedFileName == null).ToListAsync(); + + if (!items.Any()) + { + Io.WriteLine("Нечего скачивать."); + return; + } + + Scheduled(Background(items)); + } + + private async Task Background(List items) + { + var progress = await _botClient.SendMessageAsync(Io.UserId, items.Count.ToString()); + var progressUpdated = DateTime.Now; + + foreach (var (telegramMedia, i) in items.WithIndices()) + { + telegramMedia.DownloadedFileName = await Save(telegramMedia, false); + await _videosDatabase.SaveChangesAsync(); + + if (telegramMedia.ThumbnailFileId != null) + { + telegramMedia.DownloadedThumbnailFileName = await Save(telegramMedia, true); + await _videosDatabase.SaveChangesAsync(); + } + + if ((DateTime.Now - progressUpdated).TotalSeconds > 5 || i == items.Count - 1) + { + await _botClient.EditMessageTextAsync(progress.Chat.Id, progress.MessageId, $"{i + 1}/{items.Count}"); + progressUpdated = DateTime.Now; + } + } + } + + private async Task Save(TelegramMedia telegramMedia, bool isThumbnail) + { + var file = await _botClient.GetFileAsync(isThumbnail ? telegramMedia.ThumbnailFileId! : telegramMedia.FileId); + Console.WriteLine(file.FilePath); + var response = await _httpClient.GetAsync($"https://api.telegram.org/file/bot{_telegramOptions.Value.Token}/{file.FilePath}"); + var bytes = await response.Content.ReadAsByteArrayAsync(); + Console.WriteLine(bytes.Length); + var name = $"{DateTime.Now.Ticks}_{telegramMedia.FileName}"; + await File.WriteAllBytesAsync(Path.Combine(_videoOptions.Value.BasePath, "_uploaded", isThumbnail ? "thumbnails" : ".", name), bytes); + return name; + } +} \ No newline at end of file diff --git a/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/Commands/ShowHandlers.cs b/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/Commands/ShowHandlers.cs index 58770845..8a3bd740 100644 --- a/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/Commands/ShowHandlers.cs +++ b/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/Commands/ShowHandlers.cs @@ -5,7 +5,6 @@ using OneShelf.Telegram.Model.Ios; using OneShelf.Telegram.Services.Base; using OneShelf.Videos.Database; -using OneShelf.Videos.Database.Models; using OneShelf.Videos.Telegram.Processor.Model; using Telegram.BotAPI; using Telegram.BotAPI.AvailableMethods; diff --git a/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/PipelineHandlers/VideosCollector.cs b/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/PipelineHandlers/VideosCollector.cs index 5d6b5c4c..175771ba 100644 --- a/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/PipelineHandlers/VideosCollector.cs +++ b/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/PipelineHandlers/VideosCollector.cs @@ -12,8 +12,6 @@ using Telegram.BotAPI.AvailableMethods; using Telegram.BotAPI.AvailableTypes; using Telegram.BotAPI.GettingUpdates; -using Telegram.BotAPI.UpdatingMessages; -using File = System.IO.File; namespace OneShelf.Videos.Telegram.Processor.PipelineHandlers; @@ -22,18 +20,14 @@ public class VideosCollector : PipelineHandler private readonly VideosDatabase _videosDatabase; private readonly IOptions _telegramOptions; private readonly Scope _scope; - private readonly HttpClient _httpClient; - private readonly IOptions _videoOptions; private readonly VideosCollectorMemory _videosCollectorMemory; - public VideosCollector(IScopedAbstractions scopedAbstractions, VideosDatabase videosDatabase, IOptions telegramOptions, Scope scope, HttpClient httpClient, IOptions videoOptions, VideosCollectorMemory videosCollectorMemory) + public VideosCollector(IScopedAbstractions scopedAbstractions, VideosDatabase videosDatabase, IOptions telegramOptions, Scope scope, VideosCollectorMemory videosCollectorMemory) : base(scopedAbstractions) { _videosDatabase = videosDatabase; _telegramOptions = telegramOptions; _scope = scope; - _httpClient = httpClient; - _videoOptions = videoOptions; _videosCollectorMemory = videosCollectorMemory; } @@ -165,12 +159,12 @@ protected override async Task HandleSync(Update update) await _videosDatabase.SaveChangesAsync(); } - QueueApi(null, api => Respond(api, update, telegramMedia, alreadyResponded)); + QueueApi(null, api => Respond(api, update, alreadyResponded)); return true; } - private async Task Respond(TelegramBotClient api, Update update, TelegramMedia telegramMedia, bool alreadyResponded) + private async Task Respond(TelegramBotClient api, Update update, bool alreadyResponded) { if (!alreadyResponded) { @@ -179,26 +173,5 @@ await api.SetMessageReactionAsync( update.Message.MessageId, [new ReactionTypeEmoji("👀")]); } - - //telegramMedia.DownloadedFileName = await Save(api, telegramMedia, false); - //await _videosDatabase.SaveChangesAsync(); - - //if (telegramMedia.ThumbnailFileId != null) - //{ - // telegramMedia.DownloadedThumbnailFileName = await Save(api, telegramMedia, true); - // await _videosDatabase.SaveChangesAsync(); - //} } - - //private async Task Save(TelegramBotClient api, TelegramMedia telegramMedia, bool isThumbnail) - //{ - // var file = await api.GetFileAsync(isThumbnail ? telegramMedia.ThumbnailFileId! : telegramMedia.FileId); - // Console.WriteLine(file.FilePath); - // var response = await _httpClient.GetAsync($"https://api.telegram.org/file/bot{_telegramOptions.Value.Token}/{file.FilePath}"); - // var bytes = await response.Content.ReadAsByteArrayAsync(); - // Console.WriteLine(bytes.Length); - // var name = $"{DateTime.Now.Ticks}_{telegramMedia.FileName}"; - // await File.WriteAllBytesAsync(Path.Combine(_videoOptions.Value.BasePath, "_uploaded", isThumbnail ? "thumbnails" : ".", name), bytes); - // return name; - //} } \ No newline at end of file diff --git a/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/ServiceCollectionExtensions.cs b/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/ServiceCollectionExtensions.cs index 9cae843e..779bfa59 100644 --- a/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/ServiceCollectionExtensions.cs +++ b/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/ServiceCollectionExtensions.cs @@ -28,6 +28,7 @@ public static IServiceCollection AddProcessor(this IServiceCollection services, .AddCommand() .AddCommand() .AddCommand() + .AddCommand() .AddPipelineHandlerInOrder() .AddPipelineHandlerInOrder() diff --git a/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/Services/SingletonAbstractions.cs b/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/Services/SingletonAbstractions.cs index 5477ce8e..9337e616 100644 --- a/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/Services/SingletonAbstractions.cs +++ b/OneShelf.Videos/OneShelf.Videos.Telegram.Processor/Services/SingletonAbstractions.cs @@ -14,6 +14,7 @@ public List> GetCommandsGrid() => [ ], [ typeof(ShowHandlers), + typeof(DownloadAll), ], [ typeof(ViewChats),