Skip to content

Commit

Permalink
Merge pull request #81 from ES2-UFPI/servico-de-interpretacao-de-stri…
Browse files Browse the repository at this point in the history
…ng-#30

Servico de interpretacao de string #30
  • Loading branch information
M3L4O authored Mar 28, 2023
2 parents 180340c + 28f37bc commit 85b7fdb
Show file tree
Hide file tree
Showing 31 changed files with 896 additions and 176 deletions.
26 changes: 20 additions & 6 deletions src/Scraper/application/ScraperOrchestration/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@
from framework.infrastructure.connection_util import _get_engine
from framework.infrastructure.db_management.db_connection import create_session
from Scraper.domain.commands import *
from framework.domain.components import Component
from framework.application.handler import MessageBus
from SearchEngine.application.handlers import SE_COMMAND_HANDLER_MAPPER
from SearchEngine.application.unit_of_work import (
DataFrameUnitOfWork,
SQLAlchemyUnitOfWork,
)
from SearchEngine.domain.commands import GetComponentByUID, MatchName


class Wrapper:
Expand Down Expand Up @@ -54,6 +61,14 @@ def __init__(self, scheme: str, domain: str):
SQLAlchemyCategoryURLUnitOfWork,
)

self._sse_message_bus = get_message_bus(
{}, SE_COMMAND_HANDLER_MAPPER, DataFrameUnitOfWork, "../res/data/run"
)

self._search_message_bus = get_message_bus(
{}, SE_COMMAND_HANDLER_MAPPER, SQLAlchemyUnitOfWork
)

self.domain_urls = self._category_url_message_bus.handle(
GetCategoryURLByDomain(domain)
)
Expand All @@ -73,15 +88,14 @@ async def run_scraping(self):
for url, name, cost, availability in components_volatile_data:
# TODO: fazer chamada da engine de busca para classificar o componente
# component = SearchEngine.classifie(name)
component_manager = SQLAlchemyRepository(
self.session
) # placeholder
component = component_manager.get(filters_gt={"consumption": -1})[
0
] # placeholder
component_id = self._sse_message_bus.handle(MatchName(name))
component = self._search_message_bus.handle(
GetComponentByUID(component_id)
)
volatile_data = VolatileData(
_id=UUIDv5(url.url),
component_id=component.uid,
component_type=component.type,
url=url,
cost=cost,
availability=availability,
Expand Down
85 changes: 77 additions & 8 deletions src/Scraper/application/handlers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Dict, Type, List
from typing import Type, Dict, List
from smtplib import SMTP
from ssl import create_default_context
from email.mime.text import MIMEText
Expand All @@ -12,10 +12,11 @@
)
from SearchEngine.application.unit_of_work import SQLAlchemyUnitOfWork
from framework.domain.components import Component
from framework.application.handler import MessageHandler, Command
from ..domain.repositories import ICategoryURLRepository
from framework.domain.events import Command, DomainEvent
from framework.application.handler import MessageHandler
from Scraper.domain.aggragate import VolatileData
from ..domain.repositories import ICategoryURLRepository, IVolatileDataRepository
from ..domain.events import LowerPriceRegisteredEvent
from framework.domain.events import DomainEvent
from ..domain.commands import *


Expand Down Expand Up @@ -63,16 +64,79 @@ def __call__(self, cmd: GetAllDomains):
return self.uow.repository.get_all_domains()


class AddVolatileDataHandler(MessageHandler):
def __call__(self, cmd: AddVolatileData):
with self.uow:
self.uow.repository.add(cmd.volatile_data)


class GetVolatileDataByDomainHandler(MessageHandler):
def __call__(self, cmd: GetCategoryURLByDomain):
with self.uow:
return self.uow.repository.get(filters_eq={"domain": cmd.domain})


class AddVolatileDataHandler(MessageHandler):
def __call__(self, cmd: AddVolatileData):
class GetVolatileDataByMaxCostHandler(MessageHandler):
def __call__(self, cmd: GetVolatileDataByMaxCost):
with self.uow:
self.uow.repository.add(cmd.volatile_data)
return self.uow.repository.get(filters_lt={"cost": cmd.cost})


class GetLowerCostVolatileDatasHandler(MessageHandler):
def __call__(self, cmd: GetLowerCostVolatileDatas):
with self.uow:
cost_filter = {} if cmd.cost >= 0 else {"filters_lt": {"cost": cmd.cost}}
if isinstance(self.uow.repository, IVolatileDataRepository):
return self.uow.repository.get_lower_costs(**cost_filter)


class GetVolatileDataByComponentUIDHandler(MessageHandler):
def __call__(self, cmd: GetVolatileDataByComponentUID):
with self.uow:
return self.uow.repository.get(
filters_eq={"component_uid": cmd.component_uid}
)


def _get_components_from_volatile_data(volatile_data: list[VolatileData]):
message_bus = get_message_bus(
SE_EVENT_HANDLER_MAPPER, SE_COMMAND_HANDLER_MAPPER, SQLAlchemyUnitOfWork
)

components = [
message_bus.handle(GetComponentByUID(vd.component_id)) for vd in volatile_data
]

return components


class GetComponentsFromVolatileDataHandler(MessageHandler):
def __call__(self, cmd: GetComponentsFromVolatileData):
with self.uow:
return _get_components_from_volatile_data(cmd.volatile_data)


class GetVolatileDataByCostIntervalHandler(MessageHandler):
def __call__(self, cmd: GetVolatileDataByCostInterval):
with self.uow:
filters_lt = {"cost": cmd.max_cost}
filters_gt = {"cost": cmd.min_cost}
filters_eq = {"component_type": cmd.component_type}

volatile_data: list = self.uow.repository.get_lower_costs(
filters_eq=filters_eq,
filters_lt=filters_lt,
filters_gt=filters_gt,
)

components = _get_components_from_volatile_data(volatile_data)

for i, component in enumerate(components):
if component.rank is None:
del volatile_data[i]
del components[i]

return components, volatile_data


CURL_COMMAND_HANDLER_MAPPER: Dict[Type[Command], Type[MessageHandler]] = {
Expand All @@ -84,7 +148,12 @@ def __call__(self, cmd: AddVolatileData):
CURL_EVENT_HANDLER_MAPPER: Dict[Type[DomainEvent], List[Type[MessageHandler]]] = {}

VD_COMMAND_HANDLER_MAPPER: Dict[Type[Command], Type[MessageHandler]] = {
AddVolatileData: AddVolatileDataHandler
AddVolatileData: AddVolatileDataHandler,
GetVolatileDataByMaxCost: GetVolatileDataByMaxCostHandler,
GetVolatileDataByComponentUID: GetVolatileDataByComponentUIDHandler,
GetLowerCostVolatileDatas: GetLowerCostVolatileDatasHandler,
GetComponentsFromVolatileData: GetComponentsFromVolatileDataHandler,
GetVolatileDataByCostInterval: GetVolatileDataByCostIntervalHandler,
}

VD_EVENT_HANDLER_MAPPER: Dict[Type[DomainEvent], List[Type[MessageHandler]]] = {
Expand Down
15 changes: 13 additions & 2 deletions src/Scraper/domain/aggragate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,26 @@
from dataclasses import dataclass, field
from typing import List

from framework.domain.components_enums import EComponentType
from framework.domain.entity import AggregateRoot
from framework.domain.value_object import UUID, Money, URL

_AttrsVolatileData = ["_id", "url", "component_id", "cost", "availability", "timestamp"]
_AttrsVolatileData = [
"_id",
"url",
"component_id",
"component_type",
"cost",
"availability",
"timestamp",
]


@dataclass(kw_only=True)
class VolatileData(AggregateRoot):
# url_id: UUID
url: URL
component_id: UUID
component_type: EComponentType
cost: Money
availability: bool

Expand All @@ -29,13 +38,15 @@ def generateVolatileDataPoint(
self,
_id: UUID,
component_id: UUID,
component_type: EComponentType,
url: URL,
cost: Money,
availability: bool,
):
return VolatileData(
_id=_id,
component_id=component_id,
component_type=component_type,
url=url,
cost=cost,
availability=availability,
Expand Down
42 changes: 42 additions & 0 deletions src/Scraper/domain/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@

from Scraper.domain.entity import CategoryURL
from Scraper.domain.aggragate import VolatileData
from framework.domain.value_object import UUID, Money
from framework.domain.components import Component
from framework.domain.components_enums import *

__all__ = [
"AddCategoryURL",
"GetAllDomains",
"GetCategoryURLByDomain",
"AddVolatileData",
"GetVolatileDataByMaxCost",
"GetVolatileDataByComponentUID",
"GetLowerCostVolatileDatas",
"GetComponentsFromVolatileData",
"GetVolatileDataByCostInterval",
]


Expand All @@ -30,3 +38,37 @@ class GetCategoryURLByDomain(Command):
@dataclass
class AddVolatileData(Command):
volatile_data: VolatileData


@dataclass
class GetVolatileDataByUID(Command):
uid: UUID


@dataclass
class GetVolatileDataByMaxCost(Command):
cost: float


@dataclass
class GetLowerCostVolatileDatas(Command):
cost: float = -1
pass


@dataclass
class GetVolatileDataByComponentUID(Command):
component_uid: UUID


@dataclass
class GetComponentsFromVolatileData(Command):
volatile_data: list[VolatileData]


@dataclass
class GetVolatileDataByCostInterval(Command):
component_type: EComponentType
min_cost: float
max_cost: float
need_rank: bool = False
7 changes: 6 additions & 1 deletion src/Scraper/domain/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from framework.domain.repository import (
AbstractRepository,
AbstractCategoryURLRepository,
AbstractVolatileDataRepository,
)
from framework.domain.exception import DomainException
from Scraper.domain.aggragate import VolatileData
Expand Down Expand Up @@ -62,7 +63,7 @@ def __post_init__(self):
f"URL de categoria com UID {self.entity_id} já existe."


class IVolatileDataRepository(AbstractRepository, metaclass=ABCMeta):
class IVolatileDataRepository(AbstractVolatileDataRepository, metaclass=ABCMeta):
@abstractmethod
def __init__(self, session):
raise NotImplemented
Expand All @@ -79,6 +80,10 @@ def _get_by_uid(self, ref: UUID):
def _get(self, **kwargs):
raise NotImplemented

@abstractmethod
def _get_lower_costs(self, **kwargs):
raise NotImplemented

def __repr__(self):
raise NotImplemented

Expand Down
Loading

0 comments on commit 85b7fdb

Please sign in to comment.