File size: 5,622 Bytes
f61429a
 
514cd38
f61429a
4bd3dc3
a7a154b
059f849
514cd38
 
 
 
 
 
 
059f849
c5437a5
 
 
 
 
 
514cd38
c5437a5
 
d51b0b3
 
 
c5437a5
 
059f849
c5437a5
059f849
 
c5437a5
 
 
 
 
 
 
 
 
 
 
 
d51b0b3
 
c5437a5
 
 
d51b0b3
514cd38
 
 
a7a154b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f61429a
a7a154b
 
 
 
 
 
 
 
 
 
 
 
 
bf508de
a7a154b
 
 
bf508de
a7a154b
 
 
 
 
 
 
 
 
 
 
 
bf508de
 
 
 
 
 
 
 
 
 
c5437a5
 
 
bf508de
 
 
 
c5437a5
 
bf508de
 
 
 
 
 
 
 
d51b0b3
060cebe
514cd38
bf508de
060cebe
bf508de
c5437a5
bf508de
 
 
 
c5437a5
bf508de
 
f61429a
 
514cd38
059f849
514cd38
 
c5437a5
d51b0b3
514cd38
 
 
 
 
 
 
f61429a
c5437a5
514cd38
c5437a5
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
import requests
import gradio as gr
from datetime import datetime

USERNAME = "openfree"
LIMIT = 100  # ν•œ λ²ˆμ— κ°€μ Έμ˜¬ μ΅œλŒ€ spaces 수

def format_timestamp(timestamp):
    if timestamp:
        dt = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
        return dt.strftime('%Y-%m-%d %H:%M')
    return 'N/A'

def get_space_card(space):
    """Generate HTML card for a space"""
    space_id = space.get('id', '')
    space_name = space_id.split('/')[-1]
    likes = space.get('likes', 0)
    created_at = format_timestamp(space.get('createdAt'))
    sdk = space.get('sdk', 'N/A')
    
    return f"""
    <div style='border: 1px solid #ddd; padding: 20px; margin: 10px; border-radius: 12px; 
                background-color: white; box-shadow: 2px 2px 10px rgba(0,0,0,0.1);
                transition: transform 0.2s ease-in-out;'
         onmouseover='this.style.transform="scale(1.02)"'
         onmouseout='this.style.transform="scale(1)"'>
        <h3 style='color: #2d2d2d; margin: 0 0 15px 0; font-size: 1.3em;'>
            <a href='https://huggingface.co/spaces/{space_id}' target='_blank' 
               style='text-decoration: none; color: #2d2d2d;'>
                {space_name}
            </a>
        </h3>
        <div style='margin: 10px 0; color: #666;'>
            <p style='margin: 5px 0;'><strong>SDK:</strong> {sdk}</p>
            <p style='margin: 5px 0;'><strong>Created:</strong> {created_at}</p>
            <p style='margin: 5px 0;'><strong>Likes:</strong> {likes} ❀️</p>
        </div>
        <div style='margin-top: 15px; display: flex; justify-content: space-between; align-items: center;'>
            <a href='https://huggingface.co/spaces/{space_id}' target='_blank' 
               style='background-color: #0084ff; color: white; padding: 8px 16px; 
                      border-radius: 6px; text-decoration: none; display: inline-block;
                      font-weight: 500; transition: background-color 0.2s;'
               onmouseover='this.style.backgroundColor="#0066cc"'
               onmouseout='this.style.backgroundColor="#0084ff"'>
                View Space
            </a>
            <span style='color: #666; font-size: 0.9em;'>
                ID: {space_id}
            </span>
        </div>
    </div>
    """

def get_all_user_spaces():
    """Get all spaces for a user with pagination"""
    all_spaces = []
    offset = 0
    
    while True:
        url = f"https://huggingface.co/api/spaces"
        params = {
            "limit": LIMIT,
            "offset": offset,
            "full": "true"
        }
        headers = {
            "Accept": "application/json",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
        }

        try:
            response = requests.get(url, params=params, headers=headers)
            if response.status_code != 200:
                print(f"Error: Status Code {response.status_code}")
                break

            spaces_data = response.json()
            if not spaces_data:
                break

            # Filter spaces for the specific user
            user_spaces = [space for space in spaces_data if space.get('id', '').startswith(f"{USERNAME}/")]
            all_spaces.extend(user_spaces)

            # If we got less than the limit, we've reached the end
            if len(spaces_data) < LIMIT:
                break

            offset += LIMIT

        except Exception as e:
            print(f"Error fetching spaces: {e}")
            break

    return all_spaces

def get_user_spaces():
    try:
        # Get all spaces for the user
        user_spaces = get_all_user_spaces()

        if not user_spaces:
            return f"""
            <div style='padding: 20px; text-align: center; color: #666;'>
                <h2>No public Spaces found for user: {USERNAME}</h2>
                <p>Try visiting: <a href='https://huggingface.co/{USERNAME}' target='_blank'>
                    https://huggingface.co/{USERNAME}</a></p>
            </div>
            """

        # Sort spaces by likes (most liked first)
        user_spaces.sort(key=lambda x: x.get('likes', 0), reverse=True)

        # Create HTML grid layout
        html_content = f"""
        <div style='padding: 20px; background-color: #f5f5f5;'>
            <div style='margin-bottom: 20px;'>
                <h2 style='color: #333; margin: 0 0 10px 0;'>Spaces by {USERNAME}</h2>
                <p style='color: #666; margin: 0;'>Found {len(user_spaces)} public spaces</p>
            </div>
            <div style='
                display: grid;
                grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
                gap: 20px;
            '>
                {"".join(get_space_card(space) for space in user_spaces)}
            </div>
        </div>
        """

        return html_content

    except Exception as e:
        print(f"Error: {str(e)}")
        return f"""
        <div style='padding: 20px; text-align: center; color: #666;'>
            <h2>Error occurred while fetching spaces</h2>
            <p>Error details: {str(e)}</p>
            <p>Please try again later.</p>
        </div>
        """

# Creating the Gradio interface
app = gr.Interface(
    fn=get_user_spaces,
    inputs=None,
    outputs=gr.HTML(),
    title=f"Hugging Face Spaces Dashboard - {USERNAME}",
    description=f"Displays public Spaces from {USERNAME}",
    theme=gr.themes.Soft(),
    css="""
    .gradio-container {
        max-width: 100% !important;
    }
    """
)

# Launch the Gradio app
if __name__ == "__main__":
    app.launch()