Partial correction of persistence

This commit is contained in:
Guille Gutierrez 2023-01-31 13:11:39 -05:00
parent 10623cc466
commit 5978757348
19 changed files with 342 additions and 310 deletions

View File

@ -74,7 +74,7 @@ from hub.persistence import DBSetup
from pathlib import Path
dotenv_path = (Path(__file__).parent / '.env').resolve()
DBSetup(db_name='hub_db', app_env='PROD', dotenv_path=dotenv_path)
DBSetup(db_name='hub_db', app_env='PROD', dotenv_path=dotenv_path, admin_password="your password here", application_uuid="your admin application uuid")
```
The *DBSetUp* class also creates a default admin user with default credentials that can be changed.
with the import UserFactory class. The admin user (name, email, password and role) is logged into the console after it is created by the

View File

@ -34,7 +34,7 @@ class Building(CityObject):
self._roof_type = None
self._internal_zones = None
self._shell = None
self._human_readable_name = None
self._alias = None
self._type = 'building'
self._heating = dict()
self._cooling = dict()
@ -404,16 +404,16 @@ class Building(CityObject):
return False
@property
def human_readable_name(self):
def alias(self):
"""
Get the human-readable name for the building
Get the alias name for the building
:return: str
"""
return self._human_readable_name
return self._alias
@human_readable_name.setter
def human_readable_name(self, value):
@alias.setter
def alias(self, value):
"""
Set the human-readable name for the building
Set the alias name for the building
"""
self._human_readable_name = value
self._alias = value

View File

@ -11,20 +11,6 @@ import re
class Auth(object):
@staticmethod
def validate_password(password: str) -> bool:
"""
Validates a password
:param password: the password to validate
:return:
"""
pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!#%*?&]{6,20}$"
pattern = re.compile(pattern)
if not re.search(pattern, password):
raise ValueError("Password must be between 6 to 20 characters and must have at least a number, an uppercase "
"letter, a lowercase letter, and a special character")
return True
@staticmethod
def hash_password(password: str) -> str:
"""

View File

@ -7,14 +7,15 @@ from hub.persistence.models import UserRoles
from hub.persistence.models import Application
from hub.persistence.models import UserApplications
from hub.persistence.repositories import UserRepo
from hub.persistence.repositories import ApplicationRepo
from hub.hub_logger import logger
class DBSetup:
def __init__(self, db_name, app_env, dotenv_path):
def __init__(self, db_name, app_env, dotenv_path, admin_password, application_uuid):
"""
Creates database tables and a default admin user
Creates database tables a default admin user and a default admin app with the given password and uuid
:param db_name:
:param app_env:
:param dotenv_path:
@ -26,17 +27,30 @@ class DBSetup:
UserApplications.__table__.create(bind=repo.engine, checkfirst=True)
HeatPumpSimulation.__table__.create(bind=repo.engine, checkfirst=True)
self._user_repo = UserRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
self._create_admin_user(self._user_repo)
self._application_repo = ApplicationRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
self._create_admin_user(self._user_repo, admin_password)
self._create_admin_app(self._application_repo, application_uuid)
@staticmethod
def _create_admin_user(user_repo):
email = 'admin@hub.com'
password = 'HubAdmin#!98'
def _create_admin_app(application_repo, application_uuid):
name = 'AdminTool'
description = 'Admin tool to control city persistence and to test the API v1.4'
print('Creating default admin tool application...')
application = application_repo.insert(name, description, application_uuid)
if type(application) is dict:
logger.info(application)
else:
msg = f'Created Admin tool with application_uuid: {application_uuid}'
print(msg)
logger.info(msg)
@staticmethod
def _create_admin_user(user_repo, admin_password, application_id):
password = admin_password
print('Creating default admin user...')
user = user_repo.insert('Administrator', email, password, UserRoles.Admin)
user = user_repo.insert('Administrator', password, UserRoles.Admin, application_id)
if type(user) is dict:
logger.info(user)
else:
print(f'Created Admin user with email: {email}, password: {password} and role: {UserRoles.Admin.value}')
logger.info(f'Created Admin user with email: {email}, password: {password} and role: {UserRoles.Admin.value}')
print('Remember to change the admin default password and email address with the UserFactory')
print(f'Created Admin user')
logger.info(f'Created Admin user')

View File

@ -5,3 +5,4 @@ from .heat_pump_simulation import HeatPumpTypes
from .user import User, UserRoles
from .user_applications import UserApplications
from .application import Application
from .city_object import CityObject

View File

@ -7,6 +7,7 @@ Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
import datetime
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import Column, Integer, String, Sequence
from sqlalchemy import DateTime
@ -21,9 +22,11 @@ class Application(Base):
id = Column(Integer, Sequence('application_id_seq'), primary_key=True)
name = Column(String, nullable=False)
description = Column(String, nullable=False)
application_uuid = Column(UUID(as_uuid=True), nullable=False)
created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow)
def __init__(self, name, description):
def __init__(self, name, description, application_uuid):
self.name = name
self.description = description
self.application_uuid = application_uuid

View File

@ -5,13 +5,12 @@ Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com
"""
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey
from sqlalchemy import DateTime, PickleType, Float
from hub.persistence.db_config import Base
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import relationship
import datetime
import numpy as np
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey
from sqlalchemy import DateTime, PickleType
from hub.persistence.db_config import Base
class City(Base):
@ -21,28 +20,19 @@ class City(Base):
id = Column(Integer, Sequence('city_id_seq'), primary_key=True)
city = Column(PickleType, nullable=False)
name = Column(String, nullable=False)
srs_name = Column(String, nullable=False)
climate_reference_city = Column(String, nullable=True)
time_zone = Column(String, nullable=True)
country_code = Column(String, nullable=False)
latitude = Column(Float)
longitude = Column(Float)
lower_corner = Column(JSONB, nullable=False)
upper_corner = Column(JSONB, nullable=False)
level_of_detail = Column(Integer, nullable=False)
climate_file = Column(String, nullable=False)
application_id = Column(Integer, ForeignKey('application.id'), nullable=False)
user_id = Column(Integer, ForeignKey('user.id'), nullable=True)
hub_release = Column(String, nullable=False)
city_version = Column(Integer, nullable=False)
user_id = Column(Integer, ForeignKey('user.id'))
user = relationship("User", back_populates="cities")
created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow)
def __init__(self, city, name, srs_name, country_code, l_corner, u_corner, user_id):
def __init__(self, city, name, level_of_detail, climate_file, application_id, user_id, hub_release):
self.city = city
self.user_id = user_id
self.name = name
self.srs_name = srs_name
self.country_code = country_code
l_corner = l_corner.tolist() if type(l_corner) == np.ndarray else l_corner
u_corner = u_corner.tolist() if type(u_corner) == np.ndarray else u_corner
self.lower_corner = l_corner
self.upper_corner = u_corner
self.level_of_detail = level_of_detail
self.climate_file = climate_file
self.application_id = application_id
self.user_id = user_id
self.hub_release = hub_release

View File

@ -0,0 +1,44 @@
"""
Model representation of a city object
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import datetime
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey, Float
from sqlalchemy import DateTime
from hub.persistence.db_config import Base
class CityObject(Base):
"""
A model representation of an application
"""
__tablename__ = "city_object"
id = Column(Integer, Sequence('application_id_seq'), primary_key=True)
city_id = Column(Integer, ForeignKey('city.id'), nullable=False)
name = Column(String, nullable=False)
alias = Column(String, nullable=True)
type = Column(String, nullable=False)
year_of_construction = Column(Integer, nullable=True)
function = Column(String, nullable=True)
usage = Column(String, nullable=True)
volume = Column(Float, nullable=False)
area = Column(Float, nullable=False)
created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow)
def __init__(self, city_id, name, alias, object_type, year_of_construction, function, usage, volume, area):
self.city_id = city_id
self.name = name
self.alias = alias
self.type = object_type
self.year_of_construction = year_of_construction
self.function = function
self.usage = usage
self.volume = volume
self.area = area

View File

@ -1,83 +0,0 @@
"""
Model representation of the results of heat pump simulation
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com
"""
from sqlalchemy import Column, Integer, String, Sequence
from sqlalchemy import Enum, ForeignKey, Float, DateTime
from sqlalchemy.dialects.postgresql import JSONB
from hub.persistence.db_config import Base
import enum
import datetime
class SimulationTypes(enum.Enum):
Parallel = 'PARALLEL'
Series = 'SERIES'
class HeatPumpTypes(enum.Enum):
Air = 'Air Source'
Water = 'Water to Water'
class HeatPumpSimulation(Base):
"""A model representation of a building
Attributes:
city_id, A reference to the city which was used to run this simulation.
hourly_electricity_demand, A JSON object that has hours and their electricity demand
daily_electricity_demand, A JSON object that has days and their electricity demand
monthly_electricity_demand, A JSON object that has months and their electricity demand
daily_fossil_fuel_consumption, A JSON object that has days and fossil fuel consumption
monthly_fossil_fuel_consumption, A JSON object that has months and fossil fuel consumption
heat_pump_type, Water or air heat pump
simulation_type, The type of heat pump simulation (parallel or series)
heat_pump_model, The model of the heat pump (either water to water or air source)
start year, HP simulation start year
end year, HP simulation end year
max_hp_energy_input, Maximum heat pump energy input
max_demand_storage_hour, Hours of storage at maximum demand
building_supply_temp, building supply temperature
temp_difference, Difference in HP and building supply temperatures
fuel_lhv, The lower heating value of fuel
fuel_price, The price of fuel
fuel_efficiency, the efficiency of fuel
fuel_density, the density of fuel
hp_supply_temp, supply temperature of heat pump
"""
__tablename__ = "heat_pump_simulation"
id = Column(Integer, Sequence('hp_simulation_id_seq'), primary_key=True)
city_id = Column(Integer, ForeignKey('city.id'), nullable=False)
daily_electricity_demand = Column(JSONB, nullable=False)
hourly_electricity_demand = Column(JSONB, nullable=False)
daily_fossil_fuel_consumption = Column(JSONB, nullable=False)
monthly_fossil_fuel_consumption = Column(JSONB, nullable=False)
monthly_electricity_demand = Column(JSONB, nullable=False)
heat_pump_type = Column(Enum(HeatPumpTypes), nullable=False)
simulation_type = Column(Enum(SimulationTypes), nullable=False)
heat_pump_model = Column(String, nullable=False)
start_year = Column(Integer, nullable=False)
end_year = Column(Integer, nullable=False)
max_hp_energy_input = Column(Float, nullable=False)
max_demand_storage_hour = Column(Float, nullable=False)
building_supply_temp = Column(Float, nullable=False)
temp_difference = Column(Float, nullable=False)
fuel_lhv = Column(Float, nullable=False)
fuel_price = Column(Float, nullable=False)
fuel_efficiency = Column(Float, nullable=False)
fuel_density = Column(Float, nullable=False)
hp_supply_temp = Column(Float, nullable=False)
created = Column(DateTime, default=datetime.datetime.utcnow)
def __init__(self, city_id, hourly_elec_demand, daily_elec_demand, monthly_elec_demand, daily_fossil, monthly_fossil):
self.city_id = city_id
self.hourly_electricity_demand = hourly_elec_demand
self.daily_electricity_demand = daily_elec_demand
self.monthly_electricity_demand = monthly_elec_demand
self.daily_fossil_fuel_consumption = daily_fossil
self.monthly_fossil_fuel_consumption = monthly_fossil

View File

@ -0,0 +1,34 @@
"""
Model representation of simulation results
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import datetime
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey, Float
from sqlalchemy import DateTime
from sqlalchemy.dialects.postgresql import JSONB
from hub.persistence.db_config import Base
class CityObject(Base):
"""
A model representation of an application
"""
__tablename__ = "simulation_results"
id = Column(Integer, Sequence('application_id_seq'), primary_key=True)
city_id = Column(Integer, ForeignKey('city.id'), nullable=True)
city_object_id = Column(Integer, ForeignKey('city_object.id'), nullable=True)
name = Column(String, nullable=False)
values = Column(JSONB, nullable=False)
created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow)
def __init__(self, name, values, city_id=None, city_object_id=None):
self.name = name
self.values = values
self.city_id = city_id
self.city_object_id = city_object_id

View File

@ -26,22 +26,14 @@ class User(Base):
__tablename__ = "user"
id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
name = Column(String, nullable=False)
email = Column(String, nullable=False, unique=True)
password = Column(String, nullable=False)
role = Column(Enum(UserRoles), nullable=False, default=UserRoles.Hub_Reader)
cities = relationship("City", back_populates="user")
application_id = Column(Integer, nullable=False)
created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow)
@validates("email")
def validate_email(self, key, address):
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
if not re.match(pattern, address):
raise ValueError("failed simple email validation")
return address
def __init__(self, name, email, password, role):
def __init__(self, name, password, role, application_id):
self.name = name
self.email = email
self.password = password
self.role = role
self.application_id = application_id

View File

@ -1,30 +0,0 @@
"""
Model representation of the user applications
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import datetime
from sqlalchemy import Column, Integer, ForeignKey, PrimaryKeyConstraint
from sqlalchemy import DateTime
from hub.persistence.db_config import Base
class UserApplications(Base):
"""
A model representation of the user applications
"""
__tablename__ = "user_applications"
user_id = Column(Integer, ForeignKey('user.id'))
application_id = Column(Integer, ForeignKey('application.id'))
created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow)
__table_args__ = (PrimaryKeyConstraint(user_id, application_id),)
def __init__(self, user_id, application_id):
self.user_id = user_id
self.application_id = application_id

View File

@ -1 +1,2 @@
from .user_repo import UserRepo
from .application_repo import ApplicationRepo

View File

@ -0,0 +1,84 @@
"""
Application repository with database CRUD operations
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import datetime
from typing import Union, Dict
from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from hub.hub_logger import logger
from hub.persistence import BaseRepo
from hub.persistence.models import Application
class ApplicationRepo(BaseRepo):
_instance = None
def __init__(self, db_name: str, dotenv_path: str, app_env: str):
super().__init__(db_name, dotenv_path, app_env)
def __new__(cls, db_name, dotenv_path, app_env):
"""
Implemented for a singleton pattern
"""
if cls._instance is None:
cls._instance = super(ApplicationRepo, cls).__new__(cls)
return cls._instance
def insert(self, name: str, description: str, application_uuid: str) -> Union[Application, Dict]:
application = self.get_by_uuid(application_uuid)
if application is None:
try:
application = Application(name=name, description=description, application_uuid=application_uuid)
self.session.add(application)
self.session.flush()
self.session.commit()
return application
except SQLAlchemyError as err:
logger.error(f'An error occurred while creating application: {err}')
else:
return {'message': f'An application with {application_uuid} application uuid, already exists'}
def update(self, application_uuid: str, name: str, description: str) -> Union[Dict, None]:
"""
Updates an application
:param application_uuid: the application uuid of the application to be updated
:param name: the application name
:param description: the application description
:return:
"""
try:
self.session.query(Application).filter(Application.application_uuid == application_uuid) \
.update({'name': name, 'description': description, 'updated': datetime.datetime.utcnow()})
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while updating application: {err}')
return {'err_msg': 'Error occurred while updating application'}
def get_by_uuid(self, application_uuid: str) -> [Application]:
"""
Fetch Application based on the application uuid
:param application_uuid: the application uuid
:return: [Application] with the provided application_uuid
"""
try:
return self.session.execute(select(Application).where(Application.application_uuid == application_uuid)).first()
except SQLAlchemyError as err:
logger.error(f'Error while fetching application by application_uuid: {err}')
def delete_application(self, application_uuid: str):
"""
Deletes an application with the application_uuid
:param application_uuid: The application uuid
:return: None
"""
try:
self.session.query(Application).filter(Application.application_uuid == application_uuid).delete()
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while deleting application: {err}')

View File

@ -5,17 +5,18 @@ Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com
"""
from hub.city_model_structure.city import City
from hub.persistence import BaseRepo
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy import select
from hub.persistence.models import City as DBCity
import pickle
import requests
from urllib3.exceptions import HTTPError
from typing import Union, Dict
from hub.hub_logger import logger
import datetime
import pickle
from typing import Union, Dict
from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from hub.city_model_structure.city import City
from hub.hub_logger import logger
from hub.persistence import BaseRepo
from hub.persistence.models import City as DBCity
from hub.version import __version__
class CityRepo(BaseRepo):
@ -32,44 +33,25 @@ class CityRepo(BaseRepo):
cls._instance = super(CityRepo, cls).__new__(cls)
return cls._instance
def insert(self, city: City, user_id: int) -> Union[City, Dict]:
db_city = DBCity(pickle.dumps(city), city.name, city.srs_name, city.country_code, city.lower_corner,
city.upper_corner, user_id)
db_city.climate_reference_city = city.climate_reference_city
db_city.longitude = city.longitude
db_city.latitude = city.latitude
db_city.time_zone = city.time_zone
def insert(self, city: City, application_id, user_id: int) -> Union[City, Dict]:
"""
Insert a city
:param city: The complete city instance
:param application_id: Application id owning the instance
:param user_id: User id owning the instance
:return: City and Dictionary
"""
try:
# Retrieve hub project latest release
response = requests.get("https://rs-loy-gitlab.concordia.ca/api/v4/projects/2/repository/branches/master",
headers={"PRIVATE-TOKEN": self.config.hub_token})
recent_commit = response.json()["commit"]["id"]
logger.info(f'Current commit of hub is {recent_commit}')
exiting_city = self._get_by_hub_version(recent_commit, city.name)
release = __version__
db_city = DBCity(pickle.dumps(city), city.name, city.level_of_detail, city.climate_file, application_id, user_id,
release)
# Do not persist the same city for the same version of Hub
if exiting_city is None:
db_city.hub_release = recent_commit
cities = self.get_by_name(city.name)
# update version for the same city but different hub versions
if len(cities) == 0:
db_city.city_version = 0
else:
db_city.city_version = cities[-1].city_version + 1
# Persist city
self.session.add(db_city)
self.session.flush()
self.session.commit()
return db_city
else:
return {'message': f'Same version of {city.name} exist'}
self.session.add(db_city)
self.session.flush()
self.session.commit()
return db_city
except SQLAlchemyError as err:
logger.error(f'Error while adding city: {err}')
except HTTPError as err:
logger.error(f'Error retrieving Hub latest release: {err}')
logger.error(f'An error occurred while creating city: {err}')
def get_by_id(self, city_id: int) -> DBCity:
"""
@ -82,16 +64,16 @@ class CityRepo(BaseRepo):
except SQLAlchemyError as err:
logger.error(f'Error while fetching city: {err}')
def _get_by_hub_version(self, hub_commit: str, city_name: str) -> City:
def _get_by_hub_version(self, hub_release: str, city_name: str) -> City:
"""
Fetch a City based on the name and hub project recent commit
:param hub_commit: the latest hub commit
Fetch a City based on the name and hub project
:param hub_release: the hub release
:param city_name: the name of the city
:return: a city
"""
try:
return self.session.execute(select(DBCity)
.where(DBCity.hub_release == hub_commit, DBCity.name == city_name)).first()
.where(DBCity.hub_release == hub_release, DBCity.name == city_name)).first()
except SQLAlchemyError as err:
logger.error(f'Error while fetching city: {err}')

View File

@ -30,16 +30,15 @@ class UserRepo(BaseRepo):
cls._instance = super(UserRepo, cls).__new__(cls)
return cls._instance
def insert(self, name: str, email: str, password: str, role: UserRoles) -> Union[User, Dict]:
user = self.get_by_email(email)
def insert(self, name: str, password: str, role: UserRoles, application_id: int) -> Union[User, Dict]:
user = self.get_by_name_and_application(name, application_id)
if user is None:
try:
if Auth.validate_password(password):
user = User(name=name, email=email, password=Auth.hash_password(password), role=role)
self.session.add(user)
self.session.flush()
self.session.commit()
return user
user = User(name=name, password=Auth.hash_password(password), role=role, application_id=application_id)
self.session.add(user)
self.session.flush()
self.session.commit()
return user
except SQLAlchemyError as err:
logger.error(f'An error occurred while creating user: {err}')
else:

1
hub/version.py Normal file
View File

@ -0,0 +1 @@
__version__ = '0.1.7.3'

View File

@ -4,49 +4,5 @@
requires = ["setuptools>=61.0.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "cerc_hub"
version = "0.1.7.3"
description = "CERC Hub consist in a set of classes (Central data model), importers and exporters to help researchers to create better and sustainable cities"
readme = "README.md"
authors = [{ name = "Guillermo Gutierrez", email = "Guillermo.GutierrezMorote@concordia.ca" }]
license = { file = "LICENSE.md" }
classifiers = [
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
]
keywords = ["city", "hub", "cerc"]
dependencies = [
"xmltodict",
"numpy",
"trimesh",
"pyproj",
"pandas",
"requests",
"esoreader",
"geomeppy",
"PyWavefront",
"xlrd",
"openpyxl",
"networkx",
"parseidf==1.0.0",
"ply",
"rhino3dm==7.7.0",
"scipy",
"PyYAML",
"pyecore==0.12.2",
"python-dotenv",
"SQLAlchemy",
"bcrypt==4.0.1",
"shapely",
"geopandas",
"triangle"
]
requires-python = ">=3.9"
[project.optional-dependencies]
dev = ["pip-tools", "pytest"]
[project.urls]
Homepage = "https://rs-loy-gitlab.concordia.ca/Guille/hub"
[options.packages.find_namespace]
where = "hub"

106
setup.py
View File

@ -1,32 +1,90 @@
from setuptools import setup, find_packages
from setuptools import setup, find_packages, convert_path
import os.path
import glob
main_ns = {}
version = convert_path('hub/version.py')
with open(version) as f:
exec(f.read(), main_ns)
setup(
name='hub',
version="0.1",
packages=find_packages(exclude="unittests"),
name='cerc-hub',
version=main_ns['__version__'],
description="CERC Hub consist in a set of classes (Central data model), importers and exporters to help researchers "
"to create better and sustainable cities",
long_description="CERC Hub consist in a set of classes (Central data model), importers and exporters to help "
"researchers to create better and sustainable cities",
classifiers=[
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
],
include_package_data=True,
packages=['hub',
'hub.catalog_factories',
'hub.catalog_factories.construction',
'hub.catalog_factories.data_models',
'hub.catalog_factories.data_models.construction',
'hub.catalog_factories.data_models.greenery',
'hub.catalog_factories.data_models.usages',
'hub.catalog_factories.greenery',
'hub.catalog_factories.greenery.ecore_greenery',
'hub.catalog_factories.usage',
'hub.city_model_structure',
'hub.city_model_structure.attributes',
'hub.city_model_structure.building_demand',
'hub.city_model_structure.energy_systems',
'hub.city_model_structure.greenery',
'hub.city_model_structure.iot',
'hub.city_model_structure.transport',
'hub.config',
'hub.data',
'hub.exports',
'hub.exports.building_energy',
'hub.exports.building_energy.idf_files',
'hub.exports.building_energy.insel',
'hub.exports.energy_systems',
'hub.exports.formats',
'hub.helpers',
'hub.hub_logger',
'hub.imports',
'hub.imports.construction',
'hub.imports.construction.helpers',
'hub.imports.construction.data_classes',
'hub.imports.energy_systems',
'hub.imports.geometry',
'hub.imports.geometry.citygml_classes',
'hub.imports.geometry.helpers',
'hub.imports.usage',
'hub.imports.weather',
'hub.imports.weather.helpers',
'hub.persistence',
'hub.persistence.models',
'hub.persistence.repositories',
'hub.imports'
],
data_files=[
('config', [os.path.join('hub/config', 'configuration.ini')]),
('greenery', glob.glob('hub/catalog_factories/greenery/ecore_greenery/*.ecore')),
('data', glob.glob('hub/data/construction/*.xml')),
('data', glob.glob('hub/data/customized_imports/*.xml')),
('data', glob.glob('hub/data/energy_systems/*.xml')),
('data', glob.glob('hub/data/energy_systems/*.insel')),
('data', glob.glob('hub/data/energy_systems/*.xlsx')),
('data', glob.glob('hub/data/energy_systems/*.txt')),
('data', glob.glob('hub/data/energy_systems/*.yaml')),
('data', glob.glob('hub/data/greenery/*.xml')),
('data', glob.glob('hub/data/life_cycle_assessment/*.xml')),
('data', glob.glob('hub/data/schedules/*.xml')),
('data', glob.glob('hub/data/schedules/*.xlsx')),
('data', glob.glob('hub/data/schedules/idf_files/*.idf')),
('data', glob.glob('hub/data/sensors/*.json')),
('data', glob.glob('hub/data/usage/*.xml')),
('data', glob.glob('hub/data/usage/*.xlsx')),
('data', glob.glob('hub/data/weather/*.dat')),
('data', glob.glob('hub/data/weather/epw/*.epw')),
('data', glob.glob('hub/data/weather/*.dat'))
('hub/config', glob.glob('hub/config/*.ini')),
('hub/catalog_factories/greenery/ecore_greenery', glob.glob('hub/catalog_factories/greenery/ecore_greenery/*.ecore')),
('hub/data/construction.', glob.glob('hub/data/construction/*.xml')),
('hub/data/customized_imports/', glob.glob('hub/data/customized_imports/*.xml')),
('hub/data/energy_systems/', glob.glob('hub/data/energy_systems/*.xml')),
('hub/data/energy_systems/', glob.glob('hub/data/energy_systems/*.insel')),
('hub/data/energy_systems/', glob.glob('hub/data/energy_systems/*.xlsx')),
('hub/data/energy_systems/*', glob.glob('hub/data/energy_systems/*.txt')),
('hub/data/energy_systems/*', glob.glob('hub/data/energy_systems/*.yaml')),
('hub/data/greenery/', glob.glob('hub/data/greenery/*.xml')),
('hub/data/life_cycle_assessment/', glob.glob('hub/data/life_cycle_assessment/*.xml')),
('hub/data/schedules/', glob.glob('hub/data/schedules/*.xml')),
('hub/data/schedules/', glob.glob('hub/data/schedules/*.xlsx')),
('hub/data/schedules/idf_files/', glob.glob('hub/data/schedules/idf_files/*.idf')),
('hub/data/sensors/', glob.glob('hub/data/sensors/*.json')),
('hub/data/usage/', glob.glob('hub/data/usage/*.xml')),
('hub/data/usage/', glob.glob('hub/data/usage/*.xlsx')),
('hub/data/weather/', glob.glob('hub/data/weather/*.dat')),
('hub/data/weather/epw/', glob.glob('hub/data/weather/epw/*.epw')),
('hub/data/weather/', glob.glob('hub/data/weather/*.dat')),
('hub/exports/building_energy/idf_files', glob.glob('hub/exports/building_energy/idf_files/*.idf'))
],
setup_requires=['setuptools']
)