/// <summary>
    /// This method is called directly from the Config dialog and should use all settings,
    /// which may have changed in the Config GUI
    /// </summary>
    /// <param name="shares"></param>
    /// <param name="setting"></param>
    /// <returns></returns>
    public int MusicDatabaseReorg(ArrayList shares, MusicDatabaseSettings setting)
    {
      // Get the values from the Setting Object, which we received from the Config
      using (Settings xmlreader = new MPSettings())
      {
        _updateSinceLastImport = xmlreader.GetValueAsBool("musicfiles", "updateSinceLastImport", false);
        _excludeHiddenFiles = xmlreader.GetValueAsBool("musicfiles", "excludeHiddenFiles", false);
      }
      if (setting != null)
      {
        _createMissingFolderThumbs = setting.CreateMissingFolderThumb;
        _extractEmbededCoverArt = setting.ExtractEmbeddedCoverArt;
        _stripArtistPrefixes = setting.StripArtistPrefixes;
        _treatFolderAsAlbum = setting.TreatFolderAsAlbum;
        _useFolderThumbs = setting.UseFolderThumbs;
        _useAllImages = setting.UseAllImages;
        _createArtistPreviews = setting.CreateArtistPreviews;
        _createGenrePreviews = setting.CreateGenrePreviews;
        _updateSinceLastImport = setting.UseLastImportDate;
        _dateAddedValue = setting.DateAddedValue;
        //_excludeHiddenFiles = setting.ExcludeHiddenFiles; <-- no GUI setting yet; use xml file to specify this
      }

      if (!_updateSinceLastImport && !_singleFolderScan)
      {
        _lastImport = DateTime.MinValue;
      }

      if (shares == null)
      {
        LoadShares();
      }
      else
      {
        _shares = (ArrayList)shares.Clone();
      }
      DatabaseReorgEventArgs MyArgs = new DatabaseReorgEventArgs();

      DateTime startTime = DateTime.UtcNow;

      try
      {
        if (_singleFolderScan)
        {
          Log.Info("Musicdatabasereorg: Importing Music for folder: {0}", _shares[0].ToString());
        }
        else
        {
          Log.Info("Musicdatabasereorg: Beginning music database reorganization...");
          Log.Info("Musicdatabasereorg: Last import done at {0}", _lastImport.ToString());
        }

        BeginTransaction();

        // When starting a complete rescan, we cleanup the foreign keys
        if (_lastImport == DateTime.MinValue && !_singleFolderScan)
        {
          MyArgs.progress = 2;
          MyArgs.phase = "Cleaning up Artists, AlbumArtists and Genres";
          OnDatabaseReorgChanged(MyArgs);
          Log.Info("Musicdatabasereorg: Cleaning up Artists, AlbumArtists and Genres");
          CleanupForeignKeys();
        }

        // Add missing files (example: You downloaded some new files)
        MyArgs.progress = 3;
        MyArgs.phase = "Scanning new files";
        OnDatabaseReorgChanged(MyArgs);
        Log.Info("Musicdatabasereorg: Scanning for music files");

        // Start the Scanning and Update Thread
        musicFolders = new List<string>(4000);
        cueFiles = new List<string>(500);
        allFiles = new Hashtable(100000);

        _resetEvent = new AutoResetEvent(false);
        _scanThread = new Thread(AddUpdateFiles);
        _scanThread.Start();

        // Wait for the Scan and Update Thread to finish, before continuing
        _resetEvent.WaitOne();

        Log.Info("Musicdatabasereorg: Total Songs: {0}. {1} added / {2} updated / {3} skipped", _processCount,
                 _songsAdded, _songsUpdated, _songsSkipped);

        DateTime stopTime = DateTime.UtcNow;
        TimeSpan ts = stopTime - startTime;
        float fSecsPerTrack = ((float)ts.TotalSeconds / (float)_processCount);
        string trackPerSecSummary = "";

        if (_processCount > 0)
        {
          trackPerSecSummary = string.Format(" ({0} seconds per track)", fSecsPerTrack);
        }

        Log.Info(
          "Musicdatabasereorg: Processed {0} tracks in: {1:d2}:{2:d2}:{3:d2}{4}", _processCount, ts.Hours, ts.Minutes,
          ts.Seconds, trackPerSecSummary);


        if (!_singleFolderScan)
        {
          // Delete files that don't exist anymore (example: you deleted files from the Windows Explorer)
          Log.Info("Musicdatabasereorg: Removing non existing songs from the database");
          MyArgs.progress = 80;
          MyArgs.phase = "Removing non existing songs";
          OnDatabaseReorgChanged(MyArgs);
          DeleteNonExistingSongs();
        }

        if (_useFolderThumbs)
        {
          Log.Info("Musicdatabasereorg: Create Folder Thumbs");
          CreateFolderThumbs(85, 90, _shares);
        }

        if (_createArtistPreviews)
        {
          Log.Info("Musicdatabasereorg: Create Artist Thumbs");
          CreateArtistThumbs(90, 92);
        }

        if (_createGenrePreviews)
        {
          Log.Info("Musicdatabasereorg: Create Genre Thumbs");
          CreateGenreThumbs(93, 94);
        }

        if (_createMissingFolderThumbs)
        {
          // implement sth like that:
          // Util.Picture.CreateThumbnail(aThumbLocation, folderThumb, (int)Thumbs.ThumbLargeResolution, (int)Thumbs.ThumbLargeResolution, 0, Thumbs.SpeedThumbsLarge);
        }

        if (!_singleFolderScan)
        {
          MyArgs.progress = 95;
          MyArgs.phase = "Cleanup non-existing Artists, AlbumArtists and Genres";
          CleanupMultipleEntryTables();
        }
      }
      catch (Exception ex)
      {
        Log.Error("Musicdatabasereorg: Unhandled error {0} - scan aborted!\n{1}\n{2}", ex.Message, ex.Source,
                  ex.StackTrace);

        RollbackTransaction();
        _singleFolderScan = false;
        return (int)Errors.ERROR_CANCEL;
      }
      finally
      {
        MyArgs.progress = 96;
        MyArgs.phase = "Finishing";
        OnDatabaseReorgChanged(MyArgs);
        CommitTransaction();

        MyArgs.progress = 98;
        MyArgs.phase = "Compressing the database";
        OnDatabaseReorgChanged(MyArgs);
        Compress();

        MyArgs.progress = 100;
        MyArgs.phase = string.Format("Rescan completed. Total {0} Added {1} / Updated {2} / Skipped {3}", _processCount,
                                     _songsAdded, _songsUpdated, _songsSkipped);
        OnDatabaseReorgChanged(MyArgs);

        Log.Info("Musicdatabasereorg: Finished Reorganisation of the Database");

        // Save the time of the reorg, to be able to skip the files not updated / added the next time
        if (!_singleFolderScan)
        {
          using (Settings xmlreader = new MPSettings())
          {
            xmlreader.SetValue("musicfiles", "lastImport",
                               startTime.ToString("yyyy-M-d H:m:s", CultureInfo.InvariantCulture));
          }
        }

        GC.Collect();
      }
      _singleFolderScan = false;
      return (int)Errors.ERROR_OK;
    }
Beispiel #2
0
    /// <summary>
    /// Thread to scan the Shares
    /// </summary>
    private void FolderScanThread()
    {
      _scanRunning = true;
      ArrayList shares = new ArrayList();
      for (int index = 0; index < sharesListBox.CheckedIndices.Count; index++)
      {
        string path = sharesListBox.Items[(int)sharesListBox.CheckedIndices[index]].ToString();
        if (Directory.Exists(path))
        {
          try
          {
            string driveName = path.Substring(0, 1);
            if (path.StartsWith(@"\\"))
            {
              // we have the path in unc notation
              driveName = path;
            }

            ulong FreeBytesAvailable = Util.Utils.GetFreeDiskSpace(driveName);

            if (FreeBytesAvailable > 0)
            {
              ulong DiskSpace = FreeBytesAvailable / 1048576;
              if (DiskSpace > 100) // > 100MB left for creation of thumbs, etc
              {
                Log.Info("MusicDatabase: adding share {0} for scanning - available disk space: {1} MB", path,
                         DiskSpace.ToString());
                shares.Add(path);
              }
              else
              {
                Log.Warn("MusicDatabase: NOT scanning share {0} because of low disk space: {1} MB", path,
                         DiskSpace.ToString());
              }
            }
          }
          catch (Exception)
          {
            // Drive not ready, etc
          }
        }
      }
      MediaPortal.Music.Database.MusicDatabase.DatabaseReorgChanged +=
        new MusicDBReorgEventHandler(SetStatus);
      groupBox1.Enabled = false;
      groupBox2.Enabled = true;
      // Now create a Settings Object with the Settings checked to pass to the Import
      MusicDatabaseSettings setting = new MusicDatabaseSettings();
      setting.CreateMissingFolderThumb = checkBoxCreateFolderThumb.Checked;
      setting.ExtractEmbeddedCoverArt = buildThumbsCheckBox.Checked;
      setting.StripArtistPrefixes = checkBoxStripArtistPrefix.Checked;
      setting.TreatFolderAsAlbum = folderAsAlbumCheckBox.Checked;
      setting.UseFolderThumbs = checkBoxUseFolderThumb.Checked;
      setting.UseAllImages = checkBoxAllImages.Checked;
      setting.CreateArtistPreviews = checkBoxCreateArtist.Checked;
      setting.CreateGenrePreviews = checkBoxCreateGenre.Checked;
      setting.UseLastImportDate = checkBoxUpdateSinceLastImport.Checked;
      setting.ExcludeHiddenFiles = false;
      setting.DateAddedValue = comboBoxDateAdded.SelectedIndex;

      try
      {
        m_dbs.MusicDatabaseReorg(shares, setting);
      }
      catch (Exception ex)
      {
        Log.Error("Folder Scan: Exception during processing: ", ex.Message);
        _scanRunning = false;
      }

      using (Settings xmlreader = new MPSettings())
      {
        checkBoxUpdateSinceLastImport.Text = String.Format("Only update new / changed files after {0}",
                                                           xmlreader.GetValueAsString("musicfiles", "lastImport",
                                                                                      "1900-01-01 00:00:00"));
      }

      _scanRunning = false;
      groupBox1.Enabled = true;
      groupBox2.Enabled = false;
    }
    private void startButton_Click(object sender, EventArgs e)
    {
      groupBox1.Enabled = false;
      groupBox2.Enabled = true;
      // Now create a Settings Object with the Settings checked to pass to the Import
      MusicDatabaseSettings setting = new MusicDatabaseSettings
      {
        CreateMissingFolderThumb = checkBoxCreateFolderThumb.Checked,
        ExtractEmbeddedCoverArt = buildThumbsCheckBox.Checked,
        StripArtistPrefixes = checkBoxStripArtistPrefix.Checked,
        TreatFolderAsAlbum = folderAsAlbumCheckBox.Checked,
        UseFolderThumbs = checkBoxUseFolderThumb.Checked,
        UseAllImages = checkBoxAllImages.Checked,
        CreateArtistPreviews = checkBoxCreateArtist.Checked,
        CreateGenrePreviews = checkBoxCreateGenre.Checked,
        UseLastImportDate = checkBoxUpdateSinceLastImport.Checked,
        ExcludeHiddenFiles = false,
        DateAddedValue = comboBoxDateAdded.SelectedIndex
      };

      ArrayList shares = new ArrayList();
      for (int index = 0; index < sharesListBox.CheckedIndices.Count; index++)
      {
        string path = sharesListBox.Items[(int)sharesListBox.CheckedIndices[index]].ToString();
        if (Directory.Exists(path))
        {
          try
          {
            string driveName = path.Substring(0, 1);
            if (path.StartsWith(@"\\"))
            {
              // we have the path in unc notation
              driveName = path;
            }

            ulong freeBytesAvailable = Util.Utils.GetFreeDiskSpace(driveName);

            if (freeBytesAvailable > 0)
            {
              ulong diskSpace = freeBytesAvailable / 1048576;
              if (diskSpace > 100) // > 100MB left for creation of thumbs, etc
              {
                Log.Info("MusicDatabase: adding share {0} for scanning - available disk space: {1} MB", path,
                         diskSpace.ToString());
                shares.Add(path);
              }
              else
              {
                Log.Warn("MusicDatabase: NOT scanning share {0} because of low disk space: {1} MB", path,
                         diskSpace.ToString());
              }
            }
          }
          catch (Exception)
          {
            // Drive not ready, etc
          }
        }
      }

      _scanThread = new BackgroundWorker();
      _scanThread.WorkerReportsProgress = true;
      _scanThread.DoWork += FolderScan;
      _scanThread.RunWorkerCompleted += FolderScanCompleted;
      _scanThread.ProgressChanged += FolderScanProgress;
      _scanThread.RunWorkerAsync(new object[] { shares, setting });
    }
    private void FolderScanThread()
    {
      _scanRunning = true;
      ArrayList shares = new ArrayList();
      ArrayList scanShares = new ArrayList();
      
      foreach (GUIListItem item in lcFolders.ListItems)
      {
        if (item.IsPlayed)
        {
          scanShares.Add(item);
        }
      }

      for (int index = 0; index < _scanShare; index++)
      {
        GUIListItem item = (GUIListItem)scanShares[index];
        string path = item.Path;
        if (Directory.Exists(path))
        {
          try
          {
            string driveName = path.Substring(0, 1);
            if (path.StartsWith(@"\\"))
            {
              // we have the path in unc notation
              driveName = path;
            }

            ulong freeBytesAvailable = Util.Utils.GetFreeDiskSpace(driveName);

            if (freeBytesAvailable > 0)
            {
              ulong diskSpace = freeBytesAvailable / 1048576;
              if (diskSpace > 100) // > 100MB left for creation of thumbs, etc
              {
                Log.Info("MusicDatabase: adding share {0} for scanning - available disk space: {1} MB", path,
                         diskSpace.ToString());
                shares.Add(path);
              }
              else
              {
                Log.Warn("MusicDatabase: NOT scanning share {0} because of low disk space: {1} MB", path,
                         diskSpace.ToString());
              }
            }
          }
          catch (Exception)
          {
            // Drive not ready, etc
          }
        }
      }
      MusicDatabase.DatabaseReorgChanged += new MusicDBReorgEventHandler(SetStatus);
      EnableControls(false);
      // Now create a Settings Object with the Settings checked to pass to the Import
      MusicDatabaseSettings setting = new MusicDatabaseSettings();
      setting.CreateMissingFolderThumb = btnCreateMissingFolderThumbs.Selected;
      setting.ExtractEmbeddedCoverArt = btnUseAllImages.Selected;
      setting.StripArtistPrefixes = btnStripartistprefixes.Selected;
      setting.TreatFolderAsAlbum = btnTreatFolderAsAlbum.Selected;
      setting.UseFolderThumbs = btnUseFolderThumbs.Selected;
      setting.UseAllImages = btnUseAllImages.Selected;
      setting.CreateArtistPreviews = btnCreateartistthumbs.Selected;
      setting.CreateGenrePreviews = btnCreategenrethumbs.Selected;
      setting.UseLastImportDate = btnUpdateSinceLastImport.Selected;
      setting.ExcludeHiddenFiles = false;
      setting.DateAddedValue = _dateAddedSelectedIndex;

      try
      {
        m_dbs.MusicDatabaseReorg(shares, setting);
      }
      catch (Exception ex)
      {
        Log.Error("Folder Scan: Exception during processing: ", ex.Message);
        _scanRunning = false;
      }

      using (Profile.Settings xmlreader = new Profile.MPSettings())
      {
        _updateSinceLastImport = String.Format("Only update files after {0}",
                                                           xmlreader.GetValueAsString("musicfiles", "lastImport",
                                                                                      "1900-01-01 00:00:00"));
      }

      _scanRunning = false;
      EnableControls(true);
      SetProperties();

      GUIDialogNotify dlgNotify =
        (GUIDialogNotify)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_NOTIFY);
      if (null != dlgNotify)
      {
        dlgNotify.SetHeading(GUILocalizeStrings.Get(1020)); // Information
        dlgNotify.SetText(GUILocalizeStrings.Get(300024)); // Scan finished
        dlgNotify.DoModal(GetID);
      }
    }
    private void FolderScanThread()
    {
      ArrayList shares = new ArrayList();
      ArrayList scanShares = new ArrayList();
      
      foreach (GUIListItem item in lcFolders.ListItems)
      {
        if (item.IsPlayed)
        {
          scanShares.Add(item);
        }
      }

      for (int index = 0; index < _scanShare; index++)
      {
        GUIListItem item = (GUIListItem)scanShares[index];
        string path = item.Path;
        if (Directory.Exists(path))
        {
          try
          {
            string driveName = path.Substring(0, 1);
            if (path.StartsWith(@"\\"))
            {
              // we have the path in unc notation
              driveName = path;
            }

            ulong freeBytesAvailable = Util.Utils.GetFreeDiskSpace(driveName);

            if (freeBytesAvailable > 0)
            {
              ulong diskSpace = freeBytesAvailable / 1048576;
              if (diskSpace > 100) // > 100MB left for creation of thumbs, etc
              {
                Log.Info("MusicDatabase: adding share {0} for scanning - available disk space: {1} MB", path,
                         diskSpace.ToString());
                shares.Add(path);
              }
              else
              {
                Log.Warn("MusicDatabase: NOT scanning share {0} because of low disk space: {1} MB", path,
                         diskSpace.ToString());
              }
            }
          }
          catch (Exception)
          {
            // Drive not ready, etc
          }
        }
      }
      MusicDatabase.DatabaseReorgChanged += new MusicDBReorgEventHandler(SetStatus);
      EnableControls(false);
      // Now create a Settings Object with the Settings checked to pass to the Import
      MusicDatabaseSettings setting = new MusicDatabaseSettings();
      setting.CreateMissingFolderThumb = btnCreateMissingFolderThumbs.Selected;
      setting.ExtractEmbeddedCoverArt = btnExtractthumbs.Selected;
      setting.StripArtistPrefixes = btnStripartistprefixes.Selected;
      setting.TreatFolderAsAlbum = btnTreatFolderAsAlbum.Selected;
      setting.UseFolderThumbs = btnUseFolderThumbs.Selected;
      setting.UseAllImages = btnUseAllImages.Selected;
      setting.CreateArtistPreviews = btnCreateartistthumbs.Selected;
      setting.CreateGenrePreviews = btnCreategenrethumbs.Selected;
      setting.UseLastImportDate = btnUpdateSinceLastImport.Selected;
      setting.ExcludeHiddenFiles = false;
      setting.DateAddedValue = _dateAddedSelectedIndex;

      try
      {
        m_dbs.MusicDatabaseReorg(shares, setting);
      }
      catch (Exception ex)
      {
        Log.Error("Folder Scan: Exception during processing: ", ex.Message);
      }

      using (Profile.Settings xmlreader = new Profile.MPSettings())
      {
        _updateSinceLastImport = String.Format(GUILocalizeStrings.Get(300232),
                                                           xmlreader.GetValueAsString("musicfiles", "lastImport",
                                                                                      "1900-01-01 00:00:00"));
      }

      EnableControls(true);
      SetProperties();

      // We can't send the message from here as this will result to run the dislog in a wrong thread
      GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_DATABASE_SCAN_ENDED, 0, 0, 0, 0, 0, null);
      GUIWindowManager.SendThreadMessage(msg);
    }