Skip to content

Commit

Permalink
Merge branch 'dev' into init-frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
AzamatKomaev authored Sep 26, 2024
2 parents 2b4a2bf + cb2c8e0 commit 012f3bd
Show file tree
Hide file tree
Showing 54 changed files with 590 additions and 19,756 deletions.
29 changes: 0 additions & 29 deletions backend/app/controllers/home.py

This file was deleted.

105 changes: 105 additions & 0 deletions backend/app/controllers/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import datetime
import uuid
from typing import Optional

from pydantic import BaseModel, Field, computed_field


class NetologyCreds(BaseModel):
"""Netology creds."""

username: str
password: str


class ModeusCreds(BaseModel):
"""Modeus creds."""

username: str
password: str


class ModeusSearchEvents(BaseModel):
"""Modeus search events body."""
size: int = Field(examples=[50], default=50)
time_min: datetime.datetime = Field(alias="timeMin", examples=[datetime.datetime.now()])
time_max: datetime.datetime = Field(alias="timeMax",
examples=[datetime.datetime.now() - datetime.timedelta(days=7)])
attendee_person_id: list[str] = Field(alias="attendeePersonId", default="d69c87c8-aece-4f39-b6a2-7b467b968211")


class Location(BaseModel):
id: uuid.UUID = Field(alias="eventId")
custom_location: str = Field(alias="customLocation")

@computed_field # type: ignore
@property
def is_lxp(self) -> float:
return self.custom_location == 'LXP'


class Event(BaseModel):
name: str = Field(alias="name")
name_short: str = Field(alias="nameShort")
description: Optional[str] = Field(alias="description")
start_time: datetime.datetime = Field(alias="start")
end_time: datetime.datetime = Field(alias="end")
id: uuid.UUID


class Href(BaseModel):
href: str

@computed_field # type: ignore
@property
def id(self) -> uuid.UUID:
return uuid.UUID(self.href.replace('/', ''))

class Link(BaseModel):
self: Href
event: Href
person: Href

class Attender(BaseModel):
links: Link = Field(alias="_links")


class Teacher(BaseModel):
id: uuid.UUID
full_name: str = Field(alias="fullName")


class Embedded(BaseModel):
events: list[Event] = Field(alias="events")
locations: list[Location] = Field(alias="event-locations")
attendees: list[Attender] = Field(alias="event-attendees")
teacher: list[Teacher] = Field(alias="persons")


class FullEvent(Event, Location):
teacher_full_name: str


class ModeusCalendar(BaseModel):
"""Modeus calendar response."""

embedded: Embedded = Field(alias="_embedded")

def parse_modeus_response(self) -> list[FullEvent]:
locations = {location.id: location for location in self.embedded.locations}
teachers = {teacher.id: teacher for teacher in self.embedded.teacher}
teachers_with_events = {teacher.links.event.id: teacher.links for teacher in self.embedded.attendees}
full_events = []
for event in self.embedded.events:
try:
teacher_event = teachers_with_events[event.id]
teacher = teachers[teacher_event.person.id]
teacher_full_name = teacher.full_name
except KeyError:
teacher_full_name = 'unknown'
location = locations[event.id]
full_events.append(FullEvent(**{
"teacher_full_name": teacher_full_name,
**event.model_dump(by_alias=True), **location.model_dump(by_alias=True),
}))
return full_events
37 changes: 27 additions & 10 deletions backend/app/controllers/modeus.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,20 @@
from typing import Optional

from blacksheep import Response
from blacksheep.server.bindings import FromJson
from blacksheep.server.bindings import FromJson, FromHeader
from blacksheep.server.controllers import Controller, post
from integration import modeus
from integration.exceptions import ModeusError
from pydantic import BaseModel
from requests import RequestException

from integration import modeus
from integration.exceptions import ModeusError
from . import models

class ModeusCreds(BaseModel):
"""Modeus creds."""

username: str
password: str
class FromAuthorizationHeader(FromHeader[str]):
name = "bearer-token"


class NetologyController(Controller):
class ModeusController(Controller):
"""Controller for Modeus API."""

@classmethod
Expand All @@ -34,7 +32,7 @@ def class_name(cls) -> str:
return "Modeus"

@post()
async def get_modeus_cookies(self, item: FromJson[ModeusCreds]) -> Response:
async def get_modeus_cookies(self, item: FromJson[models.ModeusCreds]) -> Response:
"""
Auth in Modeus and return cookies.
"""
Expand All @@ -44,3 +42,22 @@ async def get_modeus_cookies(self, item: FromJson[ModeusCreds]) -> Response:
)
except (RequestException, ModeusError) as exception:
return self.json({"error": f"can't authenticate {exception}"}, status=400)

@post("/events/")
async def get_modeus_events(
self,
auth: FromAuthorizationHeader,
item: FromJson[models.ModeusSearchEvents],
) -> Response:
"""
Get events from Modeus.
"""
try:
jwt = auth.value.split()[1]
return self.json(await modeus.get_events(jwt, item.value))
except IndexError as exception:
return self.json(
{"error": f"cannot parse authorization header {exception}"},
)
except (RequestException, ModeusError) as exception:
return self.json({"error": f"can't authenticate {exception}"}, status=400)
15 changes: 6 additions & 9 deletions backend/app/controllers/netology.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,10 @@
from blacksheep import Response
from blacksheep.server.bindings import FromJson
from blacksheep.server.controllers import Controller, post
from integration import netology
from pydantic import BaseModel
from requests import RequestException


class NetologyCreds(BaseModel):
"""Netology creds."""

username: str
password: str
from integration import netology
from . import models


class NetologyController(Controller):
Expand All @@ -33,7 +27,10 @@ def class_name(cls) -> str:
return "Netology"

@post()
async def get_netology_cookies(self, item: FromJson[NetologyCreds]) -> Response:
async def get_netology_cookies(
self,
item: FromJson[models.NetologyCreds],
) -> Response:
"""
Auth in Netology and return cookies.
"""
Expand Down
2 changes: 1 addition & 1 deletion backend/app/docs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from app.settings import Settings
from blacksheep import Application
from blacksheep.server.openapi.v3 import OpenAPIHandler
from openapidocs.v3 import Info # type: ignore[import-untyped]
from openapidocs.v3 import Info


def configure_docs(app: Application, settings: Settings) -> None:
Expand Down
2 changes: 1 addition & 1 deletion backend/app/docs/binders.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from app.binders import PageOptionsBinder
from blacksheep.server.openapi.v3 import OpenAPIHandler
from openapidocs.v3 import ( # type: ignore[import-untyped]
from openapidocs.v3 import (
Parameter,
ParameterLocation,
Schema,
Expand Down
6 changes: 4 additions & 2 deletions backend/app/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@

def configure_error_handlers(app: Application) -> None:
async def not_found_handler(
app: Application, request: Request, exception: Exception
app: Application,
request: Request,
exception: Exception,
) -> Response:
return text(str(exception) or "Not found", 404)

Expand All @@ -37,5 +39,5 @@ async def accepted(*args: Any) -> Response:
UnauthorizedException: unauthorized,
ForbiddenException: forbidden,
AcceptedException: accepted,
}
},
)
4 changes: 1 addition & 3 deletions backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from app.errors import configure_error_handlers
from app.services import configure_services
from app.settings import Settings, load_settings
from app.templating import configure_templating
from blacksheep import Application
from rodi import Container

Expand All @@ -21,7 +20,6 @@ def configure_application(
show_error_details=settings.app.show_error_details,
)

app.serve_files("app/static")
configure_error_handlers(app)
configure_authentication(app, settings)
configure_docs(app, settings)
Expand All @@ -33,7 +31,7 @@ def configure_application(
allow_headers="*",
max_age=300,
)

return app


Expand Down
Binary file removed backend/app/static/blacksheep-favicon-white.png
Binary file not shown.
Binary file removed backend/app/static/favicon.ico
Binary file not shown.
Binary file not shown.
Binary file removed backend/app/static/images/blacksheep.png
Binary file not shown.
Binary file removed backend/app/static/img/portfolio/cabin.png
Binary file not shown.
Binary file removed backend/app/static/img/portfolio/cake.png
Binary file not shown.
Binary file removed backend/app/static/img/portfolio/circus.png
Binary file not shown.
Binary file removed backend/app/static/img/portfolio/game.png
Binary file not shown.
Binary file removed backend/app/static/img/portfolio/safe.png
Binary file not shown.
Binary file removed backend/app/static/img/portfolio/submarine.png
Binary file not shown.
63 changes: 0 additions & 63 deletions backend/app/static/scripts/freelancer.js

This file was deleted.

Loading

0 comments on commit 012f3bd

Please sign in to comment.