Skip to content

Commit

Permalink
Tag settings
Browse files Browse the repository at this point in the history
  • Loading branch information
steelegbr committed Jan 5, 2025
1 parent 4582e83 commit 2165e99
Show file tree
Hide file tree
Showing 12 changed files with 226 additions and 10 deletions.
2 changes: 2 additions & 0 deletions Backend/alldaydj/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework_simplejwt.authentication.JWTAuthentication"
],
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
"PAGE_SIZE": 100,
}

# Authentication
Expand Down
12 changes: 11 additions & 1 deletion Frontend/models/dto/api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
from pydantic import BaseModel
from pydantic import BaseModel, HttpUrl
from typing import Generic, List, Optional, TypeVar

T = TypeVar("T")


class ApiSettings(BaseModel):
auth_audience: str
auth_domain: str
auth_client_id: str


class Pagination(BaseModel, Generic[T]):
count: int
next: Optional[HttpUrl]
previous: Optional[HttpUrl]
results: List[T]
8 changes: 8 additions & 0 deletions Frontend/models/dto/audio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from pydantic import BaseModel
from typing import Optional
from uuid import UUID


class Tag(BaseModel):
id: Optional[UUID]
tag: str
19 changes: 11 additions & 8 deletions Frontend/services/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
OAuthTokenResponse,
OAuthTokenResponseError,
)
from PySide6.QtCore import QJsonDocument, QTimer
from PySide6.QtCore import QTimer
from PySide6.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest
from services.api import ApiService
from services.json import JsonService
from services.logging import get_logger, Logger
from services.settings import SettingsService
from typing import Callable, Dict, List, Optional
Expand Down Expand Up @@ -147,7 +148,7 @@ def callback(reply: QNetworkReply):
self.__network_access_manager.finished.connect(callback)
self.__network_access_manager.post(
self.__generate_json_request(url),
self.__convert_dict_for_post(payload.model_dump()),
JsonService.dict_to_json(payload.model_dump()),
)

def __make_token_request(self, *args, **kwargs):
Expand Down Expand Up @@ -198,13 +199,9 @@ def callback(reply: QNetworkReply):
self.__network_access_manager.finished.connect(callback)
self.__network_access_manager.post(
self.__generate_json_request(url),
self.__convert_dict_for_post(payload.model_dump()),
JsonService.dict_to_json(payload.model_dump()),
)

def __convert_dict_for_post(self, payload: Dict):
doc = QJsonDocument(payload)
return doc.toJson()

def __handle_error(self, error: str):
self.__set_state(AuthenticationServiceState.Error)
self.__error = error
Expand Down Expand Up @@ -278,7 +275,7 @@ def callback(reply: QNetworkReply):
self.__network_access_manager.finished.connect(callback)
self.__network_access_manager.post(
self.__generate_json_request(url),
self.__convert_dict_for_post(payload.model_dump()),
JsonService.dict_to_json(payload.model_dump()),
)

def get_token(self) -> Optional[str]:
Expand All @@ -293,6 +290,12 @@ def get_token(self) -> Optional[str]:

return self.__access_token

def get_authenticated_request(self, url: str) -> QNetworkRequest:
request = QNetworkRequest()
request.setUrl(url)
request.setRawHeader(b"Authorization", f"Bearer {self.get_token()}".encode())
return request

def get_user_code(self) -> Optional[str]:
if self.__device_code_response:
return self.__device_code_response.user_code
Expand Down
7 changes: 7 additions & 0 deletions Frontend/services/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from services.authentication import AuthenticationService
from services.logging import LoggingService, Logger
from services.settings import SettingsService
from services.tag import TagService


class ServiceFactory:
Expand Down Expand Up @@ -29,3 +30,9 @@ def authenticationService(self) -> AuthenticationService:

def settingsService(self) -> SettingsService:
return SettingsService()

def tagService(self) -> TagService:
return TagService(
authetication_service=self.authenticationService(),
settings_service=self.settingsService(),
)
9 changes: 9 additions & 0 deletions Frontend/services/json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from PySide6.QtCore import QJsonDocument
from typing import Dict


class JsonService:
@staticmethod
def dict_to_json(dict: Dict):
doc = QJsonDocument(dict)
return doc.toJson()
68 changes: 68 additions & 0 deletions Frontend/services/tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from models.dto.api import Pagination
from models.dto.audio import Tag
from PySide6.QtNetwork import QNetworkAccessManager, QNetworkReply
from services.authentication import AuthenticationService
from services.logging import LoggingService, Logger
from services.settings import SettingsService
from typing import Callable, List
from urllib.parse import urljoin


class TagService:
__authentication_service: AuthenticationService
__logger: Logger
__settings_service: SettingsService
__network_access_manager: QNetworkAccessManager

ENCODING = "utf-8"

def __init__(
self,
authetication_service: AuthenticationService = None,
logger: Logger = LoggingService().get_logger(__name__),
settings_service: SettingsService = None,
):
self.__authentication_service = authetication_service
self.__logger = logger
self.__network_access_manager = QNetworkAccessManager()
self.__settings_service = settings_service

def __get_page(
self,
url: str,
success: Callable[[List[Tag]], None],
failure: Callable[[List[str]], None],
tags_so_far: List[Tag],
):
self.__logger.info("GET Tags request", url=url)

def callback(reply: QNetworkReply):
self.__network_access_manager.finished.disconnect(callback)
content = str(reply.readAll().data(), encoding=self.ENCODING)

if reply.error() is not QNetworkReply.NoError:
self.__logger.error(
"GET Tags request failed",
url=url,
error=reply.error(),
response=content,
)
else:
self.__logger.info("GET Tags request successful", url=url)
page_of_results = Pagination[Tag].model_validate_json(content)
tags_so_far.extend(page_of_results.results)
if page_of_results.next:
self.__get_page(page_of_results.next, success, failure, tags_so_far)
else:
success(tags_so_far)

self.__network_access_manager.finished.connect(callback)
self.__network_access_manager.get(
self.__authentication_service.get_authenticated_request(url)
)

def get_all_tags(
self, success: Callable[[List[Tag]], None], failure: Callable[[List[str]], None]
):
url = urljoin(str(self.__settings_service.get().base_url), "/api/tag")
self.__get_page(url, success, failure, [])
36 changes: 36 additions & 0 deletions Frontend/ui/viewmodels/tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from models.dto.audio import Tag
from PySide6.QtCore import QAbstractListModel, Qt
from services.factory import TagService, ServiceFactory
from typing import List


class TagListModel(QAbstractListModel):
__tags: List[Tag]
__tag_service: TagService

def __init__(
self,
*args,
tags=None,
tag_service: TagService = ServiceFactory().tagService(),
**kwargs
):
super().__init__(*args, **kwargs)
self.__tag_service = tag_service
self.__tags = tags or []
self.refresh()

def refresh(self):
self.__tag_service.get_all_tags(self.__update_tags, None)

def __update_tags(self, tags: List[Tag]):
self.beginResetModel()
self.__tags = tags
self.endResetModel()

def data(self, index, role):
if role is Qt.DisplayRole:
return self.__tags[index.row()].tag

def rowCount(self, index):
return len(self.__tags)
3 changes: 2 additions & 1 deletion Frontend/ui/views/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from ui.views.clock import Clock
from ui.views.library import Library
from ui.views.placeholder import Placeholder
from ui.views.settings import Settings


class MainScreen(QMainWindow):
Expand Down Expand Up @@ -54,6 +55,6 @@ def __create_right_tabs():
right_tabs = QTabWidget(movable=True)

right_tabs.addTab(Library(), "Library")
right_tabs.addTab(Placeholder("Settings"), "Settings")
right_tabs.addTab(Settings(), "Settings")

return right_tabs
1 change: 1 addition & 0 deletions Frontend/ui/views/settings/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .settings import Settings
14 changes: 14 additions & 0 deletions Frontend/ui/views/settings/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from PySide6.QtWidgets import QTabWidget, QVBoxLayout, QWidget
from ui.views.settings.tag import TagSettings


class Settings(QWidget):
def __init__(self):
super().__init__()

tabs = QTabWidget(movable=True)
tabs.addTab(TagSettings(), "Tags")

layout = QVBoxLayout()
layout.addWidget(tabs)
self.setLayout(layout)
57 changes: 57 additions & 0 deletions Frontend/ui/views/settings/tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from PySide6.QtWidgets import (
QHBoxLayout,
QLabel,
QLineEdit,
QListView,
QPushButton,
QVBoxLayout,
QWidget,
)
from ui.viewmodels.tag import TagListModel


class TagSettings(QWidget):
__add_button: QPushButton
__add_text: QLineEdit
__tag_list: QListView
__tag_model: TagListModel

def __init__(self):
super().__init__()

layout = QVBoxLayout()
layout.addLayout(self.__generate_tag_list())
layout.addLayout(self.__generate_delete())
layout.addLayout(self.__generate_add())

self.setLayout(layout)

def __generate_tag_list(self):
layout = QHBoxLayout()

self.__tag_model = TagListModel()

self.__tag_list = QListView()
self.__tag_list.setModel(self.__tag_model)
layout.addWidget(self.__tag_list)

return layout

def __generate_delete(self):
layout = QHBoxLayout()

layout.addWidget(QLabel(""), 1)
layout.addWidget(QPushButton("Delete"))

return layout

def __generate_add(self):
layout = QHBoxLayout()

self.__add_text = QLineEdit()
layout.addWidget(self.__add_text, 1)

self.__add_button = QPushButton("Add")
layout.addWidget(self.__add_button)

return layout

0 comments on commit 2165e99

Please sign in to comment.