Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
 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);
 }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 6
0
    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
      }
    }
Exemplo n.º 7
0
    /// <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);
      }
    }
Exemplo n.º 8
0
 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;
                }
            }
        }