Click here to Skip to main content
15,896,063 members
Articles / Programming Languages / XML

Retrieving CD Information from a remote Freedb database

Rate me:
Please Sign up or sign in to vote.
4.92/5 (32 votes)
29 Jul 2004CPOL10 min read 220.4K   4.3K   125  
Describes a library that can be used to retrieve Audio CD information from the CDDB compatible freedb database.
#region COPYRIGHT (c) 2004 Brian Weeres
/* Copyright (c) 2004 by Brian Weeres
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND BRIAN WEERES DISCLAIMS
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL BRIAN WEERES 
 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */
#endregion
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using Ripper;
using System.Net;
using System.Text; // encoding
using System.Collections.Specialized;
using Freedb;

namespace FreedbDemo
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Button BTNLoadCD;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;
		private char[] m_CDDriveLetters = null;
		private System.Windows.Forms.ListBox LBResults;
		private System.Windows.Forms.ListView LVSongs;
		private FreedbHelper m_freedb = new FreedbHelper();
		private System.Windows.Forms.Button BTNDetails;
		private System.Windows.Forms.Button BTNCategories;
		private System.Windows.Forms.Button BTNSites;
		private System.Windows.Forms.Button BTNQuery;
		private System.Windows.Forms.Button BTNPreferences;
		CDDrive m_drive = null;



		public Form1()
		{
			InitializeComponent();
			SetColumns();
			m_freedb.UserName = "test";
			m_freedb.Hostname = "abc.company";
			m_freedb.ClientName = "FreedbDemo";
			m_freedb.Version = "1.0";
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.BTNLoadCD = new System.Windows.Forms.Button();
			this.LVSongs = new System.Windows.Forms.ListView();
			this.LBResults = new System.Windows.Forms.ListBox();
			this.BTNDetails = new System.Windows.Forms.Button();
			this.BTNCategories = new System.Windows.Forms.Button();
			this.BTNSites = new System.Windows.Forms.Button();
			this.BTNQuery = new System.Windows.Forms.Button();
			this.BTNPreferences = new System.Windows.Forms.Button();
			this.SuspendLayout();
			// 
			// BTNLoadCD
			// 
			this.BTNLoadCD.FlatStyle = System.Windows.Forms.FlatStyle.System;
			this.BTNLoadCD.Location = new System.Drawing.Point(24, 16);
			this.BTNLoadCD.Name = "BTNLoadCD";
			this.BTNLoadCD.Size = new System.Drawing.Size(104, 23);
			this.BTNLoadCD.TabIndex = 0;
			this.BTNLoadCD.Text = "Load CD";
			this.BTNLoadCD.Click += new System.EventHandler(this.BTNLoadCD_Click);
			// 
			// LVSongs
			// 
			this.LVSongs.FullRowSelect = true;
			this.LVSongs.Location = new System.Drawing.Point(8, 56);
			this.LVSongs.Name = "LVSongs";
			this.LVSongs.Size = new System.Drawing.Size(752, 232);
			this.LVSongs.TabIndex = 1;
			this.LVSongs.View = System.Windows.Forms.View.Details;
			// 
			// LBResults
			// 
			this.LBResults.Location = new System.Drawing.Point(8, 304);
			this.LBResults.Name = "LBResults";
			this.LBResults.Size = new System.Drawing.Size(544, 225);
			this.LBResults.TabIndex = 2;
			// 
			// BTNDetails
			// 
			this.BTNDetails.FlatStyle = System.Windows.Forms.FlatStyle.System;
			this.BTNDetails.Location = new System.Drawing.Point(560, 471);
			this.BTNDetails.Name = "BTNDetails";
			this.BTNDetails.Size = new System.Drawing.Size(88, 23);
			this.BTNDetails.TabIndex = 3;
			this.BTNDetails.Text = "Get CD Entry";
			this.BTNDetails.Click += new System.EventHandler(this.BTNDetails_Click);
			// 
			// BTNCategories
			// 
			this.BTNCategories.FlatStyle = System.Windows.Forms.FlatStyle.System;
			this.BTNCategories.Location = new System.Drawing.Point(560, 336);
			this.BTNCategories.Name = "BTNCategories";
			this.BTNCategories.Size = new System.Drawing.Size(88, 23);
			this.BTNCategories.TabIndex = 4;
			this.BTNCategories.Text = "Categories";
			this.BTNCategories.Click += new System.EventHandler(this.BTNCategories_Click);
			// 
			// BTNSites
			// 
			this.BTNSites.FlatStyle = System.Windows.Forms.FlatStyle.System;
			this.BTNSites.Location = new System.Drawing.Point(560, 381);
			this.BTNSites.Name = "BTNSites";
			this.BTNSites.Size = new System.Drawing.Size(88, 23);
			this.BTNSites.TabIndex = 5;
			this.BTNSites.Text = "Sites";
			this.BTNSites.Click += new System.EventHandler(this.BTNSites_Click);
			// 
			// BTNQuery
			// 
			this.BTNQuery.FlatStyle = System.Windows.Forms.FlatStyle.System;
			this.BTNQuery.Location = new System.Drawing.Point(560, 426);
			this.BTNQuery.Name = "BTNQuery";
			this.BTNQuery.Size = new System.Drawing.Size(88, 23);
			this.BTNQuery.TabIndex = 6;
			this.BTNQuery.Text = "Query";
			this.BTNQuery.Click += new System.EventHandler(this.BTNQuery_Click);
			// 
			// BTNPreferences
			// 
			this.BTNPreferences.FlatStyle = System.Windows.Forms.FlatStyle.System;
			this.BTNPreferences.Location = new System.Drawing.Point(184, 16);
			this.BTNPreferences.Name = "BTNPreferences";
			this.BTNPreferences.Size = new System.Drawing.Size(104, 23);
			this.BTNPreferences.TabIndex = 7;
			this.BTNPreferences.Text = "Preferences";
			this.BTNPreferences.Click += new System.EventHandler(this.BTNPreferences_Click);
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(784, 553);
			this.Controls.Add(this.BTNPreferences);
			this.Controls.Add(this.BTNQuery);
			this.Controls.Add(this.BTNSites);
			this.Controls.Add(this.BTNCategories);
			this.Controls.Add(this.BTNDetails);
			this.Controls.Add(this.LBResults);
			this.Controls.Add(this.LVSongs);
			this.Controls.Add(this.BTNLoadCD);
			this.Name = "Form1";
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			//enable XP styles
			Application.EnableVisualStyles(); 
			//some controls seem to have problems when EnableVisualStyles is called unless we call DoEvents immediately after.
			Application.DoEvents(); 
			Application.Run(new Form1());
		}

		private void BTNLoadCD_Click(object sender, System.EventArgs e)
		{
			Cursor.Current = Cursors.WaitCursor;
			if (!LoadCD())
				return;

			//query for cd info
			string query;

			try
			{
				query = m_drive.GetCDDBQuery();
			}
			
			catch (Exception ex)
			{
				//give up
				MessageBox.Show("CD Drive is not ready or cannot read cd. Details: " + ex.Message);
				return;
			}
			
			QueryResult queryResult;
			QueryResultCollection coll;
			string code = m_freedb.Query(query,out queryResult,out coll);
			//inexact match or multiple mathes show selection dialog
			if (code == FreedbHelper.ResponseCodes.CODE_210 || 
				code == FreedbHelper.ResponseCodes.CODE_211)
			{
				DLGSelectQueryResult dlg = new DLGSelectQueryResult(coll);
				DialogResult result = dlg.ShowDialog();
				if (result == DialogResult.Cancel)
				{
					MessageBox.Show("You must select one of the entries. Press the Load button to try again.");
					return;
				}

				queryResult = dlg.SelectedQueryResult;
			}
			else if (code != FreedbHelper.ResponseCodes.CODE_200)
			{
				MessageBox.Show("Query unsuccessful: " + code);
				return;
			}

			//queryResult now contains the results of our query.

			CDEntry cdEntry;
			code = this.m_freedb.Read(queryResult, out cdEntry);
			if (code != FreedbHelper.ResponseCodes.CODE_210)
				MessageBox.Show("Unable to retrieve cd entry. Code: " + code );

			LVSongs.Items.Clear();
			GetCDTracks(m_CDDriveLetters[0] + ":\\",cdEntry);
			this.LBResults.Items.Clear();
		}

		private bool LoadCD()
		{
			if (m_CDDriveLetters == null)
				m_CDDriveLetters = CDDrive.GetCDDriveLetters();

			if (m_CDDriveLetters.Length < 1)
			{
				MessageBox.Show("No CD Drives exist");
				return false;
			}

			//for now just use the first one
			m_drive  = new CDDrive();
			if (!m_drive.Open(m_CDDriveLetters[0]) )
			{
				MessageBox.Show("Unable to access CD Drive: " + m_CDDriveLetters[0]);
				return false;
			}

			if (!m_drive.IsCDReady())
			{
				MessageBox.Show("CD Drive is not ready. Please check drive:  " + m_CDDriveLetters[0]);
				return false;
			}

			m_drive.LockCD();
			m_drive.Refresh();
			m_drive.UnLockCD();
			return true;
		}


		private void GetSites()
		{
			try
			{
				LBResults.Items.Clear();
				SiteCollection sites;
				string result = m_freedb.GetSites(Freedb.Site.PROTOCOLS.HTTP, out sites);
				if (result == FreedbHelper.ResponseCodes.CODE_210)
				{
					foreach (Site site in sites)
					{
						this.LBResults.Items.Add("Address: " + site.SiteAddress + " Protocol: " + site.Protocol + " Additional: " + site.AdditionalAddressInfo +  " Desc: " + site.Description);
					}
				}
			}
			
			catch (Exception ex)
			{
				MessageBox.Show(this,ex.Message,"Retrieving Sites Information",MessageBoxButtons.OK,MessageBoxIcon.Error);
			}
			
		}



		private void GetCDTracks(string path,CDEntry cdEntry)
		{
			string[] directoryEntries;

			if (Directory.Exists(path))
			{
				directoryEntries = System.IO.Directory.GetFileSystemEntries(path);
				if (directoryEntries.GetLength(0) > 1)
				{
					int i=0;
					foreach (string str in directoryEntries) 
					{
						ListViewItem item = CreateListViewItem(str,i,cdEntry);
						LVSongs.Items.Add(item);
						i++;
					}

				}
			}
		}


		private ListViewItem CreateListViewItem(string songPath,int trackNumber,CDEntry cdEntry)
		{
			string FileName = Path.GetFileName(songPath);
			int realTrackNum = trackNumber +1;
			Track track = cdEntry.Tracks[trackNumber];
			ListViewItem item = new ListViewItem(track.Title);
			item.SubItems.Add(cdEntry.Title); 
			item.SubItems.Add(cdEntry.Artist); 
			item.SubItems.Add( realTrackNum.ToString()); 
			item.SubItems.Add(FileName);
			item.SubItems.Add(songPath);
			return item;
		}




		private void SetColumns()
		{
			LVSongs.Columns.Add("SongName",-2,HorizontalAlignment.Left);
			LVSongs.Columns.Add("Album",-2,HorizontalAlignment.Left);
			LVSongs.Columns.Add("Artist",-2,HorizontalAlignment.Left);
			LVSongs.Columns.Add("Track",-2,HorizontalAlignment.Left);
			LVSongs.Columns.Add("FileName",-2,HorizontalAlignment.Left);
			LVSongs.Columns.Add("FullPath",-2,HorizontalAlignment.Left);

			// bug defined in knowledge base article - Q316572
			// width specified in add method does not work so we do the width again here
			LVSongs.Columns[0].Width = 200;
			LVSongs.Columns[1].Width = 100;
			LVSongs.Columns[2].Width = 100;
			LVSongs.Columns[3].Width = 50;
			LVSongs.Columns[4].Width = 100;
			LVSongs.Columns[5].Width = -2;
		}


		private void menuItemLoadCD_Click(object sender, System.EventArgs e)
		{
			LoadCD();
		}




		private void BTNDetails_Click(object sender, System.EventArgs e)
		{
			if (LBResults.SelectedIndex == -1)
			{
				MessageBox.Show("No item selected");
				return;
			}
			else if (!(LBResults.SelectedItem is QueryResult))
			{
				MessageBox.Show("Please perform a query and the select the item");
				return;
			}

			CDEntry cd;

			string code = m_freedb.Read((QueryResult)LBResults.SelectedItem, out cd);
			if (code != FreedbHelper.ResponseCodes.CODE_210)
				MessageBox.Show("Unable to retrieve cd entry. Code: " + code );

			MessageBox.Show("CD Entry Retrieved: " + cd.ToString());

		}


		private void BTNCategories_Click(object sender, System.EventArgs e)
		{
			try
			{
				StringCollection coll; 
				string result = m_freedb.GetCategories(out coll);
				if (result == FreedbHelper.ResponseCodes.CODE_210)
				{
					LBResults.Items.Clear();
					foreach (string category in coll)
					{
						this.LBResults.Items.Add(category);
					}
				}

			}
			
			catch (Exception ex)
			{
				string msg;
				if (ex.InnerException != null)
					msg = ex.InnerException.Message;
				else
					msg = ex.Message;
				MessageBox.Show("Unable to retrieve categories. Reason: " + msg);
			}
		}

		private void BTNSites_Click(object sender, System.EventArgs e)
		{
			GetSites();
		}

		private void BTNQuery_Click(object sender, System.EventArgs e)
		{
			// check if the CDDrive object has been created yet. 
			if (m_drive == null)
				LoadCD();
			if (m_drive.IsOpened == false || m_drive.IsCDReady() == false)
			{
				MessageBox.Show("CD Drive is not ready.");
				return;
			}

			string query;

			// get the CDDBQuery information we need from the CDDrive class
			try
			{
				query = m_drive.GetCDDBQuery();
			}
			
			catch (Exception ex)
			{
				//give up
				MessageBox.Show("CD Drive is not ready or cannot read cd. Details: " + ex.Message);
				return;
			}

			// Query out parameters
			QueryResult queryResult; // used if only one exact match is found
			QueryResultCollection coll; // used if multiple exact or inexact matches are found
			
			// call the freedb Query method.
			string code = m_freedb.Query(query,out queryResult,out coll);
			
			//clear out the listbox where we display the results.
			LBResults.Items.Clear();
			
			//CODE_200 means one and only one exact match was found
			//CODE_210 means a number of exact matches were found
			//CODE_211 means a number of inexact matches were found
			if (code == FreedbHelper.ResponseCodes.CODE_200)
				this.LBResults.Items.Add(queryResult);
			else if (code == FreedbHelper.ResponseCodes.CODE_210 || code == FreedbHelper.ResponseCodes.CODE_211 )
			{
				// add all the results to the listbox
				foreach (QueryResult qr in coll)
				{
					this.LBResults.Items.Add(qr);
				}
			}
			else MessageBox.Show("Query unsuccessful: " + code);
		}

		private void BTNPreferences_Click(object sender, System.EventArgs e)
		{
			DLGPreferences dlg = new DLGPreferences(this.m_freedb);
			DialogResult result = dlg.ShowDialog(this);
			if (result == DialogResult.OK)
			{
				m_freedb.CurrentSite = dlg.SelectedSite;
				m_freedb.UserName = dlg.UserName;
				m_freedb.Hostname = dlg.HostName;
			}
		}


	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions