No description
  • Java 74.8%
  • Python 24.9%
  • Shell 0.2%
  • Dockerfile 0.1%
Find a file
2026-09-06 19:20:56 -03:00
nbproject fix: NoClassDefFoundError ao abrir - JSR-75 isolado em FileStoreImpl (lazy) + Store preverify + versao 1.1 2026-09-06 18:12:20 -03:00
src/lucy feat: downloads RMS ate 30KB (era 12KB) 2026-09-06 19:20:56 -03:00
.gitignore Lucy MIDlet: proxy + app J2ME (CLDC 1.1/MIDP 2.0) 2026-09-05 22:18:22 -03:00
AGENTS.md Lucy MIDlet: proxy + app J2ME (CLDC 1.1/MIDP 2.0) 2026-09-05 22:18:22 -03:00
build.sh Lucy MIDlet: proxy + app J2ME (CLDC 1.1/MIDP 2.0) 2026-09-05 22:18:22 -03:00
Dockerfile Dockerfile: imagem para rodar o proxy (Python 3.13, usuario nao-root) 2026-09-05 22:23:32 -03:00
proxy.py fix: rename de arquivo na nuvem, arquivar nota e auto-login no telefone 2026-09-06 17:52:31 -03:00
README.md feat: sem API key - MIDlet loga na Lucy por usuario/senha (proxy em modo aberto) 2026-09-06 00:03:47 -03:00

Lucy para telefone simples (J2ME)

MIDlet J2ME (CLDC 1.1 / MIDP 2.0) + proxy HTTP para usar a Lucy em celular comum ("dumbphone"), sem HTTPS. O MIDlet fala HTTP com o proxy; o proxy autentica na Lucy via sessao (cookie) e expoe um JSON compacto para o telefone.

telefone (MIDlet) --HTTP--> LucyProxy (python) --HTTPS + cookie--> Lucy

Por que um proxy?

  1. Celulares comuns de 2010 nao tem HTTPS (nem TLS moderno).
  2. Em modo API key, a Lucy original ignora chat_id e joga tudo no chat fixo "API KEY - " (routes/api.py:_resolve_request_chat_id). O proxy loga como usuario normal e resolve qualquer chat por id, viabilizando multi-chats, historico, cloud, notas e caixa de entrada.

Componentes

  • proxy.py - servidor HTTP do telefone (lib Python pura). Le as variaveis:
    • LUCY_BASE_URL URL da Lucy (padrao: https://chat.opentty.fun)
    • LUCY_USERNAME / LUCY_PASSWORD (OPCIONAL) login fixo no boot; o padrao e o usuario digitar usuario/senha no proprio MIDlet (Config -> Login/Testar), que mandam POST /p/login para o proxy
    • LUCY_API_KEY (OPCIONAL) chave fixa p/ modo fechado. Se vazia, o proxy roda em modo aberto: o telefone loga na Lucy por usuario/senha (Config -> Login/Testar), sem API key.
    • LUCY_VALIDATE_KEY legado (sem efeito)
    • LUCY_PORT porta do proxy (padrao 8090)
    • LUCY_BIND interface (padrao 0.0.0.0)
    • LUCY_EMAIL (opcional) email padrao para novos uploads compartilhados
  • src/lucy/ - codigo do MIDlet.
    • LucyApp - controladora + menu principal
    • SettingsScreen - proxy (URL) + usuario/senha da conta Lucy
    • ChatListScreen / ChatScreen - conversas, enviar, anexar, reportar
    • CloudScreen / TextEditorScreen - nuvem (navegar, abrir, editar, baixar)
    • NotesScreen / NoteEditScreen - notas, tags, arquivar, lixeira
    • InboxScreen - caixa de entrada
    • DownloadsScreen - arquivos baixados (guardados no RMS)
    • Api (HTTP CLDC), Json (parser), Store (RMS), Util
  • nbproject/project.properties - manifest do MIDlet
  • build.sh - compila com o SDK local

Rodando o proxy

O proxy pode rodar de dois jeitos:

  1. Modo aberto (recomendado p/ servidor exposto a internet): nao configure LUCY_API_KEY. O telefone loga na propia conta por usuario/senha (Config -> Login/Testar) e o proxy mantem a sessao (cookie). Se o MIDlet mandar uma chave lucy_*, ela tambem e aceita (sessao separada por chave):

    python3 proxy.py            # escuta em 0.0.0.0:8090
    
  2. Modo fechado: fixa a chave do telefone no proxy e, opcionalmente, o login:

    export LUCY_API_KEY=suachave
    export LUCY_USERNAME=seu_usuario
    export LUCY_PASSWORD=sua_senha
    

Teste rapido (modo aberto, sem chave):

curl -H 'Content-Type: application/json' \
     -X POST http://127.0.0.1:8090/p/login -d '{"u":"seu.user","p":"sua.senha"}'
curl http://127.0.0.1:8090/p/whoami   # apos login

Instalando no telefone

  1. Compile o MIDlet (Linux, com o SDK local):
    ./build.sh        # gera dist/Lucy.jad + dist/Lucy.jar
    
  2. Copie dist/Lucy.jad e dist/Lucy.jar para o celular (bluetooth, cabo, slot) e instale como outro MIDlet.
  3. No celular: Config, preencha Proxy (http://IP_do_pc:8090), Usuario Lucy e Senha Lucy, Salvar e Login/Testar (o proxy entra na Lucy e mostra seu nome). Pronto: Chat, Nuvem, Notas, Caixa de Entrada, Status e Downloads.

Endpoints que o MIDlet usa (resumo)

Todas sob /p/; o header X-API-Key e opcional (usado só em modo fechado).

Acao Rota
entrar na Lucy POST /p/login {u,p} (feito pelo MIDlet em Config)
quem sou GET /p/whoami
status da Lucy GET /p/status
conversas GET /p/chats , POST /p/chats , PUT /p/chats/<id> , DELETE /p/chats/<id>
historico GET /p/chat/h/<id>?n=40
enviar POST /p/chat {m,c,a:[{i,n}]} (via SSE da Lucy)
reportar POST /p/chat/report {i:conv,w:motivo}
nuvem GET /p/cloud?p=, POST /p/cloud/mkdir, POST /p/cloud/upload, POST /p/cloud/create, DELETE /p/cloud/<id>, POST /p/cloud/<id>/rename, POST /p/cloud/move, GET /p/cloud/view/<id>, GET /p/cloud/info/<id>, GET /p/cloud/download/<id>
editor GET /p/editor/load/<id>, POST /p/editor/save/<id>
notas GET /p/notes?s=all|arch|trash&tag=, GET /p/note/<id>, POST /p/note, PUT /p/note/<id>, DELETE /p/note/<id>?perm=1, POST /p/note/<id>/restore, DELETE /p/notes/trash, GET /p/note/tags
caixa GET /p/inbox, POST /p/inbox/<id>/read, DELETE /p/inbox/<id>, DELETE /p/inbox

Respostas compactas (prefixos curtos) para caber na memoria do celular: chats {ok,c:[{i,t}]}, historico {ok,m:[{i,u,r,a:[..]}]}, nuvem {ok,p,d:[{i,n,d,s,e}],s:[..]}, notas {ok,n:[{i,t,a,tr,tags:[..]}]}, nota {ok,id,t,c,tags:[..]}, tags {ok,tags:[{t,n}]}, caixa {ok,n:[{i,f,c,t,r}]}.

Notas e limitacoes

  • O trafego telefone->proxy nao e criptografado. Use apenas em rede confiavel; o proxy faz HTTP->HTTPS com a Lucy.
  • Usuario/senha da Lucy ficam salvos no RMS do telefone (junto com o proxy), em texto plano, para nao ter que redigitar.
  • O MIDlet compila em ASCII; acentos no teclado do celular sao convertidos.
  • Downloads ficam no RMS do celular (poucos KB por arquivo). Textos longos sao limitados a um preview.
  • Alguns modelos de telefone nao aceitam verbos HTTP fora de GET/POST; se o seu nao aceitar, o proxy tambem aceitaria POST com override (nao usado aqui).
  • Sem confirmacao de exclusao (apagar ja apaga).
  • Reporta com os motivos: nao foi isso que eu quis dizer, resposta insatisfatoria, tipo de resposta errado.

Testes

  • proxy.py contra um mock da Lucy: /tmp/opencode/mock_lucy.py + /tmp/opencode/e2e.py (timeout 60 python3 e2e.py -> "E2E OK").
  • JSON/UTF-8 do MIDlet: /tmp/opencode/lucy-tests/ (javac + java).