Skip to content

Commit

Permalink
Merge pull request #9 from pax-app/devel
Browse files Browse the repository at this point in the history
First Stable Release
  • Loading branch information
lucasdutraf authored Nov 18, 2019
2 parents 21b7f95 + da77938 commit 7db5e33
Show file tree
Hide file tree
Showing 18 changed files with 550 additions and 15 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
env
.dockerignore
Dockerfile-dev
Dockerfile-prod
18 changes: 18 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Descrição
Breve descrição das atividades realizadas para conclusão da issue e outros pontos relevantes.

# Issue Relacionada

<!---Linkar todas as issues envolvidas no PR seguindo a estrutura resolve #1, pois quando o PR é aceito todas as issues são fechadas--->
resolve pax-app/Wiki#

# Tipo de Mudanças

- [ ] História de Usuário
- [ ] Historia Técnica
- [ ] Wiki

# Responsáveis pela revisão

@esiofreitas (PO) | @lucasdutraf (PO)
@(Membro do time de desenvolvimento que não esteja envolvido do PR)
23 changes: 23 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
sudo: required
language: python
python: 3.8
services:
- docker

before_install:
# install heroku CLI
- wget -qO- https://toolbelt.heroku.com/install.sh | sh
# login to docker registries on heroku
- heroku container:login

script:
# building docker image
- heroku container:push web --app $HEROKU_APPNAME

deploy:
provider: script
script:
# releasing image
heroku container:release web --app $HEROKU_APPNAME
on:
branch: devel
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# base image
FROM python:3.6.5-alpine
FROM python:3.8.0-alpine


# set working directory
Expand All @@ -10,6 +10,8 @@ RUN apk update && \
apk add --virtual build-deps gcc python-dev musl-dev

# Dealing with requirements
RUN pip install --upgrade pip
RUN pip install Flask-SQLAlchemy
COPY ./requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt

Expand All @@ -19,4 +21,4 @@ COPY . /app


# run server
CMD python manage.py run -h 0.0.0.0
CMD ["gunicorn","project:create_app()"]
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
# Pax_Pax
# Pax
[![Maintainability](https://api.codeclimate.com/v1/badges/337ba69b4fe369201c75/maintainability)](https://codeclimate.com/github/pax-app/Pax/maintainability)


Microsserviço responsável pelos contratos cliente-prestador.

## Colocando no ar

Com o Docker e Docker-Compose instalados, basta apenas utilizar os comandos:

```shell
sudo docker-compose up
```
23 changes: 23 additions & 0 deletions database_singleton.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from __future__ import annotations
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from typing import Optional


class SingletonMeta(type):
_instance: Optional[Singleton] = None

def __call__(self) -> Singleton:
if self._instance is None:
self._instance = super().__call__()
return self._instance


class Singleton(metaclass=SingletonMeta):
def database_connection(self):
db = SQLAlchemy()
return db

def migration(self):
migrate = Migrate()
return migrate
5 changes: 5 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ services:
- 5003:5000
environment:
- FLASK_APP=project/__init__.py
- FLASK_ENV=development
- APP_SETTINGS=project.config.DevelopmentConfig
- DATABASE_URL=mysql+pymysql://paxadmin:LpvuM1QnfcxOOVeNQQvl@pax-database.cd0j8avv0tgq.sa-east-1.rds.amazonaws.com:3306/paxdb
- DATABASE_TEST_URL=mysql+pymysql://username:password@localhost:3306/pax
command: python manage.py run -h 0.0.0.0
1 change: 1 addition & 0 deletions manage.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from project import create_app
from flask.cli import FlaskGroup
from flask import current_app

# Config coverage report
app = create_app()
Expand Down
9 changes: 8 additions & 1 deletion project/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
from flask import Flask, jsonify
from project.api.views import pax_blueprint
from database_singleton import Singleton


# instantiate the app
Expand All @@ -12,7 +13,13 @@ def create_app(script_info=None):
app_settings = os.getenv('APP_SETTINGS')
app.config.from_object(app_settings)

db = Singleton().database_connection()
migrate = Singleton().migration()

db.init_app(app)
migrate.init_app(app, db)

# register blueprints
app.register_blueprint(pax_blueprint)
app.register_blueprint(pax_blueprint, url_prefix='/pax')

return app
46 changes: 46 additions & 0 deletions project/api/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from database_singleton import Singleton

db = Singleton().database_connection()


class Pax(db.Model):
__tablename__ = 'PAX'

pax_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
date = db.Column(db.Date, nullable=False)
description = db.Column(db.String(500), nullable=False)
name = db.Column(db.String(255), nullable=False)
price = db.Column(db.Float, nullable=False)
status = db.Column(db.Enum('F', 'P', 'C', 'I'), nullable=True)
user_id = db.Column(db.Integer, nullable=False)
provider_id = db.Column(db.Integer, nullable=False)
chat_id = db.Column(db.Integer, nullable=False)
address_id = db.Column(db.Integer, nullable=False)
canceled_motive = db.Column(db.String(500), nullable=True)

def __init__(self, date, description, name, price, status, user_id, provider_id, chat_id, address_id, canceled_motive):
self.date = date
self.description = description
self.name = name
self.price = price
self.status = status
self.user_id = user_id
self.provider_id = provider_id
self.chat_id = chat_id
self.address_id = address_id
self.canceled_motive = canceled_motive

def to_json(self):
return {
'pax_id': self.pax_id,
'date': self.date.isoformat(),
'description': self.description,
'name': self.name,
'price': self.price,
'status': self.status,
'user_id': self.user_id,
'provider_id': self.provider_id,
'chat_id': self.chat_id,
'address_id': self.address_id,
'canceled_motive': self.canceled_motive,
}
24 changes: 24 additions & 0 deletions project/api/utils/chain_of_responsibility/chain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from project.api.utils.chain_of_responsibility.handlers import CreateHandler, UpdateHandler, UpdateStatusHandler, ErrorHandler


class UpCreate():
_create = CreateHandler()
_update = UpdateHandler()
_error = ErrorHandler()

def __init__(self):
self._create.set_next(self._update).set_next(self._error)

def execute(self, request, row):
return self._create.handle(request, row)


class UpdateStatus():
_update = UpdateStatusHandler()
_error = ErrorHandler()

def __init__(self):
self._update.set_next(self._error)

def execute(self, request, row):
return self._update.handle(request, row)
27 changes: 27 additions & 0 deletions project/api/utils/chain_of_responsibility/definitions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from __future__ import annotations
from abc import ABC, abstractmethod


class Handler(ABC):

@abstractmethod
def set_next(self, handler: Handler) -> Handler:
pass

def handle(self, request, row):
pass


class AbstractHandler(Handler):

_next_handler: Handler = None

def set_next(self, handler: Handler) -> Handler:
self._next_handler = handler
return handler

def handle(self, request, row):
if self._next_handler:
return self._next_handler.handle(request, row)

return None
71 changes: 71 additions & 0 deletions project/api/utils/chain_of_responsibility/handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from project.api.utils.chain_of_responsibility.definitions import AbstractHandler
from project.api.utils.creation_utils import Utils
from database_singleton import Singleton
from project.api.models import Pax
from flask import jsonify

db = Singleton().database_connection()
utils = Utils()


class CreateHandler(AbstractHandler):
def handle(self, request, row):
if not row:
pax = request.get_json()

date = pax.get('date')
description = pax.get('description')
name = pax.get('name')
price = pax.get('price')
user_id = pax.get('user_id')
provider_id = pax.get('provider_id')
chat_id = pax.get('chat_id')
address_id = pax.get('address_id')
canceled_motive = pax.get('canceled_motive')

pax = Pax(date, description, name,
price, '', user_id, provider_id, chat_id, address_id, canceled_motive)
utils.commit_to_database('A', pax)
return jsonify(utils.createSuccessMessage('Pax was created!')), 201

else:
return super().handle(request, row)


class UpdateHandler(AbstractHandler):
def handle(self, request, row):
try:
pax = request.get_json()

row.date = pax.get('date')
row.description = pax.get('description')
row.name = pax.get('name')
row.price = pax.get('price')
row.address_id = pax.get('address_id')

utils.commit_to_database('M', row)
return jsonify(utils.createSuccessMessage('Pax was updated!')), 201

except:
return super().handle(request, row)


class UpdateStatusHandler(AbstractHandler):
def handle(self, request, row):
try:
body = request.get_json()

status = body.get('status')

row.status = status

utils.commit_to_database('M', row)
return jsonify(utils.createSuccessMessage('Pax state was updated!')), 201
except:
return super().handle(request, row)


class ErrorHandler(AbstractHandler):
def handle(self, request, row):
db.session.rollback()
return jsonify(utils.createFailMessage('Wrong JSON')), 400
68 changes: 68 additions & 0 deletions project/api/utils/creation_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from database_singleton import Singleton
from flask import request, jsonify
from project.api.models import Pax
from operator import itemgetter

db = Singleton().database_connection()


class Utils:
def createFailMessage(self, message):
response_object = {
'status': 'fail',
'message': '{}'.format(message)
}
return response_object

def createSuccessMessage(self, message):
response_object = {
'status': 'success',
'message': '{}'.format(message)
}
return response_object

def createSuccessGet(self, content):
response_object = {
'status': 'success',
'data': {
'pax': [pax.to_json() for pax in content]
}
}
return response_object

def commit_to_database(self, type, model):
if (type == 'A'):
db.session.add(model)
elif (type == 'M'):
db.session.merge(model)

db.session.flush()
db.session.commit()

def filter_by_status(self, value, user_type, id):
if user_type == 'provider':
pax = Pax.query.filter_by(
status=value, provider_id=int(id)).all()
elif user_type == 'user':
pax = Pax.query.filter_by(
status=value, user_id=int(id)).all()
return pax

def sqlalchemyobj_to_list(self, data):
final_list = []
for item in data:
final_list.append(item.to_json())
return final_list

def ignore_empty_status(self, data) -> list:
query = self.sqlalchemyobj_to_list(data)
filtered_pax = []
for pax in query:
if pax['status'] != '':
filtered_pax.append(pax)
return filtered_pax


def reverse_alphabetical_order(self, data: list) -> list:
reverse_alphabetical_pax = sorted(data, key=itemgetter('status'), reverse=True)
return reverse_alphabetical_pax
Loading

0 comments on commit 7db5e33

Please sign in to comment.