Open Dovyski opened 3 years ago
Eu estava realizando alguns testes alterando algumas informações ali no main.js do LBK e na página que mostra o conteúdo do LBK e acabei chegando no seguinte resultado do print abaixo, não sei se essa é a funcionalidade que estamos buscando, mas foi aonde eu cheguei.
Agora vou alterar para fazer o download pelo controller usando o puppeter.
Boa tarde, eu estou tendo alguns problemas com o node/puppeteer para coseguir capturar a imagem.
Conforme testei, foi possível capturar a imagem apenas quando o servidor era hosteado em portas diferentes, exemplo:
http://127.0.0.1:8000
não consegue capturar a imagem de http://127.0.0.1:8000/assets/lbk/screens/blank
(público para acesso sem autenticação), porém consegue capturar a imagem de http://127.0.0.1:8001/assets/lbk/screens/blank
.
Demorou até eu conseguir descobrir que funcionava com outra porta e tudo, por enquanto vou explorando para tentar achar uma solução.
Segue o erro:
(node:12858) UnhandledPromiseRejectionWarning: TimeoutError: Navigation timeout of 30000 ms exceeded
at /home/guilherme/Documents/practice/maker/node_modules/puppeteer/lib/cjs/puppeteer/common/LifecycleWatcher.js:106:111
at async FrameManager.navigateFrame (/home/guilherme/Documents/practice/maker/node_modules/puppeteer/lib/cjs/puppeteer/common/FrameManager.js:91:21)
at async Frame.goto (/home/guilherme/Documents/practice/maker/node_modules/puppeteer/lib/cjs/puppeteer/common/FrameManager.js:417:16)
at async Page.goto (/home/guilherme/Documents/practice/maker/node_modules/puppeteer/lib/cjs/puppeteer/common/Page.js:1156:16)
at async Screenshot (/home/guilherme/Documents/practice/maker/public/screenshotscript.js:6:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:12858) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:12858) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Daí estou nesse momento em descobrir como contornar este problema, não sei se o node que é rodado pelo servidor deve utilizar de outra porta ou algo assim, @Dovyski se você tiver alguma dica/caminho para eu seguir
Através deste site: https://laravel-news.com/puphpeteer Eu achei esse pacote: https://github.com/rialto-php/puphpeteer
Será que vale tentar usar essa alternativa?
Me chama no Telegram em alguma manhã para conversarmos sobre essa tarefa, @GuilhermeGraeff . Sobre o pacote, eu achei ele muito interessante (excelente ideia!).
Vamos usar o puphpeteer
para criar o job que fará a captura da imagem. Inclusive com essa abordagem, dentro do job, podemos usar route('algo')
para que o próprio laravel informe a URL da aplicação, assim não teremos problemas com portas e afins.
Não sei se o fluxo é fechar esta issue por enquanto e talvez abrir ela no futuro novamente ou deixar aberta, então não vou fechar.
Eu não consegui concluir esta tarefa por enquanto, mas acho que é importante deixar aqui registrado o que eu testei, o que funcionou e o que não funcionou.
A ideia inicial era utilizar o puppeeteer juntamente com o node para tirar o screenshot da tela com o conteúdo, portanto realizei testes com o node separado do laravel e consegui tirar os prints com diferentes configurações de tamanho e outros parâmetros.
Porém ao utilizar o comando exec()
ou shell_exec()
após construído o controller que recebia as informações do LBK e tudo, o puppeteer excedia o tempo limite de execução (30 segundos), aumentei este tempo e de nada adiantou. Então tive a ideia de rodar dois servidores e tentar um tirar print do outro, o que funcionou tranquilamente, porém este não é o fluxo que acontece, então passei a parte de tirar o print para um job do Laravel, pois os jobs são rodados separadamente, e aí sim eu consegui tirar o print, porém agora o problema era retornar esta informação do job para o LBK.
Então após pesquisar eu encontrei o puphpeteer que é uma "ponte" do puppeteer para PHP, e também realizei testes que resultaram em prints de sites de exemplo tranquilamente inclusive o LBK fazia o download destes prints dos sites que usei como teste (google/youtube...), porém quando tentava tirar um print da tela do LBK não era possível, excedia-se o tempo limite novamente, assim como ocorreu anteriormente. E nessa segunda rodada de testes eu rodei o puphpeteer já com as alteração do Fernando que era apenas "entregar" a imagem em base64 que o LBK faria o download, o que funcionou com os sites de teste.
Quando o usuário criar algum material no LBK (um poster, por exemplo) e clicar no botão
Download
, o conteúdo será gerado por um browser no back-end e, em seguida, enviado ao front-end para download. Esse processo será implementado como um job do Laravel no futuro. Para agora, vamos fazer uma implementação não ideal, porém bem mais simples.A ideia é a seguinte:
Download
ContentController@download
)download
do controllerContentController
roda um comando na máquina (usandoexec()
,system()
, etc) que é um script node que usa o puppeteerdownload()
do controller terá o retorno do script, que é a imagem resultado em formato basee64. Essa informação é retornada pelo controller dentro do campodownload_url
Dica 1
Eu acho que o mais fácil para se começar essa tarefa é criar um script node que utilize o puppeter para acessar uma URL e tirar um screenshot dela. Em seguida, o próximo passo pode ser imprimir no console essa imagem codificada como base64. Existem vários materiais na internet sobre como tirar um screenshot usando puppeter:
Dica 2
O projeto ccuffs/api-cc faz uso desse mesmo fluxo. No caso da api-cc, o script node é utilizado para acessar uma página dos sistemas da UFFS e imprimir seus conteúdos (para que o Laravel faça uso).
A execução do script acontece no arquivo SgaScrapper. Há um arquivo de configuração chamado sgascraper que contém informações sobre como o script node é executado (em linhas gerais, ele tem um
node script.js
). No caso da API cc, o script node usa um arquivo de configuração externo, que não será utilizado pelo nosso. No nosso caso, o script node pode receber os parâmetros direto pela linha de comando.