Folder info and permissions

This commit is contained in:
StNicolay 2024-08-10 08:59:11 +03:00
parent 37940d633a
commit 4c01ca7510
Signed by: StNicolay
GPG Key ID: 9693D04DCD962B0D
4 changed files with 192 additions and 20 deletions

View File

@ -83,7 +83,7 @@ class RegisterWidget(QWidget):
class LoginWidget(QWidget):
def __init__(self, switcher: State):
def __init__(self, switcher: state.State):
super().__init__()
self.switcher = switcher
@ -116,7 +116,9 @@ class LoginWidget(QWidget):
password = self.password_input.text()
if not username or not password:
QMessageBox.warning(self, "Input Error", "Email and Password are required")
QMessageBox.warning(
self, "Input Error", "Email and Password are required"
)
return
try:
@ -129,8 +131,12 @@ class LoginWidget(QWidget):
if access_token:
self.switcher.login(access_token)
else:
QMessageBox.warning(self, "Error", "No access token received")
QMessageBox.warning(
self, "Error", "No access token received"
)
else:
QMessageBox.warning(self, "Error", f"Login failed: {response.text}")
QMessageBox.warning(
self, "Error", f"Login failed: {response.text}"
)
except httpx.HTTPError as e:
QMessageBox.critical(self, "HTTP Error", str(e))

View File

@ -7,12 +7,19 @@ import uuid
from typing import Protocol, Self
import create_folder_widget
import folder_info
import httpx
import pydantic
import state
import user
from PyQt6.QtCore import QPoint, Qt
from PyQt6.QtGui import QAction, QDragEnterEvent, QDragMoveEvent, QDropEvent, QIcon
from PyQt6.QtGui import (
QAction,
QDragEnterEvent,
QDragMoveEvent,
QDropEvent,
QIcon,
)
from PyQt6.QtWidgets import (
QFileDialog,
QHBoxLayout,
@ -57,7 +64,9 @@ class File(pydantic.BaseModel):
return self.file_name
def delete(self) -> None:
RequestClient().client.delete("/files", params={"file_id": self.file_id})
RequestClient().client.delete(
"/files", params={"file_id": self.file_id}
)
def details(self, list: FileListWidget) -> QWidget:
del list
@ -114,15 +123,14 @@ class Folder(pydantic.BaseModel):
return self.folder_name
def delete(self) -> None:
print(
RequestClient()
.client.delete("/folders", params={"folder_id": self.folder_id})
.text
response = RequestClient().client.delete(
"/folders", params={"folder_id": self.folder_id}
)
if not response:
QMessageBox.warning(None, "Error deleting folder", response.text)
def details(self, list: FileListWidget) -> QWidget:
# TODO
raise NotImplementedError
return folder_info.FolderInfoWidget(self)
def icon(self) -> QIcon:
return QIcon("assets/folder.png")
@ -164,7 +172,9 @@ class ListResponse(pydantic.BaseModel):
return self.get(self.folder_id)
def create_folder(self, file_list: FileListWidget):
return create_folder_widget.CreateFolderWidget(self.folder_id, file_list)
return create_folder_widget.CreateFolderWidget(
self.folder_id, file_list
)
@dataclasses.dataclass(slots=True)
@ -186,7 +196,7 @@ class TlpResponse:
def update(self) -> ResponseProtocol:
return self.get()
def create_folder(self):
def create_folder(self, _: FileListWidget):
return # Not much to do
@ -228,7 +238,6 @@ class FileListWidget(QListWidget):
def dropEvent(self, event: QDropEvent):
event.accept()
print("hi")
for url in event.mimeData().urls():
file_path = url.toLocalFile()
self.upload_file(file_path)
@ -241,7 +250,9 @@ class FileListWidget(QListWidget):
response = RequestClient().client.post(
"http://localhost:3000/files",
files=files,
params={"parent_folder": self.current_response().folder_id},
params={
"parent_folder": self.current_response().folder_id
},
)
if response.is_success:
QMessageBox.information(
@ -283,7 +294,6 @@ class FileListWidget(QListWidget):
item = self.current_response().items()[row]
item.delete()
self.update_response()
QMessageBox.information(self, "Delete", f"{item.name()} deleted")
def update(self) -> None:
self.clear()

View File

@ -0,0 +1,152 @@
from __future__ import annotations
import uuid
from dataclasses import dataclass
from request_client import RequestClient
import enum
import file_widgets
from PyQt6.QtWidgets import (
QWidget,
QMessageBox,
QLabel,
QPushButton,
QComboBox,
QHBoxLayout,
QVBoxLayout,
QLineEdit,
)
import pydantic
from functools import cache, partial
import user
class Permission(enum.StrEnum):
read = enum.auto()
write = enum.auto()
manage = enum.auto()
def set(self, folder_id: uuid.UUID, user_id: int):
response = RequestClient().client.post(
"/permissions",
json={
"folder_id": str(folder_id),
"permission_type": str(self),
"user_id": int(user_id),
},
)
if not response.is_success:
QMessageBox.warning(
None, "Error setting permissions", response.text
)
@staticmethod
def delete(folder_id: uuid.UUID, user_id: int, widget: FolderInfoWidget):
response = RequestClient().client.delete(
"/permissions",
params={
"folder_id": folder_id,
"user_id": user_id,
},
)
if not response.is_success:
QMessageBox.warning(
None, "Error deleting permissions", response.text
)
else:
widget.redraw()
@dataclass(slots=True)
class Permissions:
mapping: dict[int, Permission]
@staticmethod
def get(folder_id: uuid.UUID) -> Permissions:
mapping = pydantic.TypeAdapter(dict[str, Permission]).validate_json(
RequestClient()
.client.get("/permissions", params={"folder_id": folder_id})
.text
)
return Permissions(mapping)
class FolderInfoWidget(QWidget):
def __init__(self, folder: file_widgets.Folder):
super().__init__()
self.setWindowTitle("Folder info")
self.folder = folder
self.user_cache = cache(user.User.get)
self.user_mapping: dict[str, int] = {}
self.redraw()
def redraw(self):
self.permissions = Permissions.get(self.folder.folder_id)
main_layout = QVBoxLayout()
owner_name = self.user_cache(self.folder.owner_id)
main_layout.addWidget(
QLabel(
f"Owner: {owner_name}\n"
+ f"Folder name: {self.folder.folder_name}\n"
+ f"Created at: {self.folder.created_at}"
)
)
for user_id, permissions in self.permissions.mapping.items():
layout = QHBoxLayout()
name = QLabel(self.user_cache(user_id).username)
combo = QComboBox()
combo.addItems(map(str, Permission))
combo.setCurrentText(str(permissions))
combo.currentTextChanged.connect(
partial(self.change, user_id=user_id)
)
delete = QPushButton("Delete")
delete.clicked.connect(
partial(
Permission.delete, self.folder.folder_id, user_id, self
)
)
layout.addWidget(name)
layout.addWidget(combo)
layout.addWidget(delete)
main_layout.addLayout(layout)
layout = QHBoxLayout()
self.search_str = QLineEdit()
layout.addWidget(self.search_str)
search = QPushButton("Search")
search.clicked.connect(self.search)
layout.addWidget(search)
main_layout.addLayout(layout)
layout = QHBoxLayout()
self.search_combo = QComboBox()
self.perm_combo = QComboBox()
self.perm_combo.addItems(map(str, Permission))
button = QPushButton("+")
button.clicked.connect(self.search_save)
layout.addWidget(self.search_combo)
layout.addWidget(self.perm_combo)
layout.addWidget(button)
main_layout.addLayout(layout)
if self.layout():
QWidget().setLayout(self.layout())
self.setLayout(main_layout)
def change(self, text: str, *, user_id: int):
Permission(text).set(self.folder.folder_id, user_id)
def search(self):
result = user.UserSearch.search(self.search_str.text())
self.search_combo.clear()
self.user_mapping.clear()
for item in result:
self.user_mapping[item.username] = item.user_id
self.search_combo.addItem(item.username)
def search_save(self):
permission = Permission(self.perm_combo.currentText())
user_id = self.user_mapping[self.search_combo.currentText()]
permission.set(self.folder.folder_id, user_id)
self.redraw()

View File

@ -27,9 +27,13 @@ class User(pydantic.BaseModel):
params["user_id"] = user_id
else:
url = "/users/current"
return User.model_validate_json(
RequestClient().client.get(url, params=params).text
)
response = RequestClient().client.get(url, params=params)
if not response.is_success:
QMessageBox.warning(
None, "Error getting permissions", response.text
)
return
return User.model_validate_json(response.text)
@staticmethod
def delete():