디렉터리 조회, 개발 환경세팅, 소스와 로그
구글 드라이브 API가 사용 가능하다면, 대형 갤러리 운영이 가능하다.
https://buly.kr/3COAS9n : 증강 포함, 프롬프트 제외
https://buly.kr/612I9BR : 이미지 관련 메타 정보
참고로 내 하드웨어 환경은 MAC + PyCharm + miniconda에 shell 명령어도 PyCharm 안에서 쓴다.
환경 설정은 다음과 같다.(본인 환경에서 부족한 부분은 AI챗봇을 이용하시기 바란다. 앞으로 다른 챕터에서도 이 말은 항상 생략되어 있음을 인지했으면 한다.)
pip install --upgrade pip
curl https://sdk.cloud.google.com | bash
아래 패키지들이 설치되며,
https://naver.how/wp/2025/07/12/google-cloud-sdk-packages/
exec -l $SHELL
gcloud init
으로 설정 확인이 가능하다.
계정을 바꾸고 싶다면,
gcloud auth login 명령어를 이용하면 된다.
You are now logged in as [mynameis@hajunho.com].
Your current project is [socanner-fc007]. You can change this setting by running:
$ gcloud config set project PROJECT_ID
프로젝트 선택 명령어도 친절하게 알려준다. SDK 설정은 구글 클라우드 콘솔에서 대부분 이루어진다.
https://console.cloud.google.com/
대부분의 대형 서비스에서 개발자를 위한 코어 컨트롤은
콘솔
이라는 이름으로 서비스되는 것 같다.
하나의 컴퓨터에서 다양한 구글 계정을 이용할 때는 불안정해 보인다. 이는 구글에서 멀티 계정 처음 도입하고 나서도 5년 간은 계속 불안정했기 때문에 엔터프라이즈급 서비스를 만든다면 다수의 가상 환경을 이용하거나 물리적 컴퓨터를 따로 두는 것을 추천한다. 이는 하나의 컴퓨터에 다양한 구글 계정의 프로젝트를 진행 후에 알려주는 삽질(값진)의 기록이다.
계정이 꼬였다면, 삭제하고 새롭게 인증을 받는 것이 좋다.
gcloud auth application-default revoke
gcloud auth application-default login --scopes="https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/drive"
다음은 간단히 자신의 폴더를 조회하는 서비스이다.
#!/usr/bin/env python3
"""
AIgallery 폴더와 그 하위 999_DEMO 폴더의 내용을 조회하는 스크립트
"""
from google.auth import default
from googleapiclient.discovery import build
def authenticate_drive():
"""gcloud CLI 인증 사용"""
try:
credentials, project = default(scopes=['https://www.googleapis.com/auth/drive'])
return build('drive', 'v3', credentials=credentials)
except Exception as e:
print(f"인증 오류: {e}")
return None
def list_folder_contents(service, folder_id, folder_name):
"""특정 폴더의 내용 조회"""
try:
query = f"parents in '{folder_id}'"
results = service.files().list(
q=query,
fields='files(id, name, mimeType, size, createdTime, modifiedTime, webViewLink)',
orderBy='folder,name'
).execute()
items = results.get('files', [])
if not items:
print(f"{folder_name} 폴더가 비어있습니다.")
return []
# 폴더와 파일 분리
folders = [item for item in items if item['mimeType'] == 'application/vnd.google-apps.folder']
files = [item for item in items if item['mimeType'] != 'application/vnd.google-apps.folder']
print(f"\n� {folder_name} 폴더 내용:")
print("=" * 80)
# 폴더 목록
if folders:
print(f"\n� 하위 폴더 ({len(folders)}개):")
print("-" * 60)
for i, folder in enumerate(folders, 1):
name = folder['name']
folder_id = folder['id']
created = folder.get('createdTime', 'N/A')[:19] if folder.get('createdTime') else 'N/A'
print(f"{i:3d}. � {name}")
print(f" ID: {folder_id}")
print(f" 생성: {created}")
# 999_DEMO 폴더인지 확인
if '999_DEMO' in name or '999demo' in name.lower():
print(f" ⭐ 찾고 있던 999_DEMO 폴더입니다!")
print()
# 파일 목록 (이미지 파일 우선)
if files:
image_files = [f for f in files if f['mimeType'].startswith('image/')]
other_files = [f for f in files if not f['mimeType'].startswith('image/')]
if image_files:
print(f"\n�️ 이미지 파일 ({len(image_files)}개):") print("-" * 60) for i, file in enumerate(image_files, 1): name = file['name'] mime_type = file['mimeType'] size = format_file_size(file.get('size')) created = file.get('createdTime', 'N/A')[:19] if file.get('createdTime') else 'N/A' print(f"{i:3d}. �️ {name}") print(f" 타입: {mime_type}") print(f" 크기: {size}") print(f" 생성: {created}") print(f" 링크: {file.get('webViewLink', 'N/A')}") print() if other_files: print(f"\n� 기타 파일 ({len(other_files)}개):") print("-" * 60) for i, file in enumerate(other_files[:10], 1): # 최대 10개만 name = file['name'] mime_type = file['mimeType'] size = format_file_size(file.get('size')) print(f"{i:3d}. � {name}") print(f" 타입: {mime_type}") print(f" 크기: {size}") print() if len(other_files) > 10: print(f"... 그리고 {len(other_files) - 10}개 파일 더") print(f"\n요약: 폴더 {len(folders)}개, 파일 {len(files)}개 (이미지: {len([f for f in files if f['mimeType'].startswith('image/')])}, 기타: {len([f for f in files if not f['mimeType'].startswith('image/')])})") return items except Exception as e: print(f"폴더 내용 조회 오류: {e}") return []def format_file_size(size_bytes): """파일 크기를 읽기 쉽게 포맷""" if size_bytes == 'N/A' or not size_bytes: return 'N/A' try: size_bytes = int(size_bytes) if size_bytes < 1024: return f"{size_bytes} B" elif size_bytes < 1024 * 1024: return f"{size_bytes / 1024:.1f} KB" elif size_bytes < 1024 * 1024 * 1024: return f"{size_bytes / (1024 * 1024):.1f} MB" else: return f"{size_bytes / (1024 * 1024 * 1024):.1f} GB" except: return 'N/A'def main(): try: # Google Drive API 서비스 생성 service = authenticate_drive() if not service: return # AIgallery 폴더 ID (앞에서 찾은 것) aigallery_folder_id = "---HJH_DEBUG---자신의 폴더ID 입력" print("AIgallery 폴더 내용을 조회 중...") # AIgallery 폴더 내용 조회 aigallery_items = list_folder_contents(service, aigallery_folder_id, "AIgallery") # 999_DEMO 폴더 찾기 demo_folders = [item for item in aigallery_items if item['mimeType'] == 'application/vnd.google-apps.folder' and ('999_DEMO' in item['name'] or '999demo' in item['name'].lower())] if demo_folders: for demo_folder in demo_folders: demo_folder_id = demo_folder['id'] demo_folder_name = demo_folder['name'] print(f"\n� {demo_folder_name} 폴더를 찾았습니다!") print(f" ID: {demo_folder_id}") # 999_DEMO 폴더 내용 조회 list_folder_contents(service, demo_folder_id, demo_folder_name) else: print("\n❓ 999_DEMO 폴더를 찾을 수 없습니다.") print("AIgallery 폴더 안에 있는 폴더들을 확인해보세요.") except Exception as e: print(f"오류 발생: {e}")if __name__ == '__main__': main()
/Users/junhoha/miniconda3/bin/python /Users/junhoha/github/kmong/kmong_upbit_surging_stock/googleAPItest/test/browse_aigallery_999.py
AIgallery 폴더 내용을 조회 중...
� AIgallery 폴더 내용:
================================================================================
� 하위 폴더 (17개):
------------------------------------------------------------
1. � 999_DEMO
ID: 12N56miNIFlNzbFH0E9r6EGhsEM6K1aCY
생성: 2025-05-06T12:40:22
⭐ 찾고 있던 999_DEMO 폴더입니다!
2. � APPs
ID: 1mn8cdlvE7ROpCY4p1Yha3VBO1mh-Cwuc
생성: 2023-12-21T15:10:34
3. � EX-music
ID: 1zYhsTa9vEDZWhP_U-F_DIifc76ESYWMM
생성: 2025-03-03T05:06:09
4. � HJH_github
ID: 1E4VaD_lBb1BbmEjZYyfpk9byAylZuCgi
생성: 2025-02-25T11:29:07
5. � linux_kernel
ID: 1hqeGbclozYtxOVoapaH-4xQ8kBsh0A3E
생성: 2025-06-07T21:38:02
6. � panorama
ID: 1ORO6yqILBFsGRzicXCFS0DzLEXQoxtAS
생성: 2024-02-08T09:29:20
7. � shiba
ID: 163IgTTc1KrRxnMhNOjWnqLWHRfv713qK
생성: 2025-07-11T18:37:09
8. � source
ID: 1lVo5v8e_b4N_WvJI0Kag8mqd6pVPw7bs
생성: 2024-01-27T00:08:22
9. � TheArt02
ID: 1GoxIWzVGX8reo5NNqa2Sk4g63dgLFw1V
생성: 2025-05-06T13:10:41
10. � TheArt03
ID: 1v0eJ8CjCg2E_zRxh2X6uOGosB-o4KNo0
생성: 2025-05-06T13:41:20
11. � TheArt04
ID: 1FyAOEBhxbQcHpgCaBHPtr1ngyRyskph5
생성: 2025-05-06T14:36:34
12. � unrealEngineMarket
ID: 12Hand-9F7FyTZCLPZouA2WLywXXLzV-L
생성: 2024-08-10T22:24:34
13. � XXX
ID: 1JIylOYODkFSfjQF8ww_d1g-Tg8nD9S5o
생성: 2024-01-30T01:56:50
14. � YOLO
ID: 1PTdCT8zBLmkmuWuYnRBjaaxwd6JBFOmb
생성: 2025-02-12T09:46:57
15. � 만들기_미드저니
ID: 1h_lje53Fj6Q_iY0N0GinwyDCtF__56Hl
생성: 2025-02-21T14:41:12
16. � 서버팀
ID: 1lkaHoCOGYYNLS0FTvblzM60fvkW679R1
생성: 2024-02-09T19:26:42
17. � 텀블벅
ID: 1-9z4BuGd5EW9smBjd62OHp-XTVK_ULLP
생성: 2025-06-29T08:51:26
� 기타 파일 (4개):
------------------------------------------------------------
1. � mongoDB
타입: application/vnd.google-apps.document
크기: 18.9 KB
2. � RESTAPI_Tester5.3.zip
타입: application/x-zip-compressed
크기: 1.2 MB
3. � RESTAPI_Tester5.4.zip
타입: application/x-zip-compressed
크기: 2.2 MB
4. � Team_SOCANNER
타입: application/vnd.google-apps.spreadsheet
크기: 1.0 KB
요약: 폴더 17개, 파일 4개 (이미지: 0, 기타: 4)
� 999_DEMO 폴더를 찾았습니다!
ID: 12N56miNIFlNzbFH0E9r6EGhsEM6K1aCY
� 999_DEMO 폴더 내용:
================================================================================
�️ 이미지 파일 (100개):
------------------------------------------------------------
1. �️ abstract_art_1746411275_base.png
타입: image/png
크기: 1.5 MB
생성: 2025-05-06T13:01:25
링크: https://drive.google.com/file/d/1BlGgVKJ-adJCB8qw1AmkkZ6iI6mQ_ahg/view?usp=drivesdk
2. �️ abstract_art_1746411276_square4k.png
타입: image/png
크기: 6.8 MB
생성: 2025-05-06T13:00:02
링크: https://drive.google.com/file/d/1A6bR9T7QI7a0Id15-hly4I3-jrT2Tg7n/view?usp=drivesdk
3. �️ abstract_art_1746411313_base.png
타입: image/png
크기: 1.6 MB
생성: 2025-05-06T12:43:41
링크: https://drive.google.com/file/d/1xT8rn5tL9FfdcAzAWxwOS2hrTDulk1PE/view?usp=drivesdk
4. �️ abstract_art_1746411314_square4k.png
타입: image/png
크기: 7.9 MB
생성: 2025-05-06T13:04:14
링크: https://drive.google.com/file/d/1HsO7Ens7P4neq2Fzn4Jyjo-W-z7ifSk4/view?usp=drivesdk
5. �️ abstract_art_1746411358_base.png
타입: image/png
크기: 1.5 MB
생성: 2025-05-06T12:48:31
링크: https://drive.google.com/file/d/12YS7WFvGFmKjRU6GoNEThIQb-WDGG3cZ/view?usp=drivesdk
6. �️ abstract_art_1746411359_square4k.png
타입: image/png
크기: 6.8 MB
생성: 2025-05-06T12:59:23
링크: https://drive.google.com/file/d/1ffsHLGBzYvND-C_nw_IzBQRzuyKq9WKp/view?usp=drivesdk
7. �️ abstract_art_1746411443_base.png
타입: image/png
크기: 1.6 MB
생성: 2025-05-06T12:56:36
링크: https://drive.google.com/file/d/1tXnxjvrWvlCqGX3Ve9MqdgKpMOFi01ad/view?usp=drivesdk
8. �️ abstract_art_1746411444_square4k.png
타입: image/png
크기: 7.6 MB
생성: 2025-05-06T12:55:42
링크: https://drive.google.com/file/d/19a9MKme4lwKmr7lr4rcY4eJqCjXGL5iX/view?usp=drivesdk
9. �️ abstract_art_1746411477_base.png
타입: image/png
크기: 1.5 MB
생성: 2025-05-06T13:06:01
링크: https://drive.google.com/file/d/1FtPlRan2XUXZ8_K9H-c47VfK6jMlGeDZ/view?usp=drivesdk
10. �️ abstract_art_1746411478_square4k.png
타입: image/png
크기: 6.7 MB
생성: 2025-05-06T12:40:52
링크: https://drive.google.com/file/d/1q9dSCRraNFyplYDmajG1nYcKelqTas8r/view?usp=drivesdk
11. �️ abstract_art_1746411511_base.png
타입: image/png
크기: 1.4 MB
생성: 2025-05-06T12:45:39
링크: https://drive.google.com/file/d/1SbPKeS92p5KIvW5dnumyFwAo00440vVY/view?usp=drivesdk
12. �️ abstract_art_1746411512_square4k.png
타입: image/png
크기: 6.5 MB
생성: 2025-05-06T12:45:01
지금 바로 작가의 멤버십 구독자가 되어
멤버십 특별 연재 콘텐츠를 모두 만나 보세요.
오직 멤버십 구독자만 볼 수 있는,
이 작가의 특별 연재 콘텐츠