[Configuration] FuzzyMatch update suggestion (1 Viewer)

ChrL

New Member
March 9, 2010
1
0
Home Country
Denmark Denmark
Since I'm not myself working on the project, I add my suggestion here.
My suggestion regards how to best match the actual movie.

I suggest that, in IMDBFetcher.cs, the FuzzyMatch is updated with the below.
Among other things it looks for the year in the title, since people often put it there, and looking for it helps disambiguating the movie.



public int FuzzyMatch(string name, string year)
{
List<int> matchingYearIndexes = new List<int>();
if (!string.IsNullOrEmpty(year))
{
for (int ixIx = 0; ixIx < _imdb.Count; ++ixIx) matchingYearIndexes.Add(ixIx);
FilterByYear(matchingYearIndexes, year);
if (matchingYearIndexes.Count == 1) return matchingYearIndexes[0];
}
List<int> relevantIndexes = new List<int>();
if (matchingYearIndexes.Count > 1) foreach (int yearMatch in matchingYearIndexes) relevantIndexes.Add(yearMatch);
else for (int ixIx = 0; ixIx < _imdb.Count; ++ixIx) relevantIndexes.Add(ixIx);

List<int> matchingIndexes = FilterByFuzz(name, relevantIndexes);
return matchingIndexes.Count > 0 ? matchingIndexes[0] : -1;
}

private List<int> FilterByFuzz(string name, List<int> relevantIndexes)
{
List<int> matchingIndexes = new List<int>();
int matchingDistance = int.MaxValue;
for (int ixIx = 0; ixIx < relevantIndexes.Count; ++ixIx)
{
int distance = Levenshtein.Match(name, _imdb[relevantIndexes[ixIx]].Title);

if (distance == matchingDistance && matchingDistance != int.MaxValue) matchingIndexes.Add(ixIx);
if (distance < matchingDistance)
{
matchingIndexes.Clear();
matchingIndexes.Add(ixIx);
matchingDistance = distance;
}
}
return matchingIndexes;
}


private void FilterByYear(List<int> matchingIndexes, string year)
{
if (!string.IsNullOrEmpty(year))
{
for (int ixIx = matchingIndexes.Count - 1; ixIx > 0; ixIx--)
if (!_imdb[matchingIndexes[ixIx]].Title.Contains(year)) matchingIndexes.Remove(ixIx);
}
}





/// <summary>
/// Download IMDB info for a movie
/// </summary>
public static bool RefreshIMDB(IMDB.IProgress progress, ref IMDBMovie currentMovie, bool fuzzyMatching,
bool getActors, bool addToDatabase)
{
Log.Info("RefreshIMDB() - Refreshing MovieInfo for {0}-{1}", currentMovie.Title, currentMovie.SearchString);
string strMovieName = currentMovie.SearchString;
string strFileName = string.Empty;
string path = currentMovie.Path;
string filename = currentMovie.File;
if (path != string.Empty)
{
if (path.EndsWith(@"\"))
{
path = path.Substring(0, path.Length - 1);
currentMovie.Path = path;
}
if (filename.StartsWith(@"\"))
{
filename = filename.Substring(1);
currentMovie.File = filename;
}
strFileName = path + @"\" + filename;
}
else
{
strFileName = filename;
}
if ((strMovieName == string.Empty) || (strMovieName == Strings.Unknown))
{
strMovieName = currentMovie.Title;
if ((strMovieName == string.Empty) || (strMovieName == Strings.Unknown))
{
if (strFileName == string.Empty)
{
return true;
}
if (Util.Utils.IsDVD(strFileName))
{
//DVD
string strDrive = strFileName.Substring(0, 2);
currentMovie.DVDLabel = Util.Utils.GetDriveName(strDrive);
strMovieName = currentMovie.DVDLabel;
}
else if (strFileName.ToUpper().IndexOf(@"\VIDEO_TS\VIDEO_TS.IFO") >= 0)
{
//DVD folder
string dvdFolder = strFileName.Substring(0, strFileName.ToUpper().IndexOf(@"\VIDEO_TS\VIDEO_TS.IFO"));
currentMovie.DVDLabel = Path.GetFileName(dvdFolder);
strMovieName = currentMovie.DVDLabel;
}
else
{
//Movie
strMovieName = Path.GetFileNameWithoutExtension(strFileName);
}
}
if ((strMovieName == string.Empty) || (strMovieName == Strings.Unknown))
{
return true;
}
}
if (currentMovie.ID == -1 && addToDatabase)
{
currentMovie.ID = VideoDatabase.AddMovieFile(strFileName);
}
currentMovie.SearchString = strMovieName;
if (currentMovie.ID >= 0 || !addToDatabase)
{
if (!Win32API.IsConnectedToInternet())
{
return false;
}
IMDBFetcher fetcher = new IMDBFetcher(progress);
fetcher.Movie = currentMovie;
fetcher.getActors = getActors;
int selectedMovie = -1;

//LOOP
do
{
if (!fetcher.Fetch(strMovieName, !(selectedMovie < 0) ))
{
return false;
}

string year = string.Empty;
if (fetcher._imdb.Count == 0)
{
MatchChopper matchChopper = new MatchChopper(strMovieName);
while (fetcher._imdb.Count == 0 && matchChopper.MoveNext())
{
if (!fetcher.Fetch(matchChopper.Current, !(selectedMovie < 0) )) return false;
}
year = matchChopper.Year;
}

if (fuzzyMatching)
{
selectedMovie = fetcher.FuzzyMatch(fetcher.MovieName, year);
if (selectedMovie == -1)
{
if (!fetcher.OnMovieNotFound(fetcher)) return false;
if (!fetcher.OnRequestMovieTitle(fetcher, out strMovieName)) return false;
if (strMovieName == string.Empty) return false;
}
}
else
{
if (fetcher.Count > 0)
{
int iMoviesFound = fetcher.Count;
//GEMX 28.03.08: There should always be a choice to enter the movie manually
// in case the 1 and only found name is wrong
/*if (iMoviesFound == 1)
{
selectedMovie = 0;
} else */
if (iMoviesFound > 0)
{
if (!fetcher.OnSelectMovie(fetcher, out selectedMovie))
{
return false;
}
if (selectedMovie < 0)
{
if (!fetcher.OnRequestMovieTitle(fetcher, out strMovieName))
{
return false;
}
if (strMovieName == string.Empty)
{
return false;
}
}
}
}
else
{
if (!fetcher.OnMovieNotFound(fetcher))
{
return false;
}
if (!fetcher.OnRequestMovieTitle(fetcher, out strMovieName))
{
return false;
}
if (strMovieName == string.Empty)
{
return false;
}
}
}
} while (selectedMovie < 0);


if (!fetcher.FetchDetails(selectedMovie, ref currentMovie))
{
return false;
}
IMDBMovie movieDetails = fetcher.Movie;

if (movieDetails != null)
{
movieDetails.SearchString = strMovieName;
currentMovie = movieDetails;
return true;
}
else
{
return fetcher.OnDetailsNotFound(fetcher);
}
}
return false;
}

public class MatchChopper : IEnumerator<string>
{
string orgName;
string movieName;
string rest;
public string Year;
bool useRest = false;

public MatchChopper(string movieName)
{
this.orgName = movieName;
this.movieName = movieName;
this.rest = string.Empty;
}

public string Current { get { return movieName; } }
object IEnumerator.Current { get { return movieName; } }
public void Reset() { movieName = orgName; rest = string.Empty; useRest = false; }
public void Dispose() { }

public bool MoveNext()
{
string[] looseSplit = movieName.Split(new char[] { ' ', ',', '.', '(', ')', '[', ']' }, StringSplitOptions.RemoveEmptyEntries);
int findIx = Array.FindIndex<string>(looseSplit, IsYearOfMovie);
if (findIx > 0)
{
Year = looseSplit[findIx];
looseSplit[findIx] = string.Empty;
movieName = Combine(looseSplit, " ");
return true;
}
else
{
//if (!string.IsNullOrEmpty(rest)) movieName = rest;
if (useRest) movieName = rest;
string[] dashSplit = movieName.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
if (dashSplit.Length>0)
{
movieName = dashSplit[0];
string upperTrimmed = movieName.ToUpper().Trim();
if (dashSplit.Length>1)
if (unimplemented_UserDefinedListOfWordsToIgnore.IndexOf(upperTrimmed)>-1))
{
movieName = dashSplit[1];
dashSplit[1] = string.Empty;
}
dashSplit[0] = string.Empty;
rest = Combine(dashSplit, " ");
useRest = true;
return true;
}
else
{
return false;
}
}
}

bool IsYearOfMovie(string text)
{
int year;
if (text.Length==6)
if ((text[0] == '{' || text[0] == '(' || text[0] == '[') &&
(text[0] == '}' || text[0] == ')' || text[0] == ']'))
{
text = text.Substring(1,4);
}
return (int.TryParse(text, out year) && (year > 1800) && (year <= DateTime.Now.Year + 3));
}

string Combine(string[] split, string delimiter)
{
StringBuilder sb = new StringBuilder();
bool first = true;
foreach (string s in split)
{
if (first == false) sb.Append(delimiter);
sb.Append(s);
first = false;
}
return sb.ToString();
}
}
 

Users who are viewing this thread

Top Bottom