├── .gitignore ├── README.md ├── pom.xml └── src ├── main └── java │ └── com │ └── imersaojava │ ├── API.java │ ├── ApiKey.java │ ├── App.java │ ├── ClienteHttp.java │ ├── Extractor.java │ ├── Manipulator.java │ ├── MarvelContent.java │ ├── MarvelExtractor.java │ ├── NasaContent.java │ ├── NasaExtractor.java │ ├── StickersGenerator.java │ ├── TERMINALFORMAT.java │ ├── TheMovieDbContent.java │ └── TheMovieDbExtractor.java └── test └── java └── com └── imersaojava └── AppTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | src/main/java/com/imersaojava/ApiKey.java 2 | 3 | .vscode/* 4 | !.vscode/settings.json 5 | !.vscode/tasks.json 6 | !.vscode/launch.json 7 | !.vscode/extensions.json 8 | !.vscode/*.code-snippets 9 | 10 | # Local History for Visual Studio Code 11 | .history/ 12 | 13 | # Built Visual Studio Code Extensions 14 | *.vsix 15 | target/ 16 | pom.xml.tag 17 | pom.xml.releaseBackup 18 | pom.xml.versionsBackup 19 | pom.xml.next 20 | release.properties 21 | dependency-reduced-pom.xml 22 | buildNumber.properties 23 | .mvn/timing.properties 24 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar 25 | .mvn/wrapper/maven-wrapper.jar 26 | 27 | # Eclipse m2e generated files 28 | # Eclipse Core 29 | .project 30 | # JDT-specific (Eclipse Java Development Tools) 31 | .classpath 32 | # Mobile Tools for Java (J2ME) 33 | .mtj.tmp/ 34 | 35 | # Package Files # 36 | *.jar 37 | *.war 38 | *.ear 39 | 40 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 41 | hs_err_pid* 42 | 43 | # Eclipse 44 | .classpath 45 | .project 46 | .settings/ 47 | 48 | # Intellij 49 | .idea/ 50 | *.iml 51 | *.iws 52 | 53 | # Mac 54 | .DS_Store 55 | 56 | # Maven 57 | log/ 58 | target/ 59 | 60 | # Inclusions 61 | !lib/** 62 | 63 | # Compiled Files 64 | *.class 65 | bin/ 66 | build/ 67 | /bin1/ 68 | java/build/** 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![CacheLib](https://lh4.googleusercontent.com/Lb2XTpd5bBDdZm2bmdG1y3YpwX18BEyCeEfOlpfpRulDMlWKjy0a1Bvs6J33iTsBcAn0Tew6J1DE2zlAUg7XhUeoE1wBjeVcNpdF6lQeWgdzLIr0tEDlfaPuOvv5vG2KDQ=w1600) 2 | 3 | ![](http://img.shields.io/static/v1?label=STATUS&message=EM%20DESENVOLVIMENTO&color=GREEN&style=for-the-badge) 4 | 5 | ## Índice 6 | 7 | * [Índice](#índice) 8 | * [Descrição do Projeto](#descrição-do-projeto) 9 | * [Funcionalidades do projeto](#funcionalidades-do-projeto) 10 | * [Acesso ao projeto](#acesso-ao-projeto) 11 | * [Técnicas e tecnologias utilizadas](#Técnicas-e-tecnologias-utilizadas) 12 | * [Links citados](#Links-citados) 13 | * [Desafios](#Desafios) 14 | * [Material Complementar](#Material-Complementar) 15 | * [Autores](#Autores) 16 | * [Instrutores e Instrutoras da Alura nessa imersão](#Instrutores-e-Instrutoras-da-Alura-nessa-imersão) 17 | 18 | ## Descrição do projeto 19 | 20 | Construção de uma aplicação do zero para consumir a API do IMDb e exibir os filmes mais populares, destacando seus pôsteres e visualizando sua classificação... 21 | 22 | Criar um gerador de figurinhas explorando outras bibliotecas nativas do Java, para que possamos enviar por Whatsapp os nossos filmes preferidos! 23 | 24 | Construção de uma API REST para expor nosso próprio conteúdo, utilizando ferramentas profissionais como o Spring Framework e um banco de dados NoSQL. 25 | 26 | Aplicação acessível por qualquer pessoa, fazendo o deploy na nuvem. 27 | 28 | ## Funcionalidades do projeto 29 | 30 | - `Funcionalidade 1`: Stickers no WhatsApp 31 | > ![](https://i.imgur.com/Sbku1Zv.jpg) 32 | 33 | - `Funcionalidade 2`: Terminal personalizado 34 | > ![](https://i.imgur.com/4nSouEj.png) 35 | 36 | - `Funcionalidade 3`: descrição da funcionalidade 3 37 | 38 | ## Acesso ao projeto 39 | 40 | 41 | 42 | | [api-stickers.git](https://github.com/cleverlf/api-stickers.git) | [linguagem-api.git](https://github.com/cleverlf/linguagem-api.git) | 43 | |:----------------------------------------------------------------:|:---------------------------------------------------------------------------:| 44 | | | [Minha API na nuvem](https://api-alura-linguagens.herokuapp.com/linguagens) | 45 | 46 | 47 | ## Técnicas e tecnologias utilizadas 48 | 49 | - ``Java`` 50 | - ``Visual Studio Code`` 51 | - ``Paradigma de orientação a objetos`` 52 | - ``Maven`` 53 | - ``Spring Boot`` 54 | - ``MongoDB`` 55 | - ``Heroku`` 56 | - ``Gson`` 57 | - ``TMDB API`` 58 | - ``Nasa API`` 59 | - ``Marvel API`` 60 | 61 | ## Links citados 62 | 63 | *``Aula 1 :``* 64 | 65 | * Os [250 melhores filmes de acordo com a classificação do IMDB](https://www.imdb.com/chart/top/). 66 | 67 | * A [documentação da API do IMDB](https://imdb-api.com/api). 68 | 69 | * Instalação do Visual Studio Code com o [Coding Pack para Java](https://code.visualstudio.com/docs/languages/java#_install-visual-studio-code-for-java) 70 | 71 | * Documentação da classe [HttpRequest do pacote java.net.http](https://docs.oracle.com/en/java/javase/17/docs/api/java.net.http/java/net/http/HttpRequest.html). 72 | 73 | * Classe pronta que utiliza Expressões Regulares para fazer [parse de um JSON](https://gist.github.com/alexandreaquiles/cf337d3bcb59dd790ed2b08a0a4db7a3). 74 | 75 | * [Biblioteca Jackson, que faz parse de JSON](https://github.com/FasterXML/jackson). 76 | 77 | * Site que ajuda a entender [Expressões Regulares](https://regex101.com/). 78 | 79 | * Artigo: [Como deixar no seu GitHub com um README interessante](https://www.alura.com.br/artigos/escrever-bom-readme). 80 | 81 | * O endpoint da API do IMDB que devolve os 250 melhores filmes: [https://imdb-api.com/en/API/Top250Movies/](https://imdb-api.com/en/API/Top250Movies/) + **SUA-API-KEY** 82 | 83 | 84 | *``Aula 2 :``* 85 | 86 | * Documentação do [pacote javax.imageio](https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/javax/imageio/package-summary.html), que trata de leitura e escrita de imagens. 87 | 88 | * Documentação da [classe BufferedImage](https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/java/awt/image/BufferedImage.html), que representa uma imagem no Java 89 | 90 | * Documentação da classe [Graphics2D](https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/java/awt/Graphics2D.html), a “caneta” que permite escrever, desenhar e imprimir outras imagens em uma imagem original. 91 | 92 | * Documentação da [abstração InputStream](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/InputStream.html), que representa um fluxo de leitura de dados de qualquer fonte, como arquivos, URLs, entre outros. 93 | 94 | 95 | *``Aula 3 :``* 96 | 97 | * Documentação das [APIs da NASA](https://api.nasa.gov/). 98 | * API da [Foto Astronômica do dia da NASA](https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY). 99 | * Artigo na Alura [“Como não aprender Java e Orientação a Objetos: getters e setters”](https://www.alura.com.br/artigos/nao-aprender-oo-getters-e-setters). 100 | * Livro [“Design Patterns”](https://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612), de 1994, que descreve soluções comuns para problemas recorrentes de como organizar seu código. 101 | * Livro [“Refactoring”](https://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672), de 1999, que cataloga maneiras sistemáticas de melhorar o código sem modificar o que é feito. 102 | 103 | *``Aula 4 :``* 104 | 105 | * [Documentação do Spring Framework](https://spring.io/). 106 | * Link para [iniciar um projeto utilizando Spring](https://start.spring.io/). 107 | * Link para [download do Maven](https://maven.apache.org/download.cgi). 108 | * Link para [download do Postman](https://www.postman.com/). 109 | * Página para fazer o [registro e começar a utilizar o MongoDb Atlas](https://www.mongodb.com/cloud/atlas/register). 110 | * GitHub com os [logos das linguagens de programação](https://github.com/abrahamcalf/programming-languages-logos). 111 | * Artigo sobre o [pack de stickers da Alura para Whatsapp e Telegram](https://www.alura.com.br/artigos/stickers-dev-aluraverso-whatsapp-telegram). 112 | 113 | *``Aula 5 :``* 114 | 115 | * [Dev em T: especialista x generalista](https://www.alura.com.br/dev-em-t). 116 | * Site do [Heroku](https://www.heroku.com/), que é um PaaS (plataforma como serviço). 117 | * Documentação sobre a [Oracle Cloud](https://docs.oracle.com/pt-br/iaas/Content/home.htm). 118 | * Artigo: [Como elaborar um bom arquivo Readme para os seus projetos](https://www.alura.com.br/artigos/escrever-bom-readme). 119 | 120 | ## Desafios 121 | 122 | *``Aula 1 :``* 123 | 124 | 1. - [ ] Consumir o endpoint de filmes mais populares da API do IMDB. Procure também, na documentação da API do IMDB, o endpoint que retorna as melhores séries e o que retorna as séries mais populares. 125 | 126 | 2. - [x] Usar sua criatividade para deixar a saída dos dados mais bonitinha: usar emojis com código UTF-8, mostrar a nota do filme como estrelinhas, decorar o terminal com cores, negrito e itálico usando códigos ANSI, e mais! 127 | 128 | 3. - [x] Colocar a chave da API do IMDB em algum lugar fora do código como um arquivo de configuração (p. ex, um arquivo .properties) ou uma variável de ambiente 129 | 130 | 4. - [x] Mudar o JsonParser para usar uma biblioteca de parsing de JSON como Jackson ou GSON 131 | 132 | 5. - [ ] **Desafio supremo:** criar alguma maneira para você dar uma avaliação ao filme, puxando de algum arquivo de configuração OU pedindo a avaliação para o usuário digitar no terminal. 133 | 134 | 135 | *``Aula 2 :``* 136 | 137 | 1. - [x] Ler a documentação da classe abstrata InputStream. 138 | 2. - [x] Centralizar o texto na figurinha. 139 | 3. - [x] Fazer um pacote no Whatsapp e/ou Telegram com as suas próprias figurinhas! 140 | 4. - [x] Criar diretório de saída das imagens, se ainda não existir. 141 | 5. - [x] Colocar outra fonte como a Comic Sans ou a Impact, a fonte usada em memes. 142 | 6. - [ ] Colocar uma imagem de você que está fazendo esse curso sorrindo, fazendo joinha! 143 | 7. - [x] Colocar contorno (outline) no texto da imagem. 144 | 8. - [x] Tratar as imagens retornadas pela API do IMDB para pegar uma imagem maior ao invés dos thumbnails. Opções: pegar a URL da imagem e remover o trecho mostrado durante a aula ou consumir o endpoint de posters da API do IMDB (mais trabalhoso), tratando o JSON retornado. 145 | 9. - [ ] Fazer com que o texto da figurinha seja personalizado de acordo com as classificações do IMDB. 146 | 10. - [ ] **Desafio supremo:** usar alguma biblioteca de manipulação de imagens como [OpenCV](https://github.com/opencv-java) pra extrair imagem principal e contorná-la. 147 | 148 | *``Aula 3 :``* 149 | 150 | 1. - [ ] Transformar a classe que representa os conteúdos em um Record, disponível a partir do Java 16 151 | 2. - [ ] Criar as suas próprias exceções e usá-las na classe que implementa o cliente HTTP 152 | 3. - [ ] Usar recursos do Java 8 e posterior, como Streams e Lambdas, para mapear uma lista em uma outra 153 | 4. - [x] Criar uma Enum que une, como configurações, a URL da API e o extrator utilizado 154 | 5. - [x] **Desafio supremo:** consumir outras APIs que contém imagens, como a da Marvel, que é bem diferente. Repositório com APIs públicas: [clique aqui](https://github.com/public-apis/public-apis). 155 | 156 | *``Aula 4 :``* 157 | 158 | 1. - [x] Finalizar o CRUD (Create, Read, Update e Delete) para que se possa atualizar e excluir uma linguagem cadastrada; 159 | 2. - [x] Devolver a listagem ordenada pelo ranking; 160 | 3. - [ ] Criar na sua API um modelo de entidade com nomes diferentes de title e image e criar seu próprio extrator de informações personalizado OU, manter com o nome title e image e traduzir para que seja retornado como título e imagem através do uso de DTO (Data Transfer Object); 161 | 4. - [x] Retornar o status 201 quando um recurso (linguagem, no nosso caso) for cadastrado através do POST; 162 | 5. - [ ] **Desafio supremo:** Aplicar modificações parciais no recurso através do método PATCH, por exemplo, modificando o número de votos ou de pessoas que utilizam cada linguagem de programação. 163 | 164 | *``Aula 5 :``* 165 | 166 | 1. - [x] Compartilhe com seus amigos a sua URL do Heroku, para que eles possam consumir a sua API (com o padrão de atributos title e image) e gerar figurinhas do conteúdo que você utilizou (linguagens de programação, filmes, músicas); 167 | 2. - [ ] Colocar a aplicação no cloud da Oracle; 168 | 3. - [ ] Implementar algum mecanismo de votação na API, para que outros amigos votem nas linguagens preferidas para que se possa fazer um ranking; 169 | 4. - [ ] **Desafio supremo**: Evoluir o projeto das três primeiras aula para que ele gere um bundle de stickers, para que se possa fazer o download e já incluir vários stickers no WhatsApp; Usar os conhecimentos aprendidos em alguma imersão React da Alura e fazer uma aplicação front-end para gerar esse bundle, onde possa se passar a URL do conteúdo e já visualizar os stickers; 170 | 171 | ## Material Complementar 172 | 173 | *``Aula 1 :``* 174 | 175 | * Artigo na Alura [“O que é JSON?”](https://www.alura.com.br/artigos/o-que-e-json). 176 | 177 | * Artigo na Alura sobre como [pintar o terminal, com tabelinha de cores e negrito](https://www.alura.com.br/artigos/decorando-terminal-cores-emojis). 178 | 179 | * Artigo na Alura sobre como usar [VS Code para codar em Java](https://www.alura.com.br/artigos/desenvolvendo-aplicacoes-java-vs-code). 180 | 181 | 182 | *``Aula 2 :``* 183 | 184 | * Primeira aula do curso [“Java Polimorfismo: entenda herança e interfaces”](https://www.alura.com.br/conteudo/java-heranca-interfaces-polimorfismo) da Alura. 185 | * Apêndice da apostila [“Java e Orientação a Objetos”](https://www.alura.com.br/apostila-java-orientacao-objetos/apendice-pacote-java-io) da Alura sobre o pacote java.io que explica com mais detalhes a abstração InputStream. 186 | 187 | *``Aula 3 :``* 188 | 189 | * Artigo na Alura [“Como não aprender Java e Orientação a Objetos: herança”](https://www.alura.com.br/artigos/como-nao-aprender-orientacao-a-objetos-heranca). 190 | * Podcast Hipsters.tech sobre [Práticas de Orientação a Objetos](https://www.alura.com.br/podcast/praticas-de-orientacao-a-objetos-hipsters-129-a453). 191 | * Podcast Hipsters.tech sobre [Design Patterns](https://www.alura.com.br/podcast/design-patterns-hipsters-206-a345). 192 | * Podcast Hipsters.tech sobre [SOLID](https://www.alura.com.br/podcast/solid-codigo-bom-e-bonito-hipsters-ponto-tech-219-a649). 193 | 194 | *``Aula 4 :``* 195 | 196 | * Primeira aula do curso [“Maven: gerenciamento de dependências e build de aplicações Java”](https://www.alura.com.br/conteudo/maven-gerenciamento-dependencias-build-aplicacoes-java) da Alura. 197 | * Alura+ [“O que é REST?”](https://www.youtube.com/watch?v=weQ8ssA6iBU&ab_channel=AluraCursosOnline). 198 | * Artigo da Alura [“Conceito e fundamentos sobre REST”](https://www.alura.com.br/artigos/rest-conceito-e-fundamentos). 199 | * Podcast [Hipsters.Tech sobre MongoDB](https://www.hipsters.tech/mongodb-hipsters-ponto-tech-305/). 200 | * Hipters.Tube [“O que é SQL e NoSQL?”](https://www.youtube.com/watch?v=aure5d3B88g&ab_channel=AluraCursosOnline). 201 | * Artigo da Alura [“Spring: Conheça esse framework Java”](https://www.alura.com.br/artigos/spring-conheca-esse-framework-java). 202 | * Alura+ [Introdução ao Postman”](https://www.youtube.com/watch?v=op81bMbgZXs&ab_channel=AluraCursosOnline). 203 | 204 | *``Aula 5 :``* 205 | 206 | * Artigo da Alura [“Heroku, Vercel e outras opções de Cloud como plataforma”](https://www.alura.com.br/artigos/heroku-vercel-outras-opcoes-cloud-plataforma). 207 | * Podcast Hipters.Tech [“Integração Contínua, Deploy Contínuo e Github Actions”](https://www.alura.com.br/podcast/hipsterstech-integracao-continua-deploy-continuo-e-github-actions-hipsters-213-a335). 208 | * Pesquisa da JetBrains, empresa que desenvolve a IDE IntelliJ, [sobre o ecossistema Java em 2021](https://www.jetbrains.com/lp/devecosystem-2021/java/). 209 | 210 | ## Autores 211 | 212 | | ![Clever](https://avatars.githubusercontent.com/u/103513175?s=400&u=b890cd5de5f71649999799d282a196ab7f5a2347&v=4)| 213 | | :---: | 214 | | [Clever](https://github.com/cleverlf) | 215 | 216 | 217 | ## Instrutores e Instrutoras da Alura nessa imersão 218 | ![Jacqueline Oliveira](https://www.alura.com.br/assets/img/imersao-java/jaque-imersao-java-bio.1657213671.png) |![Alexandre Aquiles](https://www.alura.com.br/assets/img/imersao-java/alexandre-imersao-java-bio.1657213503.png)| ![Paulo Silveira](https://www.alura.com.br/assets/img/imersao-java/paulo-imersao-java-bio.1657213503.png) 219 | | :---: | :---: | :---: 220 | Jacqueline Oliveira | Alexandre Aquiles | Paulo Silveira 221 | [![Instagram](https://www.alura.com.br/assets/img/imersao-java/instagram.1655844054.svg)](https://www.instagram.com/jacque.tech/) [![LinkedIn](https://www.alura.com.br/assets/img/imersao-java/linkedin.1655291590.svg)](https://www.linkedin.com/in/jacqueline-r-oliveira/) | [![Instagram](https://www.alura.com.br/assets/img/imersao-java/instagram.1655844054.svg)](https://www.instagram.com/aquiles3137/)[![LinkedIn](https://www.alura.com.br/assets/img/imersao-java/linkedin.1655291590.svg)](https://www.linkedin.com/in/alexandreaquiles/) | [![Instagram](https://www.alura.com.br/assets/img/imersao-java/instagram.1655844054.svg)](https://www.instagram.com/paulo_hipster)[![LinkedIn](https://www.alura.com.br/assets/img/imersao-java/linkedin.1655291590.svg)](https://www.linkedin.com/in/paulosilveira) 222 | 223 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | com.imersaojava 8 | api-sticker 9 | 1.0-SNAPSHOT 10 | 11 | api-sticker 12 | 13 | http://www.example.com 14 | 15 | 16 | UTF-8 17 | 1.7 18 | 1.7 19 | 20 | 21 | 22 | 23 | junit 24 | junit 25 | 4.11 26 | test 27 | 28 | 29 | com.google.code.gson 30 | gson 31 | 2.9.0 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | maven-clean-plugin 42 | 3.1.0 43 | 44 | 45 | 46 | maven-resources-plugin 47 | 3.0.2 48 | 49 | 50 | maven-compiler-plugin 51 | 3.8.0 52 | 53 | 54 | maven-surefire-plugin 55 | 2.22.1 56 | 57 | 58 | maven-jar-plugin 59 | 3.0.2 60 | 61 | 62 | maven-install-plugin 63 | 2.5.2 64 | 65 | 66 | maven-deploy-plugin 67 | 2.8.2 68 | 69 | 70 | 71 | maven-site-plugin 72 | 3.7.1 73 | 74 | 75 | maven-project-info-reports-plugin 76 | 3.0.0 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/API.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | import java.util.Scanner; 4 | 5 | public enum API { 6 | 7 | // docs 8 | // https://developer.marvel.com/docs#!/public/getCreatorCollection_get_0 9 | // https://api.nasa.gov/ 10 | // https://developers.themoviedb.org/4/getting-started/authorization 11 | 12 | TMDB("https://api.themoviedb.org/3/trending/all/week?api_key=" + new ApiKey().getTmdbKey()), 13 | NASA("https://api.nasa.gov/planetary/apod?api_key=" + new ApiKey().getNasaKey() 14 | + "&start_date=2022-06-01&end_date=2022-06-30"), 15 | MARVEL("https://gateway.marvel.com/v1/public/characters?ts=" + new ApiKey().getTimeStamp() + "&apikey=" 16 | + new ApiKey().getMarvelPublicKey() + "&hash=" + new ApiKey().md5() + "&limit=100"), 17 | MARVEL_NAME("https://gateway.marvel.com/v1/public/characters?ts=" + new ApiKey().getTimeStamp() + "&apikey=" 18 | + new ApiKey().getMarvelPublicKey() + "&hash=" + new ApiKey().md5() + "&nameStartsWith=" + inputName()); 19 | 20 | private String url; 21 | 22 | API(String url) { 23 | this.url = url; 24 | 25 | } 26 | 27 | public String url() { 28 | return url; 29 | } 30 | 31 | public static String inputName() { 32 | Scanner in = new Scanner(System.in); 33 | System.out.println("Type a Marvel character name: "); 34 | String characterName = in.next(); 35 | 36 | return characterName; 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/ApiKey.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | import java.math.BigInteger; 4 | import java.security.MessageDigest; 5 | import java.security.NoSuchAlgorithmException; 6 | import java.sql.Timestamp; 7 | 8 | public class ApiKey { 9 | 10 | private String tmdbKey = "18b28a0f741c6bb5155f7fd2438ab796"; 11 | private String nasaKey = "aMxMXff4fK23QXv5wGhF9lKJaIaZGy4fdggZVtSv"; 12 | private String marvelPublicKey = "b0c7fc8163cdaf499e949933dbebf10c"; 13 | private String marvelPrivateKey = "b8932830e275a76b61c4c6692c79d4db8351c5f7"; 14 | private long timeStamp = new Timestamp(System.currentTimeMillis()).getTime(); 15 | 16 | public String getTmdbKey() { 17 | return tmdbKey; 18 | } 19 | 20 | public String getNasaKey() { 21 | return nasaKey; 22 | } 23 | 24 | public String getMarvelPublicKey() { 25 | return marvelPublicKey; 26 | } 27 | 28 | public String getMarvelPrivateKey() { 29 | return marvelPrivateKey; 30 | } 31 | 32 | public long getTimeStamp() { 33 | return timeStamp; 34 | } 35 | 36 | public String md5() { 37 | String input = this.timeStamp + this.marvelPrivateKey + this.marvelPublicKey; 38 | return getMd5(input); 39 | } 40 | 41 | private static String getMd5(String input) { 42 | 43 | try { 44 | // Static getInstance method is called with hashing MD5 45 | MessageDigest md = MessageDigest.getInstance("MD5"); 46 | 47 | // digest() method is called to calculate message digest 48 | // of an input digest() return array of byte 49 | byte[] messageDigest = md.digest(input.getBytes()); 50 | 51 | // Convert byte array into signum representation 52 | BigInteger no = new BigInteger(1, messageDigest); 53 | 54 | // Convert message digest into hex value 55 | String hashtext = no.toString(16); 56 | while (hashtext.length() < 32) { 57 | hashtext = "0" + hashtext; 58 | } 59 | return hashtext; 60 | } 61 | 62 | // For specifying wrong message digest algorithms 63 | catch (NoSuchAlgorithmException e) { 64 | throw new RuntimeException(e); 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/App.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | public class App { 4 | // chcp 65001 ATIVAR EMOJI NO TERMINAL 5 | // https://jsonutils.com/ 6 | public static void main(String[] args) throws Exception { 7 | 8 | API myApi = API.NASA; 9 | 10 | ClienteHttp http = new ClienteHttp(); 11 | 12 | String json = http.searchData(myApi.url()); 13 | 14 | new NasaExtractor().extract(json); 15 | //new TheMovieDbExtractor().extract(json); 16 | //new MarvelExtractor().extract(json); 17 | 18 | 19 | 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/ClienteHttp.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | import java.io.IOException; 4 | import java.net.URI; 5 | import java.net.http.HttpClient; 6 | import java.net.http.HttpRequest; 7 | import java.net.http.HttpResponse; 8 | import java.net.http.HttpResponse.BodyHandlers; 9 | 10 | public class ClienteHttp { 11 | 12 | public String searchData(String url) { 13 | 14 | try { 15 | 16 | URI adress = URI.create(url); 17 | HttpClient client = HttpClient.newHttpClient(); 18 | HttpRequest request = HttpRequest.newBuilder(adress).GET().build(); 19 | HttpResponse response = client.send(request, BodyHandlers.ofString()); 20 | String body = response.body(); 21 | return body; 22 | 23 | } catch (IOException | InterruptedException ex) { 24 | 25 | throw new RuntimeException(ex); 26 | 27 | } 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/Extractor.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | import java.io.IOException; 4 | import java.net.MalformedURLException; 5 | 6 | public interface Extractor { 7 | 8 | public void extract(String json) throws IOException, MalformedURLException, Exception; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/Manipulator.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.util.Properties; 6 | public class Manipulator { 7 | 8 | public static Properties getProp() throws IOException { 9 | Properties props = new Properties(); 10 | FileInputStream file = new FileInputStream( 11 | "mykeys.properties"); 12 | props.load(file); 13 | return props; 14 | 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/MarvelContent.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | import java.util.List; 4 | 5 | public class MarvelContent { 6 | 7 | public Data data; 8 | 9 | public MarvelContent(Data data) { 10 | this.data = data; 11 | } 12 | 13 | public Data getData() { 14 | return data; 15 | } 16 | 17 | public void setData(Data data) { 18 | this.data = data; 19 | } 20 | 21 | public class Thumbnail { 22 | 23 | public String path; 24 | public String extension; 25 | 26 | public Thumbnail(String path, String extension) { 27 | this.path = path; 28 | this.extension = extension; 29 | } 30 | 31 | public String getPath() { 32 | return path; 33 | } 34 | 35 | public void setPath(String path) { 36 | this.path = path; 37 | } 38 | 39 | public String getExtension() { 40 | return extension; 41 | } 42 | 43 | public void setExtension(String extension) { 44 | this.extension = extension; 45 | } 46 | 47 | } 48 | 49 | public class Result { 50 | 51 | public String name; 52 | public Thumbnail thumbnail; 53 | 54 | public Result(String name, Thumbnail thumbnail) { 55 | this.name = name; 56 | this.thumbnail = thumbnail; 57 | } 58 | 59 | public String getName() { 60 | return name; 61 | } 62 | 63 | public void setName(String name) { 64 | this.name = name; 65 | } 66 | 67 | public Thumbnail getThumbnail() { 68 | return thumbnail; 69 | } 70 | 71 | public void setThumbnail(Thumbnail thumbnail) { 72 | this.thumbnail = thumbnail; 73 | } 74 | 75 | } 76 | 77 | public class Data { 78 | 79 | public List results; 80 | 81 | public Data(List results) { 82 | this.results = results; 83 | } 84 | 85 | public List getResults() { 86 | return results; 87 | } 88 | 89 | public void setResults(List results) { 90 | this.results = results; 91 | } 92 | 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/MarvelExtractor.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.net.MalformedURLException; 6 | import java.net.URL; 7 | import java.nio.file.Files; 8 | import java.nio.file.Path; 9 | import java.nio.file.Paths; 10 | import java.util.List; 11 | 12 | import com.google.gson.Gson; 13 | import com.imersaojava.MarvelContent.Result; 14 | 15 | public class MarvelExtractor implements Extractor { 16 | 17 | @Override 18 | public void extract(String json) throws IOException, MalformedURLException, Exception { 19 | MarvelContent atribute = new Gson().fromJson(json, MarvelContent.class); 20 | 21 | List personagens = atribute.getData().getResults(); 22 | StickersGenerator generator = new StickersGenerator(); 23 | 24 | for (Result result : personagens) { 25 | 26 | String formatName = "." + result.thumbnail.getExtension(); 27 | String fileName = result.getName().replaceAll("/", "-") + formatName; 28 | String image = result.getThumbnail().getPath() + formatName; 29 | 30 | System.out.println( 31 | "Titulo: " + TERMINALFORMAT.BRIGHT_GREEN.getS() + result.getName() + TERMINALFORMAT.RESET.getS()); 32 | System.out.println( 33 | "Imagem - Url: " + TERMINALFORMAT.BRIGHT_AZUL.getS() + image + TERMINALFORMAT.RESET.getS()); 34 | System.out.println(); 35 | 36 | InputStream inputStream = new URL(image).openStream(); 37 | Path stickers = Paths.get("stickers"); 38 | Files.createDirectories(stickers); 39 | generator.create(inputStream, fileName, formatName); 40 | 41 | } 42 | 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/NasaContent.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | public class NasaContent { 4 | 5 | public String hdurl; 6 | public String title; 7 | 8 | public NasaContent(String hdurl, String title) { 9 | this.hdurl = hdurl; 10 | this.title = title; 11 | } 12 | 13 | public String getHdurl() { 14 | return hdurl; 15 | } 16 | 17 | public void setHdurl(String hdurl) { 18 | this.hdurl = hdurl; 19 | } 20 | 21 | public String getTitle() { 22 | return title; 23 | } 24 | 25 | public void setTitle(String title) { 26 | this.title = title; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/NasaExtractor.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.net.MalformedURLException; 6 | import java.net.URL; 7 | import java.nio.file.Files; 8 | import java.nio.file.Path; 9 | import java.nio.file.Paths; 10 | 11 | import com.google.gson.Gson; 12 | 13 | public class NasaExtractor implements Extractor { 14 | 15 | @Override 16 | public void extract(String json) throws IOException, MalformedURLException, Exception { 17 | NasaContent[] atribute = new Gson().fromJson(json, NasaContent[].class); 18 | 19 | StickersGenerator generator = new StickersGenerator(); 20 | 21 | for (NasaContent result : atribute) { 22 | String formatName = ".png"; 23 | String fileName = result.getTitle().replaceAll(":", "-").replaceAll("/", "-") + formatName; 24 | String image; 25 | if (result.getHdurl() != null) { 26 | image = result.getHdurl(); 27 | } else { 28 | continue; 29 | } 30 | 31 | System.out.println( 32 | "Titulo: " + TERMINALFORMAT.BRIGHT_GREEN.getS() + result.getTitle() + TERMINALFORMAT.RESET.getS()); 33 | System.out.println( 34 | "Imagem - Url: " + TERMINALFORMAT.BRIGHT_AZUL.getS() + image + TERMINALFORMAT.RESET.getS()); 35 | System.out.println(); 36 | 37 | InputStream inputStream = new URL(image).openStream(); 38 | Path stickers = Paths.get("stickers"); 39 | Files.createDirectories(stickers); 40 | generator.create(inputStream, fileName, formatName); 41 | 42 | } 43 | 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/StickersGenerator.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | import java.awt.BasicStroke; 4 | import java.awt.Color; 5 | import java.awt.Font; 6 | import java.awt.FontMetrics; 7 | import java.awt.Graphics2D; 8 | import java.awt.Shape; 9 | import java.awt.font.TextLayout; 10 | import java.awt.image.BufferedImage; 11 | import java.io.File; 12 | import java.io.InputStream; 13 | 14 | import javax.imageio.ImageIO; 15 | 16 | public class StickersGenerator { 17 | 18 | public void create(InputStream inputStream, String fileName, String formatName) throws Exception { 19 | 20 | BufferedImage originalImage = ImageIO.read(inputStream); 21 | 22 | // cria nova imagem em memória com transparência e com tamanho novo 23 | int width = 400; 24 | int height = (originalImage.getHeight() * width) / originalImage.getWidth(); 25 | int newHeight = height + 50; 26 | BufferedImage newImage = new BufferedImage(width, newHeight, BufferedImage.TRANSLUCENT); 27 | 28 | // copiar a imagem original pra novo imagem (em memória) 29 | Graphics2D graphics = (Graphics2D) newImage.getGraphics(); 30 | graphics.drawImage(originalImage, 0, 0, width, height, null); 31 | 32 | // configurar a fonte e escrever uma frase na nova imagem 33 | String signature = fileName.replaceAll(formatName, ""); 34 | Font font = new Font("Comic Sans MS", Font.PLAIN, 20); 35 | 36 | TextLayout textLayout = new TextLayout(signature, font, graphics.getFontRenderContext()); 37 | Shape shape = textLayout.getOutline(null); 38 | 39 | graphics.setColor(Color.BLACK); 40 | graphics.setFont(font); 41 | 42 | FontMetrics phraseSize = graphics.getFontMetrics(font); 43 | 44 | float x = ((float) (newImage.getWidth() / 2) - ((float) phraseSize.stringWidth(signature)) / 2); 45 | int y = newImage.getHeight() - 10; 46 | 47 | graphics.translate(x, y); 48 | graphics.setStroke(new BasicStroke(4)); 49 | graphics.setColor(Color.BLACK); 50 | graphics.draw(shape); 51 | graphics.setColor(Color.GREEN); 52 | graphics.fill(shape); 53 | 54 | // escrever a nova imagem em um arquivo 55 | 56 | ImageIO.write(newImage, "png", new File("stickers/" + fileName)); 57 | 58 | } 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/TERMINALFORMAT.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | public enum TERMINALFORMAT { 4 | RESET("\u001B[0m"), 5 | // cor do texto 6 | BRIGHT_GREEN("\u001b[92m"), 7 | BRIGHT_AZUL("\u001b[96m"), 8 | BRIGHT_YELLOW("\u001b[93m"), 9 | // emoji estrela 10 | STAR("\u2b50"); 11 | 12 | private String s; 13 | 14 | private TERMINALFORMAT(String s) { 15 | this.s = s; 16 | } 17 | 18 | public String getS() { 19 | return s; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/TheMovieDbContent.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | import java.util.List; 4 | 5 | public class TheMovieDbContent { 6 | 7 | public List results; 8 | 9 | public TheMovieDbContent(List results) { 10 | this.results = results; 11 | } 12 | 13 | public List getResults() { 14 | return results; 15 | } 16 | 17 | public void setResults(List results) { 18 | this.results = results; 19 | } 20 | 21 | public class Result { 22 | 23 | public String original_title; 24 | public String poster_path; 25 | public double vote_average; 26 | public int vote_count; 27 | 28 | public Result(String original_title, String poster_path, double vote_average, int vote_count) { 29 | this.original_title = original_title; 30 | this.poster_path = poster_path; 31 | this.vote_average = vote_average; 32 | this.vote_count = vote_count; 33 | } 34 | 35 | public String getOriginal_title() { 36 | return original_title; 37 | } 38 | 39 | public void setOriginal_title(String original_title) { 40 | this.original_title = original_title; 41 | } 42 | 43 | public String getPoster_path() { 44 | return poster_path; 45 | } 46 | 47 | public void setPoster_path(String poster_path) { 48 | this.poster_path = poster_path; 49 | } 50 | 51 | public double getVote_average() { 52 | return vote_average; 53 | } 54 | 55 | public void setVote_average(double vote_average) { 56 | this.vote_average = vote_average; 57 | } 58 | 59 | public int getVote_count() { 60 | return vote_count; 61 | } 62 | 63 | public void setVote_count(int vote_count) { 64 | this.vote_count = vote_count; 65 | } 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/imersaojava/TheMovieDbExtractor.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.net.MalformedURLException; 6 | import java.net.URL; 7 | import java.nio.file.Files; 8 | import java.nio.file.Path; 9 | import java.nio.file.Paths; 10 | import java.util.List; 11 | 12 | import com.google.gson.Gson; 13 | import com.imersaojava.TheMovieDbContent.Result; 14 | 15 | public class TheMovieDbExtractor implements Extractor { 16 | 17 | @Override 18 | public void extract(String json) throws IOException, MalformedURLException, Exception { 19 | TheMovieDbContent atribute = new Gson().fromJson(json, TheMovieDbContent.class); 20 | 21 | List films = atribute.getResults(); 22 | StickersGenerator generator = new StickersGenerator(); 23 | 24 | for (Result result : films) { 25 | 26 | String formatName = ".png"; 27 | String fileName; 28 | if (result.getOriginal_title() == null) { 29 | fileName = result.getOriginal_title() + formatName; 30 | } else { 31 | fileName = result.getOriginal_title().replaceAll(":", "-") + formatName; 32 | } 33 | 34 | String image = "https://image.tmdb.org/t/p/w500" + result.getPoster_path(); 35 | String rating = Double.toString(result.getVote_average()); 36 | 37 | System.out.println( 38 | "Titulo: " + TERMINALFORMAT.BRIGHT_GREEN.getS() + result.getOriginal_title() 39 | + TERMINALFORMAT.RESET.getS()); 40 | System.out.println( 41 | "Imagem - Url: " + TERMINALFORMAT.BRIGHT_AZUL.getS() + image + TERMINALFORMAT.RESET.getS()); 42 | System.out.println( 43 | "Nota: " + TERMINALFORMAT.BRIGHT_YELLOW.getS() + rating + ratingStars(rating) 44 | + TERMINALFORMAT.RESET.getS()); 45 | System.out.println(); 46 | 47 | InputStream inputStream = new URL(image).openStream(); 48 | Path stickers = Paths.get("stickers"); 49 | Files.createDirectories(stickers); 50 | generator.create(inputStream, fileName, formatName); 51 | 52 | } 53 | 54 | } 55 | 56 | public static String ratingStars(String rating) { 57 | 58 | String stars = ""; 59 | for (int i = 0; i < Math.floor(Double.parseDouble(rating)); i++) { 60 | 61 | stars += " " + TERMINALFORMAT.STAR; 62 | 63 | } 64 | 65 | return stars; 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/com/imersaojava/AppTest.java: -------------------------------------------------------------------------------- 1 | package com.imersaojava; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | { 12 | /** 13 | * Rigorous Test :-) 14 | */ 15 | @Test 16 | public void shouldAnswerWithTrue() 17 | { 18 | assertTrue( true ); 19 | } 20 | } 21 | --------------------------------------------------------------------------------