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