From b7d5a786acc324de13590d275d535890d9be459f Mon Sep 17 00:00:00 2001 From: Francisco Sandoval Date: Mon, 10 Jul 2023 18:44:42 -0400 Subject: [PATCH] vistas se dejan en una carpeta, agrega datos de creacion de usuario --- database/create-tables.sql | 105 ----- docker/01_create_tables.sql | 514 +++++++++++++++++++++ docker/docker-compose.yml | 10 +- docker/postgres-geometry/Dockerfile | 129 ++++++ docker/postgres-geometry/initdb-postgis.sh | 22 + docker/postgres-geometry/update-postgis.sh | 28 ++ project/api/middlewares.py | 22 +- project/api/models.py | 268 ++++++++++- project/api/schemas.py | 32 ++ project/api/serializers.py | 59 ++- project/api/urls.py | 17 +- project/api/validaciones.py | 20 + project/api/views.py | 74 --- project/api/views/__init__.py | 0 project/api/views/aplicacion.py | 7 + project/api/views/auth.py | 54 +++ project/api/views/persona.py | 11 + project/api/views/tipo.py | 23 + project/api/views/usuario.py | 80 ++++ project/project/urls.py | 4 +- 20 files changed, 1270 insertions(+), 209 deletions(-) delete mode 100644 database/create-tables.sql create mode 100644 docker/01_create_tables.sql create mode 100644 docker/postgres-geometry/Dockerfile create mode 100644 docker/postgres-geometry/initdb-postgis.sh create mode 100644 docker/postgres-geometry/update-postgis.sh create mode 100644 project/api/schemas.py create mode 100644 project/api/validaciones.py delete mode 100644 project/api/views.py create mode 100644 project/api/views/__init__.py create mode 100644 project/api/views/aplicacion.py create mode 100644 project/api/views/auth.py create mode 100644 project/api/views/persona.py create mode 100644 project/api/views/tipo.py create mode 100644 project/api/views/usuario.py diff --git a/database/create-tables.sql b/database/create-tables.sql deleted file mode 100644 index 8427275..0000000 --- a/database/create-tables.sql +++ /dev/null @@ -1,105 +0,0 @@ -/*==============================================================*/ -/* Table: APLICACIONES */ -/*==============================================================*/ -create table if not exists APLICACIONES ( - ID_APLICACION integer not null primary key, - APP varchar(100) null, - VIGENTE boolean null -); - -/*==============================================================*/ -/* Table: PERSONA */ -/*==============================================================*/ -create table if not exists PERSONA ( - RUT numeric(12) not null primary key, - ID_TIPO_TRATAMIENTO integer null, - DV char(1) null, - NOMBRES varchar(100) null, - APELLIDO_A varchar(100) null, - APELLIDO_B varchar(100) null, - FONO varchar(100) null, - EMAIL varchar(100) null, - FECHA_NACIMIENTO date null -); - -/*==============================================================*/ -/* Table: ROL */ -/*==============================================================*/ -create table if not exists ROL ( - ID_ROL integer not null primary key, - NOMBRE_ROL varchar(100) not null -); - -/*==============================================================*/ -/* Table: ROL_APLICACION */ -/*==============================================================*/ -create table if not exists ROL_APLICACION ( - ID_APLICACION integer not null, - ID_ROL integer not null, - SOLO_VISUALIZAR boolean null, - constraint PK_ROL_APLICACION primary key (ID_APLICACION, ID_ROL) -); - -/*==============================================================*/ -/* Table: TIPO_TRATAMIENTO_PERSONA */ -/*==============================================================*/ -create table if not exists TIPO_TRATAMIENTO_PERSONA ( - ID_TIPO_TRATAMIENTO integer not null primary key, - TRATAMIENTO varchar(50) null -); - -comment on table TIPO_TRATAMIENTO_PERSONA is -'Establece el tratamiento de como dirigirse hacia una persona: -Ejemplo -Se�or -Se�ora -Srta'; - -/*==============================================================*/ -/* Table: USUARIO */ -/*==============================================================*/ -create table if not exists USUARIO ( - LOGIN varchar(20) not null primary key, - RUT numeric(12) null, - CLAVE varchar(20) null, - VIGENTE boolean null -); - -/*==============================================================*/ -/* Table: USUARIO_ROL */ -/*==============================================================*/ -create table if not exists USUARIO_ROL ( - LOGIN varchar(20) null, - ID_ROL integer null, - VIGENTE boolean null -); - -alter table PERSONA - add constraint FK_PERSONA_REFERENCE_TIPO_TRA foreign key (ID_TIPO_TRATAMIENTO) - references TIPO_TRATAMIENTO_PERSONA (ID_TIPO_TRATAMIENTO) - on delete restrict on update restrict; - -alter table ROL_APLICACION - add constraint FK_ROL_APLI_REFERENCE_APLICACI foreign key (ID_APLICACION) - references APLICACIONES (ID_APLICACION) - on delete restrict on update restrict; - -alter table ROL_APLICACION - add constraint FK_ROL_APLI_REFERENCE_ROL foreign key (ID_ROL) - references ROL (ID_ROL) - on delete restrict on update restrict; - -alter table USUARIO - add constraint FK_USUARIO_REFERENCE_PERSONA foreign key (RUT) - references PERSONA (RUT) - on delete restrict on update restrict; - -alter table USUARIO_ROL - add constraint FK_USUARIO__REFERENCE_USUARIO foreign key (LOGIN) - references USUARIO (LOGIN) - on delete restrict on update restrict; - -alter table USUARIO_ROL - add constraint FK_USUARIO__REFERENCE_ROL foreign key (ID_ROL) - references ROL (ID_ROL) - on delete restrict on update restrict; diff --git a/docker/01_create_tables.sql b/docker/01_create_tables.sql new file mode 100644 index 0000000..f899403 --- /dev/null +++ b/docker/01_create_tables.sql @@ -0,0 +1,514 @@ +/* AREA DE DESARROLLO */ +CREATE SCHEMA desarrollo1; +SET SEARCH_PATH TO desarrollo1; + +/* REQUERIDO PARA TIPO GEOMETRY */ +CREATE EXTENSION IF NOT EXISTS postgis; + +/*==============================================================*/ +/* Table: APLICACION */ +/*==============================================================*/ +create table if not exists APLICACION ( + ID_APLICACION INT4 not null, + NOMBRE_APP varchar(100) null, + VIGENTE BOOL null, + constraint PK_APLICACION primary key (ID_APLICACION) +); + +/*==============================================================*/ +/* Table: COMUNA */ +/*==============================================================*/ +create table if not exists COMUNA ( + ID_COMUNA INT4 not null, + ID_REGION INT4 null, + NOMBRE_COMUNA varchar(100) null, + constraint PK_COMUNA primary key (ID_COMUNA) +); + +/*==============================================================*/ +/* Table: CONDUCTOR */ +/*==============================================================*/ +create table if not exists CONDUCTOR ( + PATENTE VARCHAR(10) null, + RUT NUMERIC(12) null, + VIGENTE BOOL null +); + +/*==============================================================*/ +/* Table: DISPOSITIVO */ +/*==============================================================*/ +create table if not exists DISPOSITIVO ( + ID_DISPOSITIVO INT4 not null, + ID_PARADERO INT4 null, + VIGENTE BOOL null, + ULTIMA_CONEXION DATE null, + constraint PK_DISPOSITIVO primary key (ID_DISPOSITIVO) +); + +/*==============================================================*/ +/* Table: FUNCIONARIO */ +/*==============================================================*/ +create table if not exists FUNCIONARIO ( + RUT NUMERIC(12) null, + ID_OPERADOR INT4 null, + DESDE DATE null, + HASTA DATE null +); + +/*==============================================================*/ +/* Table: GTFS_CALENDAR */ +/*==============================================================*/ +create table if not exists GTFS_CALENDAR ( + ID_LINEA INT4 not null, + MONDAY BOOL null, + TUESDAY BOOL null, + WEDNESDAY BOOL null, + THURSDAY BOOL null, + FRIDAY BOOL null, + SALURDAY BOOL null, + SUNDAY BOOL null, + constraint PK_GTFS_CALENDAR primary key (ID_LINEA) +); + +/*==============================================================*/ +/* Table: GTFS_FREQUENCIE */ +/*==============================================================*/ +create table if not exists GTFS_FREQUENCIE ( + ID_TRIPS INT4 null, + START_TIME TIME null, + END_TIME TIME null, + HEADWAY_SECS int null, + EXACT_TIME int null +); + +/*==============================================================*/ +/* Index: INDEX_FREQUENCIE */ +/*==============================================================*/ +create index INDEX_FREQUENCIE on GTFS_FREQUENCIE ( +ID_TRIPS +); + +/*==============================================================*/ +/* Table: GTFS_ROUTES */ +/*==============================================================*/ +create table if not exists GTFS_ROUTES ( + ID_ROUTES INT4 not null, + ID_OPERADOR INT4 null, + ID_ROUTE_TYPE int null, + SHORT_NAME varchar(100) null, + LONG_NAME varchar(300) null, + DESCRIPCION varchar(500) null, + ROUTE_COLOR VARCHAR(6) null, + ROUTE_TEXT_COLOR VARCHAR(6) null, + ROUTE_SORT_ORDER int null, + constraint PK_GTFS_ROUTES primary key (ID_ROUTES) +); + +/*==============================================================*/ +/* Table: GTFS_ROUTE_TYPE */ +/*==============================================================*/ +create table if not exists GTFS_ROUTE_TYPE ( + ID_ROUTE_TYPE int not null, + DESCRIPCION varchar(100) null, + constraint PK_GTFS_ROUTE_TYPE primary key (ID_ROUTE_TYPE) +); + +/*==============================================================*/ +/* Table: GTFS_SHAPE */ +/*==============================================================*/ +create table if not exists GTFS_SHAPE ( + ID_SHAPES INT4 not null, + SHAPE_PT_LAT geometry null, + SHAPE_PT_LON geometry null, + SHAPE_PT_SEQUENCE int null, + SHAOE_DIST_TRAVELED float null, + constraint PK_GTFS_SHAPE primary key (ID_SHAPES) +); + +/*==============================================================*/ +/* Table: GTFS_STOP_TIMES */ +/*==============================================================*/ +create table if not exists GTFS_STOP_TIMES ( + ID_PARADERO INT4 not null, + ID_TRIPS INT4 not null, + ARRIVAL_TIME TIME null, + STOP_SEQUENCE int null, + STOP_HEADSIGN varchar(100) null, + constraint PK_GTFS_STOP_TIMES primary key (ID_PARADERO, ID_TRIPS) +); + +/*==============================================================*/ +/* Table: GTFS_TRIPS */ +/*==============================================================*/ +create table if not exists GTFS_TRIPS ( + ID_TRIPS INT4 not null, + ID_ROUTES INT4 null, + ID_LINEA INT4 null, + ID_SHAPES INT4 null, + ID_TRIPS_REGRESO INT4 null, + TRIP_HEADSIGN varchar(100) null, + SHORT_NAME varchar(100) null, + DIRECCION_ID int null, + constraint PK_GTFS_TRIPS primary key (ID_TRIPS) +); + +/*==============================================================*/ +/* Table: LINEA */ +/*==============================================================*/ +create table if not exists LINEA ( + ID_LINEA INT4 not null, + ID_OPERADOR INT4 null, + IID_TIPO_TRANSPORTE INT4 null, + ID_REGION INT4 null, + VIGENTE BOOL null, + NOMBRE VARCHAR(100) null, + URL varchar(300) null, + constraint PK_LINEA primary key (ID_LINEA) +); + +/*==============================================================*/ +/* Table: OPERADOR */ +/*==============================================================*/ +create table if not exists OPERADOR ( + ID_OPERADOR INT4 not null, + ID_REGION INT4 null, + VIGENTE BOOL null, + constraint PK_OPERADOR primary key (ID_OPERADOR) +); + +/*==============================================================*/ +/* Table: PARADERO */ +/*==============================================================*/ +create table if not exists PARADERO ( + ID_PARADERO INT4 not null, + ID_COMUNA INT4 null, + ID_TIPO_PARADERO INT4 null, + VIGENTE BOOL null, + STOP_CODE varchar(100) null, + STOP_NAME varchar(100) null, + STOP_DESC varchar(300) null, + STOP_LAT geometry null, + STOP_LON geometry null, + constraint PK_PARADERO primary key (ID_PARADERO) +); + +/*==============================================================*/ +/* Table: PARADERO_IMAGEN */ +/*==============================================================*/ +create table if not exists PARADERO_IMAGEN ( + ID_PARADERO INT4 not null, + IMAGEN BYTEA null, + constraint PK_PARADERO_IMAGEN primary key (ID_PARADERO) +); + +/*==============================================================*/ +/* Table: PERSONA */ +/*==============================================================*/ +create table if not exists PERSONA ( + RUT NUMERIC(12) not null, + ID_TIPO_TRATAMIENTO INT4 null, + ID_COMUNA INT4 null, + DV CHAR(1) null, + NOMBRES VARCHAR(100) null, + APELLIDO_A VARCHAR(100) null, + APELLIDO_B VARCHAR(100) null, + FONO VARCHAR(100) null, + EMAIL VARCHAR(100) null, + FECHA_NACIMIENTO DATE null, + DIRECCION VARCHAR(100) null, + constraint PK_PERSONA primary key (RUT) +); + +/*==============================================================*/ +/* Table: REGION */ +/*==============================================================*/ +create table if not exists REGION ( + ID_REGION INT4 not null, + NOMBRE_REGION VARCHAR(100) not null, + constraint PK_REGION primary key (ID_REGION) +); + +/*==============================================================*/ +/* Table: ROL */ +/*==============================================================*/ +create table if not exists ROL ( + ID_ROL INT4 not null, + NOMBRE_ROL varchar(100) not null, + constraint PK_ROL primary key (ID_ROL) +); + +/*==============================================================*/ +/* Table: ROL_APLICACION */ +/*==============================================================*/ +create table if not exists ROL_APLICACION ( + ID_APLICACION INT4 not null, + ID_ROL INT4 not null, + SOLO_VISUALIZAR BOOL null, + constraint PK_ROL_APLICACION primary key (ID_APLICACION, ID_ROL) +); + +/*==============================================================*/ +/* Table: TIPO_DISPOSITIVO */ +/*==============================================================*/ +create table if not exists TIPO_DISPOSITIVO ( + ID_DISPOSITIVO INT4 null, + ID_TIPO_DISPOSITIVO INT4 null +); + +/*==============================================================*/ +/* Table: TIPO_PARADERO */ +/*==============================================================*/ +create table if not exists TIPO_PARADERO ( + ID_TIPO_PARADERO INT4 not null, + DESCRIPCION VARCHAR(100) null, + constraint PK_TIPO_PARADERO primary key (ID_TIPO_PARADERO) +); + +/*==============================================================*/ +/* Table: TIPO_TRANSPORTE */ +/*==============================================================*/ +create table if not exists TIPO_TRANSPORTE ( + IID_TIPO_TRANSPORTE INT4 not null, + DESCRIPCION VARCHAR(50) null, + constraint PK_TIPO_TRANSPORTE primary key (IID_TIPO_TRANSPORTE) +); + +/*==============================================================*/ +/* Table: TIPO_TRATAMIENTO_PERSONA */ +/*==============================================================*/ +create table if not exists TIPO_TRATAMIENTO_PERSONA ( + ID_TIPO_TRATAMIENTO INT4 not null, + TRATAMIENTO varchar(50) null, + constraint PK_TIPO_TRATAMIENTO_PERSONA primary key (ID_TIPO_TRATAMIENTO) +); + +comment on table TIPO_TRATAMIENTO_PERSONA is +'Establece el tratamiento de como dirigirse hacia una persona: +Ejemplo +Señor +Señora +Srta'; + +/*==============================================================*/ +/* Table: TIPO_VEHICULO */ +/*==============================================================*/ +create table if not exists TIPO_VEHICULO ( + ID_TIPO_VEHICULO int not null, + DESCRIPCION varchar(100) null, + constraint PK_TIPO_VEHICULO primary key (ID_TIPO_VEHICULO) +); + +/*==============================================================*/ +/* Table: USUARIO */ +/*==============================================================*/ +create table if not exists USUARIO ( + LOGIN VARCHAR(20) not null, + RUT NUMERIC(12) null, + CLAVE VARCHAR(20) null, + VIGENTE bool null, + constraint PK_USUARIO primary key (LOGIN) +); + +/*==============================================================*/ +/* Table: USUARIO_ROL */ +/*==============================================================*/ +create table if not exists USUARIO_ROL ( + LOGIN VARCHAR(20) null, + ID_ROL INT4 null, + VIGENTE BOOL null +); + +/*==============================================================*/ +/* Table: VEHICULO */ +/*==============================================================*/ +create table if not exists VEHICULO ( + PPU VARCHAR(10) not null, + ID_TIPO_VEHICULO int null, + VIGENTE BOOL null, + constraint PK_VEHICULO primary key (PPU) +); + +/*==============================================================*/ +/* Table: VEHICULO_LINEA */ +/*==============================================================*/ +create table if not exists VEHICULO_LINEA ( + PATENTE VARCHAR(10) null, + ID_LINEA INT4 null, + VIGENTE BOOL null +); + +/*==============================================================*/ +/* View: VW_PARADERO_LINEA */ +/*==============================================================*/ +create or replace view VW_PARADERO_LINEA as +select; + +alter table COMUNA + add constraint FK_COMUNA_REFERENCE_REGION foreign key (ID_REGION) + references REGION (ID_REGION) + on delete restrict on update restrict; + +alter table CONDUCTOR + add constraint FK_CONDUCTO_REFERENCE_VEHICULO foreign key (PATENTE) + references VEHICULO (PPU) + on delete restrict on update restrict; + +alter table CONDUCTOR + add constraint FK_CONDUCTO_REFERENCE_PERSONA foreign key (RUT) + references PERSONA (RUT) + on delete restrict on update restrict; + +alter table DISPOSITIVO + add constraint FK_DISPOSIT_REFERENCE_PARADERO foreign key (ID_PARADERO) + references PARADERO (ID_PARADERO) + on delete restrict on update restrict; + +alter table FUNCIONARIO + add constraint FK_FUNCIONA_REFERENCE_PERSONA foreign key (RUT) + references PERSONA (RUT) + on delete restrict on update restrict; + +alter table FUNCIONARIO + add constraint FK_FUNCIONA_REFERENCE_OPERADOR foreign key (ID_OPERADOR) + references OPERADOR (ID_OPERADOR) + on delete restrict on update restrict; + +alter table GTFS_CALENDAR + add constraint FK_GTFS_CAL_REFERENCE_LINEA foreign key (ID_LINEA) + references LINEA (ID_LINEA) + on delete restrict on update restrict; + +alter table GTFS_FREQUENCIE + add constraint FK_GTFS_FRE_REFERENCE_GTFS_TRI foreign key (ID_TRIPS) + references GTFS_TRIPS (ID_TRIPS) + on delete restrict on update restrict; + +alter table GTFS_ROUTES + add constraint FK_GTFS_ROU_REFERENCE_OPERADOR foreign key (ID_OPERADOR) + references OPERADOR (ID_OPERADOR) + on delete restrict on update restrict; + +alter table GTFS_ROUTES + add constraint FK_GTFS_ROU_REFERENCE_GTFS_ROU foreign key (ID_ROUTE_TYPE) + references GTFS_ROUTE_TYPE (ID_ROUTE_TYPE) + on delete restrict on update restrict; + +alter table GTFS_STOP_TIMES + add constraint FK_GTFS_STO_REFERENCE_PARADERO foreign key (ID_PARADERO) + references PARADERO (ID_PARADERO) + on delete restrict on update restrict; + +alter table GTFS_STOP_TIMES + add constraint FK_GTFS_STO_REFERENCE_GTFS_TRI foreign key (ID_TRIPS) + references GTFS_TRIPS (ID_TRIPS) + on delete restrict on update restrict; + +alter table GTFS_TRIPS + add constraint FK_GTFS_TRI_REFERENCE_GTFS_ROU foreign key (ID_ROUTES) + references GTFS_ROUTES (ID_ROUTES) + on delete restrict on update restrict; + +alter table GTFS_TRIPS + add constraint FK_GTFS_TRI_REFERENCE_LINEA foreign key (ID_LINEA) + references LINEA (ID_LINEA) + on delete restrict on update restrict; + +alter table GTFS_TRIPS + add constraint FK_GTFS_TRI_REFERENCE_GTFS_SHA foreign key (ID_SHAPES) + references GTFS_SHAPE (ID_SHAPES) + on delete restrict on update restrict; + +alter table GTFS_TRIPS + add constraint FK_GTFS_TRI_REFERENCE_GTFS_TRI foreign key (ID_TRIPS_REGRESO) + references GTFS_TRIPS (ID_TRIPS) + on delete restrict on update restrict; + +alter table LINEA + add constraint FK_LINEA_REFERENCE_OPERADOR foreign key (ID_OPERADOR) + references OPERADOR (ID_OPERADOR) + on delete restrict on update restrict; + +alter table LINEA + add constraint FK_LINEA_REFERENCE_TIPO_TRA foreign key (IID_TIPO_TRANSPORTE) + references TIPO_TRANSPORTE (IID_TIPO_TRANSPORTE) + on delete restrict on update restrict; + +alter table LINEA + add constraint FK_LINEA_REFERENCE_REGION foreign key (ID_REGION) + references REGION (ID_REGION) + on delete restrict on update restrict; + +alter table OPERADOR + add constraint FK_OPERADOR_REFERENCE_REGION foreign key (ID_REGION) + references REGION (ID_REGION) + on delete restrict on update restrict; + +alter table PARADERO + add constraint FK_PARADERO_REFERENCE_COMUNA foreign key (ID_COMUNA) + references COMUNA (ID_COMUNA) + on delete restrict on update restrict; + +alter table PARADERO + add constraint FK_PARADERO_REFERENCE_TIPO_PAR foreign key (ID_TIPO_PARADERO) + references TIPO_PARADERO (ID_TIPO_PARADERO) + on delete restrict on update restrict; + +alter table PARADERO_IMAGEN + add constraint FK_PARADERO_REFERENCE_PARADERO foreign key (ID_PARADERO) + references PARADERO (ID_PARADERO) + on delete restrict on update restrict; + +alter table PERSONA + add constraint FK_PERSONA_REFERENCE_COMUNA foreign key (ID_COMUNA) + references COMUNA (ID_COMUNA) + on delete restrict on update restrict; + +alter table PERSONA + add constraint FK_PERSONA_REFERENCE_TIPO_TRA foreign key (ID_TIPO_TRATAMIENTO) + references TIPO_TRATAMIENTO_PERSONA (ID_TIPO_TRATAMIENTO) + on delete restrict on update restrict; + +alter table ROL_APLICACION + add constraint FK_ROL_APLI_REFERENCE_APLICACI foreign key (ID_APLICACION) + references APLICACION (ID_APLICACION) + on delete restrict on update restrict; + +alter table ROL_APLICACION + add constraint FK_ROL_APLI_REFERENCE_ROL foreign key (ID_ROL) + references ROL (ID_ROL) + on delete restrict on update restrict; + +alter table TIPO_DISPOSITIVO + add constraint FK_TIPO_DIS_REFERENCE_DISPOSIT foreign key (ID_DISPOSITIVO) + references DISPOSITIVO (ID_DISPOSITIVO) + on delete restrict on update restrict; + +alter table USUARIO + add constraint FK_USUARIO_REFERENCE_PERSONA foreign key (RUT) + references PERSONA (RUT) + on delete restrict on update restrict; + +alter table USUARIO_ROL + add constraint FK_USUARIO__REFERENCE_USUARIO foreign key (LOGIN) + references USUARIO (LOGIN) + on delete restrict on update restrict; + +alter table USUARIO_ROL + add constraint FK_USUARIO__REFERENCE_ROL foreign key (ID_ROL) + references ROL (ID_ROL) + on delete restrict on update restrict; + +alter table VEHICULO + add constraint FK_VEHICULO_REFERENCE_TIPO_VEH foreign key (ID_TIPO_VEHICULO) + references TIPO_VEHICULO (ID_TIPO_VEHICULO) + on delete restrict on update restrict; + +alter table VEHICULO_LINEA + add constraint FK_VEHICULO_REFERENCE_VEHICULO foreign key (PATENTE) + references VEHICULO (PPU) + on delete restrict on update restrict; + +alter table VEHICULO_LINEA + add constraint FK_VEHICULO_REFERENCE_LINEA foreign key (ID_LINEA) + references LINEA (ID_LINEA) + on delete restrict on update restrict; diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index ff8b211..98ca713 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -11,7 +11,7 @@ services: - PORT=4000 - DBHOST=db - DBNAME=database - - DBSCHEMA=desarrollo2 + - DBSCHEMA=desarrollo1 - DBUSER=postgres - DBPASS=password - SECRET_JWT="kf6Jc!f30Z!1k1N0#!%#" @@ -22,11 +22,15 @@ services: working_dir: /app command: sh /app/docker/start.sh + # REF: https://github.com/postgis/docker-postgis/tree/master/14-3.3 db: - image: postgres:14-alpine + image: postgres:14-alpine-geometry + build: + context: ./postgres-geometry + dockerfile: Dockerfile volumes: - db:/var/lib/postgresql/data - - ./backups:/docker-entrypoint-initdb.d + - ./01_create_tables.sql:/docker-entrypoint-initdb.d/01_create_tables.sql environment: POSTGRES_PASSWORD: password POSTGRES_DB: database diff --git a/docker/postgres-geometry/Dockerfile b/docker/postgres-geometry/Dockerfile new file mode 100644 index 0000000..0839550 --- /dev/null +++ b/docker/postgres-geometry/Dockerfile @@ -0,0 +1,129 @@ +FROM postgres:14-alpine3.15 + +LABEL maintainer="PostGIS Project - https://postgis.net" + +ENV POSTGIS_VERSION 3.2.1 +ENV POSTGIS_SHA256 1e9cc4c4f390e4c3be4f5c125a72f39dfa847412332952429952cbd731ac9ba3 + +RUN set -eux \ + \ + && if [ $(printf %.1s "$POSTGIS_VERSION") == 3 ]; then \ + set -eux ; \ + # + # using only v3.15 + # + #GEOS: https://pkgs.alpinelinux.org/packages?name=geos&branch=v3.15 \ + export GEOS_ALPINE_VER=3.10 ; \ + #GDAL: https://pkgs.alpinelinux.org/packages?name=gdal&branch=v3.15 \ + export GDAL_ALPINE_VER=3.4 ; \ + #PROJ: https://pkgs.alpinelinux.org/packages?name=proj&branch=v3.15 \ + export PROJ_ALPINE_VER=8.2 ; \ + # + elif [ $(printf %.1s "$POSTGIS_VERSION") == 2 ]; then \ + set -eux ; \ + # + # using older branches v3.13; v3.14 for GEOS,GDAL,PROJ + # + #GEOS: https://pkgs.alpinelinux.org/packages?name=geos&branch=v3.13 \ + export GEOS_ALPINE_VER=3.8 ; \ + #GDAL: https://pkgs.alpinelinux.org/packages?name=gdal&branch=v3.14 \ + export GDAL_ALPINE_VER=3.2 ; \ + #PROJ: https://pkgs.alpinelinux.org/packages?name=proj&branch=v3.14 \ + export PROJ_ALPINE_VER=7.2 ; \ + # + \ + echo 'https://dl-cdn.alpinelinux.org/alpine/v3.14/main' >> /etc/apk/repositories ; \ + echo 'https://dl-cdn.alpinelinux.org/alpine/v3.14/community' >> /etc/apk/repositories ; \ + echo 'https://dl-cdn.alpinelinux.org/alpine/v3.13/main' >> /etc/apk/repositories ; \ + echo 'https://dl-cdn.alpinelinux.org/alpine/v3.13/community' >> /etc/apk/repositories ; \ + \ + else \ + set -eux ; \ + echo ".... unknown \$POSTGIS_VERSION ...." ; \ + exit 1 ; \ + fi \ + \ + && apk add --no-cache --virtual .fetch-deps \ + ca-certificates \ + openssl \ + tar \ + \ + && wget -O postgis.tar.gz "https://github.com/postgis/postgis/archive/${POSTGIS_VERSION}.tar.gz" \ + && echo "${POSTGIS_SHA256} *postgis.tar.gz" | sha256sum -c - \ + && mkdir -p /usr/src/postgis \ + && tar \ + --extract \ + --file postgis.tar.gz \ + --directory /usr/src/postgis \ + --strip-components 1 \ + && rm postgis.tar.gz \ + \ + && apk add --no-cache --virtual .build-deps \ + \ + gdal-dev~=${GDAL_ALPINE_VER} \ + geos-dev~=${GEOS_ALPINE_VER} \ + proj-dev~=${PROJ_ALPINE_VER} \ + \ + autoconf \ + automake \ + clang-dev \ + file \ + g++ \ + gcc \ + gettext-dev \ + json-c-dev \ + libtool \ + libxml2-dev \ + llvm-dev \ + make \ + pcre-dev \ + perl \ + protobuf-c-dev \ + \ +# build PostGIS + \ + && cd /usr/src/postgis \ + && gettextize \ + && ./autogen.sh \ + && ./configure \ + --with-pcredir="$(pcre-config --prefix)" \ + && make -j$(nproc) \ + && make install \ + \ +# regress check + && mkdir /tempdb \ + && chown -R postgres:postgres /tempdb \ + && su postgres -c 'pg_ctl -D /tempdb init' \ + && su postgres -c 'pg_ctl -D /tempdb start' \ + && cd regress \ + && make -j$(nproc) check RUNTESTFLAGS=--extension PGUSER=postgres \ + #&& make -j$(nproc) check RUNTESTFLAGS=--dumprestore PGUSER=postgres \ + #&& make garden PGUSER=postgres \ + \ + && su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS postgis;"' \ + && su postgres -c 'psql -t -c "SELECT version();"' >> /_pgis_full_version.txt \ + && su postgres -c 'psql -t -c "SELECT PostGIS_Full_Version();"' >> /_pgis_full_version.txt \ + \ + && su postgres -c 'pg_ctl -D /tempdb --mode=immediate stop' \ + && rm -rf /tempdb \ + && rm -rf /tmp/pgis_reg \ +# add .postgis-rundeps + && apk add --no-cache --virtual .postgis-rundeps \ + \ + gdal~=${GDAL_ALPINE_VER} \ + geos~=${GEOS_ALPINE_VER} \ + proj~=${PROJ_ALPINE_VER} \ + \ + json-c \ + libstdc++ \ + pcre \ + protobuf-c \ +# clean + && cd / \ + && rm -rf /usr/src/postgis \ + && apk del .fetch-deps .build-deps \ +# print PostGIS_Full_Version() for the log. ( experimental & internal ) + && cat /_pgis_full_version.txt + +COPY ./initdb-postgis.sh /docker-entrypoint-initdb.d/10_postgis.sh +COPY ./update-postgis.sh /usr/local/bin diff --git a/docker/postgres-geometry/initdb-postgis.sh b/docker/postgres-geometry/initdb-postgis.sh new file mode 100644 index 0000000..cdde274 --- /dev/null +++ b/docker/postgres-geometry/initdb-postgis.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +set -e + +# Perform all actions as $POSTGRES_USER +export PGUSER="$POSTGRES_USER" + +# Create the 'template_postgis' template db +"${psql[@]}" <<- 'EOSQL' +CREATE DATABASE template_postgis IS_TEMPLATE true; +EOSQL + +# Load PostGIS into both template_database and $POSTGRES_DB +for DB in template_postgis "$POSTGRES_DB"; do + echo "Loading PostGIS extensions into $DB" + "${psql[@]}" --dbname="$DB" <<-'EOSQL' + CREATE EXTENSION IF NOT EXISTS postgis; + CREATE EXTENSION IF NOT EXISTS postgis_topology; + CREATE EXTENSION IF NOT EXISTS fuzzystrmatch; + CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder; +EOSQL +done diff --git a/docker/postgres-geometry/update-postgis.sh b/docker/postgres-geometry/update-postgis.sh new file mode 100644 index 0000000..f98abd2 --- /dev/null +++ b/docker/postgres-geometry/update-postgis.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +set -e + +# Perform all actions as $POSTGRES_USER +export PGUSER="$POSTGRES_USER" + +POSTGIS_VERSION="${POSTGIS_VERSION%%+*}" + +# Load PostGIS into both template_database and $POSTGRES_DB +for DB in template_postgis "$POSTGRES_DB" "${@}"; do + echo "Updating PostGIS extensions '$DB' to $POSTGIS_VERSION" + psql --dbname="$DB" -c " + -- Upgrade PostGIS (includes raster) + CREATE EXTENSION IF NOT EXISTS postgis VERSION '$POSTGIS_VERSION'; + ALTER EXTENSION postgis UPDATE TO '$POSTGIS_VERSION'; + + -- Upgrade Topology + CREATE EXTENSION IF NOT EXISTS postgis_topology VERSION '$POSTGIS_VERSION'; + ALTER EXTENSION postgis_topology UPDATE TO '$POSTGIS_VERSION'; + + -- Install Tiger dependencies in case not already installed + CREATE EXTENSION IF NOT EXISTS fuzzystrmatch; + -- Upgrade US Tiger Geocoder + CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder VERSION '$POSTGIS_VERSION'; + ALTER EXTENSION postgis_tiger_geocoder UPDATE TO '$POSTGIS_VERSION'; + " +done diff --git a/project/api/middlewares.py b/project/api/middlewares.py index 113e6eb..cc636dd 100644 --- a/project/api/middlewares.py +++ b/project/api/middlewares.py @@ -33,18 +33,18 @@ class ApiMiddleware: except jwt.InvalidTokenError: return HttpResponse('token es invalido', status = 400) - usuario = Usuario.objects.filter(login = decoded['login'], vigente = True).values().first() - if not usuario: - return HttpResponse('Usuario ya no vigente', status = 400) + if decoded['login'] != '0': + usuario = Usuario.objects.filter(login = decoded['login'], vigente = True).values().first() + if not usuario: + return HttpResponse('Usuario ya no vigente', status = 400) + + persona = Persona.objects.filter(rut = usuario['rut_id']).values().first() + if not persona: + return HttpResponse('No existe información de la persona', status = 500) - persona = Persona.objects.filter(rut = usuario['rut_id']).values().first() - if not persona: - return HttpResponse('No existe información de la persona', status = 500) - - request.jwt_info = { - 'login': usuario['login'], - 'persona': persona - } + request.jwt_info = { 'login': usuario['login'], 'persona': persona } + else: + request.jwt_info = { 'login': '0', 'persona': None } response = self.get_response(request) return response diff --git a/project/api/models.py b/project/api/models.py index 2a75849..8e59245 100644 --- a/project/api/models.py +++ b/project/api/models.py @@ -10,17 +10,201 @@ from django.db import models class Aplicacion(models.Model): id_aplicacion = models.IntegerField(primary_key=True) - app = models.CharField(max_length=100, blank=True, null=True) + nombre_app = models.CharField(max_length=100, blank=True, null=True) vigente = models.BooleanField(blank=True, null=True) class Meta: managed = False - db_table = 'aplicaciones' + db_table = 'aplicacion' + + +class Comuna(models.Model): + id_comuna = models.IntegerField(primary_key=True) + id_region = models.ForeignKey('Region', models.DO_NOTHING, db_column='id_region', blank=True, null=True) + nombre_comuna = models.CharField(max_length=100, blank=True, null=True) + + class Meta: + managed = False + db_table = 'comuna' + + +class Conductor(models.Model): + patente = models.ForeignKey('Vehiculo', models.DO_NOTHING, db_column='patente', blank=True, null=True) + rut = models.ForeignKey('Persona', models.DO_NOTHING, db_column='rut', blank=True, null=True) + vigente = models.BooleanField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'conductor' + + +class Dispositivo(models.Model): + id_dispositivo = models.IntegerField(primary_key=True) + id_paradero = models.ForeignKey('Paradero', models.DO_NOTHING, db_column='id_paradero', blank=True, null=True) + vigente = models.BooleanField(blank=True, null=True) + ultima_conexion = models.DateField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'dispositivo' + + +class Funcionario(models.Model): + rut = models.ForeignKey('Persona', models.DO_NOTHING, db_column='rut', blank=True, null=True) + id_operador = models.ForeignKey('Operador', models.DO_NOTHING, db_column='id_operador', blank=True, null=True) + desde = models.DateField(blank=True, null=True) + hasta = models.DateField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'funcionario' + + +class GtfsCalendar(models.Model): + id_linea = models.OneToOneField('Linea', models.DO_NOTHING, db_column='id_linea', primary_key=True) + monday = models.BooleanField(blank=True, null=True) + tuesday = models.BooleanField(blank=True, null=True) + wednesday = models.BooleanField(blank=True, null=True) + thursday = models.BooleanField(blank=True, null=True) + friday = models.BooleanField(blank=True, null=True) + salurday = models.BooleanField(blank=True, null=True) + sunday = models.BooleanField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'gtfs_calendar' + + +class GtfsFrequencie(models.Model): + id_trips = models.ForeignKey('GtfsTrips', models.DO_NOTHING, db_column='id_trips', blank=True, null=True) + start_time = models.TimeField(blank=True, null=True) + end_time = models.TimeField(blank=True, null=True) + headway_secs = models.IntegerField(blank=True, null=True) + exact_time = models.IntegerField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'gtfs_frequencie' + + +class GtfsRouteType(models.Model): + id_route_type = models.IntegerField(primary_key=True) + descripcion = models.CharField(max_length=100, blank=True, null=True) + + class Meta: + managed = False + db_table = 'gtfs_route_type' + + +class GtfsRoutes(models.Model): + id_routes = models.IntegerField(primary_key=True) + id_operador = models.ForeignKey('Operador', models.DO_NOTHING, db_column='id_operador', blank=True, null=True) + id_route_type = models.ForeignKey(GtfsRouteType, models.DO_NOTHING, db_column='id_route_type', blank=True, null=True) + short_name = models.CharField(max_length=100, blank=True, null=True) + long_name = models.CharField(max_length=300, blank=True, null=True) + descripcion = models.CharField(max_length=500, blank=True, null=True) + route_color = models.CharField(max_length=6, blank=True, null=True) + route_text_color = models.CharField(max_length=6, blank=True, null=True) + route_sort_order = models.IntegerField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'gtfs_routes' + + +class GtfsShape(models.Model): + id_shapes = models.IntegerField(primary_key=True) + shape_pt_lat = models.TextField(blank=True, null=True) # This field type is a guess. + shape_pt_lon = models.TextField(blank=True, null=True) # This field type is a guess. + shape_pt_sequence = models.IntegerField(blank=True, null=True) + shaoe_dist_traveled = models.FloatField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'gtfs_shape' + + +class GtfsStopTimes(models.Model): + id_paradero = models.OneToOneField('Paradero', models.DO_NOTHING, db_column='id_paradero', primary_key=True) # The composite primary key (id_paradero, id_trips) found, that is not supported. The first column is selected. + id_trips = models.ForeignKey('GtfsTrips', models.DO_NOTHING, db_column='id_trips') + arrival_time = models.TimeField(blank=True, null=True) + stop_sequence = models.IntegerField(blank=True, null=True) + stop_headsign = models.CharField(max_length=100, blank=True, null=True) + + class Meta: + managed = False + db_table = 'gtfs_stop_times' + unique_together = (('id_paradero', 'id_trips'),) + + +class GtfsTrips(models.Model): + id_trips = models.IntegerField(primary_key=True) + id_routes = models.ForeignKey(GtfsRoutes, models.DO_NOTHING, db_column='id_routes', blank=True, null=True) + id_linea = models.ForeignKey('Linea', models.DO_NOTHING, db_column='id_linea', blank=True, null=True) + id_shapes = models.ForeignKey(GtfsShape, models.DO_NOTHING, db_column='id_shapes', blank=True, null=True) + id_trips_regreso = models.ForeignKey('self', models.DO_NOTHING, db_column='id_trips_regreso', blank=True, null=True) + trip_headsign = models.CharField(max_length=100, blank=True, null=True) + short_name = models.CharField(max_length=100, blank=True, null=True) + direccion_id = models.IntegerField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'gtfs_trips' + + +class Linea(models.Model): + id_linea = models.IntegerField(primary_key=True) + id_operador = models.ForeignKey('Operador', models.DO_NOTHING, db_column='id_operador', blank=True, null=True) + iid_tipo_transporte = models.ForeignKey('TipoTransporte', models.DO_NOTHING, db_column='iid_tipo_transporte', blank=True, null=True) + id_region = models.ForeignKey('Region', models.DO_NOTHING, db_column='id_region', blank=True, null=True) + vigente = models.BooleanField(blank=True, null=True) + nombre = models.CharField(max_length=100, blank=True, null=True) + url = models.CharField(max_length=300, blank=True, null=True) + + class Meta: + managed = False + db_table = 'linea' + + +class Operador(models.Model): + id_operador = models.IntegerField(primary_key=True) + id_region = models.ForeignKey('Region', models.DO_NOTHING, db_column='id_region', blank=True, null=True) + vigente = models.BooleanField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'operador' + + +class Paradero(models.Model): + id_paradero = models.IntegerField(primary_key=True) + id_comuna = models.ForeignKey(Comuna, models.DO_NOTHING, db_column='id_comuna', blank=True, null=True) + id_tipo_paradero = models.ForeignKey('TipoParadero', models.DO_NOTHING, db_column='id_tipo_paradero', blank=True, null=True) + vigente = models.BooleanField(blank=True, null=True) + stop_code = models.CharField(max_length=100, blank=True, null=True) + stop_name = models.CharField(max_length=100, blank=True, null=True) + stop_desc = models.CharField(max_length=300, blank=True, null=True) + stop_lat = models.TextField(blank=True, null=True) # This field type is a guess. + stop_lon = models.TextField(blank=True, null=True) # This field type is a guess. + + class Meta: + managed = False + db_table = 'paradero' + + +class ParaderoImagen(models.Model): + id_paradero = models.OneToOneField(Paradero, models.DO_NOTHING, db_column='id_paradero', primary_key=True) + imagen = models.BinaryField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'paradero_imagen' class Persona(models.Model): rut = models.DecimalField(primary_key=True, max_digits=12, decimal_places=0) id_tipo_tratamiento = models.ForeignKey('TipoTratamientoPersona', models.DO_NOTHING, db_column='id_tipo_tratamiento', blank=True, null=True) + id_comuna = models.ForeignKey(Comuna, models.DO_NOTHING, db_column='id_comuna', blank=True, null=True) dv = models.CharField(max_length=1, blank=True, null=True) nombres = models.CharField(max_length=100, blank=True, null=True) apellido_a = models.CharField(max_length=100, blank=True, null=True) @@ -28,12 +212,22 @@ class Persona(models.Model): fono = models.CharField(max_length=100, blank=True, null=True) email = models.CharField(max_length=100, blank=True, null=True) fecha_nacimiento = models.DateField(blank=True, null=True) + direccion = models.CharField(max_length=100, blank=True, null=True) class Meta: managed = False db_table = 'persona' +class Region(models.Model): + id_region = models.IntegerField(primary_key=True) + nombre_region = models.CharField(max_length=100) + + class Meta: + managed = False + db_table = 'region' + + class Rol(models.Model): id_rol = models.IntegerField(primary_key=True) nombre_rol = models.CharField(max_length=100) @@ -54,6 +248,45 @@ class RolAplicacion(models.Model): unique_together = (('id_aplicacion', 'id_rol'),) +class SpatialRefSys(models.Model): + srid = models.IntegerField(primary_key=True) + auth_name = models.CharField(max_length=256, blank=True, null=True) + auth_srid = models.IntegerField(blank=True, null=True) + srtext = models.CharField(max_length=2048, blank=True, null=True) + proj4text = models.CharField(max_length=2048, blank=True, null=True) + + class Meta: + managed = False + db_table = 'spatial_ref_sys' + + +class TipoDispositivo(models.Model): + id_dispositivo = models.ForeignKey(Dispositivo, models.DO_NOTHING, db_column='id_dispositivo', blank=True, null=True) + id_tipo_dispositivo = models.IntegerField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'tipo_dispositivo' + + +class TipoParadero(models.Model): + id_tipo_paradero = models.IntegerField(primary_key=True) + descripcion = models.CharField(max_length=100, blank=True, null=True) + + class Meta: + managed = False + db_table = 'tipo_paradero' + + +class TipoTransporte(models.Model): + iid_tipo_transporte = models.IntegerField(primary_key=True) + descripcion = models.CharField(max_length=50, blank=True, null=True) + + class Meta: + managed = False + db_table = 'tipo_transporte' + + class TipoTratamientoPersona(models.Model): id_tipo_tratamiento = models.IntegerField(primary_key=True) tratamiento = models.CharField(max_length=50, blank=True, null=True) @@ -61,7 +294,16 @@ class TipoTratamientoPersona(models.Model): class Meta: managed = False db_table = 'tipo_tratamiento_persona' - db_table_comment = 'Establece el tratamiento de como dirigirse hacia una persona:\r\nEjemplo\r\nSe�or\r\nSe�ora\r\nSrta' + db_table_comment = 'Establece el tratamiento de como dirigirse hacia una persona:\r\nEjemplo\r\nSeñor\r\nSeñora\r\nSrta' + + +class TipoVehiculo(models.Model): + id_tipo_vehiculo = models.IntegerField(primary_key=True) + descripcion = models.CharField(max_length=100, blank=True, null=True) + + class Meta: + managed = False + db_table = 'tipo_vehiculo' class Usuario(models.Model): @@ -83,3 +325,23 @@ class UsuarioRol(models.Model): class Meta: managed = False db_table = 'usuario_rol' + + +class Vehiculo(models.Model): + ppu = models.CharField(primary_key=True, max_length=10) + id_tipo_vehiculo = models.ForeignKey(TipoVehiculo, models.DO_NOTHING, db_column='id_tipo_vehiculo', blank=True, null=True) + vigente = models.BooleanField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'vehiculo' + + +class VehiculoLinea(models.Model): + patente = models.ForeignKey(Vehiculo, models.DO_NOTHING, db_column='patente', blank=True, null=True) + id_linea = models.ForeignKey(Linea, models.DO_NOTHING, db_column='id_linea', blank=True, null=True) + vigente = models.BooleanField(blank=True, null=True) + + class Meta: + managed = False + db_table = 'vehiculo_linea' diff --git a/project/api/schemas.py b/project/api/schemas.py new file mode 100644 index 0000000..7488e7c --- /dev/null +++ b/project/api/schemas.py @@ -0,0 +1,32 @@ +from rest_framework.schemas import AutoSchema +import coreapi + +class AuthSchema(AutoSchema): + manual_fields = [] + + def get_manual_fields(self, path, method): + custom_fields = [] + if method.lower() == 'post': + custom_fields = [ + coreapi.Field('username', required=True, location='form', description='Usuario'), + coreapi.Field('password', required=True, location='form', description='Contraseña'), + ] + return self._manual_fields + custom_fields + +class UsuarioSchema(AutoSchema): + manual_fields = [] + + def get_manual_fields(self, path, method): + custom_fields = [] + if method.lower() == 'post': + custom_fields = [ + coreapi.Field('rut', required=True, location='form', description='RUT'), + coreapi.Field('nombres', required=True, location='form', description='Nombres'), + coreapi.Field('apellido_a', required=True, location='form', description='Apellido A'), + coreapi.Field('apellido_b', required=True, location='form', description='Apellido B'), + coreapi.Field('email', required=True, location='form', description='Correo Electrónico'), + coreapi.Field('login', required=True, location='form', description='Usuario'), + coreapi.Field('clave', required=True, location='form', description='Contraseña'), + coreapi.Field('vigente', location='form', description='Vigente'), + ] + return self._manual_fields + custom_fields diff --git a/project/api/serializers.py b/project/api/serializers.py index 655b3a4..c64d7b0 100644 --- a/project/api/serializers.py +++ b/project/api/serializers.py @@ -1,21 +1,68 @@ from rest_framework import serializers -from .models import Aplicacion -from .models import Usuario, Persona +from django.forms.models import model_to_dict +from . import models class AplicacionSerializer(serializers.ModelSerializer): class Meta: - model = Aplicacion + model = models.Aplicacion + fields = '__all__' + +class TipoDispositivoSerializer(serializers.ModelSerializer): + class Meta: + model = models.TipoDispositivo + fields = '__all__' + +class TipoParaderoSerializer(serializers.ModelSerializer): + class Meta: + model = models.TipoParadero + fields = '__all__' + +class TipoTransporteSerializer(serializers.ModelSerializer): + class Meta: + model = models.TipoTransporte + fields = '__all__' + +class TipoVehiculoSerializer(serializers.ModelSerializer): + class Meta: + model = models.TipoVehiculo + fields = '__all__' + +class TipoTratamientoPersonaSerializer(serializers.ModelSerializer): + class Meta: + model = models.TipoTratamientoPersona fields = '__all__' class PersonaSerializer(serializers.ModelSerializer): class Meta: - model = Persona + model = models.Persona fields = '__all__' class UsuarioSerializer(serializers.ModelSerializer): class Meta: - model = Usuario - fields = ('login','vigente','rut') + model = models.Usuario + fields = '__all__' + read_only_fields = ['login'] + + def get_fields(self): + fields = super().get_fields() + action = self.context['view'].action + print({ 'action': action }) + if action == 'retrieve' or action == 'list': + fields = { + 'login': fields['login'], + 'vigente': fields['vigente'], + 'rut': fields['rut'], + } + return fields + + def to_representation(self, instance): + representation = super().to_representation(instance) + + # Elimina el campo que deseas después de la actualización + if 'clave' in representation: + del representation['clave'] + + return representation class AuthSerializer(serializers.Serializer): username = serializers.CharField(required=True) diff --git a/project/api/urls.py b/project/api/urls.py index 6d8e138..93b963c 100644 --- a/project/api/urls.py +++ b/project/api/urls.py @@ -1,13 +1,20 @@ from django.urls import path, include from rest_framework import routers -from api import views +# from api import views +from api.views import usuario, auth, aplicacion, tipo, persona router = routers.DefaultRouter() -router.register(r'aplicaciones', views.AplicacionViewSet) -router.register(r'usuarios', views.UsuarioViewSet) -router.register(r'personas', views.PersonaViewSet) +router.register(r'aplicaciones', aplicacion.AplicacionViewSet) +router.register(r'usuarios', usuario.UsuarioViewSet) +router.register(r'personas', persona.PersonaViewSet) +router.register(r'tipos/persona', tipo.TipoTratamientoPersonaViewSet) +router.register(r'tipos/transporte', tipo.TipoTransporteViewSet) +router.register(r'tipos/dispositivo', tipo.TipoDispositivoViewSet) +router.register(r'tipos/paradero', tipo.TipoParaderoViewSet) +router.register(r'tipos/vehiculo', tipo.TipoVehiculoViewSet) urlpatterns = [ path('', include(router.urls)), - path(r'auth/', views.jwt_login, name='auth'), + path('auth/', auth.jwt_login, name='auth'), + # path('usuarios/', usuario.usuario_any), ] \ No newline at end of file diff --git a/project/api/validaciones.py b/project/api/validaciones.py new file mode 100644 index 0000000..2906fd9 --- /dev/null +++ b/project/api/validaciones.py @@ -0,0 +1,20 @@ +def rut_valido(rut): + rut = rut.replace(".", "").replace("-", "") # Eliminar puntos y guiones + if len(rut) < 2: + return False + verificador = rut[-1] + numero = rut[:-1] + try: + suma = 0 + contador = 0 + for i in range(len(numero) - 1, -1, -1): + suma += int(numero[i]) * (2 + contador) + contador = (contador + 1) % 6 + digito_verificador = 11 - suma % 11 + if digito_verificador == 11: + digito_verificador = 0 + if digito_verificador == 10: + digito_verificador = "k" + return str(digito_verificador) == verificador.lower() + except ValueError: + return False diff --git a/project/api/views.py b/project/api/views.py deleted file mode 100644 index 4d2dc35..0000000 --- a/project/api/views.py +++ /dev/null @@ -1,74 +0,0 @@ -from rest_framework import viewsets -from rest_framework.decorators import action, api_view, schema -from rest_framework.schemas import AutoSchema -from django.views.decorators.csrf import csrf_exempt -from django.http import HttpResponse -from django.http import JsonResponse -from .models import Usuario, Persona -from .models import Aplicacion -from .serializers import UsuarioSerializer, PersonaSerializer -from .serializers import AplicacionSerializer, AuthSerializer -import json -import jwt -import datetime -import coreapi -from decouple import config - -private_key = config('SECRET_JWT') - -# Create your views here. -class AplicacionViewSet(viewsets.ModelViewSet): - queryset = Aplicacion.objects.all() - serializer_class = AplicacionSerializer - ordering_fields = '__all__' - -class PersonaViewSet(viewsets.ModelViewSet): - queryset = Persona.objects.all() - serializer_class = PersonaSerializer - -class UsuarioViewSet(viewsets.ModelViewSet): - queryset = Usuario.objects.all() - serializer_class = UsuarioSerializer - - -class CustomAuthSchema(AutoSchema): - manual_fields = [] - - def get_manual_fields(self, path, method): - custom_fields = [] - if method.lower() == 'post': - custom_fields = [ - coreapi.Field('username', required=True, location='form', description='Usuario'), - coreapi.Field('password', required=True, location='form', description='Contraseña'), - ] - return self._manual_fields + custom_fields - -# Views jwt -@csrf_exempt -@action(detail=False, methods=['post','get']) -@api_view(['GET','POST']) -@schema(CustomAuthSchema()) -def jwt_login(request): - if request.method == 'POST': - # validar username y password - json_data = json.loads(request.body) - username = json_data['username'] - password = json_data['password'] - - usuario = Usuario.objects.filter(login = username, vigente = True).values().first() - if not usuario: - return HttpResponse('Acceso no valido', status = 400) - - if usuario['clave'] != password: - return HttpResponse('Acceso no valido', status = 400) - - now = datetime.datetime.utcnow() - payload = { - 'exp': now + datetime.timedelta(minutes=60), - 'login': usuario['login'] - } - token = jwt.encode(payload, private_key, algorithm="HS256") - return JsonResponse({ 'token': token }) - elif request.method == 'GET': - return JsonResponse(request.jwt_info) - \ No newline at end of file diff --git a/project/api/views/__init__.py b/project/api/views/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/project/api/views/aplicacion.py b/project/api/views/aplicacion.py new file mode 100644 index 0000000..f07bd9d --- /dev/null +++ b/project/api/views/aplicacion.py @@ -0,0 +1,7 @@ +from rest_framework import viewsets +from .. import models, serializers + +class AplicacionViewSet(viewsets.ModelViewSet): + queryset = models.Aplicacion.objects.all() + serializer_class = serializers.AplicacionSerializer + ordering_fields = '__all__' \ No newline at end of file diff --git a/project/api/views/auth.py b/project/api/views/auth.py new file mode 100644 index 0000000..fe7512d --- /dev/null +++ b/project/api/views/auth.py @@ -0,0 +1,54 @@ + +from django.views.decorators.csrf import csrf_exempt +from django.http import HttpResponse +from django.http import JsonResponse + +from rest_framework.decorators import action, api_view, schema + +from .. import models, schemas +from decouple import config +import json +import jwt +from datetime import datetime, timedelta + +private_key = config('SECRET_JWT') + +# Views jwt +@csrf_exempt +@action(detail=False, methods=['post','get']) +@api_view(['GET','POST']) +@schema(schemas.AuthSchema()) +def jwt_login(request): + if request.method == 'POST': + count = models.Usuario.objects.filter(vigente = True).count() + # validar username y password + input = json.loads(request.body) + username = input['username'] + password = input['password'] + usuario = None + + if count > 0: + usuario = models.Usuario.objects.filter(login = username, vigente = True).values().first() + elif username == '0' and password == '0': + usuario = { 'login': '0', 'clave': '0' } + + if not usuario: + return HttpResponse('Acceso no valido', status = 400) + + if usuario['clave'] != password: + return HttpResponse('Acceso no valido', status = 400) + + ahora = datetime.now() + manana = ahora + timedelta(days=1) + manana = manana.replace(hour=0, minute=0, second=0, microsecond=0) + # diferencia = manana - ahora + # minutos_restantes = diferencia.total_seconds() // 60 + + payload = { + 'exp': manana, + 'login': usuario['login'] + } + token = jwt.encode(payload, private_key, algorithm="HS256") + return JsonResponse({ 'token': token }) + elif request.method == 'GET': + return JsonResponse(request.jwt_info) \ No newline at end of file diff --git a/project/api/views/persona.py b/project/api/views/persona.py new file mode 100644 index 0000000..bd1b498 --- /dev/null +++ b/project/api/views/persona.py @@ -0,0 +1,11 @@ +from rest_framework import viewsets, mixins +from rest_framework.response import Response +from .. import models, serializers +from django.http import HttpResponse + +class PersonaViewSet(viewsets.ModelViewSet): + queryset = models.Persona.objects.all() + serializer_class = serializers.PersonaSerializer + + def destroy(self, request, pk=None): + return HttpResponse('No permitido eliminar', status=405) \ No newline at end of file diff --git a/project/api/views/tipo.py b/project/api/views/tipo.py new file mode 100644 index 0000000..66812b0 --- /dev/null +++ b/project/api/views/tipo.py @@ -0,0 +1,23 @@ + +from rest_framework import viewsets +from .. import models, serializers + +class TipoTratamientoPersonaViewSet(viewsets.ModelViewSet): + queryset = models.TipoTratamientoPersona.objects.all() + serializer_class = serializers.TipoTratamientoPersonaSerializer + +class TipoDispositivoViewSet(viewsets.ModelViewSet): + queryset = models.TipoDispositivo.objects.all() + serializer_class = serializers.TipoDispositivoSerializer + +class TipoParaderoViewSet(viewsets.ModelViewSet): + queryset = models.TipoParadero.objects.all() + serializer_class = serializers.TipoParaderoSerializer + +class TipoTransporteViewSet(viewsets.ModelViewSet): + queryset = models.TipoTransporte.objects.all() + serializer_class = serializers.TipoTransporteSerializer + +class TipoVehiculoViewSet(viewsets.ModelViewSet): + queryset = models.TipoVehiculo.objects.all() + serializer_class = serializers.TipoVehiculoSerializer \ No newline at end of file diff --git a/project/api/views/usuario.py b/project/api/views/usuario.py new file mode 100644 index 0000000..9ee0922 --- /dev/null +++ b/project/api/views/usuario.py @@ -0,0 +1,80 @@ + +from django.db import transaction +from django.http import HttpResponse +from django.http import JsonResponse +from django.core.serializers import serialize + +from rest_framework import viewsets +from rest_framework.response import Response +from rest_framework.decorators import action, api_view, schema + +from .. import models, schemas, serializers +from ..validaciones import rut_valido +import json + +class UsuarioViewSet(viewsets.ModelViewSet): + queryset = models.Usuario.objects.all() + serializer_class = serializers.UsuarioSerializer + schema = schemas.UsuarioSchema() + + def create(self, request): + try: + with transaction.atomic(): + input = json.loads(request.body) + if not rut_valido(input['rut']): + raise ValueError(f"RUT [{input['rut']}] no valido!") + + num, dv = input['rut'].split('-') + + usuario = models.Usuario.objects.filter(login = input['login']).first() + if usuario: + raise ValueError(f"Usuario [{input['login']}] ya existe!") + + usuario = models.Usuario.objects.filter(rut = num).first() + if usuario: + raise ValueError(f"Usuario con RUT [{input['rut']}] ya existe!") + + persona = models.Persona.objects.filter(rut = num).first() + if not persona: + persona = models.Persona( + rut = num, + dv = dv, + nombres = input['nombres'], + apellido_a = input['apellido_a'], + apellido_b = input['apellido_b'], + email = input['email'], + ) + persona.save() + else: + persona.nombres = input['nombres'] + persona.apellido_a = input['apellido_a'] + persona.apellido_b = input['apellido_b'] + persona.email = input['email'] + persona.save() + + usuario = models.Usuario( + rut = persona, + login = input['login'], + clave = input['clave'], + vigente = input['vigente'], + ) + usuario.save() + + return Response({ + 'rut': f'{persona.rut}-{persona.dv}', + 'nombres': persona.nombres, + 'apellido_a': persona.apellido_a, + 'apellido_b': persona.apellido_b, + 'email': persona.email, + 'login': usuario.login, + 'vigente': usuario.vigente, + }) + + except ValueError as e: + transaction.rollback() + return HttpResponse(str(e), status = 400) + + except Exception as e: + transaction.rollback() + print(e) + return HttpResponse(str(e), status = 500) diff --git a/project/project/urls.py b/project/project/urls.py index 0ab8201..5837bc4 100644 --- a/project/project/urls.py +++ b/project/project/urls.py @@ -15,7 +15,7 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ -from django.contrib import admin +# from django.contrib import admin from django.urls import path, include from rest_framework.documentation import include_docs_urls from django.conf import settings @@ -27,8 +27,8 @@ urlpatterns = [ path('', frontend, name='home'), # BACKEND + # path('admin/', admin.site.urls), path('api/', include('api.urls')), - path('admin/', admin.site.urls), path('docs/', include_docs_urls(title = 'API Documentation')), ]