private void RebuildFromFolder(SubscriptionInfo subscriptionInfo, string folderPath, bool restricted, int startPercent = 0, int endPercent = 100) { if (folderPath == null) { throw new ArgumentNullException(nameof(folderPath)); } using (IDbConnection db = _dbConnectionFactory.Open()) { DirectoryInfoBase directoryInfo = _fileSystem.DirectoryInfo.FromDirectoryName(folderPath); FileInfoBase[] files = directoryInfo.GetFiles("*.mp3", SearchOption.AllDirectories); int index = 0; foreach (IGrouping <string, FileInfoBase> albumFiles in files.GroupBy(f => f.DirectoryName)) { using (IDbTransaction transaction = db.OpenTransaction()) { _logger.Debug("Fetching album"); DbAlbum album = db.Single <DbAlbum>(a => a.Path == albumFiles.Key); foreach (FileInfoBase file in albumFiles) { int progress = (int)Math.Round((index + 1) / (double)files.Length * (endPercent - startPercent)) + startPercent; PublishProgress(subscriptionInfo, progress); _logger.DebugFormat("Processing file {0}", file.FullName); DbRecording recording; bool saveTagFile = false; _logger.Debug("Reading tag file"); using (File tagFile = File.Create(_fileAbstractionFactory(file.FullName, true))) { string recordingId = tagFile.GetCustomField(SoundWordsRecordingIdField); if (recordingId != null) { _logger.Debug("Fetching recording"); recording = db.Single <DbRecording>(r => r.Uid == recordingId) ?? new DbRecording { Uid = recordingId }; } else { recording = new DbRecording { Uid = Guid.NewGuid().ToString("N") }; saveTagFile = true; tagFile.SetCustomField(SoundWordsRecordingIdField, recording.Uid); } if (album == null) { string uid = tagFile.GetCustomField(SoundWordsAlbumIdField) ?? Guid.NewGuid().ToString("N"); album = new DbAlbum { Uid = uid, Name = (tagFile.Tag.Album ?? "Ukjent").Trim(), Path = albumFiles.Key, Restricted = restricted }; } UpdateAttachments(albumFiles.Key, album); if (album.Id != 0) { _logger.Debug("Saving album"); db.Update(album); } else { _logger.Debug("Creating album"); album.Id = db.Insert(album, true); } if (tagFile.GetCustomField(SoundWordsAlbumIdField) != album.Uid) { tagFile.SetCustomField(SoundWordsAlbumIdField, album.Uid); saveTagFile = true; } recording.AlbumId = album.Id; recording.Title = (tagFile.Tag.Title ?? "Ukjent").Trim(); recording.Track = (ushort)tagFile.Tag.Track; recording.Comment = tagFile.Tag.Comment; recording.Year = tagFile.Tag.Year != 0 ? (ushort?)tagFile.Tag.Year : null; recording.Path = file.FullName; recording.Restricted = restricted; if (recording.Id == 0) { _logger.DebugFormat("Creating recording: {0}", recording.Dump()); recording.Id = db.Insert(recording, true); } else { _logger.DebugFormat("Saving recording: {0}", recording.Dump()); db.Update(recording); } db.Delete <DbRecordingSpeaker>(rs => rs.RecordingId == recording.Id); foreach (string performer in tagFile.Tag.Performers) { _logger.DebugFormat($"Creating speaker {performer}"); NameInfo nameInfo = performer.ToNameInfo(); DbSpeaker speaker = db.Single <DbSpeaker>(s => s.FirstName == nameInfo.FirstName && s.LastName == nameInfo.LastName); if (speaker == null) { speaker = new DbSpeaker { Uid = Guid.NewGuid().ToString("N"), FirstName = nameInfo.FirstName, LastName = nameInfo.LastName }; speaker.Id = db.Insert(speaker, true); } if (!db.Exists <DbRecordingSpeaker>(rs => rs.RecordingId == recording.Id && rs.SpeakerId == speaker.Id)) { db.Insert(new DbRecordingSpeaker { RecordingId = recording.Id, SpeakerId = speaker.Id }); } } if (saveTagFile) { _logger.Debug("Writing ID tag data"); tagFile.Save(); } } index++; } _logger.Info("Committing transaction"); transaction.Commit(); } } } }