123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- # (c) J.Y.Amihud 2023
- # GPL-3 or any later version
- # This is a http server that will serve files over network, for multiusering
- # across the internet.
- # Server side
- from http.server import BaseHTTPRequestHandler, HTTPServer
- from subprocess import *
- import json
- import os
- import zlib
- import sys
- import time
- import random
- import mimetypes
- import datetime
- import hashlib
- import urllib.request
- import urllib.parse
- import subprocess
- # Colors are used to make the
- clr = {
- "norm":"\033[00m", # Reset to normal
- "bold":"\033[01m", # Bold Text
- "ital":"\033[03m", # Italic Text
- "undr":"\033[04m", # Underlined
- "blnk":"\033[05m", # Blinking
- # Text
- "tdbl":"\033[30m", # Dark Black
- "tdrd":"\033[31m", # Dark Red
- "tdgr":"\033[32m", # Dark Green
- "tdyl":"\033[33m", # Dark Yellow
- "tdbu":"\033[34m", # Dark Blue
- "tdma":"\033[35m", # Dark Magenta
- "tdcy":"\033[36m", # Dark Cyan
- "tdwh":"\033[37m", # Dark White
- "tbbl":"\033[90m", # Bright Black
- "tbrd":"\033[91m", # Bright Red
- "tbgr":"\033[92m", # Bright Green
- "tbyl":"\033[93m", # Bright Yellow
- "tbbu":"\033[94m", # Bright Blue
- "tbma":"\033[95m", # Bright Magenta
- "tbcy":"\033[96m", # Bright Cyan
- "tbwh":"\033[97m", # Bright White
- # Background
- "bdbl":"\033[40m", # Dark Black
- "bdrd":"\033[41m", # Dark Red
- "bdgr":"\033[42m", # Dark Green
- "bdyl":"\033[43m", # Dark Yellow
- "bdbu":"\033[44m", # Dark Blue
- "bdma":"\033[45m", # Dark Magenta
- "bdcy":"\033[46m", # Dark Cyan
- "bdwh":"\033[47m", # Dark White
- "bbbl":"\033[100m", # Bright Black
- "bbrd":"\033[101m", # Bright Red
- "bbgr":"\033[102m", # Bright Green
- "bbyl":"\033[103m", # Bright Yellow
- "bbbu":"\033[104m", # Bright Blue
- "bbma":"\033[105m", # Bright Magenta
- "bbcy":"\033[106m", # Bright Cyan
- "bbwh":"\033[108m" # Bright White
- }
- # TODO: Make this not stupidly hardcoded.
- blender = "/home/vcs/Software/blender-3.3.0-linux-x64/blender"
- try:
- PROJECT = sys.argv[2]
- except:
- print("Please specify a port number and then project folder.")
- exit()
- try:
- ORIGINAL_PROJECT = sys.argv[3]
- except:
- print("Orignal Project Name Was Not Specified.")
- ORIGINAL_PROJECT = " not a folder that can exist "
-
- def fileinfo(filename):
- fd = {}
- fd["md5"] = hashlib.md5(open(filename,'rb').read()).hexdigest()
- fd["filesize"] = os.path.getsize(filename)
- return fd
-
-
- class handler(BaseHTTPRequestHandler):
- def start_page(self, code):
-
- self.send_response(code)
- def do_GET(self):
- # Basic security measure
- self.path = self.path.replace("/..", "/")
- self.path = self.path.replace("//", "/")
- if self.path == "/":
- self.start_page(200)
- self.wfile.write(b"Welcome to Blender-Pipeline Http Server.\nUse /list/[Folder Name] to list contents of a specific folder.\nUse /download/[File Name] to download the file.\nUse /blend/[Blender File Name] to see Blend File Dependencies.")
- elif self.path.startswith("/list/"):
-
- foldername = self.path[5:]
- folder = PROJECT+foldername
-
- walk = list(os.walk(folder))[0]
- # folders
- data = {"folders":walk[1],
- "files":{}}
-
- for i in walk[2]:
- fd = fileinfo(folder+"/"+i)
- data["files"][i] = fd
-
- senddata = json.dumps(data).encode("utf-8")
- self.start_page(200)
- self.send_header('Content-type', 'application/json')
- self.end_headers()
- self.wfile.write(senddata)
- # THIS WAS A GOOD IDEA ON PAPER, BUT WITH A 100 GB PROJECT
- # IT TOOK FOREVER TO DO THIS FOR ONE PART OF THIS PROJECT.
-
- # elif self.path.startswith("/tree/"):
- # foldername = self.path[5:]
- # folder = PROJECT+foldername
-
- # walk = list(os.walk(folder))
- # data = {"folders":[],
- # "files":{}}
- # for i in walk:
- # fol = i[0].replace(PROJECT, "")[1:]
- # data["folders"].append(fol)
- # for fil in i[2]:
-
- # fd = fileinfo(PROJECT+"/"+fol+"/"+fil)
- # data["files"][fol+"/"+fil] = fd
- # senddata = json.dumps(data).encode("utf-8")
- # self.start_page(200)
- # self.send_header('Content-type', 'application/json')
- # self.end_headers()
- # self.wfile.write(senddata)
-
- elif self.path.startswith("/blend/"):
- filename = self.path[6:]
- fullfilename = PROJECT+filename
-
- if os.path.exists(fullfilename):
- try:
- linked = subprocess.check_output([blender, "-b", fullfilename, "-P", os.getcwd()+"/network/get_linked_files.py"]).decode("utf-8")
- except:
- linked = ""
- linked = linked[linked.find("!START_DATA!")+13:linked.rfind("!END_DATA!")]
- linked = linked.split("\n")
- while "" in linked:
- linked.remove("")
- parsed = []
- for i in linked:
- # This is a little weird, sometimes the files have the full URL
- # to the data.
-
- if i.startswith(PROJECT): # This is good when the server is on the same machine as the orignal project
- parsed.append(i[len(PROJECT):])
- elif i.startswith(ORIGINAL_PROJECT): # This is when the server is a mirror
- parsed.append(i[len(ORIGINAL_PROJECT):])
-
- else:
- backward = i.count("/..")
- foldername = filename[:filename.rfind("/")]
- f = foldername
- for g in range(backward):
- f = f[:f.rfind("/")]
- cleanname = f+i.replace("//..", "").replace("/..", "").replace( "//", "/")
- parsed.append(cleanname)
- data = {"files":{}}
- for f in parsed:
- try:
- fd = fileinfo(PROJECT+"/"+f)
- data["files"][f] = fd
- except Exception as e:
- print(e)
-
- linked = json.dumps(data)
-
- self.start_page(200)
- self.send_header('Content-type', 'application/json')
- self.end_headers()
- self.wfile.write(linked.encode("utf-8"))
- else:
- self.start_page(404)
- self.wfile.write(b"File: "+filename.encode("utf-8")+b" doesn't exist on server.")
-
- elif self.path.startswith("/download/"):
- filename = self.path[9:]
- fullfilename = PROJECT+filename
-
-
- if os.path.exists(fullfilename):
- self.start_page(200)
- self.send_header('Content-type', mimetypes.guess_type(filename))
- self.end_headers()
- f = open(fullfilename, "rb")
- f = f.read()
- self.wfile.write(f)
- else:
- self.start_page(404)
- self.wfile.write(b"File: "+filename.encode("utf-8")+b" doesn't exist")
-
- elif self.path.startswith("/download_z/"):
- filename = self.path[11:]
- fullfilename = PROJECT+filename
-
-
- if os.path.exists(fullfilename):
- self.start_page(200)
- self.send_header('Content-type', mimetypes.guess_type(filename))
- f = open(fullfilename, "rb")
- f = f.read()
- z = zlib.compress(f)
- self.send_header('Content-length', len(z))
- self.end_headers()
-
- self.wfile.write(z)
- else:
- self.start_page(404)
- self.wfile.write(b"File: "+filename.encode("utf-8")+b" doesn't exist")
-
-
- try:
- PORT = int(sys.argv[1])
- except:
- print("Please specify a port number and then project folder.")
- exit()
- serve = HTTPServer(("", PORT), handler)
- serve.serve_forever()
|