private static async Task SyncPlaylists(IChannel channel, List <string> dbids) { List <string> plIdsNet = await YouTubeSite.GetChannelPlaylistsIdsNetAsync(channel.ID).ConfigureAwait(true); List <string> plIdsDb = await db.GetChannelsPlaylistsIdsListDbAsync(channel.ID).ConfigureAwait(false); foreach (string playlistId in plIdsDb) { if (plIdsNet.Contains(playlistId)) { // обновим плейлисты, которые есть уже в базе List <string> plitemsIdsNet = await YouTubeSite.GetPlaylistItemsIdsListNetAsync(playlistId, 0).ConfigureAwait(true); List <string> plitemsIdsDb = await db.GetPlaylistItemsIdsListDbAsync(playlistId).ConfigureAwait(false); List <string> ids = plitemsIdsNet.Where(netid => !plitemsIdsDb.Contains(netid)).ToList(); if (!ids.Any()) { continue; } var lstInDb = new List <string>(); var lstNoInDb = new List <string>(); foreach (string id in ids) { if (dbids.Contains(id)) { lstInDb.Add(id); } else { lstNoInDb.Add(id); } } foreach (string id in lstInDb) { await db.UpdatePlaylistAsync(playlistId, id, channel.ID).ConfigureAwait(false); } IEnumerable <List <string> > chanks = lstNoInDb.SplitList(); foreach (List <string> list in chanks) { List <VideoItemPOCO> trlist = await YouTubeSite.GetVideosListByIdsLiteAsync(list).ConfigureAwait(true); List <string> trueIds = (from poco in trlist where poco.ParentID == channel.ID select poco.ID).ToList(); if (!trueIds.Any()) { continue; } // странный вариант, через аплоад видео не пришло, а через плейлист - есть, но оставим await InsertNewItems(trueIds, channel, playlistId).ConfigureAwait(true); } } else { // просто удалим уже не существующий в инете плейлист из базы await db.DeletePlaylistAsync(playlistId).ConfigureAwait(false); } } // новые плейлисты foreach (string playlistId in plIdsNet.Where(playlistId => !plIdsDb.Contains(playlistId))) { PlaylistPOCO plpoco = await YouTubeSite.GetPlaylistNetAsync(playlistId).ConfigureAwait(true); List <string> plpocoitems = await YouTubeSite.GetPlaylistItemsIdsListNetAsync(playlistId, 0).ConfigureAwait(true); plpoco.PlaylistItems.AddRange(plpocoitems); IPlaylist pl = PlaylistFactory.CreatePlaylist(plpoco, channel.Site); pl.State = SyncState.Added; channel.ChannelPlaylists.Add(pl); channel.PlaylistCount += 1; await db.InsertPlaylistAsync(pl).ConfigureAwait(false); dbids = await db.GetChannelItemsIdListDbAsync(channel.ID, 0, 0).ConfigureAwait(false); List <string> ids = plpocoitems.Where(netid => !dbids.Contains(netid)).ToList(); IEnumerable <List <string> > chanks = ids.SplitList(); foreach (List <string> trueIds in chanks) { await InsertNewItems(trueIds, channel, playlistId).ConfigureAwait(true); } foreach (string plpocoitem in plpocoitems) { await db.UpdatePlaylistAsync(pl.ID, plpocoitem, channel.ID).ConfigureAwait(false); } } }
public static async Task SyncChannelAsync(IChannel channel, bool isFastSync, bool isSyncPls = false, Action <IVideoItem, object> stateAction = null) { channel.ChannelState = ChannelState.InWork; if (channel is YouChannel) { string pluploadsid = YouChannel.MakePlaylistUploadId(channel.ID); // убираем признак предыдущей синхронизации List <IVideoItem> preds = channel.ChannelItems.Where(x => x.SyncState == SyncState.Added).ToList(); foreach (IVideoItem item in preds) { item.SyncState = SyncState.Notset; stateAction?.Invoke(item, SyncState.Notset); } if (channel.CountNew > 0) { channel.CountNew = 0; await db.UpdateItemSyncState(SyncState.Notset, SyncState.Added, channel.ID).ConfigureAwait(false); await db.UpdateChannelNewCountAsync(channel.ID, 0).ConfigureAwait(false); } // получаем списки id в базе и в нете List <string> netids; List <string> dbids; if (isFastSync) { // быстрая проверка if (channel.UseFast) { dbids = await db.GetChannelItemsIdListDbAsync(channel.ID, 0, 0, SyncState.Deleted).ConfigureAwait(false); int netcount = await YouTubeSite.GetChannelItemsCountNetAsync(channel.ID).ConfigureAwait(true); int resint = Math.Abs(netcount - dbids.Count) + 3; // буфер, можно регулировать netids = await YouTubeSite.GetPlaylistItemsIdsListNetAsync(pluploadsid, resint).ConfigureAwait(true); } else { // некоторые каналы хотим проверять жестко (добавляют, удаляют часто) dbids = await db.GetChannelItemsIdListDbAsync(channel.ID, 0, 0).ConfigureAwait(false); netids = await YouTubeSite.GetPlaylistItemsIdsListNetAsync(pluploadsid, 0).ConfigureAwait(true); await SetDeletedInDb(channel, dbids, netids); } } else { // полная проверка dbids = await db.GetChannelItemsIdListDbAsync(channel.ID, 0, 0).ConfigureAwait(false); netids = await YouTubeSite.GetPlaylistItemsIdsListNetAsync(pluploadsid, 0).ConfigureAwait(true); // проставляем в базе признак того, что видео больше нет на канале, а так же если видео было удалено, а теперь вернулось await SetDeletedInDb(channel, dbids, netids); } // cобираем новые List <string> trueids = netids.Where(netid => !dbids.Contains(netid)).ToList(); IEnumerable <List <string> > tchanks = trueids.SplitList(); foreach (List <string> list in tchanks) { List <VideoItemPOCO> trlist = await YouTubeSite.GetVideosListByIdsLiteAsync(list).ConfigureAwait(true); IEnumerable <string> trueIds = from poco in trlist where poco.ParentID == channel.ID select poco.ID; await InsertNewItems(trueIds, channel, null, dbids, stateAction).ConfigureAwait(true); } // обновим инфу о количестве новых после синхронизации if (channel.CountNew > 0) { await db.UpdateChannelNewCountAsync(channel.ID, channel.CountNew).ConfigureAwait(false); } // синхронизовать также плейлисты (двойной клик с UI по каналу) if (isSyncPls) { await SyncPlaylists(channel, dbids).ConfigureAwait(true); } int wnot = channel.ChannelItems.Count(x => x.WatchState != WatchState.Notset); int snot = channel.ChannelItems.Count(x => x.SyncState != SyncState.Notset); channel.IsHasNewFromSync = channel.ChannelItems.Any() && channel.ChannelItems.Count == wnot + snot + preds.Count; } channel.ChannelState = ChannelState.Notset; }