2014-04-30 23:39:54 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
2014-02-22 22:03:23 +00:00
|
|
|
|
using System.Linq;
|
2014-04-30 23:39:54 +00:00
|
|
|
|
using System.Net;
|
2014-01-24 16:17:56 +00:00
|
|
|
|
using NLog;
|
2014-04-30 23:39:54 +00:00
|
|
|
|
using NzbDrone.Common;
|
|
|
|
|
using NzbDrone.Common.Disk;
|
2014-05-12 02:19:15 +00:00
|
|
|
|
using NzbDrone.Common.Http;
|
2014-02-22 22:03:23 +00:00
|
|
|
|
using NzbDrone.Core.Datastore;
|
2014-01-26 07:14:55 +00:00
|
|
|
|
using NzbDrone.Core.MediaCover;
|
2014-02-22 22:03:23 +00:00
|
|
|
|
using NzbDrone.Core.MediaFiles;
|
2014-01-22 05:22:09 +00:00
|
|
|
|
using NzbDrone.Core.MediaFiles.Events;
|
|
|
|
|
using NzbDrone.Core.Messaging.Events;
|
2014-01-26 07:14:55 +00:00
|
|
|
|
using NzbDrone.Core.Metadata.Files;
|
2014-02-22 22:03:23 +00:00
|
|
|
|
using NzbDrone.Core.Tv;
|
2014-01-22 05:22:09 +00:00
|
|
|
|
|
|
|
|
|
namespace NzbDrone.Core.Metadata
|
|
|
|
|
{
|
2014-11-18 15:38:31 +00:00
|
|
|
|
public class MetadataService : IHandle<MediaCoversUpdatedEvent>,
|
|
|
|
|
IHandle<EpisodeImportedEvent>,
|
|
|
|
|
IHandle<SeriesRenamedEvent>
|
2014-01-22 05:22:09 +00:00
|
|
|
|
{
|
|
|
|
|
private readonly IMetadataFactory _metadataFactory;
|
2014-02-14 05:31:49 +00:00
|
|
|
|
private readonly IMetadataFileService _metadataFileService;
|
2014-02-19 04:51:37 +00:00
|
|
|
|
private readonly ICleanMetadataService _cleanMetadataService;
|
2014-02-22 22:03:23 +00:00
|
|
|
|
private readonly IMediaFileService _mediaFileService;
|
|
|
|
|
private readonly IEpisodeService _episodeService;
|
2014-04-30 23:39:54 +00:00
|
|
|
|
private readonly IDiskProvider _diskProvider;
|
2014-09-11 23:49:41 +00:00
|
|
|
|
private readonly IHttpClient _httpClient;
|
2014-11-18 15:38:31 +00:00
|
|
|
|
private readonly IMediaFileAttributeService _mediaFileAttributeService;
|
2014-04-30 23:39:54 +00:00
|
|
|
|
private readonly IEventAggregator _eventAggregator;
|
2014-01-22 05:22:09 +00:00
|
|
|
|
private readonly Logger _logger;
|
|
|
|
|
|
2014-02-19 04:51:37 +00:00
|
|
|
|
public MetadataService(IMetadataFactory metadataFactory,
|
|
|
|
|
IMetadataFileService metadataFileService,
|
|
|
|
|
ICleanMetadataService cleanMetadataService,
|
2014-02-22 22:03:23 +00:00
|
|
|
|
IMediaFileService mediaFileService,
|
|
|
|
|
IEpisodeService episodeService,
|
2014-04-30 23:39:54 +00:00
|
|
|
|
IDiskProvider diskProvider,
|
2014-09-11 23:49:41 +00:00
|
|
|
|
IHttpClient httpClient,
|
2014-11-18 15:38:31 +00:00
|
|
|
|
IMediaFileAttributeService mediaFileAttributeService,
|
2014-04-30 23:39:54 +00:00
|
|
|
|
IEventAggregator eventAggregator,
|
2014-02-19 04:51:37 +00:00
|
|
|
|
Logger logger)
|
2014-01-22 05:22:09 +00:00
|
|
|
|
{
|
|
|
|
|
_metadataFactory = metadataFactory;
|
2014-01-26 07:14:55 +00:00
|
|
|
|
_metadataFileService = metadataFileService;
|
2014-02-19 04:51:37 +00:00
|
|
|
|
_cleanMetadataService = cleanMetadataService;
|
2014-02-22 22:03:23 +00:00
|
|
|
|
_mediaFileService = mediaFileService;
|
|
|
|
|
_episodeService = episodeService;
|
2014-04-30 23:39:54 +00:00
|
|
|
|
_diskProvider = diskProvider;
|
2014-09-11 23:49:41 +00:00
|
|
|
|
_httpClient = httpClient;
|
2014-11-18 15:38:31 +00:00
|
|
|
|
_mediaFileAttributeService = mediaFileAttributeService;
|
2014-04-30 23:39:54 +00:00
|
|
|
|
_eventAggregator = eventAggregator;
|
2014-01-22 05:22:09 +00:00
|
|
|
|
_logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-26 07:14:55 +00:00
|
|
|
|
public void Handle(MediaCoversUpdatedEvent message)
|
2014-01-22 05:22:09 +00:00
|
|
|
|
{
|
2014-02-19 04:51:37 +00:00
|
|
|
|
_cleanMetadataService.Clean(message.Series);
|
2014-04-30 23:39:54 +00:00
|
|
|
|
|
|
|
|
|
if (!_diskProvider.FolderExists(message.Series.Path))
|
|
|
|
|
{
|
|
|
|
|
_logger.Info("Series folder does not exist, skipping metadata creation");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var seriesMetadataFiles = _metadataFileService.GetFilesBySeries(message.Series.Id);
|
|
|
|
|
var episodeFiles = GetEpisodeFiles(message.Series.Id);
|
2014-01-26 07:14:55 +00:00
|
|
|
|
|
2014-01-22 05:22:09 +00:00
|
|
|
|
foreach (var consumer in _metadataFactory.Enabled())
|
|
|
|
|
{
|
2014-04-30 23:39:54 +00:00
|
|
|
|
var consumerFiles = GetMetadataFilesForConsumer(consumer, seriesMetadataFiles);
|
|
|
|
|
var files = new List<MetadataFile>();
|
|
|
|
|
|
|
|
|
|
files.AddIfNotNull(ProcessSeriesMetadata(consumer, message.Series, consumerFiles));
|
|
|
|
|
files.AddRange(ProcessSeriesImages(consumer, message.Series, consumerFiles));
|
|
|
|
|
files.AddRange(ProcessSeasonImages(consumer, message.Series, consumerFiles));
|
|
|
|
|
|
|
|
|
|
foreach (var episodeFile in episodeFiles)
|
|
|
|
|
{
|
|
|
|
|
files.AddIfNotNull(ProcessEpisodeMetadata(consumer, message.Series, episodeFile, consumerFiles));
|
|
|
|
|
files.AddRange(ProcessEpisodeImages(consumer, message.Series, episodeFile, consumerFiles));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_eventAggregator.PublishEvent(new MetadataFilesUpdated(files));
|
2014-01-22 05:22:09 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Handle(EpisodeImportedEvent message)
|
|
|
|
|
{
|
|
|
|
|
foreach (var consumer in _metadataFactory.Enabled())
|
|
|
|
|
{
|
2014-04-30 23:39:54 +00:00
|
|
|
|
var files = new List<MetadataFile>();
|
|
|
|
|
|
|
|
|
|
files.AddIfNotNull(ProcessEpisodeMetadata(consumer, message.EpisodeInfo.Series, message.ImportedEpisode, new List<MetadataFile>()));
|
|
|
|
|
files.AddRange(ProcessEpisodeImages(consumer, message.EpisodeInfo.Series, message.ImportedEpisode, new List<MetadataFile>()));
|
|
|
|
|
|
|
|
|
|
_eventAggregator.PublishEvent(new MetadataFilesUpdated(files));
|
2014-01-22 05:22:09 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Handle(SeriesRenamedEvent message)
|
|
|
|
|
{
|
2014-02-22 22:03:23 +00:00
|
|
|
|
var seriesMetadata = _metadataFileService.GetFilesBySeries(message.Series.Id);
|
2014-04-30 23:39:54 +00:00
|
|
|
|
var episodeFiles = GetEpisodeFiles(message.Series.Id);
|
2014-02-22 22:03:23 +00:00
|
|
|
|
|
2014-01-22 05:22:09 +00:00
|
|
|
|
foreach (var consumer in _metadataFactory.Enabled())
|
|
|
|
|
{
|
2014-04-30 23:39:54 +00:00
|
|
|
|
var updatedMetadataFiles = consumer.AfterRename(message.Series,
|
|
|
|
|
GetMetadataFilesForConsumer(consumer, seriesMetadata),
|
|
|
|
|
episodeFiles);
|
|
|
|
|
|
|
|
|
|
_eventAggregator.PublishEvent(new MetadataFilesUpdated(updatedMetadataFiles));
|
2014-02-22 22:03:23 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<EpisodeFile> GetEpisodeFiles(int seriesId)
|
|
|
|
|
{
|
|
|
|
|
var episodeFiles = _mediaFileService.GetFilesBySeries(seriesId);
|
|
|
|
|
var episodes = _episodeService.GetEpisodeBySeries(seriesId);
|
|
|
|
|
|
|
|
|
|
foreach (var episodeFile in episodeFiles)
|
|
|
|
|
{
|
|
|
|
|
var localEpisodeFile = episodeFile;
|
|
|
|
|
episodeFile.Episodes = new LazyList<Episode>(episodes.Where(e => e.EpisodeFileId == localEpisodeFile.Id));
|
2014-01-22 05:22:09 +00:00
|
|
|
|
}
|
2014-02-22 22:03:23 +00:00
|
|
|
|
|
|
|
|
|
return episodeFiles;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<MetadataFile> GetMetadataFilesForConsumer(IMetadata consumer, List<MetadataFile> seriesMetadata)
|
|
|
|
|
{
|
|
|
|
|
return seriesMetadata.Where(c => c.Consumer == consumer.GetType().Name).ToList();
|
2014-01-22 05:22:09 +00:00
|
|
|
|
}
|
2014-04-30 23:39:54 +00:00
|
|
|
|
|
|
|
|
|
private MetadataFile ProcessSeriesMetadata(IMetadata consumer, Series series, List<MetadataFile> existingMetadataFiles)
|
|
|
|
|
{
|
|
|
|
|
var seriesMetadata = consumer.SeriesMetadata(series);
|
|
|
|
|
|
|
|
|
|
if (seriesMetadata == null)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var hash = seriesMetadata.Contents.SHA256Hash();
|
|
|
|
|
|
|
|
|
|
var metadata = existingMetadataFiles.SingleOrDefault(e => e.Type == MetadataType.SeriesMetadata) ??
|
|
|
|
|
new MetadataFile
|
|
|
|
|
{
|
|
|
|
|
SeriesId = series.Id,
|
2014-05-02 02:19:42 +00:00
|
|
|
|
Consumer = consumer.GetType().Name,
|
2014-04-30 23:39:54 +00:00
|
|
|
|
Type = MetadataType.SeriesMetadata,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (hash == metadata.Hash)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-03 05:08:08 +00:00
|
|
|
|
var fullPath = Path.Combine(series.Path, seriesMetadata.RelativePath);
|
|
|
|
|
|
|
|
|
|
_logger.Debug("Writing Series Metadata to: {0}", fullPath);
|
|
|
|
|
SaveMetadataFile(fullPath, seriesMetadata.Contents);
|
2014-04-30 23:39:54 +00:00
|
|
|
|
|
|
|
|
|
metadata.Hash = hash;
|
2014-09-03 05:08:08 +00:00
|
|
|
|
metadata.RelativePath = seriesMetadata.RelativePath;
|
2014-04-30 23:39:54 +00:00
|
|
|
|
|
|
|
|
|
return metadata;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private MetadataFile ProcessEpisodeMetadata(IMetadata consumer, Series series, EpisodeFile episodeFile, List<MetadataFile> existingMetadataFiles)
|
|
|
|
|
{
|
|
|
|
|
var episodeMetadata = consumer.EpisodeMetadata(series, episodeFile);
|
|
|
|
|
|
|
|
|
|
if (episodeMetadata == null)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-15 06:57:49 +00:00
|
|
|
|
var fullPath = Path.Combine(series.Path, episodeMetadata.RelativePath);
|
2014-04-30 23:39:54 +00:00
|
|
|
|
|
|
|
|
|
var existingMetadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.EpisodeMetadata &&
|
|
|
|
|
c.EpisodeFileId == episodeFile.Id);
|
|
|
|
|
|
|
|
|
|
if (existingMetadata != null)
|
|
|
|
|
{
|
2014-07-23 23:43:54 +00:00
|
|
|
|
var existingFullPath = Path.Combine(series.Path, existingMetadata.RelativePath);
|
2014-08-15 06:57:49 +00:00
|
|
|
|
if (!fullPath.PathEquals(existingFullPath))
|
2014-04-30 23:39:54 +00:00
|
|
|
|
{
|
2014-07-23 23:43:54 +00:00
|
|
|
|
_diskProvider.MoveFile(existingFullPath, fullPath);
|
2014-08-15 06:57:49 +00:00
|
|
|
|
existingMetadata.RelativePath = episodeMetadata.RelativePath;
|
2014-04-30 23:39:54 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var hash = episodeMetadata.Contents.SHA256Hash();
|
|
|
|
|
|
|
|
|
|
var metadata = existingMetadata ??
|
|
|
|
|
new MetadataFile
|
|
|
|
|
{
|
|
|
|
|
SeriesId = series.Id,
|
|
|
|
|
EpisodeFileId = episodeFile.Id,
|
2014-05-02 02:19:42 +00:00
|
|
|
|
Consumer = consumer.GetType().Name,
|
2014-04-30 23:39:54 +00:00
|
|
|
|
Type = MetadataType.EpisodeMetadata,
|
2014-08-15 06:57:49 +00:00
|
|
|
|
RelativePath = episodeMetadata.RelativePath
|
2014-04-30 23:39:54 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (hash == metadata.Hash)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-23 23:43:54 +00:00
|
|
|
|
_logger.Debug("Writing Episode Metadata to: {0}", fullPath);
|
2014-09-03 05:08:08 +00:00
|
|
|
|
SaveMetadataFile(fullPath, episodeMetadata.Contents);
|
2014-04-30 23:39:54 +00:00
|
|
|
|
|
|
|
|
|
metadata.Hash = hash;
|
|
|
|
|
|
|
|
|
|
return metadata;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<MetadataFile> ProcessSeriesImages(IMetadata consumer, Series series, List<MetadataFile> existingMetadataFiles)
|
|
|
|
|
{
|
|
|
|
|
var result = new List<MetadataFile>();
|
|
|
|
|
|
|
|
|
|
foreach (var image in consumer.SeriesImages(series))
|
|
|
|
|
{
|
2014-08-15 06:57:49 +00:00
|
|
|
|
if (_diskProvider.FileExists(image.RelativePath))
|
2014-04-30 23:39:54 +00:00
|
|
|
|
{
|
2014-08-15 06:57:49 +00:00
|
|
|
|
_logger.Debug("Series image already exists: {0}", image.RelativePath);
|
2014-04-30 23:39:54 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var metadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.SeriesImage &&
|
2014-08-15 06:57:49 +00:00
|
|
|
|
c.RelativePath == image.RelativePath) ??
|
2014-04-30 23:39:54 +00:00
|
|
|
|
new MetadataFile
|
|
|
|
|
{
|
|
|
|
|
SeriesId = series.Id,
|
2014-05-02 02:19:42 +00:00
|
|
|
|
Consumer = consumer.GetType().Name,
|
2014-04-30 23:39:54 +00:00
|
|
|
|
Type = MetadataType.SeriesImage,
|
2014-08-15 06:57:49 +00:00
|
|
|
|
RelativePath = image.RelativePath
|
2014-04-30 23:39:54 +00:00
|
|
|
|
};
|
|
|
|
|
|
2014-08-15 06:57:49 +00:00
|
|
|
|
_diskProvider.CopyFile(image.Url, image.RelativePath);
|
2014-04-30 23:39:54 +00:00
|
|
|
|
|
|
|
|
|
result.Add(metadata);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<MetadataFile> ProcessSeasonImages(IMetadata consumer, Series series, List<MetadataFile> existingMetadataFiles)
|
|
|
|
|
{
|
|
|
|
|
var result = new List<MetadataFile>();
|
|
|
|
|
|
|
|
|
|
foreach (var season in series.Seasons)
|
|
|
|
|
{
|
|
|
|
|
foreach (var image in consumer.SeasonImages(series, season))
|
|
|
|
|
{
|
2014-08-15 06:57:49 +00:00
|
|
|
|
if (_diskProvider.FileExists(image.RelativePath))
|
2014-04-30 23:39:54 +00:00
|
|
|
|
{
|
2014-08-15 06:57:49 +00:00
|
|
|
|
_logger.Debug("Season image already exists: {0}", image.RelativePath);
|
2014-04-30 23:39:54 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var metadata = existingMetadataFiles.SingleOrDefault(c => c.Type == MetadataType.SeasonImage &&
|
|
|
|
|
c.SeasonNumber == season.SeasonNumber &&
|
2014-08-15 06:57:49 +00:00
|
|
|
|
c.RelativePath == image.RelativePath) ??
|
2014-04-30 23:39:54 +00:00
|
|
|
|
new MetadataFile
|
|
|
|
|
{
|
|
|
|
|
SeriesId = series.Id,
|
|
|
|
|
SeasonNumber = season.SeasonNumber,
|
2014-05-02 02:19:42 +00:00
|
|
|
|
Consumer = consumer.GetType().Name,
|
2014-04-30 23:39:54 +00:00
|
|
|
|
Type = MetadataType.SeasonImage,
|
2014-08-15 06:57:49 +00:00
|
|
|
|
RelativePath = image.RelativePath
|
2014-04-30 23:39:54 +00:00
|
|
|
|
};
|
|
|
|
|
|
2014-08-15 06:57:49 +00:00
|
|
|
|
DownloadImage(series, image.Url, image.RelativePath);
|
2014-04-30 23:39:54 +00:00
|
|
|
|
|
|
|
|
|
result.Add(metadata);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<MetadataFile> ProcessEpisodeImages(IMetadata consumer, Series series, EpisodeFile episodeFile, List<MetadataFile> existingMetadataFiles)
|
|
|
|
|
{
|
|
|
|
|
var result = new List<MetadataFile>();
|
|
|
|
|
|
|
|
|
|
foreach (var image in consumer.EpisodeImages(series, episodeFile))
|
|
|
|
|
{
|
2014-08-15 06:57:49 +00:00
|
|
|
|
var fullPath = Path.Combine(series.Path, image.RelativePath);
|
2014-07-23 23:43:54 +00:00
|
|
|
|
|
2014-08-15 06:57:49 +00:00
|
|
|
|
if (_diskProvider.FileExists(fullPath))
|
2014-04-30 23:39:54 +00:00
|
|
|
|
{
|
2014-08-15 06:57:49 +00:00
|
|
|
|
_logger.Debug("Episode image already exists: {0}", image.RelativePath);
|
2014-04-30 23:39:54 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var existingMetadata = existingMetadataFiles.FirstOrDefault(c => c.Type == MetadataType.EpisodeImage &&
|
|
|
|
|
c.EpisodeFileId == episodeFile.Id);
|
|
|
|
|
|
|
|
|
|
if (existingMetadata != null)
|
|
|
|
|
{
|
2014-07-23 23:43:54 +00:00
|
|
|
|
var existingFullPath = Path.Combine(series.Path, existingMetadata.RelativePath);
|
|
|
|
|
if (!fullPath.PathEquals(existingFullPath))
|
2014-04-30 23:39:54 +00:00
|
|
|
|
{
|
2014-07-23 23:43:54 +00:00
|
|
|
|
_diskProvider.MoveFile(fullPath, fullPath);
|
2014-08-15 06:57:49 +00:00
|
|
|
|
existingMetadata.RelativePath = image.RelativePath;
|
2014-04-30 23:39:54 +00:00
|
|
|
|
|
|
|
|
|
return new List<MetadataFile>{ existingMetadata };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var metadata = existingMetadata ??
|
|
|
|
|
new MetadataFile
|
|
|
|
|
{
|
|
|
|
|
SeriesId = series.Id,
|
|
|
|
|
EpisodeFileId = episodeFile.Id,
|
2014-05-02 02:19:42 +00:00
|
|
|
|
Consumer = consumer.GetType().Name,
|
2014-04-30 23:39:54 +00:00
|
|
|
|
Type = MetadataType.EpisodeImage,
|
2014-08-15 06:57:49 +00:00
|
|
|
|
RelativePath = image.RelativePath
|
2014-04-30 23:39:54 +00:00
|
|
|
|
};
|
|
|
|
|
|
2014-08-15 06:57:49 +00:00
|
|
|
|
DownloadImage(series, image.Url, fullPath);
|
2014-04-30 23:39:54 +00:00
|
|
|
|
|
|
|
|
|
result.Add(metadata);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-03 05:08:08 +00:00
|
|
|
|
private void DownloadImage(Series series, String url, String path)
|
2014-04-30 23:39:54 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2014-09-11 23:49:41 +00:00
|
|
|
|
_httpClient.DownloadFile(url, path);
|
2014-11-18 15:38:31 +00:00
|
|
|
|
_mediaFileAttributeService.SetFilePermissions(path);
|
2014-04-30 23:39:54 +00:00
|
|
|
|
}
|
|
|
|
|
catch (WebException e)
|
|
|
|
|
{
|
|
|
|
|
_logger.Warn(string.Format("Couldn't download image {0} for {1}. {2}", url, series, e.Message));
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
_logger.ErrorException("Couldn't download image " + url + " for " + series, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-09-03 05:08:08 +00:00
|
|
|
|
|
|
|
|
|
private void SaveMetadataFile(String path, String contents)
|
|
|
|
|
{
|
|
|
|
|
_diskProvider.WriteAllText(path, contents);
|
2014-11-18 15:38:31 +00:00
|
|
|
|
_mediaFileAttributeService.SetFilePermissions(path);
|
2014-09-03 05:08:08 +00:00
|
|
|
|
}
|
2014-01-22 05:22:09 +00:00
|
|
|
|
}
|
|
|
|
|
}
|