using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Dokan;
using MediaAssistant.DAL;
using MediaAssistant.DAL.Constants;
namespace MediaFS
{
class MediaFSOperations : DokanOperations
{
private int count_;
private Dictionary<string, string> FilePathMap { get; set; }
private Dictionary<string, LibraryItem> LibraryItemPathMap { get; set; }
public MediaFSOperations()
{
count_ = -1;
FilePathMap=new Dictionary<string, string>();
LibraryItemPathMap=new Dictionary<string, LibraryItem>();
}
public int Cleanup(string filename, DokanFileInfo info)
{
return 0;
}
public int CloseFile(string filename, DokanFileInfo info)
{
return 0;
}
public int CreateDirectory(string filename, DokanFileInfo info)
{
return -1;
}
public int CreateFile(string filename, FileAccess access, FileShare share, FileMode mode, FileOptions options, DokanFileInfo info)
{
info.Context = count_++;
var path = GetPath(filename);
if (string.IsNullOrEmpty(path))
return -1;
if (File.Exists(path))
{
return 0;
}
info.IsDirectory = true;
return 0;
}
public int DeleteDirectory(string filename, DokanFileInfo info)
{
return -1;
}
public int DeleteFile(string filename, DokanFileInfo info)
{
return -1;
}
public int FlushFileBuffers(string filename, DokanFileInfo info)
{
return -1;
}
public int FindFiles(string filename, ArrayList files, DokanFileInfo info)
{
Debug.WriteLine(string.Format("FindFiles {0}", filename));
lock (DatabaseManager.LockObject)
{
if (filename == "\\")
{
foreach (var item in DatabaseManager.Instance.GetRootLibraryItems())
{
AddFileInfo(item.Title, FileAttributes.Directory, files);
}
return 0;
}
var libraryItem = GetLibraryItem(filename);
AddFileInfo(libraryItem, files);
}
return 0;
}
private static void AddFileInfo(LibraryItem item, ArrayList files)
{
lock (DatabaseManager.LockObject)
{
foreach (var libraryItem in item.Children)
{
AddFileInfo(libraryItem.Title, FileAttributes.Directory, files);
}
AddMovieFiles(files, item.Movies);
foreach (var music in item.Musics.Where(m => string.IsNullOrWhiteSpace(m.FullPath) == false))
{
AddFileInfo(music.FileName, FileAttributes.Normal, files);
}
var SelectedProfile = MediaFSManager.Instance.SelectedProfile;
switch (item.Type)
{
case LibraryItemType.ProcessingLibrary:
AddMovieFiles(files, DatabaseManager.Instance.UpdateProcessingMovies());
break;
case LibraryItemType.FailedLibrary:
AddMovieFiles(files, DatabaseManager.Instance.GetFailedMovies());
break;
case LibraryItemType.UnreadMovieLibrary:
if (SelectedProfile != null)
{
AddMovieFiles(files, DatabaseManager.Instance.GetNewMovies(SelectedProfile));
}
break;
case LibraryItemType.WatchListLibrary:
if (SelectedProfile != null)
{
AddMovieFiles(files, DatabaseManager.Instance.GetWatchedMovies(SelectedProfile));
}
break;
case LibraryItemType.WishListLibrary:
if (SelectedProfile != null)
{
AddMovieFiles(files, DatabaseManager.Instance.GetWishListMovie(SelectedProfile));
}
break;
case LibraryItemType.StaredMovieLibrary:
if (SelectedProfile != null)
{
AddMovieFiles(files, DatabaseManager.Instance.GetStarMovies(SelectedProfile));
}
break;
case LibraryItemType.RecommendedMovieLibrary:
if (SelectedProfile != null)
{
AddMovieFiles(files, DatabaseManager.Instance.GetStarMovies(SelectedProfile));
}
break;
case LibraryItemType.RecentlyPlayedMovieLibrary:
if (SelectedProfile != null)
{
AddMovieFiles(files, DatabaseManager.Instance.GetRecentlyPlayedMovies(SelectedProfile));
}
break;
}
}
}
private static void AddMovieFiles(ArrayList files, IEnumerable<Movie> movies)
{
foreach (var movie in movies.Where(m => string.IsNullOrWhiteSpace(m.FullPath) == false))
{
AddFileInfo(movie.FileName, FileAttributes.Normal, files);
}
}
private static void AddFileInfo(string fileName, FileAttributes fileAttributes, ArrayList files)
{
var finfo = new FileInformation
{
FileName = fileName,
Attributes = fileAttributes,
LastAccessTime = DateTime.Now,
LastWriteTime = DateTime.Now,
CreationTime = DateTime.Now
};
files.Add(finfo);
}
private LibraryItem GetLibraryItem(string filename)
{
if(LibraryItemPathMap.ContainsKey(filename))
{
return LibraryItemPathMap[filename];
}
var tokens = filename.Split("\\".ToCharArray()).Where(t => string.IsNullOrWhiteSpace(t) == false);
var items = DatabaseManager.Instance.GetRootLibraryItems();
var item = items.FirstOrDefault();
foreach (var token in tokens)
{
string title = token;
var temp = items.FirstOrDefault(o => o.Title.Equals(title, StringComparison.InvariantCultureIgnoreCase));
if (temp == null)
break;
item = temp;
items = item.Children;
}
if(item!=null)
{
LibraryItemPathMap.Add(filename,item);
}
return item;
}
public int GetFileInformation(string filename, FileInformation fileinfo, DokanFileInfo info)
{
if (filename == "\\")
{
fileinfo.Attributes = FileAttributes.Directory;
fileinfo.LastAccessTime = DateTime.Now;
fileinfo.LastWriteTime = DateTime.Now;
fileinfo.CreationTime = DateTime.Now;
return 0;
}
var path = GetPath(filename);
if(string.IsNullOrEmpty(path)==false)
{
var actualFileInfo = new FileInfo(path);
fileinfo.Attributes = actualFileInfo.Attributes;
fileinfo.LastAccessTime = actualFileInfo.LastAccessTime;
fileinfo.LastWriteTime = actualFileInfo.LastWriteTime;
fileinfo.CreationTime = actualFileInfo.CreationTime;
fileinfo.Length = actualFileInfo.Length;
fileinfo.FileName = actualFileInfo.Name;
return 0;
}
if(path==filename)
{
fileinfo.Attributes = FileAttributes.Directory;
fileinfo.LastAccessTime = DateTime.Now;
fileinfo.LastWriteTime = DateTime.Now;
fileinfo.CreationTime = DateTime.Now;
return 0;
}
return -1;
}
public int LockFile(string filename, long offset, long length, DokanFileInfo info)
{
return 0;
}
public int MoveFile(string filename, string newname, bool replace, DokanFileInfo info)
{
return -1;
}
public int OpenDirectory(string filename, DokanFileInfo info)
{
return 0;
}
public int ReadFile(string filename, byte[] buffer, ref uint readBytes, long offset, DokanFileInfo info)
{
try
{
var path = GetPath(filename);
if (string.IsNullOrEmpty(path))
return -1;
var fs = File.OpenRead(path);
fs.Seek(offset, SeekOrigin.Begin);
readBytes = (uint)fs.Read(buffer, 0, buffer.Length);
return 0;
}
catch (Exception)
{
return -1;
}
}
private string GetPath(string filename)
{
if(FilePathMap.ContainsKey(filename)==false)
{
lock (DatabaseManager.LockObject)
{
var fileInfo = new FileInfo(filename);
var libraryItem = GetLibraryItem(filename);
if (Utility.IsMusicFile(filename))
{
var music = libraryItem.Musics.FirstOrDefault(m => m.FileName.Equals(fileInfo.Name, StringComparison.InvariantCultureIgnoreCase));
FilePathMap.Add(filename,music.FullPath);
}
else if (Utility.IsMovieFile(filename))
{
var movie = libraryItem.Movies.FirstOrDefault(m => m.FileName.Equals(fileInfo.Name, StringComparison.InvariantCultureIgnoreCase));
FilePathMap.Add(filename, movie.FullPath);
}
else if(libraryItem!=null)
FilePathMap.Add(filename, filename);
else
{
FilePathMap.Add(filename, string.Empty);
}
}
}
return FilePathMap[filename];
}
public int SetEndOfFile(string filename, long length, DokanFileInfo info)
{
return -1;
}
public int SetAllocationSize(string filename, long length, DokanFileInfo info)
{
return -1;
}
public int SetFileAttributes(string filename, FileAttributes attr, DokanFileInfo info)
{
return -1;
}
public int SetFileTime(string filename, DateTime ctime, DateTime atime, DateTime mtime, DokanFileInfo info)
{
return -1;
}
public int UnlockFile(string filename, long offset, long length, DokanFileInfo info)
{
return 0;
}
public int Unmount(DokanFileInfo info)
{
return 0;
}
public int GetDiskFreeSpace(ref ulong freeBytesAvailable, ref ulong totalBytes, ref ulong totalFreeBytes, DokanFileInfo info)
{
freeBytesAvailable = 512 * 1024 * 1024;
totalBytes = 1024 * 1024 * 1024;
totalFreeBytes = 512 * 1024 * 1024;
return 0;
}
public int WriteFile(string filename, byte[] buffer, ref uint writtenBytes, long offset, DokanFileInfo info)
{
return -1;
}
}
}