Пример #1
0
	def clkMakeMov(self, widget, event, data=None):
		if 0 == self.countPublish():
			self.Alert("Publish가 안된 샷이 있습니다. Publish 된 정보를 기준으로 MOV 생성작업을 하게 됩니다.")
			return False
		
		stereo_type = {"l" : "_left", "r" : "_right"}
		
		for list_row in ListStore.projShotStore:
			row_selected = list_row[const.COLUMN_CHOICE]
			
			if not row_selected:
				continue
			
			db_shot_record = self.datastore.getShotFromName(list_row[const.COLUMN_SHOTLIST]).first()
			
			original_width = int(db_shot_record.width)
			original_height = int(db_shot_record.height)
			
			half_width = original_width / 2
			half_height = original_height / 2
			
			thumbnail_width = 300
			thumbnail_height = int(float(original_height) / float(original_width) * thumbnail_width)
			
			new_shot_name = util.NewShotNameDict()
			new_shot_name["SEQ"] = "%s_" % db_shot_record.seq
			new_shot_name["SHOT_NUMBER"] = "%s_" % db_shot_record.shotnumber
			new_shot_name["TYPE"] = "plate_%s_" % db_shot_record.type
			new_shot_name["WIDTH"] = "%dx" % original_width
			new_shot_name["HEIGHT"] = "%d" % original_height
			new_shot_name["STEREO"] = "%s" % stereo_type.get(db_shot_record.isstereo, '')
			
			# New Shot Name
			if db_shot_record.type == "org": # (박성진 코디네이터 요청. 2012/02/20)
				del new_shot_name["TYPE"]
			
			newShotName = "".join(new_shot_name.values())
						
			if "myWay" == const.PROJECT:
				del new_shot_name["SEQ"]
				newShotName = "".join(new_shot_name.values())
			
			TypeDirectory = split(db_shot_record.publishpath)[0]
			ResolutionHalfDir = path_join(TypeDirectory, "%dx%d" % (half_width, half_height))
			ThumbnailDir = path_join(TypeDirectory, "thumbnail")
			
			tmp_mov_directory = path_join(TypeDirectory, ".%.2f" % time.time())
			
			if not exists(tmp_mov_directory):
				makedirs(tmp_mov_directory)
			
			JpegNuke = path_join(tmp_mov_directory, "%s_jpeg.nk" % newShotName)
			MovNuke = path_join(tmp_mov_directory, "%s_mov.nk" % newShotName)
			
			newFrameInfo = util.getNewFrame(db_shot_record.publishpath)
			
			dpx_files = glob("%s/%s.[0-9]*%s" % (db_shot_record.publishpath, newShotName, db_shot_record.fileformat))
			dpx_files.sort()
			
			middle_frame = len(dpx_files) / 2

			Thumbnail_FileName = "%s.jpg" % splitext(basename(dpx_files[middle_frame]))[0]

			thumb_fd = open(const.watch_thumb_file, "a")
			thumb_fd.write("%s\t%s\t%s\t%s\n" % (thumbnail_width, thumbnail_height, dpx_files[middle_frame], path_join(ThumbnailDir, Thumbnail_FileName)))
			thumb_fd.close()

			time.sleep(1)

			movie_src_ext = splitext(dpx_files[0])[1]
			
			# Mov Image
			nuke_helper.nuke_run(
					path_join(db_shot_record.publishpath, "%s.%%04d%s" % (newShotName, movie_src_ext)),
					db_shot_record.clipname,
					newShotName,
					1024,
					720,
					'%d-%d' % (newFrameInfo["START"], newFrameInfo["END"]),
					path_join(tmp_mov_directory, "%s.%%04d.jpg" % newShotName),
					JpegNuke,
					path_join("/local", "%s.mov" % newShotName),
					True,
					MovNuke
				)
			
			# Mov Alfred
			MovAlfred = tractor_script.tractorSubmission(
				(
					'<ScanDataTransfer> ReMOV - %s' % newShotName,
					newFrameInfo["START"],
					newFrameInfo["END"],
					JpegNuke,
					'/bin/mv %s %s' % (
						path_join("/local", "%s.mov" % newShotName),
						path_join(TypeDirectory, "%s.mov" % newShotName)
					),
					MovNuke,
					tmp_mov_directory,
					path_join(TypeDirectory, "._%s.mov" % newShotName)
				), True)
			
			open(path_join(tmp_mov_directory, "%s.alf" % newShotName), "w").write(MovAlfred)
				
			# AlfredRunning
			tractor_script.tractor_running(path_join(tmp_mov_directory, "%s.alf" % newShotName))
		
		self.Alert(u"MOV를 만들어달라고 Tractor에 요구했습니다.")
Пример #2
0
	def clkPublish(self, widget, event, data=None):
		tmp_path = path_join(const.SCAN_ROOT, "tmp")
        
        # tmp_path exists
		if not exists(tmp_path):
			makedirs(tmp_path)

        # 물론 projectShot에서 체크된 된것만 수행한다)
		for row in ListStore.projShotStore:
			if not row[const.COLUMN_CHOICE]:
				continue

            # Choice가 선택되어진 경우만 수행한다.
            
            # Publish 단계에선 DB정보가 완성되어 있다(ScanInfo.py에서 이미 데이터를 넣는다)
            ################################################################
            # shotname을 기준으로 데이터베이스에 질의해서 db_shot_record에 값을 담는다.
            ################################################################
			db_shot_record = self.datastore.getShotFromName(row[const.COLUMN_SHOTLIST]).first()
			if db_shot_record == None:
				# 데이터가 없음을 알리고 루프를 반복한다. 물론 그럴리는 없겠지만...
				# 별도의 처리를 하기 전까지는 그냥 루프만 반복한다.
				continue

            # 새로운 Seq Name이나 새 Seq Number가 없으면 작업 하나 마나다. 에러 메시지 출력해주게 한다.(미정)
			if (None == db_shot_record.seq) or (None == db_shot_record.shotnumber):
				return False

			tmp_shot_directory = path_join(tmp_path, db_shot_record.shotname)

            # Dpx Size
			ShotMaxWidth = int(db_shot_record.width)
			ShotMaxHeight = int(db_shot_record.height)

            # Thumbnail은 항상 300으로 고정한다.
			thumbnail_width = 300
			thumbnail_height = int(float(ShotMaxHeight) / float(ShotMaxWidth) * thumbnail_width)

			# Half Size
			half_width  = ShotMaxWidth / 2
			half_height = ShotMaxHeight / 2

			tmp_resolution_dir = path_join(tmp_shot_directory, "%dx%d" % (ShotMaxWidth, ShotMaxHeight))

			if not exists(tmp_resolution_dir):
				makedirs(tmp_resolution_dir)

			# dpx, tga, cin 등의 파일을 resolution_dir에 복사
			dpx_files = glob("%s/%s/*" % (const.SCAN_ROOT, db_shot_record.shotname))

			# 임시 디렉터리에 파일이 존재하면 복사하지 않게 한다.
			new_resolution_files = glob("%s/*" % tmp_resolution_dir)

            # 이미 수행되어 있는 경우 다시 복사하지 않게 한다.(퍼블리시 여부로 대체한다.)
			if len(dpx_files) == len(new_resolution_files):
				# 하나라도 값이 다르면 수행하지 않게 한다.
				self.Alert(u"디렉터리 %s는 이미 임시 파일이 있습니다. tmp 디렉터리를 먼저 삭제하셔야 합니다" % db_shot_record.shotname)
				continue
				#return False

			util.fileCopy(dpx_files, tmp_resolution_dir)
            
            # 임시 디렉터리로 복사가 완료되었으면 이름을 변경후 Nuke를 사용하여
            # 썸네일 및 MOV파일을 만들어넣고 seq 폴더로 데이터를 옮긴다.
            
			if 0 == len(db_shot_record.type.strip()): # Type이 비어있는 값이면...
				util.changesetRecord(db_shot_record, "type", "org")
            
			newShotStereo = db_shot_record.isstereo.strip().lower()

			publish_dir = path_join("/", "show", const.PROJECT, "seq")

			# Seq, SeqNumDir, TypeDirectory, ResolutionDir, ResolutionHalfDir, ThumbnailDir
			SeqDir = path_join(publish_dir, db_shot_record.seq)
			SeqNumDir = path_join(SeqDir, "%s_%s" % (db_shot_record.seq, db_shot_record.shotnumber))

			# Rule : 김희경_110804_Rule
			if "myWay" == const.PROJECT:
				SeqNumDir = path_join(SeqDir, db_shot_record.shotnumber)

			TypeDirectory = path_join(SeqNumDir, "plate", db_shot_record.type)

			# Resolution Dir Create
			ResolutionDir 	  = path_join(TypeDirectory, "%dx%d" % (ShotMaxWidth, ShotMaxHeight))
			ResolutionHalfDir = path_join(TypeDirectory, "%dx%d" % (ShotMaxWidth / 2, ShotMaxHeight / 2))
			ThumbnailDir 	  = path_join(TypeDirectory, "thumbnail")
            
            # 비어있는 디렉터리가 있으면 생성시킨다.
			for item in (SeqDir, SeqNumDir, TypeDirectory, ResolutionDir, ResolutionHalfDir, ThumbnailDir):
				if not exists(item):
					makedirs(item)

            ################################################################
            # File Renaming Rules Define
            #
            # (선결조건 : 이름이 먼저 변경되어 있어야 함)여기에서 우선 tmp/샷네임
            # 디렉터리 안에서 이름을 교체하고 썸네일과 하프 사이즈를 생성할 수 있는
            # .nk, .alf 파일을 각각 만들고 os.system 메소드로 실행한다.
            ################################################################
			stereo_type = {"l" : "_left", "r" : "_right"}

			dpx_files = glob("%s/*" % tmp_resolution_dir)
			dpx_files.sort() # 정상적인 썸네일 및 영상 파일을 만들기 위해서...

			start_frame_number = 101

			movie_src_rename_files = dict()

			for dpx_item in dpx_files:
				movie_src_file_ext = splitext(dpx_item) # 다양한 영상 소스에 대한 대응을 하기 위해서임

				# New Fille Name Dictionaries
				new_file_name = util.NewShotNameDict()
				new_file_name["SEQ"] = "%s_" % db_shot_record.seq 
				new_file_name["SHOT_NUMBER"] = "%s_" % db_shot_record.shotnumber
				new_file_name["TYPE"] = "plate_%s_" % db_shot_record.type
				new_file_name["WIDTH"] = "%dx" % ShotMaxWidth
				new_file_name["HEIGHT"] = "%d" % ShotMaxHeight
				new_file_name["STEREO"] = "%s." % stereo_type.get(db_shot_record.isstereo, '')
				new_file_name["FRAME"] = "%s." % str(start_frame_number).zfill(4)
				new_file_name["EXT"] = "%s" % movie_src_file_ext[1][1:]
                
                # 샷 타입이 org인 경우 _plate_org를 파일 이름과 스파르타 등록네임에서 빼달라는 박성진 코디 요청 있었음
                # 메일을 받았을 당시 참조 메일 없었으니 이것으로 생기는 혼선에 대해선 박성진 코디네이터에게 책임이 있음
                # 2012.2.20 19:32 이상호([email protected])
				if db_shot_record.type == "org":
					del new_file_name["TYPE"]

				new_file_name = "".join(new_file_name.values())
                
                # Myway Rule
                # Rule Name : 김희경_110804_Rule
				if "myWay" == const.PROJECT:
					del new_file_name["SEQ"]
					new_file_name = "".join(new_file_name.values())
                
                # 영상 소스 파일 이름 변경
				util.fileRename(dpx_item, path_join(tmp_resolution_dir, new_file_name))
                
				start_frame_number += 1
                
				del new_file_name
            
			# Thumbnail 파일 생성을 위해서 tmp_resolution_dir의 내용을 리스트로 담아두고 썸네일을 생성할 때
			# 사용하게 한다.(디렉토리 경로는 미리 변경해두어야 한다.)
			dpx_files = glob("%s/*" % tmp_resolution_dir)
			dpx_files.sort() # 정상적인 썸네일 및 영상 파일을 만들기 위해서...

			################################################################
			# 이제 파일을 복사한다.
			################################################################

			new_shot_name = util.NewShotNameDict()
			new_shot_name["SEQ"] = "%s_" % db_shot_record.seq 
			new_shot_name["SHOT_NUMBER"] = "%s_" % db_shot_record.shotnumber
			new_shot_name["TYPE"] = "plate_%s_" % db_shot_record.type
			new_shot_name["WIDTH"] = "%dx" % int(db_shot_record.width)
			new_shot_name["HEIGHT"] = "%d" % int(db_shot_record.height)
			new_shot_name["STEREO"] = "%s" % stereo_type.get(db_shot_record.isstereo, '')

            # New Shot Name
            # 마이웨이 프로젝트인 경우 newShotName도 형식이 달라져야 한다.
            # Rule Name : 김희경_110804_Rule
			if db_shot_record.type == "org": # (박성진 코디네이터 요청. 2012/02/20)
				del new_shot_name["TYPE"]

            # 기본 모드
			newShotName = "".join(new_shot_name.values())

			if "myWay" == const.PROJECT:
				del new_shot_name["SEQ"]
				newShotName = "".join(new_shot_name.values())

			util.tmpPathToDestPath.tmp_path = tmp_shot_directory
			util.tmpPathToDestPath.dst_path = TypeDirectory

			# 디렉터리 경로를 임시 변환하게 하기 위하여 map을 호출하여 임시 경로를 새 경로로
			# 변경하게 한다.
			dpx_files = map(util.tmpPathToDestPath, dpx_files)

			middle_frame = len(dpx_files) / 2

			# Thumbnail File Name(Half, Thumbnail)
			Thumbnail_FileName = "%s.jpg" % splitext(basename(dpx_files[middle_frame]))[0]

			newFrameInfo = util.getNewFrame(tmp_resolution_dir)

			if exists(tmp_shot_directory):
				# 이동할 리스트를 생성한다.
				copy_list = glob("%s/*/*" % tmp_shot_directory)
				# 실제 파일을 move 시킨다.
				util.fileMove(copy_list, TypeDirectory)
				
				self.writePublishInfo(
					path_join(TypeDirectory, "%s.mov" % newShotName),
					path_join(ThumbnailDir, Thumbnail_FileName),
					ResolutionDir,
					newFrameInfo,
					db_shot_record
				)
				
				# DB에도 정보가 기록이 완료되면 tmp 디렉터리도 삭제한다.
				rmtree(tmp_shot_directory)

            ################################################################
            # 썸네일과 MOV 생성(MOV는 Nuke Run)
            ################################################################
            
            # nuke, alfredo 스크립트 파일과 임시 MOV를 생성하게 위한 디렉터리를 생성한다.
            
            # alf, nk 파일 보관용
			tmp_mov_directory = path_join(TypeDirectory, ".%.2f" % time.time())

			if not exists(tmp_mov_directory):
				makedirs(tmp_mov_directory)

			# Half Image, Thumbnail Image
			# (스테레오 샷은 스파르타 업로드 시 걸러지므로 여기에선 스테레오 여부를 무시하고 썸네일을 생성하게 한다)
			JpegNuke = path_join(tmp_mov_directory, "%s_jpeg.nk" % newShotName)
			MovNuke  = path_join(tmp_mov_directory, "%s_mov.nk"  % newShotName)

			thumb_fd = open(const.watch_thumb_file, "a")
			thumb_fd.write("%s\t%s\t%s\t%s\n" % (thumbnail_width, thumbnail_height, dpx_files[middle_frame], path_join(ThumbnailDir, Thumbnail_FileName)))
			thumb_fd.close()

			time.sleep(1)

            # 영상 소스의 확장자 얻어오기
			movie_src_ext = splitext(dpx_files[0])[1]
                
            # [MOV] 생성하기(Jpeg 생성, MOV 생성)
			nuke_helper.nuke_run(
                path_join(ResolutionDir, "%s.%%04d%s" % (newShotName, movie_src_ext)),
                db_shot_record.clipname,
                newShotName,
                1024, # 확인용
                720, # 확인용
                '%d-%d' % (newFrameInfo["START"], newFrameInfo["END"]),
                path_join(tmp_mov_directory, "%s.%%04d.jpg" % newShotName),
                JpegNuke,
                path_join("/local", "%s.mov" % newShotName),
                True,
                MovNuke
            )
            
			MovAlfred = tractor_script.tractorSubmission(
                (
					'<ScanDataTransfer> MOV - %s' % newShotName,
					newFrameInfo["START"],
					newFrameInfo["END"],
					JpegNuke,
					'/bin/mv %s %s' % (
						path_join("/local", "%s.mov" % newShotName),
						path_join(TypeDirectory, "%s.mov" % newShotName)
					),
					MovNuke,
					tmp_mov_directory,
					path_join(TypeDirectory, "._%s.mov" % newShotName)
				), True)
			
			open(path_join(tmp_mov_directory, "%s.alf" % newShotName), "w").write(MovAlfred)
			
			# AlfredRunning
			tractor_script.tractor_running(path_join(tmp_mov_directory, "%s.alf" % newShotName))
			
			self.datastore.shotSave(db_shot_record)

		gui_util.updateProjectShots(self.datastore)

		self.Alert("Publish가 모두 완료되었습니다.")