< Summary - Jellyfin

Information
Class: Jellyfin.LiveTv.Timers.ItemDataProvider<T>
Assembly: Jellyfin.LiveTv
File(s): /srv/git/jellyfin/src/Jellyfin.LiveTv/Timers/ItemDataProvider.cs
Line coverage
22%
Covered lines: 14
Uncovered lines: 49
Coverable lines: 63
Total lines: 155
Line coverage: 22.2%
Branch coverage
14%
Covered branches: 2
Total branches: 14
Branch coverage: 14.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
EnsureLoaded()33.33%20.2626.66%
SaveList()0%620%
GetAll()100%11100%
Update(...)0%620%
Add(...)0%620%
AddOrUpdate(...)0%620%
Delete(...)100%210%

File(s)

/srv/git/jellyfin/src/Jellyfin.LiveTv/Timers/ItemDataProvider.cs

#LineLine coverage
 1#pragma warning disable CS1591
 2
 3using System;
 4using System.Collections.Generic;
 5using System.Diagnostics.CodeAnalysis;
 6using System.IO;
 7using System.Linq;
 8using System.Text.Json;
 9using Jellyfin.Extensions.Json;
 10using Microsoft.Extensions.Logging;
 11
 12namespace Jellyfin.LiveTv.Timers
 13{
 14    public class ItemDataProvider<T>
 15        where T : class
 16    {
 17        private readonly string _dataPath;
 4418        private readonly object _fileDataLock = new object();
 4419        private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options;
 20        private T[]? _items;
 21
 22        public ItemDataProvider(
 23            ILogger logger,
 24            string dataPath,
 25            Func<T, T, bool> equalityComparer)
 26        {
 4427            Logger = logger;
 4428            _dataPath = dataPath;
 4429            EqualityComparer = equalityComparer;
 4430        }
 31
 32        protected ILogger Logger { get; }
 33
 34        protected Func<T, T, bool> EqualityComparer { get; }
 35
 36        [MemberNotNull(nameof(_items))]
 37        private void EnsureLoaded()
 38        {
 2239            if (_items is not null)
 40            {
 041                return;
 42            }
 43
 2244            if (File.Exists(_dataPath))
 45            {
 046                Logger.LogInformation("Loading live tv data from {Path}", _dataPath);
 47
 48                try
 49                {
 050                    var bytes = File.ReadAllBytes(_dataPath);
 051                    _items = JsonSerializer.Deserialize<T[]>(bytes, _jsonOptions);
 052                    if (_items is null)
 53                    {
 054                        Logger.LogError("Error deserializing {Path}, data was null", _dataPath);
 055                        _items = Array.Empty<T>();
 56                    }
 57
 058                    return;
 59                }
 060                catch (JsonException ex)
 61                {
 062                    Logger.LogError(ex, "Error deserializing {Path}", _dataPath);
 063                }
 64            }
 65
 2266            _items = Array.Empty<T>();
 2267        }
 68
 69        private void SaveList()
 70        {
 071            Directory.CreateDirectory(Path.GetDirectoryName(_dataPath) ?? throw new ArgumentException("Path can't be a r
 072            var jsonString = JsonSerializer.Serialize(_items, _jsonOptions);
 073            File.WriteAllText(_dataPath, jsonString);
 074        }
 75
 76        public IReadOnlyList<T> GetAll()
 77        {
 2278            lock (_fileDataLock)
 79            {
 2280                EnsureLoaded();
 2281                return (T[])_items.Clone();
 82            }
 2283        }
 84
 85        public virtual void Update(T item)
 86        {
 087            ArgumentNullException.ThrowIfNull(item);
 88
 089            lock (_fileDataLock)
 90            {
 091                EnsureLoaded();
 92
 093                var index = Array.FindIndex(_items, i => EqualityComparer(i, item));
 094                if (index == -1)
 95                {
 096                    throw new ArgumentException("item not found");
 97                }
 98
 099                _items[index] = item;
 100
 0101                SaveList();
 0102            }
 0103        }
 104
 105        public virtual void Add(T item)
 106        {
 0107            ArgumentNullException.ThrowIfNull(item);
 108
 0109            lock (_fileDataLock)
 110            {
 0111                EnsureLoaded();
 112
 0113                if (_items.Any(i => EqualityComparer(i, item)))
 114                {
 0115                    throw new ArgumentException("item already exists", nameof(item));
 116                }
 117
 0118                _items = [.._items, item];
 119
 0120                SaveList();
 0121            }
 0122        }
 123
 124        public virtual void AddOrUpdate(T item)
 125        {
 0126            lock (_fileDataLock)
 127            {
 0128                EnsureLoaded();
 129
 0130                int index = Array.FindIndex(_items, i => EqualityComparer(i, item));
 0131                if (index == -1)
 132                {
 0133                    _items = [.._items, item];
 134                }
 135                else
 136                {
 0137                    _items[index] = item;
 138                }
 139
 0140                SaveList();
 0141            }
 0142        }
 143
 144        public virtual void Delete(T item)
 145        {
 0146            lock (_fileDataLock)
 147            {
 0148                EnsureLoaded();
 0149                _items = _items.Where(i => !EqualityComparer(i, item)).ToArray();
 150
 0151                SaveList();
 0152            }
 0153        }
 154    }
 155}