packuifw 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.
pack_uifw/__init__.py
ADDED
|
File without changes
|
pack_uifw/pack_uifw.py
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
import json
|
|
4
|
+
import zipfile
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
# --- EXCLUSION CONFIGURATION ---
|
|
8
|
+
EXCLUDE_NAMES = {
|
|
9
|
+
'app.py', 'bot.py', 'server.py', 'firmware.db', 'requests.db',
|
|
10
|
+
'emergency.py', 'launcher.pyw', 'pack_uifw.py', 'emergency.log',
|
|
11
|
+
'submit_app.py', 'unpack_uifw.py', 'shell_manager_app.py',
|
|
12
|
+
'launcher_standalone.py'
|
|
13
|
+
}
|
|
14
|
+
EXCLUDE_EXTS = {'.db', '.log', '.pyc'}
|
|
15
|
+
EXCLUDE_DIRS = {'cache', '__pycache__', 'installed_shells', '.git', '.idea', '.vscode'}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def should_skip(path):
|
|
19
|
+
"""Checks if a file or directory should be excluded from the archive."""
|
|
20
|
+
if path.name in EXCLUDE_NAMES:
|
|
21
|
+
return True
|
|
22
|
+
if path.suffix.lower() in EXCLUDE_EXTS:
|
|
23
|
+
return True
|
|
24
|
+
for part in path.parts:
|
|
25
|
+
if part in EXCLUDE_DIRS:
|
|
26
|
+
return True
|
|
27
|
+
return False
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def pack_folder(folder_path, out_path=None):
|
|
31
|
+
"""Packs a shell folder into a .uifw archive."""
|
|
32
|
+
folder = Path(folder_path).resolve()
|
|
33
|
+
|
|
34
|
+
if not folder.exists() or not folder.is_dir():
|
|
35
|
+
print("From folder err.")
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
if out_path is None:
|
|
39
|
+
out = folder.parent / f"{folder.name}.uifw"
|
|
40
|
+
else:
|
|
41
|
+
out = Path(out_path).resolve()
|
|
42
|
+
|
|
43
|
+
meta_file = folder / 'shell.json'
|
|
44
|
+
if not meta_file.exists():
|
|
45
|
+
print('[!] Warning: shell.json not found in folder')
|
|
46
|
+
|
|
47
|
+
# Remove existing archive to avoid appending
|
|
48
|
+
if out.exists():
|
|
49
|
+
try:
|
|
50
|
+
out.unlink()
|
|
51
|
+
except PermissionError:
|
|
52
|
+
print(f"Cannot delete {out} — close File Explorer/archiver and try again.")
|
|
53
|
+
return False
|
|
54
|
+
|
|
55
|
+
count = 0
|
|
56
|
+
try:
|
|
57
|
+
with zipfile.ZipFile(out, 'w', zipfile.ZIP_DEFLATED) as z:
|
|
58
|
+
for item in folder.rglob('*'):
|
|
59
|
+
if item.is_dir():
|
|
60
|
+
continue
|
|
61
|
+
if should_skip(item):
|
|
62
|
+
continue
|
|
63
|
+
|
|
64
|
+
arcname = item.relative_to(folder)
|
|
65
|
+
z.write(item, arcname)
|
|
66
|
+
count += 1
|
|
67
|
+
|
|
68
|
+
size_kb = out.stat().st_size // 1024
|
|
69
|
+
firmware_key = folder.name
|
|
70
|
+
print(f"Your firmware, named by {firmware_key}, builded in uifw. Success.")
|
|
71
|
+
return True
|
|
72
|
+
|
|
73
|
+
except Exception as e:
|
|
74
|
+
print("Build err.")
|
|
75
|
+
return False
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def unpack_uifw(archive_path, dest_path=None):
|
|
79
|
+
"""Unpacks a .uifw archive into the specified folder."""
|
|
80
|
+
archive = Path(archive_path).resolve()
|
|
81
|
+
|
|
82
|
+
if not archive.exists():
|
|
83
|
+
print("From folder err.")
|
|
84
|
+
return False
|
|
85
|
+
|
|
86
|
+
if dest_path is None:
|
|
87
|
+
dest = archive.parent / f"{archive.stem}_unpacked"
|
|
88
|
+
else:
|
|
89
|
+
dest = Path(dest_path).resolve()
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
dest.mkdir(parents=True, exist_ok=True)
|
|
93
|
+
|
|
94
|
+
with zipfile.ZipFile(archive, 'r') as z:
|
|
95
|
+
z.extractall(dest)
|
|
96
|
+
|
|
97
|
+
print(f"Your firmware, named by {archive.stem}, unpacked. Success.")
|
|
98
|
+
return True
|
|
99
|
+
|
|
100
|
+
except Exception as e:
|
|
101
|
+
print("Build err.")
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def main():
|
|
106
|
+
"""Entry point for the CLI tool."""
|
|
107
|
+
args = sys.argv[1:]
|
|
108
|
+
|
|
109
|
+
if len(args) < 2:
|
|
110
|
+
print("Usage:")
|
|
111
|
+
print(' pack_uifw pack <folder_path> [output_path]')
|
|
112
|
+
print(' pack_uifw unpack <file.uifw> [dest_folder]')
|
|
113
|
+
return
|
|
114
|
+
|
|
115
|
+
command = args[0].lower()
|
|
116
|
+
target = args[1]
|
|
117
|
+
optional_arg = args[2] if len(args) > 2 else None
|
|
118
|
+
|
|
119
|
+
if command == 'pack':
|
|
120
|
+
success = pack_folder(target, optional_arg)
|
|
121
|
+
elif command == 'unpack':
|
|
122
|
+
success = unpack_uifw(target, optional_arg)
|
|
123
|
+
else:
|
|
124
|
+
print(f"Unknown command: {command}")
|
|
125
|
+
print("Use 'pack' or 'unpack'.")
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
if not success:
|
|
129
|
+
sys.exit(1)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
if __name__ == '__main__':
|
|
133
|
+
main()
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: packuifw
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Tool for packing .uifw firmware from shell folders. For Firmware Authority
|
|
5
|
+
Author: fa_creepyr
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.8
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
|
|
10
|
+
# packuifw
|
|
11
|
+
|
|
12
|
+
A tool for packing `.uifw` firmware from shell folders.
|
|
13
|
+
Part of the **Firmware Authority** project.
|
|
14
|
+
|
|
15
|
+
## What is .uifw
|
|
16
|
+
|
|
17
|
+
`.uifw` is a ZIP archive with the `.uifw` extension that contains a Windows shell:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
my_shell.uifw
|
|
21
|
+
├── shell.json metadata
|
|
22
|
+
├── launcher.exe launches the shell
|
|
23
|
+
├── main.py shell code
|
|
24
|
+
└── assets/ wallpapers, cursors, sounds
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install packuifw
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
### CLI
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pack_uifw <path_to_folder>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Creates `<folder_name>.uifw` next to the folder.
|
|
42
|
+
|
|
43
|
+
Example:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pack_uifw C:\shellpacks\win98
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Creates `C:\shellpacks\win98.uifw`.
|
|
50
|
+
|
|
51
|
+
### GUI
|
|
52
|
+
|
|
53
|
+
Run `pack_uifw` without arguments to open the window:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pack_uifw
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- Folder: shell folder (`shell.json`, `main.py`, `assets/`)
|
|
60
|
+
- Output: where to save `.uifw` (default — next to the folder)
|
|
61
|
+
- Pack: start packing
|
|
62
|
+
|
|
63
|
+
## Shell folder structure
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
my_shell/
|
|
67
|
+
├── shell.json required (metadata)
|
|
68
|
+
├── launcher.exe required (launches the shell)
|
|
69
|
+
├── main.py shell code (Python)
|
|
70
|
+
└── assets/ wallpapers, cursors, sounds
|
|
71
|
+
├── wallpaper.jpg
|
|
72
|
+
└── startup.wav
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### shell.json
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"key": "win98",
|
|
80
|
+
"name": "Windows 98",
|
|
81
|
+
"version": "1.0.0",
|
|
82
|
+
"author": "dteamcorporation",
|
|
83
|
+
"description": "Classic Windows 98 interface",
|
|
84
|
+
"launcher": "launcher.exe",
|
|
85
|
+
"entry": "main.py"
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Exclusions
|
|
90
|
+
|
|
91
|
+
The following are skipped during packing:
|
|
92
|
+
|
|
93
|
+
Files:
|
|
94
|
+
|
|
95
|
+
`app.py`, `bot.py`, `server.py`, `emergency.py`, `pack_uifw.py`, `submit_app.py`, `unpack_uifw.py`, `shell_manager_app.py`, `launcher_standalone.py`, `launcher.pyw`, `firmware.db`, `requests.db`, `emergency.log`, `pack_uifw.exe`, `unpack_uifw.exe`
|
|
96
|
+
|
|
97
|
+
Extensions:
|
|
98
|
+
|
|
99
|
+
`.db`, `.log`, `.pyc`
|
|
100
|
+
|
|
101
|
+
Directories:
|
|
102
|
+
|
|
103
|
+
`cache`, `__pycache__`, `installed_shells`, `.git`, `.idea`, `.vscode`
|
|
104
|
+
|
|
105
|
+
## Development
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
git clone https://github.com/k4024963-lang/packuifw.git
|
|
109
|
+
cd packuifw
|
|
110
|
+
pip install -e .
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
MIT © fa_creepyr
|
|
116
|
+
|
|
117
|
+
## Links
|
|
118
|
+
|
|
119
|
+
- Firmware Authority: [firmware.authority.cloudpub.ru](https://firmware.authority.cloudpub.ru)
|
|
120
|
+
- TikTok: [@dteamcorporation](https://tiktok.com/@dteamcorporation)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
pack_uifw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
pack_uifw/pack_uifw.py,sha256=MLnhe5CL8jyApX-e8p2Ag8sCEpoanGiUKM4S28rrr1M,3827
|
|
3
|
+
packuifw-1.0.0.dist-info/METADATA,sha256=zZmJpoTJPTa8TGng_3BNB4ZrZvupmJbYjdeci_O3Quk,2546
|
|
4
|
+
packuifw-1.0.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
5
|
+
packuifw-1.0.0.dist-info/entry_points.txt,sha256=cPSxz-nEQHVWs5Z6KQkK8ZD6CE1xl_HMj9gsyce8nF0,50
|
|
6
|
+
packuifw-1.0.0.dist-info/top_level.txt,sha256=ZbsoMJyWmjmFc9yxWW3mbyu3XvYZYCClzxalypGIgyU,10
|
|
7
|
+
packuifw-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pack_uifw
|