Spaces:
Sleeping
Sleeping
Download app.py from Brian045/AutoTranslateAI: direct link, hf CLI and curl.
- Browser
- Download file 7.23 kB
-
https://huggingface.co/spaces/Brian045/AutoTranslateAI/resolve/main/app.py
- Command line
-
hf download hf://spaces/Brian045/AutoTranslateAI/app.py
-
curl -L -o app.py https://huggingface.co/spaces/Brian045/AutoTranslateAI/resolve/main/app.py
7.23 kB
| import gradio as gr | |
| import pandas as pd | |
| import os | |
| from translator_utils import process_rows, revert_rows, download_dataset, LOCAL_FILENAME, ENV_HF_TOKEN, read_csv_robust | |
| def load_data(): | |
| """Load the dataset safely using robust reader.""" | |
| if not os.path.exists(LOCAL_FILENAME): | |
| try: | |
| download_dataset() | |
| except: | |
| return pd.DataFrame() | |
| df = read_csv_robust(LOCAL_FILENAME) | |
| if df.empty: | |
| return df | |
| try: | |
| if 'Judul_Inggris' not in df.columns: | |
| df['Judul_Inggris'] = "" | |
| if 'Isi_Inggris' not in df.columns: | |
| df['Isi_Inggris'] = "" | |
| df = df.fillna("") | |
| return df | |
| except: | |
| return pd.DataFrame() | |
| def force_refresh_data(): | |
| """Forces a re-download and reload of the data.""" | |
| try: | |
| download_dataset(force=True) | |
| return load_data(), "Data refreshed successfully." | |
| except Exception as e: | |
| return pd.DataFrame(), f"Failed to refresh data: {e}" | |
| def get_pending_data(full_df): | |
| """Filter for rows that are NOT fully translated.""" | |
| if full_df.empty: | |
| return full_df | |
| mask = (full_df['Judul_Inggris'].str.strip() == "") | (full_df['Isi_Inggris'].str.strip() == "") | |
| df_view = full_df[mask].copy() | |
| df_view.reset_index(inplace=True) | |
| df_view.rename(columns={'index': 'ID'}, inplace=True) | |
| df_view.insert(0, "Select", False) | |
| return df_view | |
| def get_history_data(full_df, date_filter=""): | |
| """Filter for rows that ARE fully translated.""" | |
| if full_df.empty: | |
| return full_df | |
| mask = (full_df['Judul_Inggris'].str.strip() != "") & (full_df['Isi_Inggris'].str.strip() != "") | |
| df_view = full_df[mask].copy() | |
| df_view.reset_index(inplace=True) | |
| df_view.rename(columns={'index': 'ID'}, inplace=True) | |
| if date_filter: | |
| df_view = df_view[df_view['Tanggal'].str.contains(date_filter, case=False, na=False)] | |
| # Add 'Select' column for Revert functionality | |
| df_view.insert(0, "Select", False) | |
| return df_view | |
| def on_translate_selected(df_data, token, progress=gr.Progress()): | |
| """Callback when user clicks 'Translate Selected'.""" | |
| selected_rows = df_data[df_data["Select"] == True] | |
| if selected_rows.empty: | |
| return gr.DataFrame(), gr.DataFrame(), "No rows selected!" | |
| try: | |
| indices = selected_rows['ID'].tolist() | |
| indices = [int(i) for i in indices] | |
| except KeyError: | |
| return gr.DataFrame(), gr.DataFrame(), "Error: ID column missing." | |
| updated_df, msg = process_rows(indices, token=token, progress=progress) | |
| pending = get_pending_data(updated_df) | |
| history = get_history_data(updated_df) | |
| return pending, history, msg | |
| def on_revert_selected(df_data, token, progress=gr.Progress()): | |
| """Callback when user clicks 'Revert Selected'.""" | |
| selected_rows = df_data[df_data["Select"] == True] | |
| if selected_rows.empty: | |
| return gr.DataFrame(), gr.DataFrame(), "No rows selected!" | |
| try: | |
| indices = selected_rows['ID'].tolist() | |
| indices = [int(i) for i in indices] | |
| except KeyError: | |
| return gr.DataFrame(), gr.DataFrame(), "Error: ID column missing." | |
| # Call revert | |
| updated_df, msg = revert_rows(indices, token=token, progress=progress) | |
| # Refresh views | |
| pending = get_pending_data(updated_df) | |
| history = get_history_data(updated_df) | |
| return pending, history, msg | |
| def filter_history(date_input): | |
| df = load_data() | |
| return get_history_data(df, date_input) | |
| def refresh_views(): | |
| df, msg = force_refresh_data() | |
| pending = get_pending_data(df) | |
| history = get_history_data(df) | |
| return pending, history, msg | |
| def auto_select_pending(df_view): | |
| """Automatically selects the first 10 rows in the pending view.""" | |
| if df_view.empty: | |
| return df_view, "No rows to select." | |
| # Set 'Select' to True for the first 10 rows | |
| limit = min(10, len(df_view)) | |
| df_view.loc[:limit-1, "Select"] = True | |
| return df_view, f"Auto-selected top {limit} rows." | |
| # CSS to ensure columns are readable | |
| custom_css = """ | |
| /* Fix minimum width for content columns */ | |
| table td:nth-child(5), table td:nth-child(6), table td:nth-child(7), table td:nth-child(8) { | |
| min-width: 300px !important; | |
| white-space: pre-wrap !important; | |
| } | |
| /* Ensure row ID is small */ | |
| table td:nth-child(2) { | |
| width: 50px !important; | |
| } | |
| """ | |
| with gr.Blocks(title="Auto AI News Translator") as app: | |
| gr.Markdown("# Auto AI News Translator") | |
| gr.Markdown("Translate news from Indonesian to English (with Chunking). Select rows to translate.") | |
| # Inject default value from Env Var | |
| hf_token = gr.Textbox( | |
| label="HF Token (Optional for Persistence)", | |
| placeholder="hf_... (Leave empty if set in ENV)", | |
| type="password", | |
| value=ENV_HF_TOKEN | |
| ) | |
| with gr.Row(): | |
| status_output = gr.Textbox(label="Status", value="Ready", interactive=False, scale=4) | |
| refresh_btn = gr.Button("🔄 Refresh Data (Force Redownload)", scale=1) | |
| with gr.Tabs(): | |
| with gr.TabItem("Translate Pending"): | |
| gr.Markdown("Select rows to translate and click Submit.") | |
| with gr.Row(): | |
| auto_select_btn = gr.Button("Auto-Select Next 10", size="sm") | |
| translate_btn = gr.Button("Translate Selected Rows", variant="primary") | |
| pending_df_comp = gr.DataFrame( | |
| value=get_pending_data(load_data()), | |
| label="Pending Translations", | |
| interactive=True, | |
| wrap=True, | |
| datatype=["bool", "number"] + ["str"] * 6 | |
| ) | |
| auto_select_btn.click( | |
| fn=auto_select_pending, | |
| inputs=[pending_df_comp], | |
| outputs=[pending_df_comp, status_output] | |
| ) | |
| with gr.TabItem("History (Revert Supported)"): | |
| gr.Markdown("Select rows to delete translation and move back to Pending.") | |
| date_filter = gr.Textbox(label="Filter by Date (YYYY-MM-DD)") | |
| # History now has checkbox | |
| history_df_comp = gr.DataFrame( | |
| value=get_history_data(load_data()), | |
| label="Translation History", | |
| interactive=True, | |
| wrap=True, | |
| datatype=["bool", "number"] + ["str"] * 6 | |
| ) | |
| with gr.Row(): | |
| date_filter.change(fn=filter_history, inputs=[date_filter], outputs=[history_df_comp]) | |
| revert_btn = gr.Button("Revert Selected (Delete & Move to Pending)", variant="stop") | |
| translate_btn.click( | |
| fn=on_translate_selected, | |
| inputs=[pending_df_comp, hf_token], | |
| outputs=[pending_df_comp, history_df_comp, status_output] | |
| ) | |
| revert_btn.click( | |
| fn=on_revert_selected, | |
| inputs=[history_df_comp, hf_token], | |
| outputs=[pending_df_comp, history_df_comp, status_output] | |
| ) | |
| refresh_btn.click( | |
| fn=refresh_views, | |
| outputs=[pending_df_comp, history_df_comp, status_output] | |
| ) | |
| if __name__ == "__main__": | |
| app.launch(css=custom_css) | |