File size: 5,114 Bytes
478b861
6236d6b
 
 
 
478b861
 
 
 
6236d6b
 
478b861
 
6236d6b
 
 
 
478b861
6236d6b
 
 
 
 
 
 
478b861
6236d6b
 
478b861
6236d6b
478b861
 
 
 
 
6236d6b
 
 
478b861
 
6236d6b
 
 
 
 
478b861
8df5ef2
 
 
6236d6b
478b861
6236d6b
478b861
6236d6b
 
 
478b861
 
 
6236d6b
 
 
 
 
 
 
8df5ef2
6236d6b
 
8df5ef2
6236d6b
 
 
 
 
 
 
 
 
 
 
478b861
6236d6b
8df5ef2
6236d6b
 
 
 
 
 
 
 
 
 
8df5ef2
478b861
6236d6b
 
478b861
6236d6b
 
8df5ef2
 
478b861
 
 
 
8df5ef2
478b861
 
6236d6b
 
 
 
 
 
 
 
 
478b861
 
 
6236d6b
478b861
 
 
 
 
 
 
 
 
 
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
import gradio as gr
from huggingface_hub import HfApi
from huggingface_hub.utils import HfHubHTTPError

# --- Core Functions ---

def get_my_spaces(hf_token):
    """Fetches a list of the user's public Hugging Face Spaces."""
    if not hf_token:
        # Return empty values for all outputs
        return [], "Please enter your Hugging Face token.", []
    try:
        api = HfApi(token=hf_token)
        # Get the username to list spaces accurately
        username = api.whoami()["name"]
        spaces = api.list_spaces(author=username)
        # Filter for only public spaces
        public_spaces = [space.id for space in spaces if not space.private]
        if not public_spaces:
            return [], "Successfully connected, but you have no public spaces.", []
        # Return the list of spaces for the checkboxes and the state
        return public_spaces, f"Successfully listed {len(public_spaces)} public spaces.", public_spaces
    except HfHubHTTPError as e:
        # Handle common authentication errors
        return [], f"Authentication error: Please check your token. Details: {e}", []
    except Exception as e:
        return [], f"An error occurred: {e}", []


def make_spaces_private(hf_token, selected_spaces, progress=gr.Progress()):
    """Sets the visibility of selected Hugging Face Spaces to private."""
    if not hf_token:
        return "Please enter your Hugging Face token."
    if not selected_spaces:
        return "Please select at least one space to make private."
    
    progress(0, desc="Starting...")
    
    try:
        api = HfApi(token=hf_token)
        log_messages = []
        total_spaces = len(selected_spaces)

        for i, space_id in enumerate(selected_spaces):
            progress((i + 1) / total_spaces, desc=f"Processing '{space_id}'...")
            try:
                # --- THIS IS THE FIX ---
                # We must explicitly tell the API that this is a 'space'.
                api.update_repo_settings(repo_id=space_id, private=True, repo_type="space")
                log_messages.append(f"βœ… Successfully made '{space_id}' private.")
            except Exception as e:
                log_messages.append(f"❌ Failed to make '{space_id}' private: {e}")
        
        return "\n".join(log_messages)
    except HfHubHTTPError as e:
        return f"Authentication error: Please check your token. Details: {e}"
    except Exception as e:
        return f"An error occurred: {e}"

# --- Gradio UI ---

with gr.Blocks(theme=gr.themes.Soft()) as demo:
    gr.Markdown(
        """
        # πŸ›‘οΈ Hugging Face Space Privacy Control
        Quickly make your public Hugging Face Spaces private.
        1.  Create and paste a Hugging Face access token with **write** permission.
        2.  Click "List My Public Spaces".
        3.  Select the spaces you want to make private (or use "Select All").
        4.  Click the final button to update their privacy settings.
        """
    )

    with gr.Row():
        hf_token_input = gr.Textbox(
            label="Hugging Face Write Token",
            type="password",
            placeholder="hf_...",
            scale=3,
        )
        list_spaces_button = gr.Button("List My Public Spaces", variant="secondary", scale=1)
    
    with gr.Group():
        # This (invisible) state component is the key to the select_all fix
        spaces_list_state = gr.State([])

        select_all_checkbox = gr.Checkbox(label="Select All / Deselect All")
        
        spaces_checkboxes = gr.CheckboxGroup(
            label="Your Public Spaces",
            info="Only your public spaces are shown here."
        )

    make_private_button = gr.Button("Make Selected Spaces Private", variant="primary")
    status_output = gr.Textbox(label="Status", interactive=False, lines=5)

    # --- Event Listeners ---

    def list_spaces_action(token):
        """Called when the list button is clicked. Updates the checkboxes and the state."""
        spaces, message, state_list = get_my_spaces(token)
        # Also reset the select_all checkbox to unchecked
        return gr.update(choices=spaces, value=[]), message, state_list, gr.update(value=False)

    list_spaces_button.click(
        fn=list_spaces_action,
        inputs=hf_token_input,
        outputs=[spaces_checkboxes, status_output, spaces_list_state, select_all_checkbox]
    )

    def select_all_action(select_all_checked, full_list_of_spaces):
        """
        Called when the "Select All" checkbox is changed.
        Uses the list from the state to update the checkbox group.
        """
        if select_all_checked:
            return gr.update(value=full_list_of_spaces)  # Select all
        else:
            return gr.update(value=[])  # Deselect all

    select_all_checkbox.change(
        fn=select_all_action,
        inputs=[select_all_checkbox, spaces_list_state], # Input is from the state now
        outputs=spaces_checkboxes
    )

    make_private_button.click(
        fn=make_spaces_private,
        inputs=[hf_token_input, spaces_checkboxes],
        outputs=status_output
    )

demo.launch()