dbus, zenity e kdialog

Iniciado por vampire_thunder, 05 de Maio de 2011, 14:43

tópico anterior - próximo tópico

vampire_thunder

Pergunta difícil, mas lá vai:

Estou tentando converter um script que usa kdialog (KDE) para zenity (GTK).
Já mudei quase tudo, adaptando os diálogos do kdialog para o zenity, mas chegou numa parte que não estou conseguindo avançar. É a seguinte:

dcopRef=$(kdialog --title $"mencoder" --progressbar $"Iniciando..." 12 2> /dev/null)
qdbus $dcopRef org.freedesktop.DBus.Properties.Set org.kde.kdialog.ProgressDialog maximum 100 2> /dev/null
qdbus $dcopRef org.kde.kdialog.ProgressDialog.showCancelButton true 2> /dev/null


A primeira linha substituí por essa:

dcopRef=$(zenity --progress --title $"Mencoder"  --text $"Iniciando..." 12 2> /dev/null)


O problema são as outras. Fiquei um bom tempo no Google mas não encontrei nada equivalente ao "org.kde.kdialog.ProgressDialog" para o zenity. O máximo que percebi foi que eu devo usar o dbus-send no lugar do qdbus.

Alguém sabe?


Outro problema que estou tendo é com a função de seleção de arquivos. No kdialog é assim:

kdialog --multiple --separate-output --getopenfilename


Substituí por isso:

zenity --file-selection --multiple


Acontece que no kdialog, o parâmtro --separate-output divide os múltiplos arquivos em uma lista, um embaixo do outro, enquanto no zenity não tem essa opção e os nomes dos arquivos ficam um do lado do outro, na mesma linha. Como faço para burlar isso?

irtigor

#1
Se colocar o código original - inteiro - a coisa fica mais fácil, ou pelo menos informa o que o programa deveria fazer (as vezes a única forma é escrever do zero).
---
Olhe: http://linuxlibrary.org/index.php/command-line/zenity-simple-gui-creation-tool/

vampire_thunder

Os comandos do zenity e do kdialog eu li no --help-all. A questão mora no dbus, que não sei nada (eu também não sabia os do zenity) e não consigo encontrar. Acredito que eu realmente não esteja sabendo procurar, porque provavelmente deve ter muita diferença entre o qdbus e o dbus-send (ou outro), o que deve diferenciar o org.freedesktop presente no comando.

No entanto, nas pesquisas que fiz encontrei esse script:
http://svn.dmdirc.com/trunk/installer/linux/progressbar.sh

Dando uma olhada nele, vi que o org. alguma coisa só aparece quando usa o kdialog. Quando usa o zenity não aparece. Então talvez eu nem precise desse monte de parâmetros.


Citação de: irtigor online 05 de Maio de 2011, 18:18
Se colocar o código original - inteiro - a coisa fica mais fácil, ou pelo menos informa o que o programa deveria fazer (as vezes a única forma é escrever do zero).
---
Olhe: http://linuxlibrary.org/index.php/command-line/zenity-simple-gui-creation-tool/

O programa é o Big Converter, do Big Linux, que é um frontend do mencoder. Achei no svn deles uma versão mais antiga. Não sei se teve mudanças, mas basicamente é isso:
http://biglinux.googlecode.com/svn/trunk/karmic/bigcontrolcenter-others-convert/usr/share/bigcontrolcenter/categories/others/bigconvert/submit.sh.htm

irtigor

Só serve pra mostrar uma barra de progresso. O mencoder informa isso? Se sim basta passar por um pipe.

vampire_thunder

Citação de: irtigor online 05 de Maio de 2011, 20:42
Só serve pra mostrar uma barra de progresso. O mencoder informa isso? Se sim basta passar por um pipe.

Não sei bem se ele informa. O que ele faz realmente é mostrar uma saída de 4 em 4 milésimos de segundos com o progresso até a conversão acabar:

O script, então, joga isso para um log: "> /tmp/mencoder-log$$ 2> /dev/null"

e nessa parte faz a leitura para atualizar a barra:

(...)
  #Adiciona mais dados sobre a barra de progresso
  qdbus $dcopRef org.kde.kdialog.ProgressDialog.setLabelText " Convertendo, aguarde por favor.

$(sed '$!d;s/(.*)//;s/A.*//;s/V//' /tmp/mencoder-log$$)"


  #Faz a leitura do Log e atualiza a barra de progresso
  qdbus $dcopRef org.freedesktop.DBus.Properties.Set org.kde.kdialog.ProgressDialog value $(sed '$!d;s/.*(//; s/%.*//' /tmp/mencoder-log$$)



O resultado:


O zenity com o comando "--progress --percentage=" mostra a porcentagem a partir do número mencionado, mas não continua a encher automaticamente.

irtigor

Você pode tirar o "--percentage=", você só precisa passar a porcentagem pro zenity, ex:

(
echo "00"; sleep 1
echo "33"; sleep 1
echo "66"; sleep 1
echo "100"
) |
zenity --progress --title="Aguarde..."


Se for pra seguir o original, uma saída é ler o arquivo enquanto o mencoder existe, algo como

while [ -n "`mencoder`" ] ; do
      cat /tmp/mencoder-log | filtro | zenity --progress --title="Aguarde..."
done

O "filtro" é a remoção de qualquer coisa diferente da porcentagem.

vampire_thunder

Citação de: irtigor online 06 de Maio de 2011, 07:21
Você pode tirar o "--percentage=", você só precisa passar a porcentagem pro zenity, ex:

(
echo "00"; sleep 1
echo "33"; sleep 1
echo "66"; sleep 1
echo "100"
) |
zenity --progress --title="Aguarde..."


Se for pra seguir o original, uma saída é ler o arquivo enquanto o mencoder existe, algo como

while [ -n "`mencoder`" ] ; do
     cat /tmp/mencoder-log | filtro | zenity --progress --title="Aguarde..."
done

O "filtro" é a remoção de qualquer coisa diferente da porcentagem.

Humm...
E como poderia ser esse filtro?

Tentei colocar o que já tinha no script:
cat /tmp/mencoder-log$$ | sed '$!d;s/(.*)//;s/A.*//;s/V//' /tmp/mencoder-log$$  | zenity --progress --title "Aguarde..."
Não funcionou. Ficou uma janela com um botão OK na tela direto. Eu dava OK e ela reaparecia, mesmo depois da conversão concluída.

Então tive a ideia de jogar o filtro para dentro do zenity:
cat /tmp/mencoder-log$$ | zenity --progress --title "Aguarde..." --text $(sed '$!d;s/(.*)//;s/A.*//;s/V//' /tmp/mencoder-log$$)


Também não deu certo, porque dá erro no sed.

Então gerei outro log só com a saída e tentei inseri-lo no zenity:
cat /tmp/mencoder-log$$ | sed '$!d;s/(.*)//;s/A.*//;s/V//' /tmp/mencoder-log$$  > /tmp/mencoder-percent$$ 2> /dev/null | zenity --progress --title "Aguarde..." --text $(cat /tmp/mencoder-percent$$)

E também não funcionou  :-\

Já a primeira opção, só funcionaria se a porcentagem estivesse associada ao mencoder, não? Ou eu estou enganado? E para ficar legal teria de ter mais parâmetros, pois vídeos grandes demorariam muito para a barra de progresso aumentar.

Mesmo com isso tudo, acredito que já estamos chegando no objetivo.

irtigor

Por isso tem o while, só que eu errei na verificação... o correto seria algo como while [ -n "`pidof mencoder`" ] ; doOnde "mencoder" é o nome exato do processo. O do firefox, por exemplo, é firefox-bin. Outra opção seria zerar o tamanho do arquivo no final e fazer a verificação enquanto ele tem tamanho... o importante é fazer o zenity parar de receber informação, caso contrário ele não ele não fecha mesmo, se quiser testar: while [ 1 ] ; do echo 100 | zenity --progress --title="Aguarde..."; done
(vai ter que matar)

vampire_thunder

Desculpe, sou meio noob.

Tentei a linha while [ -n "`pidof mencoder`" ] ; do echo 100 | zenity --progress --title="Aguarde..."; done

Aparece a janela "aguarde"... com a barra toda cheia e um botão OK. Ela não desaparece sozinha, só quando dá OK.

Daí fiz o casamento:
while [ -n "`pidof mencoder`" ] ; do
(
echo "00"; sleep 1
echo "33"; sleep 1
echo "66"; sleep 1
echo "100"
) |
zenity --progress --title="Aguarde..."; done


Assim a barra vai enchendo, mas bem rápido, como havia imaginado, e se eu der OK ela enche de novo.

Mas afinal, o que eu fiz estava certo?


irtigor

- 0 é 0% de progresso, 33 é 33% de progresso, 66... por isso você deve pegar o pregresso apresentado no terminal.

- A condição é enquanto não é nulo (ou seja, enquanto o programa tem id -- está rodando)... se o processo ainda existe a janela vai ser recriada. Mas dá mudar pra, por exemplo, "while [ -e "/tmp/mencoder-log" ]" enquanto o mencoder-log existe (ai pra fechar você teria que colocar um rm apagando o logo depois do comando do mencoder). Olhe: http://aurelio.net/shell/canivete/#test

vampire_thunder

#10
A parte da porcentagem eu até entendi. O que eu não entendi foi como associá-la ao log do mencoder.

Lá no script original tem uma parte que deleta o log:

 #Remove o arquivo de log
 rm -f /tmp/mencoder-log$$


Mas isso é feito depois que a conversão acaba, naturalmente.

Outra coisa que não entendi foi o fato de ter um botão OK ativo, enquanto o cancelar está inativo. E se eu quiser parar o processo?

Estava dando uma olhada no Yad, um zenity "melhorado", e vi que lá dá para controlar melhor a criação de botões:
http://www.webupd8.org/2010/12/yad-zenity-on-steroids-display.html

Será que vale a pena trocar o zenty pelo yad?

Edit: achei isso:
http://code.google.com/p/yad/wiki/TimeoutIndicator

Colei o código dentro do script mas não funcionou também. E aqui também não tinha nenhum arquivo .gtkrc-2.0.

irtigor

-O botão "cancel" é desabilitado quando o progresso é 100% e o "ok" é habilitado. Sem uma opção de habilitar manualmente o botão (acho que não existe no zenity), vai ser necessário um recurso técnico do tipo: verifica se o mencoder informou progresso de 100, se ele ainda está rodando, mostre 99 caso contrário mostre 100.

-O zenity é meio engessado mesmo, mas não achei o yad vantagem nesse caso. O ideal seria escrever em algo que desse pleno controle, como python ou perl (poderia ser qualquer linguagem, desde que fosse possível usar o gtk sem amarras).

vampire_thunder

Citação de: irtigor online 07 de Maio de 2011, 09:29
-O botão "cancel" é desabilitado quando o progresso é 100% e o "ok" é habilitado. Sem uma opção de habilitar manualmente o botão (acho que não existe no zenity), vai ser necessário um recurso técnico do tipo: verifica se o mencoder informou progresso de 100, se ele ainda está rodando, mostre 99 caso contrário mostre 100.


Mas é exatamente isso que o script faz usando o qdbus+kdialog. O tal loop.

Eu percebi que a barra do zenity aparece cheia porque o log foi criado, então eu cancelei a criação do log. Deixei o mencoder puro.
~/.convert/mencoder | while [ -n "`pidof mencoder`" ] ; do
(
echo "00"; sleep 1
echo "33"; sleep 1
echo "66"; sleep 1
echo "100"
) |
zenity --progress --title $"Mencoder" --text="por favor aguarde um instante." --auto-close --auto-kill; done


Com isso a barra passou a encher, mas daquele jeito: enche rápido e depois dá um loop, voltando a encher, sem parar, até depois da conversão.


Se eu desabilito essas linhas que vem em baixo, e não sei para que servem, o script não funciona:
IFS=$ORI_IFS
(...)
  IFS=$'\n'
fi
done
IFS=$ORI_IFS

Naquela página do shell, eu vi que tem uma opção de dar loop segundo um arquivo:
Citar
Loop nas linhas de um arquivo ou saída de comando
cat /etc/passwd | while read LINHA; do echo "$LINHA"; done
grep 'root' /etc/passwd | while read LINHA; do echo "$LINHA"; done
while read LINHA; do echo "$LINHA"; done < /etc/passwd
while read LINHA; do echo "$LINHA"; done < <(grep 'root' /etc/passwd)

De repente o caminho é por aí. Só não sei como se faz.

irtigor

#13
No exemplo eu usei um valor arbitrário qualquer, é claro que ele não vai refletir o real progresso. Olhe a terceira mensagem.

---
A minha terceira mensagem.

vampire_thunder

Tirei tudo e deixei assim:

~/.convert/mencoder | while [ -n "`pidof mencoder`" ] ; do
      zenity --progress --title $"Mencoder" --text="por favor aguarde um instante." --auto-close --auto-kill
done


Quase funcionou. A barra não enche mas pelo menos fecha sozinha depois que a conversão acaba.