| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 | 
							- using MediaBrowser.Common.Configuration;
 
- 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 Microsoft.Extensions.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.Model.IO;
 
- using MediaBrowser.Controller.Configuration;
 
- using MediaBrowser.Controller.Entities;
 
- using MediaBrowser.Model.Entities;
 
- using MediaBrowser.Model.Configuration;
 
- using MediaBrowser.Controller.Plugins;
 
- using MediaBrowser.Model.Globalization;
 
- using MediaBrowser.Controller.Security;
 
- using MediaBrowser.Model.Serialization;
 
- using MediaBrowser.Common.Extensions;
 
- namespace Emby.Server.Implementations.Devices
 
- {
 
-     public class DeviceManager : IDeviceManager
 
-     {
 
-         private readonly IJsonSerializer _json;
 
-         private readonly IUserManager _userManager;
 
-         private readonly IFileSystem _fileSystem;
 
-         private readonly ILibraryMonitor _libraryMonitor;
 
-         private readonly IServerConfigurationManager _config;
 
-         private readonly ILogger _logger;
 
-         private readonly INetworkManager _network;
 
-         private readonly ILibraryManager _libraryManager;
 
-         private readonly ILocalizationManager _localizationManager;
 
-         private readonly IAuthenticationRepository _authRepo;
 
-         public event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
 
-         public event EventHandler<GenericEventArgs<CameraImageUploadInfo>> CameraImageUploaded;
 
-         private readonly object _cameraUploadSyncLock = new object();
 
-         private readonly object _capabilitiesSyncLock = new object();
 
-         public DeviceManager(IAuthenticationRepository authRepo, IJsonSerializer json, ILibraryManager libraryManager, ILocalizationManager localizationManager, IUserManager userManager, IFileSystem fileSystem, ILibraryMonitor libraryMonitor, IServerConfigurationManager config, ILogger logger, INetworkManager network)
 
-         {
 
-             _json = json;
 
-             _userManager = userManager;
 
-             _fileSystem = fileSystem;
 
-             _libraryMonitor = libraryMonitor;
 
-             _config = config;
 
-             _logger = logger;
 
-             _network = network;
 
-             _libraryManager = libraryManager;
 
-             _localizationManager = localizationManager;
 
-             _authRepo = authRepo;
 
-         }
 
-         private Dictionary<string, ClientCapabilities> _capabilitiesCache = new Dictionary<string, ClientCapabilities>(StringComparer.OrdinalIgnoreCase);
 
-         public void SaveCapabilities(string deviceId, ClientCapabilities capabilities)
 
-         {
 
-             var path = Path.Combine(GetDevicePath(deviceId), "capabilities.json");
 
-             _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
 
-             lock (_capabilitiesSyncLock)
 
-             {
 
-                 _capabilitiesCache[deviceId] = capabilities;
 
-                 _json.SerializeToFile(capabilities, path);
 
-             }
 
-         }
 
-         public void UpdateDeviceOptions(string deviceId, DeviceOptions options)
 
-         {
 
-             _authRepo.UpdateDeviceOptions(deviceId, options);
 
-             if (DeviceOptionsUpdated != null)
 
-             {
 
-                 DeviceOptionsUpdated(this, new GenericEventArgs<Tuple<string, DeviceOptions>>()
 
-                 {
 
-                     Argument = new Tuple<string, DeviceOptions>(deviceId, options)
 
-                 });
 
-             }
 
-         }
 
-         public DeviceOptions GetDeviceOptions(string deviceId)
 
-         {
 
-             return _authRepo.GetDeviceOptions(deviceId);
 
-         }
 
-         public ClientCapabilities GetCapabilities(string id)
 
-         {
 
-             lock (_capabilitiesSyncLock)
 
-             {
 
-                 ClientCapabilities result;
 
-                 if (_capabilitiesCache.TryGetValue(id, out result))
 
-                 {
 
-                     return result;
 
-                 }
 
-                 var path = Path.Combine(GetDevicePath(id), "capabilities.json");
 
-                 try
 
-                 {
 
-                     return _json.DeserializeFromFile<ClientCapabilities>(path) ?? new ClientCapabilities();
 
-                 }
 
-                 catch
 
-                 {
 
-                 }
 
-             }
 
-             return new ClientCapabilities();
 
-         }
 
-         public DeviceInfo GetDevice(string id)
 
-         {
 
-             return GetDevice(id, true);
 
-         }
 
-         private DeviceInfo GetDevice(string id, bool includeCapabilities)
 
-         {
 
-             var session = _authRepo.Get(new AuthenticationInfoQuery
 
-             {
 
-                 DeviceId = id
 
-             }).Items.FirstOrDefault();
 
-             var device = session == null ? null : ToDeviceInfo(session);
 
-             return device;
 
-         }
 
-         public QueryResult<DeviceInfo> GetDevices(DeviceQuery query)
 
-         {
 
-             var sessions = _authRepo.Get(new AuthenticationInfoQuery
 
-             {
 
-                 //UserId = query.UserId
 
-                 HasUser = true
 
-             }).Items;
 
-             
 
-             // TODO: DeviceQuery doesn't seem to be used from client. Not even Swagger.
 
-             if (query.SupportsSync.HasValue)
 
-             {
 
-                 var val = query.SupportsSync.Value;
 
-                 sessions = sessions.Where(i => GetCapabilities(i.DeviceId).SupportsSync == val).ToArray();
 
-             }
 
-             if (!query.UserId.Equals(Guid.Empty))
 
-             {
 
-                 var user = _userManager.GetUserById(query.UserId);
 
-                 sessions = sessions.Where(i => CanAccessDevice(user, i.DeviceId)).ToArray();
 
-             }
 
-             var array = sessions.Select(ToDeviceInfo).ToArray();
 
-             return new QueryResult<DeviceInfo>
 
-             {
 
-                 Items = array,
 
-                 TotalRecordCount = array.Length
 
-             };
 
-         }
 
-         private DeviceInfo ToDeviceInfo(AuthenticationInfo authInfo)
 
-         {
 
-             var caps = GetCapabilities(authInfo.DeviceId);
 
-             return new DeviceInfo
 
-             {
 
-                 AppName = authInfo.AppName,
 
-                 AppVersion = authInfo.AppVersion,
 
-                 Id = authInfo.DeviceId,
 
-                 LastUserId = authInfo.UserId,
 
-                 LastUserName = authInfo.UserName,
 
-                 Name = authInfo.DeviceName,
 
-                 DateLastActivity = authInfo.DateLastActivity,
 
-                 IconUrl = caps == null ? null : caps.IconUrl
 
-             };
 
-         }
 
-         private string GetDevicesPath()
 
-         {
 
-             return Path.Combine(_config.ApplicationPaths.DataPath, "devices");
 
-         }
 
-         private string GetDevicePath(string id)
 
-         {
 
-             return Path.Combine(GetDevicesPath(), id.GetMD5().ToString("N"));
 
-         }
 
-         public ContentUploadHistory GetCameraUploadHistory(string deviceId)
 
-         {
 
-             var path = Path.Combine(GetDevicePath(deviceId), "camerauploads.json");
 
-             lock (_cameraUploadSyncLock)
 
-             {
 
-                 try
 
-                 {
 
-                     return _json.DeserializeFromFile<ContentUploadHistory>(path);
 
-                 }
 
-                 catch (IOException)
 
-                 {
 
-                     return new ContentUploadHistory
 
-                     {
 
-                         DeviceId = deviceId
 
-                     };
 
-                 }
 
-             }
 
-         }
 
-         public async Task AcceptCameraUpload(string deviceId, Stream stream, LocalFileInfo file)
 
-         {
 
-             var device = GetDevice(deviceId, false);
 
-             var uploadPathInfo = GetUploadPath(device);
 
-             var path = uploadPathInfo.Item1;
 
-             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");
 
-             _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
 
-             await EnsureLibraryFolder(uploadPathInfo.Item2, uploadPathInfo.Item3).ConfigureAwait(false);
 
-             _libraryMonitor.ReportFileSystemChangeBeginning(path);
 
-             try
 
-             {
 
-                 using (var fs = _fileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
 
-                 {
 
-                     await stream.CopyToAsync(fs).ConfigureAwait(false);
 
-                 }
 
-                 AddCameraUpload(deviceId, file);
 
-             }
 
-             finally
 
-             {
 
-                 _libraryMonitor.ReportFileSystemChangeComplete(path, true);
 
-             }
 
-             if (CameraImageUploaded != null)
 
-             {
 
-                 CameraImageUploaded?.Invoke(this, new GenericEventArgs<CameraImageUploadInfo>
 
-                 {
 
-                     Argument = new CameraImageUploadInfo
 
-                     {
 
-                         Device = device,
 
-                         FileInfo = file
 
-                     }
 
-                 });
 
-             }
 
-         }
 
-         private void AddCameraUpload(string deviceId, LocalFileInfo file)
 
-         {
 
-             var path = Path.Combine(GetDevicePath(deviceId), "camerauploads.json");
 
-             _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
 
-             lock (_cameraUploadSyncLock)
 
-             {
 
-                 ContentUploadHistory history;
 
-                 try
 
-                 {
 
-                     history = _json.DeserializeFromFile<ContentUploadHistory>(path);
 
-                 }
 
-                 catch (IOException)
 
-                 {
 
-                     history = new ContentUploadHistory
 
-                     {
 
-                         DeviceId = deviceId
 
-                     };
 
-                 }
 
-                 history.DeviceId = deviceId;
 
-                 var list = history.FilesUploaded.ToList();
 
-                 list.Add(file);
 
-                 history.FilesUploaded = list.ToArray();
 
-                 _json.SerializeToFile(history, path);
 
-             }
 
-         }
 
-         internal Task EnsureLibraryFolder(string path, string name)
 
-         {
 
-             var existingFolders = _libraryManager
 
-                 .RootFolder
 
-                 .Children
 
-                 .OfType<Folder>()
 
-                 .Where(i => _fileSystem.AreEqual(path, i.Path) || _fileSystem.ContainsSubPath(i.Path, path))
 
-                 .ToList();
 
-             if (existingFolders.Count > 0)
 
-             {
 
-                 return Task.CompletedTask;
 
-             }
 
-             _fileSystem.CreateDirectory(path);
 
-             var libraryOptions = new LibraryOptions
 
-             {
 
-                 PathInfos = new[] { new MediaPathInfo { Path = path } },
 
-                 EnablePhotos = true,
 
-                 EnableRealtimeMonitor = false,
 
-                 SaveLocalMetadata = true
 
-             };
 
-             if (string.IsNullOrWhiteSpace(name))
 
-             {
 
-                 name = _localizationManager.GetLocalizedString("HeaderCameraUploads");
 
-             }
 
-             return _libraryManager.AddVirtualFolder(name, CollectionType.HomeVideos, libraryOptions, true);
 
-         }
 
-         private Tuple<string, string, string> GetUploadPath(DeviceInfo device)
 
-         {
 
-             var config = _config.GetUploadOptions();
 
-             var path = config.CameraUploadPath;
 
-             if (string.IsNullOrWhiteSpace(path))
 
-             {
 
-                 path = DefaultCameraUploadsPath;
 
-             }
 
-             var topLibraryPath = path;
 
-             if (config.EnableCameraUploadSubfolders)
 
-             {
 
-                 path = Path.Combine(path, _fileSystem.GetValidFilename(device.Name));
 
-             }
 
-             return new Tuple<string, string, string>(path, topLibraryPath, null);
 
-         }
 
-         internal string GetUploadsPath()
 
-         {
 
-             var config = _config.GetUploadOptions();
 
-             var path = config.CameraUploadPath;
 
-             if (string.IsNullOrWhiteSpace(path))
 
-             {
 
-                 path = DefaultCameraUploadsPath;
 
-             }
 
-             return path;
 
-         }
 
-         private string DefaultCameraUploadsPath
 
-         {
 
-             get { return Path.Combine(_config.CommonApplicationPaths.DataPath, "camerauploads"); }
 
-         }
 
-         public bool CanAccessDevice(User user, string deviceId)
 
-         {
 
-             if (user == null)
 
-             {
 
-                 throw new ArgumentException("user not found");
 
-             }
 
-             if (string.IsNullOrEmpty(deviceId))
 
-             {
 
-                 throw new ArgumentNullException("deviceId");
 
-             }
 
-             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 policy.EnabledDevices.Contains(id, StringComparer.OrdinalIgnoreCase);
 
-         }
 
-     }
 
-     public class DeviceManagerEntryPoint : IServerEntryPoint
 
-     {
 
-         private readonly DeviceManager _deviceManager;
 
-         private readonly IServerConfigurationManager _config;
 
-         private readonly IFileSystem _fileSystem;
 
-         private ILogger _logger;
 
-         public DeviceManagerEntryPoint(IDeviceManager deviceManager, IServerConfigurationManager config, IFileSystem fileSystem, ILogger logger)
 
-         {
 
-             _deviceManager = (DeviceManager)deviceManager;
 
-             _config = config;
 
-             _fileSystem = fileSystem;
 
-             _logger = logger;
 
-         }
 
-         public async void Run()
 
-         {
 
-             if (!_config.Configuration.CameraUploadUpgraded && _config.Configuration.IsStartupWizardCompleted)
 
-             {
 
-                 var path = _deviceManager.GetUploadsPath();
 
-                 if (_fileSystem.DirectoryExists(path))
 
-                 {
 
-                     try
 
-                     {
 
-                         await _deviceManager.EnsureLibraryFolder(path, null).ConfigureAwait(false);
 
-                     }
 
-                     catch (Exception ex)
 
-                     {
 
-                         _logger.LogError(ex, "Error creating camera uploads library");
 
-                     }
 
-                     _config.Configuration.CameraUploadUpgraded = true;
 
-                     _config.SaveConfiguration();
 
-                 }
 
-             }
 
-         }
 
-         #region IDisposable Support
 
-         private bool disposedValue = false; // To detect redundant calls
 
-         protected virtual void Dispose(bool disposing)
 
-         {
 
-             if (!disposedValue)
 
-             {
 
-                 if (disposing)
 
-                 {
 
-                     // TODO: dispose managed state (managed objects).
 
-                 }
 
-                 // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
 
-                 // TODO: set large fields to null.
 
-                 disposedValue = true;
 
-             }
 
-         }
 
-         // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
 
-         // ~DeviceManagerEntryPoint() {
 
-         //   // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
 
-         //   Dispose(false);
 
-         // }
 
-         // This code added to correctly implement the disposable pattern.
 
-         public void Dispose()
 
-         {
 
-             // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
 
-             Dispose(true);
 
-             // TODO: uncomment the following line if the finalizer is overridden above.
 
-             // GC.SuppressFinalize(this);
 
-         }
 
-         #endregion
 
-     }
 
-     public class DevicesConfigStore : IConfigurationFactory
 
-     {
 
-         public IEnumerable<ConfigurationStore> GetConfigurations()
 
-         {
 
-             return new ConfigurationStore[]
 
-             {
 
-                 new ConfigurationStore
 
-                 {
 
-                      Key = "devices",
 
-                      ConfigurationType = typeof(DevicesOptions)
 
-                 }
 
-             };
 
-         }
 
-     }
 
-     public static class UploadConfigExtension
 
-     {
 
-         public static DevicesOptions GetUploadOptions(this IConfigurationManager config)
 
-         {
 
-             return config.GetConfiguration<DevicesOptions>("devices");
 
-         }
 
-     }
 
- }
 
 
  |