Skip to content

Commit e907614

Browse files
committed
improved
1 parent 32604ca commit e907614

File tree

3 files changed

+79
-48
lines changed

3 files changed

+79
-48
lines changed

MacAttack.pyw

Lines changed: 78 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,14 @@ class MacAttack(QMainWindow):
340340
QTabBar::tab {
341341
background-color: #444444;
342342
color: white;
343-
padding: 5px;
344-
border-radius: 3px; /* Optional: rounded corners for tab buttons */
343+
padding-top: 5px; /* Adds 5px top padding */
344+
padding-right: 5px; /* Adds 5px right padding */
345+
padding-bottom: 5px; /* Adds 5px bottom padding */
346+
padding-left: 5px; /* Adds 5px left padding */
347+
border-top-left-radius: 8px; /* Rounded top-left corner */
348+
border-top-right-radius: 8px; /* Rounded top-right corner */
349+
border-bottom-left-radius: 0px; /* No rounding on bottom-left */
350+
border-bottom-right-radius: 0px; /* No rounding on bottom-right */
345351
}
346352
347353
QTabBar::tab:selected {
@@ -369,6 +375,7 @@ class MacAttack(QMainWindow):
369375
self.main_layout.setSpacing(0)
370376

371377
# Create the tabs (Top-level tabs)
378+
self.main_layout.addSpacing(8) # Adds space
372379
self.tabs = QTabWidget(self) # This is for the "Mac Attack" and "Mac VideoPlayer" tabs
373380
self.main_layout.addWidget(self.tabs)
374381

@@ -385,6 +392,7 @@ class MacAttack(QMainWindow):
385392
self.update_mac_label_signal.connect(self.update_mac_label)
386393
self.update_output_text_signal.connect(self.update_output_text)
387394
self.update_error_text_signal.connect(self.update_error_text)
395+
self.tabs.currentChanged.connect(self.on_tab_change)
388396

389397
def update_mac_label(self, text):
390398
"""Update the MAC address label in the main thread."""
@@ -435,6 +443,30 @@ class MacAttack(QMainWindow):
435443
combined_layout.addWidget(self.start_button)
436444
combined_layout.addWidget(self.stop_button)
437445

446+
self.start_button.setDisabled(False)
447+
self.stop_button.setDisabled(True)
448+
449+
450+
# Set a stylesheet to make the background grey when disabled
451+
self.stop_button.setStyleSheet("""
452+
QPushButton:disabled {
453+
background-color: grey;
454+
}
455+
QPushButton:enabled {
456+
background-color: red;
457+
}
458+
""")
459+
self.start_button.setStyleSheet("""
460+
QPushButton:disabled {
461+
background-color: grey;
462+
}
463+
QPushButton:enabled {
464+
background-color: green;
465+
466+
}
467+
""")
468+
469+
438470
# Add spacer to the right of the Stop button
439471
right_spacer = QSpacerItem(10, 0, QSizePolicy.Fixed, QSizePolicy.Minimum)
440472
combined_layout.addItem(right_spacer)
@@ -469,7 +501,7 @@ class MacAttack(QMainWindow):
469501
border-right: 12px solid #2E2E2E;
470502
border-bottom: 0px;
471503
""")
472-
self.error_text.setPlainText("Error LOG:\nIt's normal for a few errors to appear down here.\nwhen speed is set high\nIf errors are getting spammed, lower the speed.")
504+
self.error_text.setHtml("Error LOG:<br>It's normal for a few errors to appear down here.<br>If <b>\"Empty response\"</b> errors are getting spammed, lower the speed.")
473505
self.error_text.setReadOnly(True)
474506
layout.addWidget(self.error_text)
475507
layout.addSpacing(15) # Adds space
@@ -500,6 +532,7 @@ class MacAttack(QMainWindow):
500532
self.hostname_layout = QHBoxLayout() # Create a horizontal layout
501533
self.hostname_layout.setContentsMargins(0, 0, 0, 0)
502534
self.hostname_layout.setSpacing(0)
535+
self.left_layout.addSpacing(8) # Adds space
503536
self.hostname_label = QLabel("Host:")
504537
self.hostname_layout.addWidget(self.hostname_label)
505538
self.hostname_input = QLineEdit()
@@ -510,20 +543,24 @@ class MacAttack(QMainWindow):
510543
self.mac_layout = QHBoxLayout()
511544
self.mac_layout.setContentsMargins(0, 0, 0, 0)
512545
self.mac_layout.setSpacing(0)
546+
self.left_layout.addSpacing(8) # Adds space
513547
self.mac_label = QLabel("MAC:")
514548
self.mac_layout.addWidget(self.mac_label)
515549
self.mac_input = QLineEdit()
516550
self.mac_layout.addWidget(self.mac_input)
517551
self.left_layout.addLayout(self.mac_layout)
518-
552+
553+
self.left_layout.addSpacing(8) # Adds space
519554
self.get_playlist_button = QPushButton("Get Playlist")
520555
self.left_layout.addWidget(self.get_playlist_button)
521556
self.get_playlist_button.clicked.connect(self.get_playlist)
522-
557+
self.left_layout.addSpacing(8) # Adds space
523558
# Create a QTabWidget (for "Live", "Movies", "Series")
524559
self.tab_widget = QTabWidget()
525560
self.left_layout.addWidget(self.tab_widget)
526-
561+
self.get_playlist_button.setFixedWidth(120)
562+
self.left_layout.setAlignment(self.get_playlist_button, Qt.AlignCenter)
563+
527564
# Dictionary to hold tab data
528565
self.tab_data = {}
529566

@@ -583,9 +620,6 @@ class MacAttack(QMainWindow):
583620
self.video_frame = QWidget(self) # Changed from QFrame to QWidget for direct size management
584621
self.video_frame.setStyleSheet("background-color: black;") # Ensure black background for video area
585622

586-
# VLC dynamic width
587-
new_width = self.width() - 360
588-
self.video_frame.setMinimumWidth(new_width)
589623

590624
main_layout.addWidget(self.video_frame)
591625

@@ -596,8 +630,13 @@ class MacAttack(QMainWindow):
596630
elif sys.platform == "darwin": # for MacOS
597631
self.videoPlayer.set_nsobject(int(self.video_frame.winId()))
598632

599-
self.videoPlayer.set_media(self.instance.media_new('https://iptv.evilvir.us/skull4K.mp4')) # Load skull
600-
self.videoPlayer.play() # Start playing the video
633+
634+
# Determine the correct path for the video
635+
if getattr(sys, 'frozen', False): # Check if running as a bundled executable
636+
video_path = os.path.join(sys._MEIPASS, 'video', 'skull.mp4')
637+
else:
638+
video_path = os.path.join('video', 'skull.mp4') # For normal Python execution
639+
self.videoPlayer.set_media(self.instance.media_new(video_path)) # Load skull
601640

602641
self.videoPlayer.video_set_mouse_input(False)
603642
self.videoPlayer.video_set_key_input(False)
@@ -607,7 +646,7 @@ class MacAttack(QMainWindow):
607646
self.progress_animation.setDuration(1000) # Duration of the animation (in milliseconds)
608647
self.progress_animation.setEasingCurve(QEasingCurve.Linear) # Smooth progress change
609648

610-
def save_settings(self):
649+
def SaveTheDay(self):
611650
"""Save user settings, including window geometry, to the configuration file."""
612651
import os
613652
import configparser
@@ -683,8 +722,8 @@ class MacAttack(QMainWindow):
683722
def TestDrive(self):
684723
# The "Let's hit the gas and see what happens" function
685724
self.running = True
686-
#self.start_button.setDisabled(True)
687-
#self.start_button.setDisabled(False)
725+
self.start_button.setDisabled(True)
726+
self.stop_button.setDisabled(False)
688727

689728
self.iptv_link = self.iptv_link_entry.text()
690729
self.parsed_url = urlparse(self.iptv_link)
@@ -693,26 +732,24 @@ class MacAttack(QMainWindow):
693732
self.base_url = f"http://{self.host}:{self.port}"
694733

695734
num_tests = self.concurrent_tests.value()
696-
# Limit to a maximum of 10 concurrent tests, 'cause we’re not running a circus here.
735+
# Limit to a maximum of 15 concurrent tests, 'cause we’re not running a circus here.
697736
if num_tests > 15:
698737
num_tests = 15
699738

700-
# Save current settings to a file so they don’t get lost forever
701-
self.SaveTheDay()
702-
703739
# Start threads to test MACs
704740
for _ in range(num_tests):
705741
thread = threading.Thread(target=self.BigMacAttack)
706742
thread.daemon = True
707743
thread.start()
708744
self.threads.append(thread)
709-
self.save_settings()
745+
self.SaveTheDay()
710746

711747
def RandomMacGenerator(self, prefix="00:1A:79:"):
712748
# Create random MACs. Purely for mischief. Don't tell anyone.
713749
return f"{prefix}{random.randint(0, 255):02X}:{random.randint(0, 255):02X}:{random.randint(0, 255):02X}"
714750

715751
def BigMacAttack(self):
752+
self.error_count = 0
716753
# BigMacAttack: Two all-beef patties, special sauce, lettuce, cheese, pickles, onions, on a sesame seed bun.
717754
while self.running: # Loop will continue as long as self.running is True
718755
mac = self.RandomMacGenerator() # Generate a random MAC
@@ -778,31 +815,20 @@ class MacAttack(QMainWindow):
778815
# Catch all relevant exceptions and ensure the loop continues
779816
except (json.decoder.JSONDecodeError, requests.exceptions.RequestException, TypeError) as e:
780817
if "Expecting value: line 1 column 1 (char 0)" in str(e):
781-
self.update_error_text_signal.emit(
782-
f"Error for MAC: {mac} : {str(e).replace('Expecting value: line 1 column 1 (char 0)', 'Empty response')}"
783-
)
818+
if self.error_count >= 6:
819+
self.update_error_text_signal.emit(
820+
f"Error for MAC: {mac} : {str(e).replace('Expecting value: line 1 column 1 (char 0)', 'Empty response')}"
821+
)
822+
self.error_count += 1 # Increment the error count
784823
else:
785-
self.update_error_text_signal.emit(f"Error for MAC {mac}: {str(e)}")
824+
if self.error_count >= 6: #skipping emitting the first 6 errors. Because, laziness.
825+
self.update_error_text_signal.emit(f"Error for MAC {mac}: {str(e)}")
826+
self.error_count += 1 # Increment the error count
786827

787-
def SaveTheDay(self):
788-
# Saving the day by storing our preferences so we can be lazy
789-
settings = {
790-
'url': self.iptv_link_entry.text(),
791-
'speed': self.concurrent_tests.value()
792-
}
793-
794-
# Ensuring the sacred settings folder is there
795-
user_profile = os.environ['USERPROFILE']
796-
settings_dir = os.path.join(user_profile, "Evilvir.us")
797-
os.makedirs(settings_dir, exist_ok=True)
798-
settings_file = os.path.join(settings_dir, "iptv_checker_settings.json")
799-
800-
with open(settings_file, 'w') as file:
801-
json.dump(settings, file)
802828

803829
def OutputMastermind(self):
804830
# Fancy file-naming because why not complicate things?
805-
current_time = datetime.now().strftime("%Y%m%d_%H%M%S")
831+
current_time = datetime.now().strftime("%m%d_%H%M%S")
806832
sanitized_url = self.base_url.replace("http://", "").replace("https://", "").replace("/", "_").replace(":", "-")
807833
filename = f"{sanitized_url}_{current_time}.txt"
808834
return filename
@@ -812,8 +838,8 @@ class MacAttack(QMainWindow):
812838
# GiveUp: Like throwing in the towel, but with less dignity. But hey, we tried, right?
813839
print("GiveUp method has been called. We tried, but it's over.") # Console printout
814840
self.running = False
815-
# self.start_button.setDisabled(False)
816-
# self.start_button.setDisabled(True)
841+
self.start_button.setDisabled(False)
842+
self.stop_button.setDisabled(True)
817843

818844
if hasattr(self, 'output_file') and self.output_file:
819845
self.output_file.close()
@@ -840,7 +866,7 @@ class MacAttack(QMainWindow):
840866
mac_address = self.mac_input.text()
841867

842868
if not hostname_input or not mac_address:
843-
self.error_label.setText("ERROR: Unable to connect to the host")
869+
self.error_label.setText("ERROR: Missing input.")
844870
self.error_label.show()
845871
logging.warning(
846872
"User attempted to get playlist without entering all required fields."
@@ -1449,17 +1475,22 @@ class MacAttack(QMainWindow):
14491475
self.error_label.hide()
14501476
self.videoPlayer.play() # Play the video
14511477
self.tabs.tabBar().setVisible(True)
1452-
1478+
1479+
def on_tab_change(self, index):
1480+
"""Method to handle video playback when the Mac VideoPlayer tab is selected"""
1481+
if self.tabs.tabText(index) == "Mac VideoPlayer":
1482+
self.videoPlayer.play() # Play the video when Mac VideoPlayer tab is selected
1483+
else:
1484+
self.videoPlayer.pause() # Pause the video when the tab is not selected
14531485
def resizeEvent(self, event):
1454-
# Calculate new width with a minimum constraint to prevent zero or negative sizes
1455-
new_width = max(self.width() - 290, 300) # keeping the playlist side @ 360, and make the window no smaller than 370
1456-
# Set the new minimum width for the video frame
1486+
# VLC dynamic width
1487+
new_width = self.width() - 250
14571488
self.video_frame.setMinimumWidth(new_width)
14581489

14591490

14601491
def closeEvent(self, event):
14611492
# Save settings when the window is about to close
1462-
self.save_settings()
1493+
self.SaveTheDay()
14631494

14641495
# Accept the close event
14651496
event.accept()

build_windows_exe.bat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
pyinstaller.exe --onefile --icon=icon.ico MacAttack.pyw
1+
pyinstaller.exe --onefile --add-data="video\;video" --icon=icon.ico MacAttack.pyw
22
copy dist\MacAttack.exe .\
33
pause

video/skull.mp4

4.25 MB
Binary file not shown.

0 commit comments

Comments
 (0)