|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data.Entity;
using Xah.MediaCatalogerLib.Model;
using Xah.MediaCatalogerLib.Model.Files;
using Xah.MediaCatalogerLib.Model.Meta;
namespace Xah.MediaCatalogerLib.TreeProcess
{
interface ICancelable
{
bool IsCancelled { get; }
void Cancel();
}
abstract class ATreeVisitor : ITreeVisitor, ICancelable
{
#region ITreeVisitor implementation
public abstract void Visit(TreeFileItem fileItem);
public abstract void Visit(TreeFolderItem folderItem);
#endregion
#region ICancelable Members
protected bool cancelled = false;
public bool IsCancelled
{
get { return cancelled; }
}
public void Cancel()
{
cancelled = true;
}
#endregion
}
class PopulateTreeVisitor : ATreeVisitor
{
private string[] extensions = new string[0];
#region ATreeVisitor implementation
public override void Visit(TreeFileItem fileItem)
{
// do nothing
}
public override void Visit(TreeFolderItem folderItem)
{
string path = folderItem.Path;
if (!Directory.Exists(path)) return;
// populate children folders
string[] folders = Directory.GetDirectories(path);
foreach (string folder in folders)
{
if (IsCancelled) return;
DirectoryInfo di = new DirectoryInfo(folder);
TreeFolderItem tfi = new TreeFolderItem(di.Name);
folderItem.AddItem(tfi);
tfi.Accept(this);
}
// populate children files
List<string> files = new List<string>();
foreach (string extension in extensions)
{
if (IsCancelled) return;
string mask = String.Format("*.{0}", extension.Trim('.', ' '));
files.AddRange(Directory.GetFiles(path, mask));
}
files.ForEach(x => folderItem.AddItem(new TreeFileItem(Path.GetFileName(x))));
}
#endregion
public PopulateTreeVisitor(string[] extensions)
{
this.extensions = extensions;
}
}
class FileListerTreeVisitor : ATreeVisitor
{
public List<TreeFileItem> Files { get; private set; }
#region ATreeVisitor implementation
public override void Visit(TreeFileItem fileItem)
{
if (IsCancelled) return;
Files.Add(fileItem);
}
public override void Visit(TreeFolderItem folderItem)
{
if (IsCancelled) return;
folderItem.Children.ForEach(x => x.Accept(this));
}
#endregion
public FileListerTreeVisitor()
{
Files = new List<TreeFileItem>();
}
}
abstract class AFileProcessorTreeVisitor : ATreeVisitor
{
public delegate void OnFileProcessedCb(TreeFileItem fileItem);
public event OnFileProcessedCb OnFileProcessed;
protected readonly MediaCatalog db;
protected readonly MediaFolder folder;
#region Abstract methods
protected abstract void PreprocessFolder(TreeFolderItem folderItem);
protected abstract void PostprocessFolder(TreeFolderItem folderItem);
#endregion
#region ATreeVisitor implementation
public override void Visit(TreeFileItem fileItem)
{
if (IsCancelled) return;
try
{
if (!db.ExistsMediaFile(folder.MediaType, fileItem.Path))
fileItem.Tag = MediaFile.Create(db, folder, fileItem.Path);
if (OnFileProcessed != null)
OnFileProcessed(fileItem);
}
catch { }
}
public override void Visit(TreeFolderItem folderItem)
{
if (IsCancelled) return;
PreprocessFolder(folderItem);
folderItem.Children.ForEach(x => x.Accept(this));
PostprocessFolder(folderItem);
// Get file list
List<MediaFile> files = folderItem.Children.Select(x => x.Tag).OfType<MediaFile>().ToList();
if (files.Count == 0) return;
try
{
// Add files to database and save changes
files.ForEach(x => x.Add(db));
db.SaveChanges();
}
catch (System.Data.Entity.Validation.DbEntityValidationException ex)
{
// Trace error
System.Diagnostics.Trace.TraceError("--------------------------------------------");
foreach (System.Data.Entity.Validation.DbEntityValidationResult errs in ex.EntityValidationErrors)
{
foreach (System.Data.Entity.Validation.DbValidationError err in errs.ValidationErrors)
System.Diagnostics.Trace.TraceError("ERROR - {0}|{1}: {2}", err.PropertyName, ((object)errs.Entry).GetType().ToString(), err.ErrorMessage);
}
System.Diagnostics.Trace.TraceError("--------------------------------------------");
}
catch (System.Data.Entity.Infrastructure.DbUpdateException ex)
{
// Trace error
System.Diagnostics.Trace.TraceError("--------------------------------------------");
foreach (var st in ex.Entries)
{
System.Diagnostics.Trace.TraceError("ERROR - {0}|{1}: {2}", st.State.ToString(), ((object)st.Entity).GetType().ToString(), ex.Message);
}
}
}
#endregion
protected AFileProcessorTreeVisitor(MediaCatalog db, MediaFolder folder)
{
this.db = db;
this.folder = folder;
}
public static AFileProcessorTreeVisitor Create(MediaCatalog db, MediaFolder folder)
{
AFileProcessorTreeVisitor processor = null;
switch (folder.MediaType)
{
case MediaFileType.Video:
processor = new VideoFileProcessorTreeVisitor(db, folder);
break;
case MediaFileType.Audio:
processor = new AudioFileProcessorTreeVisitor(db, folder);
break;
}
return processor;
}
}
class VideoFileProcessorTreeVisitor : AFileProcessorTreeVisitor
{
#region AFileProcessorTreeVisitor implementation
protected override void PreprocessFolder(TreeFolderItem folderItem)
{
// do nothing
}
protected override void PostprocessFolder(TreeFolderItem folderItem)
{
// do nothing
}
#endregion
public VideoFileProcessorTreeVisitor(MediaCatalog db, MediaFolder folder) : base(db, folder) { }
}
class AudioFileProcessorTreeVisitor : AFileProcessorTreeVisitor
{
#region AFileProcessorTreeVisitor implementation
protected override void PreprocessFolder(TreeFolderItem folderItem)
{
// do nothing
}
protected override void PostprocessFolder(TreeFolderItem folderItem)
{
// Get folder audio files
var trackFiles = folderItem.Children.Select(x => x.Tag).OfType<AudioFile>().ToList();
if (trackFiles.Count == 0) return;
// Select list with AudioFileMetaInfo
var trackInfos = trackFiles.Select(x => x.AlbumTrackInfo).Where(x => x != null).ToList();
// Create AudioAlbumMetalnfo
AudioAlbumMetalnfo albumInfo = new AudioAlbumMetalnfo(db, trackInfos);
AudioAlbumMetalnfo existingAlbumInfo = db.Albums.FirstOrDefault(x => x.Artist.Equals(albumInfo.Artist) && x.Album.Equals(albumInfo.Album));
if (existingAlbumInfo != null) albumInfo = existingAlbumInfo;
// Associate album info with audio files
trackFiles.ForEach(x => x.AlbumInfo = albumInfo);
}
#endregion
public AudioFileProcessorTreeVisitor(MediaCatalog db, MediaFolder folder) : base(db, folder) { }
}
}
|
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.
I studied Telecommunication with spezialization in Sound & Image. I was always very interested in programming at university as well and that is how I earn a living.
Since some years ago, I am also succesfully involved in software architecture and design.