Skip to content

Commit 7934f1a

Browse files
authored
Merge pull request #2 from MartinFiorde/main-fork
Main fork
2 parents 1b9b893 + e0b2606 commit 7934f1a

64 files changed

Lines changed: 4259 additions & 12 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
1+
# Fuente del commit inicial
2+
https://github.com/sierisimo/JavaSE-Functional-platzi
3+
4+
# Link del curso platzi
5+
https://platzi.com/new-home/clases/1826-java-funcional/26226-inmutabilidad/
6+
17
# JavaSE-Functional-platzi
28
Codigo de ejemplos para el curso sobre programacion funcional de Platzi

jobs-search-reporter/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
Jobs Search Reporter
2+
3+
Un pequeño CLI para buscar trabajo con Github
4+
5+
---
6+
7+
## Descripcion
8+
9+
Nuestro pequeño CLI utilizara [la API de Github](https://jobs.github.com/) para buscar empleos.
10+
Para que nuestro CLI pueda funcionar debemos pasar algunas opciones/parametros de busqueda.
11+
12+
La manera de invocar a nuestro CLI sera:
13+
14+
```
15+
jobs-search [OPTIONS] <SKILL>
16+
```
17+
18+
Donde `[OPTIONS]` son:
19+
20+
```
21+
--location <UBICACION> # <UBICACION>: Algun lugar del mundo, tambien disponible como: -l
22+
--page <PAGINA> # <PAGINA>: Los resultados se muestran de 50 en 50, cada 50 resultados se le conoce como pagina empezando en 0. Default: 0. Tambien disponible como: -p
23+
--full-time # Si queremos que sean solo empleos de tiempo completo. default: false
24+
--markdown # Mostrar los resultados en Markdown
25+
```
26+
27+
Y `<SKILL>` es el tipo de skill del que queremos encontrar trabajos.
28+
29+
### Ejemplo
30+
31+
Para buscar trabajos de `Java` en Tokyo, usariamos:
32+
33+
`jobs-search --location tokyo java`

jobs-search-reporter/build.gradle

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//Plugins que utiliza gradle para definir el tipo de tareas comunes
2+
plugins {
3+
id 'java'
4+
id 'application'
5+
}
6+
7+
//Paquete de nuestro programa, usado principalmente en librerias.
8+
group 'com.platzi'
9+
version '0.0.1'
10+
11+
//Version de java que es compatible con el codigo
12+
sourceCompatibility = 1.8
13+
14+
//Nuestra clase principal.
15+
application {
16+
mainClassName = "com.platzi.jobsearch.JobSearch"
17+
applicationName = "job-search"
18+
}
19+
20+
repositories {
21+
mavenCentral()
22+
}
23+
24+
dependencies {
25+
implementation group: 'com.beust', name: 'jcommander', version: '1.78'
26+
27+
implementation group: 'io.github.openfeign', name: 'feign-core', version: '10.6.0'
28+
implementation group: 'io.github.openfeign', name: 'feign-gson', version: '10.6.0'
29+
30+
31+
testCompile group: 'junit', name: 'junit', version: '4.12'
32+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.platzi.jobsearch;
2+
3+
import com.beust.jcommander.JCommander;
4+
import com.beust.jcommander.ParameterException;
5+
6+
import java.util.List;
7+
import java.util.Optional;
8+
import java.util.function.Supplier;
9+
10+
public interface CommanderFunctions {
11+
/**
12+
* JCommander permite generar opciones de terminal de cualquier clase, por eso el primer parametro es
13+
* de tipo Object.
14+
*
15+
* @param object Clase de la cual se generaran los argumentos de JCommander
16+
* @return una instancia de JCommander. Idealmente con CLIArguments como objeto pasado.
17+
*/
18+
static JCommander buildCommander(Object object) {
19+
return JCommander
20+
.newBuilder()
21+
.addObject(object)
22+
.build();
23+
}
24+
25+
/**
26+
* Con esta funcion, facilitamos crear una configuracion inicial de JCommander, pidiendo el nombre del
27+
* programa y un Supplier de tipo T para los argumentos. Asi podemos usar alguna funcion que nos devuelva
28+
* un objeto que funcione como argumentos de JCommander.
29+
*
30+
* @param name nombre que se mostrara en el CLI
31+
* @param argumentsSupplier una funcion que devuelva un objeto de argumentos de JCommander
32+
* @param <T> Tipo que se usara para los argumentos
33+
* @return una instancia de {@link JCommander} ya configurada con el nombre y los argumentos.
34+
*/
35+
static <T> JCommander buildCommanderWithName(String name, Supplier<T> argumentsSupplier) {
36+
JCommander jCommander = buildCommander(argumentsSupplier.get());
37+
jCommander.setProgramName(name);
38+
return jCommander;
39+
}
40+
41+
/**
42+
* Funcion utilizada para tomar los datos de JCommander, los argumentos esperados y en caso de que algo falle,
43+
* una funcion con el JCommander que genero el error.
44+
*/
45+
static Optional<List<Object>> parseArguments(
46+
JCommander jCommander,
47+
String[] arguments,
48+
OnCommandError onCommandError
49+
) {
50+
List<Object> result;
51+
try {
52+
jCommander.parse(arguments);
53+
54+
return Optional.of(jCommander.getObjects());
55+
} catch (ParameterException exception) {
56+
onCommandError.onError(jCommander);
57+
}
58+
59+
return Optional.empty();
60+
}
61+
62+
@FunctionalInterface
63+
interface OnCommandError {
64+
void onError(JCommander jCommander);
65+
}
66+
}
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
package com.platzi.jobsearch;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
5+
import java.util.Objects;
6+
7+
/**
8+
* Clase que representa los resultados de una busqueda
9+
*/
10+
public final class JobPosition {
11+
private String id;
12+
13+
private String type;
14+
15+
private String ulr;
16+
17+
@SerializedName("created_at")
18+
private String createdAt;
19+
20+
private String company;
21+
22+
@SerializedName("company_url")
23+
private String companyUrl;
24+
25+
private String location;
26+
27+
private String title;
28+
29+
private String description;
30+
31+
@SerializedName("how_to_apply")
32+
private String howToApply;
33+
34+
@SerializedName("company_logo")
35+
private String companyLogo;
36+
37+
public String getId() {
38+
return id;
39+
}
40+
41+
public void setId(String id) {
42+
this.id = id;
43+
}
44+
45+
public String getType() {
46+
return type;
47+
}
48+
49+
public void setType(String type) {
50+
this.type = type;
51+
}
52+
53+
public String getUlr() {
54+
return ulr;
55+
}
56+
57+
public void setUlr(String ulr) {
58+
this.ulr = ulr;
59+
}
60+
61+
public String getCreatedAt() {
62+
return createdAt;
63+
}
64+
65+
public void setCreatedAt(String createdAt) {
66+
this.createdAt = createdAt;
67+
}
68+
69+
public String getCompany() {
70+
return company;
71+
}
72+
73+
public void setCompany(String company) {
74+
this.company = company;
75+
}
76+
77+
public String getCompanyUrl() {
78+
return companyUrl;
79+
}
80+
81+
public void setCompanyUrl(String companyUrl) {
82+
this.companyUrl = companyUrl;
83+
}
84+
85+
public String getLocation() {
86+
return location;
87+
}
88+
89+
public void setLocation(String location) {
90+
this.location = location;
91+
}
92+
93+
public String getTitle() {
94+
return title;
95+
}
96+
97+
public void setTitle(String title) {
98+
this.title = title;
99+
}
100+
101+
public String getDescription() {
102+
return description;
103+
}
104+
105+
public void setDescription(String description) {
106+
this.description = description;
107+
}
108+
109+
public String getHowToApply() {
110+
return howToApply;
111+
}
112+
113+
public void setHowToApply(String howToApply) {
114+
this.howToApply = howToApply;
115+
}
116+
117+
public String getCompanyLogo() {
118+
return companyLogo;
119+
}
120+
121+
public void setCompanyLogo(String companyLogo) {
122+
this.companyLogo = companyLogo;
123+
}
124+
125+
@Override
126+
public boolean equals(Object o) {
127+
if (this == o) return true;
128+
if (o == null || getClass() != o.getClass()) return false;
129+
JobPosition that = (JobPosition) o;
130+
return getId().equals(that.getId()) &&
131+
getType().equals(that.getType()) &&
132+
getUlr().equals(that.getUlr()) &&
133+
getCreatedAt().equals(that.getCreatedAt()) &&
134+
getCompany().equals(that.getCompany()) &&
135+
Objects.equals(getCompanyUrl(), that.getCompanyUrl()) &&
136+
Objects.equals(getLocation(), that.getLocation()) &&
137+
getTitle().equals(that.getTitle()) &&
138+
Objects.equals(getDescription(), that.getDescription()) &&
139+
Objects.equals(getHowToApply(), that.getHowToApply()) &&
140+
Objects.equals(getCompanyLogo(), that.getCompanyLogo());
141+
}
142+
143+
@Override
144+
public int hashCode() {
145+
return Objects.hash(getId(), getType(), getUlr(), getCreatedAt(), getCompany(), getCompanyUrl(), getLocation(), getTitle(), getDescription(), getHowToApply(), getCompanyLogo());
146+
}
147+
148+
@Override
149+
public String toString() {
150+
return "JobPosition{" +
151+
"id='" + id + '\'' +
152+
", type='" + type + '\'' +
153+
", ulr='" + ulr + '\'' +
154+
", createdAt='" + createdAt + '\'' +
155+
", company='" + company + '\'' +
156+
", companyUrl='" + companyUrl + '\'' +
157+
", location='" + location + '\'' +
158+
", title='" + title + '\'' +
159+
", description='" + description + '\'' +
160+
", howToApply='" + howToApply + '\'' +
161+
", companyLogo='" + companyLogo + '\'' +
162+
'}';
163+
}
164+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.platzi.jobsearch;
2+
3+
import com.beust.jcommander.JCommander;
4+
import com.platzi.jobsearch.api.JobsAPI;
5+
import com.platzi.jobsearch.cli.CLIArguments;
6+
import com.platzi.jobsearch.cli.CLIFunctions;
7+
8+
import java.util.Collection;
9+
import java.util.Collections;
10+
import java.util.Map;
11+
import java.util.Optional;
12+
import java.util.stream.Stream;
13+
14+
import static com.platzi.jobsearch.CommanderFunctions.buildCommanderWithName;
15+
import static com.platzi.jobsearch.CommanderFunctions.parseArguments;
16+
import static com.platzi.jobsearch.api.APIFunctions.buildAPI;
17+
18+
public class JobSearch {
19+
public static void main(String[] args) {
20+
//Creacion de nuestro CLI con JCommander
21+
JCommander jCommander = buildCommanderWithName("job-search", CLIArguments::newInstance);
22+
23+
//Obtenemos las opciones que se le dieron a JCommander
24+
Stream<CLIArguments> streamOfCLI =
25+
//Nos retorna un Optional<List<Object>>
26+
parseArguments(jCommander, args, JCommander::usage)
27+
//En caso de un Optional.empty()
28+
.orElse(Collections.emptyList())
29+
.stream()
30+
.map(obj -> (CLIArguments) obj);
31+
32+
//Tomamos nuestro Stream y obtenemos las opciones que se dieron en el CLI
33+
Optional<CLIArguments> cliOptional = streamOfCLI
34+
//Solo nos interesan los casos donde no sea la solicitud de ayuda
35+
.filter(cli -> !cli.isHelp())
36+
//Y que contengan un keyword, en otros caso no tenemos que buscar
37+
.filter(cli -> cli.getKeyword() != null)
38+
.findFirst();
39+
40+
//Si el Optional tiene un dato, lo convertimos a Map<String,Object>
41+
cliOptional.map(CLIFunctions::toMap)
42+
//Convertimos el Map en un request
43+
.map(JobSearch::executeRequest)
44+
//Aun seguimos operando sobre un Optional… en caso de que no hubiera datos
45+
//Generamos un stream vacio
46+
.orElse(Stream.empty())
47+
//Imprimos los datos por pantalla.
48+
.forEach(System.out::println);
49+
}
50+
51+
private static Stream<JobPosition> executeRequest(Map<String, Object> options) {
52+
JobsAPI api = buildAPI(JobsAPI.class, "https://jobs.github.com");
53+
54+
return Stream.of(options)
55+
.map(api::jobs)
56+
.flatMap(Collection::stream);
57+
}
58+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.platzi.jobsearch.api;
2+
3+
import feign.Feign;
4+
import feign.gson.GsonDecoder;
5+
6+
public interface APIFunctions {
7+
/**
8+
* Para construir la llamada fon Feign, necesitamos generar un cliente de Feign,
9+
* esconder que internamente este es el cliente que se usa, nos facilita hacer facil
10+
* el reemplazo de la libreria para http en el futuro.
11+
*
12+
* @param api una Class de tipo T para construir nuestra api
13+
* @param url la URL base donde estaremos haciendo los requests
14+
* @param <T> el tipo de API que contruiremos
15+
* @return una instancia de T para usar como cliente de API
16+
*/
17+
static <T> T buildAPI(Class<T> api, String url) {
18+
return Feign.builder()
19+
.decoder(new GsonDecoder())
20+
.target(api, url);
21+
}
22+
}

0 commit comments

Comments
 (0)