I'm redesigning the thing so downloading of remote files would be optional.
This commit is contained in:
parent
d766371266
commit
5e7052b3ab
5 changed files with 430 additions and 35 deletions
|
@ -4,6 +4,7 @@
|
|||
import os
|
||||
import json
|
||||
import time
|
||||
import fnmatch
|
||||
import hashlib
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
|
@ -60,19 +61,19 @@ def down(win, website, filename, fsize=100000):
|
|||
|
||||
# If it is a blend file, we are in trouble.
|
||||
|
||||
if filename.endswith(".blend"):
|
||||
dp = go(win, website, "/blend"+filename)
|
||||
dplen = len(dp.get("files", {}))
|
||||
for f in dp.get("files", {}):
|
||||
try:
|
||||
hashis = hashlib.md5(open(win.project+f,'rb').read()).hexdigest()
|
||||
except:
|
||||
hashis = ""
|
||||
if hashis != dp.get("files", {}).get(f, {}).get("md5"):
|
||||
win.current["http-server"]["message"] = f[f.rfind("/")+1:]
|
||||
filesize = dp.get("files", {}).get(f, {}).get("filesize")
|
||||
print("trying to get:", f)
|
||||
pp = down(win, website, f, filesize)
|
||||
# if filename.endswith(".blend"):
|
||||
# dp = go(win, website, "/blend"+filename)
|
||||
# dplen = len(dp.get("files", {}))
|
||||
# for f in dp.get("files", {}):
|
||||
# try:
|
||||
# hashis = hashlib.md5(open(win.project+f,'rb').read()).hexdigest()
|
||||
# except:
|
||||
# hashis = ""
|
||||
# if hashis != dp.get("files", {}).get(f, {}).get("md5"):
|
||||
# win.current["http-server"]["message"] = f[f.rfind("/")+1:]
|
||||
# filesize = dp.get("files", {}).get(f, {}).get("filesize")
|
||||
# print("trying to get:", f)
|
||||
# pp = down(win, website, f, filesize)
|
||||
|
||||
# Making folder for the files
|
||||
|
||||
|
@ -99,6 +100,96 @@ def down(win, website, filename, fsize=100000):
|
|||
savef.close()
|
||||
|
||||
|
||||
def get_folder_info(win, folders, cur):
|
||||
|
||||
# This function gets an information of what files should be changed. And outputs
|
||||
# the found data into the the global win thing, so it could accessed later.
|
||||
|
||||
# Making sure we have the infrastructure.
|
||||
|
||||
print("Getting Update Info About Folders")
|
||||
website = win.analytics["remote-server-url"]
|
||||
|
||||
|
||||
if "remote-folder-data" not in win.current:
|
||||
win.current["remote-folder-data"] = {}
|
||||
|
||||
if cur not in win.current["remote-folder-data"]:
|
||||
win.current["remote-folder-data"][cur] = {"missing":{},
|
||||
"changed":{}}
|
||||
|
||||
def sort_file(filename, files, f):
|
||||
filedata = files.get(f, {})
|
||||
try:
|
||||
hashis = hashlib.md5(open(win.project+filename,'rb').read()).hexdigest()
|
||||
except:
|
||||
hashis = ""
|
||||
if not os.path.exists(win.project+filename):
|
||||
win.current["remote-folder-data"][cur]["missing"][filename] = filedata
|
||||
elif hashis != filedata.get("md5"):
|
||||
filedata["to_download"] = True
|
||||
win.current["remote-folder-data"][cur]["changed"][filename] = filedata
|
||||
|
||||
|
||||
# Part one: Getting all the data about the files.
|
||||
|
||||
for foldername in folders:
|
||||
|
||||
try:
|
||||
answer = go(win, website, "/list"+foldername)
|
||||
files = list(answer.get("files", {}).keys())
|
||||
for f in fnmatch.filter(files, folders.get(foldername, "*")):
|
||||
|
||||
# Now we need to figure out whether we have the file
|
||||
# , whether we don't even have it ,
|
||||
# or whether we have a different version.
|
||||
|
||||
fullfilename = foldername+"/"+f
|
||||
sort_file(fullfilename, answer.get("files", {}), f)
|
||||
|
||||
|
||||
|
||||
|
||||
except Exception as e:
|
||||
error = "Error: "+ str(e)
|
||||
print(error)
|
||||
|
||||
|
||||
# Part two: Unwrapping all the blend dependancies data.
|
||||
|
||||
# Here we are going to store blend file that were checked already.
|
||||
win.current["remote-folder-data"][cur]["blend_checked"] = []
|
||||
|
||||
# A function checking if we still have some unchecked .blends
|
||||
def not_checked():
|
||||
for t in ["missing", "changed"]:
|
||||
for i in win.current["remote-folder-data"][cur][t]:
|
||||
if i not in win.current["remote-folder-data"][cur]["blend_checked"] and i.endswith(".blend"):
|
||||
return i
|
||||
return False
|
||||
|
||||
nc = not_checked()
|
||||
|
||||
while nc:
|
||||
dp = go(win, website, "/blend"+nc)
|
||||
|
||||
for f in dp.get("files", {}):
|
||||
try:
|
||||
sort_file(f,
|
||||
dp.get("files", {}),
|
||||
f[f.rfind("/")+1:])
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
win.current["remote-folder-data"][cur]["blend_checked"].append(nc)
|
||||
|
||||
nc = not_checked()
|
||||
|
||||
for t in ["missing", "changed"]:
|
||||
print(t+":")
|
||||
for i in win.current["remote-folder-data"][cur][t]:
|
||||
print(" "+i)
|
||||
|
||||
def get_folders(win):
|
||||
|
||||
# This function will get specified subfolders
|
||||
|
@ -244,6 +335,7 @@ def get_files(win):
|
|||
try:
|
||||
hashis = hashlib.md5(open(win.project+filename,'rb').read()).hexdigest()
|
||||
except:
|
||||
print("missing", filename)
|
||||
hashis = ""
|
||||
|
||||
if hashis != answer.get("files", {}).get(i, {}).get("md5"):
|
||||
|
@ -386,3 +478,193 @@ def layer(win, call):
|
|||
10,)
|
||||
|
||||
return surface
|
||||
|
||||
def prompt_layer(win, call):
|
||||
|
||||
# Making the layer
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'],
|
||||
win.current['h'])
|
||||
layer = cairo.Context(surface)
|
||||
|
||||
|
||||
#text setting
|
||||
layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
|
||||
|
||||
UI_color.set(layer, win, "dark_overdrop")
|
||||
layer.rectangle(
|
||||
0,
|
||||
0,
|
||||
win.current["w"],
|
||||
win.current["h"],
|
||||
)
|
||||
layer.fill()
|
||||
|
||||
# So it's going to be like a little window in the center of the VCStudio
|
||||
# with a simple UI. Probably like 2 things. Folder and a projectname.
|
||||
|
||||
UI_color.set(layer, win, "node_background")
|
||||
UI_elements.roundrect(layer, win,
|
||||
win.current["w"]/2-350,
|
||||
100,
|
||||
700,
|
||||
win.current["h"]-200,
|
||||
10)
|
||||
|
||||
# Exit button
|
||||
def do():
|
||||
win.current["calls"][call]["var"] = False
|
||||
|
||||
|
||||
UI_elements.roundrect(layer, win,
|
||||
win.current["w"]/2+310,
|
||||
win.current["h"]-140,
|
||||
40,
|
||||
40,
|
||||
10,
|
||||
button=do,
|
||||
icon="cancel",
|
||||
tip=talk.text("cancel"))
|
||||
|
||||
# Clipping everything
|
||||
UI_elements.roundrect(layer, win,
|
||||
win.current["w"]/2-350,
|
||||
100,
|
||||
700,
|
||||
win.current["h"]-260,
|
||||
10,
|
||||
fill=False)
|
||||
layer.clip()
|
||||
|
||||
clip = [
|
||||
win.current["w"]/2-350,
|
||||
100,
|
||||
700,
|
||||
win.current["h"]-260]
|
||||
|
||||
# Setting up the scroll
|
||||
if "http-prompt" not in win.scroll:
|
||||
win.scroll["http-prompt"] = 0
|
||||
|
||||
cur = win.current["remote-folder-data"]["prompt"]
|
||||
|
||||
current_Y = 0
|
||||
|
||||
# Missing files
|
||||
|
||||
if "missing_active" not in win.current["remote-folder-data"][cur]:
|
||||
win.current["remote-folder-data"][cur]["missing_active"] = False
|
||||
|
||||
|
||||
|
||||
icon = "closed"
|
||||
if win.current["remote-folder-data"][cur]["missing_active"]:
|
||||
icon = "open"
|
||||
|
||||
def do():
|
||||
win.current["remote-folder-data"][cur]["missing_active"] = not win.current["remote-folder-data"][cur]["missing_active"]
|
||||
|
||||
|
||||
UI_elements.roundrect(layer, win,
|
||||
win.current["w"]/2-340,
|
||||
110 + current_Y + win.scroll["http-prompt"],
|
||||
680,
|
||||
40,
|
||||
10,
|
||||
button=do,
|
||||
icon=icon,
|
||||
tip=talk.text("MissingFiles"))
|
||||
|
||||
UI_color.set(layer, win, "text_normal")
|
||||
layer.set_font_size(20)
|
||||
layer.move_to(win.current["w"]/2-290,
|
||||
current_Y + win.scroll["http-prompt"] + 135)
|
||||
layer.show_text(talk.text("MissingFiles")+" ( "+str(len(win.current["remote-folder-data"][cur]["missing"]))+" ) ")
|
||||
|
||||
current_Y += 50
|
||||
|
||||
if win.current["remote-folder-data"][cur]["missing_active"]:
|
||||
for f in win.current["remote-folder-data"][cur]["missing"]:
|
||||
UI_color.set(layer, win, "text_normal")
|
||||
layer.set_font_size(20)
|
||||
layer.move_to(win.current["w"]/2-270,
|
||||
current_Y + win.scroll["http-prompt"] + 135)
|
||||
layer.show_text(f)
|
||||
|
||||
current_Y += 50
|
||||
|
||||
|
||||
# Updated files
|
||||
|
||||
if "changed_active" not in win.current["remote-folder-data"][cur]:
|
||||
win.current["remote-folder-data"][cur]["changed_active"] = True
|
||||
|
||||
|
||||
|
||||
icon = "closed"
|
||||
if win.current["remote-folder-data"][cur]["changed_active"]:
|
||||
icon = "open"
|
||||
|
||||
def do():
|
||||
win.current["remote-folder-data"][cur]["changed_active"] = not win.current["remote-folder-data"][cur]["changed_active"]
|
||||
|
||||
|
||||
UI_elements.roundrect(layer, win,
|
||||
win.current["w"]/2-340,
|
||||
110 + current_Y + win.scroll["http-prompt"],
|
||||
680,
|
||||
40,
|
||||
10,
|
||||
button=do,
|
||||
icon=icon,
|
||||
tip=talk.text("ChangedFiles"))
|
||||
|
||||
UI_color.set(layer, win, "text_normal")
|
||||
layer.set_font_size(20)
|
||||
layer.move_to(win.current["w"]/2-290,
|
||||
current_Y + win.scroll["http-prompt"] + 135)
|
||||
layer.show_text(talk.text("ChangedFiles")+" ( "+str(len(win.current["remote-folder-data"][cur]["changed"]))+" ) ")
|
||||
|
||||
current_Y += 50
|
||||
|
||||
if win.current["remote-folder-data"][cur]["changed_active"]:
|
||||
for f in win.current["remote-folder-data"][cur]["changed"]:
|
||||
|
||||
fdata = win.current["remote-folder-data"][cur]["changed"][f]
|
||||
|
||||
icon = "unchecked"
|
||||
if fdata["to_download"]:
|
||||
icon = "checked"
|
||||
|
||||
def do():
|
||||
fdata["to_download"] = not fdata["to_download"]
|
||||
|
||||
UI_elements.roundrect(layer, win,
|
||||
win.current["w"]/2-315,
|
||||
110 + current_Y + win.scroll["http-prompt"],
|
||||
660,
|
||||
40,
|
||||
10,
|
||||
button=do,
|
||||
icon=icon)
|
||||
|
||||
|
||||
UI_color.set(layer, win, "text_normal")
|
||||
layer.set_font_size(20)
|
||||
layer.move_to(win.current["w"]/2-270,
|
||||
current_Y + win.scroll["http-prompt"] + 135)
|
||||
layer.show_text(f)
|
||||
|
||||
current_Y += 50
|
||||
|
||||
UI_elements.scroll_area(layer, win, "http-prompt",
|
||||
int(win.current["w"]/2-350),
|
||||
100,
|
||||
700,
|
||||
win.current["h"]-260,
|
||||
current_Y,
|
||||
bar=True,
|
||||
mmb=True,
|
||||
url="http-server-prompt"
|
||||
)
|
||||
|
||||
return surface
|
||||
|
|
|
@ -116,7 +116,6 @@ class handler(BaseHTTPRequestHandler):
|
|||
"files":{}}
|
||||
|
||||
for i in walk[2]:
|
||||
|
||||
fd = fileinfo(folder+"/"+i)
|
||||
data["files"][i] = fd
|
||||
|
||||
|
@ -127,6 +126,30 @@ class handler(BaseHTTPRequestHandler):
|
|||
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:]
|
||||
|
|
|
@ -285,3 +285,6 @@ remote-update-initial-tip = [Download initial project files and replace
|
|||
the ones on the computer with
|
||||
the downloaded files.]
|
||||
remote-server-url = [The hostname of the remote server.]
|
||||
MissingFiles = [Missing Files]
|
||||
ChangedFiles = [Changed Files]
|
||||
RemoteAssetUpdates = [Remote Asset Updates]
|
|
@ -4,6 +4,7 @@
|
|||
# This a console project manager.
|
||||
|
||||
import os
|
||||
import threading
|
||||
|
||||
# GTK module ( Graphical interface
|
||||
import gi
|
||||
|
@ -144,21 +145,23 @@ def layer(win):
|
|||
def do():
|
||||
win.current["asset_cur_folder"] = cur
|
||||
|
||||
# Why?
|
||||
if win.current["asset_cur_folder"] == "idea":
|
||||
fl = "reference"
|
||||
elif win.current["asset_cur_folder"] == "texture":
|
||||
fl = "tex"
|
||||
elif win.current["asset_cur_folder"] == "render":
|
||||
fl = "renders"
|
||||
else:
|
||||
fl = ""
|
||||
# FUNCTIONS PER THINGS
|
||||
|
||||
# Remote Server Stuff
|
||||
if win.analytics["from-remote-server"]:
|
||||
def after(win, var):
|
||||
UI_elements.reload_images(win)
|
||||
studio_dialogs.http_client_dialog(win, "http-client", after, http_client.get_files, "/dev/"+win.cur+"/"+fl)
|
||||
# # Why?
|
||||
# if win.current["asset_cur_folder"] == "idea":
|
||||
# fl = "reference"
|
||||
# elif win.current["asset_cur_folder"] == "texture":
|
||||
# fl = "tex"
|
||||
# elif win.current["asset_cur_folder"] == "render":
|
||||
# fl = "renders"
|
||||
# else:
|
||||
# fl = ""
|
||||
|
||||
# # Remote Server Stuff
|
||||
# if win.analytics["from-remote-server"]:
|
||||
# def after(win, var):
|
||||
# UI_elements.reload_images(win)
|
||||
# studio_dialogs.http_client_dialog(win, "http-client", after, http_client.get_files, "/dev/"+win.cur+"/"+fl)
|
||||
|
||||
|
||||
UI_elements.roundrect(layer, win,
|
||||
|
@ -172,6 +175,48 @@ def layer(win):
|
|||
tip=talk.text(folds[cur]))
|
||||
|
||||
|
||||
# Little Remote Server thing
|
||||
if win.analytics["from-remote-server"]:
|
||||
|
||||
if "remote-folder-data" not in win.current:
|
||||
win.current["remote-folder-data"] = {}
|
||||
|
||||
if win.cur not in win.current["remote-folder-data"]:
|
||||
win.current["remote-folder-data"][win.cur] = {"missing":{},
|
||||
"changed":{}}
|
||||
|
||||
def do():
|
||||
|
||||
def after(win, var):
|
||||
UI_elements.reload_images(win)
|
||||
win.current["remote-folder-data"]["prompt"] = win.cur
|
||||
studio_dialogs.http_client_update_prompt(win, "http-client-prompt", after)
|
||||
|
||||
|
||||
UI_elements.roundrect(layer, win,
|
||||
win.current["w"]/4+60,
|
||||
350,
|
||||
40,
|
||||
40,
|
||||
10,
|
||||
do,
|
||||
"multiuser",
|
||||
tip=talk.text("RemoteAssetUpdates"))
|
||||
|
||||
if win.current["remote-folder-data"][win.cur]["missing"] or win.current["remote-folder-data"][win.cur]["changed"]:
|
||||
count = str(len(win.current["remote-folder-data"][win.cur]["missing"])+len(win.current["remote-folder-data"][win.cur]["changed"]))
|
||||
UI_color.set(layer, win, "progress_active")
|
||||
UI_elements.roundrect(layer, win,
|
||||
win.current["w"]/4+60+25,
|
||||
350,
|
||||
len(count)*12+6,
|
||||
25,
|
||||
5)
|
||||
layer.fill()
|
||||
UI_color.set(layer, win, "text_normal")
|
||||
layer.set_font_size(20)
|
||||
layer.move_to(win.current["w"]/4+60+28,370)
|
||||
layer.show_text(count)
|
||||
|
||||
|
||||
# Preview
|
||||
|
@ -439,12 +484,37 @@ def layer(win):
|
|||
"/dev"+win.cur+"/",
|
||||
name+".blend")
|
||||
|
||||
|
||||
# This is executed on the first frame when you click onto an asset.
|
||||
|
||||
if win.current["in-asset-remote-server"]:
|
||||
|
||||
# First we gonna change the active folder to view the Blend files.
|
||||
# This is important for the function for the remote server.
|
||||
win.current["asset_cur_folder"] = "blender"
|
||||
|
||||
# Let's also check for updates on the file
|
||||
|
||||
|
||||
|
||||
# Remote Server Stuff
|
||||
if win.analytics["from-remote-server"]:
|
||||
def after(win, var):
|
||||
UI_elements.reload_images(win)
|
||||
studio_dialogs.http_client_dialog(win, "http-client", after, http_client.get_asset_files, "/dev/"+win.cur+"/")
|
||||
|
||||
# Checking date [ FOLDER NAME ] [ FILES TO CHECK FOR ]
|
||||
check_folders = {"/dev"+win.cur : "*",
|
||||
"/ast/"+acur : name+"*",
|
||||
"/dev"+win.cur+"/renders" : "*",
|
||||
"/dev"+win.cur+"/reference" : "*",
|
||||
"/dev"+win.cur+"/tex" : "*",
|
||||
}
|
||||
|
||||
check_updates = threading.Thread(target=http_client.get_folder_info,
|
||||
args=(win, check_folders, win.cur, ))
|
||||
check_updates.setDaemon(True)
|
||||
check_updates.start()
|
||||
|
||||
|
||||
|
||||
|
||||
win.current["in-asset-remote-server"] = False
|
||||
|
||||
|
|
|
@ -365,3 +365,20 @@ def http_client_dialog(win, name, call, function, args=""):
|
|||
function_run = threading.Thread(target=function, args=(win,))
|
||||
function_run.setDaemon(True)
|
||||
function_run.start()
|
||||
|
||||
def http_client_update_prompt(win, name, call):
|
||||
|
||||
# This function is going to be the UI for http-client.
|
||||
|
||||
if name not in win.current["calls"]:
|
||||
win.current["calls"][name] = {
|
||||
"var" :None, # This is the variable that we are waiting for
|
||||
"call":call, # This is what it's going to run when it's done
|
||||
"url" :"http-server-prompt",
|
||||
"back":win.url,# This is where it's going to come back when it's done
|
||||
"draw":http_client.prompt_layer
|
||||
}
|
||||
|
||||
# Let's clear the LMB just in case
|
||||
win.previous["LMB"] = False
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue