2023-12-14 16:37:25 +01:00
# (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
2023-12-19 20:50:31 +01:00
import zlib
2023-12-14 16:37:25 +01:00
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 ( )
2023-12-20 14:56:09 +01:00
try :
ORIGINAL_PROJECT = sys . argv [ 3 ]
except :
print ( " Orignal Project Name Was Not Specified. " )
ORIGINAL_PROJECT = " not a folder that can exist "
2023-12-14 16:37:25 +01:00
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 ( " /.. " , " / " )
2023-12-16 22:17:56 +01:00
self . path = self . path . replace ( " // " , " / " )
2023-12-14 16:37:25 +01:00
if self . path == " / " :
self . start_page ( 200 )
self . wfile . write ( b " Welcome to Blender-Pipeline Http Server. \n Use /list/[Folder Name] to list contents of a specific folder. \n Use /download/[File Name] to download the file. \n Use /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 )
2023-12-17 21:28:27 +01:00
# 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)
2023-12-14 16:37:25 +01:00
elif self . path . startswith ( " /blend/ " ) :
filename = self . path [ 6 : ]
fullfilename = PROJECT + filename
2023-12-16 22:17:56 +01:00
2023-12-14 16:37:25 +01:00
if os . path . exists ( fullfilename ) :
2023-12-16 22:17:56 +01:00
try :
linked = subprocess . check_output ( [ blender , " -b " , fullfilename , " -P " , os . getcwd ( ) + " /network/get_linked_files.py " ] ) . decode ( " utf-8 " )
except :
linked = " "
2023-12-14 16:37:25 +01:00
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 :
2023-12-20 14:56:09 +01:00
# This is a little weird, sometimes the files have the full URL
# to the data.
2023-12-21 19:33:35 +01:00
if i . startswith ( PROJECT ) : # This is good when the server is on the same machine as the orignal project
2023-12-14 16:37:25 +01:00
parsed . append ( i [ len ( PROJECT ) : ] )
2023-12-20 14:56:09 +01:00
elif i . startswith ( ORIGINAL_PROJECT ) : # This is when the server is a mirror
parsed . append ( i [ len ( ORIGINAL_PROJECT ) : ] )
2023-12-14 16:37:25 +01:00
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 )
2023-12-16 22:17:56 +01:00
self . wfile . write ( b " File: " + filename . encode ( " utf-8 " ) + b " doesn ' t exist on server. " )
2023-12-14 16:37:25 +01:00
elif self . path . startswith ( " /download/ " ) :
filename = self . path [ 9 : ]
fullfilename = PROJECT + filename
2023-12-16 22:17:56 +01:00
2023-12-14 16:37:25 +01:00
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 )
2023-12-19 20:57:44 +01:00
self . wfile . write ( b " File: " + filename . encode ( " utf-8 " ) + b " doesn ' t exist " )
2023-12-14 16:37:25 +01:00
2023-12-19 20:50:31 +01:00
elif self . path . startswith ( " /download_z/ " ) :
2023-12-19 20:57:44 +01:00
filename = self . path [ 11 : ]
2023-12-19 20:50:31 +01:00
fullfilename = PROJECT + filename
if os . path . exists ( fullfilename ) :
self . start_page ( 200 )
self . send_header ( ' Content-type ' , mimetypes . guess_type ( filename ) )
2023-12-19 23:32:07 +01:00
2023-12-19 20:50:31 +01:00
f = open ( fullfilename , " rb " )
f = f . read ( )
z = zlib . compress ( f )
2023-12-19 23:32:07 +01:00
self . send_header ( ' Content-length ' , len ( z ) )
self . end_headers ( )
2023-12-19 20:50:31 +01:00
self . wfile . write ( z )
else :
self . start_page ( 404 )
2023-12-19 20:57:44 +01:00
self . wfile . write ( b " File: " + filename . encode ( " utf-8 " ) + b " doesn ' t exist " )
2023-12-19 20:50:31 +01:00
2023-12-14 16:37:25 +01:00
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 ( )