Ejemplo n.º 1
0
        /// <summary>
        /// Gets the user data.
        /// </summary>
        /// <param name="user">The user.</param>
        /// <param name="createIfNull">if set to <c>true</c> [create if null].</param>
        /// <returns>UserItemData.</returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        public UserItemData GetUserData(User user, bool createIfNull)
        {
            if (user == null)
            {
                throw new ArgumentNullException();
            }

            if (UserData == null)
            {
                if (!createIfNull)
                {
                    return(null);
                }

                AddOrUpdateUserData(user, new UserItemData {
                    UserId = user.Id
                });
            }

            var data = UserData.FirstOrDefault(u => u.UserId == user.Id);

            if (data == null && createIfNull)
            {
                data = new UserItemData {
                    UserId = user.Id
                };
                AddOrUpdateUserData(user, data);
            }

            return(data);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Adds the or update user data.
        /// </summary>
        /// <param name="user">The user.</param>
        /// <param name="data">The data.</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        public void AddOrUpdateUserData(User user, UserItemData data)
        {
            if (user == null)
            {
                throw new ArgumentNullException();
            }

            if (data == null)
            {
                throw new ArgumentNullException();
            }

            data.UserId = user.Id;

            if (UserData == null)
            {
                UserData = new[] { data };
            }
            else
            {
                var list = UserData.Where(u => u.UserId != user.Id).ToList();
                list.Add(data);
                UserData = list;
            }
        }
Ejemplo n.º 3
0
        private static bool Filter(BaseItem item, User user, UserItemsQuery query, IUserDataManager userDataManager)
        {
            if (query.MediaTypes.Length > 0 && !query.MediaTypes.Contains(item.MediaType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
            {
                return(false);
            }

            if (query.IsFolder.HasValue && query.IsFolder.Value != item.IsFolder)
            {
                return(false);
            }

            if (query.Filter != null && !query.Filter(item, user))
            {
                return(false);
            }

            UserItemData userData = null;

            if (query.IsFavorite.HasValue)
            {
                userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey());

                if (userData.IsFavorite != query.IsFavorite.Value)
                {
                    return(false);
                }
            }

            if (query.IsResumable.HasValue)
            {
                userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey());
                var isResumable = userData.PlaybackPositionTicks > 0;

                if (isResumable != query.IsResumable.Value)
                {
                    return(false);
                }
            }

            if (query.IsPlayed.HasValue)
            {
                if (item.IsPlayed(user) != query.IsPlayed.Value)
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 4
0
        public async Task SaveUserData(Guid userId, IHasUserData item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken)
        {
            if (userData == null)
            {
                throw new ArgumentNullException("userData");
            }
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            if (userId == Guid.Empty)
            {
                throw new ArgumentNullException("userId");
            }

            cancellationToken.ThrowIfCancellationRequested();

            var keys = item.GetUserDataKeys();

            foreach (var key in keys)
            {
                try
                {
                    await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);

                    var newValue = userData;

                    lock (_userData)
                    {
                        _userData[GetCacheKey(userId, key)] = newValue;
                    }
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error saving user data", ex);

                    throw;
                }
            }

            EventHelper.FireEventIfNotNull(UserDataSaved, this, new UserDataSaveEventArgs
            {
                Keys = keys,
                UserData = userData,
                SaveReason = reason,
                UserId = userId,
                Item = item

            }, _logger);
        }
Ejemplo n.º 5
0
        public override async Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user)
        {
            if (!SupportsUserDataFromChildren)
            {
                return;
            }

            var unplayedQueryResult = await GetItems(new InternalItemsQuery(user)
            {
                Recursive              = true,
                IsFolder               = false,
                IsVirtualItem          = false,
                EnableTotalRecordCount = true,
                Limit    = 0,
                IsPlayed = false
            }).ConfigureAwait(false);

            var allItemsQueryResult = await GetItems(new InternalItemsQuery(user)
            {
                Recursive              = true,
                IsFolder               = false,
                IsVirtualItem          = false,
                EnableTotalRecordCount = true,
                Limit = 0
            }).ConfigureAwait(false);

            if (itemDto != null)
            {
                itemDto.RecursiveItemCount = allItemsQueryResult.TotalRecordCount;
            }

            var    recursiveItemCount = allItemsQueryResult.TotalRecordCount;
            double unplayedCount      = unplayedQueryResult.TotalRecordCount;

            if (recursiveItemCount > 0)
            {
                var unplayedPercentage = (unplayedCount / recursiveItemCount) * 100;
                dto.PlayedPercentage  = 100 - unplayedPercentage;
                dto.Played            = dto.PlayedPercentage.Value >= 100;
                dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount;
            }

            if (itemDto != null)
            {
                if (this is Season || this is MusicAlbum)
                {
                    itemDto.ChildCount = recursiveItemCount;
                }
            }
        }
Ejemplo n.º 6
0
        public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user, List <ItemFields> fields)
        {
            if (!SupportsUserDataFromChildren)
            {
                return;
            }

            if (itemDto != null)
            {
                if (fields.Contains(ItemFields.RecursiveItemCount))
                {
                    itemDto.RecursiveItemCount = GetRecursiveChildCount(user);
                }
            }

            if (SupportsPlayedStatus)
            {
                var unplayedQueryResult = GetItems(new InternalItemsQuery(user)
                {
                    Recursive              = true,
                    IsFolder               = false,
                    IsVirtualItem          = false,
                    EnableTotalRecordCount = true,
                    Limit      = 0,
                    IsPlayed   = false,
                    DtoOptions = new DtoOptions(false)
                    {
                        EnableImages = false
                    }
                });

                double unplayedCount = unplayedQueryResult.TotalRecordCount;

                dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount;

                if (itemDto != null && itemDto.RecursiveItemCount.HasValue)
                {
                    if (itemDto.RecursiveItemCount.Value > 0)
                    {
                        var unplayedPercentage = (unplayedCount / itemDto.RecursiveItemCount.Value) * 100;
                        dto.PlayedPercentage = 100 - unplayedPercentage;
                        dto.Played           = dto.PlayedPercentage.Value >= 100;
                    }
                }
                else
                {
                    dto.Played = (dto.UnplayedItemCount ?? 0) == 0;
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Saves the user data.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="key">The key.</param>
        /// <param name="userData">The user data.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException">userData
        /// or
        /// cancellationToken
        /// or
        /// userId
        /// or
        /// userDataId</exception>
        public Task SaveUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
        {
            if (userData == null)
            {
                throw new ArgumentNullException("userData");
            }
            if (userId == Guid.Empty)
            {
                throw new ArgumentNullException("userId");
            }
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException("key");
            }

            return PersistUserData(userId, key, userData, cancellationToken);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Saves the user data.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="item">The item.</param>
        /// <param name="userData">The user data.</param>
        /// <param name="reason">The reason.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException">userData
        /// or
        /// cancellationToken
        /// or
        /// userId
        /// or
        /// key</exception>
        public async Task SaveUserData(Guid userId, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken)
        {
            if (userData == null)
            {
                throw new ArgumentNullException("userData");
            }
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            if (userId == Guid.Empty)
            {
                throw new ArgumentNullException("userId");
            }

            cancellationToken.ThrowIfCancellationRequested();

            var key = item.GetUserDataKey();

            try
            {
                await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);

                var newValue = userData;

                // Once it succeeds, put it into the dictionary to make it available to everyone else
                _userData.AddOrUpdate(GetCacheKey(userId, key), newValue, delegate { return newValue; });
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error saving user data", ex);

                throw;
            }

            EventHelper.FireEventIfNotNull(UserDataSaved, this, new UserDataSaveEventArgs
            {
                Key = key,
                UserData = userData,
                SaveReason = reason,
                UserId = userId,
                Item = item

            }, _logger);
        }
Ejemplo n.º 9
0
        public async Task SaveUserData(Guid userId, IHasUserData item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken)
        {
            if (userData == null)
            {
                throw new ArgumentNullException("userData");
            }
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            if (userId == Guid.Empty)
            {
                throw new ArgumentNullException("userId");
            }

            cancellationToken.ThrowIfCancellationRequested();

            var keys = item.GetUserDataKeys();

            foreach (var key in keys)
            {
                await Repository.SaveUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);
            }

            var cacheKey = GetCacheKey(userId, item.Id);
            _userData.AddOrUpdate(cacheKey, userData, (k, v) => userData);

            EventHelper.FireEventIfNotNull(UserDataSaved, this, new UserDataSaveEventArgs
            {
                Keys = keys,
                UserData = userData,
                SaveReason = reason,
                UserId = userId,
                Item = item

            }, _logger);
        }
        /// <summary>
        /// Persists the user data.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="key">The key.</param>
        /// <param name="userData">The user data.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task.</returns>
        public async Task PersistUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);

            IDbTransaction transaction = null;

            try
            {
                transaction = _connection.BeginTransaction();

                using (var cmd = _connection.CreateCommand())
                {
                    cmd.CommandText = "replace into userdata (key, userId, rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate) values (@key, @userId, @rating,@played,@playCount,@isFavorite,@playbackPositionTicks,@lastPlayedDate)";

                    cmd.Parameters.Add(cmd, "@key", DbType.String).Value = key;
                    cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId;
                    cmd.Parameters.Add(cmd, "@rating", DbType.Double).Value = userData.Rating;
                    cmd.Parameters.Add(cmd, "@played", DbType.Boolean).Value = userData.Played;
                    cmd.Parameters.Add(cmd, "@playCount", DbType.Int32).Value = userData.PlayCount;
                    cmd.Parameters.Add(cmd, "@isFavorite", DbType.Boolean).Value = userData.IsFavorite;
                    cmd.Parameters.Add(cmd, "@playbackPositionTicks", DbType.Int64).Value = userData.PlaybackPositionTicks;
                    cmd.Parameters.Add(cmd, "@lastPlayedDate", DbType.DateTime).Value = userData.LastPlayedDate;

                    cmd.Transaction = transaction;

                    cmd.ExecuteNonQuery();
                }

                transaction.Commit();
            }
            catch (OperationCanceledException)
            {
                if (transaction != null)
                {
                    transaction.Rollback();
                }

                throw;
            }
            catch (Exception e)
            {
                _logger.ErrorException("Failed to save user data:", e);

                if (transaction != null)
                {
                    transaction.Rollback();
                }

                throw;
            }
            finally
            {
                if (transaction != null)
                {
                    transaction.Dispose();
                }

                _writeLock.Release();
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Converts a UserItemData to a DTOUserItemData
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns>DtoUserItemData.</returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static UserItemDataDto GetUserItemDataDto(UserItemData data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            return new UserItemDataDto
            {
                IsFavorite = data.IsFavorite,
                Likes = data.Likes,
                PlaybackPositionTicks = data.PlaybackPositionTicks,
                PlayCount = data.PlayCount,
                Rating = data.Rating,
                Played = data.Played,
                LastPlayedDate = data.LastPlayedDate
            };
        }
Ejemplo n.º 12
0
        private void SetDefaultAudioStreamIndex(MediaSourceInfo source, UserItemData userData, User user, bool allowRememberingSelection)
        {
            if (userData.AudioStreamIndex.HasValue && user.Configuration.RememberAudioSelections && allowRememberingSelection)
            {
                var index = userData.AudioStreamIndex.Value;
                // Make sure the saved index is still valid
                if (source.MediaStreams.Any(i => i.Type == MediaStreamType.Audio && i.Index == index))
                {
                    source.DefaultAudioStreamIndex = index;
                    return;
                }
            }

            var preferredAudio = string.IsNullOrEmpty(user.Configuration.AudioLanguagePreference)
                ? new string[] { }
                : new[] { user.Configuration.AudioLanguagePreference };

            source.DefaultAudioStreamIndex = MediaStreamSelector.GetDefaultAudioStreamIndex(source.MediaStreams, preferredAudio, user.Configuration.PlayDefaultAudioTrack);
        }
Ejemplo n.º 13
0
        private void SetDefaultSubtitleStreamIndex(MediaSourceInfo source, UserItemData userData, User user, bool allowRememberingSelection)
        {
            if (userData.SubtitleStreamIndex.HasValue && user.Configuration.RememberSubtitleSelections && user.Configuration.SubtitleMode != SubtitlePlaybackMode.None && allowRememberingSelection)
            {
                var index = userData.SubtitleStreamIndex.Value;
                // Make sure the saved index is still valid
                if (index == -1 || source.MediaStreams.Any(i => i.Type == MediaStreamType.Subtitle && i.Index == index))
                {
                    source.DefaultSubtitleStreamIndex = index;
                    return;
                }
            }
            
            var preferredSubs = string.IsNullOrEmpty(user.Configuration.SubtitleLanguagePreference)
                ? new List<string>() : new List<string> { user.Configuration.SubtitleLanguagePreference };

            var defaultAudioIndex = source.DefaultAudioStreamIndex;
            var audioLangage = defaultAudioIndex == null
                ? null
                : source.MediaStreams.Where(i => i.Type == MediaStreamType.Audio && i.Index == defaultAudioIndex).Select(i => i.Language).FirstOrDefault();

            source.DefaultSubtitleStreamIndex = MediaStreamSelector.GetDefaultSubtitleStreamIndex(source.MediaStreams,
                preferredSubs,
                user.Configuration.SubtitleMode,
                audioLangage);

            MediaStreamSelector.SetSubtitleStreamScores(source.MediaStreams, preferredSubs,
                user.Configuration.SubtitleMode, audioLangage);
        }
Ejemplo n.º 14
0
        public override async Task FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, BaseItemDto itemDto, User user)
        {
            if (!SupportsUserDataFromChildren)
            {
                return;
            }

            var unplayedQueryResult = await GetItems(new InternalItemsQuery(user)
            {
                Recursive = true,
                IsFolder = false,
                IsVirtualItem = false,
                EnableTotalRecordCount = true,
                Limit = 0,
                IsPlayed = false

            }).ConfigureAwait(false);

            var allItemsQueryResult = await GetItems(new InternalItemsQuery(user)
            {
                Recursive = true,
                IsFolder = false,
                IsVirtualItem = false,
                EnableTotalRecordCount = true,
                Limit = 0

            }).ConfigureAwait(false);

            if (itemDto != null)
            {
                itemDto.RecursiveItemCount = allItemsQueryResult.TotalRecordCount;
            }

            var recursiveItemCount = allItemsQueryResult.TotalRecordCount;
            double unplayedCount = unplayedQueryResult.TotalRecordCount;

            if (recursiveItemCount > 0)
            {
                var unplayedPercentage = (unplayedCount / recursiveItemCount) * 100;
                dto.PlayedPercentage = 100 - unplayedPercentage;
                dto.Played = dto.PlayedPercentage.Value >= 100;
                dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount;
            }

            if (itemDto != null)
            {
                if (this is Season || this is MusicAlbum)
                {
                    itemDto.ChildCount = recursiveItemCount;
                }
            }
        }
Ejemplo n.º 15
0
 public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user)
 {
     // Nothing meaninful here and will only waste resources
 }
        /// <summary>
        /// Persists the user data.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="key">The key.</param>
        /// <param name="userData">The user data.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task.</returns>
        public async Task PersistUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var serialized = _jsonSerializer.SerializeToBytes(userData);

            cancellationToken.ThrowIfCancellationRequested();

            await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);

            SQLiteTransaction transaction = null;

            try
            {
                transaction = Connection.BeginTransaction();

                using (var cmd = Connection.CreateCommand())
                {
                    cmd.CommandText = "replace into userdata (key, userId, data) values (@1, @2, @3)";
                    cmd.AddParam("@1", key);
                    cmd.AddParam("@2", userId);
                    cmd.AddParam("@3", serialized);

                    cmd.Transaction = transaction;

                    await cmd.ExecuteNonQueryAsync(cancellationToken);
                }

                transaction.Commit();
            }
            catch (OperationCanceledException)
            {
                if (transaction != null)
                {
                    transaction.Rollback();
                }

                throw;
            }
            catch (Exception e)
            {
                Logger.ErrorException("Failed to save user data:", e);

                if (transaction != null)
                {
                    transaction.Rollback();
                }

                throw;
            }
            finally
            {
                if (transaction != null)
                {
                    transaction.Dispose();
                }

                _writeLock.Release();
            }
        }
        /// <summary>
        /// Saves the user data.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="key">The key.</param>
        /// <param name="userData">The user data.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>Task.</returns>
        /// <exception cref="System.ArgumentNullException">userData
        /// or
        /// cancellationToken
        /// or
        /// userId
        /// or
        /// userDataId</exception>
        public async Task SaveUserData(Guid userId, string key, UserItemData userData, CancellationToken cancellationToken)
        {
            if (userData == null)
            {
                throw new ArgumentNullException("userData");
            }
            if (cancellationToken == null)
            {
                throw new ArgumentNullException("cancellationToken");
            }
            if (userId == Guid.Empty)
            {
                throw new ArgumentNullException("userId");
            }
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException("key");
            }

            cancellationToken.ThrowIfCancellationRequested();

            try
            {
                await PersistUserData(userId, key, userData, cancellationToken).ConfigureAwait(false);

                var newValue = Task.FromResult(userData);

                // Once it succeeds, put it into the dictionary to make it available to everyone else
                _userData.AddOrUpdate(GetInternalKey(userId, key), newValue, delegate { return newValue; });
            }
            catch (Exception ex)
            {
                Logger.ErrorException("Error saving user data", ex);

                throw;
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Read a row from the specified reader into the provided userData object
        /// </summary>
        /// <param name="reader"></param>
        private UserItemData ReadRow(IDataReader reader)
        {
            var userData = new UserItemData();

            userData.Key = reader.GetString(0);
            userData.UserId = reader.GetGuid(1);

            if (!reader.IsDBNull(2))
            {
                userData.Rating = reader.GetDouble(2);
            }

            userData.Played = reader.GetBoolean(3);
            userData.PlayCount = reader.GetInt32(4);
            userData.IsFavorite = reader.GetBoolean(5);
            userData.PlaybackPositionTicks = reader.GetInt64(6);

            if (!reader.IsDBNull(7))
            {
                userData.LastPlayedDate = reader.GetDateTime(7).ToUniversalTime();
            }

            return userData;
        }
        /// <summary>
        /// Gets the user data.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="key">The key.</param>
        /// <returns>Task{UserItemData}.</returns>
        /// <exception cref="System.ArgumentNullException">
        /// userId
        /// or
        /// key
        /// </exception>
        public UserItemData GetUserData(Guid userId, string key)
        {
            if (userId == Guid.Empty)
            {
                throw new ArgumentNullException("userId");
            }
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException("key");
            }

            using (var cmd = _connection.CreateCommand())
            {
                cmd.CommandText = "select rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate from userdata where key = @key and userId=@userId";

                cmd.Parameters.Add(cmd, "@key", DbType.String).Value = key;
                cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId;

                var userData = new UserItemData
                {
                    UserId = userId,
                    Key = key
                };

                using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow))
                {
                    if (reader.Read())
                    {
                        if (!reader.IsDBNull(0))
                        {
                            userData.Rating = reader.GetDouble(0);
                        }

                        userData.Played = reader.GetBoolean(1);
                        userData.PlayCount = reader.GetInt32(2);
                        userData.IsFavorite = reader.GetBoolean(3);
                        userData.PlaybackPositionTicks = reader.GetInt64(4);

                        if (!reader.IsDBNull(5))
                        {
                            userData.LastPlayedDate = reader.GetDateTime(5);
                        }
                    }
                }

                return userData;
            }
        }
Ejemplo n.º 20
0
        public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user)
        {
            var recursiveItemCount = 0;
            var unplayed           = 0;

            double totalPercentPlayed = 0;

            IEnumerable <BaseItem> children;
            var folder = this;

            var season = folder as Season;

            if (season != null)
            {
                children = season.GetEpisodes(user).Where(i => i.LocationType != LocationType.Virtual);
            }
            else
            {
                children = folder.GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual);
            }

            // Loop through each recursive child
            foreach (var child in children)
            {
                recursiveItemCount++;

                var isUnplayed = true;

                var itemUserData = UserDataManager.GetUserData(user.Id, child.GetUserDataKey());

                // Incrememt totalPercentPlayed
                if (itemUserData != null)
                {
                    if (itemUserData.Played)
                    {
                        totalPercentPlayed += 100;

                        isUnplayed = false;
                    }
                    else if (itemUserData.PlaybackPositionTicks > 0 && child.RunTimeTicks.HasValue && child.RunTimeTicks.Value > 0)
                    {
                        double itemPercent = itemUserData.PlaybackPositionTicks;
                        itemPercent        /= child.RunTimeTicks.Value;
                        totalPercentPlayed += itemPercent;
                    }
                }

                if (isUnplayed)
                {
                    unplayed++;
                }
            }

            dto.UnplayedItemCount = unplayed;

            if (recursiveItemCount > 0)
            {
                dto.PlayedPercentage = totalPercentPlayed / recursiveItemCount;
                dto.Played           = dto.PlayedPercentage.Value >= 100;
            }
        }
Ejemplo n.º 21
0
        public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user)
        {
            if (!SupportsUserDataFromChildren)
            {
                return;
            }

            var recursiveItemCount = 0;
            var unplayed = 0;

            double totalPercentPlayed = 0;

            var itemsResult = GetItems(new InternalItemsQuery(user)
            {
                Recursive = true,
                IsFolder = false,
                ExcludeLocationTypes = new[] { LocationType.Virtual }

            }).Result;

            var children = itemsResult.Items;

            // Loop through each recursive child
            foreach (var child in children)
            {
                recursiveItemCount++;

                var isUnplayed = true;

                var itemUserData = UserDataManager.GetUserData(user, child);

                // Incrememt totalPercentPlayed
                if (itemUserData != null)
                {
                    if (itemUserData.Played)
                    {
                        totalPercentPlayed += 100;

                        isUnplayed = false;
                    }
                    else if (itemUserData.PlaybackPositionTicks > 0 && child.RunTimeTicks.HasValue && child.RunTimeTicks.Value > 0)
                    {
                        double itemPercent = itemUserData.PlaybackPositionTicks;
                        itemPercent /= child.RunTimeTicks.Value;
                        totalPercentPlayed += itemPercent;
                    }
                }

                if (isUnplayed)
                {
                    unplayed++;
                }
            }

            dto.UnplayedItemCount = unplayed;

            if (recursiveItemCount > 0)
            {
                dto.PlayedPercentage = totalPercentPlayed / recursiveItemCount;
                dto.Played = dto.PlayedPercentage.Value >= 100;
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Persists the user data.
        /// </summary>
        /// <param name="userData">The user data.</param>
        /// <param name="database">The database.</param>
        /// <param name="transaction">The transaction.</param>
        private static void PersistUserData(UserItemData userData, IDbConnection database, IDbTransaction transaction)
        {
            using (var cmd = database.CreateCommand())
            {
                cmd.CommandText = "replace into userdata (key, userId, rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate) values (@key, @userId, @rating,@played,@playCount,@isFavorite,@playbackPositionTicks,@lastPlayedDate)";

                cmd.Parameters.Add(cmd, "@key", DbType.String).Value = userData.Key;
                cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userData.UserId;
                cmd.Parameters.Add(cmd, "@rating", DbType.Double).Value = userData.Rating;
                cmd.Parameters.Add(cmd, "@played", DbType.Boolean).Value = userData.Played;
                cmd.Parameters.Add(cmd, "@playCount", DbType.Int32).Value = userData.PlayCount;
                cmd.Parameters.Add(cmd, "@isFavorite", DbType.Boolean).Value = userData.IsFavorite;
                cmd.Parameters.Add(cmd, "@playbackPositionTicks", DbType.Int64).Value = userData.PlaybackPositionTicks;
                cmd.Parameters.Add(cmd, "@lastPlayedDate", DbType.DateTime).Value = userData.LastPlayedDate;

                cmd.Transaction = transaction;

                cmd.ExecuteNonQuery();
            }
        }
Ejemplo n.º 23
0
        public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user)
        {
            var recursiveItemCount = 0;
            var unplayed = 0;

            double totalPercentPlayed = 0;

            IEnumerable<BaseItem> children;
            var folder = this;

            var season = folder as Season;

            if (season != null)
            {
                children = season.GetEpisodes(user).Where(i => i.LocationType != LocationType.Virtual);
            }
            else
            {
                children = folder.GetRecursiveChildren(user)
                    .Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual);
            }

            // Loop through each recursive child
            foreach (var child in children)
            {
                recursiveItemCount++;

                var isUnplayed = true;

                var itemUserData = UserDataManager.GetUserData(user.Id, child.GetUserDataKey());

                // Incrememt totalPercentPlayed
                if (itemUserData != null)
                {
                    if (itemUserData.Played)
                    {
                        totalPercentPlayed += 100;

                        isUnplayed = false;
                    }
                    else if (itemUserData.PlaybackPositionTicks > 0 && child.RunTimeTicks.HasValue && child.RunTimeTicks.Value > 0)
                    {
                        double itemPercent = itemUserData.PlaybackPositionTicks;
                        itemPercent /= child.RunTimeTicks.Value;
                        totalPercentPlayed += itemPercent;
                    }
                }

                if (isUnplayed)
                {
                    unplayed++;
                }
            }

            dto.UnplayedItemCount = unplayed;

            if (recursiveItemCount > 0)
            {
                dto.PlayedPercentage = totalPercentPlayed / recursiveItemCount;
                dto.Played = dto.PlayedPercentage.Value >= 100;
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Updates playstate position for an item but does not save
        /// </summary>
        /// <param name="item">The item</param>
        /// <param name="data">User data for the item</param>
        /// <param name="positionTicks">The current playback position</param>
        private void UpdatePlayState(BaseItem item, UserItemData data, long positionTicks)
        {
            var hasRuntime = item.RunTimeTicks.HasValue && item.RunTimeTicks > 0;

            // If a position has been reported, and if we know the duration
            if (positionTicks > 0 && hasRuntime)
            {
                var pctIn = Decimal.Divide(positionTicks, item.RunTimeTicks.Value) * 100;

                // Don't track in very beginning
                if (pctIn < _configurationManager.Configuration.MinResumePct)
                {
                    positionTicks = 0;
                }

                // If we're at the end, assume completed
                else if (pctIn > _configurationManager.Configuration.MaxResumePct || positionTicks >= item.RunTimeTicks.Value)
                {
                    positionTicks = 0;
                    data.Played = true;
                }

                else
                {
                    // Enforce MinResumeDuration
                    var durationSeconds = TimeSpan.FromTicks(item.RunTimeTicks.Value).TotalSeconds;

                    if (durationSeconds < _configurationManager.Configuration.MinResumeDurationSeconds)
                    {
                        positionTicks = 0;
                        data.Played = true;
                    }
                }
            }
            else if (!hasRuntime)
            {
                // If we don't know the runtime we'll just have to assume it was fully played
                data.Played = true;
                positionTicks = 0;
            }

            if (item is Audio)
            {
                positionTicks = 0;
            }

            data.PlaybackPositionTicks = positionTicks;
        }
Ejemplo n.º 25
0
 public override void FillUserDataDtoValues(UserItemDataDto dto, UserItemData userData, User user)
 {
     // Nothing meaninful here and will only waste resources
 }
Ejemplo n.º 26
0
        /// <summary>
        /// Gets the user data.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="key">The key.</param>
        /// <returns>Task{UserItemData}.</returns>
        public UserItemData GetUserData(Guid userId, string key)
        {
            if (userId == Guid.Empty)
            {
                throw new ArgumentNullException("userId");
            }
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException("key");
            }

            lock (_userData)
            {
                var cacheKey = GetCacheKey(userId, key);
                UserItemData value;
                if (_userData.TryGetValue(cacheKey, out value))
                {
                    return value;
                }

                value = Repository.GetUserData(userId, key);

                if (value == null)
                {
                    value = new UserItemData
                    {
                        UserId = userId,
                        Key = key
                    };
                }

                _userData[cacheKey] = value;
                return value;
            }
        }
Ejemplo n.º 27
0
        public static bool Filter(BaseItem item, User user, InternalItemsQuery query, IUserDataManager userDataManager, ILibraryManager libraryManager)
        {
            if (query.MediaTypes.Length > 0 && !query.MediaTypes.Contains(item.MediaType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
            {
                return(false);
            }

            if (query.IncludeItemTypes.Length > 0 && !query.IncludeItemTypes.Contains(item.GetClientTypeName(), StringComparer.OrdinalIgnoreCase))
            {
                return(false);
            }

            if (query.ExcludeItemTypes.Length > 0 && query.ExcludeItemTypes.Contains(item.GetClientTypeName(), StringComparer.OrdinalIgnoreCase))
            {
                return(false);
            }

            if (query.IsVirtualItem.HasValue && item.IsVirtualItem != query.IsVirtualItem.Value)
            {
                return(false);
            }

            if (query.IsFolder.HasValue && query.IsFolder.Value != item.IsFolder)
            {
                return(false);
            }

            UserItemData userData = null;

            if (query.IsLiked.HasValue)
            {
                userData = userData ?? userDataManager.GetUserData(user, item);

                if (!userData.Likes.HasValue || userData.Likes != query.IsLiked.Value)
                {
                    return(false);
                }
            }

            if (query.IsFavoriteOrLiked.HasValue)
            {
                userData = userData ?? userDataManager.GetUserData(user, item);
                var isFavoriteOrLiked = userData.IsFavorite || (userData.Likes ?? false);

                if (isFavoriteOrLiked != query.IsFavoriteOrLiked.Value)
                {
                    return(false);
                }
            }

            if (query.IsFavorite.HasValue)
            {
                userData = userData ?? userDataManager.GetUserData(user, item);

                if (userData.IsFavorite != query.IsFavorite.Value)
                {
                    return(false);
                }
            }

            if (query.IsResumable.HasValue)
            {
                userData = userData ?? userDataManager.GetUserData(user, item);
                var isResumable = userData.PlaybackPositionTicks > 0;

                if (isResumable != query.IsResumable.Value)
                {
                    return(false);
                }
            }

            if (query.IsPlayed.HasValue)
            {
                if (item.IsPlayed(user) != query.IsPlayed.Value)
                {
                    return(false);
                }
            }

            // Filter by Video3DFormat
            if (query.Is3D.HasValue)
            {
                var val   = query.Is3D.Value;
                var video = item as Video;

                if (video == null || val != video.Video3DFormat.HasValue)
                {
                    return(false);
                }
            }

            /*
             * f**k - fix this
             * if (query.IsHD.HasValue)
             * {
             *  if (item.IsHD != query.IsHD.Value)
             *  {
             *      return false;
             *  }
             * }
             */

            if (query.IsLocked.HasValue)
            {
                var val = query.IsLocked.Value;
                if (item.IsLocked != val)
                {
                    return(false);
                }
            }

            if (query.HasOverview.HasValue)
            {
                var filterValue = query.HasOverview.Value;

                var hasValue = !string.IsNullOrEmpty(item.Overview);

                if (hasValue != filterValue)
                {
                    return(false);
                }
            }

            if (query.HasImdbId.HasValue)
            {
                var filterValue = query.HasImdbId.Value;

                var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Imdb));

                if (hasValue != filterValue)
                {
                    return(false);
                }
            }

            if (query.HasTmdbId.HasValue)
            {
                var filterValue = query.HasTmdbId.Value;

                var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Tmdb));

                if (hasValue != filterValue)
                {
                    return(false);
                }
            }

            if (query.HasTvdbId.HasValue)
            {
                var filterValue = query.HasTvdbId.Value;

                var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Tvdb));

                if (hasValue != filterValue)
                {
                    return(false);
                }
            }

            if (query.HasOfficialRating.HasValue)
            {
                var filterValue = query.HasOfficialRating.Value;

                var hasValue = !string.IsNullOrEmpty(item.OfficialRating);

                if (hasValue != filterValue)
                {
                    return(false);
                }
            }

            if (query.IsPlaceHolder.HasValue)
            {
                var filterValue = query.IsPlaceHolder.Value;

                var isPlaceHolder = false;

                var hasPlaceHolder = item as ISupportsPlaceHolders;

                if (hasPlaceHolder != null)
                {
                    isPlaceHolder = hasPlaceHolder.IsPlaceHolder;
                }

                if (isPlaceHolder != filterValue)
                {
                    return(false);
                }
            }

            if (query.HasSpecialFeature.HasValue)
            {
                var filterValue = query.HasSpecialFeature.Value;

                var movie = item as IHasSpecialFeatures;

                if (movie != null)
                {
                    var ok = filterValue
                        ? movie.SpecialFeatureIds.Length > 0
                        : movie.SpecialFeatureIds.Length == 0;

                    if (!ok)
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }

            if (query.HasSubtitles.HasValue)
            {
                var val = query.HasSubtitles.Value;

                var video = item as Video;

                if (video == null || val != video.HasSubtitles)
                {
                    return(false);
                }
            }

            if (query.HasParentalRating.HasValue)
            {
                var val = query.HasParentalRating.Value;

                var rating = item.CustomRating;

                if (string.IsNullOrEmpty(rating))
                {
                    rating = item.OfficialRating;
                }

                if (val)
                {
                    if (string.IsNullOrEmpty(rating))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!string.IsNullOrEmpty(rating))
                    {
                        return(false);
                    }
                }
            }

            if (query.HasTrailer.HasValue)
            {
                var val          = query.HasTrailer.Value;
                var trailerCount = 0;

                var hasTrailers = item as IHasTrailers;
                if (hasTrailers != null)
                {
                    trailerCount = hasTrailers.GetTrailerIds().Count;
                }

                var ok = val ? trailerCount > 0 : trailerCount == 0;

                if (!ok)
                {
                    return(false);
                }
            }

            if (query.HasThemeSong.HasValue)
            {
                var filterValue = query.HasThemeSong.Value;

                var themeCount = item.ThemeSongIds.Length;
                var ok         = filterValue ? themeCount > 0 : themeCount == 0;

                if (!ok)
                {
                    return(false);
                }
            }

            if (query.HasThemeVideo.HasValue)
            {
                var filterValue = query.HasThemeVideo.Value;

                var themeCount = item.ThemeVideoIds.Length;
                var ok         = filterValue ? themeCount > 0 : themeCount == 0;

                if (!ok)
                {
                    return(false);
                }
            }

            // Apply genre filter
            if (query.Genres.Length > 0 && !query.Genres.Any(v => item.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)))
            {
                return(false);
            }

            // Filter by VideoType
            if (query.VideoTypes.Length > 0)
            {
                var video = item as Video;
                if (video == null || !query.VideoTypes.Contains(video.VideoType))
                {
                    return(false);
                }
            }

            if (query.ImageTypes.Length > 0 && !query.ImageTypes.Any(item.HasImage))
            {
                return(false);
            }

            // Apply studio filter
            if (query.StudioIds.Length > 0 && !query.StudioIds.Any(id =>
            {
                var studioItem = libraryManager.GetItemById(id);
                return(studioItem != null && item.Studios.Contains(studioItem.Name, StringComparer.OrdinalIgnoreCase));
            }))
            {
                return(false);
            }

            // Apply genre filter
            if (query.GenreIds.Length > 0 && !query.GenreIds.Any(id =>
            {
                var genreItem = libraryManager.GetItemById(id);
                return(genreItem != null && item.Genres.Contains(genreItem.Name, StringComparer.OrdinalIgnoreCase));
            }))
            {
                return(false);
            }

            // Apply year filter
            if (query.Years.Length > 0)
            {
                if (!(item.ProductionYear.HasValue && query.Years.Contains(item.ProductionYear.Value)))
                {
                    return(false);
                }
            }

            // Apply official rating filter
            if (query.OfficialRatings.Length > 0 && !query.OfficialRatings.Contains(item.OfficialRating ?? string.Empty))
            {
                return(false);
            }

            if (query.ItemIds.Length > 0)
            {
                if (!query.ItemIds.Contains(item.Id))
                {
                    return(false);
                }
            }

            // Apply tag filter
            var tags = query.Tags;

            if (tags.Length > 0)
            {
                if (!tags.Any(v => item.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))
                {
                    return(false);
                }
            }

            if (query.MinPlayers.HasValue)
            {
                var filterValue = query.MinPlayers.Value;

                var game = item as Game;

                if (game != null)
                {
                    var players = game.PlayersSupported ?? 1;

                    var ok = players >= filterValue;

                    if (!ok)
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }

            if (query.MaxPlayers.HasValue)
            {
                var filterValue = query.MaxPlayers.Value;

                var game = item as Game;

                if (game != null)
                {
                    var players = game.PlayersSupported ?? 1;

                    var ok = players <= filterValue;

                    if (!ok)
                    {
                        return(false);
                    }
                }
                else
                {
                    return(false);
                }
            }

            if (query.MinCommunityRating.HasValue)
            {
                var val = query.MinCommunityRating.Value;

                if (!(item.CommunityRating.HasValue && item.CommunityRating >= val))
                {
                    return(false);
                }
            }

            if (query.MinCriticRating.HasValue)
            {
                var val = query.MinCriticRating.Value;

                if (!(item.CriticRating.HasValue && item.CriticRating >= val))
                {
                    return(false);
                }
            }

            if (query.MinIndexNumber.HasValue)
            {
                var val = query.MinIndexNumber.Value;

                if (!(item.IndexNumber.HasValue && item.IndexNumber.Value >= val))
                {
                    return(false);
                }
            }

            if (query.MinPremiereDate.HasValue)
            {
                var val = query.MinPremiereDate.Value;

                if (!(item.PremiereDate.HasValue && item.PremiereDate.Value >= val))
                {
                    return(false);
                }
            }

            if (query.MaxPremiereDate.HasValue)
            {
                var val = query.MaxPremiereDate.Value;

                if (!(item.PremiereDate.HasValue && item.PremiereDate.Value <= val))
                {
                    return(false);
                }
            }

            if (query.ParentIndexNumber.HasValue)
            {
                var filterValue = query.ParentIndexNumber.Value;

                if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value != filterValue)
                {
                    return(false);
                }
            }

            if (query.SeriesStatuses.Length > 0)
            {
                var ok = new[] { item }.OfType <Series>().Any(p => p.Status.HasValue && query.SeriesStatuses.Contains(p.Status.Value));
                if (!ok)
                {
                    return(false);
                }
            }

            if (query.AiredDuringSeason.HasValue)
            {
                var episode = item as Episode;

                if (episode == null)
                {
                    return(false);
                }

                if (!Series.FilterEpisodesBySeason(new[] { episode }, query.AiredDuringSeason.Value, true).Any())
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 28
0
        public UserItemData GetUserData(Guid userId, List<string> keys)
        {
            if (userId == Guid.Empty)
            {
                throw new ArgumentNullException("userId");
            }
            if (keys == null)
            {
                throw new ArgumentNullException("keys");
            }

            lock (_userData)
            {
                foreach (var key in keys)
                {
                    var cacheKey = GetCacheKey(userId, key);
                    UserItemData value;
                    if (_userData.TryGetValue(cacheKey, out value))
                    {
                        return value;
                    }

                    value = Repository.GetUserData(userId, key);

                    if (value != null)
                    {
                        _userData[cacheKey] = value;
                        return value;
                    }
                }

                if (keys.Count > 0)
                {
                    var key = keys[0];
                    var cacheKey = GetCacheKey(userId, key);
                    var userdata = new UserItemData
                    {
                        UserId = userId,
                        Key = key
                    };
                    _userData[cacheKey] = userdata;
                    return userdata;
                }

                return null;
            }
        }