|
- #!/usr/bin/python
-
- import sys
- # Python 3.
- try:
- from http.server import HTTPServer
- from http.server import SimpleHTTPRequestHandler
- # Python 2.
- except ImportError:
- from BaseHTTPServer import HTTPServer
- from SimpleHTTPServer import SimpleHTTPRequestHandler
- import glob
- import os
- import base64
-
- class HTTPRequestHandler(SimpleHTTPRequestHandler):
- # Implementation.
- def do_GET(self):
- tool.process(self)
- def do_POST(self):
- tool.process(self)
-
- def listFiles(path):
- items = []
-
- fileNames = glob.glob(path + "/*")
- fileNames.sort()
- for fileName in fileNames:
- file = { }
- # Path.
- file["path"] = os.path.basename(fileName)
- # Type.
- file["type"] = None
- if (os.path.isdir(fileName)):
- file["type"] = "dir"
- elif (os.path.isfile(fileName)):
- file["type"] = "file";
-
- items.append(file)
-
- return items
- def fileListToJSON(fileList):
- out = ""
- for file in fileList:
- if (len(out)):
- out += ","
- out += "{\"path\":\"%s\",\"type\":\"%s\"}" % (file["path"], file["type"])
- return "[" + out + "]"
- def jsonToPathContents(json):
- # This function takes `abc` and `def` from string of the following format:
- # `{"path": "abc", "contents": "def"}`.
- parts = json.split('"')
- if (len(parts) == 9):
- return (parts[3], parts[7])
- return (None, None)
-
- class Tool(object):
- # Configuration.
- def __init__(self, arguments):
- self.arguments = arguments
- self.PORT = 8000
- self.serverHost = ""
- # Main execution sequence.
- def run(self):
- self.validateArguments()
- self.parseArguments()
- self.printArguments()
- self.runServer()
- # Implementation.
- def validateArguments(self):
- if (len(self.arguments) < 2):
- print(
- (
- "Usage: %s DIR [PORT]"
- "\n\n"
- "\tPORT defaults to 8000"
- ) % self.arguments[0]
- )
- sys.exit(1)
-
- def printArguments(self):
- print("DIR: '%s'" % self.DIR)
- print("PORT: '%s'" % self.PORT)
- def parseArguments(self):
- self.DIR = self.arguments[1]
- # Override default port if specified.
- if (len(self.arguments) >= 3):
- self.PORT = self.arguments[2]
- def runServer(self):
- addr = (self.serverHost, int(self.PORT))
- self.httpd = HTTPServer(addr, HTTPRequestHandler)
- self.httpd.serve_forever()
- def process(self, requestHandler):
- if (requestHandler.path == "/path"):
- self.processPath(requestHandler)
- if (requestHandler.path == "/list"):
- self.processFileList(requestHandler)
- if (requestHandler.path == "/read"):
- self.processReadFile(requestHandler)
- if (requestHandler.path == "/write"):
- self.processWriteFile(requestHandler)
- def processPath(self, request):
- request.send_response(200)
- request.send_header("Access-Control-Allow-Origin", "*")
- request.end_headers()
-
- data = self.DIR.encode()
- request.wfile.write(data)
- def processFileList(self, request):
- request.send_response(200)
- request.send_header("Access-Control-Allow-Origin", "*")
- request.end_headers()
-
- size = int(request.headers["Content-Length"])
- path = request.rfile.read(size)
- path = path.decode()
- absPath = "%s/%s" % (self.DIR, path)
-
- fileList = listFiles(absPath)
- fileListJSON = fileListToJSON(fileList)
- data = fileListJSON.encode()
- request.wfile.write(data)
- def processReadFile(self, request):
- request.send_response(200)
- request.send_header("Access-Control-Allow-Origin", "*")
- request.end_headers()
-
- size = int(request.headers["Content-Length"])
- path = request.rfile.read(size)
- path = path.decode()
- absPath = "%s/%s" % (self.DIR, path)
- print("Reading '%s'" % absPath)
-
- f = open(absPath, "r")
- contents = f.read()
- f.close()
-
- # Perform Python3 compatible encoding.
- # If this crashes for Python2 (when there are non-ASCII symbols),
- # it's probably fine for `contents` to stay intact.
- try:
- contents = contents.encode()
- except:
- pass
-
- request.wfile.write(contents)
- def processWriteFile(self, request):
- request.send_response(200)
- request.send_header("Access-Control-Allow-Origin", "*")
- request.end_headers()
-
- size = int(request.headers["Content-Length"])
- data = request.rfile.read(size)
-
- # Extract path and contents.
- (path, contents) = jsonToPathContents(data)
- if ((path is None) or (contents is None)):
- print("ERROR Writing failed due to corrupt incoming data")
-
- # Try to convert using pre-Python2.4 API.
- try:
- contents = base64.decodestring(contents)
- # Resort to Python2.4+ API.
- except:
- contents = base64.b64decode(contents)
-
- # Perform Python3 compatible DEcoding.
- # If this crashes for Python2 (when there are non-ASCII symbols),
- # it's probably fine for `contents` to stay intact.
- try:
- contents = contents.decode()
- except:
- pass
-
- # Write.
- absPath = "%s/%s" % (self.DIR, path)
- print("Writing '%s'" % absPath)
- f = open(absPath, "w")
- f.write(contents)
- f.close()
-
- tool = Tool(sys.argv)
- tool.run()
|