def run(self): d = datetime.datetime.today() current_date = d.strftime('%d-%m-%Y %H:%M:%S') for index, row in self.data_frame.iterrows(): if row['Status'] == 'Tagged': from_file = row['Filepath'] to_file = row['Publish_Filepath'] if row['Filetype'] == 'folder': print 'Copying %s to %s' % (from_file, to_file) # Send this to the Preflights - No matter what basically if not self.test: cgl_copy(from_file, to_file) CreateProductionData(to_file, json=True) self.shared_data['file_tree'].model.item(index, STATUS).setText('Published') self.signal_one.emit([index, STATUS, 'Published']) self.data_frame.at[index, 'Status'] = 'Published' self.data_frame.at[index, 'Publish_Date'] = current_date row['Publish_Date'] = current_date row['Status'] = 'Published' self.make_source_file(to_file, row) elif row['Filetype'] == 'sequence': to_dir = os.path.dirname(to_file) if not self.test: CreateProductionData(to_dir) file_sequence, self.shared_data['frange'] = split_sequence_frange(from_file) from_query = split_sequence(from_file) from_filename = os.path.split(file_sequence)[-1] self.shared_data['published_seq'] = os.path.join(to_dir, from_filename) for f in glob.glob('%s*' % from_query): to_file = os.path.join(to_dir, os.path.basename(f)) print 'Copying %s to %s' % (f, to_file) if not self.test: cgl_copy(f, to_file) self.shared_data['file_tree'].model.item(index, STATUS).setText('Published') self.data_frame.at[index, 'Status'] = 'Published' self.data_frame.at[index, 'Publish_Date'] = current_date row['Publish_Date'] = current_date row['Status'] = 'Published' self.make_source_file(to_dir, row) else: print 'FILETYPE =', row['Filetype'] if not self.test: print 'Copying %s to %s' % (from_file, to_file) CreateProductionData(os.path.dirname(to_file)) cgl_copy(from_file, to_file) self.shared_data['publish_file'] = to_file self.shared_data['file_tree'].model.item(index, STATUS).setText('Published') self.data_frame.at[index, 'Status'] = 'Published' self.data_frame.at[index, 'Publish_Date'] = current_date row['Publish_Date'] = current_date row['Status'] = 'Published' self.make_source_file(to_file, row) self.pass_check('Check Passed') print self.shared_data['publish_file'] if not self.test: self.save_data_frame()
def do_create_project(progress_bar, path_object, production_management): CreateProductionData(path_object=path_object.path_root, file_system=True, project_management=production_management) print 'setting project management to %s' % production_management create_project_config(path_object.company, path_object.project) progress_bar.hide()
def on_create_project(self): if self.title == 'Projects': progress_bar = self.parent().progress_bar dialog = CreateProjectDialog(parent=None, variable='project') dialog.exec_() if dialog.button == 'Ok': project_name = dialog.proj_line_edit.text() self.path_object.set_attr(project=project_name) production_management = dialog.proj_management_combo.currentText( ) print self.path_object.path_root print production_management process_method(progress_bar, self.do_create_project, args=(progress_bar, self.path_object, production_management), text='Creating Project') self.path_object.set_attr(project='*') self.update_location() elif self.title == 'Companies': dialog = InputDialog(title='Create Company', message='Enter the name for the company:', line_edit=True) dialog.exec_() if dialog.button == 'Ok': company = dialog.line_edit.text() self.path_object.set_attr(company=company) CreateProductionData(self.path_object, project_management='lumbermill') self.load_companies()
def create_gif_thumb(sequence, ext='gif', width='100', height='x100', do_height=True, verbose=True): if do_height: res = height else: res = width path_object = PathObject(sequence) new_res = 'gif' path_object_output = path_object.copy(resolution=new_res) output_dir = os.path.dirname(path_object_output.path_root) out_seq = '' command = '' if not os.path.exists(output_dir): CreateProductionData(path_object=output_dir, project_management=False) if '####' in sequence: in_seq = '%s*.%s' % (split_sequence(sequence), path_object.ext) out_seq = '%s/%sthumb.%s' % ( output_dir, os.path.basename(split_sequence(sequence)), ext) command = '%s %s -resize %s %s' % (CONFIG['magick'], in_seq, res, out_seq) if command: cgl_execute(command, verbose=verbose) return out_seq
def create_proxy(sequence, ext='jpg', verbose=True, methodology='local'): """ Creates a Jpeg proxy resolution based off the resolution of the given path. :param sequence: :param ext: :param project_management: :return: """ out_seq = '' path_object = PathObject(sequence) start_frame = get_start_frame(sequence) new_res = '%s%s' % (path_object.resolution, 'Proxy') path_object_output = path_object.copy(resolution=new_res, ext='jpg') output_dir = os.path.dirname(path_object_output.path_root) if not os.path.exists(output_dir): CreateProductionData(path_object=output_dir, project_management=False) if '####' in sequence: # replace ### with "*" number = hash_to_number(sequence)[-1] in_seq = '%s*.%s' % (split_sequence(sequence), path_object.ext) out_seq = '%s/%s%s.%s' % (output_dir, os.path.basename( split_sequence(sequence)), number, ext) command = '%s %s -scene %s %s' % (CONFIG['magick'], in_seq, start_frame, out_seq) run_dict = cgl_execute(command, methodology=methodology, verbose=verbose) run_dict['file_out'] = out_seq write_to_cgl_data(run_dict) return run_dict
def new_files_dragged(self, files): to_object = PathObject(self.sender().to_object) to_folder = to_object.path_root for f in files: file_ = os.path.split(f)[-1] to_file = os.path.join(to_folder, file_) if '.' in file_: logging.info('Copying %s to %s' % (f, to_file)) cgl_copy(f, to_file) CreateProductionData(path_object=to_object) self.on_task_selected(self.version_obj) else: logging.info('Copying directory %s to %s' % (f, to_file)) cgl_copy(f, to_file) CreateProductionData(path_object=to_object) self.on_task_selected(self.version_obj)
def version_up_selected_clicked(self): current = PathObject(self.current_location) # current location needs to have the version in it. next_minor = current.new_minor_version_object() next_minor.set_attr(filename='') next_minor.set_attr(resolution=self.current_location['resolution']) next_minor.set_attr(ext='') CreateProductionData(next_minor) cgl_copy(os.path.dirname(current.path_root), next_minor.path_root) # reselect the original asset. self.on_task_selected(next_minor)
def new_empty_version_clicked(self): """ Action when "Empty Version" is clicked :return: """ current = PathObject(self.version_obj) next_minor = current.new_minor_version_object() next_minor.set_attr(filename='') next_minor.set_attr(ext='') CreateProductionData(next_minor, create_default_file=True) self.on_task_selected(next_minor)
def ingest_folder(self, index, row, from_file, to_file, current_date): print 'Copying %s to %s' % (from_file, to_file) # Send this to the Preflights - No matter what basically if not self.test: cgl_copy(from_file, to_file, methodology=METHODOLOGY) CreateProductionData(to_file, json=True) self.data_frame.at[index, 'Status'] = 'Published' self.data_frame.at[index, 'Publish_Date'] = current_date row['Publish_Date'] = current_date row['Status'] = 'Published' self.make_source_file(to_file, row)
def ingest_file(self, index, row, from_file, to_file, current_date): print 'FILETYPE =', row['Filetype'] if not self.test: print 'Copying %s to %s' % (from_file, to_file) CreateProductionData(os.path.dirname(to_file)) cgl_copy(from_file, to_file, methodology=METHODOLOGY) self.shared_data['publish_path_object'] = PathObject(to_file) self.data_frame.at[index, 'Status'] = 'Published' self.data_frame.at[index, 'Publish_Date'] = current_date row['Publish_Date'] = current_date row['Status'] = 'Published' self.make_source_file(to_file, row)
def on_create_company(self): dialog = InputDialog(title='Create Company', message='Enter the name for the company:', line_edit=True) dialog.exec_() if dialog.button == 'Ok': company = dialog.line_edit.text() self.path_object.set_attr(company=company) CreateProductionData(self.path_object, project_management='lumbermill') self.load_companies()
def on_create_clicked(self): for each in self.tasks: if self.scope == 'assets': self.path_object.set_attr( asset=self.asset_widget.name_row.combo.currentText()) self.path_object.set_attr(type=self.seq) elif self.scope == 'shots': self.path_object.set_attr( shot=self.asset_widget.name_row.combo.currentText()) self.path_object.set_attr(seq=self.seq) self.path_object.set_attr(task=each) CreateProductionData(self.path_object.data, project_management=self.project_management) self.accept() self.close()
def ingest_sequence(self, index, row, from_file, to_file, current_date): to_dir = os.path.dirname(to_file) if not self.test: CreateProductionData(to_dir) from_filename = os.path.split(from_file)[-1] self.shared_data['publish_path_object'] = PathObject( os.path.join(to_dir, from_filename)) print 'Copying sequence %s to %s' % (from_file, to_dir) seq = self.shared_data['publish_path_object'].seq shot = self.shared_data['publish_path_object'].shot info_ = cgl_copy(from_file, to_dir, methodology=METHODOLOGY, job_name='%s_%s' % (seq, shot)) self.shared_data['copy_job_id'] = info_['job_id'] self.data_frame.at[index, 'Status'] = 'Published' self.data_frame.at[index, 'Publish_Date'] = current_date row['Publish_Date'] = current_date row['Status'] = 'Published' self.make_source_file(to_dir, row)
def on_create_asset(self): if self.current_location['scope'] == 'IO': dialog = InputDialog(self, title='Create Input Company', message='Enter the CLIENT or name of VENDOR', combo_box_items=['CLIENT']) dialog.exec_() self.current_location[ 'ingest_source'] = dialog.combo_box.currentText() ingest_source_location = PathObject( self.current_location).path_root if ingest_source_location.endswith(dialog.combo_box.currentText()): CreateProductionData(self.current_location, json=False) else: from apps.lumbermill.elements import asset_creator if 'asset' in self.current_location: task_mode = True else: task_mode = False dialog = asset_creator.AssetCreator( self, path_dict=self.current_location, task_mode=task_mode) dialog.exec_()
def on_assign_button_clicked(self, data): print data task = self.sender().task users_dict = CONFIG['project_management'][ self.project_management]['users'] all_users = [] for each in users_dict.keys(): all_users.append(each.lower()) dialog = InputDialog(title="%s Task Ownership" % task, combo_box_items=users_dict.keys(), message='Who are you assigning this Task?', buttons=['Cancel', 'Start']) index = dialog.combo_box.findText(current_user().lower()) if index != -1: dialog.combo_box.setCurrentIndex(index) dialog.exec_() if dialog.button == 'Start': selected_user = dialog.combo_box.currentText( ) # this denotes the OS login name of the user print selected_user user_info = CONFIG['project_management'][ self.project_management]['users'][selected_user] self.path_object.set_attr(task=task) self.path_object.set_attr(user=selected_user) self.path_object.set_attr(version='000.000') self.path_object.set_attr(resolution='high') self.path_object.set_attr(shot=data.shot) self.path_object.set_attr(seq=data.seq) self.path_object.set_attr(filename=None) self.path_object.set_attr(ext=None) self.path_object.set_attr(filename_base=None) CreateProductionData(path_object=self.path_object, project_management=self.project_management, user_login=user_info['login'], force_pm_creation=True) self.update_task_location(path_object=self.path_object)
def run(self): d = datetime.datetime.today() current_date = d.strftime('%d-%m-%Y %H:%M:%S') # This is publishing EVERYTHING, what about the scenario when we don't want that? # can i get the selected row only? for index, row in self.data_frame.iterrows(): if row['Filename'] == self.current_selection[0][0]: if row['Status'] == 'Tagged': from_file = row['Filepath'] to_file = row['Publish_Filepath'] # What to do if it's a Folder if row['Filetype'] == 'folder': print 'Copying %s to %s' % (from_file, to_file) # Send this to the Preflights - No matter what basically if not self.test: cgl_copy(from_file, to_file) CreateProductionData(to_file, json=True) self.shared_data['file_tree'].model.item( index, STATUS).setText('Published') # noinspection PyUnresolvedReferences # self.data_frame.at[index, 'Status'] = 'Published' # self.data_frame.at[index, 'Publish_Date'] = current_date row['Publish_Date'] = current_date row['Status'] = 'Published' self.make_source_file(to_file, row) # What to do with Sequences: else: to_dir = os.path.dirname(to_file) if row['Filetype'] == 'sequence': print '2, Sequence' if not self.test: print 'Creating Directory: %s' % to_dir CreateProductionData(to_dir) file_sequence, self.shared_data[ 'frange'] = split_sequence_frange(from_file) from_query = split_sequence(from_file) from_filename = os.path.split(file_sequence)[-1] self.shared_data['published_seq'] = os.path.join( to_dir, from_filename) for f in glob.glob('%s*' % from_query): to_file = os.path.join(to_dir, os.path.basename(f)) print 'Copying %s to %s' % (f, to_file) if not self.test: cgl_copy(f, to_file) # self.shared_data['file_tree'].model.item(index, STATUS).setText('Published') self.data_frame.at[index, 'Status'] = 'Published' self.data_frame.at[ index, 'Publish_Date'] = current_date row['Publish_Date'] = current_date row['Status'] = 'Published' self.make_source_file(to_dir, row) else: print '4 File' print 'Copying %s to %s' % (from_file, to_file) if not self.test: print 'Creating File: %s' % to_file CreateProductionData(to_file, json=True) cgl_copy(from_file, to_file) # self.shared_data['file_tree'].model.item(index, STATUS).setText('Published') self.data_frame.at[index, 'Status'] = 'Published' self.data_frame.at[index, 'Publish_Date'] = current_date row['Publish_Date'] = current_date row['Status'] = 'Published' self.make_source_file(to_file, row) self.save_data_frame() self.pass_check('Check Passed') else: print 'Skipping Untagged assets'
def create_movie_thumb(input_file, output_file=None, frame='middle', thumb=True, methodology='local', dependent_job=None): """ Create a thumbnail from a movie file. :param input_file: path to mov :param output_file: output file (jpg) :param frame: first, middle, or last :param thumb: Default value is True, this pulls the thumbnail resolution from the settings. :return: """ path_object = PathObject(input_file) if not output_file: if '.preview' in input_file: output_file.replace('.preview', '.thumb') else: output_file = PathObject(path_object=input_file).copy( resolution='thumb', ext='jpg').path_root if not output_file.endswith('.jpg'): file_ = os.path.splitext(output_file)[0] output_file = '%s.%s' % (file_, 'jpg') if os.path.exists(output_file): os.remove(output_file) if not os.path.exists(os.path.dirname(output_file)): CreateProductionData(os.path.dirname(output_file), project_management='lumbermill') if get_file_type(input_file) == 'movie': if thumb: res = get_thumb_res(input_file) res.replace('x', ':') if not res: logging.warning('problem with thumbnail resolution algorithm') res = settings['resolution']['thumb_cine'] else: res = settings['resolution']['image_review'].replace('x', ':') # This command will just use ffmpeg's default thumbnail generator command = '%s -i %s -vf "thumbnail,scale=%s" ' \ '-frames:v 1 %s' % (CONFIG['ffmpeg'], input_file, res, output_file) if command: run_dict = cgl_execute(command, verbose=True, methodology=methodology, command_name='%s_%s: create_mov_thumb' % (path_object.seq, path_object.shot), Wait=dependent_job) run_dict['file_out'] = output_file write_to_cgl_data(run_dict) return run_dict else: if get_file_type(input_file) == 'sequence': first_frame, middle_frame, end_frame = get_first_frame(input_file) if frame == 'middle': input_file = middle_frame elif frame == 'first': input_file = first_frame elif frame == 'last': input_file = end_frame # create the thumbnail # output_file = output_file.replace('####', 'seq') if thumb: res = thumb_res else: res = settings['resolution']['image_review'] # command = r"%s %s --fit %s --ch R,G,B -o %s" % (CONFIG['oiiotool'], input_file, res, output_file) command = '%s %s -resize %s %s' % (CONFIG['magick'], input_file, res, output_file) run_dict = cgl_execute(command, verbose=True, methodology=methodology, Wait=dependent_job) run_dict['file_out'] = output_file write_to_cgl_data(run_dict) return run_dict
def publish(path_obj): """ Requires a path with render folder with existing data. Creates the next major version of the "USER" directory and copies all source & render files to it. Creates the Next Major Version of the "PUBLISH" directory and copies all source & render files to it. As a first step these will be the same as whatever is the highest directory. :param path_obj: this can be a path object, a string, or a dictionary :return: boolean depending on whether publish is successful or not. """ # TODO this could be integrated with PathObject more elegantly import logging from cgl.core.utils.general import cgl_copy path_object = PathObject(path_obj) filename = path_object.filename resolution = path_object.resolution ext = path_object.ext # remove filename and ext to make sure we're dealing with a folder path_object = path_object.copy(filename='', ext='', resolution='') user = path_object.user if user != 'publish': if path_object.context == 'source': source_object = path_object render_object = PathObject.copy(path_object, context='render') else: source_object = PathObject.copy(path_object, context='source') render_object = path_object # Get the Right Version Number source_next = source_object.next_major_version() render_next = render_object.copy(version=source_next.version) source_pub = source_next.copy(user='******') render_pub = render_next.copy(user='******') for each in os.listdir(source_object.path_root): logging.info( 'Copying Source Resolution %s from %s to %s' % (each, source_object.path_root, source_next.path_root)) logging.info('Copying Source Resolution %s from %s to %s' % (each, source_object.path_root, source_pub.path_root)) cgl_copy(os.path.join(source_object.path_root, each), os.path.join(source_next.path_root, each)) cgl_copy(os.path.join(source_object.path_root, each), os.path.join(source_pub.path_root, each)) for each in os.listdir(render_object.path_root): logging.info( 'Copying Render Resolution %s from %s to %s' % (each, render_object.path_root, render_next.path_root)) logging.info('Copying Render Resolution %s from %s to %s' % (each, render_object.path_root, render_pub.path_root)) cgl_copy(os.path.join(render_object.path_root, each), os.path.join(render_next.path_root, each)) cgl_copy(os.path.join(render_object.path_root, each), os.path.join(render_pub.path_root, each)) # Register with Production Management etc... CreateProductionData(source_next) CreateProductionData(source_pub) return render_pub.copy(filename=filename, resolution=resolution, ext=ext) return False
def do_review(progress_bar=None, path_object=None): import shutil import logging from cgl.core.utils.general import cgl_copy from cgl.ui.widgets.dialog import InputDialog job_id = None if not path_object: print 'No Valid PathObject() found for review' return None else: selection = path_object selection.set_preview_path() selection.set_hd_proxy_path() # selection.set_path() if os.path.isdir(selection.path_root): print 'Choose a sequence or file' return if not os.path.exists(selection.preview_path): print('No Web Preview Found, creating one') job_info = selection.make_preview() job_id = job_info['job_id'] if selection.context == 'render': # lin_images = ['exr', 'dpx'] # LUMBERMILL REVIEWS if PROJ_MANAGEMENT == 'lumbermill': # do this for movies print 'Lumbermill Not connected to review features' # FTRACK REVIEWS elif PROJ_MANAGEMENT == 'ftrack': if selection.filename: if selection.file_type == 'folder' or not selection.file_type: dialog = InputDialog( title='Error: unsupported folder or file_type', message= "%s is a folder or undefined file_type\nunsure how to proceed" % selection.filename) dialog.exec_() if dialog.button == 'Ok' or dialog.button == 'Cancel': dialog.accept() return else: selection.upload_review(job_id=job_id) # CreateProductionData(selection) else: print('Select file for Review') elif PROJ_MANAGEMENT == 'shotgun': if selection.filename: if selection.file_type == 'folder' or not selection.file_type: dialog = InputDialog( title='Error: unsupported folder or file_type', message= "%s is a folder or undefined file_type\nunsure how to proceed" % selection.filename) dialog.exec_() if dialog.button == 'Ok' or dialog.button == 'Cancel': dialog.accept() return else: if os.path.exists(selection.preview_path): print 1 CreateProductionData(path_object=selection) else: selection.upload_review(job_id=job_id) else: print('Select file for Review') else: print('%s is an unknown project management type' % PROJ_MANAGEMENT) selection.set_attr(filename='') selection.set_attr(ext='') else: dialog = InputDialog(title="Prep for Review", message="Move or copy files to review area?", buttons=['Move', 'Copy']) dialog.exec_() move = False if dialog.button == 'Move': move = True if selection.file_type == 'sequence': # sequence_name = selection.filename from_path = os.path.dirname(selection.path_root) to_object = PathObject(from_path) to_object.set_attr(context='render') for each in os.listdir(from_path): from_file = os.path.join(from_path, each) to_file = os.path.join(to_object.path_root, each) if move: shutil.move(from_file, to_file) else: cgl_copy(from_file, to_file) selection.set_attr(filename='') selection.set_attr(ext='') else: to_object = PathObject.copy(selection, context='render') logging.info('Copying %s to %s' % (selection.path_root, to_object.path_root)) if move: shutil.move(selection.path_root, to_object.path_root) else: cgl_copy(selection.path_root, to_object.path_root) selection.set_attr(filename='') selection.set_attr(ext='') if progress_bar: progress_bar.hide() return True
def create_hd_proxy(sequence, output=None, mov=None, ext='jpg', width='1920', height='x1080', do_height=False, start_frame=None, verbose=True, methodology='local', dependent_job=None): """ Create HD Proxy Sequence from a givein image sequence. :param sequence: :param output: :param mov: :param ext: :param width: :param height: :param do_height: :param start_frame: :param verbose: :param methodology: :param dependent_job: :return: """ if do_height: res = height else: res = width path_object = PathObject(sequence) path_object.set_file_type() hashes = '' fileout = '' out_seq = '' command = '' number = '' if not output: logging.info('No output defined for create_hd_proxy') else: path_object_output = None output_dir = os.path.dirname(output) if path_object.file_type == 'sequence': # replace ### with "*" if '##' in sequence: hashes, number = hash_to_number(sequence) elif '%0' in sequence: hashes, number = number_to_hash(sequence) in_seq = '%s*.%s' % (split_sequence(sequence), path_object.ext) out_seq = '%s/%s%s.%s' % (output_dir, os.path.basename( split_sequence(sequence)), number, ext) fileout = out_seq.replace(number, hashes) elif path_object.file_type == 'image': sequence = sequence try: path_object_output.set_attr(ext='jpg') fileout = path_object_output.path_root except AttributeError: this_ = os.path.splitext(output)[0] fileout = this_ + '.jpg' command = '%s %s -resize %s %s' % (CONFIG['magick'], sequence, res, fileout) if methodology == 'smedge': print "I'm sending this to smedge to start after %s" % dependent_job command = r'python %s -i %s' % (__file__, sequence) # set_process_time = r'"python %s -e True -j %s -k farm_processing_end"' % (util_file, '%SMEDGE_JOB_ID%') # run_dict = cgl_execute(command, command_name='create_hd_proxy', methodology=methodology, # Wait=dependent_job, WorkPostExecuteSuccessfulEvt=set_process_time) run_dict = cgl_execute(command, command_name='%s_%s: create_hd_proxy' % (path_object.seq, path_object.shot), methodology='smedge', Wait=dependent_job) run_dict['file_out'] = fileout write_to_cgl_data(run_dict) return run_dict if not start_frame: start_frame = get_start_frame(sequence) if path_object.file_type == 'sequence': command = '%s %s -scene %s -resize %s %s' % (CONFIG['magick'], in_seq, start_frame, res, out_seq) if not os.path.exists(output_dir): CreateProductionData(path_object=output_dir, project_management='lumbermill') run_dict = cgl_execute(command, verbose=verbose, methodology=methodology, command_name='%s_%s: create_hd_proxy' % (path_object.seq, path_object.shot), Wait=dependent_job) run_dict['file_out'] = fileout write_to_cgl_data(run_dict) print 'file_out: %s' % fileout return run_dict