From 063da262c4a0f861502d68addcc7bf0ba0985fd9 Mon Sep 17 00:00:00 2001 From: Pavel Zhur Date: Fri, 20 Sep 2024 16:48:27 +0300 Subject: [PATCH] downloading the media items --- .../OneShelf.Videos.BusinessLogic.csproj | 1 + .../Services/Service4.cs | 69 +- ...920124144_DownloadedItemsAdded.Designer.cs | 748 +++++++++++++++++ .../20240920124144_DownloadedItemsAdded.cs | 36 + ...20134022_DownloadedItemsUnique.Designer.cs | 754 ++++++++++++++++++ .../20240920134022_DownloadedItemsUnique.cs | 54 ++ .../Migrations/VideosDatabaseModelSnapshot.cs | 29 + .../Models/DownloadedItem.cs | 13 + .../VideosDatabase.cs | 1 + 9 files changed, 1703 insertions(+), 2 deletions(-) create mode 100644 OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920124144_DownloadedItemsAdded.Designer.cs create mode 100644 OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920124144_DownloadedItemsAdded.cs create mode 100644 OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920134022_DownloadedItemsUnique.Designer.cs create mode 100644 OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920134022_DownloadedItemsUnique.cs create mode 100644 OneShelf.Videos/OneShelf.Videos.Database/Models/DownloadedItem.cs diff --git a/OneShelf.Videos/OneShelf.Videos.BusinessLogic/OneShelf.Videos.BusinessLogic.csproj b/OneShelf.Videos/OneShelf.Videos.BusinessLogic/OneShelf.Videos.BusinessLogic.csproj index 6b6629ca..9e1da3ae 100644 --- a/OneShelf.Videos/OneShelf.Videos.BusinessLogic/OneShelf.Videos.BusinessLogic.csproj +++ b/OneShelf.Videos/OneShelf.Videos.BusinessLogic/OneShelf.Videos.BusinessLogic.csproj @@ -11,6 +11,7 @@ + diff --git a/OneShelf.Videos/OneShelf.Videos.BusinessLogic/Services/Service4.cs b/OneShelf.Videos/OneShelf.Videos.BusinessLogic/Services/Service4.cs index 06babacc..6ee9bc86 100644 --- a/OneShelf.Videos/OneShelf.Videos.BusinessLogic/Services/Service4.cs +++ b/OneShelf.Videos/OneShelf.Videos.BusinessLogic/Services/Service4.cs @@ -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; @@ -17,6 +18,7 @@ namespace OneShelf.Videos.BusinessLogic.Services; public class Service4(IOptions options, ILogger logger, VideosDatabase videosDatabase, TelegramLoggerInitializer _) : IDisposable { private byte[]? _session; + private readonly AsyncLock _databaseLock = new(); public async Task Try() { @@ -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 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 media)> topics) diff --git a/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920124144_DownloadedItemsAdded.Designer.cs b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920124144_DownloadedItemsAdded.Designer.cs new file mode 100644 index 00000000..e77103d1 --- /dev/null +++ b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920124144_DownloadedItemsAdded.Designer.cs @@ -0,0 +1,748 @@ +// +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("20240920124144_DownloadedItemsAdded")] + partial class DownloadedItemsAdded + { + /// + 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.DownloadedItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("LiveMediaId") + .HasColumnType("bigint"); + + b.Property("ThumbnailFileName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("DownloadedItems"); + }); + + 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.LiveChat", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("LiveChats"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.LiveMedia", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("TopicChatId") + .HasColumnType("bigint"); + + b.Property("DocumentAttributeTypes") + .HasColumnType("nvarchar(max)"); + + b.Property("DocumentAttributes") + .HasColumnType("nvarchar(max)"); + + b.Property("Duration") + .HasColumnType("float"); + + b.Property("FileName") + .HasColumnType("nvarchar(max)"); + + b.Property("Flags") + .HasColumnType("nvarchar(max)"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("IsForwarded") + .HasColumnType("bit"); + + b.Property("MediaDate") + .HasColumnType("datetime2"); + + b.Property("MediaFlags") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("MediaType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("MessageDate") + .HasColumnType("datetime2"); + + b.Property("MimeType") + .HasColumnType("nvarchar(max)"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.Property("TopicId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("VideoFlags") + .HasColumnType("nvarchar(max)"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id", "TopicChatId"); + + b.HasIndex("TopicId", "TopicChatId"); + + b.ToTable("LiveMediae"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.LiveTopic", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("ChatId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id", "ChatId"); + + b.HasIndex("ChatId"); + + b.ToTable("LiveTopics"); + }); + + 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.LiveMedia", b => + { + b.HasOne("OneShelf.Videos.Database.Models.LiveTopic", "Topic") + .WithMany("Mediae") + .HasForeignKey("TopicId", "TopicChatId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Topic"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.LiveTopic", b => + { + b.HasOne("OneShelf.Videos.Database.Models.LiveChat", "Chat") + .WithMany("Topics") + .HasForeignKey("ChatId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chat"); + }); + + 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.LiveChat", b => + { + b.Navigation("Topics"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.LiveTopic", b => + { + b.Navigation("Mediae"); + }); + + 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/20240920124144_DownloadedItemsAdded.cs b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920124144_DownloadedItemsAdded.cs new file mode 100644 index 00000000..582a22ce --- /dev/null +++ b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920124144_DownloadedItemsAdded.cs @@ -0,0 +1,36 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace OneShelf.Videos.Database.Migrations.VideosDatabaseMigrations +{ + /// + public partial class DownloadedItemsAdded : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "DownloadedItems", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + LiveMediaId = table.Column(type: "bigint", nullable: false), + ThumbnailFileName = table.Column(type: "nvarchar(max)", nullable: true), + FileName = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_DownloadedItems", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "DownloadedItems"); + } + } +} diff --git a/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920134022_DownloadedItemsUnique.Designer.cs b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920134022_DownloadedItemsUnique.Designer.cs new file mode 100644 index 00000000..7d6a7ef9 --- /dev/null +++ b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920134022_DownloadedItemsUnique.Designer.cs @@ -0,0 +1,754 @@ +// +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("20240920134022_DownloadedItemsUnique")] + partial class DownloadedItemsUnique + { + /// + 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.DownloadedItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("LiveMediaId") + .HasColumnType("bigint"); + + b.Property("ThumbnailFileName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("FileName") + .IsUnique(); + + b.HasIndex("LiveMediaId") + .IsUnique(); + + b.ToTable("DownloadedItems"); + }); + + 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.LiveChat", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("LiveChats"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.LiveMedia", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("TopicChatId") + .HasColumnType("bigint"); + + b.Property("DocumentAttributeTypes") + .HasColumnType("nvarchar(max)"); + + b.Property("DocumentAttributes") + .HasColumnType("nvarchar(max)"); + + b.Property("Duration") + .HasColumnType("float"); + + b.Property("FileName") + .HasColumnType("nvarchar(max)"); + + b.Property("Flags") + .HasColumnType("nvarchar(max)"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("IsForwarded") + .HasColumnType("bit"); + + b.Property("MediaDate") + .HasColumnType("datetime2"); + + b.Property("MediaFlags") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("MediaId") + .HasColumnType("bigint"); + + b.Property("MediaType") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("MessageDate") + .HasColumnType("datetime2"); + + b.Property("MimeType") + .HasColumnType("nvarchar(max)"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.Property("TopicId") + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("VideoFlags") + .HasColumnType("nvarchar(max)"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id", "TopicChatId"); + + b.HasIndex("TopicId", "TopicChatId"); + + b.ToTable("LiveMediae"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.LiveTopic", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("ChatId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id", "ChatId"); + + b.HasIndex("ChatId"); + + b.ToTable("LiveTopics"); + }); + + 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.LiveMedia", b => + { + b.HasOne("OneShelf.Videos.Database.Models.LiveTopic", "Topic") + .WithMany("Mediae") + .HasForeignKey("TopicId", "TopicChatId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Topic"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.LiveTopic", b => + { + b.HasOne("OneShelf.Videos.Database.Models.LiveChat", "Chat") + .WithMany("Topics") + .HasForeignKey("ChatId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chat"); + }); + + 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.LiveChat", b => + { + b.Navigation("Topics"); + }); + + modelBuilder.Entity("OneShelf.Videos.Database.Models.LiveTopic", b => + { + b.Navigation("Mediae"); + }); + + 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/20240920134022_DownloadedItemsUnique.cs b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920134022_DownloadedItemsUnique.cs new file mode 100644 index 00000000..0f806035 --- /dev/null +++ b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/20240920134022_DownloadedItemsUnique.cs @@ -0,0 +1,54 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace OneShelf.Videos.Database.Migrations.VideosDatabaseMigrations +{ + /// + public partial class DownloadedItemsUnique : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "FileName", + table: "DownloadedItems", + type: "nvarchar(450)", + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(max)"); + + migrationBuilder.CreateIndex( + name: "IX_DownloadedItems_FileName", + table: "DownloadedItems", + column: "FileName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_DownloadedItems_LiveMediaId", + table: "DownloadedItems", + column: "LiveMediaId", + unique: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_DownloadedItems_FileName", + table: "DownloadedItems"); + + migrationBuilder.DropIndex( + name: "IX_DownloadedItems_LiveMediaId", + table: "DownloadedItems"); + + migrationBuilder.AlterColumn( + name: "FileName", + table: "DownloadedItems", + type: "nvarchar(max)", + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(450)"); + } + } +} diff --git a/OneShelf.Videos/OneShelf.Videos.Database/Migrations/VideosDatabaseModelSnapshot.cs b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/VideosDatabaseModelSnapshot.cs index 256e465b..ace02a62 100644 --- a/OneShelf.Videos/OneShelf.Videos.Database/Migrations/VideosDatabaseModelSnapshot.cs +++ b/OneShelf.Videos/OneShelf.Videos.Database/Migrations/VideosDatabaseModelSnapshot.cs @@ -101,6 +101,35 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("ChatFolders"); }); + modelBuilder.Entity("OneShelf.Videos.Database.Models.DownloadedItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("LiveMediaId") + .HasColumnType("bigint"); + + b.Property("ThumbnailFileName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("FileName") + .IsUnique(); + + b.HasIndex("LiveMediaId") + .IsUnique(); + + b.ToTable("DownloadedItems"); + }); + modelBuilder.Entity("OneShelf.Videos.Database.Models.InventoryItem", b => { b.Property("DatabaseInventoryItemId") diff --git a/OneShelf.Videos/OneShelf.Videos.Database/Models/DownloadedItem.cs b/OneShelf.Videos/OneShelf.Videos.Database/Models/DownloadedItem.cs new file mode 100644 index 00000000..85efba37 --- /dev/null +++ b/OneShelf.Videos/OneShelf.Videos.Database/Models/DownloadedItem.cs @@ -0,0 +1,13 @@ +using Microsoft.EntityFrameworkCore; + +namespace OneShelf.Videos.Database.Models; + +[Index(nameof(LiveMediaId), IsUnique = true)] +[Index(nameof(FileName), IsUnique = true)] +public class DownloadedItem +{ + public int Id { get; set; } + public required long LiveMediaId { get; set; } + public string? ThumbnailFileName { get; set; } + public required string FileName { get; set; } +} \ No newline at end of file diff --git a/OneShelf.Videos/OneShelf.Videos.Database/VideosDatabase.cs b/OneShelf.Videos/OneShelf.Videos.Database/VideosDatabase.cs index 22265890..9f00a428 100644 --- a/OneShelf.Videos/OneShelf.Videos.Database/VideosDatabase.cs +++ b/OneShelf.Videos/OneShelf.Videos.Database/VideosDatabase.cs @@ -31,6 +31,7 @@ public VideosDatabase(DbContextOptions options) public required DbSet LiveChats { get; set; } public required DbSet LiveTopics { get; set; } public required DbSet LiveMediae { get; set; } + public required DbSet DownloadedItems { get; set; } public async Task CreateMissingTopics() {