Skip to content

Commit ca85a98

Browse files
committed
Merge branch 'feature-win-tweaks' of https://github.com/Radiump123/Lufus into feature-win-tweaks
2 parents 5af1dce + 632824f commit ca85a98

18 files changed

Lines changed: 309 additions & 52 deletions

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@ AppDir
4242
*.spec
4343
site/
4444
.desloppify/
45-
45+
*.geany
4646
.briefcase/

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "lufus"
7-
version = "1.0.1b1" # keep synced with [tool.briefcase] version
7+
version = "1.0.0" # keep synced with [tool.briefcase] version
88
description = "A rufus clone written in Python and designed to work with Linux."
99
readme = "README.md"
1010
license = "MIT"
@@ -29,7 +29,7 @@ lufus = "lufus.__main__:main"
2929
[tool.briefcase]
3030
project_name = "Lufus"
3131
bundle = "com.github.hog185"
32-
version = "1.0.1b1" # keep synced with [project] version
32+
version = "1.0.0" # keep synced with [project] version
3333
url = "https://github.com/Hog185/Lufus"
3434
license.file = "LICENSE"
3535
author = "Hog185"

scripts/build-appimage.sh

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@ set -euo pipefail
44
ls -la
55

66
# Install system dependencies
7-
echo "------------ Installing system libraries ------------"
8-
apt-get update && apt-get upgrade -y
9-
INSTALLER="apt-get install -y"
10-
if [[ -f requirements-system.txt ]]; then
11-
$INSTALLER $(cat requirements-system.txt) >> appimage-setup.log
12-
echo "System libraries installed."
13-
else
14-
echo "requirements-system.txt not found!"
15-
exit 1
16-
fi
7+
## COMMENTED BECAUSE ALREADY HANDELED IN YAML
8+
# echo "------------ Installing system libraries ------------"
9+
# apt-get update && apt-get upgrade -y
10+
# INSTALLER="apt-get install -y"
11+
# if [[ -f requirements-system.txt ]]; then
12+
# $INSTALLER $(cat requirements-system.txt) >> appimage-setup.log
13+
# echo "System libraries installed."
14+
# else
15+
# echo "requirements-system.txt not found!"
16+
# exit 1
17+
# fi
1718

1819
if command -v python3 &>/dev/null; then
1920
PYTHON=python3

src/lufus/drives/formatting.py

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,11 @@ def check_device_bad_blocks() -> bool:
235235
probe.returncode,
236236
)
237237
except Exception as exc:
238-
log.warning("Could not probe sector size for %s: %s. Using default block size.", drive, exc)
238+
log.warning(
239+
"Could not probe sector size for %s: %s. Using default block size.",
240+
drive,
241+
exc,
242+
)
239243

240244
# -s = show progress, -v = verbose output
241245
# -n = non-destructive read-write test (safe default)
@@ -316,10 +320,30 @@ def _status(msg: str) -> None:
316320
"NTFS",
317321
"ntfs-3g",
318322
),
319-
1: ("mkfs.vfat", lambda: ["-I", "-s", str(sectors_per_cluster), "-F", "32", raw_device], "FAT32", "dosfstools"),
320-
2: ("mkfs.exfat", lambda: ["-b", str(block_size), raw_device], "exFAT", "exfatprogs or exfat-utils"),
321-
3: ("mkfs.ext4", lambda: ["-b", str(block_size), raw_device], "ext4", "e2fsprogs"),
322-
4: ("mkudffs", lambda: ["--blocksize=" + str(sector_size), raw_device], "UDF", "udftools"),
323+
1: (
324+
"mkfs.vfat",
325+
lambda: ["-I", "-s", str(sectors_per_cluster), "-F", "32", raw_device],
326+
"FAT32",
327+
"dosfstools",
328+
),
329+
2: (
330+
"mkfs.exfat",
331+
lambda: ["-b", str(block_size), raw_device],
332+
"exFAT",
333+
"exfatprogs or exfat-utils",
334+
),
335+
3: (
336+
"mkfs.ext4",
337+
lambda: ["-b", str(block_size), raw_device],
338+
"ext4",
339+
"e2fsprogs",
340+
),
341+
4: (
342+
"mkudffs",
343+
lambda: ["--blocksize=" + str(sector_size), raw_device],
344+
"UDF",
345+
"udftools",
346+
),
323347
}
324348

325349
if fs_type not in fs_configs:
@@ -367,14 +391,30 @@ def _apply_partition_scheme(drive: str) -> None:
367391
# GPT — used for UEFI targets
368392
subprocess.run([_find_tool("parted"), "-s", raw_device, "mklabel", "gpt"], check=True)
369393
subprocess.run(
370-
[_find_tool("parted"), "-s", raw_device, "mkpart", "primary", "1MiB", "100%"],
394+
[
395+
_find_tool("parted"),
396+
"-s",
397+
raw_device,
398+
"mkpart",
399+
"primary",
400+
"1MiB",
401+
"100%",
402+
],
371403
check=True,
372404
)
373405
else:
374406
# MBR — used for BIOS/legacy targets
375407
subprocess.run([_find_tool("parted"), "-s", raw_device, "mklabel", "msdos"], check=True)
376408
subprocess.run(
377-
[_find_tool("parted"), "-s", raw_device, "mkpart", "primary", "1MiB", "100%"],
409+
[
410+
_find_tool("parted"),
411+
"-s",
412+
raw_device,
413+
"mkpart",
414+
"primary",
415+
"1MiB",
416+
"100%",
417+
],
378418
check=True,
379419
)
380420
log.info("Partition scheme %s applied to %s.", scheme_name, raw_device)
@@ -388,6 +428,11 @@ def _apply_partition_scheme(drive: str) -> None:
388428

389429

390430
def drive_repair() -> None:
431+
# todo:
432+
# add smartctl check if possible
433+
# use fsck to prevent deletion of files for repair
434+
# use testdisk for partition recovery if possible
435+
# do dd if=/dev/zero of=/dev/sdX bs=1M count=10 conv=notrunc before sfdisk use
391436
_, drive, _ = _get_mount_and_drive()
392437
if not drive:
393438
log.error("No drive node found. Cannot repair.")

src/lufus/gui/dialogs.py

Lines changed: 132 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,26 @@
33
from PyQt6.QtWidgets import (
44
QApplication,
55
QComboBox,
6+
QCheckBox,
67
QDialog,
78
QFileDialog,
89
QFrame,
910
QHBoxLayout,
1011
QLabel,
12+
QLineEdit,
1113
QMessageBox,
1214
QPushButton,
1315
QTextEdit,
1416
QVBoxLayout,
1517
)
16-
from PyQt6.QtCore import Qt, pyqtSignal
17-
from PyQt6.QtGui import QFont
18+
from PyQt6.QtCore import Qt, pyqtSignal, QRegularExpression, QUrl
19+
from PyQt6.QtGui import QFont, QRegularExpressionValidator, QDesktopServices
20+
import sys
1821

1922
from lufus import state as states
2023
from lufus.gui.constants import THEME_DIR, _find_resource_dir
2124
from lufus.gui.scale import Scale
25+
from lufus.lufus_logging import get_logger
2226

2327

2428
class LogWindow(QDialog):
@@ -28,7 +32,6 @@ def __init__(self, parent=None):
2832
self._T = parent._T if parent else {}
2933
self._S: Scale = parent._S if parent else None
3034
self.setWindowTitle(self._T.get("log_window_title", "Log Window"))
31-
3235
if self._S:
3336
# apply scaled dimensions
3437
self.resize(self._S.px(650), self._S.px(450))
@@ -139,13 +142,32 @@ def __init__(self, parent=None):
139142
sep.setFrameShadow(QFrame.Shadow.Sunken)
140143
layout.addWidget(sep)
141144

145+
# version
146+
lbl_ver = QLabel(states.version)
147+
lbl_ver.setStyleSheet(f"font-family: {font_family}; font-size: {tool_pt}pt;")
148+
lbl_ver.setAlignment(Qt.AlignmentFlag.AlignCenter)
149+
layout.addWidget(lbl_ver)
150+
142151
# im lying ily (context text something area, whatever)
143152
self.about_text = QTextEdit()
144153
self.about_text.setReadOnly(True)
145154
self.about_text.setObjectName("aboutContent")
146155
self.about_text.setFrameShape(QFrame.Shape.NoFrame)
147156
self.about_text.setStyleSheet(f"font-family: {font_family}; font-size: {tool_pt}pt;")
148157
layout.addWidget(self.about_text, 1)
158+
btn_row0 = QHBoxLayout()
159+
btn_discord = QPushButton(self._T.get("btn_discord", "Join Discord Server"))
160+
btn_discord.setFixedWidth(self._S.px(300) if self._S else 90)
161+
btn_discord.clicked.connect(self.discord_open)
162+
btn_row0.addWidget(btn_discord, alignment=Qt.AlignmentFlag.AlignCenter)
163+
layout.addLayout(btn_row0)
164+
165+
btn_row1 = QHBoxLayout()
166+
btn_github = QPushButton(self._T.get("btn_github", "Open Github Repo"))
167+
btn_github.setFixedWidth(self._S.px(300) if self._S else 90)
168+
btn_github.clicked.connect(self.github_open)
169+
btn_row1.addWidget(btn_github, alignment=Qt.AlignmentFlag.AlignCenter)
170+
layout.addLayout(btn_row1)
149171

150172
btn_row = QHBoxLayout()
151173
# close button or smth, whatever
@@ -154,9 +176,16 @@ def __init__(self, parent=None):
154176
btn_close.clicked.connect(self.hide)
155177
btn_row.addWidget(btn_close, alignment=Qt.AlignmentFlag.AlignCenter)
156178
layout.addLayout(btn_row)
157-
158179
self.setLayout(layout)
159180

181+
def discord_open(self):
182+
url = QUrl("https://discord.gg/4G6FeBwsxb")
183+
QDesktopServices.openUrl(url)
184+
185+
def github_open(self):
186+
url = QUrl("https://github.com/Hog185/Lufus")
187+
QDesktopServices.openUrl(url)
188+
160189

161190
class SettingsDialog(QDialog):
162191
# signals for when settings change :D
@@ -246,3 +275,102 @@ def _detect_themes():
246275
# user themes follow the same folder structure :D
247276
custom = sorted(p.parent.name for p in user_themes_dir.glob("*/*_theme.json"))
248277
return builtin, custom
278+
279+
280+
class WinTweaks(QDialog):
281+
def __init__(self, parent=None):
282+
super().__init__(parent)
283+
re = QRegularExpression("^[a-zA-Z0-9_]*$")
284+
validator = QRegularExpressionValidator(re)
285+
self.setWindowTitle("Windows Tweaks (MAY BREAK! USE CAUTION)")
286+
self.setFixedSize(600, 300)
287+
self.ask_label = QLabel("Do you want to customize your windows installation?")
288+
self.hardware_checkbox = QCheckBox("Remove requirement for 4GB+ RAM, Secure Boot and TPM 2.0")
289+
self.hardware_checkbox.stateChanged.connect(self.update_winhardware)
290+
self.microsoft_checkbox = QCheckBox("Remove requirement for an online Microsoft Account")
291+
self.microsoft_checkbox.stateChanged.connect(self.update_winmicrosoftacc)
292+
self.localacc_checkbox = QCheckBox("Create a local account with username:")
293+
self.localacc_checkbox.stateChanged.connect(self.update_winlocalaccchk)
294+
self.username_input = QLineEdit()
295+
self.username_input.setMaxLength(20)
296+
self.username_input.setValidator(validator)
297+
self.username_input.setPlaceholderText("Enter username here...")
298+
self.microsoft_checkbox.toggled.connect(self.localacc_checkbox.setEnabled)
299+
self.localacc_checkbox.toggled.connect(self.username_input.setEnabled)
300+
self.username_input.setEnabled(self.localacc_checkbox.isChecked())
301+
self.username_input.textChanged.connect(self.sync_username)
302+
self.data_checkbox = QCheckBox("Disable data collection (skip privacy questions)")
303+
self.data_checkbox.stateChanged.connect(self.update_winprivacy)
304+
self.applytweaks_btn = QPushButton("Apply")
305+
self.applytweaks_btn.clicked.connect(self.applywintweaks)
306+
self.canceltweaks_btn = QPushButton("Cancel")
307+
self.canceltweaks_btn.clicked.connect(self.reject) # closes window
308+
layout = QVBoxLayout()
309+
layout.setSpacing(15)
310+
layout.setContentsMargins(20, 20, 20, 20)
311+
layout.addWidget(self.ask_label, alignment=Qt.AlignmentFlag.AlignCenter)
312+
layout.addWidget(self.hardware_checkbox)
313+
layout.addWidget(self.microsoft_checkbox)
314+
layout.addWidget(self.localacc_checkbox)
315+
layout.addWidget(self.username_input)
316+
layout.addWidget(self.data_checkbox)
317+
button_layout = QHBoxLayout()
318+
button_layout.addWidget(self.applytweaks_btn)
319+
button_layout.addWidget(self.canceltweaks_btn)
320+
layout.addLayout(button_layout)
321+
layout.addStretch(1)
322+
self.setLayout(layout)
323+
324+
def log_message(self, msg):
325+
# delegate logging to parent window if available, otherwise use module logger
326+
parent = self.parent()
327+
if parent is not None and hasattr(parent, "log_message"):
328+
parent.log_message(msg)
329+
else:
330+
get_logger("wintweaks").info(msg)
331+
332+
def update_winhardware(self):
333+
# update winhardware req disable setting
334+
states.win_hardware_bypass = 1 if self.hardware_checkbox.isChecked() else 0
335+
self.log_message(
336+
f"Windows hardware requirement disable: {'enabled' if self.hardware_checkbox.isChecked() else 'disabled'}"
337+
)
338+
339+
def update_winmicrosoftacc(self):
340+
# update microsoft acc disable setting
341+
states.win_microsoft_acc = 1 if self.microsoft_checkbox.isChecked() else 0
342+
self.log_message(
343+
f"Microsoft account requirement disable: {'enabled' if self.microsoft_checkbox.isChecked() else 'disabled'}"
344+
)
345+
346+
def update_winlocalaccchk(self):
347+
# update local acc setting
348+
states.win_local_acc_chk = 1 if self.localacc_checkbox.isChecked() else 0
349+
self.log_message(
350+
f"Windows Local Account Add: {'enabled' if self.localacc_checkbox.isChecked() else 'disabled'}"
351+
)
352+
353+
def sync_username(self, new_username):
354+
# changes local username
355+
states.win_local_acc = new_username
356+
357+
def update_winprivacy(self):
358+
# update win privacy setting
359+
states.win_privacy = 1 if self.data_checkbox.isChecked() else 0
360+
self.log_message(
361+
f"Windows privacy questions disable: {'enabled' if self.data_checkbox.isChecked() else 'disabled'}"
362+
)
363+
# main tweaks apply logic function
364+
365+
def applywintweaks(self):
366+
# closes window
367+
self.accept()
368+
369+
370+
# for debug
371+
# if __name__ == "__main__":
372+
# # Standard boilerplate for testing the class standalone
373+
# app = QApplication(sys.argv)
374+
# window = WinTweaks()
375+
# window.exec()
376+
# sys.exit(app.exec())

0 commit comments

Comments
 (0)