winipedia-utils 0.2.0__py3-none-any.whl → 0.2.1__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.

Potentially problematic release.


This version of winipedia-utils might be problematic. Click here for more details.

Files changed (90) hide show
  1. winipedia_utils/concurrent/concurrent.py +245 -245
  2. winipedia_utils/concurrent/multiprocessing.py +130 -130
  3. winipedia_utils/concurrent/multithreading.py +93 -93
  4. winipedia_utils/consts.py +21 -23
  5. winipedia_utils/data/__init__.py +1 -1
  6. winipedia_utils/data/dataframe/__init__.py +1 -1
  7. winipedia_utils/data/dataframe/cleaning.py +378 -378
  8. winipedia_utils/data/structures/__init__.py +1 -1
  9. winipedia_utils/data/structures/dicts.py +16 -16
  10. winipedia_utils/git/__init__.py +1 -1
  11. winipedia_utils/git/gitignore/__init__.py +1 -1
  12. winipedia_utils/git/gitignore/gitignore.py +136 -136
  13. winipedia_utils/git/pre_commit/__init__.py +1 -1
  14. winipedia_utils/git/pre_commit/config.py +70 -70
  15. winipedia_utils/git/pre_commit/hooks.py +109 -109
  16. winipedia_utils/git/pre_commit/run_hooks.py +49 -49
  17. winipedia_utils/iterating/__init__.py +1 -1
  18. winipedia_utils/iterating/iterate.py +29 -29
  19. winipedia_utils/logging/ansi.py +6 -6
  20. winipedia_utils/logging/config.py +64 -64
  21. winipedia_utils/logging/logger.py +26 -26
  22. winipedia_utils/modules/class_.py +119 -119
  23. winipedia_utils/modules/function.py +101 -101
  24. winipedia_utils/modules/module.py +379 -379
  25. winipedia_utils/modules/package.py +390 -390
  26. winipedia_utils/oop/mixins/meta.py +333 -333
  27. winipedia_utils/oop/mixins/mixin.py +37 -37
  28. winipedia_utils/os/__init__.py +1 -1
  29. winipedia_utils/os/os.py +63 -63
  30. winipedia_utils/projects/__init__.py +1 -1
  31. winipedia_utils/projects/poetry/__init__.py +1 -1
  32. winipedia_utils/projects/poetry/config.py +91 -91
  33. winipedia_utils/projects/poetry/poetry.py +31 -31
  34. winipedia_utils/projects/project.py +48 -48
  35. winipedia_utils/resources/__init__.py +1 -1
  36. winipedia_utils/resources/svgs/__init__.py +1 -1
  37. winipedia_utils/resources/svgs/download_arrow.svg +2 -2
  38. winipedia_utils/resources/svgs/exit_fullscreen_icon.svg +5 -5
  39. winipedia_utils/resources/svgs/fullscreen_icon.svg +2 -2
  40. winipedia_utils/resources/svgs/menu_icon.svg +3 -3
  41. winipedia_utils/resources/svgs/pause_icon.svg +3 -3
  42. winipedia_utils/resources/svgs/play_icon.svg +16 -16
  43. winipedia_utils/resources/svgs/plus_icon.svg +23 -23
  44. winipedia_utils/resources/svgs/svg.py +15 -15
  45. winipedia_utils/security/__init__.py +1 -1
  46. winipedia_utils/security/cryptography.py +29 -29
  47. winipedia_utils/security/keyring.py +70 -70
  48. winipedia_utils/setup.py +47 -47
  49. winipedia_utils/testing/assertions.py +23 -23
  50. winipedia_utils/testing/convention.py +177 -177
  51. winipedia_utils/testing/create_tests.py +291 -291
  52. winipedia_utils/testing/fixtures.py +28 -28
  53. winipedia_utils/testing/tests/base/fixtures/__init__.py +1 -1
  54. winipedia_utils/testing/tests/base/fixtures/fixture.py +6 -6
  55. winipedia_utils/testing/tests/base/fixtures/scopes/class_.py +33 -33
  56. winipedia_utils/testing/tests/base/fixtures/scopes/function.py +7 -7
  57. winipedia_utils/testing/tests/base/fixtures/scopes/module.py +31 -31
  58. winipedia_utils/testing/tests/base/fixtures/scopes/package.py +7 -7
  59. winipedia_utils/testing/tests/base/fixtures/scopes/session.py +312 -312
  60. winipedia_utils/testing/tests/base/utils/utils.py +82 -82
  61. winipedia_utils/testing/tests/conftest.py +32 -32
  62. winipedia_utils/text/string.py +126 -126
  63. {winipedia_utils-0.2.0.dist-info → winipedia_utils-0.2.1.dist-info}/METADATA +1 -4
  64. winipedia_utils-0.2.1.dist-info/RECORD +80 -0
  65. {winipedia_utils-0.2.0.dist-info → winipedia_utils-0.2.1.dist-info}/licenses/LICENSE +21 -21
  66. winipedia_utils/django/__init__.py +0 -24
  67. winipedia_utils/django/bulk.py +0 -538
  68. winipedia_utils/django/command.py +0 -334
  69. winipedia_utils/django/database.py +0 -289
  70. winipedia_utils/pyside/__init__.py +0 -1
  71. winipedia_utils/pyside/core/__init__.py +0 -1
  72. winipedia_utils/pyside/core/py_qiodevice.py +0 -476
  73. winipedia_utils/pyside/ui/__init__.py +0 -1
  74. winipedia_utils/pyside/ui/base/__init__.py +0 -1
  75. winipedia_utils/pyside/ui/base/base.py +0 -180
  76. winipedia_utils/pyside/ui/pages/__init__.py +0 -1
  77. winipedia_utils/pyside/ui/pages/base/__init__.py +0 -1
  78. winipedia_utils/pyside/ui/pages/base/base.py +0 -92
  79. winipedia_utils/pyside/ui/pages/browser.py +0 -26
  80. winipedia_utils/pyside/ui/pages/player.py +0 -85
  81. winipedia_utils/pyside/ui/widgets/__init__.py +0 -1
  82. winipedia_utils/pyside/ui/widgets/browser.py +0 -243
  83. winipedia_utils/pyside/ui/widgets/clickable_widget.py +0 -57
  84. winipedia_utils/pyside/ui/widgets/media_player.py +0 -430
  85. winipedia_utils/pyside/ui/widgets/notification.py +0 -78
  86. winipedia_utils/pyside/ui/windows/__init__.py +0 -1
  87. winipedia_utils/pyside/ui/windows/base/__init__.py +0 -1
  88. winipedia_utils/pyside/ui/windows/base/base.py +0 -49
  89. winipedia_utils-0.2.0.dist-info/RECORD +0 -103
  90. {winipedia_utils-0.2.0.dist-info → winipedia_utils-0.2.1.dist-info}/WHEEL +0 -0
@@ -1,430 +0,0 @@
1
- """Media player module.
2
-
3
- This module contains the media player class.
4
- """
5
-
6
- import time
7
- from functools import partial
8
- from pathlib import Path
9
- from typing import Any
10
-
11
- from cryptography.hazmat.primitives.ciphers.aead import AESGCM
12
- from PySide6.QtCore import Qt, QTimer, QUrl
13
- from PySide6.QtMultimedia import QAudioOutput, QMediaPlayer
14
- from PySide6.QtWidgets import (
15
- QHBoxLayout,
16
- QLayout,
17
- QMenu,
18
- QPushButton,
19
- QSizePolicy,
20
- QSlider,
21
- QVBoxLayout,
22
- QWidget,
23
- )
24
-
25
- from winipedia_utils.pyside.core.py_qiodevice import (
26
- EncryptedPyQFile,
27
- PyQFile,
28
- PyQIODevice,
29
- )
30
- from winipedia_utils.pyside.ui.base.base import Base as BaseUI
31
- from winipedia_utils.pyside.ui.widgets.clickable_widget import ClickableVideoWidget
32
-
33
-
34
- class MediaPlayer(QMediaPlayer):
35
- """Media player class."""
36
-
37
- def __init__(self, parent_layout: QLayout, *args: Any, **kwargs: Any) -> None:
38
- """Initialize the media player.
39
-
40
- Args:
41
- parent_layout: The parent layout to add the media player widget to.
42
- *args: Additional positional arguments passed to parent constructor.
43
- **kwargs: Additional keyword arguments passed to parent constructor.
44
- """
45
- super().__init__(*args, **kwargs)
46
- self.parent_layout = parent_layout
47
- self.io_device: PyQIODevice | None = None
48
- self.make_widget()
49
-
50
- def make_widget(self) -> None:
51
- """Make the widget.
52
-
53
- Creates the main media player widget with vertical layout, adds media controls
54
- above and below the video widget, and creates the video widget itself.
55
- """
56
- self.media_player_widget = QWidget()
57
- self.media_player_layout = QVBoxLayout(self.media_player_widget)
58
- self.parent_layout.addWidget(self.media_player_widget)
59
- self.add_media_controls_above()
60
- self.make_video_widget()
61
- self.add_media_controls_below()
62
-
63
- def make_video_widget(self) -> None:
64
- """Make the video widget.
65
-
66
- Creates a clickable video widget with expanding size policy, sets up
67
- audio output, and connects the click signal to toggle media controls.
68
- """
69
- self.video_widget = ClickableVideoWidget()
70
- self.video_widget.clicked.connect(self.on_video_clicked)
71
- self.video_widget.setSizePolicy(
72
- QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding
73
- )
74
- self.setVideoOutput(self.video_widget)
75
-
76
- self.audio_output = QAudioOutput()
77
- self.setAudioOutput(self.audio_output)
78
-
79
- self.media_player_layout.addWidget(self.video_widget)
80
-
81
- def on_video_clicked(self) -> None:
82
- """Handle video widget click.
83
-
84
- Toggles the visibility of media controls when the video widget is clicked.
85
- """
86
- if self.media_controls_widget_above.isVisible():
87
- self.hide_media_controls()
88
- return
89
- self.show_media_controls()
90
-
91
- def show_media_controls(self) -> None:
92
- """Show media controls.
93
-
94
- Makes both the above and below media control widgets visible.
95
- """
96
- self.media_controls_widget_above.show()
97
- self.media_controls_widget_below.show()
98
-
99
- def hide_media_controls(self) -> None:
100
- """Hide media controls.
101
-
102
- Hides both the above and below media control widgets.
103
- """
104
- self.media_controls_widget_above.hide()
105
- self.media_controls_widget_below.hide()
106
-
107
- def add_media_controls_above(self) -> None:
108
- """Add media controls above the video.
109
-
110
- Creates the top control bar with left, center, and right sections,
111
- then adds speed, volume, playback, and fullscreen controls.
112
- """
113
- # main above widget
114
- self.media_controls_widget_above = QWidget()
115
- self.media_controls_layout_above = QHBoxLayout(self.media_controls_widget_above)
116
- self.media_player_layout.addWidget(self.media_controls_widget_above)
117
- # left contorls
118
- self.left_controls_widget = QWidget()
119
- self.left_controls_layout = QHBoxLayout(self.left_controls_widget)
120
- self.media_controls_layout_above.addWidget(
121
- self.left_controls_widget, alignment=Qt.AlignmentFlag.AlignLeft
122
- )
123
- # center contorls
124
- self.center_controls_widget = QWidget()
125
- self.center_controls_layout = QHBoxLayout(self.center_controls_widget)
126
- self.media_controls_layout_above.addWidget(
127
- self.center_controls_widget, alignment=Qt.AlignmentFlag.AlignCenter
128
- )
129
- self.right_controls_widget = QWidget()
130
- self.right_controls_layout = QHBoxLayout(self.right_controls_widget)
131
- self.media_controls_layout_above.addWidget(
132
- self.right_controls_widget, alignment=Qt.AlignmentFlag.AlignRight
133
- )
134
-
135
- self.add_speed_control()
136
- self.add_volume_control()
137
- self.add_playback_control()
138
- self.add_fullscreen_control()
139
-
140
- def add_media_controls_below(self) -> None:
141
- """Add media controls below the video.
142
-
143
- Creates the bottom control bar and adds the progress control slider.
144
- """
145
- self.media_controls_widget_below = QWidget()
146
- self.media_controls_layout_below = QHBoxLayout(self.media_controls_widget_below)
147
- self.media_player_layout.addWidget(self.media_controls_widget_below)
148
- self.add_progress_control()
149
-
150
- def add_playback_control(self) -> None:
151
- """Add playback control.
152
-
153
- Creates a play/pause button with appropriate icons and connects it
154
- to the toggle_playback method. Adds the button to the center controls.
155
- """
156
- self.play_icon = BaseUI.get_svg_icon("play_icon")
157
- self.pause_icon = BaseUI.get_svg_icon("pause_icon")
158
- # Pause symbol: ⏸ (U+23F8)
159
- self.playback_button = QPushButton()
160
- self.playback_button.setIcon(self.pause_icon)
161
- self.playback_button.clicked.connect(self.toggle_playback)
162
-
163
- self.center_controls_layout.addWidget(self.playback_button)
164
-
165
- def toggle_playback(self) -> None:
166
- """Toggle playback.
167
-
168
- Switches between play and pause states, updating the button icon
169
- accordingly based on the current playback state.
170
- """
171
- if self.playbackState() == QMediaPlayer.PlaybackState.PlayingState:
172
- self.pause()
173
- self.playback_button.setIcon(self.play_icon)
174
- else:
175
- self.play()
176
- self.playback_button.setIcon(self.pause_icon)
177
-
178
- def add_speed_control(self) -> None:
179
- """Add speed control.
180
-
181
- Creates a button in the top left that shows a dropdown menu to select
182
- playback speed from predefined options (0.2x to 5x).
183
- """
184
- self.default_speed = 1
185
- self.speed_options = [0.2, 0.5, self.default_speed, 1.5, 2, 3, 4, 5]
186
- self.speed_button = QPushButton(f"{self.default_speed}x")
187
- self.speed_menu = QMenu(self.speed_button)
188
- for speed in self.speed_options:
189
- action = self.speed_menu.addAction(f"{speed}x")
190
- action.triggered.connect(partial(self.change_speed, speed))
191
-
192
- self.speed_button.setMenu(self.speed_menu)
193
- self.left_controls_layout.addWidget(self.speed_button)
194
-
195
- def change_speed(self, speed: float) -> None:
196
- """Change playback speed.
197
-
198
- Args:
199
- speed: The new playback speed multiplier.
200
- """
201
- self.setPlaybackRate(speed)
202
- self.speed_button.setText(f"{speed}x")
203
-
204
- def add_volume_control(self) -> None:
205
- """Add volume control.
206
-
207
- Creates a horizontal slider for volume control with range 0-100
208
- and connects it to the volume change handler.
209
- """
210
- self.volume_slider = QSlider(Qt.Orientation.Horizontal)
211
- self.volume_slider.setRange(0, 100)
212
- self.volume_slider.valueChanged.connect(self.on_volume_changed)
213
- self.left_controls_layout.addWidget(self.volume_slider)
214
-
215
- def on_volume_changed(self, value: int) -> None:
216
- """Handle volume slider value change.
217
-
218
- Args:
219
- value: The new volume value from 0-100.
220
- """
221
- volume = value / 100.0 # Convert to 0.0-1.0 range
222
- self.audio_output.setVolume(volume)
223
-
224
- def add_fullscreen_control(self) -> None:
225
- """Add fullscreen control.
226
-
227
- Creates a fullscreen toggle button with appropriate icons and determines
228
- which widgets to hide/show when entering/exiting fullscreen mode.
229
- """
230
- self.fullscreen_icon = BaseUI.get_svg_icon("fullscreen_icon")
231
- self.exit_fullscreen_icon = BaseUI.get_svg_icon("exit_fullscreen_icon")
232
- self.fullscreen_button = QPushButton()
233
- self.fullscreen_button.setIcon(self.fullscreen_icon)
234
-
235
- self.parent_widget = self.parent_layout.parentWidget()
236
- self.other_visible_widgets = [
237
- w
238
- for w in set(self.parent_widget.findChildren(QWidget))
239
- - {
240
- self.media_player_widget,
241
- *self.media_player_widget.findChildren(QWidget),
242
- }
243
- if w.isVisible() or not (w.isHidden() or w.isVisible())
244
- ]
245
- self.fullscreen_button.clicked.connect(self.toggle_fullscreen)
246
-
247
- self.right_controls_layout.addWidget(self.fullscreen_button)
248
-
249
- def toggle_fullscreen(self) -> None:
250
- """Toggle fullscreen mode.
251
-
252
- Switches between fullscreen and windowed mode, hiding/showing other
253
- widgets and updating the button icon accordingly.
254
- """
255
- # Get the main window
256
- main_window = self.media_player_widget.window()
257
- if main_window.isFullScreen():
258
- for widget in self.other_visible_widgets:
259
- widget.show()
260
- # show the window in the previous size
261
- main_window.showMaximized()
262
- self.fullscreen_button.setIcon(self.fullscreen_icon)
263
- else:
264
- for widget in self.other_visible_widgets:
265
- widget.hide()
266
- main_window.showFullScreen()
267
- self.fullscreen_button.setIcon(self.exit_fullscreen_icon)
268
-
269
- def add_progress_control(self) -> None:
270
- """Add progress control.
271
-
272
- Creates a horizontal progress slider and connects it to media player
273
- signals for position updates and user interaction handling.
274
- """
275
- self.progress_slider = QSlider(Qt.Orientation.Horizontal)
276
- self.media_controls_layout_below.addWidget(self.progress_slider)
277
-
278
- # Connect media player signals to update the progress slider
279
- self.positionChanged.connect(self.update_slider_position)
280
- self.durationChanged.connect(self.set_slider_range)
281
-
282
- # Connect slider signals to update video position
283
- self.last_slider_moved_update = time.time()
284
- self.slider_moved_update_interval = 0.1
285
- self.progress_slider.sliderMoved.connect(self.on_slider_moved)
286
- self.progress_slider.sliderReleased.connect(self.on_slider_released)
287
-
288
- def update_slider_position(self, position: int) -> None:
289
- """Update the progress slider position.
290
-
291
- Args:
292
- position: The current media position in milliseconds.
293
- """
294
- # Only update if not being dragged to prevent jumps during manual sliding
295
- if not self.progress_slider.isSliderDown():
296
- self.progress_slider.setValue(position)
297
-
298
- def set_slider_range(self, duration: int) -> None:
299
- """Set the progress slider range based on media duration.
300
-
301
- Args:
302
- duration: The total media duration in milliseconds.
303
- """
304
- self.progress_slider.setRange(0, duration)
305
-
306
- def on_slider_moved(self, position: int) -> None:
307
- """Set the media position when slider is moved.
308
-
309
- Implements throttling to prevent excessive position updates during
310
- slider dragging for better performance.
311
-
312
- Args:
313
- position: The new position from the slider in milliseconds.
314
- """
315
- current_time = time.time()
316
- if (
317
- current_time - self.last_slider_moved_update
318
- > self.slider_moved_update_interval
319
- ):
320
- self.setPosition(position)
321
- self.last_slider_moved_update = current_time
322
-
323
- def on_slider_released(self) -> None:
324
- """Handle slider release event.
325
-
326
- Sets the final media position when the user releases the slider.
327
- """
328
- self.setPosition(self.progress_slider.value())
329
-
330
- def play_video(
331
- self,
332
- io_device: PyQIODevice,
333
- source_url: QUrl,
334
- position: int = 0,
335
- ) -> None:
336
- """Play the video.
337
-
338
- Stops current playback and starts a new video using the provided
339
- source function with a delay to prevent freezing.
340
-
341
- Args:
342
- io_device: The PyQIODevice to use as the media source.
343
- source_url: The QUrl representing the source location.
344
- position: The position to start playback from in milliseconds.
345
- """
346
- self.stop_and_close_io_device()
347
-
348
- self.resume_func = partial(self.resume_to_position, position=position)
349
- self.mediaStatusChanged.connect(self.resume_func)
350
-
351
- # SingleShot prevents freezing when starting new video while another is playing
352
- QTimer.singleShot(
353
- 100,
354
- partial(
355
- self.set_source_and_play, io_device=io_device, source_url=source_url
356
- ),
357
- )
358
-
359
- def stop_and_close_io_device(self) -> None:
360
- """Stop playback and close the IO device."""
361
- self.stop()
362
- if self.io_device is not None:
363
- self.io_device.close()
364
-
365
- def resume_to_position(
366
- self, status: QMediaPlayer.MediaStatus, position: int
367
- ) -> None:
368
- """Resume playback to a position.
369
-
370
- Args:
371
- status: The current media status.
372
- position: The position to resume playback from in milliseconds.
373
- """
374
- if status == QMediaPlayer.MediaStatus.BufferedMedia:
375
- self.setPosition(position)
376
- self.mediaStatusChanged.disconnect(self.resume_func)
377
-
378
- def set_source_and_play(
379
- self,
380
- io_device: PyQIODevice,
381
- source_url: QUrl,
382
- ) -> None:
383
- """Set the source and play the video.
384
-
385
- Args:
386
- io_device: The PyQIODevice to use as the media source.
387
- source_url: The QUrl representing the source location.
388
- """
389
- self.set_source_device(io_device, source_url)
390
- self.play()
391
-
392
- def set_source_device(self, io_device: PyQIODevice, source_url: QUrl) -> None:
393
- """Set the source device for playback.
394
-
395
- Args:
396
- io_device: The PyQIODevice to use as the media source.
397
- source_url: The QUrl representing the source location.
398
- """
399
- self.source_url = source_url
400
- self.io_device = io_device
401
- self.setSourceDevice(self.io_device, self.source_url)
402
-
403
- def play_file(self, path: Path, position: int = 0) -> None:
404
- """Play a regular video file.
405
-
406
- Args:
407
- path: The file path to the video file to play.
408
- position: The position to start playback from in milliseconds.
409
- """
410
- self.play_video(
411
- position=position,
412
- io_device=PyQFile(path),
413
- source_url=QUrl.fromLocalFile(path),
414
- )
415
-
416
- def play_encrypted_file(
417
- self, path: Path, aes_gcm: AESGCM, position: int = 0
418
- ) -> None:
419
- """Play an encrypted video file.
420
-
421
- Args:
422
- path: The file path to the encrypted video file to play.
423
- aes_gcm: The AES-GCM cipher instance for decryption.
424
- position: The position to start playback from in milliseconds.
425
- """
426
- self.play_video(
427
- position=position,
428
- io_device=EncryptedPyQFile(path, aes_gcm),
429
- source_url=QUrl.fromLocalFile(path),
430
- )
@@ -1,78 +0,0 @@
1
- """Notification module.
2
-
3
- This module contains functions to show notifications.
4
- """
5
-
6
- from pyqttoast import Toast, ToastIcon, ToastPosition # type: ignore[import-untyped]
7
- from PySide6.QtWidgets import QApplication
8
-
9
- from winipedia_utils.text.string import value_to_truncated_string
10
-
11
- Toast.setPosition(ToastPosition.TOP_MIDDLE)
12
-
13
-
14
- class Notification(Toast): # type: ignore[misc]
15
- """Notification class."""
16
-
17
- def __init__(
18
- self,
19
- title: str,
20
- text: str,
21
- icon: ToastIcon = ToastIcon.INFORMATION,
22
- duration: int = 10000,
23
- ) -> None:
24
- """Initialize the notification.
25
-
26
- The notification is shown in the top middle of the screen.
27
-
28
- Args:
29
- title: The title of the notification.
30
- text: The text of the notification.
31
- icon: The icon of the notification. Defaults to INFORMATION.
32
- duration: The duration of the notification in milliseconds.
33
- Defaults to 10000.
34
- """
35
- super().__init__(QApplication.activeWindow())
36
- self.setDuration(duration)
37
- self.setIcon(icon)
38
- self.set_title(title)
39
- self.set_text(text)
40
-
41
- def set_title(self, title: str) -> None:
42
- """Set the title of the notification.
43
-
44
- Truncates the title to fit within half the window width before setting it.
45
-
46
- Args:
47
- title: The title text to set.
48
- """
49
- title = self.str_to_half_window_width(title)
50
- self.setTitle(title)
51
-
52
- def set_text(self, text: str) -> None:
53
- """Set the text of the notification.
54
-
55
- Truncates the text to fit within half the window width before setting it.
56
-
57
- Args:
58
- text: The notification text to set.
59
- """
60
- text = self.str_to_half_window_width(text)
61
- self.setText(text)
62
-
63
- def str_to_half_window_width(self, string: str) -> str:
64
- """Truncate the string to the width of the active window.
65
-
66
- Calculates half the width of the active window and truncates the string
67
- to fit within that width. Falls back to 500 pixels if no active window.
68
-
69
- Args:
70
- string: The string to truncate.
71
-
72
- Returns:
73
- The truncated string that fits within half the window width.
74
- """
75
- main_window = QApplication.activeWindow()
76
- width = main_window.width() / 2 if main_window is not None else 500
77
- width = int(width)
78
- return value_to_truncated_string(string, width)
@@ -1 +0,0 @@
1
- """__init__ module."""
@@ -1 +0,0 @@
1
- """__init__ module."""
@@ -1,49 +0,0 @@
1
- """Base window module.
2
-
3
- This module contains the base window class for the VideoVault application.
4
- """
5
-
6
- from abc import abstractmethod
7
-
8
- from PySide6.QtWidgets import QMainWindow, QStackedWidget
9
-
10
- from winipedia_utils.pyside.ui.base.base import Base as BaseUI
11
- from winipedia_utils.pyside.ui.pages.base.base import Base as BasePage
12
-
13
-
14
- class Base(BaseUI, QMainWindow):
15
- """Base window class for the VideoVault application."""
16
-
17
- @classmethod
18
- @abstractmethod
19
- def get_all_page_classes(cls) -> list[type[BasePage]]:
20
- """Get all page classes."""
21
-
22
- @classmethod
23
- @abstractmethod
24
- def get_start_page_cls(cls) -> type[BasePage]:
25
- """Get the start page class."""
26
-
27
- def base_setup(self) -> None:
28
- """Get the Qt object of the UI."""
29
- self.setWindowTitle(self.get_display_name())
30
-
31
- self.stack = QStackedWidget()
32
- self.setCentralWidget(self.stack)
33
-
34
- self.make_pages()
35
-
36
- self.set_start_page()
37
-
38
- def make_pages(self) -> None:
39
- """Get the pages to add to the window."""
40
- for page_cls in self.get_all_page_classes():
41
- page_cls(base_window=self)
42
-
43
- def set_start_page(self) -> None:
44
- """Set the start page."""
45
- self.set_current_page(self.get_start_page_cls())
46
-
47
- def add_page(self, page: BasePage) -> None:
48
- """Add the pages to the window."""
49
- self.stack.addWidget(page)
@@ -1,103 +0,0 @@
1
- winipedia_utils/__init__.py,sha256=vOWZ8n-YemVIzDLd8eWw1HVPGH3jxuT6VtDKHbmxk_A,43
2
- winipedia_utils/concurrent/__init__.py,sha256=Tu0ig4gVCk_f1n74G35hDwH-WS3P3STVQGWjxTIbbo8,54
3
- winipedia_utils/concurrent/concurrent.py,sha256=b-el36KyB1cT23Fog9Ix1TT386XF9iWahsRTX5N19TM,8521
4
- winipedia_utils/concurrent/multiprocessing.py,sha256=P1dgiooms-PH7ZLei9MgGyjpSdgMG5yvhFflAAvCNew,4726
5
- winipedia_utils/concurrent/multithreading.py,sha256=Fuc4qWECvOk2y2jPQW-XN3p-5NLvBvNBpVglk4mpEH4,3084
6
- winipedia_utils/consts.py,sha256=Sp14ZsIr4zjXTIeFgQ9o_JdYsYsiVVhNet0fzdJBbPw,513
7
- winipedia_utils/data/__init__.py,sha256=o6SXX1gBCwhb9abo8xTfZtqUNuLqXmdo2VervnJxRzc,48
8
- winipedia_utils/data/dataframe/__init__.py,sha256=XHsbmjiaGom-KX-S3leCY9cJD3aP9p_0X6xYMcdkHBU,23
9
- winipedia_utils/data/dataframe/cleaning.py,sha256=iZC6AI2Di6nLwb_A698JCoeT4221Rd8WpzfZwbzZuM8,13261
10
- winipedia_utils/data/structures/__init__.py,sha256=XHsbmjiaGom-KX-S3leCY9cJD3aP9p_0X6xYMcdkHBU,23
11
- winipedia_utils/data/structures/dicts.py,sha256=jsFzQ96cvyHsvPSnsEUhksuWvLSGq6-Rryfw6gEXq-c,274
12
- winipedia_utils/django/__init__.py,sha256=wF--LWoHlVrdQ6LHY31ByBTkpGH3GEL9J-cXQ81usew,577
13
- winipedia_utils/django/bulk.py,sha256=u01fjAQci4G6YFGr8nlMCoI4QuIqA_dIyYpS6BfrAns,19883
14
- winipedia_utils/django/command.py,sha256=dcjVIP6pAPfWYnHZDcPTDEdFlfyHQu3_FVeRG1focSA,13462
15
- winipedia_utils/django/database.py,sha256=UxjAlw9ZBEZkOgz8sLCQYBVa5pREWVVmPWgN1To2hf4,10647
16
- winipedia_utils/git/__init__.py,sha256=IRmEVz0sUEw47Eli--57YaypWitxlcYThT_ulwkhNTE,47
17
- winipedia_utils/git/gitignore/__init__.py,sha256=k-2E26JaZPkF69UUOJkpQl8T_PudrC7EYCIOxwgIQVU,57
18
- winipedia_utils/git/gitignore/gitignore.py,sha256=PoXPA2F1mptirwhTXgv-iC_ivQReAWqNpHDEaFAmPkE,4376
19
- winipedia_utils/git/pre_commit/__init__.py,sha256=gFLVGQRmS6abgy5MfPQy_GZiF1_hGxuXtcOHX95WL-A,58
20
- winipedia_utils/git/pre_commit/config.py,sha256=HNThJhfA15erOLWNIaOMJN7z6uSGbpNbpFewSvK4qKQ,2262
21
- winipedia_utils/git/pre_commit/hooks.py,sha256=Gvzye9aCP_eIkuLx7rCXN6ZD2cH5BYPL2rnuhn1xgEg,3101
22
- winipedia_utils/git/pre_commit/run_hooks.py,sha256=HFsomU-KV89gVLAzmHtLnwekldO8vpTX3Nmmp-aJc0g,1523
23
- winipedia_utils/iterating/__init__.py,sha256=rlF9hzxbowq5yOfcXvOKOQdB-EQmfrislQpf659Zeu4,53
24
- winipedia_utils/iterating/iterate.py,sha256=fP0cgEOmmwqt5wg6v61Kw3Jx9TtE8bC_a2jVd270NCM,944
25
- winipedia_utils/logging/__init__.py,sha256=AMt1LwA_E7hexYjMpGzUempoyDdAF-dowWvq59wC5aM,51
26
- winipedia_utils/logging/ansi.py,sha256=7Z-FITaUn5B1ZE0OUVARjNzuMui1V36iu4YTjlD6QfI,101
27
- winipedia_utils/logging/config.py,sha256=sdC3GHMkJqlY-WwIsOMeTcy1bihthWV2LbvxLt9dhc4,2895
28
- winipedia_utils/logging/logger.py,sha256=NluvfRpY4SfJi6URjfV52l3cxeUYFMeCAJULK_PQXpQ,701
29
- winipedia_utils/modules/__init__.py,sha256=e3CFaC3FhK4ibknFOv1bqOZxA7XeVwmLqWX7oajUm78,51
30
- winipedia_utils/modules/class_.py,sha256=8-CS_x3mPaed39Cvo93ZnOQGLU2tndqxbIUlkQ_FAIM,3577
31
- winipedia_utils/modules/function.py,sha256=9evE45wtUaEWQ23rZ0HqFZ0nZw5JTpse6ebcWJAQYRI,2827
32
- winipedia_utils/modules/module.py,sha256=B2BLh-GVapSCBWc8Hx1U8jEN-yWVuGJls8LThVp8BTs,13041
33
- winipedia_utils/modules/package.py,sha256=S-pysPGIXW4JCGPhgO7Z1iU0gZb-_23opodb-zQLq5E,13058
34
- winipedia_utils/oop/__init__.py,sha256=wGjsVwLbTVEQWOfDJvN9nlvC-3NmAi8Doc2xIrm6e78,47
35
- winipedia_utils/oop/mixins/__init__.py,sha256=PDK-cJcdRUfDUCz36qQ5pmMW07G133WtN49OpmILGNI,54
36
- winipedia_utils/oop/mixins/meta.py,sha256=0G4CzzzCoeP1Eas3vWe-uxvB5n5ncyw7Wc-sI9zmEBc,11150
37
- winipedia_utils/oop/mixins/mixin.py,sha256=S5y1IVRtkghxV7y0ttdmSYO439NHChRIFTOwlK7kmTo,1401
38
- winipedia_utils/os/__init__.py,sha256=cBRq8hWhaWvYeC3cSBYL6Y70kM9COQWHj8vVxxSadIg,46
39
- winipedia_utils/os/os.py,sha256=K_5FD1sC1h5aSdtqXAG0uq90sSweLYLkgkRPQS0Jfxg,1768
40
- winipedia_utils/projects/__init__.py,sha256=_iYHzUcTPmutpsExPDcMF9OQDgnz-kTSuWens9iP9bI,52
41
- winipedia_utils/projects/poetry/__init__.py,sha256=tbvV3wYd3H39hjjlKbF84Irj4hYgv1A7KWyXdCQzFro,59
42
- winipedia_utils/projects/poetry/config.py,sha256=Y7JYRph4FRzzzdfOEyioeThZBkdrLVoR88wP4CkNJZI,2902
43
- winipedia_utils/projects/poetry/poetry.py,sha256=UiLTnmqzfeZV79ffHEnwHRNEI-bi6tMkdnmhZH5GrTg,934
44
- winipedia_utils/projects/project.py,sha256=oRIzF2HT1mkgnOhbgfi9_Bb2Ga3oNi_Ru7a1rbySvyQ,1539
45
- winipedia_utils/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
46
- winipedia_utils/pyside/__init__.py,sha256=bBA-cUrRPGdzitk2E5v-HFN9pi-i29X_UCP57StEbeU,51
47
- winipedia_utils/pyside/core/__init__.py,sha256=fogs6TirLduZgJhSJ87CVj7YanOMPOxHpgB8CgHyGns,56
48
- winipedia_utils/pyside/core/py_qiodevice.py,sha256=5onTJAE4Q328ACXrubZ2RsBO_PdJm0rXV6ZgqnzV4aU,15313
49
- winipedia_utils/pyside/ui/__init__.py,sha256=ZEkwzP1ds6Qq0Z-6WCS4OyKgwit9LUfXmHticbkr5Uo,54
50
- winipedia_utils/pyside/ui/base/__init__.py,sha256=XHsbmjiaGom-KX-S3leCY9cJD3aP9p_0X6xYMcdkHBU,23
51
- winipedia_utils/pyside/ui/base/base.py,sha256=-oTUtd19fjGfIpwAx6sPI64G-W1P_uq6_FAMJRJavXc,5538
52
- winipedia_utils/pyside/ui/pages/__init__.py,sha256=XHsbmjiaGom-KX-S3leCY9cJD3aP9p_0X6xYMcdkHBU,23
53
- winipedia_utils/pyside/ui/pages/base/__init__.py,sha256=XHsbmjiaGom-KX-S3leCY9cJD3aP9p_0X6xYMcdkHBU,23
54
- winipedia_utils/pyside/ui/pages/base/base.py,sha256=vF_hZ6cZPr1O3QqySuQoXq5egqmsRJABlUVSyIETOEw,2948
55
- winipedia_utils/pyside/ui/pages/browser.py,sha256=znvr1bNaf9i9p237rl-ca8FzGHhQ2laM2FHqE6jtH-Y,808
56
- winipedia_utils/pyside/ui/pages/player.py,sha256=YHJY3ei86-fs7vl6mCrc2K3nFM43fAFZ8lFp9MKjGUQ,2721
57
- winipedia_utils/pyside/ui/widgets/__init__.py,sha256=XHsbmjiaGom-KX-S3leCY9cJD3aP9p_0X6xYMcdkHBU,23
58
- winipedia_utils/pyside/ui/widgets/browser.py,sha256=KFuICHUTX_8w5DfgJ3IbTu6ipuiuo-mTJku5tg-qSz0,8171
59
- winipedia_utils/pyside/ui/widgets/clickable_widget.py,sha256=yMph7whLS6Bw65gf56LHdkZg-JzjWHUnSh3WW3IK25U,1722
60
- winipedia_utils/pyside/ui/widgets/media_player.py,sha256=kOxZqNovhgw-wv5q73iJo9q3B_cvKk7nTpb7eBFYaHo,15776
61
- winipedia_utils/pyside/ui/widgets/notification.py,sha256=DKsUeIeZlNPWB1XGPI-BYwC0xSvLjUjLyWwtoj3VKRY,2479
62
- winipedia_utils/pyside/ui/windows/__init__.py,sha256=XHsbmjiaGom-KX-S3leCY9cJD3aP9p_0X6xYMcdkHBU,23
63
- winipedia_utils/pyside/ui/windows/base/__init__.py,sha256=XHsbmjiaGom-KX-S3leCY9cJD3aP9p_0X6xYMcdkHBU,23
64
- winipedia_utils/pyside/ui/windows/base/base.py,sha256=RmdfJRspo-VxiDY9g17KsssnGSn2ettNLk_EZbMDuo4,1390
65
- winipedia_utils/resources/__init__.py,sha256=XHsbmjiaGom-KX-S3leCY9cJD3aP9p_0X6xYMcdkHBU,23
66
- winipedia_utils/resources/svgs/__init__.py,sha256=XHsbmjiaGom-KX-S3leCY9cJD3aP9p_0X6xYMcdkHBU,23
67
- winipedia_utils/resources/svgs/delete_garbage_can.svg,sha256=UxEEh46w1JD4VViUBx-Ahaq5_ZR4zOjfeJn5_aM8114,318
68
- winipedia_utils/resources/svgs/download_arrow.svg,sha256=8g_cBwKFHyoeSmaLMXcGwIHT4_rZDDtDGm35E0PkniE,242
69
- winipedia_utils/resources/svgs/exit_fullscreen_icon.svg,sha256=sZSexEjab82zhAK3JRtOWH19aAFa1GhuGLChDz9wFFc,523
70
- winipedia_utils/resources/svgs/fullscreen_icon.svg,sha256=mm2n6WvaSu0OqiQSAw0QPNwzXpPLaF53_XAklUfQQPo,406
71
- winipedia_utils/resources/svgs/menu_icon.svg,sha256=pA1Z_x5gDkhYLQA0dL0l_8uBP-e6mKLcEOYwlhURUv4,344
72
- winipedia_utils/resources/svgs/pause_icon.svg,sha256=z-Cj3DOI0rwRbWCOhaiHtDQYM4s6OgkCBVcdip77rQE,179
73
- winipedia_utils/resources/svgs/play_icon.svg,sha256=7gx1EWZnyu1pA6WboAfVH3OGcp_uYPpT1syqHe-jaGE,953
74
- winipedia_utils/resources/svgs/plus_icon.svg,sha256=1ucedu8ucLI7LMNsfNN2GYiwNUe8-ViNBcanDwzTqHc,552
75
- winipedia_utils/resources/svgs/svg.py,sha256=uzlp4Rhnenvkq_YI409ZvR7JMTZmB5JpKsDBOvPNr0I,415
76
- winipedia_utils/security/__init__.py,sha256=HmGXOCROqIGHlBs2bEWRMkEX3rlXNsnA9Tef58AlCo4,52
77
- winipedia_utils/security/cryptography.py,sha256=5LMat3-9nDW2cQBr_dU7MFRdgbiK53zQqHyacs-Jq-s,793
78
- winipedia_utils/security/keyring.py,sha256=6kKgSTz1G80F6XeZ3Lskxdl2N6JgUH8gJdFYcGJuysU,2273
79
- winipedia_utils/setup.py,sha256=GIniddS2gqSV5wYZUkuI2hC7esEChnWA3SyMFYB48Ms,1603
80
- winipedia_utils/testing/__init__.py,sha256=kXhB5xw02ec5xpcW_KV--9CBKdyCjnuR-NZzAJ5tq0g,51
81
- winipedia_utils/testing/assertions.py,sha256=WUJwIkPyRduiouqWQwk5-D_mF9ZU1Ffw0q4790lbKnI,828
82
- winipedia_utils/testing/convention.py,sha256=7vurpqS--awhN_FLSOviSKENGuFyY9Ejr1NKRm0MPsg,4833
83
- winipedia_utils/testing/create_tests.py,sha256=-lHSxVXbX7Oss1veKgMhbfoJQKCaXQA0LlIcTTr3MSU,9677
84
- winipedia_utils/testing/fixtures.py,sha256=G8QIrZXndtud0uOk6PY3f8IIDoyX_ronogjeLAYGjrM,1033
85
- winipedia_utils/testing/tests/__init__.py,sha256=kL-1O6lAO5j4JPOqPdi3dHdbOQ_UXcgPFppj82HhrRU,57
86
- winipedia_utils/testing/tests/base/__init__.py,sha256=dBH1yfONmqUC49zshS6BJ4ZgEcw7iFGoFCqRmU7Vhrw,62
87
- winipedia_utils/testing/tests/base/fixtures/__init__.py,sha256=Bs_HSqx8DcMb8yU1vNbgIEszOMNVnIW02C4tmDdHB8E,71
88
- winipedia_utils/testing/tests/base/fixtures/fixture.py,sha256=KfCYXDXT-wfeuf9uiUugB4ZEWXBPuhQ-bRZ-pb99pCg,181
89
- winipedia_utils/testing/tests/base/fixtures/scopes/__init__.py,sha256=-n_BLhTVC1oH7qVL0JYXm82zqFPgobQCojO-PirrKo0,78
90
- winipedia_utils/testing/tests/base/fixtures/scopes/class_.py,sha256=zesyJxerjI3qDtIUuaEaXp2IBbmsDJYi07JQqK9yUsk,1100
91
- winipedia_utils/testing/tests/base/fixtures/scopes/function.py,sha256=l1zCCiTkXUSZp0n9QOyejhfszFJiMH88bhGMwNY5r8A,302
92
- winipedia_utils/testing/tests/base/fixtures/scopes/module.py,sha256=qbpgdNY1XAKcOLdwLarwEUpUmBUeSrtbRMjef68yyao,1138
93
- winipedia_utils/testing/tests/base/fixtures/scopes/package.py,sha256=pR3so6QPymIRM4PJTODrlBKI-yQnZ2P78BsiyTPaF8o,302
94
- winipedia_utils/testing/tests/base/fixtures/scopes/session.py,sha256=yiHYO3_UrE5h9JoCc99HBw5PTPWW1XmOLBYqDAaO2O4,10110
95
- winipedia_utils/testing/tests/base/utils/__init__.py,sha256=mC-8dCkp8xarqkQu2QQLrPjHi6Ww9hcixWdHeQHWeRs,68
96
- winipedia_utils/testing/tests/base/utils/utils.py,sha256=TStWVDt9N3pNtg74JTxGK7KgB5FOIXFfYU-BA_-jhNA,2738
97
- winipedia_utils/testing/tests/conftest.py,sha256=BLgUJtLecOwuEsIyJ__0buqovd5AhiGvbMNk8CHgSQs,888
98
- winipedia_utils/text/__init__.py,sha256=j2bwtK6kyeHI6SnoBjpRju0C1W2n2paXBDlNjNtaUxA,48
99
- winipedia_utils/text/string.py,sha256=yXmwOab5hXyVQG1NwlWDpy2prj0U7Vb2F5HKLT2Y77Q,3382
100
- winipedia_utils-0.2.0.dist-info/METADATA,sha256=TYUp3apDCr-SQY-yF-EJrz-2dNhpX-C0xA7XkN2U_zA,12597
101
- winipedia_utils-0.2.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
102
- winipedia_utils-0.2.0.dist-info/licenses/LICENSE,sha256=o316mE2gGzd__JT69p7S_zlOmKiHh8YjpImCCcWyTvM,1066
103
- winipedia_utils-0.2.0.dist-info/RECORD,,