<%@ WebHandler Language="C#" Class="FileManager" %>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Collections;
using System.Text.RegularExpressions;
/// <summary>
/// 文件名:FileManager
/// 文件功能描述:主要获取上传的配置路径以及判断上传的是哪一种格式的文件最后进行处理操作对文件的管理操作
/// 版权所有:Copyright (C) liangjw
/// 创建标识:2013.07.18 
/// 修改描述:
/// </summary>
public class FileManager : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        //根目录路径，相对路径
        string rootUrl = "/upfile/attachment";
        //图片扩展名
        string fileTypes = Utility.GetAppSetting("Attach_Image");

        string currentPath = "";
        string currentUrl = "";
        string currentDirPath = "";
        string moveupDirPath = "";

        string dirPath = context.Server.MapPath(rootUrl);
        string dirName = context.Request.QueryString["dir"];
        if (!string.IsNullOrEmpty(dirName))
        {
            if (Array.IndexOf("image,flash,media,file".Split(','), dirName) == -1)
            {
                context.Response.Write("Invalid Directory name.");
                context.Response.End();
            }
            dirPath += dirName + "/";
            rootUrl += dirName + "/";
            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
            }
        }

        //根据path参数，设置各路径和URL
        string path = context.Request.QueryString["path"];
        path = string.IsNullOrEmpty(path) ? "" : path;
        if (path == "")
        {
            currentPath = dirPath;
            currentUrl = rootUrl;
            currentDirPath = "";
            moveupDirPath = "";
        }
        else
        {
            currentPath = dirPath + path;
            currentUrl = rootUrl + path;
            currentDirPath = path;
            moveupDirPath = Regex.Replace(currentDirPath, @"(.*?)[^\/]+\/$", "$1");
        }

        //排序形式，name or size or type
        string order = context.Request.QueryString["order"];
        order = string.IsNullOrEmpty(order) ? "" : order.ToLower();

        //不允许使用..移动到上一级目录
        if (Regex.IsMatch(path, @"\.\."))
        {
            context.Response.Write("Access is not allowed.");
            context.Response.End();
        }
        //最后一个字符不是/
        if (path != "" && !path.EndsWith("/"))
        {
            context.Response.Write("Parameter is not valid.");
            context.Response.End();
        }
        //目录不存在或不是目录
        if (!Directory.Exists(currentPath))
        {
            context.Response.Write("Directory does not exist.");
            context.Response.End();
        }

        //遍历目录取得文件信息
        string[] dirList = Directory.GetDirectories(currentPath);
        string[] fileList = Directory.GetFiles(currentPath);

        switch (order)
        {
            case "size":
                Array.Sort(dirList, new NameSorter());
                Array.Sort(fileList, new SizeSorter());
                break;
            case "type":
                Array.Sort(dirList, new NameSorter());
                Array.Sort(fileList, new TypeSorter());
                break;
            case "name":
            default:
                Array.Sort(dirList, new NameSorter());
                Array.Sort(fileList, new NameSorter());
                break;
        }

        string json = "{\"moveup_dir_path\":\"" + moveupDirPath + "\",\"current_dir_path\":\"" + currentDirPath + "\",\"current_url\":\"" + currentUrl + "\",\"file_list\":[";
        for (int i = 0; i < dirList.Length; i++)
        {
            DirectoryInfo dir = new DirectoryInfo(dirList[i]);
            json += "{\"filename\":\"" + dir.Name + "\",\"filesize\":0,\"filetype\":\"\",\"is_photo\":false,\"is_dir\":true,\"has_file\":" + (dir.GetFileSystemInfos().Length > 0).ToString().ToLower() + ",\"datetime\":\"" + dir.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") + "\"},";
        }
        for (int i = 0; i < fileList.Length; i++)
        {
            FileInfo file = new FileInfo(fileList[i]);
            json += "{\"filename\":\"" + file.Name + "\",\"filesize\":" + file.Length + ",\"filetype\":\"" + file.Extension.Substring(1) + "\",\"is_photo\":" + (Array.IndexOf(fileTypes.Split(','), file.Extension.Substring(1).ToLower()) >= 0).ToString().ToLower() + ",\"is_dir\":false,\"has_file\":false,\"datetime\":\"" + file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") + "\"},";
        }
        json = json.Trim(',') + "],\"total_count\":" + (dirList.Length + fileList.Length) + "}";

        context.Response.AddHeader("Content-Type", "application/json; charset=UTF-8");
        context.Response.Write(json);
        context.Response.End();
    }

    public class NameSorter : IComparer
    {
        public int Compare(object x, object y)
        {
            if (x == null && y == null)
            {
                return 0;
            }
            if (x == null)
            {
                return -1;
            }
            if (y == null)
            {
                return 1;
            }
            FileInfo xInfo = new FileInfo(x.ToString());
            FileInfo yInfo = new FileInfo(y.ToString());

            return xInfo.FullName.CompareTo(yInfo.FullName);
        }
    }

    public class SizeSorter : IComparer
    {
        public int Compare(object x, object y)
        {
            if (x == null && y == null)
            {
                return 0;
            }
            if (x == null)
            {
                return -1;
            }
            if (y == null)
            {
                return 1;
            }
            FileInfo xInfo = new FileInfo(x.ToString());
            FileInfo yInfo = new FileInfo(y.ToString());

            return xInfo.Length.CompareTo(yInfo.Length);
        }
    }

    public class TypeSorter : IComparer
    {
        public int Compare(object x, object y)
        {
            if (x == null && y == null)
            {
                return 0;
            }
            if (x == null)
            {
                return -1;
            }
            if (y == null)
            {
                return 1;
            }
            FileInfo xInfo = new FileInfo(x.ToString());
            FileInfo yInfo = new FileInfo(y.ToString());

            return xInfo.Extension.CompareTo(yInfo.Extension);
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}