forked from ckh08045/AutoPercenty
243 lines
16 KiB
Python
243 lines
16 KiB
Python
import requests
|
|
import google.generativeai as genai
|
|
import logging
|
|
import markdown
|
|
|
|
# 로거 인스턴스 가져오기
|
|
logger = logging.getLogger('default_logger')
|
|
class ImageDescriptionGenerator:
|
|
def __init__(self, api_key):
|
|
"""API 키를 사용하여 객체를 초기화합니다."""
|
|
self.api_key = api_key
|
|
genai.configure(api_key=self.api_key)
|
|
self.model = genai.GenerativeModel('gemini-pro-vision')
|
|
|
|
|
|
def download_image(self, image_url):
|
|
"""이미지 URL에서 이미지를 다운로드하고 바이트 데이터를 반환합니다."""
|
|
response = requests.get(image_url)
|
|
response.raise_for_status() # 에러가 발생했을 경우 예외를 발생시킵니다.
|
|
return response.content
|
|
|
|
def fill_naver_products(self, product_info, required_length=5):
|
|
nv_products = product_info.naver_products
|
|
default_product = {"productTitle": "상품 정보 없음", "price": "가격 정보 없음"}
|
|
while len(nv_products) < required_length:
|
|
nv_products.append(default_product)
|
|
logger.debug(f"{len(nv_products)}번째 상품정보가 없어 기본정보로 채웁니다.")
|
|
|
|
def fill_product_info_lists(self, product_info, required_length=5):
|
|
# naver_products 리스트 채우기
|
|
nv_products = product_info.naver_products
|
|
default_product = {"productTitle": "상품 정보 없음", "price": "가격 정보 없음"}
|
|
while len(nv_products) < required_length:
|
|
nv_products.append(default_product)
|
|
logger.debug(f"{len(nv_products)}번째 상품정보가 없어 기본정보로 채웁니다.")
|
|
|
|
# trans_option_1_names 리스트 채우기
|
|
while len(product_info.trans_option_1_names) < required_length:
|
|
product_info.trans_option_1_names.append("옵션 정보 없음")
|
|
logger.debug(f"{len(product_info.trans_option_1_names)}번째 trans_option_1_names 정보가 없어 기본정보로 채웁니다.")
|
|
|
|
# trans_option_2_names 리스트 채우기
|
|
if hasattr(product_info, 'trans_option_2_names'):
|
|
while len(product_info.trans_option_2_names) < required_length:
|
|
product_info.trans_option_2_names.append("옵션 정보 없음")
|
|
logger.debug(f"{len(product_info.trans_option_2_names)}번째 trans_option_2_names 정보가 없어 기본정보로 채웁니다.")
|
|
|
|
|
|
def generate_description(self, product_info, top_k=3):
|
|
"""이미지 URL을 받아 해당 이미지에 대한 설명을 생성하고 반환합니다."""
|
|
# 'gemini-pro-vision' 모델을 사용하여 이미지 설명 생성
|
|
# prompt = f"이미지의 상품명은 {title} 1. 이 상품이 무엇인지, 어떤 용도로 사용하는지 설명해줘 2. 이 상품의 배송비 산정을 위해 대략적인 무게를 kg으로 단답형으로 추정해줘. 3. 이 이미지의 상품을 한국의 온라인 쇼핑몰에서 팔기위한 홍보문구를 상품이미지에 맞게 3줄 ~ 4줄 정도 만들어줘. 4.대답하는 방식은 [상품의 홍보문구] 여러줄, [상품의 용도] 자세히, [상품의 무게] 형식과 순서로 해줘."
|
|
# prompt = f"주어진 이미지의 상품명은 {product_info.keyword_title} 1. 이 상품이 무엇인지, 어떤 용도로 사용하는지 설명해줘 2. 이 상품의 배송비 산정을 위해 대략적인 무게를 kg으로 단답형으로 추정해줘. 3. 이 이미지의 상품을 한국의 온라인 쇼핑몰에서 팔기위한 홍보문구를 상품이미지에 맞게 3줄 ~ 4줄 정도 만들어줘."
|
|
# self.fill_naver_products(product_info)
|
|
|
|
self.fill_product_info_lists(product_info)
|
|
|
|
prompt = f'''
|
|
나는 타오바오에서 상품을 가져와서 한국의 온라인 쇼핑몰에서 구매대행업을 하는 사업가야.
|
|
너는 온라인 쇼핑몰 상세페이지 제작 전문가야. 니가 만든 상품페이지는 모두를 감동시키고, 구매로 이어지는 마법같은 능력이 있어.
|
|
이제 주어진 이미지와 내가 원하는 상세페이지에 대한 정보를 줄께.
|
|
하나씩 차근차근 진행해보자.
|
|
각 질문에 대한 답변을 기존의 html에 추가할수 있는 형태로 (HTML 태그로 이루어진) 만들어줘. HTML편집기에 바로 추가하여 사용할 수 있게 말이야. 문단기호, 구분기호등으로 분리해서 답변해줘.
|
|
[정보]
|
|
A. 해당상품의 타오바오 상품명은 '{product_info.tao_title}'
|
|
B. 해당상품의 키워드는 '{product_info.keyword_title}'
|
|
C. 해당상품을 나타나는 상품의 옵션이름은 '{product_info.trans_option_1_names}'
|
|
D. 해당상품의 특징이라 할 수 옵션의 공통적인 키워드는 '{product_info.trans_option_1_name_common_parts}'
|
|
E. 해당상품과 비슷한 상품을 파는 경쟁사의 제품정보는 아래와 같아.
|
|
E-1. 상품명1 : {product_info.naver_products[0]["productTitle"]}
|
|
상품가격1 : {product_info.naver_products[0]["price"]}
|
|
E-2. 상품명2 : {product_info.naver_products[1]["productTitle"]}
|
|
상품가격2 : {product_info.naver_products[1]["price"]}
|
|
E-3. 상품명3 : {product_info.naver_products[2]["productTitle"]}
|
|
상품가격3 : {product_info.naver_products[2]["price"]}
|
|
E-4. 상품명4 : {product_info.naver_products[3]["productTitle"]}
|
|
상품가격4 : {product_info.naver_products[3]["price"]}
|
|
E-5. 상품명5 : {product_info.naver_products[4]["productTitle"]}
|
|
상품가격5 : {product_info.naver_products[4]["price"]}
|
|
|
|
[상품명]
|
|
위의 모든 정보를 바탕으로 상품을 잘 설명한 상품명을 만들어줘 1개 만들어줘.
|
|
- 상품명 제작 권장 사항 1: 키워드, 용도, 재질, 용량, 형식, 모양,특징등의 단어를 콤마를 제외하고 띄어쓰기로 나열해(용량과 스펙등은 뒤쪽으로 배치).
|
|
- 상품명 제작 권장 사항 2: 타오바오 상품명과 옵션이름들에서 상품의 특징을 가져와서 상품명에 사용해야해.
|
|
- 상품명 제작 권장 사항 3 : 경쟁사의 상품명들을 띄어쓰기를 중심으로 단어를 분리하고, 중복된 단어를 모두 제거한 후 나머지 단어들 중 4개를 가져와서 내 상품명 제작에 사용해줘.
|
|
- 반드시 준시해야 할 상품명 제한 사항 : 형용사 사용 금지, 중복단어 절대 사용 금지, 쉼표나 별표를 포함한 모든 특수문자 금지.
|
|
- 상품명 형식 : 한글의 글자수로 35자 이상 되어야 해.
|
|
이 답변은 html 형식으로, 폰트형식은 css로 설정해줘. '폰트크기 24, 폰트 스타일 굵게'로 해줘
|
|
|
|
[상품의 용도]
|
|
이 상품이 무엇인지, 어떤 용도로 사용하는지 자세하게 설명해줘.
|
|
이 답변은 html 형식으로, 폰트형식은 css로 설정해줘. 제목을 '폰트크기 20, 폰트 스타일 굵게', 내용은 '폰트크기 16, 들여쓰기'로해줘
|
|
|
|
[상품의 무게]
|
|
이 상품의 배송비 산정을 위해 무게를 kg으로 알려줘.
|
|
이 답변은 html 형식으로, 폰트형식은 css로 설정해줘. 제목을 '폰트크기 20, 폰트 스타일 굵게', 내용은 '폰트크기 16, 들여쓰기'로해줘
|
|
|
|
[상품의 강점과 특징]
|
|
이 상품의 강점, 특징과 함께 왜 이상품을 사야하는지, 다른제품들과의 차별점은 무엇인지, 기존제품의 어떠한 단점을 개선했는지를 중심으로 홍보문구를 상품이미지에 맞게 자세하고 친절하게 만들어줘."
|
|
이 답변은 html 형식으로, 폰트형식은 css로 설정해줘. 제목을 '폰트크기 20, 폰트 스타일 굵게', 내용은 '폰트크기 16, 들여쓰기'로해줘
|
|
|
|
[사용상 주의점]
|
|
이 상품의 사용상 주의점을 자세히 알려줘
|
|
이 답변은 html 형식으로, 폰트형식은 css로 설정해줘. 제목을 '폰트크기 20, 폰트 스타일 굵게', 내용은 '폰트크기 16, 들여쓰기'로해줘
|
|
|
|
[상품의 추가 정보]
|
|
이 상품의 도움이 될만한 또 다른 추가정보를 자세하게 알려줘
|
|
이 답변은 html 형식으로, 폰트형식은 css로 설정해줘. 제목을 '폰트크기 20, 폰트 스타일 굵게', 내용은 '폰트크기 16, 들여쓰기'로해줘
|
|
|
|
'''
|
|
|
|
front_prompt = f'''
|
|
나는 타오바오에서 상품을 가져와서 한국의 온라인 쇼핑몰에서 구매대행업을 하는 사업가야.
|
|
너는 온라인 쇼핑몰 상세페이지 제작 전문가야. 니가 만든 상품페이지는 모두를 감동시키고, 구매로 이어지는 마법같은 능력이 있어.
|
|
이제 주어진 이미지와 내가 원하는 상세페이지에 대한 정보를 줄께.
|
|
하나씩 차근차근 진행해보자.
|
|
내가 원하는 답변 형식은 바로 상품페이지에 쓸수 있는 형식이야. 해당 부분을 구분하고, 부연설명은 빼줘.
|
|
[정보]
|
|
A. 해당상품의 타오바오 상품명은 '{product_info.tao_title}'
|
|
B. 해당상품의 키워드는 '{product_info.keyword_title}'
|
|
C. 해당상품을 나타나는 상품의 옵션이름은 '{product_info.trans_option_1_names}'
|
|
D. 해당상품의 특징이라 할 수 옵션의 공통적인 키워드는 '{product_info.trans_option_1_name_common_parts}'
|
|
E. 해당상품과 비슷한 상품을 파는 경쟁사의 제품정보는 아래와 같아.
|
|
E-1. 상품명1 : {product_info.naver_products[0]["productTitle"]}
|
|
상품가격1 : {product_info.naver_products[0]["price"]}
|
|
E-2. 상품명2 : {product_info.naver_products[1]["productTitle"]}
|
|
상품가격2 : {product_info.naver_products[1]["price"]}
|
|
E-3. 상품명3 : {product_info.naver_products[2]["productTitle"]}
|
|
상품가격3 : {product_info.naver_products[2]["price"]}
|
|
E-4. 상품명4 : {product_info.naver_products[3]["productTitle"]}
|
|
상품가격4 : {product_info.naver_products[3]["price"]}
|
|
E-5. 상품명5 : {product_info.naver_products[4]["productTitle"]}
|
|
상품가격5 : {product_info.naver_products[4]["price"]}
|
|
'''
|
|
purpose_prompt = f'''
|
|
[질문]
|
|
1. 이 상품이 무엇인지, 어떤 용도로 사용하는지 자세하게 설명해줘.
|
|
'''
|
|
weight_prompt = f'''
|
|
[질문]
|
|
2. 이 상품의 배송비 산정을 위해 무게를 kg으로 알려줘.
|
|
'''
|
|
character_prompt = f'''
|
|
[질문]
|
|
3. 이 상품의 강점, 특징과 함께 왜 이상품을 사야하는지, 다른제품들과의 차별점은 무엇인지, 기존제품의 어떠한 단점을 개선했는지를 중심으로 홍보문구를 상품이미지에 맞게 자세하고 친절하게 만들어줘."
|
|
'''
|
|
warning_prompt = f'''
|
|
[질문]
|
|
4. 이 상품의 사용상 주의점을 자세히 알려줘
|
|
'''
|
|
addtional_prompt = f'''
|
|
[질문]
|
|
5. 이 상품의 도움이 될만한 또 다른 추가정보를 자세하게 알려줘
|
|
'''
|
|
title_prompt = f'''
|
|
[질문]
|
|
6. 위의 모든 정보를 바탕으로 상품을 잘 설명한 상품명을 만들어줘 1개 만들어줘.
|
|
6-1. 상품명 제작 권장 사항 1: 키워드, 용도, 재질, 용량, 형식, 모양,특징등의 단어를 콤마를 제외하고 띄어쓰기로 나열해(용량과 스펙등은 뒤쪽으로 배치).
|
|
6-2. 상품명 제작 권장 사항 2: 타오바오 상품명과 옵션이름들에서 상품의 특징을 가져와서 상품명에 사용해야해.
|
|
6-3. 상품명 제작 권장 사항 3 : 경쟁사의 상품명들을 띄어쓰기를 중심으로 단어를 분리하고, 중복된 단어를 모두 제거한 후 나머지 단어들 중 4개를 가져와서 내 상품명 제작에 사용해줘.
|
|
6-4. 반드시 준시해야 할 상품명 제한 사항 : 형용사 사용 금지, 중복단어 절대 사용 금지, 쉼표나 별표를 포함한 모든 특수문자 금지.
|
|
6-5. 상품명 형식 : 한글의 글자수로 35자 이상 되어야 해.
|
|
'''
|
|
|
|
|
|
# 원하는 답변형태
|
|
# 아래와 같은 형식으로 답변해주면 좋겠어.
|
|
|
|
# [홍보문구에 해당하는 내용]
|
|
# 홍보문구
|
|
# xxxxx
|
|
# [무게에 해당하는 내용]
|
|
# 무게
|
|
# xx Kg
|
|
# [용도에 해당하는 내용]
|
|
# 용도
|
|
# xxxx
|
|
# [상품명에 해당하는 내용]
|
|
# 상품명
|
|
# XXX YYY
|
|
|
|
try:
|
|
logger.debug(f"전달된 prompt \n {prompt}")
|
|
image_data = self.download_image(product_info.main_image_url)
|
|
response = self.model.generate_content([prompt, {"mime_type": "image/jpeg", "data": image_data}])
|
|
|
|
# 후보 결과 확인 및 처리
|
|
if response.candidates and len(response.candidates) > 0:
|
|
logger.debug(f"response.text : {response.text}")
|
|
# response_html = markdown.markdown(response.text)
|
|
# logger.debug(f"response_html : {response_html}")
|
|
return response.text
|
|
|
|
else:
|
|
# 후보 결과가 없거나 유효하지 않을 경우 기본 응답 반환
|
|
return '''
|
|
### 상품의 용도\n\n
|
|
- 에러 발생: 유효한 상품 설명을 제공할 수 없습니다.\n\n
|
|
### 상품의 홍보문구\n\n
|
|
- 에러 발생: 유효한 홍보문구를 제공할 수 없습니다.\n\n
|
|
### 상품의 무게\n\n
|
|
- 에러 발생: 유효한 상품 무게를 제공할 수 없습니다.
|
|
'''
|
|
|
|
except ValueError as e:
|
|
logger.debug(f"오류 발생: {e}", exc_info=True)
|
|
return "오류 발생: 유효한 응답을 생성할 수 없습니다."
|
|
except Exception as e:
|
|
logger.debug(f"예상치 못한 오류 발생: {e}", exc_info=True)
|
|
return "예상치 못한 오류 발생: 처리할 수 없습니다."
|
|
|
|
|
|
def generate_option_description(self, product_info, top_k=3):
|
|
|
|
product_info.option_datas
|
|
|
|
prompt = f'''
|
|
나는 타오바오에서 상품을 가져와서 한국의 온라인 쇼핑몰에서 구매대행업을 하는 사업가야.
|
|
너는 온라인 쇼핑몰 상세페이지 제작 전문가야. 니가 만든 상품페이지는 모두를 감동시키고, 구매로 이어지는 마법같은 능력이 있어.
|
|
여기 중국어로 된 상품의 옵션들이 있어.
|
|
다음 옵션 목록에서 각 옵션의 고유한 특징만 추출하여 한국어로 번역하고, 최대 45바이트를 넘지 않도록 간결하게 작성해주세요. 특수 문자는 제외하고 허용되는 특수 문자(!$~()._-=+/)만 포함해주세요.
|
|
|
|
하나씩 차근차근 진행해보자.
|
|
|
|
[정보]
|
|
중국어 옵션 목록은 다음과 같아. '{product_info.option_datas}'
|
|
|
|
[출력형식]
|
|
product_info.option_datas['name']
|
|
[
|
|
{"options1": "특징1"},
|
|
{"options2": "특징2"},
|
|
...
|
|
]
|
|
|
|
options_info[f'option_type_{idx}'] = {
|
|
'name': option_type_name,
|
|
'items_count': option_items_count,
|
|
'items': option_items_info
|
|
}
|
|
|
|
'''
|