과제로 사진파일 분류해 주는 프로그램을 만들어 보기로 했다.
아무래도 사진 찍으러 많이 돌아다니다보니
그 많은 파일들 정리하기가 여간 귀찮은 일이 아닐 수 없다.
조금만 신경꺼도 금새 불어나 있는 나의 사진갤러리.......
프로그래밍 공부를 시작할 때 언젠간 만들어보리라 다짐했던 그것을
이제야 해 보게 되는구만. 조와써
일단 확장성(?) 때문에 원본폴더와 저장할 폴더는 직접 지정하는 걸로 만들긴 했지만
실제로 쓸 때는 고정 폴더로 진행할 예정
그리고 dstDir는 서버에 업로드 할 거라서
매월 1일, 15일이 되면 자동으로 photoDir을 체크해서 새 파일이 있으면 업로드 할 예정이다.
윈도우는 작업스케줄러를 쓰라는데 웬지 별로 내키지가 않아서(?)
다른 방법 찾아봐야지.
#!/bin/python3
import sys
import os
from PIL import Image
import shutil
from PIL.ExifTags import TAGS
from datetime import datetime
# photoDir = 'p:\\photo'
# dstDir = 'p:\\Photo\\DSLR Photos'
class PhotoOrgarnize:
def getImageData(self, photoDir):
# if (datetime.now().day == 1) | (datetime.now().day == 15): #매월 1일 15일에 photoDir에 새로운 파일이 있는지 체크
photoPath = []
photoInfo = {}
for filename in os.listdir(photoDir): # photoDir의 파일들에 대해 반복
if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):
photoPath.append(os.path.join(photoDir, filename)) # 전체파일경로 만들기
for filename in photoPath:
image = Image.open(filename) #해당파일명의 이미지를 오픈
exif_data = image.getexif() #이미지의 메타데이터를 저장해서 딕셔너리로 반환
# print(exif_data)
if (exif_data): #메타데이터가 있다면 저장할꺼임
for tag, value in exif_data.items(): #tag번호와 value를 돌면서 확인
tag_name = TAGS.get(tag, tag) #태그번호에 대한 이름이 없으면 그냥 태그번호랑 똑같이 그대로 사용한다.
if (tag_name == 'DateTime'):
dateTimeTaken = value.replace(':', '').replace(' ', '') #촬영날짜,시간부분을 : 공백 삭제처리하여 저장
photoInfo[dateTimeTaken] = os.path.basename(filename) #파일경로부분 빼고 순수파일명만 따와서 value로 저장
photoList = sorted(list(photoInfo.items())) #photoInfo딕셔너리를 List로 변환(오름차순 정렬)
return photoList
def moveImage(self, photoList, photoDir, dstDir, fileId=1):
prevDate = ''
for dateTaken, filename in photoList: #촬영날짜,시간을 dateTaken에 저장
getDate = dateTaken[:6] #YYYYMM 형식으로 getDate에 저장
dstPath = os.path.join(dstDir, getDate) #목적지경로에 날짜이름으로 폴더경로를 생성.
print(dstPath)
if not os.path.exists(dstPath):
os.makedirs(dstPath) #해당경로에 동일한 이름의 폴더가 없을 경우에만 폴더생성
dateTaken = dateTaken[:12]
if (prevDate == dateTaken): #DateTaken이 동일할경우 fileId + 1 해서 새파일명을 구성한다.
fileId += 1
else: fileId = 1
newFileName = '{}_{:04d}.jpg'.format(dateTaken, fileId) #filename형식정하기 '날짜시분_0001'. 확장자는 모두 jpg로 통일
prevDate = dateTaken
srcPath = os.path.join(photoDir, filename)
newDstPath = os.path.join(dstPath, newFileName)
shutil.move(srcPath, newDstPath)
print(f'{filename} moved to {newDstPath}')
# fileName = String.format("%s\\sticker%04d.txt", Main.filePath, fileId);
#---------------------------------------------------------------------------------------------------------------------
orgarnize = PhotoOrgarnize()
if len(sys.argv) > 1: #argv[0]은 실행파일이름. 길이가 1개 이상이면(전달인수가 있으면)
photoDir = sys.argv[1] #argv[1]에 photoDir로 저장
else:
photoDir = input("원본 디렉토리를 입력하세요. ")
if photoDir == '':
exit(0)
if len(sys.argv) > 2:
dstDir = sys.argv[2]
else:
dstDir = input("이동시킬 디렉토리를 입력하세요. ")
if dstDir == '':
exit(0)
print(photoDir)
print(dstDir)
photoList = orgarnize.getImageData(photoDir)
orgarnize.moveImage(photoList, photoDir, dstDir)
다 하고보니 진짜 몇 줄 안되는 간단한 데다 별 어려운 내용도 없었는데 왜 이리 오래 걸린겁니까 휴먼?
토요일은 어쩔 수 없이 노는 날(?)이라 그렇다 치는데
(심지어 노트북 들고가서 데이트했음)
오늘은 아침 9시부터 매달려서 지금 끝났네..
흑흑 나의 이 초보딱지는 언제쯤 뗄 수 있는가🙄
만들 땐 메타데이터 추출하는 것도 찾아서 써 보고 나름 재밌게 만들었는데
다 하고보니 어.. 전체적으로 봤을 때 기능이 좀 재미가 없네 싶은게
결국엔 그냥 있는 파일들 경로만 바꿔서 옮겨놓는 수준이라
이전에 학원에서 예제로 진행했던 여러 함수들을 못 써본 게 조금 아쉽긴 하다.
뭐, 다른 거 또 아이디어 짜내서 만들어보면 되지!
다음엔 read write 기능을 좀 써 봐야겠다. 사실 요게 파일클래스의 꽃 아니겠능가.
(과연 그건 또 얼마나 걸리려나......)
처음엔 콘솔에서 일일이 디렉토리를 선택해서 들어가는 식으로 cmd스럽게 만들었으나
def chooseDir(self, dirPath):
while True:
fileList = os.listdir(dirPath)
for filename in fileList:
if os.path.isdir(os.path.join(dirPath, filename)):
print(filename + "\t<DIR>") #파일경로 만들기. 디렉토리인 경우 DIR을 붙여준다.
else: print(filename)
choiceDir = input('해당폴더로 진행하시려면 1번, 계속 찾으시려면 폴더명을 입력하세요.')
if (choiceDir != '1'): #계속 찾을려고 폴더명을 입력한다.
new_dirPath = os.path.join(dirPath, choiceDir) #입력한 폴더명을 저장
if (os.path.isdir(new_dirPath)): #해당 이름의 폴더가 존재하면
dirPath = new_dirPath #dirPath에 저장
continue
else:
print('존재하지 않는 폴더입니다. 다시 입력해 주세요.')
continue
print(dirPath)
return dirPath
아빠가 뒤에서 구경하더니 비웃고 갔다(...)
아오 FileDialog만 쓰면 이런 귀찮은 일 안해도 되는데! (아니 그게 더 귀찮은가)
암튼 이 부실한 나의 코드를 조금이나마 있어보이게(?) 만들고 싶어서 msg를 조금 더 쳐 보기로 했다.
아빠가 CLI 이용하는 것도 이참에 연습 좀 해보는 게 어떻냐 했던 게 생각나 구글을 열심히 뒤졌다.
그래서 나온 게 sys모듈을 사용한 저 부분.
대단히 어려운 부분은 아니었어서 금방 바꿀 수 있었다.
쨌든 잘 된다!
자바 배울 땐 cmd 쓸 일이 별로 없었어서 잘 몰랐는데
요거 나름 재밌네. 옛날 어릴 때 생각도 나고🤣
이러면서 슬슬 리눅스를 시작하기 위한 밑밥이 되었달까.. 언젠간 하게 되겠지.
(커리큘럼에도 어차피 있어서;)
암튼 대충 이쯤에서 마무리....하고 싶으나
아 그래도 chooseDir 메소드 갖다버린 건 좀 아쉬운데
어떻게 좀 비벼서 끼워넣을 방법 없을까.🤔 고민중
'■ 공부 > Python' 카테고리의 다른 글
[과제] TeamBBS (DB연동) (0) | 2024.03.31 |
---|---|
DAY 9. 디렉토리 관리 프로그램 (2) | 2024.03.22 |
[python] 파일 입출력을 이용한 단어장 만들기 (1) | 2024.03.22 |
DAY 8-1. 파일 입출력 라이브러리 (0) | 2024.03.21 |
DAY 9. 변수 타입 어노테이션 (0) | 2024.03.21 |