Admin: Agregado soporte para EDs. Arreglado el comportamiento de OP y Links

This commit is contained in:
Fernando 2018-12-20 16:30:16 -05:00
parent 9afea99ded
commit 51c4651409
12 changed files with 408 additions and 71 deletions

3
app.ts
View File

@ -21,6 +21,9 @@ app.get('/a/', require('./srv/Admin/obtenerTodosAnimes').obtenerTodosAnimes);
app.get('/op/:id', require('./srv/Admin/OP/obtenerOPs').obtenerOPs); app.get('/op/:id', require('./srv/Admin/OP/obtenerOPs').obtenerOPs);
app.post('/op/', require('./srv/Admin/OP/nuevoOP').nuevoOP); app.post('/op/', require('./srv/Admin/OP/nuevoOP').nuevoOP);
app.get('/ed/:anime_ID', require('./srv/Admin/ED/obtenerEDs').obtenerEDs);
app.post('/ed/', require('./srv/Admin/ED/nuevoED').nuevoED);
app.get('/eps/variantes/:anime_ID', require('./srv/Admin/Eps/obtenerVariantes').obtenerVariantes); app.get('/eps/variantes/:anime_ID', require('./srv/Admin/Eps/obtenerVariantes').obtenerVariantes);
app.get('/eps/links/:opcion_ID', require('./srv/Admin/Eps/obtenerLinks').obtenerLinks); app.get('/eps/links/:opcion_ID', require('./srv/Admin/Eps/obtenerLinks').obtenerLinks);
app.post('/eps/links/', require('./srv/Admin/Eps/crearLink').crearLink); app.post('/eps/links/', require('./srv/Admin/Eps/crearLink').crearLink);

View File

@ -5,6 +5,11 @@
"link": "/Anime/2018/Otono/IrozuKai", "link": "/Anime/2018/Otono/IrozuKai",
"imgUrl": "https://myanimelist.cdn-dena.com/images/anime/1424/93855.jpg", "imgUrl": "https://myanimelist.cdn-dena.com/images/anime/1424/93855.jpg",
"descripcion": "Ambientada en la ciudad de Nagasaki, la historia tiene lugar en un mundo en el que una cantidad minúscula de magia permanece en la vida cotidiana. Hitomi Tsukishiro es una descendiente de 17 años de una familia de brujas que creció con emociones vivas, ya que perdió su sentido del color a una edad muy temprana. Sintiéndose mal por el futuro de su nieta, Kohaku, una gran bruja, envía a Hitomi al pasado, el año 2018. Mediante intercambios con su abuela de 17 años y los miembros de su club, la historia sigue el crecimiento de Hitomi como persona.", "descripcion": "Ambientada en la ciudad de Nagasaki, la historia tiene lugar en un mundo en el que una cantidad minúscula de magia permanece en la vida cotidiana. Hitomi Tsukishiro es una descendiente de 17 años de una familia de brujas que creció con emociones vivas, ya que perdió su sentido del color a una edad muy temprana. Sintiéndose mal por el futuro de su nieta, Kohaku, una gran bruja, envía a Hitomi al pasado, el año 2018. Mediante intercambios con su abuela de 17 años y los miembros de su club, la historia sigue el crecimiento de Hitomi como persona.",
"color": "#2f7090",
"onPagPrin": [true,1],
"key": 10001111,
"estudio": "P.A. Works", "estudio": "P.A. Works",
"eps": "13", "eps": "13",
"alAire": "06 de Octubre a ?", "alAire": "06 de Octubre a ?",
@ -12,15 +17,12 @@
"anio": 2018, "anio": 2018,
"fuente": "Original", "fuente": "Original",
"generos": "Drama, Magia, Romance", "generos": "Drama, Magia, Romance",
"color": "#2f7090",
"OP": { "OP": {
"1": "17sai - Haruka to Miyuki" "1": "17sai - Haruka to Miyuki"
}, },
"ED": { "ED": {
"1": "Mimei no Kimi to Hakumei no Mahou - Yanagi Nagi" "1": "Mimei no Kimi to Hakumei no Mahou - Yanagi Nagi"
}, }
"onPagPrin": [true,1],
"key": 10001111
}, },
{ {
"animeID": 28, "animeID": 28,

View File

@ -14,7 +14,8 @@
<td>{{ anime["titulo"] }}</td> <td>{{ anime["titulo"] }}</td>
<td> <td>
<button class="btn" @click="revisarOP('anime' + anime['anime_ID'], anime['anime_ID'])">OP</button> | <button class="btn" @click="revisarOP('anime' + anime['anime_ID'], anime['anime_ID'])">OP</button> |
<button class="btn">ED</button> | <button class="btn" @click="verLinks('anime' + anime['anime_ID'], anime['anime_ID'])">Link</button> <button class="btn" @click="revisarED('anime' + anime['anime_ID'], anime['anime_ID'])">ED</button> |
<button class="btn" @click="verLinks('anime' + anime['anime_ID'], anime['anime_ID'])">Link</button>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -49,46 +50,32 @@
const form = document.createElement("form"); const form = document.createElement("form");
form.style.display = "inline-block";
form.style.maxWidth = "450px";
form.onsubmit = () => false; form.onsubmit = () => false;
const input = document.createElement("input"); const input = document.createElement("input");
input.placeholder = "Numero del OP"; input.placeholder = "Numero del OP";
input.className = "OP-ED__num-ed colorTexto";
input.type = "number"; input.type = "number";
input.style.display = "inline-block";
input.style.maxWidth = "400px";
input.min = "1"; input.min = "1";
input.max = "50"; input.max = "50";
input.name = "numOP";
input.required = true;
form.appendChild(input); form.appendChild(input);
const input2 = document.createElement("input"); const input2 = document.createElement("input");
input2.placeholder = "Nombre del OP"; input2.placeholder = "Nombre del OP";
input2.className = "OP-ED__nombre colorTexto";
input2.type = "text"; input2.type = "text";
input2.name = "nombreOP";
input2.style.display = "inline-block";
input2.style.maxWidth = "400px";
input2.required = true;
form.appendChild(input2); form.appendChild(input2);
const input3 = document.createElement("input"); const input3 = document.createElement("input");
input3.placeholder = "Artista del OP"; input3.placeholder = "Artista del OP";
input3.className = "OP-ED__artista colorTexto";
input3.type = "text"; input3.type = "text";
input3.name = "artistaOP";
input3.style.display = "inline-block";
input3.style.maxWidth = "400px";
input3.required = true;
form.appendChild(input3); form.appendChild(input3);
const input4 = document.createElement("input"); const input4 = document.createElement("input");
input4.placeholder = "Episodios del OP (1 al 13)"; input4.placeholder = "Episodios del OP (1 al 13)";
input4.className = "OP-ED__eps colorTexto";
input4.type = "text"; input4.type = "text";
input4.name = "epsOP";
input4.style.display = "inline-block";
input4.style.maxWidth = "400px";
input4.required = true;
form.appendChild(input4); form.appendChild(input4);
const botonEnviar = document.createElement("button"); const botonEnviar = document.createElement("button");
@ -115,8 +102,6 @@
}; };
xhr.send(`data=${YAML.stringify(data)}`); xhr.send(`data=${YAML.stringify(data)}`);
console.log("YAML:\n" + YAML.stringify(data));
}); });
botonEnviar.innerText = "Crear."; botonEnviar.innerText = "Crear.";
@ -151,8 +136,121 @@
elemNuevo.appendChild(div); elemNuevo.appendChild(div);
} }
};
xhr.send();
console.log("El servidor respondió:\n" + xhr.responseText); marcof.appendChild(elemNuevo);
elemActual.parentNode.insertBefore(marco, elemActual.nextSibling);
},
revisarED (elemId, animeID) {
const elemActual = document.getElementById(elemId);
const marco = document.createElement("tr");
marco.appendChild(document.createElement("td"));
const marcof = document.createElement("td");
marco.appendChild(marcof);
marco.appendChild(document.createElement("td"));
const elemNuevo = document.createElement("div");
const formCrear = document.createElement("div");
formCrear.appendChild(document.createTextNode("Crear un ED:"));
formCrear.appendChild(document.createElement("br"));
formCrear.appendChild(document.createElement("br"));
const form = document.createElement("form");
form.onsubmit = () => false;
const input = document.createElement("input");
input.placeholder = "Num";
input.className = "OP-ED__num-ed colorTexto";
input.type = "number";
input.min = "1";
input.max = "50";
form.appendChild(input);
const input2 = document.createElement("input");
input2.placeholder = "Nombre del ED";
input2.className = "OP-ED__nombre colorTexto";
input2.type = "text";
form.appendChild(input2);
const input3 = document.createElement("input");
input3.placeholder = "Artista del ED";
input3.className = "OP-ED__artista colorTexto";
input3.type = "text";
form.appendChild(input3);
const input4 = document.createElement("input");
input4.placeholder = "Episodios del ED (1 al 13)";
input4.className = "OP-ED__eps colorTexto";
input4.type = "text";
form.appendChild(input4);
form.appendChild(document.createElement("br"));
const botonEnviar = document.createElement("button");
botonEnviar.className = "btn";
botonEnviar.addEventListener("click", () => {
botonEnviar.className = "btn disabled";
const data = {
anime_ID: animeID,
num_ED: input.value,
nombre: input2.value,
artista: input3.value,
eps: input4.value
};
const xhr = new XMLHttpRequest();
xhr.open("POST", "/ed/");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onload = () => {
botonEnviar.className = "btn";
console.log("Resultado:\n" + xhr.responseText);
};
xhr.send(`data=${YAML.stringify(data)}`);
});
botonEnviar.innerText = "Crear.";
form.appendChild(botonEnviar);
formCrear.appendChild(form);
elemNuevo.appendChild(formCrear);
const botonCerrar = document.createElement("button");
botonCerrar.className = "btn red";
botonCerrar.addEventListener("click", () => {
elemActual.parentNode.removeChild(marco);
});
botonCerrar.innerText = "Cerrar.";
elemNuevo.appendChild(document.createElement("br"));
elemNuevo.appendChild(botonCerrar);
elemNuevo.style.padding = "30px";
const xhr = new XMLHttpRequest();
xhr.open("GET", `/ed/${animeID}`);
xhr.onload = () => {
const data = YAML.parse(xhr.responseText);
if (Array.isArray(data)) {
for (const elemento of data) {
const div = document.createElement("div");
div.innerHTML = `<br>ED ${elemento['num_ED']}: ${elemento['nombre']} - ${elemento['artista']}<br>\
Eps: ${elemento['eps']}`;
elemNuevo.appendChild(div);
}
} else {
M.toast({html: 'Error :c'});
}
}; };
xhr.send(); xhr.send();
@ -162,10 +260,8 @@
verLinks (elemId, animeID) { verLinks (elemId, animeID) {
console.log("Viendo los links."); console.log("Viendo los links.");
/* TODO: Usar los datos para crear: /* TODO: Usar los datos para crear:
* Form para crear Variantes (usando un xhr) * Form para crear Variantes (usando un xhr)
* Form para crear links que se adecue a cada variante (usando un xhr diferente) * */
* con 2 peticiones xhr
* */
const crear = data => { const crear = data => {
const elemActual = document.getElementById(elemId); const elemActual = document.getElementById(elemId);
@ -229,23 +325,23 @@
agregarEpForm.onsubmit = () => false; agregarEpForm.onsubmit = () => false;
const numEp = document.createElement("input"); const numEp = document.createElement("input");
numEp.className = "agregar-ep-form__num-ep"; numEp.className = "colorTexto agregar-ep-form__num-ep";
numEp.placeholder = "Ep num"; numEp.placeholder = "Ep num";
agregarEpForm.appendChild(numEp); agregarEpForm.appendChild(numEp);
const visitas = document.createElement("input"); const visitas = document.createElement("input");
visitas.className = "agregar-ep-form__visitas"; visitas.className = "colorTexto agregar-ep-form__visitas";
visitas.placeholder = "Visitas"; visitas.placeholder = "Visitas";
visitas.value = '0'; visitas.value = '0';
agregarEpForm.appendChild(visitas); agregarEpForm.appendChild(visitas);
const peso = document.createElement("input"); const peso = document.createElement("input");
peso.className = "agregar-ep-form__peso"; peso.className = "colorTexto agregar-ep-form__peso";
peso.placeholder = "Peso"; peso.placeholder = "Peso";
agregarEpForm.appendChild(peso); agregarEpForm.appendChild(peso);
const link = document.createElement("input"); const link = document.createElement("input");
link.className = "agregar-ep-form__link"; link.className = "colorTexto agregar-ep-form__link";
link.placeholder = "link"; link.placeholder = "link";
agregarEpForm.appendChild(link); agregarEpForm.appendChild(link);
@ -336,6 +432,26 @@
</script> </script>
<style lang="sass"> <style lang="sass">
%form-op-ed
display: inline-block
margin: 0 10px !important
.OP-ED__num-ed
@extend %form-op-ed
width: 50px !important
.OP-ED__nombre
@extend %form-op-ed
width: 200px !important
.OP-ED__artista
@extend %form-op-ed
width: 200px !important
.OP-ED__eps
@extend %form-op-ed
width: 100px !important
%tags %tags
display: inline-block display: inline-block
cursor: default cursor: default

40
srv/Admin/ED/nuevoED.ts Normal file
View File

@ -0,0 +1,40 @@
interface Data {
anime_ID: number,
num_ED: number,
nombre: string,
artista: string,
eps: string
}
const nuevoED = (req: any, res: any) => {
const YAML = require('yaml');
const data: Data = YAML.parse(req.body.data);
const con = require('../../mysql').obtenerConexionMySql();
con.connect((err: Error) => {
if (!err && data) {
const query = `INSERT INTO ED (anime_ID, num_ED, nombre, artista, eps) VALUES ( ${data.anime_ID}, ${data.num_ED},
${con.escape(data.nombre)}, ${con.escape(data.artista)}, ${con.escape(data.eps)} )`;
con.query(query, (err: Error) => {
if (!err) {
res.send("exito: true");
} else {
res.send("error: true");
console.log("Error al ejecutar query en /Admin/ED/nuevoED (con.query):\n" + query + "\n" + err);
}
});
} else if (!err) {
res.send("error: true");
console.log("Error. La data no existe en /Admin/ED/nuevoED (con.connect)");
} else {
res.send("error: true");
console.log("Error al conectarse a la base de datos en /Admin/ED/nuevoED (con.connect):\n" + err);
}
});
};
module.exports.nuevoED = nuevoED;

View File

@ -0,0 +1,39 @@
interface RespuestaED {
ED_ID: number,
anime_ID: number,
num_ED: number,
nombre: string,
artista: string,
eps: string
}
const obtenerEDs = (req: any, res: any) => {
const YAML = require('yaml');
const anime_ID: number = req.params.anime_ID;
const con = require('../../mysql').obtenerConexionMySql();
con.connect((err: Error) => {
if (!err) {
const query = `SELECT * FROM ED WHERE anime_ID=${anime_ID}`;
con.query(query, (err: Error, response: RespuestaED[]) => {
if (!err) {
res.send(YAML.stringify(response));
} else {
res.send("error: true");
console.log("Error al ejecutar query en /Admin/ED/nuevoED (con.query):\n" + query + "\n" + err);
}
});
} else {
res.send("error: true");
console.log("Error al conectarse a la base de datos en /Admin/ED/obtenerEDs (con.connect):\n" + err);
}
});
};
module.exports.obtenerEDs = obtenerEDs;

View File

@ -10,7 +10,8 @@ const nuevoOP = (req: any, res: any) => {
con.query( con.query(
`INSERT INTO OP (anime_ID, num_OP, nombre, artista, eps) VALUES \ `INSERT INTO OP (anime_ID, num_OP, nombre, artista, eps) VALUES \
(${con.escape(data['anime_ID'])}, ${con.escape(data['num_OP'])}, ${con.escape(data['nombre'])}, ${con.escape(data['artista'])}, ${con.escape(data['eps'])})`, ( ${con.escape(data['anime_ID'])}, ${con.escape(data['num_OP'])}, ${con.escape(data['nombre'])},
${con.escape(data['artista'])}, ${con.escape(data['eps'])} )`,
(err: any) => { (err: any) => {
if (!err) { if (!err) {

View File

@ -3,26 +3,26 @@ const obtenerOPs = (req: any, res: any) => {
const con = require('../../mysql').obtenerConexionMySql(); const con = require('../../mysql').obtenerConexionMySql();
const YAML = require('yaml'); const YAML = require('yaml');
const animeID: string = req.params.id; const animeID: number = req.params.id;
con.connect((err: any) => { con.connect((err: any) => {
if (!err && animeID) { if (!err && animeID) {
con.query( const query = `SELECT * FROM OP WHERE anime_ID=${animeID}`;
`SELECT * FROM OP WHERE anime_ID=${con.escape(animeID)}`, con.query( query, (err: any, resultado: object) => {
(err: any, resultado: object) => { if (!err) {
if (!err) {
res.send(YAML.stringify(resultado)); res.send(YAML.stringify(resultado));
} else { } else {
console.log("Error al ejecutar query en /Admin/OP/obtenerOPs (con.query):\n" + query + "\n" + err);
} res.send("error: true");
} }
); });
} else { } else {
console.log("Error al conectarse a la base de datos en /Admin/OP/obtenerOPs (con.connect):\n" + err);
res.send("error: true");
} }
}); });

130
srv/Animes/obtenerDatos.ts Normal file
View File

@ -0,0 +1,130 @@
interface RespuestaDatos {
estudio: string,
eps: number,
alAire: string,
temporada: string,
anio: number,
fuente: string,
generos: string
}
interface RespuestaOP {
OP_ID: number,
anime_ID: number,
num_OP: number,
nombre: string,
artista: string,
eps: string
}
interface RespuestaED {
ED_ID: number,
anime_ID: number,
num_ED: number,
nombre: string,
artista: string,
eps: string
}
interface Respuesta extends RespuestaDatos {
}
const GestorDeTareas = require("../GestorDeTareas/GestorDeTareas").GestorDeTareas;
const YAML = require('yaml');
const obtenerDatos = (req: any, res: any) => {
const anime_ID = req.paams.anime_ID;
const con = require('../mysql').obtenerConexionMySql();
con.connect((err: Error) => {
if (!err) {
const respuesta: any = {};
const gestor = new GestorDeTareas(() => {
console.log(YAML.stringify(respuesta));
res.send(YAML.stringify(respuesta));
});
const query1 = `SELECT estudio, eps, alAire, temporada, anio, fuente, generos FROM animes WHERE anime_ID=${anime_ID}`;
gestor.agregarTarea();
con.query(query1, (err: Error, res: RespuestaDatos[]) => {
if (!err) {
const data = res[0];
respuesta.estudio = data.estudio;
respuesta.eps = data.estudio;
respuesta.alAire = data.alAire;
respuesta.temporada = data.temporada;
respuesta.anio = data.anio;
respuesta.fuente = data.fuente;
respuesta.generos = data.generos;
gestor.terminarTarea();
} else {
respuesta.error = true;
console.log(`Error al ejecutar sentencia SQL en /Anime/obtenerDatos (con.query)(1):\n${query1}\n${err}`);
}
});
const query2 = `SELECT * FROM OP WHERE anime_ID=${anime_ID}`;
gestor.agregarTarea();
con.query(query2, (err: Error, res: RespuestaOP[]) => {
if (!err) {
const ops: any = {};
for (const op of res) {
ops[op.num_OP] = {
nombre: op.nombre,
artista: op.artista,
eps: op.eps
}
}
respuesta.OP = ops;
gestor.terminarTarea();
} else {
respuesta.error = true;
console.log(`Error al ejecutar sentencia SQL en /Anime/obtenerDatos (con.query)(2):\n${query2}\n${err}`);
}
});
const query3 = `SELECT * FROM ED WHERE anime_ID=${anime_ID}`;
gestor.agregarTarea();
con.query(query3, (err: Error, res: RespuestaED[]) => {
if (!err) {
const eds: any = {};
for (const ed of res) {
eds[ed.num_ED] = {
nombre: ed.nombre,
artista: ed.artista,
eps: ed.eps
}
}
respuesta.ED = eds;
gestor.terminarTarea();
} else {
respuesta.error = true;
console.log(`Error al ejecutar sentencia SQL en /Anime/obtenerDatos (con.query)(3):\n${query3}\n${err}`);
}
});
} else {
console.log("Error al conectarse a BBDD en /Animes/obtenerDatos (con.connect):\n" + err);
res.send("error: true");
}
});
};
module.exports.obtenerDatos = obtenerDatos;

View File

@ -0,0 +1,24 @@
class GestorDeTareas {
tareas: boolean[] = [];
alCompletar: (() => void);
constructor(alCompletar: (() => void)) {
this.alCompletar = alCompletar;
}
agregarTarea() {
return (this.tareas.push(false) - 1);
}
terminarTarea() {
this.tareas.pop();
this.verificarTareas();
}
verificarTareas() {
if (this.tareas.length === 0)
this.alCompletar();
}
}
module.exports.GestorDeTareas = GestorDeTareas;

View File

@ -1,25 +1,4 @@
class GestorDeTareas { const GestorDeTareas = require("../GestorDeTareas/GestorDeTareas").GestorDeTareas;
tareas: boolean[] = [];
alCompletar: (() => void);
constructor(alCompletar: (() => void)) {
this.alCompletar = alCompletar;
}
agregarTarea() {
return (this.tareas.push(false) - 1);
}
terminarTarea() {
this.tareas.pop();
this.verificarTareas();
}
verificarTareas() {
if (this.tareas.length === 0)
this.alCompletar();
}
}
const YAML = require('yaml'); const YAML = require('yaml');

View File

@ -16,6 +16,9 @@ export default (app:any) => {
app.get('/op/:id', require('./Admin/OP/obtenerOPs').obtenerOPs); app.get('/op/:id', require('./Admin/OP/obtenerOPs').obtenerOPs);
app.post('/op/', require('./Admin/OP/nuevoOP').nuevoOP); app.post('/op/', require('./Admin/OP/nuevoOP').nuevoOP);
app.get('/ed/:anime_ID', require('./Admin/ED/obtenerEDs').obtenerEDs);
app.post('/ed/', require('./Admin/ED/nuevoED').nuevoED);
app.get('/eps/variantes/:anime_ID', require('./Admin/Eps/obtenerVariantes').obtenerVariantes); app.get('/eps/variantes/:anime_ID', require('./Admin/Eps/obtenerVariantes').obtenerVariantes);
app.get('/eps/links/:opcion_ID', require('./Admin/Eps/obtenerLinks').obtenerLinks); app.get('/eps/links/:opcion_ID', require('./Admin/Eps/obtenerLinks').obtenerLinks);
app.post('/eps/links/', require('./Admin/Eps/crearLink').crearLink); app.post('/eps/links/', require('./Admin/Eps/crearLink').crearLink);

View File

@ -14,16 +14,16 @@
1: 1:
nombre: Oonono nombre: Oonono
artista: aoetnaore artista: aoetnaore
episodios: 1 al 13 eps: 1 al 13
2: 2:
nombre: trnaontaoe nombre: trnaontaoe
artista: oaeao artista: oaeao
episodios: 14 al 23 eps: 14 al 23
ED: ED:
1: 1:
nombre: aaoeaoe nombre: aaoeaoe
artista: aoena artista: aoena
episodios: 2 al 13 eps: 2 al 13
links: links:
aviso: ooo654 aviso: ooo654
sigEp: 2 sigEp: 2