def _attach_report_to_sg_entity(self, entity, report_pdf, report_type=None): """ Potentially generic proc to attach reports to a given entity :param entity: Shotgun Entity to attach report pdf to :param report_pdf: File path to the report pdf to attach :param report_type: Optional string to set the new Attachment's sg_type to """ # Make sure an id and type has been specified for the incoming Entity if not entity.get("id") or not entity.get("type"): return e_id = entity["id"] e_type = entity["type"] # Best guess at a name for the entity. Only used for informative messages. e_name = entity.get("code") or entity.get("name") or entity.get("display_name") or e_id e_msg = "%s report for [%s]" % (e_type, e_name) # Verify the input pdf exists on disk if not os.path.isfile(report_pdf): msg = ("Cannot upload %s. Report pdf [%s] does not exist." % (e_msg, report_pdf)) update_details(self._thread, msg) return # Attach the report to the specified entity and update the attachment # type if specified. update_details(self._thread, ("Uploading %s pdf [%s] ..." % (e_msg, os.path.basename(report_pdf)))) uploaded_id = self._app.shotgun.upload(e_type, e_id, report_pdf) if report_type and uploaded_id: update_details(self._thread, ("Setting Attachment.sg_type to [%s] ..." % report_type)) self._app.shotgun.update("Attachment", uploaded_id, {"sg_type": report_type})
def _build_standard_files(self, shots, turnover_type): """ Gathers relevant data from Shotgun and create a report for each input Shot :param shots: List of Shot entities to generate Turnover reports for """ pdfs = [] # Gather the relevant Entites from Shotgun update_details(self._thread, "Finding segments") self.findTurnoverSegments(shots) update_details(self._thread, "Finding versions") self.findTurnoverVersions(shots) update_details(self._thread, "Finding notes") self.findTurnoverNotes(shots) # Build a PDF report file for each input Shot. for shot in shots: update_details(self._thread, "Building %s PDF" % shot["code"]) # Determine the output file name for the PDF. Includes a time stamp # in the file name to prevent files from being overwritten. pdf_basename = "%s_%sTurnover_%s.pdf" % ( shot["code"], str(turnover_type).capitalize(), self._app.evaluate_template(self._date_time_format_templ)) shot_pdf = os.path.join(self._temp_dir, to_safe_file_name(pdf_basename)) # Build the PDF with reportlab mojo self.buildShotPDF(shot_pdf, shot) pdfs.append(shot_pdf) # Upload the report to the Shot for future reference. self._attach_report_to_sg_entity(shot, shot_pdf, "Turnover PDF") # Update the progress bar the user is looking at right now. self.progress_ct += 1 increment_progress(self._thread, self.progress_ct) return pdfs
def execute(self, app, thread, entity_type, entity_ids, progress_ct, destination_dir, report_hook_config): """ Main procedure that gets called by the Toolkit Menu Action created for this report. :param app: This Toolkit Application instance :param thread: Current thread this Hook is running in :param entity_type: Entity type of the incoming list of entity ids :param entity_ids: List of selected entity ids to process :param progress_ct: Progress counter corresponding to the progress bar displayed while this hook is running :param destination_dir: Output directory specified by the user when this hook was launched. :param report_hook_config: Settings dictionary for this report :returns: List or path to .zip archive of the created PDF files """ # Set some local variables used throughout the report generation # process. Similar to what would typically be set in __init__() self._downloaded_thumb_paths = {} self._segments_by_shot = {} self._versions_by_shot = {} self._notes_by_shot = {} self._app = app self._thread = thread self._destination_dir = destination_dir self._report_config = report_hook_config self._temp_dir = make_temp_dir() self._date_time_format_templ = self._app.sgtk.templates.get( self._report_config.get("date_time_format") ) self.progress_ct = progress_ct # Check to make sure this report can handle the selected entity type valid_types = self._report_config["valid_entity_types"] if entity_type not in valid_types: raise Exception, "Only %s entity type(s) are supported." % valid_types # Determine what type of turnover report this is turnover_type = str(report_hook_config.get("short_name")).split("_")[0] # grab shots update_details(self._thread, "Finding shots") shot_fields = [ "code", "project.Project.sg_release_title", "sg_turnover_notes___linked_field", ] if turnover_type == "plate": shot_fields.extend([ "sg_awarded_vendor", "sg_awarded_vendor.HumanUser.sg_vendor_code", ]) shots = find_entities_by_ids(self._app.shotgun, entity_type, entity_ids, shot_fields, []) # Load thumbnails to display in report, if ever requested. #update_details(self._thread, "Retrieving Shot thumbnails") #self._downloaded_thumb_paths["Shot"] = retrieve_thumbnails("Shot", shots, self._temp_dir) # Build the PDF files update_label(self._thread, "Building PDFs...") turnover_files = self._build_standard_files(shots, turnover_type) # Package them up zip_files = self._report_config.get("zip_all_files") or False return package_reports(self._destination_dir, turnover_files, self._temp_dir, create_zip=zip_files, zip_name="plate_turnovers.zip")