static UPnPError OnScheduleImports(DvAction action, IList <object> inParams, out IList <object> outParams, CallContext context) { outParams = null; ICollection <Guid> shareIds = MarshallingHelper.ParseCsvGuidCollection((string)inParams[0]); string importJobTypeStr = (string)inParams[1]; ImportJobType importJobType; UPnPError error = ParseImportJobType("ImportJobType", importJobTypeStr, out importJobType); if (error != null) { return(error); } IDictionary <Guid, Share> allShares = MediaLibrary.GetShares(null); IDictionary <string, ICollection <Share> > importRequests = new Dictionary <string, ICollection <Share> >(); foreach (Guid shareId in shareIds) { Share importShare; if (!allShares.TryGetValue(shareId, out importShare)) { // Share not found continue; } ICollection <Share> systemShares; if (!importRequests.TryGetValue(importShare.SystemId, out systemShares)) { importRequests[importShare.SystemId] = new List <Share> { importShare } } ; else { systemShares.Add(importShare); } } // Local imports at the server ISystemResolver systemResolver = ServiceRegistration.Get <ISystemResolver>(); ICollection <Share> shares; if (importRequests.TryGetValue(systemResolver.LocalSystemId, out shares)) { IImporterWorker importerWorker = ServiceRegistration.Get <IImporterWorker>(); foreach (Share share in shares) { if (importJobType == ImportJobType.Import) { importerWorker.ScheduleImport(share.BaseResourcePath, share.MediaCategories, true); } else { importerWorker.ScheduleRefresh(share.BaseResourcePath, share.MediaCategories, true); } } } ServiceRegistration.Get <IThreadPool>().Add(() => ScheduleClientImports(importRequests, importJobType)); return(null); }
protected void ImportRecording(string fileName) { ISystemResolver systemResolver = ServiceRegistration.Get <ISystemResolver>(); IMediaLibrary mediaLibrary = ServiceRegistration.Get <IMediaLibrary>(); List <Share> possibleShares = new List <Share>(); // Shares can point to different depth, we try to find the deepest one foreach (var share in mediaLibrary.GetShares(systemResolver.LocalSystemId).Values) { var dir = LocalFsResourceProviderBase.ToDosPath(share.BaseResourcePath.LastPathSegment.Path); if (dir != null && fileName.StartsWith(dir, StringComparison.InvariantCultureIgnoreCase)) { possibleShares.Add(share); } } if (possibleShares.Count == 0) { ServiceRegistration.Get <ILogger>().Warn("SlimTvService: Received notifaction of new recording but could not find a media source. Have you added recordings folder as media source? File: {0}", fileName); return; } Share usedShare = possibleShares.OrderByDescending(s => s.BaseResourcePath.LastPathSegment.Path.Length).First(); IImporterWorker importerWorker = ServiceRegistration.Get <IImporterWorker>(); importerWorker.ScheduleImport(LocalFsResourceProviderBase.ToResourcePath(fileName), usedShare.MediaCategories, false); }
void OnBackendServerDisconnected(DeviceConnection connection) { lock (_syncObj) _isHomeServerConnected = false; IImporterWorker importerWorker = ServiceRegistration.Get<IImporterWorker>(); importerWorker.Suspend(); UpdateCurrentlyImportingShares(null); // Mark all shares as not being imported ServerConnectionMessaging.SendServerConnectionStateChangedMessage(ServerConnectionMessaging.MessageType.HomeServerDisconnected); }
public void DoImport() { ILocalSharesManagement lsm = ServiceRegistration.Get <ILocalSharesManagement>(); Share videoShare = lsm.Shares.Values.FirstOrDefault(share => share.Name.Contains("Video")); if (videoShare == null) { return; } IImporterWorker importerWorker = ServiceRegistration.Get <IImporterWorker>(); importerWorker.ScheduleImport(videoShare.BaseResourcePath, videoShare.MediaCategories, true); }
protected void ImportRecording(string fileName) { List <Share> possibleShares; // Shares can point to different depth, we try to find the deepest one if (!GetSharesForPath(fileName, out possibleShares)) { ServiceRegistration.Get <ILogger>().Warn("SlimTvService: Received notifaction of new recording but could not find a media source. Have you added recordings folder as media source? File: {0}", fileName); return; } Share usedShare = possibleShares.OrderByDescending(s => s.BaseResourcePath.LastPathSegment.Path.Length).First(); IImporterWorker importerWorker = ServiceRegistration.Get <IImporterWorker>(); importerWorker.ScheduleRefresh(usedShare.BaseResourcePath, usedShare.MediaCategories, true); }
public void DetachFromHomeServer() { ISettingsManager settingsManager = ServiceRegistration.Get<ISettingsManager>(); ServerConnectionSettings settings = settingsManager.Load<ServerConnectionSettings>(); ServiceRegistration.Get<ILogger>().Info("ServerConnectionManager: Detaching from home server '{0}'", settings.HomeServerSystemId); ServiceRegistration.Get<ILogger>().Debug("ServerConnectionManager: Clearing pending import jobs and suspending importer worker"); IImporterWorker importerWorker = ServiceRegistration.Get<IImporterWorker>(); importerWorker.Suspend(); importerWorker.CancelPendingJobs(); ServiceRegistration.Get<ILogger>().Debug("ServerConnectionManager: Notifying the MediaPortal server about the detachment"); UPnPServerControllerServiceProxy sc = ServerControllerServiceProxy; ISystemResolver systemResolver = ServiceRegistration.Get<ISystemResolver>(); if (sc != null) try { sc.DetachClient(systemResolver.LocalSystemId); sc.AttachedClientsChanged -= OnAttachedClientsChanged; sc.ConnectedClientsChanged -= OnConnectedClientsChanged; } catch (Exception e) { ServiceRegistration.Get<ILogger>().Warn("ServerConnectionManager: Error detaching from home server '{0}'", e, HomeServerSystemId); } UPnPContentDirectoryServiceProxy cd = ContentDirectoryServiceProxy; if (cd != null) try { cd.PlaylistsChanged -= OnContentDirectoryPlaylistsChanged; cd.MIATypeRegistrationsChanged -= OnContentDirectoryMIATypeRegistrationsChanged; cd.RegisteredSharesChangeCounterChanged -= OnRegisteredSharesChangeCounterChanged; } catch (Exception e) { ServiceRegistration.Get<ILogger>().Warn("ServerConnectionManager: Error unregistering from state variable change events", e); } ServiceRegistration.Get<ILogger>().Debug("ServerConnectionManager: Closing server connection"); UPnPClientControlPoint cp; lock (_syncObj) cp = _controlPoint; if (cp != null) cp.Stop(); // Must be outside the lock - sends messages lock (_syncObj) { settings.HomeServerSystemId = null; settings.LastHomeServerName = null; settings.LastHomeServerSystem = null; settingsManager.Save(settings); _controlPoint = null; } UpdateCurrentlyImportingShares(null); // Mark all shares as not being imported ServerConnectionMessaging.SendServerConnectionStateChangedMessage(ServerConnectionMessaging.MessageType.HomeServerDetached); ServiceRegistration.Get<ILogger>().Debug("ServerConnectionManager: Starting to watch for MediaPortal servers"); if (_serverWatcher == null) { lock (_syncObj) _serverWatcher = BuildServerWatcher(); _serverWatcher.Start(); // Outside the lock } }
/// <summary> /// Synchronously synchronizes all local shares and media item aspect types with the MediaPortal server. /// </summary> protected async Task CompleteServerConnectionAsync() { UPnPServerControllerServiceProxy sc = ServerControllerServiceProxy; ISystemResolver systemResolver = ServiceRegistration.Get<ISystemResolver>(); if (sc != null) { try { // Check if we're attached to the server. If the server lost its state, it might have forgotten us. if (!sc.GetAttachedClients().Select(clientMetadata => clientMetadata.SystemId).Contains(systemResolver.LocalSystemId)) sc.AttachClient(systemResolver.LocalSystemId); } catch (Exception e) { ServiceRegistration.Get<ILogger>().Warn("ServerConnectionManager: Error checking attachment state at home server '{0}'", e, HomeServerSystemId); return; // This is a real error case, we don't need to try any other service calls } // Register state variables change events sc.AttachedClientsChanged += OnAttachedClientsChanged; sc.ConnectedClientsChanged += OnConnectedClientsChanged; } IImporterWorker importerWorker = ServiceRegistration.Get<IImporterWorker>(); ICollection<Share> newShares = new List<Share>(); UPnPContentDirectoryServiceProxy cd = ContentDirectoryServiceProxy; if (cd != null) { // Update shares registration try { ISettingsManager settingsManager = ServiceRegistration.Get<ISettingsManager>(); ServerConnectionSettings settings = settingsManager.Load<ServerConnectionSettings>(); ServiceRegistration.Get<ILogger>().Info("ServerConnectionManager: Synchronizing shares with home server"); IDictionary<Guid, Share> serverShares = new Dictionary<Guid, Share>(); foreach (Share share in await cd.GetSharesAsync(systemResolver.LocalSystemId, SharesFilter.All)) serverShares.Add(share.ShareId, share); IDictionary<Guid, Share> localShares = ServiceRegistration.Get<ILocalSharesManagement>().Shares; // First remove shares - if the client lost its configuration and re-registers an already present share, the server's method will throw an exception foreach (Guid serverShareId in serverShares.Keys) if (!localShares.ContainsKey(serverShareId)) await cd.RemoveShareAsync(serverShareId); foreach (Share localShare in localShares.Values) { RelocationMode relocationMode; if (!serverShares.ContainsKey(localShare.ShareId)) { await cd.RegisterShareAsync(localShare); newShares.Add(localShare); } else if (settings.CachedSharesUpdates.TryGetValue(localShare.ShareId, out relocationMode)) { await cd.UpdateShareAsync(localShare.ShareId, localShare.BaseResourcePath, localShare.Name, localShare.UseShareWatcher, localShare.MediaCategories, relocationMode); switch (relocationMode) { case RelocationMode.ClearAndReImport: importerWorker.ScheduleImport(localShare.BaseResourcePath, localShare.MediaCategories, true); break; case RelocationMode.Relocate: importerWorker.ScheduleRefresh(localShare.BaseResourcePath, localShare.MediaCategories, true); break; } } } settings.CachedSharesUpdates.Clear(); settingsManager.Save(settings); } catch (Exception e) { ServiceRegistration.Get<ILogger>().Warn("ServerConnectionManager: Could not synchronize local shares with server", e); } // Update media item aspect type registration try { IMediaItemAspectTypeRegistration miatr = ServiceRegistration.Get<IMediaItemAspectTypeRegistration>(); ServiceRegistration.Get<ILogger>().Info("ServerConnectionManager: Checking for unregistered media item aspect types at home server"); ICollection<Guid> serverMIATypes = await cd.GetAllManagedMediaItemAspectTypesAsync(); foreach (KeyValuePair<Guid, MediaItemAspectMetadata> localMiaType in miatr.LocallyKnownMediaItemAspectTypes) if (!serverMIATypes.Contains(localMiaType.Key)) { ServiceRegistration.Get<ILogger>().Info("ServerConnectionManager: Adding unregistered media item aspect type '{0}' (ID '{1}') at home server", localMiaType.Value.Name, localMiaType.Key); await cd.AddMediaItemAspectStorageAsync(localMiaType.Value); } } catch (Exception e) { ServiceRegistration.Get<ILogger>().Warn("ServerConnectionManager: Could not synchronize local media item aspect types with server", e); } // Register state variables change events cd.PlaylistsChanged += OnContentDirectoryPlaylistsChanged; cd.MIATypeRegistrationsChanged += OnContentDirectoryMIATypeRegistrationsChanged; cd.RegisteredSharesChangeCounterChanged += OnRegisteredSharesChangeCounterChanged; // Activate importer worker ServiceRegistration.Get<ILogger>().Debug("ServerConnectionManager: Activating importer worker"); ImporterCallback ic = new ImporterCallback(cd); importerWorker.Activate(ic, ic); foreach (Share share in newShares) importerWorker.ScheduleImport(share.BaseResourcePath, share.MediaCategories, true); } }
void OnMessageReceived(AsynchronousMessageQueue queue, SystemMessage message) { if (message.ChannelName == SharesMessaging.CHANNEL) { IContentDirectory cd = ContentDirectory; SharesMessaging.MessageType messageType = (SharesMessaging.MessageType) message.MessageType; IImporterWorker importerWorker = ServiceRegistration.Get<IImporterWorker>(); Share share; switch (messageType) { case SharesMessaging.MessageType.ShareAdded: share = (Share) message.MessageData[SharesMessaging.SHARE]; if (cd != null) cd.RegisterShareAsync(share); importerWorker.ScheduleImport(share.BaseResourcePath, share.MediaCategories, true); break; case SharesMessaging.MessageType.ShareRemoved: share = (Share) message.MessageData[SharesMessaging.SHARE]; importerWorker.CancelJobsForPath(share.BaseResourcePath); if (cd != null) cd.RemoveShareAsync(share.ShareId); break; case SharesMessaging.MessageType.ShareChanged: RelocationMode relocationMode = (RelocationMode) message.MessageData[SharesMessaging.RELOCATION_MODE]; share = (Share) message.MessageData[SharesMessaging.SHARE]; importerWorker.CancelJobsForPath(share.BaseResourcePath); if (cd == null) { ISettingsManager settingsManager = ServiceRegistration.Get<ISettingsManager>(); ServerConnectionSettings settings = settingsManager.Load<ServerConnectionSettings>(); RelocationMode oldMode; if (settings.CachedSharesUpdates.TryGetValue(share.ShareId, out oldMode) && oldMode == RelocationMode.ClearAndReImport) // ClearAndReimport is stronger than Relocate, use ClearAndReImport relocationMode = oldMode; settings.CachedSharesUpdates[share.ShareId] = relocationMode; settingsManager.Save(settings); } else { cd.UpdateShareAsync(share.ShareId, share.BaseResourcePath, share.Name, share.UseShareWatcher, share.MediaCategories, relocationMode); switch (relocationMode) { case RelocationMode.ClearAndReImport: importerWorker.ScheduleImport(share.BaseResourcePath, share.MediaCategories, true); break; case RelocationMode.Relocate: importerWorker.ScheduleRefresh(share.BaseResourcePath, share.MediaCategories, true); break; } } break; case SharesMessaging.MessageType.ReImportShare: share = (Share) message.MessageData[SharesMessaging.SHARE]; importerWorker.ScheduleRefresh(share.BaseResourcePath, share.MediaCategories, true); break; } } else if (message.ChannelName == ImporterWorkerMessaging.CHANNEL) { IContentDirectory cd = ContentDirectory; ImporterWorkerMessaging.MessageType messageType = (ImporterWorkerMessaging.MessageType) message.MessageType; switch (messageType) { case ImporterWorkerMessaging.MessageType.ImportStarted: case ImporterWorkerMessaging.MessageType.ImportCompleted: if (cd == null) break; ResourcePath path = (ResourcePath) message.MessageData[ImporterWorkerMessaging.RESOURCE_PATH]; ILocalSharesManagement lsm = ServiceRegistration.Get<ILocalSharesManagement>(); ICollection<Share> shares = lsm.Shares.Values; Share share = shares.BestContainingPath(path); if (share == null) break; if (messageType == ImporterWorkerMessaging.MessageType.ImportStarted) cd.ClientStartedShareImportAsync(share.ShareId); else cd.ClientCompletedShareImportAsync(share.ShareId); break; } } else if (message.ChannelName == ServerStateMessaging.CHANNEL) { //Check if Tv Server state has changed and update if necessary ServerStateMessaging.MessageType messageType = (ServerStateMessaging.MessageType)message.MessageType; if (messageType == ServerStateMessaging.MessageType.StatesChanged) { var states = message.MessageData[ServerStateMessaging.STATES] as IDictionary<Guid, object>; if (states != null && states.ContainsKey(ShareImportServerState.STATE_ID)) { ShareImportServerState importState = states[ShareImportServerState.STATE_ID] as ShareImportServerState; if (importState != null) { List<ShareImportState> shareStates = new List<ShareImportState>(importState.Shares); lock (_syncObj) { UpdateCurrentlyImportingShares(shareStates.Where(s => s.IsImporting).Select(s => s.ShareId).ToList()); UpdateCurrentlyImportingSharesProgresses(shareStates.Where(s => s.IsImporting).ToDictionary(s => s.ShareId, s => s.Progress)); } } } else if (states != null && states.ContainsKey(DatabaseUpgradeServerState.STATE_ID)) { DatabaseUpgradeServerState upgradeState = states[DatabaseUpgradeServerState.STATE_ID] as DatabaseUpgradeServerState; if (upgradeState != null && !upgradeState.IsUpgrading && upgradeState.Progress == 100) { ServerConnectionMessaging.SendServerConnectionStateChangedMessage(ServerConnectionMessaging.MessageType.HomeServerDisconnected); ServerConnectionMessaging.SendServerConnectionStateChangedMessage(ServerConnectionMessaging.MessageType.HomeServerConnected); } } } } }
void OnMessageReceived(AsynchronousMessageQueue queue, SystemMessage message) { if (message.ChannelName == SharesMessaging.CHANNEL) { IContentDirectory cd = ContentDirectory; SharesMessaging.MessageType messageType = (SharesMessaging.MessageType)message.MessageType; IImporterWorker importerWorker = ServiceRegistration.Get <IImporterWorker>(); Share share; switch (messageType) { case SharesMessaging.MessageType.ShareAdded: share = (Share)message.MessageData[SharesMessaging.SHARE]; if (cd != null) { cd.RegisterShare(share); } importerWorker.ScheduleImport(share.BaseResourcePath, share.MediaCategories, true); break; case SharesMessaging.MessageType.ShareRemoved: share = (Share)message.MessageData[SharesMessaging.SHARE]; importerWorker.CancelJobsForPath(share.BaseResourcePath); if (cd != null) { cd.RemoveShare(share.ShareId); } break; case SharesMessaging.MessageType.ShareChanged: RelocationMode relocationMode = (RelocationMode)message.MessageData[SharesMessaging.RELOCATION_MODE]; share = (Share)message.MessageData[SharesMessaging.SHARE]; importerWorker.CancelJobsForPath(share.BaseResourcePath); if (cd == null) { ISettingsManager settingsManager = ServiceRegistration.Get <ISettingsManager>(); ServerConnectionSettings settings = settingsManager.Load <ServerConnectionSettings>(); RelocationMode oldMode; if (settings.CachedSharesUpdates.TryGetValue(share.ShareId, out oldMode) && oldMode == RelocationMode.ClearAndReImport) { // ClearAndReimport is stronger than Relocate, use ClearAndReImport relocationMode = oldMode; } settings.CachedSharesUpdates[share.ShareId] = relocationMode; settingsManager.Save(settings); } else { cd.UpdateShare(share.ShareId, share.BaseResourcePath, share.Name, share.MediaCategories, relocationMode); switch (relocationMode) { case RelocationMode.ClearAndReImport: importerWorker.ScheduleImport(share.BaseResourcePath, share.MediaCategories, true); break; case RelocationMode.Relocate: importerWorker.ScheduleRefresh(share.BaseResourcePath, share.MediaCategories, true); break; } } break; case SharesMessaging.MessageType.ReImportShare: share = (Share)message.MessageData[SharesMessaging.SHARE]; importerWorker.ScheduleRefresh(share.BaseResourcePath, share.MediaCategories, true); break; } } else if (message.ChannelName == ImporterWorkerMessaging.CHANNEL) { IContentDirectory cd = ContentDirectory; ImporterWorkerMessaging.MessageType messageType = (ImporterWorkerMessaging.MessageType)message.MessageType; switch (messageType) { case ImporterWorkerMessaging.MessageType.ImportStarted: case ImporterWorkerMessaging.MessageType.ImportCompleted: if (cd == null) { break; } ResourcePath path = (ResourcePath)message.MessageData[ImporterWorkerMessaging.RESOURCE_PATH]; ILocalSharesManagement lsm = ServiceRegistration.Get <ILocalSharesManagement>(); ICollection <Share> shares = lsm.Shares.Values; Share share = shares.BestContainingPath(path); if (share == null) { break; } if (messageType == ImporterWorkerMessaging.MessageType.ImportStarted) { cd.ClientStartedShareImport(share.ShareId); } else { cd.ClientCompletedShareImport(share.ShareId); } break; } } }