-
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #300 from bohning/custom-data
Custom data
- Loading branch information
Showing
19 changed files
with
406 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
"""Data structure for storing user defined custom data.""" | ||
|
||
import builtins | ||
import collections.abc | ||
from collections import defaultdict | ||
|
||
from usdb_syncer import db | ||
|
||
|
||
class CustomData: | ||
"""Dict of custom data.""" | ||
|
||
_data: dict[str, str] | ||
_options: defaultdict[str, builtins.set[str]] | None = None | ||
FORBIDDEN_KEY_CHARS = '?"<>|*.:/\\' | ||
|
||
@classmethod | ||
def value_options(cls, key: str) -> tuple[str, ...]: | ||
if cls._options is None: | ||
cls._options = db.get_custom_data_map() | ||
# pylingt bug: https://github.com/pylint-dev/pylint/issues/9515 | ||
return tuple(cls._options[key]) # pylint: disable=unsubscriptable-object | ||
|
||
@classmethod | ||
def key_options(cls) -> tuple[str, ...]: | ||
if cls._options is None: | ||
cls._options = db.get_custom_data_map() | ||
return tuple(cls._options) # pylint: disable=unsubscriptable-object | ||
|
||
@classmethod | ||
def is_valid_key(cls, key: str) -> bool: | ||
return ( | ||
bool(key) | ||
and key.strip() == key | ||
and not any(c in key for c in cls.FORBIDDEN_KEY_CHARS) | ||
) | ||
|
||
def __init__(self, data: dict[str, str] | None = None) -> None: | ||
self._data = data.copy() if data else {} | ||
|
||
def get(self, key: str) -> str | None: | ||
return self._data.get(key) | ||
|
||
def set(self, key: str, value: str | None) -> None: | ||
if value is None: | ||
if key in self._data: | ||
del self._data[key] | ||
else: | ||
self._data[key] = value | ||
if self._options is not None: | ||
self._options[key].add(value) # pylint: disable=unsubscriptable-object | ||
|
||
def items(self) -> collections.abc.ItemsView[str, str]: | ||
return self._data.items() | ||
|
||
def inner(self) -> dict[str, str]: | ||
return self._data.copy() | ||
|
||
def __eq__(self, value: object) -> bool: | ||
return isinstance(value, CustomData) and self._data == value._data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
BEGIN; | ||
|
||
CREATE TABLE custom_meta_data ( | ||
sync_meta_id INTEGER NOT NULL, | ||
key TEXT NOT NULL, | ||
value TEXT NOT NULL, | ||
PRIMARY KEY (sync_meta_id, key), | ||
FOREIGN KEY (sync_meta_id) REFERENCES sync_meta (sync_meta_id) ON DELETE CASCADE | ||
); | ||
|
||
END; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
INSERT INTO | ||
custom_meta_data | ||
VALUES | ||
(:sync_meta_id, :key, :value) ON CONFLICT (sync_meta_id, key) DO | ||
UPDATE | ||
SET | ||
value = :value |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
"""Dialog for adding custom sync meta data.""" | ||
|
||
from typing import Callable | ||
|
||
from PySide6 import QtWidgets | ||
|
||
from usdb_syncer.custom_data import CustomData | ||
from usdb_syncer.gui.forms.CustomDataDialog import Ui_Dialog | ||
|
||
FORBIDDEN_CHARS = '?"<>|*.:/\\' | ||
|
||
|
||
class CustomDataDialog(Ui_Dialog, QtWidgets.QDialog): | ||
"""Dialog with about info and credits.""" | ||
|
||
def __init__( | ||
self, | ||
parent: QtWidgets.QWidget, | ||
on_accept: Callable[[str, str], None], | ||
key: str | None = None, | ||
) -> None: | ||
super().__init__(parent=parent) | ||
self.setupUi(self) | ||
self._on_accept = on_accept | ||
if key: | ||
self.edit_key.setText(key) | ||
|
||
def accept(self) -> None: | ||
key = self.edit_key.text().strip() | ||
value = self.edit_value.text().strip() | ||
if not key or not value: | ||
warning = "Both key and value must be supplied!" | ||
QtWidgets.QMessageBox.warning( | ||
self, "Warning", "Both key and value must be supplied!" | ||
) | ||
elif not CustomData.is_valid_key(key): | ||
warning = ( | ||
"Key must not contain any of these characters: " | ||
+ CustomData.FORBIDDEN_KEY_CHARS | ||
) | ||
else: | ||
self._on_accept(key, value) | ||
super().accept() | ||
return | ||
QtWidgets.QMessageBox.warning(self, "Warning", warning) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ui version="4.0"> | ||
<class>Dialog</class> | ||
<widget class="QDialog" name="Dialog"> | ||
<property name="geometry"> | ||
<rect> | ||
<x>0</x> | ||
<y>0</y> | ||
<width>353</width> | ||
<height>145</height> | ||
</rect> | ||
</property> | ||
<property name="windowTitle"> | ||
<string>Dialog</string> | ||
</property> | ||
<layout class="QFormLayout" name="formLayout"> | ||
<item row="1" column="0"> | ||
<widget class="QLabel" name="label"> | ||
<property name="text"> | ||
<string>Key</string> | ||
</property> | ||
</widget> | ||
</item> | ||
<item row="1" column="1"> | ||
<widget class="QLineEdit" name="edit_key"> | ||
<property name="maxLength"> | ||
<number>100</number> | ||
</property> | ||
</widget> | ||
</item> | ||
<item row="3" column="0"> | ||
<widget class="QLabel" name="label_2"> | ||
<property name="text"> | ||
<string>Value</string> | ||
</property> | ||
</widget> | ||
</item> | ||
<item row="3" column="1"> | ||
<widget class="QLineEdit" name="edit_value"/> | ||
</item> | ||
<item row="4" column="1"> | ||
<spacer name="verticalSpacer_2"> | ||
<property name="orientation"> | ||
<enum>Qt::Orientation::Vertical</enum> | ||
</property> | ||
<property name="sizeHint" stdset="0"> | ||
<size> | ||
<width>20</width> | ||
<height>40</height> | ||
</size> | ||
</property> | ||
</spacer> | ||
</item> | ||
<item row="5" column="0" colspan="2"> | ||
<widget class="QDialogButtonBox" name="buttonBox"> | ||
<property name="orientation"> | ||
<enum>Qt::Orientation::Horizontal</enum> | ||
</property> | ||
<property name="standardButtons"> | ||
<set>QDialogButtonBox::StandardButton::Ok</set> | ||
</property> | ||
</widget> | ||
</item> | ||
</layout> | ||
</widget> | ||
<resources/> | ||
<connections> | ||
<connection> | ||
<sender>buttonBox</sender> | ||
<signal>accepted()</signal> | ||
<receiver>Dialog</receiver> | ||
<slot>accept()</slot> | ||
<hints> | ||
<hint type="sourcelabel"> | ||
<x>248</x> | ||
<y>254</y> | ||
</hint> | ||
<hint type="destinationlabel"> | ||
<x>157</x> | ||
<y>274</y> | ||
</hint> | ||
</hints> | ||
</connection> | ||
<connection> | ||
<sender>buttonBox</sender> | ||
<signal>rejected()</signal> | ||
<receiver>Dialog</receiver> | ||
<slot>reject()</slot> | ||
<hints> | ||
<hint type="sourcelabel"> | ||
<x>316</x> | ||
<y>260</y> | ||
</hint> | ||
<hint type="destinationlabel"> | ||
<x>286</x> | ||
<y>274</y> | ||
</hint> | ||
</hints> | ||
</connection> | ||
</connections> | ||
</ui> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.