otripy 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- otripy/__init__.py +1 -0
- otripy/config.py +84 -0
- otripy/journey.py +58 -0
- otripy/location.py +46 -0
- otripy/main.py +898 -0
- otripy/nextcloud.py +232 -0
- otripy/nextcloud_uuid.py +34 -0
- otripy/nextcloud_with_api.py +203 -0
- otripy/note_widget.py +122 -0
- otripy/rename_popup.py +41 -0
- otripy/search_popup.py +45 -0
- otripy/toolbar.py +249 -0
- otripy-1.0.0.dist-info/METADATA +151 -0
- otripy-1.0.0.dist-info/RECORD +17 -0
- otripy-1.0.0.dist-info/WHEEL +5 -0
- otripy-1.0.0.dist-info/entry_points.txt +2 -0
- otripy-1.0.0.dist-info/top_level.txt +1 -0
otripy/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.0.0"
|
otripy/config.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from PySide6.QtGui import QAction
|
|
2
|
+
from PySide6.QtWidgets import QApplication, QMainWindow, QDialog, QLabel, QLineEdit, QPushButton, QVBoxLayout, QMenuBar
|
|
3
|
+
from PySide6.QtCore import QSettings
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ConfigDialog(QDialog):
|
|
7
|
+
"""Dialog for configuring Nextcloud settings"""
|
|
8
|
+
def __init__(self, settings, parent=None):
|
|
9
|
+
super().__init__(parent)
|
|
10
|
+
self.settings = settings
|
|
11
|
+
self.setWindowTitle("Configure Otripy")
|
|
12
|
+
|
|
13
|
+
# Create widgets
|
|
14
|
+
self.url_label = QLabel("Nextcloud URL:")
|
|
15
|
+
self.url_input = QLineEdit()
|
|
16
|
+
|
|
17
|
+
self.username_label = QLabel("Nextcloud Username:")
|
|
18
|
+
self.username_input = QLineEdit()
|
|
19
|
+
|
|
20
|
+
self.password_label = QLabel("Nextcloud Password:")
|
|
21
|
+
self.password_input = QLineEdit()
|
|
22
|
+
self.password_input.setEchoMode(QLineEdit.Password) # Hide password
|
|
23
|
+
|
|
24
|
+
self.save_button = QPushButton("Save")
|
|
25
|
+
self.save_button.clicked.connect(self.save_settings)
|
|
26
|
+
|
|
27
|
+
# Layout
|
|
28
|
+
layout = QVBoxLayout()
|
|
29
|
+
layout.addWidget(self.url_label)
|
|
30
|
+
layout.addWidget(self.url_input)
|
|
31
|
+
layout.addWidget(self.username_label)
|
|
32
|
+
layout.addWidget(self.username_input)
|
|
33
|
+
layout.addWidget(self.password_label)
|
|
34
|
+
layout.addWidget(self.password_input)
|
|
35
|
+
layout.addWidget(self.save_button)
|
|
36
|
+
self.setLayout(layout)
|
|
37
|
+
|
|
38
|
+
# Load existing settings
|
|
39
|
+
self.load_settings()
|
|
40
|
+
|
|
41
|
+
def load_settings(self):
|
|
42
|
+
"""Load settings from QSettings"""
|
|
43
|
+
self.url_input.setText(self.settings.value("nextcloud/url", ""))
|
|
44
|
+
self.username_input.setText(self.settings.value("nextcloud/username", ""))
|
|
45
|
+
self.password_input.setText(self.settings.value("nextcloud/password", ""))
|
|
46
|
+
|
|
47
|
+
def save_settings(self):
|
|
48
|
+
"""Save settings to QSettings"""
|
|
49
|
+
self.settings.setValue("nextcloud/url", self.url_input.text())
|
|
50
|
+
self.settings.setValue("nextcloud/username", self.username_input.text())
|
|
51
|
+
self.settings.setValue("nextcloud/password", self.password_input.text())
|
|
52
|
+
self.accept() # Close the dialog
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class MainWindow(QMainWindow):
|
|
56
|
+
"""Main Application Window"""
|
|
57
|
+
def __init__(self):
|
|
58
|
+
super().__init__()
|
|
59
|
+
self.setWindowTitle("MyApp")
|
|
60
|
+
self.setGeometry(100, 100, 800, 600)
|
|
61
|
+
|
|
62
|
+
# QSettings initialization
|
|
63
|
+
self.settings = QSettings("Kleag", "Otripy")
|
|
64
|
+
|
|
65
|
+
# Menu bar
|
|
66
|
+
menubar = self.menuBar()
|
|
67
|
+
config_menu = menubar.addMenu("Configuration")
|
|
68
|
+
|
|
69
|
+
# Configuration action
|
|
70
|
+
config_action = QAction("Configure MyApp", self)
|
|
71
|
+
config_action.triggered.connect(self.open_config_dialog)
|
|
72
|
+
config_menu.addAction(config_action)
|
|
73
|
+
|
|
74
|
+
def open_config_dialog(self):
|
|
75
|
+
"""Open the configuration dialog"""
|
|
76
|
+
dialog = ConfigDialog(self.settings, self)
|
|
77
|
+
dialog.exec()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
if __name__ == "__main__":
|
|
81
|
+
app = QApplication([])
|
|
82
|
+
window = MainWindow()
|
|
83
|
+
window.show()
|
|
84
|
+
app.exec()
|
otripy/journey.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from typing import List, Iterator
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
from .location import Location
|
|
5
|
+
except ImportError:
|
|
6
|
+
from location import Location
|
|
7
|
+
|
|
8
|
+
class Journey:
|
|
9
|
+
def __init__(self, locations: List[Location] = None):
|
|
10
|
+
"""Initialize the journey with a list of Location objects."""
|
|
11
|
+
self._locations = locations if locations is not None else []
|
|
12
|
+
|
|
13
|
+
def __getitem__(self, index):
|
|
14
|
+
"""Enable indexing and slicing."""
|
|
15
|
+
return self._locations[index]
|
|
16
|
+
|
|
17
|
+
def __setitem__(self, index, value: Location):
|
|
18
|
+
"""Enable item assignment."""
|
|
19
|
+
if not isinstance(value, Location):
|
|
20
|
+
raise TypeError("Only Location instances can be added to the journey.")
|
|
21
|
+
self._locations[index] = value
|
|
22
|
+
|
|
23
|
+
def __delitem__(self, index):
|
|
24
|
+
"""Enable item deletion."""
|
|
25
|
+
del self._locations[index]
|
|
26
|
+
|
|
27
|
+
def __iter__(self) -> Iterator[Location]:
|
|
28
|
+
"""Enable iteration."""
|
|
29
|
+
return iter(self._locations)
|
|
30
|
+
|
|
31
|
+
def __len__(self) -> int:
|
|
32
|
+
"""Return the number of locations in the journey."""
|
|
33
|
+
return len(self._locations)
|
|
34
|
+
|
|
35
|
+
def append(self, location: Location):
|
|
36
|
+
"""Add a location to the journey."""
|
|
37
|
+
if not isinstance(location, Location):
|
|
38
|
+
raise TypeError("Only Location instances can be added to the journey.")
|
|
39
|
+
self._locations.append(location)
|
|
40
|
+
|
|
41
|
+
def insert(self, index: int, location: Location):
|
|
42
|
+
"""Insert a location at a specific index."""
|
|
43
|
+
if not isinstance(location, Location):
|
|
44
|
+
raise TypeError("Only Location instances can be inserted into the journey.")
|
|
45
|
+
self._locations.insert(index, location)
|
|
46
|
+
|
|
47
|
+
def remove(self, location: Location):
|
|
48
|
+
"""Remove a location from the journey."""
|
|
49
|
+
self._locations.remove(location)
|
|
50
|
+
|
|
51
|
+
def __repr__(self) -> str:
|
|
52
|
+
return f"Journey({self._locations})"
|
|
53
|
+
|
|
54
|
+
def loc_by_id(self, id: str) -> Location:
|
|
55
|
+
for loc in self:
|
|
56
|
+
if loc.id == id:
|
|
57
|
+
return loc
|
|
58
|
+
return None
|
otripy/location.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import uuid
|
|
3
|
+
|
|
4
|
+
from typing import Dict
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
class Location:
|
|
9
|
+
def __init__(self,
|
|
10
|
+
lat: float = 0.0,
|
|
11
|
+
lon: float = 0.0,
|
|
12
|
+
note: Dict[str, str] = {"markdown": ""},
|
|
13
|
+
id: str = str(uuid.uuid4())):
|
|
14
|
+
logger.info(f"Location({lat}, {lon}, {note}, {id})")
|
|
15
|
+
self.id = id
|
|
16
|
+
self.lat = lat
|
|
17
|
+
self.lon = lon
|
|
18
|
+
self.note = note
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def from_data(cls, data: Dict[str, str | dict] = {}):
|
|
22
|
+
logger.info(f"Location.from_data({data})")
|
|
23
|
+
lat = float(data["lat"]) if "lat" in data else 0.0
|
|
24
|
+
lon = float(data["lon"]) if "lon" in data else 0.0
|
|
25
|
+
note = data["note"] if "note" in data else {"markdown": ""}
|
|
26
|
+
if type(note) is str:
|
|
27
|
+
note = {"markdown": note}
|
|
28
|
+
id = data["id"] if "id" in data else str(uuid.uuid4())
|
|
29
|
+
return cls(lat, lon, note, id)
|
|
30
|
+
|
|
31
|
+
def label(self):
|
|
32
|
+
return self.note["markdown"].split('\n')[0]
|
|
33
|
+
|
|
34
|
+
def to_html(self):
|
|
35
|
+
return self.note["markdown"].split('\n')[0].replace("\n", "<br>")
|
|
36
|
+
|
|
37
|
+
def location(self):
|
|
38
|
+
return [self.lat, self.lon]
|
|
39
|
+
|
|
40
|
+
def to_dict(self):
|
|
41
|
+
return {
|
|
42
|
+
"id": self.id,
|
|
43
|
+
"lat": self.lat,
|
|
44
|
+
"lon": self.lon,
|
|
45
|
+
"note": self.note
|
|
46
|
+
}
|