aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Library/PathManager.cs
blob: ef5edb9afa3bb9c8ec71dd8593ec39cbe9472011 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
using Microsoft.Extensions.Logging;

namespace Emby.Server.Implementations.Library;

/// <summary>
/// IPathManager implementation.
/// </summary>
public class PathManager : IPathManager
{
    private readonly ILogger<PathManager> _logger;
    private readonly IServerConfigurationManager _config;
    private readonly IApplicationPaths _appPaths;

    /// <summary>
    /// Initializes a new instance of the <see cref="PathManager"/> class.
    /// </summary>
    /// <param name="logger">The logger.</param>
    /// <param name="config">The server configuration manager.</param>
    /// <param name="appPaths">The application paths.</param>
    public PathManager(
        ILogger<PathManager> logger,
        IServerConfigurationManager config,
        IApplicationPaths appPaths)
    {
        _logger = logger;
        _config = config;
        _appPaths = appPaths;
    }

    private string SubtitleCachePath => Path.Combine(_appPaths.DataPath, "subtitles");

    private string AttachmentCachePath => Path.Combine(_appPaths.DataPath, "attachments");

    /// <inheritdoc />
    public string? GetAttachmentPath(string mediaSourceId, string fileName)
    {
        var folder = GetAttachmentFolderPath(mediaSourceId);
        return folder is null ? null : Path.Combine(folder, fileName);
    }

    /// <inheritdoc />
    public string? GetAttachmentFolderPath(string mediaSourceId)
    {
        if (!Guid.TryParse(mediaSourceId, out var parsed))
        {
            _logger.LogDebug("MediaSource Id '{MediaSourceId}' is not a GUID; no on-disk attachment folder.", mediaSourceId);
            return null;
        }

        var id = parsed.ToString("D", CultureInfo.InvariantCulture).AsSpan();
        return Path.Join(AttachmentCachePath, id[..2], id);
    }

    /// <inheritdoc />
    public string? GetSubtitleFolderPath(string mediaSourceId)
    {
        if (!Guid.TryParse(mediaSourceId, out var parsed))
        {
            _logger.LogDebug("MediaSource Id '{MediaSourceId}' is not a GUID; no on-disk subtitle folder.", mediaSourceId);
            return null;
        }

        var id = parsed.ToString("D", CultureInfo.InvariantCulture).AsSpan();
        return Path.Join(SubtitleCachePath, id[..2], id);
    }

    /// <inheritdoc />
    public string? GetSubtitlePath(string mediaSourceId, int streamIndex, string extension)
    {
        var folder = GetSubtitleFolderPath(mediaSourceId);
        return folder is null ? null : Path.Combine(folder, streamIndex.ToString(CultureInfo.InvariantCulture) + extension);
    }

    /// <inheritdoc />
    public string GetTrickplayDirectory(BaseItem item, bool saveWithMedia = false)
    {
        var id = item.Id.ToString("D", CultureInfo.InvariantCulture).AsSpan();

        return saveWithMedia
            ? Path.Combine(item.ContainingFolderPath, Path.ChangeExtension(Path.GetFileName(item.Path), ".trickplay"))
            : Path.Join(_config.ApplicationPaths.TrickplayPath, id[..2], id);
    }

    /// <inheritdoc/>
    public string GetChapterImageFolderPath(BaseItem item)
    {
        return Path.Combine(item.GetInternalMetadataPath(), "chapters");
    }

    /// <inheritdoc/>
    public string GetChapterImagePath(BaseItem item, long chapterPositionTicks)
    {
        var filename = item.DateModified.Ticks.ToString(CultureInfo.InvariantCulture) + "_" + chapterPositionTicks.ToString(CultureInfo.InvariantCulture) + ".jpg";

        return Path.Combine(GetChapterImageFolderPath(item), filename);
    }

    /// <inheritdoc/>
    public IReadOnlyList<string> GetExtractedDataPaths(BaseItem item)
    {
        var mediaSourceId = item.Id.ToString("N", CultureInfo.InvariantCulture);
        List<string> paths = [];
        var attachmentFolder = GetAttachmentFolderPath(mediaSourceId);
        if (attachmentFolder is not null)
        {
            paths.Add(attachmentFolder);
        }

        var subtitleFolder = GetSubtitleFolderPath(mediaSourceId);
        if (subtitleFolder is not null)
        {
            paths.Add(subtitleFolder);
        }

        paths.Add(GetTrickplayDirectory(item, false));
        paths.Add(GetTrickplayDirectory(item, true));
        paths.Add(GetChapterImageFolderPath(item));

        return paths;
    }
}