#!/usr/bin/env python3 # ***** BEGIN GPL LICENSE BLOCK ***** # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # ***** END GPL LICENCE BLOCK ***** """ Blender asset manager """ if __name__ != "__main__": raise Exception("must be imported directly") # ------------------ # Ensure module path import os import sys path = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "modules")) if path not in sys.path: sys.path.append(path) del os, sys, path # -------- class bam_config: # fake module __slots__ = () def __new__(cls, *args, **kwargs): raise RuntimeError("%s should not be instantiated" % cls) CONFIG_DIR = ".bam" @staticmethod def find_basedir(cwd=None): """ Return the config path (or None when not found) """ import os if cwd is None: cwd = os.getcwd() parent = (os.path.normpath( os.path.abspath( cwd))) parent_prev = None while parent != parent_prev: test_dir = os.path.join(parent, bam_config.CONFIG_DIR) if os.path.isdir(test_dir): return test_dir parent_prev = parent parent = os.path.dirname(parent) return None @staticmethod def load(id_, cwd=None): basedir = bam_config.find_basedir(cwd=cwd) filepath = os.path.join(basedir, id_) with open(filepath, 'r') as f: import json return json.load(f) @staticmethod def write(id_, data, cwd=None): bam_config.find_basedir(cwd=cwd) filepath = os.path.join(basedir, id_) with open(filepath, 'w') as f: import json json.dump( data, f, ensure_ascii=False, check_circular=False, # optional (pretty) sort_keys=True, indent=4, separators=(',', ': '), ) class bam_utils: # fake module __slots__ = () def __new__(cls, *args, **kwargs): raise RuntimeError("%s should not be instantiated" % cls) @staticmethod def session_find_url(): return "http://localhost:5000" @staticmethod def session_request_url(req_path): # TODO, get from config BAM_SERVER = bam_utils.session_find_url() result = "%s/%s" % (BAM_SERVER, req_path) return result @staticmethod def init(url, directory_name=None): import os import urllib parsed_url = urllib.parse.urlsplit(url) project_directory_name = os.path.basename(parsed_url.path) if directory_name: project_directory_name = directory_name project_directory_path = os.path.join(os.getcwd(), project_directory_name) # Create the project directory inside the current directory os.mkdir(project_directory_path) # Create the .bam folder bam_folder = os.path.join(project_directory_path, ".bam") os.mkdir(bam_folder) # Add a config file with project url, username and password with open(os.path.join(bam_folder, "config"), 'w') as f: import json json.dump( { "url":url, "user":"bam", "password":"bam", "config_version":1 }, f, # Pretty printing sort_keys=True, indent=4, separators=(',', ': ') ) print("Project %s initialized" % project_directory_name) @staticmethod def checkout(paths): import sys import os import requests # TODO(cam) multiple paths path = paths[0] del paths # TODO(cam) we may want to checkout a single file? how to handle this? # we may want to checkout a dir too dst_dir = os.path.basename(path) payload = { "filepath": path, "command": "checkout", } r = requests.get( bam_utils.session_request_url("file"), params=payload, auth=("bam", "bam"), stream=True, ) if r.status_code not in {200, }: # TODO(cam), make into reusable function? print("Error %d:\n%s" % (r.status_code, next(r.iter_content(chunk_size=1024)).decode('utf-8'))) return # TODO(cam) how to tell if we get back a message payload? or real data??? dst_dir_data = payload['filepath'].split('/')[-1] if 1: dst_dir_data += ".zip" with open(dst_dir_data, 'wb') as f: import struct ID_MESSAGE = 1 ID_PAYLOAD = 2 head = r.raw.read(4) if head != b'BAM\0': print("Bad header...") return while True: msg_type, msg_size = struct.unpack("