123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484 |
- # THIS FILE IS A PART OF VCStudio
- # PYTHON 3
- ##############################################################################
- # Not all users have the ability or the desire to run a complex Graphical UI
- # to do simple tasks in the project. For example Windows users have no ability
- # to run Gtk applications in general. Even tho I dislike Window and do not
- # condone the use of it. I don't want to make VCStudio completilly unusable
- # for them. For example let's say somebody will distribute a story.vcss file.
- # I want to give Windows users at least the ability to read the text of the
- # scene.
-
- # Also the console mode could be used for the rendering servers of big
- # studios. Where running a GUI is just not practical. They usually have a
- # terminal only installation. And so some kind of way of working with project
- # should be possible from the terminal.
- ##############################################################################
- import os
- import re
- import datetime
- import threading
- # Let's get a terminal size for prettier rendering.
- try:
- w, h = os.get_terminal_size()
- except:
- w, h, = 50,50
- from settings import settings
- from settings import talk
- from settings import oscalls
- from project_manager import pm_project
- from project_manager import pm_console
- # Studio
- from studio import analytics
- from studio import story
- from studio import studio_storyDeletionLayer
- from studio import studio_storyLayer
- from studio import studio_settingsLayer
- from studio import studio_assetLayer
- from studio import studio_analyticsLayer
- from studio import studio_scriptLayer
- from studio import studio_multiuserLayer
- # UI modules
- from UI import UI_testing
- from UI import UI_color
- from UI import UI_elements
- # Network
- from network import network_renders
- from network import network_multiuser
- from network import multiuser_terminal
- commands1 = [
- "help",# - returns this help
- "asset",# - choose and asset
- "assets",# - list existsing assets
- "scene",# - read a scene
- "scenes",# - lists available scenes
- "scenes_main_chain",# - list only scenes from the main chain
- "shot",# - choose a shot
- "shots",# - list shots of a given scene
- "file",# - open a file from a given asset or shot
- "files",# - list all files from a given asset or shot
- "multiuser_start",# - starts multiuser server for this project
- "multiuser_stop",# - stops multiuser
- "multiuser_users",# - list of users connected to multiuser
- "multiuser_message",# - message users on multiuser
- "vse",# - starts a vse file
- "vses",# - lists all vse files
- "render",# - render a given file from a shot
- "render_server",# - become a render server for users on multiuser
- "render_not_server",# - stop being a render server for users
- "eval", # - run a python expression
- "exit"
- ]
- pm_console.commands = commands1.copy()
- def cls():
- #cleaning the terminal
- os.system("clear")
-
-
- class make_win:
-
- # In order to make it work with all the standard functions build for the GUI
- # experience. Like export, multiuser and such. Yes multiuser will be supported
- # here fully. We have to be able to access the win.<anything> object. BUT
- # there is a rub. The win object is not really accesable from non Gtk system.
-
- # Because I had this genious idea to use already created Gtk.Window and just
- # add a bunch stuff to it in order to have a kind of global dictionary thing.
-
- def __init__(self, project):
-
- self.project = project
- def previous(win):
- win.previous = {}
- for i in win.current:
- if type(win.current[i]) == list or type(win.current[i]) is dict:
- win.previous[i] = win.current[i].copy()
- else:
- win.previous[i] = win.current[i]
-
-
- def run(project):
-
-
- win = make_win(project)
-
- # Setting up the global variables. (kinda)
- win.animations = {}
- win.previous = {}
- win.current = {}
- win.images = {}
- win.imageload = 0
- win.text = {}
- win.textactive = ""
- win.scroll = {}
- win.FPS = 0
- win.url = "story_editor"
- win.cur = "" # This will be used to get precicelly what asset / scene / shot we are in
- win.update = {"versions":{}}
- win.project = project
- win.out_dots = {}
- win.assets = {}
- win.szone = [[100,100],[100,100]] # Square drawn if selected more then one node.
- win.surround = { # And this is the list of the squares. Because it's not
- "frame":0, # as easy to do. See UI / UI_math / rectangle_surround()
- "rects":[] # for details of this implementation.
- }
- win.calllayer = False
- win.layercashe = {} # Here I gonna store layers that are inactive to speed up stuff
- win.checklists = {}
- win.blink = False # Cursor blinking thing.
- win.renders = {} # List of current active renders.
- win.undo_history = []
- win.undo_index = 0
- win.multiuser = {
- "server":False, # Whether we are connected to the server. And the server ID
- "userid":"", # The id of current user in the server
- "last_request": "", # The last request send to the server. ( for stopping bloat )
- "curs":{}, # The information about various items on other users machines.
- "request":[["story"]], # Requests done in UI space
- "users":{}, # List of users information Names, IPs etc.
- "messages":[], # List of messages
- "unread":0 , # Amount of unread messages
- "terminal":[], # The outputs from the server
- "asset_list_check":False, # Whether the initial update happened when connecting to the server
- "story_check":False, # Whether the first story check was done.
- "analytics_check":False
- }
-
- if pm_project.is_legacy(project):
- win.story = story.get_legacy(project)
- win.analytics = analytics.get_legacy(project)
- else:
- win.story = story.load(project)
- win.analytics = analytics.load(project)
-
- # Cashed tables
- win.color = UI_color.get_table()
- win.settings = settings.load_all()
-
- # Default values
- win.current["frame"] = 0
- win.current["testing"] = False
- win.current["LMB"] = False
- win.current["MMB"] = False
- win.current["RMB"] = False
- win.current["keys"] = []
- win.current["key_letter"] = ""
- win.current["scroll"] = [0,0]
- win.current["project"] = ""
- win.current["tool"] = "selection"
- win.current["draw_dot"] = "end"
- win.current["calls"] = {} # Calls. See sutdio/studio_dialogs.py
- win.current["script_find"] = [0,0]
- win.current["camera_arrived"] = False
-
- if "pointers" not in win.story:
- win.story["pointers"] = {} # List of text pointers per scene
-
- new_date_format = "%Y/%m/%d"
- today = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
- win.current["date"] = today # Don't even ask. I'm litteraly tired already.
-
- previous(win)
-
- # Version of the software
- win.version = 0.0
- try:
- vfile = open("settings/update.data")
- vfile = vfile.read()
- vfile = vfile.split("\n")
-
- for line in vfile:
- if line.startswith("VERSION "):
- win.version = float(line.replace("VERSION ", ""))
- break
- except:
- win.version = 0.0
-
- # FPS
- win.sFPS = datetime.datetime.now()
-
-
-
- cls()
-
-
- # The title thing in the top
-
- print("\033[1;33m\n "+win.analytics["name"]+"")
- print("\033[1;33m "+win.analytics["director"]+"")
- print("\033[1;33m "+win.analytics["status"]+" \n")
- progress_bar(win.analytics["fraction"])
- print()
-
-
- while True:
-
- # making sure Tab is doing autocomlete to the right functions
- pm_console.commands = commands1.copy()
-
- command = input("\033[1;35m : \033[1;m")
-
- ##############
-
- if command == "exit":
- cls()
- exit()
-
- ###### HELP ######
- elif command == "help":
-
- print("\033[1;32m"+talk.text("sc_help")+"\n")
-
- ##### ASSETS LIST ####
-
- elif command == "assets":
- for asset in network_multiuser.list_all_assets(win):
- print("\033[1;35m "+asset)
-
- ##### ASSET ACCESS #####
-
- elif command == "asset":
-
- pm_console.commands = pm_project.get_list()
-
- n = input("\033[1;33m : ")
-
- if os.path.exists(win.project+"/dev"+n) and n.count("/") == 2:
-
- win.cur = n
-
- t, cur, name = n.split("/")
-
- print("\033[1;33m\n "+talk.text(cur)+": "+name)
- progress_bar(story.get_asset_data(win, n)["fraction"])
- print()
-
-
- else:
- print("\033[1;31m"+talk.text("failed"))
-
- #### SCENES LIST ####
-
- elif command == "scenes":
- for scene in win.story["scenes"]:
- print("\033[1;35m "+scene)
-
- #### SCENES MAIN CHAIN LIST ####
-
- elif command == "scenes_main_chain":
- lastarrow = 'start'
- for i in win.story["arrows"]:
- if lastarrow == "end":
- break
- for arrow in win.story["arrows"]:
- if arrow[0] == lastarrow:
- lastarrow = arrow[1]
- if arrow[1] != "end":
- print("\033[1;35m "+arrow[1][1])
-
- ##### READ SCENE TEXT #####
-
- elif command == "scene":
-
- pm_console.commands = list(win.story["scenes"].keys())
-
- n = input("\033[1;33m : ")
-
-
-
- if n in win.story["scenes"]:
- win.cur = "/"+n
-
-
-
- # I want to have the full scene written to the terminal at this
- # point. Good that most terminals already support tiling. I don't
- # need to care about that. So let's do that.
-
- scene = win.story["scenes"][n]["shots"]
-
- buf = "\033[1;0m"
- lines = 0
-
- for block in scene:
-
-
- # For just text parts.
- if block[0] == "text_block":
- style = "\033[1;40m"
- else:
-
- # If It's a shot. I want the shot color marking
-
- shotis = block[1]
-
- rcolors = {
- "shot_1":"\033[1;41m",
- "shot_2":"\033[1;43m",
- "shot_3":"\033[1;46m",
- "shot_4":"\033[1;44m",
- "shot_5":"\033[1;42m"
- }
-
- # Getting the color. It's not always works.
-
- if "shot_colors" not in win.story:
- win.story["shot_colors"] = {}
-
- surl = "/"+n+"/"+shotis
-
- if surl not in win.story["shot_colors"]:
-
- win.story["shot_colors"][surl] = list(rcolors.keys())[len(win.story["shot_colors"]) % len(rcolors)]
-
- style = rcolors[win.story["shot_colors"][surl]]
-
- for text in block[-1]:
-
- # For just regular parts we have our regular text
-
- if text[0] == "text" or text[0] == "link":
-
- for line in re.split("(\n)",text[-1]):
-
- if line == "\n":
-
- while buf:
- print(buf[:w])
- buf = buf[w:]
- lines = lines + 1
- if lines + 8 > h:
- input("... "+talk.text("press_to_continue")+" ...")
- lines = 0
-
- buf = "\033[1;0m"
-
- else:
-
- if text[0] == "text":
- buf = buf + style + line + "\033[1;0m"
- else:
- buf = buf + "\033[1;45m" + line + "\033[1;0m"
-
- elif text[0] == "frase":
-
- while buf:
- print(buf[:w])
- buf = buf[w:]
- lines = lines + 1
- if lines + 8 > h:
- input("... "+talk.text("press_to_continue")+" ...")
- lines = 0
- buf = "\033[1;0m"
-
- if text[1][0] == "text":
- print(" "*int(w/2-len(text[1][-1])/2)+"\033[1;40m"+text[1][-1])
- else:
- print(" "*int(w/2-len(text[1][-1])/2)+"\033[1;45m"+text[1][-1]+"\033[1;40m")
-
-
- for line in re.split("(\n)",text[-1]):
- if line == "\n":
- print(line)
-
- else:
- while line:
- print(" "*int(w/3)+style+line[:int(w/3)])
- line = line[int(w/3):]
- lines = lines + 1
- if lines + 8 > h:
- input("... "+talk.text("press_to_continue")+" ...")
- lines = 0
-
- while buf:
- print(buf[:w])
- buf = buf[w:]
- lines = lines + 1
- if lines + 8 > h:
- input("... "+talk.text("press_to_continue")+" ...")
- lines = 0
-
- print()
- print("\033[1;33m\n "+n)
- progress_bar(win.story["scenes"][n]["fraction"])
- print()
-
- else:
- print("\033[1;31m"+talk.text("failed"))
-
-
- ### FILES ###
-
- elif command == "files":
-
- prefix = "/rnd"
- for i in ["/chr", "/veh", "/obj","/loc"]:
- if win.cur.startswith(i):
- prefix = "/dev"
-
- for i in network_multiuser.get_give_folder_list(win.project, prefix+win.cur):
- print("\033[1;35m "+i[0])
-
- elif command == "file":
- n = input("\033[1;33m : ")
- oscalls.Open(win.project+n)
-
- ### EVAL ###
-
- elif command == "eval":
- n = input("\033[1;33m : ")
- try:
- print("\033[1;33m"+str(eval(n)))
- except Exception as e:
- print("\033[1;31m"+talk.text("failed")+" : "+str(e))
-
-
- #### NOT IMPLEMENTED YET ####
-
- elif command in pm_console.commands:
- print("\033[1;31m"+talk.text("failed")+" : Not Implemented Yet")
-
-
- ## FAIL ##
-
- elif command != "":
- print("\033[1;31m"+talk.text("failed"))
-
-
-
- def progress_bar(f):
- # This function will print out a progress bar similar to
-
- # [ ############################.................................. ]
-
- bw = w-6
- pw = int(round(bw*f))
- lw = bw - pw
-
- print(" [ "+"#"*pw+"."*lw+" ] ")
-
-
|