private void UpdateCoverArt() { _coverUpdateTimer.Stop(); try { // get a hook to the DB IDBClient db = Database.RetrieveClient(); //// get the audio library locations //IList<Album> albums = _theModule._theDatabase.RetrieveAlbumsWithoutCoverArt(db); // get the current timestamp, we'll use this in case anything gets modified while this is happening DateTime beforeUpdate = DateTime.Now; //_log.Info("Started cover art update at: " + DateTime.Now.ToLocalTime()); //// recurse through each of the library locations //foreach (Album album in albums) //{ // if (!_theModule._theCore._keepRunning) // { // return; // } // bool artistPresent = (null != album._artist.Name); // bool titlePresent = (null != album._title); // // if this has the imported cover art // if (artistPresent && titlePresent && album._coverArt == AudioModuleConstants.IMPORTED_COVERART) // { // // try to retrieve the cover art from Amazon // var amazon = new AmazonRestService(); // string coverArt = amazon.RetrieveImage(album, AudioModuleConstants.IMAGE_FOLDER); // // if successful, store it on the album // if (null != coverArt) // { // // add the cover art with the required prefix // string coverArtPath = AudioModuleConstants.IMAGES_PREFIX + "/" + coverArt; // album._coverArt = coverArtPath; // _theModule._theDatabase.UpdateAddAlbum(db, album); // db.Commit(); // } // } //} TimeSpan elapsedTime = DateTime.Now - beforeUpdate; _log.Info("Finished cover art update at: " + DateTime.Now.ToLocalTime() + ". Took: " + elapsedTime.TotalSeconds + " seconds"); db.Close(); } catch (Db4oException) { // TODO } finally { _coverUpdateTimer.Start(); } }
/// <summary> /// Read the configuration file, establish what library locations need to be read /// </summary> private void InitialiseLibraryLocations() { // get a hook to the DB to use IDBClient db = Database.RetrieveClient(); IList <LibraryLocation> confirmedLocations = new List <LibraryLocation>(); //// get the list from the config file first //foreach (XmlNode locationNode in GetLibraryLocations()) //{ // string name = locationNode.Attributes["Name"].Value; // string path = locationNode.Attributes["Path"].Value; // LibraryLocation location = Database.RetrieveLibraryLocation(db, name, path); // // if this is a new location, add it to the DB // if (null == location) // { // location = new VideoLibraryLocation(name, path); // } // // add it to the ones that should be there // confirmedLocations.Add(location); //} // now we'll prune the ones which shouldn't be here IList <VideoLibraryLocation> locations = Database.RetrieveLibraryLocations(db); if (locations.Count != 0) { foreach (VideoLibraryLocation location in locations) { if (!confirmedLocations.Contains(location)) { Database.RemoveLibraryLocation(db, location); } } } // wasteful, but we'll just reconfirm them all foreach (VideoLibraryLocation location in confirmedLocations) { Database.UpdateAddLibraryLocation(db, location); } db.Close(); // ------------------------------------------------------------------------------------------- }
/// <summary> /// Read the configuration file, establish what library locations need to be read /// </summary> private void InitialiseLibraryLocations() { // get a hook to the DB to use IDBClient db = Database.RetrieveClient(); IList <LibraryLocation> confirmedLocations = new List <LibraryLocation>(); // get the list from the config file first foreach (XmlNode locationNode in GetLibraryLocations()) { string name = locationNode.Attributes["Name"].Value; string path = locationNode.Attributes["Path"].Value; // either find the existing location or create a new one LibraryLocation location = Database.RetrieveLibraryLocation(db, name, path) ?? new AudioLibraryLocation(name, path); // add it to the ones that should be there confirmedLocations.Add(location); } // now we'll prune the ones which shouldn't be here IList <AudioLibraryLocation> locations = Database.RetrieveLibraryLocations(db); if (locations.Count != 0) { foreach (AudioLibraryLocation location in locations) { if (!confirmedLocations.Contains(location)) { Database.RemoveLibraryLocation(db, location); } } } // wasteful, but we'll just reconfirm them all foreach (AudioLibraryLocation location in confirmedLocations) { Database.UpdateAddLibraryLocation(db, location); } db.Close(); }
/// <summary> /// Update the library when invoked via the timer /// </summary> private void UpdateLibrary() { try { // get a hook to the DB IDBClient db = Database.RetrieveClient(); // retrieve the initial number of tracks int beforeTracks = Database.RetrieveNumberOfTracks(db); // get the audio library locations IList <AudioLibraryLocation> locations = Database.RetrieveLibraryLocations(db); // get the current timestamp, we'll use this in case anything gets modified while this is happening DateTime beforeUpdate = DateTime.Now; _log.Info("Starting library update at: " + beforeUpdate.ToLocalTime()); try { // recurse through each of the library locations foreach (AudioLibraryLocation location in locations) { if (_log.IsDebugEnabled) { _log.Debug("Updating library location: " + location.Path); } // initialise the list of directories to process IList <string> directoriesToProcess = new List <string>(); // start traversing down each directory ProcessDirectory(directoriesToProcess, location.Path, location.LastWritten); // if there was any processing needed to be done if (directoriesToProcess.Count > 0) { const int numThreads = 5; _libraryThreadPool = new FixedThreadPool(5, ThreadPriority.Lowest); _log.Debug("Created custom thread pool for library with " + numThreads + " threads"); // make all the workers for (int i = 0; i < directoriesToProcess.Count; i++) { var worker = new AudioLibraryWorker(); worker.Directory = directoriesToProcess[i]; // attach it to a worker for the pool var workerItem = new WorkerItem(worker.WorkerMethod); // add it to the pool _libraryThreadPool.QueueWorkerItem(workerItem); // start the show _libraryThreadPool.Start(); } } // reset the reference to when this update run started location.LastWritten = beforeUpdate; // store this updated location back in the DB Database.UpdateAddLibraryLocation(db, location); // commit after each location. if something goes wrong, we wont have to redo db.Commit(); } // get the number of tracks after int afterTracks = Database.RetrieveNumberOfTracks(db); TimeSpan elapsedTime = DateTime.Now - beforeUpdate; _log.Info("Finished library update at: " + DateTime.Now.ToLocalTime() + ". Took: " + elapsedTime.TotalSeconds + " seconds"); _log.Info("Imported " + (afterTracks - beforeTracks) + " tracks"); // close the db db.Close(); } catch (DatabaseClosedException) { _log.Debug("The database has been closed prematurely"); } } catch (Db4oException ex) { _log.Error("Problem occurred when updating library", ex); } finally { _libraryUpdateTimer.Start(); } }
/// <summary> /// Worker method that be threaded for parallel processing of each of the directories /// </summary> public void WorkerMethod() { // take a note of the current time var stopWatch = new Stopwatch(); stopWatch.Start(); // keep track of the number of files for reporting var numberOfFiles = 0; try { // get a hook to the DB IDBClient db = null; // retrieve all the files in the supported extensions var files = System.IO.Directory.GetFiles(Directory, string.Empty, SearchOption.TopDirectoryOnly).Where(x => AudioConstants.SUPPORTED_LOSSLESS.Concat(AudioConstants.SUPPORTED_LOSSY).Contains(Path.GetExtension(x))); // open the database if there are files to process if (numberOfFiles > 0 && db == null) { // get a DB connection db = Database.RetrieveClient(); // increment our total numberOfFiles += files.Count(); // add these to the list foreach (string file in files) { // process them accordingly ProcessTrack(db, file); } } // attach the correct artist to the album if (_tally.Count > 0) { // find the artist that appears the most var highestPair = new KeyValuePair <Artist, int>(null, 0); foreach (var pair in _tally) { if (pair.Value > highestPair.Value) { highestPair = pair; } } // if they aren't on at least half the tracks, it's a various artist album if (highestPair.Value >= (_theAlbum.Tracks.Count / 2)) { // only change this in the DB if it's changed if (_theAlbum.Artist.Name != highestPair.Key.Name) { _theAlbum.Artist = highestPair.Key; // update the DB reference Database.UpdateAddAlbum(db, _theAlbum); } } else { _theAlbum.Artist = Artist.VARIOUS_ARTISTS; // update the DB reference Database.UpdateAddAlbum(db, _theAlbum); } } // commit after each directory db.Close(); } catch (IOException e) { _log.Error("File IO problem when processing directory: " + Directory, e); } if (_log.IsDebugEnabled) { _log.Debug("Processing directory '" + Directory + "' took " + stopWatch.Elapsed.TotalSeconds + " seconds."); _log.Debug("There were " + numberOfFiles + " files, at " + (stopWatch.Elapsed.TotalSeconds / numberOfFiles) + " seconds per file"); } }
/// <summary> /// Update the library when invoked via the timer /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UpdateLibrary() { _libraryUpdateTimer.Stop(); try { // lower the priority of this thread Thread.CurrentThread.Priority = ThreadPriority.Lowest; // get a hook to the DB IDBClient db = Database.RetrieveClient(); // get the audio library locations IList <VideoLibraryLocation> locations = Database.RetrieveLibraryLocations(db); // get the current timestamp, we'll use this in case anything gets modified while this is happening DateTime beforeUpdate = DateTime.Now; _log.Info("Starting library update at: " + beforeUpdate.ToLocalTime()); try { // recurse through each of the library locations foreach (VideoLibraryLocation location in locations) { if (_log.IsDebugEnabled) { _log.Debug("Updating library location: " + location.Path); } // // initialise the list of directories to process // IList<string> directoriesToProcess = new List<string>(); // // start traversing down each directory // ProcessDirectory(directoriesToProcess, location.Path, location.LastWritten); // // if there was any processing needed to be done // if (directoriesToProcess.Count > 0) // { // _libraryThreadPool = new FixedThreadPool(5, ThreadPriority.Lowest); // _log.Debug("Created custom thread pool for library with 5 threads"); // // make all the workers // for (int i = 0; i < directoriesToProcess.Count; i++) // { // if (!_theModule._theCore._keepRunning) // { // _libraryThreadPool._keepRunning = false; // return; // } // // create the worker thread // var worker = new LibraryWorker(_theModule, directoriesToProcess[i]); // // attach it to a worker for the pool // var workerItem = // new WorkerItem(new LibraryWorker.DirectoryWorker(worker.WorkerMethod)); // // add it to the pool // _libraryThreadPool.QueueWorkerItem(workerItem); // // start the show // _libraryThreadPool.Start(); // } // } // reset the reference to when this update run started location.LastWritten = beforeUpdate; // store this updated location back in the DB Database.UpdateAddLibraryLocation(db, location); // commit after each location. if something goes wrong, we wont have to redo db.Commit(); } TimeSpan elapsedTime = DateTime.Now - beforeUpdate; _log.Info("Finished library update at: " + DateTime.Now.ToLocalTime() + ". Took: " + elapsedTime.TotalSeconds + " seconds"); // close the db db.Close(); } catch (DatabaseClosedException) { _log.Debug("The database has been closed prematurely"); _libraryThreadPool._keepRunning = false; } } catch (Db4oException ex) { _log.Error("Problem occurred when updating library", ex); } finally { _libraryUpdateTimer.Start(); } }
public Album GetTracks(CDDBEntry cddbResult) { // initialise the album to output Album newAlbum = null; // build up the command string var commandBuilder = new StringBuilder(); commandBuilder.Append("?"); commandBuilder.Append(FreeDBConstants.COMMAND); commandBuilder.Append(FreeDBConstants.COMMAND_READ); commandBuilder.Append("+"); commandBuilder.Append(cddbResult.Genre); commandBuilder.Append("+"); commandBuilder.Append(cddbResult.DiscID); commandBuilder.Append("&"); commandBuilder.Append(GenerateHello()); commandBuilder.Append("&"); commandBuilder.Append(GenerateProtocol()); // make the URL to use var urlBuilder = new StringBuilder(); urlBuilder.Append(FreeDBConstants.URL_FREEDB_MAIN); urlBuilder.Append(FreeDBConstants.URL_HTTP_ACCESS); // hit up FreeDB for the result IList <string> freeDBResponse = Query(urlBuilder.ToString(), commandBuilder.ToString()); // parse the query if (freeDBResponse.Count > 0) { // extract the response code ResponseCode responseCode = ExtractResponseCode(freeDBResponse[0]); switch (responseCode) { case ResponseCode.RESPONSE_CODE_DEFAULT: _log.Error("Problem querying album using command: " + commandBuilder); break; case ResponseCode.RESPONSE_CODE_200: case ResponseCode.RESPONSE_CODE_210: _log.Debug("Found track/s"); // get a hook to the DB IDBClient db = Database.RetrieveClient(); // we'll look for an artist to attach this all to Artist theArtist = Database.RetrieveArtistByName(db, cddbResult.ArtistName); // TODO Check for artists, as opposed to just one // if we don't we'll create one if (null == theArtist) { theArtist = new Artist(cddbResult.ArtistName); } db.Close(); // we'll create an album for this with invalid data, we'll fill that out after newAlbum = new Album(cddbResult.Title, theArtist, null, 1900, Compression.Undecided); // a list to keep track of the track lengths in seconds IList <int> trackLengths = new List <int>(); // keep track of the track offsets for track lengths int lastTrackOffset = 0; // break up each of the results foreach (string responseLine in freeDBResponse) { // extract the track lengths if (responseLine.Contains("#\t")) { // parse the next offset int newOffset = Int32.Parse(responseLine.Substring(2)); // stop the first one being processed if (lastTrackOffset > 0) { int seconds = (newOffset - lastTrackOffset) / 75; trackLengths.Add(seconds); } // store the new offset lastTrackOffset = newOffset; } // extract the total number of seconds so we can calculate the last tracks length if (responseLine.Contains("# Disc length")) { // parse the total length of the album in seconds int totalLength = Int32.Parse(responseLine.Substring(15, 4)); int secondsToDate = lastTrackOffset / 75; // extract the length of the last track from this to find out the length of the final track int lastTrackLength = totalLength - secondsToDate; // add this to the lengths trackLengths.Add(lastTrackLength); } // extract the year if (responseLine.Contains("DYEAR")) { string year = responseLine.Substring(6); newAlbum.ReleaseYear = Int32.Parse(year); } // extract a track if (responseLine.Contains("TTITLE")) { // marker for where to parse string to int indexOfSpace = responseLine.IndexOf('=', 6); string numberString = responseLine.Substring(6, (indexOfSpace - 6)); int trackNumber = Int32.Parse(numberString) + 1; string trackTitle = responseLine.Substring(indexOfSpace + 1); // create this with no path as it's not currently set var artists = new List <Artist>(); artists.Add(theArtist); var newTrack = new Track(trackNumber, artists, newAlbum, new Duration(new TimeSpan(0, 0, trackLengths[trackNumber - 1])), trackTitle, null); newAlbum.AddTrack(newTrack); } } break; default: _log.Error("Response came back we weren't expecting, handle it"); break; } } // pass back the resulting album return(newAlbum); }