Skip to content

Commit

Permalink
Merge pull request #2 from diverso-lab/refactoring
Browse files Browse the repository at this point in the history
Refactoring
  • Loading branch information
drorganvidez authored Mar 21, 2024
2 parents e84b3b6 + 7230916 commit b3b7331
Show file tree
Hide file tree
Showing 44 changed files with 301 additions and 188 deletions.
23 changes: 14 additions & 9 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
# Use an official Python runtime as a parent image
FROM python:3.11-alpine

# Set the working directory in the container to /app
# Instala el cliente de MySQL para poder usarlo en el script de espera
RUN apk add --no-cache mysql-client

# Establece el directorio de trabajo en el contenedor en /app
WORKDIR /app

# Copy the contents of the local app/ directory to the /app directory in the container
# Copia el contenido del directorio local app/ al directorio /app en el contenedor
COPY app/ ./app

# Copy requirements.txt at the /app working directory
# Copia requirements.txt en el directorio de trabajo /app
COPY requirements.txt .

# Install any needed packages specified in requirements.txt
# Copia el script wait-for-db.sh y establece los permisos de ejecución
COPY --chmod=+x scripts/wait-for-db.sh ./scripts/

# Instala los paquetes necesarios especificados en requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Update pip
# Actualiza pip
RUN pip install --no-cache-dir --upgrade pip

# Expose port 5000
# Expone el puerto 5000
EXPOSE 5000

# Run the application
CMD flask db upgrade && flask run --host=0.0.0.0 --port=5000 --reload --debug

# Ajusta el comando CMD para ejecutar correctamente el script wait-for-db.sh
CMD sh ./scripts/wait-for-db.sh && flask db upgrade && flask run --host=0.0.0.0 --port=5000 --reload --debug
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ Create an `.env` file in the root of the project with this information. It is im

```
FLASK_APP_NAME=UVLHUB.IO
MYSQL_HOSTNAME=db
MYSQL_DATABASE=uvlhubdb
MYSQL_USER=uvlhubuser
MYSQL_PASSWORD=uvlhubpass
MYSQL_ROOT_PASSWORD=uvlhubrootpass
MARIADB_HOSTNAME=db
MARIADB_PORT=3306
MARIADB_DATABASE=uvlhubdb
MARIADB_USER=uvlhubuser
MARIADB_PASSWORD=uvlhubpass
MARIADB_ROOT_PASSWORD=uvlhubrootpass
ZENODO_ACCESS_TOKEN=<GET_ACCESS_TOKEN_IN_ZENODO>
```

Expand Down
67 changes: 43 additions & 24 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import os
import secrets
import logging
import importlib.util

from flask import Flask, render_template
from flask import Flask, render_template, Blueprint, flash, redirect, url_for
from flask_login import current_user
from flask_sqlalchemy import SQLAlchemy
from dotenv import load_dotenv
from flask_migrate import Migrate
from flask_wtf import CSRFProtect

# Load environment variables
load_dotenv()
Expand All @@ -23,8 +23,11 @@ def create_app(config_name=None):

# Database configuration
app.config['SQLALCHEMY_DATABASE_URI'] = (
f"mysql+pymysql://{os.getenv('MYSQL_USER', 'default_user')}:{os.getenv('MYSQL_PASSWORD', 'default_password')}"
f"@{os.getenv('MYSQL_HOSTNAME', 'localhost')}:3306/{os.getenv('MYSQL_DATABASE', 'default_db')}"
f"mysql+pymysql://{os.getenv('MARIADB_USER', 'default_user')}:"
f"{os.getenv('MARIADB_PASSWORD', 'default_password')}@"
f"{os.getenv('MARIADB_HOSTNAME', 'localhost')}:"
f"{os.getenv('MARIADB_PORT', '3306')}/"
f"{os.getenv('MARIADB_DATABASE', 'default_db')}"
)

# Timezone
Expand All @@ -40,23 +43,9 @@ def create_app(config_name=None):
db.init_app(app)
migrate.init_app(app, db)

# Import blueprints
from app.tests.routes import test_routes
from .auth import auth_bp
from .dataset import dataset_bp
from .explore import explore_bp
from .profile import profile_bp
from .team import team_bp
from .public import public_bp

# Register blueprints
app.register_blueprint(test_routes)
app.register_blueprint(auth_bp)
app.register_blueprint(dataset_bp)
app.register_blueprint(explore_bp)
app.register_blueprint(profile_bp)
app.register_blueprint(team_bp)
app.register_blueprint(public_bp)
register_blueprints(app)
print_registered_blueprints(app)

from flask_login import LoginManager
login_manager = LoginManager()
Expand All @@ -65,7 +54,7 @@ def create_app(config_name=None):

@login_manager.user_loader
def load_user(user_id):
from app.auth.models import User
from app.blueprints.auth.models import User
return User.query.get(int(user_id))

# Logging
Expand Down Expand Up @@ -119,7 +108,7 @@ def upload_folder_name():

def get_user_by_token(token):
# TODO
from app.auth.models import User
from app.blueprints.auth.models import User
return User.query.first()


Expand All @@ -129,16 +118,46 @@ def get_authenticated_user_profile():
return None


def get_authenticated_user():
if current_user.is_authenticated:
return current_user
return None


def datasets_counter() -> int:
from app.dataset.models import DataSet
from app.blueprints.dataset.models import DataSet
count = DataSet.query.count()
return count


def feature_models_counter() -> int:
from app.dataset.models import FeatureModel
from app.blueprints.dataset.models import FeatureModel
count = FeatureModel.query.count()
return count


def register_blueprints(app):
app.blueprint_url_prefixes = {}
base_dir = os.path.abspath(os.path.dirname(__file__))
blueprints_dir = os.path.join(base_dir, 'blueprints')
for blueprint_name in os.listdir(blueprints_dir):
blueprint_path = os.path.join(blueprints_dir, blueprint_name)
if os.path.isdir(blueprint_path) and not blueprint_name.startswith('__'):
try:
routes_module = importlib.import_module(f'app.blueprints.{blueprint_name}.routes')
for item in dir(routes_module):
if isinstance(getattr(routes_module, item), Blueprint):
blueprint = getattr(routes_module, item)
app.register_blueprint(blueprint)
except ModuleNotFoundError as e:
print(f"Could not load the module for Blueprint '{blueprint_name}': {e}")


def print_registered_blueprints(app):
print("Registered blueprints")
for name, blueprint in app.blueprints.items():
url_prefix = app.blueprint_url_prefixes.get(name, 'No URL prefix set')
print(f"Name: {name}, URL prefix: {url_prefix}")


app = create_app()
Empty file added app/blueprints/__init__.py
Empty file.
1 change: 0 additions & 1 deletion app/auth/__init__.py → app/blueprints/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@

auth_bp = Blueprint('auth', __name__, template_folder='templates')

from . import routes
File renamed without changes.
2 changes: 1 addition & 1 deletion app/auth/models.py → app/blueprints/auth/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)

email = db.Column(db.String(256), unique=True, nullable=False)
password = db.Column(db.String(128), nullable=False)
password = db.Column(db.String(256), nullable=False)
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)

data_sets = db.relationship('DataSet', backref='user', lazy=True)
Expand Down
13 changes: 7 additions & 6 deletions app/auth/routes.py → app/blueprints/auth/routes.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from flask import (render_template, redirect, url_for,
request, current_app)
from flask import (render_template, redirect, url_for)
from flask_login import current_user, login_user, logout_user

from . import auth_bp
from .forms import SignupForm, LoginForm
from .models import User
from ..profile.models import UserProfile
from app.blueprints.auth import auth_bp
from app.blueprints.auth.forms import SignupForm, LoginForm

from app.blueprints.profile.models import UserProfile


@auth_bp.route("/signup/", methods=["GET", "POST"])
Expand All @@ -20,6 +19,7 @@ def show_signup_form():
email = form.email.data
password = form.password.data

from app.blueprints.auth.models import User
user = User.get_by_email(email)
if user is not None:
error = f'Email {email} in use'
Expand All @@ -46,6 +46,7 @@ def login():
return redirect(url_for('public.index'))
form = LoginForm()
if form.validate_on_submit():
from app.blueprints.auth.models import User
user = User.get_by_email(form.email.data)

if user is not None and user.check_password(form.password.data):
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from flask import Blueprint

dataset_bp = Blueprint('dataset', __name__, template_folder='templates')

from . import routes
3 changes: 1 addition & 2 deletions app/dataset/forms.py → app/blueprints/dataset/forms.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from flask_wtf import FlaskForm
from wtforms import StringField, SelectField, FieldList, FormField, SubmitField, TextAreaField
from wtforms.validators import DataRequired, URL, Optional
from enum import Enum

from .models import PublicationType
from app.blueprints.dataset.models import PublicationType


class AuthorForm(FlaskForm):
Expand Down
1 change: 0 additions & 1 deletion app/dataset/models.py → app/blueprints/dataset/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,6 @@ def __repr__(self):
return f'<FileDownload id={self.id} file_id={self.file_id} date={self.download_date} cookie={self.download_cookie}>'



def get_human_readable_size(size):
if size < 1024:
return f'{size} bytes'
Expand Down
19 changes: 7 additions & 12 deletions app/dataset/routes.py → app/blueprints/dataset/routes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import io
import logging
import os
import json
Expand All @@ -11,19 +10,16 @@
from typing import List
from zipfile import ZipFile

from flask import flash, redirect, render_template, url_for, request, jsonify, send_file, send_from_directory, abort, \
current_app, make_response
from flask import render_template, request, jsonify, send_from_directory, current_app, make_response
from flask_login import login_required, current_user
from werkzeug.utils import secure_filename

import app
from .forms import DataSetForm
from .models import DataSet, DSMetrics, FeatureModel, File, FMMetaData, FMMetrics, DSMetaData, Author, PublicationType, \
DSDownloadRecord, DSViewRecord, FileDownloadRecord
from . import dataset_bp
from ..auth.models import User
from ..flama import flamapy_valid_model
from ..zenodo import zenodo_create_new_deposition, test_zenodo_connection, zenodo_upload_file, \
from app.blueprints.dataset.forms import DataSetForm
from app.blueprints.dataset.models import DataSet, FeatureModel, File, FMMetaData, DSMetaData, Author, \
PublicationType, DSDownloadRecord, DSViewRecord, FileDownloadRecord
from app.blueprints.dataset import dataset_bp
from app.blueprints.auth.models import User
from app.zenodo import zenodo_create_new_deposition, zenodo_upload_file, \
zenodo_publish_deposition, zenodo_get_doi, test_full_zenodo_connection


Expand Down Expand Up @@ -542,7 +538,6 @@ def api_create_dataset():
# iterate for each feature model (one feature model = one request to Zenodo
try:
for feature_model in feature_models:

zenodo_upload_file(deposition_id, feature_model, user=user)

# Wait for 0.6 seconds before the next API call to ensure we do not exceed
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from flask import Blueprint

explore_bp = Blueprint('explore', __name__, template_folder='templates')

from . import routes
File renamed without changes.
10 changes: 5 additions & 5 deletions app/explore/routes.py → app/blueprints/explore/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import unidecode

from flask import render_template, request, abort, jsonify
from sqlalchemy import or_, desc, asc, any_
from flask import render_template, request, jsonify
from sqlalchemy import or_, any_

from . import explore_bp
from .forms import ExploreForm
from ..dataset.models import DataSet, DSMetaData, Author, FeatureModel, FMMetaData, PublicationType
from app.blueprints.explore import explore_bp
from app.blueprints.explore.forms import ExploreForm
from app.blueprints.dataset.models import DataSet, DSMetaData, Author, FeatureModel, FMMetaData, PublicationType


@explore_bp.route('/explore', methods=['GET', 'POST'])
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from flask import Blueprint

profile_bp = Blueprint('profile', __name__, template_folder='templates')

from . import routes
File renamed without changes.
2 changes: 1 addition & 1 deletion app/profile/models.py → app/blueprints/profile/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ class UserProfile(db.Model):
def save(self):
if not self.id:
db.session.add(self)
db.session.commit()
db.session.commit()
7 changes: 7 additions & 0 deletions app/blueprints/profile/repositories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from app.blueprints.profile.models import UserProfile
from app.repositories.BaseRepository import BaseRepository


class UserProfileRepository(BaseRepository):
def __init__(self):
super().__init__(UserProfile)
22 changes: 22 additions & 0 deletions app/blueprints/profile/routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from flask import request, render_template, flash, redirect, url_for, current_app
from flask_login import login_required

from app.blueprints.profile import profile_bp
from app.blueprints.profile.forms import UserProfileForm

from app import get_authenticated_user_profile
from app.blueprints.profile.services import UserProfileService


@profile_bp.route('/profile/edit', methods=['GET', 'POST'])
@login_required
def edit_profile():
form = UserProfileForm()
if request.method == 'POST':

service = UserProfileService()
result, errors = service.update_profile(get_authenticated_user_profile().id, form)
return service.handle_service_response(result, errors, 'profile.edit_profile', 'Profile updated successfully',
'profile/edit.html', form)

return render_template('profile/edit.html', form=form)
16 changes: 16 additions & 0 deletions app/blueprints/profile/services.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from app.blueprints.profile.repositories import UserProfileRepository
from app.services.BaseService import BaseService

from flask import current_app


class UserProfileService(BaseService):
def __init__(self):
super().__init__(UserProfileRepository())

def update_profile(self, user_profile_id, form):
if form.validate():
updated_instance = self.update(user_profile_id, **form.data)
return updated_instance, None
else:
return None, form.errors
Loading

0 comments on commit b3b7331

Please sign in to comment.