File size: 6,454 Bytes
bb9f5fd
76a8909
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb9f5fd
76a8909
bb9f5fd
76a8909
 
 
 
 
 
 
 
 
 
bb9f5fd
76a8909
 
 
 
 
 
bb9f5fd
76a8909
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb9f5fd
76a8909
 
 
 
 
 
 
 
 
 
bb9f5fd
 
76a8909
bb9f5fd
 
 
 
76a8909
bb9f5fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76a8909
bb9f5fd
 
 
 
 
76a8909
bb9f5fd
76a8909
bb9f5fd
 
 
 
 
 
 
 
 
 
 
 
76a8909
bb9f5fd
 
 
76a8909
 
 
 
 
 
 
 
 
 
 
 
 
bb9f5fd
 
76a8909
 
 
bb9f5fd
 
76a8909
 
 
 
 
 
 
 
bb9f5fd
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
# app.py - Gradio app (corrigido) para rodar DECOMPAI em Hugging Face Spaces
import os
import traceback
from typing import Optional

import gradio as gr

# Tenta carregar cliente da Hugging Face (para fallback via Inference API)
hf_token = os.environ.get("HF_TOKEN") or os.environ.get("HUGGINGFACE_TOKEN") or None
INFERENCE_MODEL = "tiiuae/falcon-40b-instruct"  # exemplo: substitua por um modelo apropriado

try:
    from huggingface_hub import InferenceClient
    hf_client = InferenceClient(token=hf_token) if hf_token else None
except Exception:
    hf_client = None

# Tenta importar função local do repositório (ajuste o caminho/nome conforme seu projeto)
LOCAL_DECOMPILE_FN = None
try:
    # tente alguns caminhos comuns — ajuste para o nome real do seu projeto
    try:
        from decompai import decompile_text as _fn  # ajuste conforme disponível
        LOCAL_DECOMPILE_FN = _fn
    except Exception:
        try:
            from src.decompai import decompile_text as _fn2
            LOCAL_DECOMPILE_FN = _fn2
        except Exception:
            LOCAL_DECOMPILE_FN = None
except Exception:
    LOCAL_DECOMPILE_FN = None


def run_local_decompile(text: str) -> str:
    """Chama a função local (se existir). Deve retornar string com resultado."""
    if not LOCAL_DECOMPILE_FN:
        raise RuntimeError("Função local decompiladora não encontrada.")
    return LOCAL_DECOMPILE_FN(text)


def run_hf_inference(prompt: str, model_name: Optional[str] = None) -> str:
    """Fallback: usa Hugging Face Inference API para gerar uma resposta."""
    model = model_name or INFERENCE_MODEL
    if not hf_client:
        raise RuntimeError("HF client não disponível — verifique HF_TOKEN nas Secrets do Space.")
    try:
        out = hf_client.text_generation(model=model, inputs=prompt, max_new_tokens=512)
        if isinstance(out, list):
            return out[0].get("generated_text", str(out[0]))
        if isinstance(out, dict):
            return out.get("generated_text") or str(out)
        return str(out)
    except Exception as e:
        try:
            resp = hf_client(model=model, inputs=prompt)
            return str(resp)
        except Exception as e2:
            raise RuntimeError(f"Erro na Inference API: {e}\n{e2}")


def prepare_prompt_from_input(file_contents: Optional[str], text_input: Optional[str]) -> str:
    prompt_parts = []
    if file_contents:
        prompt_parts.append("Input (arquivo/hex/binário):\n" + file_contents)
    if text_input:
        prompt_parts.append("Input (texto):\n" + text_input)
    prompt = "\n\n".join(prompt_parts)
    prompt = "Por favor, tente decompilar / traduzir o seguinte conteúdo para um código legível. Explique suposições e indique se algo não pôde ser recuperado.\n\n" + prompt
    return prompt


def read_file_contents_from_path_or_obj(file_obj) -> str:
    """
    Normaliza o conteúdo do arquivo:
    - se file_obj for caminho (str) e existir -> lê bytes e tenta decodificar (utf-8, latin1) ou retorna hex
    - se file_obj for bytes -> tenta decodificar ou retorna hex
    - se file_obj for None -> retorna None
    """
    if file_obj is None:
        return None
    # Se for string que representa caminho
    if isinstance(file_obj, str):
        path = file_obj
        if os.path.exists(path):
            with open(path, "rb") as f:
                b = f.read()
            try:
                return b.decode("utf-8")
            except Exception:
                try:
                    return b.decode("latin-1")
                except Exception:
                    return b.hex()
        else:
            # talvez seja conteúdo textual já
            return file_obj
    # se for bytes/bytearray
    if isinstance(file_obj, (bytes, bytearray)):
        try:
            return file_obj.decode("utf-8")
        except Exception:
            try:
                return file_obj.decode("latin-1")
            except Exception:
                return file_obj.hex()
    # file-like object (quando Spaces envia um dict ou objeto)
    try:
        # many cases in HF Spaces pass a dict-like with "name" or a tempfile-like object
        name = getattr(file_obj, "name", None)
        if name and os.path.exists(name):
            with open(name, "rb") as f:
                b = f.read()
            try:
                return b.decode("utf-8")
            except Exception:
                try:
                    return b.decode("latin-1")
                except Exception:
                    return b.hex()
    except Exception:
        pass
    # fallback para str()
    try:
        return str(file_obj)
    except Exception:
        return "<ERRO lendo arquivo>"


def decompile_interface(file_obj, text_input, model_name):
    try:
        file_contents = read_file_contents_from_path_or_obj(file_obj)
        prompt = prepare_prompt_from_input(file_contents, text_input)

        if LOCAL_DECOMPILE_FN:
            result = run_local_decompile(prompt)
            return f"--- Resultado (função local) ---\n{result}"
        if hf_client:
            result = run_hf_inference(prompt, model_name=model_name or INFERENCE_MODEL)
            return f"--- Resultado (Hugging Face Inference API) ---\n{result}"
        return "Nenhuma função local disponível e HF client não está configurado. Defina HF_TOKEN nas Secrets do Space."
    except Exception as e:
        tb = traceback.format_exc()
        return f"Erro durante a decompilação:\n{e}\n\nTraceback:\n{tb}"


with gr.Blocks(title="DECOMPAI - Decompiler (Spaces)") as demo:
    gr.Markdown("# DECOMPAI (Exemplo de Space)\nEnvie um arquivo ou cole texto e escolha o modelo (opcional).")
    with gr.Row():
        with gr.Column(scale=2):
            # <-- CORREÇÃO AQUI: usar type='filepath' ou 'binary'. Para ler do disco usamos 'filepath'
            file_in = gr.File(label="Arquivo (binário/hex) — opcional", file_count="single", type="filepath")
            text_in = gr.Textbox(label="Ou cole conteúdo / hex / texto aqui", lines=8)
            model_in = gr.Textbox(label="Modelo HF (opcional, ex: 'tiiuae/falcon-40b-instruct')", placeholder=INFERENCE_MODEL)
            run_btn = gr.Button("Decompilar")
        with gr.Column(scale=3):
            output = gr.Textbox(label="Resultado", lines=24)
    run_btn.click(fn=decompile_interface, inputs=[file_in, text_in, model_in], outputs=[output])

if __name__ == "__main__":
    demo.launch()