| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 | using MediaBrowser.Common.Configuration;using MediaBrowser.Common.Events;using MediaBrowser.Common.Net;using MediaBrowser.Controller.Devices;using MediaBrowser.Controller.Library;using MediaBrowser.Model.Devices;using MediaBrowser.Model.Events;using MediaBrowser.Model.Extensions;using MediaBrowser.Model.Logging;using MediaBrowser.Model.Net;using MediaBrowser.Model.Querying;using MediaBrowser.Model.Session;using MediaBrowser.Model.Users;using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Threading.Tasks;using MediaBrowser.Common.IO;using MediaBrowser.Model.IO;using MediaBrowser.Controller.Configuration;using MediaBrowser.Controller.IO;namespace Emby.Server.Implementations.Devices{    public class DeviceManager : IDeviceManager    {        private readonly IDeviceRepository _repo;        private readonly IUserManager _userManager;        private readonly IFileSystem _fileSystem;        private readonly ILibraryMonitor _libraryMonitor;        private readonly IServerConfigurationManager _config;        private readonly ILogger _logger;        private readonly INetworkManager _network;        public event EventHandler<GenericEventArgs<CameraImageUploadInfo>> CameraImageUploaded;        /// <summary>        /// Occurs when [device options updated].        /// </summary>        public event EventHandler<GenericEventArgs<DeviceInfo>> DeviceOptionsUpdated;        public DeviceManager(IDeviceRepository repo, IUserManager userManager, IFileSystem fileSystem, ILibraryMonitor libraryMonitor, IServerConfigurationManager config, ILogger logger, INetworkManager network)        {            _repo = repo;            _userManager = userManager;            _fileSystem = fileSystem;            _libraryMonitor = libraryMonitor;            _config = config;            _logger = logger;            _network = network;        }        public async Task<DeviceInfo> RegisterDevice(string reportedId, string name, string appName, string appVersion, string usedByUserId)        {            if (string.IsNullOrWhiteSpace(reportedId))            {                throw new ArgumentNullException("reportedId");            }            var device = GetDevice(reportedId) ?? new DeviceInfo            {                Id = reportedId            };            device.ReportedName = name;            device.AppName = appName;            device.AppVersion = appVersion;            if (!string.IsNullOrWhiteSpace(usedByUserId))            {                var user = _userManager.GetUserById(usedByUserId);                device.LastUserId = user.Id.ToString("N");                device.LastUserName = user.Name;            }            device.DateLastModified = DateTime.UtcNow;            await _repo.SaveDevice(device).ConfigureAwait(false);            return device;        }        public Task SaveCapabilities(string reportedId, ClientCapabilities capabilities)        {            return _repo.SaveCapabilities(reportedId, capabilities);        }        public ClientCapabilities GetCapabilities(string reportedId)        {            return _repo.GetCapabilities(reportedId);        }        public DeviceInfo GetDevice(string id)        {            return _repo.GetDevice(id);        }        public QueryResult<DeviceInfo> GetDevices(DeviceQuery query)        {            IEnumerable<DeviceInfo> devices = _repo.GetDevices().OrderByDescending(i => i.DateLastModified);            if (query.SupportsContentUploading.HasValue)            {                var val = query.SupportsContentUploading.Value;                devices = devices.Where(i => GetCapabilities(i.Id).SupportsContentUploading == val);            }            if (query.SupportsSync.HasValue)            {                var val = query.SupportsSync.Value;                devices = devices.Where(i => GetCapabilities(i.Id).SupportsSync == val);            }            if (query.SupportsPersistentIdentifier.HasValue)            {                var val = query.SupportsPersistentIdentifier.Value;                devices = devices.Where(i =>                {                    var caps = GetCapabilities(i.Id);                    var deviceVal = caps.SupportsPersistentIdentifier;                    return deviceVal == val;                });            }            if (!string.IsNullOrWhiteSpace(query.UserId))            {                devices = devices.Where(i => CanAccessDevice(query.UserId, i.Id));            }            var array = devices.ToArray();            return new QueryResult<DeviceInfo>            {                Items = array,                TotalRecordCount = array.Length            };        }        public Task DeleteDevice(string id)        {            return _repo.DeleteDevice(id);        }        public ContentUploadHistory GetCameraUploadHistory(string deviceId)        {            return _repo.GetCameraUploadHistory(deviceId);        }        public async Task AcceptCameraUpload(string deviceId, Stream stream, LocalFileInfo file)        {            var device = GetDevice(deviceId);            var path = GetUploadPath(device);            if (!string.IsNullOrWhiteSpace(file.Album))            {                path = Path.Combine(path, _fileSystem.GetValidFilename(file.Album));            }            path = Path.Combine(path, file.Name);            path = Path.ChangeExtension(path, MimeTypes.ToExtension(file.MimeType) ?? "jpg");            _libraryMonitor.ReportFileSystemChangeBeginning(path);            _fileSystem.CreateDirectory(Path.GetDirectoryName(path));            try            {                using (var fs = _fileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))                {                    await stream.CopyToAsync(fs).ConfigureAwait(false);                }                _repo.AddCameraUpload(deviceId, file);            }            finally            {                _libraryMonitor.ReportFileSystemChangeComplete(path, true);            }            if (CameraImageUploaded != null)            {                EventHelper.FireEventIfNotNull(CameraImageUploaded, this, new GenericEventArgs<CameraImageUploadInfo>                {                    Argument = new CameraImageUploadInfo                    {                        Device = device,                        FileInfo = file                    }                }, _logger);            }        }        private string GetUploadPath(DeviceInfo device)        {            if (!string.IsNullOrWhiteSpace(device.CameraUploadPath))            {                return device.CameraUploadPath;            }            var config = _config.GetUploadOptions();            if (!string.IsNullOrWhiteSpace(config.CameraUploadPath))            {                return config.CameraUploadPath;            }            var path = DefaultCameraUploadsPath;            if (config.EnableCameraUploadSubfolders)            {                path = Path.Combine(path, _fileSystem.GetValidFilename(device.Name));            }            return path;        }        private string DefaultCameraUploadsPath        {            get { return Path.Combine(_config.CommonApplicationPaths.DataPath, "camerauploads"); }        }        public async Task UpdateDeviceInfo(string id, DeviceOptions options)        {            var device = GetDevice(id);            device.CustomName = options.CustomName;            device.CameraUploadPath = options.CameraUploadPath;            await _repo.SaveDevice(device).ConfigureAwait(false);            EventHelper.FireEventIfNotNull(DeviceOptionsUpdated, this, new GenericEventArgs<DeviceInfo>(device), _logger);        }        public bool CanAccessDevice(string userId, string deviceId)        {            if (string.IsNullOrWhiteSpace(userId))            {                throw new ArgumentNullException("userId");            }            if (string.IsNullOrWhiteSpace(deviceId))            {                throw new ArgumentNullException("deviceId");            }            var user = _userManager.GetUserById(userId);            if (user == null)            {                throw new ArgumentException("user not found");            }            if (!CanAccessDevice(user.Policy, deviceId))            {                var capabilities = GetCapabilities(deviceId);                if (capabilities != null && capabilities.SupportsPersistentIdentifier)                {                    return false;                }            }            return true;        }        private bool CanAccessDevice(UserPolicy policy, string id)        {            if (policy.EnableAllDevices)            {                return true;            }            if (policy.IsAdministrator)            {                return true;            }            return ListHelper.ContainsIgnoreCase(policy.EnabledDevices, id);        }    }    public class DevicesConfigStore : IConfigurationFactory    {        public IEnumerable<ConfigurationStore> GetConfigurations()        {            return new List<ConfigurationStore>            {                new ConfigurationStore                {                     Key = "devices",                     ConfigurationType = typeof(DevicesOptions)                }            };        }    }    public static class UploadConfigExtension    {        public static DevicesOptions GetUploadOptions(this IConfigurationManager config)        {            return config.GetConfiguration<DevicesOptions>("devices");        }    }}
 |