File size: 6,917 Bytes
6f37261
 
 
 
 
 
 
2ea7db4
6f37261
2ea7db4
 
 
 
 
 
 
 
 
6f37261
2ea7db4
 
 
 
6f37261
 
2ea7db4
 
 
 
 
 
6f37261
2ea7db4
 
 
 
6f37261
2ea7db4
 
6f37261
2ea7db4
 
 
 
 
 
 
 
 
 
 
6f37261
2ea7db4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6f37261
2ea7db4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6f37261
2ea7db4
 
 
 
 
 
 
 
 
 
 
 
aa37bd4
 
 
2ea7db4
 
 
 
 
 
 
 
 
 
 
 
6f37261
2ea7db4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6f37261
 
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
import gradio as gr
import requests
import json
from PIL import Image
import io

# API 기본 URL
BASE_URL = "https://collectionapi.metmuseum.org/public/collection/v1"

def get_departments():
    """Get all departments from the Met API"""
    response = requests.get(f"{BASE_URL}/departments")
    return response.json()['departments']

def search_artworks(query, department_id=None, is_highlight=False, has_images=True, 
                   is_on_view=False, medium=None, geo_location=None):
    """Search artworks with various filters"""
    search_url = f"{BASE_URL}/search"
    params = {
        'q': query,
        'hasImages': has_images,
        'isHighlight': is_highlight,
        'isOnView': is_on_view
    }
    
    if department_id:
        params['departmentId'] = department_id
    if medium:
        params['medium'] = medium
    if geo_location:
        params['geoLocation'] = geo_location
        
    try:
        # Get object IDs from search
        response = requests.get(search_url, params=params)
        results = response.json()
        
        if not results.get('objectIDs'):
            return [], "No results found."
            
        # Limit to first 12 objects for performance
        object_ids = results['objectIDs'][:12]
        
        images = []
        captions = []
        
        # Get details for each object
        for object_id in object_ids:
            object_url = f"{BASE_URL}/objects/{object_id}"
            object_response = requests.get(object_url)
            artwork = object_response.json()
            
            if artwork.get('primaryImage'):
                try:
                    img_response = requests.get(artwork['primaryImage'], timeout=10)
                    img = Image.open(io.BytesIO(img_response.content))
                    
                    if img.mode in ('RGBA', 'LA') or (img.mode == 'P' and 'transparency' in img.info):
                        img = img.convert('RGB')
                    
                    artwork_info = f"""
                    Title: {artwork.get('title', 'Unknown')}
                    Artist: {artwork.get('artistDisplayName', 'Unknown')}
                    Date: {artwork.get('objectDate', 'Unknown')}
                    Medium: {artwork.get('medium', 'Unknown')}
                    Department: {artwork.get('department', 'Unknown')}
                    """
                    
                    images.append(img)
                    captions.append(artwork_info)
                except Exception as e:
                    print(f"Error processing image for object {object_id}: {e}")
                    continue
        
        return images, "\n\n".join(captions)
        
    except Exception as e:
        return [], f"An error occurred: {str(e)}"

# Custom CSS
custom_css = """
.gradio-container {
    background: linear-gradient(135deg, #1a1a1a, #2d2d2d) !important;
    color: #ffffff !important;
}
.gr-button {
    background: linear-gradient(135deg, #8e2de2, #4a00e0) !important;
    border: none !important;
    color: white !important;
    font-weight: bold !important;
    padding: 10px 20px !important;
    font-size: 1.1em !important;
    box-shadow: 0 4px 15px rgba(0,0,0,0.2) !important;
}
.gr-button:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(0,0,0,0.3) !important;
    transition: all 0.3s ease;
}
.gr-input, .gr-select {
    border: 2px solid #4a00e0 !important;
    background: rgba(255, 255, 255, 0.1) !important;
    color: white !important;
    font-size: 1.1em !important;
    border-radius: 8px !important;
}
.gr-gallery {
    background: rgba(0, 0, 0, 0.3) !important;
    border-radius: 15px !important;
    padding: 20px !important;
    min-height: 800px !important;
    box-shadow: 0 8px 32px rgba(0,0,0,0.3) !important;
}
.title-text {
    text-align: center !important;
    color: #ffffff !important;
    font-size: 2.8em !important;
    margin-bottom: 0.3em !important;
    text-shadow: 2px 2px 4px rgba(0,0,0,0.5) !important;
    font-weight: bold !important;
}
.subtitle-text {
    text-align: center !important;
    color: #cccccc !important;
    font-size: 1.3em !important;
    margin-bottom: 2em !important;
    font-style: italic !important;
    text-shadow: 1px 1px 2px rgba(0,0,0,0.3) !important;
}
"""

# Get departments for dropdown
departments = get_departments()
department_choices = {dept['displayName']: dept['departmentId'] for dept in departments}

# Gradio interface
with gr.Blocks(css=custom_css) as demo:
    gr.HTML(
        """
        <div class="title-text">🎨 The Met Art Explorer</div>
        <div class="subtitle-text">Explore over 5,000 years of art from The Metropolitan Museum of Art's collection</div>
        """
    )
    gr.HTML("""<a href="https://visitorbadge.io/status?path=https%3A%2F%2Fimmunobiotech-MetropolitanMuseum.hf.space">
               <img src="https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fimmunobiotech-MetropolitanMuseum.hf.space&countColor=%23263759" />
               </a>""")    
    with gr.Row():
        with gr.Column(scale=3):
            search_input = gr.Textbox(
                label="Search artwork",
                placeholder="Enter keywords (e.g., sunflowers, portrait, landscape...)"
            )
        with gr.Column(scale=2):
            department_dropdown = gr.Dropdown(
                choices=list(department_choices.keys()),
                label="Department",
                value=None
            )
    
    with gr.Row():
        with gr.Column():
            highlight_checkbox = gr.Checkbox(label="Show Highlights Only", value=False)
            on_view_checkbox = gr.Checkbox(label="Currently On View", value=False)
        with gr.Column():
            medium_input = gr.Textbox(
                label="Medium",
                placeholder="e.g., Paintings, Sculpture, Ceramics"
            )
            location_input = gr.Textbox(
                label="Geographic Location",
                placeholder="e.g., France, Japan, Egypt"
            )
    
    search_btn = gr.Button("🔍 Search Collection", variant="primary")
    
    gallery = gr.Gallery(
        label="Search Results",
        show_label=True,
        elem_id="gallery",
        columns=3,
        rows=4,
        height="800px",
        object_fit="contain"
    )
    
    info = gr.Textbox(
        label="Artwork Details",
        lines=10,
        show_label=True
    )
    
    def handle_search(query, dept, highlight, on_view, medium, location):
        dept_id = department_choices.get(dept) if dept else None
        return search_artworks(query, dept_id, highlight, True, on_view, medium, location)
    
    search_btn.click(
        fn=handle_search,
        inputs=[search_input, department_dropdown, highlight_checkbox, 
                on_view_checkbox, medium_input, location_input],
        outputs=[gallery, info]
    )

demo.launch()