Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 4,433 Bytes
cf957e4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
"""
Core emoji processing logic for the Emoji Mashup application.
"""
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
import requests
from PIL import Image
from io import BytesIO
from config import CONFIG
from utils import logger, kitchen_txt_to_dict
class EmojiProcessor:
def __init__(self, model_name=CONFIG["model_name"]):
"""Initialize the emoji processor with the specified model.
Args:
model_name: Name of the sentence transformer model to use
"""
logger.info(f"Loading model: {model_name}")
self.model = SentenceTransformer(model_name)
self.emotion_dict = {}
self.event_dict = {}
self.emotion_embeddings = {}
self.event_embeddings = {}
def load_emoji_dictionaries(self, emotion_file=CONFIG["emotion_file"], item_file=CONFIG["item_file"]):
"""Load emoji dictionaries from text files.
Args:
emotion_file: Path to the emotion emoji file
item_file: Path to the item emoji file
"""
logger.info("Loading emoji dictionaries")
self.emotion_dict = kitchen_txt_to_dict(emotion_file)
self.event_dict = kitchen_txt_to_dict(item_file)
# Precompute embeddings
logger.info("Computing embeddings for emoji dictionaries")
self.emotion_embeddings = {emoji: self.model.encode(desc) for emoji, desc in self.emotion_dict.items()}
self.event_embeddings = {emoji: self.model.encode(desc) for emoji, desc in self.event_dict.items()}
def find_top_emojis(self, embedding, emoji_embeddings, top_n=1):
"""Find top matching emojis based on cosine similarity.
Args:
embedding: Sentence embedding to compare
emoji_embeddings: Dictionary of emoji embeddings
top_n: Number of top emojis to return
Returns:
List of top matching emojis
"""
similarities = [
(emoji, cosine_similarity([embedding], [e_embed])[0][0])
for emoji, e_embed in emoji_embeddings.items()
]
similarities.sort(key=lambda x: x[1], reverse=True)
return [emoji for emoji, _ in similarities[:top_n]]
def get_emoji_mashup_url(self, emoji1, emoji2, size=CONFIG["default_size"]):
"""Generate URL for emoji mashup.
Args:
emoji1: First emoji character
emoji2: Second emoji character
size: Image size in pixels
Returns:
URL for the emoji mashup
"""
return f"{CONFIG['emoji_kitchen_url'].format(emoji1=emoji1, emoji2=emoji2)}?size={size}"
def fetch_mashup_image(self, url):
"""Fetch emoji mashup image from URL.
Args:
url: URL of the emoji mashup image
Returns:
PIL Image object or None if fetch failed
"""
try:
response = requests.get(url)
if response.status_code == 200 and "image" in response.headers.get("Content-Type", ""):
return Image.open(BytesIO(response.content))
else:
logger.warning(f"Failed to fetch image: Status code {response.status_code}")
return None
except Exception as e:
logger.error(f"Error fetching image: {e}")
return None
def sentence_to_emojis(self, sentence):
"""Process sentence to find matching emojis and generate mashup.
Args:
sentence: User input text
Returns:
Tuple of (emotion emoji, event emoji, mashup image)
"""
if not sentence.strip():
return "β", "β", None
try:
embedding = self.model.encode(sentence)
top_emotion = self.find_top_emojis(embedding, self.emotion_embeddings, top_n=1)[0]
top_event = self.find_top_emojis(embedding, self.event_embeddings, top_n=1)[0]
mashup_url = self.get_emoji_mashup_url(top_emotion, top_event)
mashup_image = self.fetch_mashup_image(mashup_url)
return top_emotion, top_event, mashup_image
except Exception as e:
logger.error(f"Error processing sentence: {e}")
return "β", "β", None |