dars-framework 1.0.0__tar.gz
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.
- dars_framework-1.0.0/LICENSE +21 -0
- dars_framework-1.0.0/PKG-INFO +146 -0
- dars_framework-1.0.0/README.md +113 -0
- dars_framework-1.0.0/dars/__init__.py +0 -0
- dars_framework-1.0.0/dars/all.py +52 -0
- dars_framework-1.0.0/dars/cli/__init__.py +0 -0
- dars_framework-1.0.0/dars/cli/hot_reload.py +33 -0
- dars_framework-1.0.0/dars/cli/main.py +637 -0
- dars_framework-1.0.0/dars/cli/preview.py +419 -0
- dars_framework-1.0.0/dars/cli/translations.py +389 -0
- dars_framework-1.0.0/dars/components/__init__.py +0 -0
- dars_framework-1.0.0/dars/components/advanced/__init__.py +8 -0
- dars_framework-1.0.0/dars/components/advanced/accordion.py +21 -0
- dars_framework-1.0.0/dars/components/advanced/card.py +28 -0
- dars_framework-1.0.0/dars/components/advanced/modal.py +40 -0
- dars_framework-1.0.0/dars/components/advanced/navbar.py +31 -0
- dars_framework-1.0.0/dars/components/advanced/table.py +24 -0
- dars_framework-1.0.0/dars/components/advanced/tabs.py +26 -0
- dars_framework-1.0.0/dars/components/basic/__init__.py +34 -0
- dars_framework-1.0.0/dars/components/basic/button.py +29 -0
- dars_framework-1.0.0/dars/components/basic/checkbox.py +34 -0
- dars_framework-1.0.0/dars/components/basic/container.py +23 -0
- dars_framework-1.0.0/dars/components/basic/datepicker.py +139 -0
- dars_framework-1.0.0/dars/components/basic/image.py +36 -0
- dars_framework-1.0.0/dars/components/basic/input.py +50 -0
- dars_framework-1.0.0/dars/components/basic/link.py +31 -0
- dars_framework-1.0.0/dars/components/basic/page.py +20 -0
- dars_framework-1.0.0/dars/components/basic/progressbar.py +17 -0
- dars_framework-1.0.0/dars/components/basic/radiobutton.py +34 -0
- dars_framework-1.0.0/dars/components/basic/select.py +81 -0
- dars_framework-1.0.0/dars/components/basic/slider.py +63 -0
- dars_framework-1.0.0/dars/components/basic/spinner.py +11 -0
- dars_framework-1.0.0/dars/components/basic/text.py +22 -0
- dars_framework-1.0.0/dars/components/basic/textarea.py +46 -0
- dars_framework-1.0.0/dars/components/basic/tooltip.py +18 -0
- dars_framework-1.0.0/dars/components/layout/__init__.py +0 -0
- dars_framework-1.0.0/dars/components/layout/anchor.py +13 -0
- dars_framework-1.0.0/dars/components/layout/flex.py +26 -0
- dars_framework-1.0.0/dars/components/layout/grid.py +45 -0
- dars_framework-1.0.0/dars/core/__init__.py +0 -0
- dars_framework-1.0.0/dars/core/app.py +630 -0
- dars_framework-1.0.0/dars/core/component.py +25 -0
- dars_framework-1.0.0/dars/core/events.py +101 -0
- dars_framework-1.0.0/dars/core/properties.py +127 -0
- dars_framework-1.0.0/dars/docs/__init__.py +0 -0
- dars_framework-1.0.0/dars/exporters/__init__.py +0 -0
- dars_framework-1.0.0/dars/exporters/base.py +69 -0
- dars_framework-1.0.0/dars/exporters/web/__init__.py +0 -0
- dars_framework-1.0.0/dars/exporters/web/html_css_js.py +1406 -0
- dars_framework-1.0.0/dars/scripts/__init__.py +0 -0
- dars_framework-1.0.0/dars/scripts/script.py +38 -0
- dars_framework-1.0.0/dars/templates/__init__.py +0 -0
- dars_framework-1.0.0/dars/templates/examples/advanced/all_components_demo.py +87 -0
- dars_framework-1.0.0/dars/templates/examples/advanced/dashboard.py +440 -0
- dars_framework-1.0.0/dars/templates/examples/advanced/modern_web_app.py +452 -0
- dars_framework-1.0.0/dars/templates/examples/basic/flex_layout_responsive.py +13 -0
- dars_framework-1.0.0/dars/templates/examples/basic/form_components.py +516 -0
- dars_framework-1.0.0/dars/templates/examples/basic/grid_layout_responsive.py +13 -0
- dars_framework-1.0.0/dars/templates/examples/basic/hello_world.py +104 -0
- dars_framework-1.0.0/dars/templates/examples/basic/layout_multipage_demo.py +23 -0
- dars_framework-1.0.0/dars/templates/examples/basic/multipage_example.py +70 -0
- dars_framework-1.0.0/dars/templates/examples/basic/pwa_custom_icons.py +31 -0
- dars_framework-1.0.0/dars/templates/examples/basic/simple_form.py +377 -0
- dars_framework-1.0.0/dars/templates/examples/demo/complete_app.py +720 -0
- dars_framework-1.0.0/dars/templates/html/__init__.py +0 -0
- dars_framework-1.0.0/dars_framework.egg-info/PKG-INFO +146 -0
- dars_framework-1.0.0/dars_framework.egg-info/SOURCES.txt +71 -0
- dars_framework-1.0.0/dars_framework.egg-info/dependency_links.txt +1 -0
- dars_framework-1.0.0/dars_framework.egg-info/entry_points.txt +2 -0
- dars_framework-1.0.0/dars_framework.egg-info/requires.txt +2 -0
- dars_framework-1.0.0/dars_framework.egg-info/top_level.txt +1 -0
- dars_framework-1.0.0/pyproject.toml +20 -0
- dars_framework-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 ZtaDev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dars-framework
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Dars Framework build applications with Python and export to web
|
|
5
|
+
Author-email: ztamdev <zondax2009@gmail.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2025 ZtaDev
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: rich
|
|
31
|
+
Requires-Dist: bs4
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# Dars Framework
|
|
35
|
+
|
|
36
|
+
Dars is a Python UI framework for building modern, interactive web apps with only Python code. Write your interface in Python, export it to static HTML/CSS/JS, and deploy anywhere—no Javascript or frontend stack required.
|
|
37
|
+
|
|
38
|
+
## How It Works
|
|
39
|
+
- Build your UI using Python classes and components (like Text, Button, Container, Page, etc).
|
|
40
|
+
- Preview instantly with hot-reload using `app.rTimeCompile()`.
|
|
41
|
+
- Export your app to static web files with a single CLI command.
|
|
42
|
+
- Use multipage, layouts, scripts, and more—see docs for advanced features.
|
|
43
|
+
|
|
44
|
+
## Quick Example: Your First App
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
#!/usr/bin/env python3
|
|
48
|
+
from dars.core.app import App
|
|
49
|
+
from dars.components.basic.text import Text
|
|
50
|
+
from dars.components.basic.button import Button
|
|
51
|
+
from dars.components.basic.container import Container
|
|
52
|
+
from dars.scripts.script import InlineScript
|
|
53
|
+
|
|
54
|
+
# Crear aplicación
|
|
55
|
+
app = App(title="Mi Primera App")
|
|
56
|
+
|
|
57
|
+
# Crear componentes
|
|
58
|
+
container = Container(style={
|
|
59
|
+
'display': 'flex',
|
|
60
|
+
'flex-direction': 'column',
|
|
61
|
+
'align-items': 'center',
|
|
62
|
+
'padding': '40px'
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
titulo = Text(
|
|
66
|
+
text="Hola Dars",
|
|
67
|
+
style={'font-size': '32px', 'color': '#333'}
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
boton = Button(
|
|
71
|
+
text="Hacer clic",
|
|
72
|
+
style={'background-color': '#007bff', 'color': 'white'}
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Script para interactividad
|
|
76
|
+
script = InlineScript("""
|
|
77
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
78
|
+
const boton = document.querySelector('button');
|
|
79
|
+
boton.addEventListener('click', function() {
|
|
80
|
+
alert('Hola desde Dars.');
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
""")
|
|
84
|
+
|
|
85
|
+
# Ensamblar aplicación
|
|
86
|
+
container.add_child(titulo)
|
|
87
|
+
container.add_child(boton)
|
|
88
|
+
app.set_root(container)
|
|
89
|
+
app.add_script(script)
|
|
90
|
+
|
|
91
|
+
if __name__ == "__main__":
|
|
92
|
+
app.rTimeCompile() # Live preview at http://localhost:8000
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## CLI Usage
|
|
96
|
+
| Command | What it does |
|
|
97
|
+
|-----------------------------------------|--------------------------------------------|
|
|
98
|
+
| `dars export my_app.py --format html` | Export app to HTML/CSS/JS in `./my_app_web` |
|
|
99
|
+
| `dars preview ./my_app_web` | Preview exported app locally |
|
|
100
|
+
| `dars init my_project` | Create a new Dars project |
|
|
101
|
+
| `dars info my_app.py` | Show info about your app |
|
|
102
|
+
| `dars formats` | List supported export formats |
|
|
103
|
+
| `dars --help` | Show help and all CLI options |
|
|
104
|
+
|
|
105
|
+
## More
|
|
106
|
+
- [Project Roadmap](ROADMAP.md)
|
|
107
|
+
- [Getting Started](dars/docs/getting_started.md)
|
|
108
|
+
- [Components Reference](dars/docs/components.md)
|
|
109
|
+
- [Exporters](dars/docs/exporters.md)
|
|
110
|
+
- [Scripts System](dars/docs/scripts.md)
|
|
111
|
+
- [CLI usage and commands](dars/docs/cli.md)
|
|
112
|
+
- [Project Structure](STRUCTURE.md)
|
|
113
|
+
- [Architecture](DARS_ARCHITECTURE.md)
|
|
114
|
+
- [Installation Guide](INSTALL.md)
|
|
115
|
+
|
|
116
|
+
## Local Execution and Live Preview
|
|
117
|
+
|
|
118
|
+
To test your app locally before exporting, use the hot-reload preview from any Python file that defines your app:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
if __name__ == "__main__":
|
|
122
|
+
app.rTimeCompile()
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Then run your file directly:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
python my_app.py
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
This will start a local server at http://localhost:8000 so you can view your app in the browser—no manual export needed. You can change the port with:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
python my_app.py --port 8088
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
You can also use the CLI preview command on an exported app:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
dars preview ./my_exported_app
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
This will start a local server at http://localhost:8000 to view your exported app in the browser.
|
|
146
|
+
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Dars Framework
|
|
2
|
+
|
|
3
|
+
Dars is a Python UI framework for building modern, interactive web apps with only Python code. Write your interface in Python, export it to static HTML/CSS/JS, and deploy anywhere—no Javascript or frontend stack required.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
- Build your UI using Python classes and components (like Text, Button, Container, Page, etc).
|
|
7
|
+
- Preview instantly with hot-reload using `app.rTimeCompile()`.
|
|
8
|
+
- Export your app to static web files with a single CLI command.
|
|
9
|
+
- Use multipage, layouts, scripts, and more—see docs for advanced features.
|
|
10
|
+
|
|
11
|
+
## Quick Example: Your First App
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
#!/usr/bin/env python3
|
|
15
|
+
from dars.core.app import App
|
|
16
|
+
from dars.components.basic.text import Text
|
|
17
|
+
from dars.components.basic.button import Button
|
|
18
|
+
from dars.components.basic.container import Container
|
|
19
|
+
from dars.scripts.script import InlineScript
|
|
20
|
+
|
|
21
|
+
# Crear aplicación
|
|
22
|
+
app = App(title="Mi Primera App")
|
|
23
|
+
|
|
24
|
+
# Crear componentes
|
|
25
|
+
container = Container(style={
|
|
26
|
+
'display': 'flex',
|
|
27
|
+
'flex-direction': 'column',
|
|
28
|
+
'align-items': 'center',
|
|
29
|
+
'padding': '40px'
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
titulo = Text(
|
|
33
|
+
text="Hola Dars",
|
|
34
|
+
style={'font-size': '32px', 'color': '#333'}
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
boton = Button(
|
|
38
|
+
text="Hacer clic",
|
|
39
|
+
style={'background-color': '#007bff', 'color': 'white'}
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Script para interactividad
|
|
43
|
+
script = InlineScript("""
|
|
44
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
45
|
+
const boton = document.querySelector('button');
|
|
46
|
+
boton.addEventListener('click', function() {
|
|
47
|
+
alert('Hola desde Dars.');
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
""")
|
|
51
|
+
|
|
52
|
+
# Ensamblar aplicación
|
|
53
|
+
container.add_child(titulo)
|
|
54
|
+
container.add_child(boton)
|
|
55
|
+
app.set_root(container)
|
|
56
|
+
app.add_script(script)
|
|
57
|
+
|
|
58
|
+
if __name__ == "__main__":
|
|
59
|
+
app.rTimeCompile() # Live preview at http://localhost:8000
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## CLI Usage
|
|
63
|
+
| Command | What it does |
|
|
64
|
+
|-----------------------------------------|--------------------------------------------|
|
|
65
|
+
| `dars export my_app.py --format html` | Export app to HTML/CSS/JS in `./my_app_web` |
|
|
66
|
+
| `dars preview ./my_app_web` | Preview exported app locally |
|
|
67
|
+
| `dars init my_project` | Create a new Dars project |
|
|
68
|
+
| `dars info my_app.py` | Show info about your app |
|
|
69
|
+
| `dars formats` | List supported export formats |
|
|
70
|
+
| `dars --help` | Show help and all CLI options |
|
|
71
|
+
|
|
72
|
+
## More
|
|
73
|
+
- [Project Roadmap](ROADMAP.md)
|
|
74
|
+
- [Getting Started](dars/docs/getting_started.md)
|
|
75
|
+
- [Components Reference](dars/docs/components.md)
|
|
76
|
+
- [Exporters](dars/docs/exporters.md)
|
|
77
|
+
- [Scripts System](dars/docs/scripts.md)
|
|
78
|
+
- [CLI usage and commands](dars/docs/cli.md)
|
|
79
|
+
- [Project Structure](STRUCTURE.md)
|
|
80
|
+
- [Architecture](DARS_ARCHITECTURE.md)
|
|
81
|
+
- [Installation Guide](INSTALL.md)
|
|
82
|
+
|
|
83
|
+
## Local Execution and Live Preview
|
|
84
|
+
|
|
85
|
+
To test your app locally before exporting, use the hot-reload preview from any Python file that defines your app:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
app.rTimeCompile()
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Then run your file directly:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
python my_app.py
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
This will start a local server at http://localhost:8000 so you can view your app in the browser—no manual export needed. You can change the port with:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
python my_app.py --port 8088
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
You can also use the CLI preview command on an exported app:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
dars preview ./my_exported_app
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
This will start a local server at http://localhost:8000 to view your exported app in the browser.
|
|
113
|
+
|
|
File without changes
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Barrel import for all Dars components and core modules
|
|
2
|
+
# Usage: from dars.all import *
|
|
3
|
+
|
|
4
|
+
# Core
|
|
5
|
+
from dars.core.app import App
|
|
6
|
+
from dars.core.component import Component
|
|
7
|
+
from dars.core.events import EventManager
|
|
8
|
+
|
|
9
|
+
# Basic Components
|
|
10
|
+
from dars.components.basic.button import Button
|
|
11
|
+
from dars.components.basic.checkbox import Checkbox
|
|
12
|
+
from dars.components.basic.container import Container
|
|
13
|
+
from dars.components.basic.datepicker import DatePicker
|
|
14
|
+
from dars.components.basic.image import Image
|
|
15
|
+
from dars.components.basic.input import Input
|
|
16
|
+
from dars.components.basic.link import Link
|
|
17
|
+
from dars.components.basic.page import Page
|
|
18
|
+
from dars.components.basic.progressbar import ProgressBar
|
|
19
|
+
from dars.components.basic.radiobutton import RadioButton
|
|
20
|
+
from dars.components.basic.select import Select
|
|
21
|
+
from dars.components.basic.slider import Slider
|
|
22
|
+
from dars.components.basic.spinner import Spinner
|
|
23
|
+
from dars.components.basic.text import Text
|
|
24
|
+
from dars.components.basic.textarea import Textarea
|
|
25
|
+
from dars.components.basic.tooltip import Tooltip
|
|
26
|
+
|
|
27
|
+
# Advanced Components
|
|
28
|
+
from dars.components.advanced.accordion import Accordion
|
|
29
|
+
from dars.components.advanced.card import Card
|
|
30
|
+
from dars.components.advanced.modal import Modal
|
|
31
|
+
from dars.components.advanced.navbar import Navbar
|
|
32
|
+
from dars.components.advanced.table import Table
|
|
33
|
+
from dars.components.advanced.tabs import Tabs
|
|
34
|
+
|
|
35
|
+
# Layout
|
|
36
|
+
from dars.components.layout.grid import GridLayout, LayoutBase
|
|
37
|
+
from dars.components.layout.flex import FlexLayout
|
|
38
|
+
from dars.components.layout.anchor import AnchorPoint
|
|
39
|
+
|
|
40
|
+
# Exporters (optional, for direct use)
|
|
41
|
+
# from dars.exporters.web.html_css_js import HTMLCSSJSExporter
|
|
42
|
+
|
|
43
|
+
# CLI (optional, for advanced usage)
|
|
44
|
+
# from dars.cli.main import main as dars_cli_main
|
|
45
|
+
|
|
46
|
+
__all__ = [
|
|
47
|
+
'App', 'Component', 'EventManager',
|
|
48
|
+
'Button', 'Checkbox', 'Container', 'DatePicker', 'Image', 'Input', 'Link', 'Page', 'ProgressBar',
|
|
49
|
+
'RadioButton', 'Select', 'Slider', 'Spinner', 'Text', 'Textarea', 'Tooltip',
|
|
50
|
+
'Accordion', 'Card', 'Modal', 'Navbar', 'Table', 'Tabs',
|
|
51
|
+
'GridLayout', 'FlexLayout', 'LayoutBase', 'AnchorPoint',
|
|
52
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import time
|
|
3
|
+
import threading
|
|
4
|
+
import importlib
|
|
5
|
+
|
|
6
|
+
class FileWatcher:
|
|
7
|
+
"""Watches a file for changes and triggers a callback when it changes."""
|
|
8
|
+
def __init__(self, path, on_change, poll_interval=0.5):
|
|
9
|
+
self.path = path
|
|
10
|
+
self.on_change = on_change
|
|
11
|
+
self.poll_interval = poll_interval
|
|
12
|
+
self._last_mtime = None
|
|
13
|
+
self._stop_event = threading.Event()
|
|
14
|
+
self._thread = threading.Thread(target=self._watch, daemon=True)
|
|
15
|
+
|
|
16
|
+
def start(self):
|
|
17
|
+
self._last_mtime = os.path.getmtime(self.path)
|
|
18
|
+
self._thread.start()
|
|
19
|
+
|
|
20
|
+
def stop(self):
|
|
21
|
+
self._stop_event.set()
|
|
22
|
+
self._thread.join()
|
|
23
|
+
|
|
24
|
+
def _watch(self):
|
|
25
|
+
while not self._stop_event.is_set():
|
|
26
|
+
try:
|
|
27
|
+
mtime = os.path.getmtime(self.path)
|
|
28
|
+
if mtime != self._last_mtime:
|
|
29
|
+
self._last_mtime = mtime
|
|
30
|
+
self.on_change()
|
|
31
|
+
except Exception:
|
|
32
|
+
pass
|
|
33
|
+
time.sleep(self.poll_interval)
|