diff options
Diffstat (limited to 'Emby.Server.Implementations/Devices')
4 files changed, 292 insertions, 650 deletions
diff --git a/Emby.Server.Implementations/Devices/CameraUploadsDynamicFolder.cs b/Emby.Server.Implementations/Devices/CameraUploadsDynamicFolder.cs deleted file mode 100644 index bb9ef157c..000000000 --- a/Emby.Server.Implementations/Devices/CameraUploadsDynamicFolder.cs +++ /dev/null @@ -1,40 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Entities; -using System; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -using MediaBrowser.Controller.IO; -using MediaBrowser.Model.IO; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Serialization; - -namespace Emby.Server.Implementations.Devices -{ - public class CameraUploadsDynamicFolder : IVirtualFolderCreator - { - private readonly IApplicationPaths _appPaths; - private readonly IFileSystem _fileSystem; - - public CameraUploadsDynamicFolder(IApplicationPaths appPaths, IFileSystem fileSystem) - { - _appPaths = appPaths; - _fileSystem = fileSystem; - } - - public BasePluginFolder GetFolder() - { - var path = Path.Combine(_appPaths.DataPath, "camerauploads"); - - _fileSystem.CreateDirectory(path); - - return new CameraUploadsFolder - { - Path = path - }; - } - } - -} diff --git a/Emby.Server.Implementations/Devices/CameraUploadsFolder.cs b/Emby.Server.Implementations/Devices/CameraUploadsFolder.cs deleted file mode 100644 index 5c205dd19..000000000 --- a/Emby.Server.Implementations/Devices/CameraUploadsFolder.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Serialization; - -namespace Emby.Server.Implementations.Devices -{ - public class CameraUploadsFolder : BasePluginFolder, ISupportsUserSpecificView - { - public CameraUploadsFolder() - { - Name = "Camera Uploads"; - } - - public override bool IsVisible(User user) - { - if (!user.Policy.EnableAllFolders && !user.Policy.EnabledFolders.Contains(Id.ToString("N"), StringComparer.OrdinalIgnoreCase)) - { - return false; - } - - return base.IsVisible(user) && HasChildren(); - } - - [IgnoreDataMember] - public override string CollectionType - { - get { return MediaBrowser.Model.Entities.CollectionType.HomeVideos; } - } - - [IgnoreDataMember] - public override bool SupportsInheritedParentImages - { - get - { - return false; - } - } - - public override string GetClientTypeName() - { - return typeof(CollectionFolder).Name; - } - - private bool? _hasChildren; - private bool HasChildren() - { - if (!_hasChildren.HasValue) - { - _hasChildren = LibraryManager.GetItemIds(new InternalItemsQuery { Parent = this }).Count > 0; - } - - return _hasChildren.Value; - } - - protected override Task ValidateChildrenInternal(IProgress<double> progress, CancellationToken cancellationToken, bool recursive, bool refreshChildMetadata, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService) - { - _hasChildren = null; - return base.ValidateChildrenInternal(progress, cancellationToken, recursive, refreshChildMetadata, refreshOptions, directoryService); - } - - [IgnoreDataMember] - public bool EnableUserSpecificView - { - get { return true; } - } - } -} diff --git a/Emby.Server.Implementations/Devices/DeviceManager.cs b/Emby.Server.Implementations/Devices/DeviceManager.cs index ee4c4bb26..0fac886ef 100644 --- a/Emby.Server.Implementations/Devices/DeviceManager.cs +++ b/Emby.Server.Implementations/Devices/DeviceManager.cs @@ -18,114 +18,150 @@ using System.Linq; using System.Threading.Tasks; using MediaBrowser.Model.IO; using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.IO; +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 IDeviceRepository _repo; + 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; - /// <summary> - /// Occurs when [device options updated]. - /// </summary> - public event EventHandler<GenericEventArgs<DeviceInfo>> DeviceOptionsUpdated; + private readonly object _cameraUploadSyncLock = new object(); + private readonly object _capabilitiesSyncLock = new object(); - public DeviceManager(IDeviceRepository repo, IUserManager userManager, IFileSystem fileSystem, ILibraryMonitor libraryMonitor, IServerConfigurationManager config, ILogger logger, INetworkManager network) + public DeviceManager(IAuthenticationRepository authRepo, IJsonSerializer json, ILibraryManager libraryManager, ILocalizationManager localizationManager, IUserManager userManager, IFileSystem fileSystem, ILibraryMonitor libraryMonitor, IServerConfigurationManager config, ILogger logger, INetworkManager network) { - _repo = repo; + _json = json; _userManager = userManager; _fileSystem = fileSystem; _libraryMonitor = libraryMonitor; _config = config; _logger = logger; _network = network; + _libraryManager = libraryManager; + _localizationManager = localizationManager; + _authRepo = authRepo; } - public DeviceInfo RegisterDevice(string reportedId, string name, string appName, string appVersion, string usedByUserId) + + private Dictionary<string, ClientCapabilities> _capabilitiesCache = new Dictionary<string, ClientCapabilities>(StringComparer.OrdinalIgnoreCase); + public void SaveCapabilities(string deviceId, ClientCapabilities capabilities) { - if (string.IsNullOrWhiteSpace(reportedId)) - { - throw new ArgumentNullException("reportedId"); - } + var path = Path.Combine(GetDevicePath(deviceId), "capabilities.json"); + _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path)); - var device = GetDevice(reportedId) ?? new DeviceInfo + lock (_capabilitiesSyncLock) { - Id = reportedId - }; + _capabilitiesCache[deviceId] = capabilities; - device.ReportedName = name; - device.AppName = appName; - device.AppVersion = appVersion; + _json.SerializeToFile(capabilities, path); + } + } - if (!string.IsNullOrWhiteSpace(usedByUserId)) - { - var user = _userManager.GetUserById(usedByUserId); + public void UpdateDeviceOptions(string deviceId, DeviceOptions options) + { + _authRepo.UpdateDeviceOptions(deviceId, options); - device.LastUserId = user.Id.ToString("N"); - device.LastUserName = user.Name; + if (DeviceOptionsUpdated != null) + { + DeviceOptionsUpdated(this, new GenericEventArgs<Tuple<string, DeviceOptions>>() + { + Argument = new Tuple<string, DeviceOptions>(deviceId, options) + }); } + } - device.DateLastModified = DateTime.UtcNow; + public DeviceOptions GetDeviceOptions(string deviceId) + { + return _authRepo.GetDeviceOptions(deviceId); + } - device.Name = string.IsNullOrWhiteSpace(device.CustomName) ? device.ReportedName : device.CustomName; + public ClientCapabilities GetCapabilities(string id) + { + lock (_capabilitiesSyncLock) + { + ClientCapabilities result; + if (_capabilitiesCache.TryGetValue(id, out result)) + { + return result; + } - _repo.SaveDevice(device); + var path = Path.Combine(GetDevicePath(id), "capabilities.json"); + try + { + return _json.DeserializeFromFile<ClientCapabilities>(path) ?? new ClientCapabilities(); + } + catch + { + } + } - return device; + return new ClientCapabilities(); } - public void SaveCapabilities(string reportedId, ClientCapabilities capabilities) + public DeviceInfo GetDevice(string id) { - _repo.SaveCapabilities(reportedId, capabilities); + return GetDevice(id, true); } - public ClientCapabilities GetCapabilities(string reportedId) + private DeviceInfo GetDevice(string id, bool includeCapabilities) { - return _repo.GetCapabilities(reportedId); - } + var session = _authRepo.Get(new AuthenticationInfoQuery + { + DeviceId = id - public DeviceInfo GetDevice(string id) - { - return _repo.GetDevice(id); + }).Items.FirstOrDefault(); + + var device = session == null ? null : ToDeviceInfo(session); + + return device; } public QueryResult<DeviceInfo> GetDevices(DeviceQuery query) { - IEnumerable<DeviceInfo> devices = _repo.GetDevices(); + var sessions = _authRepo.Get(new AuthenticationInfoQuery + { + //UserId = query.UserId + HasUser = true + + }).Items; if (query.SupportsSync.HasValue) { var val = query.SupportsSync.Value; - devices = devices.Where(i => i.Capabilities.SupportsSync == val); + sessions = sessions.Where(i => GetCapabilities(i.DeviceId).SupportsSync == val).ToArray(); } - if (query.SupportsPersistentIdentifier.HasValue) + if (!query.UserId.Equals(Guid.Empty)) { - var val = query.SupportsPersistentIdentifier.Value; + var user = _userManager.GetUserById(query.UserId); - devices = devices.Where(i => - { - var deviceVal = i.Capabilities.SupportsPersistentIdentifier; - return deviceVal == val; - }); + sessions = sessions.Where(i => CanAccessDevice(user, i.DeviceId)).ToArray(); } - if (!string.IsNullOrWhiteSpace(query.UserId)) - { - devices = devices.Where(i => CanAccessDevice(query.UserId, i.Id)); - } + var array = sessions.Select(ToDeviceInfo).ToArray(); - var array = devices.ToArray(); return new QueryResult<DeviceInfo> { Items = array, @@ -133,20 +169,59 @@ namespace Emby.Server.Implementations.Devices }; } - public void DeleteDevice(string id) + 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) { - _repo.DeleteDevice(id); + return Path.Combine(GetDevicesPath(), id.GetMD5().ToString("N")); } public ContentUploadHistory GetCameraUploadHistory(string deviceId) { - return _repo.GetCameraUploadHistory(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); - var path = GetUploadPath(device); + var device = GetDevice(deviceId, false); + var uploadPathInfo = GetUploadPath(device); + + var path = uploadPathInfo.Item1; if (!string.IsNullOrWhiteSpace(file.Album)) { @@ -156,10 +231,12 @@ namespace Emby.Server.Implementations.Devices path = Path.Combine(path, file.Name); path = Path.ChangeExtension(path, MimeTypes.ToExtension(file.MimeType) ?? "jpg"); - _libraryMonitor.ReportFileSystemChangeBeginning(path); - _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)) @@ -167,7 +244,7 @@ namespace Emby.Server.Implementations.Devices await stream.CopyToAsync(fs).ConfigureAwait(false); } - _repo.AddCameraUpload(deviceId, file); + AddCameraUpload(deviceId, file); } finally { @@ -187,65 +264,118 @@ namespace Emby.Server.Implementations.Devices } } - private string GetUploadPath(DeviceInfo device) + private void AddCameraUpload(string deviceId, LocalFileInfo file) { - if (!string.IsNullOrWhiteSpace(device.CameraUploadPath)) + var path = Path.Combine(GetDevicePath(deviceId), "camerauploads.json"); + _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path)); + + lock (_cameraUploadSyncLock) { - return device.CameraUploadPath; + 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(list.Count); + + _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 path; - } - - private string DefaultCameraUploadsPath - { - get { return Path.Combine(_config.CommonApplicationPaths.DataPath, "camerauploads"); } + return new Tuple<string, string, string>(path, topLibraryPath, null); } - public void UpdateDeviceInfo(string id, DeviceOptions options) + internal string GetUploadsPath() { - var device = GetDevice(id); - - device.CustomName = options.CustomName; - device.CameraUploadPath = options.CameraUploadPath; + var config = _config.GetUploadOptions(); + var path = config.CameraUploadPath; - device.Name = string.IsNullOrWhiteSpace(device.CustomName) ? device.ReportedName : device.CustomName; + if (string.IsNullOrWhiteSpace(path)) + { + path = DefaultCameraUploadsPath; + } - _repo.SaveDevice(device); + return path; + } - EventHelper.FireEventIfNotNull(DeviceOptionsUpdated, this, new GenericEventArgs<DeviceInfo>(device), _logger); + private string DefaultCameraUploadsPath + { + get { return Path.Combine(_config.CommonApplicationPaths.DataPath, "camerauploads"); } } - public bool CanAccessDevice(string userId, string deviceId) + public bool CanAccessDevice(User user, string deviceId) { - if (string.IsNullOrWhiteSpace(userId)) + if (user == null) { - throw new ArgumentNullException("userId"); + throw new ArgumentException("user not found"); } - if (string.IsNullOrWhiteSpace(deviceId)) + if (string.IsNullOrEmpty(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); @@ -271,15 +401,89 @@ namespace Emby.Server.Implementations.Devices return true; } - return ListHelper.ContainsIgnoreCase(policy.EnabledDevices, id); + 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.ErrorException("Error creating camera uploads library", ex); + } + + _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 List<ConfigurationStore> + return new ConfigurationStore[] { new ConfigurationStore { diff --git a/Emby.Server.Implementations/Devices/SqliteDeviceRepository.cs b/Emby.Server.Implementations/Devices/SqliteDeviceRepository.cs deleted file mode 100644 index d7817b17a..000000000 --- a/Emby.Server.Implementations/Devices/SqliteDeviceRepository.cs +++ /dev/null @@ -1,451 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using Emby.Server.Implementations.Data; -using MediaBrowser.Controller; -using MediaBrowser.Model.Logging; -using SQLitePCL.pretty; -using MediaBrowser.Model.Extensions; -using MediaBrowser.Model.IO; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Controller.Devices; -using MediaBrowser.Model.Devices; -using MediaBrowser.Model.Serialization; -using MediaBrowser.Model.Session; -using MediaBrowser.Controller.Configuration; - -namespace Emby.Server.Implementations.Devices -{ - public class SqliteDeviceRepository : BaseSqliteRepository, IDeviceRepository - { - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - protected IFileSystem FileSystem { get; private set; } - private readonly object _syncLock = new object(); - private readonly IJsonSerializer _json; - private IServerApplicationPaths _appPaths; - - public SqliteDeviceRepository(ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem, IJsonSerializer json) - : base(logger) - { - var appPaths = config.ApplicationPaths; - - DbFilePath = Path.Combine(appPaths.DataPath, "devices.db"); - FileSystem = fileSystem; - _json = json; - _appPaths = appPaths; - } - - public void Initialize() - { - try - { - InitializeInternal(); - } - catch (Exception ex) - { - Logger.ErrorException("Error loading database file. Will reset and retry.", ex); - - FileSystem.DeleteFile(DbFilePath); - - InitializeInternal(); - } - } - - private void InitializeInternal() - { - using (var connection = CreateConnection()) - { - RunDefaultInitialization(connection); - - string[] queries = { - "create table if not exists Devices (Id TEXT PRIMARY KEY, Name TEXT NOT NULL, ReportedName TEXT NOT NULL, CustomName TEXT, CameraUploadPath TEXT, LastUserName TEXT, AppName TEXT NOT NULL, AppVersion TEXT NOT NULL, LastUserId TEXT, DateLastModified DATETIME NOT NULL, Capabilities TEXT NOT NULL)", - "create index if not exists idx_id on Devices(Id)" - }; - - connection.RunQueries(queries); - - MigrateDevices(); - } - } - - private void MigrateDevices() - { - List<string> files; - try - { - files = FileSystem - .GetFilePaths(GetDevicesPath(), true) - .Where(i => string.Equals(Path.GetFileName(i), "device.json", StringComparison.OrdinalIgnoreCase)) - .ToList(); - } - catch (IOException) - { - return; - } - - foreach (var file in files) - { - try - { - var device = _json.DeserializeFromFile<DeviceInfo>(file); - - device.Name = string.IsNullOrWhiteSpace(device.CustomName) ? device.ReportedName : device.CustomName; - - SaveDevice(device); - } - catch (Exception ex) - { - Logger.ErrorException("Error reading {0}", ex, file); - } - finally - { - try - { - FileSystem.DeleteFile(file); - } - catch (IOException) - { - try - { - FileSystem.MoveFile(file, Path.ChangeExtension(file, ".old")); - } - catch (IOException) - { - } - } - } - } - } - - private const string BaseSelectText = "select Id, Name, ReportedName, CustomName, CameraUploadPath, LastUserName, AppName, AppVersion, LastUserId, DateLastModified, Capabilities from Devices"; - - public void SaveCapabilities(string deviceId, ClientCapabilities capabilities) - { - using (WriteLock.Write()) - { - using (var connection = CreateConnection()) - { - connection.RunInTransaction(db => - { - using (var statement = db.PrepareStatement("update devices set Capabilities=@Capabilities where Id=@Id")) - { - statement.TryBind("@Id", deviceId); - - if (capabilities == null) - { - statement.TryBindNull("@Capabilities"); - } - else - { - statement.TryBind("@Capabilities", _json.SerializeToString(capabilities)); - } - - statement.MoveNext(); - } - }, TransactionMode); - } - } - } - - public void SaveDevice(DeviceInfo entry) - { - if (entry == null) - { - throw new ArgumentNullException("entry"); - } - - using (WriteLock.Write()) - { - using (var connection = CreateConnection()) - { - connection.RunInTransaction(db => - { - using (var statement = db.PrepareStatement("replace into Devices (Id, Name, ReportedName, CustomName, CameraUploadPath, LastUserName, AppName, AppVersion, LastUserId, DateLastModified, Capabilities) values (@Id, @Name, @ReportedName, @CustomName, @CameraUploadPath, @LastUserName, @AppName, @AppVersion, @LastUserId, @DateLastModified, @Capabilities)")) - { - statement.TryBind("@Id", entry.Id); - statement.TryBind("@Name", entry.Name); - statement.TryBind("@ReportedName", entry.ReportedName); - statement.TryBind("@CustomName", entry.CustomName); - statement.TryBind("@CameraUploadPath", entry.CameraUploadPath); - statement.TryBind("@LastUserName", entry.LastUserName); - statement.TryBind("@AppName", entry.AppName); - statement.TryBind("@AppVersion", entry.AppVersion); - statement.TryBind("@DateLastModified", entry.DateLastModified); - - if (entry.Capabilities == null) - { - statement.TryBindNull("@Capabilities"); - } - else - { - statement.TryBind("@Capabilities", _json.SerializeToString(entry.Capabilities)); - } - - statement.MoveNext(); - } - }, TransactionMode); - } - } - } - - public DeviceInfo GetDevice(string id) - { - using (WriteLock.Read()) - { - using (var connection = CreateConnection(true)) - { - var statementTexts = new List<string>(); - statementTexts.Add(BaseSelectText + " where Id=@Id"); - - return connection.RunInTransaction(db => - { - var statements = PrepareAllSafe(db, statementTexts).ToList(); - - using (var statement = statements[0]) - { - statement.TryBind("@Id", id); - - foreach (var row in statement.ExecuteQuery()) - { - return GetEntry(row); - } - } - - return null; - - }, ReadTransactionMode); - } - } - } - - public List<DeviceInfo> GetDevices() - { - using (WriteLock.Read()) - { - using (var connection = CreateConnection(true)) - { - var statementTexts = new List<string>(); - statementTexts.Add(BaseSelectText + " order by DateLastModified desc"); - - return connection.RunInTransaction(db => - { - var list = new List<DeviceInfo>(); - - var statements = PrepareAllSafe(db, statementTexts).ToList(); - - using (var statement = statements[0]) - { - foreach (var row in statement.ExecuteQuery()) - { - list.Add(GetEntry(row)); - } - } - - return list; - - }, ReadTransactionMode); - } - } - } - - public ClientCapabilities GetCapabilities(string id) - { - using (WriteLock.Read()) - { - using (var connection = CreateConnection(true)) - { - var statementTexts = new List<string>(); - statementTexts.Add("Select Capabilities from Devices where Id=@Id"); - - return connection.RunInTransaction(db => - { - var statements = PrepareAllSafe(db, statementTexts).ToList(); - - using (var statement = statements[0]) - { - statement.TryBind("@Id", id); - - foreach (var row in statement.ExecuteQuery()) - { - if (row[0].SQLiteType != SQLiteType.Null) - { - return _json.DeserializeFromString<ClientCapabilities>(row.GetString(0)); - } - } - } - - return null; - - }, ReadTransactionMode); - } - } - } - - private DeviceInfo GetEntry(IReadOnlyList<IResultSetValue> reader) - { - var index = 0; - - var info = new DeviceInfo - { - Id = reader.GetString(index) - }; - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.Name = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.ReportedName = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.CustomName = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.CameraUploadPath = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.LastUserName = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.AppName = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.AppVersion = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.LastUserId = reader.GetString(index); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.DateLastModified = reader[index].ReadDateTime(); - } - - index++; - if (reader[index].SQLiteType != SQLiteType.Null) - { - info.Capabilities = _json.DeserializeFromString<ClientCapabilities>(reader.GetString(index)); - } - - return info; - } - - private string GetDevicesPath() - { - return Path.Combine(_appPaths.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 (_syncLock) - { - try - { - return _json.DeserializeFromFile<ContentUploadHistory>(path); - } - catch (IOException) - { - return new ContentUploadHistory - { - DeviceId = deviceId - }; - } - } - } - - public void AddCameraUpload(string deviceId, LocalFileInfo file) - { - var path = Path.Combine(GetDevicePath(deviceId), "camerauploads.json"); - FileSystem.CreateDirectory(FileSystem.GetDirectoryName(path)); - - lock (_syncLock) - { - 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(list.Count); - - _json.SerializeToFile(history, path); - } - } - - public void DeleteDevice(string id) - { - using (WriteLock.Write()) - { - using (var connection = CreateConnection()) - { - connection.RunInTransaction(db => - { - using (var statement = db.PrepareStatement("delete from devices where Id=@Id")) - { - statement.TryBind("@Id", id); - - statement.MoveNext(); - } - }, TransactionMode); - } - } - - var path = GetDevicePath(id); - - lock (_syncLock) - { - try - { - FileSystem.DeleteDirectory(path, true); - } - catch (IOException) - { - } - } - } - } -} |
