/*
* Copyright (C) 2007 Eskil Bylund
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using DCSharp.Backend.Managers;
using DCSharp.Backend.Objects;
using DCSharp.Xml;
namespace DCSharp
{
// TODO: Get whether or not to monitor from the settings.
///
/// Finds sources for the active downloads.
///
public class FileFinder : IDisposable
{
private Runtime runtime;
private ActionQueue actionQueue;
private bool monitorLists;
private bool monitorResults;
public FileFinder(Runtime runtime)
{
if (runtime == null)
{
throw new ArgumentNullException("runtime");
}
this.runtime = runtime;
actionQueue = new ActionQueue("FileFinderThread");
runtime.DownloadManager.DownloaderAdded += OnDownloaderAdded;
runtime.DownloadManager.DownloaderRemoved += OnDownloaderRemoved;
runtime.SearchManager.ResultReceived += OnResultReceived;
}
#region Properties
public bool MonitorFileLists
{
get { return monitorLists; }
set { monitorLists = value; }
}
public bool MonitorSearchResults
{
get { return monitorResults; }
set { monitorResults = value; }
}
#endregion
#region Methods
public void CheckFileList(User user)
{
ListDownloader downloader = runtime.DownloadManager.Find(
delegate(ListDownloader ld)
{
return ld.User == user;
});
if (downloader == null && !actionQueue.Contains(user))
{
Monitor(runtime.DownloadManager.DownloadList(user));
}
}
public void Dispose()
{
runtime.DownloadManager.DownloaderAdded -= OnDownloaderAdded;
runtime.DownloadManager.DownloaderRemoved -= OnDownloaderRemoved;
runtime.SearchManager.ResultReceived -= OnResultReceived;
}
#region Search
private void OnResultReceived(object obj, ResultReceivedEventArgs args)
{
SearchResult result = args.Result;
if (monitorResults && result.TTH != null)
{
FileDownloader downloader = runtime.DownloadManager.GetDownloader(result.TTH)
as FileDownloader;
if (downloader != null)
{
downloader.AddSource(result.User);
}
}
}
#endregion
#region FileList
private void Monitor(ListDownloader downloader)
{
downloader.ListReceived += OnListReceived;
}
private void OnDownloaderAdded(object obj, DownloadEventArgs args)
{
ListDownloader downloader = args.Downloader as ListDownloader;
if (monitorLists && downloader != null)
{
Monitor(downloader);
}
}
private void OnDownloaderRemoved(object obj, DownloadEventArgs args)
{
ListDownloader downloader = args.Downloader as ListDownloader;
if (downloader != null)
{
downloader.ListReceived -= OnListReceived;
}
}
private void OnListReceived(object obj, EventArgs args)
{
ListDownloader downloader = (ListDownloader)obj;
if (downloader.Result != null)
{
actionQueue.Queue(downloader.User, FindSources, downloader);
}
}
private void FindSources(object state)
{
ListDownloader downloader = (ListDownloader)state;
FindSources(downloader.Result, downloader.User);
}
private void FindSources(FileList list, User user)
{
Queue queue = new Queue(list.Directories);
while (queue.Count > 0)
{
DirectoryNode directory = queue.Dequeue();
foreach (DirectoryNode child in directory.Directories)
{
queue.Enqueue(child);
}
foreach (FileNode file in directory.Files)
{
if (file.TTH != null)
{
FileDownloader downloader = runtime.DownloadManager.GetDownloader(file.TTH)
as FileDownloader;
if (downloader != null)
{
downloader.AddSource(user);
}
}
}
}
}
#endregion
#endregion
}
}