
import java.net.*;
import java.io.*;
import java.util.*;
import java.lang.*;

public class XMLRecompiler {

    static int PORT = 2001;
    static String EXTIP = "xx.xx.xxx.xx";
    static String RootDir = "x:\\XXXXXXXXXX\\xxxxx";
    static String DLPath = "x:\\XXXXXXXXXX\\xxxxx";
    final static String CRLF = "\r\n";
    static Socket Rsocket;
    static InputStream input;
    static OutputStream output;
    static BufferedReader br;
    static int FileCount = 0;

    public static void HTMLGen(String dir) {
        FileCount = 0;
        String HTML = "<?xml version=\"1.0\" encoding='UTF-8'?>\n" +
                "<rss version=\"2.0\" xmlns:media=\"http://search.yahoo.com/mrss/\">\n" +
                "<channel>\n" +
                "<title>HomeMadeFeed</title>\n" +
                "<description>HOMEMADEFEEDBITCHES</description>\n" +
                "<link>http://" + EXTIP + ":" + PORT + "/</link>\n" +
                "<docs>http://blogs.law.harvard.edu/tech/rss</docs>\n" +
                "<pubDate>Mon, 23 Oct 2006 22:31:10 -0300</pubDate>\n" +
                "<generator>pspad (by hand)</generator>\n";
        HTML += HTMLRecur(dir);
        HTML += "</channel>\n" +
                "</rss>\n";
        // return HTML;
        File f = new File(RootDir);
        try {
            BufferedWriter out = new BufferedWriter(new FileWriter(f.getPath() + "/" + f.getName() + ".xml"));
            out.write(HTML);
            out.close();
        } catch (IOException e) {
        }
    }

    public static String HTMLRecur(String dir) {
        String HTML = "";
        File f = new File(dir);
        String[] files = f.list();
        for (int i = 0; i < files.length; i++) {
            File f2 = new File(dir, files[i]);
            String PATHTODL = f2.getParent();
            String[] Paths = new String[21];
            int recur = 0;
            File recurF;
            while (PATHTODL != null && !PATHTODL.equals(new File(RootDir).getParent())) {
                recurF = new File(PATHTODL);
                PATHTODL = recurF.getParent();
                Paths[recur] = recurF.getName();
                recur++;
            }
            recur = 20;
            String filewpath = "";
            while (recur > -1) {
                if (Paths[recur] != null) {
                    filewpath += "\\" + Paths[recur];
                }
                recur--;
            }
            filewpath += "\\" + files[i];
            String news = URLEncoder.encode(filewpath);
            news = news.replace("%5C", "/");
            news = news.replace("%28", "(");
            news = news.replace("%29", ")");
            news = news.replace("%5B", "[");
            news = news.replace("%5D", "]");
            news = news.replace("+", "%20");
            if (f2.isFile() && (files[i].endsWith(".mp3") || files[i].endsWith(".avi") || files[i].endsWith(".mp4"))) {
                FileCount++;
                HTML += "<item>\n" +
                        " <title>" + URLEncoder.encode(files[i]) + "</title>\n" +
                        " <description>" + news + " - </description>\n" +
                        "<link>http://" + EXTIP + ":" + PORT + news + "</link>\n" +
                        " <pubDate>Mon, 23 Oct 2006 22:30:15 -0300</pubDate>\n" +
                        "<enclosure url=\"http://" + EXTIP + ":" + PORT + news + "\" length=\"" + f2.length() + "\" type = \"" + contentType(files[i]) + "\" /> \n" +
                        "</item>\n";
            } else if (f2.isDirectory()) {
                HTML += HTMLRecur(dir + "/" + files[i]);
            }
        }
        return HTML;
    }

    public static String FindFolder(String dir) {
        File f = new File(dir);
        String HTML;
        if(!dir.equalsIgnoreCase(RootDir)){
        HTML = "Name: " +". Back"+ "<br>" +
                "<form action=\"http://" + EXTIP + ":" + Rsocket.getLocalPort() + "/\" method=\"GET\">\n" +
                "<input type=\"hidden\" name=\"review\" value = \"" +f.getParent()+ "\">" +
                "<input type=\"submit\" class = \"submitLink\"value=\"Back...\">\n" +
                "</form>\n + <br><br>";}
        else{HTML = "";}
        HTML+=FindFolderRecur(dir);
        return HTML;
    }

    public static String FindFolderRecur(String dir) {
        String HTML = "";
        File f = new File(dir);
        String[] files = f.list();
        for (int i = 0; i < files.length; i++) {
            File f2 = new File(dir, files[i]);
            String PATHTODL = f2.getParent();
            String[] Paths = new String[21];
            int recur = 0;
            File recurF;
            while (PATHTODL != null && !PATHTODL.equals(RootDir)) {
                recurF = new File(PATHTODL);
                PATHTODL = recurF.getParent();
                Paths[recur] = recurF.getName();
                recur++;
            }
            recur = 20;
            String filewpath = "";
            while (recur > -1) {
                if (Paths[recur] != null) {
                    filewpath += "\\" + Paths[recur];
                }
                recur--;
            }
            filewpath += "\\" + files[i];
            String news = URLEncoder.encode(filewpath);
            news = news.replace("%5C", "/");
            if (f2.isDirectory()) {
                HTML += "Name: " + files[i] + "<br>" +
                        "<form action=\"http://" + EXTIP + ":" + Rsocket.getLocalPort() + "/\" method=\"GET\">\n" +
                        "<input type=\"hidden\" name=\"review\" value = \"" + RootDir + filewpath + "\">" +
                        "<input type=\"submit\" class = \"submitLink\"value=\"Go!\">\n" +
                        "</form>\n + <br><br>";
                FindFolderRecur(dir + "/" + files[i]);
            }
        }
        return HTML;
    }

    public static void main(String[] args) {
        int port = 2000;
        ServerSocket server_socket;
        System.out.println("Enter your External IP Address...");
        System.out.println();
        try {
            BufferedReader IN = new BufferedReader(new InputStreamReader(System.in));
            EXTIP = IN.readLine();
            System.out.println("Enter a port to use...");
            System.out.println();
            port = Integer.parseInt(IN.readLine());
            System.out.println("Enter the port HFS is using...");
            System.out.println();
            PORT = Integer.parseInt(IN.readLine());
            System.out.println("Enter a Root Directory...");
            System.out.println();
            RootDir = (IN.readLine());
            DLPath = RootDir;
        } catch (IOException evt) {
            System.out.println("Error.");
            System.exit(1);
        }
        HTMLGen(DLPath);

        try {

            //print out the port number for user
            server_socket = new ServerSocket(port);
            System.out.println("httpServer running on port " +
                    server_socket.getLocalPort());

            // server infinite loop
            while (true) {
                Socket socket = server_socket.accept();
                System.out.println("New connection accepted " +
                        socket.getInetAddress() +
                        ":" + socket.getPort());

                // Construct handler to process the HTTP request message.
                try {
                    Rsocket = socket;
                    input = socket.getInputStream();
                    output = socket.getOutputStream();
                    br =
                            new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    while (true) {
                        processRequest();
                    }
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        } catch (IOException e) {
            System.out.println(e);
        }
    }

    private static void processRequest() throws Exception {
        boolean keepalive = true;
        while (true) {

            String headerLine = br.readLine();

            if (headerLine.contains("Close")) {
                keepalive = false;
            }
            System.out.println(headerLine);
            if (headerLine.equals(CRLF) || headerLine.equals("")) {
                break;
            }
            StringTokenizer s = new StringTokenizer(headerLine);
            String temp = s.nextToken();


            String fileName = s.nextToken();
            String p = URLDecoder.decode(fileName);
            String entityBody = null;
            if (fileName.contains("?review=")) {
                p = p.replace("/", "");
                p = p.replace("?review=", "");
                boolean isinRootDir = false;
                String G = p;
                while (G != null) {
                    if (G.equals(RootDir)) {
                        isinRootDir = true;
                    }
                    G = new File(G).getParent();
                }
                if (isinRootDir) {
                    DLPath = p;
                    HTMLGen(DLPath);
                    entityBody = "<head> <style type=\"text/css\">\n" +
                            ".submitLink {\n" +
                            "color: #00f;\n" +
                            " background-color: transparent;\n" +
                            "text-decoration: underline;\n" +
                            "border: none;\n" +
                            "cursor: pointer;\n" +
                            "cursor: hand;\n" +
                            "}\n" +
                            "</style> </head>" + "<br>XML document has successfully been recompiled. Please restart your stream.<br>" +
                            "Number of Entries: " + FileCount + "<br><br> <form action=\"http://" + EXTIP + ":" + Rsocket.getLocalPort() + "/\" method=\"GET\">\n" +
                            "<textarea name=\"review\" cols=40 rows=4>" + RootDir + "</textarea>\n" +
                            "<input type=\"submit\" class = \"submitLink\"value=\"Publish\">\n" +
                            "</form>\n + <br><br>" + FindFolder(DLPath);
                } else {
                    entityBody = "ERROR: Pick a directory that is in the Root Directory!";
                }

            } else {
                entityBody = "<head> <style type=\"text/css\">\n" +
                        ".submitLink {\n" +
                        "color: #00f;\n" +
                        " background-color: transparent;\n" +
                        "text-decoration: underline;\n" +
                        "border: none;\n" +
                        "cursor: pointer;\n" +
                        "cursor: hand;\n" +
                        "}\n" +
                        "</style> </head>" + "<form action=\"http://" + EXTIP + ":" + PORT + "/\" method=\"GET\">\n" +
                        "<textarea name=\"review\" cols=40 rows=4>" + RootDir + "</textarea>\n" +
                        "<input type=\"submit\" value=\"Publish\">\n" +
                        "</form>\n + <br><br>" + FindFolder(DLPath);

            }

// Open the requested file.
            FileInputStream fis = null;
            boolean fileExists = true;
            try {
                fis = new FileInputStream(fileName);
            } catch (FileNotFoundException e) {
                try {
                    fileName = DLPath + "/" + new File(DLPath).getName() + ".htm";
                    fis = new FileInputStream(fileName);
                } catch (FileNotFoundException m) {
                    System.exit(0);
                }
            }
            Rsocket.setKeepAlive(true);
// Construct the response message.
            String serverLine = "Server: fpont simple java httpServer";
            String statusLine = null;
            String contentTypeLine = null;
            String contentLengthLine = "error";
            statusLine = "HTTP/1.0 200 OK" + CRLF;
            contentTypeLine = "Content-type: " +
                    contentType(fileName) + CRLF;
            contentLengthLine = "Content-Length: " + (new Integer(fis.available())).toString() + CRLF;
// Send the status line.
            if (temp.equals("GET") || temp.equals("HEAD")) {
                output.write(statusLine.getBytes());

// Send the content type line.
                output.write(contentTypeLine.getBytes());

// Send the Content-Length
                output.write(contentLengthLine.getBytes());

// Send a blank line to indicate the end of the header lines.
                output.write(CRLF.getBytes());

// Send the entity body.
                if (temp.equals("GET")) {

                    output.write(entityBody.getBytes());

                }
            }
        }

        try {
            output.close();
            br.close();
            Rsocket.close();
        } catch (Exception e) {
        }
    }

    private static void sendBytes(FileInputStream fis, OutputStream os)
            throws Exception {
// Construct a 1K buffer to hold bytes on their way to the socket.
        byte[] buffer = new byte[1024];
        int bytes = 0;

// Copy requested file into the socket's output stream.
        while ((bytes = fis.read(buffer)) != -1) {
            os.write(buffer, 0, bytes);
        }
    }

    private static String contentType(String fileName) {
        if (fileName.endsWith(".htm") || fileName.endsWith(".html")) {
            return "text/html";
        }
        if (fileName.endsWith(".mp3")) {
            return "audio/mp3";
        }
        if (fileName.endsWith(".mp4")) {
            return "video/mp4";
        }
        if (fileName.endsWith(".avi")) {
            return "video/avi";
        }
        return "";

    }
}
